json-ts
Version:
Automatically generate Typescript Definition files or Flow types from JSON input
122 lines • 19.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var transformer_1 = require("./transformer");
var util_1 = require("./util");
function collapseInterfaces(interfaces) {
/**
* {
* 'IItems': {count: 5, names: Set {'pets', 'age'} }
* }
* @type {any}
*/
var memberStack = interfaces.reduce(function (acc, int) {
var lookup = acc[int.name.text];
if (lookup) {
lookup.count += 1;
int.members.forEach(function (mem) {
lookup.names.add(mem.name.text);
});
}
else {
acc[int.name.text] = { count: 1, names: new Set([]) };
}
return acc;
}, {});
/**
* Look at each interface and mark any members absent in others
* as optional.
*/
interfaces.forEach(function (i) {
var curName = i.name.text;
var fromStack = memberStack[curName];
if (fromStack.count === 1) {
return;
}
i.members.forEach(function (localMember) {
var localName = localMember.name.text;
if (!fromStack.names.has(localName)) {
localMember.questionToken = ts.createNode(ts.SyntaxKind.QuestionToken);
}
});
});
return interfaces.reduce(function (accInterfaces, current) {
var currentName = current.name.text;
var currentMemberNames = new Set(current.members.map(function (x) { return (x.name || x.label).text; }));
var matchingInterfaceIndex = accInterfaces.findIndex(function (x) { return (x.name || x.label).text === currentName; });
if (matchingInterfaceIndex === -1) {
return accInterfaces.concat(current);
}
accInterfaces.forEach(function (int, index) {
if (index !== matchingInterfaceIndex) {
return int;
}
var prevMemberNames = new Set(int.members.map(function (x) { return (x.name || x.label).text; }));
// if the current interface has less props than a previous one
// we need to back-track and make the previous one optional
if (currentMemberNames.size < prevMemberNames.size) {
// elements that existed before, but not in the current
int.members.forEach(function (mem) {
if (!currentMemberNames.has(mem.name.text)) {
mem.questionToken = ts.createNode(ts.SyntaxKind.QuestionToken);
}
});
}
// Modify members based on missing props, union types etc
modifyMembers(int.members, current.members);
});
return accInterfaces;
}, []);
}
exports.collapseInterfaces = collapseInterfaces;
function modifyMembers(interfaceMembers, currentMembers) {
currentMembers.forEach(function (mem) {
var existingIndex = interfaceMembers.findIndex(function (x) { return x.name.text === mem.name.text; });
var existingMember = interfaceMembers[existingIndex];
// Here, the current member does NOT already exist in this
// interface, so we add it, but as optional
if (!existingMember) {
mem.questionToken = ts.createNode(ts.SyntaxKind.QuestionToken);
interfaceMembers.push(mem);
}
else {
// here it exists in both, are the types the same?
// console.log(ts.SyntaxKind[mem.type.kind]);
// console.log(existingMember.kind, mem.kind);
if (util_1.membersMatch(existingMember, mem)) {
return;
}
else {
var updatedMember = transformer_1.namedProp({ name: existingMember.name.text });
// const exists = existingMember.type.types.some(x => x.kind === mem.kind);
// already a union, so just push a new type
if (existingMember.type.kind === ts.SyntaxKind.UnionType) {
var asSet = new Set(existingMember.type.types.map(function (x) { return x.kind; }));
if (!asSet.has(mem.type.kind)) {
existingMember.type.types.push(mem.type);
interfaceMembers[existingIndex] = existingMember;
}
}
else {
// was this previously marked as an empty array? eg: any[]
// if so & the next item is NOT, then we can ignore the any[]
if (util_1.isEmptyArrayType(existingMember) && !util_1.isEmptyArrayType(mem)) {
updatedMember.type = ts.createNode(ts.SyntaxKind.ArrayType);
updatedMember.type.elementType = mem.type.elementType;
interfaceMembers[existingIndex] = updatedMember;
}
else {
// If the INCOMING member type is an empty array, but we already have an array element with items, we bail
if (util_1.isEmptyArrayType(mem) && existingMember.type.kind === ts.SyntaxKind.ArrayType && (!util_1.isEmptyArrayType(existingMember))) {
return;
}
var memberNodes = [existingMember.type, mem.type];
updatedMember.type = ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.UnionType, memberNodes);
interfaceMembers[existingIndex] = updatedMember;
}
}
}
}
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGFwc2UtaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsYXBzZS1pbnRlcmZhY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0JBQWlDO0FBQ2pDLDZDQUF3QztBQUN4QywrQkFBc0Q7QUFFdEQsNEJBQW1DLFVBQWlCO0lBRWhEOzs7OztPQUtHO0lBQ0gsSUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxVQUFDLEdBQUcsRUFBRSxHQUFHO1FBQzNDLElBQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDVCxNQUFNLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUNsQixHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFBLEdBQUc7Z0JBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsQ0FBQyxDQUFDLENBQUE7UUFDTixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDSixHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUE7UUFDdkQsQ0FBQztRQUNELE1BQU0sQ0FBQyxHQUFHLENBQUM7SUFDZixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFUDs7O09BR0c7SUFDSCxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQUMsQ0FBQztRQUNqQixJQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztRQUM1QixJQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLENB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Y0FBYyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ3BELGFBQWEsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDLGlDQUFpQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO3dCQUNoRyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsR0FBRyxhQUFhLENBQUM7b0JBQ3BELENBQUM7Z0JBQ0wsQ0FBQztZQUNMLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdHMgZnJvbSAndHlwZXNjcmlwdCc7XG5pbXBvcnQge25hbWVkUHJvcH0gZnJvbSBcIi4vdHJhbnNmb3JtZXJcIjtcbmltcG9ydCB7aXNFbXB0eUFycmF5VHlwZSwgbWVtYmVyc01hdGNofSBmcm9tIFwiLi91dGlsXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xsYXBzZUludGVyZmFjZXMoaW50ZXJmYWNlczogYW55W10pOiBhbnlbXSB7XG5cbiAgICAvKipcbiAgICAgKiB7XG4gICAgICogICdJSXRlbXMnOiB7Y291bnQ6IDUsIG5hbWVzOiBTZXQgeydwZXRzJywgJ2FnZSd9IH1cbiAgICAgKiB9XG4gICAgICogQHR5cGUge2FueX1cbiAgICAgKi9cbiAgICBjb25zdCBtZW1iZXJTdGFjayA9IGludGVyZmFjZXMucmVkdWNlKChhY2MsIGludCkgPT4ge1xuICAgICAgICBjb25zdCBsb29rdXAgPSBhY2NbaW50Lm5hbWUudGV4dF07XG4gICAgICAgIGlmIChsb29rdXApIHtcbiAgICAgICAgICAgIGxvb2t1cC5jb3VudCArPSAxO1xuICAgICAgICAgICAgaW50Lm1lbWJlcnMuZm9yRWFjaChtZW0gPT4ge1xuICAgICAgICAgICAgICAgIGxvb2t1cC5uYW1lcy5hZGQobWVtLm5hbWUudGV4dCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWNjW2ludC5uYW1lLnRleHRdID0ge2NvdW50OiAxLCBuYW1lczogbmV3IFNldChbXSl9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG5cbiAgICAvKipcbiAgICAgKiBMb29rIGF0IGVhY2ggaW50ZXJmYWNlIGFuZCBtYXJrIGFueSBtZW1iZXJzIGFic2VudCBpbiBvdGhlcnNcbiAgICAgKiBhcyBvcHRpb25hbC5cbiAgICAgKi9cbiAgICBpbnRlcmZhY2VzLmZvckVhY2goKGkpID0+IHtcbiAgICAgICAgY29uc3QgY3VyTmFtZSA9IGkubmFtZS50ZXh0O1xuICAgICAgICBjb25zdCBmcm9tU3RhY2sgPSBtZW1iZXJTdGFja1tjdXJOYW1lXTtcbiAgICAgICAgaWYgKGZyb21TdGFjay5jb3VudCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGkubWVtYmVycy5mb3JFYWNoKGxvY2FsTWVtYmVyID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxvY2FsTmFtZSA9IGxvY2FsTWVtYmVyLm5hbWUudGV4dDtcbiAgICAgICAgICAgIGlmICghZnJvbVN0YWNrLm5hbWVzLmhhcyhsb2NhbE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxNZW1iZXIucXVlc3Rpb25Ub2tlbiA9IHRzLmNyZWF0ZU5vZGUodHMuU3ludGF4S2luZC5RdWVzdGlvblRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gaW50ZXJmYWNlcy5yZWR1Y2UoKGFjY0ludGVyZmFjZXMsIGN1cnJlbnQpID0+IHtcblxuICAgICAgICBjb25zdCBjdXJyZW50TmFtZSA9IGN1cnJlbnQubmFtZS50ZXh0O1xuICAgICAgICBjb25zdCBjdXJyZW50TWVtYmVyTmFtZXMgPSBuZXcgU2V0KGN1cnJlbnQubWVtYmVycy5tYXAoeCA9PiAoeC5uYW1lIHx8IHgubGFiZWwpLnRleHQpKTtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdJbnRlcmZhY2VJbmRleCA9IGFjY0ludGVyZmFjZXMuZmluZEluZGV4KHggPT4gKHgubmFtZSB8fCB4LmxhYmVsKS50ZXh0ID09PSBjdXJyZW50TmFtZSk7XG5cbiAgICAgICAgaWYgKG1hdGNoaW5nSW50ZXJmYWNlSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gYWNjSW50ZXJmYWNlcy5jb25jYXQoY3VycmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBhY2NJbnRlcmZhY2VzLmZvckVhY2goKGludCwgaW5kZXgpID0+IHtcblxuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSBtYXRjaGluZ0ludGVyZmFjZUluZGV4KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGludDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcHJldk1lbWJlck5hbWVzID0gbmV3IFNldChpbnQubWVtYmVycy5tYXAoeCA9PiAoeC5uYW1lIHx8IHgubGFiZWwpLnRleHQpKTtcblxuICAgICAgICAgICAgLy8gaWYgdGhlIGN1cnJlbnQgaW50ZXJmYWNlIGhhcyBsZXNzIHByb3BzIHRoYW4gYSBwcmV2aW91cyBvbmVcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gYmFjay10cmFjayBhbmQgbWFrZSB0aGUgcHJldmlvdXMgb25lIG9wdGlvbmFsXG4gICAgICAgICAgICBpZiAoY3VycmVudE1lbWJlck5hbWVzLnNpemUgPCBwcmV2TWVtYmVyTmFtZXMuc2l6ZSkge1xuICAgICAgICAgICAgICAgIC8vIGVsZW1lbnRzIHRoYXQgZXhpc3RlZCBiZWZvcmUsIGJ1dCBub3QgaW4gdGhlIGN1cnJlbnRcbiAgICAgICAgICAgICAgICBpbnQubWVtYmVycy5mb3JFYWNoKG1lbSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY3VycmVudE1lbWJlck5hbWVzLmhhcyhtZW0ubmFtZS50ZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVtLnF1ZXN0aW9uVG9rZW4gPSB0cy5jcmVhdGVOb2RlKHRzLlN5bnRheEtpbmQuUXVlc3Rpb25Ub2tlbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTW9kaWZ5IG1lbWJlcnMgYmFzZWQgb24gbWlzc2luZyBwcm9wcywgdW5pb24gdHlwZXMgZXRjXG4gICAgICAgICAgICBtb2RpZnlNZW1iZXJzKGludC5tZW1iZXJzLCBjdXJyZW50Lm1lbWJlcnMpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gYWNjSW50ZXJmYWNlcztcblxuICAgIH0sIFtdKTtcbn1cblxuZnVuY3Rpb24gbW9kaWZ5TWVtYmVycyhpbnRlcmZhY2VNZW1iZXJzLCBjdXJyZW50TWVtYmVycykge1xuICAgIGN1cnJlbnRNZW1iZXJzLmZvckVhY2gobWVtID0+IHtcblxuICAgICAgICBjb25zdCBleGlzdGluZ0luZGV4ID0gaW50ZXJmYWNlTWVtYmVycy5maW5kSW5kZXgoeCA9PiB4Lm5hbWUudGV4dCA9PT0gbWVtLm5hbWUudGV4dCk7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nTWVtYmVyID0gaW50ZXJmYWNlTWVtYmVyc1tleGlzdGluZ0luZGV4XTtcblxuICAgICAgICAvLyBIZXJlLCB0aGUgY3VycmVudCBtZW1iZXIgZG9lcyBOT1QgYWxyZWFkeSBleGlzdCBpbiB0aGlzXG4gICAgICAgIC8vIGludGVyZmFjZSwgc28gd2UgYWRkIGl0LCBidXQgYXMgb3B0aW9uYWxcbiAgICAgICAgaWYgKCFleGlzdGluZ01lbWJlcikge1xuICAgICAgICAgICAgbWVtLnF1ZXN0aW9uVG9rZW4gPSB0cy5jcmVhdGVOb2RlKHRzLlN5bnRheEtpbmQuUXVlc3Rpb25Ub2tlbik7XG4gICAgICAgICAgICBpbnRlcmZhY2VNZW1iZXJzLnB1c2gobWVtKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGhlcmUgaXQgZXhpc3RzIGluIGJvdGgsIGFyZSB0aGUgdHlwZXMgdGhlIHNhbWU/XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyh0cy5TeW50YXhLaW5kW21lbS50eXBlLmtpbmRdKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGV4aXN0aW5nTWVtYmVyLmtpbmQsIG1lbS5raW5kKTtcbiAgICAgICAgICAgIGlmIChtZW1iZXJzTWF0Y2goZXhpc3RpbmdNZW1iZXIsIG1lbSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRNZW1iZXIgPSBuYW1lZFByb3Aoe25hbWU6IGV4aXN0aW5nTWVtYmVyLm5hbWUudGV4dH0pO1xuICAgICAgICAgICAgICAgIC8vIGNvbnN0IGV4aXN0cyAgPSBleGlzdGluZ01lbWJlci50eXBlLnR5cGVzLnNvbWUoeCA9PiB4LmtpbmQgPT09IG1lbS5raW5kKTtcblxuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgYSB1bmlvbiwgc28ganVzdCBwdXNoIGEgbmV3IHR5cGVcbiAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdNZW1iZXIudHlwZS5raW5kID09PSB0cy5TeW50YXhLaW5kLlVuaW9uVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhc1NldCA9IG5ldyBTZXQoZXhpc3RpbmdNZW1iZXIudHlwZS50eXBlcy5tYXAoeCA9PiB4LmtpbmQpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhc1NldC5oYXMobWVtLnR5cGUua2luZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nTWVtYmVyLnR5cGUudHlwZXMucHVzaChtZW0udHlwZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2VNZW1iZXJzW2V4aXN0aW5nSW5kZXhdID0gZXhpc3RpbmdNZW1iZXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBub3QgYSB1bmlvbiB5ZXQsIHNvIGNyZWF0ZSBvbmUgZm9yIG5leHQgdGltZSBhcm91bmRcblxuICAgICAgICAgICAgICAgICAgICAvLyB3YXMgdGhpcyBwcmV2aW91c2x5IG1hcmtlZCBhcyBhbiBlbXB0eSBhcnJheT8gZWc6IGFueVtdXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHNvICYgdGhlIG5leHQgaXRlbSBpcyBOT1QsIHRoZW4gd2UgY2FuIGlnbm9yZSB0aGUgYW55W11cbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHlBcnJheVR5cGUoZXhpc3RpbmdNZW1iZXIpICYmICFpc0VtcHR5QXJyYXlUeXBlKG1lbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRNZW1iZXIudHlwZSA9IHRzLmNyZWF0ZU5vZGUodHMuU3ludGF4S2luZC5BcnJheVR5cGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZE1lbWJlci50eXBlLmVsZW1lbnRUeXBlID0gbWVtLnR5cGUuZWxlbWVudFR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2VNZW1iZXJzW2V4aXN0aW5nSW5kZXhdID0gdXBkYXRlZE1lbWJlcjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBJTkNPTUlORyBtZW1iZXIgdHlwZSBpcyBhbiBlbXB0eSBhcnJheSwgYnV0IHdlIGFscmVhZHkgaGF2ZSBhbiBhcnJheSBlbGVtZW50IHdpdGggaXRlbXMsIHdlIGJhaWxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0VtcHR5QXJyYXlUeXBlKG1lbSkgJiYgZXhpc3RpbmdNZW1iZXIudHlwZS5raW5kID09PSB0cy5TeW50YXhLaW5kLkFycmF5VHlwZSAmJiAoIWlzRW1wdHlBcnJheVR5cGUoZXhpc3RpbmdNZW1iZXIpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lbWJlck5vZGVzID0gW2V4aXN0aW5nTWVtYmVyLnR5cGUsIG1lbS50eXBlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRNZW1iZXIudHlwZSA9IHRzLmNyZWF0ZVVuaW9uT3JJbnRlcnNlY3Rpb25UeXBlTm9kZSh0cy5TeW50YXhLaW5kLlVuaW9uVHlwZSwgbWVtYmVyTm9kZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlTWVtYmVyc1tleGlzdGluZ0luZGV4XSA9IHVwZGF0ZWRNZW1iZXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn0iXX0=