UNPKG

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