Skip to content

Commit 3494dbd

Browse files
authored
Fix Nested XML Serialization (#3730)
* Fix nested serialization * fix hardcoded contentType property name * Support includeRootSlash * Fix xml serialization * fix return type * Fix record serialization * Update tests * disable auto formatting in xml
1 parent 79af6fc commit 3494dbd

File tree

15 files changed

+1304
-57
lines changed

15 files changed

+1304
-57
lines changed

packages/typespec-ts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"@azure-tools/typespec-autorest": "^0.64.0",
7474
"@azure-tools/typespec-azure-core": "^0.64.0",
7575
"@azure-tools/typespec-azure-resource-manager": "^0.64.0",
76-
"@azure-tools/typespec-client-generator-core": "^0.64.4",
76+
"@azure-tools/typespec-client-generator-core": "^0.64.6",
7777
"@azure/abort-controller": "^2.1.2",
7878
"@azure/core-auth": "^1.6.0",
7979
"@azure/core-lro": "^3.1.0",

packages/typespec-ts/src/modular/buildOperations.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ export function buildOperationFiles(
8686
const sendOperationDeclaration = getSendPrivateFunction(
8787
dpgContext,
8888
[prefixes, op],
89-
clientType
89+
clientType,
90+
client
9091
);
9192
const deserializeOperationDeclaration = getDeserializePrivateFunction(
9293
dpgContext,

packages/typespec-ts/src/modular/emitModels.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import {
5151
import {
5252
buildXmlModelSerializer,
5353
buildXmlModelDeserializer,
54+
buildXmlObjectModelSerializer,
55+
buildXmlObjectModelDeserializer,
5456
hasXmlSerialization
5557
} from "./serialization/buildXmlSerializerFunction.js";
5658
import path from "path";
@@ -384,6 +386,14 @@ function addSerializationFunctions(
384386
if (typeOrProperty.kind === "model" && hasXmlSerialization(typeOrProperty)) {
385387
const xmlSerializerRefKey = refkey(typeOrProperty, "xmlSerializer");
386388
const xmlDeserializerRefKey = refkey(typeOrProperty, "xmlDeserializer");
389+
const xmlObjectSerializerRefKey = refkey(
390+
typeOrProperty,
391+
"xmlObjectSerializer"
392+
);
393+
const xmlObjectDeserializerRefKey = refkey(
394+
typeOrProperty,
395+
"xmlObjectDeserializer"
396+
);
387397

388398
const xmlSerializationFunction = buildXmlModelSerializer(
389399
context,
@@ -398,6 +408,24 @@ function addSerializationFunctions(
398408
addDeclaration(sourceFile, xmlSerializationFunction, xmlSerializerRefKey);
399409
}
400410

411+
// Also generate XML object serializer for nested object serialization
412+
const xmlObjectSerializationFunction = buildXmlObjectModelSerializer(
413+
context,
414+
typeOrProperty,
415+
options
416+
);
417+
if (
418+
xmlObjectSerializationFunction &&
419+
typeof xmlObjectSerializationFunction !== "string" &&
420+
xmlObjectSerializationFunction.name
421+
) {
422+
addDeclaration(
423+
sourceFile,
424+
xmlObjectSerializationFunction,
425+
xmlObjectSerializerRefKey
426+
);
427+
}
428+
401429
const xmlDeserializationFunction = buildXmlModelDeserializer(
402430
context,
403431
typeOrProperty,
@@ -414,6 +442,24 @@ function addSerializationFunctions(
414442
xmlDeserializerRefKey
415443
);
416444
}
445+
446+
// Also generate XML object deserializer for nested object deserialization
447+
const xmlObjectDeserializationFunction = buildXmlObjectModelDeserializer(
448+
context,
449+
typeOrProperty,
450+
options
451+
);
452+
if (
453+
xmlObjectDeserializationFunction &&
454+
typeof xmlObjectDeserializationFunction !== "string" &&
455+
xmlObjectDeserializationFunction.name
456+
) {
457+
addDeclaration(
458+
sourceFile,
459+
xmlObjectDeserializationFunction,
460+
xmlObjectDeserializerRefKey
461+
);
462+
}
417463
}
418464
}
419465

packages/typespec-ts/src/modular/helpers/operationHelpers.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ import {
7171
} from "../type-expressions/get-type-expression.js";
7272
import { SdkContext } from "../../utils/interfaces.js";
7373
import {
74+
getClientOptions,
7475
isHttpMetadata,
7576
isReadOnly,
7677
SdkBodyParameter,
78+
SdkClientType,
7779
SdkConstantType,
7880
SdkEnumType,
7981
SdkHttpOperation,
@@ -96,7 +98,8 @@ import { emitInlineModel } from "../type-expressions/get-model-expression.js";
9698
export function getSendPrivateFunction(
9799
dpgContext: SdkContext,
98100
method: [string[], ServiceOperation],
99-
clientType: string
101+
clientType: string,
102+
client?: SdkClientType<SdkHttpOperation>
100103
): OptionalKind<FunctionDeclarationStructure> {
101104
const operation = method[1];
102105
const parameters = getOperationSignatureParameters(
@@ -128,7 +131,15 @@ export function getSendPrivateFunction(
128131
// Generate a unique local variable name that doesn't conflict with parameter names
129132
const paramNames = new Set(parameters.map((p) => p.name));
130133
const pathVarName = generateLocallyUniqueName("path", paramNames);
131-
statements.push(`const ${pathVarName} = ${resolveReference(UrlTemplateHelpers.parseTemplate)}("${operation.operation.uriTemplate}", {
134+
const includeRootSlash = client
135+
? getClientOptions(client, "includeRootSlash") !== false
136+
: true;
137+
138+
const uriTemplate = includeRootSlash
139+
? operation.operation.uriTemplate
140+
: operation.operation.uriTemplate.replace(/^\//, "");
141+
142+
statements.push(`const ${pathVarName} = ${resolveReference(UrlTemplateHelpers.parseTemplate)}("${uriTemplate}", {
132143
${urlTemplateParams.join(",\n")}
133144
},{
134145
allowReserved: ${optionalParamName}?.requestOptions?.skipUrlEncoding
@@ -1347,7 +1358,7 @@ function getContentTypeValue(
13471358
} else {
13481359
return `contentType: ${
13491360
!param.optional
1350-
? "contentType"
1361+
? normalizeName(param.name, NameType.Property)
13511362
: `${optionalParamName}.` + param.name + " as any"
13521363
}`;
13531364
}

0 commit comments

Comments
 (0)