@azure-tools/typespec-java 0.19.3 → 0.20.1
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 +5 -16
- package/dist/src/code-model-builder.d.ts.map +1 -1
- package/dist/src/code-model-builder.js +518 -641
- package/dist/src/code-model-builder.js.map +1 -1
- package/dist/src/common/schemas/usage.d.ts +2 -2
- package/dist/src/common/schemas/usage.d.ts.map +1 -1
- package/dist/src/common/schemas/usage.js +2 -2
- package/dist/src/common/schemas/usage.js.map +1 -1
- package/dist/src/operation-utils.d.ts +5 -3
- package/dist/src/operation-utils.d.ts.map +1 -1
- package/dist/src/operation-utils.js +8 -11
- package/dist/src/operation-utils.js.map +1 -1
- package/dist/src/type-utils.d.ts +2 -4
- package/dist/src/type-utils.d.ts.map +1 -1
- package/dist/src/type-utils.js +1 -18
- package/dist/src/type-utils.js.map +1 -1
- package/dist/src/utils.d.ts +1 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +4 -0
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/target/emitter.jar +0 -0
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { AnySchema, ApiVersion, ArraySchema, BinaryResponse, BinarySchema, BooleanSchema, ByteArraySchema, ChoiceValue, DateSchema, DateTimeSchema, DictionarySchema, Discriminator, GroupProperty, GroupSchema, HttpHeader, HttpParameter, ImplementationLocation, KeySecurityScheme, Language, Metadata, NumberSchema, OAuth2SecurityScheme, ObjectSchema, OperationGroup, Parameter, ParameterLocation, Property, Relations, Response, SchemaResponse, SchemaType, Security, SerializationStyle, StringSchema, TimeSchema, UnixTimeSchema, UriSchema, VirtualParameter, } from "@autorest/codemodel";
|
|
2
2
|
import { KnownMediaType } from "@azure-tools/codegen";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { getAddedOnVersions, getVersion } from "@typespec/versioning";
|
|
3
|
+
import { createSdkContext, getAllModels, getClientType, getWireName, isApiVersion, isSdkBuiltInKind, isSdkIntKind, } from "@azure-tools/typespec-client-generator-core";
|
|
4
|
+
import { getDoc, getEffectiveModelType, getNamespaceFullName, getOverloadedOperation, getSummary, getVisibility, isArrayModelType, isRecordModelType, listServices, } from "@typespec/compiler";
|
|
5
|
+
import { Visibility, getAuthentication, getHeaderFieldName, getPathParamName, getQueryParamName, isHeader, isPathParam, isQueryParam, } from "@typespec/http";
|
|
6
|
+
import { getSegment } from "@typespec/rest";
|
|
7
|
+
import { getAddedOnVersions } from "@typespec/versioning";
|
|
9
8
|
import { fail } from "assert";
|
|
10
9
|
import pkg from "lodash";
|
|
11
10
|
import { Client as CodeModelClient } from "./common/client.js";
|
|
@@ -19,10 +18,10 @@ import { DurationSchema } from "./common/schemas/time.js";
|
|
|
19
18
|
import { SchemaContext } from "./common/schemas/usage.js";
|
|
20
19
|
import { createPollOperationDetailsSchema, getFileDetailsSchema } from "./external-schemas.js";
|
|
21
20
|
import { ClientContext } from "./models.js";
|
|
22
|
-
import { ORIGIN_API_VERSION, SPECIAL_HEADER_NAMES, cloneOperationParameter, getServiceVersion, isKnownContentType, isLroNewPollingStrategy, isPayloadProperty, operationIsJsonMergePatch, operationIsMultipart, operationIsMultipleContentTypes, } from "./operation-utils.js";
|
|
21
|
+
import { CONTENT_TYPE_KEY, ORIGIN_API_VERSION, SPECIAL_HEADER_NAMES, cloneOperationParameter, getServiceVersion, isKnownContentType, isLroNewPollingStrategy, isPayloadProperty, operationIsJsonMergePatch, operationIsMultipart, operationIsMultipleContentTypes, } from "./operation-utils.js";
|
|
23
22
|
import { PreNamer } from "./prenamer/prenamer.js";
|
|
24
|
-
import { ProcessingCache, getAccess, getDurationFormatFromSdkType, getNonNullSdkType, getUnionDescription, getUsage,
|
|
25
|
-
import { getNamespace, logWarning, pascalCase, stringArrayContainsIgnoreCase, trace } from "./utils.js";
|
|
23
|
+
import { ProcessingCache, getAccess, getDurationFormatFromSdkType, getNonNullSdkType, getUnionDescription, getUsage, isStable, modelIs, pushDistinct, } from "./type-utils.js";
|
|
24
|
+
import { getNamespace, logWarning, pascalCase, removeClientSuffix, stringArrayContainsIgnoreCase, trace, } from "./utils.js";
|
|
26
25
|
const { isEqual } = pkg;
|
|
27
26
|
export class CodeModelBuilder {
|
|
28
27
|
constructor(program1, context) {
|
|
@@ -77,7 +76,9 @@ export class CodeModelBuilder {
|
|
|
77
76
|
});
|
|
78
77
|
}
|
|
79
78
|
async build() {
|
|
80
|
-
this.sdkContext = await createSdkContext(this.emitterContext, "@azure-tools/typespec-java"
|
|
79
|
+
this.sdkContext = await createSdkContext(this.emitterContext, "@azure-tools/typespec-java", {
|
|
80
|
+
versioning: { previewStringRegex: /$/ },
|
|
81
|
+
}); // include all versions and do the filter by ourselves
|
|
81
82
|
// auth
|
|
82
83
|
// TODO: it is not very likely, but different client could have different auth
|
|
83
84
|
const auth = getAuthentication(this.program, this.serviceNamespace);
|
|
@@ -89,8 +90,8 @@ export class CodeModelBuilder {
|
|
|
89
90
|
this.codeModel.arm = true;
|
|
90
91
|
this.options["group-etag-headers"] = false;
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
-
this.processModels(
|
|
93
|
+
this.processClients();
|
|
94
|
+
this.processModels();
|
|
94
95
|
this.processSchemaUsage();
|
|
95
96
|
if (this.options.namer) {
|
|
96
97
|
this.codeModel = new PreNamer(this.codeModel).init().process();
|
|
@@ -98,64 +99,41 @@ export class CodeModelBuilder {
|
|
|
98
99
|
this.deduplicateSchemaName();
|
|
99
100
|
return this.codeModel;
|
|
100
101
|
}
|
|
101
|
-
|
|
102
|
+
processHostParameters(sdkPathParameters) {
|
|
102
103
|
const hostParameters = [];
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
serializedName: it.name,
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
extensions: {
|
|
128
|
-
// TODO: deprecate this logic of string/url for x-ms-skip-url-encoding
|
|
129
|
-
"x-ms-skip-url-encoding": schema instanceof UriSchema,
|
|
104
|
+
let parameter;
|
|
105
|
+
sdkPathParameters.forEach((arg) => {
|
|
106
|
+
var _a;
|
|
107
|
+
if (arg.isApiVersionParam) {
|
|
108
|
+
parameter = this.createApiVersionParameter(arg.name, ParameterLocation.Uri);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const schema = this.processSchemaFromSdkType(arg.type, arg.name);
|
|
112
|
+
this.trackSchemaUsage(schema, {
|
|
113
|
+
usage: [SchemaContext.Input, SchemaContext.Output /*SchemaContext.Public*/],
|
|
114
|
+
});
|
|
115
|
+
parameter = new Parameter(arg.name, (_a = arg.description) !== null && _a !== void 0 ? _a : "", schema, {
|
|
116
|
+
implementation: ImplementationLocation.Client,
|
|
117
|
+
origin: "modelerfour:synthesized/host",
|
|
118
|
+
required: true,
|
|
119
|
+
protocol: {
|
|
120
|
+
http: new HttpParameter(ParameterLocation.Uri),
|
|
121
|
+
},
|
|
122
|
+
language: {
|
|
123
|
+
default: {
|
|
124
|
+
serializedName: arg.name,
|
|
130
125
|
},
|
|
131
|
-
// // make the logic same as TCGC, which takes the server-side default of host as client-side default
|
|
132
|
-
// clientDefaultValue: getDefaultValue(it.defaultValue),
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
hostParameters.push(this.codeModel.addGlobalParameter(parameter));
|
|
136
|
-
});
|
|
137
|
-
return hostParameters;
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
// use "endpoint"
|
|
141
|
-
hostParameters.push(this.codeModel.addGlobalParameter(new Parameter("endpoint", "Server parameter", this.stringSchema, {
|
|
142
|
-
implementation: ImplementationLocation.Client,
|
|
143
|
-
origin: "modelerfour:synthesized/host",
|
|
144
|
-
required: true,
|
|
145
|
-
protocol: {
|
|
146
|
-
http: new HttpParameter(ParameterLocation.Uri),
|
|
147
|
-
},
|
|
148
|
-
language: {
|
|
149
|
-
default: {
|
|
150
|
-
serializedName: "endpoint",
|
|
151
126
|
},
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
127
|
+
// TODO: deprecate this logic of string/url for x-ms-skip-url-encoding
|
|
128
|
+
extensions: {
|
|
129
|
+
"x-ms-skip-url-encoding": schema instanceof UriSchema,
|
|
130
|
+
},
|
|
131
|
+
clientDefaultValue: arg.clientDefaultValue,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
hostParameters.push(this.codeModel.addGlobalParameter(parameter));
|
|
135
|
+
});
|
|
136
|
+
return hostParameters;
|
|
159
137
|
}
|
|
160
138
|
processAuth(auth) {
|
|
161
139
|
const securitySchemes = [];
|
|
@@ -210,16 +188,7 @@ export class CodeModelBuilder {
|
|
|
210
188
|
isBranded() {
|
|
211
189
|
return !this.options["flavor"] || this.options["flavor"].toLocaleLowerCase() === "azure";
|
|
212
190
|
}
|
|
213
|
-
|
|
214
|
-
const access = getAccess(operation);
|
|
215
|
-
if (access) {
|
|
216
|
-
return access === "internal";
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
processModels(clients) {
|
|
191
|
+
processModels() {
|
|
223
192
|
const processedSdkModels = new Set();
|
|
224
193
|
// lambda to mark model as public
|
|
225
194
|
const modelAsPublic = (model) => {
|
|
@@ -305,33 +274,37 @@ export class CodeModelBuilder {
|
|
|
305
274
|
schemaUsage.splice(index, 1);
|
|
306
275
|
}
|
|
307
276
|
}
|
|
308
|
-
// Internal on
|
|
309
|
-
if (schemaUsage === null || schemaUsage === void 0 ? void 0 : schemaUsage.includes(SchemaContext.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
277
|
+
// Internal on PublicSpread, but Public takes precedence
|
|
278
|
+
if (schemaUsage === null || schemaUsage === void 0 ? void 0 : schemaUsage.includes(SchemaContext.PublicSpread)) {
|
|
279
|
+
// remove PublicSpread as it now served its purpose
|
|
280
|
+
schemaUsage.splice(schemaUsage.indexOf(SchemaContext.PublicSpread), 1);
|
|
281
|
+
// Public would override PublicSpread, hence do nothing if this schema is Public
|
|
282
|
+
if (!(schemaUsage === null || schemaUsage === void 0 ? void 0 : schemaUsage.includes(SchemaContext.Public))) {
|
|
283
|
+
// set the model as Internal, so that it is not exposed to user
|
|
284
|
+
if (!schemaUsage.includes(SchemaContext.Internal)) {
|
|
285
|
+
schemaUsage.push(SchemaContext.Internal);
|
|
286
|
+
}
|
|
313
287
|
}
|
|
314
288
|
}
|
|
315
289
|
}
|
|
316
290
|
}
|
|
317
291
|
processClients() {
|
|
318
|
-
var _a, _b;
|
|
319
|
-
const clients = listClients(this.sdkContext);
|
|
292
|
+
var _a, _b, _c;
|
|
320
293
|
// preprocess group-etag-headers
|
|
321
294
|
this.options["group-etag-headers"] = (_a = this.options["group-etag-headers"]) !== null && _a !== void 0 ? _a : true;
|
|
322
|
-
|
|
295
|
+
const sdkPackage = this.sdkContext.sdkPackage;
|
|
296
|
+
for (const client of sdkPackage.clients) {
|
|
323
297
|
let clientName = client.name;
|
|
324
|
-
let clientSubNamespace = undefined;
|
|
325
298
|
let javaNamespace = this.getJavaNamespace(this.namespace);
|
|
326
299
|
const clientFullName = client.name;
|
|
327
300
|
const clientNameSegments = clientFullName.split(".");
|
|
328
301
|
if (clientNameSegments.length > 1) {
|
|
329
302
|
clientName = clientNameSegments.at(-1);
|
|
330
|
-
clientSubNamespace = clientNameSegments.slice(0, -1).join(".");
|
|
303
|
+
const clientSubNamespace = clientNameSegments.slice(0, -1).join(".");
|
|
331
304
|
javaNamespace = this.getJavaNamespace(this.namespace + "." + clientSubNamespace);
|
|
332
305
|
}
|
|
333
|
-
const codeModelClient = new CodeModelClient(clientName,
|
|
334
|
-
summary:
|
|
306
|
+
const codeModelClient = new CodeModelClient(clientName, (_b = client.details) !== null && _b !== void 0 ? _b : "", {
|
|
307
|
+
summary: client.description,
|
|
335
308
|
language: {
|
|
336
309
|
default: {
|
|
337
310
|
namespace: this.namespace,
|
|
@@ -345,111 +318,144 @@ export class CodeModelBuilder {
|
|
|
345
318
|
});
|
|
346
319
|
codeModelClient.crossLanguageDefinitionId = client.crossLanguageDefinitionId;
|
|
347
320
|
// versioning
|
|
348
|
-
const
|
|
349
|
-
if (
|
|
350
|
-
// @versioned in versioning
|
|
321
|
+
const versions = client.apiVersions;
|
|
322
|
+
if (versions && versions.length > 0) {
|
|
351
323
|
if (!this.sdkContext.apiVersion || ["all", "latest"].includes(this.sdkContext.apiVersion)) {
|
|
352
|
-
this.apiVersion =
|
|
324
|
+
this.apiVersion = versions[versions.length - 1];
|
|
353
325
|
}
|
|
354
326
|
else {
|
|
355
|
-
this.apiVersion =
|
|
327
|
+
this.apiVersion = versions.find((it) => it === this.sdkContext.apiVersion);
|
|
356
328
|
if (!this.apiVersion) {
|
|
357
329
|
throw new Error("Unrecognized api-version: " + this.sdkContext.apiVersion);
|
|
358
330
|
}
|
|
359
331
|
}
|
|
360
332
|
codeModelClient.apiVersions = [];
|
|
361
|
-
for (const version of this.getFilteredApiVersions(this.apiVersion,
|
|
333
|
+
for (const version of this.getFilteredApiVersions(this.apiVersion, versions, this.options["service-version-exclude-preview"])) {
|
|
362
334
|
const apiVersion = new ApiVersion();
|
|
363
|
-
apiVersion.version = version
|
|
335
|
+
apiVersion.version = version;
|
|
364
336
|
codeModelClient.apiVersions.push(apiVersion);
|
|
365
337
|
}
|
|
366
338
|
}
|
|
367
|
-
//
|
|
339
|
+
// client initialization
|
|
368
340
|
let baseUri = "{endpoint}";
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
341
|
+
let hostParameters = [];
|
|
342
|
+
client.initialization.properties.forEach((initializationProperty) => {
|
|
343
|
+
if (initializationProperty.kind === "endpoint") {
|
|
344
|
+
let sdkPathParameters = [];
|
|
345
|
+
if (initializationProperty.type.kind === "union") {
|
|
346
|
+
if (initializationProperty.type.values.length === 2) {
|
|
347
|
+
// only get the sdkPathParameters from the endpoint whose serverUrl is not {"endpoint"}
|
|
348
|
+
for (const endpointType of initializationProperty.type.values) {
|
|
349
|
+
if (endpointType.kind === "endpoint" && endpointType.serverUrl !== "{endpoint}") {
|
|
350
|
+
sdkPathParameters = endpointType.templateArguments;
|
|
351
|
+
baseUri = endpointType.serverUrl;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
else if (initializationProperty.type.values.length > 2) {
|
|
356
|
+
throw new Error("Multiple server url defined for one client is not supported yet.");
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else if (initializationProperty.type.kind === "endpoint") {
|
|
360
|
+
sdkPathParameters = initializationProperty.type.templateArguments;
|
|
361
|
+
baseUri = initializationProperty.type.serverUrl;
|
|
362
|
+
}
|
|
363
|
+
hostParameters = this.processHostParameters(sdkPathParameters);
|
|
364
|
+
codeModelClient.addGlobalParameters(hostParameters);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
375
367
|
const clientContext = new ClientContext(baseUri, hostParameters, codeModelClient.globalParameters, codeModelClient.apiVersions);
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const
|
|
368
|
+
// preprocess operation groups and operations
|
|
369
|
+
// operations without operation group
|
|
370
|
+
const serviceMethodsWithoutSubClient = this.listServiceMethodsUnderClient(client);
|
|
379
371
|
let codeModelGroup = new OperationGroup("");
|
|
380
|
-
for (const
|
|
381
|
-
if (!this.needToSkipProcessingOperation(
|
|
382
|
-
codeModelGroup.addOperation(this.processOperation(
|
|
372
|
+
for (const serviceMethod of serviceMethodsWithoutSubClient) {
|
|
373
|
+
if (!this.needToSkipProcessingOperation(serviceMethod.__raw, clientContext)) {
|
|
374
|
+
codeModelGroup.addOperation(this.processOperation(serviceMethod, clientContext, ""));
|
|
383
375
|
}
|
|
384
376
|
}
|
|
385
|
-
if (((
|
|
377
|
+
if (((_c = codeModelGroup.operations) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
386
378
|
codeModelClient.operationGroups.push(codeModelGroup);
|
|
387
379
|
}
|
|
388
|
-
|
|
389
|
-
|
|
380
|
+
// operations under operation groups
|
|
381
|
+
const subClients = this.listSubClientsUnderClient(client, true, true);
|
|
382
|
+
for (const subClient of subClients) {
|
|
383
|
+
const serviceMethods = this.listServiceMethodsUnderClient(subClient);
|
|
390
384
|
// operation group with no operation is skipped
|
|
391
|
-
if (
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
operationGroupPath = operationGroupPath.slice((clientSubNamespace + ".").length);
|
|
397
|
-
}
|
|
398
|
-
const groupPath = operationGroupPath.split(".");
|
|
399
|
-
let operationGroupName;
|
|
400
|
-
if (groupPath.length > 1) {
|
|
401
|
-
// remove ClientName
|
|
402
|
-
operationGroupName = groupPath.slice(1).join("");
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
operationGroupName = groupPath[0];
|
|
406
|
-
}
|
|
407
|
-
codeModelGroup = new OperationGroup(operationGroupName);
|
|
408
|
-
for (const operation of operations) {
|
|
409
|
-
if (!this.needToSkipProcessingOperation(operation, clientContext)) {
|
|
410
|
-
codeModelGroup.addOperation(this.processOperation(operationGroupName, operation, clientContext));
|
|
385
|
+
if (serviceMethods.length > 0) {
|
|
386
|
+
codeModelGroup = new OperationGroup(subClient.name);
|
|
387
|
+
for (const serviceMethod of serviceMethods) {
|
|
388
|
+
if (!this.needToSkipProcessingOperation(serviceMethod.__raw, clientContext)) {
|
|
389
|
+
codeModelGroup.addOperation(this.processOperation(serviceMethod, clientContext, subClient.name));
|
|
411
390
|
}
|
|
412
391
|
}
|
|
413
392
|
codeModelClient.operationGroups.push(codeModelGroup);
|
|
414
393
|
}
|
|
415
394
|
}
|
|
416
395
|
this.codeModel.clients.push(codeModelClient);
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
396
|
+
// postprocess for ServiceVersion
|
|
397
|
+
let apiVersionSameForAllClients = true;
|
|
398
|
+
let sharedApiVersions = undefined;
|
|
399
|
+
for (const client of this.codeModel.clients) {
|
|
400
|
+
const apiVersions = client.apiVersions;
|
|
401
|
+
if (!apiVersions) {
|
|
402
|
+
// client does not have apiVersions
|
|
403
|
+
apiVersionSameForAllClients = false;
|
|
404
|
+
}
|
|
405
|
+
else if (!sharedApiVersions) {
|
|
406
|
+
// first client, set it to sharedApiVersions
|
|
407
|
+
sharedApiVersions = apiVersions;
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
apiVersionSameForAllClients = isEqual(sharedApiVersions, apiVersions);
|
|
411
|
+
}
|
|
412
|
+
if (!apiVersionSameForAllClients) {
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
426
415
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
416
|
+
if (apiVersionSameForAllClients) {
|
|
417
|
+
const serviceVersion = getServiceVersion(this.codeModel);
|
|
418
|
+
for (const client of this.codeModel.clients) {
|
|
419
|
+
client.serviceVersion = serviceVersion;
|
|
420
|
+
}
|
|
430
421
|
}
|
|
431
422
|
else {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
423
|
+
for (const client of this.codeModel.clients) {
|
|
424
|
+
const apiVersions = client.apiVersions;
|
|
425
|
+
if (apiVersions) {
|
|
426
|
+
client.serviceVersion = getServiceVersion(client);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
436
429
|
}
|
|
437
430
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
431
|
+
}
|
|
432
|
+
listSubClientsUnderClient(client, includeNestedOperationGroups, isRootClient) {
|
|
433
|
+
const operationGroups = [];
|
|
434
|
+
for (const method of client.methods) {
|
|
435
|
+
if (method.kind === "clientaccessor") {
|
|
436
|
+
const subClient = method.response;
|
|
437
|
+
if (!isRootClient) {
|
|
438
|
+
// if it is not root client, append the parent client's name
|
|
439
|
+
subClient.name = removeClientSuffix(client.name) + removeClientSuffix(pascalCase(subClient.name));
|
|
440
|
+
}
|
|
441
|
+
operationGroups.push(subClient);
|
|
442
|
+
if (includeNestedOperationGroups) {
|
|
443
|
+
for (const operationGroup of this.listSubClientsUnderClient(subClient, includeNestedOperationGroups, false)) {
|
|
444
|
+
operationGroups.push(operationGroup);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
442
447
|
}
|
|
443
448
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
449
|
+
return operationGroups;
|
|
450
|
+
}
|
|
451
|
+
listServiceMethodsUnderClient(client) {
|
|
452
|
+
const methods = [];
|
|
453
|
+
for (const method of client.methods) {
|
|
454
|
+
if (method.kind !== "clientaccessor") {
|
|
455
|
+
methods.push(method);
|
|
450
456
|
}
|
|
451
457
|
}
|
|
452
|
-
return
|
|
458
|
+
return methods;
|
|
453
459
|
}
|
|
454
460
|
/**
|
|
455
461
|
* Filter api-versions for "ServiceVersion".
|
|
@@ -467,20 +473,12 @@ export class CodeModelBuilder {
|
|
|
467
473
|
.slice(0, versions.indexOf(pinnedApiVersion) + 1)
|
|
468
474
|
.filter((version) => !excludePreview || !isStable(pinnedApiVersion) || isStable(version));
|
|
469
475
|
}
|
|
470
|
-
/**
|
|
471
|
-
* `@armProviderNamespace` currently will add a default server if not defined globally:
|
|
472
|
-
* https://github.com/Azure/typespec-azure/blob/8b8d7c05f168d9305a09691c4fedcb88f4a57652/packages/typespec-azure-resource-manager/src/namespace.ts#L121-L128
|
|
473
|
-
* TODO: if the synthesized server has the right hostParameter, we can use that instead
|
|
474
|
-
*
|
|
475
|
-
* @param server returned by getServers
|
|
476
|
-
* @returns whether it's synthesized by `@armProviderNamespace`
|
|
477
|
-
*/
|
|
478
|
-
isArmSynthesizedServer(server) {
|
|
479
|
-
return this.isArm() && (!server.parameters || server.parameters.size == 0);
|
|
480
|
-
}
|
|
481
476
|
needToSkipProcessingOperation(operation, clientContext) {
|
|
482
477
|
// don't generate protocol and convenience method for overloaded operations
|
|
483
478
|
// issue link: https://github.com/Azure/autorest.java/issues/1958#issuecomment-1562558219 we will support generate overload methods for non-union type in future (TODO issue: https://github.com/Azure/autorest.java/issues/2160)
|
|
479
|
+
if (operation === undefined) {
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
484
482
|
if (getOverloadedOperation(this.program, operation)) {
|
|
485
483
|
this.trace(`Operation '${operation.name}' is temporary skipped, as it is an overloaded operation`);
|
|
486
484
|
return true;
|
|
@@ -493,9 +491,9 @@ export class CodeModelBuilder {
|
|
|
493
491
|
supportsAdvancedVersioning() {
|
|
494
492
|
return Boolean(this.options["advanced-versioning"]);
|
|
495
493
|
}
|
|
496
|
-
getOperationExample(
|
|
494
|
+
getOperationExample(sdkMethod) {
|
|
497
495
|
var _a, _b;
|
|
498
|
-
const httpOperationExamples =
|
|
496
|
+
const httpOperationExamples = sdkMethod.operation.examples;
|
|
499
497
|
if (httpOperationExamples && httpOperationExamples.length > 0) {
|
|
500
498
|
const operationExamples = {};
|
|
501
499
|
for (const example of httpOperationExamples) {
|
|
@@ -503,8 +501,7 @@ export class CodeModelBuilder {
|
|
|
503
501
|
// example.filePath is relative path from sdkContext.examplesDir
|
|
504
502
|
// this is not a URL format (file:// or https://)
|
|
505
503
|
operationExample["x-ms-original-file"] = example.filePath;
|
|
506
|
-
operationExamples[(_b = (_a = operationExample.title) !== null && _a !== void 0 ? _a : operationExample.operationId) !== null && _b !== void 0 ? _b :
|
|
507
|
-
operationExample;
|
|
504
|
+
operationExamples[(_b = (_a = operationExample.title) !== null && _a !== void 0 ? _a : operationExample.operationId) !== null && _b !== void 0 ? _b : sdkMethod.name] = operationExample;
|
|
508
505
|
}
|
|
509
506
|
return operationExamples;
|
|
510
507
|
}
|
|
@@ -512,58 +509,47 @@ export class CodeModelBuilder {
|
|
|
512
509
|
return undefined;
|
|
513
510
|
}
|
|
514
511
|
}
|
|
515
|
-
processOperation(
|
|
512
|
+
processOperation(sdkMethod, clientContext, groupName) {
|
|
516
513
|
var _a;
|
|
517
|
-
const
|
|
514
|
+
const operationName = sdkMethod.name;
|
|
515
|
+
const httpOperation = sdkMethod.operation;
|
|
516
|
+
const operationId = groupName ? `${groupName}_${operationName}` : `${operationName}`;
|
|
518
517
|
const operationGroup = this.codeModel.getOperationGroup(groupName);
|
|
519
|
-
const
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
operationId: opId,
|
|
524
|
-
summary: this.getSummary(operation),
|
|
518
|
+
const operationExamples = this.getOperationExample(sdkMethod);
|
|
519
|
+
const codeModelOperation = new CodeModelOperation(operationName, (_a = sdkMethod.details) !== null && _a !== void 0 ? _a : "", {
|
|
520
|
+
operationId: operationId,
|
|
521
|
+
summary: sdkMethod.description,
|
|
525
522
|
extensions: {
|
|
526
523
|
"x-ms-examples": operationExamples,
|
|
527
524
|
},
|
|
528
525
|
});
|
|
529
|
-
codeModelOperation.crossLanguageDefinitionId =
|
|
530
|
-
codeModelOperation.internalApi =
|
|
531
|
-
const convenienceApiName = this.getConvenienceApiName(
|
|
532
|
-
let generateConvenienceApi =
|
|
533
|
-
let generateProtocolApi =
|
|
526
|
+
codeModelOperation.crossLanguageDefinitionId = sdkMethod.crossLanguageDefintionId;
|
|
527
|
+
codeModelOperation.internalApi = sdkMethod.access === "internal";
|
|
528
|
+
const convenienceApiName = this.getConvenienceApiName(sdkMethod);
|
|
529
|
+
let generateConvenienceApi = sdkMethod.generateConvenient;
|
|
530
|
+
let generateProtocolApi = sdkMethod.generateProtocol;
|
|
534
531
|
let apiComment = undefined;
|
|
535
532
|
if (generateConvenienceApi) {
|
|
536
533
|
// check if the convenience API need to be disabled for some special cases
|
|
537
|
-
if (operationIsMultipart(
|
|
534
|
+
if (operationIsMultipart(httpOperation)) {
|
|
538
535
|
// do not generate protocol method for multipart/form-data, as it be very hard for user to prepare the request body as BinaryData
|
|
539
536
|
generateProtocolApi = false;
|
|
540
|
-
apiComment = `Protocol API requires serialization of parts with content-disposition and data, as operation '${
|
|
537
|
+
apiComment = `Protocol API requires serialization of parts with content-disposition and data, as operation '${operationName}' is 'multipart/form-data'`;
|
|
541
538
|
this.logWarning(apiComment);
|
|
542
539
|
}
|
|
543
|
-
else if (operationIsMultipleContentTypes(
|
|
540
|
+
else if (operationIsMultipleContentTypes(httpOperation)) {
|
|
544
541
|
// and multiple content types
|
|
545
542
|
// issue link: https://github.com/Azure/autorest.java/issues/1958#issuecomment-1562558219
|
|
546
543
|
generateConvenienceApi = false;
|
|
547
|
-
apiComment = `Convenience API is not generated, as operation '${
|
|
544
|
+
apiComment = `Convenience API is not generated, as operation '${operationName}' is multiple content-type`;
|
|
548
545
|
this.logWarning(apiComment);
|
|
549
546
|
}
|
|
550
|
-
else if (operationIsJsonMergePatch(
|
|
547
|
+
else if (operationIsJsonMergePatch(httpOperation) && this.options["stream-style-serialization"] === false) {
|
|
551
548
|
// do not generate convenient method for json merge patch operation if stream-style-serialization is not enabled
|
|
552
549
|
generateConvenienceApi = false;
|
|
553
|
-
apiComment = `Convenience API is not generated, as operation '${
|
|
550
|
+
apiComment = `Convenience API is not generated, as operation '${operationName}' is 'application/merge-patch+json' and stream-style-serialization is not enabled`;
|
|
554
551
|
this.logWarning(apiComment);
|
|
555
552
|
}
|
|
556
|
-
// else {
|
|
557
|
-
// const union = operationRefersUnion(this.program, op, this.typeUnionRefCache);
|
|
558
|
-
// if (union) {
|
|
559
|
-
// // and Union
|
|
560
|
-
// generateConvenienceApi = false;
|
|
561
|
-
// apiComment = `Convenience API is not generated, as operation '${
|
|
562
|
-
// op.operation.name
|
|
563
|
-
// }' refers Union '${getUnionDescription(union, this.typeNameOptions)}'`;
|
|
564
|
-
// this.logWarning(apiComment);
|
|
565
|
-
// }
|
|
566
|
-
// }
|
|
567
553
|
}
|
|
568
554
|
if (generateConvenienceApi && convenienceApiName) {
|
|
569
555
|
codeModelOperation.convenienceApi = new ConvenienceApi(convenienceApiName);
|
|
@@ -577,75 +563,76 @@ export class CodeModelBuilder {
|
|
|
577
563
|
codeModelOperation.addRequest(new Request({
|
|
578
564
|
protocol: {
|
|
579
565
|
http: {
|
|
580
|
-
path:
|
|
581
|
-
method:
|
|
566
|
+
path: httpOperation.path,
|
|
567
|
+
method: httpOperation.verb,
|
|
582
568
|
uri: clientContext.baseUri,
|
|
583
569
|
},
|
|
584
570
|
},
|
|
585
571
|
}));
|
|
586
572
|
// host
|
|
587
573
|
clientContext.hostParameters.forEach((it) => codeModelOperation.addParameter(it));
|
|
588
|
-
// parameters
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
this.processParameterBody(codeModelOperation, op, op.parameters.body.property);
|
|
574
|
+
// path/query/header parameters
|
|
575
|
+
for (const param of httpOperation.parameters) {
|
|
576
|
+
// if it's paged operation with request body, skip content-type header added by TCGC, as next link call should not have content type header
|
|
577
|
+
if ((sdkMethod.kind === "paging" || sdkMethod.kind === "lropaging") &&
|
|
578
|
+
httpOperation.bodyParam &&
|
|
579
|
+
param.kind === "header") {
|
|
580
|
+
if (param.serializedName.toLocaleLowerCase() === CONTENT_TYPE_KEY) {
|
|
581
|
+
continue;
|
|
597
582
|
}
|
|
598
583
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
if (resourceType && op.responses && op.responses.length > 0) {
|
|
605
|
-
const resp = op.responses[0];
|
|
606
|
-
if (resp.responses && resp.responses.length > 0 && resp.responses[0].body) {
|
|
607
|
-
const responseBody = resp.responses[0].body;
|
|
608
|
-
const bodyTypeInResponse = this.findResponseBody(responseBody.type);
|
|
609
|
-
// response body type is resource type, and request body type (if templated) contains resource type
|
|
610
|
-
if (bodyTypeInResponse === resourceType && isModelReferredInTemplate(bodyType, resourceType)) {
|
|
611
|
-
bodyType = resourceType;
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
this.processParameterBody(codeModelOperation, op, bodyType);
|
|
584
|
+
// if the request body is optional, skip content-type header added by TCGC
|
|
585
|
+
// TODO: add optional content type to code-model, and support optional content-type from codegen, https://github.com/Azure/autorest.java/issues/2930
|
|
586
|
+
if (httpOperation.bodyParam && httpOperation.bodyParam.optional) {
|
|
587
|
+
if (param.serializedName.toLocaleLowerCase() === CONTENT_TYPE_KEY) {
|
|
588
|
+
continue;
|
|
616
589
|
}
|
|
617
590
|
}
|
|
591
|
+
this.processParameter(codeModelOperation, param, clientContext);
|
|
592
|
+
}
|
|
593
|
+
// body
|
|
594
|
+
if (httpOperation.bodyParam && httpOperation.__raw && httpOperation.bodyParam.type.__raw) {
|
|
595
|
+
this.processParameterBody(codeModelOperation, httpOperation.__raw, httpOperation, httpOperation.bodyParam);
|
|
618
596
|
}
|
|
619
597
|
// group ETag header parameters, if exists
|
|
620
598
|
if (this.options["group-etag-headers"]) {
|
|
621
|
-
this.processEtagHeaderParameters(codeModelOperation,
|
|
599
|
+
this.processEtagHeaderParameters(codeModelOperation, sdkMethod.operation);
|
|
622
600
|
}
|
|
623
601
|
// lro metadata
|
|
624
|
-
|
|
602
|
+
let lroMetadata = new LongRunningMetadata(false);
|
|
603
|
+
if (sdkMethod.kind === "lro" || sdkMethod.kind === "lropaging") {
|
|
604
|
+
lroMetadata = this.processLroMetadata(codeModelOperation, sdkMethod);
|
|
605
|
+
}
|
|
625
606
|
// responses
|
|
626
|
-
|
|
607
|
+
for (const [code, response] of sdkMethod.operation.responses) {
|
|
608
|
+
this.processResponse(codeModelOperation, code, response, lroMetadata.longRunning, false);
|
|
609
|
+
}
|
|
610
|
+
// exception
|
|
611
|
+
for (const [code, response] of sdkMethod.operation.exceptions) {
|
|
612
|
+
this.processResponse(codeModelOperation, code, response, lroMetadata.longRunning, true);
|
|
613
|
+
}
|
|
627
614
|
// check for paged
|
|
628
|
-
this.processRouteForPaged(codeModelOperation,
|
|
615
|
+
this.processRouteForPaged(codeModelOperation, sdkMethod.operation.responses, sdkMethod);
|
|
629
616
|
// check for long-running operation
|
|
630
|
-
this.processRouteForLongRunning(codeModelOperation, operation
|
|
617
|
+
this.processRouteForLongRunning(codeModelOperation, sdkMethod.operation.responses, lroMetadata);
|
|
631
618
|
operationGroup.addOperation(codeModelOperation);
|
|
632
619
|
return codeModelOperation;
|
|
633
620
|
}
|
|
634
|
-
processRouteForPaged(op, responses) {
|
|
635
|
-
var _a, _b
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
const
|
|
642
|
-
if (
|
|
621
|
+
processRouteForPaged(op, responses, sdkMethod) {
|
|
622
|
+
var _a, _b;
|
|
623
|
+
if (sdkMethod.kind === "paging" || sdkMethod.kind === "lropaging") {
|
|
624
|
+
for (const [_, response] of responses) {
|
|
625
|
+
const bodyType = response.type;
|
|
626
|
+
if (bodyType && bodyType.kind === "model") {
|
|
627
|
+
const itemName = sdkMethod.response.resultPath;
|
|
628
|
+
const nextLinkName = sdkMethod.nextLinkPath;
|
|
629
|
+
if (itemName && nextLinkName) {
|
|
643
630
|
op.extensions = (_a = op.extensions) !== null && _a !== void 0 ? _a : {};
|
|
644
631
|
op.extensions["x-ms-pageable"] = {
|
|
645
|
-
itemName:
|
|
646
|
-
nextLinkName:
|
|
632
|
+
itemName: itemName,
|
|
633
|
+
nextLinkName: nextLinkName,
|
|
647
634
|
};
|
|
648
|
-
(
|
|
635
|
+
(_b = op.responses) === null || _b === void 0 ? void 0 : _b.forEach((r) => {
|
|
649
636
|
if (r instanceof SchemaResponse) {
|
|
650
637
|
this.trackSchemaUsage(r.schema, { usage: [SchemaContext.Paged] });
|
|
651
638
|
}
|
|
@@ -656,18 +643,17 @@ export class CodeModelBuilder {
|
|
|
656
643
|
}
|
|
657
644
|
}
|
|
658
645
|
}
|
|
659
|
-
processLroMetadata(op,
|
|
660
|
-
const operation = httpOperation.operation;
|
|
646
|
+
processLroMetadata(op, sdkMethod) {
|
|
661
647
|
const trackConvenienceApi = Boolean(op.convenienceApi);
|
|
662
|
-
const lroMetadata =
|
|
648
|
+
const lroMetadata = sdkMethod.__raw_lro_metadata;
|
|
663
649
|
// needs lroMetadata.statusMonitorStep, as getLroMetadata would return for @pollingOperation operation
|
|
664
650
|
if (lroMetadata && lroMetadata.pollingInfo && lroMetadata.statusMonitorStep) {
|
|
665
651
|
let pollingSchema = undefined;
|
|
666
652
|
let finalSchema = undefined;
|
|
667
653
|
let pollingStrategy = undefined;
|
|
668
654
|
let finalResultPropertySerializedName = undefined;
|
|
669
|
-
const verb =
|
|
670
|
-
const useNewPollStrategy = isLroNewPollingStrategy(
|
|
655
|
+
const verb = sdkMethod.operation.verb;
|
|
656
|
+
const useNewPollStrategy = isLroNewPollingStrategy(sdkMethod.operation.__raw, lroMetadata);
|
|
671
657
|
if (useNewPollStrategy) {
|
|
672
658
|
// use OperationLocationPollingStrategy
|
|
673
659
|
pollingStrategy = new Metadata({
|
|
@@ -728,24 +714,13 @@ export class CodeModelBuilder {
|
|
|
728
714
|
}
|
|
729
715
|
return new LongRunningMetadata(false);
|
|
730
716
|
}
|
|
731
|
-
processRouteForLongRunning(op,
|
|
732
|
-
var _a
|
|
717
|
+
processRouteForLongRunning(op, responses, lroMetadata) {
|
|
718
|
+
var _a;
|
|
733
719
|
if (lroMetadata.longRunning) {
|
|
734
720
|
op.extensions = (_a = op.extensions) !== null && _a !== void 0 ? _a : {};
|
|
735
721
|
op.extensions["x-ms-long-running-operation"] = true;
|
|
736
722
|
return;
|
|
737
723
|
}
|
|
738
|
-
for (const resp of responses) {
|
|
739
|
-
if (resp.responses && resp.responses.length > 0 && resp.responses[0].headers) {
|
|
740
|
-
for (const [_, header] of Object.entries(resp.responses[0].headers)) {
|
|
741
|
-
if (isPollingLocation(this.program, header)) {
|
|
742
|
-
op.extensions = (_b = op.extensions) !== null && _b !== void 0 ? _b : {};
|
|
743
|
-
op.extensions["x-ms-long-running-operation"] = true;
|
|
744
|
-
break;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
724
|
}
|
|
750
725
|
processParameter(op, param, clientContext) {
|
|
751
726
|
var _a, _b;
|
|
@@ -754,65 +729,52 @@ export class CodeModelBuilder {
|
|
|
754
729
|
if (this.isArm()) {
|
|
755
730
|
// Currently we assume ARM tsp only have one client and one api-version.
|
|
756
731
|
// TODO: How will service define mixed api-versions(like those in Compute RP)?
|
|
757
|
-
const apiVersion =
|
|
732
|
+
const apiVersion = this.apiVersion;
|
|
758
733
|
if (!this._armApiVersionParameter) {
|
|
759
|
-
this._armApiVersionParameter = this.createApiVersionParameter("api-version", param.
|
|
734
|
+
this._armApiVersionParameter = this.createApiVersionParameter("api-version", param.kind === "query" ? ParameterLocation.Query : ParameterLocation.Path, apiVersion);
|
|
760
735
|
clientContext.addGlobalParameter(this._armApiVersionParameter);
|
|
761
736
|
}
|
|
762
737
|
op.addParameter(this._armApiVersionParameter);
|
|
763
738
|
}
|
|
764
739
|
else {
|
|
765
|
-
const parameter = param.
|
|
740
|
+
const parameter = param.kind === "query" ? this.apiVersionParameter : this.apiVersionParameterInPath;
|
|
766
741
|
op.addParameter(parameter);
|
|
767
742
|
clientContext.addGlobalParameter(parameter);
|
|
768
743
|
}
|
|
769
744
|
}
|
|
770
|
-
else if (this.isSubscriptionId(param)) {
|
|
745
|
+
else if (param.kind === "path" && param.onClient && this.isSubscriptionId(param)) {
|
|
771
746
|
const parameter = this.subscriptionIdParameter(param);
|
|
772
747
|
op.addParameter(parameter);
|
|
773
748
|
clientContext.addGlobalParameter(parameter);
|
|
774
749
|
}
|
|
775
|
-
else if (SPECIAL_HEADER_NAMES.has(param.
|
|
750
|
+
else if (param.kind === "header" && SPECIAL_HEADER_NAMES.has(param.serializedName.toLowerCase())) {
|
|
776
751
|
// special headers
|
|
777
|
-
op.specialHeaders = (
|
|
778
|
-
if (!stringArrayContainsIgnoreCase(op.specialHeaders, param.
|
|
779
|
-
op.specialHeaders.push(param.
|
|
752
|
+
op.specialHeaders = (_a = op.specialHeaders) !== null && _a !== void 0 ? _a : [];
|
|
753
|
+
if (!stringArrayContainsIgnoreCase(op.specialHeaders, param.serializedName)) {
|
|
754
|
+
op.specialHeaders.push(param.serializedName);
|
|
780
755
|
}
|
|
781
756
|
}
|
|
782
757
|
else {
|
|
783
758
|
// schema
|
|
784
|
-
|
|
785
|
-
const
|
|
786
|
-
if (param.type === "header" &&
|
|
787
|
-
param.param.type.kind === "Scalar" &&
|
|
788
|
-
getEncode(this.program, param.param) === undefined &&
|
|
789
|
-
getEncode(this.program, param.param.type) === undefined &&
|
|
790
|
-
(hasScalarAsBase(param.param.type, "utcDateTime") || hasScalarAsBase(param.param.type, "offsetDateTime")) &&
|
|
791
|
-
(sdkType.kind === "utcDateTime" || sdkType.kind === "offsetDateTime")) {
|
|
792
|
-
// utcDateTime in header maps to rfc7231
|
|
793
|
-
schema = this.processDateTimeSchemaFromSdkType(sdkType, param.param.name, true);
|
|
794
|
-
}
|
|
795
|
-
else {
|
|
796
|
-
schema = this.processSchemaFromSdkType(sdkType, param.param.name);
|
|
797
|
-
}
|
|
759
|
+
const sdkType = getNonNullSdkType(param.type);
|
|
760
|
+
const schema = this.processSchemaFromSdkType(sdkType, param.name);
|
|
798
761
|
let extensions = undefined;
|
|
799
|
-
|
|
800
|
-
if (param.type === "path") {
|
|
762
|
+
if (param.kind === "path") {
|
|
801
763
|
if (param.allowReserved) {
|
|
802
764
|
extensions = extensions !== null && extensions !== void 0 ? extensions : {};
|
|
803
765
|
extensions["x-ms-skip-url-encoding"] = true;
|
|
804
766
|
}
|
|
805
767
|
}
|
|
806
768
|
// TODO: deprecate this logic of string/url for x-ms-skip-url-encoding
|
|
807
|
-
if ((param.
|
|
808
|
-
|
|
769
|
+
if ((param.kind === "query" || param.kind === "path") &&
|
|
770
|
+
isSdkBuiltInKind(sdkType.kind) &&
|
|
809
771
|
schema instanceof UriSchema) {
|
|
810
772
|
extensions = extensions !== null && extensions !== void 0 ? extensions : {};
|
|
811
773
|
extensions["x-ms-skip-url-encoding"] = true;
|
|
812
774
|
}
|
|
813
|
-
if (this.supportsAdvancedVersioning()) {
|
|
775
|
+
if (this.supportsAdvancedVersioning() && param.__raw) {
|
|
814
776
|
// versioning
|
|
815
|
-
const addedOn = getAddedOnVersions(this.program, param.
|
|
777
|
+
const addedOn = getAddedOnVersions(this.program, param.__raw);
|
|
816
778
|
if (addedOn) {
|
|
817
779
|
extensions = extensions !== null && extensions !== void 0 ? extensions : {};
|
|
818
780
|
extensions["x-ms-versioning-added"] = clientContext.getAddedVersions(addedOn);
|
|
@@ -821,62 +783,59 @@ export class CodeModelBuilder {
|
|
|
821
783
|
// format if array
|
|
822
784
|
let style = undefined;
|
|
823
785
|
let explode = undefined;
|
|
824
|
-
if (
|
|
825
|
-
if (param.
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
default:
|
|
847
|
-
this.logWarning(`Unrecognized query parameter format: '${queryParamFormat}'.`);
|
|
848
|
-
break;
|
|
849
|
-
}
|
|
786
|
+
if (sdkType.kind === "array") {
|
|
787
|
+
if (param.kind === "query") {
|
|
788
|
+
const format = param.collectionFormat;
|
|
789
|
+
switch (format) {
|
|
790
|
+
case "csv":
|
|
791
|
+
case "simple":
|
|
792
|
+
style = SerializationStyle.Simple;
|
|
793
|
+
break;
|
|
794
|
+
case "ssv":
|
|
795
|
+
style = SerializationStyle.SpaceDelimited;
|
|
796
|
+
break;
|
|
797
|
+
case "tsv":
|
|
798
|
+
style = SerializationStyle.TabDelimited;
|
|
799
|
+
break;
|
|
800
|
+
case "pipes":
|
|
801
|
+
style = SerializationStyle.PipeDelimited;
|
|
802
|
+
break;
|
|
803
|
+
case "multi":
|
|
804
|
+
case "form":
|
|
805
|
+
style = SerializationStyle.Form;
|
|
806
|
+
explode = true;
|
|
807
|
+
break;
|
|
850
808
|
}
|
|
851
809
|
}
|
|
852
|
-
else if (param.
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
810
|
+
else if (param.kind === "header") {
|
|
811
|
+
const format = param.collectionFormat;
|
|
812
|
+
switch (format) {
|
|
813
|
+
case "csv":
|
|
814
|
+
style = SerializationStyle.Simple;
|
|
815
|
+
break;
|
|
816
|
+
default:
|
|
817
|
+
if (format) {
|
|
818
|
+
this.logWarning(`Unrecognized header parameter format: '${format}'.`);
|
|
819
|
+
}
|
|
820
|
+
break;
|
|
862
821
|
}
|
|
863
822
|
}
|
|
864
823
|
}
|
|
865
|
-
const nullable =
|
|
866
|
-
const parameter = new Parameter(
|
|
867
|
-
summary:
|
|
824
|
+
const nullable = param.type.kind === "nullable";
|
|
825
|
+
const parameter = new Parameter(param.name, (_b = param.details) !== null && _b !== void 0 ? _b : "", schema, {
|
|
826
|
+
summary: param.description,
|
|
868
827
|
implementation: ImplementationLocation.Method,
|
|
869
|
-
required: !param.
|
|
828
|
+
required: !param.optional,
|
|
870
829
|
nullable: nullable,
|
|
871
830
|
protocol: {
|
|
872
|
-
http: new HttpParameter(param.
|
|
831
|
+
http: new HttpParameter(param.kind, {
|
|
873
832
|
style: style,
|
|
874
833
|
explode: explode,
|
|
875
834
|
}),
|
|
876
835
|
},
|
|
877
836
|
language: {
|
|
878
837
|
default: {
|
|
879
|
-
serializedName:
|
|
838
|
+
serializedName: param.serializedName, // it uses param.name previously, but better to use param.serializedName directly
|
|
880
839
|
},
|
|
881
840
|
},
|
|
882
841
|
extensions: extensions,
|
|
@@ -888,43 +847,6 @@ export class CodeModelBuilder {
|
|
|
888
847
|
}
|
|
889
848
|
}
|
|
890
849
|
}
|
|
891
|
-
addAcceptHeaderParameter(op, responses) {
|
|
892
|
-
var _a, _b, _c;
|
|
893
|
-
if ((_a = op.parameters) === null || _a === void 0 ? void 0 : _a.some((it) => { var _a; return ((_a = it.language.default.serializedName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "accept"; })) {
|
|
894
|
-
// parameters already include "accept" header
|
|
895
|
-
return;
|
|
896
|
-
}
|
|
897
|
-
const produces = new Set();
|
|
898
|
-
for (const resp of responses) {
|
|
899
|
-
if (resp.responses && resp.responses.length > 0) {
|
|
900
|
-
for (const response of resp.responses) {
|
|
901
|
-
(_b = response.body) === null || _b === void 0 ? void 0 : _b.contentTypes.forEach((it) => produces.add(it));
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
if (produces.size === 0) {
|
|
906
|
-
produces.add("application/json");
|
|
907
|
-
}
|
|
908
|
-
const acceptTypes = Array.from(produces.values()).join(", ");
|
|
909
|
-
const acceptSchema = ((_c = this.codeModel.schemas.constants) === null || _c === void 0 ? void 0 : _c.find((it) => it.language.default.name === "accept" && it.value.value === acceptTypes)) ||
|
|
910
|
-
this.codeModel.schemas.add(new ConstantSchema("accept", `Accept: ${acceptTypes}`, {
|
|
911
|
-
valueType: this.stringSchema,
|
|
912
|
-
value: new ConstantValue(acceptTypes),
|
|
913
|
-
}));
|
|
914
|
-
op.addParameter(new Parameter("accept", "Accept header", acceptSchema, {
|
|
915
|
-
implementation: ImplementationLocation.Method,
|
|
916
|
-
origin: "modelerfour:synthesized/accept",
|
|
917
|
-
required: true,
|
|
918
|
-
protocol: {
|
|
919
|
-
http: new HttpParameter(ParameterLocation.Header),
|
|
920
|
-
},
|
|
921
|
-
language: {
|
|
922
|
-
default: {
|
|
923
|
-
serializedName: "accept",
|
|
924
|
-
},
|
|
925
|
-
},
|
|
926
|
-
}));
|
|
927
|
-
}
|
|
928
850
|
processEtagHeaderParameters(op, httpOperation) {
|
|
929
851
|
if (op.convenienceApi && op.parameters && op.signatureParameters) {
|
|
930
852
|
const etagHeadersNames = new Set([
|
|
@@ -975,7 +897,7 @@ export class CodeModelBuilder {
|
|
|
975
897
|
request.signatureParameters.push(clonedParameter);
|
|
976
898
|
}
|
|
977
899
|
}
|
|
978
|
-
const namespace = getNamespace(httpOperation.operation);
|
|
900
|
+
const namespace = getNamespace(httpOperation.__raw.operation); // TODO: SdkHttpOperation does not have namespace
|
|
979
901
|
const schemaName = groupToRequestConditions ? "RequestConditions" : "MatchConditions";
|
|
980
902
|
const schemaDescription = groupToRequestConditions
|
|
981
903
|
? "Specifies HTTP options for conditional requests based on modification time."
|
|
@@ -1026,274 +948,272 @@ export class CodeModelBuilder {
|
|
|
1026
948
|
}
|
|
1027
949
|
}
|
|
1028
950
|
}
|
|
1029
|
-
processParameterBody(op,
|
|
951
|
+
processParameterBody(op, rawHttpOperation, sdkHttpOperation, sdkBody) {
|
|
1030
952
|
var _a, _b, _c;
|
|
1031
953
|
// set contentTypes to mediaTypes
|
|
1032
|
-
op.requests[0].protocol.http.mediaTypes =
|
|
1033
|
-
const parameters = httpOperation.operation.parameters;
|
|
954
|
+
op.requests[0].protocol.http.mediaTypes = sdkBody.contentTypes;
|
|
1034
955
|
const unknownRequestBody = op.requests[0].protocol.http.mediaTypes &&
|
|
1035
956
|
op.requests[0].protocol.http.mediaTypes.length > 0 &&
|
|
1036
957
|
!isKnownContentType(op.requests[0].protocol.http.mediaTypes);
|
|
1037
|
-
const sdkType =
|
|
958
|
+
const sdkType = sdkBody.type;
|
|
1038
959
|
let schema;
|
|
1039
|
-
if (unknownRequestBody &&
|
|
1040
|
-
body
|
|
1041
|
-
|
|
1042
|
-
body.type.name === "bytes") {
|
|
1043
|
-
// handle binary request body
|
|
1044
|
-
schema = this.processBinarySchema(body.type);
|
|
960
|
+
if (unknownRequestBody && sdkType.kind === "bytes") {
|
|
961
|
+
// if it's unknown request body, handle binary request body
|
|
962
|
+
schema = this.processBinarySchemaFromSdkType(sdkType);
|
|
1045
963
|
}
|
|
1046
964
|
else {
|
|
1047
|
-
schema = this.processSchemaFromSdkType(sdkType,
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
const bodyParameterFlatten = sdkType.kind === "model" && body.kind === "Model" && !this.isArm();
|
|
1053
|
-
const parameterName = body.kind === "Model" ? (sdkType.kind === "model" ? sdkType.name : "") : this.getName(body);
|
|
1054
|
-
const parameter = new Parameter(parameterName, this.getDoc(body), schema, {
|
|
1055
|
-
summary: this.getSummary(body),
|
|
965
|
+
schema = this.processSchemaFromSdkType(getNonNullSdkType(sdkType), sdkBody.name);
|
|
966
|
+
}
|
|
967
|
+
const parameterName = sdkBody.name;
|
|
968
|
+
const parameter = new Parameter(parameterName, (_a = sdkBody.description) !== null && _a !== void 0 ? _a : "", schema, {
|
|
969
|
+
summary: sdkBody.details,
|
|
1056
970
|
implementation: ImplementationLocation.Method,
|
|
1057
|
-
required:
|
|
971
|
+
required: !sdkBody.optional,
|
|
1058
972
|
protocol: {
|
|
1059
973
|
http: new HttpParameter(ParameterLocation.Body),
|
|
1060
974
|
},
|
|
1061
975
|
});
|
|
1062
976
|
op.addParameter(parameter);
|
|
977
|
+
const jsonMergePatch = operationIsJsonMergePatch(sdkHttpOperation);
|
|
978
|
+
const schemaIsPublicBeforeProcess = schema instanceof ObjectSchema && ((_b = schema.usage) === null || _b === void 0 ? void 0 : _b.includes(SchemaContext.Public));
|
|
1063
979
|
this.trackSchemaUsage(schema, { usage: [SchemaContext.Input] });
|
|
1064
980
|
if (op.convenienceApi) {
|
|
1065
981
|
// model/schema does not need to be Public or Internal, if it is not to be used in convenience API
|
|
1066
982
|
this.trackSchemaUsage(schema, { usage: [op.internalApi ? SchemaContext.Internal : SchemaContext.Public] });
|
|
1067
983
|
}
|
|
1068
|
-
if (
|
|
984
|
+
if (jsonMergePatch) {
|
|
1069
985
|
this.trackSchemaUsage(schema, { usage: [SchemaContext.JsonMergePatch] });
|
|
1070
986
|
}
|
|
1071
|
-
if (op.convenienceApi && operationIsMultipart(
|
|
987
|
+
if (op.convenienceApi && operationIsMultipart(sdkHttpOperation)) {
|
|
1072
988
|
this.trackSchemaUsage(schema, { serializationFormats: [KnownMediaType.Multipart] });
|
|
1073
989
|
}
|
|
1074
|
-
if (
|
|
1075
|
-
//
|
|
1076
|
-
//
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
if (
|
|
1083
|
-
//
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
op.convenienceApi.requests.push(request);
|
|
1095
|
-
for (const [_, opParameter] of parameters.properties) {
|
|
1096
|
-
const serializedName = this.getSerializedName(opParameter);
|
|
1097
|
-
const paramLocation = this.getParameterLocation(opParameter);
|
|
1098
|
-
let existParameter;
|
|
1099
|
-
if (paramLocation === "BodyProperty") {
|
|
1100
|
-
// property of body, it won't match existing parameter (whose paramLocation be body, path, query, header)
|
|
1101
|
-
existParameter = undefined;
|
|
990
|
+
if (op.convenienceApi) {
|
|
991
|
+
// Explicit body parameter @body or @bodyRoot would result to the existance of rawHttpOperation.parameters.body.property
|
|
992
|
+
// Implicit body parameter would result to rawHttpOperation.parameters.body.property be undefined
|
|
993
|
+
// see https://typespec.io/docs/libraries/http/cheat-sheet#data-types
|
|
994
|
+
const bodyParameterFlatten = schema instanceof ObjectSchema &&
|
|
995
|
+
sdkType.kind === "model" &&
|
|
996
|
+
!((_c = rawHttpOperation.parameters.body) === null || _c === void 0 ? void 0 : _c.property) &&
|
|
997
|
+
!this.isArm();
|
|
998
|
+
if (schema instanceof ObjectSchema && bodyParameterFlatten) {
|
|
999
|
+
// flatten body parameter
|
|
1000
|
+
const parameters = sdkHttpOperation.parameters;
|
|
1001
|
+
const bodyParameter = sdkHttpOperation.bodyParam;
|
|
1002
|
+
if (!parameter.language.default.name) {
|
|
1003
|
+
// name the parameter for documentation
|
|
1004
|
+
parameter.language.default.name = "request";
|
|
1005
|
+
}
|
|
1006
|
+
if (jsonMergePatch) {
|
|
1007
|
+
// skip model flatten, if "application/merge-patch+json"
|
|
1008
|
+
if (sdkType.isGeneratedName) {
|
|
1009
|
+
schema.language.default.name = pascalCase(op.language.default.name) + "PatchRequest";
|
|
1102
1010
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
const schemaUsage = schema.usage;
|
|
1014
|
+
if (!schemaIsPublicBeforeProcess && (schemaUsage === null || schemaUsage === void 0 ? void 0 : schemaUsage.includes(SchemaContext.Public))) {
|
|
1015
|
+
// Public added in this op, change it to PublicSpread
|
|
1016
|
+
// This means that if this op would originally add Public to this schema, it adds PublicSpread instead
|
|
1017
|
+
schemaUsage === null || schemaUsage === void 0 ? void 0 : schemaUsage.splice(schemaUsage === null || schemaUsage === void 0 ? void 0 : schemaUsage.indexOf(SchemaContext.Public), 1);
|
|
1018
|
+
this.trackSchemaUsage(schema, { usage: [SchemaContext.PublicSpread] });
|
|
1019
|
+
}
|
|
1020
|
+
if (op.convenienceApi && op.parameters) {
|
|
1021
|
+
op.convenienceApi.requests = [];
|
|
1022
|
+
const request = new Request({
|
|
1023
|
+
protocol: op.requests[0].protocol,
|
|
1024
|
+
});
|
|
1025
|
+
request.parameters = [];
|
|
1026
|
+
op.convenienceApi.requests.push(request);
|
|
1027
|
+
// header/query/path params
|
|
1028
|
+
for (const opParameter of parameters) {
|
|
1029
|
+
this.addParameterOrBodyPropertyToCodeModelRequest(opParameter, op, request, schema, parameter);
|
|
1117
1030
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
if (
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1031
|
+
// body param
|
|
1032
|
+
if (bodyParameter) {
|
|
1033
|
+
if (bodyParameter.type.kind === "model") {
|
|
1034
|
+
for (const bodyProperty of bodyParameter.type.properties) {
|
|
1035
|
+
if (bodyProperty.kind === "property") {
|
|
1036
|
+
this.addParameterOrBodyPropertyToCodeModelRequest(bodyProperty, op, request, schema, parameter);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1124
1039
|
}
|
|
1125
1040
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1041
|
+
request.signatureParameters = request.parameters;
|
|
1042
|
+
if (request.signatureParameters.length > 6) {
|
|
1043
|
+
// create an option bag
|
|
1044
|
+
const name = op.language.default.name + "Options";
|
|
1045
|
+
const namespace = getNamespace(rawHttpOperation.operation);
|
|
1046
|
+
// option bag schema
|
|
1047
|
+
const optionBagSchema = this.codeModel.schemas.add(new GroupSchema(name, `Options for ${op.language.default.name} API`, {
|
|
1048
|
+
language: {
|
|
1049
|
+
default: {
|
|
1050
|
+
namespace: namespace,
|
|
1051
|
+
},
|
|
1052
|
+
java: {
|
|
1053
|
+
namespace: this.getJavaNamespace(namespace),
|
|
1139
1054
|
},
|
|
1140
|
-
summary: existBodyProperty.summary,
|
|
1141
|
-
implementation: ImplementationLocation.Method,
|
|
1142
|
-
required: existBodyProperty.required,
|
|
1143
|
-
nullable: existBodyProperty.nullable,
|
|
1144
|
-
}));
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
request.signatureParameters = request.parameters;
|
|
1149
|
-
if (request.signatureParameters.length > 6) {
|
|
1150
|
-
// create an option bag
|
|
1151
|
-
const name = op.language.default.name + "Options";
|
|
1152
|
-
const namespace = getNamespace(httpOperation.operation);
|
|
1153
|
-
// option bag schema
|
|
1154
|
-
const optionBagSchema = this.codeModel.schemas.add(new GroupSchema(name, `Options for ${op.language.default.name} API`, {
|
|
1155
|
-
language: {
|
|
1156
|
-
default: {
|
|
1157
|
-
namespace: namespace,
|
|
1158
|
-
},
|
|
1159
|
-
java: {
|
|
1160
|
-
namespace: this.getJavaNamespace(namespace),
|
|
1161
1055
|
},
|
|
1162
|
-
},
|
|
1163
|
-
}));
|
|
1164
|
-
request.parameters.forEach((it) => {
|
|
1165
|
-
optionBagSchema.add(new GroupProperty(it.language.default.name, it.language.default.description, it.schema, {
|
|
1166
|
-
originalParameter: [it],
|
|
1167
|
-
summary: it.summary,
|
|
1168
|
-
required: it.required,
|
|
1169
|
-
nullable: it.nullable,
|
|
1170
|
-
readOnly: false,
|
|
1171
|
-
serializedName: it.language.default.serializedName,
|
|
1172
1056
|
}));
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1057
|
+
request.parameters.forEach((it) => {
|
|
1058
|
+
optionBagSchema.add(new GroupProperty(it.language.default.name, it.language.default.description, it.schema, {
|
|
1059
|
+
originalParameter: [it],
|
|
1060
|
+
summary: it.summary,
|
|
1061
|
+
required: it.required,
|
|
1062
|
+
nullable: it.nullable,
|
|
1063
|
+
readOnly: false,
|
|
1064
|
+
serializedName: it.language.default.serializedName,
|
|
1065
|
+
}));
|
|
1066
|
+
});
|
|
1067
|
+
this.trackSchemaUsage(optionBagSchema, { usage: [SchemaContext.Input] });
|
|
1068
|
+
if (op.convenienceApi) {
|
|
1069
|
+
this.trackSchemaUsage(optionBagSchema, {
|
|
1070
|
+
usage: [op.internalApi ? SchemaContext.Internal : SchemaContext.Public],
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
// option bag parameter
|
|
1074
|
+
const optionBagParameter = new Parameter("options", optionBagSchema.language.default.description, optionBagSchema, {
|
|
1075
|
+
implementation: ImplementationLocation.Method,
|
|
1076
|
+
required: true,
|
|
1077
|
+
nullable: false,
|
|
1178
1078
|
});
|
|
1079
|
+
request.signatureParameters = [optionBagParameter];
|
|
1080
|
+
request.parameters.forEach((it) => (it.groupedBy = optionBagParameter));
|
|
1081
|
+
request.parameters.push(optionBagParameter);
|
|
1179
1082
|
}
|
|
1180
|
-
// option bag parameter
|
|
1181
|
-
const optionBagParameter = new Parameter("options", optionBagSchema.language.default.description, optionBagSchema, {
|
|
1182
|
-
implementation: ImplementationLocation.Method,
|
|
1183
|
-
required: true,
|
|
1184
|
-
nullable: false,
|
|
1185
|
-
});
|
|
1186
|
-
request.signatureParameters = [optionBagParameter];
|
|
1187
|
-
request.parameters.forEach((it) => (it.groupedBy = optionBagParameter));
|
|
1188
|
-
request.parameters.push(optionBagParameter);
|
|
1189
1083
|
}
|
|
1190
1084
|
}
|
|
1191
1085
|
}
|
|
1192
1086
|
}
|
|
1087
|
+
addParameterOrBodyPropertyToCodeModelRequest(opParameter, op, request, schema, originalParameter) {
|
|
1088
|
+
var _a, _b, _c, _d, _e;
|
|
1089
|
+
const serializedName = opParameter.serializedName;
|
|
1090
|
+
let existParameter;
|
|
1091
|
+
if (opParameter.kind !== "property") {
|
|
1092
|
+
// not body property
|
|
1093
|
+
// header/query/path, same location and same serializedName
|
|
1094
|
+
existParameter = (_a = op.parameters) === null || _a === void 0 ? void 0 : _a.find((it) => { var _a; return ((_a = it.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === opParameter.kind && it.language.default.serializedName === serializedName; });
|
|
1095
|
+
}
|
|
1096
|
+
request.parameters = (_b = request.parameters) !== null && _b !== void 0 ? _b : [];
|
|
1097
|
+
if (existParameter) {
|
|
1098
|
+
// parameter
|
|
1099
|
+
if (existParameter.implementation === ImplementationLocation.Method &&
|
|
1100
|
+
((_d = (_c = existParameter.origin) === null || _c === void 0 ? void 0 : _c.startsWith("modelerfour:synthesized/")) !== null && _d !== void 0 ? _d : true) &&
|
|
1101
|
+
!(existParameter.schema instanceof ConstantSchema)) {
|
|
1102
|
+
request.parameters.push(cloneOperationParameter(existParameter));
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
else {
|
|
1106
|
+
// property from anonymous model
|
|
1107
|
+
const existBodyProperty = (_e = schema.properties) === null || _e === void 0 ? void 0 : _e.find((it) => it.serializedName === serializedName);
|
|
1108
|
+
if (existBodyProperty && !existBodyProperty.readOnly && !(existBodyProperty.schema instanceof ConstantSchema)) {
|
|
1109
|
+
request.parameters.push(new VirtualParameter(existBodyProperty.language.default.name, existBodyProperty.language.default.description, existBodyProperty.schema, {
|
|
1110
|
+
originalParameter: originalParameter,
|
|
1111
|
+
targetProperty: existBodyProperty,
|
|
1112
|
+
language: {
|
|
1113
|
+
default: {
|
|
1114
|
+
serializedName: existBodyProperty.serializedName,
|
|
1115
|
+
},
|
|
1116
|
+
},
|
|
1117
|
+
summary: existBodyProperty.summary,
|
|
1118
|
+
implementation: ImplementationLocation.Method,
|
|
1119
|
+
required: existBodyProperty.required,
|
|
1120
|
+
nullable: existBodyProperty.nullable,
|
|
1121
|
+
}));
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1193
1125
|
findResponseBody(bodyType) {
|
|
1194
1126
|
// find a type that possibly without http metadata like @statusCode
|
|
1195
1127
|
return this.getEffectiveSchemaType(bodyType);
|
|
1196
1128
|
}
|
|
1197
|
-
processResponse(op,
|
|
1129
|
+
processResponse(op, statusCode, sdkResponse, longRunning, isErrorResponse) {
|
|
1130
|
+
var _a;
|
|
1198
1131
|
// TODO: what to do if more than 1 response?
|
|
1199
1132
|
// It happens when the response type is Union, on one status code.
|
|
1200
|
-
let response;
|
|
1133
|
+
// let response: Response;
|
|
1201
1134
|
let headers = undefined;
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
for (const
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
const sdkType = getClientType(this.sdkContext, header);
|
|
1209
|
-
const schema = this.processSchemaFromSdkType(sdkType, key);
|
|
1210
|
-
headers.push(new HttpHeader(key, schema, {
|
|
1211
|
-
language: {
|
|
1212
|
-
default: {
|
|
1213
|
-
name: key,
|
|
1214
|
-
description: this.getDoc(header),
|
|
1215
|
-
},
|
|
1216
|
-
},
|
|
1217
|
-
}));
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
let responseBody = undefined;
|
|
1223
|
-
let bodyType = undefined;
|
|
1224
|
-
let trackConvenienceApi = Boolean(op.convenienceApi);
|
|
1225
|
-
if (resp.responses && resp.responses.length > 0 && resp.responses[0].body) {
|
|
1226
|
-
responseBody = resp.responses[0].body;
|
|
1227
|
-
}
|
|
1228
|
-
if (responseBody) {
|
|
1229
|
-
const unknownResponseBody = responseBody.contentTypes.length > 0 && !isKnownContentType(responseBody.contentTypes);
|
|
1230
|
-
bodyType = this.findResponseBody(responseBody.type);
|
|
1231
|
-
if (unknownResponseBody && bodyType.kind === "Scalar" && bodyType.name === "bytes") {
|
|
1232
|
-
// binary
|
|
1233
|
-
response = new BinaryResponse({
|
|
1234
|
-
protocol: {
|
|
1235
|
-
http: {
|
|
1236
|
-
statusCodes: this.getStatusCodes(resp.statusCodes),
|
|
1237
|
-
headers: headers,
|
|
1238
|
-
mediaTypes: responseBody.contentTypes,
|
|
1239
|
-
knownMediaType: KnownMediaType.Binary,
|
|
1240
|
-
},
|
|
1241
|
-
},
|
|
1135
|
+
// headers
|
|
1136
|
+
headers = [];
|
|
1137
|
+
if (sdkResponse.headers) {
|
|
1138
|
+
for (const header of sdkResponse.headers) {
|
|
1139
|
+
const schema = this.processSchemaFromSdkType(header.type, header.serializedName);
|
|
1140
|
+
headers.push(new HttpHeader(header.serializedName, schema, {
|
|
1242
1141
|
language: {
|
|
1243
1142
|
default: {
|
|
1244
|
-
name:
|
|
1245
|
-
description:
|
|
1143
|
+
name: header.serializedName,
|
|
1144
|
+
description: (_a = header.description) !== null && _a !== void 0 ? _a : header.details,
|
|
1246
1145
|
},
|
|
1247
1146
|
},
|
|
1248
|
-
});
|
|
1147
|
+
}));
|
|
1249
1148
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
statusCodes: this.getStatusCodes(resp.statusCodes),
|
|
1265
|
-
headers: headers,
|
|
1266
|
-
mediaTypes: responseBody.contentTypes,
|
|
1267
|
-
},
|
|
1149
|
+
}
|
|
1150
|
+
const bodyType = sdkResponse.type;
|
|
1151
|
+
let trackConvenienceApi = Boolean(op.convenienceApi);
|
|
1152
|
+
const unknownResponseBody = sdkResponse.contentTypes && sdkResponse.contentTypes.length > 0 && !isKnownContentType(sdkResponse.contentTypes);
|
|
1153
|
+
let response;
|
|
1154
|
+
if (unknownResponseBody && bodyType && bodyType.kind === "bytes") {
|
|
1155
|
+
// binary
|
|
1156
|
+
response = new BinaryResponse({
|
|
1157
|
+
protocol: {
|
|
1158
|
+
http: {
|
|
1159
|
+
statusCodes: this.getStatusCodes(statusCode),
|
|
1160
|
+
headers: headers,
|
|
1161
|
+
mediaTypes: sdkResponse.contentTypes,
|
|
1162
|
+
knownMediaType: KnownMediaType.Binary,
|
|
1268
1163
|
},
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1164
|
+
},
|
|
1165
|
+
language: {
|
|
1166
|
+
default: {
|
|
1167
|
+
name: op.language.default.name + "Response",
|
|
1168
|
+
description: sdkResponse.description,
|
|
1274
1169
|
},
|
|
1275
|
-
}
|
|
1170
|
+
},
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
else if (bodyType) {
|
|
1174
|
+
// schema (usually JSON)
|
|
1175
|
+
let schema = undefined;
|
|
1176
|
+
if (longRunning) {
|
|
1177
|
+
// LRO uses the LroMetadata for poll/final result, not the response of activation request
|
|
1178
|
+
trackConvenienceApi = false;
|
|
1179
|
+
}
|
|
1180
|
+
if (!schema) {
|
|
1181
|
+
schema = this.processSchemaFromSdkType(bodyType, op.language.default.name + "Response");
|
|
1276
1182
|
}
|
|
1183
|
+
response = new SchemaResponse(schema, {
|
|
1184
|
+
protocol: {
|
|
1185
|
+
http: {
|
|
1186
|
+
statusCodes: this.getStatusCodes(statusCode),
|
|
1187
|
+
headers: headers,
|
|
1188
|
+
mediaTypes: sdkResponse.contentTypes,
|
|
1189
|
+
},
|
|
1190
|
+
},
|
|
1191
|
+
language: {
|
|
1192
|
+
default: {
|
|
1193
|
+
name: op.language.default.name + "Response",
|
|
1194
|
+
description: sdkResponse.description,
|
|
1195
|
+
},
|
|
1196
|
+
},
|
|
1197
|
+
});
|
|
1277
1198
|
}
|
|
1278
1199
|
else {
|
|
1279
1200
|
// not binary nor schema, usually NoContent
|
|
1280
1201
|
response = new Response({
|
|
1281
1202
|
protocol: {
|
|
1282
1203
|
http: {
|
|
1283
|
-
statusCodes: this.getStatusCodes(
|
|
1204
|
+
statusCodes: this.getStatusCodes(statusCode),
|
|
1284
1205
|
headers: headers,
|
|
1285
1206
|
},
|
|
1286
1207
|
},
|
|
1287
1208
|
language: {
|
|
1288
1209
|
default: {
|
|
1289
1210
|
name: op.language.default.name + "Response",
|
|
1290
|
-
description:
|
|
1211
|
+
description: sdkResponse.description,
|
|
1291
1212
|
},
|
|
1292
1213
|
},
|
|
1293
1214
|
});
|
|
1294
1215
|
}
|
|
1295
|
-
if (
|
|
1296
|
-
// "*", or the model is @error
|
|
1216
|
+
if (isErrorResponse) {
|
|
1297
1217
|
op.addException(response);
|
|
1298
1218
|
if (response instanceof SchemaResponse) {
|
|
1299
1219
|
this.trackSchemaUsage(response.schema, { usage: [SchemaContext.Exception] });
|
|
@@ -1327,11 +1247,6 @@ export class CodeModelBuilder {
|
|
|
1327
1247
|
.map((it) => it.toString());
|
|
1328
1248
|
}
|
|
1329
1249
|
}
|
|
1330
|
-
getResponseDescription(resp) {
|
|
1331
|
-
return (resp.description ||
|
|
1332
|
-
(resp.statusCodes === "*" ? "An unexpected error response" : getStatusCodeDescription(resp.statusCodes)) ||
|
|
1333
|
-
"");
|
|
1334
|
-
}
|
|
1335
1250
|
processSchemaFromSdkType(type, nameHint) {
|
|
1336
1251
|
return this.schemaCache.process(type, nameHint) || fail("Unable to process schema.");
|
|
1337
1252
|
}
|
|
@@ -1744,9 +1659,10 @@ export class CodeModelBuilder {
|
|
|
1744
1659
|
});
|
|
1745
1660
|
return this.codeModel.schemas.add(unionSchema);
|
|
1746
1661
|
}
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1662
|
+
processBinarySchemaFromSdkType(type) {
|
|
1663
|
+
var _a;
|
|
1664
|
+
return this.codeModel.schemas.add(new BinarySchema((_a = type.description) !== null && _a !== void 0 ? _a : "", {
|
|
1665
|
+
summary: type.details,
|
|
1750
1666
|
}));
|
|
1751
1667
|
}
|
|
1752
1668
|
getUnionVariantName(type, option) {
|
|
@@ -1834,30 +1750,6 @@ export class CodeModelBuilder {
|
|
|
1834
1750
|
getSummary(target) {
|
|
1835
1751
|
return target ? getSummary(this.program, target) : undefined;
|
|
1836
1752
|
}
|
|
1837
|
-
getName(target, nameHint = undefined) {
|
|
1838
|
-
// 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
|
|
1839
|
-
const emitterClientName = getClientNameOverride(this.sdkContext, target);
|
|
1840
|
-
if (emitterClientName && typeof emitterClientName === "string") {
|
|
1841
|
-
return emitterClientName;
|
|
1842
|
-
}
|
|
1843
|
-
// TODO: deprecate getProjectedName
|
|
1844
|
-
const languageProjectedName = getProjectedName(this.program, target, "java");
|
|
1845
|
-
if (languageProjectedName) {
|
|
1846
|
-
return languageProjectedName;
|
|
1847
|
-
}
|
|
1848
|
-
const clientProjectedName = getProjectedName(this.program, target, "client");
|
|
1849
|
-
if (clientProjectedName) {
|
|
1850
|
-
return clientProjectedName;
|
|
1851
|
-
}
|
|
1852
|
-
const friendlyName = getFriendlyName(this.program, target);
|
|
1853
|
-
if (friendlyName) {
|
|
1854
|
-
return friendlyName;
|
|
1855
|
-
}
|
|
1856
|
-
if (typeof target.name === "symbol") {
|
|
1857
|
-
return "";
|
|
1858
|
-
}
|
|
1859
|
-
return target.name || "";
|
|
1860
|
-
}
|
|
1861
1753
|
getSerializedName(target) {
|
|
1862
1754
|
if (isHeader(this.program, target)) {
|
|
1863
1755
|
return getHeaderFieldName(this.program, target);
|
|
@@ -1873,25 +1765,6 @@ export class CodeModelBuilder {
|
|
|
1873
1765
|
return getWireName(this.sdkContext, target);
|
|
1874
1766
|
}
|
|
1875
1767
|
}
|
|
1876
|
-
getParameterLocation(target) {
|
|
1877
|
-
if (isHeader(this.program, target)) {
|
|
1878
|
-
return ParameterLocation.Header;
|
|
1879
|
-
}
|
|
1880
|
-
else if (isQueryParam(this.program, target)) {
|
|
1881
|
-
return ParameterLocation.Query;
|
|
1882
|
-
}
|
|
1883
|
-
else if (isPathParam(this.program, target)) {
|
|
1884
|
-
return ParameterLocation.Path;
|
|
1885
|
-
}
|
|
1886
|
-
else if (isBody(this.program, target) ||
|
|
1887
|
-
isBodyRoot(this.program, target) ||
|
|
1888
|
-
isMultipartBodyProperty(this.program, target)) {
|
|
1889
|
-
return ParameterLocation.Body;
|
|
1890
|
-
}
|
|
1891
|
-
else {
|
|
1892
|
-
return "BodyProperty";
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
1768
|
isReadOnly(target) {
|
|
1896
1769
|
const segment = target.__raw ? getSegment(this.program, target.__raw) !== undefined : false;
|
|
1897
1770
|
if (segment) {
|
|
@@ -1943,10 +1816,10 @@ export class CodeModelBuilder {
|
|
|
1943
1816
|
return undefined;
|
|
1944
1817
|
}
|
|
1945
1818
|
}
|
|
1946
|
-
getConvenienceApiName(
|
|
1947
|
-
// check @
|
|
1948
|
-
if (
|
|
1949
|
-
return
|
|
1819
|
+
getConvenienceApiName(sdkMethod) {
|
|
1820
|
+
// check @convenienceAPI
|
|
1821
|
+
if (sdkMethod.generateConvenient) {
|
|
1822
|
+
return sdkMethod.name;
|
|
1950
1823
|
}
|
|
1951
1824
|
else {
|
|
1952
1825
|
return undefined;
|
|
@@ -2028,16 +1901,11 @@ export class CodeModelBuilder {
|
|
|
2028
1901
|
(this._apiVersionParameterInPath = this.createApiVersionParameter("apiVersion", ParameterLocation.Path)));
|
|
2029
1902
|
}
|
|
2030
1903
|
isSubscriptionId(param) {
|
|
2031
|
-
|
|
2032
|
-
return ("subscriptionId".toLocaleLowerCase() === ((_a = param === null || param === void 0 ? void 0 : param.name) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase()) &&
|
|
2033
|
-
param.param &&
|
|
2034
|
-
isArmCommonType(param.param) &&
|
|
2035
|
-
isPathParam(this.program, param.param));
|
|
1904
|
+
return "subscriptionId".toLocaleLowerCase() === param.serializedName.toLocaleLowerCase();
|
|
2036
1905
|
}
|
|
2037
1906
|
subscriptionIdParameter(parameter) {
|
|
2038
1907
|
if (!this._subscriptionParameter) {
|
|
2039
|
-
const
|
|
2040
|
-
const description = getDoc(this.program, param);
|
|
1908
|
+
const description = parameter.description;
|
|
2041
1909
|
this._subscriptionParameter = new Parameter("subscriptionId", description ? description : "The ID of the target subscription.", this.stringSchema, {
|
|
2042
1910
|
implementation: ImplementationLocation.Client,
|
|
2043
1911
|
required: true,
|
|
@@ -2054,7 +1922,7 @@ export class CodeModelBuilder {
|
|
|
2054
1922
|
return this._subscriptionParameter;
|
|
2055
1923
|
}
|
|
2056
1924
|
propagateSchemaUsage(schema) {
|
|
2057
|
-
var _a, _b;
|
|
1925
|
+
var _a, _b, _c, _d;
|
|
2058
1926
|
const processedSchemas = new Set();
|
|
2059
1927
|
const innerApplySchemaUsage = (schema, schemaUsage) => {
|
|
2060
1928
|
this.trackSchemaUsage(schema, schemaUsage);
|
|
@@ -2110,9 +1978,18 @@ export class CodeModelBuilder {
|
|
|
2110
1978
|
}
|
|
2111
1979
|
};
|
|
2112
1980
|
// Exclude context that not to be propagated
|
|
1981
|
+
const updatedSchemaUsage = (_a = schema.usage) === null || _a === void 0 ? void 0 : _a.filter((it) => it !== SchemaContext.Paged && it !== SchemaContext.PublicSpread);
|
|
1982
|
+
const indexSpread = (_b = schema.usage) === null || _b === void 0 ? void 0 : _b.indexOf(SchemaContext.PublicSpread);
|
|
1983
|
+
if (updatedSchemaUsage &&
|
|
1984
|
+
indexSpread &&
|
|
1985
|
+
indexSpread >= 0 &&
|
|
1986
|
+
!((_c = schema.usage) === null || _c === void 0 ? void 0 : _c.includes(SchemaContext.Public))) {
|
|
1987
|
+
// Propagate Public, if schema is PublicSpread
|
|
1988
|
+
updatedSchemaUsage.push(SchemaContext.Public);
|
|
1989
|
+
}
|
|
2113
1990
|
const schemaUsage = {
|
|
2114
|
-
usage:
|
|
2115
|
-
serializationFormats: (
|
|
1991
|
+
usage: updatedSchemaUsage,
|
|
1992
|
+
serializationFormats: (_d = schema.serializationFormats) === null || _d === void 0 ? void 0 : _d.filter((it) => it !== KnownMediaType.Multipart),
|
|
2116
1993
|
};
|
|
2117
1994
|
// Propagate the usage of the initial schema itself
|
|
2118
1995
|
innerPropagateSchemaUsage(schema, schemaUsage);
|