@azure-tools/typespec-ts 0.17.0-alpha.20231010.1 → 0.17.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 (45) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +3 -1
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
  6. package/dist/src/modular/buildClassicalClient.js +16 -0
  7. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  8. package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
  9. package/dist/src/modular/buildCodeModel.js +9 -0
  10. package/dist/src/modular/buildCodeModel.js.map +1 -1
  11. package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
  12. package/dist/src/modular/buildProjectFiles.js +10 -5
  13. package/dist/src/modular/buildProjectFiles.js.map +1 -1
  14. package/dist/src/modular/emitModels.d.ts.map +1 -1
  15. package/dist/src/modular/emitModels.js +2 -1
  16. package/dist/src/modular/emitModels.js.map +1 -1
  17. package/dist/src/modular/helpers/typeHelpers.js +7 -7
  18. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  19. package/dist/src/transform/transform.d.ts.map +1 -1
  20. package/dist/src/transform/transform.js +5 -1
  21. package/dist/src/transform/transform.js.map +1 -1
  22. package/dist/src/transform/transformParameters.js +2 -1
  23. package/dist/src/transform/transformParameters.js.map +1 -1
  24. package/dist/src/transform/transformSchemas.d.ts.map +1 -1
  25. package/dist/src/transform/transformSchemas.js +13 -11
  26. package/dist/src/transform/transformSchemas.js.map +1 -1
  27. package/dist/src/utils/emitUtil.d.ts.map +1 -1
  28. package/dist/src/utils/emitUtil.js +9 -3
  29. package/dist/src/utils/emitUtil.js.map +1 -1
  30. package/dist/src/utils/modelUtils.d.ts.map +1 -1
  31. package/dist/src/utils/modelUtils.js +135 -129
  32. package/dist/src/utils/modelUtils.js.map +1 -1
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +6 -5
  35. package/src/index.ts +8 -1
  36. package/src/modular/buildClassicalClient.ts +17 -0
  37. package/src/modular/buildCodeModel.ts +8 -0
  38. package/src/modular/buildProjectFiles.ts +11 -5
  39. package/src/modular/emitModels.ts +5 -1
  40. package/src/modular/helpers/typeHelpers.ts +1 -1
  41. package/src/transform/transform.ts +8 -2
  42. package/src/transform/transformParameters.ts +2 -1
  43. package/src/transform/transformSchemas.ts +7 -3
  44. package/src/utils/emitUtil.ts +9 -3
  45. package/src/utils/modelUtils.ts +148 -143
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-tools/typespec-ts",
3
- "version": "0.17.0-alpha.20231010.1",
3
+ "version": "0.17.1",
4
4
  "description": "An experimental TypeSpec emitter for TypeScript RLC",
5
5
  "main": "dist/src/index.js",
6
6
  "type": "module",
@@ -33,7 +33,8 @@
33
33
  "@azure/core-lro": "^2.5.4",
34
34
  "@azure/core-rest-pipeline": "^1.12.0",
35
35
  "@azure/logger": "^1.0.4",
36
- "@azure/core-util": "^1.4.0"
36
+ "@azure/core-util": "^1.4.0",
37
+ "eslint-plugin-require-extensions": "0.1.3"
37
38
  },
38
39
  "peerDependencies": {
39
40
  "@azure-tools/typespec-azure-core": ">=0.34.0 <1.0.0",
@@ -46,7 +47,7 @@
46
47
  "dependencies": {
47
48
  "prettier": "^2.6.1",
48
49
  "tslib": "^2.3.1",
49
- "@azure-tools/rlc-common": "^0.17.0",
50
+ "@azure-tools/rlc-common": "^0.17.1",
50
51
  "ts-morph": "^15.1.0",
51
52
  "fs-extra": "^11.1.0"
52
53
  },
@@ -90,8 +91,8 @@
90
91
  "generate-tsp-only:rlc": "ts-node ./test/commands/gen-cadl-ranch.ts --tag=rlc",
91
92
  "generate-tsp-only:modular": "ts-node ./test/commands/gen-cadl-ranch.ts --tag=modular",
92
93
  "integration-test:alone": "npm run integration-test:alone:rlc && npm run integration-test:alone:modular",
93
- "integration-test:alone:rlc": "cross-env TS_NODE_PROJECT=tsconfig.test.json mocha -r ts-node/register --experimental-specifier-resolution=node --timeout 4000 ./test/integration/*.spec.ts",
94
- "integration-test:alone:modular": "cross-env TS_NODE_PROJECT=tsconfig.test.json mocha -r ts-node/register --experimental-specifier-resolution=node --timeout 4000 ./test/modularIntegration/*.spec.ts",
94
+ "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",
95
+ "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",
95
96
  "stop-test-server": "npx cadl-ranch server stop",
96
97
  "unit-test": "npm run unit-test:rlc && npm run unit-test:modular",
97
98
  "unit-test:rlc": "cross-env TS_NODE_PROJECT=tsconfig.json mocha -r ts-node/register --experimental-specifier-resolution=node --experimental-modules=true --timeout 4000 './test/unit/**/*.spec.ts'",
package/src/index.ts CHANGED
@@ -29,7 +29,8 @@ import {
29
29
  buildLogger,
30
30
  RLCOptions,
31
31
  hasUnexpectedHelper,
32
- RLCModel
32
+ RLCModel,
33
+ buildSamples
33
34
  } from "@azure-tools/rlc-common";
34
35
  import { transformRLCModel } from "./transform/transform.js";
35
36
  import { emitContentByBuilder, emitModels } from "./utils/emitUtil.js";
@@ -137,6 +138,12 @@ export async function $onEmit(context: EmitContext) {
137
138
  await emitContentByBuilder(program, buildPaginateHelper, rlcModels);
138
139
  await emitContentByBuilder(program, buildPollingHelper, rlcModels);
139
140
  await emitContentByBuilder(program, buildSerializeHelper, rlcModels);
141
+ await emitContentByBuilder(
142
+ program,
143
+ buildSamples,
144
+ rlcModels,
145
+ dpgContext.generationPathDetail?.metadataDir
146
+ );
140
147
  }
141
148
  }
142
149
 
@@ -62,6 +62,15 @@ export function buildClassicalClient(
62
62
  });
63
63
  }
64
64
 
65
+ // Add the pipeline member. This will be the pipeline from /api
66
+ clientClass.addProperty({
67
+ name: "pipeline",
68
+ type: "Pipeline",
69
+ scope: Scope.Public,
70
+ isReadonly: true,
71
+ docs: ["The pipeline used by this client to make requests"]
72
+ });
73
+
65
74
  // TODO: We may need to generate constructor overloads at some point. Here we'd do that.
66
75
  const constructor = clientClass.addConstructor({
67
76
  docs: getDocsFromDescription(description),
@@ -72,7 +81,9 @@ export function buildClassicalClient(
72
81
  .map((p) => p.name)
73
82
  .join(",")})`
74
83
  ]);
84
+ constructor.addStatements(`this.pipeline = this._client.pipeline`);
75
85
  importCredential(clientFile);
86
+ importPipeline(clientFile);
76
87
  importAllModels(clientFile, srcPath, subfolder);
77
88
  buildClientOperationGroups(client, clientClass, subfolder);
78
89
  importAllApis(clientFile, srcPath, subfolder);
@@ -143,6 +154,12 @@ function importAllModels(
143
154
  });
144
155
  }
145
156
 
157
+ function importPipeline(clientSourceFile: SourceFile): void {
158
+ clientSourceFile.addImportDeclaration({
159
+ moduleSpecifier: "@azure/core-rest-pipeline",
160
+ namedImports: ["Pipeline"]
161
+ });
162
+ }
146
163
  function buildClientOperationGroups(
147
164
  client: Client,
148
165
  clientClass: ClassDeclaration,
@@ -1052,6 +1052,14 @@ function emitCredential(auth: HttpAuth): Record<string, any> {
1052
1052
  key: auth.name
1053
1053
  }
1054
1054
  };
1055
+ } else if (auth.type === "http") {
1056
+ credential_type = {
1057
+ type: "Key",
1058
+ policy: {
1059
+ type: "AzureKeyCredentialPolicy",
1060
+ key: "Authorization"
1061
+ }
1062
+ };
1055
1063
  }
1056
1064
  return credential_type;
1057
1065
  }
@@ -206,10 +206,10 @@ export function emitPackage(
206
206
  if (generateTest) {
207
207
  packageInfo.module = `./dist-esm/src/index.js`;
208
208
  packageInfo.devDependencies["@azure-tools/test-credential"] = "^1.0.0";
209
- packageInfo.devDependencies["@azure/identity"] = "^2.0.1";
209
+ packageInfo.devDependencies["@azure/identity"] = "^3.3.0";
210
210
  packageInfo.devDependencies["@azure-tools/test-recorder"] = "^3.0.0";
211
- packageInfo.devDependencies["mocha"] = "^7.1.1";
212
- packageInfo.devDependencies["@types/mocha"] = "^7.0.2";
211
+ packageInfo.devDependencies["mocha"] = "^10.0.0";
212
+ packageInfo.devDependencies["@types/mocha"] = "^10.0.0";
213
213
  packageInfo.devDependencies["mocha-junit-reporter"] = "^1.18.0";
214
214
  packageInfo.devDependencies["cross-env"] = "^7.0.2";
215
215
  packageInfo.devDependencies["@types/chai"] = "^4.2.8";
@@ -242,12 +242,12 @@ export function emitPackage(
242
242
  packageInfo.scripts["unit-test"] =
243
243
  "npm run unit-test:node && npm run unit-test:browser";
244
244
  packageInfo.scripts["unit-test:node"] =
245
- 'mocha -r esm --require ts-node/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 1200000 --full-trace "test/{,!(browser)/**/}*.spec.ts"';
245
+ 'mocha --full-trace "test/{,!(browser)/**/}*.spec.ts"';
246
246
  packageInfo.scripts["unit-test:browser"] = "karma start --single-run";
247
247
  packageInfo.scripts["integration-test:browser"] =
248
248
  "karma start --single-run";
249
249
  packageInfo.scripts["integration-test:node"] =
250
- 'nyc mocha -r esm --require source-map-support/register --reporter ../../../common/tools/mocha-multi-reporter.js --timeout 5000000 --full-trace "dist-esm/test/{,!(browser)/**/}*.spec.js"';
250
+ 'nyc mocha --require source-map-support/register.js --timeout 5000000 --full-trace "dist-esm/test/{,!(browser)/**/}*.spec.js"';
251
251
  packageInfo.scripts["integration-test"] =
252
252
  "npm run integration-test:node && npm run integration-test:browser";
253
253
  if (azureSdkForJs) {
@@ -265,6 +265,12 @@ export function emitPackage(
265
265
  "./dist-esm/test/public/utils/env.js":
266
266
  "./dist-esm/test/public/utils/env.browser.js"
267
267
  };
268
+
269
+ packageInfo["mocha"] = {
270
+ extension: ["ts"],
271
+ timeout: "1200000",
272
+ loader: "ts-node/esm"
273
+ };
268
274
  }
269
275
 
270
276
  if (generateSample) {
@@ -139,7 +139,11 @@ export function buildModelsOptions(
139
139
  client: Client
140
140
  ) {
141
141
  const modelOptionsFile = codeModel.project.createSourceFile(
142
- `${codeModel.modularOptions.sourceRoot}/${client.subfolder}/models/options.ts`,
142
+ path.join(
143
+ codeModel.modularOptions.sourceRoot,
144
+ client.subfolder ?? "",
145
+ `models/options.ts`
146
+ ),
143
147
  undefined,
144
148
  {
145
149
  overwrite: true
@@ -38,7 +38,7 @@ export function getType(type: Type, format?: string): TypeMetadata {
38
38
  case "boolean":
39
39
  return { name: getNullableType(type.type, type) };
40
40
  case "constant": {
41
- let typeName: string = type.value ?? "undefined";
41
+ let typeName: string = type.value?.toString() ?? "undefined";
42
42
  if (type.valueType?.type === "string") {
43
43
  typeName = type.value ? `"${type.value}"` : "undefined";
44
44
  }
@@ -35,6 +35,7 @@ import { transformApiVersionInfo } from "./transformApiVersionInfo.js";
35
35
  import { getClientLroOverload } from "../utils/operationUtil.js";
36
36
  import { transformTelemetryInfo } from "./transformTelemetryInfo.js";
37
37
  import { SdkContext } from "../utils/interfaces.js";
38
+ import { transformSampleGroups } from "@azure-tools/rlc-common";
38
39
 
39
40
  export async function transformRLCModel(
40
41
  client: SdkClient,
@@ -60,7 +61,6 @@ export async function transformRLCModel(
60
61
  const importSet = new Map<ImportKind, Set<string>>();
61
62
  const paths: Paths = transformPaths(program, client, dpgContext);
62
63
  const schemas: Schema[] = transformSchemas(program, client, dpgContext);
63
-
64
64
  const responses: OperationResponse[] = transformToResponseTypes(
65
65
  importSet,
66
66
  client,
@@ -77,7 +77,7 @@ export async function transformRLCModel(
77
77
  const urlInfo = transformUrlInfo(dpgContext);
78
78
  const apiVersionInfo = transformApiVersionInfo(client, dpgContext, urlInfo);
79
79
  const telemetryOptions = transformTelemetryInfo(dpgContext, client);
80
- return {
80
+ const model: RLCModel = {
81
81
  srcPath,
82
82
  libraryName,
83
83
  paths,
@@ -91,6 +91,12 @@ export async function transformRLCModel(
91
91
  urlInfo,
92
92
  telemetryOptions
93
93
  };
94
+ model.sampleGroups = transformSampleGroups(
95
+ model,
96
+ options?.generateSample ===
97
+ true /* Enable mock sample content if generateSample === true */
98
+ );
99
+ return model;
94
100
  }
95
101
 
96
102
  export function transformUrlInfo(dpgContext: SdkContext): UrlInfo | undefined {
@@ -304,7 +304,8 @@ function transformNormalBody(
304
304
  name: "body",
305
305
  type: overrideType ?? type,
306
306
  required: parameters?.bodyParameter?.optional === false,
307
- description: descriptions.join("\n\n")
307
+ description: descriptions.join("\n\n"),
308
+ oriSchema: schema
308
309
  }
309
310
  ]
310
311
  };
@@ -122,8 +122,12 @@ export function transformSchemas(
122
122
 
123
123
  setModelMap(model, context);
124
124
  const indexer = (model as Model).indexer;
125
- if (indexer?.value && !program.stateMap(modelKey).get(indexer?.value)) {
126
- setModelMap(indexer.value, context);
125
+ if (
126
+ indexer?.value &&
127
+ (!program.stateMap(modelKey).get(indexer?.value) ||
128
+ !program.stateMap(modelKey).get(indexer?.value)?.includes(context))
129
+ ) {
130
+ getGeneratedModels(indexer.value, context);
127
131
  }
128
132
  for (const prop of model.properties) {
129
133
  if (
@@ -131,7 +135,7 @@ export function transformSchemas(
131
135
  (!program.stateMap(modelKey).get(prop[1].type) ||
132
136
  !program.stateMap(modelKey).get(prop[1].type)?.includes(context))
133
137
  ) {
134
- if (prop[1].type.name === "Error") {
138
+ if (isAzureCoreErrorType(prop[1].type)) {
135
139
  continue;
136
140
  }
137
141
  getGeneratedModels(prop[1].type, context);
@@ -29,9 +29,15 @@ export async function emitContentByBuilder(
29
29
  builderFnOrList = [builderFnOrList];
30
30
  }
31
31
  for (const builderFn of builderFnOrList) {
32
- const contentFile = builderFn(rlcModels);
33
- if (contentFile) {
34
- await emitFile(contentFile, program, emitterOutputDir);
32
+ let contentFiles: File[] | File | undefined = builderFn(rlcModels);
33
+ if (!contentFiles) {
34
+ continue;
35
+ }
36
+ if (!Array.isArray(contentFiles)) {
37
+ contentFiles = [contentFiles];
38
+ }
39
+ for (const file of contentFiles) {
40
+ await emitFile(file, program, emitterOutputDir);
35
41
  }
36
42
  }
37
43
  }
@@ -41,7 +41,9 @@ import {
41
41
  listServices,
42
42
  Program,
43
43
  getEncode,
44
- EncodeData
44
+ EncodeData,
45
+ isRecordModelType,
46
+ isArrayModelType
45
47
  } from "@typespec/compiler";
46
48
  import { reportDiagnostic } from "../lib.js";
47
49
  import {
@@ -134,7 +136,7 @@ export function getSchemaForType(
134
136
  const program = dpgContext.program;
135
137
  const type = getEffectiveModelFromType(program, typeInput);
136
138
 
137
- const builtinType = mapTypeSpecTypeToTypeScript(dpgContext, type, usage);
139
+ const builtinType = getSchemaForLiteral(type);
138
140
  if (builtinType !== undefined) {
139
141
  // add in description elements for types derived from primitive types (SecureString, etc.)
140
142
  const doc = getDoc(program, type);
@@ -145,17 +147,19 @@ export function getSchemaForType(
145
147
  }
146
148
  if (type.kind === "Model") {
147
149
  const schema = getSchemaForModel(dpgContext, type, usage, needRef) as any;
148
- if (usage && usage.includes(SchemaContext.Output)) {
149
- if (!schema.name || schema.name === "") {
150
- //TODO: HANDLE ANONYMOUS
151
- schema.outputTypeName =
152
- schema.type === "object" ? "Record<string, any>" : "any";
153
- schema.typeName =
154
- schema.type === "object" ? "Record<string, unknown>" : "unknown";
155
- schema.type = "unknown";
156
- } else {
157
- schema.outputTypeName = `${schema.name}Output`;
158
- schema.typeName = `${schema.name}`;
150
+ if (!isArrayModelType(program, type) && !isRecordModelType(program, type)) {
151
+ if (usage && usage.includes(SchemaContext.Output)) {
152
+ if (!schema.name || schema.name === "") {
153
+ //TODO: HANDLE ANONYMOUS
154
+ schema.outputTypeName =
155
+ schema.type === "object" ? "Record<string, any>" : "any";
156
+ schema.typeName =
157
+ schema.type === "object" ? "Record<string, unknown>" : "unknown";
158
+ schema.type = "unknown";
159
+ } else {
160
+ schema.outputTypeName = `${schema.name}Output`;
161
+ schema.typeName = `${schema.name}`;
162
+ }
159
163
  }
160
164
  }
161
165
  schema.usage = usage;
@@ -418,6 +422,10 @@ function getSchemaForModel(
418
422
  usage?: SchemaContext[],
419
423
  needRef?: boolean
420
424
  ) {
425
+ if (isArrayModelType(dpgContext.program, model)) {
426
+ return getSchemaForArrayModel(dpgContext, model, usage!);
427
+ }
428
+
421
429
  const program = dpgContext.program;
422
430
  const overridedModelName =
423
431
  getFriendlyName(program, model) ?? getProjectedName(program, model, "json");
@@ -443,7 +451,8 @@ function getSchemaForModel(
443
451
  })
444
452
  .join("") + "List";
445
453
  }
446
- let modelSchema: ObjectSchema = {
454
+
455
+ const modelSchema: ObjectSchema = {
447
456
  name: overridedModelName ?? name,
448
457
  type: "object",
449
458
  description: getDoc(program, model) ?? ""
@@ -455,7 +464,13 @@ function getSchemaForModel(
455
464
  true /** shouldGuard */
456
465
  );
457
466
 
467
+ if (modelSchema.name === "Record" && isRecordModelType(program, model)) {
468
+ return getSchemaForRecordModel(dpgContext, model, usage!);
469
+ }
458
470
  modelSchema.typeName = modelSchema.name;
471
+ if (usage && usage.includes(SchemaContext.Output)) {
472
+ modelSchema.outputTypeName = modelSchema.name + "Output";
473
+ }
459
474
 
460
475
  if (isAzureCoreErrorType(model)) {
461
476
  modelSchema.fromCore = true;
@@ -489,6 +504,7 @@ function getSchemaForModel(
489
504
  }
490
505
  }
491
506
  modelSchema.properties = {};
507
+
492
508
  const derivedModels = model.derivedModels.filter(includeDerivedModel);
493
509
 
494
510
  // getSchemaOrRef on all children to push them into components.schemas
@@ -545,6 +561,12 @@ function getSchemaForModel(
545
561
  if (needRef) {
546
562
  return modelSchema;
547
563
  }
564
+ if (isRecordModelType(program, model)) {
565
+ modelSchema.parents = {
566
+ all: [getSchemaForRecordModel(dpgContext, model, usage!)],
567
+ immediate: [getSchemaForRecordModel(dpgContext, model, usage!)]
568
+ };
569
+ }
548
570
  for (const [propName, prop] of model.properties) {
549
571
  const restApiName = getProjectedName(program, prop, "json");
550
572
  const name = `"${restApiName ?? propName}"`;
@@ -617,27 +639,7 @@ function getSchemaForModel(
617
639
  modelSchema.properties[name] = newPropSchema;
618
640
  }
619
641
 
620
- // Special case: if a model type extends a single *templated* base type and
621
- // has no properties of its own, absorb the definition of the base model
622
- // into this schema definition. The assumption here is that any model type
623
- // defined like this is just meant to rename the underlying instance of a
624
- // templated type.
625
- if (
626
- model.baseModel &&
627
- model.baseModel.templateMapper &&
628
- model.baseModel.templateMapper.args &&
629
- model.baseModel.templateMapper.args.length > 0 &&
630
- modelSchema.properties &&
631
- Object.keys(modelSchema.properties).length === 0
632
- ) {
633
- // Take the base model schema but carry across the documentation property
634
- // that we set before
635
- const baseSchema = getSchemaForType(dpgContext, model.baseModel, usage);
636
- modelSchema = {
637
- ...baseSchema,
638
- description: modelSchema.description
639
- };
640
- } else if (model.baseModel) {
642
+ if (model.baseModel) {
641
643
  modelSchema.parents = {
642
644
  all: [getSchemaForType(dpgContext, model.baseModel, usage, true)],
643
645
  immediate: [getSchemaForType(dpgContext, model.baseModel, usage, true)]
@@ -647,20 +649,14 @@ function getSchemaForModel(
647
649
  }
648
650
  // Map an typespec type to an OA schema. Returns undefined when the resulting
649
651
  // OA schema is just a regular object schema.
650
- function mapTypeSpecTypeToTypeScript(
651
- dpgContext: SdkContext,
652
- type: Type,
653
- usage?: SchemaContext[]
654
- ): any {
652
+ function getSchemaForLiteral(type: Type): any {
655
653
  switch (type.kind) {
656
654
  case "Number":
657
- return { type: `${type.value}` };
655
+ return { type: `${type.value}`, isConstant: true };
658
656
  case "String":
659
- return { type: `"${type.value}"` };
657
+ return { type: `"${type.value}"`, isConstant: true };
660
658
  case "Boolean":
661
- return { type: `${type.value}` };
662
- case "Model":
663
- return mapTypeSpecStdTypeToTypeScript(dpgContext, type, usage);
659
+ return { type: `${type.value}`, isConstant: true };
664
660
  }
665
661
  if (type.kind === undefined) {
666
662
  if (typeof type === "string") {
@@ -669,6 +665,7 @@ function mapTypeSpecTypeToTypeScript(
669
665
  return { type: `${type}` };
670
666
  }
671
667
  }
668
+ return undefined;
672
669
  }
673
670
  function applyIntrinsicDecorators(
674
671
  program: Program,
@@ -735,7 +732,7 @@ function applyIntrinsicDecorators(
735
732
  function getSchemaForEnumMember(program: Program, e: EnumMember) {
736
733
  const value = e.value ?? e.name;
737
734
  const type = enumMemberType(e) === "string" ? `"${value}"` : `${value}`;
738
- return { type, description: getDoc(program, e) };
735
+ return { type, description: getDoc(program, e), isConstant: true };
739
736
  }
740
737
 
741
738
  function getSchemaForEnum(program: Program, e: Enum) {
@@ -774,111 +771,119 @@ function enumMemberType(member: EnumMember) {
774
771
  /**
775
772
  * Map TypeSpec intrinsic models to open api definitions
776
773
  */
777
- function mapTypeSpecStdTypeToTypeScript(
774
+ function getSchemaForArrayModel(
778
775
  dpgContext: SdkContext,
779
776
  type: Model,
780
- usage?: SchemaContext[]
781
- ): any | undefined {
782
- const program = dpgContext.program;
783
- const indexer = (type as Model).indexer;
784
- if (indexer !== undefined) {
785
- if (!isNeverType(indexer.key)) {
786
- const name = indexer.key.name;
787
- let schema: any = {};
788
- if (name === "string") {
789
- const valueType = getSchemaForType(
790
- dpgContext,
791
- indexer.value!,
792
- usage,
793
- true
794
- );
795
- schema = {
796
- type: "dictionary",
797
- additionalProperties: valueType,
798
- description: getDoc(program, type)
799
- };
800
- if (
801
- !program.checker.isStdType(indexer.value) &&
802
- !isUnknownType(indexer.value!) &&
803
- !isUnionType(indexer.value!)
804
- ) {
805
- schema.typeName = `Record<string, ${valueType.typeName}>`;
806
- schema.valueTypeName = valueType.name;
807
- if (usage && usage.includes(SchemaContext.Output)) {
808
- schema.outputTypeName = `Record<string, ${valueType.outputTypeName}>`;
809
- schema.outputValueTypeName = `${valueType.outputTypeName}`;
810
- }
811
- } else if (isUnknownType(indexer.value!)) {
812
- schema.typeName = `Record<string, ${
813
- valueType.typeName ?? valueType.type
814
- }>`;
815
- if (usage && usage.includes(SchemaContext.Output)) {
816
- schema.outputTypeName = `Record<string, ${
817
- valueType.outputTypeName ?? valueType.type
818
- }>`;
819
- }
820
- } else {
821
- schema.typeName = `Record<string, ${getTypeName(valueType, [
822
- SchemaContext.Input
823
- ])}>`;
824
- schema.outputTypeName = `Record<string, ${getTypeName(valueType, [
825
- SchemaContext.Output
826
- ])}>`;
827
- }
828
- } else if (name === "integer") {
829
- schema = {
830
- type: "array",
831
- items: getSchemaForType(dpgContext, indexer.value!, usage, true),
832
- description: getDoc(program, type)
833
- };
834
- if (
835
- !program.checker.isStdType(indexer.value) &&
836
- !isUnknownType(indexer.value!) &&
837
- indexer.value?.kind &&
838
- schema.items.name &&
839
- !schema.items.enum
840
- ) {
841
- schema.typeName = `Array<${schema.items.name}>`;
842
- if (usage && usage.includes(SchemaContext.Output)) {
843
- schema.outputTypeName = `Array<${schema.items.name}Output>`;
844
- }
777
+ usage: SchemaContext[]
778
+ ) {
779
+ const { program } = dpgContext;
780
+ const { indexer } = type;
781
+ let schema: any = {};
782
+ if (!indexer) {
783
+ return schema;
784
+ }
785
+ if (isArrayModelType(program, type)) {
786
+ schema = {
787
+ type: "array",
788
+ items: getSchemaForType(dpgContext, indexer.value!, usage, true),
789
+ description: getDoc(program, type)
790
+ };
791
+ if (
792
+ !program.checker.isStdType(indexer.value) &&
793
+ !isUnknownType(indexer.value!) &&
794
+ indexer.value?.kind &&
795
+ schema.items.name &&
796
+ !schema.items.enum
797
+ ) {
798
+ schema.typeName = `Array<${schema.items.name}>`;
799
+ if (usage && usage.includes(SchemaContext.Output)) {
800
+ schema.outputTypeName = `Array<${schema.items.name}Output>`;
801
+ }
802
+ } else {
803
+ if (schema.items.typeName) {
804
+ if (schema.items.type === "dictionary") {
805
+ schema.typeName = `${schema.items.typeName}[]`;
806
+ } else if (schema.items.type === "union") {
807
+ schema.typeName = `(${schema.items.typeName})[]`;
845
808
  } else {
846
- if (schema.items.typeName) {
847
- if (schema.items.type === "dictionary") {
848
- schema.typeName = `${schema.items.typeName}[]`;
849
- } else if (schema.items.type === "union") {
850
- schema.typeName = `(${schema.items.typeName})[]`;
851
- } else {
852
- schema.typeName = schema.items.typeName
853
- .split("|")
854
- .map((typeName: string) => {
855
- return `${typeName}[]`;
856
- })
857
- .join(" | ");
858
- if (
859
- schema.items.outputTypeName &&
860
- usage &&
861
- usage.includes(SchemaContext.Output)
862
- ) {
863
- schema.outputTypeName = schema.items.outputTypeName
864
- .split("|")
865
- .map((typeName: string) => {
866
- return `${typeName}[]`;
867
- })
868
- .join(" | ");
869
- }
870
- }
871
- } else if (schema.items.type.includes("|")) {
872
- schema.typeName = `(${schema.items.type})[]`;
873
- } else {
874
- schema.typeName = `${schema.items.type}[]`;
809
+ schema.typeName = schema.items.typeName
810
+ .split("|")
811
+ .map((typeName: string) => {
812
+ return `${typeName}[]`;
813
+ })
814
+ .join(" | ");
815
+ if (
816
+ schema.items.outputTypeName &&
817
+ usage &&
818
+ usage.includes(SchemaContext.Output)
819
+ ) {
820
+ schema.outputTypeName = schema.items.outputTypeName
821
+ .split("|")
822
+ .map((typeName: string) => {
823
+ return `${typeName}[]`;
824
+ })
825
+ .join(" | ");
875
826
  }
876
827
  }
828
+ } else if (schema.items.type.includes("|")) {
829
+ schema.typeName = `(${schema.items.type})[]`;
830
+ } else {
831
+ schema.typeName = `${schema.items.type}[]`;
877
832
  }
833
+ }
834
+ schema.usage = usage;
835
+ return schema;
836
+ }
837
+ }
878
838
 
879
- schema.usage = usage;
880
- return schema;
839
+ function getSchemaForRecordModel(
840
+ dpgContext: SdkContext,
841
+ type: Model,
842
+ usage: SchemaContext[]
843
+ ) {
844
+ const { program } = dpgContext;
845
+ const { indexer } = type;
846
+ let schema: any = {};
847
+ if (!indexer) {
848
+ return schema;
849
+ }
850
+ if (isRecordModelType(program, type)) {
851
+ const valueType = getSchemaForType(dpgContext, indexer?.value, usage, true);
852
+ schema = {
853
+ type: "dictionary",
854
+ additionalProperties: valueType,
855
+ description: getDoc(program, type)
856
+ };
857
+ if (
858
+ !program.checker.isStdType(indexer.value) &&
859
+ !isUnknownType(indexer.value!) &&
860
+ !isUnionType(indexer.value!)
861
+ ) {
862
+ schema.typeName = `Record<string, ${valueType.typeName}>`;
863
+ schema.valueTypeName = valueType.name;
864
+ if (usage && usage.includes(SchemaContext.Output)) {
865
+ schema.outputTypeName = `Record<string, ${valueType.outputTypeName}>`;
866
+ schema.outputValueTypeName = `${valueType.outputTypeName}`;
867
+ }
868
+ } else if (isUnknownType(indexer.value!)) {
869
+ schema.typeName = `Record<string, ${
870
+ valueType.typeName ?? valueType.type
871
+ }>`;
872
+ if (usage && usage.includes(SchemaContext.Output)) {
873
+ schema.outputTypeName = `Record<string, ${
874
+ valueType.outputTypeName ?? valueType.type
875
+ }>`;
876
+ }
877
+ } else {
878
+ schema.typeName = `Record<string, ${getTypeName(valueType, [
879
+ SchemaContext.Input
880
+ ])}>`;
881
+ schema.outputTypeName = `Record<string, ${getTypeName(valueType, [
882
+ SchemaContext.Output
883
+ ])}>`;
881
884
  }
885
+ schema.usage = usage;
886
+ return schema;
882
887
  }
883
888
  }
884
889