UNPKG

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