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

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 (145) 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 +4 -1
  6. package/dist/src/framework/load-static-helpers.d.ts.map +1 -1
  7. package/dist/src/framework/load-static-helpers.js +19 -15
  8. package/dist/src/framework/load-static-helpers.js.map +1 -1
  9. package/dist/src/framework/sample.js +1 -1
  10. package/dist/src/framework/sample.js.map +1 -1
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +47 -28
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/lib.js +30 -31
  15. package/dist/src/lib.js.map +1 -1
  16. package/dist/src/modular/build-project-files.d.ts.map +1 -1
  17. package/dist/src/modular/build-project-files.js +4 -4
  18. package/dist/src/modular/build-project-files.js.map +1 -1
  19. package/dist/src/modular/build-restore-poller.js +2 -2
  20. package/dist/src/modular/build-restore-poller.js.map +1 -1
  21. package/dist/src/modular/build-root-index.d.ts.map +1 -1
  22. package/dist/src/modular/build-root-index.js +5 -6
  23. package/dist/src/modular/build-root-index.js.map +1 -1
  24. package/dist/src/modular/build-subpath-index.d.ts.map +1 -1
  25. package/dist/src/modular/build-subpath-index.js +4 -4
  26. package/dist/src/modular/build-subpath-index.js.map +1 -1
  27. package/dist/src/modular/emit-models-options.js +2 -2
  28. package/dist/src/modular/emit-models-options.js.map +1 -1
  29. package/dist/src/modular/emit-models.d.ts.map +1 -1
  30. package/dist/src/modular/emit-models.js +2 -3
  31. package/dist/src/modular/emit-models.js.map +1 -1
  32. package/dist/src/modular/emit-samples.d.ts.map +1 -1
  33. package/dist/src/modular/emit-samples.js +3 -4
  34. package/dist/src/modular/emit-samples.js.map +1 -1
  35. package/dist/src/modular/emit-tests.d.ts +2 -1
  36. package/dist/src/modular/emit-tests.d.ts.map +1 -1
  37. package/dist/src/modular/emit-tests.js +21 -11
  38. package/dist/src/modular/emit-tests.js.map +1 -1
  39. package/dist/src/modular/helpers/example-value-helpers.js +4 -4
  40. package/dist/src/modular/helpers/example-value-helpers.js.map +1 -1
  41. package/dist/src/rlc-common/build-client-definitions.js +3 -3
  42. package/dist/src/rlc-common/build-client-definitions.js.map +1 -1
  43. package/dist/src/rlc-common/build-client.js +4 -4
  44. package/dist/src/rlc-common/build-client.js.map +1 -1
  45. package/dist/src/rlc-common/build-index-file.js +3 -3
  46. package/dist/src/rlc-common/build-index-file.js.map +1 -1
  47. package/dist/src/rlc-common/build-is-unexpected-helper.js +3 -3
  48. package/dist/src/rlc-common/build-is-unexpected-helper.js.map +1 -1
  49. package/dist/src/rlc-common/build-logger.js +3 -3
  50. package/dist/src/rlc-common/build-logger.js.map +1 -1
  51. package/dist/src/rlc-common/build-paginate-helper.js +2 -2
  52. package/dist/src/rlc-common/build-paginate-helper.js.map +1 -1
  53. package/dist/src/rlc-common/build-parameter-types.js +3 -3
  54. package/dist/src/rlc-common/build-parameter-types.js.map +1 -1
  55. package/dist/src/rlc-common/build-polling-helper.js +2 -2
  56. package/dist/src/rlc-common/build-polling-helper.js.map +1 -1
  57. package/dist/src/rlc-common/build-response-types.js +3 -3
  58. package/dist/src/rlc-common/build-response-types.js.map +1 -1
  59. package/dist/src/rlc-common/build-samples.js +2 -2
  60. package/dist/src/rlc-common/build-samples.js.map +1 -1
  61. package/dist/src/rlc-common/build-schema-type.js +4 -4
  62. package/dist/src/rlc-common/build-schema-type.js.map +1 -1
  63. package/dist/src/rlc-common/build-serialize-helper.js +2 -2
  64. package/dist/src/rlc-common/build-serialize-helper.js.map +1 -1
  65. package/dist/src/rlc-common/build-top-level-index-file.js +3 -3
  66. package/dist/src/rlc-common/build-top-level-index-file.js.map +1 -1
  67. package/dist/src/rlc-common/helpers/path-utils.d.ts.map +1 -1
  68. package/dist/src/rlc-common/helpers/path-utils.js +1 -2
  69. package/dist/src/rlc-common/helpers/path-utils.js.map +1 -1
  70. package/dist/src/rlc-common/metadata/build-api-extractor-config.js +1 -1
  71. package/dist/src/rlc-common/metadata/build-api-extractor-config.js.map +1 -1
  72. package/dist/src/rlc-common/metadata/build-es-lint-config.js +1 -1
  73. package/dist/src/rlc-common/metadata/build-es-lint-config.js.map +1 -1
  74. package/dist/src/rlc-common/metadata/build-package-file.js +1 -1
  75. package/dist/src/rlc-common/metadata/build-package-file.js.map +1 -1
  76. package/dist/src/rlc-common/metadata/build-readme-file.d.ts +2 -2
  77. package/dist/src/rlc-common/metadata/build-readme-file.d.ts.map +1 -1
  78. package/dist/src/rlc-common/metadata/build-readme-file.js +11 -14
  79. package/dist/src/rlc-common/metadata/build-readme-file.js.map +1 -1
  80. package/dist/src/rlc-common/metadata/build-rollup-config.js +1 -1
  81. package/dist/src/rlc-common/metadata/build-rollup-config.js.map +1 -1
  82. package/dist/src/rlc-common/metadata/build-ts-config.js +1 -1
  83. package/dist/src/rlc-common/metadata/build-ts-config.js.map +1 -1
  84. package/dist/src/transform/transform.d.ts.map +1 -1
  85. package/dist/src/transform/transform.js +2 -3
  86. package/dist/src/transform/transform.js.map +1 -1
  87. package/dist/src/utils/emit-util.d.ts.map +1 -1
  88. package/dist/src/utils/emit-util.js +10 -5
  89. package/dist/src/utils/emit-util.js.map +1 -1
  90. package/dist/src/utils/file-system-utils.d.ts +4 -4
  91. package/dist/src/utils/file-system-utils.d.ts.map +1 -1
  92. package/dist/src/utils/file-system-utils.js +14 -16
  93. package/dist/src/utils/file-system-utils.js.map +1 -1
  94. package/dist/src/utils/import-helper.js +3 -3
  95. package/dist/src/utils/import-helper.js.map +1 -1
  96. package/dist/src/utils/resolve-project-root.d.ts +6 -4
  97. package/dist/src/utils/resolve-project-root.d.ts.map +1 -1
  98. package/dist/src/utils/resolve-project-root.js +11 -18
  99. package/dist/src/utils/resolve-project-root.js.map +1 -1
  100. package/dist/tsconfig.tsbuildinfo +1 -1
  101. package/package.json +26 -26
  102. package/src/framework/hooks/binder.ts +3 -4
  103. package/src/framework/load-static-helpers.ts +29 -18
  104. package/src/framework/sample.ts +1 -1
  105. package/src/index.ts +61 -28
  106. package/src/lib.ts +31 -31
  107. package/src/modular/build-project-files.ts +11 -4
  108. package/src/modular/build-restore-poller.ts +2 -2
  109. package/src/modular/build-root-index.ts +5 -6
  110. package/src/modular/build-subpath-index.ts +4 -4
  111. package/src/modular/emit-models-options.ts +2 -2
  112. package/src/modular/emit-models.ts +2 -3
  113. package/src/modular/emit-samples.ts +3 -4
  114. package/src/modular/emit-tests.ts +28 -11
  115. package/src/modular/helpers/example-value-helpers.ts +4 -4
  116. package/src/rlc-common/build-client-definitions.ts +3 -3
  117. package/src/rlc-common/build-client.ts +4 -4
  118. package/src/rlc-common/build-index-file.ts +3 -3
  119. package/src/rlc-common/build-is-unexpected-helper.ts +3 -3
  120. package/src/rlc-common/build-logger.ts +3 -3
  121. package/src/rlc-common/build-paginate-helper.ts +2 -2
  122. package/src/rlc-common/build-parameter-types.ts +3 -3
  123. package/src/rlc-common/build-polling-helper.ts +2 -2
  124. package/src/rlc-common/build-response-types.ts +3 -3
  125. package/src/rlc-common/build-samples.ts +2 -2
  126. package/src/rlc-common/build-schema-type.ts +4 -4
  127. package/src/rlc-common/build-serialize-helper.ts +2 -2
  128. package/src/rlc-common/build-top-level-index-file.ts +3 -3
  129. package/src/rlc-common/helpers/path-utils.ts +1 -3
  130. package/src/rlc-common/metadata/build-api-extractor-config.ts +1 -1
  131. package/src/rlc-common/metadata/build-es-lint-config.ts +1 -1
  132. package/src/rlc-common/metadata/build-package-file.ts +1 -1
  133. package/src/rlc-common/metadata/build-readme-file.ts +12 -15
  134. package/src/rlc-common/metadata/build-rollup-config.ts +1 -1
  135. package/src/rlc-common/metadata/build-ts-config.ts +1 -1
  136. package/src/transform/transform.ts +2 -3
  137. package/src/utils/emit-util.ts +10 -8
  138. package/src/utils/file-system-utils.ts +14 -15
  139. package/src/utils/import-helper.ts +3 -3
  140. package/src/utils/resolve-project-root.ts +11 -24
  141. package/dist/src/utils/dirname.d.ts +0 -9
  142. package/dist/src/utils/dirname.d.ts.map +0 -1
  143. package/dist/src/utils/dirname.js +0 -12
  144. package/dist/src/utils/dirname.js.map +0 -1
  145. package/src/utils/dirname.ts +0 -12
@@ -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,4 @@
1
- import { existsSync, rmSync } from "fs";
2
- import { join } from "path";
1
+ import { type CompilerHost, joinPaths } from "@typespec/compiler";
3
2
  import { SourceFile } from "ts-morph";
4
3
  import { resolveReference } from "../framework/reference.js";
5
4
  import { NameType, normalizeName } from "../rlc-common/index.js";
@@ -22,23 +21,36 @@ import { CreateRecorderHelpers } from "./static-helpers-metadata.js";
22
21
  /**
23
22
  * Clean up the test/generated folder before generating new tests
24
23
  */
25
- async function cleanupTestFolder(dpgContext: SdkContext) {
24
+ async function cleanupTestFolder(dpgContext: SdkContext, host: CompilerHost) {
26
25
  const clients = dpgContext.sdkPackage.clients;
27
- const baseTestFolder = join(dpgContext.generationPathDetail?.rootDir ?? "", "test", "generated");
26
+ const baseTestFolder = joinPaths(
27
+ dpgContext.generationPathDetail?.rootDir ?? "",
28
+ "test",
29
+ "generated",
30
+ );
31
+
32
+ async function dirExists(path: string): Promise<boolean> {
33
+ try {
34
+ const s = await host.stat(path);
35
+ return s.isDirectory();
36
+ } catch {
37
+ return false;
38
+ }
39
+ }
28
40
 
29
41
  // If there are multiple clients, clean up subfolders
30
42
  if (clients.length > 1) {
31
43
  for (const client of clients) {
32
44
  const subFolder = normalizeName(getClassicalClientName(client), NameType.File);
33
- const clientTestFolder = join(baseTestFolder, subFolder);
34
- if (existsSync(clientTestFolder)) {
35
- rmSync(clientTestFolder, { recursive: true, force: true });
45
+ const clientTestFolder = joinPaths(baseTestFolder, subFolder);
46
+ if (await dirExists(clientTestFolder)) {
47
+ await host.rm(clientTestFolder, { recursive: true });
36
48
  }
37
49
  }
38
50
  } else {
39
51
  // Single client, clean up the entire test/generated folder
40
- if (existsSync(baseTestFolder)) {
41
- rmSync(baseTestFolder, { recursive: true, force: true });
52
+ if (await dirExists(baseTestFolder)) {
53
+ await host.rm(baseTestFolder, { recursive: true });
42
54
  }
43
55
  }
44
56
  }
@@ -46,9 +58,14 @@ async function cleanupTestFolder(dpgContext: SdkContext) {
46
58
  /**
47
59
  * Helpers to emit tests similar to samples
48
60
  */
49
- export async function emitTests(dpgContext: SdkContext): Promise<SourceFile[]> {
61
+ export async function emitTests(
62
+ dpgContext: SdkContext,
63
+ host?: CompilerHost,
64
+ ): Promise<SourceFile[]> {
50
65
  // Clean up the test/generated folder before generating new tests
51
- await cleanupTestFolder(dpgContext);
66
+ if (host) {
67
+ await cleanupTestFolder(dpgContext, host);
68
+ }
52
69
 
53
70
  return iterateClientsAndMethods(dpgContext, emitMethodTests);
54
71
  }
@@ -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,
@@ -30,9 +30,9 @@ export function buildClientDefinitions(model: RLCModel) {
30
30
  importedResponses: new Set<string>(),
31
31
  clientImports: new Set<string>(),
32
32
  };
33
- const project = new Project();
33
+ const project = new Project({ useInMemoryFileSystem: true });
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
  });
@@ -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
  InterfaceDeclarationStructure,
7
7
  OptionalKind,
@@ -62,8 +62,8 @@ function getClientOptionsInterface(
62
62
  export function buildClient(model: RLCModel): File | undefined {
63
63
  const name = normalizeName(model.libraryName, NameType.File);
64
64
  const { srcPath } = model;
65
- const project = new Project();
66
- const filePath = path.join(srcPath, `${name}.ts`);
65
+ const project = new Project({ useInMemoryFileSystem: true });
66
+ const filePath = joinPaths(srcPath, `${name}.ts`);
67
67
  const clientFile = project.createSourceFile(filePath, undefined, {
68
68
  overwrite: true,
69
69
  });
@@ -171,7 +171,7 @@ export function buildClient(model: RLCModel): File | undefined {
171
171
  }
172
172
  clientFile.addFunction(functionStatement);
173
173
 
174
- const paths = srcPath.replace(/\//g, path.sep).split(path.sep);
174
+ const paths = srcPath.split("/");
175
175
  while (paths.length > 0 && paths[paths.length - 1] === "") {
176
176
  paths.pop();
177
177
  }
@@ -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 { Project, SourceFile } from "ts-morph";
6
6
  import { getImportModuleName } from "./helpers/name-constructors.js";
7
7
  import { NameType, normalizeName } from "./helpers/name-utils.js";
@@ -23,9 +23,9 @@ import { RLCModel } from "./interfaces.js";
23
23
  export function buildIndexFile(model: RLCModel) {
24
24
  const multiClient = Boolean(model.options?.multiClient),
25
25
  batch = model.options?.batch;
26
- const project = new Project();
26
+ const project = new Project({ useInMemoryFileSystem: true });
27
27
  const { srcPath } = model;
28
- const filePath = path.join(srcPath, `index.ts`);
28
+ const filePath = joinPaths(srcPath, `index.ts`);
29
29
  const indexFile = project.createSourceFile(filePath, undefined, {
30
30
  overwrite: true,
31
31
  });
@@ -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
  FunctionDeclarationOverloadStructure,
7
7
  OptionalKind,
@@ -15,9 +15,9 @@ export function buildIsUnexpectedHelper(model: RLCModel) {
15
15
  if (!hasUnexpectedHelper(model)) {
16
16
  return;
17
17
  }
18
- const project = new Project();
18
+ const project = new Project({ useInMemoryFileSystem: true });
19
19
  const srcPath = model.srcPath;
20
- const filePath = path.join(srcPath, `isUnexpected.ts`);
20
+ const filePath = joinPaths(srcPath, `isUnexpected.ts`);
21
21
  const isErrorHelper = project.createSourceFile(filePath, undefined, {
22
22
  overwrite: true,
23
23
  });
@@ -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 { Project } from "ts-morph";
6
6
  import { RLCModel } from "./interfaces.js";
7
7
 
@@ -13,10 +13,10 @@ export function buildLogger(model: RLCModel) {
13
13
  if (model.options.flavor !== "azure") {
14
14
  return undefined;
15
15
  }
16
- const project = new Project();
16
+ const project = new Project({ useInMemoryFileSystem: true });
17
17
  const { srcPath, rlcSourceDir } = model;
18
18
  const { packageDetails } = model.options;
19
- const filePath = path.join(
19
+ const filePath = joinPaths(
20
20
  model.options.sourceFrom === "Swagger"
21
21
  ? srcPath.substring(
22
22
  0,
@@ -1,4 +1,4 @@
1
- import * as path from "path";
1
+ import { joinPaths } from "@typespec/compiler";
2
2
  import { RLCModel } from "./interfaces.js";
3
3
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
4
  // @ts-ignore: to fix the handlebars issue
@@ -25,7 +25,7 @@ export function buildPaginateHelper(model: RLCModel) {
25
25
  noEscape: true,
26
26
  });
27
27
  return {
28
- path: path.join(srcPath, "paginateHelper.ts"),
28
+ path: joinPaths(srcPath, "paginateHelper.ts"),
29
29
  content: paginateHelperContents(pagingInfo.pageDetails),
30
30
  };
31
31
  }
@@ -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
  InterfaceDeclarationStructure,
7
7
  Project,
@@ -27,9 +27,9 @@ import {
27
27
  } from "./interfaces.js";
28
28
 
29
29
  export function buildParameterTypes(model: RLCModel) {
30
- const project = new Project();
30
+ const project = new Project({ useInMemoryFileSystem: true });
31
31
  const srcPath = model.srcPath;
32
- const filePath = path.join(srcPath, `parameters.ts`);
32
+ const filePath = joinPaths(srcPath, `parameters.ts`);
33
33
  const partialBodyTypeNames = new Set<string>();
34
34
  const parametersFile = project.createSourceFile(filePath, undefined, {
35
35
  overwrite: true,
@@ -1,4 +1,4 @@
1
- import * as path from "path";
1
+ import { joinPaths } from "@typespec/compiler";
2
2
  import { OPERATION_LRO_HIGH_PRIORITY, RLCModel } from "./interfaces.js";
3
3
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
4
  // @ts-ignore: to fix the handlebars issue
@@ -28,7 +28,7 @@ export function buildPollingHelper(model: RLCModel) {
28
28
  const readmeFileContents = hbs.compile(pollingContent, { noEscape: true });
29
29
  const { srcPath } = model;
30
30
  return {
31
- path: path.join(srcPath, "pollingHelper.ts"),
31
+ path: joinPaths(srcPath, "pollingHelper.ts"),
32
32
  content: readmeFileContents(lroDetail),
33
33
  };
34
34
  }
@@ -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
  InterfaceDeclarationStructure,
7
7
  OptionalKind,
@@ -19,9 +19,9 @@ import { ResponseHeaderSchema, ResponseMetadata, RLCModel } from "./interfaces.j
19
19
 
20
20
  let hasErrorResponse = false;
21
21
  export function buildResponseTypes(model: RLCModel) {
22
- const project = new Project();
22
+ const project = new Project({ useInMemoryFileSystem: true });
23
23
  const srcPath = model.srcPath;
24
- const filePath = path.join(srcPath, `responses.ts`);
24
+ const filePath = joinPaths(srcPath, `responses.ts`);
25
25
  hasErrorResponse = false;
26
26
  const responsesFile = project.createSourceFile(filePath, undefined, {
27
27
  overwrite: true,
@@ -5,8 +5,8 @@ import { File as RLCFile, RLCModel, RLCSampleGroup } from "./interfaces.js";
5
5
  import { sampleTemplate } from "./static/sample-template.js";
6
6
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
7
7
  // @ts-ignore: to fix the handlebars issue
8
+ import { joinPaths } from "@typespec/compiler";
8
9
  import hbs from "handlebars";
9
- import * as path from "path";
10
10
 
11
11
  // Build sample files for the model based on the sample groups
12
12
  export function buildSamples(model: RLCModel) {
@@ -22,7 +22,7 @@ export function buildSamples(model: RLCModel) {
22
22
  const sampleGroupFileContents = hbs.compile(sampleTemplate, {
23
23
  noEscape: true,
24
24
  });
25
- const filePath = path.join("samples-dev", `${sampleGroup.filename}.ts`);
25
+ const filePath = joinPaths("samples-dev", `${sampleGroup.filename}.ts`);
26
26
  sampleFiles.push({
27
27
  path: filePath,
28
28
  content: sampleGroupFileContents(sampleGroup),
@@ -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 { Project } from "ts-morph";
6
6
  import {
7
7
  buildObjectAliases,
@@ -17,10 +17,10 @@ import { RLCModel, SchemaContext } from "./interfaces.js";
17
17
  */
18
18
  export function buildSchemaTypes(model: RLCModel) {
19
19
  const { srcPath } = model;
20
- const project = new Project();
21
- let filePath = path.join(srcPath, `models.ts`);
20
+ const project = new Project({ useInMemoryFileSystem: true });
21
+ let filePath = joinPaths(srcPath, `models.ts`);
22
22
  const inputModelFile = generateModelFiles(model, project, filePath, [SchemaContext.Input]);
23
- filePath = path.join(srcPath, `outputModels.ts`);
23
+ filePath = joinPaths(srcPath, `outputModels.ts`);
24
24
  const outputModelFile = generateModelFiles(model, project, filePath, [
25
25
  SchemaContext.Output,
26
26
  SchemaContext.Exception,
@@ -1,4 +1,4 @@
1
- import * as path from "path";
1
+ import { joinPaths } from "@typespec/compiler";
2
2
  import { RLCModel } from "./interfaces.js";
3
3
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
4
  // @ts-ignore: to fix the handlebars issue
@@ -41,7 +41,7 @@ export function buildSerializeHelper(model: RLCModel) {
41
41
  });
42
42
  const { srcPath } = model;
43
43
  return {
44
- path: path.join(srcPath, "serializeHelper.ts"),
44
+ path: joinPaths(srcPath, "serializeHelper.ts"),
45
45
  content: readmeFileContents({}),
46
46
  };
47
47
  }
@@ -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 { Project } from "ts-morph";
6
6
  import { getImportModuleName } from "./helpers/name-constructors.js";
7
7
  import { NameType, normalizeName } from "./helpers/name-utils.js";
@@ -14,7 +14,7 @@ export function buildTopLevelIndex(model: RLCModel) {
14
14
  if (!model.options) {
15
15
  return undefined;
16
16
  }
17
- const project = new Project();
17
+ const project = new Project({ useInMemoryFileSystem: true });
18
18
  const { srcPath } = model;
19
19
  const { multiClient } = model.options;
20
20
  const batch = model.options.batch;
@@ -47,7 +47,7 @@ export function buildTopLevelIndex(model: RLCModel) {
47
47
  namedExports: [...allModules],
48
48
  });
49
49
  const content = indexFile.getFullText();
50
- const filePath = path.join(
50
+ const filePath = joinPaths(
51
51
  srcPath.substring(0, srcPath.lastIndexOf("src") + 4),
52
52
  model.options.isModularLibrary ? "rest" : "",
53
53
  `index.ts`,
@@ -1,7 +1,5 @@
1
- import * as path from "path";
2
-
3
1
  export function getRelativePartFromSrcPath(srcPath: string, isModularLibrary: boolean = false) {
4
- const sep = srcPath.includes(path.sep + "src") ? path.sep : "/";
2
+ const sep = "/";
5
3
  let relativePart = srcPath.substring(srcPath.indexOf(sep + "src") + 4);
6
4
  if (isModularLibrary) {
7
5
  relativePart = relativePart.substring(srcPath.indexOf(sep + "rest"), +5);
@@ -6,7 +6,7 @@ import { RLCModel } from "../interfaces.js";
6
6
 
7
7
  export function buildApiExtractorConfig(model: RLCModel) {
8
8
  const { packageDetails, isModularLibrary, generateTest, azureSdkForJs } = model.options || {};
9
- const project = new Project();
9
+ const project = new Project({ useInMemoryFileSystem: true });
10
10
 
11
11
  let mainEntryPointFilePath = "dist/esm/index.d.ts";
12
12
 
@@ -65,7 +65,7 @@ export function buildEsLintConfig(model: RLCModel) {
65
65
  if (model.options?.flavor !== "azure") {
66
66
  return;
67
67
  }
68
- const project = new Project();
68
+ const project = new Project({ useInMemoryFileSystem: true });
69
69
  const filePath = "eslint.config.mjs";
70
70
 
71
71
  let template: string;
@@ -66,7 +66,7 @@ export function buildPackageFile(
66
66
  packageInfo = buildAzureStandalonePackage(extendedConfig);
67
67
  }
68
68
 
69
- const project = new Project();
69
+ const project = new Project({ useInMemoryFileSystem: true });
70
70
  const filePath = "package.json";
71
71
 
72
72
  if (!packageInfo) {
@@ -1,14 +1,13 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
 
4
- import { RLCModel } from "../interfaces.js";
5
4
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
6
5
  // @ts-ignore: to fix the handlebars issue
7
- import { readFileSync } from "fs";
8
6
  import hbs from "handlebars";
9
7
  import { getClientName } from "../helpers/name-constructors.js";
10
8
  import { NameType, normalizeName } from "../helpers/name-utils.js";
11
9
  import { isAzurePackage } from "../helpers/package-util.js";
10
+ import { RLCModel } from "../interfaces.js";
12
11
 
13
12
  const azureReadmeRLCTemplate = `# {{ clientDescriptiveName }} library for JavaScript
14
13
 
@@ -58,11 +57,11 @@ npm install {{ clientPackageName }}
58
57
 
59
58
  ### Create and authenticate a \`{{ clientClassName }}\`
60
59
 
61
- To use an [Azure Active Directory (AAD) token credential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token),
60
+ To use a [Microsoft Entra token credential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token),
62
61
  provide an instance of the desired credential type obtained from the
63
62
  [@azure/identity](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) library.
64
63
 
65
- To authenticate with AAD, you must first \`npm\` install [\`@azure/identity\`](https://www.npmjs.com/package/@azure/identity) {{#if dependencyLink}}and
64
+ To authenticate with Microsoft Entra ID, you must first \`npm\` install [\`@azure/identity\`](https://www.npmjs.com/package/@azure/identity) {{#if dependencyLink}}and
66
65
  [{{dependencyDescription }}]({{ dependencyLink }}){{/if}}
67
66
 
68
67
  After setup, you can choose which type of [credential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) from \`@azure/identity\` to use.
@@ -134,10 +133,10 @@ npm install {{ clientPackageName }}
134
133
  {{#if addCredentials}}
135
134
  ### Create and authenticate a \`{{ clientClassName}}\`
136
135
 
137
- To create a client object to access the {{ serviceName }} API, you will need the \`endpoint\` of your {{ serviceName }} resource and a \`credential\`. The {{ clientDescriptiveName }} can use Azure Active Directory credentials to authenticate.
136
+ To create a client object to access the {{ serviceName }} API, you will need the \`endpoint\` of your {{ serviceName }} resource and a \`credential\`. The {{ clientDescriptiveName }} can use Microsoft Entra credentials to authenticate.
138
137
  You can find the endpoint for your {{ serviceName }} resource in the [Azure Portal][azure_portal].
139
138
 
140
- You can authenticate with Azure Active Directory using a credential from the [@azure/identity][azure_identity] library or [an existing AAD Token](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token).
139
+ You can authenticate with Microsoft Entra ID using a credential from the [@azure/identity][azure_identity] library or [an existing Microsoft Entra token](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token).
141
140
 
142
141
  To use the [DefaultAzureCredential][defaultazurecredential] provider shown below, or other credential providers provided with the Azure SDK, please install the \`@azure/identity\` package:
143
142
 
@@ -145,9 +144,9 @@ To use the [DefaultAzureCredential][defaultazurecredential] provider shown below
145
144
  npm install @azure/identity
146
145
  \`\`\`
147
146
 
148
- You will also need to **register a new AAD application and grant access to {{ serviceName}}** by assigning the suitable role to your service principal (note: roles such as \`"Owner"\` will not grant the necessary permissions).
147
+ You will also need to **register a new Microsoft Entra application and grant access to {{ serviceName}}** by assigning the suitable role to your service principal (note: roles such as \`"Owner"\` will not grant the necessary permissions).
149
148
 
150
- For more information about how to create an Azure AD Application check out [this guide](https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal).
149
+ For more information about how to create a Microsoft Entra application check out [this guide](https://learn.microsoft.com/entra/identity-platform/howto-create-service-principal-portal).
151
150
 
152
151
  {{#if azureArm}}
153
152
  Using Node.js and Node-like environments, you can use the \`DefaultAzureCredential\` class to authenticate the client.
@@ -363,10 +362,9 @@ export function buildReadmeFile(model: RLCModel) {
363
362
  };
364
363
  }
365
364
 
366
- export function hasClientNameChanged(model: RLCModel, existingReadmeFilePath: string): boolean {
365
+ export function hasClientNameChanged(model: RLCModel, existingReadmeContent: string): boolean {
367
366
  try {
368
- const existingContent = readFileSync(existingReadmeFilePath, "utf8");
369
- const importMatch = existingContent.match(
367
+ const importMatch = existingReadmeContent.match(
370
368
  /import\s*\{\s*([A-Za-z0-9_]+)\s*\}\s*from\s*["'][^"']*["']/,
371
369
  );
372
370
  const existingClientName = importMatch?.[1];
@@ -379,21 +377,20 @@ export function hasClientNameChanged(model: RLCModel, existingReadmeFilePath: st
379
377
 
380
378
  export function updateReadmeFile(
381
379
  model: RLCModel,
382
- existingReadmeFilePath: string,
380
+ existingReadmeContent: string,
383
381
  ): { path: string; content: string } | undefined {
384
382
  try {
385
- const existingContent = readFileSync(existingReadmeFilePath, "utf8");
386
383
  const metadata = createMetadata(model) ?? {};
387
384
 
388
385
  const newApiRefLink = hbs.compile(apiReferenceTemplate, { noEscape: true })(metadata).trim();
389
386
 
390
387
  if (!newApiRefLink) {
391
- return { path: "README.md", content: existingContent };
388
+ return { path: "README.md", content: existingReadmeContent };
392
389
  }
393
390
 
394
391
  const apiRefRegex =
395
392
  /^- \[API reference documentation\]\(https:\/\/learn\.microsoft\.com\/javascript\/api\/[^)]+\)$/m;
396
- const updatedContent = existingContent.replace(apiRefRegex, (match) =>
393
+ const updatedContent = existingReadmeContent.replace(apiRefRegex, (match) =>
397
394
  match ? newApiRefLink : match,
398
395
  );
399
396
 
@@ -12,7 +12,7 @@ export function buildRollupConfig(model: RLCModel) {
12
12
  return;
13
13
  }
14
14
 
15
- const project = new Project();
15
+ const project = new Project({ useInMemoryFileSystem: true });
16
16
  const filePath = "rollup.config.js";
17
17
  const rollupFile = project.createSourceFile(filePath, undefined, {
18
18
  overwrite: true,
@@ -14,7 +14,7 @@ export function buildTsConfig(model: RLCModel) {
14
14
  const { packageDetails, azureSdkForJs } = model.options || {};
15
15
  const { generateTest, generateSample, generateReactNativeTarget } = model.options || {};
16
16
  const clientPackageName = packageDetails?.name ?? "";
17
- const project = new Project();
17
+ const project = new Project({ useInMemoryFileSystem: true });
18
18
 
19
19
  let tsConfig: Record<string, any>;
20
20
 
@@ -2,9 +2,8 @@
2
2
  // Licensed under the MIT License.
3
3
 
4
4
  import { SdkClient } from "@azure-tools/typespec-client-generator-core";
5
- import { getDoc } from "@typespec/compiler";
5
+ import { getDoc, joinPaths } from "@typespec/compiler";
6
6
  import { getServers } from "@typespec/http";
7
- import * as path from "path";
8
7
  import {
9
8
  buildRuntimeImports,
10
9
  Imports,
@@ -47,7 +46,7 @@ export async function transformRLCModel(
47
46
  const program = dpgContext.program;
48
47
  const options: RLCOptions = dpgContext.rlcOptions!;
49
48
  const rlcSourceDir = dpgContext.generationPathDetail?.rlcSourcesDir;
50
- const srcPath = path.join(
49
+ const srcPath = joinPaths(
51
50
  dpgContext.generationPathDetail?.rlcSourcesDir ?? "",
52
51
  options.batch && options.batch.length > 1
53
52
  ? normalizeName(client.name.replace("Client", ""), NameType.File)