UNPKG

10.2 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.addOptionalInformation = exports.addComment = exports.buildTypeReferenceNode = exports.buildTupleTypeNode = exports.buildUnionTypeNode = 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.buildUnknownKeyword = exports.buildNeverKeyword = exports.buildAnyKeyword = exports.buildKeyword = void 0;
4const tslib_1 = require("tslib");
5const ts = tslib_1.__importStar(require("typescript"));
6const config_1 = tslib_1.__importDefault(require("./config"));
7const validateIdentifier_1 = require("./validateIdentifier");
8function buildTypeNameIdentifier(name) {
9 return ts.factory.createIdentifier(validateIdentifier_1.toValidIdentifier(name, config_1.default.target));
10}
11function buildPropertyNameIdentifier(name) {
12 if (/^\d/.test(name)) {
13 name = '$' + name;
14 }
15 if (validateIdentifier_1.checkInvalidCharacter(name, config_1.default.target)) {
16 return ts.factory.createIdentifier(name);
17 }
18 else {
19 return ts.factory.createStringLiteral(name);
20 }
21}
22function buildKeyword(kind) {
23 return ts.factory.createKeywordTypeNode(kind);
24}
25exports.buildKeyword = buildKeyword;
26function buildAnyKeyword() {
27 return buildKeyword(ts.SyntaxKind.AnyKeyword);
28}
29exports.buildAnyKeyword = buildAnyKeyword;
30function buildNeverKeyword() {
31 return buildKeyword(ts.SyntaxKind.NeverKeyword);
32}
33exports.buildNeverKeyword = buildNeverKeyword;
34function buildUnknownKeyword() {
35 return buildKeyword(ts.SyntaxKind.UnknownKeyword);
36}
37exports.buildUnknownKeyword = buildUnknownKeyword;
38function buildStringKeyword() {
39 return buildKeyword(ts.SyntaxKind.StringKeyword);
40}
41exports.buildStringKeyword = buildStringKeyword;
42function buildSimpleArrayNode(element) {
43 return ts.factory.createArrayTypeNode(element);
44}
45exports.buildSimpleArrayNode = buildSimpleArrayNode;
46function buildNullKeyword() {
47 return ts.factory.createLiteralTypeNode(ts.factory.createToken(ts.SyntaxKind.NullKeyword));
48}
49exports.buildNullKeyword = buildNullKeyword;
50function buildStringLiteralTypeNode(s) {
51 return ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(s));
52}
53exports.buildStringLiteralTypeNode = buildStringLiteralTypeNode;
54function buildNumericLiteralTypeNode(n) {
55 return ts.factory.createLiteralTypeNode(ts.factory.createNumericLiteral(n));
56}
57exports.buildNumericLiteralTypeNode = buildNumericLiteralTypeNode;
58function buildBooleanLiteralTypeNode(b) {
59 return ts.factory.createLiteralTypeNode(b ? ts.factory.createTrue() : ts.factory.createFalse());
60}
61exports.buildBooleanLiteralTypeNode = buildBooleanLiteralTypeNode;
62function buildNamespaceNode(name, statements, root) {
63 const modifiers = root
64 ? [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)]
65 : undefined;
66 return ts.factory.createModuleDeclaration(undefined, modifiers, buildTypeNameIdentifier(name), ts.factory.createModuleBlock(statements), ts.NodeFlags.Namespace |
67 ts.NodeFlags.ExportContext |
68 ts.NodeFlags.ContextFlags);
69}
70exports.buildNamespaceNode = buildNamespaceNode;
71function buildInterfaceNode(id, members, root) {
72 const name = getLastTypeName(id);
73 const modifiers = root
74 ? [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)]
75 : [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)];
76 return ts.factory.createInterfaceDeclaration(undefined, modifiers, buildTypeNameIdentifier(name), undefined, undefined, members);
77}
78exports.buildInterfaceNode = buildInterfaceNode;
79function buildTypeAliasNode(id, type, root) {
80 const name = getLastTypeName(id);
81 const modifiers = root
82 ? [ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword)]
83 : [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)];
84 return ts.factory.createTypeAliasDeclaration(undefined, modifiers, buildTypeNameIdentifier(name), undefined, type);
85}
86exports.buildTypeAliasNode = buildTypeAliasNode;
87function buildPropertySignature(schema, propertyName, valueType, required, isPattern) {
88 const content = schema.content;
89 const modifiers = 'readOnly' in content && content.readOnly
90 ? [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)]
91 : undefined;
92 const questionToken = required == null || required.indexOf(propertyName) < 0
93 ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
94 : undefined;
95 if (isPattern) {
96 return ts.factory.createIndexSignature(undefined, modifiers, [
97 ts.factory.createParameterDeclaration([], [], undefined, ts.factory.createIdentifier('pattern'), undefined, ts.factory.createTypeReferenceNode('string', []), undefined),
98 ], valueType);
99 }
100 return ts.factory.createPropertySignature(modifiers, buildPropertyNameIdentifier(propertyName), questionToken, valueType);
101}
102exports.buildPropertySignature = buildPropertySignature;
103function buildIndexSignatureNode(name, indexType, valueType) {
104 return ts.factory.createIndexSignature(undefined, undefined, [
105 ts.factory.createParameterDeclaration(undefined, undefined, undefined, buildTypeNameIdentifier(name), undefined, indexType, undefined),
106 ], valueType);
107}
108exports.buildIndexSignatureNode = buildIndexSignatureNode;
109function buildTypeLiteralNode(elements) {
110 return ts.factory.createTypeLiteralNode(elements);
111}
112exports.buildTypeLiteralNode = buildTypeLiteralNode;
113function buildUnionTypeNode(types, builder, terminate) {
114 const node = ts.factory.createUnionTypeNode(types.map(builder));
115 if (terminate) {
116 return node;
117 }
118 return ts.factory.createParenthesizedType(node);
119}
120exports.buildUnionTypeNode = buildUnionTypeNode;
121function buildTupleTypeNode(types, minItems, maxItems) {
122 const nodes = [];
123 const itemCount = maxItems != null ? maxItems : Math.max(types.length, minItems !== null && minItems !== void 0 ? minItems : 0);
124 for (let i = 0; i < itemCount; i++) {
125 let node = i < types.length ? types[i] : buildAnyKeyword();
126 if (minItems == null || i >= minItems) {
127 node = ts.factory.createOptionalTypeNode(node);
128 }
129 nodes.push(node);
130 }
131 if (maxItems == null) {
132 nodes.push(ts.factory.createRestTypeNode(ts.factory.createArrayTypeNode(buildAnyKeyword())));
133 }
134 return ts.factory.createTupleTypeNode(nodes);
135}
136exports.buildTupleTypeNode = buildTupleTypeNode;
137function buildTypeReferenceNode(schema, currentSchema) {
138 const typeName = getTypename(schema.id, currentSchema);
139 if (typeName.length === 0) {
140 throw new Error('TypeName array must not be empty.');
141 }
142 let node = buildTypeNameIdentifier(typeName[0]);
143 for (let i = 1; i < typeName.length; i++) {
144 node = ts.factory.createQualifiedName(node, buildTypeNameIdentifier(typeName[i]));
145 }
146 return ts.factory.createTypeReferenceNode(node, undefined);
147}
148exports.buildTypeReferenceNode = buildTypeReferenceNode;
149function getTypename(id, baseSchema) {
150 const result = id.toNames();
151 const baseId = baseSchema.id;
152 if (baseId) {
153 const baseTypes = baseId.toNames().slice(0, -1);
154 for (const type of baseTypes) {
155 if (result.length === 1) {
156 break;
157 }
158 if (result[0] === type) {
159 result.shift();
160 }
161 else {
162 break;
163 }
164 }
165 }
166 return result;
167}
168function addComment(node, schema, terminate) {
169 const comments = getComment(schema);
170 if (comments.length === 0) {
171 return node;
172 }
173 else if (!terminate && comments.length === 1) {
174 return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, ` ${comments[0]} `, false);
175 }
176 else {
177 let result = '*\n';
178 for (const comment of comments) {
179 result += ' * ' + comment + '\n';
180 }
181 result += ' ';
182 return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, result, true);
183 }
184}
185exports.addComment = addComment;
186function getComment(schema) {
187 const content = schema.content;
188 let comments = [];
189 function protectComment(str) {
190 return str.replace(/\*\//g, '*\u200B/');
191 }
192 function appendComment(value) {
193 if (value == null) {
194 return;
195 }
196 const s = typeof value === 'string' ? value : JSON.stringify(value, null, 2);
197 const lines = s.split('\n').map((line) => protectComment(line));
198 comments = comments.concat(...lines);
199 }
200 if ('$comment' in content) {
201 appendComment(content.$comment);
202 }
203 appendComment(content.title);
204 appendComment(content.description);
205 if ('example' in content || 'examples' in content) {
206 appendComment('example:');
207 if ('example' in content) {
208 appendComment(content.example);
209 }
210 if ('examples' in content) {
211 if (content.examples) {
212 for (const e of content.examples) {
213 appendComment(e);
214 }
215 }
216 }
217 }
218 return comments;
219}
220function addOptionalInformation(node, schema, terminate) {
221 const format = schema.content.format;
222 const pattern = schema.content.pattern;
223 if (!format && !pattern) {
224 return node;
225 }
226 let comment = '';
227 if (format) {
228 comment += ' ' + format;
229 }
230 if (pattern) {
231 comment += ' ' + pattern;
232 }
233 if (!terminate) {
234 comment += ' ';
235 }
236 const kind = terminate
237 ? ts.SyntaxKind.SingleLineCommentTrivia
238 : ts.SyntaxKind.MultiLineCommentTrivia;
239 return ts.addSyntheticTrailingComment(node, kind, comment, false);
240}
241exports.addOptionalInformation = addOptionalInformation;
242function getLastTypeName(id) {
243 const names = id.toNames();
244 if (names.length > 0) {
245 return names[names.length - 1];
246 }
247 else {
248 return '';
249 }
250}