@nestia/sdk
Version:
Nestia SDK and Swagger generator
122 lines • 5.07 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImportAnalyzer = void 0;
const typescript_1 = __importDefault(require("typescript"));
const MapUtil_1 = require("../utils/MapUtil");
var ImportAnalyzer;
(function (ImportAnalyzer) {
ImportAnalyzer.analyze = (checker, generics, type) => {
const imports = new Map();
try {
type = escape(checker, type);
return {
type: explore({
checker,
generics,
imports,
type,
}),
imports: [...imports].map(([file, instances]) => ({
file,
instances: Array.from(instances),
})),
};
}
catch (_a) {
return {
imports: [],
type: null,
};
}
};
ImportAnalyzer.unique = (imports) => {
const map = new Map();
imports.forEach(({ file, instances }) => {
const set = MapUtil_1.MapUtil.take(map, file, () => new Set());
instances.forEach((instance) => set.add(instance));
});
return [...map].map(([file, instances]) => ({
file,
instances: Array.from(instances),
}));
};
/* ---------------------------------------------------------
TYPE
--------------------------------------------------------- */
const escape = (checker, type) => {
if (type.symbol && getNameOfSymbol(type.symbol) === "Promise") {
const generic = checker.getTypeArguments(type);
if (generic.length !== 1)
throw new Error("Error on ImportAnalyzer.analyze(): invalid promise type.");
type = generic[0];
}
return type;
};
const getNameOfSymbol = (symbol) => {
var _a, _b;
return exploreName(symbol.escapedName.toString(), (_b = (_a = symbol.getDeclarations()) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.parent);
};
/* ---------------------------------------------------------
ESCAPED TEXT WITH IMPORT STATEMENTS
--------------------------------------------------------- */
const explore = (props) => {
var _a, _b, _c, _d;
//----
// CONDITIONAL BRANCHES
//----
// DECOMPOSE GENERIC ARGUMENT
let type = props.type;
while (props.generics.has(type) === true)
type = props.generics.get(type);
// PRIMITIVE
const symbol = (_a = type.aliasSymbol) !== null && _a !== void 0 ? _a : type.symbol;
// UNION OR INTERSECT
if (type.aliasSymbol === undefined && type.isUnionOrIntersection()) {
const joiner = type.isIntersection() ? " & " : " | ";
return {
name: type.types
.map((child) => explore(Object.assign(Object.assign({}, props), { type: child })))
.map(getEscapedText)
.join(joiner),
};
}
// NO SYMBOL
else if (symbol === undefined)
return {
name: props.checker.typeToString(type, undefined, typescript_1.default.TypeFormatFlags.NoTruncation),
};
//----
// SPECIALIZATION
//----
const name = getNameOfSymbol(symbol);
const sourceFile = (_c = (_b = symbol.declarations) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.getSourceFile();
if (sourceFile === undefined)
return { name };
else if (sourceFile.fileName.indexOf("typescript/lib") === -1) {
const set = MapUtil_1.MapUtil.take(props.imports, sourceFile.fileName, () => new Set());
set.add(name.split(".")[0]);
}
// CHECK GENERIC
const generic = type.aliasSymbol
? (_d = type.aliasTypeArguments) !== null && _d !== void 0 ? _d : []
: props.checker.getTypeArguments(type);
return generic.length
? name === "Promise"
? explore(Object.assign(Object.assign({}, props), { type: generic[0] }))
: {
name,
typeArguments: generic.map((child) => explore(Object.assign(Object.assign({}, props), { type: child }))),
}
: { name };
};
const exploreName = (name, decl) => decl && typescript_1.default.isModuleBlock(decl)
? exploreName(`${decl.parent.name.getFullText().trim()}.${name}`, decl.parent.parent)
: name;
const getEscapedText = (type) => type.typeArguments
? `${type.name}<${type.typeArguments.map(getEscapedText).join(", ")}>`
: type.name;
})(ImportAnalyzer || (exports.ImportAnalyzer = ImportAnalyzer = {}));
//# sourceMappingURL=ImportAnalyzer.js.map
;