@azure-tools/typespec-ts 0.57.0-dev.6 → 0.57.0-dev.8

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 (96) 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/metadata/build-package-file.d.ts +1 -0
  6. package/dist/src/metadata/build-package-file.d.ts.map +1 -1
  7. package/dist/src/metadata/build-package-file.js +3 -0
  8. package/dist/src/metadata/build-package-file.js.map +1 -1
  9. package/dist/src/metadata/package-json/build-azure-monorepo-package.d.ts +2 -0
  10. package/dist/src/metadata/package-json/build-azure-monorepo-package.d.ts.map +1 -1
  11. package/dist/src/metadata/package-json/build-azure-monorepo-package.js +1 -0
  12. package/dist/src/metadata/package-json/build-azure-monorepo-package.js.map +1 -1
  13. package/dist/src/modular/build-classical-client.d.ts.map +1 -1
  14. package/dist/src/modular/build-classical-client.js +8 -8
  15. package/dist/src/modular/build-classical-client.js.map +1 -1
  16. package/dist/src/modular/build-operations.js +2 -2
  17. package/dist/src/modular/build-operations.js.map +1 -1
  18. package/dist/src/modular/build-root-index.js +1 -1
  19. package/dist/src/modular/build-root-index.js.map +1 -1
  20. package/dist/src/modular/emit-models.d.ts.map +1 -1
  21. package/dist/src/modular/emit-models.js +17 -8
  22. package/dist/src/modular/emit-models.js.map +1 -1
  23. package/dist/src/modular/emit-samples.d.ts.map +1 -1
  24. package/dist/src/modular/emit-samples.js +29 -21
  25. package/dist/src/modular/emit-samples.js.map +1 -1
  26. package/dist/src/modular/emit-tests.js +2 -2
  27. package/dist/src/modular/emit-tests.js.map +1 -1
  28. package/dist/src/modular/helpers/classical-operation-helpers.d.ts.map +1 -1
  29. package/dist/src/modular/helpers/classical-operation-helpers.js +7 -6
  30. package/dist/src/modular/helpers/classical-operation-helpers.js.map +1 -1
  31. package/dist/src/modular/helpers/client-helpers.d.ts.map +1 -1
  32. package/dist/src/modular/helpers/client-helpers.js +7 -6
  33. package/dist/src/modular/helpers/client-helpers.js.map +1 -1
  34. package/dist/src/modular/helpers/example-value-helpers.d.ts +2 -1
  35. package/dist/src/modular/helpers/example-value-helpers.d.ts.map +1 -1
  36. package/dist/src/modular/helpers/example-value-helpers.js +34 -24
  37. package/dist/src/modular/helpers/example-value-helpers.js.map +1 -1
  38. package/dist/src/modular/helpers/naming-helpers.d.ts.map +1 -1
  39. package/dist/src/modular/helpers/naming-helpers.js +3 -3
  40. package/dist/src/modular/helpers/naming-helpers.js.map +1 -1
  41. package/dist/src/modular/helpers/operation-helpers.d.ts.map +1 -1
  42. package/dist/src/modular/helpers/operation-helpers.js +23 -18
  43. package/dist/src/modular/helpers/operation-helpers.js.map +1 -1
  44. package/dist/src/modular/helpers/type-helpers.d.ts.map +1 -1
  45. package/dist/src/modular/helpers/type-helpers.js +2 -2
  46. package/dist/src/modular/helpers/type-helpers.js.map +1 -1
  47. package/dist/src/modular/serialization/build-deserializer-function.js +6 -4
  48. package/dist/src/modular/serialization/build-deserializer-function.js.map +1 -1
  49. package/dist/src/modular/serialization/build-serializer-function.d.ts.map +1 -1
  50. package/dist/src/modular/serialization/build-serializer-function.js +9 -7
  51. package/dist/src/modular/serialization/build-serializer-function.js.map +1 -1
  52. package/dist/src/modular/serialization/build-xml-serializer-function.d.ts.map +1 -1
  53. package/dist/src/modular/serialization/build-xml-serializer-function.js +11 -13
  54. package/dist/src/modular/serialization/build-xml-serializer-function.js.map +1 -1
  55. package/dist/src/modular/type-expressions/get-type-expression.d.ts +1 -0
  56. package/dist/src/modular/type-expressions/get-type-expression.d.ts.map +1 -1
  57. package/dist/src/modular/type-expressions/get-type-expression.js +6 -4
  58. package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
  59. package/dist/src/utils/client-utils.d.ts.map +1 -1
  60. package/dist/src/utils/client-utils.js +16 -5
  61. package/dist/src/utils/client-utils.js.map +1 -1
  62. package/dist/src/utils/cross-language-def.d.ts.map +1 -1
  63. package/dist/src/utils/cross-language-def.js +1 -2
  64. package/dist/src/utils/cross-language-def.js.map +1 -1
  65. package/dist/src/utils/name-utils.d.ts +15 -0
  66. package/dist/src/utils/name-utils.d.ts.map +1 -1
  67. package/dist/src/utils/name-utils.js +60 -0
  68. package/dist/src/utils/name-utils.js.map +1 -1
  69. package/dist/src/utils/operation-util.d.ts.map +1 -1
  70. package/dist/src/utils/operation-util.js +15 -5
  71. package/dist/src/utils/operation-util.js.map +1 -1
  72. package/dist/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +10 -10
  74. package/src/lib.ts +6 -0
  75. package/src/metadata/build-package-file.ts +4 -0
  76. package/src/metadata/package-json/build-azure-monorepo-package.ts +1 -0
  77. package/src/modular/build-classical-client.ts +11 -8
  78. package/src/modular/build-operations.ts +2 -2
  79. package/src/modular/build-root-index.ts +1 -1
  80. package/src/modular/emit-models.ts +25 -8
  81. package/src/modular/emit-samples.ts +42 -34
  82. package/src/modular/emit-tests.ts +2 -2
  83. package/src/modular/helpers/classical-operation-helpers.ts +9 -11
  84. package/src/modular/helpers/client-helpers.ts +6 -5
  85. package/src/modular/helpers/example-value-helpers.ts +52 -41
  86. package/src/modular/helpers/naming-helpers.ts +8 -3
  87. package/src/modular/helpers/operation-helpers.ts +31 -18
  88. package/src/modular/helpers/type-helpers.ts +2 -5
  89. package/src/modular/serialization/build-deserializer-function.ts +6 -9
  90. package/src/modular/serialization/build-serializer-function.ts +14 -11
  91. package/src/modular/serialization/build-xml-serializer-function.ts +11 -17
  92. package/src/modular/type-expressions/get-type-expression.ts +10 -4
  93. package/src/utils/client-utils.ts +28 -4
  94. package/src/utils/cross-language-def.ts +1 -2
  95. package/src/utils/name-utils.ts +94 -0
  96. package/src/utils/operation-util.ts +27 -14
@@ -12,11 +12,12 @@ import {
12
12
  isTemplateDeclaration,
13
13
  isTemplateDeclarationOrInstance,
14
14
  type Namespace,
15
+ NoTarget,
15
16
  type Operation,
16
17
  } from "@typespec/compiler";
17
18
  import type { ClientModuleInfo } from "../modular/interfaces.js";
18
19
  import type { SdkContext } from "./interfaces.js";
19
- import { NameType, normalizeName } from "./name-utils.js";
20
+ import { NameType, normalizeSdkName, reportInvalidExactName } from "./name-utils.js";
20
21
 
21
22
  export function getClients(dpgContext: SdkContext): SdkClient[] {
22
23
  const clients = listClients(dpgContext);
@@ -116,8 +117,9 @@ export function isMultiEndpointClient(dpgContext: SdkContext): boolean {
116
117
 
117
118
  export function getClientModuleInfo(clientMap: [string[], SdkClientType<SdkServiceOperation>]) {
118
119
  const [hierarchy, client] = clientMap;
120
+ const clientName = client.name.replace(/Client$/, "");
119
121
  const clientModuleInfo: ClientModuleInfo = {
120
- clientName: `${client.name.replace(/Client$/, "")}Context`,
122
+ clientName: `${clientName}Context`,
121
123
  };
122
124
  clientModuleInfo.subfolder = hierarchy.join("/");
123
125
  return clientModuleInfo;
@@ -133,13 +135,33 @@ export function getClientHierarchyMap(
133
135
  const clients = individualClients.map((client) => {
134
136
  return [
135
137
  context.sdkPackage.clients.length > 1
136
- ? [normalizeName(client.name.replace("Client", ""), NameType.File)]
138
+ ? [
139
+ normalizeSdkName(client, NameType.File, {
140
+ nameOverride: client.name.replace(/Client$/, ""),
141
+ }),
142
+ ]
137
143
  : [],
138
144
  client,
139
145
  ];
140
146
  }) as [string[], SdkClientType<SdkServiceOperation>][];
141
147
  for (let i = 0; i < clients.length; i++) {
142
148
  const [hierarchy, client] = clients[i]!;
149
+ reportInvalidExactName(
150
+ context.program,
151
+ client,
152
+ NameType.Class,
153
+ "client",
154
+ client.__raw.type ?? NoTarget,
155
+ );
156
+ for (const parameter of client.clientInitialization.parameters) {
157
+ reportInvalidExactName(
158
+ context.program,
159
+ parameter,
160
+ NameType.Parameter,
161
+ "parameter",
162
+ parameter.__raw ?? NoTarget,
163
+ );
164
+ }
143
165
  clientMap.push([hierarchy, client]);
144
166
  const childClientsToGenerate = client.children?.filter((child) => {
145
167
  return (
@@ -151,7 +173,9 @@ export function getClientHierarchyMap(
151
173
  childClientsToGenerate.forEach((child) => {
152
174
  const childHierarchy = [
153
175
  ...hierarchy,
154
- normalizeName(child.name.replace("Client", ""), NameType.File),
176
+ normalizeSdkName(child, NameType.File, {
177
+ nameOverride: child.name.replace(/Client$/, ""),
178
+ }),
155
179
  ];
156
180
  clients.push([childHierarchy, child]);
157
181
  });
@@ -48,8 +48,7 @@ export function generateCrossLanguageDefinitionFile(dpgContext: SdkContext): {
48
48
  }
49
49
  } else {
50
50
  // e,g., @azure/ai-client!ConnectionsOperations#getConnectionWithSecrets:member": "Azure.AI.Projects.Connections.getConnectionWithSecrets"
51
- const rawGroupName = normalizeName(prefixes[0] ?? "", NameType.Interface);
52
- const propertyType = `${normalizeName(rawGroupName, NameType.OperationGroup)}Operations`;
51
+ const propertyType = `${normalizeName(prefixes[0] ?? "", NameType.OperationGroup)}Operations`;
53
52
  for (const operation of operations) {
54
53
  const { name } = operation;
55
54
  const operationName = `${packageName}!${propertyType}#${name}:member`;
@@ -1,6 +1,9 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
 
4
+ import { NoTarget, type DiagnosticTarget, type Program } from "@typespec/compiler";
5
+ import { reportDiagnostic } from "../lib.js";
6
+
4
7
  export interface NormalizeNameOption {
5
8
  shouldGuard?: boolean;
6
9
  customReservedNames?: ReservedName[];
@@ -8,6 +11,15 @@ export interface NormalizeNameOption {
8
11
  numberPrefixOverride?: string;
9
12
  }
10
13
 
14
+ export interface NormalizeSdkNameOption extends NormalizeNameOption {
15
+ nameOverride?: string;
16
+ }
17
+
18
+ export interface SdkName {
19
+ name: string;
20
+ isExactName?: boolean;
21
+ }
22
+
11
23
  export interface ReservedName {
12
24
  name: string;
13
25
  reservedFor: NameType[];
@@ -208,6 +220,88 @@ export function normalizeName(
208
220
  return fixLeadingNumber(result, nameType, numberPrefixOverride);
209
221
  }
210
222
 
223
+ export function normalizeSdkName(
224
+ sdkName: SdkName,
225
+ nameType: NameType,
226
+ options: NormalizeSdkNameOption = {},
227
+ ): string {
228
+ const { nameOverride, ...normalizeOptions } = options;
229
+ const name = nameOverride ?? sdkName.name;
230
+ if (!sdkName.isExactName) {
231
+ return normalizeName(name, nameType, normalizeOptions);
232
+ }
233
+ return normalizeOptions.shouldGuard && nameType === NameType.Method
234
+ ? guardReservedNames(name, nameType, normalizeOptions.customReservedNames)
235
+ : name;
236
+ }
237
+
238
+ export function normalizeSdkPropertyName(sdkName: SdkName): string {
239
+ return normalizeSdkName(sdkName, NameType.Property);
240
+ }
241
+
242
+ export function isValidTypeScriptIdentifierName(name: string): boolean {
243
+ return /^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u.test(name);
244
+ }
245
+
246
+ const reportedInvalidExactNames = new WeakMap<Program, WeakSet<object>>();
247
+
248
+ export function reportInvalidExactName(
249
+ program: Program,
250
+ item: SdkName & object,
251
+ nameType: NameType,
252
+ nameKind: string,
253
+ target: DiagnosticTarget | typeof NoTarget = NoTarget,
254
+ ): void {
255
+ if (
256
+ !item.isExactName ||
257
+ nameType === NameType.Property ||
258
+ nameType === NameType.EnumMemberName ||
259
+ nameType === NameType.File
260
+ ) {
261
+ return;
262
+ }
263
+
264
+ const requiresMethodGuard = guardReservedNames(item.name, NameType.Method) !== item.name;
265
+ const isValid =
266
+ isValidTypeScriptIdentifierName(item.name) &&
267
+ (nameType === NameType.Method || !requiresMethodGuard);
268
+ if (isValid) {
269
+ return;
270
+ }
271
+
272
+ let reported = reportedInvalidExactNames.get(program);
273
+ if (!reported) {
274
+ reported = new WeakSet<object>();
275
+ reportedInvalidExactNames.set(program, reported);
276
+ }
277
+ if (reported.has(item)) {
278
+ return;
279
+ }
280
+ reported.add(item);
281
+
282
+ reportDiagnostic(program, {
283
+ code: "invalid-exact-name",
284
+ format: { nameKind, name: item.name },
285
+ target,
286
+ });
287
+ }
288
+
289
+ export function formatPropertyName(name: string): string {
290
+ return isValidTypeScriptIdentifierName(name) ? name : JSON.stringify(name);
291
+ }
292
+
293
+ export function formatPropertyAccess(base: string, name: string): string {
294
+ return isValidTypeScriptIdentifierName(name)
295
+ ? `${base}.${name}`
296
+ : `${base}[${JSON.stringify(name)}]`;
297
+ }
298
+
299
+ export function formatOptionalPropertyAccess(base: string, name: string): string {
300
+ return isValidTypeScriptIdentifierName(name)
301
+ ? `${base}?.${name}`
302
+ : `${base}?.[${JSON.stringify(name)}]`;
303
+ }
304
+
211
305
  export function fixLeadingNumber(name: string, nameType: NameType, prefix: string = "_"): string {
212
306
  const casingConvention = getCasingConvention(nameType);
213
307
  if (!name || !name.match(/^[-.]?\d/)) {
@@ -53,7 +53,7 @@ import {
53
53
  } from "./media-types.js";
54
54
  import { isByteOrByteUnion } from "./model-utils.js";
55
55
  import { getLroLogicalResponseName, getResponseTypeName } from "./name-constructors.js";
56
- import { NameType, normalizeName } from "./name-utils.js";
56
+ import { NameType, normalizeName, normalizeSdkName, reportInvalidExactName } from "./name-utils.js";
57
57
  import { getOperationNamespaceInterfaceName } from "./namespace-utils.js";
58
58
 
59
59
  // Sorts the responses by status code
@@ -645,9 +645,10 @@ export function getMethodHierarchiesMap(
645
645
  const operationOrGroup = method[1];
646
646
 
647
647
  if (operationOrGroup.kind === "client") {
648
- operationOrGroup.methods.forEach((m) =>
649
- methodQueue.push([[...prefixes, operationOrGroup.name], m]),
650
- );
648
+ const hierarchyName = operationOrGroup.isExactName
649
+ ? `$DO_NOT_NORMALIZE$${operationOrGroup.name}`
650
+ : operationOrGroup.name;
651
+ operationOrGroup.methods.forEach((m) => methodQueue.push([[...prefixes, hierarchyName], m]));
651
652
  const nonIndependentChildren = operationOrGroup.children?.filter((child) => {
652
653
  return (
653
654
  !(child.clientInitialization.initializedBy & InitializedByFlags.Individually) &&
@@ -656,10 +657,26 @@ export function getMethodHierarchiesMap(
656
657
  });
657
658
  if (nonIndependentChildren && nonIndependentChildren.length > 0) {
658
659
  nonIndependentChildren.forEach((child) =>
659
- methodQueue.push([[...prefixes, operationOrGroup.name], child]),
660
+ methodQueue.push([[...prefixes, hierarchyName], child]),
660
661
  );
661
662
  }
662
663
  } else {
664
+ reportInvalidExactName(
665
+ context.program,
666
+ operationOrGroup,
667
+ NameType.Method,
668
+ "operation",
669
+ operationOrGroup.__raw ?? NoTarget,
670
+ );
671
+ for (const parameter of operationOrGroup.parameters) {
672
+ reportInvalidExactName(
673
+ context.program,
674
+ parameter,
675
+ NameType.Parameter,
676
+ "parameter",
677
+ parameter.__raw ?? NoTarget,
678
+ );
679
+ }
663
680
  const prefixKey =
664
681
  context.emitterOptions?.hierarchyClient || context.emitterOptions?.enableOperationGroup
665
682
  ? prefixes.join("/")
@@ -736,18 +753,14 @@ function resolveParameterNameConflict(
736
753
  // subsequent calls (e.g. emitNonModelResponseTypes then buildApiOptions both call
737
754
  // getMethodHierarchiesMap on the same TCGC object) always normalize from the
738
755
  // original, not from the already-mutated value.
739
- const paramName = normalizeName(
740
- p.name,
741
- NameType.Parameter,
742
- true,
743
- undefined,
744
- undefined,
745
- p.oriName,
746
- );
756
+ const paramName = normalizeSdkName(p, NameType.Parameter, {
757
+ shouldGuard: true,
758
+ nameOverride: p.oriName ?? p.name,
759
+ });
747
760
  if (!p.oriName) {
748
761
  p.oriName = p.name;
749
762
  }
750
- if (paramName === operationOrGroup.name) {
763
+ if (!p.isExactName && paramName === operationOrGroup.name) {
751
764
  p.name = `${paramName}Parameter`;
752
765
  } else {
753
766
  p.name = paramName;