@azure-tools/typespec-ts 0.20.0 → 0.21.0-alpha.20240129.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 (56) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
  3. package/dist/src/modular/buildCodeModel.js +52 -31
  4. package/dist/src/modular/buildCodeModel.js.map +1 -1
  5. package/dist/src/modular/buildProjectFiles.js +2 -2
  6. package/dist/src/modular/helpers/operationHelpers.d.ts +3 -2
  7. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  8. package/dist/src/modular/helpers/operationHelpers.js +61 -52
  9. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  10. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
  11. package/dist/src/modular/helpers/typeHelpers.js +2 -0
  12. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  13. package/dist/src/modular/modularCodeModel.d.ts +1 -1
  14. package/dist/src/modular/modularCodeModel.d.ts.map +1 -1
  15. package/dist/src/transform/transformApiVersionInfo.js +22 -22
  16. package/dist/src/transform/transformApiVersionInfo.js.map +1 -1
  17. package/dist/src/transform/transformHelperFunctionDetails.js +50 -50
  18. package/dist/src/transform/transformHelperFunctionDetails.js.map +1 -1
  19. package/dist/src/transform/transformParameters.d.ts.map +1 -1
  20. package/dist/src/transform/transformParameters.js +11 -11
  21. package/dist/src/transform/transformParameters.js.map +1 -1
  22. package/dist/src/transform/transformPaths.d.ts.map +1 -1
  23. package/dist/src/transform/transformPaths.js +11 -11
  24. package/dist/src/transform/transformPaths.js.map +1 -1
  25. package/dist/src/transform/transformResponses.js +11 -11
  26. package/dist/src/transform/transformResponses.js.map +1 -1
  27. package/dist/src/transform/transformSchemas.js +11 -11
  28. package/dist/src/transform/transformSchemas.js.map +1 -1
  29. package/dist/src/transform/transformTelemetryInfo.js +8 -8
  30. package/dist/src/transform/transformTelemetryInfo.js.map +1 -1
  31. package/dist/src/transform/transfromRLCOptions.js +12 -12
  32. package/dist/src/transform/transfromRLCOptions.js.map +1 -1
  33. package/dist/src/utils/namespaceUtils.d.ts +1 -1
  34. package/dist/src/utils/namespaceUtils.d.ts.map +1 -1
  35. package/dist/src/utils/namespaceUtils.js +3 -1
  36. package/dist/src/utils/namespaceUtils.js.map +1 -1
  37. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  38. package/dist/src/utils/operationUtil.js +27 -27
  39. package/dist/src/utils/operationUtil.js.map +1 -1
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +29 -19
  42. package/src/modular/buildCodeModel.ts +75 -30
  43. package/src/modular/buildProjectFiles.ts +2 -2
  44. package/src/modular/helpers/operationHelpers.ts +70 -49
  45. package/src/modular/helpers/typeHelpers.ts +3 -0
  46. package/src/modular/modularCodeModel.ts +2 -1
  47. package/src/transform/transformApiVersionInfo.ts +30 -30
  48. package/src/transform/transformHelperFunctionDetails.ts +51 -51
  49. package/src/transform/transformParameters.ts +11 -10
  50. package/src/transform/transformPaths.ts +11 -10
  51. package/src/transform/transformResponses.ts +10 -10
  52. package/src/transform/transformSchemas.ts +10 -10
  53. package/src/transform/transformTelemetryInfo.ts +10 -10
  54. package/src/transform/transfromRLCOptions.ts +11 -11
  55. package/src/utils/namespaceUtils.ts +6 -2
  56. package/src/utils/operationUtil.ts +25 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-tools/typespec-ts",
3
- "version": "0.20.0",
3
+ "version": "0.21.0-alpha.20240129.1",
4
4
  "description": "An experimental TypeSpec emitter for TypeScript RLC",
5
5
  "main": "dist/src/index.js",
6
6
  "type": "module",
@@ -21,9 +21,9 @@
21
21
  "ts-node": "~10.9.1",
22
22
  "typescript": "~5.2.0",
23
23
  "prettier": "^3.1.0",
24
- "@azure-tools/cadl-ranch-specs": "^0.26.2",
25
- "@azure-tools/cadl-ranch-expect": "^0.9.0",
26
- "@azure-tools/cadl-ranch": "^0.10.0",
24
+ "@azure-tools/cadl-ranch-specs": "^0.28.7",
25
+ "@azure-tools/cadl-ranch-expect": "^0.11.0",
26
+ "@azure-tools/cadl-ranch": "^0.11.2",
27
27
  "chalk": "^4.0.0",
28
28
  "@azure-rest/core-client": "^1.1.6",
29
29
  "@azure/core-auth": "^1.3.2",
@@ -34,20 +34,26 @@
34
34
  "@azure/logger": "^1.0.4",
35
35
  "@azure/core-util": "^1.4.0",
36
36
  "eslint-plugin-require-extensions": "0.1.3",
37
- "@typespec/ts-http-runtime": "1.0.0-alpha.20231129.4"
37
+ "@typespec/ts-http-runtime": "1.0.0-alpha.20231129.4",
38
+ "@azure-tools/typespec-azure-core": "0.37.2",
39
+ "@azure-tools/typespec-client-generator-core": "0.37.0",
40
+ "@typespec/compiler": "0.51.0",
41
+ "@typespec/http": "0.51.0",
42
+ "@typespec/rest": "0.51.0",
43
+ "@typespec/versioning": "0.51.0"
38
44
  },
39
45
  "peerDependencies": {
40
- "@azure-tools/typespec-azure-core": ">=0.36.0 <1.0.0",
41
- "@azure-tools/typespec-client-generator-core": ">=0.36.1 <1.0.0",
42
- "@typespec/compiler": ">=0.50.0 <1.0.0",
43
- "@typespec/http": ">=0.50.0 <1.0.0",
44
- "@typespec/rest": ">=0.50.0 <1.0.0",
45
- "@typespec/versioning": ">=0.50.0 <1.0.0"
46
+ "@azure-tools/typespec-azure-core": ">=0.37.2 <1.0.0",
47
+ "@azure-tools/typespec-client-generator-core": ">=0.37.0 <1.0.0",
48
+ "@typespec/compiler": ">=0.51.0 <1.0.0",
49
+ "@typespec/http": ">=0.51.0 <1.0.0",
50
+ "@typespec/rest": ">=0.51.0 <1.0.0",
51
+ "@typespec/versioning": ">=0.51.0 <1.0.0"
46
52
  },
47
53
  "dependencies": {
48
54
  "prettier": "^3.1.0",
49
55
  "tslib": "^2.3.1",
50
- "@azure-tools/rlc-common": "^0.20.0",
56
+ "@azure-tools/rlc-common": "^0.21.0",
51
57
  "ts-morph": "^15.1.0",
52
58
  "fs-extra": "^11.1.0"
53
59
  },
@@ -78,22 +84,26 @@
78
84
  "check-format": "npm run prettier -- --check",
79
85
  "prettier": "prettier --config ./.prettierrc src/**/*.ts",
80
86
  "check:tree": "node --loader ts-node/esm ./test/commands/check-clean-tree.ts",
81
- "integration-test-ci": "npm run integration-test-ci:rlc && npm run integration-test-ci:modular && npm run integration-test-ci:non-branded",
82
- "integration-test-ci:rlc": "npm run start-test-server:rlc & npm run copy:typespec && npm run generate-and-run:rlc",
83
- "integration-test-ci:modular": "npm run start-test-server:modular & npm run copy:typespec && npm run generate-and-run:modular",
84
- "integration-test-ci:non-branded": "npm run start-test-server & npm run copy:typespec && npm run generate-tsp-only:non-branded && npm run integration-test:alone:non-branded-rlc && npm run integration-test:alone:non-branded-modular && npm run stop-test-server",
87
+ "integration-test-ci": "npm run integration-test-ci:rlc && npm run integration-test-ci:modular && npm run integration-test-ci:non-branded-rlc && npm run integration-test-ci:non-branded-modular",
88
+ "integration-test-ci:rlc": "npm run start-test-server:rlc & npm run copy:typespec && npm run generate-and-run:rlc && npm run stop-test-server",
89
+ "integration-test-ci:modular": "npm run start-test-server:modular & npm run copy:typespec && npm run generate-and-run:modular && npm run stop-test-server",
90
+ "integration-test-ci:non-branded-rlc": "npm run start-test-server:non-branded-rlc & npm run copy:typespec && npm run generate-tsp-only:non-branded-rlc && npm run integration-test:alone:non-branded-rlc && npm run stop-test-server",
91
+ "integration-test-ci:non-branded-modular": "npm run start-test-server:non-branded-modular & npm run copy:typespec && npm run generate-tsp-only:non-branded-modular && npm run integration-test:alone:non-branded-modular && npm run stop-test-server",
85
92
  "start-test-server": "mkdirp -p coverage && npx cadl-ranch serve ./node_modules/@azure-tools/cadl-ranch-specs/http --coverageFile ./coverage/cadl-ranch-coverage-typescript.json",
86
- "start-test-server:rlc": "mkdirp -p coverage && npx cadl-ranch serve ./node_modules/@azure-tools/cadl-ranch-specs/http --coverageFile ./coverage/cadl-ranch-coverage-typescript-rlc.json",
87
- "start-test-server:modular": "mkdirp -p coverage && npx cadl-ranch serve ./node_modules/@azure-tools/cadl-ranch-specs/http --coverageFile ./coverage/cadl-ranch-coverage-typescript-modular.json",
93
+ "start-test-server:rlc": "mkdirp -p coverage && npx cadl-ranch serve ./node_modules/@azure-tools/cadl-ranch-specs/http --coverageFile ./coverage/cadl-ranch-coverage-typescript-rlc-azure.json",
94
+ "start-test-server:modular": "mkdirp -p coverage && npx cadl-ranch serve ./node_modules/@azure-tools/cadl-ranch-specs/http --coverageFile ./coverage/cadl-ranch-coverage-typescript-modular-azure.json",
95
+ "start-test-server:non-branded-rlc": "mkdirp -p coverage && npx cadl-ranch serve ./node_modules/@azure-tools/cadl-ranch-specs/http --coverageFile ./coverage/cadl-ranch-coverage-typescript-rlc-standard.json",
96
+ "start-test-server:non-branded-modular": "mkdirp -p coverage && npx cadl-ranch serve ./node_modules/@azure-tools/cadl-ranch-specs/http --coverageFile ./coverage/cadl-ranch-coverage-typescript-modular-standard.json",
88
97
  "copy:typespec": "rm -rf temp && mkdirp -p temp && cp -r ./node_modules/@azure-tools/cadl-ranch-specs/* ./temp && cp -r ./test/integration/typespec/* ./temp/http",
89
98
  "generate-and-run:rlc": "npm run generate-tsp-only:rlc && npm run integration-test:alone:rlc && npm run stop-test-server",
90
99
  "generate-and-run:modular": "npm run generate-tsp-only:modular && npm run integration-test:alone:modular && npm run stop-test-server",
91
- "generate-tsp-only": "npm run generate-tsp-only:rlc && npm run generate-tsp-only:modular",
100
+ "generate-tsp-only": "npm run generate-tsp-only:rlc && npm run generate-tsp-only:modular && npm run generate-tsp-only:non-branded-rlc && npm run generate-tsp-only:non-branded-modular",
92
101
  "generate-tsp-only:rlc": "node --loader ts-node/esm ./test/commands/gen-cadl-ranch.ts --tag=rlc",
93
102
  "generate-tsp-only:modular": "node --loader ts-node/esm ./test/commands/gen-cadl-ranch.ts --tag=modular",
94
103
  "generate-tsp-only:non-branded": "npm run generate-tsp-only:non-branded-rlc && npm run generate-tsp-only:non-branded-modular",
95
104
  "generate-tsp-only:non-branded-rlc": "node --loader ts-node/esm ./test/commands/gen-cadl-ranch.ts --tag=non-branded-rlc",
96
105
  "generate-tsp-only:non-branded-modular": "node --loader ts-node/esm ./test/commands/gen-cadl-ranch.ts --tag=non-branded-modular",
106
+ "regen-test-baselines": "npm run generate-tsp-only && npm run generate-tsp-only:non-branded",
97
107
  "integration-test:alone": "npm run integration-test:alone:rlc && npm run integration-test:alone:modular",
98
108
  "integration-test:alone:rlc": "cross-env TS_NODE_PROJECT=tsconfig.integration.json mocha -r ts-node/register --experimental-specifier-resolution=node --timeout 4000 ./test/integration/*.spec.ts",
99
109
  "integration-test:alone:modular": "cross-env TS_NODE_PROJECT=tsconfig.integration.json mocha -r ts-node/register --experimental-specifier-resolution=node --timeout 4000 ./test/modularIntegration/*.spec.ts",
@@ -103,10 +103,7 @@ import {
103
103
  import { SdkContext } from "../utils/interfaces.js";
104
104
  import { Project } from "ts-morph";
105
105
  import { buildRuntimeImports } from "@azure-tools/rlc-common";
106
- import {
107
- getModelNamespaceName,
108
- getOperationNamespaceInterfaceName
109
- } from "../utils/namespaceUtils.js";
106
+ import { getModelNamespaceName } from "../utils/namespaceUtils.js";
110
107
  import { reportDiagnostic } from "../lib.js";
111
108
  import { getType as getTypeName } from "./helpers/typeHelpers.js";
112
109
 
@@ -277,6 +274,9 @@ function processModelProperties(
277
274
  if (!isSchemaProperty(context.program, property)) {
278
275
  continue;
279
276
  }
277
+ if (isNeverType(property.type)) {
278
+ continue;
279
+ }
280
280
  if (newValue.properties === undefined || newValue.properties === null) {
281
281
  newValue.properties = [];
282
282
  }
@@ -615,7 +615,8 @@ function emitOperation(
615
615
  context: SdkContext,
616
616
  operation: Operation,
617
617
  operationGroupName: string,
618
- rlcModels: RLCModel
618
+ rlcModels: RLCModel,
619
+ hierarchies: string[]
619
620
  ): HrlcOperation {
620
621
  const isBranded = rlcModels.options?.branded ?? true;
621
622
  // Skip to extract paging and lro information for non-branded clients.
@@ -624,7 +625,8 @@ function emitOperation(
624
625
  context,
625
626
  operation,
626
627
  operationGroupName,
627
- rlcModels
628
+ rlcModels,
629
+ hierarchies
628
630
  );
629
631
  }
630
632
  const lro = isLongRunningOperation(
@@ -655,19 +657,33 @@ function emitOperation(
655
657
  context,
656
658
  operation,
657
659
  operationGroupName,
658
- rlcModels
660
+ rlcModels,
661
+ hierarchies
659
662
  );
660
663
  } else if (paging) {
661
664
  return emitPagingOperation(
662
665
  context,
663
666
  operation,
664
667
  operationGroupName,
665
- rlcModels
668
+ rlcModels,
669
+ hierarchies
666
670
  );
667
671
  } else if (lro) {
668
- return emitLroOperation(context, operation, operationGroupName, rlcModels);
672
+ return emitLroOperation(
673
+ context,
674
+ operation,
675
+ operationGroupName,
676
+ rlcModels,
677
+ hierarchies
678
+ );
669
679
  }
670
- return emitBasicOperation(context, operation, operationGroupName, rlcModels);
680
+ return emitBasicOperation(
681
+ context,
682
+ operation,
683
+ operationGroupName,
684
+ rlcModels,
685
+ hierarchies
686
+ );
671
687
  }
672
688
 
673
689
  function addLroInformation(emittedOperation: HrlcOperation) {
@@ -694,13 +710,15 @@ function emitLroPagingOperation(
694
710
  context: SdkContext,
695
711
  operation: Operation,
696
712
  operationGroupName: string,
697
- rlcModels: RLCModel
713
+ rlcModels: RLCModel,
714
+ hierarchies: string[]
698
715
  ): HrlcOperation {
699
716
  const emittedOperation = emitBasicOperation(
700
717
  context,
701
718
  operation,
702
719
  operationGroupName,
703
- rlcModels
720
+ rlcModels,
721
+ hierarchies
704
722
  );
705
723
  addLroInformation(emittedOperation);
706
724
  addPagingInformation(context.program, operation, emittedOperation);
@@ -712,13 +730,15 @@ function emitLroOperation(
712
730
  context: SdkContext,
713
731
  operation: Operation,
714
732
  operationGroupName: string,
715
- rlcModels: RLCModel
733
+ rlcModels: RLCModel,
734
+ hierarchies: string[]
716
735
  ): HrlcOperation {
717
736
  const emittedOperation = emitBasicOperation(
718
737
  context,
719
738
  operation,
720
739
  operationGroupName,
721
- rlcModels
740
+ rlcModels,
741
+ hierarchies
722
742
  );
723
743
  addLroInformation(emittedOperation);
724
744
  return emittedOperation;
@@ -728,13 +748,15 @@ function emitPagingOperation(
728
748
  context: SdkContext,
729
749
  operation: Operation,
730
750
  operationGroupName: string,
731
- rlcModels: RLCModel
751
+ rlcModels: RLCModel,
752
+ hierarchies: string[]
732
753
  ): HrlcOperation {
733
754
  const emittedOperation = emitBasicOperation(
734
755
  context,
735
756
  operation,
736
757
  operationGroupName,
737
- rlcModels
758
+ rlcModels,
759
+ hierarchies
738
760
  );
739
761
  addPagingInformation(context.program, operation, emittedOperation);
740
762
  return emittedOperation;
@@ -744,7 +766,8 @@ function emitBasicOperation(
744
766
  context: SdkContext,
745
767
  operation: Operation,
746
768
  operationGroupName: string,
747
- rlcModels: RLCModel
769
+ rlcModels: RLCModel,
770
+ hierarchies: string[]
748
771
  ): HrlcOperation {
749
772
  // Set up parameters for operation
750
773
  const parameters: any[] = [];
@@ -782,9 +805,7 @@ function emitBasicOperation(
782
805
  });
783
806
 
784
807
  const namespaceHierarchies =
785
- context.rlcOptions?.hierarchyClient === true
786
- ? getOperationNamespaceInterfaceName(context, operation)
787
- : [];
808
+ context.rlcOptions?.hierarchyClient === true ? hierarchies : [];
788
809
 
789
810
  if (
790
811
  namespaceHierarchies.length === 0 &&
@@ -1167,6 +1188,16 @@ function emitStdScalar(
1167
1188
  return { type: "duration", format: newScalar.format };
1168
1189
  case "numeric":
1169
1190
  return {}; // Waiting on design for more precise type https://github.com/microsoft/cadl/issues/1260
1191
+ case "decimal":
1192
+ case "decimal128":
1193
+ reportDiagnostic(program, {
1194
+ code: "decimal-to-number",
1195
+ format: {
1196
+ propertyName: newScalar?.name ?? ""
1197
+ },
1198
+ target: newScalar ?? scalar
1199
+ });
1200
+ return { type: "integer", format: newScalar.format };
1170
1201
  default:
1171
1202
  return {};
1172
1203
  }
@@ -1479,26 +1510,40 @@ function emitOperationGroups(
1479
1510
  string,
1480
1511
  OperationGroup
1481
1512
  >();
1482
- for (const operationGroup of listOperationGroups(context, client)) {
1513
+ const clientOperations: HrlcOperation[] = [];
1514
+ for (const operation of listOperationsInOperationGroup(context, client)) {
1515
+ clientOperations.push(emitOperation(context, operation, "", rlcModels, []));
1516
+ }
1517
+ if (clientOperations.length > 0) {
1518
+ addHierarchyOperationGroup(clientOperations, groupMapping);
1519
+ }
1520
+ for (const operationGroup of listOperationGroups(context, client, true)) {
1483
1521
  const operations: HrlcOperation[] = [];
1484
- const name = operationGroup.type.name;
1522
+ const name =
1523
+ context.rlcOptions?.hierarchyClient ||
1524
+ context.rlcOptions?.enableOperationGroup
1525
+ ? operationGroup.type.name
1526
+ : "";
1527
+ const hierarchies =
1528
+ context.rlcOptions?.hierarchyClient ||
1529
+ context.rlcOptions?.enableOperationGroup
1530
+ ? operationGroup.groupPath.split(".")
1531
+ : [];
1532
+ if (hierarchies[0]?.endsWith("Client")) {
1533
+ hierarchies.shift();
1534
+ }
1485
1535
  for (const operation of listOperationsInOperationGroup(
1486
1536
  context,
1487
1537
  operationGroup
1488
1538
  )) {
1489
- operations.push(emitOperation(context, operation, name, rlcModels));
1539
+ operations.push(
1540
+ emitOperation(context, operation, name, rlcModels, hierarchies)
1541
+ );
1490
1542
  }
1491
1543
  if (operations.length > 0) {
1492
1544
  addHierarchyOperationGroup(operations, groupMapping);
1493
1545
  }
1494
1546
  }
1495
- const clientOperations: HrlcOperation[] = [];
1496
- for (const operation of listOperationsInOperationGroup(context, client)) {
1497
- clientOperations.push(emitOperation(context, operation, "", rlcModels));
1498
- }
1499
- if (clientOperations.length > 0) {
1500
- addHierarchyOperationGroup(clientOperations, groupMapping);
1501
- }
1502
1547
 
1503
1548
  groupMapping.forEach((value) => {
1504
1549
  operationGroups.push(value);
@@ -223,7 +223,7 @@ function emitNonBrandedPackage(codeModel: ModularCodeModel) {
223
223
  prettier: "^3.1.0",
224
224
  rimraf: "^5.0.0",
225
225
  "source-map-support": "^0.5.9",
226
- typescript: "~5.2.0",
226
+ typescript: "~5.3.3",
227
227
  "@rollup/plugin-commonjs": "^24.0.0",
228
228
  "@rollup/plugin-json": "^6.0.0",
229
229
  "@rollup/plugin-multi-entry": "^6.0.0",
@@ -329,7 +329,7 @@ function emitBrandedPackage(
329
329
  prettier: "^3.1.0",
330
330
  rimraf: "^5.0.0",
331
331
  "source-map-support": "^0.5.9",
332
- typescript: "~5.2.0"
332
+ typescript: "~5.3.3"
333
333
  }
334
334
  } as any;
335
335
 
@@ -157,20 +157,21 @@ export function getDeserializePrivateFunction(
157
157
  }
158
158
  }
159
159
 
160
+ const allParents = getAllAncestors(response.type);
161
+ const properties = getAllProperties(response.type, allParents) ?? [];
162
+
160
163
  if (
161
164
  response?.type?.type === "any" ||
162
165
  response.isBinaryPayload ||
163
166
  response?.type?.aliasType
164
167
  ) {
165
168
  statements.push(`return result.body`);
166
- } else if (getAllProperties(response?.type).length > 0) {
169
+ } else if (properties.length > 0) {
167
170
  statements.push(
168
171
  `return {`,
169
- getResponseMapping(
170
- getAllProperties(response.type) ?? [],
171
- "result.body",
172
- runtimeImports
173
- ).join(","),
172
+ getResponseMapping(response.type, "result.body", runtimeImports).join(
173
+ ","
174
+ ),
174
175
  `}`
175
176
  );
176
177
  } else if (returnType.type === "void") {
@@ -182,6 +183,7 @@ export function getDeserializePrivateFunction(
182
183
  "result.body",
183
184
  runtimeImports,
184
185
  response.type.nullable !== undefined ? !response.type.nullable : false,
186
+ [response.type],
185
187
  response.type.format
186
188
  )}`
187
189
  );
@@ -449,11 +451,14 @@ function buildBodyParameter(
449
451
  const bodyParts: string[] = getRequestModelMapping(
450
452
  bodyParameter.type,
451
453
  bodyParameter.clientName,
452
- runtimeImports
454
+ runtimeImports,
455
+ [bodyParameter.type]
453
456
  );
454
457
 
455
458
  if (bodyParameter && bodyParts.length > 0) {
456
459
  return `\nbody: {${bodyParts.join(",\n")}},`;
460
+ } else if (bodyParameter && bodyParts.length === 0) {
461
+ return `\nbody: ${bodyParameter.clientName},`;
457
462
  }
458
463
  } else if (
459
464
  bodyParameter.type.type === "model" &&
@@ -470,7 +475,8 @@ function buildBodyParameter(
470
475
  const bodyParts = getRequestModelMapping(
471
476
  bodyParameter.type.elementType,
472
477
  "p",
473
- runtimeImports
478
+ runtimeImports,
479
+ [bodyParameter.type.elementType]
474
480
  );
475
481
  return `\nbody: (${bodyParameter.clientName} ?? []).map((p) => { return {
476
482
  ${bodyParts.join(", ")}
@@ -553,6 +559,7 @@ function getCollectionFormat(param: Parameter, runtimeImports: RuntimeImports) {
553
559
  param.clientName,
554
560
  runtimeImports,
555
561
  true,
562
+ [param.type],
556
563
  param.format
557
564
  )}${additionalParam})`;
558
565
  }
@@ -563,6 +570,7 @@ function getCollectionFormat(param: Parameter, runtimeImports: RuntimeImports) {
563
570
  "options?." + param.clientName,
564
571
  runtimeImports,
565
572
  false,
573
+ [param.type],
566
574
  param.format
567
575
  )}${additionalParam}): undefined`;
568
576
  }
@@ -602,7 +610,8 @@ function getRequired(param: RequiredType, runtimeImports: RuntimeImports) {
602
610
  return `"${param.restApiName}": {${getRequestModelMapping(
603
611
  param.type,
604
612
  param.clientName,
605
- runtimeImports
613
+ runtimeImports,
614
+ [param.type]
606
615
  ).join(",")}}`;
607
616
  }
608
617
  return `"${param.restApiName}": ${serializeRequestValue(
@@ -610,6 +619,7 @@ function getRequired(param: RequiredType, runtimeImports: RuntimeImports) {
610
619
  param.clientName,
611
620
  runtimeImports,
612
621
  true,
622
+ [param.type],
613
623
  param.format === undefined &&
614
624
  (param as Parameter).location === "header" &&
615
625
  param.type.type === "datetime"
@@ -654,7 +664,8 @@ function getOptional(param: OptionalType, runtimeImports: RuntimeImports) {
654
664
  return `"${param.restApiName}": {${getRequestModelMapping(
655
665
  param.type,
656
666
  "options?." + param.clientName + "?",
657
- runtimeImports
667
+ runtimeImports,
668
+ [param.type]
658
669
  ).join(", ")}}`;
659
670
  }
660
671
  return `"${param.restApiName}": ${serializeRequestValue(
@@ -662,6 +673,7 @@ function getOptional(param: OptionalType, runtimeImports: RuntimeImports) {
662
673
  `options?.${param.clientName}`,
663
674
  runtimeImports,
664
675
  false,
676
+ [param.type],
665
677
  param.format === undefined &&
666
678
  (param as Parameter).location === "header" &&
667
679
  param.type.type === "datetime"
@@ -729,13 +741,16 @@ function getNullableCheck(name: string, type: Type) {
729
741
  function getRequestModelMapping(
730
742
  modelPropertyType: Type,
731
743
  propertyPath: string = "body",
732
- runtimeImports: RuntimeImports
744
+ runtimeImports: RuntimeImports,
745
+ typeStack: Type[] = []
733
746
  ) {
734
- if (getAllProperties(modelPropertyType).length <= 0) {
747
+ const props: string[] = [];
748
+ const allParents = getAllAncestors(modelPropertyType);
749
+ const properties: Property[] =
750
+ getAllProperties(modelPropertyType, allParents) ?? [];
751
+ if (properties.length <= 0) {
735
752
  return [];
736
753
  }
737
- const props: string[] = [];
738
- const properties: Property[] = getAllProperties(modelPropertyType) ?? [];
739
754
  for (const property of properties) {
740
755
  if (property.readonly) {
741
756
  continue;
@@ -750,12 +765,7 @@ function getRequestModelMapping(
750
765
  )} ${
751
766
  !property.optional ? "" : `!${propertyFullName} ? undefined :`
752
767
  } ${propertyFullName}`;
753
- } else if (
754
- (property.restApiName === "message" ||
755
- property.restApiName === "messages") &&
756
- (property.type.name === "ChatMessage" ||
757
- property.type.elementType?.name === "ChatMessage")
758
- ) {
768
+ } else if (typeStack.includes(property.type)) {
759
769
  definition = `"${property.restApiName}": ${
760
770
  !property.optional
761
771
  ? `${propertyFullName} as any`
@@ -772,17 +782,13 @@ function getRequestModelMapping(
772
782
  `${propertyPath}.${property.clientName}${
773
783
  property.optional ? "?" : ""
774
784
  }`,
775
- runtimeImports
785
+ runtimeImports,
786
+ [...typeStack, property.type]
776
787
  )}}`;
777
788
  }
778
789
 
779
790
  props.push(definition);
780
- } else if (
781
- (property.restApiName === "message" ||
782
- property.restApiName === "messages") &&
783
- (property.type.name === "ChatMessage" ||
784
- property.type.elementType?.name === "ChatMessage")
785
- ) {
791
+ } else if (typeStack.includes(property.type)) {
786
792
  const definition = `"${property.restApiName}": ${
787
793
  !property.optional
788
794
  ? `${propertyFullName} as any`
@@ -800,6 +806,7 @@ function getRequestModelMapping(
800
806
  clientValue,
801
807
  runtimeImports,
802
808
  !property.optional,
809
+ [...typeStack, property.type],
803
810
  property.format
804
811
  )}`
805
812
  );
@@ -814,10 +821,16 @@ function getRequestModelMapping(
814
821
  * extracting properties from body and headers and building the HLC response object
815
822
  */
816
823
  export function getResponseMapping(
817
- properties: Property[],
824
+ type: Type,
818
825
  propertyPath: string = "result.body",
819
- runtimeImports: RuntimeImports
826
+ runtimeImports: RuntimeImports,
827
+ typeStack: Type[] = []
820
828
  ) {
829
+ const allParents = getAllAncestors(type);
830
+ const properties = getAllProperties(type, allParents) ?? [];
831
+ if (typeStack.length <= 0) {
832
+ typeStack.push(type);
833
+ }
821
834
  const props: string[] = [];
822
835
  for (const property of properties) {
823
836
  // TODO: Do we need to also add headers in the result type?
@@ -831,12 +844,7 @@ export function getResponseMapping(
831
844
  )} ${
832
845
  !property.optional ? "" : `!${propertyFullName} ? undefined :`
833
846
  } ${propertyFullName}`;
834
- } else if (
835
- (property.restApiName === "message" ||
836
- property.restApiName === "messages") &&
837
- (property.type.name === "ChatMessage" ||
838
- property.type.elementType?.name === "ChatMessage")
839
- ) {
847
+ } else if (typeStack.includes(property.type)) {
840
848
  definition = `"${property.clientName}": ${
841
849
  !property.optional
842
850
  ? `${propertyFullName} as any`
@@ -849,11 +857,12 @@ export function getResponseMapping(
849
857
  )} ${
850
858
  !property.optional ? "" : `!${propertyFullName} ? undefined :`
851
859
  } {${getResponseMapping(
852
- getAllProperties(property.type) ?? [],
860
+ property.type,
853
861
  `${propertyPath}.${property.restApiName}${
854
862
  property.optional ? "?" : ""
855
863
  }`,
856
- runtimeImports
864
+ runtimeImports,
865
+ [...typeStack, property.type]
857
866
  )}}`;
858
867
  }
859
868
 
@@ -863,12 +872,7 @@ export function getResponseMapping(
863
872
  const restValue = `${
864
873
  propertyPath ? `${propertyPath}${dot}` : `${dot}`
865
874
  }["${property.restApiName}"]`;
866
- if (
867
- (property.restApiName === "message" ||
868
- property.restApiName === "messages") &&
869
- (property.type.name === "ChatMessage" ||
870
- property.type.elementType?.name === "ChatMessage")
871
- ) {
875
+ if (typeStack.includes(property.type)) {
872
876
  props.push(
873
877
  `"${property.clientName}": ${
874
878
  !property.optional
@@ -883,6 +887,7 @@ export function getResponseMapping(
883
887
  restValue,
884
888
  runtimeImports,
885
889
  property.optional !== undefined ? !property.optional : false,
890
+ [...typeStack, property.type],
886
891
  property.format
887
892
  )}`
888
893
  );
@@ -890,6 +895,7 @@ export function getResponseMapping(
890
895
  }
891
896
  }
892
897
 
898
+ typeStack.pop();
893
899
  return props;
894
900
  }
895
901
 
@@ -903,6 +909,7 @@ function deserializeResponseValue(
903
909
  restValue: string,
904
910
  runtimeImports: RuntimeImports,
905
911
  required: boolean,
912
+ typeStack: Type[] = [],
906
913
  format?: string
907
914
  ): string {
908
915
  switch (type.type) {
@@ -922,9 +929,10 @@ function deserializeResponseValue(
922
929
  if (type.elementType?.type === "model") {
923
930
  if (!type.elementType.aliasType) {
924
931
  return `${prefix}.map(p => ({${getResponseMapping(
925
- getAllProperties(type.elementType) ?? [],
932
+ type.elementType,
926
933
  "p",
927
- runtimeImports
934
+ runtimeImports,
935
+ [...typeStack, type.elementType]
928
936
  )}}))`;
929
937
  }
930
938
  return `${prefix}`;
@@ -936,7 +944,8 @@ function deserializeResponseValue(
936
944
  type.elementType!,
937
945
  "p",
938
946
  runtimeImports,
939
- required,
947
+ true,
948
+ [...typeStack, type.elementType!],
940
949
  type.elementType?.format
941
950
  )})`;
942
951
  } else {
@@ -966,6 +975,7 @@ function serializeRequestValue(
966
975
  clientValue: string,
967
976
  runtimeImports: RuntimeImports,
968
977
  required: boolean,
978
+ typeStack: Type[] = [],
969
979
  format?: string
970
980
  ): string {
971
981
  switch (type.type) {
@@ -993,7 +1003,8 @@ function serializeRequestValue(
993
1003
  return `${prefix}.map(p => ({${getRequestModelMapping(
994
1004
  type.elementType,
995
1005
  "p",
996
- runtimeImports
1006
+ runtimeImports,
1007
+ [...typeStack, type.elementType]
997
1008
  )}}))`;
998
1009
  } else if (
999
1010
  needsDeserialize(type.elementType) &&
@@ -1004,6 +1015,7 @@ function serializeRequestValue(
1004
1015
  "p",
1005
1016
  runtimeImports,
1006
1017
  required,
1018
+ [...typeStack, type.elementType!],
1007
1019
  type.elementType?.format
1008
1020
  )})`;
1009
1021
  } else {
@@ -1070,12 +1082,12 @@ export function isPagingOperation(op: Operation): boolean {
1070
1082
  return op.discriminator === "paging" || op.discriminator === "lropaging";
1071
1083
  }
1072
1084
 
1073
- function getAllProperties(type: Type): Property[] {
1085
+ export function getAllProperties(type: Type, parents?: Type[]): Property[] {
1074
1086
  const propertiesMap: Map<string, Property> = new Map();
1075
1087
  if (!type) {
1076
1088
  return [];
1077
1089
  }
1078
- type.parents?.forEach((p) => {
1090
+ parents?.forEach((p) => {
1079
1091
  getAllProperties(p).forEach((prop) => {
1080
1092
  propertiesMap.set(prop.clientName, prop);
1081
1093
  });
@@ -1085,3 +1097,12 @@ function getAllProperties(type: Type): Property[] {
1085
1097
  });
1086
1098
  return [...propertiesMap.values()];
1087
1099
  }
1100
+
1101
+ function getAllAncestors(type: Type): Type[] {
1102
+ const ancestors: Type[] = [];
1103
+ type?.parents?.forEach((p) => {
1104
+ ancestors.push(p);
1105
+ ancestors.push(...getAllAncestors(p));
1106
+ });
1107
+ return ancestors;
1108
+ }
@@ -101,6 +101,9 @@ export function getType(type: Type, format?: string): TypeMetadata {
101
101
  case "dict":
102
102
  return handleDictType(type);
103
103
 
104
+ case "never":
105
+ return { name: "never", nullable: type.nullable };
106
+
104
107
  default:
105
108
  throw new Error(`Unsupported type ${type.type}`);
106
109
  }
@@ -83,7 +83,8 @@ export interface Type {
83
83
  | "dict"
84
84
  | "combined"
85
85
  | "any"
86
- | "unknown";
86
+ | "unknown"
87
+ | "never";
87
88
  policy?: Policy;
88
89
  apiVersions?: any[];
89
90
  clientDefaultValue?: any;