UNPKG

13.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 'object':
69 case 'any':
70 return this.generateTypeModel(normalized);
71 case 'array':
72 return this.generateTypeCollection(normalized);
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 this.convertor.outputExportType(schema.id);
134 this.generateTypeProperty(schema, true);
135 };
136 DtsGenerator.prototype.generateTypeModel = function (schema) {
137 this.convertor.startInterfaceNest(schema.id);
138 if (schema.content.type === 'any') {
139 this.convertor.outputRawValue('[name: string]: any; // any', true);
140 }
141 this.generateProperties(schema);
142 this.convertor.endInterfaceNest();
143 };
144 DtsGenerator.prototype.generateTypeCollection = function (schema) {
145 this.convertor.outputExportType(schema.id);
146 this.generateArrayTypeProperty(schema, true);
147 };
148 DtsGenerator.prototype.generateProperties = function (baseSchema) {
149 var e_3, _a;
150 var content = baseSchema.content;
151 if (content.additionalProperties) {
152 this.convertor.outputRawValue('[name: string]: ');
153 var schema = this.normalizeContent(baseSchema, '/additionalProperties');
154 if (content.additionalProperties === true) {
155 this.convertor.outputStringTypeName(schema, 'any', true);
156 }
157 else {
158 this.generateTypeProperty(schema, true);
159 }
160 }
161 if (content.properties) {
162 try {
163 for (var _b = tslib_1.__values(Object.keys(content.properties)), _c = _b.next(); !_c.done; _c = _b.next()) {
164 var propertyName = _c.value;
165 var schema = this.normalizeContent(baseSchema, '/properties/' + jsonPointer_1.tilde(propertyName));
166 this.convertor.outputComments(schema);
167 this.convertor.outputPropertyAttribute(schema);
168 this.convertor.outputPropertyName(schema, propertyName, baseSchema.content.required);
169 this.generateTypeProperty(schema);
170 }
171 }
172 catch (e_3_1) { e_3 = { error: e_3_1 }; }
173 finally {
174 try {
175 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
176 }
177 finally { if (e_3) throw e_3.error; }
178 }
179 }
180 };
181 DtsGenerator.prototype.generateTypeProperty = function (schema, terminate) {
182 var _this = this;
183 if (terminate === void 0) { terminate = true; }
184 var content = schema.content;
185 if (content.$ref) {
186 var ref = this.resolver.dereference(content.$ref);
187 if (ref.id == null) {
188 throw new Error('target referenced id is nothing: ' + content.$ref);
189 }
190 var refSchema = this.normalizeContent(ref);
191 return this.convertor.outputTypeIdName(refSchema, this.currentSchema, terminate);
192 }
193 if (content.anyOf || content.oneOf) {
194 this.generateArrayedType(schema, content.anyOf, '/anyOf/', terminate);
195 this.generateArrayedType(schema, content.oneOf, '/oneOf/', terminate);
196 return;
197 }
198 if (content.enum) {
199 this.convertor.outputArrayedType(schema, content.enum, function (value) {
200 if (content.type === 'integer') {
201 _this.convertor.outputRawValue('' + value);
202 }
203 else {
204 _this.convertor.outputRawValue("\"" + value + "\"");
205 }
206 }, terminate);
207 }
208 else if ('const' in content) {
209 var value = content.const;
210 if (content.type === 'integer') {
211 this.convertor.outputStringTypeName(schema, '' + value, terminate);
212 }
213 else {
214 this.convertor.outputStringTypeName(schema, "\"" + value + "\"", terminate);
215 }
216 }
217 else {
218 this.generateType(schema, terminate);
219 }
220 };
221 DtsGenerator.prototype.generateArrayedType = function (baseSchema, contents, path, terminate) {
222 var _this = this;
223 if (contents) {
224 this.convertor.outputArrayedType(baseSchema, contents, function (_content, index) {
225 var schema = _this.normalizeContent(baseSchema, path + index);
226 if (schema.id.isEmpty()) {
227 _this.generateTypeProperty(schema, false);
228 }
229 else {
230 _this.convertor.outputTypeIdName(schema, _this.currentSchema, false);
231 }
232 }, terminate);
233 }
234 };
235 DtsGenerator.prototype.generateArrayTypeProperty = function (schema, terminate) {
236 if (terminate === void 0) { terminate = true; }
237 var items = schema.content.items;
238 var minItems = schema.content.minItems;
239 if (items == null) {
240 this.convertor.outputStringTypeName(schema, 'any[]', terminate);
241 }
242 else if (!Array.isArray(items)) {
243 this.generateTypeProperty(this.normalizeContent(schema, '/items'), false);
244 this.convertor.outputStringTypeName(schema, '[]', terminate);
245 }
246 else if (items.length === 0 && minItems === undefined) {
247 this.convertor.outputStringTypeName(schema, 'any[]', terminate);
248 }
249 else {
250 var effectiveMaxItems = 1 + Math.max(minItems || 0, items.length);
251 for (var unionIndex = minItems === undefined ? 1 : minItems; unionIndex <= effectiveMaxItems; unionIndex++) {
252 this.convertor.outputRawValue('[');
253 for (var i = 0; i < unionIndex; i++) {
254 if (i > 0) {
255 this.convertor.outputRawValue(', ');
256 }
257 if (i < items.length) {
258 var type = this.normalizeContent(schema, '/items/' + i);
259 if (type.id.isEmpty()) {
260 this.generateTypeProperty(type, false);
261 }
262 else {
263 this.convertor.outputTypeIdName(type, this.currentSchema, false);
264 }
265 }
266 else {
267 if (i < effectiveMaxItems - 1) {
268 this.convertor.outputStringTypeName(schema, 'Object', false, false);
269 }
270 else {
271 this.convertor.outputStringTypeName(schema, 'any', false, false);
272 }
273 }
274 }
275 this.convertor.outputRawValue(']');
276 if (unionIndex < effectiveMaxItems) {
277 this.convertor.outputRawValue(' | ');
278 }
279 }
280 this.convertor.outputStringTypeName(schema, '', terminate);
281 }
282 };
283 DtsGenerator.prototype.generateType = function (schema, terminate, outputOptional) {
284 var _this = this;
285 if (outputOptional === void 0) { outputOptional = true; }
286 var type = schema.content.type;
287 if (type == null) {
288 this.convertor.outputPrimitiveTypeName(schema, 'any', terminate, outputOptional);
289 }
290 else if (typeof type === 'string') {
291 this.generateTypeName(schema, type, terminate, outputOptional);
292 }
293 else {
294 var types = utils.reduceTypes(type);
295 if (types.length <= 1) {
296 schema.content.type = types[0];
297 this.generateType(schema, terminate, outputOptional);
298 }
299 else {
300 this.convertor.outputArrayedType(schema, types, function (t) {
301 _this.generateTypeName(schema, t, false, false);
302 }, terminate);
303 }
304 }
305 };
306 DtsGenerator.prototype.generateTypeName = function (schema, type, terminate, outputOptional) {
307 if (outputOptional === void 0) { outputOptional = true; }
308 var tsType = utils.toTSType(type, schema.content);
309 if (tsType) {
310 this.convertor.outputPrimitiveTypeName(schema, tsType, terminate, outputOptional);
311 }
312 else if (type === 'object') {
313 this.convertor.startTypeNest();
314 this.generateProperties(schema);
315 this.convertor.endTypeNest(terminate);
316 }
317 else if (type === 'array') {
318 this.generateArrayTypeProperty(schema, terminate);
319 }
320 else {
321 throw new Error('unknown type: ' + type);
322 }
323 };
324 return DtsGenerator;
325}());
326exports.default = DtsGenerator;
327//# sourceMappingURL=dtsGenerator.js.map
\No newline at end of file