зеркало из https://github.com/Azure/autorest.git
schema validation (#2750)
* undid modeler-only flag (whoops, past-me added that to the modeler's readme) * dep * schema-validator * schema validation * local schemas * regen * typo * das fix * rename
This commit is contained in:
Родитель
6eeda4228e
Коммит
965e4ad491
|
@ -6,9 +6,7 @@
|
|||
"type": "integer"
|
||||
},
|
||||
"details": {
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ErrorDetails"
|
||||
}
|
||||
"$ref": "#/definitions/ErrorDetails"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
|
|
|
@ -396,8 +396,7 @@ definitions:
|
|||
message:
|
||||
type: string
|
||||
details:
|
||||
schema:
|
||||
"$ref": "https://github.com/Azure/azure-rest-api-specs/blob/master/arm-network/2016-09-01/swagger/network.json#/definitions/ErrorDetails"
|
||||
"$ref": "https://github.com/Azure/azure-rest-api-specs/blob/master/arm-network/2016-09-01/swagger/network.json#/definitions/ErrorDetails"
|
||||
responses:
|
||||
error:
|
||||
description: OK
|
||||
|
|
|
@ -267,7 +267,7 @@ pipeline:
|
|||
suffixes:
|
||||
- ''
|
||||
swagger-document/individual/identity:
|
||||
input: transform
|
||||
input: schema-validator
|
||||
output-artifact: swagger-document
|
||||
suffixes:
|
||||
- ''
|
||||
|
@ -276,6 +276,11 @@ pipeline:
|
|||
scope: azure-validator-individual
|
||||
suffixes:
|
||||
- ''
|
||||
swagger-document/individual/schema-validator:
|
||||
input: transform
|
||||
output-artifact: swagger-document
|
||||
suffixes:
|
||||
- ''
|
||||
swagger-document/individual/transform:
|
||||
input: loader
|
||||
output-artifact: swagger-document
|
||||
|
|
|
@ -148,7 +148,7 @@ swagger-document/individual/identity:
|
|||
configScope:
|
||||
- perform-load
|
||||
inputs:
|
||||
- swagger-document/individual/transform
|
||||
- swagger-document/individual/schema-validator
|
||||
outputArtifact: swagger-document
|
||||
pluginName: identity
|
||||
swagger-document/individual/openapi-validator:
|
||||
|
@ -158,6 +158,13 @@ swagger-document/individual/openapi-validator:
|
|||
inputs:
|
||||
- swagger-document/individual/identity
|
||||
pluginName: openapi-validator
|
||||
swagger-document/individual/schema-validator:
|
||||
configScope:
|
||||
- perform-load
|
||||
inputs:
|
||||
- swagger-document/individual/transform
|
||||
outputArtifact: swagger-document
|
||||
pluginName: schema-validator
|
||||
swagger-document/individual/transform:
|
||||
configScope:
|
||||
- perform-load
|
||||
|
|
|
@ -35,3 +35,4 @@ definitions:
|
|||
name:
|
||||
type: string
|
||||
additionalProperties: true
|
||||
paths: {}
|
|
@ -0,0 +1,7 @@
|
|||
# Test: OpenAPI definition violation the schema
|
||||
|
||||
> see https://aka.ms/autorest
|
||||
|
||||
``` yaml
|
||||
input-file: tiny.yaml
|
||||
```
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,9 @@
|
|||
- /Samples/test/error-behavior/openapi-bad-schema/tiny.yaml:18:6 ($.paths["/cowbell"].post.parameters)
|
||||
- /Samples/test/error-behavior/openapi-bad-schema/tiny.yaml:28:2 ($.definitions.Cowbell)
|
||||
- /Samples/test/error-behavior/openapi-bad-schema/tiny.yaml:33:8 ($.definitions.Cowbell.properties.id.type)
|
||||
ERROR: Schema violation: Additional properties not allowed: foo
|
||||
ERROR: Schema violation: Data does not match any schemas from 'anyOf'
|
||||
ERROR: Schema violation: Data does not match any schemas from 'oneOf'
|
||||
FATAL: Error: [OperationAbortedException] Error occurred. Exiting.
|
||||
FATAL: swagger-document/individual/schema-validator - FAILED
|
||||
Process() Cancelled due to exception : [OperationAbortedException] Error occurred. Exiting.
|
|
@ -0,0 +1,3 @@
|
|||
(C) 2017 Microsoft Corporation.
|
||||
AutoRest code generation utility [version: 2.0.0]
|
||||
https://aka.ms/autorest
|
|
@ -0,0 +1,38 @@
|
|||
swagger: '2.0'
|
||||
info:
|
||||
description: This is a sample.
|
||||
version: 1.0.0
|
||||
title: Cowbell Factory
|
||||
host: localhost
|
||||
schemes:
|
||||
- https
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
"/cowbell":
|
||||
post:
|
||||
description: A good description.
|
||||
operationId: Cowbell_Add
|
||||
parameters:
|
||||
- in: bodi
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Cowbell'
|
||||
responses:
|
||||
'200':
|
||||
description: Cowbell was added.
|
||||
definitions:
|
||||
Cowbell:
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: int
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
description: A cowbell.
|
||||
foo: bar
|
|
@ -14,6 +14,7 @@ consumes:
|
|||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
paths: {}
|
||||
```
|
||||
|
||||
Host definition in JSON, because we can.
|
||||
|
|
|
@ -32,7 +32,7 @@ A good description.
|
|||
paths:
|
||||
"/cowbell":
|
||||
post:
|
||||
description: []
|
||||
# description: [] # TODO: add to schema if moving on with that
|
||||
operationId: Cowbell_Add
|
||||
parameters:
|
||||
- in: body
|
||||
|
@ -62,5 +62,5 @@ definitions:
|
|||
format: int64
|
||||
name:
|
||||
type: string
|
||||
description: []
|
||||
# description: [] # TODO: add to schema if moving on with that
|
||||
```
|
|
@ -1 +1,7 @@
|
|||
ERROR: Error converting value "Cowbell" to type 'System.Nullable`1[AutoRest.Modeler.Model.DataType]'. Path 'requestBody.content.application/json.schema.type', line 14, position 27.
|
||||
at ...
|
||||
at ...
|
||||
Error: Plugin imodeler1 reported failure.
|
||||
--- End of stack trace from previous location where exception was thrown ---
|
||||
FATAL: csharp/imodeler1 - FAILED
|
||||
FATAL: Error: Plugin imodeler1 reported failure.
|
||||
FATAL: System.ArgumentException: Reference path '#Cowbell' does not exist in the definition section of the Swagger document.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
(C) 2017 Microsoft Corporation.
|
||||
AutoRest code generation utility [version: 2.0.0]
|
||||
https://aka.ms/autorest
|
||||
Process() Cancelled due to exception : Plugin imodeler1 reported failure.
|
||||
|
|
|
@ -20,7 +20,7 @@ paths:
|
|||
name: body
|
||||
required: true
|
||||
schema:
|
||||
type: Cowbell
|
||||
$ref: "#Cowbell"
|
||||
responses:
|
||||
'200':
|
||||
description: Cowbell was added.
|
||||
|
|
|
@ -31,6 +31,7 @@ paths:
|
|||
- application/json
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/Cowbell'
|
||||
schemes:
|
||||
|
|
|
@ -32,6 +32,7 @@ paths:
|
|||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/Cowbell'
|
||||
definitions:
|
||||
|
|
|
@ -31,7 +31,8 @@ paths:
|
|||
modelAsString: false
|
||||
name: ImageType
|
||||
responses:
|
||||
'200': {}
|
||||
'200':
|
||||
description: OK
|
||||
"/ProcessImage/FunctionB":
|
||||
post:
|
||||
operationId: Image_B
|
||||
|
@ -48,7 +49,8 @@ paths:
|
|||
modelAsString: false
|
||||
name: ImageType
|
||||
responses:
|
||||
'200': {}
|
||||
'200':
|
||||
description: OK
|
||||
"/ProcessImage/FunctionC":
|
||||
post:
|
||||
operationId: Image_C
|
||||
|
@ -68,7 +70,8 @@ paths:
|
|||
- image/png
|
||||
- image/tiff
|
||||
responses:
|
||||
'200': {}
|
||||
'200':
|
||||
description: OK
|
||||
"/ProcessImage/FunctionD":
|
||||
post:
|
||||
operationId: Image_D
|
||||
|
@ -88,7 +91,8 @@ paths:
|
|||
- image/png
|
||||
- image/tiff
|
||||
responses:
|
||||
'200': {}
|
||||
'200':
|
||||
description: OK
|
||||
"/ProcessImage/FunctionTA":
|
||||
post:
|
||||
consumes:
|
||||
|
@ -99,7 +103,8 @@ paths:
|
|||
- "$ref": "#/parameters/TextStream"
|
||||
- "$ref": "#/parameters/TextContentType"
|
||||
responses:
|
||||
'200': {}
|
||||
'200':
|
||||
description: OK
|
||||
"/ProcessImage/FunctionTB":
|
||||
post:
|
||||
consumes:
|
||||
|
@ -110,7 +115,8 @@ paths:
|
|||
- "$ref": "#/parameters/TextStream"
|
||||
- "$ref": "#/parameters/TextContentType"
|
||||
responses:
|
||||
'200': {}
|
||||
'200':
|
||||
description: OK
|
||||
parameters:
|
||||
ImageStream:
|
||||
name: Image
|
||||
|
@ -119,7 +125,8 @@ parameters:
|
|||
x-ms-parameter-location: method
|
||||
description: An image stream.
|
||||
schema:
|
||||
type: file
|
||||
type: string
|
||||
format: binary
|
||||
TextStream:
|
||||
name: Text
|
||||
in: body
|
||||
|
@ -127,7 +134,8 @@ parameters:
|
|||
x-ms-parameter-location: method
|
||||
description: A text stream.
|
||||
schema:
|
||||
type: file
|
||||
type: string
|
||||
format: binary
|
||||
TextContentType:
|
||||
name: Content-Type
|
||||
in: header
|
||||
|
|
|
@ -401,6 +401,9 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"x-ms-headers": {
|
||||
"$ref": "#/definitions/schema"
|
||||
},
|
||||
"headers": {
|
||||
"$ref": "#/definitions/headers"
|
||||
},
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -3,8 +3,8 @@
|
|||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
import { parseJsonPointer } from '../lib/ref/jsonpath';
|
||||
import { JsonPath, SourceMap } from './source-map';
|
||||
|
||||
import { Location, Position } from 'vscode-languageserver';
|
||||
import { value, stringify, parse, nodes, paths, } from "jsonpath";
|
||||
|
||||
|
@ -64,7 +64,7 @@ export class DocumentAnalysis {
|
|||
if (path.length > 0 && path[path.length - 1] === "$ref") {
|
||||
// lookup object
|
||||
const refValueJsonPointer: string = value(this.fullyResolvedAndMergedDefinition, stringify(path));
|
||||
const refValueJsonPath: JsonPath = refValueJsonPointer.split("/").slice(1).map(part => part.replace(/~1/g, "/").replace(/~0/g, "~"));
|
||||
const refValueJsonPath: JsonPath = parseJsonPointer(refValueJsonPointer);
|
||||
return stringify(refValueJsonPath);
|
||||
}
|
||||
} // else { console.warn("no object path for that location"); return null; }
|
||||
|
|
|
@ -784,28 +784,32 @@ export class Configuration {
|
|||
}
|
||||
|
||||
public static async DetectConfigurationFiles(fileSystem: IFileSystem, configFileOrFolderUri: string | null, messageEmitter?: MessageEmitter, walkUpFolders: boolean = false): Promise<Array<string>> {
|
||||
const results = new Array<string>();
|
||||
const originalConfigFileOrFolderUri = configFileOrFolderUri;
|
||||
|
||||
// null means null!
|
||||
if (!configFileOrFolderUri) {
|
||||
return results;
|
||||
return [];
|
||||
}
|
||||
|
||||
// try querying the Uri directly
|
||||
let content: string | null;
|
||||
try {
|
||||
const content = await fileSystem.ReadFile(configFileOrFolderUri);
|
||||
content = await fileSystem.ReadFile(configFileOrFolderUri);
|
||||
} catch {
|
||||
// didn't get the file successfully, move on.
|
||||
content = null;
|
||||
}
|
||||
if (content !== null) {
|
||||
if (content.indexOf(Constants.MagicString) > -1) {
|
||||
// the file name was passed in!
|
||||
return [configFileOrFolderUri];
|
||||
}
|
||||
// this *was* an actual file passed in, not a folder. don't make this harder than it has to be.
|
||||
return results;
|
||||
} catch {
|
||||
// didn't get the file successfully, move on.
|
||||
throw new Error(`Specified file '${originalConfigFileOrFolderUri}' is not a valid configuration file (missing magic string, see https://github.com/Azure/autorest/blob/master/docs/user/literate-file-formats/configuration.md#the-file-format).`);
|
||||
}
|
||||
|
||||
// scan the filesystem items for configurations.
|
||||
const results = new Array<string>();
|
||||
for (const name of await fileSystem.EnumerateFileUris(EnsureIsFolderUri(configFileOrFolderUri))) {
|
||||
if (name.endsWith(".md")) {
|
||||
const content = await fileSystem.ReadFile(name);
|
||||
|
|
|
@ -50,7 +50,7 @@ export abstract class DataSource {
|
|||
public async ReadStrict(uri: string): Promise<DataHandle> {
|
||||
const result = await this.Read(uri);
|
||||
if (result === null) {
|
||||
throw new Error(`Could not to read '${uri}'.`);
|
||||
throw new Error(`Could not read '${uri}'.`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ export class DataStore {
|
|||
uri = ResolveUri(this.BaseUri, uri);
|
||||
const data = this.store[uri];
|
||||
if (!data) {
|
||||
throw new Error(`Could not to read '${uri}'.`);
|
||||
throw new Error(`Could not read '${uri}'.`);
|
||||
}
|
||||
return new DataHandle(uri, data);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ConfigurationView } from "../configuration";
|
||||
import { DataHandle, DataSink, QuickDataSource, DataSource } from "../data-store/data-store";
|
||||
|
||||
export type PipelinePlugin = (config: ConfigurationView, input: DataSource, sink: DataSink) => Promise<DataSource>;
|
||||
|
||||
export function CreatePerFilePlugin(processorBuilder: (config: ConfigurationView) => Promise<(input: DataHandle, sink: DataSink) => Promise<DataHandle>>): PipelinePlugin {
|
||||
return async (config, input, sink) => {
|
||||
const processor = await processorBuilder(config);
|
||||
const files = await input.Enum();
|
||||
const result: DataHandle[] = [];
|
||||
for (let file of files) {
|
||||
const fileIn = await input.ReadStrict(file);
|
||||
const fileOut = await processor(fileIn, sink);
|
||||
result.push(fileOut);
|
||||
}
|
||||
return new QuickDataSource(result);
|
||||
};
|
||||
}
|
|
@ -7,7 +7,7 @@ import { ReadUri, ResolveUri } from '../ref/uri';
|
|||
import { QuickDataSource } from '../data-store/data-store';
|
||||
import { Parse } from '../ref/yaml';
|
||||
import { Help } from "../../help";
|
||||
import { PipelinePlugin } from "./pipeline";
|
||||
import { PipelinePlugin } from "./common";
|
||||
|
||||
export function GetPlugin_Help(): PipelinePlugin {
|
||||
return async config => {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { QuickDataSource } from '../data-store/data-store';
|
||||
import { PipelinePlugin } from './pipeline';
|
||||
import { PipelinePlugin } from './common';
|
||||
|
||||
export function GetPlugin_ReflectApiVersion(): PipelinePlugin {
|
||||
return async (config, input, sink) => {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { GetPlugin_SchemaValidator } from './schema-validation';
|
||||
import { ConvertJsonx2Yaml, ConvertYaml2Jsonx } from '../parsing/yaml';
|
||||
import { Descendants, FastStringify, StringifyAst } from '../ref/yaml';
|
||||
import { JsonPath, stringify } from "../ref/jsonpath";
|
||||
|
@ -23,8 +24,8 @@ import { ConvertOAI2toOAI3 } from "../openapi/conversion";
|
|||
import { Help } from '../../help';
|
||||
import { GetPlugin_Help } from "./help";
|
||||
import { GetPlugin_ReflectApiVersion } from "./metadata-generation";
|
||||
import { CreatePerFilePlugin, PipelinePlugin } from './common';
|
||||
|
||||
export type PipelinePlugin = (config: ConfigurationView, input: DataSource, sink: DataSink) => Promise<DataSource>;
|
||||
interface PipelineNode {
|
||||
outputArtifact?: string;
|
||||
pluginName: string;
|
||||
|
@ -64,19 +65,6 @@ function GetPlugin_MdOverrideLoader(): PipelinePlugin {
|
|||
};
|
||||
}
|
||||
|
||||
function CreatePerFilePlugin(processorBuilder: (config: ConfigurationView) => Promise<(input: DataHandle, sink: DataSink) => Promise<DataHandle>>): PipelinePlugin {
|
||||
return async (config, input, sink) => {
|
||||
const processor = await processorBuilder(config);
|
||||
const files = await input.Enum();
|
||||
const result: DataHandle[] = [];
|
||||
for (let file of files) {
|
||||
const fileIn = await input.ReadStrict(file);
|
||||
const fileOut = await processor(fileIn, sink);
|
||||
result.push(fileOut);
|
||||
}
|
||||
return new QuickDataSource(result);
|
||||
};
|
||||
}
|
||||
function GetPlugin_OAI2toOAIx(): PipelinePlugin {
|
||||
return CreatePerFilePlugin(async config => async (fileIn, sink) => {
|
||||
const fileOut = await ConvertOAI2toOAI3(fileIn, sink);
|
||||
|
@ -300,6 +288,7 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi
|
|||
"transform": GetPlugin_Transformer(),
|
||||
"transform-immediate": GetPlugin_TransformerImmediate(),
|
||||
"compose": GetPlugin_Composer(),
|
||||
"schema-validator": GetPlugin_SchemaValidator(),
|
||||
// TODO: replace with OAV again
|
||||
"semantic-validator": GetPlugin_Identity(),
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as SchemaValidator from 'z-schema';
|
||||
import { parseJsonPointer } from '../ref/jsonpath';
|
||||
import { ReadUri, ResolveUri } from '../ref/uri';
|
||||
import { QuickDataSource } from '../data-store/data-store';
|
||||
import { Parse } from '../ref/yaml';
|
||||
import { CreatePerFilePlugin, PipelinePlugin } from "./common";
|
||||
import { Channel } from "../message";
|
||||
import { OperationAbortedException } from '../exception';
|
||||
|
||||
export function GetPlugin_SchemaValidator(): PipelinePlugin {
|
||||
const validator = new SchemaValidator({ breakOnFirstError: false });
|
||||
|
||||
const extendedSwaggerSchema = require("./swagger-extensions.json");
|
||||
(validator as any).setRemoteReference("http://json.schemastore.org/swagger-2.0", require("./swagger.json"));
|
||||
(validator as any).setRemoteReference("https://raw.githubusercontent.com/Azure/autorest/master/schema/example-schema.json", require("./example-schema.json"));
|
||||
return CreatePerFilePlugin(async config => async (fileIn, sink) => {
|
||||
const obj = fileIn.ReadObject<any>();
|
||||
const errors = await new Promise<{ code: string, params: string[], message: string, path: string }[] | null>(res => validator.validate(obj, extendedSwaggerSchema, (err, valid) => res(valid ? null : err)));
|
||||
if (errors !== null) {
|
||||
for (const error of errors) {
|
||||
config.Message({
|
||||
Channel: Channel.Error,
|
||||
Details: error,
|
||||
Plugin: "schema-validator",
|
||||
Source: [{ document: fileIn.key, Position: { path: parseJsonPointer(error.path) } as any }],
|
||||
Text: `Schema violation: ${error.message}`
|
||||
});
|
||||
}
|
||||
throw new OperationAbortedException();
|
||||
}
|
||||
return await sink.Forward(fileIn.Description, fileIn);
|
||||
});
|
||||
}
|
|
@ -93,4 +93,8 @@ export function matches(jsonQuery: string, jsonPath: JsonPath): boolean {
|
|||
|
||||
// check that `jsonQuery` on that object returns the `leafNode`
|
||||
return nodes(obj, jsonQuery).some(res => res.value === leafNode);
|
||||
}
|
||||
|
||||
export function parseJsonPointer(jsonPointer: string): JsonPath {
|
||||
return jsonPointer.split("/").slice(1).map(part => part.replace(/~1/g, "/").replace(/~0/g, "~"));
|
||||
}
|
|
@ -25,11 +25,11 @@
|
|||
},
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/mocha ./dist/test --timeout 50000",
|
||||
"build": "tsc -p . & dts-generator --name autorest-core --project . --out ../autorest/interfaces/autorest-core.d.ts --exclude \"test/**/*\" --exclude \"node_modules/**/*.d.ts\" --exclude \"lib/source-map/**\" --exclude \"lib/pipeline/**\" --exclude \"lib/parsing/**\" --exclude \"lib/data-store/**\" --exclude \"lib/ref/yaml.ts\" --extern ./source-maps.d.ts",
|
||||
"build": "tsc -p . && dts-generator --name autorest-core --project . --out ../autorest/interfaces/autorest-core.d.ts --exclude \"test/**/*\" --exclude \"node_modules/**/*.d.ts\" --exclude \"lib/source-map/**\" --exclude \"lib/pipeline/**\" --exclude \"lib/parsing/**\" --exclude \"lib/data-store/**\" --exclude \"lib/ref/yaml.ts\" --extern ./source-maps.d.ts && shx cp ../../schema/swagger-extensions.json dist/lib/pipeline && shx cp ../../schema/example-schema.json dist/lib/pipeline && shx cp ../../schema/swagger.json dist/lib/pipeline",
|
||||
"static-link": "static-link",
|
||||
"postinstall": "node ./post-install --force",
|
||||
"reinstall": "shx rm ./package-lock.json && shx rm -rf ./node_modules && npm install",
|
||||
"prepack": "static-link & npm run build"
|
||||
"prepack": "static-link && npm run build"
|
||||
},
|
||||
"typings": "./dist/main.d.ts",
|
||||
"devDependencies": {
|
||||
|
@ -39,6 +39,7 @@
|
|||
"@types/node": "^8.0.53",
|
||||
"@types/source-map": "^0.5.0",
|
||||
"@types/yargs": "^8.0.2",
|
||||
"@types/z-schema": "^3.16.31",
|
||||
"dts-generator": "^2.1.0",
|
||||
"mocha": "^4.0.1",
|
||||
"shx": "0.2.2",
|
||||
|
@ -65,8 +66,9 @@
|
|||
"untildify": "^3.0.2",
|
||||
"urijs": "^1.18.10",
|
||||
"vscode-jsonrpc": "^3.3.1",
|
||||
"yaml-ast-parser": "https://github.com/olydis/yaml-ast-parser/releases/download/0.0.34/yaml-ast-parser-0.0.34.tgz"
|
||||
"yaml-ast-parser": "https://github.com/olydis/yaml-ast-parser/releases/download/0.0.34/yaml-ast-parser-0.0.34.tgz",
|
||||
"z-schema": "^3.19.0"
|
||||
},
|
||||
"patch": "const fs = require(`fs`); let txt = fs.readFileSync('./node_modules/npm/lib/install/action/extract.js','utf8').replace(`const ENABLE_WORKERS = process.platform === 'darwin'`, `const ENABLE_WORKERS = false;`); fs.writeFileSync('./node_modules/npm/lib/install/action/extract.js', txt ); txt = fs.readFileSync(`./node_modules/npm/lib/npm.js`,`utf8`).replace(`var j = parseJSON(fs.readFileSync(`, `var j = require(path.join(__dirname, '../package.json'));` ).replace(`path.join(__dirname, '../package.json')) + '')`,``); fs.writeFileSync(`./node_modules/npm/lib/npm.js`, txt ); txt = fs.readFileSync('./node_modules/npm/lib/pack.js','utf8').replace(`require.main.filename`, `require.resolve('../bin/npm-cli.js')`); fs.writeFileSync('./node_modules/npm/lib/pack.js', txt );"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -246,9 +246,12 @@ pipeline:
|
|||
swagger-document/individual/transform:
|
||||
input: loader
|
||||
output-artifact: swagger-document
|
||||
swagger-document/individual/identity:
|
||||
swagger-document/individual/schema-validator:
|
||||
input: transform
|
||||
output-artifact: swagger-document
|
||||
swagger-document/individual/identity:
|
||||
input: schema-validator
|
||||
output-artifact: swagger-document
|
||||
swagger-document/compose:
|
||||
input: individual/identity
|
||||
output-artifact: swagger-document
|
||||
|
@ -303,28 +306,6 @@ scope-cm/emitter: # can remove once every generator depends on recent modeler
|
|||
"code-model-v1"
|
||||
```
|
||||
|
||||
#### Modeler Only
|
||||
|
||||
``` yaml $(run-modeler)
|
||||
use-extension:
|
||||
"@microsoft.azure/autorest.modeler": "2.3.38"
|
||||
|
||||
pipeline:
|
||||
standalone/imodeler1:
|
||||
input: openapi-document/identity
|
||||
output-artifact: code-model-v1
|
||||
scope: run-modeler
|
||||
standalone/commonmarker:
|
||||
input: imodeler1
|
||||
output-artifact: code-model-v1
|
||||
standalone/cm/transform:
|
||||
input: commonmarker
|
||||
output-artifact: code-model-v1
|
||||
standalone/cm/emitter:
|
||||
input: transform
|
||||
scope: scope-cm/emitter
|
||||
```
|
||||
|
||||
#### Polyfills
|
||||
|
||||
|
||||
|
|
|
@ -392,8 +392,7 @@ definitions:
|
|||
message:
|
||||
type: string
|
||||
details:
|
||||
schema:
|
||||
"$ref": "https://github.com/Azure/azure-rest-api-specs/blob/813c8e8b8b12f3d541daeb45bb2298d223845d37/arm-network/2016-09-01/swagger/network.json#/definitions/ErrorDetails"
|
||||
"$ref": "https://github.com/Azure/azure-rest-api-specs/blob/813c8e8b8b12f3d541daeb45bb2298d223845d37/arm-network/2016-09-01/swagger/network.json#/definitions/ErrorDetails"
|
||||
responses:
|
||||
error:
|
||||
description: OK
|
||||
|
|
|
@ -30,157 +30,7 @@ export function nodes<T>(obj: T, jsonQuery: string): {
|
|||
export function IsPrefix(prefix: JsonPath, path: JsonPath): boolean;
|
||||
export function CreateObject(jsonPath: JsonPath, leafObject: any): any;
|
||||
export function matches(jsonQuery: string, jsonPath: JsonPath): boolean;
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/source-map' {
|
||||
export { Position } from "source-map";
|
||||
import { Position } from "source-map";
|
||||
export { RawSourceMap } from "source-map";
|
||||
import { JsonPath } from 'autorest-core/lib/ref/jsonpath';
|
||||
export interface PositionEnhancements {
|
||||
path?: JsonPath;
|
||||
length?: number;
|
||||
valueOffset?: number;
|
||||
valueLength?: number;
|
||||
}
|
||||
export type EnhancedPosition = Position & PositionEnhancements;
|
||||
export type SmartPosition = Position | {
|
||||
path: JsonPath;
|
||||
};
|
||||
export interface Mapping {
|
||||
generated: SmartPosition;
|
||||
original: SmartPosition;
|
||||
source: string;
|
||||
name?: string;
|
||||
}
|
||||
export type Mappings = Array<Mapping>;
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/lazy' {
|
||||
export class Lazy<T> {
|
||||
private factory;
|
||||
private promise;
|
||||
constructor(factory: () => T);
|
||||
readonly Value: T;
|
||||
}
|
||||
export class LazyPromise<T> implements PromiseLike<T> {
|
||||
private factory;
|
||||
private promise;
|
||||
constructor(factory: () => Promise<T>);
|
||||
private readonly Value;
|
||||
readonly hasValue: boolean;
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/exception' {
|
||||
export class Exception extends Error {
|
||||
exitCode: number;
|
||||
constructor(message: string, exitCode?: number);
|
||||
}
|
||||
export class OperationCanceledException extends Exception {
|
||||
exitCode: number;
|
||||
constructor(message?: string, exitCode?: number);
|
||||
}
|
||||
export class OutstandingTaskAlreadyCompletedException extends Exception {
|
||||
constructor();
|
||||
}
|
||||
export class OperationAbortedException extends Exception {
|
||||
constructor();
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/outstanding-task-awaiter' {
|
||||
export class OutstandingTaskAwaiter {
|
||||
private locked;
|
||||
private outstandingTasks;
|
||||
Wait(): Promise<void>;
|
||||
Await<T>(task: Promise<T>): Promise<T>;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/events' {
|
||||
/// <reference types="node" />
|
||||
import * as events from "events";
|
||||
export interface IEvent<TSender extends events.EventEmitter, TArgs> {
|
||||
Subscribe(fn: (sender: TSender, args: TArgs) => void): () => void;
|
||||
Unsubscribe(fn: (sender: TSender, args: TArgs) => void): void;
|
||||
Dispatch(args: TArgs): void;
|
||||
}
|
||||
export class EventDispatcher<TSender extends EventEmitter, TArgs> implements IEvent<TSender, TArgs> {
|
||||
private _instance;
|
||||
private _name;
|
||||
private _subscriptions;
|
||||
constructor(instance: TSender, name: string);
|
||||
UnsubscribeAll(): void;
|
||||
Subscribe(fn: (sender: TSender, args: TArgs) => void): () => void;
|
||||
Unsubscribe(fn: (sender: TSender, args: TArgs) => void): void;
|
||||
Dispatch(args: TArgs): void;
|
||||
}
|
||||
export class EventEmitter extends events.EventEmitter {
|
||||
private _subscriptions;
|
||||
constructor();
|
||||
protected static Event<TSender extends EventEmitter, TArgs>(target: TSender, propertyKey: string): void;
|
||||
protected _init(t: EventEmitter): void;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/cancellation' {
|
||||
export { CancellationToken, CancellationTokenSource } from "vscode-jsonrpc";
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/jsonrpc' {
|
||||
export * from "vscode-jsonrpc";
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/message' {
|
||||
import { EnhancedPosition, Position } from 'autorest-core/lib/ref/source-map';
|
||||
/**
|
||||
* The Channel that a message is registered with.
|
||||
*/
|
||||
export enum Channel {
|
||||
/** Information is considered the mildest of responses; not necesarily actionable. */
|
||||
Information,
|
||||
/** Warnings are considered important for best practices, but not catastrophic in nature. */
|
||||
Warning,
|
||||
/** Errors are considered blocking issues that block a successful operation. */
|
||||
Error,
|
||||
/** Debug messages are designed for the developer to communicate internal autorest implementation details. */
|
||||
Debug,
|
||||
/** Verbose messages give the user additional clarity on the process. */
|
||||
Verbose,
|
||||
/** Catastrophic failure, likely abending the process. */
|
||||
Fatal,
|
||||
/** Hint messages offer guidance or support without forcing action. */
|
||||
Hint,
|
||||
}
|
||||
export interface SourceLocation {
|
||||
document: string;
|
||||
Position: EnhancedPosition;
|
||||
}
|
||||
export interface Range {
|
||||
document: string;
|
||||
start: Position;
|
||||
end: Position;
|
||||
}
|
||||
export interface Message {
|
||||
Channel: Channel;
|
||||
Key?: Iterable<string>;
|
||||
Details?: any;
|
||||
Text: string;
|
||||
Source?: Array<SourceLocation>;
|
||||
Range?: Iterable<Range>;
|
||||
Plugin?: string;
|
||||
FormattedMessage?: string;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/array' {
|
||||
export function pushAll<T>(target: T[], source: T[]): void;
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/commonmark' {
|
||||
export { Node, Parser } from "commonmark";
|
||||
export function parseJsonPointer(jsonPointer: string): JsonPath;
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/async' {
|
||||
|
@ -240,6 +90,157 @@ export function ClearFolder(folderUri: string): Promise<void>;
|
|||
export function FileUriToPath(fileUri: string): string;
|
||||
export function GetExtension(name: string): string;
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/source-map' {
|
||||
export { Position } from "source-map";
|
||||
import { Position } from "source-map";
|
||||
export { RawSourceMap } from "source-map";
|
||||
import { JsonPath } from 'autorest-core/lib/ref/jsonpath';
|
||||
export interface PositionEnhancements {
|
||||
path?: JsonPath;
|
||||
length?: number;
|
||||
valueOffset?: number;
|
||||
valueLength?: number;
|
||||
}
|
||||
export type EnhancedPosition = Position & PositionEnhancements;
|
||||
export type SmartPosition = Position | {
|
||||
path: JsonPath;
|
||||
};
|
||||
export interface Mapping {
|
||||
generated: SmartPosition;
|
||||
original: SmartPosition;
|
||||
source: string;
|
||||
name?: string;
|
||||
}
|
||||
export type Mappings = Array<Mapping>;
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/message' {
|
||||
import { EnhancedPosition, Position } from 'autorest-core/lib/ref/source-map';
|
||||
/**
|
||||
* The Channel that a message is registered with.
|
||||
*/
|
||||
export enum Channel {
|
||||
/** Information is considered the mildest of responses; not necesarily actionable. */
|
||||
Information,
|
||||
/** Warnings are considered important for best practices, but not catastrophic in nature. */
|
||||
Warning,
|
||||
/** Errors are considered blocking issues that block a successful operation. */
|
||||
Error,
|
||||
/** Debug messages are designed for the developer to communicate internal autorest implementation details. */
|
||||
Debug,
|
||||
/** Verbose messages give the user additional clarity on the process. */
|
||||
Verbose,
|
||||
/** Catastrophic failure, likely abending the process. */
|
||||
Fatal,
|
||||
/** Hint messages offer guidance or support without forcing action. */
|
||||
Hint,
|
||||
}
|
||||
export interface SourceLocation {
|
||||
document: string;
|
||||
Position: EnhancedPosition;
|
||||
}
|
||||
export interface Range {
|
||||
document: string;
|
||||
start: Position;
|
||||
end: Position;
|
||||
}
|
||||
export interface Message {
|
||||
Channel: Channel;
|
||||
Key?: Iterable<string>;
|
||||
Details?: any;
|
||||
Text: string;
|
||||
Source?: Array<SourceLocation>;
|
||||
Range?: Iterable<Range>;
|
||||
Plugin?: string;
|
||||
FormattedMessage?: string;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/exception' {
|
||||
export class Exception extends Error {
|
||||
exitCode: number;
|
||||
constructor(message: string, exitCode?: number);
|
||||
}
|
||||
export class OperationCanceledException extends Exception {
|
||||
exitCode: number;
|
||||
constructor(message?: string, exitCode?: number);
|
||||
}
|
||||
export class OutstandingTaskAlreadyCompletedException extends Exception {
|
||||
constructor();
|
||||
}
|
||||
export class OperationAbortedException extends Exception {
|
||||
constructor();
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/lazy' {
|
||||
export class Lazy<T> {
|
||||
private factory;
|
||||
private promise;
|
||||
constructor(factory: () => T);
|
||||
readonly Value: T;
|
||||
}
|
||||
export class LazyPromise<T> implements PromiseLike<T> {
|
||||
private factory;
|
||||
private promise;
|
||||
constructor(factory: () => Promise<T>);
|
||||
private readonly Value;
|
||||
readonly hasValue: boolean;
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/outstanding-task-awaiter' {
|
||||
export class OutstandingTaskAwaiter {
|
||||
private locked;
|
||||
private outstandingTasks;
|
||||
Wait(): Promise<void>;
|
||||
Await<T>(task: Promise<T>): Promise<T>;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/events' {
|
||||
/// <reference types="node" />
|
||||
import * as events from "events";
|
||||
export interface IEvent<TSender extends events.EventEmitter, TArgs> {
|
||||
Subscribe(fn: (sender: TSender, args: TArgs) => void): () => void;
|
||||
Unsubscribe(fn: (sender: TSender, args: TArgs) => void): void;
|
||||
Dispatch(args: TArgs): void;
|
||||
}
|
||||
export class EventDispatcher<TSender extends EventEmitter, TArgs> implements IEvent<TSender, TArgs> {
|
||||
private _instance;
|
||||
private _name;
|
||||
private _subscriptions;
|
||||
constructor(instance: TSender, name: string);
|
||||
UnsubscribeAll(): void;
|
||||
Subscribe(fn: (sender: TSender, args: TArgs) => void): () => void;
|
||||
Unsubscribe(fn: (sender: TSender, args: TArgs) => void): void;
|
||||
Dispatch(args: TArgs): void;
|
||||
}
|
||||
export class EventEmitter extends events.EventEmitter {
|
||||
private _subscriptions;
|
||||
constructor();
|
||||
protected static Event<TSender extends EventEmitter, TArgs>(target: TSender, propertyKey: string): void;
|
||||
protected _init(t: EventEmitter): void;
|
||||
}
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/cancellation' {
|
||||
export { CancellationToken, CancellationTokenSource } from "vscode-jsonrpc";
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/jsonrpc' {
|
||||
export * from "vscode-jsonrpc";
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/array' {
|
||||
export function pushAll<T>(target: T[], source: T[]): void;
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/ref/commonmark' {
|
||||
export { Node, Parser } from "commonmark";
|
||||
|
||||
}
|
||||
declare module 'autorest-core/lib/file-system' {
|
||||
export interface IFileSystem {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
"prepare": "node ./post-install --force",
|
||||
"preinstall": "node ./preinstall-check",
|
||||
"reinstall": "shx rm ./package-lock.json && shx rm -rf ./node_modules && npm install",
|
||||
"prepack": "static-link & npm run build"
|
||||
"prepack": "static-link && npm run build"
|
||||
},
|
||||
"typings": "./dist/main.d.ts",
|
||||
"devDependencies": {
|
||||
|
|
Загрузка…
Ссылка в новой задаче