@azure-tools/typespec-autorest 0.42.0-dev.4 → 0.42.0-dev.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/emit.d.ts +22 -0
- package/dist/src/emit.d.ts.map +1 -0
- package/dist/src/emit.js +114 -0
- package/dist/src/emit.js.map +1 -0
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +117 -1
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +1 -1
- package/dist/src/lib.js.map +1 -1
- package/dist/src/openapi.d.ts +27 -19
- package/dist/src/openapi.d.ts.map +1 -1
- package/dist/src/openapi.js +161 -290
- package/dist/src/openapi.js.map +1 -1
- package/dist/src/{types.d.ts → openapi2-document.d.ts} +1 -1
- package/dist/src/openapi2-document.d.ts.map +1 -0
- package/dist/src/openapi2-document.js +2 -0
- package/dist/src/openapi2-document.js.map +1 -0
- package/dist/src/utils.d.ts +9 -6
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +10 -4
- package/dist/src/utils.js.map +1 -1
- package/package.json +3 -3
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/types.js +0 -2
- package/dist/src/types.js.map +0 -1
package/dist/src/openapi.js
CHANGED
|
@@ -1,44 +1,14 @@
|
|
|
1
1
|
import { extractLroStates, getArmResourceIdentifierConfig, getAsEmbeddingVector, getLroMetadata, getPagedResult, getUnionAsEnum, isFixed, } from "@azure-tools/typespec-azure-core";
|
|
2
|
-
import {
|
|
3
|
-
import { NoTarget, SyntaxKind,
|
|
2
|
+
import { shouldFlattenProperty } from "@azure-tools/typespec-client-generator-core";
|
|
3
|
+
import { NoTarget, SyntaxKind, compilerAssert, createDiagnosticCollector, getAllTags, getDirectoryPath, getDiscriminator, getDoc, getEncode, getFormat, getKnownValues, getMaxItems, getMaxLength, getMaxValue, getMinItems, getMinLength, getMinValue, getPattern, getProjectedName, getProperty, getPropertyType, getRelativePathFromDirectory, getRootLength, getSummary, getVisibility, ignoreDiagnostics, interpolatePath, isArrayModelType, isDeprecated, isErrorModel, isErrorType, isGlobalNamespace, isNeverType, isNullType, isNumericType, isRecordModelType, isSecret, isService, isStringType, isTemplateDeclaration, isTemplateDeclarationOrInstance, isVoidType, navigateTypesInNamespace, resolveEncodedName, resolvePath, stringTemplateToString, } from "@typespec/compiler";
|
|
4
|
+
import { TwoLevelMap } from "@typespec/compiler/utils";
|
|
4
5
|
import { Visibility, createMetadataInfo, getAllHttpServices, getAuthentication, getHeaderFieldOptions, getQueryParamOptions, getServers, getStatusCodeDescription, getVisibilitySuffix, isContentTypeHeader, isSharedRoute, reportIfNoRoutes, resolveRequestVisibility, } from "@typespec/http";
|
|
5
6
|
import { checkDuplicateTypeName, getExtensions, getExternalDocs, getOpenAPITypeName, getParameterKey, isReadonlyProperty, resolveInfo, shouldInline, } from "@typespec/openapi";
|
|
6
|
-
import { buildVersionProjections } from "@typespec/versioning";
|
|
7
7
|
import { AutorestOpenAPISchema } from "./autorest-openapi-schema.js";
|
|
8
8
|
import { getExamples, getRef } from "./decorators.js";
|
|
9
9
|
import { sortWithJsonSchema } from "./json-schema-sorter/sorter.js";
|
|
10
|
-
import {
|
|
11
|
-
import { resolveOperationId } from "./utils.js";
|
|
12
|
-
const defaultOptions = {
|
|
13
|
-
"output-file": "{azure-resource-provider-folder}/{service-name}/{version-status}/{version}/openapi.json",
|
|
14
|
-
"new-line": "lf",
|
|
15
|
-
"include-x-typespec-name": "never",
|
|
16
|
-
};
|
|
17
|
-
export async function $onEmit(context) {
|
|
18
|
-
const resolvedOptions = { ...defaultOptions, ...context.options };
|
|
19
|
-
const tcgcSdkContext = createSdkContext(context, "@azure-tools/typespec-autorest");
|
|
20
|
-
const armTypesDir = interpolatePath(resolvedOptions["arm-types-dir"] ?? "{project-root}/../../common-types/resource-management", {
|
|
21
|
-
"project-root": context.program.projectRoot,
|
|
22
|
-
"emitter-output-dir": context.emitterOutputDir,
|
|
23
|
-
});
|
|
24
|
-
const options = {
|
|
25
|
-
outputFile: resolvedOptions["output-file"],
|
|
26
|
-
outputDir: context.emitterOutputDir,
|
|
27
|
-
azureResourceProviderFolder: resolvedOptions["azure-resource-provider-folder"],
|
|
28
|
-
examplesDirectory: resolvedOptions["examples-directory"],
|
|
29
|
-
version: resolvedOptions["version"],
|
|
30
|
-
newLine: resolvedOptions["new-line"],
|
|
31
|
-
omitUnreachableTypes: resolvedOptions["omit-unreachable-types"],
|
|
32
|
-
includeXTypeSpecName: resolvedOptions["include-x-typespec-name"],
|
|
33
|
-
armTypesDir,
|
|
34
|
-
useReadOnlyStatusSchema: resolvedOptions["use-read-only-status-schema"],
|
|
35
|
-
};
|
|
36
|
-
const emitter = createOAPIEmitter(context.program, tcgcSdkContext, options);
|
|
37
|
-
await emitter.emitOpenAPI();
|
|
38
|
-
}
|
|
39
|
-
function getEmitterDetails(program) {
|
|
40
|
-
return [{ emitter: "@azure-tools/typespec-autorest" }];
|
|
41
|
-
}
|
|
10
|
+
import { createDiagnostic, reportDiagnostic } from "./lib.js";
|
|
11
|
+
import { getClientName, resolveOperationId } from "./utils.js";
|
|
42
12
|
/**
|
|
43
13
|
* Represents a node that will hold a JSON reference. The value is computed
|
|
44
14
|
* at the end so that we can defer decisions about the name that is
|
|
@@ -51,113 +21,111 @@ class Ref {
|
|
|
51
21
|
return this.value;
|
|
52
22
|
}
|
|
53
23
|
}
|
|
54
|
-
function
|
|
55
|
-
const
|
|
56
|
-
tracer.trace("options", JSON.stringify(options, null, 2));
|
|
24
|
+
export async function getOpenAPIForService(context, options) {
|
|
25
|
+
const { program, service } = context;
|
|
57
26
|
const typeNameOptions = {
|
|
58
27
|
// shorten type names by removing TypeSpec and service namespace
|
|
59
28
|
namespaceFilter(ns) {
|
|
60
29
|
return !isService(program, ns);
|
|
61
30
|
},
|
|
62
31
|
};
|
|
63
|
-
|
|
64
|
-
|
|
32
|
+
const info = resolveInfo(program, service.type);
|
|
33
|
+
const auth = processAuth(service.type);
|
|
34
|
+
const root = {
|
|
35
|
+
swagger: "2.0",
|
|
36
|
+
info: {
|
|
37
|
+
title: "(title)",
|
|
38
|
+
...info,
|
|
39
|
+
version: context.version ?? info?.version ?? "0000-00-00",
|
|
40
|
+
"x-typespec-generated": [{ emitter: "@azure-tools/typespec-autorest" }],
|
|
41
|
+
},
|
|
42
|
+
schemes: ["https"],
|
|
43
|
+
...resolveHost(program, service.type),
|
|
44
|
+
externalDocs: getExternalDocs(program, service.type),
|
|
45
|
+
produces: [], // Pre-initialize produces and consumes so that
|
|
46
|
+
consumes: [], // they show up at the top of the document
|
|
47
|
+
security: auth?.security,
|
|
48
|
+
securityDefinitions: auth?.securitySchemes ?? {},
|
|
49
|
+
tags: [],
|
|
50
|
+
paths: {},
|
|
51
|
+
"x-ms-paths": {},
|
|
52
|
+
definitions: {},
|
|
53
|
+
parameters: {},
|
|
54
|
+
};
|
|
65
55
|
let currentEndpoint;
|
|
66
56
|
let currentConsumes;
|
|
67
57
|
let currentProduces;
|
|
68
|
-
|
|
58
|
+
const metadataInfo = createMetadataInfo(program, {
|
|
59
|
+
canonicalVisibility: Visibility.Read,
|
|
60
|
+
canShareProperty: canSharePropertyUsingReadonlyOrXMSMutability,
|
|
61
|
+
});
|
|
69
62
|
// Keep a map of all Types+Visibility combinations that were encountered
|
|
70
63
|
// that need schema definitions.
|
|
71
|
-
|
|
64
|
+
const pendingSchemas = new TwoLevelMap();
|
|
72
65
|
// Reuse a single ref object per Type+Visibility combination.
|
|
73
|
-
|
|
66
|
+
const refs = new TwoLevelMap();
|
|
74
67
|
// Keep track of inline types still in the process of having their schema computed
|
|
75
68
|
// This is used to detect cycles in inline types, which is an
|
|
76
|
-
|
|
69
|
+
const inProgressInlineTypes = new Set();
|
|
77
70
|
// Map model properties that represent shared parameters to their parameter
|
|
78
71
|
// definition that will go in #/parameters. Inlined parameters do not go in
|
|
79
72
|
// this map.
|
|
80
|
-
|
|
73
|
+
const params = new Map();
|
|
81
74
|
// Keep track of models that have had properties spread into parameters. We won't
|
|
82
75
|
// consider these unreferenced when emitting unreferenced types.
|
|
83
|
-
|
|
76
|
+
const paramModels = new Set();
|
|
84
77
|
// De-dupe the per-endpoint tags that will be added into the #/tags
|
|
85
|
-
|
|
78
|
+
const tags = new Set();
|
|
86
79
|
// The set of produces/consumes values found in all operations
|
|
87
80
|
const globalProduces = new Set(["application/json"]);
|
|
88
81
|
const globalConsumes = new Set(["application/json"]);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
return {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
externalDocs: getExternalDocs(program, service.type),
|
|
137
|
-
produces: [], // Pre-initialize produces and consumes so that
|
|
138
|
-
consumes: [], // they show up at the top of the document
|
|
139
|
-
security: auth?.security,
|
|
140
|
-
securityDefinitions: auth?.securitySchemes ?? {},
|
|
141
|
-
tags: [],
|
|
142
|
-
paths: {},
|
|
143
|
-
"x-ms-paths": {},
|
|
144
|
-
definitions: {},
|
|
145
|
-
parameters: {},
|
|
146
|
-
};
|
|
147
|
-
pendingSchemas = new TwoLevelMap();
|
|
148
|
-
refs = new TwoLevelMap();
|
|
149
|
-
metadataInfo = createMetadataInfo(program, {
|
|
150
|
-
canonicalVisibility: Visibility.Read,
|
|
151
|
-
canShareProperty: canSharePropertyUsingReadonlyOrXMSMutability,
|
|
152
|
-
});
|
|
153
|
-
inProgressInlineTypes = new Set();
|
|
154
|
-
params = new Map();
|
|
155
|
-
paramModels = new Set();
|
|
156
|
-
tags = new Set();
|
|
157
|
-
operationExamplesMap = new Map();
|
|
158
|
-
operationIdsWithExample = new Set();
|
|
159
|
-
outputFile = resolveOutputFile(program, service, multipleService, options, version);
|
|
160
|
-
}
|
|
82
|
+
const operationIdsWithExample = new Set();
|
|
83
|
+
const [exampleMap, diagnostics] = await loadExamples(program.host, options, context.version);
|
|
84
|
+
program.reportDiagnostics(diagnostics);
|
|
85
|
+
const services = ignoreDiagnostics(getAllHttpServices(program));
|
|
86
|
+
const routes = services[0].operations;
|
|
87
|
+
reportIfNoRoutes(program, routes);
|
|
88
|
+
routes.forEach(emitOperation);
|
|
89
|
+
emitParameters();
|
|
90
|
+
emitSchemas(service.type);
|
|
91
|
+
emitTags();
|
|
92
|
+
// Finalize global produces/consumes
|
|
93
|
+
if (globalProduces.size > 0) {
|
|
94
|
+
root.produces = [...globalProduces.values()];
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
delete root.produces;
|
|
98
|
+
}
|
|
99
|
+
if (globalConsumes.size > 0) {
|
|
100
|
+
root.consumes = [...globalConsumes.values()];
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
delete root.consumes;
|
|
104
|
+
}
|
|
105
|
+
// Clean up empty entries
|
|
106
|
+
if (root["x-ms-paths"] && Object.keys(root["x-ms-paths"]).length === 0) {
|
|
107
|
+
delete root["x-ms-paths"];
|
|
108
|
+
}
|
|
109
|
+
if (root.security && Object.keys(root.security).length === 0) {
|
|
110
|
+
delete root["security"];
|
|
111
|
+
}
|
|
112
|
+
if (root.securityDefinitions && Object.keys(root.securityDefinitions).length === 0) {
|
|
113
|
+
delete root["securityDefinitions"];
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
document: root,
|
|
117
|
+
operationExamples: [...operationIdsWithExample]
|
|
118
|
+
.map((operationId) => {
|
|
119
|
+
const data = exampleMap.get(operationId);
|
|
120
|
+
if (data) {
|
|
121
|
+
return { operationId, examples: Object.values(data) };
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
.filter((x) => x),
|
|
128
|
+
};
|
|
161
129
|
function resolveHost(program, namespace) {
|
|
162
130
|
const servers = getServers(program, namespace);
|
|
163
131
|
if (servers === undefined) {
|
|
@@ -210,83 +178,6 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
210
178
|
},
|
|
211
179
|
};
|
|
212
180
|
}
|
|
213
|
-
async function emitOpenAPIFromVersion(service, multipleService, version) {
|
|
214
|
-
initializeEmitter(service, multipleService, version);
|
|
215
|
-
try {
|
|
216
|
-
await loadExamples(version);
|
|
217
|
-
const services = ignoreDiagnostics(getAllHttpServices(program));
|
|
218
|
-
const routes = services[0].operations;
|
|
219
|
-
reportIfNoRoutes(program, routes);
|
|
220
|
-
routes.forEach(emitOperation);
|
|
221
|
-
emitParameters();
|
|
222
|
-
emitSchemas(service.type);
|
|
223
|
-
emitTags();
|
|
224
|
-
// Finalize global produces/consumes
|
|
225
|
-
if (globalProduces.size > 0) {
|
|
226
|
-
root.produces = [...globalProduces.values()];
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
delete root.produces;
|
|
230
|
-
}
|
|
231
|
-
if (globalConsumes.size > 0) {
|
|
232
|
-
root.consumes = [...globalConsumes.values()];
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
delete root.consumes;
|
|
236
|
-
}
|
|
237
|
-
// Clean up empty entries
|
|
238
|
-
if (root["x-ms-paths"] && Object.keys(root["x-ms-paths"]).length === 0) {
|
|
239
|
-
delete root["x-ms-paths"];
|
|
240
|
-
}
|
|
241
|
-
if (root.security && Object.keys(root.security).length === 0) {
|
|
242
|
-
delete root["security"];
|
|
243
|
-
}
|
|
244
|
-
if (root.securityDefinitions && Object.keys(root.securityDefinitions).length === 0) {
|
|
245
|
-
delete root["securityDefinitions"];
|
|
246
|
-
}
|
|
247
|
-
if (!program.compilerOptions.noEmit && !program.hasError()) {
|
|
248
|
-
// Sort the document
|
|
249
|
-
const sortedRoot = sortOpenAPIDocument(root);
|
|
250
|
-
// Write out the OpenAPI document to the output path
|
|
251
|
-
await emitFile(program, {
|
|
252
|
-
path: outputFile,
|
|
253
|
-
content: prettierOutput(JSON.stringify(sortedRoot, null, 2)),
|
|
254
|
-
newLine: options.newLine,
|
|
255
|
-
});
|
|
256
|
-
// Copy examples to the output directory
|
|
257
|
-
if (options.examplesDirectory && operationIdsWithExample.size > 0) {
|
|
258
|
-
const examplesPath = resolvePath(getDirectoryPath(outputFile), "examples");
|
|
259
|
-
const exampleDir = version
|
|
260
|
-
? resolvePath(options.examplesDirectory, version)
|
|
261
|
-
: resolvePath(options.examplesDirectory);
|
|
262
|
-
await program.host.mkdirp(examplesPath);
|
|
263
|
-
for (const operationId of operationIdsWithExample) {
|
|
264
|
-
const examples = operationExamplesMap.get(operationId);
|
|
265
|
-
if (examples) {
|
|
266
|
-
for (const [_, fileName] of Object.entries(examples)) {
|
|
267
|
-
const content = await program.host.readFile(resolvePath(exampleDir, fileName));
|
|
268
|
-
await emitFile(program, {
|
|
269
|
-
path: resolvePath(examplesPath, fileName),
|
|
270
|
-
content: content.text,
|
|
271
|
-
newLine: options.newLine,
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
catch (err) {
|
|
280
|
-
if (err instanceof ErrorTypeFoundError) {
|
|
281
|
-
// Return early, there must be a parse error if an ErrorType was
|
|
282
|
-
// inserted into the TypeSpec output
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
else {
|
|
286
|
-
throw err;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
181
|
function parseNextLinkName(paged) {
|
|
291
182
|
const pathComponents = paged.nextLinkSegments;
|
|
292
183
|
if (pathComponents) {
|
|
@@ -418,12 +309,12 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
418
309
|
currentEndpoint["x-ms-examples"] = examples.reduce((acc, example) => ({ ...acc, [example.title]: { $ref: example.pathOrUri } }), {});
|
|
419
310
|
}
|
|
420
311
|
if (options.examplesDirectory) {
|
|
421
|
-
const examples =
|
|
312
|
+
const examples = exampleMap.get(currentEndpoint.operationId);
|
|
422
313
|
if (examples && currentEndpoint.operationId) {
|
|
423
314
|
operationIdsWithExample.add(currentEndpoint.operationId);
|
|
424
315
|
currentEndpoint["x-ms-examples"] = currentEndpoint["x-ms-examples"] || {};
|
|
425
|
-
for (const [title,
|
|
426
|
-
currentEndpoint["x-ms-examples"][title] = { $ref: `./examples/${
|
|
316
|
+
for (const [title, example] of Object.entries(examples)) {
|
|
317
|
+
currentEndpoint["x-ms-examples"][title] = { $ref: `./examples/${example.relativePath}` };
|
|
427
318
|
}
|
|
428
319
|
}
|
|
429
320
|
}
|
|
@@ -581,7 +472,7 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
581
472
|
if (getRootLength(absoluteRef) === 0) {
|
|
582
473
|
return absoluteRef; // It is already relative.
|
|
583
474
|
}
|
|
584
|
-
return getRelativePathFromDirectory(getDirectoryPath(outputFile), absoluteRef, false);
|
|
475
|
+
return getRelativePathFromDirectory(getDirectoryPath(context.outputFile), absoluteRef, false);
|
|
585
476
|
}
|
|
586
477
|
function getSchemaOrRef(type, schemaContext) {
|
|
587
478
|
const refUrl = getRef(program, type, { version: context.version, service: context.service });
|
|
@@ -696,11 +587,6 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
696
587
|
// `resolveEncodedName` will return the original name if no @encodedName so we have to do that check
|
|
697
588
|
return encodedName === type.name ? viaProjection ?? type.name : encodedName;
|
|
698
589
|
}
|
|
699
|
-
function getClientName(type) {
|
|
700
|
-
const viaProjection = getProjectedName(program, type, "client");
|
|
701
|
-
const clientName = getClientNameOverride(tcgcSdkContext, type);
|
|
702
|
-
return clientName ?? viaProjection ?? type.name;
|
|
703
|
-
}
|
|
704
590
|
function emitEndpointParameters(methodParams, visibility) {
|
|
705
591
|
const consumes = methodParams.body?.contentTypes ?? [];
|
|
706
592
|
for (const httpOpParam of methodParams.parameters) {
|
|
@@ -956,66 +842,6 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
956
842
|
root.tags.push({ name: tag });
|
|
957
843
|
}
|
|
958
844
|
}
|
|
959
|
-
async function loadExamples(version) {
|
|
960
|
-
if (options.examplesDirectory) {
|
|
961
|
-
const exampleDir = version
|
|
962
|
-
? resolvePath(options.examplesDirectory, version)
|
|
963
|
-
: resolvePath(options.examplesDirectory);
|
|
964
|
-
try {
|
|
965
|
-
if (!(await program.host.stat(exampleDir)).isDirectory())
|
|
966
|
-
return;
|
|
967
|
-
}
|
|
968
|
-
catch (err) {
|
|
969
|
-
reportDiagnostic(program, {
|
|
970
|
-
code: "example-loading",
|
|
971
|
-
messageId: "noDirectory",
|
|
972
|
-
format: { directory: exampleDir },
|
|
973
|
-
target: NoTarget,
|
|
974
|
-
});
|
|
975
|
-
return;
|
|
976
|
-
}
|
|
977
|
-
const exampleFiles = await program.host.readDir(exampleDir);
|
|
978
|
-
for (const fileName of exampleFiles) {
|
|
979
|
-
try {
|
|
980
|
-
const exampleFile = await program.host.readFile(resolvePath(exampleDir, fileName));
|
|
981
|
-
const example = JSON.parse(exampleFile.text);
|
|
982
|
-
if (!example.operationId || !example.title) {
|
|
983
|
-
reportDiagnostic(program, {
|
|
984
|
-
code: "example-loading",
|
|
985
|
-
messageId: "noOperationId",
|
|
986
|
-
format: { filename: fileName },
|
|
987
|
-
target: NoTarget,
|
|
988
|
-
});
|
|
989
|
-
continue;
|
|
990
|
-
}
|
|
991
|
-
if (!operationExamplesMap.has(example.operationId)) {
|
|
992
|
-
operationExamplesMap.set(example.operationId, {});
|
|
993
|
-
}
|
|
994
|
-
const examples = operationExamplesMap.get(example.operationId);
|
|
995
|
-
if (example.title in examples) {
|
|
996
|
-
reportDiagnostic(program, {
|
|
997
|
-
code: "duplicate-example-file",
|
|
998
|
-
target: NoTarget,
|
|
999
|
-
format: {
|
|
1000
|
-
filename: fileName,
|
|
1001
|
-
operationId: example.operationId,
|
|
1002
|
-
title: example.title,
|
|
1003
|
-
},
|
|
1004
|
-
});
|
|
1005
|
-
}
|
|
1006
|
-
examples[example.title] = fileName;
|
|
1007
|
-
}
|
|
1008
|
-
catch (err) {
|
|
1009
|
-
reportDiagnostic(program, {
|
|
1010
|
-
code: "example-loading",
|
|
1011
|
-
messageId: "default",
|
|
1012
|
-
format: { filename: fileName, error: err?.toString() ?? "" },
|
|
1013
|
-
target: NoTarget,
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
845
|
function getSchemaForType(type, schemaContext) {
|
|
1020
846
|
const builtinType = getSchemaForLiterals(type);
|
|
1021
847
|
if (builtinType !== undefined) {
|
|
@@ -1288,7 +1114,7 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
1288
1114
|
continue;
|
|
1289
1115
|
}
|
|
1290
1116
|
const jsonName = getJsonName(prop);
|
|
1291
|
-
const clientName = getClientName(prop);
|
|
1117
|
+
const clientName = getClientName(context, prop);
|
|
1292
1118
|
const description = getDoc(program, prop);
|
|
1293
1119
|
// if this property is a discriminator property, remove it to keep autorest validation happy
|
|
1294
1120
|
if (model.baseModel) {
|
|
@@ -1511,7 +1337,7 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
1511
1337
|
}
|
|
1512
1338
|
}
|
|
1513
1339
|
if (typespecType.kind === "ModelProperty" &&
|
|
1514
|
-
shouldFlattenProperty(tcgcSdkContext, typespecType)) {
|
|
1340
|
+
shouldFlattenProperty(context.tcgcSdkContext, typespecType)) {
|
|
1515
1341
|
newTarget["x-ms-client-flatten"] = true;
|
|
1516
1342
|
}
|
|
1517
1343
|
attachExtensions(typespecType, newTarget);
|
|
@@ -1788,7 +1614,7 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
1788
1614
|
reportDiagnostic(program, {
|
|
1789
1615
|
code: "unsupported-auth",
|
|
1790
1616
|
format: { authType: auth.type },
|
|
1791
|
-
target:
|
|
1617
|
+
target: service.type,
|
|
1792
1618
|
});
|
|
1793
1619
|
return undefined;
|
|
1794
1620
|
}
|
|
@@ -1809,9 +1635,6 @@ function createOAPIEmitter(program, tcgcSdkContext, options) {
|
|
|
1809
1635
|
}
|
|
1810
1636
|
}
|
|
1811
1637
|
}
|
|
1812
|
-
function prettierOutput(output) {
|
|
1813
|
-
return output + "\n";
|
|
1814
|
-
}
|
|
1815
1638
|
class ErrorTypeFoundError extends Error {
|
|
1816
1639
|
constructor() {
|
|
1817
1640
|
super("Error type found in evaluated TypeSpec output");
|
|
@@ -1823,24 +1646,72 @@ export function sortOpenAPIDocument(doc) {
|
|
|
1823
1646
|
const sorted = sortWithJsonSchema(unsorted, AutorestOpenAPISchema, "#/$defs/AutorestOpenAPISchema");
|
|
1824
1647
|
return sorted;
|
|
1825
1648
|
}
|
|
1826
|
-
function
|
|
1827
|
-
const
|
|
1828
|
-
if (
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
:
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1649
|
+
async function loadExamples(host, options, version) {
|
|
1650
|
+
const diagnostics = createDiagnosticCollector();
|
|
1651
|
+
if (!options.examplesDirectory) {
|
|
1652
|
+
return diagnostics.wrap(new Map());
|
|
1653
|
+
}
|
|
1654
|
+
const exampleDir = version
|
|
1655
|
+
? resolvePath(options.examplesDirectory, version)
|
|
1656
|
+
: resolvePath(options.examplesDirectory);
|
|
1657
|
+
try {
|
|
1658
|
+
if (!(await host.stat(exampleDir)).isDirectory())
|
|
1659
|
+
return diagnostics.wrap(new Map());
|
|
1660
|
+
}
|
|
1661
|
+
catch (err) {
|
|
1662
|
+
diagnostics.add(createDiagnostic({
|
|
1663
|
+
code: "example-loading",
|
|
1664
|
+
messageId: "noDirectory",
|
|
1665
|
+
format: { directory: exampleDir },
|
|
1666
|
+
target: NoTarget,
|
|
1667
|
+
}));
|
|
1668
|
+
return diagnostics.wrap(new Map());
|
|
1669
|
+
}
|
|
1670
|
+
const map = new Map();
|
|
1671
|
+
const exampleFiles = await host.readDir(exampleDir);
|
|
1672
|
+
for (const fileName of exampleFiles) {
|
|
1673
|
+
try {
|
|
1674
|
+
const exampleFile = await host.readFile(resolvePath(exampleDir, fileName));
|
|
1675
|
+
const example = JSON.parse(exampleFile.text);
|
|
1676
|
+
if (!example.operationId || !example.title) {
|
|
1677
|
+
diagnostics.add(createDiagnostic({
|
|
1678
|
+
code: "example-loading",
|
|
1679
|
+
messageId: "noOperationId",
|
|
1680
|
+
format: { filename: fileName },
|
|
1681
|
+
target: NoTarget,
|
|
1682
|
+
}));
|
|
1683
|
+
continue;
|
|
1684
|
+
}
|
|
1685
|
+
if (!map.has(example.operationId)) {
|
|
1686
|
+
map.set(example.operationId, {});
|
|
1687
|
+
}
|
|
1688
|
+
const examples = map.get(example.operationId);
|
|
1689
|
+
if (example.title in examples) {
|
|
1690
|
+
diagnostics.add(createDiagnostic({
|
|
1691
|
+
code: "duplicate-example-file",
|
|
1692
|
+
target: NoTarget,
|
|
1693
|
+
format: {
|
|
1694
|
+
filename: fileName,
|
|
1695
|
+
operationId: example.operationId,
|
|
1696
|
+
title: example.title,
|
|
1697
|
+
},
|
|
1698
|
+
}));
|
|
1699
|
+
}
|
|
1700
|
+
examples[example.title] = {
|
|
1701
|
+
relativePath: fileName,
|
|
1702
|
+
file: exampleFile,
|
|
1703
|
+
data: example,
|
|
1704
|
+
};
|
|
1705
|
+
}
|
|
1706
|
+
catch (err) {
|
|
1707
|
+
diagnostics.add(createDiagnostic({
|
|
1708
|
+
code: "example-loading",
|
|
1709
|
+
messageId: "default",
|
|
1710
|
+
format: { filename: fileName, error: err?.toString() ?? "" },
|
|
1711
|
+
target: NoTarget,
|
|
1712
|
+
}));
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
return diagnostics.wrap(map);
|
|
1845
1716
|
}
|
|
1846
1717
|
//# sourceMappingURL=openapi.js.map
|