UNPKG

14.2 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 var e_2, _a;
79 if (pointer != null) {
80 schema = jsonSchema_1.getSubSchema(schema, pointer);
81 }
82 var content = schema.content;
83 if (typeof content === 'boolean') {
84 content = content ? {} : { not: {} };
85 }
86 else {
87 if (content.allOf) {
88 var work = content;
89 try {
90 for (var _b = tslib_1.__values(content.allOf), _c = _b.next(); !_c.done; _c = _b.next()) {
91 var sub = _c.value;
92 if (typeof sub === 'object' && sub.$ref) {
93 var ref = this.resolver.dereference(sub.$ref);
94 sub = this.normalizeContent(ref).content;
95 }
96 utils.mergeSchema(work, sub);
97 }
98 }
99 catch (e_2_1) { e_2 = { error: e_2_1 }; }
100 finally {
101 try {
102 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
103 }
104 finally { if (e_2) throw e_2.error; }
105 }
106 delete content.allOf;
107 content = work;
108 }
109 if (content.type === undefined && (content.properties || content.additionalProperties)) {
110 content.type = 'object';
111 }
112 if (content.nullable) {
113 var type = content.type;
114 if (type == null) {
115 content.type = 'null';
116 }
117 else if (!Array.isArray(type)) {
118 content.type = [type, 'null'];
119 }
120 else {
121 type.push('null');
122 }
123 }
124 var types = content.type;
125 if (Array.isArray(types)) {
126 var reduced = utils.reduceTypes(types);
127 content.type = reduced.length === 1 ? reduced[0] : reduced;
128 }
129 }
130 return Object.assign({}, schema, { content: content });
131 };
132 DtsGenerator.prototype.generateDeclareType = function (schema) {
133 var content = schema.content;
134 if (content.$ref || content.oneOf || content.anyOf || content.enum || 'const' in content || content.type !== 'object') {
135 this.convertor.outputExportType(schema.id);
136 this.generateTypeProperty(schema, true);
137 }
138 else {
139 this.convertor.startInterfaceNest(schema.id);
140 this.generateProperties(schema);
141 this.convertor.endInterfaceNest();
142 }
143 };
144 DtsGenerator.prototype.generateAnyTypeModel = function (schema) {
145 this.convertor.startInterfaceNest(schema.id);
146 this.convertor.outputRawValue('[name: string]: any; // any', true);
147 this.convertor.endInterfaceNest();
148 };
149 DtsGenerator.prototype.generateTypeCollection = function (schema) {
150 this.convertor.outputExportType(schema.id);
151 this.generateArrayTypeProperty(schema, true);
152 };
153 DtsGenerator.prototype.generateProperties = function (baseSchema) {
154 var e_3, _a;
155 var content = baseSchema.content;
156 if (content.additionalProperties) {
157 this.convertor.outputRawValue('[name: string]: ');
158 var schema = this.normalizeContent(baseSchema, '/additionalProperties');
159 if (content.additionalProperties === true) {
160 this.convertor.outputStringTypeName(schema, 'any', true);
161 }
162 else {
163 this.generateTypeProperty(schema, true);
164 }
165 }
166 if (content.properties) {
167 try {
168 for (var _b = tslib_1.__values(Object.keys(content.properties)), _c = _b.next(); !_c.done; _c = _b.next()) {
169 var propertyName = _c.value;
170 var schema = this.normalizeContent(baseSchema, '/properties/' + jsonPointer_1.tilde(propertyName));
171 this.convertor.outputComments(schema);
172 this.convertor.outputPropertyAttribute(schema);
173 this.convertor.outputPropertyName(schema, propertyName, baseSchema.content.required);
174 this.generateTypeProperty(schema);
175 }
176 }
177 catch (e_3_1) { e_3 = { error: e_3_1 }; }
178 finally {
179 try {
180 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
181 }
182 finally { if (e_3) throw e_3.error; }
183 }
184 }
185 };
186 DtsGenerator.prototype.generateTypeProperty = function (schema, terminate) {
187 var _this = this;
188 if (terminate === void 0) { terminate = true; }
189 var content = schema.content;
190 if (content.$ref) {
191 var ref = this.resolver.dereference(content.$ref);
192 if (ref.id == null) {
193 throw new Error('target referenced id is nothing: ' + content.$ref);
194 }
195 var refSchema = this.normalizeContent(ref);
196 return this.convertor.outputTypeIdName(refSchema, this.currentSchema, terminate);
197 }
198 if (content.anyOf || content.oneOf) {
199 this.generateArrayedType(schema, content.anyOf, '/anyOf/', terminate);
200 this.generateArrayedType(schema, content.oneOf, '/oneOf/', terminate);
201 return;
202 }
203 if (content.enum) {
204 this.convertor.outputArrayedType(schema, content.enum, function (value) {
205 if (content.type === 'integer') {
206 _this.convertor.outputRawValue('' + value);
207 }
208 else {
209 _this.convertor.outputRawValue("\"" + value + "\"");
210 }
211 }, terminate);
212 }
213 else if ('const' in content) {
214 var value = content.const;
215 if (content.type === 'integer') {
216 this.convertor.outputStringTypeName(schema, '' + value, terminate);
217 }
218 else {
219 this.convertor.outputStringTypeName(schema, "\"" + value + "\"", terminate);
220 }
221 }
222 else {
223 this.generateType(schema, terminate);
224 }
225 };
226 DtsGenerator.prototype.generateArrayedType = function (baseSchema, contents, path, terminate) {
227 var _this = this;
228 if (contents) {
229 this.convertor.outputArrayedType(baseSchema, contents, function (_content, index) {
230 var schema = _this.normalizeContent(baseSchema, path + index);
231 if (schema.id.isEmpty()) {
232 _this.generateTypeProperty(schema, false);
233 }
234 else {
235 _this.convertor.outputTypeIdName(schema, _this.currentSchema, false);
236 }
237 }, terminate);
238 }
239 };
240 DtsGenerator.prototype.generateArrayTypeProperty = function (schema, terminate) {
241 if (terminate === void 0) { terminate = true; }
242 var items = schema.content.items;
243 var minItems = schema.content.minItems;
244 var maxItems = schema.content.maxItems;
245 if (items == null) {
246 this.convertor.outputStringTypeName(schema, 'any[]', terminate);
247 }
248 else if (!Array.isArray(items)) {
249 this.generateTypeProperty(this.normalizeContent(schema, '/items'), false);
250 this.convertor.outputStringTypeName(schema, '[]', terminate);
251 }
252 else if (items.length === 0 && minItems === undefined && maxItems === undefined) {
253 this.convertor.outputStringTypeName(schema, 'any[]', terminate);
254 }
255 else if (minItems != null && maxItems != null && maxItems < minItems) {
256 this.convertor.outputStringTypeName(schema, 'never', terminate);
257 }
258 else {
259 this.convertor.outputRawValue('[');
260 var itemCount = Math.max(minItems || 0, maxItems || 0, items.length);
261 if (maxItems != null) {
262 itemCount = Math.min(itemCount, maxItems);
263 }
264 for (var i = 0; i < itemCount; i++) {
265 if (i > 0) {
266 this.convertor.outputRawValue(', ');
267 }
268 if (i < items.length) {
269 var type = this.normalizeContent(schema, '/items/' + i);
270 if (type.id.isEmpty()) {
271 this.generateTypeProperty(type, false);
272 }
273 else {
274 this.convertor.outputTypeIdName(type, this.currentSchema, false);
275 }
276 }
277 else {
278 this.convertor.outputStringTypeName(schema, 'any', false, false);
279 }
280 if (minItems == null || i >= minItems) {
281 this.convertor.outputRawValue('?');
282 }
283 }
284 if (maxItems == null) {
285 if (itemCount > 0) {
286 this.convertor.outputRawValue(', ');
287 }
288 this.convertor.outputStringTypeName(schema, '...any[]', false, false);
289 }
290 this.convertor.outputRawValue(']');
291 this.convertor.outputStringTypeName(schema, '', terminate);
292 }
293 };
294 DtsGenerator.prototype.generateType = function (schema, terminate, outputOptional) {
295 var _this = this;
296 if (outputOptional === void 0) { outputOptional = true; }
297 var type = schema.content.type;
298 if (type == null) {
299 this.convertor.outputPrimitiveTypeName(schema, 'any', terminate, outputOptional);
300 }
301 else if (typeof type === 'string') {
302 this.generateTypeName(schema, type, terminate, outputOptional);
303 }
304 else {
305 var types = utils.reduceTypes(type);
306 if (types.length <= 1) {
307 schema.content.type = types[0];
308 this.generateType(schema, terminate, outputOptional);
309 }
310 else {
311 this.convertor.outputArrayedType(schema, types, function (t) {
312 _this.generateTypeName(schema, t, false, false);
313 }, terminate);
314 }
315 }
316 };
317 DtsGenerator.prototype.generateTypeName = function (schema, type, terminate, outputOptional) {
318 if (outputOptional === void 0) { outputOptional = true; }
319 var tsType = utils.toTSType(type, schema.content);
320 if (tsType) {
321 this.convertor.outputPrimitiveTypeName(schema, tsType, terminate, outputOptional);
322 }
323 else if (type === 'object') {
324 this.convertor.startTypeNest();
325 this.generateProperties(schema);
326 this.convertor.endTypeNest(terminate);
327 }
328 else if (type === 'array') {
329 this.generateArrayTypeProperty(schema, terminate);
330 }
331 else {
332 throw new Error('unknown type: ' + type);
333 }
334 };
335 return DtsGenerator;
336}());
337exports.default = DtsGenerator;
338//# sourceMappingURL=dtsGenerator.js.map
\No newline at end of file