@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-tools/typespec-ts",
3
- "version": "0.57.0-dev.5",
3
+ "version": "0.57.0-dev.7",
4
4
  "description": "A TypeSpec emitter for TypeScript",
5
5
  "main": "dist/src/index.js",
6
6
  "type": "module",
@@ -19,9 +19,9 @@
19
19
  "devDependencies": {
20
20
  "@azure-rest/core-client": "^2.7.0",
21
21
  "@azure-tools/azure-http-specs": "^0.1.0-alpha.44 || >= 0.1.0-alpha.45-dev.4",
22
- "@azure-tools/typespec-autorest": "^0.71.0 || >= 0.72.0-dev.0",
23
- "@azure-tools/typespec-azure-core": "^0.71.0 || >= 0.72.0-dev.0",
24
- "@azure-tools/typespec-azure-resource-manager": "^0.71.0 || >= 0.72.0-dev.1",
22
+ "@azure-tools/typespec-autorest": "^0.71.0 || >= 0.72.0-dev.1",
23
+ "@azure-tools/typespec-azure-core": "^0.71.0 || >= 0.72.0-dev.1",
24
+ "@azure-tools/typespec-azure-resource-manager": "^0.71.0 || >= 0.72.0-dev.4",
25
25
  "@azure-tools/typespec-client-generator-core": "^0.71.2 || >= 0.72.0-dev.4",
26
26
  "@azure/abort-controller": "^2.1.2",
27
27
  "@azure/core-auth": "^1.6.0",
@@ -40,25 +40,25 @@
40
40
  "@types/pluralize": "^0.0.33",
41
41
  "yaml": "^2.8.3",
42
42
  "@azure-tools/spector-runner": "^0.1.0",
43
- "@typespec/spec-api": "^0.1.0-alpha.16",
44
43
  "@typespec/spector": "^0.1.0-alpha.28",
45
44
  "@typespec/http-specs": "^0.1.0-alpha.41",
46
- "@typespec/tspd": "^0.77.0",
45
+ "@typespec/spec-api": "^0.1.0-alpha.16",
47
46
  "@typespec/compiler": "^1.15.0",
47
+ "@typespec/tspd": "^0.77.0",
48
48
  "@typespec/http": "^1.15.0",
49
49
  "@typespec/openapi": "^1.15.0",
50
+ "@typespec/rest": "^0.85.0",
50
51
  "@typespec/versioning": "^0.85.0",
51
- "@typespec/xml": "^0.85.0",
52
- "@typespec/rest": "^0.85.0"
52
+ "@typespec/xml": "^0.85.0"
53
53
  },
54
54
  "peerDependencies": {
55
- "@azure-tools/typespec-azure-core": "^0.71.0 || >= 0.72.0-dev.0",
55
+ "@azure-tools/typespec-azure-core": "^0.71.0 || >= 0.72.0-dev.1",
56
56
  "@azure-tools/typespec-client-generator-core": "^0.71.2 || >= 0.72.0-dev.4",
57
57
  "@typespec/compiler": "^1.15.0",
58
- "@typespec/versioning": "^0.85.0",
59
58
  "@typespec/rest": "^0.85.0",
60
- "@typespec/xml": "^0.85.0",
61
- "@typespec/http": "^1.15.0"
59
+ "@typespec/versioning": "^0.85.0",
60
+ "@typespec/http": "^1.15.0",
61
+ "@typespec/xml": "^0.85.0"
62
62
  },
63
63
  "dependencies": {
64
64
  "fast-xml-parser": "^5.10.1",
package/src/lib.ts CHANGED
@@ -483,6 +483,12 @@ const libDef = {
483
483
  default: paramMessage`Property name ${"propertyName"} is normalized to ${"normalizedName"}.`,
484
484
  },
485
485
  },
486
+ "invalid-exact-name": {
487
+ severity: "warning",
488
+ messages: {
489
+ default: paramMessage`Exact ${"nameKind"} name ${"name"} is not a valid TypeScript identifier. Choose a valid TypeScript identifier or remove exact().`,
490
+ },
491
+ },
486
492
  "un-supported-format-cases": {
487
493
  severity: "warning",
488
494
  messages: {
@@ -21,7 +21,7 @@ import { resolveReference } from "../framework/reference.js";
21
21
  import { refkey } from "../framework/refkey.js";
22
22
  import { getClientModuleInfo } from "../utils/client-utils.js";
23
23
  import type { SdkContext } from "../utils/interfaces.js";
24
- import { NameType, normalizeName } from "../utils/name-utils.js";
24
+ import { NameType, normalizeName, normalizeSdkName } from "../utils/name-utils.js";
25
25
  import { getMethodHierarchiesMap, isTenantLevelOperation } from "../utils/operation-util.js";
26
26
  import { AzurePollingDependencies } from "./external-dependencies.js";
27
27
  import { getPagingLROMethodName } from "./helpers/classical-operation-helpers.js";
@@ -137,9 +137,14 @@ export function buildClassicalClient(
137
137
  `this._clientParams = {${classicalParams.map((p) => p.name).join(",")}};`,
138
138
  );
139
139
  for (const childClient of client.children) {
140
- const subfolder = normalizeName(childClient.name.replace("Client", ""), NameType.File);
140
+ const subfolder = normalizeSdkName(childClient, NameType.File, {
141
+ nameOverride: childClient.name.replace(/Client$/, ""),
142
+ });
141
143
  clientFile.addImportDeclaration({
142
- moduleSpecifier: `./${subfolder}/${normalizeName(childClient.name, NameType.File)}.js`,
144
+ moduleSpecifier: `./${subfolder}/${normalizeName(
145
+ getClassicalClientName(childClient),
146
+ NameType.File,
147
+ )}.js`,
143
148
  namedImports: [
144
149
  `${getClassicalClientName(childClient)}`,
145
150
  `${getClassicalClientName(childClient)}OptionalParams`,
@@ -275,11 +280,9 @@ function buildClientOperationGroups(
275
280
  const operationName = `_get${rawGroupName}Operations`;
276
281
  const propertyType = `${rawGroupName}Operations`;
277
282
  // The `groupName` is used to any places where we don't need normalized name again
278
- const groupName = normalizeName(rawGroupName, NameType.Property);
279
- const existProperty = clientClass.getProperties().filter((p) => {
280
- return p.getName() === normalizeName(groupName, NameType.Property);
281
- });
282
- if (!existProperty || existProperty.length === 0) {
283
+ const groupName = normalizeName(prefixes[0] ?? "", NameType.Property);
284
+ const existingProperty = clientClass.getProperty(groupName);
285
+ if (!existingProperty) {
283
286
  clientClass.addProperty({
284
287
  name: groupName,
285
288
  type: resolveReference(refkey(client, propertyType, layer, "classicOperations")),
@@ -24,7 +24,7 @@ import { resolveReference } from "../framework/reference.js";
24
24
  import { refkey } from "../framework/refkey.js";
25
25
  import { getClientModuleInfo } from "../utils/client-utils.js";
26
26
  import type { SdkContext } from "../utils/interfaces.js";
27
- import { NameType, normalizeName } from "../utils/name-utils.js";
27
+ import { NameType, normalizeName, normalizeSdkName } from "../utils/name-utils.js";
28
28
  import {
29
29
  getMethodHierarchiesMap,
30
30
  hasDualFormatSupport,
@@ -186,7 +186,7 @@ export function buildOperationOptions(
186
186
  docs: getDocsFromDescription(p.doc),
187
187
  hasQuestionToken: true,
188
188
  type: getTypeExpression(context, p.type, { isOptional: true }),
189
- name: normalizeName(p.name, NameType.Parameter),
189
+ name: normalizeSdkName(p, NameType.Parameter),
190
190
  };
191
191
  }),
192
192
  ),
@@ -278,7 +278,7 @@ function exportClassicalClient(
278
278
  subfolder: string,
279
279
  isSubClient: boolean = false,
280
280
  ) {
281
- const clientName = client.name;
281
+ const clientName = getClassicalClientName(client);
282
282
  enqueueStatement(indexFile, {
283
283
  kind: StructureKind.ExportDeclaration,
284
284
  namedExports: [clientName],
@@ -51,7 +51,14 @@ import { reportDiagnostic } from "../lib.js";
51
51
  import { getClientHierarchyMap } from "../utils/client-utils.js";
52
52
  import type { SdkContext } from "../utils/interfaces.js";
53
53
  import { isAzureCoreErrorType } from "../utils/model-utils.js";
54
- import { fixLeadingNumber, NameType, normalizeName } from "../utils/name-utils.js";
54
+ import {
55
+ fixLeadingNumber,
56
+ formatPropertyName,
57
+ NameType,
58
+ normalizeName,
59
+ normalizeSdkName,
60
+ reportInvalidExactName,
61
+ } from "../utils/name-utils.js";
55
62
  import { getMethodHierarchiesMap } from "../utils/operation-util.js";
56
63
  import { getHeaderClientOptions } from "./helpers/client-option-helpers.js";
57
64
  import {
@@ -620,11 +627,15 @@ function emitEnumMember(
620
627
  member: SdkEnumValueType,
621
628
  reportMemberNameDiagnostic = false, // if reportMemberNameDiagnostic is true, it will report diagnostic for enum member name
622
629
  ): EnumMemberStructure {
623
- const shouldNormalizeName = !member.name.startsWith("$DO_NOT_NORMALIZE$");
624
- const enumTypeName = normalizeName(member.enumType.name, NameType.Interface, true);
625
- let normalizedMemberName = context.emitterOptions?.ignoreEnumMemberNameNormalize
626
- ? fixLeadingNumber(member.name, NameType.EnumMemberName) // need to fix the leading number also for enum member
627
- : normalizeName(member.name, NameType.EnumMemberName, true);
630
+ const shouldNormalizeName = !member.isExactName && !member.name.startsWith("$DO_NOT_NORMALIZE$");
631
+ const enumTypeName = normalizeSdkName(member.enumType, NameType.Interface, {
632
+ shouldGuard: true,
633
+ });
634
+ let normalizedMemberName = member.isExactName
635
+ ? formatPropertyName(member.name)
636
+ : context.emitterOptions?.ignoreEnumMemberNameNormalize
637
+ ? fixLeadingNumber(member.name, NameType.EnumMemberName) // need to fix the leading number also for enum member
638
+ : normalizeSdkName(member, NameType.EnumMemberName, { shouldGuard: true });
628
639
  // If the member name starts with _ due to a leading digit (not because the original has _),
629
640
  // replace the _ prefix with either "V" (for API version enums) or the enum type name.
630
641
  if (
@@ -846,6 +857,8 @@ export function normalizeModelName(
846
857
  return getTypeExpression(context, type);
847
858
  }
848
859
 
860
+ reportInvalidExactName(context.program, type, nameType, type.kind, type.__raw ?? NoTarget);
861
+
849
862
  const segments = getModelNamespaces(context, type);
850
863
  let unionSuffix = "";
851
864
  if (!skipPolymorphicUnionSuffix) {
@@ -853,12 +866,15 @@ export function normalizeModelName(
853
866
  unionSuffix = "Union";
854
867
  }
855
868
  }
856
- const namespacePrefix = context.emitterOptions?.enableModelNamespace ? segments.join("") : "";
869
+ const namespacePrefix = context.emitterOptions?.enableModelNamespace
870
+ ? normalizeName(segments.join(""), nameType)
871
+ : "";
857
872
  const internalModelPrefix =
858
873
  (isPagedResultModel(context, type) && !pagedModelsKeptPublic.has(type)) || type.isGeneratedName
859
874
  ? "_"
860
875
  : "";
861
- return `${internalModelPrefix}${normalizeName(namespacePrefix + type.name, nameType, true)}${unionSuffix}`;
876
+ const modelName = normalizeSdkName(type, nameType, { shouldGuard: true });
877
+ return `${internalModelPrefix}${namespacePrefix}${modelName}${unionSuffix}`;
862
878
  }
863
879
 
864
880
  function buildModelPolymorphicType(context: SdkContext, type: SdkModelType) {
@@ -898,6 +914,7 @@ function buildModelProperty(
898
914
  const normalizedPropName = normalizeModelPropertyName(context, property);
899
915
  if (
900
916
  !context.emitterOptions?.ignorePropertyNameNormalize &&
917
+ !property.isExactName &&
901
918
  normalizedPropName !== `"${property.name}"`
902
919
  ) {
903
920
  reportDiagnostic(context.program, {
@@ -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
@@ -85,7 +84,7 @@ export function getClassicalOperation(
85
84
  const declaration = getOperationFunction(dpgContext, [prefixes, operation], clientName);
86
85
  operationDeclarationMap.set(declaration, {
87
86
  declaration,
88
- oriName: operation.oriName,
87
+ operation,
89
88
  declarationRefKey: resolveReference(refkey(operation, "api")),
90
89
  isLro: declaration.isLro,
91
90
  lroFinalReturnType: declaration.lroFinalReturnType,
@@ -370,12 +369,11 @@ export function getClassicalOperation(
370
369
  propertyName?: string;
371
370
  },
372
371
  ) {
373
- return normalizeName(
374
- operationDeclarationMap.get(declaration)?.oriName ??
375
- declaration.propertyName ??
376
- declaration.name ??
377
- "FIXME",
378
- NameType.Method,
379
- );
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
+ });
380
378
  }
381
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(