@azure-tools/typespec-python 0.22.5 → 0.23.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.d.ts +4 -0
- package/dist/src/code-model.d.ts.map +1 -0
- package/dist/src/code-model.js +205 -0
- package/dist/src/code-model.js.map +1 -0
- package/dist/src/emitter.d.ts.map +1 -1
- package/dist/src/emitter.js +14 -753
- package/dist/src/emitter.js.map +1 -1
- package/dist/src/http.d.ts +7 -0
- package/dist/src/http.d.ts.map +1 -0
- package/dist/src/http.js +255 -0
- package/dist/src/http.js.map +1 -0
- package/dist/src/lib.d.ts +5 -0
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js.map +1 -1
- package/dist/src/types.d.ts +4 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +43 -51
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils.d.ts +24 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +88 -0
- package/dist/src/utils.js.map +1 -1
- package/package.json +22 -22
package/dist/src/emitter.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getDoc, getSummary, ignoreDiagnostics, listServices, getNamespaceFullName, } from "@typespec/compiler";
|
|
3
|
-
import { getAuthentication, getHttpOperation, getServers, } from "@typespec/http";
|
|
4
|
-
import { getAddedOnVersions } from "@typespec/versioning";
|
|
5
|
-
import { listClients, listOperationGroups, listOperationsInOperationGroup, isApiVersion, getDefaultApiVersion, getClientNamespaceString, createSdkContext, getLibraryName, getAllModels, isInternal, getPropertyNames, getEffectivePayloadType, getAccess, isErrorOrChildOfError, getCrossLanguagePackageId, getCrossLanguageDefinitionId, } from "@azure-tools/typespec-client-generator-core";
|
|
6
|
-
import { getResourceOperation } from "@typespec/rest";
|
|
1
|
+
import { createSdkContext, } from "@azure-tools/typespec-client-generator-core";
|
|
7
2
|
import { resolveModuleRoot, saveCodeModelAsYaml } from "./external-process.js";
|
|
8
3
|
import { dirname } from "path";
|
|
9
4
|
import { fileURLToPath } from "url";
|
|
10
5
|
import { execFileSync } from "child_process";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
6
|
+
import { emitCodeModel } from "./code-model.js";
|
|
7
|
+
import { removeUnderscoresFromNamespace } from "./utils.js";
|
|
13
8
|
export function getModelsMode(context) {
|
|
14
9
|
const specifiedModelsMode = context.emitContext.options["models-mode"];
|
|
15
10
|
if (specifiedModelsMode) {
|
|
@@ -37,7 +32,7 @@ function addDefaultOptions(sdkContext) {
|
|
|
37
32
|
options["package-mode"] = sdkContext.arm ? "azure-mgmt" : "azure-dataplane";
|
|
38
33
|
}
|
|
39
34
|
if (!options["package-name"]) {
|
|
40
|
-
options["package-name"] =
|
|
35
|
+
options["package-name"] = removeUnderscoresFromNamespace(sdkContext.experimental_sdkPackage.rootNamespace.toLowerCase()).replace(/\./g, "-");
|
|
41
36
|
}
|
|
42
37
|
if (options.flavor !== "azure") {
|
|
43
38
|
// if they pass in a flavor other than azure, we want to ignore the value
|
|
@@ -47,14 +42,20 @@ function addDefaultOptions(sdkContext) {
|
|
|
47
42
|
options.flavor = "azure";
|
|
48
43
|
}
|
|
49
44
|
}
|
|
45
|
+
function createPythonSdkContext(context) {
|
|
46
|
+
return {
|
|
47
|
+
...createSdkContext(context, "@azure-tools/typespec-python"),
|
|
48
|
+
__endpointPathParameters: [],
|
|
49
|
+
__subscriptionIdPathParameter: undefined,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
50
52
|
export async function $onEmit(context) {
|
|
51
53
|
const program = context.program;
|
|
52
|
-
const sdkContext =
|
|
53
|
-
const clients = listClients(sdkContext);
|
|
54
|
-
addDefaultOptions(sdkContext);
|
|
54
|
+
const sdkContext = createPythonSdkContext(context);
|
|
55
55
|
const root = await resolveModuleRoot(program, "@autorest/python", dirname(fileURLToPath(import.meta.url)));
|
|
56
56
|
const outputDir = context.emitterOutputDir;
|
|
57
|
-
const yamlMap = emitCodeModel(sdkContext
|
|
57
|
+
const yamlMap = emitCodeModel(sdkContext);
|
|
58
|
+
addDefaultOptions(sdkContext);
|
|
58
59
|
const yamlPath = await saveCodeModelAsYaml("typespec-python-yaml-map", yamlMap);
|
|
59
60
|
const commandArgs = [
|
|
60
61
|
`${root}/run-python3.js`,
|
|
@@ -85,744 +86,4 @@ export async function $onEmit(context) {
|
|
|
85
86
|
execFileSync(process.execPath, commandArgs);
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
const endpointPathParameters = [];
|
|
89
|
-
let apiVersionParam = undefined;
|
|
90
|
-
let subscriptionIdParam = undefined;
|
|
91
|
-
function getDocStr(context, target) {
|
|
92
|
-
var _a;
|
|
93
|
-
return (_a = getDoc(context.program, target)) !== null && _a !== void 0 ? _a : "";
|
|
94
|
-
}
|
|
95
|
-
// To pass the yaml dump
|
|
96
|
-
function getAddedOnVersion(context, t) {
|
|
97
|
-
const versions = getAddedOnVersions(context.program, t);
|
|
98
|
-
if (versions !== undefined && versions.length > 0) {
|
|
99
|
-
return versions[0].value;
|
|
100
|
-
}
|
|
101
|
-
return undefined;
|
|
102
|
-
}
|
|
103
|
-
function emitParamBase(context, parameter) {
|
|
104
|
-
let optional;
|
|
105
|
-
let name;
|
|
106
|
-
let description = "";
|
|
107
|
-
let addedOn;
|
|
108
|
-
if (parameter.kind === "ModelProperty") {
|
|
109
|
-
optional = parameter.optional;
|
|
110
|
-
name = getLibraryName(context, parameter);
|
|
111
|
-
description = getDocStr(context, parameter);
|
|
112
|
-
addedOn = getAddedOnVersion(context, parameter);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
optional = false;
|
|
116
|
-
name = "body";
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
optional,
|
|
120
|
-
description,
|
|
121
|
-
addedOn,
|
|
122
|
-
clientName: camelToSnakeCase(name),
|
|
123
|
-
inOverload: false,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
function getBodyType(context, route) {
|
|
127
|
-
var _a, _b, _c, _d;
|
|
128
|
-
let bodyModel = (_a = route.parameters.body) === null || _a === void 0 ? void 0 : _a.type;
|
|
129
|
-
if (bodyModel && bodyModel.kind === "Model" && route.operation) {
|
|
130
|
-
const resourceType = (_b = getResourceOperation(context.program, route.operation)) === null || _b === void 0 ? void 0 : _b.resourceType;
|
|
131
|
-
if (resourceType && route.responses && route.responses.length > 0) {
|
|
132
|
-
const resp = route.responses[0];
|
|
133
|
-
if (resp && resp.responses && resp.responses.length > 0) {
|
|
134
|
-
const responseBody = (_c = resp.responses[0]) === null || _c === void 0 ? void 0 : _c.body;
|
|
135
|
-
if (((_d = responseBody === null || responseBody === void 0 ? void 0 : responseBody.type) === null || _d === void 0 ? void 0 : _d.kind) === "Model") {
|
|
136
|
-
const bodyTypeInResponse = getEffectivePayloadType(context, responseBody.type);
|
|
137
|
-
// response body type is reosurce type, and request body type (if templated) contains resource type
|
|
138
|
-
if (bodyTypeInResponse === resourceType &&
|
|
139
|
-
bodyModel.templateMapper &&
|
|
140
|
-
bodyModel.templateMapper.args.some((it) => {
|
|
141
|
-
return it.kind === "Model" || it.kind === "Union" ? it === bodyTypeInResponse : false;
|
|
142
|
-
})) {
|
|
143
|
-
bodyModel = resourceType;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
if (resourceType && bodyModel.name === "") {
|
|
149
|
-
const effectivePayloadType = getEffectivePayloadType(context, bodyModel);
|
|
150
|
-
if (effectivePayloadType.name !== "") {
|
|
151
|
-
bodyModel = effectivePayloadType;
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
bodyModel = resourceType;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (bodyModel && bodyModel.kind === "Scalar") {
|
|
159
|
-
return getType(context, route.parameters.body.parameter, true);
|
|
160
|
-
}
|
|
161
|
-
return getType(context, bodyModel, true);
|
|
162
|
-
}
|
|
163
|
-
function emitBodyParameter(context, httpOperation) {
|
|
164
|
-
var _a, _b, _c, _d, _e;
|
|
165
|
-
const params = httpOperation.parameters;
|
|
166
|
-
const body = params.body;
|
|
167
|
-
const base = emitParamBase(context, (_a = body.parameter) !== null && _a !== void 0 ? _a : body.type);
|
|
168
|
-
let contentTypes = body.contentTypes;
|
|
169
|
-
if (contentTypes.length === 0) {
|
|
170
|
-
contentTypes = ["application/json"];
|
|
171
|
-
}
|
|
172
|
-
const type = getBodyType(context, httpOperation);
|
|
173
|
-
if (type.type === "model" && type.name === "") {
|
|
174
|
-
type.name = capitalize(httpOperation.operation.name) + "Request";
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
contentTypes,
|
|
178
|
-
type,
|
|
179
|
-
wireName: (_c = (_b = body.parameter) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : "body",
|
|
180
|
-
location: "body",
|
|
181
|
-
...base,
|
|
182
|
-
defaultContentType: ((_e = (_d = body.parameter) === null || _d === void 0 ? void 0 : _d.default) !== null && _e !== void 0 ? _e : contentTypes.includes("application/json")) ? "application/json" : contentTypes[0],
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
function isSubscriptionId(context, param) {
|
|
186
|
-
return Boolean(context.arm) && param.wireName === "subscriptionId";
|
|
187
|
-
}
|
|
188
|
-
function getDefaultApiVersionValue(context) {
|
|
189
|
-
const defaultApiVersion = getDefaultApiVersion(context, getServiceNamespace(context));
|
|
190
|
-
if (!defaultApiVersion) {
|
|
191
|
-
if (context.arm) {
|
|
192
|
-
const services = listServices(context.program);
|
|
193
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
194
|
-
return services.length > 0 ? services[0].version : undefined;
|
|
195
|
-
}
|
|
196
|
-
return defaultApiVersion;
|
|
197
|
-
}
|
|
198
|
-
return defaultApiVersion.value;
|
|
199
|
-
}
|
|
200
|
-
function emitParameter(context, parameter, implementation) {
|
|
201
|
-
const base = emitParamBase(context, parameter.param);
|
|
202
|
-
base.clientName = camelToSnakeCase(getPropertyNames(context, parameter.param)[0]);
|
|
203
|
-
let type = getType(context, parameter.param);
|
|
204
|
-
let clientDefaultValue = undefined;
|
|
205
|
-
if (parameter.name.toLowerCase() === "content-type" && type["type"] === "constant") {
|
|
206
|
-
/// We don't want constant types for content types, so we make sure if it's
|
|
207
|
-
/// a constant, we make it not constant
|
|
208
|
-
clientDefaultValue = type["value"];
|
|
209
|
-
type = type["valueType"];
|
|
210
|
-
}
|
|
211
|
-
const paramMap = {
|
|
212
|
-
wireName: parameter.type === "path" ? parameter.param.name : parameter.name,
|
|
213
|
-
location: parameter.type,
|
|
214
|
-
type: type,
|
|
215
|
-
implementation: implementation,
|
|
216
|
-
skipUrlEncoding: parameter.type === "endpointPath",
|
|
217
|
-
};
|
|
218
|
-
if (type.type === "list" && (parameter.type === "query" || parameter.type === "header")) {
|
|
219
|
-
if (parameter.format === "csv") {
|
|
220
|
-
paramMap["delimiter"] = "comma";
|
|
221
|
-
}
|
|
222
|
-
else if (parameter.format === "ssv") {
|
|
223
|
-
paramMap["delimiter"] = "space";
|
|
224
|
-
}
|
|
225
|
-
else if (parameter.format === "tsv") {
|
|
226
|
-
paramMap["delimiter"] = "tab";
|
|
227
|
-
}
|
|
228
|
-
else if (parameter.format === "pipes") {
|
|
229
|
-
paramMap["delimiter"] = "pipe";
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
paramMap["explode"] = true;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (paramMap.type.type === "constant") {
|
|
236
|
-
clientDefaultValue = paramMap.type.value;
|
|
237
|
-
}
|
|
238
|
-
if (isApiVersion(context, parameter)) {
|
|
239
|
-
const defaultApiVersion = getDefaultApiVersionValue(context);
|
|
240
|
-
paramMap.type = defaultApiVersion ? getConstantType(defaultApiVersion) : KnownTypes.string;
|
|
241
|
-
paramMap.implementation = "Client";
|
|
242
|
-
paramMap.in_docstring = false;
|
|
243
|
-
paramMap.isApiVersion = true;
|
|
244
|
-
if (defaultApiVersion) {
|
|
245
|
-
clientDefaultValue = defaultApiVersion;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (isSubscriptionId(context, paramMap)) {
|
|
249
|
-
paramMap.implementation = "Client";
|
|
250
|
-
}
|
|
251
|
-
return { clientDefaultValue, ...base, ...paramMap };
|
|
252
|
-
}
|
|
253
|
-
function emitContentTypeParameter(bodyParameter, inOverload, inOverriden) {
|
|
254
|
-
return {
|
|
255
|
-
checkClientInput: false,
|
|
256
|
-
clientDefaultValue: bodyParameter.defaultContentType,
|
|
257
|
-
clientName: "content_type",
|
|
258
|
-
delimiter: null,
|
|
259
|
-
description: `Body parameter Content-Type. Known values are: ${bodyParameter.contentTypes}.`,
|
|
260
|
-
implementation: "Method",
|
|
261
|
-
inDocstring: true,
|
|
262
|
-
inOverload: inOverload,
|
|
263
|
-
inOverriden: inOverriden,
|
|
264
|
-
location: "header",
|
|
265
|
-
optional: true,
|
|
266
|
-
wireName: "Content-Type",
|
|
267
|
-
type: KnownTypes.string,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
function emitFlattenedParameter(bodyParameter, property) {
|
|
271
|
-
return {
|
|
272
|
-
checkClientInput: false,
|
|
273
|
-
clientDefaultValue: null,
|
|
274
|
-
clientName: property.clientName,
|
|
275
|
-
delimiter: null,
|
|
276
|
-
description: property.description,
|
|
277
|
-
implementation: "Method",
|
|
278
|
-
inDocstring: true,
|
|
279
|
-
inFlattenedBody: true,
|
|
280
|
-
inOverload: false,
|
|
281
|
-
inOverriden: false,
|
|
282
|
-
isApiVersion: bodyParameter["isApiVersion"],
|
|
283
|
-
location: "other",
|
|
284
|
-
optional: property["optional"],
|
|
285
|
-
wireName: null,
|
|
286
|
-
skipUrlEncoding: false,
|
|
287
|
-
type: property["type"],
|
|
288
|
-
defaultToUnsetSentinel: true,
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
function emitAcceptParameter(inOverload, inOverriden, contentType) {
|
|
292
|
-
return {
|
|
293
|
-
checkClientInput: false,
|
|
294
|
-
clientDefaultValue: contentType,
|
|
295
|
-
clientName: "accept",
|
|
296
|
-
delimiter: null,
|
|
297
|
-
description: "Accept header.",
|
|
298
|
-
explode: false,
|
|
299
|
-
groupedBy: null,
|
|
300
|
-
implementation: "Method",
|
|
301
|
-
inDocstring: true,
|
|
302
|
-
inOverload: inOverload,
|
|
303
|
-
inOverriden: inOverriden,
|
|
304
|
-
location: "header",
|
|
305
|
-
optional: false,
|
|
306
|
-
wireName: "Accept",
|
|
307
|
-
skipUrlEncoding: false,
|
|
308
|
-
type: getConstantType(contentType),
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
function emitResponseHeaders(context, response) {
|
|
312
|
-
const headers = [];
|
|
313
|
-
for (const innerResponse of response.responses) {
|
|
314
|
-
if (innerResponse.headers && Object.keys(innerResponse.headers).length > 0) {
|
|
315
|
-
for (const [key, value] of Object.entries(innerResponse.headers)) {
|
|
316
|
-
headers.push({
|
|
317
|
-
type: getType(context, value),
|
|
318
|
-
wireName: key,
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
return headers;
|
|
324
|
-
}
|
|
325
|
-
function isAzureCoreModel(t) {
|
|
326
|
-
return (t.kind === "Model" &&
|
|
327
|
-
t.namespace !== undefined &&
|
|
328
|
-
["Azure.Core", "Azure.Core.Foundations"].includes(getNamespaceFullName(t.namespace)));
|
|
329
|
-
}
|
|
330
|
-
function getBodyFromResponse(context, response) {
|
|
331
|
-
let body = undefined;
|
|
332
|
-
for (const innerResponse of response.responses) {
|
|
333
|
-
if (!body && innerResponse.body) {
|
|
334
|
-
body = innerResponse.body.type;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
if (body && body.kind === "Model") {
|
|
338
|
-
body = getEffectivePayloadType(context, body);
|
|
339
|
-
}
|
|
340
|
-
return body;
|
|
341
|
-
}
|
|
342
|
-
function isHttpStatusCode(statusCodes) {
|
|
343
|
-
if (typeof statusCodes !== "object") {
|
|
344
|
-
return false;
|
|
345
|
-
}
|
|
346
|
-
return "start" in statusCodes;
|
|
347
|
-
}
|
|
348
|
-
function getContentTypesFromResponse(context, response) {
|
|
349
|
-
let contentTypes = [];
|
|
350
|
-
for (const innerResponse of response.responses) {
|
|
351
|
-
if (innerResponse.body) {
|
|
352
|
-
contentTypes = contentTypes.concat(innerResponse.body.contentTypes);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return contentTypes;
|
|
356
|
-
}
|
|
357
|
-
function emitResponse(context, response) {
|
|
358
|
-
let type = undefined;
|
|
359
|
-
const body = getBodyFromResponse(context, response);
|
|
360
|
-
if (body) {
|
|
361
|
-
if (body.kind === "Model") {
|
|
362
|
-
if (body && body.decorators.find((d) => d.decorator.name === "$pagedResult")) {
|
|
363
|
-
type = getType(context, Array.from(body.properties.values())[0]);
|
|
364
|
-
}
|
|
365
|
-
else if (body && !isAzureCoreModel(body)) {
|
|
366
|
-
type = getType(context, body);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
type = getType(context, body);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
const statusCodes = [];
|
|
374
|
-
if (response.statusCodes === "*") {
|
|
375
|
-
statusCodes.push("default");
|
|
376
|
-
}
|
|
377
|
-
else if (isHttpStatusCode(response.statusCodes)) {
|
|
378
|
-
statusCodes.push(response.statusCodes.start);
|
|
379
|
-
}
|
|
380
|
-
else {
|
|
381
|
-
statusCodes.push(response.statusCodes);
|
|
382
|
-
}
|
|
383
|
-
const contentTypes = getContentTypesFromResponse(context, response);
|
|
384
|
-
return {
|
|
385
|
-
headers: emitResponseHeaders(context, response),
|
|
386
|
-
statusCodes: statusCodes,
|
|
387
|
-
addedOn: getAddedOnVersion(context, response.type),
|
|
388
|
-
discriminator: "basic",
|
|
389
|
-
type: type,
|
|
390
|
-
contentTypes: contentTypes,
|
|
391
|
-
defaultContentType: contentTypes.length > 0 && !contentTypes.includes("application/json")
|
|
392
|
-
? contentTypes[0]
|
|
393
|
-
: "application/json",
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
function emitOperation(context, operation, operationGroupName) {
|
|
397
|
-
const lro = getLroMetadata(context.program, operation);
|
|
398
|
-
const paging = getPagedResult(context.program, operation);
|
|
399
|
-
if (lro && paging) {
|
|
400
|
-
return emitLroPagingOperation(context, operation, operationGroupName);
|
|
401
|
-
}
|
|
402
|
-
else if (paging) {
|
|
403
|
-
return emitPagingOperation(context, operation, operationGroupName);
|
|
404
|
-
}
|
|
405
|
-
else if (lro) {
|
|
406
|
-
return emitLroOperation(context, operation, operationGroupName);
|
|
407
|
-
}
|
|
408
|
-
return emitBasicOperation(context, operation, operationGroupName);
|
|
409
|
-
}
|
|
410
|
-
function addLroInformation(context, tspOperation, emittedOperation, initialOperation) {
|
|
411
|
-
emittedOperation["discriminator"] = "lro";
|
|
412
|
-
emittedOperation["initialOperation"] = initialOperation;
|
|
413
|
-
emittedOperation["exposeStreamKeyword"] = false;
|
|
414
|
-
const lroMeta = getLroMetadata(context.program, tspOperation);
|
|
415
|
-
let logicalResult = lroMeta.logicalResult;
|
|
416
|
-
if (logicalResult.name === "") {
|
|
417
|
-
logicalResult = getEffectivePayloadType(context, logicalResult);
|
|
418
|
-
}
|
|
419
|
-
if (!isAzureCoreModel(logicalResult)) {
|
|
420
|
-
emittedOperation["responses"][0]["type"] = getType(context, logicalResult);
|
|
421
|
-
if (lroMeta.logicalPath) {
|
|
422
|
-
emittedOperation["responses"][0]["resultProperty"] = lroMeta.logicalPath;
|
|
423
|
-
}
|
|
424
|
-
addAcceptParameter(context, tspOperation, emittedOperation["parameters"]);
|
|
425
|
-
addAcceptParameter(context, lroMeta.operation, emittedOperation["initialOperation"]["parameters"]);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
function addPagingInformation(context, operation, emittedOperation) {
|
|
429
|
-
emittedOperation["discriminator"] = "paging";
|
|
430
|
-
const pagedResult = getPagedResult(context.program, operation);
|
|
431
|
-
if (pagedResult === undefined) {
|
|
432
|
-
throw Error("Trying to add paging information, but not paging metadata for this operation");
|
|
433
|
-
}
|
|
434
|
-
if (!isAzureCoreModel(pagedResult.modelType)) {
|
|
435
|
-
getType(context, pagedResult.modelType)["pageResultModel"] = true;
|
|
436
|
-
}
|
|
437
|
-
emittedOperation["itemName"] = pagedResult.itemsSegments ? pagedResult.itemsSegments.join(".") : null;
|
|
438
|
-
emittedOperation["itemType"] = getType(context, pagedResult.itemsProperty.type);
|
|
439
|
-
emittedOperation["continuationTokenName"] = pagedResult.nextLinkSegments
|
|
440
|
-
? pagedResult.nextLinkSegments.join(".")
|
|
441
|
-
: null;
|
|
442
|
-
emittedOperation["exposeStreamKeyword"] = false;
|
|
443
|
-
}
|
|
444
|
-
function getLroInitialOperation(context, operation, operationGroupName) {
|
|
445
|
-
const initialTspOperation = getLroMetadata(context.program, operation).operation;
|
|
446
|
-
const initialOperation = emitBasicOperation(context, initialTspOperation, operationGroupName)[0];
|
|
447
|
-
initialOperation["name"] = `_${initialOperation["name"]}_initial`;
|
|
448
|
-
initialOperation["isLroInitialOperation"] = true;
|
|
449
|
-
initialOperation["wantTracing"] = false;
|
|
450
|
-
initialOperation["exposeStreamKeyword"] = false;
|
|
451
|
-
initialOperation["responses"].forEach((resp, index) => {
|
|
452
|
-
if (getBodyFromResponse(context, ignoreDiagnostics(getHttpOperation(context.program, initialTspOperation)).responses[index])) {
|
|
453
|
-
// if there's a body, even if it's an Azure.Core model, we want to use anyObject
|
|
454
|
-
resp["type"] = KnownTypes.anyObject;
|
|
455
|
-
}
|
|
456
|
-
});
|
|
457
|
-
return initialOperation;
|
|
458
|
-
}
|
|
459
|
-
function emitLroPagingOperation(context, operation, operationGroupName) {
|
|
460
|
-
const retval = [];
|
|
461
|
-
for (const emittedOperation of emitBasicOperation(context, operation, operationGroupName)) {
|
|
462
|
-
const initialOperation = getLroInitialOperation(context, operation, operationGroupName);
|
|
463
|
-
addLroInformation(context, operation, emittedOperation, initialOperation);
|
|
464
|
-
addPagingInformation(context, operation, emittedOperation);
|
|
465
|
-
emittedOperation["discriminator"] = "lropaging";
|
|
466
|
-
retval.push(emittedOperation);
|
|
467
|
-
}
|
|
468
|
-
return retval;
|
|
469
|
-
}
|
|
470
|
-
function emitLroOperation(context, operation, operationGroupName) {
|
|
471
|
-
const retval = [];
|
|
472
|
-
for (const emittedOperation of emitBasicOperation(context, operation, operationGroupName)) {
|
|
473
|
-
const initialOperation = getLroInitialOperation(context, operation, operationGroupName);
|
|
474
|
-
addLroInformation(context, operation, emittedOperation, initialOperation);
|
|
475
|
-
retval.push(initialOperation);
|
|
476
|
-
retval.push(emittedOperation);
|
|
477
|
-
}
|
|
478
|
-
return retval;
|
|
479
|
-
}
|
|
480
|
-
function emitPagingOperation(context, operation, operationGroupName) {
|
|
481
|
-
const retval = [];
|
|
482
|
-
for (const emittedOperation of emitBasicOperation(context, operation, operationGroupName)) {
|
|
483
|
-
addPagingInformation(context, operation, emittedOperation);
|
|
484
|
-
retval.push(emittedOperation);
|
|
485
|
-
}
|
|
486
|
-
return retval;
|
|
487
|
-
}
|
|
488
|
-
function isAbstract(operation) {
|
|
489
|
-
const body = operation.parameters.body;
|
|
490
|
-
const multipleContentTypes = body !== undefined && body.contentTypes.length > 1;
|
|
491
|
-
if (!multipleContentTypes)
|
|
492
|
-
return false;
|
|
493
|
-
return body.contentTypes.some((x) => x.includes("json"));
|
|
494
|
-
}
|
|
495
|
-
function addAcceptParameter(context, operation, parameters, contentType = "application/json") {
|
|
496
|
-
const httpOperation = ignoreDiagnostics(getHttpOperation(context.program, operation));
|
|
497
|
-
if (getBodyFromResponse(context, httpOperation.responses[0]) &&
|
|
498
|
-
parameters.filter((e) => e.wireName.toLowerCase() === "accept").length === 0) {
|
|
499
|
-
parameters.push(emitAcceptParameter(false, false, contentType));
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
function emitBasicOperation(context, operation, operationGroupName) {
|
|
503
|
-
// Set up parameters for operation
|
|
504
|
-
const parameters = [];
|
|
505
|
-
if (endpointPathParameters) {
|
|
506
|
-
for (const param of endpointPathParameters) {
|
|
507
|
-
parameters.push(param);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
const httpOperation = ignoreDiagnostics(getHttpOperation(context.program, operation));
|
|
511
|
-
for (const param of httpOperation.parameters.parameters) {
|
|
512
|
-
const emittedParam = emitParameter(context, param, "Method");
|
|
513
|
-
if (isApiVersion(context, param) && apiVersionParam === undefined) {
|
|
514
|
-
apiVersionParam = emittedParam;
|
|
515
|
-
}
|
|
516
|
-
if (isSubscriptionId(context, emittedParam) && subscriptionIdParam === undefined) {
|
|
517
|
-
subscriptionIdParam = emittedParam;
|
|
518
|
-
}
|
|
519
|
-
parameters.push(emittedParam);
|
|
520
|
-
}
|
|
521
|
-
// Set up responses for operation
|
|
522
|
-
const responses = [];
|
|
523
|
-
const exceptions = [];
|
|
524
|
-
const isOverload = false;
|
|
525
|
-
const isOverriden = false;
|
|
526
|
-
for (const response of httpOperation.responses) {
|
|
527
|
-
const emittedResponse = emitResponse(context, response);
|
|
528
|
-
addAcceptParameter(context, operation, parameters, emittedResponse.defaultContentType);
|
|
529
|
-
if (response.type && response.type.kind === "Model" && isErrorOrChildOfError(context, response.type)) {
|
|
530
|
-
// * is valid status code in cadl but invalid for autorest.python
|
|
531
|
-
if (response.statusCodes === "*") {
|
|
532
|
-
exceptions.push(emittedResponse);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
else {
|
|
536
|
-
responses.push(emittedResponse);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
let bodyParameter;
|
|
540
|
-
if (httpOperation.parameters.body === undefined) {
|
|
541
|
-
bodyParameter = undefined;
|
|
542
|
-
}
|
|
543
|
-
else {
|
|
544
|
-
bodyParameter = emitBodyParameter(context, httpOperation);
|
|
545
|
-
if (parameters.filter((e) => e.wireName.toLowerCase() === "content-type").length === 0) {
|
|
546
|
-
parameters.push(emitContentTypeParameter(bodyParameter, isOverload, isOverriden));
|
|
547
|
-
}
|
|
548
|
-
if (bodyParameter.type.type === "model" && bodyParameter.type.base === "json") {
|
|
549
|
-
bodyParameter["propertyToParameterName"] = {};
|
|
550
|
-
if (!isOverload) {
|
|
551
|
-
bodyParameter.defaultToUnsetSentinel = true;
|
|
552
|
-
}
|
|
553
|
-
for (const property of bodyParameter.type.properties) {
|
|
554
|
-
bodyParameter["propertyToParameterName"][property["wireName"]] = property["clientName"];
|
|
555
|
-
parameters.push(emitFlattenedParameter(bodyParameter, property));
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
const name = camelToSnakeCase(getLibraryName(context, operation));
|
|
560
|
-
return [
|
|
561
|
-
{
|
|
562
|
-
name: name,
|
|
563
|
-
description: getDocStr(context, operation),
|
|
564
|
-
summary: getSummary(context.program, operation),
|
|
565
|
-
url: httpOperation.path,
|
|
566
|
-
method: httpOperation.verb.toUpperCase(),
|
|
567
|
-
parameters: parameters,
|
|
568
|
-
bodyParameter: bodyParameter,
|
|
569
|
-
responses: responses,
|
|
570
|
-
exceptions: exceptions,
|
|
571
|
-
groupName: operationGroupName,
|
|
572
|
-
addedOn: getAddedOnVersion(context, operation),
|
|
573
|
-
discriminator: "basic",
|
|
574
|
-
isOverload: false,
|
|
575
|
-
overloads: [],
|
|
576
|
-
apiVersions: [getAddedOnVersion(context, operation)],
|
|
577
|
-
wantTracing: true,
|
|
578
|
-
exposeStreamKeyword: true,
|
|
579
|
-
abstract: isAbstract(httpOperation),
|
|
580
|
-
internal: isInternal(context, operation) || getAccess(context, operation) === "internal",
|
|
581
|
-
crossLanguageDefinitionId: getCrossLanguageDefinitionId(operation),
|
|
582
|
-
},
|
|
583
|
-
];
|
|
584
|
-
}
|
|
585
|
-
function capitalize(name) {
|
|
586
|
-
return name[0].toUpperCase() + name.slice(1);
|
|
587
|
-
}
|
|
588
|
-
function emitOperationGroups(context, group) {
|
|
589
|
-
const operationGroups = [];
|
|
590
|
-
if (group.kind === "SdkClient") {
|
|
591
|
-
for (const operationGroup of listOperationGroups(context, group)) {
|
|
592
|
-
const name = operationGroup.type.name;
|
|
593
|
-
operationGroups.push({
|
|
594
|
-
name: name,
|
|
595
|
-
className: name,
|
|
596
|
-
propertyName: name,
|
|
597
|
-
operations: listOperationsInOperationGroup(context, operationGroup)
|
|
598
|
-
.map((o) => emitOperation(context, o, name))
|
|
599
|
-
.reduce((a, b) => a.concat(...b), []),
|
|
600
|
-
operationGroups: emitOperationGroups(context, operationGroup),
|
|
601
|
-
});
|
|
602
|
-
}
|
|
603
|
-
// mixin operation group
|
|
604
|
-
const operations = listOperationsInOperationGroup(context, group);
|
|
605
|
-
if (operations.length > 0) {
|
|
606
|
-
operationGroups.push({
|
|
607
|
-
name: "",
|
|
608
|
-
className: "",
|
|
609
|
-
propertyName: "",
|
|
610
|
-
operations: listOperationsInOperationGroup(context, group)
|
|
611
|
-
.map((o) => emitOperation(context, o, ""))
|
|
612
|
-
.reduce((a, b) => a.concat(b), []),
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
else {
|
|
617
|
-
if (group.subOperationGroups === undefined) {
|
|
618
|
-
return undefined;
|
|
619
|
-
}
|
|
620
|
-
for (const operationGroup of group.subOperationGroups) {
|
|
621
|
-
const name = operationGroup.groupPath.split(".").slice(1).join("");
|
|
622
|
-
operationGroups.push({
|
|
623
|
-
name: name,
|
|
624
|
-
className: name,
|
|
625
|
-
propertyName: operationGroup.type.name,
|
|
626
|
-
operations: listOperationsInOperationGroup(context, operationGroup)
|
|
627
|
-
.map((o) => emitOperation(context, o, name))
|
|
628
|
-
.reduce((a, b) => a.concat(...b), []),
|
|
629
|
-
operationGroups: emitOperationGroups(context, operationGroup),
|
|
630
|
-
});
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
return operationGroups;
|
|
634
|
-
}
|
|
635
|
-
function getServerHelper(context, namespace) {
|
|
636
|
-
const servers = getServers(context.program, namespace);
|
|
637
|
-
if (servers === undefined) {
|
|
638
|
-
return undefined;
|
|
639
|
-
}
|
|
640
|
-
return servers[0];
|
|
641
|
-
}
|
|
642
|
-
function hostParam(clientName = "endpoint", clientDefaultValue = null) {
|
|
643
|
-
return {
|
|
644
|
-
optional: false,
|
|
645
|
-
description: "Service host",
|
|
646
|
-
clientName: clientName,
|
|
647
|
-
clientDefaultValue: clientDefaultValue,
|
|
648
|
-
wireName: "$host",
|
|
649
|
-
location: "path",
|
|
650
|
-
type: KnownTypes.string,
|
|
651
|
-
implementation: "Client",
|
|
652
|
-
inOverload: false,
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
function emitServerParams(context, namespace) {
|
|
656
|
-
const server = getServerHelper(context, namespace);
|
|
657
|
-
if (server === undefined) {
|
|
658
|
-
return [hostParam()];
|
|
659
|
-
}
|
|
660
|
-
if (server.parameters.size > 0) {
|
|
661
|
-
const params = [];
|
|
662
|
-
for (const param of server.parameters.values()) {
|
|
663
|
-
const serverParameter = {
|
|
664
|
-
type: "endpointPath",
|
|
665
|
-
name: param.name,
|
|
666
|
-
param: param,
|
|
667
|
-
};
|
|
668
|
-
const emittedParameter = emitParameter(context, serverParameter, "Client");
|
|
669
|
-
if (!endpointPathParameters.some((p) => p.clientName === emittedParameter.clientName)) {
|
|
670
|
-
endpointPathParameters.push(emittedParameter);
|
|
671
|
-
}
|
|
672
|
-
if (isApiVersion(context, serverParameter) && apiVersionParam === undefined) {
|
|
673
|
-
apiVersionParam = emittedParameter;
|
|
674
|
-
continue;
|
|
675
|
-
}
|
|
676
|
-
params.push(emittedParameter);
|
|
677
|
-
}
|
|
678
|
-
return params;
|
|
679
|
-
}
|
|
680
|
-
else {
|
|
681
|
-
return [hostParam(context.arm ? "base_url" : "endpoint", server.url)];
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
function emitCredentialParam(context, namespace) {
|
|
685
|
-
const auth = getAuthentication(context.program, namespace);
|
|
686
|
-
if (auth) {
|
|
687
|
-
const credential_types = [];
|
|
688
|
-
for (const option of auth.options) {
|
|
689
|
-
for (const scheme of option.schemes) {
|
|
690
|
-
const type = {
|
|
691
|
-
kind: "Credential",
|
|
692
|
-
scheme: scheme,
|
|
693
|
-
};
|
|
694
|
-
credential_types.push(type);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
if (credential_types.length > 0) {
|
|
698
|
-
let type;
|
|
699
|
-
if (credential_types.length === 1) {
|
|
700
|
-
type = credential_types[0];
|
|
701
|
-
}
|
|
702
|
-
else {
|
|
703
|
-
type = {
|
|
704
|
-
kind: "CredentialTypeUnion",
|
|
705
|
-
types: credential_types,
|
|
706
|
-
};
|
|
707
|
-
}
|
|
708
|
-
const service = context.emitContext.options.flavor ? "Azure" : "cloud service";
|
|
709
|
-
return {
|
|
710
|
-
type: getType(context, type),
|
|
711
|
-
optional: false,
|
|
712
|
-
description: `Credential needed for the client to connect to ${service}.`,
|
|
713
|
-
clientName: "credential",
|
|
714
|
-
location: "other",
|
|
715
|
-
wireName: "credential",
|
|
716
|
-
implementation: "Client",
|
|
717
|
-
skipUrlEncoding: true,
|
|
718
|
-
inOverload: false,
|
|
719
|
-
};
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
return undefined;
|
|
723
|
-
}
|
|
724
|
-
function emitGlobalParameters(context, namespace) {
|
|
725
|
-
const clientParameters = emitServerParams(context, namespace);
|
|
726
|
-
const credentialParam = emitCredentialParam(context, namespace);
|
|
727
|
-
if (credentialParam) {
|
|
728
|
-
clientParameters.push(credentialParam);
|
|
729
|
-
}
|
|
730
|
-
return clientParameters;
|
|
731
|
-
}
|
|
732
|
-
function getApiVersionParameter(context) {
|
|
733
|
-
const version = getDefaultApiVersionValue(context);
|
|
734
|
-
if (apiVersionParam) {
|
|
735
|
-
return apiVersionParam;
|
|
736
|
-
}
|
|
737
|
-
else if (version !== undefined) {
|
|
738
|
-
return {
|
|
739
|
-
clientName: "api_version",
|
|
740
|
-
clientDefaultValue: version,
|
|
741
|
-
description: "Api Version",
|
|
742
|
-
implementation: "Client",
|
|
743
|
-
location: "query",
|
|
744
|
-
wireName: "api-version",
|
|
745
|
-
skipUrlEncoding: false,
|
|
746
|
-
optional: false,
|
|
747
|
-
inDocString: true,
|
|
748
|
-
inOverload: false,
|
|
749
|
-
inOverridden: false,
|
|
750
|
-
type: getConstantType(version),
|
|
751
|
-
isApiVersion: true,
|
|
752
|
-
};
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
function emitClients(context, namespace, clients) {
|
|
756
|
-
const retval = [];
|
|
757
|
-
for (const client of clients) {
|
|
758
|
-
if (getNamespace(context, client.name) !== namespace) {
|
|
759
|
-
continue;
|
|
760
|
-
}
|
|
761
|
-
const server = getServerHelper(context, client.service);
|
|
762
|
-
const emittedClient = {
|
|
763
|
-
name: client.name.split(".").at(-1),
|
|
764
|
-
description: getDocStr(context, client.type),
|
|
765
|
-
parameters: emitGlobalParameters(context, client.service),
|
|
766
|
-
operationGroups: emitOperationGroups(context, client),
|
|
767
|
-
url: server ? server.url : "",
|
|
768
|
-
apiVersions: [],
|
|
769
|
-
arm: client.arm,
|
|
770
|
-
};
|
|
771
|
-
const emittedApiVersionParam = getApiVersionParameter(context);
|
|
772
|
-
if (emittedApiVersionParam) {
|
|
773
|
-
emittedClient.parameters.push(emittedApiVersionParam);
|
|
774
|
-
}
|
|
775
|
-
if (subscriptionIdParam) {
|
|
776
|
-
emittedClient.parameters.push(subscriptionIdParam);
|
|
777
|
-
}
|
|
778
|
-
retval.push(emittedClient);
|
|
779
|
-
}
|
|
780
|
-
return retval;
|
|
781
|
-
}
|
|
782
|
-
function getServiceNamespace(context) {
|
|
783
|
-
return listServices(context.program)[0].type;
|
|
784
|
-
}
|
|
785
|
-
function getNamespace(context, clientName) {
|
|
786
|
-
// We get client namespaces from the client name. If there's a dot, we add that to the namespace
|
|
787
|
-
const submodule = clientName.split(".").slice(0, -1).join(".").toLowerCase();
|
|
788
|
-
if (!submodule) {
|
|
789
|
-
return getClientNamespaceStringHelper(context);
|
|
790
|
-
}
|
|
791
|
-
return removeUnderscoresFromNamespace(submodule);
|
|
792
|
-
}
|
|
793
|
-
function getNamespaces(context) {
|
|
794
|
-
const namespaces = new Set();
|
|
795
|
-
for (const client of listClients(context)) {
|
|
796
|
-
namespaces.add(getNamespace(context, client.name));
|
|
797
|
-
}
|
|
798
|
-
return namespaces;
|
|
799
|
-
}
|
|
800
|
-
function getClientNamespaceStringHelper(context) {
|
|
801
|
-
var _a;
|
|
802
|
-
return removeUnderscoresFromNamespace((_a = getClientNamespaceString(context)) === null || _a === void 0 ? void 0 : _a.toLowerCase());
|
|
803
|
-
}
|
|
804
|
-
function emitCodeModel(sdkContext, clients) {
|
|
805
|
-
const clientNamespaceString = getClientNamespaceStringHelper(sdkContext);
|
|
806
|
-
// Get types
|
|
807
|
-
const codeModel = {
|
|
808
|
-
namespace: clientNamespaceString,
|
|
809
|
-
subnamespaceToClients: {},
|
|
810
|
-
};
|
|
811
|
-
for (const model of getAllModels(sdkContext)) {
|
|
812
|
-
if (model.name !== "") {
|
|
813
|
-
getType(sdkContext, model);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
for (const namespace of getNamespaces(sdkContext)) {
|
|
817
|
-
if (namespace === clientNamespaceString) {
|
|
818
|
-
codeModel["clients"] = emitClients(sdkContext, namespace, clients);
|
|
819
|
-
}
|
|
820
|
-
else {
|
|
821
|
-
codeModel["subnamespaceToClients"][namespace] = emitClients(sdkContext, namespace, clients);
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
codeModel["types"] = [...typesMap.values(), ...Object.values(KnownTypes), ...simpleTypesMap.values()];
|
|
825
|
-
codeModel["crossLanguagePackageId"] = ignoreDiagnostics(getCrossLanguagePackageId(sdkContext));
|
|
826
|
-
return codeModel;
|
|
827
|
-
}
|
|
828
89
|
//# sourceMappingURL=emitter.js.map
|