@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.
- package/README.md +96 -24
- package/dist/src/framework/hooks/binder.d.ts.map +1 -1
- package/dist/src/framework/hooks/binder.js +3 -4
- package/dist/src/framework/hooks/binder.js.map +1 -1
- package/dist/src/framework/load-static-helpers.d.ts +4 -1
- package/dist/src/framework/load-static-helpers.d.ts.map +1 -1
- package/dist/src/framework/load-static-helpers.js +19 -15
- package/dist/src/framework/load-static-helpers.js.map +1 -1
- package/dist/src/framework/sample.js +1 -1
- package/dist/src/framework/sample.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +47 -28
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.js +30 -31
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/build-project-files.d.ts.map +1 -1
- package/dist/src/modular/build-project-files.js +4 -4
- package/dist/src/modular/build-project-files.js.map +1 -1
- package/dist/src/modular/build-restore-poller.js +2 -2
- package/dist/src/modular/build-restore-poller.js.map +1 -1
- package/dist/src/modular/build-root-index.d.ts.map +1 -1
- package/dist/src/modular/build-root-index.js +5 -6
- package/dist/src/modular/build-root-index.js.map +1 -1
- package/dist/src/modular/build-subpath-index.d.ts.map +1 -1
- package/dist/src/modular/build-subpath-index.js +4 -4
- package/dist/src/modular/build-subpath-index.js.map +1 -1
- package/dist/src/modular/emit-models-options.js +2 -2
- package/dist/src/modular/emit-models-options.js.map +1 -1
- package/dist/src/modular/emit-models.d.ts.map +1 -1
- package/dist/src/modular/emit-models.js +2 -3
- package/dist/src/modular/emit-models.js.map +1 -1
- package/dist/src/modular/emit-samples.d.ts.map +1 -1
- package/dist/src/modular/emit-samples.js +3 -4
- package/dist/src/modular/emit-samples.js.map +1 -1
- package/dist/src/modular/emit-tests.d.ts +2 -1
- package/dist/src/modular/emit-tests.d.ts.map +1 -1
- package/dist/src/modular/emit-tests.js +21 -11
- package/dist/src/modular/emit-tests.js.map +1 -1
- package/dist/src/modular/helpers/example-value-helpers.js +4 -4
- package/dist/src/modular/helpers/example-value-helpers.js.map +1 -1
- package/dist/src/rlc-common/build-client-definitions.js +3 -3
- package/dist/src/rlc-common/build-client-definitions.js.map +1 -1
- package/dist/src/rlc-common/build-client.js +4 -4
- package/dist/src/rlc-common/build-client.js.map +1 -1
- package/dist/src/rlc-common/build-index-file.js +3 -3
- package/dist/src/rlc-common/build-index-file.js.map +1 -1
- package/dist/src/rlc-common/build-is-unexpected-helper.js +3 -3
- package/dist/src/rlc-common/build-is-unexpected-helper.js.map +1 -1
- package/dist/src/rlc-common/build-logger.js +3 -3
- package/dist/src/rlc-common/build-logger.js.map +1 -1
- package/dist/src/rlc-common/build-paginate-helper.js +2 -2
- package/dist/src/rlc-common/build-paginate-helper.js.map +1 -1
- package/dist/src/rlc-common/build-parameter-types.js +3 -3
- package/dist/src/rlc-common/build-parameter-types.js.map +1 -1
- package/dist/src/rlc-common/build-polling-helper.js +2 -2
- package/dist/src/rlc-common/build-polling-helper.js.map +1 -1
- package/dist/src/rlc-common/build-response-types.js +3 -3
- package/dist/src/rlc-common/build-response-types.js.map +1 -1
- package/dist/src/rlc-common/build-samples.js +2 -2
- package/dist/src/rlc-common/build-samples.js.map +1 -1
- package/dist/src/rlc-common/build-schema-type.js +4 -4
- package/dist/src/rlc-common/build-schema-type.js.map +1 -1
- package/dist/src/rlc-common/build-serialize-helper.js +2 -2
- package/dist/src/rlc-common/build-serialize-helper.js.map +1 -1
- package/dist/src/rlc-common/build-top-level-index-file.js +3 -3
- package/dist/src/rlc-common/build-top-level-index-file.js.map +1 -1
- package/dist/src/rlc-common/helpers/path-utils.d.ts.map +1 -1
- package/dist/src/rlc-common/helpers/path-utils.js +1 -2
- package/dist/src/rlc-common/helpers/path-utils.js.map +1 -1
- package/dist/src/rlc-common/metadata/build-api-extractor-config.js +1 -1
- package/dist/src/rlc-common/metadata/build-api-extractor-config.js.map +1 -1
- package/dist/src/rlc-common/metadata/build-es-lint-config.js +1 -1
- package/dist/src/rlc-common/metadata/build-es-lint-config.js.map +1 -1
- package/dist/src/rlc-common/metadata/build-package-file.js +1 -1
- package/dist/src/rlc-common/metadata/build-package-file.js.map +1 -1
- package/dist/src/rlc-common/metadata/build-readme-file.d.ts +2 -2
- package/dist/src/rlc-common/metadata/build-readme-file.d.ts.map +1 -1
- package/dist/src/rlc-common/metadata/build-readme-file.js +11 -14
- package/dist/src/rlc-common/metadata/build-readme-file.js.map +1 -1
- package/dist/src/rlc-common/metadata/build-rollup-config.js +1 -1
- package/dist/src/rlc-common/metadata/build-rollup-config.js.map +1 -1
- package/dist/src/rlc-common/metadata/build-ts-config.js +1 -1
- package/dist/src/rlc-common/metadata/build-ts-config.js.map +1 -1
- package/dist/src/transform/transform.d.ts.map +1 -1
- package/dist/src/transform/transform.js +2 -3
- package/dist/src/transform/transform.js.map +1 -1
- package/dist/src/utils/emit-util.d.ts.map +1 -1
- package/dist/src/utils/emit-util.js +10 -5
- package/dist/src/utils/emit-util.js.map +1 -1
- package/dist/src/utils/file-system-utils.d.ts +4 -4
- package/dist/src/utils/file-system-utils.d.ts.map +1 -1
- package/dist/src/utils/file-system-utils.js +14 -16
- package/dist/src/utils/file-system-utils.js.map +1 -1
- package/dist/src/utils/import-helper.js +3 -3
- package/dist/src/utils/import-helper.js.map +1 -1
- package/dist/src/utils/resolve-project-root.d.ts +6 -4
- package/dist/src/utils/resolve-project-root.d.ts.map +1 -1
- package/dist/src/utils/resolve-project-root.js +11 -18
- package/dist/src/utils/resolve-project-root.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -26
- package/src/framework/hooks/binder.ts +3 -4
- package/src/framework/load-static-helpers.ts +29 -18
- package/src/framework/sample.ts +1 -1
- package/src/index.ts +61 -28
- package/src/lib.ts +31 -31
- package/src/modular/build-project-files.ts +11 -4
- package/src/modular/build-restore-poller.ts +2 -2
- package/src/modular/build-root-index.ts +5 -6
- package/src/modular/build-subpath-index.ts +4 -4
- package/src/modular/emit-models-options.ts +2 -2
- package/src/modular/emit-models.ts +2 -3
- package/src/modular/emit-samples.ts +3 -4
- package/src/modular/emit-tests.ts +28 -11
- package/src/modular/helpers/example-value-helpers.ts +4 -4
- package/src/rlc-common/build-client-definitions.ts +3 -3
- package/src/rlc-common/build-client.ts +4 -4
- package/src/rlc-common/build-index-file.ts +3 -3
- package/src/rlc-common/build-is-unexpected-helper.ts +3 -3
- package/src/rlc-common/build-logger.ts +3 -3
- package/src/rlc-common/build-paginate-helper.ts +2 -2
- package/src/rlc-common/build-parameter-types.ts +3 -3
- package/src/rlc-common/build-polling-helper.ts +2 -2
- package/src/rlc-common/build-response-types.ts +3 -3
- package/src/rlc-common/build-samples.ts +2 -2
- package/src/rlc-common/build-schema-type.ts +4 -4
- package/src/rlc-common/build-serialize-helper.ts +2 -2
- package/src/rlc-common/build-top-level-index-file.ts +3 -3
- package/src/rlc-common/helpers/path-utils.ts +1 -3
- package/src/rlc-common/metadata/build-api-extractor-config.ts +1 -1
- package/src/rlc-common/metadata/build-es-lint-config.ts +1 -1
- package/src/rlc-common/metadata/build-package-file.ts +1 -1
- package/src/rlc-common/metadata/build-readme-file.ts +12 -15
- package/src/rlc-common/metadata/build-rollup-config.ts +1 -1
- package/src/rlc-common/metadata/build-ts-config.ts +1 -1
- package/src/transform/transform.ts +2 -3
- package/src/utils/emit-util.ts +10 -8
- package/src/utils/file-system-utils.ts +14 -15
- package/src/utils/import-helper.ts +3 -3
- package/src/utils/resolve-project-root.ts +11 -24
- package/dist/src/utils/dirname.d.ts +0 -9
- package/dist/src/utils/dirname.d.ts.map +0 -1
- package/dist/src/utils/dirname.js +0 -12
- package/dist/src/utils/dirname.js.map +0 -1
- 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.
|
|
3
|
+
"version": "0.55.0-dev.4",
|
|
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
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"types": "./dist/src/index.d.ts",
|
|
10
|
+
"default": "./dist/src/index.js"
|
|
11
11
|
},
|
|
12
12
|
"./testing": {
|
|
13
|
-
"
|
|
14
|
-
"
|
|
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.
|
|
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.
|
|
25
|
-
"@azure-tools/azure-http-specs": "^0.1.0-alpha.
|
|
26
|
-
"@azure-tools/typespec-autorest": "^0.
|
|
27
|
-
"@azure-tools/typespec-azure-core": "^0.
|
|
28
|
-
"@azure-tools/typespec-azure-resource-manager": "^0.
|
|
29
|
-
"@azure-tools/typespec-client-generator-core": "^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.
|
|
38
|
-
"@typespec/http": "^1.
|
|
39
|
-
"@typespec/openapi": "^1.
|
|
40
|
-
"@typespec/rest": "^0.
|
|
41
|
-
"@typespec/versioning": "^0.
|
|
42
|
-
"@typespec/xml": "^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.
|
|
57
|
-
"@azure-tools/typespec-client-generator-core": "^0.
|
|
58
|
-
"@typespec/compiler": "^1.
|
|
59
|
-
"@typespec/http": "^1.
|
|
60
|
-
"@typespec/rest": "^0.
|
|
61
|
-
"@typespec/versioning": "^0.
|
|
62
|
-
"@typespec/xml": "^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
|
|
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(
|
|
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(
|
|
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,4 @@
|
|
|
1
|
-
import { NoTarget, Program } from "@typespec/compiler";
|
|
2
|
-
import { readdir, readFile, stat } from "fs/promises";
|
|
3
|
-
import * as path from "path";
|
|
1
|
+
import { type CompilerHost, joinPaths, NoTarget, Program } from "@typespec/compiler";
|
|
4
2
|
import {
|
|
5
3
|
ClassDeclaration,
|
|
6
4
|
EnumDeclaration,
|
|
@@ -39,6 +37,9 @@ export interface LoadStaticHelpersOptions extends Partial<ModularEmitterOptions>
|
|
|
39
37
|
sourcesDir?: string;
|
|
40
38
|
rootDir?: string;
|
|
41
39
|
program?: Program;
|
|
40
|
+
host?: CompilerHost;
|
|
41
|
+
/** The emitter package root directory (where static/ lives). */
|
|
42
|
+
packageRoot?: string;
|
|
42
43
|
/** When true, also load test helpers from static/test-helpers/ into test/generated/util/ */
|
|
43
44
|
loadTestHelpers?: boolean;
|
|
44
45
|
}
|
|
@@ -54,13 +55,20 @@ export async function loadStaticHelpers(
|
|
|
54
55
|
options: LoadStaticHelpersOptions = {},
|
|
55
56
|
): Promise<Map<string, StaticHelperMetadata>> {
|
|
56
57
|
const helpersMap = new Map<string, StaticHelperMetadata>();
|
|
58
|
+
const host = options.host ?? options.program?.host;
|
|
59
|
+
if (!host) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
"loadStaticHelpers requires either a host or program in options to access the file system.",
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const packageRoot = options.packageRoot ?? resolveProjectRoot();
|
|
66
|
+
|
|
57
67
|
// Load static helpers used in sources code
|
|
58
|
-
const defaultStaticHelpersPath =
|
|
59
|
-
resolveProjectRoot(),
|
|
60
|
-
DEFAULT_SOURCES_STATIC_HELPERS_PATH,
|
|
61
|
-
);
|
|
68
|
+
const defaultStaticHelpersPath = joinPaths(packageRoot, DEFAULT_SOURCES_STATIC_HELPERS_PATH);
|
|
62
69
|
const filesInSources = await traverseDirectory(
|
|
63
70
|
options.helpersAssetDirectory ?? defaultStaticHelpersPath,
|
|
71
|
+
host,
|
|
64
72
|
options.program,
|
|
65
73
|
);
|
|
66
74
|
await loadFiles(filesInSources, options.sourcesDir ?? "");
|
|
@@ -69,12 +77,10 @@ export async function loadStaticHelpers(
|
|
|
69
77
|
options.loadTestHelpers ??
|
|
70
78
|
(options.options?.generateTest && isAzurePackage({ options: options.options }))
|
|
71
79
|
) {
|
|
72
|
-
const defaultTestingHelpersPath =
|
|
73
|
-
resolveProjectRoot(),
|
|
74
|
-
DEFAULT_SOURCES_TESTING_HELPERS_PATH,
|
|
75
|
-
);
|
|
80
|
+
const defaultTestingHelpersPath = joinPaths(packageRoot, DEFAULT_SOURCES_TESTING_HELPERS_PATH);
|
|
76
81
|
const filesInTestings = await traverseDirectory(
|
|
77
82
|
defaultTestingHelpersPath,
|
|
83
|
+
host,
|
|
78
84
|
options.program,
|
|
79
85
|
[],
|
|
80
86
|
"",
|
|
@@ -86,8 +92,9 @@ export async function loadStaticHelpers(
|
|
|
86
92
|
|
|
87
93
|
async function loadFiles(files: FileMetadata[], generateDir: string) {
|
|
88
94
|
for (const file of files) {
|
|
89
|
-
const targetPath =
|
|
90
|
-
const
|
|
95
|
+
const targetPath = joinPaths(generateDir, file.target);
|
|
96
|
+
const sourceFile = await host!.readFile(file.source);
|
|
97
|
+
const contents = sourceFile.text;
|
|
91
98
|
const addedFile = project.createSourceFile(targetPath, contents, {
|
|
92
99
|
overwrite: true,
|
|
93
100
|
});
|
|
@@ -187,32 +194,36 @@ function getDeclarationByMetadata(
|
|
|
187
194
|
}
|
|
188
195
|
}
|
|
189
196
|
|
|
197
|
+
type FsHost = Pick<CompilerHost, "readFile" | "readDir" | "stat">;
|
|
198
|
+
|
|
190
199
|
const _targetStaticHelpersBaseDir = "static-helpers";
|
|
191
200
|
async function traverseDirectory(
|
|
192
201
|
directory: string,
|
|
202
|
+
host: FsHost,
|
|
193
203
|
program?: Program,
|
|
194
204
|
result: { source: string; target: string }[] = [],
|
|
195
205
|
relativePath: string = "",
|
|
196
206
|
targetBaseDir: string = _targetStaticHelpersBaseDir,
|
|
197
207
|
): Promise<{ source: string; target: string }[]> {
|
|
198
208
|
try {
|
|
199
|
-
const files = await
|
|
209
|
+
const files = await host.readDir(directory);
|
|
200
210
|
|
|
201
211
|
await Promise.all(
|
|
202
212
|
files.map(async (file) => {
|
|
203
|
-
const filePath =
|
|
204
|
-
const fileStat = await stat(filePath);
|
|
213
|
+
const filePath = joinPaths(directory, file);
|
|
214
|
+
const fileStat = await host.stat(filePath);
|
|
205
215
|
|
|
206
216
|
if (fileStat.isDirectory()) {
|
|
207
217
|
await traverseDirectory(
|
|
208
218
|
filePath,
|
|
219
|
+
host,
|
|
209
220
|
program,
|
|
210
221
|
result,
|
|
211
|
-
|
|
222
|
+
joinPaths(relativePath, file),
|
|
212
223
|
targetBaseDir,
|
|
213
224
|
);
|
|
214
225
|
} else if (fileStat.isFile() && !file.endsWith(".d.ts") && /.*\..?ts$/.test(file)) {
|
|
215
|
-
const target =
|
|
226
|
+
const target = joinPaths(targetBaseDir, relativePath, file);
|
|
216
227
|
result.push({ source: filePath, target });
|
|
217
228
|
}
|
|
218
229
|
}),
|
package/src/framework/sample.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { useBinder } from "./hooks/binder.js";
|
|
|
9
9
|
import { resolveReference } from "./reference.js";
|
|
10
10
|
|
|
11
11
|
// Create a new ts-morph project
|
|
12
|
-
const project = new Project();
|
|
12
|
+
const project = new Project({ useInMemoryFileSystem: true });
|
|
13
13
|
|
|
14
14
|
// Create a source file
|
|
15
15
|
const sourceFile = project.createSourceFile("test.ts", "", { overwrite: true });
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
EmitContext,
|
|
6
|
+
Program,
|
|
7
|
+
getBaseFileName,
|
|
8
|
+
getDirectoryPath,
|
|
9
|
+
joinPaths,
|
|
10
|
+
resolvePath,
|
|
11
|
+
type CompilerHost,
|
|
12
|
+
} from "@typespec/compiler";
|
|
5
13
|
import { provideContext, useContext } from "./context-manager.js";
|
|
6
14
|
import { buildRootIndex, buildSubClientIndexFile } from "./modular/build-root-index.js";
|
|
7
15
|
import {
|
|
@@ -79,8 +87,6 @@ import {
|
|
|
79
87
|
createSdkContext,
|
|
80
88
|
listAllServiceNamespaces,
|
|
81
89
|
} from "@azure-tools/typespec-client-generator-core";
|
|
82
|
-
import { existsSync } from "fs";
|
|
83
|
-
import { basename, join } from "path";
|
|
84
90
|
import { Project } from "ts-morph";
|
|
85
91
|
import { provideBinder } from "./framework/hooks/binder.js";
|
|
86
92
|
import { provideSdkTypes } from "./framework/hooks/sdk-types.js";
|
|
@@ -118,8 +124,15 @@ export async function $onEmit(context: EmitContext) {
|
|
|
118
124
|
return;
|
|
119
125
|
}
|
|
120
126
|
/** Shared status */
|
|
121
|
-
const outputProject = new Project();
|
|
127
|
+
const outputProject = new Project({ useInMemoryFileSystem: true });
|
|
122
128
|
const program: Program = context.program;
|
|
129
|
+
const host: CompilerHost = program.host;
|
|
130
|
+
// Derive the emitter package root from the compiler's resolved emitter entry point.
|
|
131
|
+
// This works correctly in both Node.js and the browser playground VFS.
|
|
132
|
+
const emitterRef = program.emitters.find((e) => e.metadata.name === "@azure-tools/typespec-ts");
|
|
133
|
+
const emitterPackageRoot = emitterRef
|
|
134
|
+
? resolvePath(getDirectoryPath(emitterRef.main), "../..")
|
|
135
|
+
: undefined;
|
|
123
136
|
const emitterOptions: EmitterOptions = context.options;
|
|
124
137
|
const dpgContext = await createContextWithDefaultOptions(context);
|
|
125
138
|
|
|
@@ -161,6 +174,8 @@ export async function $onEmit(context: EmitContext) {
|
|
|
161
174
|
rootDir: dpgContext.generationPathDetail?.rootDir,
|
|
162
175
|
options: rlcOptions,
|
|
163
176
|
program,
|
|
177
|
+
host,
|
|
178
|
+
packageRoot: emitterPackageRoot,
|
|
164
179
|
},
|
|
165
180
|
);
|
|
166
181
|
const extraDependencies = isAzurePackage({ options: rlcOptions })
|
|
@@ -217,10 +232,11 @@ export async function $onEmit(context: EmitContext) {
|
|
|
217
232
|
// clear output folder if needed
|
|
218
233
|
if (options.clearOutputFolder) {
|
|
219
234
|
// Clear output directory while preserving TempTypeSpecFiles
|
|
220
|
-
await clearDirectory(context.emitterOutputDir, ["TempTypeSpecFiles"], program);
|
|
235
|
+
await clearDirectory(host, context.emitterOutputDir, ["TempTypeSpecFiles"], program);
|
|
221
236
|
}
|
|
222
237
|
const hasTestFolder = await pathExists(
|
|
223
|
-
|
|
238
|
+
host,
|
|
239
|
+
joinPaths(dpgContext.generationPathDetail?.metadataDir ?? "", "test"),
|
|
224
240
|
);
|
|
225
241
|
options.generateTest =
|
|
226
242
|
options.generateTest === true ||
|
|
@@ -232,15 +248,15 @@ export async function $onEmit(context: EmitContext) {
|
|
|
232
248
|
|
|
233
249
|
async function calculateGenerationDir(): Promise<GenerationDirDetail> {
|
|
234
250
|
const projectRoot = context.emitterOutputDir ?? "";
|
|
235
|
-
const customizationFolder =
|
|
236
|
-
const srcGeneratedFolder =
|
|
251
|
+
const customizationFolder = joinPaths(projectRoot, "generated");
|
|
252
|
+
const srcGeneratedFolder = joinPaths(projectRoot, "src", "generated");
|
|
237
253
|
// if customization folder exists, use it as sources root
|
|
238
|
-
const finalCustomizationFolder = (await pathExists(srcGeneratedFolder))
|
|
254
|
+
const finalCustomizationFolder = (await pathExists(host, srcGeneratedFolder))
|
|
239
255
|
? srcGeneratedFolder
|
|
240
256
|
: customizationFolder;
|
|
241
|
-
const sourcesRoot = (await pathExists(finalCustomizationFolder))
|
|
257
|
+
const sourcesRoot = (await pathExists(host, finalCustomizationFolder))
|
|
242
258
|
? finalCustomizationFolder
|
|
243
|
-
:
|
|
259
|
+
: joinPaths(projectRoot, "src");
|
|
244
260
|
return {
|
|
245
261
|
rootDir: projectRoot,
|
|
246
262
|
metadataDir: projectRoot,
|
|
@@ -251,6 +267,7 @@ export async function $onEmit(context: EmitContext) {
|
|
|
251
267
|
|
|
252
268
|
async function clearSrcFolder() {
|
|
253
269
|
await emptyDir(
|
|
270
|
+
host,
|
|
254
271
|
dpgContext.generationPathDetail?.modularSourcesDir ??
|
|
255
272
|
dpgContext.generationPathDetail?.rlcSourcesDir ??
|
|
256
273
|
"",
|
|
@@ -259,9 +276,12 @@ export async function $onEmit(context: EmitContext) {
|
|
|
259
276
|
|
|
260
277
|
async function clearSamplesDevFolder() {
|
|
261
278
|
if (emitterOptions["generate-sample"] === true) {
|
|
262
|
-
const samplesDevPath =
|
|
263
|
-
|
|
264
|
-
|
|
279
|
+
const samplesDevPath = joinPaths(
|
|
280
|
+
dpgContext.generationPathDetail?.rootDir ?? "",
|
|
281
|
+
"samples-dev",
|
|
282
|
+
);
|
|
283
|
+
if (await pathExists(host, samplesDevPath)) {
|
|
284
|
+
await emptyDir(host, samplesDevPath);
|
|
265
285
|
}
|
|
266
286
|
}
|
|
267
287
|
}
|
|
@@ -316,7 +336,7 @@ export async function $onEmit(context: EmitContext) {
|
|
|
316
336
|
// platform-types (and its browser/react-native variants); emit those
|
|
317
337
|
// files directly under src/ (strip the static-helpers/ segment) to match
|
|
318
338
|
// the RLC design where all generated output lives in src/.
|
|
319
|
-
if (!
|
|
339
|
+
if (!getBaseFileName(filePath).startsWith("platform-types")) {
|
|
320
340
|
continue;
|
|
321
341
|
}
|
|
322
342
|
const outputPath = filePath.replace(/\/static-helpers\//g, "/");
|
|
@@ -450,27 +470,30 @@ export async function $onEmit(context: EmitContext) {
|
|
|
450
470
|
// to avoid unexpected modifications to files like package.json, README.md,
|
|
451
471
|
// warp.config.yml, and snippets.spec.ts. metadata.json is still updated.
|
|
452
472
|
const sourcesDir = dpgContext.generationPathDetail?.modularSourcesDir ?? "";
|
|
453
|
-
const hasManualConvenienceLayer =
|
|
473
|
+
const hasManualConvenienceLayer = getBaseFileName(sourcesDir) === "generated";
|
|
454
474
|
const isAzureFlavor = isAzurePackage({ options: option });
|
|
455
475
|
// Generate metadata
|
|
456
|
-
const existingPackageFilePath =
|
|
476
|
+
const existingPackageFilePath = joinPaths(
|
|
457
477
|
dpgContext.generationPathDetail?.metadataDir ?? "",
|
|
458
478
|
"package.json",
|
|
459
479
|
);
|
|
460
|
-
const hasPackageFile = await
|
|
461
|
-
const existingReadmeFilePath =
|
|
480
|
+
const hasPackageFile = await pathExists(host, existingPackageFilePath);
|
|
481
|
+
const existingReadmeFilePath = joinPaths(
|
|
462
482
|
dpgContext.generationPathDetail?.metadataDir ?? "",
|
|
463
483
|
"README.md",
|
|
464
484
|
);
|
|
465
|
-
const hasReadmeFile = await
|
|
466
|
-
const existingChangelogFilePath =
|
|
485
|
+
const hasReadmeFile = await pathExists(host, existingReadmeFilePath);
|
|
486
|
+
const existingChangelogFilePath = joinPaths(
|
|
467
487
|
dpgContext.generationPathDetail?.metadataDir ?? "",
|
|
468
488
|
"CHANGELOG.md",
|
|
469
489
|
);
|
|
470
|
-
const hasChangelogFile = await
|
|
490
|
+
const hasChangelogFile = await pathExists(host, existingChangelogFilePath);
|
|
471
491
|
const shouldGenerateMetadata = option.generateMetadata === true || !hasPackageFile;
|
|
472
|
-
const existingTestFolderPath =
|
|
473
|
-
|
|
492
|
+
const existingTestFolderPath = joinPaths(
|
|
493
|
+
dpgContext.generationPathDetail?.metadataDir ?? "",
|
|
494
|
+
"test",
|
|
495
|
+
);
|
|
496
|
+
const hasTestFolder = await pathExists(host, existingTestFolderPath);
|
|
474
497
|
if (option.generateTest === undefined) {
|
|
475
498
|
if (hasTestFolder) {
|
|
476
499
|
option.generateTest = false;
|
|
@@ -511,7 +534,7 @@ export async function $onEmit(context: EmitContext) {
|
|
|
511
534
|
option.azureSdkForJs === true &&
|
|
512
535
|
emitterOptions["generate-metadata"] === true
|
|
513
536
|
) {
|
|
514
|
-
await emitTests(dpgContext);
|
|
537
|
+
await emitTests(dpgContext, host);
|
|
515
538
|
}
|
|
516
539
|
let modularPackageInfo = {};
|
|
517
540
|
if (option.isModularLibrary) {
|
|
@@ -612,8 +635,16 @@ export async function $onEmit(context: EmitContext) {
|
|
|
612
635
|
// Always update package.json for monorepo packages (adds #platform/* imports)
|
|
613
636
|
// and for modular packages (adds exports, clientContextPaths, LRO deps)
|
|
614
637
|
if (option.isModularLibrary || option.azureSdkForJs) {
|
|
638
|
+
// Read package.json content via host and pass parsed object
|
|
639
|
+
const pkgSourceFile = await host.readFile(existingPackageFilePath);
|
|
640
|
+
let packageInfo: Record<string, any>;
|
|
641
|
+
try {
|
|
642
|
+
packageInfo = JSON.parse(pkgSourceFile.text);
|
|
643
|
+
} catch {
|
|
644
|
+
packageInfo = {};
|
|
645
|
+
}
|
|
615
646
|
updateBuilders.push((model: RLCModel) =>
|
|
616
|
-
updatePackageFile(model,
|
|
647
|
+
updatePackageFile(model, packageInfo, modularPackageInfo),
|
|
617
648
|
);
|
|
618
649
|
}
|
|
619
650
|
|
|
@@ -625,11 +656,13 @@ export async function $onEmit(context: EmitContext) {
|
|
|
625
656
|
// If the client name changed, regenerate the README and snippets completely;
|
|
626
657
|
// otherwise update only the API reference link in-place.
|
|
627
658
|
if (hasReadmeFile) {
|
|
628
|
-
const
|
|
659
|
+
const readmeSourceFile = await host.readFile(existingReadmeFilePath);
|
|
660
|
+
const existingReadmeContent = readmeSourceFile.text;
|
|
661
|
+
const clientNameChanged = hasClientNameChanged(rlcClient, existingReadmeContent);
|
|
629
662
|
updateBuilders.push(
|
|
630
663
|
clientNameChanged
|
|
631
664
|
? buildReadmeFile
|
|
632
|
-
: (model: RLCModel) => updateReadmeFile(model,
|
|
665
|
+
: (model: RLCModel) => updateReadmeFile(model, existingReadmeContent),
|
|
633
666
|
);
|
|
634
667
|
|
|
635
668
|
// Regenerate snippets.spec.ts only when the client name changed
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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:
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 = [
|
|
318
|
+
folders = [joinPaths(srcPath, subfolder, moduleName).replace(/\\/g, "/")];
|
|
320
319
|
}
|
|
321
320
|
for (const folder of folders) {
|
|
322
|
-
const apiFilePattern =
|
|
321
|
+
const apiFilePattern = joinPaths(folder, "index.ts").replace(/\\/g, "/");
|
|
323
322
|
const modelsFile = project.getSourceFile(apiFilePattern);
|
|
324
323
|
if (!modelsFile) {
|
|
325
324
|
continue;
|