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 CHANGED
@@ -1 +1,4 @@
1
+ npm run lint
2
+ npm run format
1
3
  npm run build
4
+ git add .
@@ -0,0 +1 @@
1
+ **/*.md
package/CHANGELOG.md CHANGED
@@ -1,11 +1,34 @@
1
- # 0.2.0 (2024-11-12)
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
- - warning log level ([8b74b01](https://github.com/crowbait/typespec-typescript-emitter/commit/8b74b0197ed4b8fa3aad57d0f50cb884af879243))
24
+ * warning log level ([8b74b01](https://github.com/crowbait/typespec-typescript-emitter/commit/8b74b0197ed4b8fa3aad57d0f50cb884af879243))
25
+
6
26
 
7
27
  ### Features
8
28
 
9
- - routes emitter ([fdafc1c](https://github.com/crowbait/typespec-typescript-emitter/commit/fdafc1c081058e9d683946b010d10ff3bd962cdc))
10
- - support optional model properties ([729d9f1](https://github.com/crowbait/typespec-typescript-emitter/commit/729d9f125434ead7a33326014082cd172c79f2ff))
11
- - types emitter ([e31d459](https://github.com/crowbait/typespec-typescript-emitter/commit/e31d459edce08d010e590681e3a2e17d636de64e))
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 export two things:
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 Emitter](#types-emitter)
24
+ - [Types emitter](#types-emitter)
23
25
  - [Alias's](#aliass)
24
- - [Routes Emitter](#routes-emitter)
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-routes: true
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
- declare const emitRoutes: (context: EmitContext, namespace: Namespace, rootServer: string) => string;
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;
@@ -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
- line(`/** ${doc} */`);
37
- line(`${op.name}: {`);
19
+ out = out.addLine(`/** ${doc} */`, nestLevel + 1);
20
+ out = out.addLine(`${op.name}: {`, nestLevel + 1);
38
21
  // http method
39
- line(`method: '${httpOp[0].verb}',`, 1);
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
- line("getUrl: (p: {", 1);
26
+ out = out.addLine("getUrl: (p: {", nestLevel + 2);
44
27
  pathParams
45
28
  .map((p) => `${p.name}: string`)
46
- .forEach((p, i) => line(p, 2));
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
- line(fn, 1);
32
+ out = out.addLine(fn, nestLevel + 2);
50
33
  }
51
34
  else {
52
- line(`getUrl: () => '${rootServer}${httpOp[0].path}',`, 1);
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
- line(`auth: ${typeof auth === "string" ? `'${auth}'` : auth.toString()}`, 1);
74
- line(`}${opNum < n.operations.size || n.namespaces.size > 0 ? "," : ""}`);
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
- line(`/** ${doc} */`);
83
- line(`${ns.name}: {`);
116
+ out = out.addLine(`/** ${doc} */`, nestLevel + 1);
117
+ out = out.addLine(`${ns.name}: {`, nestLevel + 1);
84
118
  traverseNamespace(ns, nestLevel + 1);
85
- line(`}${nsNum < n.namespaces.size ? "," : ""}`);
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":"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"}
1
+ {"version":3,"file":"emit_routes.js","sourceRoot":"","sources":["../../src/emit_routes.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
1
  import { EmitContext, Namespace } from "@typespec/compiler";
2
- declare global {
3
- interface String {
4
- addLine(str: string, tabs?: number, continued?: boolean): string;
5
- }
6
- }
7
- declare const emitTypes: (context: EmitContext, namespace: Namespace) => Record<string, string>;
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;
@@ -1,170 +1,64 @@
1
- import { getDoc, } from "@typespec/compiler";
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
- String.prototype.addLine = function (str, tabs, continued) {
4
- return `${this}${" ".repeat(tabs ?? 0)}${str}${continued ? "" : "\n"}`;
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 = autogenerateWarning;
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
- const resolved = resolveEnum(e, 0);
141
- if (resolved) {
142
- const doc = getDoc(context.program, e);
143
- if (doc)
144
- file = file.addLine(`/** ${doc} */`);
145
- file = file.addLine(`export enum ${e.name} ${resolved};\n`);
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
- const resolved = resolveUnion(u, 0);
150
- if (resolved) {
151
- const doc = getDoc(context.program, u);
152
- if (doc)
153
- file = file.addLine(`/** ${doc} */`);
154
- file = file.addLine(`export type ${u.name} = ${resolved};\n`);
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
- const resolved = resolveModel(m);
159
- if (resolved) {
160
- const doc = getDoc(context.program, m);
161
- if (doc)
162
- file = file.addLine(`/** ${doc} */`);
163
- file = file.addLine(`export interface ${m.name} ${resolved};\n`);
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
  };