@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-tools/typespec-ts",
3
- "version": "0.36.0",
3
+ "version": "0.37.0-alpha.20241230.1",
4
4
  "description": "An experimental TypeSpec emitter for TypeScript RLC",
5
5
  "main": "dist/src/index.js",
6
6
  "type": "module",
@@ -44,7 +44,7 @@
44
44
  "@typespec/http": ">=0.63.0 <1.0.0",
45
45
  "@typespec/openapi": ">=0.63.0, <1.0.0",
46
46
  "@typespec/rest": ">=0.63.0 <1.0.0",
47
- "@typespec/ts-http-runtime": "1.0.0-alpha.20240314.2",
47
+ "@typespec/ts-http-runtime": "0.1.0",
48
48
  "@typespec/versioning": ">=0.63.0 <1.0.0",
49
49
  "chai": "^4.3.6",
50
50
  "chalk": "^4.0.0",
@@ -73,7 +73,7 @@
73
73
  "@typespec/versioning": ">=0.63.0 <1.0.0"
74
74
  },
75
75
  "dependencies": {
76
- "@azure-tools/rlc-common": "^0.36.0",
76
+ "@azure-tools/rlc-common": "^0.37.0",
77
77
  "fs-extra": "^11.1.0",
78
78
  "lodash": "^4.17.21",
79
79
  "prettier": "^3.3.3",
@@ -1,5 +1,5 @@
1
1
  import { Project, SourceFile } from "ts-morph";
2
- import { ModularMetaTree, RlcMetaTree } from "./metaTree.js";
2
+ import { RlcMetaTree } from "./metaTree.js";
3
3
  import { EmitContext } from "@typespec/compiler";
4
4
  import { SdkContext } from "@azure-tools/typespec-client-generator-core";
5
5
  import { SdkTypeContext } from "./framework/hooks/sdkTypes.js";
@@ -21,7 +21,6 @@ import { ExternalDependencies } from "./framework/dependency.js";
21
21
  */
22
22
  type Contexts = {
23
23
  rlcMetaTree: RlcMetaTree; // Context for RLC types metadata.
24
- modularMetaTree: ModularMetaTree; // Context for modular types metadata.
25
24
  outputProject: Project; // The TS-Morph root project context for code generation.
26
25
  symbolMap: Map<string, SourceFile>; // Mapping of symbols to their corresponding source files.
27
26
  sdkTypes: SdkTypeContext;
@@ -10,6 +10,8 @@ import {
10
10
  } from "ts-morph";
11
11
  import { refkey } from "./refkey.js";
12
12
  import { resolveProjectRoot } from "../utils/resolve-project-root.js";
13
+ import { isAzurePackage } from "@azure-tools/rlc-common";
14
+ import { ModularEmitterOptions } from "../modular/interfaces.js";
13
15
  export const SourceFileSymbol = Symbol("SourceFile");
14
16
  export interface StaticHelperMetadata {
15
17
  name: string;
@@ -34,7 +36,8 @@ export type StaticHelpers = Record<string, StaticHelperMetadata>;
34
36
 
35
37
  const DEFAULT_STATIC_HELPERS_PATH = "static/static-helpers";
36
38
 
37
- export interface LoadStaticHelpersOptions {
39
+ export interface LoadStaticHelpersOptions
40
+ extends Partial<ModularEmitterOptions> {
38
41
  helpersAssetDirectory?: string;
39
42
  sourcesDir?: string;
40
43
  }
@@ -60,6 +63,26 @@ export async function loadStaticHelpers(
60
63
  const addedFile = project.createSourceFile(targetPath, contents, {
61
64
  overwrite: true
62
65
  });
66
+ addedFile.getImportDeclarations().map((i) => {
67
+ if (!isAzurePackage({ options: options.options })) {
68
+ if (
69
+ i
70
+ .getModuleSpecifier()
71
+ .getFullText()
72
+ .includes("@azure/core-rest-pipeline")
73
+ ) {
74
+ i.setModuleSpecifier("@typespec/ts-http-runtime");
75
+ }
76
+ if (
77
+ i
78
+ .getModuleSpecifier()
79
+ .getFullText()
80
+ .includes("@azure-rest/core-client")
81
+ ) {
82
+ i.setModuleSpecifier("@typespec/ts-http-runtime");
83
+ }
84
+ }
85
+ });
63
86
 
64
87
  for (const entry of Object.values(helpers)) {
65
88
  if (!addedFile.getFilePath().endsWith(entry.location)) {
package/src/index.ts CHANGED
@@ -55,7 +55,7 @@ import { emitContentByBuilder, emitModels } from "./utils/emitUtil.js";
55
55
  import { provideContext, useContext } from "./contextManager.js";
56
56
 
57
57
  import { EmitterOptions } from "./lib.js";
58
- import { ModularCodeModel } from "./modular/modularCodeModel.js";
58
+ import { ModularEmitterOptions } from "./modular/interfaces.js";
59
59
  import { Project, SourceFile } from "ts-morph";
60
60
  import { buildClassicOperationFiles } from "./modular/buildClassicalOperationGroups.js";
61
61
  import { buildClassicalClient } from "./modular/buildClassicalClient.js";
@@ -68,7 +68,7 @@ import { buildOperationFiles } from "./modular/buildOperations.js";
68
68
  import { buildRestorePoller } from "./modular/buildRestorePoller.js";
69
69
  import { buildSubpathIndexFile } from "./modular/buildSubpathIndex.js";
70
70
  import { createSdkContext } from "@azure-tools/typespec-client-generator-core";
71
- import { emitCodeModel } from "./modular/buildCodeModel.js";
71
+ import { transformModularEmitterOptions } from "./modular/buildModularOptions.js";
72
72
  import { emitLoggerFile } from "./modular/emitLoggerFile.js";
73
73
  import { emitSerializerHelpersFile } from "./modular/buildHelperSerializers.js";
74
74
  import { emitTypes } from "./modular/emitModels.js";
@@ -105,7 +105,6 @@ export async function $onEmit(context: EmitContext) {
105
105
  >();
106
106
  provideContext("rlcMetaTree", new Map());
107
107
  provideContext("symbolMap", new Map());
108
- provideContext("modularMetaTree", new Map());
109
108
  provideContext("outputProject", outputProject);
110
109
  provideContext("emitContext", {
111
110
  compilerContext: context,
@@ -118,7 +117,10 @@ export async function $onEmit(context: EmitContext) {
118
117
  ...PagingHelpers,
119
118
  ...PollingHelpers
120
119
  },
121
- { sourcesDir: dpgContext.generationPathDetail?.modularSourcesDir }
120
+ {
121
+ sourcesDir: dpgContext.generationPathDetail?.modularSourcesDir,
122
+ options: rlcOptions
123
+ }
122
124
  );
123
125
  const extraDependencies = isAzurePackage({ options: rlcOptions })
124
126
  ? {
@@ -136,8 +138,7 @@ export async function $onEmit(context: EmitContext) {
136
138
  provideSdkTypes(dpgContext);
137
139
 
138
140
  const rlcCodeModels: RLCModel[] = [];
139
- let modularCodeModel: ModularCodeModel;
140
-
141
+ let modularEmitterOptions: ModularEmitterOptions;
141
142
  // 1. Clear sources folder
142
143
  await clearSrcFolder();
143
144
  // 2. Generate RLC code model
@@ -152,7 +153,7 @@ export async function $onEmit(context: EmitContext) {
152
153
  }
153
154
 
154
155
  // 5. Generate metadata and test files
155
- await generateMetadataAndTest();
156
+ await generateMetadataAndTest(dpgContext);
156
157
 
157
158
  async function enrichDpgContext() {
158
159
  const generationPathDetail: GenerationDirDetail =
@@ -243,9 +244,8 @@ export async function $onEmit(context: EmitContext) {
243
244
  dpgContext.generationPathDetail?.modularSourcesDir ?? "src";
244
245
  const project = useContext("outputProject");
245
246
  emitSerializerHelpersFile(project, modularSourcesRoot);
246
- modularCodeModel = emitCodeModel(
247
+ modularEmitterOptions = transformModularEmitterOptions(
247
248
  dpgContext,
248
- serviceNameToRlcModelsMap,
249
249
  modularSourcesRoot,
250
250
  project,
251
251
  {
@@ -253,7 +253,7 @@ export async function $onEmit(context: EmitContext) {
253
253
  }
254
254
  );
255
255
 
256
- emitLoggerFile(modularCodeModel, project, modularSourcesRoot);
256
+ emitLoggerFile(modularEmitterOptions, modularSourcesRoot);
257
257
 
258
258
  const rootIndexFile = project.createSourceFile(
259
259
  `${modularSourcesRoot}/index.ts`,
@@ -263,10 +263,10 @@ export async function $onEmit(context: EmitContext) {
263
263
  }
264
264
  );
265
265
 
266
- const isMultiClients = modularCodeModel.clients.length > 1;
266
+ const isMultiClients = dpgContext.sdkPackage.clients.length > 1;
267
267
 
268
268
  emitTypes(dpgContext, { sourceRoot: modularSourcesRoot });
269
- buildSubpathIndexFile(modularCodeModel, "models");
269
+ buildSubpathIndexFile(dpgContext, modularEmitterOptions, "models");
270
270
  // Enable modular sample generation when explicitly set to true or MPG
271
271
  if (emitterOptions?.generateSample === true) {
272
272
  const samples = emitSamples(dpgContext);
@@ -276,29 +276,51 @@ export async function $onEmit(context: EmitContext) {
276
276
  dpgContext.rlcOptions!.generateSample = true;
277
277
  }
278
278
  }
279
- for (const subClient of modularCodeModel.clients) {
280
- buildApiOptions(dpgContext, subClient, modularCodeModel);
281
- buildOperationFiles(subClient, dpgContext, modularCodeModel);
282
- buildClientContext(subClient, dpgContext, modularCodeModel);
283
- buildRestorePoller(modularCodeModel, subClient);
279
+ for (const subClient of dpgContext.sdkPackage.clients) {
280
+ buildApiOptions(dpgContext, subClient, modularEmitterOptions);
281
+ buildOperationFiles(dpgContext, subClient, modularEmitterOptions);
282
+ buildClientContext(dpgContext, subClient, modularEmitterOptions);
283
+ buildRestorePoller(dpgContext, subClient, modularEmitterOptions);
284
284
  if (dpgContext.rlcOptions?.hierarchyClient) {
285
- buildSubpathIndexFile(modularCodeModel, "api", subClient);
285
+ buildSubpathIndexFile(
286
+ dpgContext,
287
+ modularEmitterOptions,
288
+ "api",
289
+ subClient
290
+ );
286
291
  } else {
287
- buildSubpathIndexFile(modularCodeModel, "api", subClient, {
288
- exportIndex: true
289
- });
292
+ buildSubpathIndexFile(
293
+ dpgContext,
294
+ modularEmitterOptions,
295
+ "api",
296
+ subClient,
297
+ {
298
+ exportIndex: true
299
+ }
300
+ );
290
301
  }
291
302
 
292
- buildClassicalClient(subClient, dpgContext, modularCodeModel);
293
- buildClassicOperationFiles(dpgContext, modularCodeModel, subClient);
294
- buildSubpathIndexFile(modularCodeModel, "classic", subClient, {
295
- exportIndex: true,
296
- interfaceOnly: true
297
- });
303
+ buildClassicalClient(dpgContext, subClient, modularEmitterOptions);
304
+ buildClassicOperationFiles(dpgContext, subClient, modularEmitterOptions);
305
+ buildSubpathIndexFile(
306
+ dpgContext,
307
+ modularEmitterOptions,
308
+ "classic",
309
+ subClient,
310
+ {
311
+ exportIndex: true,
312
+ interfaceOnly: true
313
+ }
314
+ );
298
315
  if (isMultiClients) {
299
- buildSubClientIndexFile(subClient, modularCodeModel);
316
+ buildSubClientIndexFile(dpgContext, subClient, modularEmitterOptions);
300
317
  }
301
- buildRootIndex(subClient, modularCodeModel, rootIndexFile);
318
+ buildRootIndex(
319
+ dpgContext,
320
+ subClient,
321
+ modularEmitterOptions,
322
+ rootIndexFile
323
+ );
302
324
  }
303
325
 
304
326
  binder.resolveAllReferences(modularSourcesRoot);
@@ -318,12 +340,12 @@ export async function $onEmit(context: EmitContext) {
318
340
  await emitContentByBuilder(
319
341
  program,
320
342
  () => ({ content: file.getFullText(), path: file.getFilePath() }),
321
- modularCodeModel as any
343
+ modularEmitterOptions as any
322
344
  );
323
345
  }
324
346
  }
325
347
 
326
- async function generateMetadataAndTest() {
348
+ async function generateMetadataAndTest(context: SdkContext) {
327
349
  const project = useContext("outputProject");
328
350
  if (rlcCodeModels.length === 0 || !rlcCodeModels[0]) {
329
351
  return;
@@ -359,7 +381,7 @@ export async function $onEmit(context: EmitContext) {
359
381
  let modularPackageInfo = {};
360
382
  if (option.isModularLibrary) {
361
383
  modularPackageInfo = {
362
- exports: getModuleExports(modularCodeModel)
384
+ exports: getModuleExports(context, modularEmitterOptions)
363
385
  };
364
386
  if (isAzureFlavor) {
365
387
  modularPackageInfo = {
@@ -367,7 +389,10 @@ export async function $onEmit(context: EmitContext) {
367
389
  dependencies: {
368
390
  "@azure/core-util": "^1.9.2"
369
391
  },
370
- clientContextPaths: getRelativeContextPaths(modularCodeModel)
392
+ clientContextPaths: getRelativeContextPaths(
393
+ context,
394
+ modularEmitterOptions
395
+ )
371
396
  };
372
397
  }
373
398
  }
@@ -388,7 +413,7 @@ export async function $onEmit(context: EmitContext) {
388
413
  await emitContentByBuilder(
389
414
  program,
390
415
  () => ({ content: file.getFullText(), path: file.getFilePath() }),
391
- modularCodeModel as any
416
+ modularEmitterOptions as any
392
417
  );
393
418
  }
394
419
  }
@@ -413,9 +438,12 @@ export async function $onEmit(context: EmitContext) {
413
438
  }
414
439
  }
415
440
 
416
- function getRelativeContextPaths(codeModel: ModularCodeModel) {
417
- return codeModel.clients
418
- .map((subClient) => getClientContextPath(subClient, codeModel))
441
+ function getRelativeContextPaths(
442
+ context: SdkContext,
443
+ options: ModularEmitterOptions
444
+ ) {
445
+ return context.sdkPackage.clients
446
+ .map((subClient) => getClientContextPath(context, subClient, options))
419
447
  .map((path) => path.substring(path.indexOf("src")));
420
448
  }
421
449
  }
package/src/lib.ts CHANGED
@@ -116,7 +116,7 @@ const libDef = {
116
116
  }
117
117
  },
118
118
  "no-service-defined": {
119
- severity: "error",
119
+ severity: "warning",
120
120
  messages: {
121
121
  default:
122
122
  "No service defined and must have one and only one service defined."
package/src/metaTree.ts CHANGED
@@ -1,14 +1,8 @@
1
1
  import { Schema as RlcType } from "@azure-tools/rlc-common";
2
- import { Type as ModularType } from "./modular/modularCodeModel.js";
3
2
  import { Type } from "@typespec/compiler";
4
3
 
5
4
  export interface RlcTypeMetadata {
6
5
  rlcType: RlcType;
7
6
  }
8
7
 
9
- export interface ModularTypeMetadata {
10
- modularType: ModularType;
11
- }
12
-
13
8
  export type RlcMetaTree = Map<Type, RlcTypeMetadata>;
14
- export type ModularMetaTree = Map<Type, ModularTypeMetadata>;
@@ -5,7 +5,7 @@ import {
5
5
  SourceFile,
6
6
  StructureKind
7
7
  } from "ts-morph";
8
- import { Client, ModularCodeModel } from "./modularCodeModel.js";
8
+ import { ModularEmitterOptions } from "./interfaces.js";
9
9
  import { NameType, normalizeName } from "@azure-tools/rlc-common";
10
10
  import {
11
11
  buildUserAgentOptions,
@@ -13,39 +13,48 @@ import {
13
13
  } from "./helpers/clientHelpers.js";
14
14
  import {
15
15
  getClassicalClientName,
16
- getClassicalLayerPrefix,
17
16
  getClientName
18
17
  } from "./helpers/namingHelpers.js";
19
18
 
20
19
  import { SdkContext } from "../utils/interfaces.js";
21
20
  import { getDocsFromDescription } from "./helpers/docsHelpers.js";
22
21
  import { getOperationFunction } from "./helpers/operationHelpers.js";
23
- import { isRLCMultiEndpoint } from "../utils/clientUtils.js";
22
+ import {
23
+ getModularClientOptions,
24
+ isRLCMultiEndpoint
25
+ } from "../utils/clientUtils.js";
24
26
  import { resolveReference } from "../framework/reference.js";
25
- import { shouldPromoteSubscriptionId } from "./helpers/classicalOperationHelpers.js";
26
27
  import { useDependencies } from "../framework/hooks/useDependencies.js";
28
+ import {
29
+ SdkClientType,
30
+ SdkServiceMethod,
31
+ SdkServiceOperation
32
+ } from "@azure-tools/typespec-client-generator-core";
33
+ import { getMethodHierarchiesMap } from "../utils/operationUtil.js";
27
34
 
28
35
  export function buildClassicalClient(
29
- _client: Client,
30
36
  dpgContext: SdkContext,
31
- codeModel: ModularCodeModel
37
+ client: SdkClientType<SdkServiceOperation>,
38
+ emitterOptions: ModularEmitterOptions
32
39
  ) {
33
- const { description, tcgcClient: client } = _client;
34
40
  const dependencies = useDependencies();
35
41
  const modularClientName = getClientName(client);
36
42
  const classicalClientName = `${getClassicalClientName(client)}`;
37
- const classicalParams = getClientParametersDeclaration(_client, dpgContext, {
43
+ const classicalParams = getClientParametersDeclaration(client, dpgContext, {
38
44
  requiredOnly: true
39
45
  });
40
- const contextParams = getClientParametersDeclaration(_client, dpgContext, {
41
- onClientOnly: true,
46
+ const contextParams = getClientParametersDeclaration(client, dpgContext, {
47
+ onClientOnly: false,
42
48
  requiredOnly: true
43
49
  });
44
- const srcPath = codeModel.modularOptions.sourceRoot;
45
- const subfolder = _client.subfolder ?? "";
50
+ const srcPath = emitterOptions.modularOptions.sourceRoot;
51
+ const { subfolder, rlcClientName } = getModularClientOptions(
52
+ dpgContext,
53
+ client
54
+ );
46
55
 
47
- const clientFile = codeModel.project.createSourceFile(
48
- `${srcPath}/${subfolder !== "" ? subfolder + "/" : ""}${normalizeName(
56
+ const clientFile = emitterOptions.project.createSourceFile(
57
+ `${srcPath}/${subfolder && subfolder !== "" ? subfolder + "/" : ""}${normalizeName(
49
58
  classicalClientName,
50
59
  NameType.File
51
60
  )}.ts`
@@ -68,13 +77,13 @@ export function buildClassicalClient(
68
77
  if (isRLCMultiEndpoint(dpgContext)) {
69
78
  clientClass.addProperty({
70
79
  name: "_client",
71
- type: `Client.${_client.rlcClientName}`,
80
+ type: `Client.${rlcClientName}`,
72
81
  scope: Scope.Private
73
82
  });
74
83
  } else {
75
84
  clientClass.addProperty({
76
85
  name: "_client",
77
- type: `${_client.rlcClientName}`,
86
+ type: `${rlcClientName}`,
78
87
  scope: Scope.Private
79
88
  });
80
89
  }
@@ -89,7 +98,7 @@ export function buildClassicalClient(
89
98
 
90
99
  // TODO: We may need to generate constructor overloads at some point. Here we'd do that.
91
100
  const constructor = clientClass.addConstructor({
92
- docs: getDocsFromDescription(description),
101
+ docs: getDocsFromDescription(client.doc),
93
102
  parameters: classicalParams
94
103
  });
95
104
 
@@ -99,7 +108,7 @@ export function buildClassicalClient(
99
108
  if (x === "options") {
100
109
  return `{...options, userAgentOptions: ${buildUserAgentOptions(
101
110
  constructor,
102
- codeModel,
111
+ emitterOptions,
103
112
  "azsdk-js-client"
104
113
  )}}`;
105
114
  } else {
@@ -112,8 +121,8 @@ export function buildClassicalClient(
112
121
  ]);
113
122
  constructor.addStatements(`this.pipeline = this._client.pipeline;`);
114
123
 
115
- buildClientOperationGroups(clientFile, _client, dpgContext, clientClass);
116
- importAllApis(clientFile, srcPath, subfolder);
124
+ buildClientOperationGroups(clientFile, client, dpgContext, clientClass);
125
+ importAllApis(clientFile, srcPath, subfolder ?? "");
117
126
  clientFile.fixUnusedIdentifiers();
118
127
  return clientFile;
119
128
  }
@@ -125,7 +134,7 @@ function importAllApis(
125
134
  ) {
126
135
  const project = clientFile.getProject();
127
136
  const apiModels = project.getSourceFile(
128
- `${srcPath}/${subfolder !== "" ? subfolder + "/" : ""}api/index.ts`
137
+ `${srcPath}/${subfolder && subfolder !== "" ? subfolder + "/" : ""}api/index.ts`
129
138
  );
130
139
 
131
140
  if (!apiModels) {
@@ -140,96 +149,85 @@ function importAllApis(
140
149
  });
141
150
  }
142
151
 
152
+ function generateMethod(
153
+ context: SdkContext,
154
+ clientType: string,
155
+ method: [string[], SdkServiceMethod<SdkServiceOperation>]
156
+ ) {
157
+ const declarations = getOperationFunction(context, method, clientType);
158
+ const result: MethodDeclarationStructure = {
159
+ docs: declarations.docs,
160
+ name: declarations.propertyName ?? declarations.name ?? "FIXME",
161
+ kind: StructureKind.Method,
162
+ returnType: declarations.returnType,
163
+ parameters: declarations.parameters?.filter((p) => p.name !== "context"),
164
+ statements: `return ${declarations.name}(${[
165
+ "this._client",
166
+ ...[
167
+ declarations.parameters
168
+ ?.map((p) => p.name)
169
+ .filter((p) => p !== "context")
170
+ ]
171
+ ].join(",")})`
172
+ };
173
+ return result;
174
+ }
143
175
  function buildClientOperationGroups(
144
176
  clientFile: SourceFile,
145
- client: Client,
177
+ client: SdkClientType<SdkServiceOperation>,
146
178
  dpgContext: SdkContext,
147
179
  clientClass: ClassDeclaration
148
180
  ) {
149
181
  let clientType = "Client";
150
- const subfolder = client.subfolder ?? "";
182
+ const { subfolder } = getModularClientOptions(dpgContext, client);
151
183
  if (subfolder && subfolder !== "") {
152
184
  clientType = `Client.${clientClass.getName()}`;
153
185
  }
154
- for (const operationGroup of client.operationGroups) {
155
- const groupName = normalizeName(
156
- operationGroup.namespaceHierarchies[0] ?? operationGroup.propertyName,
157
- NameType.Property
158
- );
159
- // TODO: remove this logic once client-level parameter design is finalized
160
- // https://github.com/Azure/autorest.typescript/issues/2618
161
- const hasSubscriptionIdPromoted = shouldPromoteSubscriptionId(
162
- dpgContext,
163
- operationGroup
164
- );
165
- if (groupName === "") {
166
- operationGroup.operations.forEach((op) => {
167
- const declarations = getOperationFunction(dpgContext, op, clientType);
168
- const method: MethodDeclarationStructure = {
169
- docs: declarations.docs,
170
- name: declarations.propertyName ?? declarations.name ?? "FIXME",
171
- kind: StructureKind.Method,
172
- returnType: declarations.returnType,
173
- parameters: declarations.parameters?.filter(
174
- (p) => p.name !== "context"
175
- ),
176
- statements: `return ${declarations.name}(${[
177
- "this._client",
178
- ...[
179
- declarations.parameters
180
- ?.map((p) => p.name)
181
- .filter((p) => p !== "context")
182
- ]
183
- ].join(",")})`
184
- };
186
+ const methodMap = getMethodHierarchiesMap(dpgContext, client);
187
+ for (const [prefixKey, operations] of methodMap) {
188
+ const prefixes = prefixKey.split("/");
189
+ if (prefixKey === "") {
190
+ operations.forEach((op) => {
191
+ const method = generateMethod(dpgContext, clientType, [prefixes, op]);
185
192
  clientClass.addMethod(method);
186
193
  });
187
- continue;
188
- }
189
- const operationName = `get${getClassicalLayerPrefix(
190
- operationGroup,
191
- NameType.Interface,
192
- "",
193
- 0
194
- )}Operations`;
195
- const propertyType = `${getClassicalLayerPrefix(
196
- operationGroup,
197
- NameType.Interface,
198
- "",
199
- 0
200
- )}Operations`;
201
- const existProperty = clientClass.getProperties().filter((p) => {
202
- return p.getName() === groupName;
203
- });
204
- if (!existProperty || existProperty.length === 0) {
205
- clientFile.addImportDeclaration({
206
- namedImports: [operationName, propertyType],
207
- moduleSpecifier: `./classic/${getClassicalLayerPrefix(
208
- operationGroup,
209
- NameType.File,
210
- "/",
211
- 0
212
- )}/index.js`
194
+ } else {
195
+ const groupName = normalizeName(prefixes[0] ?? "", NameType.Property);
196
+ const operationName = `get${normalizeName(
197
+ groupName,
198
+ NameType.OperationGroup
199
+ )}Operations`;
200
+ const propertyType = `${normalizeName(
201
+ groupName,
202
+ NameType.OperationGroup
203
+ )}Operations`;
204
+ const existProperty = clientClass.getProperties().filter((p) => {
205
+ return p.getName() === groupName;
213
206
  });
214
- clientClass.addProperty({
215
- name: groupName,
216
- type: propertyType,
217
- scope: Scope.Public,
218
- isReadonly: true,
219
- docs: ["The operation groups for " + operationGroup.propertyName]
220
- });
221
- clientClass
222
- .getConstructors()[0]
223
- ?.addStatements(
224
- `this.${groupName} = get${getClassicalLayerPrefix(
225
- operationGroup,
226
- NameType.Interface,
227
- "",
228
- 0
229
- )}Operations(this._client${
230
- hasSubscriptionIdPromoted ? ", subscriptionId" : ""
231
- })`
232
- );
207
+ if (!existProperty || existProperty.length === 0) {
208
+ clientFile.addImportDeclaration({
209
+ namedImports: [operationName, propertyType],
210
+ moduleSpecifier: `./classic/${normalizeName(
211
+ groupName,
212
+ NameType.File
213
+ )}/index.js`
214
+ });
215
+ clientClass.addProperty({
216
+ name: groupName,
217
+ type: propertyType,
218
+ scope: Scope.Public,
219
+ isReadonly: true,
220
+ docs: ["The operation groups for " + groupName]
221
+ });
222
+ clientClass
223
+ .getConstructors()[0]
224
+ ?.addStatements(
225
+ `this.${groupName} = get${normalizeName(
226
+ groupName,
227
+ NameType.OperationGroup
228
+ )}Operations(this._client)`
229
+ );
230
+ }
233
231
  }
234
232
  }
235
233
  }