@azure-tools/typespec-ts 0.48.0 → 0.48.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +20 -5
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/modular/buildClientContext.d.ts.map +1 -1
  6. package/dist/src/modular/buildClientContext.js +7 -3
  7. package/dist/src/modular/buildClientContext.js.map +1 -1
  8. package/dist/src/modular/buildOperations.d.ts.map +1 -1
  9. package/dist/src/modular/buildOperations.js +24 -3
  10. package/dist/src/modular/buildOperations.js.map +1 -1
  11. package/dist/src/modular/emitModels.d.ts.map +1 -1
  12. package/dist/src/modular/emitModels.js +19 -0
  13. package/dist/src/modular/emitModels.js.map +1 -1
  14. package/dist/src/modular/emitSamples.js +2 -2
  15. package/dist/src/modular/emitSamples.js.map +1 -1
  16. package/dist/src/modular/helpers/clientHelpers.d.ts +2 -1
  17. package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
  18. package/dist/src/modular/helpers/clientHelpers.js +5 -2
  19. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  20. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  21. package/dist/src/modular/helpers/operationHelpers.js +266 -43
  22. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  23. package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts +32 -0
  24. package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts.map +1 -0
  25. package/dist/src/modular/serialization/buildXmlSerializerFunction.js +373 -0
  26. package/dist/src/modular/serialization/buildXmlSerializerFunction.js.map +1 -0
  27. package/dist/src/modular/static-helpers-metadata.d.ts +57 -0
  28. package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
  29. package/dist/src/modular/static-helpers-metadata.js +57 -0
  30. package/dist/src/modular/static-helpers-metadata.js.map +1 -1
  31. package/dist/src/utils/clientUtils.d.ts.map +1 -1
  32. package/dist/src/utils/clientUtils.js +1 -0
  33. package/dist/src/utils/clientUtils.js.map +1 -1
  34. package/dist/src/utils/mediaTypes.d.ts +4 -0
  35. package/dist/src/utils/mediaTypes.d.ts.map +1 -1
  36. package/dist/src/utils/mediaTypes.js +10 -0
  37. package/dist/src/utils/mediaTypes.js.map +1 -1
  38. package/dist/src/utils/modelUtils.d.ts.map +1 -1
  39. package/dist/src/utils/modelUtils.js +3 -0
  40. package/dist/src/utils/modelUtils.js.map +1 -1
  41. package/dist/src/utils/operationUtil.d.ts +12 -0
  42. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  43. package/dist/src/utils/operationUtil.js +22 -1
  44. package/dist/src/utils/operationUtil.js.map +1 -1
  45. package/dist/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +4 -3
  47. package/src/index.ts +20 -5
  48. package/src/modular/buildClientContext.ts +12 -5
  49. package/src/modular/buildOperations.ts +34 -3
  50. package/src/modular/emitModels.ts +43 -0
  51. package/src/modular/emitSamples.ts +2 -2
  52. package/src/modular/helpers/clientHelpers.ts +6 -2
  53. package/src/modular/helpers/operationHelpers.ts +377 -57
  54. package/src/modular/serialization/buildXmlSerializerFunction.ts +511 -0
  55. package/src/modular/static-helpers-metadata.ts +58 -0
  56. package/src/utils/clientUtils.ts +1 -0
  57. package/src/utils/mediaTypes.ts +12 -0
  58. package/src/utils/modelUtils.ts +3 -0
  59. package/src/utils/operationUtil.ts +34 -1
  60. package/static/static-helpers/serialization/xml-helpers.ts +596 -0
@@ -0,0 +1,511 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import { FunctionDeclarationStructure, StructureKind } from "ts-morph";
5
+ import {
6
+ SdkModelPropertyType,
7
+ SdkModelType,
8
+ SdkPackage,
9
+ SdkType,
10
+ UsageFlags
11
+ } from "@azure-tools/typespec-client-generator-core";
12
+ import { SdkContext } from "../../utils/interfaces.js";
13
+ import {
14
+ getAllAncestors,
15
+ getAllProperties
16
+ } from "../helpers/operationHelpers.js";
17
+ import { normalizeModelName } from "../emitModels.js";
18
+ import { NameType } from "@azure-tools/rlc-common";
19
+ import { isAzureCoreErrorType } from "../../utils/modelUtils.js";
20
+ import {
21
+ isSupportedSerializeType,
22
+ ModelSerializeOptions
23
+ } from "./serializeUtils.js";
24
+ import { XmlHelpers } from "../static-helpers-metadata.js";
25
+ import { resolveReference } from "../../framework/reference.js";
26
+ import { refkey } from "../../framework/refkey.js";
27
+ import { reportDiagnostic } from "../../lib.js";
28
+ import { NoTarget } from "@typespec/compiler";
29
+ import { isMetadata } from "@typespec/http";
30
+ import { normalizeModelPropertyName } from "../type-expressions/get-type-expression.js";
31
+ import { isReadOnly } from "@azure-tools/typespec-client-generator-core";
32
+ import { buildModelSerializer } from "./buildSerializerFunction.js";
33
+ import { buildModelDeserializer } from "./buildDeserializerFunction.js";
34
+
35
+ /**
36
+ * Checks if a model type has XML serialization options defined
37
+ */
38
+ export function hasXmlSerialization(type: SdkType): boolean {
39
+ if (type.kind !== "model") {
40
+ return false;
41
+ }
42
+ // Check if the model itself has XML options
43
+ if (type.serializationOptions?.xml) {
44
+ return true;
45
+ }
46
+ // Check if any property has XML options
47
+ return type.properties?.some((p) => p.serializationOptions?.xml) ?? false;
48
+ }
49
+
50
+ /**
51
+ * Checks if any model in the SDK package uses XML serialization
52
+ */
53
+ export function packageUsesXmlSerialization(
54
+ sdkPackage: SdkPackage<any>
55
+ ): boolean {
56
+ for (const model of sdkPackage.models) {
57
+ if (hasXmlSerialization(model)) {
58
+ return true;
59
+ }
60
+ }
61
+ return false;
62
+ }
63
+
64
+ /**
65
+ * Gets the XML element name for a model type
66
+ */
67
+ export function getXmlRootName(type: SdkModelType): string {
68
+ return type.serializationOptions?.xml?.name ?? type.name;
69
+ }
70
+
71
+ /**
72
+ * Gets the XML namespace for a model type
73
+ */
74
+ export function getXmlRootNs(
75
+ type: SdkModelType
76
+ ): { namespace: string; prefix: string } | undefined {
77
+ return type.serializationOptions?.xml?.ns;
78
+ }
79
+
80
+ /**
81
+ * Builds an XML serializer function for a model type
82
+ */
83
+ export function buildXmlModelSerializer(
84
+ context: SdkContext,
85
+ type: SdkModelType,
86
+ options: ModelSerializeOptions = {
87
+ nameOnly: false,
88
+ skipDiscriminatedUnionSuffix: false
89
+ }
90
+ ): FunctionDeclarationStructure | string | undefined {
91
+ if (!isSupportedSerializeType(type)) {
92
+ return undefined;
93
+ }
94
+
95
+ if (!type.name) {
96
+ reportDiagnostic(context.program, {
97
+ code: "anonymous-type-serialization",
98
+ target: type.__raw || NoTarget
99
+ });
100
+ return undefined;
101
+ }
102
+
103
+ if (
104
+ !type.usage ||
105
+ (type.usage !== undefined &&
106
+ (type.usage & UsageFlags.Input) !== UsageFlags.Input)
107
+ ) {
108
+ return undefined;
109
+ }
110
+
111
+ if (isAzureCoreErrorType(context.program, type.__raw!)) {
112
+ return undefined;
113
+ }
114
+
115
+ const serializerFunctionName =
116
+ options.predefinedName ??
117
+ `${normalizeModelName(
118
+ context,
119
+ type,
120
+ NameType.Operation,
121
+ options.skipDiscriminatedUnionSuffix
122
+ )}XmlSerializer`;
123
+
124
+ if (options.nameOnly) {
125
+ return resolveReference(refkey(type, "xmlSerializer"));
126
+ }
127
+
128
+ const serializeToXmlRef = resolveReference(XmlHelpers.serializeToXml);
129
+ const xmlPropertyMetadataRef = resolveReference(
130
+ XmlHelpers.XmlPropertyMetadata
131
+ );
132
+
133
+ const properties = getAllProperties(context, type, getAllAncestors(type));
134
+ const xmlRootName = getXmlRootName(type);
135
+ const xmlRootNs = getXmlRootNs(type);
136
+
137
+ // Build property metadata array
138
+ const propertyMetadata = buildPropertyMetadataArray(context, properties);
139
+
140
+ const statements: string[] = [];
141
+
142
+ // Generate the properties metadata constant
143
+ statements.push(
144
+ `const properties: ${xmlPropertyMetadataRef}[] = [${propertyMetadata}];`
145
+ );
146
+
147
+ // Generate the serialization call
148
+ if (xmlRootNs) {
149
+ statements.push(
150
+ `return ${serializeToXmlRef}(item, properties, "${xmlRootName}", { namespace: "${xmlRootNs.namespace}", prefix: "${xmlRootNs.prefix}" });`
151
+ );
152
+ } else {
153
+ statements.push(
154
+ `return ${serializeToXmlRef}(item, properties, "${xmlRootName}");`
155
+ );
156
+ }
157
+
158
+ const serializerFunction: FunctionDeclarationStructure = {
159
+ kind: StructureKind.Function,
160
+ name: serializerFunctionName,
161
+ isExported: true,
162
+ parameters: [
163
+ {
164
+ name: "item",
165
+ type: resolveReference(refkey(type))
166
+ }
167
+ ],
168
+ returnType: "string",
169
+ statements
170
+ };
171
+
172
+ return serializerFunction;
173
+ }
174
+
175
+ /**
176
+ * Builds the property metadata array for XML serialization
177
+ */
178
+ function buildPropertyMetadataArray(
179
+ context: SdkContext,
180
+ properties: SdkModelPropertyType[]
181
+ ): string {
182
+ const metadataEntries: string[] = [];
183
+
184
+ for (const property of properties) {
185
+ if (property.kind !== "property") {
186
+ continue;
187
+ }
188
+ if (isReadOnly(property)) {
189
+ continue;
190
+ }
191
+ if (isMetadata(context.program, property.__raw!)) {
192
+ continue;
193
+ }
194
+
195
+ const xmlOptions = property.serializationOptions?.xml;
196
+ const jsonOptions = property.serializationOptions?.json;
197
+ const propertyName = normalizeModelPropertyName(context, property);
198
+ const cleanPropertyName = propertyName.replace(/^"|"$/g, "");
199
+
200
+ // Use XML name if available, fall back to JSON name, then property name
201
+ const serializedName =
202
+ xmlOptions?.name ?? jsonOptions?.name ?? property.name;
203
+
204
+ const metadataObj: string[] = [
205
+ `propertyName: "${cleanPropertyName}"`,
206
+ `xmlOptions: { name: "${serializedName}"${buildXmlOptionsString(xmlOptions)} }`
207
+ ];
208
+
209
+ // Add type information for special handling
210
+ const typeInfo = getPropertyTypeInfo(property.type);
211
+ if (typeInfo.type) {
212
+ metadataObj.push(`type: "${typeInfo.type}"`);
213
+ }
214
+ if (typeInfo.dateEncoding) {
215
+ metadataObj.push(`dateEncoding: "${typeInfo.dateEncoding}"`);
216
+ }
217
+
218
+ // Add serializer for complex types
219
+ const nestedSerializer = getNestedXmlSerializer(context, property.type);
220
+ if (nestedSerializer) {
221
+ metadataObj.push(`serializer: ${nestedSerializer}`);
222
+ }
223
+
224
+ metadataEntries.push(`{ ${metadataObj.join(", ")} }`);
225
+ }
226
+
227
+ return metadataEntries.join(",\n ");
228
+ }
229
+
230
+ /**
231
+ * Builds the XML options string from XmlSerializationOptions
232
+ */
233
+ function buildXmlOptionsString(xmlOptions?: {
234
+ name: string;
235
+ attribute?: boolean;
236
+ ns?: { namespace: string; prefix: string };
237
+ unwrapped?: boolean;
238
+ itemsName?: string;
239
+ itemsNs?: { namespace: string; prefix: string };
240
+ }): string {
241
+ if (!xmlOptions) {
242
+ return "";
243
+ }
244
+
245
+ const parts: string[] = [];
246
+
247
+ if (xmlOptions.attribute) {
248
+ parts.push(`attribute: true`);
249
+ }
250
+ if (xmlOptions.ns) {
251
+ parts.push(
252
+ `ns: { namespace: "${xmlOptions.ns.namespace}", prefix: "${xmlOptions.ns.prefix}" }`
253
+ );
254
+ }
255
+ if (xmlOptions.unwrapped) {
256
+ parts.push(`unwrapped: true`);
257
+ }
258
+ if (xmlOptions.itemsName) {
259
+ parts.push(`itemsName: "${xmlOptions.itemsName}"`);
260
+ }
261
+ if (xmlOptions.itemsNs) {
262
+ parts.push(
263
+ `itemsNs: { namespace: "${xmlOptions.itemsNs.namespace}", prefix: "${xmlOptions.itemsNs.prefix}" }`
264
+ );
265
+ }
266
+
267
+ return parts.length > 0 ? `, ${parts.join(", ")}` : "";
268
+ }
269
+
270
+ /**
271
+ * Gets type information for a property for XML serialization
272
+ */
273
+ function getPropertyTypeInfo(type: SdkType): {
274
+ type?: "array" | "object" | "primitive" | "date" | "bytes" | "dict";
275
+ dateEncoding?: "rfc3339" | "rfc7231" | "unixTimestamp";
276
+ } {
277
+ switch (type.kind) {
278
+ case "array":
279
+ return { type: "array" };
280
+ case "model":
281
+ return { type: "object" };
282
+ case "dict":
283
+ return { type: "dict" };
284
+ case "utcDateTime":
285
+ return {
286
+ type: "date",
287
+ dateEncoding:
288
+ (type.encode as "rfc3339" | "rfc7231" | "unixTimestamp") ?? "rfc3339"
289
+ };
290
+ case "bytes":
291
+ return { type: "bytes" };
292
+ default:
293
+ return { type: "primitive" };
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Gets the nested XML serializer function reference for complex types
299
+ */
300
+ function getNestedXmlSerializer(
301
+ context: SdkContext,
302
+ type: SdkType
303
+ ): string | undefined {
304
+ if (type.kind === "model") {
305
+ // For nested objects, use the regular JSON serializer which returns objects
306
+ // The XML builder will convert these objects to XML elements
307
+ const serializerName = buildModelSerializer(context, type, {
308
+ nameOnly: true,
309
+ skipDiscriminatedUnionSuffix: false
310
+ });
311
+ if (typeof serializerName === "string") {
312
+ return serializerName;
313
+ }
314
+ }
315
+ if (type.kind === "array" && type.valueType.kind === "model") {
316
+ // For arrays, use the regular JSON serializer which returns objects
317
+ // The XML helper calls this for each item and handles the array mapping
318
+ const itemSerializer = buildModelSerializer(context, type.valueType, {
319
+ nameOnly: true,
320
+ skipDiscriminatedUnionSuffix: false
321
+ });
322
+ if (typeof itemSerializer === "string") {
323
+ return itemSerializer;
324
+ }
325
+ }
326
+ return undefined;
327
+ }
328
+
329
+ /**
330
+ * Builds an XML deserializer function for a model type
331
+ */
332
+ export function buildXmlModelDeserializer(
333
+ context: SdkContext,
334
+ type: SdkModelType,
335
+ options: ModelSerializeOptions = {
336
+ nameOnly: false,
337
+ skipDiscriminatedUnionSuffix: false
338
+ }
339
+ ): FunctionDeclarationStructure | string | undefined {
340
+ if (!isSupportedSerializeType(type)) {
341
+ return undefined;
342
+ }
343
+
344
+ if (!type.name) {
345
+ reportDiagnostic(context.program, {
346
+ code: "anonymous-type-deserialization",
347
+ target: type.__raw || NoTarget
348
+ });
349
+ return undefined;
350
+ }
351
+
352
+ if (
353
+ !type.usage ||
354
+ (type.usage !== undefined &&
355
+ (type.usage & UsageFlags.Output) !== UsageFlags.Output &&
356
+ (type.usage & UsageFlags.Exception) !== UsageFlags.Exception)
357
+ ) {
358
+ return undefined;
359
+ }
360
+
361
+ if (isAzureCoreErrorType(context.program, type.__raw!)) {
362
+ return undefined;
363
+ }
364
+
365
+ const deserializerFunctionName =
366
+ options.predefinedName ??
367
+ `${normalizeModelName(
368
+ context,
369
+ type,
370
+ NameType.Operation,
371
+ options.skipDiscriminatedUnionSuffix
372
+ )}XmlDeserializer`;
373
+
374
+ if (options.nameOnly) {
375
+ return resolveReference(refkey(type, "xmlDeserializer"));
376
+ }
377
+
378
+ const deserializeFromXmlRef = resolveReference(XmlHelpers.deserializeFromXml);
379
+ const xmlPropertyDeserializeMetadataRef = resolveReference(
380
+ XmlHelpers.XmlPropertyDeserializeMetadata
381
+ );
382
+
383
+ const properties = getAllProperties(context, type, getAllAncestors(type));
384
+ const xmlRootName = getXmlRootName(type);
385
+ const xmlRootNs = getXmlRootNs(type);
386
+
387
+ // Build property metadata array for deserialization
388
+ const propertyMetadata = buildDeserializePropertyMetadataArray(
389
+ context,
390
+ properties
391
+ );
392
+
393
+ const statements: string[] = [];
394
+
395
+ // Generate the properties metadata constant
396
+ statements.push(
397
+ `const properties: ${xmlPropertyDeserializeMetadataRef}[] = [${propertyMetadata}];`
398
+ );
399
+
400
+ // Generate the deserialization call
401
+ const typeRef = resolveReference(refkey(type));
402
+ if (xmlRootNs) {
403
+ statements.push(
404
+ `return ${deserializeFromXmlRef}<${typeRef}>(xmlString, properties, "${xmlRootName}", { namespace: "${xmlRootNs.namespace}", prefix: "${xmlRootNs.prefix}" });`
405
+ );
406
+ } else {
407
+ statements.push(
408
+ `return ${deserializeFromXmlRef}<${typeRef}>(xmlString, properties, "${xmlRootName}");`
409
+ );
410
+ }
411
+
412
+ const deserializerFunction: FunctionDeclarationStructure = {
413
+ kind: StructureKind.Function,
414
+ name: deserializerFunctionName,
415
+ isExported: true,
416
+ parameters: [
417
+ {
418
+ name: "xmlString",
419
+ type: "string"
420
+ }
421
+ ],
422
+ returnType: resolveReference(refkey(type)),
423
+ statements
424
+ };
425
+
426
+ return deserializerFunction;
427
+ }
428
+
429
+ /**
430
+ * Builds the property metadata array for XML deserialization
431
+ */
432
+ function buildDeserializePropertyMetadataArray(
433
+ context: SdkContext,
434
+ properties: SdkModelPropertyType[]
435
+ ): string {
436
+ const metadataEntries: string[] = [];
437
+
438
+ for (const property of properties) {
439
+ if (property.kind !== "property") {
440
+ continue;
441
+ }
442
+ if (isMetadata(context.program, property.__raw!)) {
443
+ continue;
444
+ }
445
+
446
+ const xmlOptions = property.serializationOptions?.xml;
447
+ const jsonOptions = property.serializationOptions?.json;
448
+ const propertyName = normalizeModelPropertyName(context, property);
449
+ const cleanPropertyName = propertyName.replace(/^"|"$/g, "");
450
+
451
+ // Use XML name if available, fall back to JSON name, then property name
452
+ const serializedName =
453
+ xmlOptions?.name ?? jsonOptions?.name ?? property.name;
454
+
455
+ const metadataObj: string[] = [
456
+ `propertyName: "${cleanPropertyName}"`,
457
+ `xmlOptions: { name: "${serializedName}"${buildXmlOptionsString(xmlOptions)} }`
458
+ ];
459
+
460
+ // Add type information for special handling
461
+ const typeInfo = getPropertyTypeInfo(property.type);
462
+ if (typeInfo.type) {
463
+ metadataObj.push(`type: "${typeInfo.type}"`);
464
+ }
465
+ if (typeInfo.dateEncoding) {
466
+ metadataObj.push(`dateEncoding: "${typeInfo.dateEncoding}"`);
467
+ }
468
+
469
+ // Add deserializer for complex types
470
+ const nestedDeserializer = getNestedXmlDeserializer(context, property.type);
471
+ if (nestedDeserializer) {
472
+ metadataObj.push(`deserializer: ${nestedDeserializer}`);
473
+ }
474
+
475
+ metadataEntries.push(`{ ${metadataObj.join(", ")} }`);
476
+ }
477
+
478
+ return metadataEntries.join(",\n ");
479
+ }
480
+
481
+ /**
482
+ * Gets the nested XML deserializer function reference for complex types
483
+ */
484
+ function getNestedXmlDeserializer(
485
+ context: SdkContext,
486
+ type: SdkType
487
+ ): string | undefined {
488
+ if (type.kind === "model") {
489
+ // For nested objects, use the regular JSON deserializer which takes parsed objects
490
+ // The XML parser has already converted the XML to an object structure
491
+ const deserializerName = buildModelDeserializer(context, type, {
492
+ nameOnly: true,
493
+ skipDiscriminatedUnionSuffix: false
494
+ });
495
+ if (typeof deserializerName === "string") {
496
+ return deserializerName;
497
+ }
498
+ }
499
+ if (type.kind === "array" && type.valueType.kind === "model") {
500
+ // For arrays, use the regular JSON deserializer which takes parsed objects
501
+ // The XML helper calls this for each item and handles the array mapping
502
+ const itemDeserializer = buildModelDeserializer(context, type.valueType, {
503
+ nameOnly: true,
504
+ skipDiscriminatedUnionSuffix: false
505
+ });
506
+ if (typeof itemDeserializer === "string") {
507
+ return itemDeserializer;
508
+ }
509
+ }
510
+ return undefined;
511
+ }
@@ -162,3 +162,61 @@ export const CloudSettingHelpers = {
162
162
  location: "cloudSettingHelpers.ts"
163
163
  }
164
164
  } as const;
165
+
166
+ export const XmlHelpers = {
167
+ XmlSerializationOptions: {
168
+ kind: "interface",
169
+ name: "XmlSerializationOptions",
170
+ location: "serialization/xml-helpers.ts"
171
+ },
172
+ XmlPropertyMetadata: {
173
+ kind: "interface",
174
+ name: "XmlPropertyMetadata",
175
+ location: "serialization/xml-helpers.ts"
176
+ },
177
+ XmlPropertyDeserializeMetadata: {
178
+ kind: "interface",
179
+ name: "XmlPropertyDeserializeMetadata",
180
+ location: "serialization/xml-helpers.ts"
181
+ },
182
+ serializeModelToXml: {
183
+ kind: "function",
184
+ name: "serializeModelToXml",
185
+ location: "serialization/xml-helpers.ts"
186
+ },
187
+ serializeToXml: {
188
+ kind: "function",
189
+ name: "serializeToXml",
190
+ location: "serialization/xml-helpers.ts"
191
+ },
192
+ xmlObjectToString: {
193
+ kind: "function",
194
+ name: "xmlObjectToString",
195
+ location: "serialization/xml-helpers.ts"
196
+ },
197
+ parseXmlString: {
198
+ kind: "function",
199
+ name: "parseXmlString",
200
+ location: "serialization/xml-helpers.ts"
201
+ },
202
+ deserializeXmlToModel: {
203
+ kind: "function",
204
+ name: "deserializeXmlToModel",
205
+ location: "serialization/xml-helpers.ts"
206
+ },
207
+ deserializeFromXml: {
208
+ kind: "function",
209
+ name: "deserializeFromXml",
210
+ location: "serialization/xml-helpers.ts"
211
+ },
212
+ isXmlContentType: {
213
+ kind: "function",
214
+ name: "isXmlContentType",
215
+ location: "serialization/xml-helpers.ts"
216
+ },
217
+ isJsonContentType: {
218
+ kind: "function",
219
+ name: "isJsonContentType",
220
+ location: "serialization/xml-helpers.ts"
221
+ }
222
+ } as const;
@@ -41,6 +41,7 @@ export function getRLCClients(dpgContext: SdkContext): SdkClient[] {
41
41
  name: clientName,
42
42
  service: service,
43
43
  type: service,
44
+ services: [service],
44
45
  arm: Boolean(dpgContext.arm),
45
46
  crossLanguageDefinitionId: `${getNamespaceFullName(
46
47
  service
@@ -142,6 +142,18 @@ export function isMediaTypeMultipartFormData(
142
142
  return mt ? mt.type === multipart && mt.subtype === formData : false;
143
143
  }
144
144
 
145
+ /**
146
+ * Checks if the media type is any multipart type (multipart/mixed, multipart/form-data, etc.)
147
+ */
148
+ export function isMediaTypeMultipart(mediaType: string | string[]): boolean {
149
+ if (Array.isArray(mediaType)) {
150
+ return mediaType.some((mt) => isMediaTypeMultipart(mt));
151
+ }
152
+
153
+ const mt = parseMediaType(mediaType);
154
+ return mt ? mt.type === multipart : false;
155
+ }
156
+
145
157
  export function hasMediaType(
146
158
  target: KnownMediaType,
147
159
  sourceTypes: KnownMediaType[] = []
@@ -268,6 +268,9 @@ export function getSchemaForType(
268
268
  if (isNullType(type)) {
269
269
  return { name: "null", type: "null" };
270
270
  }
271
+ if (type.kind === "Intrinsic" && type.name === "void") {
272
+ return { name: "void", type: "void" };
273
+ }
271
274
  reportDiagnostic(program, {
272
275
  code: "invalid-schema",
273
276
  format: {
@@ -43,7 +43,12 @@ import {
43
43
  HttpStatusCodesEntry
44
44
  } from "@typespec/http";
45
45
  import { SdkContext } from "./interfaces.js";
46
- import { KnownMediaType, knownMediaType } from "./mediaTypes.js";
46
+ import {
47
+ KnownMediaType,
48
+ knownMediaType,
49
+ isMediaTypeXml,
50
+ isMediaTypeMultipart
51
+ } from "./mediaTypes.js";
47
52
  import { isByteOrByteUnion } from "./modelUtils.js";
48
53
  import { getOperationNamespaceInterfaceName } from "./namespaceUtils.js";
49
54
  import { resolveReference } from "../framework/reference.js";
@@ -200,6 +205,34 @@ export function isBinaryPayload(
200
205
  return false;
201
206
  }
202
207
 
208
+ /**
209
+ * Checks if the content type(s) indicate XML payload
210
+ */
211
+ export function isXmlPayload(contentType: string | string[]): boolean {
212
+ const contentTypes = Array.isArray(contentType) ? contentType : [contentType];
213
+ return contentTypes.some((ct) => isMediaTypeXml(ct));
214
+ }
215
+
216
+ /**
217
+ * Checks if the content type(s) indicate multipart payload (multipart/mixed, multipart/form-data, etc.)
218
+ */
219
+ export function isMultipartPayload(contentType: string | string[]): boolean {
220
+ return isMediaTypeMultipart(contentType);
221
+ }
222
+
223
+ /**
224
+ * Checks if the operation supports multiple content types (e.g., both JSON and XML)
225
+ */
226
+ export function hasDualFormatSupport(contentTypes: string[]): boolean {
227
+ const hasJson = contentTypes.some(
228
+ (ct) => knownMediaType(ct) === KnownMediaType.Json
229
+ );
230
+ const hasXml = contentTypes.some(
231
+ (ct) => knownMediaType(ct) === KnownMediaType.Xml
232
+ );
233
+ return hasJson && hasXml;
234
+ }
235
+
203
236
  export function isLongRunningOperation(
204
237
  program: Program,
205
238
  operation: HttpOperation