@azure-tools/typespec-ts 0.56.1-dev.0 → 0.57.0-dev.10

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 (120) hide show
  1. package/README.md +6 -0
  2. package/dist/src/framework/hooks/sdk-types.d.ts.map +1 -1
  3. package/dist/src/framework/hooks/sdk-types.js +2 -0
  4. package/dist/src/framework/hooks/sdk-types.js.map +1 -1
  5. package/dist/src/interfaces.d.ts +4 -0
  6. package/dist/src/interfaces.d.ts.map +1 -1
  7. package/dist/src/interfaces.js.map +1 -1
  8. package/dist/src/lib.d.ts +11 -1
  9. package/dist/src/lib.d.ts.map +1 -1
  10. package/dist/src/lib.js +11 -0
  11. package/dist/src/lib.js.map +1 -1
  12. package/dist/src/metadata/build-package-file.d.ts +1 -0
  13. package/dist/src/metadata/build-package-file.d.ts.map +1 -1
  14. package/dist/src/metadata/build-package-file.js +3 -0
  15. package/dist/src/metadata/build-package-file.js.map +1 -1
  16. package/dist/src/metadata/package-json/build-azure-monorepo-package.d.ts +2 -0
  17. package/dist/src/metadata/package-json/build-azure-monorepo-package.d.ts.map +1 -1
  18. package/dist/src/metadata/package-json/build-azure-monorepo-package.js +1 -0
  19. package/dist/src/metadata/package-json/build-azure-monorepo-package.js.map +1 -1
  20. package/dist/src/modular/build-classical-client.d.ts.map +1 -1
  21. package/dist/src/modular/build-classical-client.js +19 -33
  22. package/dist/src/modular/build-classical-client.js.map +1 -1
  23. package/dist/src/modular/build-operations.d.ts.map +1 -1
  24. package/dist/src/modular/build-operations.js +4 -5
  25. package/dist/src/modular/build-operations.js.map +1 -1
  26. package/dist/src/modular/build-root-index.js +1 -1
  27. package/dist/src/modular/build-root-index.js.map +1 -1
  28. package/dist/src/modular/emit-models.d.ts.map +1 -1
  29. package/dist/src/modular/emit-models.js +46 -23
  30. package/dist/src/modular/emit-models.js.map +1 -1
  31. package/dist/src/modular/emit-samples.d.ts.map +1 -1
  32. package/dist/src/modular/emit-samples.js +29 -21
  33. package/dist/src/modular/emit-samples.js.map +1 -1
  34. package/dist/src/modular/emit-tests.js +2 -2
  35. package/dist/src/modular/emit-tests.js.map +1 -1
  36. package/dist/src/modular/helpers/classical-operation-helpers.d.ts.map +1 -1
  37. package/dist/src/modular/helpers/classical-operation-helpers.js +17 -15
  38. package/dist/src/modular/helpers/classical-operation-helpers.js.map +1 -1
  39. package/dist/src/modular/helpers/client-helpers.d.ts.map +1 -1
  40. package/dist/src/modular/helpers/client-helpers.js +7 -6
  41. package/dist/src/modular/helpers/client-helpers.js.map +1 -1
  42. package/dist/src/modular/helpers/example-value-helpers.d.ts +2 -1
  43. package/dist/src/modular/helpers/example-value-helpers.d.ts.map +1 -1
  44. package/dist/src/modular/helpers/example-value-helpers.js +34 -24
  45. package/dist/src/modular/helpers/example-value-helpers.js.map +1 -1
  46. package/dist/src/modular/helpers/naming-helpers.d.ts.map +1 -1
  47. package/dist/src/modular/helpers/naming-helpers.js +3 -3
  48. package/dist/src/modular/helpers/naming-helpers.js.map +1 -1
  49. package/dist/src/modular/helpers/operation-helpers.d.ts.map +1 -1
  50. package/dist/src/modular/helpers/operation-helpers.js +23 -18
  51. package/dist/src/modular/helpers/operation-helpers.js.map +1 -1
  52. package/dist/src/modular/helpers/type-helpers.d.ts.map +1 -1
  53. package/dist/src/modular/helpers/type-helpers.js +2 -2
  54. package/dist/src/modular/helpers/type-helpers.js.map +1 -1
  55. package/dist/src/modular/helpers/visibility-helpers.d.ts +7 -0
  56. package/dist/src/modular/helpers/visibility-helpers.d.ts.map +1 -0
  57. package/dist/src/modular/helpers/visibility-helpers.js +353 -0
  58. package/dist/src/modular/helpers/visibility-helpers.js.map +1 -0
  59. package/dist/src/modular/serialization/build-deserializer-function.js +6 -4
  60. package/dist/src/modular/serialization/build-deserializer-function.js.map +1 -1
  61. package/dist/src/modular/serialization/build-serializer-function.d.ts.map +1 -1
  62. package/dist/src/modular/serialization/build-serializer-function.js +9 -7
  63. package/dist/src/modular/serialization/build-serializer-function.js.map +1 -1
  64. package/dist/src/modular/serialization/build-xml-serializer-function.d.ts.map +1 -1
  65. package/dist/src/modular/serialization/build-xml-serializer-function.js +11 -13
  66. package/dist/src/modular/serialization/build-xml-serializer-function.js.map +1 -1
  67. package/dist/src/modular/type-expressions/get-type-expression.d.ts +1 -0
  68. package/dist/src/modular/type-expressions/get-type-expression.d.ts.map +1 -1
  69. package/dist/src/modular/type-expressions/get-type-expression.js +6 -4
  70. package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
  71. package/dist/src/transform/transform-client-options.d.ts.map +1 -1
  72. package/dist/src/transform/transform-client-options.js +2 -0
  73. package/dist/src/transform/transform-client-options.js.map +1 -1
  74. package/dist/src/utils/client-utils.d.ts.map +1 -1
  75. package/dist/src/utils/client-utils.js +16 -5
  76. package/dist/src/utils/client-utils.js.map +1 -1
  77. package/dist/src/utils/cross-language-def.d.ts.map +1 -1
  78. package/dist/src/utils/cross-language-def.js +1 -2
  79. package/dist/src/utils/cross-language-def.js.map +1 -1
  80. package/dist/src/utils/interfaces.d.ts +1 -0
  81. package/dist/src/utils/interfaces.d.ts.map +1 -1
  82. package/dist/src/utils/name-utils.d.ts +15 -0
  83. package/dist/src/utils/name-utils.d.ts.map +1 -1
  84. package/dist/src/utils/name-utils.js +60 -0
  85. package/dist/src/utils/name-utils.js.map +1 -1
  86. package/dist/src/utils/operation-util.d.ts.map +1 -1
  87. package/dist/src/utils/operation-util.js +15 -5
  88. package/dist/src/utils/operation-util.js.map +1 -1
  89. package/dist/tsconfig.tsbuildinfo +1 -1
  90. package/package.json +31 -31
  91. package/src/framework/hooks/sdk-types.ts +2 -0
  92. package/src/interfaces.ts +4 -0
  93. package/src/lib.ts +13 -0
  94. package/src/metadata/build-package-file.ts +4 -0
  95. package/src/metadata/package-json/build-azure-monorepo-package.ts +1 -0
  96. package/src/modular/build-classical-client.ts +21 -32
  97. package/src/modular/build-operations.ts +4 -5
  98. package/src/modular/build-root-index.ts +1 -1
  99. package/src/modular/emit-models.ts +59 -24
  100. package/src/modular/emit-samples.ts +42 -34
  101. package/src/modular/emit-tests.ts +2 -2
  102. package/src/modular/helpers/classical-operation-helpers.ts +21 -20
  103. package/src/modular/helpers/client-helpers.ts +6 -5
  104. package/src/modular/helpers/example-value-helpers.ts +52 -41
  105. package/src/modular/helpers/naming-helpers.ts +8 -3
  106. package/src/modular/helpers/operation-helpers.ts +31 -18
  107. package/src/modular/helpers/type-helpers.ts +2 -5
  108. package/src/modular/helpers/visibility-helpers.ts +471 -0
  109. package/src/modular/serialization/build-deserializer-function.ts +6 -9
  110. package/src/modular/serialization/build-serializer-function.ts +14 -11
  111. package/src/modular/serialization/build-xml-serializer-function.ts +11 -17
  112. package/src/modular/type-expressions/get-type-expression.ts +10 -4
  113. package/src/transform/transform-client-options.ts +3 -0
  114. package/src/utils/client-utils.ts +28 -4
  115. package/src/utils/cross-language-def.ts +1 -2
  116. package/src/utils/interfaces.ts +1 -0
  117. package/src/utils/name-utils.ts +94 -0
  118. package/src/utils/operation-util.ts +27 -14
  119. package/static/static-helpers/storageCompatResponse.ts +3 -2
  120. package/static/static-helpers/urlTemplate.ts +4 -2
@@ -17,7 +17,14 @@ import { AzureIdentityDependencies } from "../modular/external-dependencies.js";
17
17
  import { getSubscriptionId } from "../transform/transform-client-options.js";
18
18
  import { hasKeyCredential, hasTokenCredential } from "../utils/credential-utils.js";
19
19
  import type { SdkContext } from "../utils/interfaces.js";
20
- import { NameType, normalizeName } from "../utils/name-utils.js";
20
+ import {
21
+ formatPropertyName,
22
+ NameType,
23
+ normalizeName,
24
+ normalizeSdkName,
25
+ normalizeSdkPropertyName,
26
+ type SdkName,
27
+ } from "../utils/name-utils.js";
21
28
  import {
22
29
  getMethodHierarchiesMap,
23
30
  isTenantLevelOperation,
@@ -61,10 +68,7 @@ export function emitSamples(dpgContext: SdkContext): SourceFile[] {
61
68
  emitClientSamples(dpgContext, client, {
62
69
  topLevelClient: client,
63
70
  generatedFiles,
64
- subFolder:
65
- clients.length > 1
66
- ? normalizeName(getClassicalClientName(client), NameType.File)
67
- : undefined,
71
+ subFolder: clients.length > 1 ? normalizeSdkName(client, NameType.File) : undefined,
68
72
  });
69
73
  }
70
74
  return generatedFiles;
@@ -193,9 +197,9 @@ function emitMethodSamples(
193
197
  }
194
198
  const prefix = options.classicalMethodPrefix ? `${options.classicalMethodPrefix}.` : "";
195
199
  const isPaging = method.kind === "paging";
196
- const methodCall = `client.${prefix}${normalizeName(method.oriName ?? method.name, NameType.Property)}(${methodParams.join(
197
- ", ",
198
- )})`;
200
+ const methodCall = `client.${prefix}${normalizeSdkName(method, NameType.Property, {
201
+ nameOverride: method.oriName ?? method.name,
202
+ })}(${methodParams.join(", ")})`;
199
203
  if (isPaging) {
200
204
  exampleFunctionBody.push(`const resArray = new Array();`);
201
205
  exampleFunctionBody.push(`for await (const item of ${methodCall}) { resArray.push(item); }`);
@@ -244,13 +248,14 @@ function buildParameterValueMap(example: SdkHttpOperationExample) {
244
248
 
245
249
  function prepareExampleValue(
246
250
  context: SdkContext,
247
- name: string,
251
+ name: string | SdkName,
248
252
  value: SdkExampleValue | string,
249
253
  isOptional?: boolean,
250
254
  onClient?: boolean,
251
255
  ): ExampleValue {
256
+ const sdkName = typeof name === "string" ? { name } : name;
252
257
  return {
253
- name: normalizeName(name, NameType.Parameter, true),
258
+ name: normalizeSdkName(sdkName, NameType.Parameter, { shouldGuard: true }),
254
259
  value: typeof value === "string" ? value : getParameterValue(context, value),
255
260
  isOptional: Boolean(isOptional),
256
261
  onClient: Boolean(onClient),
@@ -356,13 +361,7 @@ function prepareExampleParameters(
356
361
  subscriptionIdValue = getParameterValue(dpgContext, exampleValue.value);
357
362
  }
358
363
  result.push(
359
- prepareExampleValue(
360
- dpgContext,
361
- param.name,
362
- subscriptionIdValue,
363
- param.optional,
364
- param.onClient,
365
- ),
364
+ prepareExampleValue(dpgContext, param, subscriptionIdValue, param.optional, param.onClient),
366
365
  );
367
366
  continue;
368
367
  }
@@ -413,7 +412,8 @@ function prepareExampleParameters(
413
412
  bodyExample.value.kind === "model"
414
413
  ) {
415
414
  for (const prop of bodyParam.type.properties) {
416
- const propExample = bodyExample.value.value[prop.name];
415
+ const wireName = prop.serializationOptions.json?.name ?? prop.name;
416
+ const propExample = bodyExample.value.value[wireName] ?? bodyExample.value.value[prop.name];
417
417
  if (!propExample) {
418
418
  continue;
419
419
  }
@@ -422,7 +422,7 @@ function prepareExampleParameters(
422
422
  continue;
423
423
  }
424
424
  result.push(
425
- prepareExampleValue(dpgContext, prop.name, propExample, prop.optional, prop.onClient),
425
+ prepareExampleValue(dpgContext, prop, propExample, prop.optional, prop.onClient),
426
426
  );
427
427
  }
428
428
  } else {
@@ -433,18 +433,17 @@ function prepareExampleParameters(
433
433
  if (isNestedBody) {
434
434
  const path = segments[0]!;
435
435
  // The first segment is the method-level wrapper param (e.g., "body")
436
- const methodParamName = path[0]!.name;
437
436
  const methodParamOptional = path[0]!.optional;
438
437
  // Wrap the example value with the intermediate property names
439
438
  let wrappedValue = getParameterValue(dpgContext, bodyExample.value);
440
439
  for (let i = path.length - 1; i >= 1; i--) {
441
- const propName = normalizeName(path[i]!.name, NameType.Property, true);
440
+ const propName = formatPropertyName(normalizeSdkPropertyName(path[i]!));
442
441
  wrappedValue = `{ ${propName}: ${wrappedValue} }`;
443
442
  }
444
443
  result.push(
445
444
  prepareExampleValue(
446
445
  dpgContext,
447
- methodParamName,
446
+ path[0]!,
448
447
  wrappedValue,
449
448
  methodParamOptional,
450
449
  bodyParam.onClient,
@@ -454,7 +453,7 @@ function prepareExampleParameters(
454
453
  result.push(
455
454
  prepareExampleValue(
456
455
  dpgContext,
457
- bodyParam.name,
456
+ bodyParam,
458
457
  bodyExample.value,
459
458
  bodyParam.optional,
460
459
  bodyParam.onClient,
@@ -467,7 +466,7 @@ function prepareExampleParameters(
467
466
  // a scalar value; a parameter with nested leaves carries an object literal.
468
467
  for (const arg of methodArguments.values()) {
469
468
  result.push({
470
- name: normalizeName(arg.name, NameType.Parameter, true),
469
+ name: normalizeSdkName(arg, NameType.Parameter, { shouldGuard: true }),
471
470
  value: serializeNestedValue(arg.value),
472
471
  isOptional: arg.isOptional,
473
472
  onClient: false,
@@ -491,15 +490,20 @@ interface ValueTreeNode {
491
490
  function placeMethodArgument(
492
491
  methodArguments: Map<
493
492
  string,
494
- { name: string; isOptional: boolean; value: ValueTreeNode | string }
493
+ { name: string; isExactName?: boolean; isOptional: boolean; value: ValueTreeNode | string }
495
494
  >,
496
- path: readonly { name: string; optional?: boolean }[],
495
+ path: readonly { name: string; isExactName?: boolean; optional?: boolean }[],
497
496
  leaf: string,
498
497
  ): void {
499
498
  const root = path[0]!;
500
499
  let arg = methodArguments.get(root.name);
501
500
  if (!arg) {
502
- arg = { name: root.name, isOptional: Boolean(root.optional), value: {} };
501
+ arg = {
502
+ name: root.name,
503
+ isExactName: root.isExactName,
504
+ isOptional: Boolean(root.optional),
505
+ value: {},
506
+ };
503
507
  methodArguments.set(root.name, arg);
504
508
  }
505
509
  if (path.length === 1) {
@@ -515,12 +519,12 @@ function placeMethodArgument(
515
519
  /** Places `leaf` at `path` (segments after the root), creating intermediate objects as needed. */
516
520
  function setNestedValue(
517
521
  root: ValueTreeNode,
518
- path: readonly { name: string }[],
522
+ path: readonly { name: string; isExactName?: boolean }[],
519
523
  leaf: string,
520
524
  ): void {
521
525
  let node = root;
522
526
  for (let i = 0; i < path.length; i++) {
523
- const key = normalizeName(path[i]!.name, NameType.Property, true);
527
+ const key = normalizeSdkPropertyName(path[i]!);
524
528
  if (i === path.length - 1) {
525
529
  node[key] = leaf;
526
530
  } else {
@@ -539,7 +543,7 @@ function serializeNestedValue(node: ValueTreeNode | string): string {
539
543
  return node;
540
544
  }
541
545
  const entries = Object.entries(node).map(
542
- ([key, value]) => `${key}: ${serializeNestedValue(value)}`,
546
+ ([key, value]) => `${formatPropertyName(key)}: ${serializeNestedValue(value)}`,
543
547
  );
544
548
  return `{ ${entries.join(", ")} }`;
545
549
  }
@@ -635,7 +639,10 @@ function getParameterValue(
635
639
  }) {
636
640
  let property;
637
641
  if (value.type.kind === "model") {
638
- property = value.type.properties.find((p) => p.name === propName);
642
+ property =
643
+ value.type.properties.find(
644
+ (p) => (p.serializationOptions.json?.name ?? p.name) === propName,
645
+ ) ?? value.type.properties.find((p) => p.name === propName);
639
646
  }
640
647
  const propValue = value.value[propName];
641
648
  if (propValue === undefined || propValue === null) {
@@ -668,7 +675,7 @@ function getParameterValue(
668
675
  // so that independent inner flattens at deeper levels still work.
669
676
  const childOptions = options?.overrides?.enableFlatten === false ? undefined : options;
670
677
  propRetValue =
671
- `"${mapper.get(propName) ?? propName}": ` +
678
+ `${JSON.stringify(mapper.get(propName) ?? propName)}: ` +
672
679
  getParameterValue(context, propValue, childOptions);
673
680
  }
674
681
  if (propRetValue) values.push(propRetValue);
@@ -682,14 +689,15 @@ function getParameterValue(
682
689
  continue;
683
690
  }
684
691
  const propRetValue =
685
- `"${mapper.get(propName) ?? propName}": ` + getParameterValue(context, propValue);
692
+ `${JSON.stringify(mapper.get(propName) ?? propName)}: ` +
693
+ getParameterValue(context, propValue);
686
694
  additionalBags.push(propRetValue);
687
695
  }
688
696
  if (additionalBags.length > 0) {
689
697
  const name = mapper.get("additionalProperties")
690
698
  ? "additionalPropertiesBag"
691
699
  : "additionalProperties";
692
- values.push(`"${name}": {
700
+ values.push(`${JSON.stringify(name)}: {
693
701
  ${additionalBags.join(", ")}
694
702
  }`);
695
703
  }
@@ -2,7 +2,7 @@ import { type CompilerHost, joinPaths } from "@typespec/compiler";
2
2
  import { SourceFile } from "ts-morph";
3
3
  import { resolveReference } from "../framework/reference.js";
4
4
  import type { SdkContext } from "../utils/interfaces.js";
5
- import { NameType, normalizeName } from "../utils/name-utils.js";
5
+ import { NameType, normalizeName, normalizeSdkName } from "../utils/name-utils.js";
6
6
  import type { ServiceOperation } from "../utils/operation-util.js";
7
7
  import { AzureTestDependencies } from "./external-dependencies.js";
8
8
  import {
@@ -41,7 +41,7 @@ async function cleanupTestFolder(dpgContext: SdkContext, host: CompilerHost) {
41
41
  // If there are multiple clients, clean up subfolders
42
42
  if (clients.length > 1) {
43
43
  for (const client of clients) {
44
- const subFolder = normalizeName(getClassicalClientName(client), NameType.File);
44
+ const subFolder = normalizeSdkName(client, NameType.File);
45
45
  const clientTestFolder = joinPaths(baseTestFolder, subFolder);
46
46
  if (await dirExists(clientTestFolder)) {
47
47
  await host.rm(clientTestFolder, { recursive: true });
@@ -15,7 +15,7 @@ import { resolveReference } from "../../framework/reference.js";
15
15
  import { refkey } from "../../framework/refkey.js";
16
16
  import { getClientModuleInfo } from "../../utils/client-utils.js";
17
17
  import type { SdkContext } from "../../utils/interfaces.js";
18
- import { NameType, normalizeName } from "../../utils/name-utils.js";
18
+ import { NameType, normalizeName, normalizeSdkName } from "../../utils/name-utils.js";
19
19
  import type { ServiceOperation } from "../../utils/operation-util.js";
20
20
  import { AzurePollingDependencies } from "../external-dependencies.js";
21
21
  import { PagingHelpers, SimplePollerHelpers } from "../static-helpers-metadata.js";
@@ -25,8 +25,7 @@ import { getOperationFunction } from "./operation-helpers.js";
25
25
  interface OperationDeclarationInfo {
26
26
  // the operation function
27
27
  declaration: OptionalKind<FunctionDeclarationStructure>;
28
- // the original operation name
29
- oriName: string | undefined;
28
+ operation: ServiceOperation;
30
29
  // the refkey of the operation declaration
31
30
  declarationRefKey: string | undefined;
32
31
  // the default is false
@@ -58,6 +57,7 @@ export function getClassicalOperation(
58
57
  ) {
59
58
  const prefixes = operationGroup[0];
60
59
  const operations = operationGroup[1];
60
+ const client = clientMap[1];
61
61
  const { clientName } = getClientModuleInfo(clientMap);
62
62
  const hasClientContextImport = classicFile.getImportDeclarations().filter((i) => {
63
63
  return (
@@ -84,7 +84,7 @@ export function getClassicalOperation(
84
84
  const declaration = getOperationFunction(dpgContext, [prefixes, operation], clientName);
85
85
  operationDeclarationMap.set(declaration, {
86
86
  declaration,
87
- oriName: operation.oriName,
87
+ operation,
88
88
  declarationRefKey: resolveReference(refkey(operation, "api")),
89
89
  isLro: declaration.isLro,
90
90
  lroFinalReturnType: declaration.lroFinalReturnType,
@@ -119,7 +119,9 @@ export function getClassicalOperation(
119
119
  properties.push({
120
120
  kind: StructureKind.PropertySignature,
121
121
  name,
122
- type: resolveReference(refkey(nextLayerInterfaceName, layer + 1, "classicOperations")),
122
+ type: resolveReference(
123
+ refkey(client, nextLayerInterfaceName, layer + 1, "classicOperations"),
124
+ ),
123
125
  });
124
126
  }
125
127
  } else {
@@ -197,7 +199,7 @@ export function getClassicalOperation(
197
199
  addDeclaration(
198
200
  classicFile,
199
201
  interfaceDeclaration,
200
- refkey(interfaceName, layer, "classicOperations"),
202
+ refkey(client, interfaceName, layer, "classicOperations"),
201
203
  );
202
204
  }
203
205
 
@@ -286,7 +288,7 @@ export function getClassicalOperation(
286
288
  addDeclaration(
287
289
  classicFile,
288
290
  functionDeclaration,
289
- refkey(functionName, layer, "getClassicOperation"),
291
+ refkey(client, functionName, layer, "getClassicOperation"),
290
292
  );
291
293
  }
292
294
 
@@ -319,11 +321,11 @@ export function getClassicalOperation(
319
321
  ${normalizeName(
320
322
  prefixes[layer + 1] ?? "FIXME",
321
323
  NameType.Property,
322
- )}: ${resolveReference(refkey(nextLayerOperationFunctionName, layer + 1, "getClassicOperations"))}(context)}`;
324
+ )}: ${resolveReference(refkey(client, nextLayerOperationFunctionName, layer + 1, "getClassicOperations"))}(context)}`;
323
325
  }
324
326
  } else {
325
327
  statement = `,
326
- ...${resolveReference(refkey(nextLayerOperationFunctionName, layer + 1, "getClassicOperations"))}(context)}`;
328
+ ...${resolveReference(refkey(client, nextLayerOperationFunctionName, layer + 1, "getClassicOperations"))}(context)}`;
327
329
  }
328
330
 
329
331
  if (statement) {
@@ -342,23 +344,23 @@ export function getClassicalOperation(
342
344
  type: clientName,
343
345
  },
344
346
  ],
345
- returnType: resolveReference(refkey(interfaceName, layer, "classicOperations")),
347
+ returnType: resolveReference(refkey(client, interfaceName, layer, "classicOperations")),
346
348
  statements:
347
349
  layer !== prefixes.length - 1
348
350
  ? `return {
349
351
  ${normalizeName(
350
352
  prefixes[layer + 1] ?? "FIXME",
351
353
  NameType.Property,
352
- )}: ${resolveReference(refkey(nextLayerOperationFunctionName, layer + 1, "getClassicOperations"))}(context)
354
+ )}: ${resolveReference(refkey(client, nextLayerOperationFunctionName, layer + 1, "getClassicOperations"))}(context)
353
355
  }`
354
356
  : `return {
355
- ...${resolveReference(refkey(functionName, layer, "getClassicOperation"))}(context)
357
+ ...${resolveReference(refkey(client, functionName, layer, "getClassicOperation"))}(context)
356
358
  }`,
357
359
  };
358
360
  addDeclaration(
359
361
  classicFile,
360
362
  functions,
361
- refkey(operationFunctionName, layer, "getClassicOperations"),
363
+ refkey(client, operationFunctionName, layer, "getClassicOperations"),
362
364
  );
363
365
  }
364
366
 
@@ -367,12 +369,11 @@ export function getClassicalOperation(
367
369
  propertyName?: string;
368
370
  },
369
371
  ) {
370
- return normalizeName(
371
- operationDeclarationMap.get(declaration)?.oriName ??
372
- declaration.propertyName ??
373
- declaration.name ??
374
- "FIXME",
375
- NameType.Method,
376
- );
372
+ const operationInfo = operationDeclarationMap.get(declaration);
373
+ const name =
374
+ operationInfo?.operation.oriName ?? declaration.propertyName ?? declaration.name ?? "FIXME";
375
+ return normalizeSdkName(operationInfo?.operation ?? { name }, NameType.Method, {
376
+ nameOverride: name,
377
+ });
377
378
  }
378
379
  }
@@ -16,7 +16,7 @@ import type { ModularEmitterOptions } from "../interfaces.js";
16
16
 
17
17
  import { resolveReference } from "../../framework/reference.js";
18
18
  import type { SdkContext } from "../../utils/interfaces.js";
19
- import { NameType, normalizeName } from "../../utils/name-utils.js";
19
+ import { NameType, normalizeSdkName } from "../../utils/name-utils.js";
20
20
  import { CloudSettingHelpers } from "../static-helpers-metadata.js";
21
21
  import { getTypeExpression } from "../type-expressions/get-type-expression.js";
22
22
  import { getClassicalClientName } from "./naming-helpers.js";
@@ -154,15 +154,16 @@ function getClientParameterTypeExpression(context: SdkContext, parameter: SdkPar
154
154
  export function getClientParameterName(parameter: SdkParameter) {
155
155
  // We have been calling this endpointParam, so special handling this here to make sure there are no unexpected side effects
156
156
  if (
157
- (parameter.type.kind === "union" &&
157
+ !parameter.isExactName &&
158
+ ((parameter.type.kind === "union" &&
158
159
  parameter.type.variantTypes.some((v) => v.kind === "endpoint")) ||
159
- ((parameter.kind === "endpoint" || parameter.kind === "path") &&
160
- parameter.name.toLowerCase() === "endpoint")
160
+ ((parameter.kind === "endpoint" || parameter.kind === "path") &&
161
+ parameter.name.toLowerCase() === "endpoint"))
161
162
  ) {
162
163
  return "endpointParam";
163
164
  }
164
165
 
165
- return normalizeName(parameter.name, NameType.Parameter, true);
166
+ return normalizeSdkName(parameter, NameType.Parameter, { shouldGuard: true });
166
167
  }
167
168
 
168
169
  export function buildGetClientEndpointParam(
@@ -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