@azure-tools/typespec-ts 0.30.1 → 0.31.0-alpha.20240723.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/src/contextManager.d.ts +4 -0
- package/dist/src/contextManager.d.ts.map +1 -1
- package/dist/src/contextManager.js.map +1 -1
- package/dist/src/framework/declaration.d.ts +9 -0
- package/dist/src/framework/declaration.d.ts.map +1 -0
- package/dist/src/framework/declaration.js +28 -0
- package/dist/src/framework/declaration.js.map +1 -0
- package/dist/src/framework/hooks/binder.d.ts +25 -0
- package/dist/src/framework/hooks/binder.d.ts.map +1 -0
- package/dist/src/framework/hooks/binder.js +168 -0
- package/dist/src/framework/hooks/binder.js.map +1 -0
- package/dist/src/framework/hooks/sdkTypes.d.ts +12 -0
- package/dist/src/framework/hooks/sdkTypes.d.ts.map +1 -0
- package/dist/src/framework/hooks/sdkTypes.js +67 -0
- package/dist/src/framework/hooks/sdkTypes.js.map +1 -0
- package/dist/src/framework/reference.d.ts +2 -0
- package/dist/src/framework/reference.d.ts.map +1 -0
- package/dist/src/framework/reference.js +8 -0
- package/dist/src/framework/reference.js.map +1 -0
- package/dist/src/framework/refkey.d.ts +7 -0
- package/dist/src/framework/refkey.d.ts.map +1 -0
- package/dist/src/framework/refkey.js +22 -0
- package/dist/src/framework/refkey.js.map +1 -0
- package/dist/src/framework/sample.d.ts +2 -0
- package/dist/src/framework/sample.d.ts.map +1 -0
- package/dist/src/framework/sample.js +71 -0
- package/dist/src/framework/sample.js.map +1 -0
- package/dist/src/framework/utils/tsmorph-helpers.d.ts +2 -0
- package/dist/src/framework/utils/tsmorph-helpers.d.ts.map +1 -0
- package/dist/src/framework/utils/tsmorph-helpers.js +2 -0
- package/dist/src/framework/utils/tsmorph-helpers.js.map +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +10 -1
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +6 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
- package/dist/src/modular/buildClassicalClient.js +6 -5
- package/dist/src/modular/buildClassicalClient.js.map +1 -1
- package/dist/src/modular/buildClientContext.d.ts.map +1 -1
- package/dist/src/modular/buildClientContext.js +8 -4
- package/dist/src/modular/buildClientContext.js.map +1 -1
- package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
- package/dist/src/modular/buildCodeModel.js +22 -11
- package/dist/src/modular/buildCodeModel.js.map +1 -1
- package/dist/src/modular/buildOperations.d.ts +1 -2
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +3 -9
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildRootIndex.js +1 -1
- package/dist/src/modular/buildRootIndex.js.map +1 -1
- package/dist/src/modular/buildSerializeUtils.d.ts.map +1 -1
- package/dist/src/modular/buildSerializeUtils.js +2 -1
- package/dist/src/modular/buildSerializeUtils.js.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts +4 -0
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +15 -1
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.d.ts +1 -0
- package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.js +3 -1
- package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +60 -40
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.js +6 -1
- package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
- package/dist/src/modular/modularCodeModel.d.ts +2 -0
- package/dist/src/modular/modularCodeModel.d.ts.map +1 -1
- package/dist/src/transform/transformApiVersionInfo.d.ts.map +1 -1
- package/dist/src/transform/transformApiVersionInfo.js +3 -5
- package/dist/src/transform/transformApiVersionInfo.js.map +1 -1
- package/dist/src/transform/transformHelperFunctionDetails.d.ts.map +1 -1
- package/dist/src/transform/transformHelperFunctionDetails.js +7 -10
- package/dist/src/transform/transformHelperFunctionDetails.js.map +1 -1
- package/dist/src/transform/transformParameters.d.ts.map +1 -1
- package/dist/src/transform/transformParameters.js +5 -7
- package/dist/src/transform/transformParameters.js.map +1 -1
- package/dist/src/transform/transformPaths.d.ts.map +1 -1
- package/dist/src/transform/transformPaths.js +4 -6
- package/dist/src/transform/transformPaths.js.map +1 -1
- package/dist/src/transform/transformResponses.d.ts.map +1 -1
- package/dist/src/transform/transformResponses.js +70 -16
- package/dist/src/transform/transformResponses.js.map +1 -1
- package/dist/src/transform/transformSchemas.d.ts.map +1 -1
- package/dist/src/transform/transformSchemas.js +5 -6
- package/dist/src/transform/transformSchemas.js.map +1 -1
- package/dist/src/transform/transformTelemetryInfo.d.ts.map +1 -1
- package/dist/src/transform/transformTelemetryInfo.js +3 -6
- package/dist/src/transform/transformTelemetryInfo.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +5 -6
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +3 -3
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +42 -24
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/src/utils/operationUtil.d.ts +2 -2
- package/dist/src/utils/operationUtil.d.ts.map +1 -1
- package/dist/src/utils/operationUtil.js +5 -7
- package/dist/src/utils/operationUtil.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +23 -23
- package/src/contextManager.ts +4 -0
- package/src/framework/declaration.ts +100 -0
- package/src/framework/hooks/binder.ts +259 -0
- package/src/framework/hooks/sdkTypes.ts +101 -0
- package/src/framework/reference.ts +9 -0
- package/src/framework/refkey.ts +28 -0
- package/src/framework/sample.ts +92 -0
- package/src/framework/utils/tsmorph-helpers.ts +0 -0
- package/src/index.ts +8 -10
- package/src/lib.ts +6 -0
- package/src/modular/buildClassicalClient.ts +11 -4
- package/src/modular/buildClientContext.ts +11 -5
- package/src/modular/buildCodeModel.ts +25 -21
- package/src/modular/buildOperations.ts +13 -41
- package/src/modular/buildRootIndex.ts +1 -1
- package/src/modular/buildSerializeUtils.ts +2 -1
- package/src/modular/helpers/clientHelpers.ts +25 -1
- package/src/modular/helpers/namingHelpers.ts +4 -1
- package/src/modular/helpers/operationHelpers.ts +86 -45
- package/src/modular/helpers/typeHelpers.ts +6 -1
- package/src/modular/modularCodeModel.ts +2 -0
- package/src/transform/transformApiVersionInfo.ts +3 -6
- package/src/transform/transformHelperFunctionDetails.ts +9 -9
- package/src/transform/transformParameters.ts +5 -6
- package/src/transform/transformPaths.ts +5 -9
- package/src/transform/transformResponses.ts +92 -19
- package/src/transform/transformSchemas.ts +6 -5
- package/src/transform/transformTelemetryInfo.ts +3 -5
- package/src/transform/transfromRLCOptions.ts +5 -10
- package/src/utils/modelUtils.ts +49 -39
- package/src/utils/operationUtil.ts +6 -12
- package/dist/src/modular/serialization/collectionUtils.d.ts +0 -3
- package/dist/src/modular/serialization/collectionUtils.d.ts.map +0 -1
- package/dist/src/modular/serialization/collectionUtils.js +0 -17
- package/dist/src/modular/serialization/collectionUtils.js.map +0 -1
- package/dist/src/modular/serialization/index.d.ts +0 -5
- package/dist/src/modular/serialization/index.d.ts.map +0 -1
- package/dist/src/modular/serialization/index.js +0 -155
- package/dist/src/modular/serialization/index.js.map +0 -1
- package/dist/src/modular/serialization/operationHelpers.d.ts +0 -37
- package/dist/src/modular/serialization/operationHelpers.d.ts.map +0 -1
- package/dist/src/modular/serialization/operationHelpers.js +0 -457
- package/dist/src/modular/serialization/operationHelpers.js.map +0 -1
- package/dist/src/modular/serialization/serializeArray.d.ts +0 -5
- package/dist/src/modular/serialization/serializeArray.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializeArray.js +0 -33
- package/dist/src/modular/serialization/serializeArray.js.map +0 -1
- package/dist/src/modular/serialization/serializeDateTime.d.ts +0 -4
- package/dist/src/modular/serialization/serializeDateTime.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializeDateTime.js +0 -19
- package/dist/src/modular/serialization/serializeDateTime.js.map +0 -1
- package/dist/src/modular/serialization/serializeHeaders.d.ts +0 -7
- package/dist/src/modular/serialization/serializeHeaders.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializeHeaders.js +0 -44
- package/dist/src/modular/serialization/serializeHeaders.js.map +0 -1
- package/dist/src/modular/serialization/serializers.d.ts +0 -17
- package/dist/src/modular/serialization/serializers.d.ts.map +0 -1
- package/dist/src/modular/serialization/serializers.js +0 -175
- package/dist/src/modular/serialization/serializers.js.map +0 -1
- package/dist/src/modular/serialization/util.d.ts +0 -27
- package/dist/src/modular/serialization/util.d.ts.map +0 -1
- package/dist/src/modular/serialization/util.js +0 -115
- package/dist/src/modular/serialization/util.js.map +0 -1
- package/dist/src/reify/index.d.ts +0 -12
- package/dist/src/reify/index.d.ts.map +0 -1
- package/dist/src/reify/index.js +0 -22
- package/dist/src/reify/index.js.map +0 -1
- package/src/modular/serialization/collectionUtils.ts +0 -20
- package/src/modular/serialization/index.ts +0 -267
- package/src/modular/serialization/operationHelpers.ts +0 -659
- package/src/modular/serialization/serializeArray.ts +0 -51
- package/src/modular/serialization/serializeDateTime.ts +0 -22
- package/src/modular/serialization/serializeHeaders.ts +0 -64
- package/src/modular/serialization/serializers.ts +0 -304
- package/src/modular/serialization/util.ts +0 -171
- package/src/modular/static/karma.conf.cjs +0 -120
- package/src/reify/index.ts +0 -41
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0-alpha.20240723.1",
|
|
4
4
|
"description": "An experimental TypeSpec emitter for TypeScript RLC",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -18,16 +18,16 @@
|
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@azure-rest/core-client": "^2.1.0",
|
|
21
|
-
"@azure-tools/cadl-ranch-expect": "^0.
|
|
22
|
-
"@azure-tools/cadl-ranch-specs": "^0.
|
|
23
|
-
"@azure-tools/cadl-ranch": "^0.
|
|
24
|
-
"@azure-tools/typespec-autorest": ">=0.
|
|
25
|
-
"@azure-tools/typespec-azure-core": ">=0.
|
|
26
|
-
"@azure-tools/typespec-azure-resource-manager": ">=0.
|
|
27
|
-
"@azure-tools/typespec-client-generator-core": ">=0.
|
|
21
|
+
"@azure-tools/cadl-ranch-expect": "^0.14.1",
|
|
22
|
+
"@azure-tools/cadl-ranch-specs": "^0.34.7",
|
|
23
|
+
"@azure-tools/cadl-ranch": "^0.13.4",
|
|
24
|
+
"@azure-tools/typespec-autorest": ">=0.44.0 <1.0.0",
|
|
25
|
+
"@azure-tools/typespec-azure-core": ">=0.44.0 <1.0.0",
|
|
26
|
+
"@azure-tools/typespec-azure-resource-manager": ">=0.44.0 <1.0.0",
|
|
27
|
+
"@azure-tools/typespec-client-generator-core": ">=0.44.1 <1.0.0",
|
|
28
28
|
"@azure/abort-controller": "^2.1.2",
|
|
29
29
|
"@azure/core-auth": "^1.6.0",
|
|
30
|
-
"@azure/core-lro": "3.0.0",
|
|
30
|
+
"@azure/core-lro": "^3.0.0",
|
|
31
31
|
"@azure/core-paging": "^1.5.0",
|
|
32
32
|
"@azure/core-rest-pipeline": "^1.14.0",
|
|
33
33
|
"@azure/core-util": "^1.4.0",
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"@types/node": "^18.0.0",
|
|
40
40
|
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
41
41
|
"@typescript-eslint/parser": "^6.8.0",
|
|
42
|
-
"@typespec/compiler": ">=0.
|
|
43
|
-
"@typespec/http": ">=0.
|
|
44
|
-
"@typespec/openapi": ">=0.
|
|
45
|
-
"@typespec/rest": ">=0.
|
|
42
|
+
"@typespec/compiler": ">=0.58.1 <1.0.0",
|
|
43
|
+
"@typespec/http": ">=0.58.0 <1.0.0",
|
|
44
|
+
"@typespec/openapi": ">=0.58.0, <1.0.0",
|
|
45
|
+
"@typespec/rest": ">=0.58.0 <1.0.0",
|
|
46
46
|
"@typespec/ts-http-runtime": "1.0.0-alpha.20240314.2",
|
|
47
|
-
"@typespec/versioning": ">=0.
|
|
47
|
+
"@typespec/versioning": ">=0.58.0 <1.0.0",
|
|
48
48
|
"chai": "^4.3.6",
|
|
49
49
|
"chalk": "^4.0.0",
|
|
50
50
|
"cross-env": "^7.0.3",
|
|
@@ -56,21 +56,21 @@
|
|
|
56
56
|
"prettier": "^3.1.0",
|
|
57
57
|
"rimraf": "^5.0.0",
|
|
58
58
|
"ts-node": "~10.9.1",
|
|
59
|
-
"typescript": "~5.
|
|
59
|
+
"typescript": "~5.5.3",
|
|
60
60
|
"vitest": "~1.6.0",
|
|
61
61
|
"@vitest/coverage-v8": "~1.6.0",
|
|
62
62
|
"@vitest/coverage-istanbul": "~1.6.0"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
-
"@azure-tools/typespec-azure-core": ">=0.
|
|
66
|
-
"@azure-tools/typespec-client-generator-core": ">=0.
|
|
67
|
-
"@typespec/compiler": ">=0.
|
|
68
|
-
"@typespec/http": ">=0.
|
|
69
|
-
"@typespec/rest": ">=0.
|
|
70
|
-
"@typespec/versioning": ">=0.
|
|
65
|
+
"@azure-tools/typespec-azure-core": ">=0.44.0 <1.0.0",
|
|
66
|
+
"@azure-tools/typespec-client-generator-core": ">=0.44.1 <1.0.0",
|
|
67
|
+
"@typespec/compiler": ">=0.58.1 <1.0.0",
|
|
68
|
+
"@typespec/http": ">=0.58.0 <1.0.0",
|
|
69
|
+
"@typespec/rest": ">=0.58.0 <1.0.0",
|
|
70
|
+
"@typespec/versioning": ">=0.58.0 <1.0.0"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@azure-tools/rlc-common": "^0.
|
|
73
|
+
"@azure-tools/rlc-common": "^0.31.0",
|
|
74
74
|
"fs-extra": "^11.1.0",
|
|
75
75
|
"lodash": "^4.17.21",
|
|
76
76
|
"prettier": "^3.1.0",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"test-next:coverage": "vitest run ./test-next --coverage",
|
|
100
100
|
"clean": "rimraf ./dist ./typespec-output",
|
|
101
101
|
"build": "tsc -p .",
|
|
102
|
-
"test": "npm run unit-test && npm run integration-test-ci",
|
|
102
|
+
"test": "npm run test-next && npm run unit-test && npm run integration-test-ci",
|
|
103
103
|
"lint": "eslint src --ext .ts --max-warnings=0",
|
|
104
104
|
"lint:fix": "eslint src --fix --ext .ts",
|
|
105
105
|
"format": "npm run -s prettier -- --write",
|
package/src/contextManager.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { Project, SourceFile } from "ts-morph";
|
|
|
2
2
|
import { ModularMetaTree, RlcMetaTree } from "./metaTree.js";
|
|
3
3
|
import { EmitContext } from "@typespec/compiler";
|
|
4
4
|
import { SdkContext } from "@azure-tools/typespec-client-generator-core";
|
|
5
|
+
import { SdkTypeContext } from "./framework/hooks/sdkTypes.js";
|
|
6
|
+
import { Binder } from "./framework/hooks/binder.js";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Contexts Object Guidelines
|
|
@@ -21,10 +23,12 @@ type Contexts = {
|
|
|
21
23
|
modularMetaTree: ModularMetaTree; // Context for modular types metadata.
|
|
22
24
|
outputProject: Project; // The TS-Morph root project context for code generation.
|
|
23
25
|
symbolMap: Map<string, SourceFile>; // Mapping of symbols to their corresponding source files.
|
|
26
|
+
sdkTypes: SdkTypeContext;
|
|
24
27
|
emitContext: {
|
|
25
28
|
compilerContext: EmitContext;
|
|
26
29
|
tcgcContext: SdkContext;
|
|
27
30
|
};
|
|
31
|
+
binder: Binder;
|
|
28
32
|
};
|
|
29
33
|
|
|
30
34
|
type ContextKey = keyof Contexts;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SourceFile,
|
|
3
|
+
ClassDeclarationStructure,
|
|
4
|
+
EnumDeclarationStructure,
|
|
5
|
+
FunctionDeclarationStructure,
|
|
6
|
+
InterfaceDeclarationStructure,
|
|
7
|
+
TypeAliasDeclarationStructure,
|
|
8
|
+
StructureKind,
|
|
9
|
+
ClassDeclaration,
|
|
10
|
+
EnumDeclaration,
|
|
11
|
+
FunctionDeclaration,
|
|
12
|
+
InterfaceDeclaration,
|
|
13
|
+
TypeAliasDeclaration
|
|
14
|
+
} from "ts-morph";
|
|
15
|
+
import { useBinder } from "./hooks/binder.js";
|
|
16
|
+
import { refkey as getRefKey } from "./refkey.js";
|
|
17
|
+
export type DeclarationStructures =
|
|
18
|
+
| ClassDeclarationStructure
|
|
19
|
+
| EnumDeclarationStructure
|
|
20
|
+
| FunctionDeclarationStructure
|
|
21
|
+
| InterfaceDeclarationStructure
|
|
22
|
+
| TypeAliasDeclarationStructure;
|
|
23
|
+
|
|
24
|
+
export type Declarations =
|
|
25
|
+
| ClassDeclaration
|
|
26
|
+
| EnumDeclaration
|
|
27
|
+
| FunctionDeclaration
|
|
28
|
+
| InterfaceDeclaration
|
|
29
|
+
| TypeAliasDeclaration;
|
|
30
|
+
|
|
31
|
+
export function addDeclaration(
|
|
32
|
+
sourceFile: SourceFile,
|
|
33
|
+
declaration: ClassDeclarationStructure,
|
|
34
|
+
refkey: unknown
|
|
35
|
+
): ClassDeclaration;
|
|
36
|
+
|
|
37
|
+
export function addDeclaration(
|
|
38
|
+
sourceFile: SourceFile,
|
|
39
|
+
declaration: EnumDeclarationStructure,
|
|
40
|
+
refkey: unknown
|
|
41
|
+
): EnumDeclaration;
|
|
42
|
+
|
|
43
|
+
export function addDeclaration(
|
|
44
|
+
sourceFile: SourceFile,
|
|
45
|
+
declaration: FunctionDeclarationStructure,
|
|
46
|
+
refkey: unknown
|
|
47
|
+
): FunctionDeclaration;
|
|
48
|
+
|
|
49
|
+
export function addDeclaration(
|
|
50
|
+
sourceFile: SourceFile,
|
|
51
|
+
declaration: InterfaceDeclarationStructure,
|
|
52
|
+
refkey: unknown
|
|
53
|
+
): InterfaceDeclaration;
|
|
54
|
+
|
|
55
|
+
export function addDeclaration(
|
|
56
|
+
sourceFile: SourceFile,
|
|
57
|
+
declaration: TypeAliasDeclarationStructure,
|
|
58
|
+
refkey: unknown
|
|
59
|
+
): TypeAliasDeclaration;
|
|
60
|
+
export function addDeclaration(
|
|
61
|
+
sourceFile: SourceFile,
|
|
62
|
+
declaration: DeclarationStructures,
|
|
63
|
+
refkey: unknown
|
|
64
|
+
): Declarations {
|
|
65
|
+
const binder = useBinder();
|
|
66
|
+
|
|
67
|
+
if (!declaration.name) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Declaration must have a name ${JSON.stringify(declaration)}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const stringRefkey = typeof refkey === "string" ? refkey : getRefKey(refkey);
|
|
74
|
+
|
|
75
|
+
const trackedDeclarationName = binder.trackDeclaration(
|
|
76
|
+
stringRefkey,
|
|
77
|
+
declaration.name,
|
|
78
|
+
sourceFile
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Update the declaration name to be unique
|
|
82
|
+
const trackedDeclaration = { ...declaration, name: trackedDeclarationName };
|
|
83
|
+
|
|
84
|
+
switch (trackedDeclaration.kind) {
|
|
85
|
+
case StructureKind.Class:
|
|
86
|
+
return sourceFile.addClass(trackedDeclaration);
|
|
87
|
+
case StructureKind.Enum:
|
|
88
|
+
return sourceFile.addEnum(trackedDeclaration);
|
|
89
|
+
case StructureKind.Function:
|
|
90
|
+
return sourceFile.addFunction(trackedDeclaration);
|
|
91
|
+
case StructureKind.Interface:
|
|
92
|
+
return sourceFile.addInterface(trackedDeclaration);
|
|
93
|
+
case StructureKind.TypeAlias:
|
|
94
|
+
return sourceFile.addTypeAlias(trackedDeclaration);
|
|
95
|
+
default:
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Unsupported declaration kind ${(trackedDeclaration as any).kind}`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SourceFile,
|
|
3
|
+
ImportDeclarationStructure,
|
|
4
|
+
StructureKind,
|
|
5
|
+
ImportSpecifierStructure,
|
|
6
|
+
Project
|
|
7
|
+
} from "ts-morph";
|
|
8
|
+
import { provideContext, useContext } from "../../contextManager.js";
|
|
9
|
+
|
|
10
|
+
export interface DeclarationInfo {
|
|
11
|
+
name: string;
|
|
12
|
+
sourceFile: SourceFile;
|
|
13
|
+
alias?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface Binder {
|
|
17
|
+
/**
|
|
18
|
+
* Tracks a new declaration.
|
|
19
|
+
* @param refkey - A unique reference key for the declaration.
|
|
20
|
+
* @param name - The name of the declaration.
|
|
21
|
+
* @param sourceFile - The source file where the declaration is made.
|
|
22
|
+
* @returns The tracked declaration name.
|
|
23
|
+
*/
|
|
24
|
+
trackDeclaration(
|
|
25
|
+
refkey: unknown,
|
|
26
|
+
name: string,
|
|
27
|
+
sourceFile: SourceFile
|
|
28
|
+
): string;
|
|
29
|
+
resolveReference(refkey: unknown): string;
|
|
30
|
+
applyImports(): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class BinderImp implements Binder {
|
|
34
|
+
private declarations = new Map<unknown, DeclarationInfo>();
|
|
35
|
+
private imports = new Map<SourceFile, ImportDeclarationStructure[]>();
|
|
36
|
+
private symbolsBySourceFile = new Map<SourceFile, Set<string>>();
|
|
37
|
+
private project: Project;
|
|
38
|
+
|
|
39
|
+
constructor(project?: Project) {
|
|
40
|
+
this.project = project ?? new Project();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
trackDeclaration(
|
|
44
|
+
refkey: unknown,
|
|
45
|
+
name: string,
|
|
46
|
+
sourceFile: SourceFile
|
|
47
|
+
): string {
|
|
48
|
+
const uniqueName = this.generateLocallyUniqueDeclarationName(
|
|
49
|
+
name,
|
|
50
|
+
sourceFile
|
|
51
|
+
);
|
|
52
|
+
const declarationInfo: DeclarationInfo = { name: uniqueName, sourceFile };
|
|
53
|
+
this.declarations.set(refkey, declarationInfo);
|
|
54
|
+
|
|
55
|
+
// Ensure symbolsBySourceFile has an entry for this sourceFile
|
|
56
|
+
if (!this.symbolsBySourceFile.has(sourceFile)) {
|
|
57
|
+
this.symbolsBySourceFile.set(sourceFile, new Set());
|
|
58
|
+
}
|
|
59
|
+
this.symbolsBySourceFile.get(sourceFile)!.add(uniqueName);
|
|
60
|
+
|
|
61
|
+
return uniqueName;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generates a locally unique name for a declaration within a source file.
|
|
66
|
+
* @param name - The base name of the declaration.
|
|
67
|
+
* @param sourceFile - The source file where the declaration is made.
|
|
68
|
+
* @returns A unique name for the declaration within the file.
|
|
69
|
+
*/
|
|
70
|
+
private generateLocallyUniqueDeclarationName(
|
|
71
|
+
name: string,
|
|
72
|
+
sourceFile: SourceFile
|
|
73
|
+
): string {
|
|
74
|
+
const existingNamesInFile =
|
|
75
|
+
this.symbolsBySourceFile.get(sourceFile) ?? new Set<string>();
|
|
76
|
+
return this.generateLocallyUniqueName(name, existingNamesInFile);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Generates a locally unique name for an import within a source file.
|
|
81
|
+
* @param name - The base name of the import.
|
|
82
|
+
* @param sourceFile - The source file where the import is made.
|
|
83
|
+
* @returns A unique name for the import within the file.
|
|
84
|
+
*/
|
|
85
|
+
private generateLocallyUniqueImportName(
|
|
86
|
+
name: string,
|
|
87
|
+
sourceFile: SourceFile
|
|
88
|
+
): string {
|
|
89
|
+
const existingImports = (this.imports.get(sourceFile) ?? [])
|
|
90
|
+
.flatMap((i) => i.namedImports as ImportSpecifierStructure[])
|
|
91
|
+
.map((i) => i.alias ?? i.name);
|
|
92
|
+
|
|
93
|
+
const existingDeclarations =
|
|
94
|
+
this.symbolsBySourceFile.get(sourceFile) ?? new Set<string>();
|
|
95
|
+
return this.generateLocallyUniqueName(
|
|
96
|
+
name,
|
|
97
|
+
new Set([...existingImports, ...existingDeclarations])
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Generates a locally unique name within a set of existing names.
|
|
103
|
+
* @param name - The base name.
|
|
104
|
+
* @param existingNames - A set of names already in use.
|
|
105
|
+
* @returns A unique name not present in the existing names set.
|
|
106
|
+
*/
|
|
107
|
+
private generateLocallyUniqueName(
|
|
108
|
+
name: string,
|
|
109
|
+
existingNames: Set<string>
|
|
110
|
+
): string {
|
|
111
|
+
let uniqueName = name;
|
|
112
|
+
let counter = 1;
|
|
113
|
+
while (existingNames.has(uniqueName)) {
|
|
114
|
+
uniqueName = `${name}_${counter}`;
|
|
115
|
+
counter++;
|
|
116
|
+
}
|
|
117
|
+
return uniqueName;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Resolves a reference to a declaration.
|
|
122
|
+
* If a declaration is not ready yet, a placeholder is added to the source file.
|
|
123
|
+
* Placeholders will be resolved when the imports are applied.
|
|
124
|
+
* @param refkey - The reference key for the declaration.
|
|
125
|
+
* @param currentSourceFile - The current source file where the reference is being resolved.
|
|
126
|
+
* @returns The declaration information if resolved, or a placeholder if not found.
|
|
127
|
+
*/
|
|
128
|
+
resolveReference(refkey: unknown): string {
|
|
129
|
+
return this.serializePlaceholder(refkey);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Serializes a placeholder reference key to a string.
|
|
134
|
+
* @param refkey - The reference key.
|
|
135
|
+
* @returns The serialized placeholder string.
|
|
136
|
+
*/
|
|
137
|
+
private serializePlaceholder(refkey: unknown): string {
|
|
138
|
+
return `PLACEHOLDER:${String(refkey)}`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Adds an import declaration to a source file.
|
|
143
|
+
* @param fileWhereImportIsAdded - The source file where the import is added.
|
|
144
|
+
* @param fileWhereImportPointsTo - The source file being imported.
|
|
145
|
+
* @param name - The name of the import.
|
|
146
|
+
* @returns The import specifier structure.
|
|
147
|
+
*/
|
|
148
|
+
private addImport(
|
|
149
|
+
fileWhereImportIsAdded: SourceFile,
|
|
150
|
+
fileWhereImportPointsTo: SourceFile,
|
|
151
|
+
name: string
|
|
152
|
+
): ImportSpecifierStructure {
|
|
153
|
+
const importAlias = this.generateLocallyUniqueImportName(
|
|
154
|
+
name,
|
|
155
|
+
fileWhereImportIsAdded
|
|
156
|
+
);
|
|
157
|
+
const relativePath =
|
|
158
|
+
fileWhereImportIsAdded.getRelativePathAsModuleSpecifierTo(
|
|
159
|
+
fileWhereImportPointsTo
|
|
160
|
+
);
|
|
161
|
+
const importStructures = this.imports.get(fileWhereImportIsAdded) || [];
|
|
162
|
+
|
|
163
|
+
let importStructure = importStructures.find(
|
|
164
|
+
(imp) => imp.moduleSpecifier === relativePath
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (!importStructure) {
|
|
168
|
+
importStructure = {
|
|
169
|
+
kind: StructureKind.ImportDeclaration,
|
|
170
|
+
moduleSpecifier: relativePath,
|
|
171
|
+
namedImports: []
|
|
172
|
+
};
|
|
173
|
+
importStructures.push(importStructure);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const namedImports =
|
|
177
|
+
importStructure.namedImports as ImportSpecifierStructure[];
|
|
178
|
+
let importSpecifier = namedImports.find((n) => n.name === importAlias);
|
|
179
|
+
|
|
180
|
+
if (!importSpecifier) {
|
|
181
|
+
importSpecifier = {
|
|
182
|
+
name: name,
|
|
183
|
+
alias: name === importAlias ? undefined : importAlias,
|
|
184
|
+
kind: StructureKind.ImportSpecifier
|
|
185
|
+
};
|
|
186
|
+
namedImports.push(importSpecifier);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
importStructure.namedImports = namedImports;
|
|
190
|
+
this.imports.set(fileWhereImportIsAdded, importStructures);
|
|
191
|
+
return importSpecifier;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Applies all tracked imports to their respective source files.
|
|
196
|
+
*/
|
|
197
|
+
applyImports(): void {
|
|
198
|
+
for (const file of this.project.getSourceFiles()) {
|
|
199
|
+
for (const [declarationKey, declaration] of this.declarations) {
|
|
200
|
+
const placeholderKey = this.serializePlaceholder(declarationKey);
|
|
201
|
+
let name = declaration.name;
|
|
202
|
+
if (file !== declaration.sourceFile) {
|
|
203
|
+
const importDec = this.addImport(
|
|
204
|
+
file,
|
|
205
|
+
declaration.sourceFile,
|
|
206
|
+
declaration.name
|
|
207
|
+
);
|
|
208
|
+
name = importDec.alias ?? declaration.name;
|
|
209
|
+
}
|
|
210
|
+
replacePlaceholder(file, placeholderKey, name);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
for (const [sourceFile, importStructures] of this.imports) {
|
|
215
|
+
for (const importStructure of importStructures) {
|
|
216
|
+
sourceFile.addImportDeclaration(importStructure);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Provide the binder context to be used globally
|
|
223
|
+
export function provideBinder(project?: Project): void {
|
|
224
|
+
return provideContext("binder", new BinderImp(project));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Hook to use the binder context.
|
|
229
|
+
* @returns The binder instance.
|
|
230
|
+
*/
|
|
231
|
+
export function useBinder(): Binder {
|
|
232
|
+
return useContext("binder");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Replaces all instances of a placeholder in a source file with a given value.
|
|
237
|
+
* @param sourceFile - The source file where the replacement occurs.
|
|
238
|
+
* @param placeholder - The placeholder string to replace.
|
|
239
|
+
* @param value - The value to replace the placeholder with.
|
|
240
|
+
*/
|
|
241
|
+
function replacePlaceholder(
|
|
242
|
+
sourceFile: SourceFile,
|
|
243
|
+
placeholder: string,
|
|
244
|
+
value: string
|
|
245
|
+
): void {
|
|
246
|
+
const fileText = sourceFile.getFullText();
|
|
247
|
+
const regex = new RegExp(escapeRegExp(placeholder), "g");
|
|
248
|
+
const updatedText = fileText.replace(regex, value);
|
|
249
|
+
sourceFile.replaceWithText(updatedText);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Escapes special characters in a string to be used in a regular expression.
|
|
254
|
+
* @param string - The input string.
|
|
255
|
+
* @returns The escaped string.
|
|
256
|
+
*/
|
|
257
|
+
function escapeRegExp(string: string): string {
|
|
258
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
259
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SdkClientType,
|
|
3
|
+
SdkHttpOperation,
|
|
4
|
+
SdkPackage,
|
|
5
|
+
SdkServiceMethod,
|
|
6
|
+
SdkType,
|
|
7
|
+
getClientType
|
|
8
|
+
} from "@azure-tools/typespec-client-generator-core";
|
|
9
|
+
import { Operation, Type, getNamespaceFullName } from "@typespec/compiler";
|
|
10
|
+
import { provideContext, useContext } from "../../contextManager.js";
|
|
11
|
+
|
|
12
|
+
export interface SdkTypeContext {
|
|
13
|
+
operations: Map<Type, SdkServiceMethod<SdkHttpOperation>>;
|
|
14
|
+
types: Map<Type, SdkType>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useSdkTypes() {
|
|
18
|
+
const sdkTypesContext = useContext("sdkTypes");
|
|
19
|
+
const { tcgcContext } = useContext("emitContext");
|
|
20
|
+
|
|
21
|
+
function getSdkType(type: Operation): SdkServiceMethod<SdkHttpOperation>;
|
|
22
|
+
function getSdkType(type: Type): SdkType;
|
|
23
|
+
function getSdkType(
|
|
24
|
+
type: Type | Operation
|
|
25
|
+
): SdkType | SdkServiceMethod<SdkHttpOperation> {
|
|
26
|
+
let sdkType: SdkType | SdkServiceMethod<SdkHttpOperation> | undefined;
|
|
27
|
+
|
|
28
|
+
if (type.kind === "Operation") {
|
|
29
|
+
sdkType = sdkTypesContext.operations.get(type);
|
|
30
|
+
} else {
|
|
31
|
+
sdkType =
|
|
32
|
+
sdkTypesContext.types.get(type) ?? getClientType(tcgcContext, type);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!sdkType) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`SdkType not found for type: ${type.kind} ${
|
|
38
|
+
"name" in type && typeof type.name == "string" ? type.name : ""
|
|
39
|
+
} ${
|
|
40
|
+
"namespace" in type && type.namespace
|
|
41
|
+
? ` in ${getNamespaceFullName(type.namespace)}`
|
|
42
|
+
: ""
|
|
43
|
+
}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return sdkType;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return getSdkType;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function provideSdkTypes(sdkPackage: SdkPackage<SdkHttpOperation>) {
|
|
54
|
+
const sdkTypesContext = {
|
|
55
|
+
operations: new Map<Type, SdkServiceMethod<SdkHttpOperation>>(),
|
|
56
|
+
types: new Map<Type, SdkType>()
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
for (const sdkEnum of sdkPackage.enums) {
|
|
60
|
+
if (!sdkEnum.__raw) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
sdkTypesContext.types.set(sdkEnum.__raw, sdkEnum);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
for (const sdkModel of sdkPackage.models) {
|
|
68
|
+
if (!sdkModel.__raw) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
sdkTypesContext.types.set(sdkModel.__raw, sdkModel);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (const client of sdkPackage.clients) {
|
|
76
|
+
for (const method of getAllOperationsFromClient(client)) {
|
|
77
|
+
if (!method.__raw) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
sdkTypesContext.operations.set(method.__raw, method);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
provideContext("sdkTypes", sdkTypesContext);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getAllOperationsFromClient(client: SdkClientType<SdkHttpOperation>) {
|
|
89
|
+
const methodQueue = [...client.methods];
|
|
90
|
+
const operations: SdkServiceMethod<SdkHttpOperation>[] = [];
|
|
91
|
+
while (methodQueue.length > 0) {
|
|
92
|
+
const method = methodQueue.pop()!;
|
|
93
|
+
if (method.kind === "clientaccessor") {
|
|
94
|
+
method.response.methods.forEach((m) => methodQueue.push(m));
|
|
95
|
+
} else {
|
|
96
|
+
operations.push(method);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return operations;
|
|
101
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useBinder } from "./hooks/binder.js";
|
|
2
|
+
import { refkey as getRefKey } from "./refkey.js";
|
|
3
|
+
|
|
4
|
+
export function resolveReference(refkey: unknown): string | undefined {
|
|
5
|
+
const binder = useBinder();
|
|
6
|
+
const stringRefkey = typeof refkey === "string" ? refkey : getRefKey(refkey);
|
|
7
|
+
|
|
8
|
+
return binder.resolveReference(stringRefkey);
|
|
9
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const objectIds = new WeakMap<WeakKey, string>();
|
|
2
|
+
let objId = 0;
|
|
3
|
+
|
|
4
|
+
function getObjectKey(value: WeakKey) {
|
|
5
|
+
if (objectIds.has(value)) {
|
|
6
|
+
return `${objectIds.get(value)}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const key = `o${objId++}`;
|
|
10
|
+
objectIds.set(value, key);
|
|
11
|
+
|
|
12
|
+
return key;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare const RefkeySym: unique symbol;
|
|
16
|
+
export type RefKey = string & { [RefkeySym]: true };
|
|
17
|
+
|
|
18
|
+
function getKey(value: unknown): RefKey {
|
|
19
|
+
if (typeof value === "object" && value !== null) {
|
|
20
|
+
return getObjectKey(value) as RefKey;
|
|
21
|
+
} else {
|
|
22
|
+
return `s${String(value)}` as RefKey;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function refkey(...args: unknown[]) {
|
|
27
|
+
return args.map((v) => getKey(v)).join("\u2063");
|
|
28
|
+
}
|