зеркало из https://github.com/Azure/git-rest-api.git
Feature: Generate typescript SDK (#13)
This commit is contained in:
Родитель
c1940cc747
Коммит
ba2f985669
|
@ -1,5 +1,3 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
pool:
|
||||
vmImage: "Ubuntu 16.04"
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pr: none
|
||||
|
||||
stages:
|
||||
- stage: Build_Docker
|
||||
jobs:
|
||||
- job: Build_Docker
|
||||
pool:
|
||||
vmImage: "Ubuntu-16.04"
|
||||
steps:
|
||||
- task: Docker@2
|
||||
displayName: "Build azuredevx/git-rest-api"
|
||||
inputs:
|
||||
containerRegistry: "git-rest-api docker"
|
||||
repository: "azuredevx/git-rest-api"
|
||||
tags: |
|
||||
$(Build.BuildId)
|
||||
latest
|
||||
- stage: Publish_Docker
|
||||
dependsOn: Build_Docker
|
||||
jobs:
|
||||
- job: Publish_Docker
|
||||
pool:
|
||||
vmImage: "Ubuntu-16.04"
|
||||
steps:
|
||||
- task: Docker@2
|
||||
displayName: "Push azuredevx/git-rest-api"
|
||||
inputs:
|
||||
containerRegistry: "git-rest-api docker"
|
||||
repository: "azuredevx/git-rest-api"
|
|
@ -0,0 +1,58 @@
|
|||
trigger:
|
||||
- master
|
||||
|
||||
pr: none
|
||||
|
||||
stages:
|
||||
- stage: Build_Docker
|
||||
jobs:
|
||||
- job: Build_Docker
|
||||
pool:
|
||||
vmImage: "Ubuntu-16.04"
|
||||
steps:
|
||||
- task: Docker@2
|
||||
displayName: "Build azuredevx/git-rest-api"
|
||||
inputs:
|
||||
containerRegistry: "git-rest-api docker"
|
||||
repository: "azuredevx/git-rest-api"
|
||||
tags: |
|
||||
$(Build.BuildId)
|
||||
latest
|
||||
- stage: Publish_Docker
|
||||
dependsOn: Build_Docker
|
||||
jobs:
|
||||
- job: Publish_Docker
|
||||
pool:
|
||||
vmImage: "Ubuntu-16.04"
|
||||
steps:
|
||||
- task: Docker@2
|
||||
displayName: "Push azuredevx/git-rest-api"
|
||||
inputs:
|
||||
containerRegistry: "git-rest-api docker"
|
||||
repository: "azuredevx/git-rest-api"
|
||||
|
||||
- stage: build_sdks
|
||||
displayName: Build SDKs
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- job: build
|
||||
pool:
|
||||
vmImage: "Ubuntu-16.04"
|
||||
steps:
|
||||
- script: npm -s ci
|
||||
displayName: Install
|
||||
- script: npm -s run sdk:gen
|
||||
displayName: Generate SDKs
|
||||
- script: npm -s pack
|
||||
workingDirectory: sdk/out/typescript
|
||||
displayName: Pack
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: drop'
|
||||
inputs:
|
||||
sourceFolder: ./sdk/out/typescript
|
||||
contents: '*.tgz'
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)/drop
|
||||
- task: PublishPipelineArtifact@0
|
||||
inputs:
|
||||
artifactName: "drop"
|
||||
targetPath: $(Build.ArtifactStagingDirectory)/drop
|
|
@ -62,3 +62,6 @@ buildcache/
|
|||
tmp/
|
||||
# Junit
|
||||
test-results*
|
||||
|
||||
# Generated sdk folder
|
||||
sdk/out/
|
|
@ -6,5 +6,14 @@
|
|||
"buildcache": true,
|
||||
"coverage": true
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
"files.exclude": {
|
||||
"**/.git": true,
|
||||
"**/.svn": true,
|
||||
"**/.hg": true,
|
||||
"**/CVS": true,
|
||||
"**/.DS_Store": true,
|
||||
"sdk/out/**/node_modules": true
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"typescript.disableAutomaticTypeAcquisition": true // Cause issue with locking folder on windows. Types should be installed anyway in package.json
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
10
package.json
10
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "git-rest-api",
|
||||
"version": "1.0.0",
|
||||
"version": "0.2.0",
|
||||
"description": "This project welcomes contributions and suggestions. Most contributions require you to agree to a\r Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us\r the rights to use your contribution. For details, visit https://cla.microsoft.com.",
|
||||
"main": "bin/main.js",
|
||||
"scripts": {
|
||||
|
@ -14,7 +14,10 @@
|
|||
"test:ci": "jest --ci --reporters=default --reporters=jest-junit",
|
||||
"lint": "tslint -p tsconfig.json",
|
||||
"test:watch": "jest --watch --coverage=false --config ./config/jest.dev.config.js",
|
||||
"swagger:gen": "node ./bin/scripts/generate-swagger-specs.js"
|
||||
"swagger:gen": "node ./bin/scripts/generate-swagger-specs.js",
|
||||
"autorest": "cross-var autorest sdk/config.yaml --package-version=$npm_package_version",
|
||||
"sdk:gen": "npm run sdk:gen:ts",
|
||||
"sdk:gen:ts": "cross-var rimraf ./sdk/out/typescript/* && copyfiles -u 3 \"./sdk/src/typescript/**/*\" ./sdk/out/typescript && npm run autorest -- --typescript --enum-types=true && npm run prepack --prefix ./sdk/out/typescript"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -33,7 +36,10 @@
|
|||
"@types/jest": "^24.0.13",
|
||||
"@types/node-fetch": "^2.3.4",
|
||||
"@types/nodegit": "^0.24.6",
|
||||
"autorest": "^2.0.4283",
|
||||
"concurrently": "^4.1.0",
|
||||
"copyfiles": "^2.1.0",
|
||||
"cross-var": "^1.1.0",
|
||||
"jest": "^24.8.0",
|
||||
"jest-junit": "^6.4.0",
|
||||
"prettier": "^1.17.1",
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
input-file: ../swagger-spec.json
|
||||
typescript:
|
||||
package-name: "git-rest-api"
|
||||
payload-flattening-threshold: 0
|
||||
generate-package-json: false
|
||||
output-folder: "out/typescript"
|
||||
enum-types: true
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./models";
|
||||
export * from "./gITRestAPI";
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"name": "git-rest-api-sdk",
|
||||
"author": "Microsoft Corporation",
|
||||
"description": "GITRestAPI Library with typescript type definitions for node.js and browser.",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@azure/ms-rest-js": "^1.1.0",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"keywords": [
|
||||
"node",
|
||||
"azure",
|
||||
"git",
|
||||
"typescript",
|
||||
"browser",
|
||||
"isomorphic"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./dist/bundle.js",
|
||||
"module": "./esm/index.js",
|
||||
"types": "./esm/index.d.ts",
|
||||
"devDependencies": {
|
||||
"typescript": "^3.1.1",
|
||||
"rollup": "^0.66.2",
|
||||
"rollup-plugin-node-resolve": "^3.4.0",
|
||||
"uglify-js": "^3.4.9"
|
||||
},
|
||||
"homepage": "https://github.com/azure/git-rest-api",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/azure/git-rest-api.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/azure/git-rest-api/issues"
|
||||
},
|
||||
"files": [
|
||||
"dist/**/*.js",
|
||||
"dist/**/*.js.map",
|
||||
"dist/**/*.d.ts",
|
||||
"dist/**/*.d.ts.map",
|
||||
"esm/**/*.js",
|
||||
"esm/**/*.js.map",
|
||||
"esm/**/*.d.ts",
|
||||
"esm/**/*.d.ts.map",
|
||||
"lib/**/*.ts",
|
||||
"rollup.config.js",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc && rollup -c rollup.config.js && npm run minify",
|
||||
"minify": "uglifyjs -c -m --comments --source-map \"content='./dist/bundle.js.map'\" -o ./dist/bundle.min.js ./dist/bundle.js",
|
||||
"prepack": "npm install && npm run build"
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import nodeResolve from "rollup-plugin-node-resolve";
|
||||
/**
|
||||
* @type {import('rollup').RollupFileOptions}
|
||||
*/
|
||||
const config = {
|
||||
input: './esm/index.js',
|
||||
external: ["@azure/ms-rest-js", "@azure/ms-rest-azure-js"],
|
||||
output: {
|
||||
file: "./dist/bundle.js",
|
||||
format: "umd",
|
||||
name: "Bundle",
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
"@azure/ms-rest-js": "msRest",
|
||||
"@azure/ms-rest-azure-js": "msRestAzure"
|
||||
},
|
||||
banner: `/*
|
||||
* Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
* Changes may cause incorrect behavior and will be lost if the code is
|
||||
* regenerated.
|
||||
*/`
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve({ module: true })
|
||||
]
|
||||
};
|
||||
export default config;
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "es6",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"target": "es5",
|
||||
"sourceMap": true,
|
||||
"declarationMap": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["es6"],
|
||||
"declaration": true,
|
||||
"outDir": "./esm",
|
||||
"importHelpers": true
|
||||
},
|
||||
"include": ["./lib/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package-lock.json
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "git-rest-api-sdk-test",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "ts-node test.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"git-rest-api-sdk": "../../out/typescript",
|
||||
"ts-node": "^8.1.0",
|
||||
"typescript": "^3.4.5"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { GITRestAPI, GitBranch } from "git-rest-api-sdk";
|
||||
// tslint:disable: no-console
|
||||
|
||||
const sdk = new GITRestAPI({ baseUri: "http://localhost:3009" });
|
||||
|
||||
async function run() {
|
||||
const branches: GitBranch[] = await sdk.branches.list("github.com/Azure/BatchExplorer");
|
||||
console.log("Branches:");
|
||||
|
||||
for (const branch of branches) {
|
||||
console.log(` - ${branch.name} ${branch.commit.sha}`);
|
||||
}
|
||||
}
|
||||
|
||||
run().catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
|
@ -1,13 +1,7 @@
|
|||
import { Module } from "@nestjs/common";
|
||||
|
||||
import { Configuration } from "./config";
|
||||
import {
|
||||
AppController,
|
||||
BranchesController,
|
||||
CommitsController,
|
||||
CompareController,
|
||||
HealthCheckController,
|
||||
} from "./controllers";
|
||||
import { BranchesController, CommitsController, CompareController, HealthCheckController } from "./controllers";
|
||||
import {
|
||||
AppService,
|
||||
BranchService,
|
||||
|
@ -23,7 +17,7 @@ import {
|
|||
|
||||
@Module({
|
||||
imports: [],
|
||||
controllers: [AppController, HealthCheckController, BranchesController, CommitsController, CompareController],
|
||||
controllers: [HealthCheckController, BranchesController, CommitsController, CompareController],
|
||||
providers: [
|
||||
AppService,
|
||||
CompareService,
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
import { Controller, Get } from "@nestjs/common";
|
||||
|
||||
import { AppService } from "../services";
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService) {
|
||||
this.appService.getHello();
|
||||
}
|
||||
|
||||
@Get()
|
||||
public getHello(): string {
|
||||
return this.appService.getHello();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { Controller, Get, Param } from "@nestjs/common";
|
||||
import { ApiNotFoundResponse, ApiOkResponse } from "@nestjs/swagger";
|
||||
import { ApiNotFoundResponse, ApiOkResponse, ApiOperation } from "@nestjs/swagger";
|
||||
|
||||
import { ApiHasPassThruAuth, Auth, RepoAuth } from "../../core";
|
||||
import { GitBranch } from "../../dtos";
|
||||
|
@ -13,6 +13,7 @@ export class BranchesController {
|
|||
@ApiHasPassThruAuth()
|
||||
@ApiOkResponse({ type: GitBranch, isArray: true })
|
||||
@ApiNotFoundResponse({})
|
||||
@ApiOperation({ title: "List branches", operationId: "Branches_List" })
|
||||
public async list(@Param("remote") remote: string, @Auth() auth: RepoAuth): Promise<GitBranch[]> {
|
||||
const branches = await this.branchService.list(remote, { auth });
|
||||
return branches;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Controller, Get, NotFoundException, Param } from "@nestjs/common";
|
||||
import { ApiNotFoundResponse, ApiOkResponse } from "@nestjs/swagger";
|
||||
import { ApiNotFoundResponse, ApiOkResponse, ApiOperation } from "@nestjs/swagger";
|
||||
|
||||
import { ApiHasPassThruAuth, Auth, RepoAuth } from "../../core";
|
||||
import { GitCommit } from "../../dtos";
|
||||
|
@ -13,6 +13,7 @@ export class CommitsController {
|
|||
@ApiHasPassThruAuth()
|
||||
@ApiOkResponse({ type: GitCommit, isArray: true })
|
||||
@ApiNotFoundResponse({})
|
||||
@ApiOperation({ title: "Get a commit", operationId: "commits_get" })
|
||||
public async get(@Param("remote") remote: string, @Param("commitSha") commitSha: string, @Auth() auth: RepoAuth) {
|
||||
const commit = await this.commitService.get(remote, commitSha, { auth });
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Controller, Get, HttpException, Param } from "@nestjs/common";
|
||||
import { ApiNotFoundResponse, ApiOkResponse } from "@nestjs/swagger";
|
||||
import { ApiNotFoundResponse, ApiOkResponse, ApiOperation } from "@nestjs/swagger";
|
||||
|
||||
import { ApiHasPassThruAuth, Auth, RepoAuth } from "../../core";
|
||||
import { GitDiff } from "../../dtos/git-diff";
|
||||
|
@ -13,6 +13,7 @@ export class CompareController {
|
|||
@ApiHasPassThruAuth()
|
||||
@ApiOkResponse({ type: GitDiff, isArray: true })
|
||||
@ApiNotFoundResponse({})
|
||||
@ApiOperation({ title: "Compare two commits", operationId: "commits_compare" })
|
||||
public async compare(
|
||||
@Param("remote") remote: string,
|
||||
@Param("base") base: string,
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { Controller, Get } from "@nestjs/common";
|
||||
import { ApiOperation } from "@nestjs/swagger";
|
||||
|
||||
@Controller("/health")
|
||||
export class HealthCheckController {
|
||||
@Get("/alive")
|
||||
@ApiOperation({ title: "Check alive", operationId: "health_checkAlive" })
|
||||
public async getAlive() {
|
||||
return "alive";
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
export * from "./app.controller";
|
||||
export * from "./commits/commits.controller";
|
||||
export * from "./health-check/health-check.controller";
|
||||
export * from "./branches/branches.controller";
|
||||
|
|
|
@ -10,6 +10,8 @@ const SWAGGER_FILE_PATH = "./swagger-spec.json";
|
|||
|
||||
export async function generateSwagger(): Promise<string> {
|
||||
const { document } = await createApp();
|
||||
reorderPaths(document.paths);
|
||||
|
||||
return JSON.stringify(document, null, 2);
|
||||
}
|
||||
|
||||
|
@ -22,3 +24,34 @@ export async function getSavedSwagger(): Promise<string> {
|
|||
const response = await readFile(SWAGGER_FILE_PATH);
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Because of how the nestjs generate the path params they might not be in order which could lead to breaking changes without noticing.
|
||||
* Force the params to be ordered how they are defined in the path
|
||||
*/
|
||||
export function reorderPaths(paths: StringMap<StringMap<any>>) {
|
||||
for (const [path, methods] of Object.entries(paths)) {
|
||||
for (const def of Object.values(methods)) {
|
||||
if (def.parameters) {
|
||||
def.parameters = getOrderedPathParams(path, def.parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface SwaggerParam {
|
||||
type: string;
|
||||
name: string;
|
||||
required: boolean;
|
||||
in: "path" | "header";
|
||||
}
|
||||
|
||||
export function getOrderedPathParams(path: string, parameters: SwaggerParam[]) {
|
||||
const pathParams = parameters.filter(x => x.in === "path");
|
||||
const otherParams = parameters.filter(x => x.in !== "path");
|
||||
|
||||
const sortedPathParams = [...pathParams].sort((a, b) => {
|
||||
return path.indexOf(`{${a.name}}`) - path.indexOf(`{${b.name}}`);
|
||||
});
|
||||
return [...sortedPathParams, ...otherParams];
|
||||
}
|
||||
|
|
|
@ -12,23 +12,10 @@
|
|||
"https"
|
||||
],
|
||||
"paths": {
|
||||
"/": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/health/alive": {
|
||||
"get": {
|
||||
"summary": "Check alive",
|
||||
"operationId": "health_checkAlive",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
|
@ -44,6 +31,8 @@
|
|||
},
|
||||
"/repos/{remote}/branches": {
|
||||
"get": {
|
||||
"summary": "List branches",
|
||||
"operationId": "Branches_List",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -91,16 +80,18 @@
|
|||
},
|
||||
"/repos/{remote}/commits/{commitSha}": {
|
||||
"get": {
|
||||
"summary": "Get a commit",
|
||||
"operationId": "commits_get",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "commitSha",
|
||||
"name": "remote",
|
||||
"required": true,
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "remote",
|
||||
"name": "commitSha",
|
||||
"required": true,
|
||||
"in": "path"
|
||||
},
|
||||
|
@ -144,10 +135,12 @@
|
|||
},
|
||||
"/repos/{remote}/compare/{base}...{head}": {
|
||||
"get": {
|
||||
"summary": "Compare two commits",
|
||||
"operationId": "commits_compare",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "head",
|
||||
"name": "remote",
|
||||
"required": true,
|
||||
"in": "path"
|
||||
},
|
||||
|
@ -159,7 +152,7 @@
|
|||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "remote",
|
||||
"name": "head",
|
||||
"required": true,
|
||||
"in": "path"
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче