@azure-tools/typespec-ts 0.47.1 → 0.48.0-alpha.20260108.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 +12 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +11 -2
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +7 -1
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/emitModels.js +1 -1
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/emitSamples.js +11 -6
- package/dist/src/modular/emitSamples.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +3 -5
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +76 -42
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/serialization/serializeUtils.d.ts +1 -0
- package/dist/src/modular/serialization/serializeUtils.d.ts.map +1 -1
- package/dist/src/modular/serialization/serializeUtils.js.map +1 -1
- package/dist/src/modular/static-helpers-metadata.d.ts +25 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
- package/dist/src/modular/static-helpers-metadata.js +25 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -1
- package/dist/src/utils/clientUtils.d.ts.map +1 -1
- package/dist/src/utils/clientUtils.js +14 -3
- package/dist/src/utils/clientUtils.js.map +1 -1
- package/dist/src/utils/operationUtil.d.ts +11 -1
- package/dist/src/utils/operationUtil.d.ts.map +1 -1
- package/dist/src/utils/operationUtil.js +65 -21
- package/dist/src/utils/operationUtil.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/index.ts +4 -1
- package/src/lib.ts +8 -2
- package/src/modular/emitModels.ts +1 -1
- package/src/modular/emitSamples.ts +10 -3
- package/src/modular/helpers/operationHelpers.ts +100 -52
- package/src/modular/serialization/serializeUtils.ts +4 -0
- package/src/modular/static-helpers-metadata.ts +25 -0
- package/src/utils/clientUtils.ts +13 -3
- package/src/utils/operationUtil.ts +71 -24
- package/static/static-helpers/serialization/build-newline-collection.ts +3 -0
- package/static/static-helpers/serialization/parse-csv-collection.ts +3 -0
- package/static/static-helpers/serialization/parse-newline-collection.ts +3 -0
- package/static/static-helpers/serialization/parse-pipe-collection.ts +3 -0
- package/static/static-helpers/serialization/parse-ssv-collection.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0-alpha.20260108.1",
|
|
4
4
|
"description": "An experimental TypeSpec emitter for TypeScript RLC",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@azure-tools/typespec-autorest": "^0.63.0",
|
|
27
27
|
"@azure-tools/typespec-azure-core": "^0.63.0",
|
|
28
28
|
"@azure-tools/typespec-azure-resource-manager": "^0.63.0",
|
|
29
|
-
"@azure-tools/typespec-client-generator-core": "^0.63.
|
|
29
|
+
"@azure-tools/typespec-client-generator-core": "^0.63.3",
|
|
30
30
|
"@azure/abort-controller": "^2.1.2",
|
|
31
31
|
"@azure/core-auth": "^1.6.0",
|
|
32
32
|
"@azure/core-lro": "^3.1.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"@azure-tools/typespec-azure-core": "^0.63.0",
|
|
68
|
-
"@azure-tools/typespec-client-generator-core": "^0.63.
|
|
68
|
+
"@azure-tools/typespec-client-generator-core": "^0.63.3",
|
|
69
69
|
"@typespec/compiler": "^1.7.0",
|
|
70
70
|
"@typespec/http": "^1.7.0",
|
|
71
71
|
"@typespec/rest": "^0.77.0",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"@typespec/xml": "^0.77.0"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@azure-tools/rlc-common": "
|
|
76
|
+
"@azure-tools/rlc-common": "0.48.0-alpha.20260108.1",
|
|
77
77
|
"fs-extra": "^11.1.0",
|
|
78
78
|
"lodash": "^4.17.21",
|
|
79
79
|
"prettier": "^3.3.3",
|
package/src/index.ts
CHANGED
|
@@ -258,7 +258,10 @@ export async function $onEmit(context: EmitContext) {
|
|
|
258
258
|
for (const client of clients) {
|
|
259
259
|
const rlcModels = await transformRLCModel(client, dpgContext);
|
|
260
260
|
rlcCodeModels.push(rlcModels);
|
|
261
|
-
|
|
261
|
+
const serviceName = Array.isArray(client.service)
|
|
262
|
+
? (client.service[0]?.name ?? "Unknown")
|
|
263
|
+
: client.service.name;
|
|
264
|
+
serviceNameToRlcModelsMap.set(serviceName, rlcModels);
|
|
262
265
|
needUnexpectedHelper.set(
|
|
263
266
|
getClientName(rlcModels),
|
|
264
267
|
hasUnexpectedHelper(rlcModels)
|
package/src/lib.ts
CHANGED
|
@@ -54,7 +54,7 @@ export interface EmitterOptions {
|
|
|
54
54
|
"azure-arm"?: boolean;
|
|
55
55
|
"source-from"?: "TypeSpec" | "Swagger";
|
|
56
56
|
"is-modular-library"?: boolean;
|
|
57
|
-
"module-kind"?: "esm"
|
|
57
|
+
"module-kind"?: "esm";
|
|
58
58
|
"enable-operation-group"?: boolean;
|
|
59
59
|
flavor?: PackageFlavor;
|
|
60
60
|
"enable-model-namespace"?: boolean;
|
|
@@ -272,7 +272,7 @@ export const RLCOptionsSchema: JSONSchemaType<EmitterOptions> = {
|
|
|
272
272
|
"module-kind": {
|
|
273
273
|
type: "string",
|
|
274
274
|
nullable: true,
|
|
275
|
-
enum: ["esm"
|
|
275
|
+
enum: ["esm"],
|
|
276
276
|
default: "esm",
|
|
277
277
|
description: "Internal option for test."
|
|
278
278
|
},
|
|
@@ -608,6 +608,12 @@ const libDef = {
|
|
|
608
608
|
messages: {
|
|
609
609
|
default: paramMessage`Model name conflict detected: "${"modelName"}" exists in multiple namespaces: ${"namespaces"}. Please use @clientName to rename them.`
|
|
610
610
|
}
|
|
611
|
+
},
|
|
612
|
+
"un-supported-array-encoding": {
|
|
613
|
+
severity: "warning",
|
|
614
|
+
messages: {
|
|
615
|
+
default: paramMessage`The array property "${"arrayName"}" of ${"arrayType"} type is not supported for encoding and will be ignored.`
|
|
616
|
+
}
|
|
611
617
|
}
|
|
612
618
|
},
|
|
613
619
|
emitter: {
|
|
@@ -670,7 +670,7 @@ export function normalizeModelName(
|
|
|
670
670
|
: "";
|
|
671
671
|
const internalModelPrefix =
|
|
672
672
|
isPagedResultModel(context, type) || type.isGeneratedName ? "_" : "";
|
|
673
|
-
return `${internalModelPrefix}${normalizeName(namespacePrefix + type.name
|
|
673
|
+
return `${internalModelPrefix}${normalizeName(namespacePrefix + type.name, nameType, true)}${unionSuffix}`;
|
|
674
674
|
}
|
|
675
675
|
|
|
676
676
|
function buildModelPolymorphicType(context: SdkContext, type: SdkModelType) {
|
|
@@ -571,12 +571,19 @@ function getParameterValue(
|
|
|
571
571
|
}
|
|
572
572
|
let propRetValue;
|
|
573
573
|
|
|
574
|
-
if (
|
|
574
|
+
if (
|
|
575
|
+
property?.flatten &&
|
|
576
|
+
property.type.kind === "model" &&
|
|
577
|
+
options?.overrides?.enableFlatten !== false
|
|
578
|
+
) {
|
|
579
|
+
// For flatten property, we need to recursively get its properties
|
|
580
|
+
// but disable further flattening to match the TypeScript interface structure
|
|
575
581
|
const paramValue = getParameterValue(context, propValue, {
|
|
576
582
|
overrides: {
|
|
577
583
|
propertyRenames:
|
|
578
584
|
useContext("sdkTypes").flattenProperties.get(property)
|
|
579
|
-
?.conflictMap
|
|
585
|
+
?.conflictMap,
|
|
586
|
+
enableFlatten: false
|
|
580
587
|
}
|
|
581
588
|
});
|
|
582
589
|
propRetValue =
|
|
@@ -584,7 +591,7 @@ function getParameterValue(
|
|
|
584
591
|
} else {
|
|
585
592
|
propRetValue =
|
|
586
593
|
`"${mapper.get(propName) ?? propName}": ` +
|
|
587
|
-
getParameterValue(context, propValue);
|
|
594
|
+
getParameterValue(context, propValue, options);
|
|
588
595
|
}
|
|
589
596
|
if (propRetValue) values.push(propRetValue);
|
|
590
597
|
}
|
|
@@ -21,7 +21,10 @@ import {
|
|
|
21
21
|
getCollectionFormatHelper,
|
|
22
22
|
hasCollectionFormatInfo,
|
|
23
23
|
isBinaryPayload,
|
|
24
|
-
ServiceOperation
|
|
24
|
+
ServiceOperation,
|
|
25
|
+
getCollectionFormatParseHelper,
|
|
26
|
+
getCollectionFormatFromArrayEncoding,
|
|
27
|
+
KnownCollectionFormat
|
|
25
28
|
} from "../../utils/operationUtil.js";
|
|
26
29
|
import {
|
|
27
30
|
getPropertyWithOverrides,
|
|
@@ -245,6 +248,7 @@ export function getDeserializePrivateFunction(
|
|
|
245
248
|
context,
|
|
246
249
|
deserializedType,
|
|
247
250
|
deserializedRoot,
|
|
251
|
+
true,
|
|
248
252
|
isBinaryPayload(context, response.type!.__raw!, contentTypes!)
|
|
249
253
|
? "binary"
|
|
250
254
|
: getEncodeForType(deserializedType)
|
|
@@ -856,6 +860,7 @@ function buildBodyParameter(
|
|
|
856
860
|
isBinaryPayload(context, bodyParameter.__raw!, bodyParameter.contentTypes)
|
|
857
861
|
? "binary"
|
|
858
862
|
: getEncodeForType(bodyParameter.type),
|
|
863
|
+
undefined,
|
|
859
864
|
true
|
|
860
865
|
);
|
|
861
866
|
return `\nbody: ${serializedBody.startsWith(nullOrUndefinedPrefix) ? "" : nullOrUndefinedPrefix}${serializedBody},`;
|
|
@@ -884,7 +889,7 @@ export function getParameterMap(
|
|
|
884
889
|
}
|
|
885
890
|
|
|
886
891
|
if (hasCollectionFormatInfo(param.kind, (param as any).collectionFormat)) {
|
|
887
|
-
return
|
|
892
|
+
return getCollectionFormatForParam(context, param, optionalParamName);
|
|
888
893
|
}
|
|
889
894
|
|
|
890
895
|
// if the parameter or property is optional, we don't need to handle the default value
|
|
@@ -909,39 +914,22 @@ export function getParameterMap(
|
|
|
909
914
|
return `"${param.name}": undefined`;
|
|
910
915
|
}
|
|
911
916
|
|
|
912
|
-
function
|
|
917
|
+
function getCollectionFormatForParam(
|
|
913
918
|
context: SdkContext,
|
|
914
919
|
param: SdkHttpParameter,
|
|
915
920
|
optionalParamName: string = "options"
|
|
916
921
|
) {
|
|
917
922
|
const serializedName = getPropertySerializedName(param);
|
|
918
923
|
const format = (param as any).collectionFormat;
|
|
919
|
-
|
|
920
|
-
if (!collectionInfo) {
|
|
921
|
-
throw "Has collection format info but without helper function detected";
|
|
922
|
-
}
|
|
923
|
-
const isMulti = format.toLowerCase() === "multi";
|
|
924
|
-
const additionalParam = isMulti ? `, "${serializedName}"` : "";
|
|
925
|
-
if (!param.optional) {
|
|
926
|
-
return `"${serializedName}": ${collectionInfo}(${serializeRequestValue(
|
|
927
|
-
context,
|
|
928
|
-
param.type,
|
|
929
|
-
param.name,
|
|
930
|
-
true,
|
|
931
|
-
getEncodeForType(param.type),
|
|
932
|
-
true
|
|
933
|
-
)}${additionalParam})`;
|
|
934
|
-
}
|
|
935
|
-
return `"${serializedName}": ${optionalParamName}?.${
|
|
936
|
-
param.name
|
|
937
|
-
} !== undefined ? ${collectionInfo}(${serializeRequestValue(
|
|
924
|
+
return `"${serializedName}": ${serializeRequestValue(
|
|
938
925
|
context,
|
|
939
926
|
param.type,
|
|
940
|
-
`${optionalParamName}?.${param.name}
|
|
941
|
-
|
|
942
|
-
|
|
927
|
+
param.optional ? `${optionalParamName}?.${param.name}` : param.name,
|
|
928
|
+
!param.optional,
|
|
929
|
+
format,
|
|
930
|
+
serializedName,
|
|
943
931
|
true
|
|
944
|
-
)}
|
|
932
|
+
)}`;
|
|
945
933
|
}
|
|
946
934
|
|
|
947
935
|
function isContentType(param: SdkHttpParameter): boolean {
|
|
@@ -992,6 +980,7 @@ function getRequired(context: SdkContext, param: SdkHttpParameter) {
|
|
|
992
980
|
clientValue,
|
|
993
981
|
true,
|
|
994
982
|
getEncodeForType(param.type),
|
|
983
|
+
serializedName,
|
|
995
984
|
true
|
|
996
985
|
)}`;
|
|
997
986
|
}
|
|
@@ -1033,6 +1022,7 @@ function getOptional(
|
|
|
1033
1022
|
paramName,
|
|
1034
1023
|
false,
|
|
1035
1024
|
getEncodeForType(param.type),
|
|
1025
|
+
serializedName,
|
|
1036
1026
|
true
|
|
1037
1027
|
)}`;
|
|
1038
1028
|
}
|
|
@@ -1172,6 +1162,41 @@ function getNullableCheck(name: string, type: SdkType) {
|
|
|
1172
1162
|
return `${name} === null ? null :`;
|
|
1173
1163
|
}
|
|
1174
1164
|
|
|
1165
|
+
/**
|
|
1166
|
+
* Determines the appropriate encoding format for a model property, especially for arrays with collection format encoding.
|
|
1167
|
+
* For example, returns "csv" for comma-delimited arrays or the property's type encoding for regular properties.
|
|
1168
|
+
*/
|
|
1169
|
+
function getEncodeForModelProperty(
|
|
1170
|
+
context: SdkContext,
|
|
1171
|
+
property: SdkModelPropertyType
|
|
1172
|
+
): string | undefined {
|
|
1173
|
+
if (property.encode && property.type.kind === "array") {
|
|
1174
|
+
// Only arrays of string type can have collectionFormat encoding
|
|
1175
|
+
if (property.type.valueType.kind !== "string") {
|
|
1176
|
+
reportDiagnostic(context.program, {
|
|
1177
|
+
code: "un-supported-array-encoding",
|
|
1178
|
+
format: {
|
|
1179
|
+
arrayName: property.name,
|
|
1180
|
+
arrayType: property.type.valueType.kind
|
|
1181
|
+
},
|
|
1182
|
+
target: NoTarget
|
|
1183
|
+
});
|
|
1184
|
+
return getEncodeForType(property.type);
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
const collectionFormat = getCollectionFormatFromArrayEncoding(
|
|
1188
|
+
property.encode
|
|
1189
|
+
);
|
|
1190
|
+
if (
|
|
1191
|
+
collectionFormat &&
|
|
1192
|
+
hasCollectionFormatInfo(property.kind, collectionFormat)
|
|
1193
|
+
) {
|
|
1194
|
+
return collectionFormat;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return getEncodeForType(property.type);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1175
1200
|
function getSerializationExpressionForFlatten(
|
|
1176
1201
|
context: SdkContext,
|
|
1177
1202
|
property: SdkModelPropertyType,
|
|
@@ -1194,9 +1219,6 @@ function getSerializationExpressionForFlatten(
|
|
|
1194
1219
|
!isReadOnly(p) &&
|
|
1195
1220
|
!isMetadata(context.program, p.__raw!)
|
|
1196
1221
|
);
|
|
1197
|
-
if (validProps.length === 0) {
|
|
1198
|
-
return `undefined`;
|
|
1199
|
-
}
|
|
1200
1222
|
const optionalPrefix = property.optional
|
|
1201
1223
|
? `${resolveReference(SerializationHelpers.areAllPropsUndefined)}(${propertyPath}, [${validProps
|
|
1202
1224
|
.map((p) => `"${p.name}"`)
|
|
@@ -1245,7 +1267,8 @@ export function getSerializationExpression(
|
|
|
1245
1267
|
property.type,
|
|
1246
1268
|
propertyFullName,
|
|
1247
1269
|
!property.optional,
|
|
1248
|
-
|
|
1270
|
+
getEncodeForModelProperty(context, property),
|
|
1271
|
+
getPropertySerializedName(property),
|
|
1249
1272
|
propertyPath === "" ? true : false
|
|
1250
1273
|
);
|
|
1251
1274
|
}
|
|
@@ -1373,20 +1396,17 @@ export function getResponseMapping(
|
|
|
1373
1396
|
context,
|
|
1374
1397
|
property.type,
|
|
1375
1398
|
`${propertyPath}${dot}["${serializedName}"]`,
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
props.push(
|
|
1379
|
-
`${propertyName}: ${deserializeValue === `${propertyPath}${dot}["${serializedName}"]` ? "" : nullOrUndefinedPrefix}${deserializeValue}`
|
|
1399
|
+
!property.optional,
|
|
1400
|
+
getEncodeForModelProperty(context, property)
|
|
1380
1401
|
);
|
|
1402
|
+
props.push(`${propertyName}: ${deserializeValue}`);
|
|
1381
1403
|
}
|
|
1382
1404
|
}
|
|
1383
1405
|
return props;
|
|
1384
1406
|
}
|
|
1385
1407
|
|
|
1386
1408
|
/**
|
|
1387
|
-
*
|
|
1388
|
-
* We need to drill down into Array elements to make sure that the element type is
|
|
1389
|
-
* deserialized correctly
|
|
1409
|
+
* Converts JavaScript values to their serialized wire format for HTTP requests.
|
|
1390
1410
|
*/
|
|
1391
1411
|
export function serializeRequestValue(
|
|
1392
1412
|
context: SdkContext,
|
|
@@ -1394,6 +1414,7 @@ export function serializeRequestValue(
|
|
|
1394
1414
|
clientValue: string,
|
|
1395
1415
|
required: boolean,
|
|
1396
1416
|
format?: string,
|
|
1417
|
+
serializedName?: string,
|
|
1397
1418
|
isTopLevel: boolean = false
|
|
1398
1419
|
): string {
|
|
1399
1420
|
const getSdkType = useSdkTypes();
|
|
@@ -1414,8 +1435,8 @@ export function serializeRequestValue(
|
|
|
1414
1435
|
return `${nullOrUndefinedPrefix}${clientValue}.toISOString()`;
|
|
1415
1436
|
}
|
|
1416
1437
|
case "array": {
|
|
1417
|
-
const prefix = nullOrUndefinedPrefix + clientValue;
|
|
1418
1438
|
if (type.valueType) {
|
|
1439
|
+
const prefix = nullOrUndefinedPrefix + clientValue;
|
|
1419
1440
|
const elementNullOrUndefinedPrefix =
|
|
1420
1441
|
isTypeNullable(type.valueType) || getOptionalForType(type.valueType)
|
|
1421
1442
|
? "!p ? p : "
|
|
@@ -1435,7 +1456,17 @@ export function serializeRequestValue(
|
|
|
1435
1456
|
) {
|
|
1436
1457
|
return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}p})`;
|
|
1437
1458
|
} else {
|
|
1438
|
-
|
|
1459
|
+
const serializedValue = `${clientValue}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${serializeRequestValue(context, type.valueType, "p", true, getEncodeForType(type.valueType))}})`;
|
|
1460
|
+
if (format) {
|
|
1461
|
+
const formatHelper = getCollectionFormatHelper(format);
|
|
1462
|
+
if (formatHelper) {
|
|
1463
|
+
if (format?.toLowerCase() === KnownCollectionFormat.Multi) {
|
|
1464
|
+
return `${nullOrUndefinedPrefix}${formatHelper}(${serializedValue}, "${serializedName}")`;
|
|
1465
|
+
}
|
|
1466
|
+
return `${nullOrUndefinedPrefix}${formatHelper}(${serializedValue})`;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
return `${nullOrUndefinedPrefix}${serializedValue}`;
|
|
1439
1470
|
}
|
|
1440
1471
|
}
|
|
1441
1472
|
return clientValue;
|
|
@@ -1507,14 +1538,16 @@ export function deserializeResponseValue(
|
|
|
1507
1538
|
context: SdkContext,
|
|
1508
1539
|
type: SdkType,
|
|
1509
1540
|
restValue: string,
|
|
1510
|
-
|
|
1541
|
+
required: boolean,
|
|
1542
|
+
format?: string,
|
|
1543
|
+
recursionDepth: number = 0
|
|
1511
1544
|
): string {
|
|
1512
1545
|
const dependencies = useDependencies();
|
|
1513
1546
|
const stringToUint8ArrayReference = resolveReference(
|
|
1514
1547
|
dependencies.stringToUint8Array
|
|
1515
1548
|
);
|
|
1516
1549
|
const nullOrUndefinedPrefix =
|
|
1517
|
-
isTypeNullable(type) || getOptionalForType(type)
|
|
1550
|
+
isTypeNullable(type) || getOptionalForType(type) || !required
|
|
1518
1551
|
? `!${restValue}? ${restValue}: `
|
|
1519
1552
|
: "";
|
|
1520
1553
|
switch (type.kind) {
|
|
@@ -1522,12 +1555,13 @@ export function deserializeResponseValue(
|
|
|
1522
1555
|
return `${nullOrUndefinedPrefix} new Date(${type.encode === "unixTimestamp" ? `${restValue} * 1000` : restValue})`;
|
|
1523
1556
|
case "array": {
|
|
1524
1557
|
const prefix = nullOrUndefinedPrefix + restValue;
|
|
1558
|
+
const varName = recursionDepth > 0 ? `p${recursionDepth}` : "p";
|
|
1525
1559
|
let elementNullOrUndefinedPrefix = "";
|
|
1526
1560
|
if (
|
|
1527
1561
|
type.valueType &&
|
|
1528
1562
|
(isTypeNullable(type.valueType) || getOptionalForType(type.valueType))
|
|
1529
1563
|
) {
|
|
1530
|
-
elementNullOrUndefinedPrefix =
|
|
1564
|
+
elementNullOrUndefinedPrefix = `!${varName} ? ${varName} :`;
|
|
1531
1565
|
}
|
|
1532
1566
|
const deserializeFunctionName = type.valueType
|
|
1533
1567
|
? buildModelDeserializer(
|
|
@@ -1540,26 +1574,38 @@ export function deserializeResponseValue(
|
|
|
1540
1574
|
)
|
|
1541
1575
|
: undefined;
|
|
1542
1576
|
if (deserializeFunctionName) {
|
|
1543
|
-
return `${prefix}.map((
|
|
1577
|
+
return `${prefix}.map((${varName}: any) => { return ${elementNullOrUndefinedPrefix}${deserializeFunctionName}(${varName})})`;
|
|
1544
1578
|
} else if (
|
|
1545
1579
|
type.valueType &&
|
|
1546
1580
|
isAzureCoreErrorType(context.program, type.valueType.__raw)
|
|
1547
1581
|
) {
|
|
1548
|
-
return `${prefix}.map((
|
|
1582
|
+
return `${prefix}.map((${varName}: any) => { return ${elementNullOrUndefinedPrefix}${varName}})`;
|
|
1549
1583
|
} else if (type.valueType) {
|
|
1550
|
-
|
|
1584
|
+
if (format) {
|
|
1585
|
+
const parseHelper = getCollectionFormatParseHelper(format);
|
|
1586
|
+
if (parseHelper) {
|
|
1587
|
+
// We shouldn't check for an empty string here since an empty string should be parsed as an empty array
|
|
1588
|
+
const optionalPrefixForString =
|
|
1589
|
+
isTypeNullable(type) || getOptionalForType(type) || !required
|
|
1590
|
+
? `${restValue} === null || ${restValue} === undefined ? ${restValue}: `
|
|
1591
|
+
: "";
|
|
1592
|
+
return `${optionalPrefixForString}${parseHelper}(${restValue})`;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
return `${prefix}.map((${varName}: any) => { return ${elementNullOrUndefinedPrefix}${deserializeResponseValue(context, type.valueType, varName, true, getEncodeForType(type.valueType), recursionDepth + 1)}})`;
|
|
1551
1596
|
} else {
|
|
1552
1597
|
return restValue;
|
|
1553
1598
|
}
|
|
1554
1599
|
}
|
|
1555
1600
|
case "dict": {
|
|
1556
|
-
const
|
|
1601
|
+
const keyVar = recursionDepth > 0 ? `k${recursionDepth}` : "k";
|
|
1602
|
+
const valueVar = recursionDepth > 0 ? `p${recursionDepth}` : "p";
|
|
1557
1603
|
let elementNullOrUndefinedPrefix = "";
|
|
1558
1604
|
if (
|
|
1559
1605
|
type.valueType &&
|
|
1560
1606
|
(isTypeNullable(type.valueType) || getOptionalForType(type.valueType))
|
|
1561
1607
|
) {
|
|
1562
|
-
elementNullOrUndefinedPrefix =
|
|
1608
|
+
elementNullOrUndefinedPrefix = `!${valueVar} ? ${valueVar} :`;
|
|
1563
1609
|
}
|
|
1564
1610
|
const deserializeFunctionName = type.valueType
|
|
1565
1611
|
? buildModelDeserializer(
|
|
@@ -1572,21 +1618,21 @@ export function deserializeResponseValue(
|
|
|
1572
1618
|
)
|
|
1573
1619
|
: undefined;
|
|
1574
1620
|
if (deserializeFunctionName) {
|
|
1575
|
-
return
|
|
1621
|
+
return `${nullOrUndefinedPrefix}Object.fromEntries(Object.entries(${restValue}).map(([${keyVar}, ${valueVar}]: [string, any]) => [${keyVar}, ${elementNullOrUndefinedPrefix}${deserializeFunctionName}(${valueVar})]))`;
|
|
1576
1622
|
} else if (
|
|
1577
1623
|
type.valueType &&
|
|
1578
1624
|
isAzureCoreErrorType(context.program, type.valueType.__raw)
|
|
1579
1625
|
) {
|
|
1580
|
-
return
|
|
1626
|
+
return `${nullOrUndefinedPrefix}Object.fromEntries(Object.entries(${restValue}).map(([${keyVar}, ${valueVar}]: [string, any]) => [${keyVar}, ${elementNullOrUndefinedPrefix}${valueVar}]))`;
|
|
1581
1627
|
} else if (type.valueType) {
|
|
1582
|
-
return
|
|
1628
|
+
return `${nullOrUndefinedPrefix}Object.fromEntries(Object.entries(${restValue}).map(([${keyVar}, ${valueVar}]: [string, any]) => [${keyVar}, ${elementNullOrUndefinedPrefix}${deserializeResponseValue(context, type.valueType, valueVar, true, getEncodeForType(type.valueType), recursionDepth + 1)}]))`;
|
|
1583
1629
|
} else {
|
|
1584
1630
|
return restValue;
|
|
1585
1631
|
}
|
|
1586
1632
|
}
|
|
1587
1633
|
case "bytes":
|
|
1588
1634
|
if (format !== "binary" && format !== "bytes") {
|
|
1589
|
-
return
|
|
1635
|
+
return `${nullOrUndefinedPrefix}typeof ${restValue} === 'string'
|
|
1590
1636
|
? ${stringToUint8ArrayReference}(${restValue}, "${format ?? "base64"}")
|
|
1591
1637
|
: ${restValue}`;
|
|
1592
1638
|
}
|
|
@@ -1616,7 +1662,9 @@ export function deserializeResponseValue(
|
|
|
1616
1662
|
context,
|
|
1617
1663
|
type.type,
|
|
1618
1664
|
restValue,
|
|
1619
|
-
|
|
1665
|
+
false,
|
|
1666
|
+
getEncodeForType(type.type),
|
|
1667
|
+
recursionDepth + 1
|
|
1620
1668
|
);
|
|
1621
1669
|
default:
|
|
1622
1670
|
return restValue;
|
|
@@ -201,6 +201,10 @@ export interface ModelOverrideOptions {
|
|
|
201
201
|
// The <Property, Client_Name> map for any renamed properties.
|
|
202
202
|
// Mainly because the original client name has collision with other property names during flattening.
|
|
203
203
|
propertyRenames?: Map<SdkModelPropertyType, string>;
|
|
204
|
+
|
|
205
|
+
// If true (default), enable flattening for nested flatten properties when generating samples.
|
|
206
|
+
// When false, nested flatten properties are not further flattened to match the TypeScript interface structure.
|
|
207
|
+
enableFlatten?: boolean;
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
export function getPropertyWithOverrides(
|
|
@@ -24,6 +24,31 @@ export const SerializationHelpers = {
|
|
|
24
24
|
name: "buildTsvCollection",
|
|
25
25
|
location: "serialization/build-tsv-collection.ts"
|
|
26
26
|
},
|
|
27
|
+
buildNewlineCollection: {
|
|
28
|
+
kind: "function",
|
|
29
|
+
name: "buildNewlineCollection",
|
|
30
|
+
location: "serialization/build-newline-collection.ts"
|
|
31
|
+
},
|
|
32
|
+
parseCsvCollection: {
|
|
33
|
+
kind: "function",
|
|
34
|
+
name: "parseCsvCollection",
|
|
35
|
+
location: "serialization/parse-csv-collection.ts"
|
|
36
|
+
},
|
|
37
|
+
parsePipeCollection: {
|
|
38
|
+
kind: "function",
|
|
39
|
+
name: "parsePipeCollection",
|
|
40
|
+
location: "serialization/parse-pipe-collection.ts"
|
|
41
|
+
},
|
|
42
|
+
parseSsvCollection: {
|
|
43
|
+
kind: "function",
|
|
44
|
+
name: "parseSsvCollection",
|
|
45
|
+
location: "serialization/parse-ssv-collection.ts"
|
|
46
|
+
},
|
|
47
|
+
parseNewlineCollection: {
|
|
48
|
+
kind: "function",
|
|
49
|
+
name: "parseNewlineCollection",
|
|
50
|
+
location: "serialization/parse-newline-collection.ts"
|
|
51
|
+
},
|
|
27
52
|
serializeRecord: {
|
|
28
53
|
kind: "function",
|
|
29
54
|
name: "serializeRecord",
|
package/src/utils/clientUtils.ts
CHANGED
|
@@ -20,7 +20,14 @@ import { NameType, normalizeName } from "@azure-tools/rlc-common";
|
|
|
20
20
|
|
|
21
21
|
export function getRLCClients(dpgContext: SdkContext): SdkClient[] {
|
|
22
22
|
const services = new Set<Namespace>();
|
|
23
|
-
listClients(dpgContext).forEach((c) =>
|
|
23
|
+
listClients(dpgContext).forEach((c) => {
|
|
24
|
+
const clientService = c.service;
|
|
25
|
+
if (Array.isArray(clientService)) {
|
|
26
|
+
clientService.forEach((ns) => services.add(ns));
|
|
27
|
+
} else {
|
|
28
|
+
services.add(clientService);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
24
31
|
const rawServiceNamespaces = listAllServiceNamespaces(dpgContext);
|
|
25
32
|
if (services.size === 0 && rawServiceNamespaces.length > 0) {
|
|
26
33
|
// If no clients are found, fall back to raw service namespaces
|
|
@@ -45,7 +52,10 @@ export function getRLCClients(dpgContext: SdkContext): SdkClient[] {
|
|
|
45
52
|
|
|
46
53
|
export function listOperationsUnderRLCClient(client: SdkClient): Operation[] {
|
|
47
54
|
const operations = [];
|
|
48
|
-
const
|
|
55
|
+
const serviceArray = Array.isArray(client.service)
|
|
56
|
+
? client.service
|
|
57
|
+
: [client.service];
|
|
58
|
+
const queue: (Namespace | Interface)[] = [...serviceArray];
|
|
49
59
|
while (queue.length > 0) {
|
|
50
60
|
const current = queue.shift()!;
|
|
51
61
|
if (
|
|
@@ -55,7 +65,7 @@ export function listOperationsUnderRLCClient(client: SdkClient): Operation[] {
|
|
|
55
65
|
getNamespaceFullName(d.definition?.namespace) ===
|
|
56
66
|
"Azure.ClientGenerator.Core"
|
|
57
67
|
) &&
|
|
58
|
-
current
|
|
68
|
+
!serviceArray.includes(current as Namespace)
|
|
59
69
|
) {
|
|
60
70
|
continue;
|
|
61
71
|
}
|
|
@@ -461,7 +461,8 @@ export function hasCollectionFormatInfo(
|
|
|
461
461
|
getHasSsvCollection(paramType, paramFormat) ||
|
|
462
462
|
getHasTsvCollection(paramType, paramFormat) ||
|
|
463
463
|
getHasCsvCollection(paramType, paramFormat) ||
|
|
464
|
-
getHasPipeCollection(paramType, paramFormat)
|
|
464
|
+
getHasPipeCollection(paramType, paramFormat) ||
|
|
465
|
+
getHasNewlineCollection(paramType, paramFormat)
|
|
465
466
|
);
|
|
466
467
|
}
|
|
467
468
|
|
|
@@ -503,50 +504,96 @@ function getHasMultiCollection(
|
|
|
503
504
|
) {
|
|
504
505
|
return (
|
|
505
506
|
((includeQuery && paramType === "query") || paramType === "header") &&
|
|
506
|
-
paramFormat ===
|
|
507
|
+
paramFormat === KnownCollectionFormat.Multi
|
|
507
508
|
);
|
|
508
509
|
}
|
|
509
510
|
function getHasSsvCollection(paramType: string, paramFormat: string) {
|
|
510
|
-
return
|
|
511
|
+
return (
|
|
512
|
+
(paramType === "query" || paramType === "property") &&
|
|
513
|
+
paramFormat === KnownCollectionFormat.Ssv
|
|
514
|
+
);
|
|
511
515
|
}
|
|
512
516
|
|
|
513
517
|
function getHasTsvCollection(paramType: string, paramFormat: string) {
|
|
514
|
-
return paramType === "query" && paramFormat ===
|
|
518
|
+
return paramType === "query" && paramFormat === KnownCollectionFormat.Tsv;
|
|
515
519
|
}
|
|
516
520
|
|
|
517
521
|
function getHasCsvCollection(paramType: string, paramFormat: string) {
|
|
518
|
-
return
|
|
522
|
+
return (
|
|
523
|
+
(paramType === "header" || paramType === "property") &&
|
|
524
|
+
paramFormat === KnownCollectionFormat.Csv
|
|
525
|
+
);
|
|
519
526
|
}
|
|
520
527
|
|
|
521
528
|
function getHasPipeCollection(paramType: string, paramFormat: string) {
|
|
522
|
-
return
|
|
529
|
+
return (
|
|
530
|
+
(paramType === "query" || paramType === "property") &&
|
|
531
|
+
paramFormat === KnownCollectionFormat.Pipes
|
|
532
|
+
);
|
|
523
533
|
}
|
|
524
534
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
)
|
|
529
|
-
|
|
530
|
-
return resolveReference(SerializationHelpers.buildMultiCollection);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
if (getHasPipeCollection(paramType, paramFormat)) {
|
|
534
|
-
return resolveReference(SerializationHelpers.buildPipeCollection);
|
|
535
|
-
}
|
|
535
|
+
function getHasNewlineCollection(paramType: string, paramFormat: string) {
|
|
536
|
+
return (
|
|
537
|
+
paramType === "property" && paramFormat === KnownCollectionFormat.Newline
|
|
538
|
+
);
|
|
539
|
+
}
|
|
536
540
|
|
|
537
|
-
|
|
538
|
-
|
|
541
|
+
export function getCollectionFormatHelper(format: string) {
|
|
542
|
+
switch (format) {
|
|
543
|
+
case KnownCollectionFormat.Multi:
|
|
544
|
+
return resolveReference(SerializationHelpers.buildMultiCollection);
|
|
545
|
+
case KnownCollectionFormat.Pipes:
|
|
546
|
+
return resolveReference(SerializationHelpers.buildPipeCollection);
|
|
547
|
+
case KnownCollectionFormat.Ssv:
|
|
548
|
+
return resolveReference(SerializationHelpers.buildSsvCollection);
|
|
549
|
+
case KnownCollectionFormat.Tsv:
|
|
550
|
+
return resolveReference(SerializationHelpers.buildTsvCollection);
|
|
551
|
+
case KnownCollectionFormat.Csv:
|
|
552
|
+
return resolveReference(SerializationHelpers.buildCsvCollection);
|
|
553
|
+
case KnownCollectionFormat.Newline:
|
|
554
|
+
return resolveReference(SerializationHelpers.buildNewlineCollection);
|
|
555
|
+
default:
|
|
556
|
+
return undefined;
|
|
539
557
|
}
|
|
558
|
+
}
|
|
540
559
|
|
|
541
|
-
|
|
542
|
-
|
|
560
|
+
export function getCollectionFormatParseHelper(format: string) {
|
|
561
|
+
switch (format) {
|
|
562
|
+
case KnownCollectionFormat.Pipes:
|
|
563
|
+
return resolveReference(SerializationHelpers.parsePipeCollection);
|
|
564
|
+
case KnownCollectionFormat.Ssv:
|
|
565
|
+
return resolveReference(SerializationHelpers.parseSsvCollection);
|
|
566
|
+
case KnownCollectionFormat.Csv:
|
|
567
|
+
return resolveReference(SerializationHelpers.parseCsvCollection);
|
|
568
|
+
case KnownCollectionFormat.Newline:
|
|
569
|
+
return resolveReference(SerializationHelpers.parseNewlineCollection);
|
|
570
|
+
default:
|
|
571
|
+
return undefined;
|
|
543
572
|
}
|
|
573
|
+
}
|
|
544
574
|
|
|
545
|
-
|
|
546
|
-
|
|
575
|
+
export function getCollectionFormatFromArrayEncoding(encoding: string) {
|
|
576
|
+
switch (encoding) {
|
|
577
|
+
case "pipeDelimited":
|
|
578
|
+
return KnownCollectionFormat.Pipes;
|
|
579
|
+
case "spaceDelimited":
|
|
580
|
+
return KnownCollectionFormat.Ssv;
|
|
581
|
+
case "commaDelimited":
|
|
582
|
+
return KnownCollectionFormat.Csv;
|
|
583
|
+
case "newlineDelimited":
|
|
584
|
+
return KnownCollectionFormat.Newline;
|
|
585
|
+
default:
|
|
586
|
+
return undefined;
|
|
547
587
|
}
|
|
588
|
+
}
|
|
548
589
|
|
|
549
|
-
|
|
590
|
+
export enum KnownCollectionFormat {
|
|
591
|
+
Csv = "csv",
|
|
592
|
+
Ssv = "ssv",
|
|
593
|
+
Tsv = "tsv",
|
|
594
|
+
Pipes = "pipes",
|
|
595
|
+
Newline = "newline",
|
|
596
|
+
Multi = "multi"
|
|
550
597
|
}
|
|
551
598
|
|
|
552
599
|
export function getCustomRequestHeaderNameForOperation(
|