UNPKG

14.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var debug_1 = tslib_1.__importDefault(require("debug"));
5var jsonPointer_1 = require("../jsonPointer");
6var jsonSchema_1 = require("./jsonSchema");
7var utils = tslib_1.__importStar(require("./utils"));
8var debug = debug_1.default('dtsgen');
9var typeMarker = Symbol();
10var DtsGenerator = (function () {
11 function DtsGenerator(resolver, convertor) {
12 this.resolver = resolver;
13 this.convertor = convertor;
14 }
15 DtsGenerator.prototype.generate = function () {
16 return tslib_1.__awaiter(this, void 0, void 0, function () {
17 var map, result;
18 return tslib_1.__generator(this, function (_a) {
19 switch (_a.label) {
20 case 0:
21 debug('generate type definition files.');
22 return [4, this.resolver.resolve()];
23 case 1:
24 _a.sent();
25 map = this.convertor.buildSchemaMergedMap(this.resolver.getAllRegisteredSchema(), typeMarker);
26 this.convertor.start();
27 this.walk(map);
28 result = this.convertor.end();
29 return [2, result];
30 }
31 });
32 });
33 };
34 DtsGenerator.prototype.walk = function (map) {
35 var e_1, _a;
36 var keys = Object.keys(map).sort();
37 try {
38 for (var keys_1 = tslib_1.__values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
39 var key = keys_1_1.value;
40 var value = map[key];
41 if (value.hasOwnProperty(typeMarker)) {
42 var schema = value[typeMarker];
43 debug(" walk doProcess: key=" + key + " schemaId=" + schema.id.getAbsoluteId());
44 this.walkSchema(schema);
45 delete value[typeMarker];
46 }
47 if (typeof value === 'object' && Object.keys(value).length > 0) {
48 this.convertor.startNest(key);
49 this.walk(value);
50 this.convertor.endNest();
51 }
52 }
53 }
54 catch (e_1_1) { e_1 = { error: e_1_1 }; }
55 finally {
56 try {
57 if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
58 }
59 finally { if (e_1) throw e_1.error; }
60 }
61 };
62 DtsGenerator.prototype.walkSchema = function (schema) {
63 var normalized = this.normalizeContent(schema);
64 this.currentSchema = normalized;
65 this.convertor.outputComments(normalized);
66 var type = normalized.content.type;
67 switch (type) {
68 case 'any':
69 return this.generateAnyTypeModel(normalized);
70 case 'array':
71 return this.generateTypeCollection(normalized);
72 case 'object':
73 default:
74 return this.generateDeclareType(normalized);
75 }
76 };
77 DtsGenerator.prototype.normalizeContent = function (schema, pointer) {
78 if (pointer != null) {
79 schema = jsonSchema_1.getSubSchema(schema, pointer);
80 }
81 var content = this.normalizeSchemaContent(schema.content);
82 return Object.assign({}, schema, { content: content });
83 };
84 DtsGenerator.prototype.normalizeSchemaContent = function (content) {
85 var e_2, _a;
86 if (typeof content === 'boolean') {
87 content = content ? {} : { not: {} };
88 }
89 else {
90 if (content.allOf) {
91 var work = content;
92 try {
93 for (var _b = tslib_1.__values(content.allOf), _c = _b.next(); !_c.done; _c = _b.next()) {
94 var sub = _c.value;
95 if (typeof sub === 'object' && sub.$ref) {
96 var ref = this.resolver.dereference(sub.$ref);
97 var normalized = this.normalizeContent(ref).content;
98 utils.mergeSchema(work, normalized);
99 }
100 else if (typeof sub === 'object') {
101 var normalized = this.normalizeSchemaContent(sub);
102 utils.mergeSchema(work, normalized);
103 }
104 else {
105 utils.mergeSchema(work, sub);
106 }
107 }
108 }
109 catch (e_2_1) { e_2 = { error: e_2_1 }; }
110 finally {
111 try {
112 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
113 }
114 finally { if (e_2) throw e_2.error; }
115 }
116 delete content.allOf;
117 content = work;
118 }
119 if (content.type === undefined && (content.properties || content.additionalProperties)) {
120 content.type = 'object';
121 }
122 if (content.nullable) {
123 var type = content.type;
124 if (type == null) {
125 content.type = 'null';
126 }
127 else if (!Array.isArray(type)) {
128 content.type = [type, 'null'];
129 }
130 else {
131 type.push('null');
132 }
133 }
134 var types = content.type;
135 if (Array.isArray(types)) {
136 var reduced = utils.reduceTypes(types);
137 content.type = reduced.length === 1 ? reduced[0] : reduced;
138 }
139 }
140 return content;
141 };
142 DtsGenerator.prototype.generateDeclareType = function (schema) {
143 var content = schema.content;
144 if (content.$ref || content.oneOf || content.anyOf || content.enum || 'const' in content || content.type !== 'object') {
145 this.convertor.outputExportType(schema.id);
146 this.generateTypeProperty(schema, true);
147 }
148 else {
149 this.convertor.startInterfaceNest(schema.id);
150 this.generateProperties(schema);
151 this.convertor.endInterfaceNest();
152 }
153 };
154 DtsGenerator.prototype.generateAnyTypeModel = function (schema) {
155 this.convertor.startInterfaceNest(schema.id);
156 this.convertor.outputRawValue('[name: string]: any; // any', true);
157 this.convertor.endInterfaceNest();
158 };
159 DtsGenerator.prototype.generateTypeCollection = function (schema) {
160 this.convertor.outputExportType(schema.id);
161 this.generateArrayTypeProperty(schema, true);
162 };
163 DtsGenerator.prototype.generateProperties = function (baseSchema) {
164 var e_3, _a;
165 var content = baseSchema.content;
166 if (content.additionalProperties) {
167 this.convertor.outputRawValue('[name: string]: ');
168 var schema = this.normalizeContent(baseSchema, '/additionalProperties');
169 if (content.additionalProperties === true) {
170 this.convertor.outputStringTypeName(schema, 'any', true);
171 }
172 else {
173 this.generateTypeProperty(schema, true);
174 }
175 }
176 if (content.properties) {
177 try {
178 for (var _b = tslib_1.__values(Object.keys(content.properties)), _c = _b.next(); !_c.done; _c = _b.next()) {
179 var propertyName = _c.value;
180 var schema = this.normalizeContent(baseSchema, '/properties/' + jsonPointer_1.tilde(propertyName));
181 this.convertor.outputComments(schema);
182 this.convertor.outputPropertyAttribute(schema);
183 this.convertor.outputPropertyName(schema, propertyName, baseSchema.content.required);
184 this.generateTypeProperty(schema);
185 }
186 }
187 catch (e_3_1) { e_3 = { error: e_3_1 }; }
188 finally {
189 try {
190 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
191 }
192 finally { if (e_3) throw e_3.error; }
193 }
194 }
195 };
196 DtsGenerator.prototype.generateTypeProperty = function (schema, terminate) {
197 var _this = this;
198 if (terminate === void 0) { terminate = true; }
199 var content = schema.content;
200 if (content.$ref) {
201 var ref = this.resolver.dereference(content.$ref);
202 if (ref.id == null) {
203 throw new Error('target referenced id is nothing: ' + content.$ref);
204 }
205 var refSchema = this.normalizeContent(ref);
206 return this.convertor.outputTypeIdName(refSchema, this.currentSchema, terminate);
207 }
208 if (content.anyOf || content.oneOf) {
209 this.generateArrayedType(schema, content.anyOf, '/anyOf/', terminate);
210 this.generateArrayedType(schema, content.oneOf, '/oneOf/', terminate);
211 return;
212 }
213 if (content.enum) {
214 this.convertor.outputArrayedType(schema, content.enum, function (value) {
215 if (content.type === 'integer' || content.type === 'number') {
216 _this.convertor.outputRawValue('' + value);
217 }
218 else {
219 _this.convertor.outputRawValue("\"" + value + "\"");
220 }
221 }, terminate);
222 }
223 else if ('const' in content) {
224 var value = content.const;
225 if (content.type === 'integer' || content.type === 'number') {
226 this.convertor.outputStringTypeName(schema, '' + value, terminate);
227 }
228 else {
229 this.convertor.outputStringTypeName(schema, "\"" + value + "\"", terminate);
230 }
231 }
232 else {
233 this.generateType(schema, terminate);
234 }
235 };
236 DtsGenerator.prototype.generateArrayedType = function (baseSchema, contents, path, terminate) {
237 var _this = this;
238 if (contents) {
239 this.convertor.outputArrayedType(baseSchema, contents, function (_content, index) {
240 var schema = _this.normalizeContent(baseSchema, path + index);
241 if (schema.id.isEmpty()) {
242 _this.generateTypeProperty(schema, false);
243 }
244 else {
245 _this.convertor.outputTypeIdName(schema, _this.currentSchema, false);
246 }
247 }, terminate);
248 }
249 };
250 DtsGenerator.prototype.generateArrayTypeProperty = function (schema, terminate) {
251 if (terminate === void 0) { terminate = true; }
252 var items = schema.content.items;
253 var minItems = schema.content.minItems;
254 var maxItems = schema.content.maxItems;
255 if (items == null) {
256 this.convertor.outputStringTypeName(schema, 'any[]', terminate);
257 }
258 else if (!Array.isArray(items)) {
259 this.generateTypeProperty(this.normalizeContent(schema, '/items'), false);
260 this.convertor.outputStringTypeName(schema, '[]', terminate);
261 }
262 else if (items.length === 0 && minItems === undefined && maxItems === undefined) {
263 this.convertor.outputStringTypeName(schema, 'any[]', terminate);
264 }
265 else if (minItems != null && maxItems != null && maxItems < minItems) {
266 this.convertor.outputStringTypeName(schema, 'never', terminate);
267 }
268 else {
269 this.convertor.outputRawValue('[');
270 var itemCount = Math.max(minItems || 0, maxItems || 0, items.length);
271 if (maxItems != null) {
272 itemCount = Math.min(itemCount, maxItems);
273 }
274 for (var i = 0; i < itemCount; i++) {
275 if (i > 0) {
276 this.convertor.outputRawValue(', ');
277 }
278 if (i < items.length) {
279 var type = this.normalizeContent(schema, '/items/' + i);
280 if (type.id.isEmpty()) {
281 this.generateTypeProperty(type, false);
282 }
283 else {
284 this.convertor.outputTypeIdName(type, this.currentSchema, false);
285 }
286 }
287 else {
288 this.convertor.outputStringTypeName(schema, 'any', false, false);
289 }
290 if (minItems == null || i >= minItems) {
291 this.convertor.outputRawValue('?');
292 }
293 }
294 if (maxItems == null) {
295 if (itemCount > 0) {
296 this.convertor.outputRawValue(', ');
297 }
298 this.convertor.outputStringTypeName(schema, '...any[]', false, false);
299 }
300 this.convertor.outputRawValue(']');
301 this.convertor.outputStringTypeName(schema, '', terminate);
302 }
303 };
304 DtsGenerator.prototype.generateType = function (schema, terminate, outputOptional) {
305 var _this = this;
306 if (outputOptional === void 0) { outputOptional = true; }
307 var type = schema.content.type;
308 if (type == null) {
309 this.convertor.outputPrimitiveTypeName(schema, 'any', terminate, outputOptional);
310 }
311 else if (typeof type === 'string') {
312 this.generateTypeName(schema, type, terminate, outputOptional);
313 }
314 else {
315 var types = utils.reduceTypes(type);
316 if (types.length <= 1) {
317 schema.content.type = types[0];
318 this.generateType(schema, terminate, outputOptional);
319 }
320 else {
321 this.convertor.outputArrayedType(schema, types, function (t) {
322 _this.generateTypeName(schema, t, false, false);
323 }, terminate);
324 }
325 }
326 };
327 DtsGenerator.prototype.generateTypeName = function (schema, type, terminate, outputOptional) {
328 if (outputOptional === void 0) { outputOptional = true; }
329 var tsType = utils.toTSType(type, schema.content);
330 if (tsType) {
331 this.convertor.outputPrimitiveTypeName(schema, tsType, terminate, outputOptional);
332 }
333 else if (type === 'object') {
334 this.convertor.startTypeNest();
335 this.generateProperties(schema);
336 this.convertor.endTypeNest(terminate);
337 }
338 else if (type === 'array') {
339 this.generateArrayTypeProperty(schema, terminate);
340 }
341 else {
342 throw new Error('unknown type: ' + type);
343 }
344 };
345 return DtsGenerator;
346}());
347exports.default = DtsGenerator;
348//# sourceMappingURL=dtsGenerator.js.map
\No newline at end of file