зеркало из https://github.com/Azure/autorest.git
file <=> message stuff (#2841)
* message <=> file translation * filter on list inputs * fix * source map * strict JSON parse * nit * regen
This commit is contained in:
Родитель
da436a481f
Коммит
feaf5e9b5c
|
@ -1,5 +1,7 @@
|
|||
- /Samples/test/error-behavior/openapi-json-bad-syntax/tiny.json:45:6
|
||||
- /Samples/test/error-behavior/openapi-json-bad-syntax/tiny.json:45:6
|
||||
Error: Syntax errors encountered.
|
||||
ERROR: Syntax Error Encountered: Unexpected token ] in JSON
|
||||
ERROR: Syntax error: missed comma between flow collection entries
|
||||
FATAL: Error: Syntax errors encountered.
|
||||
FATAL: swagger-document/loader - FAILED
|
||||
|
|
|
@ -16,12 +16,14 @@ import { Lazy } from "../lazy";
|
|||
import { IFileSystem } from "../file-system";
|
||||
import { OperationCanceledException } from "../exception";
|
||||
|
||||
const FALLBACK_DEFAULT_OUTPUT_ARTIFACT = "";
|
||||
|
||||
/********************************************
|
||||
* Data model section (not exposed)
|
||||
********************************************/
|
||||
|
||||
export interface Metadata {
|
||||
artifact: string | null;
|
||||
artifact: string;
|
||||
inputSourceMap: Lazy<RawSourceMap>;
|
||||
sourceMap: Lazy<RawSourceMap>;
|
||||
sourceMapEachMappingByLine: Lazy<sourceMap.MappingItem[][]>;
|
||||
|
@ -170,7 +172,7 @@ export class DataStore {
|
|||
return this.Read(uri);
|
||||
}
|
||||
|
||||
public async WriteData(description: string, data: string, artifact: string | null, sourceMapFactory?: (self: DataHandle) => RawSourceMap): Promise<DataHandle> {
|
||||
public async WriteData(description: string, data: string, artifact: string, sourceMapFactory?: (self: DataHandle) => RawSourceMap): Promise<DataHandle> {
|
||||
const uri = this.createUri(description);
|
||||
|
||||
// metadata
|
||||
|
@ -222,9 +224,9 @@ export class DataStore {
|
|||
return ResolveUri(this.BaseUri, `${this.uid++}?${encodeURIComponent(description)}`);
|
||||
}
|
||||
|
||||
public getDataSink(artifact: string | null = null): DataSink {
|
||||
public getDataSink(defaultArtifact: string = FALLBACK_DEFAULT_OUTPUT_ARTIFACT): DataSink {
|
||||
return new DataSink(
|
||||
(description, data, sourceMapFactory) => this.WriteData(description, data, artifact, sourceMapFactory),
|
||||
(description, data, artifact, sourceMapFactory) => this.WriteData(description, data, artifact || defaultArtifact, sourceMapFactory),
|
||||
async (description, input) => {
|
||||
const uri = this.createUri(description);
|
||||
this.store[uri] = this.store[input.key];
|
||||
|
@ -299,24 +301,24 @@ export class DataStore {
|
|||
|
||||
export class DataSink {
|
||||
constructor(
|
||||
private write: (description: string, rawData: string, metadataFactory: (readHandle: DataHandle) => RawSourceMap) => Promise<DataHandle>,
|
||||
private write: (description: string, rawData: string, artifact: string | undefined, metadataFactory: (readHandle: DataHandle) => RawSourceMap) => Promise<DataHandle>,
|
||||
private forward: (description: string, input: DataHandle) => Promise<DataHandle>) {
|
||||
}
|
||||
|
||||
public async WriteDataWithSourceMap(description: string, data: string, sourceMapFactory: (readHandle: DataHandle) => RawSourceMap): Promise<DataHandle> {
|
||||
return await this.write(description, data, sourceMapFactory);
|
||||
public async WriteDataWithSourceMap(description: string, data: string, artifact: string | undefined, sourceMapFactory: (readHandle: DataHandle) => RawSourceMap): Promise<DataHandle> {
|
||||
return await this.write(description, data, artifact, sourceMapFactory);
|
||||
}
|
||||
|
||||
public async WriteData(description: string, data: string, mappings: Mappings = [], mappingSources: DataHandle[] = []): Promise<DataHandle> {
|
||||
return await this.WriteDataWithSourceMap(description, data, readHandle => {
|
||||
public async WriteData(description: string, data: string, artifact?: string, mappings: Mappings = [], mappingSources: DataHandle[] = []): Promise<DataHandle> {
|
||||
return await this.WriteDataWithSourceMap(description, data, artifact, readHandle => {
|
||||
const sourceMapGenerator = new SourceMapGenerator({ file: readHandle.key });
|
||||
Compile(mappings, sourceMapGenerator, mappingSources.concat(readHandle));
|
||||
return sourceMapGenerator.toJSON();
|
||||
});
|
||||
}
|
||||
|
||||
public WriteObject<T>(description: string, obj: T, mappings: Mappings = [], mappingSources: DataHandle[] = []): Promise<DataHandle> {
|
||||
return this.WriteData(description, FastStringify(obj), mappings, mappingSources);
|
||||
public WriteObject<T>(description: string, obj: T, artifact?: string, mappings: Mappings = [], mappingSources: DataHandle[] = []): Promise<DataHandle> {
|
||||
return this.WriteData(description, FastStringify(obj), artifact, mappings, mappingSources);
|
||||
}
|
||||
|
||||
public Forward(description: string, input: DataHandle): Promise<DataHandle> {
|
||||
|
@ -344,7 +346,7 @@ export class DataHandle {
|
|||
return this.ReadMetadata().yamlAst.Value;
|
||||
}
|
||||
|
||||
public GetArtifact(): string | null {
|
||||
public GetArtifact(): string {
|
||||
return this.ReadMetadata().artifact;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EnhancedPosition, Position } from "./ref/source-map";
|
||||
import { EnhancedPosition, Position, Mappings, RawSourceMap } from "./ref/source-map";
|
||||
import { Artifact } from "./artifact";
|
||||
|
||||
|
||||
|
@ -60,6 +60,6 @@ export interface Message {
|
|||
FormattedMessage?: string;
|
||||
};
|
||||
|
||||
export interface ArtifactMessage extends Message {
|
||||
Details: Artifact;
|
||||
export interface ArtifactMessage extends Message {
|
||||
Details: Artifact & { sourceMap?: Mappings | RawSourceMap };
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { OperationAbortedException } from "../exception";
|
||||
import { ParseNode } from "../ref/yaml";
|
||||
import { ParseNode, StrictJsonSyntaxCheck } from "../ref/yaml";
|
||||
import { MergeYamls, resolveRValue } from "../source-map/merging";
|
||||
import { DataHandle, DataSink } from "../data-store/data-store";
|
||||
import { Parse as ParseLiterate } from "./literate";
|
||||
|
@ -55,15 +55,12 @@ async function ParseCodeBlocksInternal(config: ConfigurationView, hLiterate: Dat
|
|||
// super-quick JSON block syntax check.
|
||||
if (/^(json)/i.test(codeBlock.info || "")) {
|
||||
// check syntax on JSON blocks with simple check first
|
||||
try {
|
||||
// quick check on data.
|
||||
JSON.parse(data.ReadData());
|
||||
} catch (e) {
|
||||
const index = parseInt(e.message.substring(e.message.lastIndexOf(" ")).trim());
|
||||
const error = StrictJsonSyntaxCheck(data.ReadData());
|
||||
if (error) {
|
||||
config.Message({
|
||||
Channel: Channel.Error,
|
||||
Text: "Syntax Error Encountered: " + e.message.substring(0, e.message.lastIndexOf("at")).trim(),
|
||||
Source: [<SourceLocation>{ Position: IndexToPosition(data, index), document: data.key }],
|
||||
Text: "Syntax Error Encountered: " + error.message,
|
||||
Source: [<SourceLocation>{ Position: IndexToPosition(data, error.index), document: data.key }],
|
||||
});
|
||||
throw new OperationAbortedException();
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ export async function Parse(hConfigFile: DataHandle, sink: DataSink): Promise<{
|
|||
const data = codeBlock.literal || "";
|
||||
const mappings = GetSourceMapForCodeBlock(hConfigFile.key, codeBlock);
|
||||
|
||||
const hCodeBlock = await sink.WriteData(codeBlockKey, data, mappings, [hConfigFile]);
|
||||
const hCodeBlock = await sink.WriteData(codeBlockKey, data, undefined, mappings, [hConfigFile]);
|
||||
result.push({
|
||||
data: hCodeBlock,
|
||||
codeBlock: codeBlock
|
||||
|
|
|
@ -48,7 +48,8 @@ async function EmitArtifactInternal(config: ConfigurationView, artifactType: str
|
|||
}
|
||||
}
|
||||
let emitCtr = 0;
|
||||
async function EmitArtifact(config: ConfigurationView, artifactType: string, uri: string, handle: DataHandle, isObject: boolean): Promise<void> {
|
||||
async function EmitArtifact(config: ConfigurationView, uri: string, handle: DataHandle, isObject: boolean): Promise<void> {
|
||||
const artifactType = handle.GetArtifact();
|
||||
await EmitArtifactInternal(config, artifactType, uri, handle);
|
||||
|
||||
if (isObject) {
|
||||
|
@ -57,27 +58,30 @@ async function EmitArtifact(config: ConfigurationView, artifactType: string, uri
|
|||
const ast = new Lazy<YAMLNode>(() => handle.ReadYamlAst());
|
||||
|
||||
if (IsOutputArtifactOrMapRequested(config, artifactType + ".yaml")) {
|
||||
const h = await sink.WriteData(`${++emitCtr}.yaml`, Stringify(object.Value), IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
const h = await sink.WriteData(`${++emitCtr}.yaml`, Stringify(object.Value), artifactType, IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
await EmitArtifactInternal(config, artifactType + ".yaml", uri + ".yaml", h);
|
||||
}
|
||||
if (IsOutputArtifactOrMapRequested(config, artifactType + ".norm.yaml")) {
|
||||
const h = await sink.WriteData(`${++emitCtr}.norm.yaml`, Stringify(Normalize(object.Value)), IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
const h = await sink.WriteData(`${++emitCtr}.norm.yaml`, Stringify(Normalize(object.Value)), artifactType, IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
await EmitArtifactInternal(config, artifactType + ".norm.yaml", uri + ".norm.yaml", h);
|
||||
}
|
||||
if (IsOutputArtifactOrMapRequested(config, artifactType + ".json")) {
|
||||
const h = await sink.WriteData(`${++emitCtr}.json`, JSON.stringify(object.Value, null, 2), IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
const h = await sink.WriteData(`${++emitCtr}.json`, JSON.stringify(object.Value, null, 2), artifactType, IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
await EmitArtifactInternal(config, artifactType + ".json", uri + ".json", h);
|
||||
}
|
||||
if (IsOutputArtifactOrMapRequested(config, artifactType + ".norm.json")) {
|
||||
const h = await sink.WriteData(`${++emitCtr}.norm.json`, JSON.stringify(Normalize(object.Value), null, 2), IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
const h = await sink.WriteData(`${++emitCtr}.norm.json`, JSON.stringify(Normalize(object.Value), null, 2), artifactType, IdentitySourceMapping(handle.key, ast.Value), [handle]);
|
||||
await EmitArtifactInternal(config, artifactType + ".norm.json", uri + ".norm.json", h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function EmitArtifacts(config: ConfigurationView, artifactType: string, uriResolver: (key: string) => string, scope: DataSource, isObject: boolean): Promise<void> {
|
||||
export async function EmitArtifacts(config: ConfigurationView, artifactTypeFilter: string /* what's set on the emitter */, uriResolver: (key: string) => string, scope: DataSource, isObject: boolean): Promise<void> {
|
||||
for (const key of await scope.Enum()) {
|
||||
const file = await scope.ReadStrict(key);
|
||||
await EmitArtifact(config, artifactType, uriResolver(file.Description), file, isObject);
|
||||
const fileArtifact = file.GetArtifact();
|
||||
if (fileArtifact === artifactTypeFilter) {
|
||||
await EmitArtifact(config, uriResolver(file.Description), file, isObject);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -88,5 +88,5 @@ export async function ProcessCodeModel(codeModel: DataHandle, sink: DataSink): P
|
|||
}
|
||||
}
|
||||
|
||||
return await sink.WriteData("codeModel.yaml", StringifyAst(ast), mapping, [codeModel]);
|
||||
return await sink.WriteData("codeModel.yaml", StringifyAst(ast), undefined, mapping, [codeModel]);
|
||||
}
|
|
@ -54,6 +54,6 @@ ${tuples.map(x => ` ${x},`).join("\n")}
|
|||
}
|
||||
}
|
||||
}
|
||||
`)]);
|
||||
`, "source-file-csharp")]);
|
||||
};
|
||||
}
|
|
@ -48,7 +48,7 @@ export async function ManipulateObject(
|
|||
const reasonSuffix = mappingInfo ? ` (${mappingInfo.reason})` : "";
|
||||
if (mappingInfo) {
|
||||
mapping.push(
|
||||
...From(Descendants(newAst)).Select(descendant => {
|
||||
...From(Descendants(newAst)).Select((descendant: any) => {
|
||||
return <Mapping>{
|
||||
name: `Injected object at '${stringify(hit.path)}'${reasonSuffix}`,
|
||||
source: mappingInfo.transformerSourceHandle.key,
|
||||
|
@ -61,8 +61,8 @@ export async function ManipulateObject(
|
|||
// try to be smart and assume that nodes existing in both old and new AST have a relationship
|
||||
mapping.push(
|
||||
...From(Descendants(newAst))
|
||||
.Where(descendant => paths(doc, stringify(hit.path.concat(descendant.path))).length === 1)
|
||||
.Select(descendant => {
|
||||
.Where((descendant: any) => paths(doc, stringify(hit.path.concat(descendant.path))).length === 1)
|
||||
.Select((descendant: any) => {
|
||||
return <Mapping>{
|
||||
name: `Original object at '${stringify(hit.path)}'${reasonSuffix}`,
|
||||
source: src.key,
|
||||
|
@ -74,7 +74,7 @@ export async function ManipulateObject(
|
|||
}
|
||||
|
||||
// write back
|
||||
const resultHandle = await target.WriteData("manipulated", StringifyAst(ast), mapping, mappingInfo ? [src, mappingInfo.transformerSourceHandle] : [src]);
|
||||
const resultHandle = await target.WriteData("manipulated", StringifyAst(ast), undefined, mapping, mappingInfo ? [src, mappingInfo.transformerSourceHandle] : [src]);
|
||||
return {
|
||||
anyHit: true,
|
||||
result: resultHandle
|
||||
|
|
|
@ -300,8 +300,8 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi
|
|||
"reflect-api-versions-cs": GetPlugin_ReflectApiVersion(),
|
||||
"commonmarker": GetPlugin_CommonmarkProcessor(),
|
||||
"emitter": GetPlugin_ArtifactEmitter(),
|
||||
"pipeline-emitter": GetPlugin_ArtifactEmitter(async () => new QuickDataSource([await configView.DataStore.getDataSink().WriteObject("pipeline", pipeline.pipeline)])),
|
||||
"configuration-emitter": GetPlugin_ArtifactEmitter(async () => new QuickDataSource([await configView.DataStore.getDataSink().WriteObject("configuration", configView.Raw)]))
|
||||
"pipeline-emitter": GetPlugin_ArtifactEmitter(async () => new QuickDataSource([await configView.DataStore.getDataSink().WriteObject("pipeline", pipeline.pipeline, "pipeline")])),
|
||||
"configuration-emitter": GetPlugin_ArtifactEmitter(async () => new QuickDataSource([await configView.DataStore.getDataSink().WriteObject("configuration", configView.Raw, "configuration")]))
|
||||
};
|
||||
|
||||
// dynamically loaded, auto-discovered plugins
|
||||
|
|
|
@ -12,8 +12,9 @@ import { createMessageConnection, MessageConnection } from "../ref/jsonrpc";
|
|||
import { DataHandle, DataSink, DataSource } from '../data-store/data-store';
|
||||
import { IAutoRestPluginInitiator_Types, IAutoRestPluginTarget_Types, IAutoRestPluginInitiator } from "./plugin-api";
|
||||
import { Exception } from "../exception";
|
||||
import { Message } from "../message";
|
||||
import { Message, Channel, ArtifactMessage } from "../message";
|
||||
import { Readable, Writable } from "stream";
|
||||
import { Artifact } from "../artifact";
|
||||
|
||||
interface IAutoRestPluginTargetEndpoint {
|
||||
GetPluginNames(cancellationToken: CancellationToken): Promise<string[]>;
|
||||
|
@ -25,7 +26,7 @@ interface IAutoRestPluginInitiatorEndpoint {
|
|||
|
||||
ReadFile(filename: string): Promise<string>;
|
||||
GetValue(key: string): Promise<any>;
|
||||
ListInputs(artifactType?:string): Promise<string[]>;
|
||||
ListInputs(artifactType?: string): Promise<string[]>;
|
||||
|
||||
WriteFile(filename: string, content: string, sourceMap?: Mappings | RawSourceMap): Promise<void>;
|
||||
Message(message: Message, path?: SmartPosition, sourceFile?: string): Promise<void>;
|
||||
|
@ -169,6 +170,24 @@ export class AutoRestExtension extends EventEmitter {
|
|||
const friendly2internal: (name: string) => Promise<string | undefined> = async name => ((await inputFileHandles).filter(h => h.Description === name || decodeURIComponent(h.Description) === decodeURIComponent(name))[0] || {}).key;
|
||||
const internal2friendly: (name: string) => Promise<string | undefined> = async key => (await inputScope.Read(key) || <any>{}).Description;
|
||||
|
||||
const writeFileToSinkAndNotify = async (filename: string, content: string, artifactType?: string, sourceMap?: Mappings | RawSourceMap): Promise<Artifact> => {
|
||||
if (!sourceMap) {
|
||||
sourceMap = [];
|
||||
}
|
||||
// TODO: transform mappings so friendly names are replaced by internals
|
||||
let handle: DataHandle;
|
||||
if (typeof (sourceMap as any).mappings === "string") {
|
||||
onFile(handle = await sink.WriteDataWithSourceMap(filename, content, artifactType, () => sourceMap as any));
|
||||
} else {
|
||||
onFile(handle = await sink.WriteData(filename, content, artifactType, sourceMap as Mappings, await inputFileHandles));
|
||||
}
|
||||
return {
|
||||
uri: handle.key,
|
||||
type: handle.GetArtifact(),
|
||||
content: handle.ReadData()
|
||||
};
|
||||
};
|
||||
|
||||
let finishNotifications: Promise<void> = Promise.resolve();
|
||||
const apiInitiator: IAutoRestPluginInitiatorEndpoint = {
|
||||
FinishNotifications(): Promise<void> { return finishNotifications; },
|
||||
|
@ -184,8 +203,10 @@ export class AutoRestExtension extends EventEmitter {
|
|||
return null;
|
||||
}
|
||||
},
|
||||
async ListInputs(artifactType?:string): Promise<string[]> {
|
||||
return (await inputFileHandles).map(x => x.Description);
|
||||
async ListInputs(artifactType?: string): Promise<string[]> {
|
||||
return (await inputFileHandles)
|
||||
.filter(x => typeof artifactType !== "string" || artifactType === x.GetArtifact())
|
||||
.map(x => x.Description);
|
||||
},
|
||||
|
||||
async WriteFile(filename: string, content: string, sourceMap?: Mappings | RawSourceMap): Promise<void> {
|
||||
|
@ -196,12 +217,8 @@ export class AutoRestExtension extends EventEmitter {
|
|||
let notify: () => void = () => { };
|
||||
finishNotifications = new Promise<void>(res => notify = res);
|
||||
|
||||
// TODO: transform mappings so friendly names are replaced by internals
|
||||
if (typeof (sourceMap as any).mappings === "string") {
|
||||
onFile(await sink.WriteDataWithSourceMap(filename, content, () => sourceMap as any));
|
||||
} else {
|
||||
onFile(await sink.WriteData(filename, content, sourceMap as Mappings, await inputFileHandles));
|
||||
}
|
||||
const artifact = await writeFileToSinkAndNotify(filename, content, undefined, sourceMap);
|
||||
onMessage(<ArtifactMessage>{ Channel: Channel.File, Details: artifact, Text: artifact.content, Plugin: pluginName, Key: [artifact.type, artifact.uri] })
|
||||
|
||||
await finishPrev;
|
||||
notify();
|
||||
|
@ -220,6 +237,14 @@ export class AutoRestExtension extends EventEmitter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (message.Channel === Channel.File) {
|
||||
// wire through `sink` in order to retrieve default artifact type
|
||||
const artifactMessage = message as ArtifactMessage;
|
||||
const artifact = artifactMessage.Details;
|
||||
await writeFileToSinkAndNotify(artifact.uri, artifact.content, artifact.type, artifact.sourceMap);
|
||||
}
|
||||
|
||||
onMessage(message);
|
||||
|
||||
await finishPrev;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { pushAll } from '../ref/array';
|
||||
import { Lines } from "../parsing/text-utility";
|
||||
import { Lines, IndexToPosition } from "../parsing/text-utility";
|
||||
import {
|
||||
CommonmarkHeadingFollowingText,
|
||||
CommonmarkHeadingText,
|
||||
|
@ -18,7 +18,7 @@ import { ConfigurationView } from "../autorest-core";
|
|||
import { DataHandle, DataSink, DataSource } from '../data-store/data-store';
|
||||
import { IsPrefix, JsonPath, JsonPathComponent, stringify } from "../ref/jsonpath";
|
||||
import { ResolvePath, ResolveRelativeNode } from "../parsing/yaml";
|
||||
import { Clone, CloneAst, Descendants, StringifyAst, ToAst, YAMLNodeWithPath } from "../ref/yaml";
|
||||
import { Clone, CloneAst, Descendants, StringifyAst, ToAst, YAMLNodeWithPath, StrictJsonSyntaxCheck } from "../ref/yaml";
|
||||
import { ResolveUri } from "../ref/uri";
|
||||
import { From } from "../ref/linq";
|
||||
import { Mappings, Mapping } from "../ref/source-map";
|
||||
|
@ -188,7 +188,7 @@ async function EnsureCompleteDefinitionIsPresent(
|
|||
}
|
||||
|
||||
// commit back
|
||||
externalFiles[sourceFileUri] = await sink.WriteObject("revision", sourceDocObj, sourceDocMappings, [...Object.getOwnPropertyNames(externalFiles).map(x => externalFiles[x]), sourceDoc] /* inputs */ /*TODO: fix*/);
|
||||
externalFiles[sourceFileUri] = await sink.WriteObject("revision", sourceDocObj, undefined, sourceDocMappings, [...Object.getOwnPropertyNames(externalFiles).map(x => externalFiles[x]), sourceDoc] /* inputs */ /*TODO: fix*/);
|
||||
return sourceDocMappings;
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ async function StripExternalReferences(swagger: DataHandle, sink: DataSink): Pro
|
|||
}
|
||||
}
|
||||
}
|
||||
return await sink.WriteData("result.yaml", StringifyAst(ast), mapping, [swagger]);
|
||||
return await sink.WriteData("result.yaml", StringifyAst(ast), undefined, mapping, [swagger]);
|
||||
}
|
||||
|
||||
export async function LoadLiterateSwaggerOverride(config: ConfigurationView, inputScope: DataSource, inputFileUri: string, sink: DataSink): Promise<DataHandle> {
|
||||
|
@ -275,11 +275,23 @@ export async function LoadLiterateSwaggerOverride(config: ConfigurationView, inp
|
|||
state.push(...[...CommonmarkSubHeadings(x.node)].map(y => { return { node: y, query: clue || x.query }; }));
|
||||
}
|
||||
|
||||
return sink.WriteObject("override-directives", { directive: directives }, mappings, [commonmark]);
|
||||
return sink.WriteObject("override-directives", { directive: directives }, undefined, mappings, [commonmark]);
|
||||
}
|
||||
|
||||
export async function LoadLiterateSwagger(config: ConfigurationView, inputScope: DataSource, inputFileUri: string, sink: DataSink): Promise<DataHandle> {
|
||||
const data = await ParseLiterateYaml(config, await inputScope.ReadStrict(inputFileUri), sink);
|
||||
const handle = await inputScope.ReadStrict(inputFileUri);
|
||||
// strict JSON check
|
||||
if (inputFileUri.toLowerCase().endsWith(".json")) {
|
||||
const error = StrictJsonSyntaxCheck(handle.ReadData());
|
||||
if (error) {
|
||||
config.Message({
|
||||
Channel: Channel.Error,
|
||||
Text: "Syntax Error Encountered: " + error.message,
|
||||
Source: [<SourceLocation>{ Position: IndexToPosition(handle, error.index), document: handle.key }],
|
||||
});
|
||||
}
|
||||
}
|
||||
const data = await ParseLiterateYaml(config, handle, sink);
|
||||
// check OpenAPI version
|
||||
if (data.ReadObject<any>().swagger !== "2.0") {
|
||||
throw new Error(`File '${inputFileUri}' is not a valid OpenAPI 2.0 definition (expected 'swagger: 2.0')`);
|
||||
|
@ -373,8 +385,8 @@ export async function ComposeSwaggers(config: ConfigurationView, overrideInfoTit
|
|||
.Concat(getPropertyValues(getProperty({ obj: swagger, path: [] }, "x-ms-paths")));
|
||||
const methods = paths.SelectMany(getPropertyValues);
|
||||
const parameters =
|
||||
methods.SelectMany(method => getArrayValues<any>(getProperty<any, any>(method, "parameters"))).Concat(
|
||||
paths.SelectMany(path => getArrayValues<any>(getProperty<any, any>(path, "parameters"))));
|
||||
methods.SelectMany((method: any) => getArrayValues<any>(getProperty<any, any>(method, "parameters"))).Concat(
|
||||
paths.SelectMany((path: any) => getArrayValues<any>(getProperty<any, any>(path, "parameters"))));
|
||||
|
||||
// inline api-version params
|
||||
if (!uniqueVersion) {
|
||||
|
@ -383,7 +395,7 @@ export async function ComposeSwaggers(config: ConfigurationView, overrideInfoTit
|
|||
const apiVersionClientParam = apiVersionClientParamName ? clientParams[apiVersionClientParamName] : null;
|
||||
if (apiVersionClientParam) {
|
||||
const apiVersionClientParam = clientParams[apiVersionClientParamName];
|
||||
const apiVersionParameters = parameters.Where(p => p.obj.$ref === `#/parameters/${apiVersionClientParamName}`);
|
||||
const apiVersionParameters = parameters.Where((p: any) => p.obj.$ref === `#/parameters/${apiVersionClientParamName}`);
|
||||
for (let apiVersionParameter of apiVersionParameters) {
|
||||
delete apiVersionParameter.obj.$ref;
|
||||
|
||||
|
@ -437,7 +449,7 @@ export async function ComposeSwaggers(config: ConfigurationView, overrideInfoTit
|
|||
populate.forEach(f => f());
|
||||
|
||||
// write back
|
||||
inputSwaggers[i] = await sink.WriteObject("prepared", swagger, mapping, [inputSwagger]);
|
||||
inputSwaggers[i] = await sink.WriteObject("prepared", swagger, undefined, mapping, [inputSwagger]);
|
||||
}
|
||||
|
||||
let hSwagger = await MergeYamls(config, inputSwaggers, sink);
|
||||
|
|
|
@ -249,3 +249,18 @@ export function FastStringify<T>(obj: T): string {
|
|||
}
|
||||
return Stringify(obj);
|
||||
}
|
||||
|
||||
export function StrictJsonSyntaxCheck(json: string): { message: string, index: number } | null {
|
||||
try {
|
||||
// quick check on data.
|
||||
JSON.parse(json);
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) {
|
||||
const message = "" + e.message;
|
||||
try {
|
||||
return { message: message.substring(0, message.lastIndexOf("at")).trim(), index: parseInt(e.message.substring(e.message.lastIndexOf(" ")).trim()) };
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
|
@ -227,5 +227,5 @@ export function MergeYamls(config: ConfigurationView, yamlInputHandles: DataHand
|
|||
if (failed) {
|
||||
throw new Error("Syntax errors encountered.");
|
||||
}
|
||||
return sink.WriteObject("merged YAMLs", resultObject, mappings, yamlInputHandles);
|
||||
return sink.WriteObject("merged YAMLs", resultObject, undefined, mappings, yamlInputHandles);
|
||||
}
|
|
@ -62,7 +62,7 @@ export type Mappings = Array<Mapping>;
|
|||
|
||||
}
|
||||
declare module 'autorest-core/lib/message' {
|
||||
import { EnhancedPosition, Position } from 'autorest-core/lib/ref/source-map';
|
||||
import { EnhancedPosition, Position, Mappings, RawSourceMap } from 'autorest-core/lib/ref/source-map';
|
||||
import { Artifact } from 'autorest-core/lib/artifact';
|
||||
/**
|
||||
* The Channel that a message is registered with.
|
||||
|
@ -105,7 +105,9 @@ export interface Message {
|
|||
FormattedMessage?: string;
|
||||
}
|
||||
export interface ArtifactMessage extends Message {
|
||||
Details: Artifact;
|
||||
Details: Artifact & {
|
||||
sourceMap?: Mappings | RawSourceMap;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче