UNPKG

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