UNPKG

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