@azure-tools/typespec-ts 0.57.0-dev.5 → 0.57.0-dev.7

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 (87) hide show
  1. package/dist/src/lib.d.ts +10 -1
  2. package/dist/src/lib.d.ts.map +1 -1
  3. package/dist/src/lib.js +6 -0
  4. package/dist/src/lib.js.map +1 -1
  5. package/dist/src/modular/build-classical-client.d.ts.map +1 -1
  6. package/dist/src/modular/build-classical-client.js +8 -8
  7. package/dist/src/modular/build-classical-client.js.map +1 -1
  8. package/dist/src/modular/build-operations.js +2 -2
  9. package/dist/src/modular/build-operations.js.map +1 -1
  10. package/dist/src/modular/build-root-index.js +1 -1
  11. package/dist/src/modular/build-root-index.js.map +1 -1
  12. package/dist/src/modular/emit-models.d.ts.map +1 -1
  13. package/dist/src/modular/emit-models.js +17 -8
  14. package/dist/src/modular/emit-models.js.map +1 -1
  15. package/dist/src/modular/emit-samples.d.ts.map +1 -1
  16. package/dist/src/modular/emit-samples.js +29 -21
  17. package/dist/src/modular/emit-samples.js.map +1 -1
  18. package/dist/src/modular/emit-tests.js +2 -2
  19. package/dist/src/modular/emit-tests.js.map +1 -1
  20. package/dist/src/modular/helpers/classical-operation-helpers.d.ts.map +1 -1
  21. package/dist/src/modular/helpers/classical-operation-helpers.js +7 -6
  22. package/dist/src/modular/helpers/classical-operation-helpers.js.map +1 -1
  23. package/dist/src/modular/helpers/client-helpers.d.ts.map +1 -1
  24. package/dist/src/modular/helpers/client-helpers.js +7 -6
  25. package/dist/src/modular/helpers/client-helpers.js.map +1 -1
  26. package/dist/src/modular/helpers/example-value-helpers.d.ts +2 -1
  27. package/dist/src/modular/helpers/example-value-helpers.d.ts.map +1 -1
  28. package/dist/src/modular/helpers/example-value-helpers.js +34 -24
  29. package/dist/src/modular/helpers/example-value-helpers.js.map +1 -1
  30. package/dist/src/modular/helpers/naming-helpers.d.ts.map +1 -1
  31. package/dist/src/modular/helpers/naming-helpers.js +3 -3
  32. package/dist/src/modular/helpers/naming-helpers.js.map +1 -1
  33. package/dist/src/modular/helpers/operation-helpers.d.ts.map +1 -1
  34. package/dist/src/modular/helpers/operation-helpers.js +23 -18
  35. package/dist/src/modular/helpers/operation-helpers.js.map +1 -1
  36. package/dist/src/modular/helpers/type-helpers.d.ts.map +1 -1
  37. package/dist/src/modular/helpers/type-helpers.js +2 -2
  38. package/dist/src/modular/helpers/type-helpers.js.map +1 -1
  39. package/dist/src/modular/serialization/build-deserializer-function.js +6 -4
  40. package/dist/src/modular/serialization/build-deserializer-function.js.map +1 -1
  41. package/dist/src/modular/serialization/build-serializer-function.d.ts.map +1 -1
  42. package/dist/src/modular/serialization/build-serializer-function.js +9 -7
  43. package/dist/src/modular/serialization/build-serializer-function.js.map +1 -1
  44. package/dist/src/modular/serialization/build-xml-serializer-function.d.ts.map +1 -1
  45. package/dist/src/modular/serialization/build-xml-serializer-function.js +11 -13
  46. package/dist/src/modular/serialization/build-xml-serializer-function.js.map +1 -1
  47. package/dist/src/modular/type-expressions/get-type-expression.d.ts +1 -0
  48. package/dist/src/modular/type-expressions/get-type-expression.d.ts.map +1 -1
  49. package/dist/src/modular/type-expressions/get-type-expression.js +6 -4
  50. package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
  51. package/dist/src/utils/client-utils.d.ts.map +1 -1
  52. package/dist/src/utils/client-utils.js +16 -5
  53. package/dist/src/utils/client-utils.js.map +1 -1
  54. package/dist/src/utils/cross-language-def.d.ts.map +1 -1
  55. package/dist/src/utils/cross-language-def.js +1 -2
  56. package/dist/src/utils/cross-language-def.js.map +1 -1
  57. package/dist/src/utils/name-utils.d.ts +15 -0
  58. package/dist/src/utils/name-utils.d.ts.map +1 -1
  59. package/dist/src/utils/name-utils.js +60 -0
  60. package/dist/src/utils/name-utils.js.map +1 -1
  61. package/dist/src/utils/operation-util.d.ts.map +1 -1
  62. package/dist/src/utils/operation-util.js +15 -5
  63. package/dist/src/utils/operation-util.js.map +1 -1
  64. package/dist/tsconfig.tsbuildinfo +1 -1
  65. package/package.json +12 -12
  66. package/src/lib.ts +6 -0
  67. package/src/modular/build-classical-client.ts +11 -8
  68. package/src/modular/build-operations.ts +2 -2
  69. package/src/modular/build-root-index.ts +1 -1
  70. package/src/modular/emit-models.ts +25 -8
  71. package/src/modular/emit-samples.ts +42 -34
  72. package/src/modular/emit-tests.ts +2 -2
  73. package/src/modular/helpers/classical-operation-helpers.ts +9 -11
  74. package/src/modular/helpers/client-helpers.ts +6 -5
  75. package/src/modular/helpers/example-value-helpers.ts +52 -41
  76. package/src/modular/helpers/naming-helpers.ts +8 -3
  77. package/src/modular/helpers/operation-helpers.ts +31 -18
  78. package/src/modular/helpers/type-helpers.ts +2 -5
  79. package/src/modular/serialization/build-deserializer-function.ts +6 -9
  80. package/src/modular/serialization/build-serializer-function.ts +14 -11
  81. package/src/modular/serialization/build-xml-serializer-function.ts +11 -17
  82. package/src/modular/type-expressions/get-type-expression.ts +10 -4
  83. package/src/utils/client-utils.ts +28 -4
  84. package/src/utils/cross-language-def.ts +1 -2
  85. package/src/utils/name-utils.ts +94 -0
  86. package/src/utils/operation-util.ts +27 -14
  87. package/static/static-helpers/urlTemplate.ts +4 -2
@@ -15,7 +15,16 @@ import { resolveReference } from "../../framework/reference.js";
15
15
  import { getSubscriptionId } from "../../transform/transform-client-options.js";
16
16
  import { hasKeyCredential, hasTokenCredential } from "../../utils/credential-utils.js";
17
17
  import type { SdkContext } from "../../utils/interfaces.js";
18
- import { NameType, normalizeName } from "../../utils/name-utils.js";
18
+ import {
19
+ formatOptionalPropertyAccess,
20
+ formatPropertyAccess,
21
+ formatPropertyName,
22
+ NameType,
23
+ normalizeName,
24
+ normalizeSdkName,
25
+ normalizeSdkPropertyName,
26
+ type SdkName,
27
+ } from "../../utils/name-utils.js";
19
28
  import { getMethodHierarchiesMap, type ServiceOperation } from "../../utils/operation-util.js";
20
29
  import { AzureIdentityDependencies, AzureTestDependencies } from "../external-dependencies.js";
21
30
  import { getClientParametersDeclaration } from "./client-helpers.js";
@@ -56,13 +65,14 @@ export function buildParameterValueMap(
56
65
  * Prepare a common value for tests
57
66
  */
58
67
  export function prepareCommonValue(
59
- name: string,
68
+ name: string | SdkName,
60
69
  value: SdkExampleValue | string,
61
70
  isOptional?: boolean,
62
71
  onClient?: boolean,
63
72
  ): CommonValue {
73
+ const sdkName = typeof name === "string" ? { name } : name;
64
74
  return {
65
- name: normalizeName(name, NameType.Parameter),
75
+ name: normalizeSdkName(sdkName, NameType.Parameter),
66
76
  value: typeof value === "string" ? value : serializeExampleValue(value),
67
77
  isOptional: Boolean(isOptional),
68
78
  onClient: Boolean(onClient),
@@ -187,7 +197,10 @@ export function serializeExampleValue(value: SdkExampleValue): string {
187
197
  }) {
188
198
  let property;
189
199
  if (value.type.kind === "model") {
190
- property = value.type.properties.find((p) => p.name === propName);
200
+ property =
201
+ value.type.properties.find(
202
+ (p) => (p.serializationOptions.json?.name ?? p.name) === propName,
203
+ ) ?? value.type.properties.find((p) => p.name === propName);
191
204
  }
192
205
  const propValue = value.value[propName];
193
206
  if (propValue === undefined || propValue === null) {
@@ -205,19 +218,23 @@ export function serializeExampleValue(value: SdkExampleValue): string {
205
218
  if (innerPropValue === undefined || innerPropValue === null) {
206
219
  continue;
207
220
  }
208
- const innerProperty = property.type.properties.find((p) => p.name === innerPropName);
221
+ const innerProperty =
222
+ property.type.properties.find(
223
+ (p) => (p.serializationOptions.json?.name ?? p.name) === innerPropName,
224
+ ) ?? property.type.properties.find((p) => p.name === innerPropName);
209
225
  if (innerProperty && isReadOnly(innerProperty as SdkModelPropertyType)) {
210
226
  continue;
211
227
  }
212
228
  values.push(
213
- `"${innerMapper.get(innerPropName) ?? innerPropName}": ` +
229
+ `${JSON.stringify(innerMapper.get(innerPropName) ?? innerPropName)}: ` +
214
230
  serializeExampleValue(innerPropValue),
215
231
  );
216
232
  }
217
233
  continue;
218
234
  }
219
235
  const propRetValue =
220
- `"${mapper.get(propName) ?? propName}": ` + serializeExampleValue(propValue);
236
+ `${JSON.stringify(mapper.get(propName) ?? propName)}: ` +
237
+ serializeExampleValue(propValue);
221
238
  values.push(propRetValue);
222
239
  }
223
240
  const additionalBags = [];
@@ -229,14 +246,15 @@ export function serializeExampleValue(value: SdkExampleValue): string {
229
246
  continue;
230
247
  }
231
248
  const propRetValue =
232
- `"${mapper.get(propName) ?? propName}": ` + serializeExampleValue(propValue);
249
+ `${JSON.stringify(mapper.get(propName) ?? propName)}: ` +
250
+ serializeExampleValue(propValue);
233
251
  additionalBags.push(propRetValue);
234
252
  }
235
253
  if (additionalBags.length > 0) {
236
254
  const name = mapper.get("additionalProperties")
237
255
  ? "additionalPropertiesBag"
238
256
  : "additionalProperties";
239
- values.push(`"${name}": {
257
+ values.push(`${JSON.stringify(name)}: {
240
258
  ${additionalBags.join(", ")}
241
259
  }`);
242
260
  }
@@ -268,10 +286,7 @@ function buildTestPropertyNameMapper(type: SdkExampleValue["type"]) {
268
286
  if (prop.kind !== "property") {
269
287
  continue;
270
288
  }
271
- mapper.set(
272
- prop.serializationOptions.json?.name || prop.name,
273
- normalizeName(prop.name, NameType.Property),
274
- );
289
+ mapper.set(prop.serializationOptions.json?.name || prop.name, normalizeSdkPropertyName(prop));
275
290
  }
276
291
  return mapper;
277
292
  }
@@ -368,16 +383,14 @@ export function prepareCommonParameters(
368
383
  if (!exampleValue || !exampleValue.value) {
369
384
  if (!param.optional) {
370
385
  // Generate default values for required parameters without examples in tests
371
- result.push(
372
- prepareCommonValue(param.name, `"{Your ${param.name}}"`, false, param.onClient),
373
- );
386
+ result.push(prepareCommonValue(param, `"{Your ${param.name}}"`, false, param.onClient));
374
387
  }
375
388
  continue;
376
389
  }
377
390
 
378
391
  result.push(
379
392
  prepareCommonValue(
380
- exampleValue.parameter.name,
393
+ exampleValue.parameter,
381
394
  exampleValue.value,
382
395
  param.optional,
383
396
  param.onClient,
@@ -401,7 +414,8 @@ export function prepareCommonParameters(
401
414
  bodyExample.value.kind === "model"
402
415
  ) {
403
416
  for (const prop of bodyParam.type.properties) {
404
- const propExample = bodyExample.value.value[prop.name];
417
+ const wireName = prop.serializationOptions.json?.name ?? prop.name;
418
+ const propExample = bodyExample.value.value[wireName] ?? bodyExample.value.value[prop.name];
405
419
  if (!propExample) {
406
420
  continue;
407
421
  }
@@ -409,7 +423,7 @@ export function prepareCommonParameters(
409
423
  if (isReadOnly(prop as SdkModelPropertyType)) {
410
424
  continue;
411
425
  }
412
- result.push(prepareCommonValue(prop.name, propExample, prop.optional, prop.onClient));
426
+ result.push(prepareCommonValue(prop, propExample, prop.optional, prop.onClient));
413
427
  }
414
428
  } else {
415
429
  // Check if the body parameter is nested inside a wrapper (e.g., @bodyRoot)
@@ -419,30 +433,19 @@ export function prepareCommonParameters(
419
433
  if (isNestedBody) {
420
434
  const path = segments[0]!;
421
435
  // The first segment is the method-level wrapper param (e.g., "body")
422
- const methodParamName = path[0]!.name;
423
436
  const methodParamOptional = path[0]!.optional;
424
437
  // Wrap the example value with the intermediate property names
425
438
  let wrappedValue = serializeExampleValue(bodyExample.value);
426
439
  for (let i = path.length - 1; i >= 1; i--) {
427
- const propName = normalizeName(path[i]!.name, NameType.Property);
440
+ const propName = formatPropertyName(normalizeSdkPropertyName(path[i]!));
428
441
  wrappedValue = `{ ${propName}: ${wrappedValue} }`;
429
442
  }
430
443
  result.push(
431
- prepareCommonValue(
432
- methodParamName,
433
- wrappedValue,
434
- methodParamOptional,
435
- bodyParam.onClient,
436
- ),
444
+ prepareCommonValue(path[0]!, wrappedValue, methodParamOptional, bodyParam.onClient),
437
445
  );
438
446
  } else {
439
447
  result.push(
440
- prepareCommonValue(
441
- bodyParam.name,
442
- bodyExample.value,
443
- bodyParam.optional,
444
- bodyParam.onClient,
445
- ),
448
+ prepareCommonValue(bodyParam, bodyExample.value, bodyParam.optional, bodyParam.onClient),
446
449
  );
447
450
  }
448
451
  }
@@ -457,7 +460,7 @@ export function prepareCommonParameters(
457
460
  .forEach((param) => {
458
461
  const exampleValue = parameterMap[param.serializedName];
459
462
  if (exampleValue && exampleValue.value) {
460
- result.push(prepareCommonValue(param.name, exampleValue.value, true, param.onClient));
463
+ result.push(prepareCommonValue(param, exampleValue.value, true, param.onClient));
461
464
  }
462
465
  });
463
466
 
@@ -492,10 +495,7 @@ export function iterateClientsAndMethods(
492
495
  client,
493
496
  generatedFiles,
494
497
  classicalMethodPrefix: prefix,
495
- subFolder:
496
- clients.length > 1
497
- ? normalizeName(getClassicalClientName(client), NameType.File)
498
- : undefined,
498
+ subFolder: clients.length > 1 ? normalizeSdkName(client, NameType.File) : undefined,
499
499
  hierarchies: hierarchies,
500
500
  });
501
501
  }
@@ -564,7 +564,9 @@ export function generateMethodCall(
564
564
  }
565
565
 
566
566
  const prefix = options.classicalMethodPrefix ? `${options.classicalMethodPrefix}.` : "";
567
- const methodCall = `client.${prefix}${normalizeName(method.oriName ?? method.name, NameType.Property)}(${methodParams.join(", ")})`;
567
+ const methodCall = `client.${prefix}${normalizeSdkName(method, NameType.Property, {
568
+ nameOverride: method.oriName ?? method.name,
569
+ })}(${methodParams.join(", ")})`;
568
570
 
569
571
  return { methodCall, clientParams, clientParamDefs };
570
572
  }
@@ -681,7 +683,11 @@ export function generateAssertionsForValue(
681
683
  // Check if this property is flattened in the model type
682
684
  let property;
683
685
  if (value.kind === "model" && value.type.kind === "model") {
684
- property = value.type.properties.find((p) => p.kind === "property" && p.name === key);
686
+ property =
687
+ value.type.properties.find(
688
+ (p) =>
689
+ p.kind === "property" && (p.serializationOptions.json?.name ?? p.name) === key,
690
+ ) ?? value.type.properties.find((p) => p.kind === "property" && p.name === key);
685
691
  }
686
692
  if (property?.flatten && (val as SdkExampleValue).kind === "model") {
687
693
  // For flattened properties, recurse using the parent path so
@@ -694,7 +700,12 @@ export function generateAssertionsForValue(
694
700
  );
695
701
  assertions.push(...innerAssertions);
696
702
  } else {
697
- const propPath = `${path}.${key}`;
703
+ const propertyName = property ? normalizeSdkPropertyName(property) : key;
704
+ const optionalBase = path.endsWith("?");
705
+ const basePath = optionalBase ? path.slice(0, -1) : path;
706
+ const propPath = optionalBase
707
+ ? formatOptionalPropertyAccess(basePath, propertyName)
708
+ : formatPropertyAccess(basePath, propertyName);
698
709
  const nestedVal = val as SdkExampleValue;
699
710
  // For nested model/dict values, append "?" to the path so child
700
711
  // property accesses use optional chaining (e.g. result.systemData?.createdBy)
@@ -5,7 +5,12 @@ import {
5
5
  } from "@azure-tools/typespec-client-generator-core";
6
6
  import pluralize from "pluralize";
7
7
  import type { SdkContext } from "../../utils/interfaces.js";
8
- import { NameType, normalizeName, ReservedModelNames } from "../../utils/name-utils.js";
8
+ import {
9
+ NameType,
10
+ normalizeName,
11
+ normalizeSdkName,
12
+ ReservedModelNames,
13
+ } from "../../utils/name-utils.js";
9
14
  import type { ServiceOperation } from "../../utils/operation-util.js";
10
15
 
11
16
  export function getClientName(client: SdkClientType<SdkServiceOperation>): string {
@@ -29,8 +34,8 @@ export function getOperationName(
29
34
  dpgContext?: SdkContext,
30
35
  prefixes: string[] = [],
31
36
  ): GuardedName {
32
- const name = normalizeName(operation.name, NameType.Method, true);
33
- const propertyName = normalizeName(operation.name, NameType.Property);
37
+ const name = normalizeSdkName(operation, NameType.Method, { shouldGuard: true });
38
+ const propertyName = normalizeSdkName(operation, NameType.Property);
34
39
  const isDataplane = dpgContext !== undefined && !dpgContext.emitterOptions?.azureArm;
35
40
  // An explicit `@clientName` override is an intentional naming choice by the user, so we
36
41
  // honor it verbatim and skip the reserved-word disambiguation (and its `@fixme`). The
@@ -35,7 +35,13 @@ import { refkey } from "../../framework/refkey.js";
35
35
  import { reportDiagnostic } from "../../lib.js";
36
36
  import type { SdkContext } from "../../utils/interfaces.js";
37
37
  import { isAzureCoreErrorType } from "../../utils/model-utils.js";
38
- import { NameType, normalizeName } from "../../utils/name-utils.js";
38
+ import {
39
+ formatOptionalPropertyAccess,
40
+ formatPropertyAccess,
41
+ NameType,
42
+ normalizeSdkName,
43
+ normalizeSdkPropertyName,
44
+ } from "../../utils/name-utils.js";
39
45
  import {
40
46
  getCollectionFormatFromArrayEncoding,
41
47
  getCollectionFormatHelper,
@@ -1400,7 +1406,7 @@ export function getOperationOptionsName(
1400
1406
  includeGroupName && operation.name.indexOf("_") === -1
1401
1407
  ? getClassicalLayerPrefix(prefixes, NameType.Interface)
1402
1408
  : "";
1403
- const optionName = `${prefix}${normalizeName(operation.name, NameType.Interface)}OptionalParams`;
1409
+ const optionName = `${prefix}${normalizeSdkName(operation, NameType.Interface)}OptionalParams`;
1404
1410
  return optionName;
1405
1411
  }
1406
1412
 
@@ -1690,17 +1696,19 @@ function isContentType(param: SdkHttpParameter): boolean {
1690
1696
 
1691
1697
  function getContentTypeValue(param: SdkHttpParameter, optionalParamName: string = "options") {
1692
1698
  const defaultValue = param.clientDefaultValue;
1699
+ const optionAccessor = formatPropertyAccess(
1700
+ optionalParamName,
1701
+ normalizeSdkName(param, NameType.Parameter),
1702
+ );
1693
1703
  // allow customers to customize the content type if it's guessed by tcgc.
1694
1704
  if (isConstant(param.type)) {
1695
1705
  return `contentType: ${getConstantValue(param.type)}`;
1696
1706
  }
1697
1707
  if (defaultValue) {
1698
- return `contentType: ${optionalParamName}.${param.name} as any ?? "${defaultValue}"`;
1708
+ return `contentType: ${optionAccessor} as any ?? "${defaultValue}"`;
1699
1709
  } else {
1700
1710
  return `contentType: ${
1701
- !param.optional
1702
- ? normalizeName(param.name, NameType.Property)
1703
- : `${optionalParamName}.` + param.name + " as any"
1711
+ !param.optional ? normalizeSdkName(param, NameType.Property) : `${optionAccessor} as any`
1704
1712
  }`;
1705
1713
  }
1706
1714
  }
@@ -1919,10 +1927,11 @@ function getParamAccessor(param: SdkHttpParameter, optionalParamName: string = "
1919
1927
  if (param.onClient) {
1920
1928
  return `${clientPrefix}${getClientParameterName(param)}`;
1921
1929
  }
1930
+ const parameterName = normalizeSdkName(param, NameType.Parameter, { shouldGuard: true });
1922
1931
  if (getEffectiveOptional(param)) {
1923
- return `${optionalParamName}?.${param.name}`;
1932
+ return formatOptionalPropertyAccess(optionalParamName, parameterName);
1924
1933
  }
1925
- return param.name;
1934
+ return parameterName;
1926
1935
  }
1927
1936
 
1928
1937
  /**
@@ -1948,25 +1957,29 @@ function getMethodParamExpr(
1948
1957
  return undefined;
1949
1958
  }
1950
1959
 
1951
- const parts: string[] = [];
1960
+ let expression = "";
1952
1961
  for (let i = 0; i < path.length; i++) {
1953
1962
  const segment = path[i]!;
1954
1963
  if (i === 0) {
1955
1964
  // Normalize names for client-level segments to match the context interface property names
1956
1965
  const segmentName = segment.onClient
1957
1966
  ? getClientParameterName(segment as SdkMethodParameter)
1958
- : segment.name;
1967
+ : normalizeSdkName(segment, NameType.Parameter, { shouldGuard: true });
1959
1968
  if (segment.optional && !segment.onClient) {
1960
1969
  // If the first segment is optional and not on the client, we need to start with the optionalParamName
1961
- parts.push(`${optionalParamName}?.`);
1970
+ expression = formatOptionalPropertyAccess(optionalParamName, segmentName);
1971
+ } else {
1972
+ expression = segmentName;
1962
1973
  }
1963
- parts.push(segmentName);
1964
1974
  } else {
1965
1975
  const needsOptionalChain = path[i - 1]!.optional;
1966
- parts.push(`${needsOptionalChain ? "?." : "."}${segment.name}`);
1976
+ const segmentName = normalizeSdkPropertyName(segment);
1977
+ expression = needsOptionalChain
1978
+ ? formatOptionalPropertyAccess(expression, segmentName)
1979
+ : formatPropertyAccess(expression, segmentName);
1967
1980
  }
1968
1981
  }
1969
- return parts.join("");
1982
+ return expression;
1970
1983
  }
1971
1984
 
1972
1985
  function getPathParamExpr(
@@ -2692,14 +2705,14 @@ export function getPropertyFullName(
2692
2705
  ) {
2693
2706
  const normalizedPropertyName =
2694
2707
  propertyPath === ""
2695
- ? normalizeName(property.name, NameType.Parameter, true)
2696
- : normalizeModelPropertyName(context, property).replace(/^"/g, "").replace(/"$/g, "");
2708
+ ? normalizeSdkName(property, NameType.Parameter, { shouldGuard: true })
2709
+ : normalizeModelPropertyName(context, property);
2697
2710
 
2698
2711
  let fullName = normalizedPropertyName;
2699
2712
  if (propertyPath === "" && property.optional) {
2700
2713
  fullName = `options?.${normalizedPropertyName}`;
2701
2714
  } else if (propertyPath) {
2702
- fullName = `${propertyPath}["${normalizedPropertyName}"]`;
2715
+ fullName = `${propertyPath}[${normalizedPropertyName}]`;
2703
2716
  }
2704
2717
 
2705
2718
  return fullName;
@@ -2896,7 +2909,7 @@ export function getOperationResponseTypeName(method: [string[], ServiceOperation
2896
2909
  const prefix = !operation.name.includes("_")
2897
2910
  ? getClassicalLayerPrefix(prefixes, NameType.Interface)
2898
2911
  : "";
2899
- return `${prefix}${normalizeName(operation.name, NameType.Interface)}Response`;
2912
+ return `${prefix}${normalizeSdkName(operation, NameType.Interface)}Response`;
2900
2913
  }
2901
2914
 
2902
2915
  /**
@@ -7,7 +7,7 @@ import type {
7
7
  SdkType,
8
8
  } from "@azure-tools/typespec-client-generator-core";
9
9
  import type { SdkContext } from "../../utils/interfaces.js";
10
- import { NameType, normalizeName } from "../../utils/name-utils.js";
10
+ import { normalizeSdkPropertyName } from "../../utils/name-utils.js";
11
11
  import {
12
12
  getPropertyWithOverrides,
13
13
  type ModelOverrideOptions,
@@ -110,10 +110,7 @@ export function buildPropertyNameMapper(
110
110
  continue;
111
111
  }
112
112
  const prop = getPropertyWithOverrides(p, overrides);
113
- mapper.set(
114
- prop.serializationOptions.json?.name || prop.name,
115
- normalizeName(prop.name, NameType.Property),
116
- );
113
+ mapper.set(prop.serializationOptions.json?.name || prop.name, normalizeSdkPropertyName(prop));
117
114
  }
118
115
  return mapper;
119
116
  }
@@ -184,7 +184,6 @@ function buildPolymorphicDeserializer(
184
184
  ) {
185
185
  return;
186
186
  }
187
- const union = subType?.discriminatedSubtypes ? "_Union" : "";
188
187
  if (!subType || !subType?.name) {
189
188
  reportDiagnostic(context.program, {
190
189
  code: "anonymous-type-deserialization",
@@ -192,14 +191,12 @@ function buildPolymorphicDeserializer(
192
191
  });
193
192
  return; // Skip this subtype
194
193
  }
195
-
196
- const rawSubTypeName = `${subType.name}${union}`;
197
- const subTypeName = `${normalizeName(rawSubTypeName, NameType.Interface, true)}`;
198
- const subtypeDeserializerName = normalizeName(
199
- `${subTypeName}Deserializer`,
200
- NameType.Operation,
201
- true,
202
- );
194
+ const union = subType.discriminatedSubtypes ? "Union" : "";
195
+ const subTypeName = normalizeModelName(context, subType, NameType.Interface, !union);
196
+ const subtypeDeserializerName = buildModelDeserializer(context, subType, {
197
+ nameOnly: true,
198
+ skipDiscriminatedUnionSuffix: false,
199
+ }) as string;
203
200
 
204
201
  cases.push(`
205
202
  case "${discriminatedValue}":
@@ -16,7 +16,12 @@ import { refkey } from "../../framework/refkey.js";
16
16
  import { reportDiagnostic } from "../../lib.js";
17
17
  import type { SdkContext } from "../../utils/interfaces.js";
18
18
  import { isAzureCoreErrorType } from "../../utils/model-utils.js";
19
- import { NameType, normalizeName } from "../../utils/name-utils.js";
19
+ import {
20
+ formatPropertyAccess,
21
+ NameType,
22
+ normalizeName,
23
+ normalizeSdkPropertyName,
24
+ } from "../../utils/name-utils.js";
20
25
  import { getAdditionalPropertiesName, normalizeModelName } from "../emit-models.js";
21
26
  import {
22
27
  getAllAncestors,
@@ -185,7 +190,6 @@ function buildPolymorphicSerializer(
185
190
  ) {
186
191
  return;
187
192
  }
188
- const union = subType?.discriminatedSubtypes ? "_Union" : "";
189
193
  if (!subType || !subType?.name) {
190
194
  reportDiagnostic(context.program, {
191
195
  code: "anonymous-type-serialization",
@@ -193,13 +197,12 @@ function buildPolymorphicSerializer(
193
197
  });
194
198
  return; // Skip this subtype
195
199
  }
196
- const rawSubTypeName = `${subType.name}${union}`;
197
- const subTypeName = `${normalizeName(rawSubTypeName, NameType.Interface, true)}`;
198
- const subtypeSerializerName = normalizeName(
199
- `${rawSubTypeName}_Serializer`,
200
- NameType.Method,
201
- true,
202
- );
200
+ const union = subType.discriminatedSubtypes ? "Union" : "";
201
+ const subTypeName = normalizeModelName(context, subType, NameType.Interface, !union);
202
+ const subtypeSerializerName = buildModelSerializer(context, subType, {
203
+ nameOnly: true,
204
+ skipDiscriminatedUnionSuffix: false,
205
+ }) as string;
203
206
 
204
207
  cases.push(`
205
208
  case "${discriminatedValue}":
@@ -208,7 +211,7 @@ function buildPolymorphicSerializer(
208
211
  });
209
212
 
210
213
  statements.push(`
211
- switch (item.${normalizeName(type.discriminatorProperty.name, NameType.Property)}) {
214
+ switch (${formatPropertyAccess("item", normalizeSdkPropertyName(type.discriminatorProperty))}) {
212
215
  ${cases.join("\n")}
213
216
  default:
214
217
  return item;
@@ -281,7 +284,7 @@ function buildDiscriminatedUnionSerializer(
281
284
  `);
282
285
  }
283
286
  output.push(`
284
- switch (item.${type.discriminatorProperty ? normalizeName(type.discriminatorProperty.name, NameType.Property) : "unknown"}) {
287
+ switch (${formatPropertyAccess("item", type.discriminatorProperty ? normalizeSdkPropertyName(type.discriminatorProperty) : "unknown")}) {
285
288
  ${cases.join("\n")}
286
289
  default:
287
290
  return ${baseSerializerName}(item);
@@ -23,7 +23,7 @@ import { getAdditionalPropertiesName, normalizeModelName } from "../emit-models.
23
23
  import { getAllAncestors, getAllProperties } from "../helpers/operation-helpers.js";
24
24
  import { getAdditionalPropertiesType } from "../helpers/type-helpers.js";
25
25
  import { XmlHelpers } from "../static-helpers-metadata.js";
26
- import { normalizeModelPropertyName } from "../type-expressions/get-type-expression.js";
26
+ import { getModelPropertyName } from "../type-expressions/get-type-expression.js";
27
27
  import { isSupportedSerializeType, type ModelSerializeOptions } from "./serialize-utils.js";
28
28
 
29
29
  /**
@@ -290,8 +290,8 @@ function buildXmlObjectPropertyAssignments(
290
290
  }
291
291
 
292
292
  const xmlOptions = property.serializationOptions?.xml;
293
- const propertyName = normalizeModelPropertyName(context, property);
294
- const cleanPropertyName = propertyName.replace(/^"|"$/g, "");
293
+ const propertyName = getModelPropertyName(context, property);
294
+ const propertyAccessor = `item[${JSON.stringify(propertyName)}]`;
295
295
 
296
296
  // Use XML name if available, fall back to serializedName, then JSON name, then property name
297
297
  const xmlName = xmlOptions?.name ?? property.name;
@@ -302,14 +302,14 @@ function buildXmlObjectPropertyAssignments(
302
302
  let valueExpr: string;
303
303
  if (nestedSerializer && property.type.kind === "model") {
304
304
  // Nested object - use XML object serializer
305
- valueExpr = `item["${cleanPropertyName}"] !== undefined ? ${nestedSerializer}(item["${cleanPropertyName}"]) : undefined`;
305
+ valueExpr = `${propertyAccessor} !== undefined ? ${nestedSerializer}(${propertyAccessor}) : undefined`;
306
306
  } else if (
307
307
  nestedSerializer &&
308
308
  property.type.kind === "array" &&
309
309
  property.type.valueType.kind === "model"
310
310
  ) {
311
311
  // Array of objects - map each item through XML object serializer
312
- const mappedExpr = `item["${cleanPropertyName}"]?.map((i: any) => ${nestedSerializer}(i))`;
312
+ const mappedExpr = `${propertyAccessor}?.map((i: any) => ${nestedSerializer}(i))`;
313
313
  if (xmlOptions?.unwrapped) {
314
314
  // Unwrapped: items are direct siblings under the item element name
315
315
  const itemKey = xmlOptions?.itemsName ?? xmlName;
@@ -326,7 +326,7 @@ function buildXmlObjectPropertyAssignments(
326
326
  const primitiveExpr = buildXmlValueSerializationExpr(
327
327
  context,
328
328
  property.type,
329
- `item["${cleanPropertyName}"]`,
329
+ propertyAccessor,
330
330
  );
331
331
  if (xmlOptions?.unwrapped) {
332
332
  const itemKey = xmlOptions?.itemsName ?? xmlName;
@@ -339,11 +339,7 @@ function buildXmlObjectPropertyAssignments(
339
339
  }
340
340
  } else {
341
341
  // Handle type-specific serialization
342
- valueExpr = buildXmlValueSerializationExpr(
343
- context,
344
- property.type,
345
- `item["${cleanPropertyName}"]`,
346
- );
342
+ valueExpr = buildXmlValueSerializationExpr(context, property.type, propertyAccessor);
347
343
  }
348
344
 
349
345
  assignments.push(`"${xmlName}": ${valueExpr}`);
@@ -419,14 +415,13 @@ function buildPropertyMetadataArray(
419
415
 
420
416
  const xmlOptions = property.serializationOptions?.xml;
421
417
  const jsonOptions = property.serializationOptions?.json;
422
- const propertyName = normalizeModelPropertyName(context, property);
423
- const cleanPropertyName = propertyName.replace(/^"|"$/g, "");
418
+ const propertyName = getModelPropertyName(context, property);
424
419
 
425
420
  // Use XML name if available, fall back to JSON name, then property name
426
421
  const serializedName = xmlOptions?.name ?? jsonOptions?.name ?? property.name;
427
422
 
428
423
  const metadataObj: string[] = [
429
- `propertyName: "${cleanPropertyName}"`,
424
+ `propertyName: ${JSON.stringify(propertyName)}`,
430
425
  `xmlOptions: { name: "${serializedName}"${buildXmlOptionsString(xmlOptions)} }`,
431
426
  ];
432
427
 
@@ -737,14 +732,13 @@ function buildDeserializePropertyMetadataArray(
737
732
 
738
733
  const xmlOptions = property.serializationOptions?.xml;
739
734
  const jsonOptions = property.serializationOptions?.json;
740
- const propertyName = normalizeModelPropertyName(context, property);
741
- const cleanPropertyName = propertyName.replace(/^"|"$/g, "");
735
+ const propertyName = getModelPropertyName(context, property);
742
736
 
743
737
  // Use XML name if available, fall back to JSON name, then property name
744
738
  const serializedName = xmlOptions?.name ?? jsonOptions?.name ?? property.name;
745
739
 
746
740
  const metadataObj: string[] = [
747
- `propertyName: "${cleanPropertyName}"`,
741
+ `propertyName: ${JSON.stringify(propertyName)}`,
748
742
  `xmlOptions: { name: "${serializedName}"${buildXmlOptionsString(xmlOptions)} }`,
749
743
  ];
750
744
 
@@ -5,7 +5,7 @@ import type {
5
5
  SdkType,
6
6
  } from "@azure-tools/typespec-client-generator-core";
7
7
  import type { SdkContext } from "../../utils/interfaces.js";
8
- import { NameType, normalizeName } from "../../utils/name-utils.js";
8
+ import { normalizeSdkPropertyName } from "../../utils/name-utils.js";
9
9
  import { getCredentialExpression } from "./get-credential-expression.js";
10
10
  import { getEnumExpression } from "./get-enum-expression.js";
11
11
  import { getModelExpression } from "./get-model-expression.js";
@@ -21,10 +21,16 @@ export function normalizeModelPropertyName(
21
21
  context: SdkContext,
22
22
  property: SdkModelPropertyType | SdkHttpParameter | SdkServiceResponseHeader,
23
23
  ): string {
24
- const normalizedPropName = normalizeName(property.name, NameType.Property);
24
+ return JSON.stringify(getModelPropertyName(context, property));
25
+ }
26
+
27
+ export function getModelPropertyName(
28
+ context: SdkContext,
29
+ property: SdkModelPropertyType | SdkHttpParameter | SdkServiceResponseHeader,
30
+ ): string {
25
31
  return context.emitterOptions?.ignorePropertyNameNormalize
26
- ? `"${property.name}"`
27
- : `"${normalizedPropName}"`;
32
+ ? property.name
33
+ : normalizeSdkPropertyName(property);
28
34
  }
29
35
 
30
36
  export function getTypeExpression(