@azure-tools/typespec-java 0.5.0
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/code-model-builder.d.ts +102 -0
- package/dist/src/code-model-builder.d.ts.map +1 -0
- package/dist/src/code-model-builder.js +1675 -0
- package/dist/src/code-model-builder.js.map +1 -0
- package/dist/src/common/client.d.ts +18 -0
- package/dist/src/common/client.d.ts.map +1 -0
- package/dist/src/common/client.js +29 -0
- package/dist/src/common/client.js.map +1 -0
- package/dist/src/common/code-model.d.ts +26 -0
- package/dist/src/common/code-model.d.ts.map +1 -0
- package/dist/src/common/code-model.js +59 -0
- package/dist/src/common/code-model.js.map +1 -0
- package/dist/src/common/operation.d.ts +80 -0
- package/dist/src/common/operation.d.ts.map +1 -0
- package/dist/src/common/operation.js +88 -0
- package/dist/src/common/operation.js.map +1 -0
- package/dist/src/common/schemas/choice.d.ts +28 -0
- package/dist/src/common/schemas/choice.d.ts.map +1 -0
- package/dist/src/common/schemas/choice.js +14 -0
- package/dist/src/common/schemas/choice.js.map +1 -0
- package/dist/src/common/schemas/relationship.d.ts +44 -0
- package/dist/src/common/schemas/relationship.d.ts.map +1 -0
- package/dist/src/common/schemas/relationship.js +15 -0
- package/dist/src/common/schemas/relationship.js.map +1 -0
- package/dist/src/common/schemas/usage.d.ts +22 -0
- package/dist/src/common/schemas/usage.d.ts.map +1 -0
- package/dist/src/common/schemas/usage.js +16 -0
- package/dist/src/common/schemas/usage.js.map +1 -0
- package/dist/src/emitter.d.ts +21 -0
- package/dist/src/emitter.d.ts.map +1 -0
- package/dist/src/emitter.js +84 -0
- package/dist/src/emitter.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/models.d.ts +15 -0
- package/dist/src/models.d.ts.map +1 -0
- package/dist/src/models.js +21 -0
- package/dist/src/models.js.map +1 -0
- package/dist/src/prenamer/naming-utils.d.ts +67 -0
- package/dist/src/prenamer/naming-utils.d.ts.map +1 -0
- package/dist/src/prenamer/naming-utils.js +146 -0
- package/dist/src/prenamer/naming-utils.js.map +1 -0
- package/dist/src/prenamer/prenamer.d.ts +36 -0
- package/dist/src/prenamer/prenamer.d.ts.map +1 -0
- package/dist/src/prenamer/prenamer.js +332 -0
- package/dist/src/prenamer/prenamer.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +65 -0
- package/readme.md +74 -0
- package/target/azure-cadl-extension-jar-with-dependencies.jar +0 -0
|
@@ -0,0 +1,1675 @@
|
|
|
1
|
+
import { getDoc, getEffectiveModelType, getFormat, getFriendlyName, getKnownValues, getSummary, getVisibility, ignoreDiagnostics, isArrayModelType, isRecordModelType, isTemplateDeclaration, isTemplateInstance, isUnknownType, getDiscriminator, isNeverType, listServices, getNamespaceFullName, isNullType, NoTarget, getTypeName, getProjectedName, getService, } from "@typespec/compiler";
|
|
2
|
+
import { getResourceOperation, getSegment } from "@typespec/rest";
|
|
3
|
+
import { getAuthentication, getHeaderFieldName, getPathParamName, getQueryParamName, getServers, getStatusCodeDescription, isStatusCode, getHttpOperation, getQueryParamOptions, getHeaderFieldOptions, } from "@typespec/http";
|
|
4
|
+
import { getVersion } from "@typespec/versioning";
|
|
5
|
+
import { isPollingLocation, getPagedResult, getOperationLinks, isFixed } from "@azure-tools/typespec-azure-core";
|
|
6
|
+
import { listClients, listOperationGroups, listOperationsInOperationGroup, isApiVersion, shouldGenerateConvenient, createDpgContext, shouldGenerateProtocol, } from "@azure-tools/typespec-client-generator-core";
|
|
7
|
+
import { fail } from "assert";
|
|
8
|
+
import { AnySchema, ArraySchema, BinaryResponse, BinarySchema, BooleanSchema, ByteArraySchema, ChoiceValue, ConstantSchema, ConstantValue, DateTimeSchema, DateSchema, DictionarySchema, Discriminator, DurationSchema, HttpHeader, HttpParameter, ImplementationLocation, NumberSchema, ObjectSchema, Parameter, ParameterLocation, Property, Relations, Response, SchemaResponse, SchemaType, StringSchema, TimeSchema, Security, OAuth2SecurityScheme, KeySecurityScheme, OperationGroup, UriSchema, VirtualParameter, GroupSchema, GroupProperty, ApiVersion, SerializationStyle, } from "@autorest/codemodel";
|
|
9
|
+
import { CodeModel } from "./common/code-model.js";
|
|
10
|
+
import { Client as CodeModelClient, ServiceVersion } from "./common/client.js";
|
|
11
|
+
import { ConvenienceApi, Operation as CodeModelOperation, OperationLink, Request } from "./common/operation.js";
|
|
12
|
+
import { SchemaContext } from "./common/schemas/usage.js";
|
|
13
|
+
import { ChoiceSchema, SealedChoiceSchema } from "./common/schemas/choice.js";
|
|
14
|
+
import { OrSchema } from "./common/schemas/relationship.js";
|
|
15
|
+
import { PreNamer } from "./prenamer/prenamer.js";
|
|
16
|
+
import { ClientContext, LongRunningMetadata } from "./models.js";
|
|
17
|
+
import pkg from "lodash";
|
|
18
|
+
const { isEqual } = pkg;
|
|
19
|
+
export class CodeModelBuilder {
|
|
20
|
+
constructor(program1, context) {
|
|
21
|
+
this.schemaCache = new ProcessingCache((type, name) => this.processSchemaImpl(type, name));
|
|
22
|
+
this.operationCache = new Map();
|
|
23
|
+
this.options = context.options;
|
|
24
|
+
this.program = program1;
|
|
25
|
+
this.dpgContext = createDpgContext(context);
|
|
26
|
+
const service = listServices(this.program)[0];
|
|
27
|
+
const serviceNamespace = service.type;
|
|
28
|
+
if (serviceNamespace === undefined) {
|
|
29
|
+
throw Error("Can not emit yaml for a namespace that doesn't exist.");
|
|
30
|
+
}
|
|
31
|
+
// java namespace
|
|
32
|
+
this.namespace = getNamespaceFullName(serviceNamespace) || "Azure.Client";
|
|
33
|
+
const javaNamespace = getJavaNamespace(this.namespace);
|
|
34
|
+
const namespace1 = this.namespace;
|
|
35
|
+
this.typeNameOptions = {
|
|
36
|
+
// shorten type names by removing TypeSpec and service namespace
|
|
37
|
+
namespaceFilter(ns) {
|
|
38
|
+
const name = getNamespaceFullName(ns);
|
|
39
|
+
return name !== "Cadl" && name !== namespace1;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
// init code model
|
|
43
|
+
const title = serviceNamespace.name;
|
|
44
|
+
const description = this.getDoc(serviceNamespace);
|
|
45
|
+
this.codeModel = new CodeModel(title, false, {
|
|
46
|
+
info: {
|
|
47
|
+
description: description,
|
|
48
|
+
},
|
|
49
|
+
language: {
|
|
50
|
+
default: {
|
|
51
|
+
name: title,
|
|
52
|
+
description: description,
|
|
53
|
+
summary: this.getSummary(serviceNamespace),
|
|
54
|
+
namespace: this.namespace,
|
|
55
|
+
},
|
|
56
|
+
java: {
|
|
57
|
+
namespace: javaNamespace,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
// auth
|
|
62
|
+
// TODO: it is not very likely, but different client could have different auth
|
|
63
|
+
const auth = getAuthentication(this.program, serviceNamespace);
|
|
64
|
+
if (auth) {
|
|
65
|
+
this.processAuth(auth);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
build() {
|
|
69
|
+
var _a;
|
|
70
|
+
this.processClients();
|
|
71
|
+
(_a = this.codeModel.schemas.objects) === null || _a === void 0 ? void 0 : _a.forEach((it) => this.propagateSchemaUsage(it));
|
|
72
|
+
if (this.options.namer) {
|
|
73
|
+
this.codeModel = new PreNamer(this.codeModel).init().process();
|
|
74
|
+
}
|
|
75
|
+
return this.codeModel;
|
|
76
|
+
}
|
|
77
|
+
processHost(server) {
|
|
78
|
+
const hostParameters = [];
|
|
79
|
+
if (server) {
|
|
80
|
+
server.parameters.forEach((it) => {
|
|
81
|
+
let parameter;
|
|
82
|
+
if (isApiVersion(this.dpgContext, it)) {
|
|
83
|
+
parameter = this.createApiVersionParameter(it.name, ParameterLocation.Uri);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const schema = this.processSchema(it.type, it.name);
|
|
87
|
+
parameter = new Parameter(it.name, this.getDoc(it), schema, {
|
|
88
|
+
implementation: ImplementationLocation.Client,
|
|
89
|
+
origin: "modelerfour:synthesized/host",
|
|
90
|
+
required: true,
|
|
91
|
+
protocol: {
|
|
92
|
+
http: new HttpParameter(ParameterLocation.Uri),
|
|
93
|
+
},
|
|
94
|
+
clientDefaultValue: this.getDefaultValue(it.default),
|
|
95
|
+
language: {
|
|
96
|
+
default: {
|
|
97
|
+
serializedName: it.name,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
extensions: {
|
|
101
|
+
"x-ms-skip-url-encoding": schema instanceof UriSchema,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
hostParameters.push(this.codeModel.addGlobalParameter(parameter));
|
|
106
|
+
});
|
|
107
|
+
return hostParameters;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
hostParameters.push(this.codeModel.addGlobalParameter(new Parameter("endpoint", "Server parameter", this.stringSchema, {
|
|
111
|
+
implementation: ImplementationLocation.Client,
|
|
112
|
+
origin: "modelerfour:synthesized/host",
|
|
113
|
+
required: true,
|
|
114
|
+
protocol: {
|
|
115
|
+
http: new HttpParameter(ParameterLocation.Uri),
|
|
116
|
+
},
|
|
117
|
+
language: {
|
|
118
|
+
default: {
|
|
119
|
+
serializedName: "endpoint",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
extensions: {
|
|
123
|
+
"x-ms-skip-url-encoding": true,
|
|
124
|
+
},
|
|
125
|
+
})));
|
|
126
|
+
return hostParameters;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
processAuth(auth) {
|
|
130
|
+
const securitySchemes = [];
|
|
131
|
+
for (const option of auth.options) {
|
|
132
|
+
for (const scheme of option.schemes) {
|
|
133
|
+
switch (scheme.type) {
|
|
134
|
+
case "oauth2":
|
|
135
|
+
{
|
|
136
|
+
const oauth2Scheme = new OAuth2SecurityScheme({
|
|
137
|
+
scopes: [],
|
|
138
|
+
});
|
|
139
|
+
scheme.flows.forEach((it) => oauth2Scheme.scopes.push(...it.scopes.map((it) => it.value)));
|
|
140
|
+
securitySchemes.push(oauth2Scheme);
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
case "apiKey":
|
|
144
|
+
{
|
|
145
|
+
const keyScheme = new KeySecurityScheme({
|
|
146
|
+
name: scheme.name,
|
|
147
|
+
});
|
|
148
|
+
securitySchemes.push(keyScheme);
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (securitySchemes.length > 0) {
|
|
155
|
+
this.codeModel.security = new Security(true, {
|
|
156
|
+
schemes: securitySchemes,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
processClients() {
|
|
161
|
+
var _a;
|
|
162
|
+
const clients = listClients(this.dpgContext);
|
|
163
|
+
for (const client of clients) {
|
|
164
|
+
const codeModelClient = new CodeModelClient(client.name, this.getDoc(client.type), {
|
|
165
|
+
summary: this.getSummary(client.type),
|
|
166
|
+
// at present, use global security definition
|
|
167
|
+
security: this.codeModel.security,
|
|
168
|
+
});
|
|
169
|
+
// versioning
|
|
170
|
+
const versioning = getVersion(this.program, client.service);
|
|
171
|
+
if (versioning && versioning.getVersions()) {
|
|
172
|
+
// @versioned in versioning
|
|
173
|
+
codeModelClient.apiVersions = [];
|
|
174
|
+
for (const version of versioning.getVersions()) {
|
|
175
|
+
const apiVersion = new ApiVersion();
|
|
176
|
+
apiVersion.version = version.value;
|
|
177
|
+
codeModelClient.apiVersions.push(apiVersion);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// fallback to @service.version
|
|
182
|
+
const service = getService(this.program, client.service);
|
|
183
|
+
if (service === null || service === void 0 ? void 0 : service.version) {
|
|
184
|
+
codeModelClient.apiVersions = [];
|
|
185
|
+
const apiVersion = new ApiVersion();
|
|
186
|
+
apiVersion.version = service.version;
|
|
187
|
+
codeModelClient.apiVersions.push(apiVersion);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
throw new Error(`API version not available for client ${client.name}.`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// server
|
|
194
|
+
let baseUri = "{endpoint}";
|
|
195
|
+
const servers = getServers(this.program, client.service);
|
|
196
|
+
if (servers && servers.length === 1) {
|
|
197
|
+
baseUri = servers[0].url;
|
|
198
|
+
}
|
|
199
|
+
const hostParameters = this.processHost((servers === null || servers === void 0 ? void 0 : servers.length) === 1 ? servers[0] : undefined);
|
|
200
|
+
codeModelClient.addGlobalParameters(hostParameters);
|
|
201
|
+
const clientContext = new ClientContext(baseUri, hostParameters, codeModelClient.globalParameters);
|
|
202
|
+
const operationGroups = listOperationGroups(this.dpgContext, client);
|
|
203
|
+
const operationWithoutGroup = listOperationsInOperationGroup(this.dpgContext, client);
|
|
204
|
+
let codeModelGroup = new OperationGroup("");
|
|
205
|
+
for (const operation of operationWithoutGroup) {
|
|
206
|
+
codeModelGroup.addOperation(this.processOperation("", operation, clientContext));
|
|
207
|
+
}
|
|
208
|
+
if (((_a = codeModelGroup.operations) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
209
|
+
codeModelClient.operationGroups.push(codeModelGroup);
|
|
210
|
+
}
|
|
211
|
+
for (const operationGroup of operationGroups) {
|
|
212
|
+
const operations = listOperationsInOperationGroup(this.dpgContext, operationGroup);
|
|
213
|
+
codeModelGroup = new OperationGroup(operationGroup.type.name);
|
|
214
|
+
for (const operation of operations) {
|
|
215
|
+
codeModelGroup.addOperation(this.processOperation(operationGroup.type.name, operation, clientContext));
|
|
216
|
+
}
|
|
217
|
+
codeModelClient.operationGroups.push(codeModelGroup);
|
|
218
|
+
}
|
|
219
|
+
this.codeModel.clients.push(codeModelClient);
|
|
220
|
+
}
|
|
221
|
+
// postprocess for ServiceVersion
|
|
222
|
+
let apiVersionSameForAllClients = true;
|
|
223
|
+
let sharedApiVersions = undefined;
|
|
224
|
+
for (const client of this.codeModel.clients) {
|
|
225
|
+
const apiVersions = getClientApiVersions(client);
|
|
226
|
+
if (!apiVersions) {
|
|
227
|
+
// client does not have apiVersions
|
|
228
|
+
apiVersionSameForAllClients = false;
|
|
229
|
+
}
|
|
230
|
+
else if (!sharedApiVersions) {
|
|
231
|
+
// first client, set it to sharedApiVersions
|
|
232
|
+
sharedApiVersions = apiVersions;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
apiVersionSameForAllClients = isEqual(sharedApiVersions, apiVersions);
|
|
236
|
+
}
|
|
237
|
+
if (!apiVersionSameForAllClients) {
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (apiVersionSameForAllClients) {
|
|
242
|
+
const serviceVersion = getServiceVersion(this.codeModel);
|
|
243
|
+
for (const client of this.codeModel.clients) {
|
|
244
|
+
client.serviceVersion = serviceVersion;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
for (const client of this.codeModel.clients) {
|
|
249
|
+
const apiVersions = getClientApiVersions(client);
|
|
250
|
+
if (apiVersions) {
|
|
251
|
+
client.serviceVersion = getServiceVersion(client);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
processOperation(groupName, operation, clientContext, fromLinkedOperation = false) {
|
|
257
|
+
var _a;
|
|
258
|
+
const op = ignoreDiagnostics(getHttpOperation(this.program, operation));
|
|
259
|
+
const operationGroup = this.codeModel.getOperationGroup(groupName);
|
|
260
|
+
const operationName = this.getName(operation);
|
|
261
|
+
const opId = groupName ? `${groupName}_${operationName}` : `${operationName}`;
|
|
262
|
+
const codeModelOperation = new CodeModelOperation(operationName, this.getDoc(operation), {
|
|
263
|
+
operationId: opId,
|
|
264
|
+
summary: this.getSummary(operation),
|
|
265
|
+
});
|
|
266
|
+
if (fromLinkedOperation || !operationContainsJsonMergePatch(op)) {
|
|
267
|
+
// do not generate convenience method for JSON Merge Patch
|
|
268
|
+
const convenienceApiName = this.getConvenienceApiName(operation);
|
|
269
|
+
if (convenienceApiName) {
|
|
270
|
+
codeModelOperation.convenienceApi = new ConvenienceApi(convenienceApiName);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (!fromLinkedOperation) {
|
|
274
|
+
// cache for later reference from operationLinks
|
|
275
|
+
this.operationCache.set(operation, codeModelOperation);
|
|
276
|
+
}
|
|
277
|
+
codeModelOperation.addRequest(new Request({
|
|
278
|
+
protocol: {
|
|
279
|
+
http: {
|
|
280
|
+
path: op.path,
|
|
281
|
+
method: op.verb,
|
|
282
|
+
uri: clientContext.baseUri,
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
}));
|
|
286
|
+
// host
|
|
287
|
+
clientContext.hostParameters.forEach((it) => codeModelOperation.addParameter(it));
|
|
288
|
+
// parameters
|
|
289
|
+
op.parameters.parameters.map((it) => this.processParameter(codeModelOperation, it, clientContext));
|
|
290
|
+
// "accept" header
|
|
291
|
+
this.addAcceptHeaderParameter(codeModelOperation, op.responses);
|
|
292
|
+
// body
|
|
293
|
+
if (op.parameters.body) {
|
|
294
|
+
if (op.parameters.body.parameter) {
|
|
295
|
+
this.processParameterBody(codeModelOperation, op.parameters.body.parameter, operation.parameters);
|
|
296
|
+
}
|
|
297
|
+
else if (op.parameters.body.type) {
|
|
298
|
+
let bodyType = this.getEffectiveSchemaType(op.parameters.body.type);
|
|
299
|
+
if (bodyType.kind === "Model") {
|
|
300
|
+
// try use resource type as round-trip model
|
|
301
|
+
const resourceType = (_a = getResourceOperation(this.program, operation)) === null || _a === void 0 ? void 0 : _a.resourceType;
|
|
302
|
+
if (resourceType && op.responses && op.responses.length > 0) {
|
|
303
|
+
const resp = op.responses[0];
|
|
304
|
+
if (resp.responses && resp.responses.length > 0 && resp.responses[0].body) {
|
|
305
|
+
const responseBody = resp.responses[0].body;
|
|
306
|
+
const bodyTypeInResponse = this.findResponseBody(responseBody.type);
|
|
307
|
+
// response body type is resource type, and request body type (if templated) contains resource type
|
|
308
|
+
if (bodyTypeInResponse === resourceType && isModelReferredInTemplate(bodyType, resourceType)) {
|
|
309
|
+
bodyType = resourceType;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
this.processParameterBody(codeModelOperation, bodyType, operation.parameters);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// linked operations
|
|
318
|
+
const lroMetadata = this.processLinkedOperation(codeModelOperation, groupName, operation, clientContext);
|
|
319
|
+
// responses
|
|
320
|
+
const candidateResponseSchema = lroMetadata.pollResultType; // candidate: response body type of pollingOperation
|
|
321
|
+
op.responses.map((it) => this.processResponse(codeModelOperation, it, candidateResponseSchema));
|
|
322
|
+
// check for paged
|
|
323
|
+
this.processRouteForPaged(codeModelOperation, op.responses);
|
|
324
|
+
// check for long-running operation
|
|
325
|
+
this.processRouteForLongRunning(codeModelOperation, op.responses, lroMetadata.longRunning);
|
|
326
|
+
// check for generating protocol api or not
|
|
327
|
+
codeModelOperation.generateProtocolApi = shouldGenerateProtocol(this.dpgContext, operation);
|
|
328
|
+
operationGroup.addOperation(codeModelOperation);
|
|
329
|
+
return codeModelOperation;
|
|
330
|
+
}
|
|
331
|
+
processRouteForPaged(op, responses) {
|
|
332
|
+
var _a, _b, _c, _d;
|
|
333
|
+
for (const response of responses) {
|
|
334
|
+
if (response.responses && response.responses.length > 0 && response.responses[0].body) {
|
|
335
|
+
const responseBody = response.responses[0].body;
|
|
336
|
+
const bodyType = this.findResponseBody(responseBody.type);
|
|
337
|
+
if (bodyType.kind === "Model") {
|
|
338
|
+
const pagedResult = getPagedResult(this.program, bodyType);
|
|
339
|
+
if (pagedResult) {
|
|
340
|
+
op.extensions = (_a = op.extensions) !== null && _a !== void 0 ? _a : {};
|
|
341
|
+
op.extensions["x-ms-pageable"] = {
|
|
342
|
+
itemName: (_b = pagedResult.itemsProperty) === null || _b === void 0 ? void 0 : _b.name,
|
|
343
|
+
nextLinkName: (_c = pagedResult.nextLinkProperty) === null || _c === void 0 ? void 0 : _c.name,
|
|
344
|
+
};
|
|
345
|
+
(_d = op.responses) === null || _d === void 0 ? void 0 : _d.forEach((r) => {
|
|
346
|
+
if (r instanceof SchemaResponse) {
|
|
347
|
+
this.trackSchemaUsage(r.schema, { usage: [SchemaContext.Paged] });
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
processLinkedOperation(op, groupName, operation, clientContext) {
|
|
357
|
+
let pollingSchema = undefined;
|
|
358
|
+
let finalSchema = undefined;
|
|
359
|
+
let pollingFoundInOperationLinks = false;
|
|
360
|
+
const operationLinks = getOperationLinks(this.program, operation);
|
|
361
|
+
if (operationLinks) {
|
|
362
|
+
op.operationLinks = {};
|
|
363
|
+
for (const [linkType, linkOperation] of operationLinks) {
|
|
364
|
+
if (linkType === "polling" || linkType === "final") {
|
|
365
|
+
// some TypeSpec writes pollingOperation without the operation
|
|
366
|
+
pollingFoundInOperationLinks = true;
|
|
367
|
+
}
|
|
368
|
+
if (linkOperation.linkedOperation) {
|
|
369
|
+
// process linked operation, if not processed
|
|
370
|
+
let linkedOperation = this.operationCache.get(linkOperation.linkedOperation);
|
|
371
|
+
if (!linkedOperation) {
|
|
372
|
+
linkedOperation = this.processOperation(groupName, linkOperation.linkedOperation, clientContext, true);
|
|
373
|
+
}
|
|
374
|
+
const opLink = new OperationLink(linkedOperation);
|
|
375
|
+
// parameters of operation link
|
|
376
|
+
if (linkOperation.parameters) {
|
|
377
|
+
opLink.parameters = this.processSchema(linkOperation.parameters, "parameters");
|
|
378
|
+
}
|
|
379
|
+
op.operationLinks[linkType] = opLink;
|
|
380
|
+
const getResponse = (linkedOp) => {
|
|
381
|
+
if (linkedOp.responses) {
|
|
382
|
+
const response = linkedOp.responses.find((it) => { var _a, _b, _c; return (_c = (_b = (_a = it.protocol) === null || _a === void 0 ? void 0 : _a.http) === null || _b === void 0 ? void 0 : _b.statusCodes) === null || _c === void 0 ? void 0 : _c.includes("200"); });
|
|
383
|
+
if (response && response instanceof SchemaResponse) {
|
|
384
|
+
const schema = response.schema;
|
|
385
|
+
if (op.convenienceApi) {
|
|
386
|
+
this.trackSchemaUsage(schema, { usage: [SchemaContext.ConvenienceApi] });
|
|
387
|
+
}
|
|
388
|
+
return schema;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return undefined;
|
|
392
|
+
};
|
|
393
|
+
if (linkType === "polling") {
|
|
394
|
+
pollingSchema = getResponse(linkedOperation);
|
|
395
|
+
}
|
|
396
|
+
else if (linkType === "final") {
|
|
397
|
+
finalSchema = getResponse(linkedOperation);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return new LongRunningMetadata(pollingFoundInOperationLinks, pollingSchema, finalSchema);
|
|
403
|
+
}
|
|
404
|
+
processRouteForLongRunning(op, responses, pollingFoundInOperationLinks) {
|
|
405
|
+
var _a, _b;
|
|
406
|
+
if (pollingFoundInOperationLinks) {
|
|
407
|
+
op.extensions = (_a = op.extensions) !== null && _a !== void 0 ? _a : {};
|
|
408
|
+
op.extensions["x-ms-long-running-operation"] = true;
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
for (const resp of responses) {
|
|
412
|
+
if (resp.responses && resp.responses.length > 0 && resp.responses[0].headers) {
|
|
413
|
+
for (const [_, header] of Object.entries(resp.responses[0].headers)) {
|
|
414
|
+
if (isPollingLocation(this.program, header)) {
|
|
415
|
+
op.extensions = (_b = op.extensions) !== null && _b !== void 0 ? _b : {};
|
|
416
|
+
op.extensions["x-ms-long-running-operation"] = true;
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
processParameter(op, param, clientContext) {
|
|
424
|
+
var _a;
|
|
425
|
+
if (isApiVersion(this.dpgContext, param)) {
|
|
426
|
+
const parameter = param.type === "query" ? this.apiVersionParameter : this.apiVersionParameterInPath;
|
|
427
|
+
op.addParameter(parameter);
|
|
428
|
+
clientContext.addGlobalParameter(parameter);
|
|
429
|
+
}
|
|
430
|
+
else if (specialHeaderNames.has(param.name.toLowerCase())) {
|
|
431
|
+
// special headers
|
|
432
|
+
op.specialHeaders = (_a = op.specialHeaders) !== null && _a !== void 0 ? _a : [];
|
|
433
|
+
if (!containsIgnoreCase(op.specialHeaders, param.name)) {
|
|
434
|
+
op.specialHeaders.push(param.name);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
// schema
|
|
439
|
+
let schema;
|
|
440
|
+
if (param.type === "header" && param.param.type.kind === "Scalar" && param.param.type.name === "zonedDateTime") {
|
|
441
|
+
// zonedTateTime in header maps to RFC 5322
|
|
442
|
+
schema = this.processDateTimeSchema(param.param.type, param.param.name, true);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
schema = this.processSchema(param.param.type, param.param.name);
|
|
446
|
+
}
|
|
447
|
+
// skip-url-encoding
|
|
448
|
+
let extensions = undefined;
|
|
449
|
+
if ((param.type === "query" || param.type === "path") &&
|
|
450
|
+
param.param.type.kind === "Scalar" &&
|
|
451
|
+
schema instanceof UriSchema) {
|
|
452
|
+
extensions = { "x-ms-skip-url-encoding": true };
|
|
453
|
+
}
|
|
454
|
+
// format if array
|
|
455
|
+
let style = undefined;
|
|
456
|
+
let explode = undefined;
|
|
457
|
+
if (param.param.type.kind === "Model" && isArrayModelType(this.program, param.param.type)) {
|
|
458
|
+
if (param.type === "query") {
|
|
459
|
+
const queryParamOptions = getQueryParamOptions(this.program, param.param);
|
|
460
|
+
switch (queryParamOptions === null || queryParamOptions === void 0 ? void 0 : queryParamOptions.format) {
|
|
461
|
+
case "csv":
|
|
462
|
+
style = SerializationStyle.Simple;
|
|
463
|
+
break;
|
|
464
|
+
case "multi":
|
|
465
|
+
style = SerializationStyle.Form;
|
|
466
|
+
explode = true;
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
else if (param.type === "header") {
|
|
471
|
+
const headerFieldOptions = getHeaderFieldOptions(this.program, param.param);
|
|
472
|
+
switch (headerFieldOptions === null || headerFieldOptions === void 0 ? void 0 : headerFieldOptions.format) {
|
|
473
|
+
case "csv":
|
|
474
|
+
style = SerializationStyle.Simple;
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const nullable = this.isNullableType(param.param.type);
|
|
480
|
+
const parameter = new Parameter(param.param.name, this.getDoc(param.param), schema, {
|
|
481
|
+
summary: this.getSummary(param.param),
|
|
482
|
+
implementation: ImplementationLocation.Method,
|
|
483
|
+
required: !param.param.optional,
|
|
484
|
+
nullable: nullable,
|
|
485
|
+
protocol: {
|
|
486
|
+
http: new HttpParameter(param.type, {
|
|
487
|
+
style: style,
|
|
488
|
+
explode: explode,
|
|
489
|
+
}),
|
|
490
|
+
},
|
|
491
|
+
// clientDefaultValue: this.getDefaultValue(param.param.default),
|
|
492
|
+
language: {
|
|
493
|
+
default: {
|
|
494
|
+
serializedName: param.name,
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
extensions: extensions,
|
|
498
|
+
});
|
|
499
|
+
op.addParameter(parameter);
|
|
500
|
+
this.trackSchemaUsage(schema, { usage: [SchemaContext.Input] });
|
|
501
|
+
if (op.convenienceApi) {
|
|
502
|
+
this.trackSchemaUsage(schema, { usage: [SchemaContext.ConvenienceApi] });
|
|
503
|
+
}
|
|
504
|
+
if (param.name.toLowerCase() === "content-type") {
|
|
505
|
+
let mediaTypes = ["application/json"];
|
|
506
|
+
if (schema instanceof ConstantSchema) {
|
|
507
|
+
mediaTypes = [schema.value.value.toString()];
|
|
508
|
+
}
|
|
509
|
+
else if (schema instanceof SealedChoiceSchema) {
|
|
510
|
+
mediaTypes = schema.choices.map((it) => it.value.toString());
|
|
511
|
+
}
|
|
512
|
+
op.requests[0].protocol.http.mediaTypes = mediaTypes;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
addAcceptHeaderParameter(op, responses) {
|
|
517
|
+
var _a, _b;
|
|
518
|
+
const produces = new Set(["application/json"]);
|
|
519
|
+
for (const resp of responses) {
|
|
520
|
+
if (resp.responses && resp.responses.length > 0) {
|
|
521
|
+
for (const response of resp.responses) {
|
|
522
|
+
(_a = response.body) === null || _a === void 0 ? void 0 : _a.contentTypes.forEach((it) => produces.add(it));
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
const acceptTypes = Array.from(produces.values()).join(", ");
|
|
527
|
+
const acceptSchema = ((_b = this.codeModel.schemas.constants) === null || _b === void 0 ? void 0 : _b.find((it) => it.language.default.name === "accept" && it.value.value === acceptTypes)) ||
|
|
528
|
+
this.codeModel.schemas.add(new ConstantSchema("accept", `Accept: ${acceptTypes}`, {
|
|
529
|
+
valueType: this.stringSchema,
|
|
530
|
+
value: new ConstantValue(acceptTypes),
|
|
531
|
+
}));
|
|
532
|
+
op.addParameter(new Parameter("accept", "Accept header", acceptSchema, {
|
|
533
|
+
implementation: ImplementationLocation.Method,
|
|
534
|
+
origin: "modelerfour:synthesized/accept",
|
|
535
|
+
required: true,
|
|
536
|
+
protocol: {
|
|
537
|
+
http: new HttpParameter(ParameterLocation.Header),
|
|
538
|
+
},
|
|
539
|
+
language: {
|
|
540
|
+
default: {
|
|
541
|
+
serializedName: "accept",
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
}));
|
|
545
|
+
}
|
|
546
|
+
processParameterBody(op, body, parameters) {
|
|
547
|
+
var _a, _b, _c;
|
|
548
|
+
let schema;
|
|
549
|
+
if (body.kind === "ModelProperty" && body.type.kind === "Scalar" && body.type.name === "bytes") {
|
|
550
|
+
//handle for binary body
|
|
551
|
+
schema = this.processBinarySchema(body.name);
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
schema = this.processSchema(body.kind === "Model" ? body : body.type, body.name);
|
|
555
|
+
}
|
|
556
|
+
const parameter = new Parameter(body.name, this.getDoc(body), schema, {
|
|
557
|
+
summary: this.getSummary(body),
|
|
558
|
+
implementation: ImplementationLocation.Method,
|
|
559
|
+
required: body.kind === "Model" || !body.optional,
|
|
560
|
+
protocol: {
|
|
561
|
+
http: new HttpParameter(ParameterLocation.Body),
|
|
562
|
+
},
|
|
563
|
+
// clientDefaultValue: this.getDefaultValue(body.default),
|
|
564
|
+
});
|
|
565
|
+
op.addParameter(parameter);
|
|
566
|
+
this.trackSchemaUsage(schema, { usage: [SchemaContext.Input] });
|
|
567
|
+
if (op.convenienceApi) {
|
|
568
|
+
this.trackSchemaUsage(schema, { usage: [SchemaContext.ConvenienceApi] });
|
|
569
|
+
}
|
|
570
|
+
if (!schema.language.default.name && schema instanceof ObjectSchema) {
|
|
571
|
+
// anonymous model
|
|
572
|
+
if (!parameter.language.default.name) {
|
|
573
|
+
// name the parameter for documentation
|
|
574
|
+
parameter.language.default.name = "request";
|
|
575
|
+
}
|
|
576
|
+
this.trackSchemaUsage(schema, { usage: [SchemaContext.Anonymous] });
|
|
577
|
+
if (op.convenienceApi && op.parameters) {
|
|
578
|
+
op.convenienceApi.requests = [];
|
|
579
|
+
const request = new Request();
|
|
580
|
+
request.parameters = [];
|
|
581
|
+
op.convenienceApi.requests.push(request);
|
|
582
|
+
for (const [key, _] of parameters.properties) {
|
|
583
|
+
const existParameter = op.parameters.find((it) => it.language.default.serializedName === key);
|
|
584
|
+
if (existParameter) {
|
|
585
|
+
// parameter
|
|
586
|
+
if (existParameter.implementation === ImplementationLocation.Method &&
|
|
587
|
+
((_b = (_a = existParameter.origin) === null || _a === void 0 ? void 0 : _a.startsWith("modelerfour:synthesized/")) !== null && _b !== void 0 ? _b : true)) {
|
|
588
|
+
request.parameters.push(new Parameter(existParameter.language.default.name, existParameter.language.default.description, existParameter.schema, {
|
|
589
|
+
language: {
|
|
590
|
+
default: {
|
|
591
|
+
serializedName: existParameter.language.default.serializedName,
|
|
592
|
+
},
|
|
593
|
+
},
|
|
594
|
+
protocol: existParameter.protocol,
|
|
595
|
+
summary: existParameter.summary,
|
|
596
|
+
implementation: ImplementationLocation.Method,
|
|
597
|
+
required: existParameter.required,
|
|
598
|
+
nullable: existParameter.nullable,
|
|
599
|
+
extensions: existParameter.extensions,
|
|
600
|
+
}));
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
// property from anonymous model
|
|
605
|
+
const existBodyProperty = (_c = schema.properties) === null || _c === void 0 ? void 0 : _c.find((it) => it.serializedName === key);
|
|
606
|
+
if (existBodyProperty) {
|
|
607
|
+
request.parameters.push(new VirtualParameter(existBodyProperty.language.default.name, existBodyProperty.language.default.description, existBodyProperty.schema, {
|
|
608
|
+
originalParameter: parameter,
|
|
609
|
+
targetProperty: existBodyProperty,
|
|
610
|
+
language: {
|
|
611
|
+
default: {
|
|
612
|
+
serializedName: existBodyProperty.serializedName,
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
summary: existBodyProperty.summary,
|
|
616
|
+
implementation: ImplementationLocation.Method,
|
|
617
|
+
required: existBodyProperty.required,
|
|
618
|
+
nullable: existBodyProperty.nullable,
|
|
619
|
+
}));
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
request.signatureParameters = request.parameters;
|
|
624
|
+
if (request.signatureParameters.length > 6) {
|
|
625
|
+
// create an option bag
|
|
626
|
+
const name = op.language.default.name + "Options";
|
|
627
|
+
const namespace = body.kind === "Model" ? getNamespace(body) : this.namespace;
|
|
628
|
+
// option bag schema
|
|
629
|
+
const optionBagSchema = this.codeModel.schemas.add(new GroupSchema(name, `Options for ${op.language.default.name} API`, {
|
|
630
|
+
language: {
|
|
631
|
+
default: {
|
|
632
|
+
namespace: namespace,
|
|
633
|
+
},
|
|
634
|
+
java: {
|
|
635
|
+
namespace: getJavaNamespace(namespace),
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
}));
|
|
639
|
+
request.parameters.forEach((it) => {
|
|
640
|
+
optionBagSchema.add(new GroupProperty(it.language.default.name, it.language.default.description, it.schema, {
|
|
641
|
+
originalParameter: [it],
|
|
642
|
+
summary: it.summary,
|
|
643
|
+
required: it.required,
|
|
644
|
+
nullable: it.nullable,
|
|
645
|
+
readOnly: false,
|
|
646
|
+
serializedName: it.language.default.serializedName,
|
|
647
|
+
}));
|
|
648
|
+
});
|
|
649
|
+
this.trackSchemaUsage(optionBagSchema, { usage: [SchemaContext.Input, SchemaContext.ConvenienceApi] });
|
|
650
|
+
// option bag parameter
|
|
651
|
+
const optionBagParameter = new Parameter("options", optionBagSchema.language.default.description, optionBagSchema, {
|
|
652
|
+
implementation: ImplementationLocation.Method,
|
|
653
|
+
required: true,
|
|
654
|
+
nullable: false,
|
|
655
|
+
});
|
|
656
|
+
request.signatureParameters = [optionBagParameter];
|
|
657
|
+
request.parameters.forEach((it) => (it.groupedBy = optionBagParameter));
|
|
658
|
+
request.parameters.push(optionBagParameter);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
findResponseBody(bodyType) {
|
|
664
|
+
// find a type that possibly without http metadata like @statusCode
|
|
665
|
+
return this.getEffectiveSchemaType(bodyType);
|
|
666
|
+
}
|
|
667
|
+
processResponse(op, resp, candidateResponseSchema = undefined) {
|
|
668
|
+
var _a, _b, _c, _d, _e, _f;
|
|
669
|
+
// TODO: what to do if more than 1 response?
|
|
670
|
+
let response;
|
|
671
|
+
let headers = undefined;
|
|
672
|
+
if (resp.responses && resp.responses.length > 0 && resp.responses[0].headers) {
|
|
673
|
+
// headers
|
|
674
|
+
headers = [];
|
|
675
|
+
for (const [key, header] of Object.entries(resp.responses[0].headers)) {
|
|
676
|
+
const schema = this.processSchema(header.type, key);
|
|
677
|
+
headers.push(new HttpHeader(key, schema, {
|
|
678
|
+
language: {
|
|
679
|
+
default: {
|
|
680
|
+
name: key,
|
|
681
|
+
description: this.getDoc(header),
|
|
682
|
+
},
|
|
683
|
+
},
|
|
684
|
+
}));
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
let trackConvenienceApi = (_a = op.convenienceApi) !== null && _a !== void 0 ? _a : false;
|
|
688
|
+
if (resp.responses && resp.responses.length > 0 && resp.responses[0].body) {
|
|
689
|
+
const responseBody = resp.responses[0].body;
|
|
690
|
+
const bodyType = this.findResponseBody(responseBody.type);
|
|
691
|
+
if (bodyType.kind === "Scalar" && bodyType.name === "bytes") {
|
|
692
|
+
// binary
|
|
693
|
+
response = new BinaryResponse({
|
|
694
|
+
protocol: {
|
|
695
|
+
http: {
|
|
696
|
+
statusCodes: [this.getStatusCode(resp.statusCode)],
|
|
697
|
+
headers: headers,
|
|
698
|
+
mediaTypes: responseBody.contentTypes,
|
|
699
|
+
knownMediaType: "binary",
|
|
700
|
+
},
|
|
701
|
+
},
|
|
702
|
+
language: {
|
|
703
|
+
default: {
|
|
704
|
+
name: op.language.default.name + "Response",
|
|
705
|
+
description: this.getResponseDescription(resp),
|
|
706
|
+
},
|
|
707
|
+
},
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
// schema (usually JSON)
|
|
712
|
+
let schema = undefined;
|
|
713
|
+
const verb = (_d = (_c = (_b = op.requests) === null || _b === void 0 ? void 0 : _b[0].protocol) === null || _c === void 0 ? void 0 : _c.http) === null || _d === void 0 ? void 0 : _d.method;
|
|
714
|
+
if (
|
|
715
|
+
// LRO, candidateResponseSchema is Model/ObjectSchema
|
|
716
|
+
candidateResponseSchema &&
|
|
717
|
+
candidateResponseSchema instanceof ObjectSchema &&
|
|
718
|
+
// bodyType is templated Model
|
|
719
|
+
bodyType.kind === "Model" &&
|
|
720
|
+
bodyType.templateMapper &&
|
|
721
|
+
bodyType.templateMapper.args &&
|
|
722
|
+
bodyType.templateMapper.args.length > 0) {
|
|
723
|
+
if (verb === "post") {
|
|
724
|
+
// for LRO ResourceAction, the standard does not require a final type, hence it can be the same as intermediate type
|
|
725
|
+
// https://github.com/microsoft/api-guidelines/blob/vNext/azure/ConsiderationsForServiceDesign.md#long-running-action-operations
|
|
726
|
+
// check if we can use candidateResponseSchema as response schema (instead of the templated Model), for LRO ResourceAction
|
|
727
|
+
if (((_e = candidateResponseSchema.properties) === null || _e === void 0 ? void 0 : _e.length) === bodyType.properties.size) {
|
|
728
|
+
let match = true;
|
|
729
|
+
for (const prop of Array.from(bodyType.properties.values())) {
|
|
730
|
+
const name = this.getName(prop);
|
|
731
|
+
if (!((_f = candidateResponseSchema.properties) === null || _f === void 0 ? void 0 : _f.find((it) => it.language.default.name === name))) {
|
|
732
|
+
match = false;
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
if (match) {
|
|
737
|
+
schema = candidateResponseSchema;
|
|
738
|
+
this.program.trace("typespec-java", `Replace TypeSpec model ${this.getName(bodyType)} with ${candidateResponseSchema.language.default.name}`);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
else if (verb === "delete") {
|
|
743
|
+
// for LRO ResourceDelete, final type will be replaced to "Void" in convenience API, hence do not generate the class
|
|
744
|
+
trackConvenienceApi = false;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
if (!schema) {
|
|
748
|
+
schema = this.processSchema(bodyType, "response");
|
|
749
|
+
}
|
|
750
|
+
response = new SchemaResponse(schema, {
|
|
751
|
+
protocol: {
|
|
752
|
+
http: {
|
|
753
|
+
statusCodes: [this.getStatusCode(resp.statusCode)],
|
|
754
|
+
headers: headers,
|
|
755
|
+
mediaTypes: responseBody.contentTypes,
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
language: {
|
|
759
|
+
default: {
|
|
760
|
+
name: op.language.default.name + "Response",
|
|
761
|
+
description: this.getResponseDescription(resp),
|
|
762
|
+
},
|
|
763
|
+
},
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
// not binary nor schema, usually NoContent
|
|
769
|
+
response = new Response({
|
|
770
|
+
protocol: {
|
|
771
|
+
http: {
|
|
772
|
+
statusCodes: [this.getStatusCode(resp.statusCode)],
|
|
773
|
+
headers: headers,
|
|
774
|
+
},
|
|
775
|
+
},
|
|
776
|
+
language: {
|
|
777
|
+
default: {
|
|
778
|
+
name: op.language.default.name + "Response",
|
|
779
|
+
description: this.getResponseDescription(resp),
|
|
780
|
+
},
|
|
781
|
+
},
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
if (resp.statusCode === "*" || Number(resp.statusCode) / 100 > 3) {
|
|
785
|
+
// TODO: x-ms-error-response
|
|
786
|
+
op.addException(response);
|
|
787
|
+
if (response instanceof SchemaResponse) {
|
|
788
|
+
this.trackSchemaUsage(response.schema, { usage: [SchemaContext.Exception] });
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
op.addResponse(response);
|
|
793
|
+
if (response instanceof SchemaResponse) {
|
|
794
|
+
this.trackSchemaUsage(response.schema, { usage: [SchemaContext.Output] });
|
|
795
|
+
if (trackConvenienceApi) {
|
|
796
|
+
this.trackSchemaUsage(response.schema, { usage: [SchemaContext.ConvenienceApi] });
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
getStatusCode(statusCode) {
|
|
802
|
+
return statusCode === "*" ? "default" : statusCode;
|
|
803
|
+
}
|
|
804
|
+
getResponseDescription(resp) {
|
|
805
|
+
return (resp.description ||
|
|
806
|
+
(resp.statusCode === "*" ? "An unexpected error response" : getStatusCodeDescription(resp.statusCode)) ||
|
|
807
|
+
"");
|
|
808
|
+
}
|
|
809
|
+
processSchema(type, nameHint) {
|
|
810
|
+
return this.schemaCache.process(type, nameHint) || fail("Unable to process schema.");
|
|
811
|
+
}
|
|
812
|
+
processSchemaImpl(type, nameHint) {
|
|
813
|
+
switch (type.kind) {
|
|
814
|
+
case "Intrinsic":
|
|
815
|
+
if (isUnknownType(type)) {
|
|
816
|
+
return this.processAnySchema(type, nameHint);
|
|
817
|
+
}
|
|
818
|
+
else {
|
|
819
|
+
throw new Error(`Unrecognized intrinsic type: '${type.name}'.`);
|
|
820
|
+
}
|
|
821
|
+
case "String":
|
|
822
|
+
return this.processChoiceSchemaForLiteral(type, nameHint);
|
|
823
|
+
case "Number":
|
|
824
|
+
// TODO: float
|
|
825
|
+
return this.processChoiceSchemaForLiteral(type, nameHint);
|
|
826
|
+
case "Boolean":
|
|
827
|
+
return this.processChoiceSchemaForLiteral(type, nameHint);
|
|
828
|
+
case "Enum":
|
|
829
|
+
return this.processChoiceSchema(type, this.getName(type), isFixed(this.program, type));
|
|
830
|
+
case "Union":
|
|
831
|
+
return this.processUnionSchema(type, nameHint);
|
|
832
|
+
case "ModelProperty": {
|
|
833
|
+
let schema = undefined;
|
|
834
|
+
const knownValues = getKnownValues(this.program, type);
|
|
835
|
+
if (knownValues) {
|
|
836
|
+
// use it for extensible enum
|
|
837
|
+
schema = this.processChoiceSchema(knownValues, this.getName(knownValues), false);
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
schema = this.processSchema(type.type, nameHint);
|
|
841
|
+
}
|
|
842
|
+
return this.applyModelPropertyDecorators(type, nameHint, schema);
|
|
843
|
+
}
|
|
844
|
+
case "Scalar":
|
|
845
|
+
return this.processScalar(type, undefined, nameHint);
|
|
846
|
+
case "Model":
|
|
847
|
+
if (isArrayModelType(this.program, type)) {
|
|
848
|
+
return this.processArraySchema(type, nameHint);
|
|
849
|
+
}
|
|
850
|
+
else if (isRecordModelType(this.program, type)) {
|
|
851
|
+
return this.processDictionarySchema(type, nameHint);
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
return this.processObjectSchema(type, this.getName(type));
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
throw new Error(`Unrecognized type: '${type.kind}'.`);
|
|
858
|
+
}
|
|
859
|
+
processScalar(type, formatFromDerived, nameHint) {
|
|
860
|
+
const scalarName = type.name;
|
|
861
|
+
if (this.program.checker.isStdType(type)) {
|
|
862
|
+
switch (scalarName) {
|
|
863
|
+
case "string": {
|
|
864
|
+
const format = formatFromDerived !== null && formatFromDerived !== void 0 ? formatFromDerived : getFormat(this.program, type);
|
|
865
|
+
if (format) {
|
|
866
|
+
return this.processFormatString(type, format, nameHint);
|
|
867
|
+
}
|
|
868
|
+
return this.processStringSchema(type, nameHint);
|
|
869
|
+
}
|
|
870
|
+
case "bytes":
|
|
871
|
+
return this.processByteArraySchema(type, nameHint, false);
|
|
872
|
+
case "boolean":
|
|
873
|
+
return this.processBooleanSchema(type, nameHint);
|
|
874
|
+
case "plainTime":
|
|
875
|
+
return this.processTimeSchema(type, nameHint);
|
|
876
|
+
case "plainDate":
|
|
877
|
+
return this.processDateSchema(type, nameHint);
|
|
878
|
+
case "zonedDateTime":
|
|
879
|
+
return this.processDateTimeSchema(type, nameHint, false);
|
|
880
|
+
case "duration":
|
|
881
|
+
return this.processDurationSchema(type, nameHint);
|
|
882
|
+
case "url":
|
|
883
|
+
return this.processUrlSchema(type, nameHint);
|
|
884
|
+
}
|
|
885
|
+
if (scalarName.startsWith("int") || scalarName.startsWith("uint") || scalarName === "safeint") {
|
|
886
|
+
// integer
|
|
887
|
+
const integerSize = scalarName === "safeint" || scalarName.includes("int64") ? 64 : 32;
|
|
888
|
+
return this.processIntegerSchema(type, nameHint, integerSize);
|
|
889
|
+
}
|
|
890
|
+
else if (scalarName.startsWith("float")) {
|
|
891
|
+
// float point
|
|
892
|
+
return this.processNumberSchema(type, nameHint);
|
|
893
|
+
}
|
|
894
|
+
else {
|
|
895
|
+
throw new Error(`Unrecognized scalar type: '${scalarName}'.`);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
const knownValues = getKnownValues(this.program, type);
|
|
900
|
+
if (knownValues) {
|
|
901
|
+
// use it for extensible enum
|
|
902
|
+
return this.processChoiceSchema(knownValues, this.getName(type), false);
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
if (type.baseScalar) {
|
|
906
|
+
// fallback to baseScalar
|
|
907
|
+
const schema = this.processScalar(type.baseScalar, getFormat(this.program, type), nameHint);
|
|
908
|
+
const doc = getDoc(this.program, type);
|
|
909
|
+
const summary = getSummary(this.program, type);
|
|
910
|
+
if (doc) {
|
|
911
|
+
schema.language.default.description = doc;
|
|
912
|
+
}
|
|
913
|
+
if (summary) {
|
|
914
|
+
schema.summary = summary;
|
|
915
|
+
}
|
|
916
|
+
return schema;
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
throw new Error(`Unrecognized scalar type: '${scalarName}'.`);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
processAnySchema(type, name) {
|
|
925
|
+
return this.codeModel.schemas.add(new AnySchema(this.getDoc(type), {
|
|
926
|
+
summary: this.getSummary(type),
|
|
927
|
+
}));
|
|
928
|
+
}
|
|
929
|
+
processStringSchema(type, name) {
|
|
930
|
+
return this.codeModel.schemas.add(new StringSchema(name, this.getDoc(type), {
|
|
931
|
+
summary: this.getSummary(type),
|
|
932
|
+
}));
|
|
933
|
+
}
|
|
934
|
+
processByteArraySchema(type, name, base64Encoded) {
|
|
935
|
+
return this.codeModel.schemas.add(new ByteArraySchema(name, this.getDoc(type), {
|
|
936
|
+
summary: this.getSummary(type),
|
|
937
|
+
format: base64Encoded ? "base64url" : "byte",
|
|
938
|
+
}));
|
|
939
|
+
}
|
|
940
|
+
processIntegerSchema(type, name, precision) {
|
|
941
|
+
return this.codeModel.schemas.add(new NumberSchema(name, this.getDoc(type), SchemaType.Integer, precision, {
|
|
942
|
+
summary: this.getSummary(type),
|
|
943
|
+
}));
|
|
944
|
+
}
|
|
945
|
+
processNumberSchema(type, name) {
|
|
946
|
+
return this.codeModel.schemas.add(new NumberSchema(name, this.getDoc(type), SchemaType.Number, 64, {
|
|
947
|
+
summary: this.getSummary(type),
|
|
948
|
+
}));
|
|
949
|
+
}
|
|
950
|
+
processBooleanSchema(type, name) {
|
|
951
|
+
return this.codeModel.schemas.add(new BooleanSchema(name, this.getDoc(type), {
|
|
952
|
+
summary: this.getSummary(type),
|
|
953
|
+
}));
|
|
954
|
+
}
|
|
955
|
+
processArraySchema(type, name) {
|
|
956
|
+
const elementSchema = this.processSchema(type.indexer.value, name);
|
|
957
|
+
return this.codeModel.schemas.add(new ArraySchema(name, this.getDoc(type), elementSchema, {
|
|
958
|
+
summary: this.getSummary(type),
|
|
959
|
+
}));
|
|
960
|
+
}
|
|
961
|
+
processDictionarySchema(type, name) {
|
|
962
|
+
const dictSchema = new DictionarySchema(name, this.getDoc(type), null, {
|
|
963
|
+
summary: this.getSummary(type),
|
|
964
|
+
});
|
|
965
|
+
// cache this now before we accidentally recurse on this type.
|
|
966
|
+
this.schemaCache.set(type, dictSchema);
|
|
967
|
+
const elementSchema = this.processSchema(type.indexer.value, name);
|
|
968
|
+
dictSchema.elementType = elementSchema;
|
|
969
|
+
return this.codeModel.schemas.add(dictSchema);
|
|
970
|
+
}
|
|
971
|
+
processChoiceSchema(type, name, sealed) {
|
|
972
|
+
const namespace = getNamespace(type);
|
|
973
|
+
const valueType = typeof type.members.values().next().value.value === "number" ? this.integerSchema : this.stringSchema;
|
|
974
|
+
const choices = [];
|
|
975
|
+
type.members.forEach((it) => { var _a; return choices.push(new ChoiceValue(it.name, this.getDoc(it), (_a = it.value) !== null && _a !== void 0 ? _a : it.name)); });
|
|
976
|
+
if (sealed) {
|
|
977
|
+
return this.codeModel.schemas.add(new SealedChoiceSchema(name, this.getDoc(type), {
|
|
978
|
+
summary: this.getSummary(type),
|
|
979
|
+
choiceType: valueType,
|
|
980
|
+
choices: choices,
|
|
981
|
+
language: {
|
|
982
|
+
default: {
|
|
983
|
+
namespace: namespace,
|
|
984
|
+
},
|
|
985
|
+
java: {
|
|
986
|
+
namespace: getJavaNamespace(namespace),
|
|
987
|
+
},
|
|
988
|
+
},
|
|
989
|
+
}));
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
return this.codeModel.schemas.add(new ChoiceSchema(name, this.getDoc(type), {
|
|
993
|
+
summary: this.getSummary(type),
|
|
994
|
+
choiceType: valueType,
|
|
995
|
+
choices: choices,
|
|
996
|
+
language: {
|
|
997
|
+
default: {
|
|
998
|
+
namespace: namespace,
|
|
999
|
+
},
|
|
1000
|
+
java: {
|
|
1001
|
+
namespace: getJavaNamespace(namespace),
|
|
1002
|
+
},
|
|
1003
|
+
},
|
|
1004
|
+
}));
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
processChoiceSchemaForLiteral(type, name) {
|
|
1008
|
+
const valueType = type.kind === "String" ? this.stringSchema : type.kind === "Boolean" ? this.booleanSchema : this.integerSchema;
|
|
1009
|
+
return this.codeModel.schemas.add(new ConstantSchema(name, this.getDoc(type), {
|
|
1010
|
+
summary: this.getSummary(type),
|
|
1011
|
+
valueType: valueType,
|
|
1012
|
+
value: new ConstantValue(type.value),
|
|
1013
|
+
}));
|
|
1014
|
+
// return this.codeModel.schemas.add(
|
|
1015
|
+
// new ChoiceSchema(name, this.getDoc(type), {
|
|
1016
|
+
// summary: this.getSummary(type),
|
|
1017
|
+
// choiceType: valueType as any,
|
|
1018
|
+
// choices: [new ChoiceValue(type.value.toString(), this.getDoc(type), type.value)]
|
|
1019
|
+
// })
|
|
1020
|
+
// );
|
|
1021
|
+
}
|
|
1022
|
+
processChoiceSchemaForUnion(type, variants, name) {
|
|
1023
|
+
const kind = variants[0].type.kind;
|
|
1024
|
+
const valueType = kind === "String" ? this.stringSchema : kind === "Boolean" ? this.booleanSchema : this.integerSchema;
|
|
1025
|
+
const choices = [];
|
|
1026
|
+
variants.forEach((it) => choices.push(new ChoiceValue(it.type.value.toString(), this.getDoc(it), it.type.value)));
|
|
1027
|
+
const namespace = getNamespace(type);
|
|
1028
|
+
return this.codeModel.schemas.add(new SealedChoiceSchema(name, this.getDoc(type), {
|
|
1029
|
+
summary: this.getSummary(type),
|
|
1030
|
+
choiceType: valueType,
|
|
1031
|
+
choices: choices,
|
|
1032
|
+
language: {
|
|
1033
|
+
default: {
|
|
1034
|
+
namespace: namespace,
|
|
1035
|
+
},
|
|
1036
|
+
java: {
|
|
1037
|
+
namespace: getJavaNamespace(namespace),
|
|
1038
|
+
},
|
|
1039
|
+
},
|
|
1040
|
+
}));
|
|
1041
|
+
}
|
|
1042
|
+
processDateTimeSchema(type, name, rfc1123) {
|
|
1043
|
+
return this.codeModel.schemas.add(new DateTimeSchema(name, this.getDoc(type), {
|
|
1044
|
+
summary: this.getSummary(type),
|
|
1045
|
+
format: rfc1123 ? "date-time-rfc1123" : "date-time",
|
|
1046
|
+
}));
|
|
1047
|
+
}
|
|
1048
|
+
processDateSchema(type, name) {
|
|
1049
|
+
return this.codeModel.schemas.add(new DateSchema(name, this.getDoc(type), {
|
|
1050
|
+
summary: this.getSummary(type),
|
|
1051
|
+
}));
|
|
1052
|
+
}
|
|
1053
|
+
processTimeSchema(type, name) {
|
|
1054
|
+
return this.codeModel.schemas.add(new TimeSchema(name, this.getDoc(type), {
|
|
1055
|
+
summary: this.getSummary(type),
|
|
1056
|
+
}));
|
|
1057
|
+
}
|
|
1058
|
+
processDurationSchema(type, name) {
|
|
1059
|
+
return this.codeModel.schemas.add(new DurationSchema(name, this.getDoc(type), {
|
|
1060
|
+
summary: this.getSummary(type),
|
|
1061
|
+
}));
|
|
1062
|
+
}
|
|
1063
|
+
processUrlSchema(type, name) {
|
|
1064
|
+
return this.codeModel.schemas.add(new UriSchema(name, this.getDoc(type), {
|
|
1065
|
+
summary: this.getSummary(type),
|
|
1066
|
+
}));
|
|
1067
|
+
}
|
|
1068
|
+
processObjectSchema(type, name) {
|
|
1069
|
+
var _a;
|
|
1070
|
+
const namespace = getNamespace(type);
|
|
1071
|
+
const objectSchema = this.codeModel.schemas.add(new ObjectSchema(name, this.getDoc(type), {
|
|
1072
|
+
summary: this.getSummary(type),
|
|
1073
|
+
language: {
|
|
1074
|
+
default: {
|
|
1075
|
+
namespace: namespace,
|
|
1076
|
+
},
|
|
1077
|
+
java: {
|
|
1078
|
+
namespace: getJavaNamespace(namespace),
|
|
1079
|
+
},
|
|
1080
|
+
},
|
|
1081
|
+
}));
|
|
1082
|
+
// cache this now before we accidentally recurse on this type.
|
|
1083
|
+
this.schemaCache.set(type, objectSchema);
|
|
1084
|
+
// discriminator
|
|
1085
|
+
let discriminatorPropertyName = undefined;
|
|
1086
|
+
const discriminator = getDiscriminator(this.program, type);
|
|
1087
|
+
if (discriminator) {
|
|
1088
|
+
discriminatorPropertyName = discriminator.propertyName;
|
|
1089
|
+
objectSchema.discriminator = new Discriminator(new Property(discriminatorPropertyName, discriminatorPropertyName, this.stringSchema, {
|
|
1090
|
+
required: true,
|
|
1091
|
+
serializedName: discriminatorPropertyName,
|
|
1092
|
+
}));
|
|
1093
|
+
}
|
|
1094
|
+
// parent
|
|
1095
|
+
if (type.baseModel) {
|
|
1096
|
+
const parentSchema = this.processSchema(type.baseModel, this.getName(type.baseModel));
|
|
1097
|
+
objectSchema.parents = new Relations();
|
|
1098
|
+
objectSchema.parents.immediate.push(parentSchema);
|
|
1099
|
+
if (parentSchema instanceof ObjectSchema) {
|
|
1100
|
+
pushDistinct(objectSchema.parents.all, parentSchema);
|
|
1101
|
+
parentSchema.children = parentSchema.children || new Relations();
|
|
1102
|
+
pushDistinct(parentSchema.children.immediate, objectSchema);
|
|
1103
|
+
pushDistinct(parentSchema.children.all, objectSchema);
|
|
1104
|
+
if (parentSchema.parents) {
|
|
1105
|
+
pushDistinct(objectSchema.parents.all, ...parentSchema.parents.all);
|
|
1106
|
+
parentSchema.parents.all.forEach((it) => {
|
|
1107
|
+
if (it instanceof ObjectSchema && it.children) {
|
|
1108
|
+
pushDistinct(it.children.all, objectSchema);
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
// value of the discriminator property
|
|
1115
|
+
if (objectSchema.parents) {
|
|
1116
|
+
const parentWithDiscriminator = objectSchema.parents.all.find((it) => it instanceof ObjectSchema && it.discriminator);
|
|
1117
|
+
if (parentWithDiscriminator) {
|
|
1118
|
+
discriminatorPropertyName = parentWithDiscriminator.discriminator.property.serializedName;
|
|
1119
|
+
const discriminatorProperty = Array.from(type.properties.values()).find((it) => it.name === discriminatorPropertyName && it.type.kind === "String");
|
|
1120
|
+
if (discriminatorProperty) {
|
|
1121
|
+
// value of the StringLiteral of the discriminator property
|
|
1122
|
+
objectSchema.discriminatorValue = discriminatorProperty.type.value;
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
// fallback to name of the Model
|
|
1126
|
+
objectSchema.discriminatorValue = name;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
// properties
|
|
1131
|
+
for (const prop of type.properties.values()) {
|
|
1132
|
+
if (prop.name === discriminatorPropertyName || // skip the discriminator property
|
|
1133
|
+
isNeverType(prop.type) || // skip property of type "never"
|
|
1134
|
+
!isPayloadProperty(this.program, prop)) {
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
1137
|
+
objectSchema.addProperty(this.processModelProperty(prop));
|
|
1138
|
+
}
|
|
1139
|
+
// process all children
|
|
1140
|
+
(_a = type.derivedModels) === null || _a === void 0 ? void 0 : _a.filter(modelContainsDerivedModel).forEach((it) => this.processSchema(it, this.getName(it)));
|
|
1141
|
+
return objectSchema;
|
|
1142
|
+
}
|
|
1143
|
+
getEffectiveSchemaType(type) {
|
|
1144
|
+
const program = this.program;
|
|
1145
|
+
function isSchemaProperty(property) {
|
|
1146
|
+
return isPayloadProperty(program, property);
|
|
1147
|
+
}
|
|
1148
|
+
if (type.kind === "Model") {
|
|
1149
|
+
const effective = getEffectiveModelType(program, type, isSchemaProperty);
|
|
1150
|
+
if (effective.name) {
|
|
1151
|
+
return effective;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
return type;
|
|
1155
|
+
}
|
|
1156
|
+
applyModelPropertyDecorators(prop, nameHint, schema) {
|
|
1157
|
+
// if (schema instanceof StringSchema) {
|
|
1158
|
+
// const decorators = {
|
|
1159
|
+
// minLength: getMinLength(this.program, prop),
|
|
1160
|
+
// maxLength: getMaxLength(this.program, prop),
|
|
1161
|
+
// pattern: getPattern(this.program, prop),
|
|
1162
|
+
// };
|
|
1163
|
+
// if (Object.values(decorators).some((it) => it !== undefined)) {
|
|
1164
|
+
// schema = new StringSchema(schema.language.default.name, schema.language.default.description, {
|
|
1165
|
+
// language: schema.language,
|
|
1166
|
+
// summary: schema.summary,
|
|
1167
|
+
// extensions: schema.extensions,
|
|
1168
|
+
// ...decorators,
|
|
1169
|
+
// });
|
|
1170
|
+
// }
|
|
1171
|
+
// } else if (schema instanceof NumberSchema) {
|
|
1172
|
+
// const decorators = {
|
|
1173
|
+
// minimum: getMinValue(this.program, prop),
|
|
1174
|
+
// maximum: getMaxValue(this.program, prop),
|
|
1175
|
+
// };
|
|
1176
|
+
// if (Object.values(decorators).some((it) => it !== undefined)) {
|
|
1177
|
+
// schema = new NumberSchema(
|
|
1178
|
+
// schema.language.default.name,
|
|
1179
|
+
// schema.language.default.description,
|
|
1180
|
+
// schema.type,
|
|
1181
|
+
// schema.precision,
|
|
1182
|
+
// {
|
|
1183
|
+
// language: schema.language,
|
|
1184
|
+
// summary: schema.summary,
|
|
1185
|
+
// extensions: schema.extensions,
|
|
1186
|
+
// ...decorators,
|
|
1187
|
+
// },
|
|
1188
|
+
// );
|
|
1189
|
+
// }
|
|
1190
|
+
// }
|
|
1191
|
+
const format = getFormat(this.program, prop);
|
|
1192
|
+
if (format) {
|
|
1193
|
+
if (prop.type.kind === "Scalar" && schema instanceof StringSchema) {
|
|
1194
|
+
schema = this.processFormatString(prop.type, format, nameHint);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return schema;
|
|
1198
|
+
}
|
|
1199
|
+
processModelProperty(prop) {
|
|
1200
|
+
const schema = this.processSchema(prop, prop.name);
|
|
1201
|
+
const nullable = this.isNullableType(prop.type);
|
|
1202
|
+
return new Property(this.getName(prop), this.getDoc(prop), schema, {
|
|
1203
|
+
summary: this.getSummary(prop),
|
|
1204
|
+
required: !prop.optional,
|
|
1205
|
+
nullable: nullable,
|
|
1206
|
+
readOnly: this.isReadOnly(prop),
|
|
1207
|
+
// clientDefaultValue: this.getDefaultValue(prop.default),
|
|
1208
|
+
serializedName: this.getSerializedName(prop),
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
processFormatString(type, format, nameHint) {
|
|
1212
|
+
switch (format) {
|
|
1213
|
+
case "byte":
|
|
1214
|
+
return this.processByteArraySchema(type, nameHint, true);
|
|
1215
|
+
case "binary":
|
|
1216
|
+
return this.processByteArraySchema(type, nameHint, false);
|
|
1217
|
+
case "date-time":
|
|
1218
|
+
return this.processDateTimeSchema(type, nameHint, false);
|
|
1219
|
+
case "date-time-rfc1123":
|
|
1220
|
+
return this.processDateTimeSchema(type, nameHint, true);
|
|
1221
|
+
case "password":
|
|
1222
|
+
case "url":
|
|
1223
|
+
case "uuid":
|
|
1224
|
+
return this.processStringSchema(type, nameHint);
|
|
1225
|
+
}
|
|
1226
|
+
throw new Error(`Unrecognized string format: '${format}'.`);
|
|
1227
|
+
}
|
|
1228
|
+
processUnionSchema(type, name) {
|
|
1229
|
+
const nonNullVariants = Array.from(type.variants.values()).filter((it) => !isNullType(it.type));
|
|
1230
|
+
if (nonNullVariants.length === 1) {
|
|
1231
|
+
// nullable
|
|
1232
|
+
return this.processSchema(nonNullVariants[0].type, name);
|
|
1233
|
+
}
|
|
1234
|
+
if (this.isSameLiteralTypes(nonNullVariants)) {
|
|
1235
|
+
// enum
|
|
1236
|
+
return this.processChoiceSchemaForUnion(type, nonNullVariants, name);
|
|
1237
|
+
}
|
|
1238
|
+
// TODO: name from typespec-client-generator-core
|
|
1239
|
+
const namespace = getNamespace(type);
|
|
1240
|
+
const unionSchema = new OrSchema(pascalCase(name) + "ModelBase", this.getDoc(type), {
|
|
1241
|
+
summary: this.getSummary(type),
|
|
1242
|
+
});
|
|
1243
|
+
unionSchema.anyOf = [];
|
|
1244
|
+
nonNullVariants.forEach((it) => {
|
|
1245
|
+
const variantName = this.getUnionVariantName(it.type, { depth: 0 });
|
|
1246
|
+
const modelName = variantName + pascalCase(name) + "Model";
|
|
1247
|
+
const propertyName = "value";
|
|
1248
|
+
// these ObjectSchema is not added to codeModel.schemas
|
|
1249
|
+
const objectSchema = new ObjectSchema(modelName, this.getDoc(type), {
|
|
1250
|
+
summary: this.getSummary(type),
|
|
1251
|
+
language: {
|
|
1252
|
+
default: {
|
|
1253
|
+
namespace: namespace,
|
|
1254
|
+
},
|
|
1255
|
+
java: {
|
|
1256
|
+
namespace: getJavaNamespace(namespace),
|
|
1257
|
+
},
|
|
1258
|
+
},
|
|
1259
|
+
});
|
|
1260
|
+
const variantSchema = this.processSchema(it.type, variantName);
|
|
1261
|
+
objectSchema.addProperty(new Property(propertyName, this.getDoc(type), variantSchema, {
|
|
1262
|
+
summary: this.getSummary(type),
|
|
1263
|
+
required: true,
|
|
1264
|
+
nullable: true,
|
|
1265
|
+
readOnly: false,
|
|
1266
|
+
}));
|
|
1267
|
+
unionSchema.anyOf.push(objectSchema);
|
|
1268
|
+
});
|
|
1269
|
+
return this.codeModel.schemas.add(unionSchema);
|
|
1270
|
+
}
|
|
1271
|
+
processBinarySchema(name) {
|
|
1272
|
+
return this.codeModel.schemas.add(new BinarySchema(name));
|
|
1273
|
+
}
|
|
1274
|
+
getUnionVariantName(type, option) {
|
|
1275
|
+
switch (type.kind) {
|
|
1276
|
+
case "Scalar": {
|
|
1277
|
+
const scalarName = type.name;
|
|
1278
|
+
let name = type.name;
|
|
1279
|
+
if (scalarName.startsWith("int") || scalarName.startsWith("uint") || scalarName === "safeint") {
|
|
1280
|
+
name = scalarName === "safeint" || scalarName.includes("int64") ? "Long" : "Integer";
|
|
1281
|
+
}
|
|
1282
|
+
else if (scalarName.startsWith("float")) {
|
|
1283
|
+
name = "Double";
|
|
1284
|
+
}
|
|
1285
|
+
else if (scalarName === "bytes") {
|
|
1286
|
+
name = "ByteArray";
|
|
1287
|
+
}
|
|
1288
|
+
else if (scalarName === "zonedDateTime") {
|
|
1289
|
+
name = "Time";
|
|
1290
|
+
}
|
|
1291
|
+
return pascalCase(name);
|
|
1292
|
+
}
|
|
1293
|
+
case "Enum":
|
|
1294
|
+
return pascalCase(type.name);
|
|
1295
|
+
case "Model":
|
|
1296
|
+
if (isArrayModelType(this.program, type)) {
|
|
1297
|
+
++option.depth;
|
|
1298
|
+
if (option.depth == 1) {
|
|
1299
|
+
return this.getUnionVariantName(type.indexer.value, option) + "List";
|
|
1300
|
+
}
|
|
1301
|
+
else {
|
|
1302
|
+
return "ListOf" + this.getUnionVariantName(type.indexer.value, option);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
else if (isRecordModelType(this.program, type)) {
|
|
1306
|
+
++option.depth;
|
|
1307
|
+
if (option.depth == 1) {
|
|
1308
|
+
return this.getUnionVariantName(type.indexer.value, option) + "Map";
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
return "MapOf" + this.getUnionVariantName(type.indexer.value, option);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
else {
|
|
1315
|
+
return pascalCase(type.name);
|
|
1316
|
+
}
|
|
1317
|
+
default:
|
|
1318
|
+
throw new Error(`Unrecognized type for union variable: '${type.kind}'.`);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
isNullableType(type) {
|
|
1322
|
+
if (type.kind === "Union") {
|
|
1323
|
+
const nullVariants = Array.from(type.variants.values()).filter((it) => isNullType(it.type));
|
|
1324
|
+
return nullVariants.length >= 1;
|
|
1325
|
+
}
|
|
1326
|
+
else {
|
|
1327
|
+
return false;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
isSameLiteralTypes(variants) {
|
|
1331
|
+
const kindSet = new Set(variants.map((it) => it.type.kind));
|
|
1332
|
+
if (kindSet.size === 1) {
|
|
1333
|
+
const kind = kindSet.values().next().value;
|
|
1334
|
+
return kind === "String" || kind === "Number" || kind === "Boolean";
|
|
1335
|
+
}
|
|
1336
|
+
else {
|
|
1337
|
+
return false;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
getDefaultValue(type) {
|
|
1341
|
+
if (type) {
|
|
1342
|
+
switch (type.kind) {
|
|
1343
|
+
case "String":
|
|
1344
|
+
return type.value;
|
|
1345
|
+
case "Number":
|
|
1346
|
+
return type.value;
|
|
1347
|
+
case "Boolean":
|
|
1348
|
+
return type.value;
|
|
1349
|
+
// case "Tuple":
|
|
1350
|
+
// return type.values.map(getDefaultValue);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
return undefined;
|
|
1354
|
+
}
|
|
1355
|
+
getDoc(target) {
|
|
1356
|
+
return getDoc(this.program, target) || "";
|
|
1357
|
+
}
|
|
1358
|
+
getSummary(target) {
|
|
1359
|
+
return getSummary(this.program, target);
|
|
1360
|
+
}
|
|
1361
|
+
getName(target) {
|
|
1362
|
+
// TODO: once getLibraryName API in typespec-client-generator-core can get projected name from language and client, as well as can handle template case, use getLibraryName API
|
|
1363
|
+
const languageProjectedName = getProjectedName(this.program, target, "java");
|
|
1364
|
+
if (languageProjectedName) {
|
|
1365
|
+
return languageProjectedName;
|
|
1366
|
+
}
|
|
1367
|
+
const clientProjectedName = getProjectedName(this.program, target, "client");
|
|
1368
|
+
if (clientProjectedName) {
|
|
1369
|
+
return clientProjectedName;
|
|
1370
|
+
}
|
|
1371
|
+
const friendlyName = getFriendlyName(this.program, target);
|
|
1372
|
+
if (friendlyName) {
|
|
1373
|
+
return friendlyName;
|
|
1374
|
+
}
|
|
1375
|
+
// if no projectedName and friendlyName found, return the name of the target (including special handling for template)
|
|
1376
|
+
if (target.kind === "Model" &&
|
|
1377
|
+
target.templateMapper &&
|
|
1378
|
+
target.templateMapper.args &&
|
|
1379
|
+
target.templateMapper.args.length > 0) {
|
|
1380
|
+
const tspName = getTypeName(target, this.typeNameOptions);
|
|
1381
|
+
const newName = getNameForTemplate(target);
|
|
1382
|
+
this.logWarning(`Rename TypeSpec model '${tspName}' to '${newName}'`);
|
|
1383
|
+
return newName;
|
|
1384
|
+
}
|
|
1385
|
+
return target.name;
|
|
1386
|
+
}
|
|
1387
|
+
getSerializedName(target) {
|
|
1388
|
+
// First get projected name, if not found, return target.name
|
|
1389
|
+
const jsonProjectedName = getProjectedName(this.program, target, "json");
|
|
1390
|
+
if (jsonProjectedName) {
|
|
1391
|
+
return jsonProjectedName;
|
|
1392
|
+
}
|
|
1393
|
+
return target.name;
|
|
1394
|
+
}
|
|
1395
|
+
isReadOnly(target) {
|
|
1396
|
+
// const key = isKey(this.program, target);
|
|
1397
|
+
const segment = getSegment(this.program, target) !== undefined;
|
|
1398
|
+
if (segment) {
|
|
1399
|
+
return true;
|
|
1400
|
+
}
|
|
1401
|
+
else {
|
|
1402
|
+
const visibility = getVisibility(this.program, target);
|
|
1403
|
+
if (visibility) {
|
|
1404
|
+
return (!visibility.includes("write") &&
|
|
1405
|
+
!visibility.includes("create") &&
|
|
1406
|
+
!visibility.includes("update") &&
|
|
1407
|
+
!visibility.includes("delete") &&
|
|
1408
|
+
!visibility.includes("query"));
|
|
1409
|
+
}
|
|
1410
|
+
else {
|
|
1411
|
+
return false;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
getConvenienceApiName(op) {
|
|
1416
|
+
// check @convenienceMethod
|
|
1417
|
+
if (shouldGenerateConvenient(this.dpgContext, op)) {
|
|
1418
|
+
return this.getName(op);
|
|
1419
|
+
}
|
|
1420
|
+
else {
|
|
1421
|
+
return undefined;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
logWarning(msg) {
|
|
1425
|
+
this.program.trace("typespec-java", msg);
|
|
1426
|
+
this.program.reportDiagnostic({
|
|
1427
|
+
code: "typespec-java",
|
|
1428
|
+
severity: "warning",
|
|
1429
|
+
message: msg,
|
|
1430
|
+
target: NoTarget,
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
get stringSchema() {
|
|
1434
|
+
return (this._stringSchema ||
|
|
1435
|
+
(this._stringSchema = this.codeModel.schemas.add(new StringSchema("string", "simple string"))));
|
|
1436
|
+
}
|
|
1437
|
+
get integerSchema() {
|
|
1438
|
+
return (this._integerSchema ||
|
|
1439
|
+
(this._integerSchema = this.codeModel.schemas.add(new NumberSchema("integer", "simple integer", SchemaType.Integer, 64))));
|
|
1440
|
+
}
|
|
1441
|
+
get booleanSchema() {
|
|
1442
|
+
return (this._booleanSchema ||
|
|
1443
|
+
(this._booleanSchema = this.codeModel.schemas.add(new BooleanSchema("boolean", "simple boolean"))));
|
|
1444
|
+
}
|
|
1445
|
+
get binarySchema() {
|
|
1446
|
+
return this._binarySchema || (this._binarySchema = this.codeModel.schemas.add(new BinarySchema("binary")));
|
|
1447
|
+
}
|
|
1448
|
+
get anySchema() {
|
|
1449
|
+
var _a;
|
|
1450
|
+
return (_a = this._anySchema) !== null && _a !== void 0 ? _a : (this._anySchema = this.codeModel.schemas.add(new AnySchema("Anything")));
|
|
1451
|
+
}
|
|
1452
|
+
createApiVersionParameter(serializedName, parameterLocation) {
|
|
1453
|
+
return new Parameter(serializedName, "Version parameter", this.codeModel.schemas.add(new ConstantSchema(serializedName, "API Version", {
|
|
1454
|
+
valueType: this.stringSchema,
|
|
1455
|
+
value: new ConstantValue(""),
|
|
1456
|
+
})), {
|
|
1457
|
+
implementation: ImplementationLocation.Client,
|
|
1458
|
+
origin: originApiVersion,
|
|
1459
|
+
required: true,
|
|
1460
|
+
protocol: {
|
|
1461
|
+
http: new HttpParameter(parameterLocation),
|
|
1462
|
+
},
|
|
1463
|
+
language: {
|
|
1464
|
+
default: {
|
|
1465
|
+
serializedName: serializedName,
|
|
1466
|
+
},
|
|
1467
|
+
},
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
get apiVersionParameter() {
|
|
1471
|
+
return (this._apiVersionParameter ||
|
|
1472
|
+
(this._apiVersionParameter = this.createApiVersionParameter("api-version", ParameterLocation.Query)));
|
|
1473
|
+
}
|
|
1474
|
+
get apiVersionParameterInPath() {
|
|
1475
|
+
return (this._apiVersionParameterInPath ||
|
|
1476
|
+
// TODO: hardcode as "apiVersion", as it is what we get from compiler
|
|
1477
|
+
(this._apiVersionParameterInPath = this.createApiVersionParameter("apiVersion", ParameterLocation.Path)));
|
|
1478
|
+
}
|
|
1479
|
+
propagateSchemaUsage(schema) {
|
|
1480
|
+
var _a;
|
|
1481
|
+
const processedSchemas = new Set();
|
|
1482
|
+
const innerApplySchemaUsage = (schema, schemaUsage) => {
|
|
1483
|
+
this.trackSchemaUsage(schema, schemaUsage);
|
|
1484
|
+
innerPropagateSchemaUsage(schema, schemaUsage);
|
|
1485
|
+
};
|
|
1486
|
+
const innerPropagateSchemaUsage = (schema, schemaUsage) => {
|
|
1487
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
1488
|
+
if (processedSchemas.has(schema)) {
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
processedSchemas.add(schema);
|
|
1492
|
+
if (schema instanceof ObjectSchema) {
|
|
1493
|
+
if (schemaUsage.usage || schemaUsage.serializationFormats) {
|
|
1494
|
+
(_a = schema.properties) === null || _a === void 0 ? void 0 : _a.forEach((p) => innerApplySchemaUsage(p.schema, schemaUsage));
|
|
1495
|
+
(_c = (_b = schema.parents) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.forEach((p) => innerApplySchemaUsage(p, schemaUsage));
|
|
1496
|
+
(_e = (_d = schema.parents) === null || _d === void 0 ? void 0 : _d.immediate) === null || _e === void 0 ? void 0 : _e.forEach((p) => innerApplySchemaUsage(p, schemaUsage));
|
|
1497
|
+
(_g = (_f = schema.children) === null || _f === void 0 ? void 0 : _f.all) === null || _g === void 0 ? void 0 : _g.forEach((c) => innerApplySchemaUsage(c, schemaUsage));
|
|
1498
|
+
(_j = (_h = schema.children) === null || _h === void 0 ? void 0 : _h.immediate) === null || _j === void 0 ? void 0 : _j.forEach((c) => innerApplySchemaUsage(c, schemaUsage));
|
|
1499
|
+
// Object.values(schema.discriminator?.all ?? {}).forEach((d) => {
|
|
1500
|
+
// innerApplySchemaUsage(d, schemaUsage);
|
|
1501
|
+
// });
|
|
1502
|
+
// Object.values(schema.discriminator?.immediate ?? {}).forEach((d) => {
|
|
1503
|
+
// innerApplySchemaUsage(d, schemaUsage);
|
|
1504
|
+
// });
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
else if (schema instanceof DictionarySchema) {
|
|
1508
|
+
innerApplySchemaUsage(schema.elementType, schemaUsage);
|
|
1509
|
+
}
|
|
1510
|
+
else if (schema instanceof ArraySchema) {
|
|
1511
|
+
innerApplySchemaUsage(schema.elementType, schemaUsage);
|
|
1512
|
+
}
|
|
1513
|
+
else if (schema instanceof OrSchema) {
|
|
1514
|
+
(_k = schema.anyOf) === null || _k === void 0 ? void 0 : _k.forEach((it) => innerApplySchemaUsage(it, schemaUsage));
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
// Exclude context that not to be propagated
|
|
1518
|
+
const schemaUsage = {
|
|
1519
|
+
usage: (_a = schema.usage) === null || _a === void 0 ? void 0 : _a.filter((it) => it !== SchemaContext.Paged && it !== SchemaContext.Anonymous),
|
|
1520
|
+
serializationFormats: schema.serializationFormats,
|
|
1521
|
+
};
|
|
1522
|
+
// Propagate the usage of the initial schema itself
|
|
1523
|
+
innerPropagateSchemaUsage(schema, schemaUsage);
|
|
1524
|
+
}
|
|
1525
|
+
trackSchemaUsage(schema, schemaUsage) {
|
|
1526
|
+
if (schema instanceof ObjectSchema ||
|
|
1527
|
+
schema instanceof GroupSchema ||
|
|
1528
|
+
schema instanceof ChoiceSchema ||
|
|
1529
|
+
schema instanceof SealedChoiceSchema ||
|
|
1530
|
+
schema instanceof OrSchema) {
|
|
1531
|
+
if (schemaUsage.usage) {
|
|
1532
|
+
pushDistinct((schema.usage = schema.usage || []), ...schemaUsage.usage);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
else if (schema instanceof DictionarySchema) {
|
|
1536
|
+
this.trackSchemaUsage(schema.elementType, schemaUsage);
|
|
1537
|
+
}
|
|
1538
|
+
else if (schema instanceof ArraySchema) {
|
|
1539
|
+
this.trackSchemaUsage(schema.elementType, schemaUsage);
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
/** Acts as a cache for processing inputs.
|
|
1544
|
+
*
|
|
1545
|
+
* If the input is undefined, the output is always undefined.
|
|
1546
|
+
* for a given input, the process is only ever called once.
|
|
1547
|
+
*
|
|
1548
|
+
*
|
|
1549
|
+
*/
|
|
1550
|
+
class ProcessingCache {
|
|
1551
|
+
constructor(transform) {
|
|
1552
|
+
this.transform = transform;
|
|
1553
|
+
this.results = new Map();
|
|
1554
|
+
}
|
|
1555
|
+
has(original) {
|
|
1556
|
+
return !!original && !!this.results.get(original);
|
|
1557
|
+
}
|
|
1558
|
+
set(original, result) {
|
|
1559
|
+
this.results.set(original, result);
|
|
1560
|
+
return result;
|
|
1561
|
+
}
|
|
1562
|
+
process(original, ...args) {
|
|
1563
|
+
if (original) {
|
|
1564
|
+
const result = this.results.get(original) || this.transform(original, ...args);
|
|
1565
|
+
this.results.set(original, result);
|
|
1566
|
+
return result;
|
|
1567
|
+
}
|
|
1568
|
+
return undefined;
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
/** adds only if the item is not in the collection already
|
|
1572
|
+
*
|
|
1573
|
+
* @note While this isn't very efficient, it doesn't disturb the original
|
|
1574
|
+
* collection, so you won't get inadvertent side effects from using Set, etc.
|
|
1575
|
+
*/
|
|
1576
|
+
function pushDistinct(targetArray, ...items) {
|
|
1577
|
+
for (const i of items) {
|
|
1578
|
+
if (!targetArray.includes(i)) {
|
|
1579
|
+
targetArray.push(i);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
return targetArray;
|
|
1583
|
+
}
|
|
1584
|
+
function getNamespace(type) {
|
|
1585
|
+
let namespaceRef = type.namespace;
|
|
1586
|
+
let namespaceStr = undefined;
|
|
1587
|
+
while (namespaceRef && namespaceRef.name.length !== 0) {
|
|
1588
|
+
namespaceStr = namespaceRef.name + (namespaceStr ? "." + namespaceStr : "");
|
|
1589
|
+
namespaceRef = namespaceRef.namespace;
|
|
1590
|
+
}
|
|
1591
|
+
return namespaceStr;
|
|
1592
|
+
}
|
|
1593
|
+
function getJavaNamespace(namespace) {
|
|
1594
|
+
return namespace ? "com." + namespace.toLowerCase() : undefined;
|
|
1595
|
+
}
|
|
1596
|
+
function modelContainsDerivedModel(model) {
|
|
1597
|
+
return !isTemplateDeclaration(model) && !(isTemplateInstance(model) && model.derivedModels.length === 0);
|
|
1598
|
+
}
|
|
1599
|
+
function isModelReferredInTemplate(template, target) {
|
|
1600
|
+
var _a, _b, _c;
|
|
1601
|
+
return (template === target ||
|
|
1602
|
+
((_c = (_b = (_a = template === null || template === void 0 ? void 0 : template.templateMapper) === null || _a === void 0 ? void 0 : _a.args) === null || _b === void 0 ? void 0 : _b.some((it) => it.kind === "Model" || it.kind === "Union" ? isModelReferredInTemplate(it, target) : false)) !== null && _c !== void 0 ? _c : false));
|
|
1603
|
+
}
|
|
1604
|
+
function getNameForTemplate(target) {
|
|
1605
|
+
switch (target.kind) {
|
|
1606
|
+
case "Model": {
|
|
1607
|
+
let name = target.name;
|
|
1608
|
+
if (target.templateMapper && target.templateMapper.args) {
|
|
1609
|
+
name = name + target.templateMapper.args.map((it) => getNameForTemplate(it)).join("");
|
|
1610
|
+
}
|
|
1611
|
+
return name;
|
|
1612
|
+
}
|
|
1613
|
+
case "String":
|
|
1614
|
+
return target.value;
|
|
1615
|
+
default:
|
|
1616
|
+
return "";
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
function containsIgnoreCase(stringList, str) {
|
|
1620
|
+
return stringList && str ? stringList.findIndex((s) => s.toLowerCase() === str.toLowerCase()) != -1 : false;
|
|
1621
|
+
}
|
|
1622
|
+
function operationContainsJsonMergePatch(op) {
|
|
1623
|
+
for (const param of op.parameters.parameters) {
|
|
1624
|
+
if (param.type === "header" && param.name.toLowerCase() === "content-type") {
|
|
1625
|
+
if (param.param.type.kind === "String" && param.param.type.value === "application/merge-patch+json") {
|
|
1626
|
+
return true;
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
return false;
|
|
1631
|
+
}
|
|
1632
|
+
function pascalCase(name) {
|
|
1633
|
+
if (name.length > 0) {
|
|
1634
|
+
return name[0].toUpperCase() + name.slice(1);
|
|
1635
|
+
}
|
|
1636
|
+
else {
|
|
1637
|
+
return name;
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
function isPayloadProperty(program, property) {
|
|
1641
|
+
const headerInfo = getHeaderFieldName(program, property);
|
|
1642
|
+
const queryInfo = getQueryParamName(program, property);
|
|
1643
|
+
const pathInfo = getPathParamName(program, property);
|
|
1644
|
+
const statusCodeInfo = isStatusCode(program, property);
|
|
1645
|
+
return !(headerInfo || queryInfo || pathInfo || statusCodeInfo);
|
|
1646
|
+
}
|
|
1647
|
+
function getClientApiVersions(client) {
|
|
1648
|
+
var _a;
|
|
1649
|
+
if ((_a = client.globalParameters) === null || _a === void 0 ? void 0 : _a.find((it) => it.origin === originApiVersion)) {
|
|
1650
|
+
return client.apiVersions;
|
|
1651
|
+
}
|
|
1652
|
+
else {
|
|
1653
|
+
return undefined;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
function getServiceVersion(client) {
|
|
1657
|
+
let name = client.language.default.name;
|
|
1658
|
+
let description = name;
|
|
1659
|
+
if (name.endsWith("Client")) {
|
|
1660
|
+
name = name.substring(0, name.length - "Client".length);
|
|
1661
|
+
}
|
|
1662
|
+
else {
|
|
1663
|
+
description = description + "Client";
|
|
1664
|
+
}
|
|
1665
|
+
if (name.endsWith("Service")) {
|
|
1666
|
+
name = name + "Version";
|
|
1667
|
+
}
|
|
1668
|
+
else {
|
|
1669
|
+
name = name + "ServiceVersion";
|
|
1670
|
+
}
|
|
1671
|
+
return new ServiceVersion(name, description);
|
|
1672
|
+
}
|
|
1673
|
+
const specialHeaderNames = new Set(["repeatability-request-id", "repeatability-first-sent"]);
|
|
1674
|
+
const originApiVersion = "modelerfour:synthesized/api-version";
|
|
1675
|
+
//# sourceMappingURL=code-model-builder.js.map
|