dtsgenerator 3.13.2 → 3.15.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/.prettierignore +1 -0
- package/README.md +15 -0
- package/SupportedFeatures.md +2 -0
- package/dist/cli.js +4 -4
- package/dist/commandOptions.d.ts +0 -1
- package/dist/commandOptions.js +1 -4
- package/dist/core/astBuilder.d.ts +1 -0
- package/dist/core/astBuilder.js +11 -3
- package/dist/core/dtsGenerator.d.ts +4 -2
- package/dist/core/dtsGenerator.js +78 -72
- package/dist/core/index.js +3 -3
- package/dist/core/jsonSchema.js +3 -3
- package/dist/core/referenceResolver.js +2 -2
- package/dist/core/schemaId.js +1 -1
- package/dist/core/type.js +3 -3
- package/dist/core/typeTree.d.ts +6 -0
- package/dist/core/typeTree.js +34 -0
- package/dist/core/utils.d.ts +1 -1
- package/dist/core/utils.js +8 -9
- package/dist/utils.js +11 -4
- package/package.json +18 -18
- package/src/commandOptions.ts +1 -7
- package/src/core/astBuilder.ts +12 -1
- package/src/core/dtsGenerator.ts +123 -101
- package/src/core/jsonSchema.ts +1 -1
- package/src/core/typeTree.ts +39 -0
- package/src/core/utils.ts +7 -9
- package/src/utils.ts +7 -1
package/.prettierignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/test/snapshots
|
package/README.md
CHANGED
|
@@ -143,6 +143,21 @@ Output debug message by [debug](https://www.npmjs.com/package/debug) library.
|
|
|
143
143
|
|
|
144
144
|
## ChangeLog
|
|
145
145
|
|
|
146
|
+
### [v3.15.1](https://github.com/horiuchi/dtsgenerator/releases/tag/v3.15.1) (2022-03-10)
|
|
147
|
+
|
|
148
|
+
- fixed:
|
|
149
|
+
- Fix handling of stdin option with config file for #534. Thank you @arnestaphorsius :+1:
|
|
150
|
+
|
|
151
|
+
### [v3.15.0](https://github.com/horiuchi/dtsgenerator/releases/tag/v3.15.0) (2022-02-06)
|
|
152
|
+
|
|
153
|
+
- features:
|
|
154
|
+
- Support mobile wallet media types(`application/jwt` and `application/vnd.apple.pkpass`) for #530. Thank you @eostrom :+1:
|
|
155
|
+
|
|
156
|
+
### [v3.14.0](https://github.com/horiuchi/dtsgenerator/releases/tag/v3.14.0) (2022-01-27)
|
|
157
|
+
|
|
158
|
+
- features:
|
|
159
|
+
- Support the nested `allOf` and `oneOf` schema for #513. Thank you for your report @Cry0nicS :+1:
|
|
160
|
+
|
|
146
161
|
### [v3.13.2](https://github.com/horiuchi/dtsgenerator/releases/tag/v3.13.2) (2021-10-08)
|
|
147
162
|
|
|
148
163
|
- features:
|
package/SupportedFeatures.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const fs =
|
|
4
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
-
const commandOptions_1 =
|
|
7
|
-
const core_1 =
|
|
8
|
-
const config_1 =
|
|
6
|
+
const commandOptions_1 = tslib_1.__importStar(require("./commandOptions"));
|
|
7
|
+
const core_1 = tslib_1.__importStar(require("./core"));
|
|
8
|
+
const config_1 = tslib_1.__importStar(require("./core/config"));
|
|
9
9
|
const utils_1 = require("./utils");
|
|
10
10
|
async function loadContents() {
|
|
11
11
|
let contents = [];
|
package/dist/commandOptions.d.ts
CHANGED
package/dist/commandOptions.js
CHANGED
|
@@ -2,16 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.clear = exports.initialize = exports.CommandOptions = exports.defaultConfigFile = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const commander =
|
|
5
|
+
const commander = tslib_1.__importStar(require("commander"));
|
|
6
6
|
exports.defaultConfigFile = 'dtsgen.json';
|
|
7
7
|
class CommandOptions {
|
|
8
8
|
constructor() {
|
|
9
9
|
this.files = [];
|
|
10
10
|
this.urls = [];
|
|
11
11
|
}
|
|
12
|
-
isReadFromStdin() {
|
|
13
|
-
return (this.stdin || (this.files.length === 0 && this.urls.length === 0));
|
|
14
|
-
}
|
|
15
12
|
}
|
|
16
13
|
exports.CommandOptions = CommandOptions;
|
|
17
14
|
const opts = new CommandOptions();
|
|
@@ -21,6 +21,7 @@ export declare function buildIndexSignatureNode(name: string, indexType: ts.Type
|
|
|
21
21
|
export declare function buildTypeLiteralNode(elements: ts.TypeElement[]): ts.TypeNode;
|
|
22
22
|
export declare function buildFreeFormObjectTypeLiteralNode(): ts.TypeNode;
|
|
23
23
|
export declare function buildUnionTypeNode<T>(types: T[], builder: (t: T, index: number) => ts.TypeNode, terminate: boolean): ts.TypeNode;
|
|
24
|
+
export declare function buildIntersectionTypeNode(types: readonly ts.TypeNode[], terminate: boolean): ts.TypeNode;
|
|
24
25
|
export declare function buildTupleTypeNode(types: ts.TypeNode | ts.TypeNode[], minItems?: number, maxItems?: number, additionalItems?: ts.TypeNode | false): ts.TypeNode;
|
|
25
26
|
export declare function buildTypeReferenceNode(schema: NormalizedSchema, currentSchema: Schema): ts.TypeReferenceNode;
|
|
26
27
|
export declare function addComment<T extends ts.Node>(node: T, schema: NormalizedSchema, terminate: boolean): T;
|
package/dist/core/astBuilder.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.addOptionalInformation = exports.addComment = exports.buildTypeReferenceNode = exports.buildTupleTypeNode = exports.buildUnionTypeNode = exports.buildFreeFormObjectTypeLiteralNode = exports.buildTypeLiteralNode = exports.buildIndexSignatureNode = exports.buildPropertySignature = exports.buildTypeAliasNode = exports.buildInterfaceNode = exports.buildNamespaceNode = exports.buildBooleanLiteralTypeNode = exports.buildNumericLiteralTypeNode = exports.buildStringLiteralTypeNode = exports.buildNullKeyword = exports.buildSimpleArrayNode = exports.buildStringKeyword = exports.buildVoidKeyword = exports.buildUnknownKeyword = exports.buildNeverKeyword = exports.buildAnyKeyword = exports.buildKeyword = void 0;
|
|
3
|
+
exports.addOptionalInformation = exports.addComment = exports.buildTypeReferenceNode = exports.buildTupleTypeNode = exports.buildIntersectionTypeNode = exports.buildUnionTypeNode = exports.buildFreeFormObjectTypeLiteralNode = exports.buildTypeLiteralNode = exports.buildIndexSignatureNode = exports.buildPropertySignature = exports.buildTypeAliasNode = exports.buildInterfaceNode = exports.buildNamespaceNode = exports.buildBooleanLiteralTypeNode = exports.buildNumericLiteralTypeNode = exports.buildStringLiteralTypeNode = exports.buildNullKeyword = exports.buildSimpleArrayNode = exports.buildStringKeyword = exports.buildVoidKeyword = exports.buildUnknownKeyword = exports.buildNeverKeyword = exports.buildAnyKeyword = exports.buildKeyword = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const ts =
|
|
6
|
-
const config_1 =
|
|
5
|
+
const ts = tslib_1.__importStar(require("typescript"));
|
|
6
|
+
const config_1 = tslib_1.__importDefault(require("./config"));
|
|
7
7
|
const validateIdentifier_1 = require("./validateIdentifier");
|
|
8
8
|
function buildTypeNameIdentifier(name) {
|
|
9
9
|
return ts.factory.createIdentifier((0, validateIdentifier_1.toValidIdentifier)(name, config_1.default.target));
|
|
@@ -122,6 +122,14 @@ function buildUnionTypeNode(types, builder, terminate) {
|
|
|
122
122
|
return ts.factory.createParenthesizedType(node);
|
|
123
123
|
}
|
|
124
124
|
exports.buildUnionTypeNode = buildUnionTypeNode;
|
|
125
|
+
function buildIntersectionTypeNode(types, terminate) {
|
|
126
|
+
const node = ts.factory.createIntersectionTypeNode(types);
|
|
127
|
+
if (terminate) {
|
|
128
|
+
return node;
|
|
129
|
+
}
|
|
130
|
+
return ts.factory.createParenthesizedType(node);
|
|
131
|
+
}
|
|
132
|
+
exports.buildIntersectionTypeNode = buildIntersectionTypeNode;
|
|
125
133
|
function buildTupleTypeNode(types, minItems, maxItems, additionalItems) {
|
|
126
134
|
function typesIsArray(types) {
|
|
127
135
|
return Array.isArray(types);
|
|
@@ -5,12 +5,12 @@ export default class DtsGenerator {
|
|
|
5
5
|
private contents;
|
|
6
6
|
constructor(contents: Schema[]);
|
|
7
7
|
generate(): Promise<string>;
|
|
8
|
-
private buildSchemaMergedMap;
|
|
9
8
|
private getPlugins;
|
|
10
9
|
private getPreProcess;
|
|
11
10
|
private getPostProcess;
|
|
12
11
|
private walk;
|
|
13
12
|
private walkSchema;
|
|
13
|
+
private parseSchema;
|
|
14
14
|
private normalizeContent;
|
|
15
15
|
private normalizeSchemaContent;
|
|
16
16
|
private generateDeclareType;
|
|
@@ -18,8 +18,10 @@ export default class DtsGenerator {
|
|
|
18
18
|
private generateTypeCollection;
|
|
19
19
|
private generateProperties;
|
|
20
20
|
private generateTypeProperty;
|
|
21
|
+
private generateLiteralTypeProperty;
|
|
22
|
+
private checkExistOtherType;
|
|
21
23
|
private generateLiteralTypeNode;
|
|
22
|
-
private
|
|
24
|
+
private generateUnionType;
|
|
23
25
|
private generateArrayTypeProperty;
|
|
24
26
|
private generateType;
|
|
25
27
|
private generateTypeName;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const debug_1 =
|
|
5
|
-
const ts =
|
|
4
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
5
|
+
const ts = tslib_1.__importStar(require("typescript"));
|
|
6
6
|
const jsonPointer_1 = require("../jsonPointer");
|
|
7
|
-
const ast =
|
|
8
|
-
const config_1 =
|
|
7
|
+
const ast = tslib_1.__importStar(require("./astBuilder"));
|
|
8
|
+
const config_1 = tslib_1.__importDefault(require("./config"));
|
|
9
9
|
const jsonSchema_1 = require("./jsonSchema");
|
|
10
|
-
const referenceResolver_1 =
|
|
10
|
+
const referenceResolver_1 = tslib_1.__importDefault(require("./referenceResolver"));
|
|
11
11
|
const type_1 = require("./type");
|
|
12
|
-
const
|
|
12
|
+
const typeTree_1 = require("./typeTree");
|
|
13
|
+
const utils = tslib_1.__importStar(require("./utils"));
|
|
13
14
|
const debug = (0, debug_1.default)('dtsgen');
|
|
14
|
-
const typeMarker = Symbol();
|
|
15
15
|
class DtsGenerator {
|
|
16
16
|
constructor(contents) {
|
|
17
17
|
this.resolver = new referenceResolver_1.default();
|
|
@@ -26,8 +26,8 @@ class DtsGenerator {
|
|
|
26
26
|
debug('generate type definition files.');
|
|
27
27
|
this.contents.forEach((schema) => this.resolver.registerSchema(schema));
|
|
28
28
|
await this.resolver.resolve();
|
|
29
|
-
const
|
|
30
|
-
const root = this.walk(
|
|
29
|
+
const tree = (0, typeTree_1.buildTypeTree)(this.resolver.getAllRegisteredSchema());
|
|
30
|
+
const root = this.walk(tree);
|
|
31
31
|
const file = ts.createSourceFile('_.d.ts', '', config_1.default.target, false, ts.ScriptKind.TS);
|
|
32
32
|
Object.assign(file, {
|
|
33
33
|
statements: ts.factory.createNodeArray(root),
|
|
@@ -44,28 +44,6 @@ class DtsGenerator {
|
|
|
44
44
|
result.dispose();
|
|
45
45
|
return transformedContent;
|
|
46
46
|
}
|
|
47
|
-
buildSchemaMergedMap(schemas) {
|
|
48
|
-
const map = {};
|
|
49
|
-
const paths = [];
|
|
50
|
-
for (const type of schemas) {
|
|
51
|
-
const path = type.id.toNames();
|
|
52
|
-
paths.push({ path, type });
|
|
53
|
-
}
|
|
54
|
-
for (const item of paths) {
|
|
55
|
-
const path = item.path;
|
|
56
|
-
const parent = (0, jsonPointer_1.get)(map, path, true);
|
|
57
|
-
if (parent == null) {
|
|
58
|
-
(0, jsonPointer_1.set)(map, path, { [typeMarker]: item.type });
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
Object.assign(parent, { [typeMarker]: item.type });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (Object.keys(map).length === 0) {
|
|
65
|
-
throw new Error('There is no schema in the input contents.');
|
|
66
|
-
}
|
|
67
|
-
return map;
|
|
68
|
-
}
|
|
69
47
|
async getPlugins() {
|
|
70
48
|
const pre = [];
|
|
71
49
|
const post = [];
|
|
@@ -117,18 +95,20 @@ class DtsGenerator {
|
|
|
117
95
|
}
|
|
118
96
|
return result;
|
|
119
97
|
}
|
|
120
|
-
walk(
|
|
98
|
+
walk(tree, root = true) {
|
|
121
99
|
const result = [];
|
|
122
|
-
const keys =
|
|
100
|
+
const keys = [...tree.children.keys()].sort();
|
|
123
101
|
for (const key of keys) {
|
|
124
|
-
const value =
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
102
|
+
const value = tree.children.get(key);
|
|
103
|
+
if (value === undefined) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (value.schema !== undefined) {
|
|
107
|
+
const schema = value.schema;
|
|
128
108
|
debug(` walk doProcess: key=${key} schemaId=${schema.id.getAbsoluteId()}`);
|
|
129
109
|
result.push(this.walkSchema(schema, root));
|
|
130
110
|
}
|
|
131
|
-
if (
|
|
111
|
+
if (value.children.size > 0) {
|
|
132
112
|
result.push(ast.buildNamespaceNode(key, this.walk(value, false), root));
|
|
133
113
|
}
|
|
134
114
|
}
|
|
@@ -137,19 +117,19 @@ class DtsGenerator {
|
|
|
137
117
|
walkSchema(schema, root) {
|
|
138
118
|
const normalized = this.normalizeContent(schema);
|
|
139
119
|
this.currentSchema = normalized;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
120
|
+
return ast.addOptionalInformation(ast.addComment(this.parseSchema(normalized, root), normalized, true), normalized, true);
|
|
121
|
+
}
|
|
122
|
+
parseSchema(schema, root = false) {
|
|
123
|
+
const type = schema.content.type;
|
|
124
|
+
switch (type) {
|
|
125
|
+
case 'any':
|
|
126
|
+
return this.generateAnyTypeModel(schema, root);
|
|
127
|
+
case 'array':
|
|
128
|
+
return this.generateTypeCollection(schema, root);
|
|
129
|
+
case 'object':
|
|
130
|
+
default:
|
|
131
|
+
return this.generateDeclareType(schema, root);
|
|
132
|
+
}
|
|
153
133
|
}
|
|
154
134
|
normalizeContent(schema, pointer) {
|
|
155
135
|
if (pointer != null) {
|
|
@@ -253,13 +233,9 @@ class DtsGenerator {
|
|
|
253
233
|
}
|
|
254
234
|
}
|
|
255
235
|
if (content.patternProperties) {
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
schemasTypes.push(this.generateTypeProperty(schema));
|
|
260
|
-
}
|
|
261
|
-
const node = ast.buildPropertySignature({ content: { readOnly: false } }, 'pattern', ts.createUnionTypeNode(schemasTypes), baseSchema.content.required, true);
|
|
262
|
-
result.push(ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, ` Patterns: ${Object.keys(content.patternProperties).join(' | ')} `));
|
|
236
|
+
const properties = Object.keys(content.patternProperties);
|
|
237
|
+
const node = ast.buildPropertySignature({ content: { readOnly: false } }, 'pattern', ast.buildUnionTypeNode(properties, (propertyName) => this.generateTypeProperty(this.normalizeContent(baseSchema, '/patternProperties/' + (0, jsonPointer_1.tilde)(propertyName))), true), baseSchema.content.required, true);
|
|
238
|
+
result.push(ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, ` Patterns: ${properties.join(' | ')} `));
|
|
263
239
|
}
|
|
264
240
|
return result;
|
|
265
241
|
}
|
|
@@ -271,19 +247,23 @@ class DtsGenerator {
|
|
|
271
247
|
throw new Error('target referenced id is nothing: ' + content.$ref);
|
|
272
248
|
}
|
|
273
249
|
const refSchema = this.normalizeContent(ref);
|
|
274
|
-
const node = ast.buildTypeReferenceNode(refSchema, this.currentSchema);
|
|
275
|
-
return
|
|
250
|
+
const node = ast.addOptionalInformation(ast.addComment(ast.buildTypeReferenceNode(refSchema, this.currentSchema), refSchema, false), refSchema, false);
|
|
251
|
+
return node;
|
|
276
252
|
}
|
|
277
253
|
if (content.anyOf) {
|
|
278
254
|
const mergeContent = Object.assign({}, content);
|
|
279
255
|
delete mergeContent.anyOf;
|
|
280
|
-
return this.
|
|
256
|
+
return this.generateUnionType(schema, content.anyOf, mergeContent, '/anyOf/', terminate);
|
|
281
257
|
}
|
|
282
258
|
if (content.oneOf) {
|
|
283
259
|
const mergeContent = Object.assign({}, content);
|
|
284
260
|
delete mergeContent.oneOf;
|
|
285
|
-
return this.
|
|
261
|
+
return this.generateUnionType(schema, content.oneOf, mergeContent, '/oneOf/', terminate);
|
|
286
262
|
}
|
|
263
|
+
return this.generateLiteralTypeProperty(schema, terminate);
|
|
264
|
+
}
|
|
265
|
+
generateLiteralTypeProperty(schema, terminate = true) {
|
|
266
|
+
const content = schema.content;
|
|
287
267
|
if (content.enum) {
|
|
288
268
|
return ast.buildUnionTypeNode(content.enum, (value) => {
|
|
289
269
|
return this.generateLiteralTypeNode(content, value);
|
|
@@ -299,17 +279,32 @@ class DtsGenerator {
|
|
|
299
279
|
return this.generateType(schema, terminate);
|
|
300
280
|
}
|
|
301
281
|
}
|
|
282
|
+
checkExistOtherType(content, base) {
|
|
283
|
+
const schema = Object.assign({}, base, { content });
|
|
284
|
+
const result = this.generateLiteralTypeProperty(schema, false);
|
|
285
|
+
if (result.kind === ts.SyntaxKind.AnyKeyword) {
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
else if (result.kind === ts.SyntaxKind.TypeLiteral) {
|
|
289
|
+
const node = result;
|
|
290
|
+
if (node.members.length === 1 &&
|
|
291
|
+
node.members[0].kind === ts.SyntaxKind.IndexSignature) {
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
302
297
|
generateLiteralTypeNode(content, value) {
|
|
303
298
|
switch (content.type) {
|
|
304
299
|
case 'integer':
|
|
305
300
|
case 'number':
|
|
306
301
|
return ast.buildNumericLiteralTypeNode(String(value));
|
|
307
302
|
case 'boolean':
|
|
308
|
-
return ast.buildBooleanLiteralTypeNode(value);
|
|
303
|
+
return ast.buildBooleanLiteralTypeNode(Boolean(value));
|
|
309
304
|
case 'null':
|
|
310
305
|
return ast.buildNullKeyword();
|
|
311
306
|
case 'string':
|
|
312
|
-
return ast.buildStringLiteralTypeNode(value);
|
|
307
|
+
return ast.buildStringLiteralTypeNode(String(value));
|
|
313
308
|
}
|
|
314
309
|
if (value === null) {
|
|
315
310
|
return ast.buildNullKeyword();
|
|
@@ -324,17 +319,28 @@ class DtsGenerator {
|
|
|
324
319
|
}
|
|
325
320
|
return ast.buildStringLiteralTypeNode(String(value));
|
|
326
321
|
}
|
|
327
|
-
|
|
328
|
-
|
|
322
|
+
generateUnionType(baseSchema, contents, mergeContent, path, terminate) {
|
|
323
|
+
const merged = [];
|
|
324
|
+
const children = contents.map((_, index) => {
|
|
329
325
|
const schema = this.normalizeContent(baseSchema, path + index.toString());
|
|
330
|
-
utils.mergeSchema(schema.content, mergeContent);
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
326
|
+
merged.push(utils.mergeSchema(schema.content, mergeContent));
|
|
327
|
+
return schema;
|
|
328
|
+
});
|
|
329
|
+
const allRef = merged.every((b) => !b);
|
|
330
|
+
const baseType = this.checkExistOtherType(mergeContent, baseSchema);
|
|
331
|
+
const result = ast.addOptionalInformation(ast.addComment(ast.buildUnionTypeNode(children, (schema, index) => {
|
|
332
|
+
const node = schema.id.isEmpty()
|
|
333
|
+
? ast.addOptionalInformation(this.generateTypeProperty(schema, false), schema, false)
|
|
334
|
+
: ast.addOptionalInformation(ast.buildTypeReferenceNode(schema, this.currentSchema), schema, false);
|
|
335
|
+
if (baseType != null && !allRef && !merged[index]) {
|
|
336
|
+
return ast.buildIntersectionTypeNode([baseType, node], false);
|
|
336
337
|
}
|
|
338
|
+
return node;
|
|
337
339
|
}, terminate), baseSchema, false), baseSchema, terminate);
|
|
340
|
+
if (baseType != null && allRef) {
|
|
341
|
+
return ast.buildIntersectionTypeNode([baseType, result], terminate);
|
|
342
|
+
}
|
|
343
|
+
return result;
|
|
338
344
|
}
|
|
339
345
|
generateArrayTypeProperty(schema, terminate = true) {
|
|
340
346
|
const items = schema.content.items;
|
package/dist/core/index.js
CHANGED
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SchemaId = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const config_1 = require("./config");
|
|
6
|
-
const dtsGenerator_1 =
|
|
6
|
+
const dtsGenerator_1 = tslib_1.__importDefault(require("./dtsGenerator"));
|
|
7
7
|
var schemaId_1 = require("./schemaId");
|
|
8
|
-
Object.defineProperty(exports, "SchemaId", { enumerable: true, get: function () { return
|
|
9
|
-
|
|
8
|
+
Object.defineProperty(exports, "SchemaId", { enumerable: true, get: function () { return tslib_1.__importDefault(schemaId_1).default; } });
|
|
9
|
+
tslib_1.__exportStar(require("./type"), exports);
|
|
10
10
|
async function dtsGenerator(options) {
|
|
11
11
|
if (options.config) {
|
|
12
12
|
(0, config_1.setConfig)(options.config);
|
package/dist/core/jsonSchema.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.selectSchemaType = exports.searchAllSubSchema = exports.setId = exports.getId = exports.getSubSchema = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const JsonPointer =
|
|
6
|
-
const schemaId_1 =
|
|
5
|
+
const JsonPointer = tslib_1.__importStar(require("../jsonPointer"));
|
|
6
|
+
const schemaId_1 = tslib_1.__importDefault(require("./schemaId"));
|
|
7
7
|
const type_1 = require("./type");
|
|
8
8
|
function getSubSchema(rootSchema, pointer, id) {
|
|
9
9
|
const content = JsonPointer.get(rootSchema.content, JsonPointer.parse(pointer));
|
|
@@ -256,7 +256,7 @@ function searchAllSubSchema(schema, onFoundSchema, onFoundReference) {
|
|
|
256
256
|
return;
|
|
257
257
|
}
|
|
258
258
|
for (const mime of Object.keys(types)) {
|
|
259
|
-
if (/^text\/|^(?:application\/x-www-form-urlencoded$|^application\/([a-z0-9-_.]+\+)?json)$|^application\/octet-stream$|^multipart\/form-data$/.test(mime)) {
|
|
259
|
+
if (/^text\/|^(?:application\/x-www-form-urlencoded$|^application\/([a-z0-9-_.]+\+)?json)$|^application\/octet-stream$|^application\/jwt$|^application\/vnd.apple.pkpass$|^multipart\/form-data$/.test(mime)) {
|
|
260
260
|
const mt = types[mime];
|
|
261
261
|
setSubId(mt.schema, keys);
|
|
262
262
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
require("cross-fetch/polyfill");
|
|
5
|
-
const debug_1 =
|
|
5
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
6
6
|
const jsonSchema_1 = require("./jsonSchema");
|
|
7
|
-
const schemaId_1 =
|
|
7
|
+
const schemaId_1 = tslib_1.__importDefault(require("./schemaId"));
|
|
8
8
|
const type_1 = require("./type");
|
|
9
9
|
const debug = (0, debug_1.default)('dtsgen');
|
|
10
10
|
class ReferenceResolver {
|
package/dist/core/schemaId.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const url =
|
|
4
|
+
const url = tslib_1.__importStar(require("url"));
|
|
5
5
|
const validateIdentifier_1 = require("./validateIdentifier");
|
|
6
6
|
class SchemaId {
|
|
7
7
|
constructor(inputId, parentIds) {
|
package/dist/core/type.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.loadPlugin = exports.parseFileContent = exports.readSchemaFromUrl = exports.readSchemasFromFile = exports.readSchemaFromStdin = exports.parseSchema = exports.isJsonSchemaDraft04 = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const fs =
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const js_yaml_1 = require("js-yaml");
|
|
8
8
|
const utils_1 = require("../utils");
|
|
9
9
|
const jsonSchema_1 = require("./jsonSchema");
|
|
10
|
-
const schemaId_1 =
|
|
10
|
+
const schemaId_1 = tslib_1.__importDefault(require("./schemaId"));
|
|
11
11
|
exports.ts = require("typescript");
|
|
12
12
|
function isJsonSchemaDraft04(_content, type) {
|
|
13
13
|
return type === 'Draft04';
|
|
@@ -81,7 +81,7 @@ async function loadPlugin(name, option) {
|
|
|
81
81
|
if (!option) {
|
|
82
82
|
return undefined;
|
|
83
83
|
}
|
|
84
|
-
const mod = (await Promise.resolve().then(() =>
|
|
84
|
+
const mod = (await Promise.resolve().then(() => tslib_1.__importStar(require(name))));
|
|
85
85
|
if (!(mod === null || mod === void 0 ? void 0 : mod.default)) {
|
|
86
86
|
console.warn(`The plugin (${name}) is invalid module. That is not default export format.`);
|
|
87
87
|
return undefined;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildTypeTree = void 0;
|
|
4
|
+
function buildTypeTree(schemas) {
|
|
5
|
+
const tree = buildTree();
|
|
6
|
+
for (const type of schemas) {
|
|
7
|
+
setTypeToTree(tree, type.id.toNames(), type);
|
|
8
|
+
}
|
|
9
|
+
if (tree.children.size === 0) {
|
|
10
|
+
throw new Error('There is no schema in the input contents.');
|
|
11
|
+
}
|
|
12
|
+
return tree;
|
|
13
|
+
}
|
|
14
|
+
exports.buildTypeTree = buildTypeTree;
|
|
15
|
+
function setTypeToTree(tree, paths, type) {
|
|
16
|
+
if (paths.length === 0) {
|
|
17
|
+
throw new Error('The paths is nothing for set the type to TypeTree.');
|
|
18
|
+
}
|
|
19
|
+
let t = tree;
|
|
20
|
+
for (const key of paths) {
|
|
21
|
+
let next = t.children.get(key);
|
|
22
|
+
if (next === undefined) {
|
|
23
|
+
next = buildTree();
|
|
24
|
+
t.children.set(key, next);
|
|
25
|
+
}
|
|
26
|
+
t = next;
|
|
27
|
+
}
|
|
28
|
+
t.schema = type;
|
|
29
|
+
}
|
|
30
|
+
function buildTree() {
|
|
31
|
+
return {
|
|
32
|
+
children: new Map(),
|
|
33
|
+
};
|
|
34
|
+
}
|
package/dist/core/utils.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ import { JsonSchemaObject } from './type';
|
|
|
4
4
|
import SimpleTypes = JsonSchemaDraft04.Schema.Definitions.SimpleTypes;
|
|
5
5
|
export declare function toTSType(type: string, debugSource?: JsonSchemaObject): ts.KeywordTypeSyntaxKind | ts.SyntaxKind.NullKeyword | undefined;
|
|
6
6
|
export declare function reduceTypes(types: SimpleTypes[]): SimpleTypes[];
|
|
7
|
-
export declare function mergeSchema(a: any, b: any):
|
|
7
|
+
export declare function mergeSchema(a: any, b: any): boolean;
|
package/dist/core/utils.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.mergeSchema = exports.reduceTypes = exports.toTSType = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const debug_1 =
|
|
6
|
-
const ts =
|
|
5
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
6
|
+
const ts = tslib_1.__importStar(require("typescript"));
|
|
7
7
|
const debug = (0, debug_1.default)('dtsgen');
|
|
8
8
|
function toTSType(type, debugSource) {
|
|
9
9
|
switch (type) {
|
|
@@ -39,18 +39,16 @@ function reduceTypes(types) {
|
|
|
39
39
|
return types;
|
|
40
40
|
}
|
|
41
41
|
const set = new Set(types);
|
|
42
|
-
if (set.delete('integer')) {
|
|
43
|
-
set.add('number');
|
|
44
|
-
}
|
|
45
42
|
return Array.from(set.values());
|
|
46
43
|
}
|
|
47
44
|
exports.reduceTypes = reduceTypes;
|
|
48
45
|
function mergeSchema(a, b) {
|
|
49
46
|
if ('$ref' in a || '$ref' in b) {
|
|
50
|
-
|
|
47
|
+
a.$ref = b.$ref || a.$ref;
|
|
48
|
+
return false;
|
|
51
49
|
}
|
|
52
50
|
Object.keys(b).forEach((key) => {
|
|
53
|
-
var _a;
|
|
51
|
+
var _a, _b;
|
|
54
52
|
const value = b[key];
|
|
55
53
|
if (a[key] != null && typeof value !== typeof a[key]) {
|
|
56
54
|
debug(`mergeSchema warning: type is mismatched, key=${key}`);
|
|
@@ -59,12 +57,13 @@ function mergeSchema(a, b) {
|
|
|
59
57
|
a[key] = ((_a = a[key]) !== null && _a !== void 0 ? _a : []).concat(value);
|
|
60
58
|
}
|
|
61
59
|
else if (value != null && typeof value === 'object') {
|
|
62
|
-
a[key]
|
|
60
|
+
(_b = a[key]) !== null && _b !== void 0 ? _b : (a[key] = {});
|
|
61
|
+
mergeSchema(a[key], value);
|
|
63
62
|
}
|
|
64
63
|
else {
|
|
65
64
|
a[key] = value;
|
|
66
65
|
}
|
|
67
66
|
});
|
|
68
|
-
return
|
|
67
|
+
return true;
|
|
69
68
|
}
|
|
70
69
|
exports.mergeSchema = mergeSchema;
|
package/dist/utils.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.readConfig = exports.globFiles = exports.buildProxyOptions = exports.readUrl = exports.readStream = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const fs =
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
6
|
const url_1 = require("url");
|
|
7
|
-
const glob_1 =
|
|
8
|
-
const https_proxy_agent_1 =
|
|
7
|
+
const glob_1 = tslib_1.__importDefault(require("glob"));
|
|
8
|
+
const https_proxy_agent_1 = tslib_1.__importDefault(require("https-proxy-agent"));
|
|
9
9
|
const typescript_1 = require("typescript");
|
|
10
10
|
const commandOptions_1 = require("./commandOptions");
|
|
11
11
|
function readStream(stream, encoding = 'utf8') {
|
|
@@ -107,7 +107,14 @@ function readConfig(options) {
|
|
|
107
107
|
else if (pc.input.urls == null) {
|
|
108
108
|
pc.input.urls = [];
|
|
109
109
|
}
|
|
110
|
-
|
|
110
|
+
if (options.stdin != null) {
|
|
111
|
+
pc.input.stdin = options.stdin;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
pc.input.stdin =
|
|
115
|
+
pc.input.stdin ||
|
|
116
|
+
(pc.input.files.length === 0 && pc.input.urls.length === 0);
|
|
117
|
+
}
|
|
111
118
|
if (options.out != null) {
|
|
112
119
|
pc.outputFile = options.out;
|
|
113
120
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dtsgenerator",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.1",
|
|
4
4
|
"description": "TypeScript d.ts file generator for JSON Schema file",
|
|
5
5
|
"bin": {
|
|
6
6
|
"dtsgen": "bin/dtsgen"
|
|
@@ -44,37 +44,37 @@
|
|
|
44
44
|
"node": ">= 10.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"commander": "^
|
|
48
|
-
"cross-fetch": "^3.1.
|
|
49
|
-
"debug": "^4.3.
|
|
47
|
+
"commander": "^9.0.0",
|
|
48
|
+
"cross-fetch": "^3.1.5",
|
|
49
|
+
"debug": "^4.3.3",
|
|
50
50
|
"glob": "^7.2.0",
|
|
51
51
|
"https-proxy-agent": "^5.0.0",
|
|
52
52
|
"js-yaml": "^4.1.0",
|
|
53
53
|
"tslib": "^2.3.1",
|
|
54
|
-
"typescript": "^4.
|
|
54
|
+
"typescript": "^4.6.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@dtsgenerator/do-nothing": "^2.5.1",
|
|
58
|
-
"@dtsgenerator/eslint-config": "^0.
|
|
58
|
+
"@dtsgenerator/eslint-config": "^0.5.0",
|
|
59
59
|
"@dtsgenerator/replace-namespace": "^1.5.1",
|
|
60
60
|
"@dtsgenerator/single-quote": "^1.6.1",
|
|
61
|
-
"@istanbuljs/nyc-config-typescript": "^1.0.
|
|
61
|
+
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
62
62
|
"@types/debug": "^4.1.7",
|
|
63
|
-
"@types/glob": "^7.
|
|
64
|
-
"@types/js-yaml": "^4.0.
|
|
63
|
+
"@types/glob": "^7.2.0",
|
|
64
|
+
"@types/js-yaml": "^4.0.5",
|
|
65
65
|
"@types/mkdirp": "^1.0.2",
|
|
66
|
-
"@types/mocha": "^9.
|
|
67
|
-
"@types/node": "^16.
|
|
66
|
+
"@types/mocha": "^9.1.0",
|
|
67
|
+
"@types/node": "^16.11.26",
|
|
68
68
|
"cross-env": "^7.0.3",
|
|
69
|
-
"eslint": "^
|
|
70
|
-
"husky": "^7.0.
|
|
71
|
-
"lint-staged": "^
|
|
72
|
-
"mocha": "^9.1
|
|
69
|
+
"eslint": "^8.10.0",
|
|
70
|
+
"husky": "^7.0.4",
|
|
71
|
+
"lint-staged": "^12.3.5",
|
|
72
|
+
"mocha": "^9.2.1",
|
|
73
73
|
"nyc": "^15.1.0",
|
|
74
|
-
"prettier": "^2.
|
|
74
|
+
"prettier": "^2.5.1",
|
|
75
75
|
"rimraf": "^3.0.2",
|
|
76
|
-
"source-map-support": "^0.5.
|
|
77
|
-
"ts-node": "^10.
|
|
76
|
+
"source-map-support": "^0.5.21",
|
|
77
|
+
"ts-node": "^10.7.0"
|
|
78
78
|
},
|
|
79
79
|
"lint-staged": {
|
|
80
80
|
"**/*.ts": [
|
package/src/commandOptions.ts
CHANGED
|
@@ -11,12 +11,6 @@ export class CommandOptions {
|
|
|
11
11
|
public target?: string;
|
|
12
12
|
public info?: boolean;
|
|
13
13
|
public outputAST?: boolean;
|
|
14
|
-
|
|
15
|
-
public isReadFromStdin(): boolean {
|
|
16
|
-
return (
|
|
17
|
-
this.stdin || (this.files.length === 0 && this.urls.length === 0)
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
const opts = new CommandOptions();
|
|
@@ -47,7 +41,7 @@ function parse(options: CommandOptions, argv: string[]): commander.Command {
|
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
// eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
|
|
50
|
-
const pkg: Record<string,
|
|
44
|
+
const pkg: Record<string, string> = require('../package.json');
|
|
51
45
|
|
|
52
46
|
// <hoge> is required, [hoge] is optional
|
|
53
47
|
program
|
package/src/core/astBuilder.ts
CHANGED
|
@@ -195,6 +195,17 @@ export function buildUnionTypeNode<T>(
|
|
|
195
195
|
return ts.factory.createParenthesizedType(node);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
export function buildIntersectionTypeNode(
|
|
199
|
+
types: readonly ts.TypeNode[],
|
|
200
|
+
terminate: boolean
|
|
201
|
+
): ts.TypeNode {
|
|
202
|
+
const node = ts.factory.createIntersectionTypeNode(types);
|
|
203
|
+
if (terminate) {
|
|
204
|
+
return node;
|
|
205
|
+
}
|
|
206
|
+
return ts.factory.createParenthesizedType(node);
|
|
207
|
+
}
|
|
208
|
+
|
|
198
209
|
export function buildTupleTypeNode(
|
|
199
210
|
types: ts.TypeNode | ts.TypeNode[],
|
|
200
211
|
minItems?: number,
|
|
@@ -322,7 +333,7 @@ function getComment(schema: NormalizedSchema): string[] {
|
|
|
322
333
|
function protectComment(str: string): string {
|
|
323
334
|
return str.replace(/\*\//g, '*\u200B/'); // Unicode [ZERO WIDTH SPACE]
|
|
324
335
|
}
|
|
325
|
-
function appendComment(value?:
|
|
336
|
+
function appendComment(value?: any): void {
|
|
326
337
|
if (value == null) {
|
|
327
338
|
return;
|
|
328
339
|
}
|
package/src/core/dtsGenerator.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Debug from 'debug';
|
|
2
2
|
import * as ts from 'typescript';
|
|
3
|
-
import {
|
|
3
|
+
import { tilde } from '../jsonPointer';
|
|
4
4
|
import * as ast from './astBuilder';
|
|
5
5
|
import config from './config';
|
|
6
6
|
import { getSubSchema, NormalizedSchema } from './jsonSchema';
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
PreProcessHandler,
|
|
14
14
|
loadPlugin,
|
|
15
15
|
} from './type';
|
|
16
|
+
import { buildTypeTree, TypeTree } from './typeTree';
|
|
16
17
|
import * as utils from './utils';
|
|
17
18
|
|
|
18
19
|
const debug = Debug('dtsgen');
|
|
19
|
-
const typeMarker = Symbol();
|
|
20
20
|
|
|
21
21
|
interface PluginConfig {
|
|
22
22
|
plugin: Plugin;
|
|
@@ -42,11 +42,8 @@ export default class DtsGenerator {
|
|
|
42
42
|
this.contents.forEach((schema) => this.resolver.registerSchema(schema));
|
|
43
43
|
await this.resolver.resolve();
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
this.resolver.getAllRegisteredSchema()
|
|
48
|
-
);
|
|
49
|
-
const root = this.walk(map, true);
|
|
45
|
+
const tree = buildTypeTree(this.resolver.getAllRegisteredSchema());
|
|
46
|
+
const root = this.walk(tree);
|
|
50
47
|
const file = ts.createSourceFile(
|
|
51
48
|
'_.d.ts',
|
|
52
49
|
'',
|
|
@@ -77,31 +74,6 @@ export default class DtsGenerator {
|
|
|
77
74
|
return transformedContent;
|
|
78
75
|
}
|
|
79
76
|
|
|
80
|
-
private buildSchemaMergedMap(schemas: IterableIterator<Schema>): any {
|
|
81
|
-
const map: any = {};
|
|
82
|
-
const paths: { path: string[]; type: Schema }[] = [];
|
|
83
|
-
for (const type of schemas) {
|
|
84
|
-
const path = type.id.toNames();
|
|
85
|
-
paths.push({ path, type });
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
for (const item of paths) {
|
|
89
|
-
const path = item.path;
|
|
90
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
91
|
-
const parent = get(map, path, true);
|
|
92
|
-
if (parent == null) {
|
|
93
|
-
set(map, path, { [typeMarker]: item.type });
|
|
94
|
-
} else {
|
|
95
|
-
Object.assign(parent, { [typeMarker]: item.type });
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (Object.keys(map).length === 0) {
|
|
99
|
-
throw new Error('There is no schema in the input contents.');
|
|
100
|
-
}
|
|
101
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
102
|
-
return map;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
77
|
private async getPlugins(): Promise<{
|
|
106
78
|
pre: PluginConfig[];
|
|
107
79
|
post: PluginConfig[];
|
|
@@ -169,24 +141,22 @@ export default class DtsGenerator {
|
|
|
169
141
|
return result;
|
|
170
142
|
}
|
|
171
143
|
|
|
172
|
-
private walk(
|
|
144
|
+
private walk(tree: TypeTree, root = true): ts.Statement[] {
|
|
173
145
|
const result: ts.Statement[] = [];
|
|
174
|
-
const keys =
|
|
146
|
+
const keys = [...tree.children.keys()].sort();
|
|
175
147
|
for (const key of keys) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
183
|
-
const schema = value[typeMarker] as Schema;
|
|
148
|
+
const value = tree.children.get(key);
|
|
149
|
+
if (value === undefined) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (value.schema !== undefined) {
|
|
153
|
+
const schema = value.schema;
|
|
184
154
|
debug(
|
|
185
155
|
` walk doProcess: key=${key} schemaId=${schema.id.getAbsoluteId()}`
|
|
186
156
|
);
|
|
187
157
|
result.push(this.walkSchema(schema, root));
|
|
188
158
|
}
|
|
189
|
-
if (
|
|
159
|
+
if (value.children.size > 0) {
|
|
190
160
|
result.push(
|
|
191
161
|
ast.buildNamespaceNode(key, this.walk(value, false), root)
|
|
192
162
|
);
|
|
@@ -199,25 +169,33 @@ export default class DtsGenerator {
|
|
|
199
169
|
const normalized = this.normalizeContent(schema);
|
|
200
170
|
this.currentSchema = normalized;
|
|
201
171
|
|
|
202
|
-
const getNode = () => {
|
|
203
|
-
const type = normalized.content.type;
|
|
204
|
-
switch (type) {
|
|
205
|
-
case 'any':
|
|
206
|
-
return this.generateAnyTypeModel(normalized, root);
|
|
207
|
-
case 'array':
|
|
208
|
-
return this.generateTypeCollection(normalized, root);
|
|
209
|
-
case 'object':
|
|
210
|
-
default:
|
|
211
|
-
return this.generateDeclareType(normalized, root);
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
172
|
return ast.addOptionalInformation(
|
|
215
|
-
ast.addComment(
|
|
173
|
+
ast.addComment(
|
|
174
|
+
this.parseSchema(normalized, root),
|
|
175
|
+
normalized,
|
|
176
|
+
true
|
|
177
|
+
),
|
|
216
178
|
normalized,
|
|
217
179
|
true
|
|
218
180
|
);
|
|
219
181
|
}
|
|
220
182
|
|
|
183
|
+
private parseSchema(
|
|
184
|
+
schema: NormalizedSchema,
|
|
185
|
+
root = false
|
|
186
|
+
): ts.DeclarationStatement {
|
|
187
|
+
const type = schema.content.type;
|
|
188
|
+
switch (type) {
|
|
189
|
+
case 'any':
|
|
190
|
+
return this.generateAnyTypeModel(schema, root);
|
|
191
|
+
case 'array':
|
|
192
|
+
return this.generateTypeCollection(schema, root);
|
|
193
|
+
case 'object':
|
|
194
|
+
default:
|
|
195
|
+
return this.generateDeclareType(schema, root);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
221
199
|
private normalizeContent(
|
|
222
200
|
schema: Schema,
|
|
223
201
|
pointer?: string
|
|
@@ -361,18 +339,21 @@ export default class DtsGenerator {
|
|
|
361
339
|
}
|
|
362
340
|
}
|
|
363
341
|
if (content.patternProperties) {
|
|
364
|
-
const
|
|
365
|
-
for (const propertyName of Object.keys(content.patternProperties)) {
|
|
366
|
-
const schema = this.normalizeContent(
|
|
367
|
-
baseSchema,
|
|
368
|
-
'/patternProperties/' + tilde(propertyName)
|
|
369
|
-
);
|
|
370
|
-
schemasTypes.push(this.generateTypeProperty(schema));
|
|
371
|
-
}
|
|
342
|
+
const properties = Object.keys(content.patternProperties);
|
|
372
343
|
const node = ast.buildPropertySignature(
|
|
373
344
|
{ content: { readOnly: false } } as NormalizedSchema,
|
|
374
345
|
'pattern',
|
|
375
|
-
|
|
346
|
+
ast.buildUnionTypeNode(
|
|
347
|
+
properties,
|
|
348
|
+
(propertyName) =>
|
|
349
|
+
this.generateTypeProperty(
|
|
350
|
+
this.normalizeContent(
|
|
351
|
+
baseSchema,
|
|
352
|
+
'/patternProperties/' + tilde(propertyName)
|
|
353
|
+
)
|
|
354
|
+
),
|
|
355
|
+
true
|
|
356
|
+
),
|
|
376
357
|
baseSchema.content.required,
|
|
377
358
|
true
|
|
378
359
|
);
|
|
@@ -380,9 +361,7 @@ export default class DtsGenerator {
|
|
|
380
361
|
ts.addSyntheticTrailingComment(
|
|
381
362
|
node,
|
|
382
363
|
ts.SyntaxKind.MultiLineCommentTrivia,
|
|
383
|
-
` Patterns: ${
|
|
384
|
-
' | '
|
|
385
|
-
)} `
|
|
364
|
+
` Patterns: ${properties.join(' | ')} `
|
|
386
365
|
)
|
|
387
366
|
);
|
|
388
367
|
}
|
|
@@ -401,20 +380,21 @@ export default class DtsGenerator {
|
|
|
401
380
|
);
|
|
402
381
|
}
|
|
403
382
|
const refSchema = this.normalizeContent(ref);
|
|
404
|
-
const node = ast.
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
383
|
+
const node = ast.addOptionalInformation(
|
|
384
|
+
ast.addComment(
|
|
385
|
+
ast.buildTypeReferenceNode(refSchema, this.currentSchema),
|
|
386
|
+
refSchema,
|
|
387
|
+
false
|
|
388
|
+
),
|
|
410
389
|
refSchema,
|
|
411
390
|
false
|
|
412
391
|
);
|
|
392
|
+
return node;
|
|
413
393
|
}
|
|
414
394
|
if (content.anyOf) {
|
|
415
395
|
const mergeContent = Object.assign({}, content);
|
|
416
396
|
delete mergeContent.anyOf;
|
|
417
|
-
return this.
|
|
397
|
+
return this.generateUnionType(
|
|
418
398
|
schema,
|
|
419
399
|
content.anyOf,
|
|
420
400
|
mergeContent,
|
|
@@ -425,7 +405,7 @@ export default class DtsGenerator {
|
|
|
425
405
|
if (content.oneOf) {
|
|
426
406
|
const mergeContent = Object.assign({}, content);
|
|
427
407
|
delete mergeContent.oneOf;
|
|
428
|
-
return this.
|
|
408
|
+
return this.generateUnionType(
|
|
429
409
|
schema,
|
|
430
410
|
content.oneOf,
|
|
431
411
|
mergeContent,
|
|
@@ -433,6 +413,13 @@ export default class DtsGenerator {
|
|
|
433
413
|
terminate
|
|
434
414
|
);
|
|
435
415
|
}
|
|
416
|
+
return this.generateLiteralTypeProperty(schema, terminate);
|
|
417
|
+
}
|
|
418
|
+
private generateLiteralTypeProperty(
|
|
419
|
+
schema: NormalizedSchema,
|
|
420
|
+
terminate = true
|
|
421
|
+
): ts.TypeNode {
|
|
422
|
+
const content = schema.content;
|
|
436
423
|
if (content.enum) {
|
|
437
424
|
return ast.buildUnionTypeNode(
|
|
438
425
|
content.enum,
|
|
@@ -449,6 +436,25 @@ export default class DtsGenerator {
|
|
|
449
436
|
return this.generateType(schema, terminate);
|
|
450
437
|
}
|
|
451
438
|
}
|
|
439
|
+
private checkExistOtherType(
|
|
440
|
+
content: JsonSchemaObject,
|
|
441
|
+
base: NormalizedSchema
|
|
442
|
+
): ts.TypeNode | undefined {
|
|
443
|
+
const schema = Object.assign({}, base, { content });
|
|
444
|
+
const result = this.generateLiteralTypeProperty(schema, false);
|
|
445
|
+
if (result.kind === ts.SyntaxKind.AnyKeyword) {
|
|
446
|
+
return undefined;
|
|
447
|
+
} else if (result.kind === ts.SyntaxKind.TypeLiteral) {
|
|
448
|
+
const node = result as ts.TypeLiteralNode;
|
|
449
|
+
if (
|
|
450
|
+
node.members.length === 1 &&
|
|
451
|
+
node.members[0].kind === ts.SyntaxKind.IndexSignature
|
|
452
|
+
) {
|
|
453
|
+
return undefined;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return result;
|
|
457
|
+
}
|
|
452
458
|
private generateLiteralTypeNode(
|
|
453
459
|
content: JsonSchemaObject,
|
|
454
460
|
value: any
|
|
@@ -458,11 +464,11 @@ export default class DtsGenerator {
|
|
|
458
464
|
case 'number':
|
|
459
465
|
return ast.buildNumericLiteralTypeNode(String(value));
|
|
460
466
|
case 'boolean':
|
|
461
|
-
return ast.buildBooleanLiteralTypeNode(value);
|
|
467
|
+
return ast.buildBooleanLiteralTypeNode(Boolean(value));
|
|
462
468
|
case 'null':
|
|
463
469
|
return ast.buildNullKeyword();
|
|
464
470
|
case 'string':
|
|
465
|
-
return ast.buildStringLiteralTypeNode(value);
|
|
471
|
+
return ast.buildStringLiteralTypeNode(String(value));
|
|
466
472
|
}
|
|
467
473
|
if (value === null) {
|
|
468
474
|
return ast.buildNullKeyword();
|
|
@@ -478,39 +484,51 @@ export default class DtsGenerator {
|
|
|
478
484
|
return ast.buildStringLiteralTypeNode(String(value));
|
|
479
485
|
}
|
|
480
486
|
|
|
481
|
-
private
|
|
487
|
+
private generateUnionType(
|
|
482
488
|
baseSchema: NormalizedSchema,
|
|
483
489
|
contents: JsonSchema[],
|
|
484
|
-
mergeContent:
|
|
490
|
+
mergeContent: JsonSchemaObject,
|
|
485
491
|
path: string,
|
|
486
492
|
terminate: boolean
|
|
487
493
|
): ts.TypeNode {
|
|
488
|
-
|
|
494
|
+
const merged: boolean[] = [];
|
|
495
|
+
const children = contents.map((_, index) => {
|
|
496
|
+
const schema = this.normalizeContent(
|
|
497
|
+
baseSchema,
|
|
498
|
+
path + index.toString()
|
|
499
|
+
);
|
|
500
|
+
merged.push(utils.mergeSchema(schema.content, mergeContent));
|
|
501
|
+
return schema;
|
|
502
|
+
});
|
|
503
|
+
const allRef = merged.every((b) => !b);
|
|
504
|
+
const baseType = this.checkExistOtherType(mergeContent, baseSchema);
|
|
505
|
+
|
|
506
|
+
const result = ast.addOptionalInformation(
|
|
489
507
|
ast.addComment(
|
|
490
508
|
ast.buildUnionTypeNode(
|
|
491
|
-
|
|
492
|
-
(
|
|
493
|
-
const
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
schema,
|
|
509
|
+
children,
|
|
510
|
+
(schema, index) => {
|
|
511
|
+
const node = schema.id.isEmpty()
|
|
512
|
+
? ast.addOptionalInformation(
|
|
513
|
+
this.generateTypeProperty(schema, false),
|
|
514
|
+
schema,
|
|
515
|
+
false
|
|
516
|
+
)
|
|
517
|
+
: ast.addOptionalInformation(
|
|
518
|
+
ast.buildTypeReferenceNode(
|
|
519
|
+
schema,
|
|
520
|
+
this.currentSchema
|
|
521
|
+
),
|
|
522
|
+
schema,
|
|
523
|
+
false
|
|
524
|
+
);
|
|
525
|
+
if (baseType != null && !allRef && !merged[index]) {
|
|
526
|
+
return ast.buildIntersectionTypeNode(
|
|
527
|
+
[baseType, node],
|
|
511
528
|
false
|
|
512
529
|
);
|
|
513
530
|
}
|
|
531
|
+
return node;
|
|
514
532
|
},
|
|
515
533
|
terminate
|
|
516
534
|
),
|
|
@@ -520,6 +538,10 @@ export default class DtsGenerator {
|
|
|
520
538
|
baseSchema,
|
|
521
539
|
terminate
|
|
522
540
|
);
|
|
541
|
+
if (baseType != null && allRef) {
|
|
542
|
+
return ast.buildIntersectionTypeNode([baseType, result], terminate);
|
|
543
|
+
}
|
|
544
|
+
return result;
|
|
523
545
|
}
|
|
524
546
|
|
|
525
547
|
private generateArrayTypeProperty(
|
package/src/core/jsonSchema.ts
CHANGED
|
@@ -379,7 +379,7 @@ export function searchAllSubSchema(
|
|
|
379
379
|
}
|
|
380
380
|
for (const mime of Object.keys(types)) {
|
|
381
381
|
if (
|
|
382
|
-
/^text\/|^(?:application\/x-www-form-urlencoded$|^application\/([a-z0-9-_.]+\+)?json)$|^application\/octet-stream$|^multipart\/form-data$/.test(
|
|
382
|
+
/^text\/|^(?:application\/x-www-form-urlencoded$|^application\/([a-z0-9-_.]+\+)?json)$|^application\/octet-stream$|^application\/jwt$|^application\/vnd.apple.pkpass$|^multipart\/form-data$/.test(
|
|
383
383
|
mime
|
|
384
384
|
)
|
|
385
385
|
) {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Schema } from './type';
|
|
2
|
+
|
|
3
|
+
export interface TypeTree {
|
|
4
|
+
children: Map<string, TypeTree>;
|
|
5
|
+
schema?: Schema;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function buildTypeTree(schemas: IterableIterator<Schema>): TypeTree {
|
|
9
|
+
const tree: TypeTree = buildTree();
|
|
10
|
+
for (const type of schemas) {
|
|
11
|
+
setTypeToTree(tree, type.id.toNames(), type);
|
|
12
|
+
}
|
|
13
|
+
if (tree.children.size === 0) {
|
|
14
|
+
throw new Error('There is no schema in the input contents.');
|
|
15
|
+
}
|
|
16
|
+
return tree;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function setTypeToTree(tree: TypeTree, paths: string[], type: Schema): void {
|
|
20
|
+
if (paths.length === 0) {
|
|
21
|
+
throw new Error('The paths is nothing for set the type to TypeTree.');
|
|
22
|
+
}
|
|
23
|
+
let t: TypeTree = tree;
|
|
24
|
+
for (const key of paths) {
|
|
25
|
+
let next = t.children.get(key);
|
|
26
|
+
if (next === undefined) {
|
|
27
|
+
next = buildTree();
|
|
28
|
+
t.children.set(key, next);
|
|
29
|
+
}
|
|
30
|
+
t = next;
|
|
31
|
+
}
|
|
32
|
+
t.schema = type;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function buildTree(): TypeTree {
|
|
36
|
+
return {
|
|
37
|
+
children: new Map(),
|
|
38
|
+
};
|
|
39
|
+
}
|
package/src/core/utils.ts
CHANGED
|
@@ -52,18 +52,16 @@ export function reduceTypes(types: SimpleTypes[]): SimpleTypes[] {
|
|
|
52
52
|
return types;
|
|
53
53
|
}
|
|
54
54
|
const set = new Set<SimpleTypes>(types);
|
|
55
|
-
if (set.delete('integer')) {
|
|
56
|
-
set.add('number');
|
|
57
|
-
}
|
|
58
55
|
return Array.from(set.values());
|
|
59
56
|
}
|
|
60
57
|
|
|
61
58
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
62
|
-
export function mergeSchema(a: any, b: any):
|
|
59
|
+
export function mergeSchema(a: any, b: any): boolean {
|
|
63
60
|
if ('$ref' in a || '$ref' in b) {
|
|
64
|
-
|
|
61
|
+
a.$ref = b.$ref || a.$ref;
|
|
62
|
+
return false;
|
|
65
63
|
}
|
|
66
|
-
Object.keys(b).forEach((key: string) => {
|
|
64
|
+
Object.keys(b as object).forEach((key: string) => {
|
|
67
65
|
const value = b[key];
|
|
68
66
|
if (a[key] != null && typeof value !== typeof a[key]) {
|
|
69
67
|
debug(`mergeSchema warning: type is mismatched, key=${key}`);
|
|
@@ -72,11 +70,11 @@ export function mergeSchema(a: any, b: any): any {
|
|
|
72
70
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
73
71
|
a[key] = (a[key] ?? []).concat(value);
|
|
74
72
|
} else if (value != null && typeof value === 'object') {
|
|
75
|
-
a[key]
|
|
73
|
+
a[key] ??= {};
|
|
74
|
+
mergeSchema(a[key], value);
|
|
76
75
|
} else {
|
|
77
76
|
a[key] = value;
|
|
78
77
|
}
|
|
79
78
|
});
|
|
80
|
-
|
|
81
|
-
return a;
|
|
79
|
+
return true;
|
|
82
80
|
}
|
package/src/utils.ts
CHANGED
|
@@ -109,7 +109,13 @@ export function readConfig(options: CommandOptions): Partial<Config> {
|
|
|
109
109
|
} else if (pc.input.urls == null) {
|
|
110
110
|
pc.input.urls = [];
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
if (options.stdin != null) {
|
|
113
|
+
pc.input.stdin = options.stdin;
|
|
114
|
+
} else {
|
|
115
|
+
pc.input.stdin =
|
|
116
|
+
pc.input.stdin ||
|
|
117
|
+
(pc.input.files.length === 0 && pc.input.urls.length === 0);
|
|
118
|
+
}
|
|
113
119
|
|
|
114
120
|
if (options.out != null) {
|
|
115
121
|
pc.outputFile = options.out;
|