@azure-tools/typespec-ts 0.55.0-dev.2 → 0.55.0-dev.3

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 (122) hide show
  1. package/README.md +96 -24
  2. package/dist/src/framework/hooks/binder.d.ts.map +1 -1
  3. package/dist/src/framework/hooks/binder.js +3 -4
  4. package/dist/src/framework/hooks/binder.js.map +1 -1
  5. package/dist/src/framework/load-static-helpers.d.ts.map +1 -1
  6. package/dist/src/framework/load-static-helpers.js +7 -8
  7. package/dist/src/framework/load-static-helpers.js.map +1 -1
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +17 -17
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/lib.js +30 -31
  12. package/dist/src/lib.js.map +1 -1
  13. package/dist/src/modular/build-project-files.d.ts.map +1 -1
  14. package/dist/src/modular/build-project-files.js +4 -4
  15. package/dist/src/modular/build-project-files.js.map +1 -1
  16. package/dist/src/modular/build-restore-poller.js +2 -2
  17. package/dist/src/modular/build-restore-poller.js.map +1 -1
  18. package/dist/src/modular/build-root-index.d.ts.map +1 -1
  19. package/dist/src/modular/build-root-index.js +5 -6
  20. package/dist/src/modular/build-root-index.js.map +1 -1
  21. package/dist/src/modular/build-subpath-index.d.ts.map +1 -1
  22. package/dist/src/modular/build-subpath-index.js +4 -4
  23. package/dist/src/modular/build-subpath-index.js.map +1 -1
  24. package/dist/src/modular/emit-models-options.js +2 -2
  25. package/dist/src/modular/emit-models-options.js.map +1 -1
  26. package/dist/src/modular/emit-models.d.ts.map +1 -1
  27. package/dist/src/modular/emit-models.js +2 -3
  28. package/dist/src/modular/emit-models.js.map +1 -1
  29. package/dist/src/modular/emit-samples.d.ts.map +1 -1
  30. package/dist/src/modular/emit-samples.js +3 -4
  31. package/dist/src/modular/emit-samples.js.map +1 -1
  32. package/dist/src/modular/emit-tests.d.ts.map +1 -1
  33. package/dist/src/modular/emit-tests.js +3 -3
  34. package/dist/src/modular/emit-tests.js.map +1 -1
  35. package/dist/src/modular/helpers/example-value-helpers.js +4 -4
  36. package/dist/src/modular/helpers/example-value-helpers.js.map +1 -1
  37. package/dist/src/rlc-common/build-client-definitions.js +2 -2
  38. package/dist/src/rlc-common/build-client-definitions.js.map +1 -1
  39. package/dist/src/rlc-common/build-client.js +3 -3
  40. package/dist/src/rlc-common/build-client.js.map +1 -1
  41. package/dist/src/rlc-common/build-index-file.js +2 -2
  42. package/dist/src/rlc-common/build-index-file.js.map +1 -1
  43. package/dist/src/rlc-common/build-is-unexpected-helper.js +2 -2
  44. package/dist/src/rlc-common/build-is-unexpected-helper.js.map +1 -1
  45. package/dist/src/rlc-common/build-logger.js +2 -2
  46. package/dist/src/rlc-common/build-logger.js.map +1 -1
  47. package/dist/src/rlc-common/build-paginate-helper.js +2 -2
  48. package/dist/src/rlc-common/build-paginate-helper.js.map +1 -1
  49. package/dist/src/rlc-common/build-parameter-types.js +2 -2
  50. package/dist/src/rlc-common/build-parameter-types.js.map +1 -1
  51. package/dist/src/rlc-common/build-polling-helper.js +2 -2
  52. package/dist/src/rlc-common/build-polling-helper.js.map +1 -1
  53. package/dist/src/rlc-common/build-response-types.js +2 -2
  54. package/dist/src/rlc-common/build-response-types.js.map +1 -1
  55. package/dist/src/rlc-common/build-samples.js +2 -2
  56. package/dist/src/rlc-common/build-samples.js.map +1 -1
  57. package/dist/src/rlc-common/build-schema-type.js +3 -3
  58. package/dist/src/rlc-common/build-schema-type.js.map +1 -1
  59. package/dist/src/rlc-common/build-serialize-helper.js +2 -2
  60. package/dist/src/rlc-common/build-serialize-helper.js.map +1 -1
  61. package/dist/src/rlc-common/build-top-level-index-file.js +2 -2
  62. package/dist/src/rlc-common/build-top-level-index-file.js.map +1 -1
  63. package/dist/src/rlc-common/helpers/path-utils.d.ts.map +1 -1
  64. package/dist/src/rlc-common/helpers/path-utils.js +1 -2
  65. package/dist/src/rlc-common/helpers/path-utils.js.map +1 -1
  66. package/dist/src/rlc-common/metadata/build-readme-file.d.ts.map +1 -1
  67. package/dist/src/rlc-common/metadata/build-readme-file.js +6 -6
  68. package/dist/src/rlc-common/metadata/build-readme-file.js.map +1 -1
  69. package/dist/src/transform/transform.d.ts.map +1 -1
  70. package/dist/src/transform/transform.js +2 -3
  71. package/dist/src/transform/transform.js.map +1 -1
  72. package/dist/src/utils/emit-util.d.ts.map +1 -1
  73. package/dist/src/utils/emit-util.js +3 -4
  74. package/dist/src/utils/emit-util.js.map +1 -1
  75. package/dist/src/utils/file-system-utils.d.ts.map +1 -1
  76. package/dist/src/utils/file-system-utils.js +3 -4
  77. package/dist/src/utils/file-system-utils.js.map +1 -1
  78. package/dist/src/utils/import-helper.js +3 -3
  79. package/dist/src/utils/import-helper.js.map +1 -1
  80. package/dist/src/utils/resolve-project-root.d.ts.map +1 -1
  81. package/dist/src/utils/resolve-project-root.js +1 -3
  82. package/dist/src/utils/resolve-project-root.js.map +1 -1
  83. package/dist/tsconfig.tsbuildinfo +1 -1
  84. package/package.json +26 -26
  85. package/src/framework/hooks/binder.ts +3 -4
  86. package/src/framework/load-static-helpers.ts +7 -8
  87. package/src/index.ts +23 -18
  88. package/src/lib.ts +31 -31
  89. package/src/modular/build-project-files.ts +11 -4
  90. package/src/modular/build-restore-poller.ts +2 -2
  91. package/src/modular/build-root-index.ts +5 -6
  92. package/src/modular/build-subpath-index.ts +4 -4
  93. package/src/modular/emit-models-options.ts +2 -2
  94. package/src/modular/emit-models.ts +2 -3
  95. package/src/modular/emit-samples.ts +3 -4
  96. package/src/modular/emit-tests.ts +7 -3
  97. package/src/modular/helpers/example-value-helpers.ts +4 -4
  98. package/src/rlc-common/build-client-definitions.ts +2 -2
  99. package/src/rlc-common/build-client.ts +3 -3
  100. package/src/rlc-common/build-index-file.ts +2 -2
  101. package/src/rlc-common/build-is-unexpected-helper.ts +2 -2
  102. package/src/rlc-common/build-logger.ts +2 -2
  103. package/src/rlc-common/build-paginate-helper.ts +2 -2
  104. package/src/rlc-common/build-parameter-types.ts +2 -2
  105. package/src/rlc-common/build-polling-helper.ts +2 -2
  106. package/src/rlc-common/build-response-types.ts +2 -2
  107. package/src/rlc-common/build-samples.ts +2 -2
  108. package/src/rlc-common/build-schema-type.ts +3 -3
  109. package/src/rlc-common/build-serialize-helper.ts +2 -2
  110. package/src/rlc-common/build-top-level-index-file.ts +2 -2
  111. package/src/rlc-common/helpers/path-utils.ts +1 -3
  112. package/src/rlc-common/metadata/build-readme-file.ts +7 -7
  113. package/src/transform/transform.ts +2 -3
  114. package/src/utils/emit-util.ts +3 -4
  115. package/src/utils/file-system-utils.ts +3 -4
  116. package/src/utils/import-helper.ts +3 -3
  117. package/src/utils/resolve-project-root.ts +1 -3
  118. package/dist/src/utils/dirname.d.ts +0 -9
  119. package/dist/src/utils/dirname.d.ts.map +0 -1
  120. package/dist/src/utils/dirname.js +0 -12
  121. package/dist/src/utils/dirname.js.map +0 -1
  122. package/src/utils/dirname.ts +0 -12
package/package.json CHANGED
@@ -1,32 +1,32 @@
1
1
  {
2
2
  "name": "@azure-tools/typespec-ts",
3
- "version": "0.55.0-dev.2",
3
+ "version": "0.55.0-dev.3",
4
4
  "description": "An experimental TypeSpec emitter for TypeScript RLC",
5
5
  "main": "dist/src/index.js",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  ".": {
9
- "default": "./dist/src/index.js",
10
- "types": "./dist/src/index.d.ts"
9
+ "types": "./dist/src/index.d.ts",
10
+ "default": "./dist/src/index.js"
11
11
  },
12
12
  "./testing": {
13
- "default": "./dist/src/testing/index.js",
14
- "types": "./dist/src/testing/index.d.ts"
13
+ "types": "./dist/src/testing/index.d.ts",
14
+ "default": "./dist/src/testing/index.js"
15
15
  }
16
16
  },
17
17
  "author": "Jose Heredia <joheredi@microsoft.com>",
18
18
  "license": "MIT",
19
19
  "devDependencies": {
20
20
  "@azure-rest/core-client": "^2.3.1",
21
- "@typespec/http-specs": "^0.1.0-alpha.37 || >=0.1.0-alpha.38-dev <0.1.0-alpha.38",
21
+ "@typespec/http-specs": "^0.1.0-alpha.38 || >=0.1.0-alpha.39-dev <0.1.0-alpha.39",
22
22
  "@typespec/spector": "^0.1.0-alpha.25 || >=0.1.0-alpha.26-dev <0.1.0-alpha.26",
23
23
  "@typespec/spec-api": "^0.1.0-alpha.14 || >=0.1.0-alpha.15-dev <0.1.0-alpha.15",
24
- "@typespec/tspd": "^0.74.2 || >=0.75.0-dev <0.75.0",
25
- "@azure-tools/azure-http-specs": "^0.1.0-alpha.40 || >=0.1.0-alpha.41-dev <0.1.0-alpha.41",
26
- "@azure-tools/typespec-autorest": "^0.68.0 || >=0.69.0-dev <0.69.0",
27
- "@azure-tools/typespec-azure-core": "^0.68.0 || >=0.69.0-dev <0.69.0",
28
- "@azure-tools/typespec-azure-resource-manager": "^0.68.0 || >=0.69.0-dev <0.69.0",
29
- "@azure-tools/typespec-client-generator-core": "^0.68.4 || >=0.69.0-dev <0.69.0",
24
+ "@typespec/tspd": "^0.75.0 || >=0.76.0-dev <0.76.0",
25
+ "@azure-tools/azure-http-specs": "^0.1.0-alpha.42 || >=0.1.0-alpha.43-dev <0.1.0-alpha.43",
26
+ "@azure-tools/typespec-autorest": "^0.69.0 || >=0.70.0-dev <0.70.0",
27
+ "@azure-tools/typespec-azure-core": "^0.69.0 || >=0.70.0-dev <0.70.0",
28
+ "@azure-tools/typespec-azure-resource-manager": "^0.69.0 || >=0.70.0-dev <0.70.0",
29
+ "@azure-tools/typespec-client-generator-core": "^0.69.0 || >=0.70.0-dev <0.70.0",
30
30
  "@azure/abort-controller": "^2.1.2",
31
31
  "@azure/core-auth": "^1.6.0",
32
32
  "@azure/core-lro": "^3.1.0",
@@ -34,12 +34,12 @@
34
34
  "@azure/core-rest-pipeline": "^1.14.0",
35
35
  "@azure/core-util": "^1.4.0",
36
36
  "@azure/logger": "^1.0.4",
37
- "@typespec/compiler": "^1.12.0",
38
- "@typespec/http": "^1.12.0",
39
- "@typespec/openapi": "^1.12.0",
40
- "@typespec/rest": "^0.82.0 || >=0.83.0-dev <0.83.0",
41
- "@typespec/versioning": "^0.82.0 || >=0.83.0-dev <0.83.0",
42
- "@typespec/xml": "^0.82.0 || >=0.83.0-dev <0.83.0",
37
+ "@typespec/compiler": "^1.13.0",
38
+ "@typespec/http": "^1.13.0",
39
+ "@typespec/openapi": "^1.13.0",
40
+ "@typespec/rest": "^0.83.0 || >=0.84.0-dev <0.84.0",
41
+ "@typespec/versioning": "^0.83.0 || >=0.84.0-dev <0.84.0",
42
+ "@typespec/xml": "^0.83.0 || >=0.84.0-dev <0.84.0",
43
43
  "@typespec/ts-http-runtime": "0.3.5",
44
44
  "cross-env": "^10.1.0",
45
45
  "mkdirp": "^3.0.1",
@@ -53,13 +53,13 @@
53
53
  "yaml": "^2.8.3"
54
54
  },
55
55
  "peerDependencies": {
56
- "@azure-tools/typespec-azure-core": "^0.68.0 || >=0.69.0-dev <0.69.0",
57
- "@azure-tools/typespec-client-generator-core": "^0.68.4 || >=0.69.0-dev <0.69.0",
58
- "@typespec/compiler": "^1.12.0",
59
- "@typespec/http": "^1.12.0",
60
- "@typespec/rest": "^0.82.0 || >=0.83.0-dev <0.83.0",
61
- "@typespec/versioning": "^0.82.0 || >=0.83.0-dev <0.83.0",
62
- "@typespec/xml": "^0.82.0 || >=0.83.0-dev <0.83.0"
56
+ "@azure-tools/typespec-azure-core": "^0.69.0 || >=0.70.0-dev <0.70.0",
57
+ "@azure-tools/typespec-client-generator-core": "^0.69.0 || >=0.70.0-dev <0.70.0",
58
+ "@typespec/compiler": "^1.13.0",
59
+ "@typespec/http": "^1.13.0",
60
+ "@typespec/rest": "^0.83.0 || >=0.84.0-dev <0.84.0",
61
+ "@typespec/versioning": "^0.83.0 || >=0.84.0-dev <0.84.0",
62
+ "@typespec/xml": "^0.83.0 || >=0.84.0-dev <0.84.0"
63
63
  },
64
64
  "dependencies": {
65
65
  "fast-xml-parser": "^5.7.0",
@@ -127,6 +127,6 @@
127
127
  "unit-test": "npm-run-all --parallel unit-test:rlc unit-test:modular",
128
128
  "unit-test:rlc": "vitest run --project unit-rlc",
129
129
  "unit-test:modular": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vitest run --project unit-modular",
130
- "regen-docs": "npm run build && tspd doc . --enable-experimental --output-dir ./website/src/content/docs/docs/emitters/clients/typespec-ts/reference --skip-js"
130
+ "regen-docs": "npm run build && tspd doc . --enable-experimental --output-dir ../../website/src/content/docs/docs/emitters/clients/typespec-ts/reference --skip-js"
131
131
  }
132
132
  }
@@ -1,5 +1,4 @@
1
- import { normalizePath } from "@typespec/compiler";
2
- import path from "path/posix";
1
+ import { joinPaths, normalizePath } from "@typespec/compiler";
3
2
  import {
4
3
  ImportDeclarationStructure,
5
4
  ImportSpecifierStructure,
@@ -354,7 +353,7 @@ class BinderImp implements Binder {
354
353
 
355
354
  // Also keep files that are imported by any used helper file
356
355
  const helperFiles = this.project.getSourceFiles(
357
- normalizePath(path.join(sourceRoot, "static-helpers/**/*.*ts")),
356
+ normalizePath(joinPaths(sourceRoot, "static-helpers/**/*.*ts")),
358
357
  );
359
358
  const usedFiles = helperFiles.filter((file) => !isFileUnused(file, usedHelperNames));
360
359
  for (const usedFile of usedFiles) {
@@ -378,7 +377,7 @@ class BinderImp implements Binder {
378
377
  }
379
378
  this.project
380
379
  //normalizae the final path to adapt to different systems
381
- .getSourceFiles(normalizePath(path.join(testRoot, "test/generated/util/**/*.*ts")))
380
+ .getSourceFiles(normalizePath(joinPaths(testRoot, "test/generated/util/**/*.*ts")))
382
381
  .filter((file) => isFileUnused(file, usedHelperNames))
383
382
  .forEach((helperFile) => helperFile.delete());
384
383
  }
@@ -1,6 +1,5 @@
1
- import { NoTarget, Program } from "@typespec/compiler";
1
+ import { joinPaths, NoTarget, Program } from "@typespec/compiler";
2
2
  import { readdir, readFile, stat } from "fs/promises";
3
- import * as path from "path";
4
3
  import {
5
4
  ClassDeclaration,
6
5
  EnumDeclaration,
@@ -55,7 +54,7 @@ export async function loadStaticHelpers(
55
54
  ): Promise<Map<string, StaticHelperMetadata>> {
56
55
  const helpersMap = new Map<string, StaticHelperMetadata>();
57
56
  // Load static helpers used in sources code
58
- const defaultStaticHelpersPath = path.join(
57
+ const defaultStaticHelpersPath = joinPaths(
59
58
  resolveProjectRoot(),
60
59
  DEFAULT_SOURCES_STATIC_HELPERS_PATH,
61
60
  );
@@ -69,7 +68,7 @@ export async function loadStaticHelpers(
69
68
  options.loadTestHelpers ??
70
69
  (options.options?.generateTest && isAzurePackage({ options: options.options }))
71
70
  ) {
72
- const defaultTestingHelpersPath = path.join(
71
+ const defaultTestingHelpersPath = joinPaths(
73
72
  resolveProjectRoot(),
74
73
  DEFAULT_SOURCES_TESTING_HELPERS_PATH,
75
74
  );
@@ -86,7 +85,7 @@ export async function loadStaticHelpers(
86
85
 
87
86
  async function loadFiles(files: FileMetadata[], generateDir: string) {
88
87
  for (const file of files) {
89
- const targetPath = path.join(generateDir, file.target);
88
+ const targetPath = joinPaths(generateDir, file.target);
90
89
  const contents = await readFile(file.source, "utf-8");
91
90
  const addedFile = project.createSourceFile(targetPath, contents, {
92
91
  overwrite: true,
@@ -200,7 +199,7 @@ async function traverseDirectory(
200
199
 
201
200
  await Promise.all(
202
201
  files.map(async (file) => {
203
- const filePath = path.join(directory, file);
202
+ const filePath = joinPaths(directory, file);
204
203
  const fileStat = await stat(filePath);
205
204
 
206
205
  if (fileStat.isDirectory()) {
@@ -208,11 +207,11 @@ async function traverseDirectory(
208
207
  filePath,
209
208
  program,
210
209
  result,
211
- path.join(relativePath, file),
210
+ joinPaths(relativePath, file),
212
211
  targetBaseDir,
213
212
  );
214
213
  } else if (fileStat.isFile() && !file.endsWith(".d.ts") && /.*\..?ts$/.test(file)) {
215
- const target = path.join(targetBaseDir, relativePath, file);
214
+ const target = joinPaths(targetBaseDir, relativePath, file);
216
215
  result.push({ source: filePath, target });
217
216
  }
218
217
  }),
package/src/index.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
 
4
- import { EmitContext, Program } from "@typespec/compiler";
4
+ import { EmitContext, Program, getBaseFileName, joinPaths } from "@typespec/compiler";
5
+ import { existsSync } from "fs";
5
6
  import { provideContext, useContext } from "./context-manager.js";
6
7
  import { buildRootIndex, buildSubClientIndexFile } from "./modular/build-root-index.js";
7
8
  import {
@@ -79,8 +80,6 @@ import {
79
80
  createSdkContext,
80
81
  listAllServiceNamespaces,
81
82
  } from "@azure-tools/typespec-client-generator-core";
82
- import { existsSync } from "fs";
83
- import { basename, join } from "path";
84
83
  import { Project } from "ts-morph";
85
84
  import { provideBinder } from "./framework/hooks/binder.js";
86
85
  import { provideSdkTypes } from "./framework/hooks/sdk-types.js";
@@ -220,7 +219,7 @@ export async function $onEmit(context: EmitContext) {
220
219
  await clearDirectory(context.emitterOutputDir, ["TempTypeSpecFiles"], program);
221
220
  }
222
221
  const hasTestFolder = await pathExists(
223
- join(dpgContext.generationPathDetail?.metadataDir ?? "", "test"),
222
+ joinPaths(dpgContext.generationPathDetail?.metadataDir ?? "", "test"),
224
223
  );
225
224
  options.generateTest =
226
225
  options.generateTest === true ||
@@ -232,15 +231,15 @@ export async function $onEmit(context: EmitContext) {
232
231
 
233
232
  async function calculateGenerationDir(): Promise<GenerationDirDetail> {
234
233
  const projectRoot = context.emitterOutputDir ?? "";
235
- const customizationFolder = join(projectRoot, "generated");
236
- const srcGeneratedFolder = join(projectRoot, "src", "generated");
234
+ const customizationFolder = joinPaths(projectRoot, "generated");
235
+ const srcGeneratedFolder = joinPaths(projectRoot, "src", "generated");
237
236
  // if customization folder exists, use it as sources root
238
237
  const finalCustomizationFolder = (await pathExists(srcGeneratedFolder))
239
238
  ? srcGeneratedFolder
240
239
  : customizationFolder;
241
240
  const sourcesRoot = (await pathExists(finalCustomizationFolder))
242
241
  ? finalCustomizationFolder
243
- : join(projectRoot, "src");
242
+ : joinPaths(projectRoot, "src");
244
243
  return {
245
244
  rootDir: projectRoot,
246
245
  metadataDir: projectRoot,
@@ -259,7 +258,10 @@ export async function $onEmit(context: EmitContext) {
259
258
 
260
259
  async function clearSamplesDevFolder() {
261
260
  if (emitterOptions["generate-sample"] === true) {
262
- const samplesDevPath = join(dpgContext.generationPathDetail?.rootDir ?? "", "samples-dev");
261
+ const samplesDevPath = joinPaths(
262
+ dpgContext.generationPathDetail?.rootDir ?? "",
263
+ "samples-dev",
264
+ );
263
265
  if (await pathExists(samplesDevPath)) {
264
266
  await emptyDir(samplesDevPath);
265
267
  }
@@ -316,7 +318,7 @@ export async function $onEmit(context: EmitContext) {
316
318
  // platform-types (and its browser/react-native variants); emit those
317
319
  // files directly under src/ (strip the static-helpers/ segment) to match
318
320
  // the RLC design where all generated output lives in src/.
319
- if (!basename(filePath).startsWith("platform-types")) {
321
+ if (!getBaseFileName(filePath).startsWith("platform-types")) {
320
322
  continue;
321
323
  }
322
324
  const outputPath = filePath.replace(/\/static-helpers\//g, "/");
@@ -450,27 +452,30 @@ export async function $onEmit(context: EmitContext) {
450
452
  // to avoid unexpected modifications to files like package.json, README.md,
451
453
  // warp.config.yml, and snippets.spec.ts. metadata.json is still updated.
452
454
  const sourcesDir = dpgContext.generationPathDetail?.modularSourcesDir ?? "";
453
- const hasManualConvenienceLayer = basename(sourcesDir) === "generated";
455
+ const hasManualConvenienceLayer = getBaseFileName(sourcesDir) === "generated";
454
456
  const isAzureFlavor = isAzurePackage({ options: option });
455
457
  // Generate metadata
456
- const existingPackageFilePath = join(
458
+ const existingPackageFilePath = joinPaths(
457
459
  dpgContext.generationPathDetail?.metadataDir ?? "",
458
460
  "package.json",
459
461
  );
460
- const hasPackageFile = await existsSync(existingPackageFilePath);
461
- const existingReadmeFilePath = join(
462
+ const hasPackageFile = existsSync(existingPackageFilePath);
463
+ const existingReadmeFilePath = joinPaths(
462
464
  dpgContext.generationPathDetail?.metadataDir ?? "",
463
465
  "README.md",
464
466
  );
465
- const hasReadmeFile = await existsSync(existingReadmeFilePath);
466
- const existingChangelogFilePath = join(
467
+ const hasReadmeFile = existsSync(existingReadmeFilePath);
468
+ const existingChangelogFilePath = joinPaths(
467
469
  dpgContext.generationPathDetail?.metadataDir ?? "",
468
470
  "CHANGELOG.md",
469
471
  );
470
- const hasChangelogFile = await existsSync(existingChangelogFilePath);
472
+ const hasChangelogFile = existsSync(existingChangelogFilePath);
471
473
  const shouldGenerateMetadata = option.generateMetadata === true || !hasPackageFile;
472
- const existingTestFolderPath = join(dpgContext.generationPathDetail?.metadataDir ?? "", "test");
473
- const hasTestFolder = await existsSync(existingTestFolderPath);
474
+ const existingTestFolderPath = joinPaths(
475
+ dpgContext.generationPathDetail?.metadataDir ?? "",
476
+ "test",
477
+ );
478
+ const hasTestFolder = existsSync(existingTestFolderPath);
474
479
  if (option.generateTest === undefined) {
475
480
  if (hasTestFolder) {
476
481
  option.generateTest = false;
package/src/lib.ts CHANGED
@@ -145,18 +145,18 @@ export const RLCOptionsSchema: JSONSchemaType<EmitterOptions> = {
145
145
  "add-credentials": {
146
146
  type: "boolean",
147
147
  nullable: true,
148
- description: `
149
- We support two types of authentication: Azure Key Credential(AzureKey) and Token credential(AADToken), any other will need to be handled manually.
150
-
151
- There are two ways to set up our credential details
152
-
153
- - To use \`@useAuth\` decorator in TypeSpec
154
- - To config in yaml file
155
-
156
- Please notice defining in TypeSpec is recommended and also has higher priority than second one.
157
-
158
- To enable credential in \`tspconfig.yaml\` and we need to provide more details to let codegen know types.
159
- `,
148
+ description: [
149
+ "We support two types of authentication: Azure Key Credential(AzureKey) and Token credential(AADToken), any other will need to be handled manually.",
150
+ "",
151
+ "There are two ways to set up our credential details",
152
+ "",
153
+ "- To use `@useAuth` decorator in TypeSpec",
154
+ "- To config in yaml file",
155
+ "",
156
+ "Please notice defining in TypeSpec is recommended and also has higher priority than second one.",
157
+ "",
158
+ "To enable credential in `tspconfig.yaml` and we need to provide more details to let codegen know types.",
159
+ ].join("\n"),
160
160
  },
161
161
  "credential-scopes": {
162
162
  type: "array",
@@ -186,20 +186,19 @@ export const RLCOptionsSchema: JSONSchemaType<EmitterOptions> = {
186
186
  "generate-metadata": {
187
187
  type: "boolean",
188
188
  nullable: true,
189
- description: `
190
- Whether to generate metadata files which includes package.json, README.md and tsconfig.json etc. Defaults to \`undefined\`. If there's not a package.json under package-dir, defaults to \`true\`. but if you'd like to disable this feature you could set it as \`false\`.
191
- `,
189
+ description:
190
+ "Whether to generate metadata files which includes package.json, README.md and tsconfig.json etc. Defaults to `undefined`. If there's not a package.json under package-dir, defaults to `true`. but if you'd like to disable this feature you could set it as `false`.",
192
191
  },
193
192
  "generate-test": {
194
193
  type: "boolean",
195
194
  nullable: true,
196
- description: `
197
- Whether to generate test files, for basic testing of your generated sdks. Defaults to \`undefined\`.
198
- other cases:
199
- - If azure-sdk-for-js is \`false\`. Defaults to \`false\`.
200
- - If azure-sdk-for-js is \`true\` but there's a test folder under package-dir. Defaults to \`false\`.
201
- - If azure-sdk-for-js is \`true\` but there's not a test folder under package-dir. Defaults to \`true\`.
202
- `,
195
+ description: [
196
+ "Whether to generate test files, for basic testing of your generated sdks. Defaults to `undefined`.",
197
+ "other cases:",
198
+ "- If azure-sdk-for-js is `false`. Defaults to `false`.",
199
+ "- If azure-sdk-for-js is `true` but there's a test folder under package-dir. Defaults to `false`.",
200
+ "- If azure-sdk-for-js is `true` but there's not a test folder under package-dir. Defaults to `true`.",
201
+ ].join("\n"),
203
202
  },
204
203
  "generate-sample": {
205
204
  type: "boolean",
@@ -359,15 +358,16 @@ export const RLCOptionsSchema: JSONSchemaType<EmitterOptions> = {
359
358
  },
360
359
  required: [],
361
360
  nullable: true,
362
- description: `Only for Modular generation
363
- By default, code generation uses the titles specified in the \`@client\` and \`@service\` decorators in TypeSpec to name modular clients. If you need to override these names, you can configure the \`typespec-title-map\`. The map's keys represent the original client names from TypeSpec, and the values are the desired client names. This configuration supports renaming multiple clients.
364
-
365
- \`\`\`yaml
366
- typespec-title-map:
367
- AnomalyDetectorClient: AnomalyDetectorRest
368
- AnomalyDetectorClient2: AnomalyDetectorRest2
369
- \`\`\`
370
- `,
361
+ description: [
362
+ "Only for Modular generation",
363
+ "By default, code generation uses the titles specified in the `@client` and `@service` decorators in TypeSpec to name modular clients. If you need to override these names, you can configure the `typespec-title-map`. The map's keys represent the original client names from TypeSpec, and the values are the desired client names. This configuration supports renaming multiple clients.",
364
+ "",
365
+ "```yaml",
366
+ "typespec-title-map:",
367
+ " AnomalyDetectorClient: AnomalyDetectorRest",
368
+ " AnomalyDetectorClient2: AnomalyDetectorRest2",
369
+ "```",
370
+ ].join("\n"),
371
371
  },
372
372
  "should-use-pnpm-dep": {
373
373
  type: "boolean",
@@ -1,6 +1,6 @@
1
1
  import { NameType } from "../rlc-common/index.js";
2
2
 
3
- import path from "path/posix";
3
+ import { getRelativePathFromDirectory, joinPaths } from "@typespec/compiler";
4
4
  import { useContext } from "../context-manager.js";
5
5
  import { getClientHierarchyMap, getModularClientOptions } from "../utils/client-utils.js";
6
6
  import { SdkContext } from "../utils/interfaces.js";
@@ -19,7 +19,10 @@ function getSourceRootPrefix(emitterOptions: ModularEmitterOptions, context: Sdk
19
19
  const rootDir = (context.generationPathDetail?.rootDir ?? "").replace(/\\/g, "/");
20
20
 
21
21
  if (rootDir && sourceRoot.startsWith(rootDir)) {
22
- const relativePath = path.relative(rootDir, sourceRoot).replace(/\\/g, "/");
22
+ const relativePath = getRelativePathFromDirectory(rootDir, sourceRoot, false).replace(
23
+ /\\/g,
24
+ "/",
25
+ );
23
26
  return `./${relativePath}`;
24
27
  }
25
28
 
@@ -95,7 +98,7 @@ export function getModuleExports(context: SdkContext, emitterOptions: ModularEmi
95
98
  function getModelSubpaths(emitterOptions: ModularEmitterOptions) {
96
99
  const outputProject = useContext("outputProject");
97
100
  const modelFiles = outputProject.getSourceFiles(
98
- path.join(emitterOptions.modularOptions.sourceRoot.replace(/\\/g, "/"), `models/**/*.ts`),
101
+ joinPaths(emitterOptions.modularOptions.sourceRoot.replace(/\\/g, "/"), `models/**/*.ts`),
99
102
  );
100
103
  const subpath = new Set<string>();
101
104
  for (const modelFile of modelFiles) {
@@ -104,7 +107,11 @@ function getModelSubpaths(emitterOptions: ModularEmitterOptions) {
104
107
  continue;
105
108
  }
106
109
  subpath.add(
107
- path.relative(emitterOptions.modularOptions.sourceRoot.replace(/\\/g, "/"), filepath),
110
+ getRelativePathFromDirectory(
111
+ emitterOptions.modularOptions.sourceRoot.replace(/\\/g, "/"),
112
+ filepath,
113
+ false,
114
+ ),
108
115
  );
109
116
  }
110
117
  return Array.from(subpath);
@@ -1,5 +1,5 @@
1
1
  import { SdkClientType, SdkServiceOperation } from "@azure-tools/typespec-client-generator-core";
2
- import path from "path";
2
+ import { joinPaths } from "@typespec/compiler";
3
3
  import { SourceFile } from "ts-morph";
4
4
  import { useContext } from "../context-manager.js";
5
5
  import { useDependencies } from "../framework/hooks/use-dependencies.js";
@@ -32,7 +32,7 @@ export function buildRestorePoller(
32
32
  return;
33
33
  }
34
34
  const srcPath = emitterOptions.modularOptions.sourceRoot;
35
- const filePath = path.join(
35
+ const filePath = joinPaths(
36
36
  `${srcPath}/${subfolder && subfolder !== "" ? subfolder + "/" : ""}restorePollerHelpers.ts`,
37
37
  );
38
38
  const restorePollerFile = project.createSourceFile(filePath, undefined, {
@@ -1,6 +1,5 @@
1
1
  import { SdkClientType, SdkServiceOperation } from "@azure-tools/typespec-client-generator-core";
2
- import { NoTarget } from "@typespec/compiler";
3
- import { join } from "path/posix";
2
+ import { joinPaths, NoTarget } from "@typespec/compiler";
4
3
  import { Project, SourceFile } from "ts-morph";
5
4
  import { useContext } from "../context-manager.js";
6
5
  import { resolveReference } from "../framework/reference.js";
@@ -298,7 +297,7 @@ function exportModules(
298
297
  .getDirectories()
299
298
  .filter((dir) => {
300
299
  const formattedDir = dir.getPath().replace(/\\/g, "/");
301
- const targetPath = join(srcPath, subfolder, moduleName).replace(/\\/g, "/");
300
+ const targetPath = joinPaths(srcPath, subfolder, moduleName).replace(/\\/g, "/");
302
301
  return formattedDir.startsWith(targetPath);
303
302
  })
304
303
  .map((dir) => {
@@ -309,17 +308,17 @@ function exportModules(
309
308
  .getDirectories()
310
309
  .filter((dir) => {
311
310
  const formattedDir = dir.getPath().replace(/\\/g, "/");
312
- const targetPath = join(srcPath, subfolder, moduleName).replace(/\\/g, "/");
311
+ const targetPath = joinPaths(srcPath, subfolder, moduleName).replace(/\\/g, "/");
313
312
  return formattedDir.startsWith(targetPath);
314
313
  })
315
314
  .map((dir) => {
316
315
  return dir.getPath().replace(/\\/g, "/");
317
316
  });
318
317
  } else {
319
- folders = [join(srcPath, subfolder, moduleName).replace(/\\/g, "/")];
318
+ folders = [joinPaths(srcPath, subfolder, moduleName).replace(/\\/g, "/")];
320
319
  }
321
320
  for (const folder of folders) {
322
- const apiFilePattern = join(folder, "index.ts").replace(/\\/g, "/");
321
+ const apiFilePattern = joinPaths(folder, "index.ts").replace(/\\/g, "/");
323
322
  const modelsFile = project.getSourceFile(apiFilePattern);
324
323
  if (!modelsFile) {
325
324
  continue;
@@ -1,7 +1,7 @@
1
1
  import { SdkClientType, SdkServiceOperation } from "@azure-tools/typespec-client-generator-core";
2
+ import { joinPaths } from "@typespec/compiler";
2
3
  import { ModularEmitterOptions } from "./interfaces.js";
3
4
 
4
- import { join } from "path";
5
5
  import { Node, SourceFile } from "ts-morph";
6
6
  import { useContext } from "../context-manager.js";
7
7
  import { getModularClientOptions } from "../utils/client-utils.js";
@@ -29,7 +29,7 @@ export function buildSubpathIndexFile(
29
29
  .getDirectories()
30
30
  .filter((dir) => {
31
31
  const formattedDir = dir.getPath().replace(/\\/g, "/");
32
- const targetPath = join(srcPath, subfolder, subpath).replace(/\\/g, "/");
32
+ const targetPath = joinPaths(srcPath, subfolder, subpath).replace(/\\/g, "/");
33
33
  return (
34
34
  formattedDir.startsWith(targetPath) && !project.getSourceFile(`${formattedDir}/index.ts`)
35
35
  );
@@ -38,10 +38,10 @@ export function buildSubpathIndexFile(
38
38
  return dir.getPath().replace(/\\/g, "/");
39
39
  });
40
40
  } else {
41
- folders = [join(srcPath, subfolder, subpath).replace(/\\/g, "/")];
41
+ folders = [joinPaths(srcPath, subfolder, subpath).replace(/\\/g, "/")];
42
42
  }
43
43
  for (const folder of folders) {
44
- const apiFilePattern = subpath === "models" ? join(folder, "models.ts") : folder;
44
+ const apiFilePattern = subpath === "models" ? joinPaths(folder, "models.ts") : folder;
45
45
  const apiFiles = project.getSourceFiles().filter((file) => {
46
46
  if (subpath === "api" && options.recursive) {
47
47
  return file.getDirectoryPath().replace(/\\/g, "/") === apiFilePattern.replace(/\\/g, "/");
@@ -1,4 +1,4 @@
1
- import * as path from "path";
1
+ import { joinPaths } from "@typespec/compiler";
2
2
 
3
3
  import { ModularEmitterOptions } from "./interfaces.js";
4
4
 
@@ -25,7 +25,7 @@ export function buildApiOptions(
25
25
  for (const [prefixKey, operations] of methodMap) {
26
26
  const prefixes = prefixKey.split("/");
27
27
  const modelOptionsFile = project.createSourceFile(
28
- path.join(
28
+ joinPaths(
29
29
  emitterOptions.modularOptions.sourceRoot,
30
30
  subfolder ?? "",
31
31
  `api`,
@@ -36,9 +36,8 @@ import {
36
36
  getMultipartFileTypeExpression,
37
37
  } from "./type-expressions/get-model-expression.js";
38
38
 
39
- import { getNamespaceFullName, NoTarget } from "@typespec/compiler";
39
+ import { getNamespaceFullName, joinPaths, NoTarget } from "@typespec/compiler";
40
40
  import { isMetadata, isOrExtendsHttpFile, Visibility } from "@typespec/http";
41
- import path from "path";
42
41
  import { useContext } from "../context-manager.js";
43
42
  import { addDeclaration } from "../framework/declaration.js";
44
43
  import {
@@ -304,7 +303,7 @@ export function getApiVersionEnum(context: SdkContext) {
304
303
  }
305
304
 
306
305
  export function getModelsPath(sourceRoot: string, modelNamespace: string[] = []): string {
307
- return path.join(
306
+ return joinPaths(
308
307
  ...[
309
308
  sourceRoot,
310
309
  "models",
@@ -8,8 +8,7 @@ import {
8
8
  SdkModelPropertyType,
9
9
  SdkServiceOperation,
10
10
  } from "@azure-tools/typespec-client-generator-core";
11
- import { NoTarget } from "@typespec/compiler";
12
- import { join } from "path";
11
+ import { joinPaths, NoTarget } from "@typespec/compiler";
13
12
  import { FunctionDeclarationStructure, SourceFile, StructureKind } from "ts-morph";
14
13
  import { useContext } from "../context-manager.js";
15
14
  import { resolveReference } from "../framework/reference.js";
@@ -105,13 +104,13 @@ function emitMethodSamples(
105
104
  }
106
105
  const project = useContext("outputProject");
107
106
  const operationPrefix = `${options.classicalMethodPrefix ?? ""} ${method.oriName ?? method.name}`;
108
- const sampleFolder = join(
107
+ const sampleFolder = joinPaths(
109
108
  dpgContext.generationPathDetail?.rootDir ?? "",
110
109
  "samples-dev",
111
110
  options.subFolder ?? "",
112
111
  );
113
112
  const fileName = normalizeName(`${operationPrefix} Sample`, NameType.File);
114
- const sourceFile = project.createSourceFile(join(sampleFolder, `${fileName}.ts`), "", {
113
+ const sourceFile = project.createSourceFile(joinPaths(sampleFolder, `${fileName}.ts`), "", {
115
114
  overwrite: true,
116
115
  });
117
116
  const exampleFunctions = [];
@@ -1,5 +1,5 @@
1
+ import { joinPaths } from "@typespec/compiler";
1
2
  import { existsSync, rmSync } from "fs";
2
- import { join } from "path";
3
3
  import { SourceFile } from "ts-morph";
4
4
  import { resolveReference } from "../framework/reference.js";
5
5
  import { NameType, normalizeName } from "../rlc-common/index.js";
@@ -24,13 +24,17 @@ import { CreateRecorderHelpers } from "./static-helpers-metadata.js";
24
24
  */
25
25
  async function cleanupTestFolder(dpgContext: SdkContext) {
26
26
  const clients = dpgContext.sdkPackage.clients;
27
- const baseTestFolder = join(dpgContext.generationPathDetail?.rootDir ?? "", "test", "generated");
27
+ const baseTestFolder = joinPaths(
28
+ dpgContext.generationPathDetail?.rootDir ?? "",
29
+ "test",
30
+ "generated",
31
+ );
28
32
 
29
33
  // If there are multiple clients, clean up subfolders
30
34
  if (clients.length > 1) {
31
35
  for (const client of clients) {
32
36
  const subFolder = normalizeName(getClassicalClientName(client), NameType.File);
33
- const clientTestFolder = join(baseTestFolder, subFolder);
37
+ const clientTestFolder = joinPaths(baseTestFolder, subFolder);
34
38
  if (existsSync(clientTestFolder)) {
35
39
  rmSync(clientTestFolder, { recursive: true, force: true });
36
40
  }
@@ -8,7 +8,7 @@ import {
8
8
  SdkModelPropertyType,
9
9
  SdkServiceOperation,
10
10
  } from "@azure-tools/typespec-client-generator-core";
11
- import { join } from "path";
11
+ import { joinPaths } from "@typespec/compiler";
12
12
  import { SourceFile } from "ts-morph";
13
13
  import { useContext } from "../../context-manager.js";
14
14
  import { resolveReference } from "../../framework/reference.js";
@@ -596,8 +596,8 @@ export function createSourceFile(
596
596
  ): SourceFile {
597
597
  const project = useContext("outputProject");
598
598
  const operationPrefix = `${options.classicalMethodPrefix ?? ""} ${method.oriName ?? method.name}`;
599
- const baseFolder = type === "sample" ? "samples-dev" : join("test", "generated");
600
- const folder = join(
599
+ const baseFolder = type === "sample" ? "samples-dev" : joinPaths("test", "generated");
600
+ const folder = joinPaths(
601
601
  dpgContext.generationPathDetail?.rootDir ?? "",
602
602
  baseFolder,
603
603
  options.subFolder ?? "",
@@ -605,7 +605,7 @@ export function createSourceFile(
605
605
  const fileExtension = type === "sample" ? ".ts" : ".spec.ts";
606
606
  const normalizedFileName = normalizeName(fileName || `${operationPrefix} ${type}`, NameType.File);
607
607
 
608
- return project.createSourceFile(join(folder, `${normalizedFileName}${fileExtension}`), "", {
608
+ return project.createSourceFile(joinPaths(folder, `${normalizedFileName}${fileExtension}`), "", {
609
609
  overwrite: true,
610
610
  });
611
611
  }
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
 
4
- import * as path from "path";
4
+ import { joinPaths } from "@typespec/compiler";
5
5
  import {
6
6
  CallSignatureDeclarationStructure,
7
7
  InterfaceDeclarationStructure,
@@ -32,7 +32,7 @@ export function buildClientDefinitions(model: RLCModel) {
32
32
  };
33
33
  const project = new Project();
34
34
  const srcPath = model.srcPath;
35
- const filePath = path.join(srcPath, `clientDefinitions.ts`);
35
+ const filePath = joinPaths(srcPath, `clientDefinitions.ts`);
36
36
  const clientDefinitionsFile = project.createSourceFile(filePath, undefined, {
37
37
  overwrite: true,
38
38
  });