blob: da4b29caa4696bd83f8af045bc7277efeb532e02 [file] [log] [blame]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var debug_1 = tslib_1.__importDefault(require("debug"));
var jsonPointer_1 = require("../jsonPointer");
var jsonSchema_1 = require("./jsonSchema");
var utils = tslib_1.__importStar(require("./utils"));
var debug = debug_1.default('dtsgen');
var typeMarker = Symbol();
var DtsGenerator = (function () {
function DtsGenerator(resolver, convertor) {
this.resolver = resolver;
this.convertor = convertor;
}
DtsGenerator.prototype.generate = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var map, result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
debug('generate type definition files.');
return [4, this.resolver.resolve()];
case 1:
_a.sent();
map = this.convertor.buildSchemaMergedMap(this.resolver.getAllRegisteredSchema(), typeMarker);
this.convertor.start();
this.walk(map);
result = this.convertor.end();
return [2, result];
}
});
});
};
DtsGenerator.prototype.walk = function (map) {
var e_1, _a;
var keys = Object.keys(map).sort();
try {
for (var keys_1 = tslib_1.__values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
var key = keys_1_1.value;
var value = map[key];
if (value.hasOwnProperty(typeMarker)) {
var schema = value[typeMarker];
debug(" walk doProcess: key=" + key + " schemaId=" + schema.id.getAbsoluteId());
this.walkSchema(schema);
delete value[typeMarker];
}
if (typeof value === 'object' && Object.keys(value).length > 0) {
this.convertor.startNest(key);
this.walk(value);
this.convertor.endNest();
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
}
finally { if (e_1) throw e_1.error; }
}
};
DtsGenerator.prototype.walkSchema = function (schema) {
var normalized = this.normalizeContent(schema);
this.currentSchema = normalized;
this.convertor.outputComments(normalized);
var type = normalized.content.type;
switch (type) {
case 'any':
return this.generateAnyTypeModel(normalized);
case 'array':
return this.generateTypeCollection(normalized);
case 'object':
default:
return this.generateDeclareType(normalized);
}
};
DtsGenerator.prototype.normalizeContent = function (schema, pointer) {
var e_2, _a;
if (pointer != null) {
schema = jsonSchema_1.getSubSchema(schema, pointer);
}
var content = schema.content;
if (typeof content === 'boolean') {
content = content ? {} : { not: {} };
}
else {
if (content.allOf) {
var work = content;
try {
for (var _b = tslib_1.__values(content.allOf), _c = _b.next(); !_c.done; _c = _b.next()) {
var sub = _c.value;
if (typeof sub === 'object' && sub.$ref) {
var ref = this.resolver.dereference(sub.$ref);
sub = this.normalizeContent(ref).content;
}
utils.mergeSchema(work, sub);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
delete content.allOf;
content = work;
}
if (content.type === undefined && (content.properties || content.additionalProperties)) {
content.type = 'object';
}
if (content.nullable) {
var type = content.type;
if (type == null) {
content.type = 'null';
}
else if (!Array.isArray(type)) {
content.type = [type, 'null'];
}
else {
type.push('null');
}
}
var types = content.type;
if (Array.isArray(types)) {
var reduced = utils.reduceTypes(types);
content.type = reduced.length === 1 ? reduced[0] : reduced;
}
}
return Object.assign({}, schema, { content: content });
};
DtsGenerator.prototype.generateDeclareType = function (schema) {
var content = schema.content;
if (content.$ref || content.oneOf || content.anyOf || content.enum || 'const' in content || content.type !== 'object') {
this.convertor.outputExportType(schema.id);
this.generateTypeProperty(schema, true);
}
else {
this.convertor.startInterfaceNest(schema.id);
this.generateProperties(schema);
this.convertor.endInterfaceNest();
}
};
DtsGenerator.prototype.generateAnyTypeModel = function (schema) {
this.convertor.startInterfaceNest(schema.id);
this.convertor.outputRawValue('[name: string]: any; // any', true);
this.convertor.endInterfaceNest();
};
DtsGenerator.prototype.generateTypeCollection = function (schema) {
this.convertor.outputExportType(schema.id);
this.generateArrayTypeProperty(schema, true);
};
DtsGenerator.prototype.generateProperties = function (baseSchema) {
var e_3, _a;
var content = baseSchema.content;
if (content.additionalProperties) {
this.convertor.outputRawValue('[name: string]: ');
var schema = this.normalizeContent(baseSchema, '/additionalProperties');
if (content.additionalProperties === true) {
this.convertor.outputStringTypeName(schema, 'any', true);
}
else {
this.generateTypeProperty(schema, true);
}
}
if (content.properties) {
try {
for (var _b = tslib_1.__values(Object.keys(content.properties)), _c = _b.next(); !_c.done; _c = _b.next()) {
var propertyName = _c.value;
var schema = this.normalizeContent(baseSchema, '/properties/' + jsonPointer_1.tilde(propertyName));
this.convertor.outputComments(schema);
this.convertor.outputPropertyAttribute(schema);
this.convertor.outputPropertyName(schema, propertyName, baseSchema.content.required);
this.generateTypeProperty(schema);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_3) throw e_3.error; }
}
}
};
DtsGenerator.prototype.generateTypeProperty = function (schema, terminate) {
var _this = this;
if (terminate === void 0) { terminate = true; }
var content = schema.content;
if (content.$ref) {
var ref = this.resolver.dereference(content.$ref);
if (ref.id == null) {
throw new Error('target referenced id is nothing: ' + content.$ref);
}
var refSchema = this.normalizeContent(ref);
return this.convertor.outputTypeIdName(refSchema, this.currentSchema, terminate);
}
if (content.anyOf || content.oneOf) {
this.generateArrayedType(schema, content.anyOf, '/anyOf/', terminate);
this.generateArrayedType(schema, content.oneOf, '/oneOf/', terminate);
return;
}
if (content.enum) {
this.convertor.outputArrayedType(schema, content.enum, function (value) {
if (content.type === 'integer') {
_this.convertor.outputRawValue('' + value);
}
else {
_this.convertor.outputRawValue("\"" + value + "\"");
}
}, terminate);
}
else if ('const' in content) {
var value = content.const;
if (content.type === 'integer') {
this.convertor.outputStringTypeName(schema, '' + value, terminate);
}
else {
this.convertor.outputStringTypeName(schema, "\"" + value + "\"", terminate);
}
}
else {
this.generateType(schema, terminate);
}
};
DtsGenerator.prototype.generateArrayedType = function (baseSchema, contents, path, terminate) {
var _this = this;
if (contents) {
this.convertor.outputArrayedType(baseSchema, contents, function (_content, index) {
var schema = _this.normalizeContent(baseSchema, path + index);
if (schema.id.isEmpty()) {
_this.generateTypeProperty(schema, false);
}
else {
_this.convertor.outputTypeIdName(schema, _this.currentSchema, false);
}
}, terminate);
}
};
DtsGenerator.prototype.generateArrayTypeProperty = function (schema, terminate) {
if (terminate === void 0) { terminate = true; }
var items = schema.content.items;
var minItems = schema.content.minItems;
if (items == null) {
this.convertor.outputStringTypeName(schema, 'any[]', terminate);
}
else if (!Array.isArray(items)) {
this.generateTypeProperty(this.normalizeContent(schema, '/items'), false);
this.convertor.outputStringTypeName(schema, '[]', terminate);
}
else if (items.length === 0 && minItems === undefined) {
this.convertor.outputStringTypeName(schema, 'any[]', terminate);
}
else {
var effectiveMaxItems = 1 + Math.max(minItems || 0, items.length);
for (var unionIndex = minItems === undefined ? 1 : minItems; unionIndex <= effectiveMaxItems; unionIndex++) {
this.convertor.outputRawValue('[');
for (var i = 0; i < unionIndex; i++) {
if (i > 0) {
this.convertor.outputRawValue(', ');
}
if (i < items.length) {
var type = this.normalizeContent(schema, '/items/' + i);
if (type.id.isEmpty()) {
this.generateTypeProperty(type, false);
}
else {
this.convertor.outputTypeIdName(type, this.currentSchema, false);
}
}
else {
if (i < effectiveMaxItems - 1) {
this.convertor.outputStringTypeName(schema, 'Object', false, false);
}
else {
this.convertor.outputStringTypeName(schema, 'any', false, false);
}
}
}
this.convertor.outputRawValue(']');
if (unionIndex < effectiveMaxItems) {
this.convertor.outputRawValue(' | ');
}
}
this.convertor.outputStringTypeName(schema, '', terminate);
}
};
DtsGenerator.prototype.generateType = function (schema, terminate, outputOptional) {
var _this = this;
if (outputOptional === void 0) { outputOptional = true; }
var type = schema.content.type;
if (type == null) {
this.convertor.outputPrimitiveTypeName(schema, 'any', terminate, outputOptional);
}
else if (typeof type === 'string') {
this.generateTypeName(schema, type, terminate, outputOptional);
}
else {
var types = utils.reduceTypes(type);
if (types.length <= 1) {
schema.content.type = types[0];
this.generateType(schema, terminate, outputOptional);
}
else {
this.convertor.outputArrayedType(schema, types, function (t) {
_this.generateTypeName(schema, t, false, false);
}, terminate);
}
}
};
DtsGenerator.prototype.generateTypeName = function (schema, type, terminate, outputOptional) {
if (outputOptional === void 0) { outputOptional = true; }
var tsType = utils.toTSType(type, schema.content);
if (tsType) {
this.convertor.outputPrimitiveTypeName(schema, tsType, terminate, outputOptional);
}
else if (type === 'object') {
this.convertor.startTypeNest();
this.generateProperties(schema);
this.convertor.endTypeNest(terminate);
}
else if (type === 'array') {
this.generateArrayTypeProperty(schema, terminate);
}
else {
throw new Error('unknown type: ' + type);
}
};
return DtsGenerator;
}());
exports.default = DtsGenerator;
//# sourceMappingURL=dtsGenerator.js.map