@azure-tools/typespec-ts 0.49.0 → 0.49.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/CHANGELOG.md +24 -0
- package/dist/src/framework/hooks/binder.d.ts.map +1 -1
- package/dist/src/framework/hooks/binder.js +8 -17
- package/dist/src/framework/hooks/binder.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +13 -11
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +8 -0
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +10 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +10 -5
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
- package/dist/src/modular/buildProjectFiles.js +13 -10
- package/dist/src/modular/buildProjectFiles.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +43 -40
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/emitSamples.d.ts.map +1 -1
- package/dist/src/modular/emitSamples.js +9 -0
- package/dist/src/modular/emitSamples.js.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +4 -1
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.d.ts +7 -0
- package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.js +15 -0
- package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +19 -2
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +410 -39
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.js +9 -3
- package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts +12 -0
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js +259 -18
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js.map +1 -1
- package/dist/src/modular/static-helpers-metadata.d.ts +10 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
- package/dist/src/modular/static-helpers-metadata.js +10 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -1
- package/dist/src/modular/type-expressions/get-model-expression.d.ts +3 -1
- package/dist/src/modular/type-expressions/get-model-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-model-expression.js +50 -9
- package/dist/src/modular/type-expressions/get-model-expression.js.map +1 -1
- package/dist/src/modular/type-expressions/get-nullable-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-nullable-expression.js +8 -0
- package/dist/src/modular/type-expressions/get-nullable-expression.js.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.d.ts +3 -2
- package/dist/src/modular/type-expressions/get-type-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
- package/dist/src/transform/transform.d.ts.map +1 -1
- package/dist/src/transform/transform.js +10 -10
- package/dist/src/transform/transform.js.map +1 -1
- package/dist/src/transform/transformSchemas.d.ts.map +1 -1
- package/dist/src/transform/transformSchemas.js +4 -4
- package/dist/src/transform/transformSchemas.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +37 -24
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/clientUtils.d.ts +1 -1
- package/dist/src/utils/clientUtils.d.ts.map +1 -1
- package/dist/src/utils/clientUtils.js +40 -17
- package/dist/src/utils/clientUtils.js.map +1 -1
- package/dist/src/utils/crossLanguageDef.d.ts.map +1 -1
- package/dist/src/utils/crossLanguageDef.js +9 -3
- package/dist/src/utils/crossLanguageDef.js.map +1 -1
- package/dist/src/utils/interfaces.d.ts +2 -1
- package/dist/src/utils/interfaces.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +2 -2
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +15 -16
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/src/framework/hooks/binder.ts +12 -22
- package/src/index.ts +17 -10
- package/src/lib.ts +20 -0
- package/src/modular/buildOperations.ts +12 -4
- package/src/modular/buildProjectFiles.ts +19 -16
- package/src/modular/emitModels.ts +72 -44
- package/src/modular/emitSamples.ts +11 -1
- package/src/modular/helpers/clientHelpers.ts +5 -1
- package/src/modular/helpers/namingHelpers.ts +19 -0
- package/src/modular/helpers/operationHelpers.ts +533 -40
- package/src/modular/serialization/buildDeserializerFunction.ts +11 -2
- package/src/modular/serialization/buildXmlSerializerFunction.ts +375 -24
- package/src/modular/static-helpers-metadata.ts +10 -0
- package/src/modular/type-expressions/get-model-expression.ts +78 -13
- package/src/modular/type-expressions/get-nullable-expression.ts +9 -0
- package/src/modular/type-expressions/get-type-expression.ts +3 -1
- package/src/transform/transform.ts +5 -2
- package/src/transform/transformSchemas.ts +4 -1
- package/src/transform/transfromRLCOptions.ts +65 -24
- package/src/utils/clientUtils.ts +49 -16
- package/src/utils/crossLanguageDef.ts +8 -0
- package/src/utils/interfaces.ts +2 -1
- package/src/utils/modelUtils.ts +22 -18
- package/static/static-helpers/serialization/serialize-record.ts +3 -3
- package/static/static-helpers/serialization/xml-helpers.ts +91 -36
- package/static/static-helpers/urlTemplate.ts +5 -5
|
@@ -2,7 +2,7 @@ import { StructureKind } from "ts-morph";
|
|
|
2
2
|
import { NoTarget } from "@typespec/compiler";
|
|
3
3
|
import { PagingHelpers, PollingHelpers, SerializationHelpers, UrlTemplateHelpers, XmlHelpers } from "../static-helpers-metadata.js";
|
|
4
4
|
import { getNullableValidType, isSpreadBodyParameter, isTypeNullable } from "./typeHelpers.js";
|
|
5
|
-
import { getClassicalLayerPrefix, getOperationName } from "./namingHelpers.js";
|
|
5
|
+
import { getClassicalLayerPrefix, getOperationName, generateLocallyUniqueName } from "./namingHelpers.js";
|
|
6
6
|
import { getCollectionFormatHelper, hasCollectionFormatInfo, isBinaryPayload, isXmlPayload, isMultipartPayload, hasDualFormatSupport, getCollectionFormatParseHelper, getCollectionFormatFromArrayEncoding, KnownCollectionFormat } from "../../utils/operationUtil.js";
|
|
7
7
|
import { getPropertyWithOverrides, isNormalUnion, isSpecialHandledUnion } from "../serialization/serializeUtils.js";
|
|
8
8
|
import { getDocsFromDescription, getFixmeForMultilineDocs } from "./docsHelpers.js";
|
|
@@ -18,11 +18,12 @@ import { useDependencies } from "../../framework/hooks/useDependencies.js";
|
|
|
18
18
|
import { useSdkTypes } from "../../framework/hooks/sdkTypes.js";
|
|
19
19
|
import { isAzureCoreErrorType } from "../../utils/modelUtils.js";
|
|
20
20
|
import { getTypeExpression, normalizeModelPropertyName } from "../type-expressions/get-type-expression.js";
|
|
21
|
-
import { isHttpMetadata, isReadOnly } from "@azure-tools/typespec-client-generator-core";
|
|
22
|
-
import { isMetadata } from "@typespec/http";
|
|
21
|
+
import { getClientOptions, isHttpMetadata, isReadOnly } from "@azure-tools/typespec-client-generator-core";
|
|
22
|
+
import { isHeader, isMetadata } from "@typespec/http";
|
|
23
23
|
import { useContext } from "../../contextManager.js";
|
|
24
24
|
import { isExtensibleEnum } from "../type-expressions/get-enum-expression.js";
|
|
25
|
-
|
|
25
|
+
import { emitInlineModel } from "../type-expressions/get-model-expression.js";
|
|
26
|
+
export function getSendPrivateFunction(dpgContext, method, clientType, client) {
|
|
26
27
|
const operation = method[1];
|
|
27
28
|
const parameters = getOperationSignatureParameters(dpgContext, method, clientType);
|
|
28
29
|
const { name } = getOperationName(operation);
|
|
@@ -44,12 +45,21 @@ export function getSendPrivateFunction(dpgContext, method, clientType) {
|
|
|
44
45
|
...getQueryParameters(dpgContext, operation)
|
|
45
46
|
];
|
|
46
47
|
if (urlTemplateParams.length > 0) {
|
|
47
|
-
|
|
48
|
+
// Generate a unique local variable name that doesn't conflict with parameter names
|
|
49
|
+
const paramNames = new Set(parameters.map((p) => p.name));
|
|
50
|
+
const pathVarName = generateLocallyUniqueName("path", paramNames);
|
|
51
|
+
const includeRootSlash = client
|
|
52
|
+
? getClientOptions(client, "includeRootSlash") !== false
|
|
53
|
+
: true;
|
|
54
|
+
const uriTemplate = includeRootSlash
|
|
55
|
+
? operation.operation.uriTemplate
|
|
56
|
+
: operation.operation.uriTemplate.replace(/^\//, "");
|
|
57
|
+
statements.push(`const ${pathVarName} = ${resolveReference(UrlTemplateHelpers.parseTemplate)}("${uriTemplate}", {
|
|
48
58
|
${urlTemplateParams.join(",\n")}
|
|
49
59
|
},{
|
|
50
60
|
allowReserved: ${optionalParamName}?.requestOptions?.skipUrlEncoding
|
|
51
61
|
});`);
|
|
52
|
-
pathStr =
|
|
62
|
+
pathStr = pathVarName;
|
|
53
63
|
}
|
|
54
64
|
statements.push(`return context.path(${pathStr}).${operationMethod}({...${resolveReference(dependencies.operationOptionsToRequestParameters)}(${optionalParamName}), ${getHeaderAndBodyParameters(dpgContext, operation, optionalParamName)}});`);
|
|
55
65
|
return {
|
|
@@ -58,7 +68,7 @@ export function getSendPrivateFunction(dpgContext, method, clientType) {
|
|
|
58
68
|
};
|
|
59
69
|
}
|
|
60
70
|
export function getDeserializePrivateFunction(context, operation) {
|
|
61
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
71
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
62
72
|
const { name } = getOperationName(operation);
|
|
63
73
|
const dependencies = useDependencies();
|
|
64
74
|
const PathUncheckedResponseReference = resolveReference(dependencies.PathUncheckedResponse);
|
|
@@ -70,6 +80,7 @@ export function getDeserializePrivateFunction(context, operation) {
|
|
|
70
80
|
];
|
|
71
81
|
const isLroOnly = isLroOnlyOperation(operation);
|
|
72
82
|
const isLroAndPaging = isLroAndPagingOperation(operation);
|
|
83
|
+
const isPagingOnly = isPagingOnlyOperation(operation);
|
|
73
84
|
// TODO: Support operation overloads
|
|
74
85
|
// TODO: Support multiple responses
|
|
75
86
|
const response = operation.response;
|
|
@@ -78,12 +89,20 @@ export function getDeserializePrivateFunction(context, operation) {
|
|
|
78
89
|
if (isLroOnly || isLroAndPaging) {
|
|
79
90
|
returnType = buildLroReturnType(context, operation);
|
|
80
91
|
}
|
|
81
|
-
else if (
|
|
92
|
+
else if (isPagingOnly && (restResponse === null || restResponse === void 0 ? void 0 : restResponse.type)) {
|
|
93
|
+
// For paging operations, use the full response model (e.g., _OperationListResult)
|
|
94
|
+
// instead of just the array element type
|
|
82
95
|
returnType = {
|
|
83
96
|
name: (_a = restResponse.name) !== null && _a !== void 0 ? _a : "",
|
|
84
97
|
type: getTypeExpression(context, restResponse.type)
|
|
85
98
|
};
|
|
86
99
|
}
|
|
100
|
+
else if (response.type) {
|
|
101
|
+
returnType = {
|
|
102
|
+
name: (_b = response.name) !== null && _b !== void 0 ? _b : "",
|
|
103
|
+
type: getTypeExpression(context, response.type)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
87
106
|
else {
|
|
88
107
|
returnType = { name: "", type: "void" };
|
|
89
108
|
}
|
|
@@ -99,12 +118,12 @@ export function getDeserializePrivateFunction(context, operation) {
|
|
|
99
118
|
statements.push(`const expectedStatuses = ${getExpectedStatuses(operation)};`);
|
|
100
119
|
statements.push(`if(!expectedStatuses.includes(result.status)){`, `${getExceptionThrowStatement(context, operation)}`, "}");
|
|
101
120
|
const deserializedType = isLroOnly || isLroAndPaging
|
|
102
|
-
? (
|
|
103
|
-
: restResponse
|
|
121
|
+
? (_d = (_c = operation === null || operation === void 0 ? void 0 : operation.lroMetadata) === null || _c === void 0 ? void 0 : _c.finalResponse) === null || _d === void 0 ? void 0 : _d.result
|
|
122
|
+
: isPagingOnly && (restResponse === null || restResponse === void 0 ? void 0 : restResponse.type)
|
|
104
123
|
? restResponse.type
|
|
105
124
|
: response.type;
|
|
106
125
|
const lroSubSegments = isLroOnly
|
|
107
|
-
? (
|
|
126
|
+
? (_f = (_e = operation === null || operation === void 0 ? void 0 : operation.lroMetadata) === null || _e === void 0 ? void 0 : _e.finalResponse) === null || _f === void 0 ? void 0 : _f.resultSegments
|
|
108
127
|
: undefined;
|
|
109
128
|
let lroSubPath;
|
|
110
129
|
if (lroSubSegments && lroSubSegments.length > 0) {
|
|
@@ -123,7 +142,7 @@ export function getDeserializePrivateFunction(context, operation) {
|
|
|
123
142
|
`);
|
|
124
143
|
}
|
|
125
144
|
if (deserializedType) {
|
|
126
|
-
const contentTypes = (
|
|
145
|
+
const contentTypes = (_h = (_g = operation.operation.responses[0]) === null || _g === void 0 ? void 0 : _g.contentTypes) !== null && _h !== void 0 ? _h : [];
|
|
127
146
|
const isXml = isXmlPayload(contentTypes);
|
|
128
147
|
const isDualFormat = hasDualFormatSupport(contentTypes);
|
|
129
148
|
const isMultipart = isMultipartPayload(contentTypes);
|
|
@@ -216,9 +235,48 @@ export function getDeserializePrivateFunction(context, operation) {
|
|
|
216
235
|
statements
|
|
217
236
|
};
|
|
218
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Generates a private function to deserialize response headers.
|
|
240
|
+
* Only generated when response headers are present and include-headers-in-response is enabled.
|
|
241
|
+
*/
|
|
242
|
+
export function getDeserializeHeadersPrivateFunction(context, operation) {
|
|
243
|
+
var _a;
|
|
244
|
+
const responseHeaders = getResponseHeaders(operation.operation.responses);
|
|
245
|
+
const isResponseHeadersEnabled = ((_a = context.rlcOptions) === null || _a === void 0 ? void 0 : _a.includeHeadersInResponse) === true;
|
|
246
|
+
// Only generate if headers exist and feature is enabled
|
|
247
|
+
if (responseHeaders.length === 0 || !isResponseHeadersEnabled) {
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
const { name } = getOperationName(operation);
|
|
251
|
+
const dependencies = useDependencies();
|
|
252
|
+
const PathUncheckedResponseReference = resolveReference(dependencies.PathUncheckedResponse);
|
|
253
|
+
const parameters = [
|
|
254
|
+
{
|
|
255
|
+
name: "result",
|
|
256
|
+
type: PathUncheckedResponseReference
|
|
257
|
+
}
|
|
258
|
+
];
|
|
259
|
+
const returnType = buildHeaderOnlyResponseType(context, responseHeaders);
|
|
260
|
+
const functionStatement = {
|
|
261
|
+
isAsync: false,
|
|
262
|
+
isExported: true,
|
|
263
|
+
name: `_${name}DeserializeHeaders`,
|
|
264
|
+
parameters,
|
|
265
|
+
returnType
|
|
266
|
+
};
|
|
267
|
+
const statements = [];
|
|
268
|
+
statements.push(`return ${buildHeaderOnlyResponseValue(context, responseHeaders)};`);
|
|
269
|
+
return {
|
|
270
|
+
...functionStatement,
|
|
271
|
+
statements
|
|
272
|
+
};
|
|
273
|
+
}
|
|
219
274
|
function getExceptionDetails(context, operation) {
|
|
275
|
+
var _a;
|
|
220
276
|
const customized = [];
|
|
221
277
|
let defaultDeserializer;
|
|
278
|
+
let defaultXmlDeserializer;
|
|
279
|
+
let defaultIsXmlOnly;
|
|
222
280
|
for (const exception of operation.operation.exceptions) {
|
|
223
281
|
if (!exception.type) {
|
|
224
282
|
continue;
|
|
@@ -232,56 +290,124 @@ function getExceptionDetails(context, operation) {
|
|
|
232
290
|
typeof deserializeFunctionName !== "string") {
|
|
233
291
|
continue;
|
|
234
292
|
}
|
|
293
|
+
// Check if the exception type has XML serialization support
|
|
294
|
+
// Use exception contentTypes when available, otherwise check the type itself
|
|
295
|
+
const exceptionContentTypes = (_a = exception.contentTypes) !== null && _a !== void 0 ? _a : [];
|
|
296
|
+
const exceptionIsXml = isXmlPayload(exceptionContentTypes);
|
|
297
|
+
const exceptionIsDualFormat = hasDualFormatSupport(exceptionContentTypes);
|
|
298
|
+
const typeHasXml = exception.type.kind === "model" && hasXmlSerialization(exception.type);
|
|
299
|
+
let xmlDeserializerName;
|
|
300
|
+
if (exception.type.kind === "model" && (typeHasXml || exceptionIsXml)) {
|
|
301
|
+
const xmlName = buildXmlModelDeserializer(context, exception.type, {
|
|
302
|
+
nameOnly: true,
|
|
303
|
+
skipDiscriminatedUnionSuffix: false
|
|
304
|
+
});
|
|
305
|
+
if (typeof xmlName === "string") {
|
|
306
|
+
xmlDeserializerName = xmlName;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// XML-only when all content types are XML (no JSON support)
|
|
310
|
+
const isXmlOnly = xmlDeserializerName !== undefined &&
|
|
311
|
+
exceptionIsXml &&
|
|
312
|
+
!exceptionIsDualFormat;
|
|
235
313
|
if (statusCode === "*") {
|
|
236
314
|
defaultDeserializer = deserializeFunctionName;
|
|
315
|
+
defaultXmlDeserializer = xmlDeserializerName;
|
|
316
|
+
defaultIsXmlOnly = isXmlOnly;
|
|
237
317
|
}
|
|
238
318
|
else if (typeof statusCode === "number") {
|
|
239
319
|
customized.push({
|
|
240
320
|
start: statusCode,
|
|
241
|
-
deserializer: deserializeFunctionName
|
|
321
|
+
deserializer: deserializeFunctionName,
|
|
322
|
+
xmlDeserializer: xmlDeserializerName,
|
|
323
|
+
isXmlOnly
|
|
242
324
|
});
|
|
243
325
|
}
|
|
244
326
|
else {
|
|
245
327
|
customized.push({
|
|
246
328
|
start: statusCode.start,
|
|
247
329
|
end: statusCode.end,
|
|
248
|
-
deserializer: deserializeFunctionName
|
|
330
|
+
deserializer: deserializeFunctionName,
|
|
331
|
+
xmlDeserializer: xmlDeserializerName,
|
|
332
|
+
isXmlOnly
|
|
249
333
|
});
|
|
250
334
|
}
|
|
251
335
|
}
|
|
252
|
-
return {
|
|
336
|
+
return {
|
|
337
|
+
customized,
|
|
338
|
+
defaultDeserializer,
|
|
339
|
+
defaultXmlDeserializer,
|
|
340
|
+
defaultIsXmlOnly
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
function getExceptionDeserializeExpr(exception) {
|
|
344
|
+
if (!exception.xmlDeserializer) {
|
|
345
|
+
return `${exception.deserializer}(result.body)`;
|
|
346
|
+
}
|
|
347
|
+
if (exception.isXmlOnly) {
|
|
348
|
+
return `${exception.xmlDeserializer}(result.body)`;
|
|
349
|
+
}
|
|
350
|
+
return `isXml ? ${exception.xmlDeserializer}(result.body) : ${exception.deserializer}(result.body)`;
|
|
253
351
|
}
|
|
254
352
|
function getExceptionThrowStatement(context, operation) {
|
|
255
353
|
const statements = [];
|
|
256
354
|
const createRestErrorReference = resolveReference(useDependencies().createRestError);
|
|
257
|
-
const { customized, defaultDeserializer } = getExceptionDetails(context, operation);
|
|
355
|
+
const { customized, defaultDeserializer, defaultXmlDeserializer, defaultIsXmlOnly } = getExceptionDetails(context, operation);
|
|
356
|
+
// Check if any exception has XML deserialization support that requires runtime content-type check
|
|
357
|
+
const hasAnyDualFormatXml = (defaultXmlDeserializer !== undefined && !defaultIsXmlOnly) ||
|
|
358
|
+
customized.some((e) => e.xmlDeserializer !== undefined && !e.isXmlOnly);
|
|
258
359
|
if (customized.length > 0) {
|
|
259
360
|
statements.push(`const error = ${createRestErrorReference}(result);`);
|
|
361
|
+
if (hasAnyDualFormatXml) {
|
|
362
|
+
const isXmlContentTypeRef = resolveReference(XmlHelpers.isXmlContentType);
|
|
363
|
+
statements.push(`const responseContentType = result.headers?.["content-type"] ?? "";`);
|
|
364
|
+
statements.push(`const isXml = ${isXmlContentTypeRef}(responseContentType);`);
|
|
365
|
+
}
|
|
260
366
|
statements.push(`const statusCode = Number.parseInt(result.status);`);
|
|
261
367
|
const stats = customized.map((exception) => {
|
|
368
|
+
const deserializeExpr = getExceptionDeserializeExpr(exception);
|
|
262
369
|
if (exception.end) {
|
|
263
370
|
return `if(statusCode >= ${exception.start} && statusCode <= ${exception.end}) {
|
|
264
|
-
error.details = ${
|
|
371
|
+
error.details = ${deserializeExpr};
|
|
265
372
|
}`;
|
|
266
373
|
}
|
|
267
374
|
else {
|
|
268
375
|
return `if(statusCode === ${exception.start}) {
|
|
269
|
-
error.details = ${
|
|
376
|
+
error.details = ${deserializeExpr};
|
|
270
377
|
}`;
|
|
271
378
|
}
|
|
272
379
|
});
|
|
273
380
|
statements.push(stats.join("\nelse "));
|
|
274
381
|
if (defaultDeserializer) {
|
|
382
|
+
const defaultDeserializeExpr = !defaultXmlDeserializer
|
|
383
|
+
? `${defaultDeserializer}(result.body)`
|
|
384
|
+
: defaultIsXmlOnly
|
|
385
|
+
? `${defaultXmlDeserializer}(result.body)`
|
|
386
|
+
: `isXml ? ${defaultXmlDeserializer}(result.body) : ${defaultDeserializer}(result.body)`;
|
|
275
387
|
statements.push(`else {
|
|
276
|
-
error.details = ${
|
|
388
|
+
error.details = ${defaultDeserializeExpr};
|
|
277
389
|
}`);
|
|
278
390
|
}
|
|
279
391
|
statements.push("throw error;");
|
|
280
392
|
}
|
|
281
393
|
else {
|
|
282
394
|
if (defaultDeserializer) {
|
|
283
|
-
|
|
284
|
-
|
|
395
|
+
if (defaultXmlDeserializer) {
|
|
396
|
+
if (defaultIsXmlOnly) {
|
|
397
|
+
statements.push(`const error = ${createRestErrorReference}(result);
|
|
398
|
+
error.details = ${defaultXmlDeserializer}(result.body);`);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
const isXmlContentTypeRef = resolveReference(XmlHelpers.isXmlContentType);
|
|
402
|
+
statements.push(`const error = ${createRestErrorReference}(result);
|
|
403
|
+
const responseContentType = result.headers?.["content-type"] ?? "";
|
|
404
|
+
error.details = ${isXmlContentTypeRef}(responseContentType) ? ${defaultXmlDeserializer}(result.body) : ${defaultDeserializer}(result.body);`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
statements.push(`const error = ${createRestErrorReference}(result);
|
|
409
|
+
error.details = ${defaultDeserializer}(result.body);`);
|
|
410
|
+
}
|
|
285
411
|
statements.push("throw error;");
|
|
286
412
|
}
|
|
287
413
|
else {
|
|
@@ -309,7 +435,6 @@ function getOperationSignatureParameters(context, method, clientType) {
|
|
|
309
435
|
((_a = param.methodParameterSegments[0]) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
|
|
310
436
|
((_b = param.methodParameterSegments[0]) === null || _b === void 0 ? void 0 : _b[0]) === p);
|
|
311
437
|
})[0]) === null || _a === void 0 ? void 0 : _a.kind) !== "cookie" &&
|
|
312
|
-
p.clientDefaultValue === undefined &&
|
|
313
438
|
!p.optional &&
|
|
314
439
|
!(p.isGeneratedName &&
|
|
315
440
|
(p.name === "contentType" || p.name === "accept"));
|
|
@@ -339,7 +464,7 @@ function getOperationSignatureParameters(context, method, clientType) {
|
|
|
339
464
|
* This operation builds and returns the function declaration for an operation.
|
|
340
465
|
*/
|
|
341
466
|
export function getOperationFunction(context, method, clientType) {
|
|
342
|
-
var _a, _b;
|
|
467
|
+
var _a, _b, _c, _d;
|
|
343
468
|
const operation = method[1];
|
|
344
469
|
// Extract required parameters
|
|
345
470
|
const parameters = getOperationSignatureParameters(context, method, clientType);
|
|
@@ -358,12 +483,34 @@ export function getOperationFunction(context, method, clientType) {
|
|
|
358
483
|
}
|
|
359
484
|
// TODO: Support operation overloads
|
|
360
485
|
const response = operation.response;
|
|
486
|
+
const responseHeaders = getResponseHeaders(operation.operation.responses);
|
|
487
|
+
const hasHeaderOnlyResponse = !response.type && responseHeaders.length > 0;
|
|
488
|
+
const isResponseHeadersEnabled = ((_a = context.rlcOptions) === null || _a === void 0 ? void 0 : _a.includeHeadersInResponse) === true;
|
|
361
489
|
let returnType = { name: "", type: "void" };
|
|
362
490
|
if (response.type) {
|
|
363
491
|
const type = response.type;
|
|
492
|
+
// If feature flag enabled, we'll append the response headers to the operation response type.
|
|
493
|
+
if (type.kind === "model" &&
|
|
494
|
+
responseHeaders.length > 0 &&
|
|
495
|
+
isResponseHeadersEnabled) {
|
|
496
|
+
// Build a composite type that includes both model and additional header properties
|
|
497
|
+
returnType = {
|
|
498
|
+
name: (_b = type.name) !== null && _b !== void 0 ? _b : "",
|
|
499
|
+
type: `${buildCompositeResponseType(context, type, responseHeaders)}`
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
returnType = {
|
|
504
|
+
name: (_c = type.name) !== null && _c !== void 0 ? _c : "",
|
|
505
|
+
type: getTypeExpression(context, type)
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
else if (hasHeaderOnlyResponse && isResponseHeadersEnabled) {
|
|
510
|
+
// Here we handle returning headers when the operation return type is void
|
|
364
511
|
returnType = {
|
|
365
|
-
name:
|
|
366
|
-
type:
|
|
512
|
+
name: "",
|
|
513
|
+
type: `${buildHeaderOnlyResponseType(context, responseHeaders)}`
|
|
367
514
|
};
|
|
368
515
|
}
|
|
369
516
|
const { name, fixme = [] } = getOperationName(operation);
|
|
@@ -381,17 +528,37 @@ export function getOperationFunction(context, method, clientType) {
|
|
|
381
528
|
returnType: `Promise<${returnType.type}>`
|
|
382
529
|
};
|
|
383
530
|
const statements = [];
|
|
531
|
+
// Generate unique local variable names that don't conflict with parameter names
|
|
532
|
+
const paramNames = new Set(parameters.map((p) => p.name));
|
|
533
|
+
const resultVarName = generateLocallyUniqueName("result", paramNames);
|
|
384
534
|
const parameterList = parameters.map((p) => p.name).join(", ");
|
|
385
535
|
// Special case for binary-only bodies: use helper to call streaming methods so that Core doesn't poison the response body by
|
|
386
536
|
// doing a UTF-8 decode on the raw bytes.
|
|
387
|
-
if (((
|
|
388
|
-
|
|
389
|
-
statements.push(`const
|
|
537
|
+
if (((_d = response === null || response === void 0 ? void 0 : response.type) === null || _d === void 0 ? void 0 : _d.kind) === "bytes" && response.type.encode === "bytes") {
|
|
538
|
+
const streamableMethodVarName = generateLocallyUniqueName("streamableMethod", paramNames);
|
|
539
|
+
statements.push(`const ${streamableMethodVarName} = _${name}Send(${parameterList});`);
|
|
540
|
+
statements.push(`const ${resultVarName} = await ${resolveReference(SerializationHelpers.getBinaryResponse)}(${streamableMethodVarName});`);
|
|
390
541
|
}
|
|
391
542
|
else {
|
|
392
|
-
statements.push(`const
|
|
543
|
+
statements.push(`const ${resultVarName} = await _${name}Send(${parameterList});`);
|
|
544
|
+
}
|
|
545
|
+
// If the response has headers and the feature flag to include headers in response is enabled, build the headers object and include it in the return value
|
|
546
|
+
if (responseHeaders.length > 0 && isResponseHeadersEnabled) {
|
|
547
|
+
const headersVarName = generateLocallyUniqueName("headers", paramNames);
|
|
548
|
+
statements.push(`const ${headersVarName} = _${name}DeserializeHeaders(result);`);
|
|
549
|
+
// If there is no body payload just return the headers
|
|
550
|
+
if (hasHeaderOnlyResponse) {
|
|
551
|
+
statements.push(`return {...${headersVarName} };`);
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
const payloadVarName = generateLocallyUniqueName("payload", paramNames);
|
|
555
|
+
statements.push(`const ${payloadVarName} = await _${name}Deserialize(${resultVarName});`);
|
|
556
|
+
statements.push(`return { ...${payloadVarName}, ...${headersVarName} };`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
statements.push(`return _${name}Deserialize(${resultVarName});`);
|
|
393
561
|
}
|
|
394
|
-
statements.push(`return _${name}Deserialize(result);`);
|
|
395
562
|
return {
|
|
396
563
|
...functionStatement,
|
|
397
564
|
statements
|
|
@@ -434,7 +601,7 @@ function getLroOnlyOperationFunction(context, method, clientType, optionalParamN
|
|
|
434
601
|
allowedFinalLocation.includes(lroMetadata === null || lroMetadata === void 0 ? void 0 : lroMetadata.finalStateVia)
|
|
435
602
|
? `resourceLocationConfig: "${lroMetadata === null || lroMetadata === void 0 ? void 0 : lroMetadata.finalStateVia}",`
|
|
436
603
|
: "";
|
|
437
|
-
const apiVersion = getApiVersionExpression(operation);
|
|
604
|
+
const apiVersion = getApiVersionExpression(context, operation);
|
|
438
605
|
const statements = [];
|
|
439
606
|
statements.push(`
|
|
440
607
|
|
|
@@ -460,7 +627,7 @@ function getLroAndPagingOperationFunction(context, method, clientType, optionalP
|
|
|
460
627
|
const { name, fixme = [] } = getOperationName(operation);
|
|
461
628
|
const returnType = buildLroPagingReturnType(context, operation);
|
|
462
629
|
// Get apiVersion expression for both LRO poller and paging options
|
|
463
|
-
const apiVersion = getApiVersionExpression(operation);
|
|
630
|
+
const apiVersion = getApiVersionExpression(context, operation);
|
|
464
631
|
// Build paging options from metadata
|
|
465
632
|
const pagingOptions = [
|
|
466
633
|
operation.response.resultSegments &&
|
|
@@ -593,7 +760,7 @@ function getPagingOnlyOperationFunction(context, method, clientType) {
|
|
|
593
760
|
}).join(".");
|
|
594
761
|
// Check for nextLinkVerb from TCGC pagingMetadata (supports @Legacy.nextLinkVerb decorator)
|
|
595
762
|
const nextLinkMethod = operation.pagingMetadata.nextLinkVerb;
|
|
596
|
-
const apiVersion = getApiVersionExpression(operation);
|
|
763
|
+
const apiVersion = getApiVersionExpression(context, operation);
|
|
597
764
|
if (itemName) {
|
|
598
765
|
options.push(`itemName: "${itemName}"`);
|
|
599
766
|
}
|
|
@@ -726,10 +893,23 @@ function buildBodyParameter(context, bodyParameter, optionalParamName = "options
|
|
|
726
893
|
});
|
|
727
894
|
}
|
|
728
895
|
const bodyParamName = normalizeName(bodyParameter.name, NameType.Parameter, true);
|
|
729
|
-
|
|
896
|
+
let bodyNameExpression = bodyParameter.optional
|
|
730
897
|
? `${optionalParamName}["${bodyParamName}"]`
|
|
731
898
|
: bodyParamName;
|
|
732
|
-
|
|
899
|
+
// Check if body parameter has a client default value with matching type
|
|
900
|
+
const hasClientDefault = bodyParameter.optional &&
|
|
901
|
+
bodyParameter.clientDefaultValue !== undefined &&
|
|
902
|
+
isDefaultValueTypeMatch(bodyParameter, bodyParameter.clientDefaultValue);
|
|
903
|
+
// Apply client default value if present for optional body parameters
|
|
904
|
+
if (hasClientDefault) {
|
|
905
|
+
const formattedDefault = formatDefaultValue(bodyParameter.clientDefaultValue);
|
|
906
|
+
bodyNameExpression = `(${bodyNameExpression} ?? ${formattedDefault})`;
|
|
907
|
+
}
|
|
908
|
+
// Only apply nullOrUndefinedPrefix if there's no client default value
|
|
909
|
+
// because the default value already handles null/undefined cases
|
|
910
|
+
const nullOrUndefinedPrefix = hasClientDefault
|
|
911
|
+
? ""
|
|
912
|
+
: getPropertySerializationPrefix(context, bodyParameter, bodyParameter.optional ? optionalParamName : undefined);
|
|
733
913
|
// For dual-format operations, check the contentType option at runtime
|
|
734
914
|
if (isDualFormat &&
|
|
735
915
|
bodyType.kind === "model" &&
|
|
@@ -771,6 +951,7 @@ function getEncodingFormat(type) {
|
|
|
771
951
|
* This function helps with renames, translating client names to rest api names
|
|
772
952
|
*/
|
|
773
953
|
export function getParameterMap(context, param, optionalParamName = "options") {
|
|
954
|
+
var _a;
|
|
774
955
|
// Use lowercase for header names since HTTP headers are case-insensitive
|
|
775
956
|
const serializedName = param.kind === "header"
|
|
776
957
|
? getHeaderSerializedName(param)
|
|
@@ -780,6 +961,10 @@ export function getParameterMap(context, param, optionalParamName = "options") {
|
|
|
780
961
|
}
|
|
781
962
|
// Special case for api-version parameters with default values
|
|
782
963
|
if (param.isApiVersionParam && param.clientDefaultValue) {
|
|
964
|
+
// For multi-service, use only the default value (don't reference context.apiVersion)
|
|
965
|
+
if ((_a = context.rlcOptions) === null || _a === void 0 ? void 0 : _a.isMultiService) {
|
|
966
|
+
return `"${serializedName}": "${param.clientDefaultValue}"`;
|
|
967
|
+
}
|
|
783
968
|
return `"${serializedName}": ${param.onClient ? "context." : ""}${param.name} ?? "${param.clientDefaultValue}"`;
|
|
784
969
|
}
|
|
785
970
|
if (hasCollectionFormatInfo(param.kind, param.collectionFormat)) {
|
|
@@ -822,7 +1007,7 @@ function getContentTypeValue(param, optionalParamName = "options") {
|
|
|
822
1007
|
}
|
|
823
1008
|
else {
|
|
824
1009
|
return `contentType: ${!param.optional
|
|
825
|
-
?
|
|
1010
|
+
? normalizeName(param.name, NameType.Property)
|
|
826
1011
|
: `${optionalParamName}.` + param.name + " as any"}`;
|
|
827
1012
|
}
|
|
828
1013
|
}
|
|
@@ -851,12 +1036,18 @@ function isOptional(param) {
|
|
|
851
1036
|
}
|
|
852
1037
|
function getOptional(context, param, optionalParamName, serializedName) {
|
|
853
1038
|
const paramName = `${param.onClient ? "context." : `${optionalParamName}?.`}${param.name}`;
|
|
1039
|
+
// Apply client default value if present and type matches
|
|
1040
|
+
const defaultSuffix = param.clientDefaultValue !== undefined &&
|
|
1041
|
+
isDefaultValueTypeMatch(param, param.clientDefaultValue)
|
|
1042
|
+
? ` ?? ${formatDefaultValue(param.clientDefaultValue)}`
|
|
1043
|
+
: "";
|
|
854
1044
|
if (param.type.kind === "model") {
|
|
855
1045
|
const propertiesStr = getRequestModelMapping(context, { ...param.type, optional: param.optional }, paramName + "?.");
|
|
856
1046
|
const serializeContent = `{${propertiesStr.join(",")}}`;
|
|
857
1047
|
return `"${serializedName}": ${serializeContent}`;
|
|
858
1048
|
}
|
|
859
|
-
|
|
1049
|
+
const serializedValue = serializeRequestValue(context, param.type, paramName, false, getEncodeForType(param.type), serializedName, true);
|
|
1050
|
+
return `"${serializedName}": ${serializedValue}${defaultSuffix}`;
|
|
860
1051
|
}
|
|
861
1052
|
/**
|
|
862
1053
|
* Get the encode for SDK type
|
|
@@ -1068,7 +1259,7 @@ export function getRequestModelProperties(context, modelPropertyType, propertyPa
|
|
|
1068
1259
|
export function getRequestModelMapping(context, modelPropertyType, propertyPath = "body", overrides, enableFlatten = true) {
|
|
1069
1260
|
return getRequestModelProperties(context, modelPropertyType, propertyPath, overrides, enableFlatten).map(([name, value]) => `"${name}": ${value}`);
|
|
1070
1261
|
}
|
|
1071
|
-
function getPropertySerializedName(property) {
|
|
1262
|
+
export function getPropertySerializedName(property) {
|
|
1072
1263
|
var _a, _b;
|
|
1073
1264
|
return ((_b = (property.kind === "property"
|
|
1074
1265
|
? (_a = property.serializationOptions.json) === null || _a === void 0 ? void 0 : _a.name
|
|
@@ -1227,6 +1418,63 @@ export function serializeRequestValue(context, type, clientValue, required, form
|
|
|
1227
1418
|
return clientValue;
|
|
1228
1419
|
}
|
|
1229
1420
|
}
|
|
1421
|
+
/**
|
|
1422
|
+
* Wrapper of deserializeResponseValue, this is used to handle the special cases for response header deserialization, since response header only supports primitive types, we will have a simpler deserialization logic comparing to response body, and we also need to handle the null/undefined cases differently since if a header is missing, the value will be undefined instead of null.
|
|
1423
|
+
* Note: that this has been added to isolate these changes behind the feature flag. Once the feature flag is removed, we can consider merging this back to deserializeResponseValue if the special handling logic is not needed anymore.
|
|
1424
|
+
*/
|
|
1425
|
+
export function deserializeResponseHeadersValue(context, type, restValue, required, format, recursionDepth = 0) {
|
|
1426
|
+
const nullOrUndefinedPrefix = isTypeNullable(type) || getOptionalForType(type) || !required
|
|
1427
|
+
? `${restValue} === undefined || ${restValue} === null ? ${restValue}: `
|
|
1428
|
+
: "";
|
|
1429
|
+
switch (type.kind) {
|
|
1430
|
+
case "constant":
|
|
1431
|
+
return `${restValue} as any`;
|
|
1432
|
+
case "boolean":
|
|
1433
|
+
return `${nullOrUndefinedPrefix} ${restValue}.trim().toLowerCase() === "true"`;
|
|
1434
|
+
case "int16":
|
|
1435
|
+
case "int32":
|
|
1436
|
+
case "int64":
|
|
1437
|
+
case "uint16":
|
|
1438
|
+
case "uint32":
|
|
1439
|
+
case "uint64":
|
|
1440
|
+
case "float":
|
|
1441
|
+
case "decimal":
|
|
1442
|
+
case "decimal128":
|
|
1443
|
+
case "float32":
|
|
1444
|
+
case "float64":
|
|
1445
|
+
case "int8":
|
|
1446
|
+
case "integer":
|
|
1447
|
+
case "numeric":
|
|
1448
|
+
case "safeint":
|
|
1449
|
+
case "uint8":
|
|
1450
|
+
return `${nullOrUndefinedPrefix} Number(${restValue})`;
|
|
1451
|
+
case "enum":
|
|
1452
|
+
if (isNormalUnion(type)) {
|
|
1453
|
+
return `${restValue}`;
|
|
1454
|
+
}
|
|
1455
|
+
else if (isSpecialHandledUnion(type)) {
|
|
1456
|
+
const deserializeFunctionName = type
|
|
1457
|
+
? buildModelDeserializer(context, getNullableValidType(type), {
|
|
1458
|
+
nameOnly: true,
|
|
1459
|
+
skipDiscriminatedUnionSuffix: false
|
|
1460
|
+
})
|
|
1461
|
+
: undefined;
|
|
1462
|
+
if (deserializeFunctionName) {
|
|
1463
|
+
return `${deserializeFunctionName}(${restValue})`;
|
|
1464
|
+
}
|
|
1465
|
+
else {
|
|
1466
|
+
return `${restValue} as any`;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
else {
|
|
1470
|
+
return `${restValue} as any`;
|
|
1471
|
+
}
|
|
1472
|
+
default: {
|
|
1473
|
+
const val = deserializeResponseValue(context, type, restValue, true, format, recursionDepth);
|
|
1474
|
+
return `${nullOrUndefinedPrefix} ${val}`;
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1230
1478
|
/**
|
|
1231
1479
|
* This function helps converting strings into JS complex types recursively.
|
|
1232
1480
|
* We need to drill down into Array elements to make sure that the element type is
|
|
@@ -1391,6 +1639,43 @@ export function getAllAncestors(type) {
|
|
|
1391
1639
|
}
|
|
1392
1640
|
return ancestors;
|
|
1393
1641
|
}
|
|
1642
|
+
/**
|
|
1643
|
+
* Checks if a clientDefaultValue type matches the parameter type.
|
|
1644
|
+
* Returns true if the default value type is compatible with the parameter type.
|
|
1645
|
+
*/
|
|
1646
|
+
function isDefaultValueTypeMatch(param, defaultValue) {
|
|
1647
|
+
const defaultType = typeof defaultValue;
|
|
1648
|
+
const paramType = param.type;
|
|
1649
|
+
// Map JavaScript types to TypeSpec types
|
|
1650
|
+
if (defaultType === "string") {
|
|
1651
|
+
return paramType.kind === "string" || paramType.kind === "enum";
|
|
1652
|
+
}
|
|
1653
|
+
if (defaultType === "number") {
|
|
1654
|
+
return (paramType.kind === "int32" ||
|
|
1655
|
+
paramType.kind === "int64" ||
|
|
1656
|
+
paramType.kind === "float32" ||
|
|
1657
|
+
paramType.kind === "float64" ||
|
|
1658
|
+
paramType.kind === "numeric" ||
|
|
1659
|
+
paramType.kind === "integer" ||
|
|
1660
|
+
paramType.kind === "float" ||
|
|
1661
|
+
paramType.kind === "decimal");
|
|
1662
|
+
}
|
|
1663
|
+
if (defaultType === "boolean") {
|
|
1664
|
+
return paramType.kind === "boolean";
|
|
1665
|
+
}
|
|
1666
|
+
// For other types, don't apply the default
|
|
1667
|
+
return false;
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Formats a default value for code generation.
|
|
1671
|
+
* Strings are wrapped in quotes, other values are used as-is.
|
|
1672
|
+
*/
|
|
1673
|
+
function formatDefaultValue(defaultValue) {
|
|
1674
|
+
if (typeof defaultValue === "string") {
|
|
1675
|
+
return `"${defaultValue}"`;
|
|
1676
|
+
}
|
|
1677
|
+
return String(defaultValue);
|
|
1678
|
+
}
|
|
1394
1679
|
export function getPropertySerializationPrefix(context, property, propertyPath) {
|
|
1395
1680
|
const propertyFullName = getPropertyFullName(context, property, propertyPath);
|
|
1396
1681
|
if (property.optional || isTypeNullable(property.type)) {
|
|
@@ -1436,18 +1721,104 @@ export function getExpectedStatuses(operation) {
|
|
|
1436
1721
|
}
|
|
1437
1722
|
/**
|
|
1438
1723
|
* Gets the apiVersion expression with default value fallback for query parameters.
|
|
1724
|
+
* @param dpgContext - The SDK context
|
|
1439
1725
|
* @param operation - The operation to get the apiVersion parameter from
|
|
1440
1726
|
* @returns The apiVersion expression string, or undefined if no apiVersion query param exists
|
|
1441
1727
|
*/
|
|
1442
|
-
function getApiVersionExpression(operation) {
|
|
1728
|
+
function getApiVersionExpression(dpgContext, operation) {
|
|
1729
|
+
var _a;
|
|
1443
1730
|
const queryApiVersionParam = operation.operation.parameters.find((p) => p.kind === "query" && p.isApiVersionParam);
|
|
1444
1731
|
if (!queryApiVersionParam) {
|
|
1445
1732
|
return undefined;
|
|
1446
1733
|
}
|
|
1734
|
+
// For multi-service, use only the default value (don't reference context.apiVersion)
|
|
1735
|
+
if ((_a = dpgContext.rlcOptions) === null || _a === void 0 ? void 0 : _a.isMultiService) {
|
|
1736
|
+
return queryApiVersionParam.clientDefaultValue
|
|
1737
|
+
? `"${queryApiVersionParam.clientDefaultValue}"`
|
|
1738
|
+
: undefined;
|
|
1739
|
+
}
|
|
1447
1740
|
const paramAccess = `${queryApiVersionParam.onClient ? "context." : ""}${queryApiVersionParam.name}`;
|
|
1448
1741
|
const defaultValueSuffix = queryApiVersionParam.clientDefaultValue
|
|
1449
1742
|
? ` ?? "${queryApiVersionParam.clientDefaultValue}"`
|
|
1450
1743
|
: "";
|
|
1451
1744
|
return `${paramAccess}${defaultValueSuffix}`;
|
|
1452
1745
|
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Extracts and deduplicates all response headers from operation responses.
|
|
1748
|
+
* @param responses - The operation responses
|
|
1749
|
+
* @returns Array of unique response headers
|
|
1750
|
+
*/
|
|
1751
|
+
export function getResponseHeaders(responses) {
|
|
1752
|
+
var _a, _b;
|
|
1753
|
+
const headerMap = new Map();
|
|
1754
|
+
for (const response of responses !== null && responses !== void 0 ? responses : []) {
|
|
1755
|
+
for (const header of (_a = response.headers) !== null && _a !== void 0 ? _a : []) {
|
|
1756
|
+
const key = (_b = header.serializedName) !== null && _b !== void 0 ? _b : header.name;
|
|
1757
|
+
if (!headerMap.has(key)) {
|
|
1758
|
+
headerMap.set(key, header);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
return Array.from(headerMap.values());
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Builds a composite return type for operations that return both a model and additional headers.
|
|
1766
|
+
* Combines model properties and header properties into an inline object type.
|
|
1767
|
+
* @param context - The SDK context
|
|
1768
|
+
* @param modelType - The model type
|
|
1769
|
+
* @param headers - The response headers that are NOT in the model
|
|
1770
|
+
* @returns The composite type expression as a string (e.g., "{ name: string; email: string; requestId: string }")
|
|
1771
|
+
*/
|
|
1772
|
+
function buildCompositeResponseType(context, modelType, headers) {
|
|
1773
|
+
const allParents = getAllAncestors(modelType);
|
|
1774
|
+
const modelProps = getAllProperties(context, modelType, allParents);
|
|
1775
|
+
// Collect header property names already in the model to avoid duplicates
|
|
1776
|
+
const modelHeaderNames = new Set();
|
|
1777
|
+
for (const property of modelProps) {
|
|
1778
|
+
if (isHeader(context.program, property.__raw)) {
|
|
1779
|
+
modelHeaderNames.add(property.name.toLowerCase());
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
// Add only additional host response header properties not already in model
|
|
1783
|
+
for (const header of headers) {
|
|
1784
|
+
if (modelHeaderNames.has(header.name.toLowerCase())) {
|
|
1785
|
+
continue;
|
|
1786
|
+
}
|
|
1787
|
+
modelProps.push(header);
|
|
1788
|
+
}
|
|
1789
|
+
return emitInlineModel(context, modelProps);
|
|
1790
|
+
}
|
|
1791
|
+
/**
|
|
1792
|
+
* Builds an inline type string for header-only responses.
|
|
1793
|
+
* @param context - The SDK context
|
|
1794
|
+
* @param headers - The response headers
|
|
1795
|
+
* @returns The inline type expression as a string (e.g., "{ requestId: string; optionalHeader?: string }")
|
|
1796
|
+
*/
|
|
1797
|
+
function buildHeaderOnlyResponseType(context, headers) {
|
|
1798
|
+
const properties = [];
|
|
1799
|
+
for (const header of headers) {
|
|
1800
|
+
const headerName = normalizeModelPropertyName(context, header);
|
|
1801
|
+
const headerType = getTypeExpression(context, header.type);
|
|
1802
|
+
const isOptional = header.optional ? "?" : "";
|
|
1803
|
+
properties.push(`${headerName}${isOptional}: ${headerType}`);
|
|
1804
|
+
}
|
|
1805
|
+
return `{ ${properties.join("; ")} }`;
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Builds the object literal expression for a header-only response.
|
|
1809
|
+
* Handles type conversions for headers (string to boolean, Date, number, Uint8Array).
|
|
1810
|
+
* @param operation - The service operation
|
|
1811
|
+
* @param headers - The response headers
|
|
1812
|
+
* @returns JavaScript expression string for the header-only response object
|
|
1813
|
+
*/
|
|
1814
|
+
function buildHeaderOnlyResponseValue(context, headers) {
|
|
1815
|
+
const props = headers.map((header) => {
|
|
1816
|
+
var _a;
|
|
1817
|
+
const headerName = ((_a = header.serializedName) !== null && _a !== void 0 ? _a : header.name).toLowerCase();
|
|
1818
|
+
const key = normalizeModelPropertyName(context, header);
|
|
1819
|
+
const value = deserializeResponseHeadersValue(context, header.type, `result.headers[${JSON.stringify(headerName)}]`, !header.optional, getEncodeForType(header.type), 0);
|
|
1820
|
+
return `${key}: ${value}`;
|
|
1821
|
+
});
|
|
1822
|
+
return `{ ${props.join(", ")} }`;
|
|
1823
|
+
}
|
|
1453
1824
|
//# sourceMappingURL=operationHelpers.js.map
|