typespec-typescript-emitter 0.2.0 → 0.3.0
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/.husky/pre-commit +3 -0
- package/.prettierignore +1 -0
- package/CHANGELOG.md +28 -5
- package/README.md +49 -32
- package/dist/src/emit_routes.d.ts +5 -1
- package/dist/src/emit_routes.js +68 -33
- package/dist/src/emit_routes.js.map +1 -1
- package/dist/src/emit_types.d.ts +8 -6
- package/dist/src/emit_types.js +49 -155
- package/dist/src/emit_types.js.map +1 -1
- package/dist/src/emit_types_resolve.d.ts +8 -0
- package/dist/src/emit_types_resolve.js +122 -0
- package/dist/src/emit_types_resolve.js.map +1 -0
- package/dist/src/emit_types_typeguards.d.ts +17 -0
- package/dist/src/emit_types_typeguards.js +107 -0
- package/dist/src/emit_types_typeguards.js.map +1 -0
- package/dist/src/emitter.d.ts +5 -0
- package/dist/src/emitter.js +23 -10
- package/dist/src/emitter.js.map +1 -1
- package/dist/src/lib.d.ts +2 -0
- package/dist/src/lib.js +2 -0
- package/dist/src/lib.js.map +1 -1
- package/eslint.config.js +6 -1
- package/package.json +6 -7
- package/src/emit_routes.ts +104 -37
- package/src/emit_types.ts +55 -187
- package/src/emit_types_resolve.ts +167 -0
- package/src/emit_types_typeguards.ts +137 -0
- package/src/emitter.ts +38 -8
- package/src/lib.ts +4 -0
package/.husky/pre-commit
CHANGED
package/.prettierignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
**/*.md
|
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
|
-
# 0.2.0 (2024-
|
|
1
|
+
# [0.3.0](https://github.com/crowbait/typespec-typescript-emitter/compare/v0.2.0...v0.3.0) (2024-12-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* content-type+body response models in typeguards ([61f37e3](https://github.com/crowbait/typespec-typescript-emitter/commit/61f37e31a330585f4b97ffd7aa2e4a6aa73cc689))
|
|
7
|
+
* remove useless routes interface ([b828ee9](https://github.com/crowbait/typespec-typescript-emitter/commit/b828ee994743c7fbbb313adb042088057f59466f))
|
|
8
|
+
* typo in typeguards (double space) ([253aacf](https://github.com/crowbait/typespec-typescript-emitter/commit/253aacff2859e58c659a1357a0d7e16088520f6f))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* support for unions and nested models in typeguards ([9292107](https://github.com/crowbait/typespec-typescript-emitter/commit/92921073ad83a1cec74d7b7595cb178120cdc32b))
|
|
14
|
+
* typeguards ([8dc3eef](https://github.com/crowbait/typespec-typescript-emitter/commit/8dc3eef62c4d9bc0df71d7878ada52254ed1475a))
|
|
15
|
+
* typeguards in routes ([010388a](https://github.com/crowbait/typespec-typescript-emitter/commit/010388a2ff1c0c53ce34828e4197e31ada745e83))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# [0.2.0](https://github.com/crowbait/typespec-typescript-emitter/compare/fdafc1c081058e9d683946b010d10ff3bd962cdc...v0.2.0) (2024-11-12)
|
|
20
|
+
|
|
2
21
|
|
|
3
22
|
### Bug Fixes
|
|
4
23
|
|
|
5
|
-
|
|
24
|
+
* warning log level ([8b74b01](https://github.com/crowbait/typespec-typescript-emitter/commit/8b74b0197ed4b8fa3aad57d0f50cb884af879243))
|
|
25
|
+
|
|
6
26
|
|
|
7
27
|
### Features
|
|
8
28
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
29
|
+
* routes emitter ([fdafc1c](https://github.com/crowbait/typespec-typescript-emitter/commit/fdafc1c081058e9d683946b010d10ff3bd962cdc))
|
|
30
|
+
* support optional model properties ([729d9f1](https://github.com/crowbait/typespec-typescript-emitter/commit/729d9f125434ead7a33326014082cd172c79f2ff))
|
|
31
|
+
* types emitter ([e31d459](https://github.com/crowbait/typespec-typescript-emitter/commit/e31d459edce08d010e590681e3a2e17d636de64e))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
package/README.md
CHANGED
|
@@ -6,22 +6,24 @@ TypeScript output to a TypeSpec project.
|
|
|
6
6
|
Currently, this library is tailored to my specific use case, which is defining
|
|
7
7
|
an HTTP API. The 'routes'-emitter will only work on HTTP operations. **However**, exporting all models as types is independent of HTTP, and so may also benefit projects with a different usage scenario.
|
|
8
8
|
|
|
9
|
-
It can
|
|
9
|
+
It can the following things:
|
|
10
10
|
|
|
11
11
|
- ts files exporting every model present in the spec
|
|
12
12
|
- 1 file for each (nested) namespace
|
|
13
13
|
- exports models, enums and unions
|
|
14
14
|
- does NOT export aliases (see below)
|
|
15
|
+
- optional typeguards, *if* type export is enabled
|
|
16
|
+
- referenced or generated in the routes object as well, if enabled (experimental)
|
|
15
17
|
- for `TypeSpec.Http`: ts file containing a nested object containing information about every route
|
|
16
18
|
- this can be imported at runtime to provide a robust way of eg. accessing URLs
|
|
17
19
|
|
|
18
|
-
## Content
|
|
20
|
+
## Content <!-- omit from toc -->
|
|
19
21
|
|
|
20
22
|
- [Installation](#installation)
|
|
21
23
|
- [Configuration](#configuration)
|
|
22
|
-
- [Types
|
|
24
|
+
- [Types emitter](#types-emitter)
|
|
23
25
|
- [Alias's](#aliass)
|
|
24
|
-
- [Routes
|
|
26
|
+
- [Routes emitter](#routes-emitter)
|
|
25
27
|
|
|
26
28
|
## Installation
|
|
27
29
|
|
|
@@ -41,7 +43,9 @@ options:
|
|
|
41
43
|
root-namespace: "string"
|
|
42
44
|
out-dir: "{cwd}/path"
|
|
43
45
|
enable-types: true
|
|
44
|
-
enable-
|
|
46
|
+
enable-typeguards: false
|
|
47
|
+
enable-routes: false
|
|
48
|
+
typeguards-in-routes: true
|
|
45
49
|
```
|
|
46
50
|
|
|
47
51
|
The following options are available:
|
|
@@ -49,7 +53,9 @@ The following options are available:
|
|
|
49
53
|
- `root-namespace` **(required)**: name of the most outer namespace. As the TypeSpec docs recommend, your project is expected to consist of one or more nested namespaces. Here, you need to specify the most outer / general namespace you want emitted.
|
|
50
54
|
- `out-dir`: output directory. Must be an absolute path; replacers like `{cwd}` are permitted.
|
|
51
55
|
- `enable-types` (default: true): enables output of TypeScript types.
|
|
56
|
+
- `enable-typeguards` (default: false): enables output of typeguards, *IF* type-output is enabled.
|
|
52
57
|
- `enable-routes` (default: false): enables output of the HTTP-routes object.
|
|
58
|
+
- `typeguards-in-routes` (default: false) **Experimental**: generates or references typeguards in the routes object, *IF* types, typeguards *and* routes are enabled.
|
|
53
59
|
|
|
54
60
|
## Types emitter
|
|
55
61
|
|
|
@@ -94,20 +100,34 @@ namespace myProject { // remember to set in config!
|
|
|
94
100
|
export enum ReadStatus {
|
|
95
101
|
Never,
|
|
96
102
|
Once,
|
|
97
|
-
Often
|
|
103
|
+
Often
|
|
98
104
|
}
|
|
99
105
|
export type Author = "unknown" | string;
|
|
100
106
|
export interface Book {
|
|
101
|
-
author: Author
|
|
102
|
-
title: string
|
|
103
|
-
subtitile: null | string
|
|
104
|
-
read: ReadStatus
|
|
105
|
-
chapterTitles?: string[]
|
|
107
|
+
author: Author,
|
|
108
|
+
title: string,
|
|
109
|
+
subtitile: null | string,
|
|
110
|
+
read: ReadStatus,
|
|
111
|
+
chapterTitles?: string[]
|
|
106
112
|
}
|
|
107
113
|
|
|
114
|
+
// if `enable-typeguards` is set to true
|
|
115
|
+
export function isBook(arg: any): arg is Book {
|
|
116
|
+
return (
|
|
117
|
+
(arg['author'] !== undefined) &&
|
|
118
|
+
(arg['title'] !== undefined && typeof arg['title'] === 'string') &&
|
|
119
|
+
(arg['subtitle'] !== undefined) &&
|
|
120
|
+
(arg['read'] !== undefined) &&
|
|
121
|
+
(arg['chapterTitles'] === undefined || Array.isArray(arg['chapterTitles']))
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
|
+
|
|
108
125
|
// the other namespace will be emitted to `/path/to/outdir/SubNameSpace.ts`
|
|
109
126
|
```
|
|
110
127
|
|
|
128
|
+
Typeguards *should* create comprehensive checks that adhere as strictly to the source model as possible.
|
|
129
|
+
If you find a case where the typeguard is looser than it needs to be, please report that as a bug.
|
|
130
|
+
|
|
111
131
|
### Alias's
|
|
112
132
|
|
|
113
133
|
There seems to be no way to extract aliases from TypeSpec's emitter framework. Because of that, `Alias`'s are ignored by the emitter (or, to be more precise: `Alias`'s reach the emitter already resolved. They won't be exported as their own type but directly substituted where they're needed).
|
|
@@ -143,12 +163,14 @@ Example:
|
|
|
143
163
|
@server("https://api.example.com", "Server")
|
|
144
164
|
namespace myProject { // remember to set in config!
|
|
145
165
|
@get
|
|
146
|
-
op getSomething(): string;
|
|
166
|
+
op getSomething(): {@body body: string};
|
|
167
|
+
// if you want to use `typeguards-in-routes`, make sure
|
|
168
|
+
// to properly declare responses as a model with a `body`-property
|
|
147
169
|
|
|
148
170
|
@get
|
|
149
171
|
@route("{param}")
|
|
150
172
|
@useAuth(NoAuth | BasicAuth)
|
|
151
|
-
op getSmthElse(@path param: string): string;
|
|
173
|
+
op getSmthElse(@path param: string): {@body body: string};
|
|
152
174
|
|
|
153
175
|
@route("/subroute")
|
|
154
176
|
namespace sub {
|
|
@@ -158,7 +180,7 @@ namespace myProject { // remember to set in config!
|
|
|
158
180
|
op postSomething(
|
|
159
181
|
@path post_param: int32,
|
|
160
182
|
@body body: string
|
|
161
|
-
): string;
|
|
183
|
+
): {@body body: string};
|
|
162
184
|
}
|
|
163
185
|
}
|
|
164
186
|
```
|
|
@@ -167,37 +189,32 @@ namespace myProject { // remember to set in config!
|
|
|
167
189
|
|
|
168
190
|
```ts
|
|
169
191
|
/* /path/to/outdir/routes_{root-namespace}.ts */
|
|
170
|
-
export interface IRoute {
|
|
171
|
-
method: string
|
|
172
|
-
getUrl: (p: any) => string
|
|
173
|
-
auth: boolean | 'varies'
|
|
174
|
-
};
|
|
175
|
-
|
|
176
192
|
export const routes_myProject = {
|
|
177
193
|
getSomething: {
|
|
178
194
|
method: 'get',
|
|
179
195
|
getUrl: () => 'https://api.example.com/',
|
|
180
|
-
auth: false
|
|
196
|
+
auth: false,
|
|
197
|
+
// with `typeguards-in-routes`
|
|
198
|
+
isRequestType: null,
|
|
199
|
+
isResponseType: (arg: any): boolean => typeof arg === 'string'
|
|
181
200
|
},
|
|
182
201
|
getSmthElse: {
|
|
183
202
|
method: 'get',
|
|
184
203
|
getUrl: (p: {param: string}) => `https://api.example.com/${p.param}`,
|
|
185
|
-
auth: 'varies
|
|
204
|
+
auth: 'varies',
|
|
205
|
+
// with `typeguards-in-routes`
|
|
206
|
+
isRequestType: null,
|
|
207
|
+
isResponseType: (arg: any): boolean => typeof arg === 'string'
|
|
186
208
|
},
|
|
187
209
|
sub: {
|
|
188
210
|
postSomething: {
|
|
189
211
|
method: 'post',
|
|
190
212
|
getUrl: (p: {post_param: string}) => `https://api.example.com/subroute/post/${p.post_param}`,
|
|
191
|
-
auth: true
|
|
213
|
+
auth: true,
|
|
214
|
+
// with `typeguards-in-routes`
|
|
215
|
+
isRequestType: (arg: any): boolean => typeof arg === 'string',
|
|
216
|
+
isResponseType: (arg: any): boolean => typeof arg === 'string'
|
|
192
217
|
}
|
|
193
218
|
}
|
|
194
219
|
} as const;
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
The `IRoute` interface should be used sparsely. Consider the following:
|
|
198
|
-
|
|
199
|
-
```ts
|
|
200
|
-
const foo: IRoute = routes_myProject.some.route;
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Now `foo.getUrl` will have lost its signature and your IDE can no longer suggest its parameters (if any).
|
|
220
|
+
```
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { EmitContext, Namespace } from "@typespec/compiler";
|
|
2
|
-
|
|
2
|
+
import { EmitterOptions } from "./lib.js";
|
|
3
|
+
declare const emitRoutes: (context: EmitContext, namespace: Namespace, rootServer: string, options: EmitterOptions, knownTypeguards: Array<{
|
|
4
|
+
filename: string;
|
|
5
|
+
name: string;
|
|
6
|
+
}>) => string;
|
|
3
7
|
export default emitRoutes;
|
package/dist/src/emit_routes.js
CHANGED
|
@@ -1,30 +1,13 @@
|
|
|
1
|
-
import { getDoc } from "@typespec/compiler";
|
|
1
|
+
import { getDoc, } from "@typespec/compiler";
|
|
2
2
|
import { getAuthentication, getHttpOperation } from "@typespec/http";
|
|
3
|
+
import { getTypeguard } from "./emit_types_typeguards.js";
|
|
3
4
|
import autogenerateWarning from "./helper_autogenerateWarning.js";
|
|
4
|
-
const emitRoutes = (context, namespace, rootServer) => {
|
|
5
|
+
const emitRoutes = (context, namespace, rootServer, options, knownTypeguards) => {
|
|
5
6
|
const rootNode = `routes_${context.options["root-namespace"]}`;
|
|
7
|
+
const imports = [];
|
|
6
8
|
let out = autogenerateWarning;
|
|
7
|
-
out +=
|
|
8
|
-
"/** This type is mostly meant for use in function signatures and `extends`' in generic functions.\n";
|
|
9
|
-
out += " * eg: `const callApi(route: IRoute) => fetch(route.getUrl(...))`\n";
|
|
10
|
-
out +=
|
|
11
|
-
" * It should not be used to type variables (eg.: `let x: IRoute`), because the resulting type\n";
|
|
12
|
-
out += " * loses it's information about the getUrl parameters.\n";
|
|
13
|
-
out += " */\n";
|
|
14
|
-
out += "export interface IRoute {\n";
|
|
15
|
-
out += " method: string\n";
|
|
16
|
-
/* The "getUrl" type should really be more specific; something that at least shows that it's a Record.
|
|
17
|
-
* However, doing that, Typescript always complains about the actual fields (of an implemented function in the output)
|
|
18
|
-
* is missing from the type. I think, it's a TS issue...
|
|
19
|
-
*/
|
|
20
|
-
out += " getUrl: (p: any) => string\n";
|
|
21
|
-
out += " auth: boolean | 'varies'\n";
|
|
22
|
-
out += "};\n\n";
|
|
23
9
|
out += `const ${rootNode} = {\n`;
|
|
24
10
|
const traverseNamespace = (n, nestLevel) => {
|
|
25
|
-
const line = (str, addLevels) => {
|
|
26
|
-
out += `${" ".repeat(nestLevel + 1 + (addLevels ?? 0))}${str}\n`;
|
|
27
|
-
};
|
|
28
11
|
// operations
|
|
29
12
|
let opNum = 0;
|
|
30
13
|
n.operations.forEach((op) => {
|
|
@@ -33,23 +16,23 @@ const emitRoutes = (context, namespace, rootServer) => {
|
|
|
33
16
|
// jsdoc comment
|
|
34
17
|
const doc = getDoc(context.program, op);
|
|
35
18
|
if (doc)
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
out = out.addLine(`/** ${doc} */`, nestLevel + 1);
|
|
20
|
+
out = out.addLine(`${op.name}: {`, nestLevel + 1);
|
|
38
21
|
// http method
|
|
39
|
-
|
|
22
|
+
out = out.addLine(`method: '${httpOp[0].verb}',`, nestLevel + 2);
|
|
40
23
|
// url parameters
|
|
41
24
|
const pathParams = httpOp[0].parameters.parameters.filter((p) => p.type === "path");
|
|
42
25
|
if (pathParams.length > 0) {
|
|
43
|
-
|
|
26
|
+
out = out.addLine("getUrl: (p: {", nestLevel + 2);
|
|
44
27
|
pathParams
|
|
45
28
|
.map((p) => `${p.name}: string`)
|
|
46
|
-
.forEach((p
|
|
29
|
+
.forEach((p) => (out = out.addLine(p, nestLevel + 3)));
|
|
47
30
|
let fn = "}) => ";
|
|
48
31
|
fn += pathParams.reduce((sum, cur) => sum.replaceAll(`{${cur.name}}`, `${"$"}{p.${cur.name}}`), `\`${rootServer}${httpOp[0].path}\`,`);
|
|
49
|
-
|
|
32
|
+
out = out.addLine(fn, nestLevel + 2);
|
|
50
33
|
}
|
|
51
34
|
else {
|
|
52
|
-
|
|
35
|
+
out = out.addLine(`getUrl: () => '${rootServer}${httpOp[0].path}',`, nestLevel + 2);
|
|
53
36
|
}
|
|
54
37
|
// auth
|
|
55
38
|
let auth = false;
|
|
@@ -70,8 +53,59 @@ const emitRoutes = (context, namespace, rootServer) => {
|
|
|
70
53
|
? true
|
|
71
54
|
: false;
|
|
72
55
|
}
|
|
73
|
-
|
|
74
|
-
|
|
56
|
+
out = out.addLine(`auth: ${typeof auth === "string" ? `'${auth}'` : auth.toString()}${options["typeguards-in-routes"] ? "," : ""}`, nestLevel + 2);
|
|
57
|
+
// typeguards
|
|
58
|
+
const typeguardLines = (t) => {
|
|
59
|
+
const guard = getTypeguard(t, "arg", 0, knownTypeguards);
|
|
60
|
+
imports.push(...guard[1]);
|
|
61
|
+
return guard[0].split("\n");
|
|
62
|
+
};
|
|
63
|
+
if (options["typeguards-in-routes"]) {
|
|
64
|
+
if (!knownTypeguards) {
|
|
65
|
+
console.warn("Typeguard Names List was empty when it shouldn't have been.");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (op.parameters.properties.has("body")) {
|
|
69
|
+
const lines = typeguardLines(op.parameters.properties.get("body").type);
|
|
70
|
+
out = out.addLine(`isRequestType: ${lines.length === 0 ? "null" : `(arg: any): boolean => ${lines.shift()}`}${lines.length < 1 ? "," : ""}`, nestLevel + 2, lines.length === 1);
|
|
71
|
+
if (lines.length > 0) {
|
|
72
|
+
lines[lines.length - 1] += ",";
|
|
73
|
+
lines.forEach((line, i, arr) => {
|
|
74
|
+
out = out.addLine(line, lines.length > 1 ? nestLevel + (i < arr.length - 1 ? 3 : 2) : 0);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else
|
|
79
|
+
out = out.addLine("isRequestType: null,", nestLevel + 2);
|
|
80
|
+
if (op.returnType &&
|
|
81
|
+
op.returnType.kind &&
|
|
82
|
+
op.returnType.kind !== "Intrinsic") {
|
|
83
|
+
const lines = [];
|
|
84
|
+
const addModelLines = (m) => {
|
|
85
|
+
if (m.properties.has("body")) {
|
|
86
|
+
lines.push(...typeguardLines(m.properties.get("body").type));
|
|
87
|
+
// else (no "body" prop): stays empty -> 'null'
|
|
88
|
+
// why?: unnamed model return type is likely to be / should be
|
|
89
|
+
// headers'n'stuff, so if there is no "body" property, play it safe
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
if (op.returnType.kind === "Union") {
|
|
93
|
+
op.returnType.variants.forEach((v) => {
|
|
94
|
+
if (v.type.kind === "Model")
|
|
95
|
+
addModelLines(v.type);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (op.returnType.kind === "Model")
|
|
99
|
+
addModelLines(op.returnType);
|
|
100
|
+
out = out.addLine(`isResponseType: ${lines.length === 0 ? "null" : `(arg: any): boolean => ${lines.shift()}`}${lines.length < 1 ? "," : ""}`, nestLevel + 2, lines.length === 1);
|
|
101
|
+
lines.forEach((line, i, arr) => {
|
|
102
|
+
out = out.addLine(line, lines.length > 1 ? nestLevel + (i < arr.length - 1 ? 3 : 2) : 0);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else
|
|
106
|
+
out = out.addLine("isResponseType: null", nestLevel + 2);
|
|
107
|
+
}
|
|
108
|
+
out = out.addLine(`}${opNum < n.operations.size || n.namespaces.size > 0 ? "," : ""}`, nestLevel + 1);
|
|
75
109
|
});
|
|
76
110
|
// namespaces
|
|
77
111
|
let nsNum = 0;
|
|
@@ -79,15 +113,16 @@ const emitRoutes = (context, namespace, rootServer) => {
|
|
|
79
113
|
nsNum++;
|
|
80
114
|
const doc = getDoc(context.program, ns);
|
|
81
115
|
if (doc)
|
|
82
|
-
|
|
83
|
-
|
|
116
|
+
out = out.addLine(`/** ${doc} */`, nestLevel + 1);
|
|
117
|
+
out = out.addLine(`${ns.name}: {`, nestLevel + 1);
|
|
84
118
|
traverseNamespace(ns, nestLevel + 1);
|
|
85
|
-
|
|
119
|
+
out = out.addLine(`}${nsNum < n.namespaces.size ? "," : ""}`, nestLevel + 1);
|
|
86
120
|
});
|
|
87
121
|
};
|
|
88
122
|
traverseNamespace(namespace, 0);
|
|
89
123
|
out += "} as const;\n";
|
|
90
124
|
out += `export default ${rootNode};\n`;
|
|
125
|
+
out = `${imports.filter((x, i, arr) => arr.indexOf(x) === i).join("\n")}\n\n${out}`;
|
|
91
126
|
return out;
|
|
92
127
|
};
|
|
93
128
|
export default emitRoutes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit_routes.js","sourceRoot":"","sources":["../../src/emit_routes.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"emit_routes.js","sourceRoot":"","sources":["../../src/emit_routes.ts"],"names":[],"mappings":"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"}
|
package/dist/src/emit_types.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { EmitContext, Namespace } from "@typespec/compiler";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { EmitterOptions } from "./lib.js";
|
|
3
|
+
declare const emitTypes: (context: EmitContext, namespace: Namespace, options: EmitterOptions) => {
|
|
4
|
+
files: Record<string, string>;
|
|
5
|
+
typeguardedNames: Array<{
|
|
6
|
+
filename: string;
|
|
7
|
+
name: string;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
8
10
|
export default emitTypes;
|
package/dist/src/emit_types.js
CHANGED
|
@@ -1,170 +1,64 @@
|
|
|
1
|
-
import { getDoc
|
|
1
|
+
import { getDoc } from "@typespec/compiler";
|
|
2
|
+
import { resolveEnum, resolveModel, resolveUnion, } from "./emit_types_resolve.js";
|
|
3
|
+
import { getTypeguardModel } from "./emit_types_typeguards.js";
|
|
2
4
|
import autogenerateWarning from "./helper_autogenerateWarning.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
const emitTypes = (context, namespace) => {
|
|
7
|
-
const out = {};
|
|
5
|
+
const emitTypes = (context, namespace, options) => {
|
|
6
|
+
const out = { files: {}, typeguardedNames: [] };
|
|
8
7
|
const traverseNamespace = (n) => {
|
|
9
|
-
let file =
|
|
10
|
-
const resolvedNames = {
|
|
11
|
-
enums: [],
|
|
12
|
-
unions: [],
|
|
13
|
-
models: [],
|
|
14
|
-
};
|
|
15
|
-
const resolveType = (t, nestlevel) => {
|
|
16
|
-
let typeStr = "unknown";
|
|
17
|
-
switch (t.kind) {
|
|
18
|
-
case "Model":
|
|
19
|
-
if (t.name === "Array") {
|
|
20
|
-
typeStr = resolveArray(t, nestlevel);
|
|
21
|
-
}
|
|
22
|
-
else
|
|
23
|
-
typeStr = resolveModel(t, nestlevel + 1);
|
|
24
|
-
break;
|
|
25
|
-
case "Boolean":
|
|
26
|
-
typeStr = "boolean";
|
|
27
|
-
break;
|
|
28
|
-
case "Enum":
|
|
29
|
-
typeStr = resolveEnum(t, nestlevel);
|
|
30
|
-
break;
|
|
31
|
-
case "Intrinsic":
|
|
32
|
-
typeStr = t.name;
|
|
33
|
-
break;
|
|
34
|
-
case "Number":
|
|
35
|
-
typeStr = t.valueAsString;
|
|
36
|
-
break;
|
|
37
|
-
case "Scalar":
|
|
38
|
-
typeStr = resolveScalar(t);
|
|
39
|
-
break;
|
|
40
|
-
case "String":
|
|
41
|
-
typeStr = `'${t.value}'`;
|
|
42
|
-
break;
|
|
43
|
-
case "Tuple":
|
|
44
|
-
typeStr = resolveTuple(t, nestlevel);
|
|
45
|
-
break;
|
|
46
|
-
case "Union":
|
|
47
|
-
typeStr = resolveUnion(t, nestlevel);
|
|
48
|
-
break;
|
|
49
|
-
default:
|
|
50
|
-
console.warn("Could not resolve type:", t.kind);
|
|
51
|
-
}
|
|
52
|
-
return typeStr;
|
|
53
|
-
};
|
|
54
|
-
const resolveArray = (a, nestlevel) => {
|
|
55
|
-
if (a.name !== "Array")
|
|
56
|
-
throw new Error(`Trying to parse model ${a.name} as Array`);
|
|
57
|
-
let ret = `${resolveType(a.indexer.value, nestlevel)}[]`;
|
|
58
|
-
return ret;
|
|
59
|
-
};
|
|
60
|
-
const resolveEnum = (e, nestlevel) => {
|
|
61
|
-
if (e.name && resolvedNames.enums.includes(e.name))
|
|
62
|
-
return e.name;
|
|
63
|
-
let ret = "{\n";
|
|
64
|
-
let i = 1;
|
|
65
|
-
e.members.forEach((p) => {
|
|
66
|
-
const val = p.value === undefined
|
|
67
|
-
? ""
|
|
68
|
-
: " = " +
|
|
69
|
-
(typeof p.value === "string"
|
|
70
|
-
? `'${p.value}'`
|
|
71
|
-
: p.value.toString());
|
|
72
|
-
ret = ret.addLine(`${p.name}${val}${i < e.members.size ? "," : ""}`, nestlevel + 1);
|
|
73
|
-
i++;
|
|
74
|
-
});
|
|
75
|
-
ret = ret.addLine("}", nestlevel, true);
|
|
76
|
-
resolvedNames.enums.push(e.name);
|
|
77
|
-
return ret;
|
|
78
|
-
};
|
|
79
|
-
const resolveTuple = (t, nestlevel) => {
|
|
80
|
-
return `[${t.values.map((v) => resolveType(v, nestlevel)).join(", ")}]`;
|
|
81
|
-
};
|
|
82
|
-
const resolveUnion = (u, nestlevel) => {
|
|
83
|
-
if (u.name && resolvedNames.unions.includes(u.name))
|
|
84
|
-
return u.name;
|
|
85
|
-
return Array.from(u.variants)
|
|
86
|
-
.map((v) => resolveType(v[1].type, nestlevel))
|
|
87
|
-
.join(" | ");
|
|
88
|
-
};
|
|
89
|
-
const resolveScalar = (s) => {
|
|
90
|
-
let ret = "unknown";
|
|
91
|
-
if (!s.baseScalar) {
|
|
92
|
-
switch (s.name) {
|
|
93
|
-
case "boolean":
|
|
94
|
-
ret = "boolean";
|
|
95
|
-
break;
|
|
96
|
-
case "bytes":
|
|
97
|
-
ret = "Uint8Array";
|
|
98
|
-
break;
|
|
99
|
-
case "duration":
|
|
100
|
-
case "numeric":
|
|
101
|
-
ret = "number";
|
|
102
|
-
break;
|
|
103
|
-
case "plainTime":
|
|
104
|
-
case "string":
|
|
105
|
-
case "url":
|
|
106
|
-
ret = "string";
|
|
107
|
-
break;
|
|
108
|
-
case "offsetDateTime":
|
|
109
|
-
case "plainDate":
|
|
110
|
-
case "unixTimestamp32":
|
|
111
|
-
case "utcDateTime":
|
|
112
|
-
ret = "Date";
|
|
113
|
-
break;
|
|
114
|
-
default:
|
|
115
|
-
console.warn("Could not resolve scalar:", s.name);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return s.baseScalar ? resolveScalar(s.baseScalar) : ret;
|
|
119
|
-
};
|
|
120
|
-
const resolveModel = (m, nestlevel = 0) => {
|
|
121
|
-
if (m.name && resolvedNames.models.includes(m.name))
|
|
122
|
-
return m.name;
|
|
123
|
-
let ret = "{\n";
|
|
124
|
-
let i = 1;
|
|
125
|
-
m.properties.forEach((p) => {
|
|
126
|
-
const doc = getDoc(context.program, p);
|
|
127
|
-
if (doc)
|
|
128
|
-
ret = ret.addLine(`/** ${doc} */`, nestlevel + 1);
|
|
129
|
-
const typeStr = resolveType(p.type, nestlevel);
|
|
130
|
-
if (typeStr.includes("unknown"))
|
|
131
|
-
console.warn(`Could not resolve property ${p.name} on ${m.name}`);
|
|
132
|
-
ret = ret.addLine(`${p.name}${p.optional ? "?" : ""}: ${typeStr}${i < m.properties.size ? "," : ""}`, nestlevel + 1);
|
|
133
|
-
i++;
|
|
134
|
-
});
|
|
135
|
-
ret = ret.addLine("}", nestlevel, true);
|
|
136
|
-
resolvedNames.models.push(m.name);
|
|
137
|
-
return ret;
|
|
138
|
-
};
|
|
8
|
+
let file = "";
|
|
139
9
|
n.enums.forEach((e) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
10
|
+
if (options["enable-types"]) {
|
|
11
|
+
const resolved = resolveEnum(e, 0, true);
|
|
12
|
+
if (resolved) {
|
|
13
|
+
const doc = getDoc(context.program, e);
|
|
14
|
+
if (doc)
|
|
15
|
+
file = file.addLine(`/** ${doc} */`);
|
|
16
|
+
file = file.addLine(`export enum ${e.name} ${resolved};\n`);
|
|
17
|
+
}
|
|
146
18
|
}
|
|
147
19
|
});
|
|
148
20
|
n.unions.forEach((u) => {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
21
|
+
if (options["enable-types"]) {
|
|
22
|
+
const resolved = resolveUnion(context, u, 0, true);
|
|
23
|
+
if (resolved) {
|
|
24
|
+
const doc = getDoc(context.program, u);
|
|
25
|
+
if (doc)
|
|
26
|
+
file = file.addLine(`/** ${doc} */`);
|
|
27
|
+
file = file.addLine(`export type ${u.name} = ${resolved};\n`);
|
|
28
|
+
}
|
|
155
29
|
}
|
|
156
30
|
});
|
|
157
31
|
n.models.forEach((m) => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
32
|
+
if (options["enable-types"]) {
|
|
33
|
+
const resolved = resolveModel(context, m, 0, true);
|
|
34
|
+
if (resolved) {
|
|
35
|
+
const doc = getDoc(context.program, m);
|
|
36
|
+
if (doc)
|
|
37
|
+
file = file.addLine(`/** ${doc} */`);
|
|
38
|
+
file = file.addLine(`export interface ${m.name} ${resolved};`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (options["enable-typeguards"]) {
|
|
42
|
+
file = file.addLine(`export function is${m.name}(arg: any): arg is ${m.name} {`);
|
|
43
|
+
file = file.addLine("return (", 1);
|
|
44
|
+
getTypeguardModel(m, "arg")[0]
|
|
45
|
+
.split("\n")
|
|
46
|
+
.forEach((line) => {
|
|
47
|
+
file = file.addLine(line, 1);
|
|
48
|
+
});
|
|
49
|
+
file = file.addLine(");", 1);
|
|
50
|
+
file = file.addLine("};");
|
|
51
|
+
out.typeguardedNames.push({
|
|
52
|
+
filename: n.name.charAt(0).toUpperCase() + n.name.slice(1),
|
|
53
|
+
name: m.name,
|
|
54
|
+
});
|
|
164
55
|
}
|
|
56
|
+
file += "\n";
|
|
165
57
|
});
|
|
58
|
+
if (file)
|
|
59
|
+
file = autogenerateWarning + file;
|
|
166
60
|
// set output for this namespace
|
|
167
|
-
out[n.name.charAt(0).toUpperCase() + n.name.slice(1)] = file;
|
|
61
|
+
out.files[n.name.charAt(0).toUpperCase() + n.name.slice(1)] = file;
|
|
168
62
|
// recursively iterate child namespaces
|
|
169
63
|
n.namespaces.forEach((ns) => traverseNamespace(ns));
|
|
170
64
|
};
|