@azure-tools/typespec-ts 0.36.0 → 0.37.0-alpha.20241230.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/src/contextManager.d.ts +1 -2
  3. package/dist/src/contextManager.d.ts.map +1 -1
  4. package/dist/src/contextManager.js.map +1 -1
  5. package/dist/src/framework/load-static-helpers.d.ts +2 -1
  6. package/dist/src/framework/load-static-helpers.d.ts.map +1 -1
  7. package/dist/src/framework/load-static-helpers.js +17 -0
  8. package/dist/src/framework/load-static-helpers.js.map +1 -1
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +31 -29
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/lib.js +1 -1
  13. package/dist/src/lib.js.map +1 -1
  14. package/dist/src/metaTree.d.ts +0 -5
  15. package/dist/src/metaTree.d.ts.map +1 -1
  16. package/dist/src/modular/buildClassicalClient.d.ts +3 -2
  17. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
  18. package/dist/src/modular/buildClassicalClient.js +64 -62
  19. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  20. package/dist/src/modular/buildClassicalOperationGroups.d.ts +3 -2
  21. package/dist/src/modular/buildClassicalOperationGroups.d.ts.map +1 -1
  22. package/dist/src/modular/buildClassicalOperationGroups.js +35 -27
  23. package/dist/src/modular/buildClassicalOperationGroups.js.map +1 -1
  24. package/dist/src/modular/buildClientContext.d.ts +4 -3
  25. package/dist/src/modular/buildClientContext.d.ts.map +1 -1
  26. package/dist/src/modular/buildClientContext.js +84 -35
  27. package/dist/src/modular/buildClientContext.js.map +1 -1
  28. package/dist/src/modular/buildModularOptions.d.ts +7 -0
  29. package/dist/src/modular/buildModularOptions.d.ts.map +1 -0
  30. package/dist/src/modular/buildModularOptions.js +16 -0
  31. package/dist/src/modular/buildModularOptions.js.map +1 -0
  32. package/dist/src/modular/buildOperations.d.ts +6 -4
  33. package/dist/src/modular/buildOperations.d.ts.map +1 -1
  34. package/dist/src/modular/buildOperations.js +56 -55
  35. package/dist/src/modular/buildOperations.js.map +1 -1
  36. package/dist/src/modular/buildProjectFiles.d.ts +3 -2
  37. package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
  38. package/dist/src/modular/buildProjectFiles.js +18 -16
  39. package/dist/src/modular/buildProjectFiles.js.map +1 -1
  40. package/dist/src/modular/buildRestorePoller.d.ts +4 -2
  41. package/dist/src/modular/buildRestorePoller.d.ts.map +1 -1
  42. package/dist/src/modular/buildRestorePoller.js +22 -18
  43. package/dist/src/modular/buildRestorePoller.js.map +1 -1
  44. package/dist/src/modular/buildRootIndex.d.ts +4 -3
  45. package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
  46. package/dist/src/modular/buildRootIndex.js +40 -31
  47. package/dist/src/modular/buildRootIndex.js.map +1 -1
  48. package/dist/src/modular/buildSubpathIndex.d.ts +4 -2
  49. package/dist/src/modular/buildSubpathIndex.d.ts.map +1 -1
  50. package/dist/src/modular/buildSubpathIndex.js +8 -5
  51. package/dist/src/modular/buildSubpathIndex.js.map +1 -1
  52. package/dist/src/modular/emitLoggerFile.d.ts +2 -3
  53. package/dist/src/modular/emitLoggerFile.d.ts.map +1 -1
  54. package/dist/src/modular/emitLoggerFile.js +4 -4
  55. package/dist/src/modular/emitLoggerFile.js.map +1 -1
  56. package/dist/src/modular/emitModels.d.ts +1 -2
  57. package/dist/src/modular/emitModels.d.ts.map +1 -1
  58. package/dist/src/modular/emitModels.js +10 -3
  59. package/dist/src/modular/emitModels.js.map +1 -1
  60. package/dist/src/modular/emitModelsOptions.d.ts +3 -24
  61. package/dist/src/modular/emitModelsOptions.d.ts.map +1 -1
  62. package/dist/src/modular/emitModelsOptions.js +10 -86
  63. package/dist/src/modular/emitModelsOptions.js.map +1 -1
  64. package/dist/src/modular/emitSamples.js +2 -1
  65. package/dist/src/modular/emitSamples.js.map +1 -1
  66. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts +3 -3
  67. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts.map +1 -1
  68. package/dist/src/modular/helpers/classicalOperationHelpers.js +40 -50
  69. package/dist/src/modular/helpers/classicalOperationHelpers.js.map +1 -1
  70. package/dist/src/modular/helpers/clientHelpers.d.ts +11 -8
  71. package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
  72. package/dist/src/modular/helpers/clientHelpers.js +87 -60
  73. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  74. package/dist/src/modular/helpers/namingHelpers.d.ts +4 -7
  75. package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
  76. package/dist/src/modular/helpers/namingHelpers.js +3 -26
  77. package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
  78. package/dist/src/modular/helpers/operationHelpers.d.ts +21 -20
  79. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  80. package/dist/src/modular/helpers/operationHelpers.js +336 -291
  81. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  82. package/dist/src/modular/helpers/typeHelpers.d.ts +4 -25
  83. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
  84. package/dist/src/modular/helpers/typeHelpers.js +6 -218
  85. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  86. package/dist/src/modular/interfaces.d.ts +15 -8
  87. package/dist/src/modular/interfaces.d.ts.map +1 -1
  88. package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
  89. package/dist/src/modular/serialization/buildDeserializerFunction.js +1 -2
  90. package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
  91. package/dist/src/modular/serialization/buildSerializerFunction.d.ts.map +1 -1
  92. package/dist/src/modular/serialization/buildSerializerFunction.js +1 -2
  93. package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
  94. package/dist/src/modular/serialization/serializeUtils.d.ts +8 -5
  95. package/dist/src/modular/serialization/serializeUtils.d.ts.map +1 -1
  96. package/dist/src/modular/serialization/serializeUtils.js +22 -22
  97. package/dist/src/modular/serialization/serializeUtils.js.map +1 -1
  98. package/dist/src/utils/clientUtils.d.ts +3 -1
  99. package/dist/src/utils/clientUtils.d.ts.map +1 -1
  100. package/dist/src/utils/clientUtils.js +10 -0
  101. package/dist/src/utils/clientUtils.js.map +1 -1
  102. package/dist/src/utils/operationUtil.d.ts +6 -2
  103. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  104. package/dist/src/utils/operationUtil.js +66 -7
  105. package/dist/src/utils/operationUtil.js.map +1 -1
  106. package/dist/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +3 -3
  108. package/src/contextManager.ts +1 -2
  109. package/src/framework/load-static-helpers.ts +24 -1
  110. package/src/index.ts +65 -37
  111. package/src/lib.ts +1 -1
  112. package/src/metaTree.ts +0 -6
  113. package/src/modular/buildClassicalClient.ts +97 -99
  114. package/src/modular/buildClassicalOperationGroups.ts +53 -47
  115. package/src/modular/buildClientContext.ts +101 -44
  116. package/src/modular/buildModularOptions.ts +27 -0
  117. package/src/modular/buildOperations.ts +91 -78
  118. package/src/modular/buildProjectFiles.ts +24 -21
  119. package/src/modular/buildRestorePoller.ts +39 -23
  120. package/src/modular/buildRootIndex.ts +51 -42
  121. package/src/modular/buildSubpathIndex.ts +16 -7
  122. package/src/modular/emitLoggerFile.ts +12 -10
  123. package/src/modular/emitModels.ts +15 -7
  124. package/src/modular/emitModelsOptions.ts +18 -125
  125. package/src/modular/emitSamples.ts +2 -3
  126. package/src/modular/helpers/classicalOperationHelpers.ts +50 -75
  127. package/src/modular/helpers/clientHelpers.ts +107 -73
  128. package/src/modular/helpers/namingHelpers.ts +6 -65
  129. package/src/modular/helpers/operationHelpers.ts +506 -384
  130. package/src/modular/helpers/typeHelpers.ts +11 -267
  131. package/src/modular/interfaces.ts +16 -8
  132. package/src/modular/serialization/buildDeserializerFunction.ts +1 -6
  133. package/src/modular/serialization/buildSerializerFunction.ts +1 -2
  134. package/src/modular/serialization/serializeUtils.ts +31 -30
  135. package/src/utils/clientUtils.ts +23 -1
  136. package/src/utils/operationUtil.ts +106 -14
  137. package/dist/src/modular/buildCodeModel.d.ts +0 -34
  138. package/dist/src/modular/buildCodeModel.d.ts.map +0 -1
  139. package/dist/src/modular/buildCodeModel.js +0 -1489
  140. package/dist/src/modular/buildCodeModel.js.map +0 -1
  141. package/dist/src/modular/modularCodeModel.d.ts +0 -166
  142. package/dist/src/modular/modularCodeModel.d.ts.map +0 -1
  143. package/dist/src/modular/modularCodeModel.js +0 -2
  144. package/dist/src/modular/modularCodeModel.js.map +0 -1
  145. package/src/modular/buildCodeModel.ts +0 -1965
  146. package/src/modular/modularCodeModel.ts +0 -211
@@ -1,272 +1,18 @@
1
1
  import {
2
2
  SdkBodyParameter,
3
+ SdkModelPropertyType,
3
4
  SdkType
4
5
  } from "@azure-tools/typespec-client-generator-core";
5
- import { Type } from "../modularCodeModel.js";
6
6
 
7
- /**
8
- * Represents metadata for a given Type to generate the TypeScript equivalent.
9
- */
10
- export interface TypeMetadata {
11
- name: string;
12
- originModule?: string;
13
- isRelative?: boolean;
14
- nullable?: boolean;
15
- modifier?: "Array";
16
- }
17
-
18
- // Mapping of simple types to their TypeScript equivalents.
19
- const simpleTypeMap: Record<string, TypeMetadata> = {
20
- Key: {
21
- name: "KeyCredential"
22
- },
23
- OAuth2: {
24
- name: "TokenCredential"
25
- },
26
- boolean: { name: "boolean" },
27
- datetime: { name: "Date" },
28
- float: { name: "number" },
29
- integer: { name: "number" },
30
- "byte-array": { name: "Uint8Array" },
31
- string: { name: "string" },
32
- any: { name: "Record<string, any>" },
33
- unknown: { name: "any" }
34
- };
35
-
36
- function handleAnomymousModelName(type: Type) {
37
- let retVal = `{`;
38
- for (const prop of type.properties ?? []) {
39
- const propName = prop.clientName ?? prop.restApiName ?? "";
40
- const propTypeName = getType(prop.type, prop.type.format).name;
41
- if (!propName || !propTypeName) {
42
- continue;
43
- }
44
- retVal += `"${propName}"${prop.optional ? "?" : ""}: ${propTypeName};`;
45
- }
46
-
47
- retVal += `}`;
48
- return retVal;
49
- }
50
-
51
- function handleNullableTypeName(type: {
52
- name?: string;
53
- nullable?: boolean;
54
- }): string {
55
- if (!type.name) {
56
- throw new Error("Unable to process type without name");
57
- }
58
- let name = type.name;
59
-
60
- if (type.nullable) {
61
- name = `(${name} | null)`;
62
- }
63
-
64
- return name;
65
- }
66
-
67
- /**
68
- * Maps a given Type to its TypeScript representation metadata.
69
- */
70
- export function getType(type: Type, format?: string): TypeMetadata {
71
- // Handle simple type conversions
72
- const simpleType = simpleTypeMap[type.type];
73
- if (simpleType) {
74
- const typeMetadata: TypeMetadata = { ...simpleType };
75
- if (isTypeNullable(type)) {
76
- typeMetadata.nullable = true;
77
- typeMetadata.name = handleNullableTypeName(typeMetadata);
78
- }
79
- return typeMetadata;
80
- }
81
-
82
- switch (type.type) {
83
- case "constant":
84
- return handleConstantType(type);
85
-
86
- case "enum":
87
- return handleEnumType(type);
88
-
89
- case "list":
90
- return handleListType(type);
91
-
92
- case "model":
93
- return handleModelType(type);
94
-
95
- case "duration":
96
- return handleDurationType(type, format);
97
-
98
- case "combined":
99
- return handleCombinedType(type);
100
-
101
- case "dict":
102
- return handleDictType(type);
103
-
104
- case "never":
105
- return { name: "never", nullable: isTypeNullable(type) };
106
- default:
107
- throw new Error(`Unsupported type ${type.type}`);
108
- }
109
- }
110
-
111
- /**
112
- * Handles the conversion of constant types to TypeScript representation metadata.
113
- */
114
- function handleConstantType(type: Type): TypeMetadata {
115
- let typeName: string = type.value?.toString() ?? "undefined";
116
- if (type.valueType?.type === "string") {
117
- typeName = type.value ? `"${type.value}"` : "undefined";
118
- }
119
- const name = handleNullableTypeName({
120
- name: typeName,
121
- nullable: isTypeNullable(type)
122
- });
123
- return { name, nullable: isTypeNullable(type) };
124
- }
125
-
126
- /**
127
- * Handles the conversion of enum types to TypeScript representation metadata.
128
- */
129
- function handleEnumType(type: Type): TypeMetadata {
130
- if (!type.name) {
131
- const valueType = !type.isFixed
132
- ? ((type.values?.[0] as Type).valueType?.type ?? "string") + " | "
133
- : "";
134
- return {
135
- name: `${valueType}${type.values
136
- ?.map((e) => {
137
- return getType(e as Type).name;
138
- })
139
- .join(" | ")}`,
140
- nullable: isTypeNullable(type)
141
- };
142
- }
143
- const name = handleNullableTypeName({
144
- name: type.name,
145
- nullable: isTypeNullable(type)
146
- });
147
- return {
148
- name,
149
- nullable: isTypeNullable(type),
150
- originModule: "models.js"
151
- };
7
+ export function isTypeNullable(type: SdkType) {
8
+ return Boolean(type.kind === "nullable");
152
9
  }
153
10
 
154
- export function isTypeNullable(type: Type) {
155
- return Boolean(type.tcgcType?.kind === "nullable");
156
- }
157
-
158
- /**
159
- * Handles the conversion of list types to TypeScript representation metadata.
160
- */
161
- function handleListType(type: Type): TypeMetadata {
162
- if (!type.elementType) {
163
- throw new Error("Unable to process Array with no elementType");
164
- }
165
-
166
- const elementTypeMetadata = getType(
167
- type.elementType,
168
- type.elementType.format
169
- );
170
-
171
- let name = `${elementTypeMetadata.name}[]`;
172
-
173
- const isTypeNullable = type.tcgcType?.kind === "nullable";
174
-
175
- if (isTypeNullable) {
176
- name = `(${name} | null)`;
177
- }
178
-
179
- const listTypeMetadata: TypeMetadata = {
180
- name: name,
181
- nullable: isTypeNullable,
182
- originModule: type.elementType?.type === "model" ? "models.js" : undefined
183
- };
184
-
185
- return listTypeMetadata;
186
- }
187
-
188
- /**
189
- * Handles the conversion of model types to TypeScript representation metadata.
190
- */
191
- function handleModelType(type: Type): TypeMetadata {
192
- let name = !type.name ? handleAnomymousModelName(type) : type.name;
193
- name = handleNullableTypeName({
194
- name,
195
- nullable: isTypeNullable(type)
196
- });
197
- return {
198
- name,
199
- nullable: isTypeNullable(type),
200
- originModule: "models.js"
201
- };
202
- }
203
-
204
- /**
205
- * Handles the conversion of duration types to TypeScript representation metadata.
206
- */
207
- function handleDurationType(type: Type, format?: string): TypeMetadata {
208
- const isFormatSeconds = format === "seconds";
209
- let name = isFormatSeconds ? "number" : "string";
210
- name = handleNullableTypeName({ name, nullable: isTypeNullable(type) });
211
- return {
212
- name,
213
- nullable: isTypeNullable(type)
214
- };
215
- }
216
-
217
- /**
218
- * Handles the conversion of combined types to TypeScript representation metadata.
219
- */
220
- function handleCombinedType(type: Type): TypeMetadata {
221
- if (!type.types) {
222
- throw new Error("Unable to process combined without combinedTypes");
223
- }
224
- const name =
225
- type.name ??
226
- type.types
227
- .map((t) => {
228
- const sdkType = getType(t, t.format).name;
229
- return `${sdkType}`;
230
- })
231
- .join(" | ");
232
- return { name: `(${name})`, nullable: isTypeNullable(type) };
233
- }
234
-
235
- /**
236
- * Handles the conversion of dict types to TypeScript representation metadata.
237
- */
238
- function handleDictType(type: Type): TypeMetadata {
239
- if (!type.elementType) {
240
- throw new Error("Unable to process dict without elemetType info");
11
+ export function getNullableValidType(type: SdkType): SdkType {
12
+ if (type.kind === "nullable") {
13
+ return type.type;
241
14
  }
242
- if (type.name && type.name !== "Record") {
243
- return {
244
- name: type.name
245
- };
246
- }
247
- const elementType = getType(type.elementType, type.elementType.format);
248
- const elementName = elementType.name;
249
- const name = handleNullableTypeName({
250
- name: `Record<string, ${elementName}>`,
251
- nullable: isTypeNullable(type)
252
- });
253
- return {
254
- name,
255
- nullable: isTypeNullable(type)
256
- };
257
- }
258
-
259
- /**
260
- * Generates a TypeScript type representation for a given client name, type, and format.
261
- */
262
- export function buildType(clientName?: string, type?: Type, format?: string) {
263
- if (!type) {
264
- throw new Error("Type should be defined");
265
- }
266
-
267
- const typeMetadata = getType(type, format);
268
-
269
- return { name: clientName ?? "", type: typeMetadata.name };
15
+ return type;
270
16
  }
271
17
 
272
18
  const NumericTypeKinds = [
@@ -299,12 +45,10 @@ export function isDateTimeTypeKind(kind: string): boolean {
299
45
  return DateTimeTypeKinds.includes(kind);
300
46
  }
301
47
 
302
- export function isCredentialType(type: Type): boolean {
303
- const credentialTypes = ["OAuth2", "Key"];
304
- return (
305
- credentialTypes.includes(type.type) ||
306
- (type.type === "combined" && (type.types?.every(isCredentialType) ?? false))
307
- );
48
+ export function isCredentialType(
49
+ type: SdkType | SdkModelPropertyType
50
+ ): boolean {
51
+ return type.kind === "credential";
308
52
  }
309
53
 
310
54
  /**
@@ -1,12 +1,20 @@
1
- import { OptionalKind, ParameterDeclarationStructure } from "ts-morph";
2
- import { Parameter } from "./modularCodeModel.js";
1
+ import { RLCOptions } from "@azure-tools/rlc-common";
2
+ import { Project } from "ts-morph";
3
3
 
4
- export interface ClientDetails {
5
- name: string;
6
- params?: OptionalKind<ParameterDeclarationStructure>[];
7
- description: string;
8
- baseUrl?: string;
9
- credentialsParam?: Parameter;
4
+ export interface ModularOptions {
5
+ sourceRoot: string;
6
+ compatibilityMode: boolean;
7
+ experimentalExtensibleEnums: boolean;
8
+ }
9
+ export interface ModularEmitterOptions {
10
+ options: RLCOptions;
11
+ modularOptions: ModularOptions;
12
+ project: Project;
13
+ }
14
+
15
+ export interface ModularClientOptions {
16
+ subfolder?: string;
17
+ rlcClientName: string;
10
18
  }
11
19
 
12
20
  export interface OperationPathAndDeserDetails {
@@ -11,7 +11,6 @@ import { toCamelCase, toPascalCase } from "../../utils/casingUtils.js";
11
11
 
12
12
  import { SdkContext } from "../../utils/interfaces.js";
13
13
  import { getResponseMapping } from "../helpers/operationHelpers.js";
14
- import { getType } from "../buildCodeModel.js";
15
14
  import { normalizeModelName } from "../emitModels.js";
16
15
  import { NameType } from "@azure-tools/rlc-common";
17
16
  import { isAzureCoreErrorType } from "../../utils/modelUtils.js";
@@ -344,11 +343,7 @@ function buildModelTypeDeserializer(
344
343
  ? "...item,"
345
344
  : "";
346
345
 
347
- const propertiesStr = getResponseMapping(
348
- context,
349
- getType(context, type.__raw!),
350
- "item"
351
- );
346
+ const propertiesStr = getResponseMapping(context, type, "item");
352
347
  const propertiesDeserialization = propertiesStr.filter((p) => p.trim());
353
348
 
354
349
  const output = [];
@@ -11,7 +11,6 @@ import { toCamelCase, toPascalCase } from "../../utils/casingUtils.js";
11
11
 
12
12
  import { SdkContext } from "../../utils/interfaces.js";
13
13
  import { getRequestModelMapping } from "../helpers/operationHelpers.js";
14
- import { getType } from "../buildCodeModel.js";
15
14
  import { normalizeModelName } from "../emitModels.js";
16
15
  import { NameType } from "@azure-tools/rlc-common";
17
16
  import { isAzureCoreErrorType } from "../../utils/modelUtils.js";
@@ -339,7 +338,7 @@ function buildModelTypeSerializer(
339
338
 
340
339
  const { directAssignment, propertiesStr } = getRequestModelMapping(
341
340
  context,
342
- getType(context, type.__raw!),
341
+ type,
343
342
  "item"
344
343
  );
345
344
  if (additionalPropertiesSpread) {
@@ -1,4 +1,3 @@
1
- import { Type } from "../modularCodeModel.js";
2
1
  import { getAllAncestors } from "../helpers/operationHelpers.js";
3
2
  import {
4
3
  SdkModelType,
@@ -26,10 +25,10 @@ export function isSupportedSerializeType(type: SdkType): boolean {
26
25
  * 6. nested model i.e. model with property that is a model with one of the above three conditions.
27
26
  * If we consider array type, with all the above 6 types as the element types.
28
27
  */
29
- const specialVariantMap = new Map<Type, boolean>();
28
+ const specialVariantMap = new Map<SdkType, boolean>();
30
29
  export function isSpecialUnionVariant(
31
- t: Type,
32
- variantStack: Type[] = []
30
+ t: SdkType & { isNonExhaustive?: boolean },
31
+ variantStack: SdkType[] = []
33
32
  ): boolean {
34
33
  if (variantStack.length <= 0) {
35
34
  variantStack.push(t);
@@ -41,40 +40,40 @@ export function isSpecialUnionVariant(
41
40
  }
42
41
 
43
42
  if (
44
- t.type === "datetime" ||
45
- t.type === "byte-array" ||
46
- (t.type === "model" &&
43
+ t.kind === "utcDateTime" ||
44
+ t.kind === "bytes" ||
45
+ (t.kind === "model" &&
47
46
  t.properties
48
47
  ?.filter((p) => {
49
48
  return !(
50
49
  variantStack.includes(p.type) ||
51
50
  ancestors.includes(p.type) ||
52
- (p.type.type === "list" &&
53
- p.type.elementType &&
54
- (variantStack.includes(p.type.elementType) ||
55
- ancestors.includes(p.type.elementType)))
51
+ (p.type.kind === "array" &&
52
+ p.type.valueType &&
53
+ (variantStack.includes(p.type.valueType) ||
54
+ ancestors.includes(p.type.valueType)))
56
55
  );
57
56
  })
58
57
  ?.some(
59
58
  (p) =>
60
- p.clientName !== p.restApiName ||
59
+ (p.kind === "property" && p.name !== p.serializedName) ||
61
60
  isSpecialUnionVariant(p.type, [...variantStack, p.type])
62
61
  )) ||
63
62
  isPolymorphicUnion(t) ||
64
- (t.type === "list" &&
65
- t.elementType &&
66
- !variantStack.includes(t.elementType) &&
67
- !ancestors.includes(t.elementType) &&
68
- isSpecialUnionVariant(t.elementType, [...variantStack, t.elementType])) ||
69
- (t.type === "combined" &&
70
- t.types
63
+ (t.kind === "array" &&
64
+ t.valueType &&
65
+ !variantStack.includes(t.valueType) &&
66
+ !ancestors.includes(t.valueType) &&
67
+ isSpecialUnionVariant(t.valueType, [...variantStack, t.valueType])) ||
68
+ (t.kind === "union" &&
69
+ t.variantTypes
71
70
  ?.filter((p) => {
72
71
  return !(variantStack.includes(p) || ancestors.includes(p));
73
72
  })
74
73
  ?.some((p) => {
75
74
  return isSpecialUnionVariant(p, [...variantStack, p]);
76
75
  })) ||
77
- (t.type === "enum" && !(t.isFixed || t.isNonExhaustive))
76
+ (t.kind === "enum" && !(t.isFixed || t.isNonExhaustive))
78
77
  ) {
79
78
  specialVariantMap.set(t, true);
80
79
  variantStack.pop();
@@ -85,11 +84,11 @@ export function isSpecialUnionVariant(
85
84
  return false;
86
85
  }
87
86
 
88
- export function isNormalUnion(t: Type): boolean {
87
+ export function isNormalUnion(t: SdkType): boolean {
89
88
  return (
90
- t.type === "combined" &&
89
+ t.kind === "union" &&
91
90
  !(
92
- t.types?.some((p) => {
91
+ t.variantTypes?.some((p) => {
93
92
  return isSpecialUnionVariant(p);
94
93
  }) ?? false
95
94
  )
@@ -109,20 +108,22 @@ export function isDiscriminatedUnion(
109
108
  );
110
109
  }
111
110
 
112
- export function isSpecialHandledUnion(t: Type): boolean {
113
- return isDiscriminatedUnion(t.tcgcType!) || isPolymorphicUnion(t);
111
+ export function isSpecialHandledUnion(
112
+ t: SdkType & { isNonExhaustive?: boolean }
113
+ ): boolean {
114
+ return isDiscriminatedUnion(t!) || isPolymorphicUnion(t);
114
115
  }
115
116
 
116
- const polymorphicUnionMap = new Map<Type, boolean>();
117
- export function isPolymorphicUnion(t: Type): boolean {
117
+ const polymorphicUnionMap = new Map<SdkType, boolean>();
118
+ export function isPolymorphicUnion(t: SdkType): boolean {
118
119
  if (polymorphicUnionMap.has(t)) {
119
120
  return polymorphicUnionMap.get(t) ?? false;
120
121
  }
121
122
  const ancestors = getAllAncestors(t);
122
123
  if (
123
- t.type === "model" &&
124
- t.isPolymorphicBaseModel &&
125
- t.types
124
+ t.kind === "model" &&
125
+ t.discriminatedSubtypes &&
126
+ Object.values(t.discriminatedSubtypes)
126
127
  ?.filter((p) => {
127
128
  return !ancestors.includes(p);
128
129
  })
@@ -1,6 +1,12 @@
1
- import { SdkClient } from "@azure-tools/typespec-client-generator-core";
1
+ import {
2
+ SdkClient,
3
+ SdkClientType,
4
+ SdkServiceOperation
5
+ } from "@azure-tools/typespec-client-generator-core";
2
6
  import { getNamespaceFullName, listServices } from "@typespec/compiler";
3
7
  import { SdkContext } from "./interfaces.js";
8
+ import { NameType, normalizeName } from "@azure-tools/rlc-common";
9
+ import { ModularClientOptions } from "../modular/interfaces.js";
4
10
 
5
11
  export function getRLCClients(dpgContext: SdkContext): SdkClient[] {
6
12
  const services = listServices(dpgContext.program);
@@ -23,3 +29,19 @@ export function getRLCClients(dpgContext: SdkContext): SdkClient[] {
23
29
  export function isRLCMultiEndpoint(dpgContext: SdkContext): boolean {
24
30
  return getRLCClients(dpgContext).length > 1;
25
31
  }
32
+
33
+ export function getModularClientOptions(
34
+ context: SdkContext,
35
+ client: SdkClientType<SdkServiceOperation>
36
+ ) {
37
+ const clientOptions: ModularClientOptions = {
38
+ rlcClientName: `${client.name.replace("Client", "")}Context`
39
+ };
40
+ if (context.sdkPackage.clients.length > 1) {
41
+ clientOptions.subfolder = normalizeName(
42
+ client.name.replace("Client", ""),
43
+ NameType.File
44
+ );
45
+ }
46
+ return clientOptions;
47
+ }
@@ -23,7 +23,15 @@ import {
23
23
  getWireName,
24
24
  listOperationGroups,
25
25
  listOperationsInOperationGroup,
26
- SdkClient
26
+ SdkBodyParameter,
27
+ SdkClient,
28
+ SdkClientType,
29
+ SdkHttpOperation,
30
+ SdkHttpParameter,
31
+ SdkMethod,
32
+ SdkMethodParameter,
33
+ SdkServiceMethod,
34
+ SdkServiceOperation
27
35
  } from "@azure-tools/typespec-client-generator-core";
28
36
  import { Model, Operation, Program, Type } from "@typespec/compiler";
29
37
  import {
@@ -408,6 +416,19 @@ export function extractPagedMetadataNested(
408
416
  return paged;
409
417
  }
410
418
 
419
+ export function hasCollectionFormatInfo(
420
+ paramType: string,
421
+ paramFormat: string
422
+ ) {
423
+ return (
424
+ getHasMultiCollection(paramType, paramFormat) ||
425
+ getHasSsvCollection(paramType, paramFormat) ||
426
+ getHasTsvCollection(paramType, paramFormat) ||
427
+ getHasCsvCollection(paramType, paramFormat) ||
428
+ getHasPipeCollection(paramType, paramFormat)
429
+ );
430
+ }
431
+
411
432
  export function getSpecialSerializeInfo(
412
433
  dpgContext: SdkContext,
413
434
  paramType: string,
@@ -465,19 +486,6 @@ function getHasPipeCollection(paramType: string, paramFormat: string) {
465
486
  return paramType === "query" && paramFormat === "pipes";
466
487
  }
467
488
 
468
- export function hasCollectionFormatInfo(
469
- paramType: string,
470
- paramFormat: string
471
- ) {
472
- return (
473
- getHasMultiCollection(paramType, paramFormat) ||
474
- getHasSsvCollection(paramType, paramFormat) ||
475
- getHasTsvCollection(paramType, paramFormat) ||
476
- getHasCsvCollection(paramType, paramFormat) ||
477
- getHasPipeCollection(paramType, paramFormat)
478
- );
479
- }
480
-
481
489
  export function getCollectionFormatHelper(
482
490
  paramType: string,
483
491
  paramFormat: string
@@ -546,3 +554,87 @@ export function parseItemName(paged: PagedResultMetadata): string | undefined {
546
554
  // TODO: support the nested item names
547
555
  return (paged.itemsSegments ?? [])[0];
548
556
  }
557
+
558
+ export type ServiceOperation = SdkServiceMethod<SdkHttpOperation> & {
559
+ oriName?: string;
560
+ };
561
+
562
+ export function getMethodHierarchiesMap(
563
+ context: SdkContext,
564
+ client: SdkClientType<SdkServiceOperation>
565
+ ): Map<string, ServiceOperation[]> {
566
+ const methodQueue: [string[], SdkMethod<SdkHttpOperation>][] =
567
+ client.methods.map((m) => {
568
+ return [[], m];
569
+ });
570
+ const operationHierarchiesMap: Map<string, ServiceOperation[]> = new Map<
571
+ string,
572
+ ServiceOperation[]
573
+ >();
574
+ while (methodQueue.length > 0) {
575
+ const method = methodQueue.pop();
576
+ if (!method) {
577
+ continue;
578
+ }
579
+ const prefixes = method[0];
580
+ const operationOrGroup = method[1];
581
+
582
+ if (operationOrGroup.kind === "clientaccessor") {
583
+ operationOrGroup.response.methods.forEach((m) =>
584
+ methodQueue.push([[...prefixes, operationOrGroup.response.name], m])
585
+ );
586
+ } else {
587
+ const prefixKey =
588
+ context.rlcOptions?.hierarchyClient ||
589
+ context.rlcOptions?.enableOperationGroup
590
+ ? prefixes.join("/")
591
+ : "";
592
+ const groupName = prefixes
593
+ .map((p) => normalizeName(p, NameType.OperationGroup))
594
+ .join("");
595
+ if (
596
+ context.rlcOptions?.hierarchyClient === false &&
597
+ context.rlcOptions?.enableOperationGroup &&
598
+ groupName !== "" &&
599
+ !operationOrGroup.name.startsWith(groupName + "_")
600
+ ) {
601
+ (operationOrGroup as ServiceOperation).oriName = operationOrGroup.name;
602
+ operationOrGroup.name = `${groupName}_${operationOrGroup.name}`;
603
+ }
604
+
605
+ operationOrGroup.parameters.map((p) => {
606
+ return resolveParameterNameConflict(operationOrGroup, p);
607
+ });
608
+ operationOrGroup.operation.parameters.map((p) => {
609
+ return resolveParameterNameConflict(operationOrGroup, p);
610
+ });
611
+ if (
612
+ operationOrGroup.operation.bodyParam?.name === operationOrGroup.name
613
+ ) {
614
+ operationOrGroup.operation.bodyParam = resolveParameterNameConflict(
615
+ operationOrGroup,
616
+ operationOrGroup.operation.bodyParam
617
+ ) as SdkBodyParameter;
618
+ }
619
+ const operations = operationHierarchiesMap.get(prefixKey);
620
+ operationHierarchiesMap.set(prefixKey, [
621
+ ...(operations ?? []),
622
+ operationOrGroup
623
+ ]);
624
+ }
625
+ }
626
+ return operationHierarchiesMap;
627
+ }
628
+
629
+ function resolveParameterNameConflict(
630
+ operationOrGroup: SdkServiceMethod<SdkHttpOperation>,
631
+ p: SdkMethodParameter | SdkHttpParameter | SdkBodyParameter
632
+ ): SdkMethodParameter | SdkHttpParameter | SdkBodyParameter {
633
+ const paramName = normalizeName(p.name, NameType.Parameter, true);
634
+ if (paramName === operationOrGroup.name) {
635
+ p.name = `${paramName}Parameter`;
636
+ } else {
637
+ p.name = paramName;
638
+ }
639
+ return p;
640
+ }
@@ -1,34 +0,0 @@
1
- import { Model, Type, UsageFlags } from "@typespec/compiler";
2
- import { ModularCodeModel } from "./modularCodeModel.js";
3
- import { HttpAuth } from "@typespec/http";
4
- import { RLCModel } from "@azure-tools/rlc-common";
5
- import { Project } from "ts-morph";
6
- import { SdkContext } from "../utils/interfaces.js";
7
- interface CredentialType {
8
- kind: "Credential";
9
- scheme: HttpAuth;
10
- }
11
- interface CredentialTypeUnion {
12
- kind: "CredentialTypeUnion";
13
- types: CredentialType[];
14
- }
15
- type EmitterType = Type | CredentialType | CredentialTypeUnion;
16
- export interface EmitterOptions {
17
- "basic-setup-py"?: boolean;
18
- "package-version"?: string;
19
- "package-name"?: string;
20
- "output-dir"?: string;
21
- "package-mode"?: string;
22
- debug?: boolean;
23
- }
24
- interface EmitTypeOptions {
25
- disableEffectiveModel?: boolean;
26
- usage?: UsageFlags;
27
- }
28
- export declare function getType(context: SdkContext, type: EmitterType, options?: EmitTypeOptions): any;
29
- export declare function emitModel(context: SdkContext, type: Model, options?: EmitTypeOptions): Record<string, any>;
30
- export declare function emitCodeModel(dpgContext: SdkContext, rlcModelsMap: Map<string, RLCModel>, modularSourcesRoot: string, project: Project, options?: {
31
- casing: "snake" | "camel";
32
- }): ModularCodeModel;
33
- export {};
34
- //# sourceMappingURL=buildCodeModel.d.ts.map