@azure-tools/typespec-ts 0.34.0 → 0.35.0-alpha.20241203.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 (70) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +16 -0
  3. package/dist/src/index.d.ts.map +1 -1
  4. package/dist/src/index.js +22 -19
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/lib.d.ts +19 -1
  7. package/dist/src/lib.d.ts.map +1 -1
  8. package/dist/src/lib.js +14 -1
  9. package/dist/src/lib.js.map +1 -1
  10. package/dist/src/modular/buildClassicalClient.js +2 -2
  11. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  12. package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
  13. package/dist/src/modular/buildCodeModel.js +18 -0
  14. package/dist/src/modular/buildCodeModel.js.map +1 -1
  15. package/dist/src/modular/helpers/clientHelpers.js +1 -1
  16. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  17. package/dist/src/modular/helpers/operationHelpers.js +2 -2
  18. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  19. package/dist/src/transform/transform.d.ts.map +1 -1
  20. package/dist/src/transform/transform.js +7 -5
  21. package/dist/src/transform/transform.js.map +1 -1
  22. package/dist/src/transform/transformApiVersionInfo.js +2 -2
  23. package/dist/src/transform/transformApiVersionInfo.js.map +1 -1
  24. package/dist/src/transform/transformHelperFunctionDetails.js +2 -29
  25. package/dist/src/transform/transformHelperFunctionDetails.js.map +1 -1
  26. package/dist/src/transform/transformParameters.d.ts +8 -1
  27. package/dist/src/transform/transformParameters.d.ts.map +1 -1
  28. package/dist/src/transform/transformParameters.js +63 -38
  29. package/dist/src/transform/transformParameters.js.map +1 -1
  30. package/dist/src/transform/transformPaths.d.ts.map +1 -1
  31. package/dist/src/transform/transformPaths.js +14 -6
  32. package/dist/src/transform/transformPaths.js.map +1 -1
  33. package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
  34. package/dist/src/transform/transfromRLCOptions.js +6 -4
  35. package/dist/src/transform/transfromRLCOptions.js.map +1 -1
  36. package/dist/src/utils/emitUtil.js +3 -0
  37. package/dist/src/utils/emitUtil.js.map +1 -1
  38. package/dist/src/utils/modelUtils.d.ts +2 -1
  39. package/dist/src/utils/modelUtils.d.ts.map +1 -1
  40. package/dist/src/utils/modelUtils.js +10 -25
  41. package/dist/src/utils/modelUtils.js.map +1 -1
  42. package/dist/src/utils/operationUtil.d.ts +1 -4
  43. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  44. package/dist/src/utils/operationUtil.js +8 -22
  45. package/dist/src/utils/operationUtil.js.map +1 -1
  46. package/dist/src/utils/parameterUtils.d.ts +9 -0
  47. package/dist/src/utils/parameterUtils.d.ts.map +1 -0
  48. package/dist/src/utils/parameterUtils.js +165 -0
  49. package/dist/src/utils/parameterUtils.js.map +1 -0
  50. package/dist/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +20 -20
  52. package/src/index.ts +22 -24
  53. package/src/lib.ts +14 -1
  54. package/src/modular/buildClassicalClient.ts +2 -2
  55. package/src/modular/buildCodeModel.ts +19 -1
  56. package/src/modular/helpers/clientHelpers.ts +1 -1
  57. package/src/modular/helpers/operationHelpers.ts +2 -2
  58. package/src/transform/transform.ts +3 -1
  59. package/src/transform/transformApiVersionInfo.ts +2 -2
  60. package/src/transform/transformHelperFunctionDetails.ts +2 -27
  61. package/src/transform/transformParameters.ts +83 -42
  62. package/src/transform/transformPaths.ts +23 -5
  63. package/src/transform/transfromRLCOptions.ts +6 -4
  64. package/src/utils/emitUtil.ts +3 -0
  65. package/src/utils/modelUtils.ts +14 -34
  66. package/src/utils/operationUtil.ts +14 -23
  67. package/src/utils/parameterUtils.ts +234 -0
  68. package/static/static-helpers/pagingHelpers.ts +0 -3
  69. package/static/static-helpers/pollingHelpers.ts +0 -3
  70. package/static/static-helpers/serialization/build-csv-collection.ts +0 -3
@@ -317,10 +317,12 @@ function getServiceInfo(program: Program): ServiceInfo {
317
317
  }
318
318
 
319
319
  function getAzureSdkForJs(emitterOptions: EmitterOptions) {
320
- return emitterOptions.azureSdkForJs === undefined ||
321
- emitterOptions.azureSdkForJs === null
322
- ? true
323
- : Boolean(emitterOptions.azureSdkForJs);
320
+ return emitterOptions.flavor !== "azure"
321
+ ? false
322
+ : emitterOptions.azureSdkForJs === undefined ||
323
+ emitterOptions.azureSdkForJs === null
324
+ ? true
325
+ : Boolean(emitterOptions.azureSdkForJs);
324
326
  }
325
327
 
326
328
  function getGenerateMetadata(emitterOptions: EmitterOptions) {
@@ -54,6 +54,9 @@ async function emitFile(
54
54
  isAzureFlavor: boolean,
55
55
  emitterOutputDir?: string
56
56
  ) {
57
+ if (program.compilerOptions.noEmit || program.hasError()) {
58
+ return;
59
+ }
57
60
  const host: CompilerHost = program.host;
58
61
  const filePath = join(emitterOutputDir ?? "", file.path);
59
62
  const isJson = /\.json$/gi.test(filePath);
@@ -1132,6 +1132,18 @@ function isUnionType(type: Type) {
1132
1132
  return type.kind === "Union";
1133
1133
  }
1134
1134
 
1135
+ export function isObjectOrDictType(schema: Schema) {
1136
+ return (
1137
+ (schema.type === "object" &&
1138
+ (schema as ObjectSchema).properties !== undefined) ||
1139
+ schema.type === "dictionary"
1140
+ );
1141
+ }
1142
+
1143
+ export function isArrayType(schema: Schema) {
1144
+ return schema.type === "array";
1145
+ }
1146
+
1135
1147
  function getSchemaForStdScalar(
1136
1148
  program: Program,
1137
1149
  type: Scalar,
@@ -1331,38 +1343,6 @@ export function getTypeName(schema: Schema, usage?: SchemaContext[]): string {
1331
1343
  return getPriorityName(schema, usage) ?? schema.type ?? "any";
1332
1344
  }
1333
1345
 
1334
- export function getSerializeTypeName(
1335
- program: Program,
1336
- schema: Schema,
1337
- usage?: SchemaContext[]
1338
- ): string {
1339
- const typeName = getTypeName(schema, usage);
1340
- const formattedName = (schema.alias ?? typeName).replace(
1341
- "Date | string",
1342
- "string"
1343
- );
1344
- const canSerialize = isSerializable(schema);
1345
- if (canSerialize) {
1346
- return schema.alias ? typeName : formattedName;
1347
- }
1348
- reportDiagnostic(program, {
1349
- code: "unable-serialized-type",
1350
- format: { type: typeName },
1351
- target: NoTarget
1352
- });
1353
- return "string";
1354
- function isSerializable(type: any) {
1355
- if (type.enum) {
1356
- return type.enum.every((i: any) => {
1357
- return isSerializable(i) || i.type === "null";
1358
- });
1359
- }
1360
- return (
1361
- ["string", "number", "boolean"].includes(type.type) || type.isConstant
1362
- );
1363
- }
1364
- }
1365
-
1366
1346
  export function getImportedModelName(
1367
1347
  schema: Schema,
1368
1348
  usage?: SchemaContext[]
@@ -1448,7 +1428,7 @@ function getEnumStringDescription(type: any) {
1448
1428
  return undefined;
1449
1429
  }
1450
1430
 
1451
- function getBinaryDescripton(type: any) {
1431
+ function getBinaryDescription(type: any) {
1452
1432
  if (type?.typeName?.includes(BINARY_TYPE_UNION)) {
1453
1433
  return `Value may contain any sequence of octets`;
1454
1434
  }
@@ -1480,7 +1460,7 @@ export function getFormattedPropertyDoc(
1480
1460
  const enhancedDocFromType =
1481
1461
  getEnumStringDescription(schemaType) ??
1482
1462
  getDecimalDescription(schemaType) ??
1483
- getBinaryDescripton(schemaType);
1463
+ getBinaryDescription(schemaType);
1484
1464
  if (propertyDoc && enhancedDocFromType) {
1485
1465
  return `${propertyDoc}${sperator}${enhancedDocFromType}`;
1486
1466
  }
@@ -409,13 +409,16 @@ export function extractPagedMetadataNested(
409
409
  }
410
410
 
411
411
  export function getSpecialSerializeInfo(
412
+ dpgContext: SdkContext,
412
413
  paramType: string,
413
414
  paramFormat: string
414
415
  ) {
415
- const hasMultiCollection = getHasMultiCollection(paramType, paramFormat);
416
- const hasPipeCollection = getHasPipeCollection(paramType, paramFormat);
417
- const hasSsvCollection = getHasSsvCollection(paramType, paramFormat);
418
- const hasTsvCollection = getHasTsvCollection(paramType, paramFormat);
416
+ const hasMultiCollection = getHasMultiCollection(
417
+ paramType,
418
+ paramFormat,
419
+ // Include query multi support in compatibility mode
420
+ dpgContext.rlcOptions?.compatibilityQueryMultiFormat ?? false
421
+ );
419
422
  const hasCsvCollection = getHasCsvCollection(paramType, paramFormat);
420
423
  const descriptions = [];
421
424
  const collectionInfo = [];
@@ -423,20 +426,6 @@ export function getSpecialSerializeInfo(
423
426
  descriptions.push("buildMultiCollection");
424
427
  collectionInfo.push("multi");
425
428
  }
426
- if (hasSsvCollection) {
427
- descriptions.push("buildSsvCollection");
428
- collectionInfo.push("ssv");
429
- }
430
-
431
- if (hasTsvCollection) {
432
- descriptions.push("buildTsvCollection");
433
- collectionInfo.push("tsv");
434
- }
435
-
436
- if (hasPipeCollection) {
437
- descriptions.push("buildPipeCollection");
438
- collectionInfo.push("pipe");
439
- }
440
429
 
441
430
  if (hasCsvCollection) {
442
431
  descriptions.push("buildCsvCollection");
@@ -444,18 +433,20 @@ export function getSpecialSerializeInfo(
444
433
  }
445
434
  return {
446
435
  hasMultiCollection,
447
- hasPipeCollection,
448
- hasSsvCollection,
449
- hasTsvCollection,
450
436
  hasCsvCollection,
451
437
  descriptions,
452
438
  collectionInfo
453
439
  };
454
440
  }
455
441
 
456
- function getHasMultiCollection(paramType: string, paramFormat: string) {
442
+ function getHasMultiCollection(
443
+ paramType: string,
444
+ paramFormat: string,
445
+ includeQuery = true
446
+ ) {
457
447
  return (
458
- (paramType === "query" || paramType === "header") && paramFormat === "multi"
448
+ ((includeQuery && paramType === "query") || paramType === "header") &&
449
+ paramFormat === "multi"
459
450
  );
460
451
  }
461
452
  function getHasSsvCollection(paramType: string, paramFormat: string) {
@@ -0,0 +1,234 @@
1
+ import {
2
+ NameType,
3
+ normalizeName,
4
+ Schema,
5
+ SchemaContext
6
+ } from "@azure-tools/rlc-common";
7
+ import { HttpOperationParameter } from "@typespec/http";
8
+ import { getTypeName, isArrayType, isObjectOrDictType } from "./modelUtils.js";
9
+ import { SdkContext } from "./interfaces.js";
10
+ import { reportDiagnostic } from "../lib.js";
11
+ import { NoTarget, Program } from "@typespec/compiler";
12
+
13
+ export interface ParameterSerializationInfo {
14
+ typeName: string;
15
+ wrapperType?: Schema;
16
+ }
17
+
18
+ export function getParameterSerializationInfo(
19
+ dpgContext: SdkContext,
20
+ parameter: HttpOperationParameter,
21
+ valueSchema: Schema,
22
+ operationGroup: string = "",
23
+ operationName: string = ""
24
+ ): ParameterSerializationInfo {
25
+ const schemaContext = [SchemaContext.Input];
26
+ const retVal: ParameterSerializationInfo = buildSerializationInfo(
27
+ getTypeName(valueSchema, schemaContext)
28
+ );
29
+ const prefix = `${operationGroup}_${operationName}_${parameter.name}`;
30
+ switch (parameter.type) {
31
+ case "path": {
32
+ if (parameter.allowReserved === true) {
33
+ const wrapperType = buildAllowReserved(
34
+ normalizeName(`${prefix}_PathParam`, NameType.Interface),
35
+ valueSchema,
36
+ parameter.name
37
+ );
38
+ return buildSerializationInfo(wrapperType);
39
+ }
40
+ return retVal;
41
+ }
42
+ case "query": {
43
+ if (!isArrayType(valueSchema) && !isObjectOrDictType(valueSchema)) {
44
+ // if the value is a primitive type or other types, we will not generate a wrapper type
45
+ return retVal;
46
+ }
47
+ const name = normalizeName(`${prefix}_QueryParam`, NameType.Interface);
48
+ if (parameter.explode === true) {
49
+ if (parameter.format !== undefined && parameter.format !== "multi") {
50
+ reportDiagnostic(dpgContext.program, {
51
+ code: "un-supported-format-cases",
52
+ format: {
53
+ paramName: parameter.name,
54
+ explode: String(parameter.explode),
55
+ format: parameter.format
56
+ },
57
+ target: NoTarget
58
+ });
59
+ }
60
+ let wrapperType: Schema = buildExplodeAndStyle(
61
+ name,
62
+ true,
63
+ "form",
64
+ valueSchema,
65
+ parameter.name
66
+ );
67
+ if (dpgContext.rlcOptions?.compatibilityQueryMultiFormat) {
68
+ wrapperType = buildUnionType([
69
+ wrapperType,
70
+ { type: "string", name: "string" }
71
+ ]);
72
+ }
73
+ return buildSerializationInfo(wrapperType);
74
+ }
75
+
76
+ if (parameter.format === undefined || parameter.format === "csv") {
77
+ let wrapperType: Schema = buildExplodeAndStyle(
78
+ name,
79
+ false,
80
+ "form",
81
+ valueSchema,
82
+ parameter.name
83
+ );
84
+ if (isArrayType(valueSchema)) {
85
+ wrapperType = buildUnionType([valueSchema, wrapperType]);
86
+ }
87
+ return buildSerializationInfo(wrapperType);
88
+ } else if (parameter.format === "ssv" || parameter.format === "pipes") {
89
+ const wrapperType = buildExplodeAndStyle(
90
+ name,
91
+ false,
92
+ parameter.format === "ssv" ? "spaceDelimited" : "pipeDelimited",
93
+ valueSchema,
94
+ parameter.name
95
+ );
96
+ return buildSerializationInfo(wrapperType);
97
+ } else {
98
+ reportDiagnostic(dpgContext.program, {
99
+ code: "un-supported-format-cases",
100
+ format: {
101
+ paramName: parameter.name,
102
+ explode: String(parameter.explode),
103
+ format: parameter.format
104
+ },
105
+ target: NoTarget
106
+ });
107
+ }
108
+ return buildSerializationInfo("string");
109
+ }
110
+ case "header": {
111
+ return buildSerializationInfo(
112
+ getHeaderSerializeTypeName(
113
+ dpgContext.program,
114
+ valueSchema,
115
+ schemaContext
116
+ )
117
+ );
118
+ }
119
+ default:
120
+ return retVal;
121
+ }
122
+ }
123
+
124
+ function buildSerializationInfo(
125
+ typeOrSchema: string | Schema
126
+ ): ParameterSerializationInfo {
127
+ if (typeof typeOrSchema === "string") {
128
+ return {
129
+ typeName: typeOrSchema
130
+ };
131
+ }
132
+ return {
133
+ typeName: getTypeName(typeOrSchema),
134
+ wrapperType: typeOrSchema
135
+ };
136
+ }
137
+
138
+ function getHeaderSerializeTypeName(
139
+ program: Program,
140
+ schema: Schema,
141
+ usage?: SchemaContext[]
142
+ ): string {
143
+ const typeName = getTypeName(schema, usage);
144
+ const formattedName = (schema.alias ?? typeName).replace(
145
+ "Date | string",
146
+ "string"
147
+ );
148
+ const canSerialize = isSerializable(schema);
149
+ if (canSerialize) {
150
+ return schema.alias ? typeName : formattedName;
151
+ }
152
+ reportDiagnostic(program, {
153
+ code: "unable-serialized-type",
154
+ format: { type: typeName },
155
+ target: NoTarget
156
+ });
157
+ return "string";
158
+ function isSerializable(type: any) {
159
+ if (type.enum) {
160
+ return type.enum.every((i: any) => {
161
+ return isSerializable(i) || i.type === "null";
162
+ });
163
+ }
164
+ return (
165
+ ["string", "number", "boolean"].includes(type.type) || type.isConstant
166
+ );
167
+ }
168
+ }
169
+
170
+ function buildAllowReserved(
171
+ typeName: string,
172
+ valueSchema: Schema,
173
+ parameterName: string
174
+ ) {
175
+ return {
176
+ type: "object",
177
+ name: typeName,
178
+ description: `This is the wrapper object for the parameter \`${parameterName}\` with allowReserved set to true.`,
179
+ properties: {
180
+ value: {
181
+ ...valueSchema,
182
+ description: valueSchema.description ?? "Value of the parameter",
183
+ required: true
184
+ },
185
+ allowReserved: {
186
+ type: `true`,
187
+ description: "Whether to allow reserved characters",
188
+ required: true
189
+ }
190
+ }
191
+ };
192
+ }
193
+
194
+ function buildExplodeAndStyle(
195
+ typeName: string,
196
+ explode: boolean,
197
+ style: string,
198
+ valueSchema: Schema,
199
+ parameterName: string
200
+ ) {
201
+ return {
202
+ type: "object",
203
+ name: typeName,
204
+ description: `This is the wrapper object for the parameter \`${parameterName}\` with explode set to ${explode} and style set to ${style}.`,
205
+ properties: {
206
+ value: {
207
+ ...valueSchema,
208
+ description: valueSchema.description ?? "Value of the parameter",
209
+ required: true
210
+ },
211
+ explode: {
212
+ type: `${explode}`,
213
+ description: "Should we explode the value?",
214
+ required: true
215
+ },
216
+ style: {
217
+ type: `"${style}"`,
218
+ description: "Style of the value",
219
+ required: true
220
+ }
221
+ }
222
+ };
223
+ }
224
+
225
+ function buildUnionType(values: Schema[]) {
226
+ return {
227
+ name: "",
228
+ enum: values,
229
+ type: "union",
230
+ typeName: `${values.map((v) => getTypeName(v)).join(" | ")}`,
231
+ required: true,
232
+ description: undefined
233
+ };
234
+ }
@@ -1,6 +1,3 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
-
4
1
  import {
5
2
  Client,
6
3
  createRestError,
@@ -1,6 +1,3 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
-
4
1
  import {
5
2
  PollerLike,
6
3
  OperationState,
@@ -1,6 +1,3 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
-
4
1
  export function buildCsvCollection(items: string[] | number[]): string {
5
2
  return items.join(",");
6
3
  }