@nestia/sdk
Version:
Nestia SDK and Swagger generator
155 lines • 6.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImportDictionary = void 0;
const factory_1 = require("@ttsc/factory");
const path_1 = __importDefault(require("path"));
const tstl_1 = require("tstl");
const ImportAnalyzer_1 = require("../../analyses/ImportAnalyzer");
const FilePrinter_1 = require("./FilePrinter");
class ImportDictionary {
constructor(file) {
this.file = file;
this.components_ = new tstl_1.HashMap((key) => (0, tstl_1.hash)(key.file, key.declaration, key.asterisk, key.default), (a, b) => a.file === b.file &&
a.declaration === b.declaration &&
a.asterisk === b.asterisk &&
a.default === b.default);
}
empty() {
return this.components_.empty();
}
declarations(imports) {
var _a;
var _b;
imports = ImportAnalyzer_1.ImportAnalyzer.merge(imports);
for (const imp of imports) {
if (imp.asterisk !== null)
this.internal({
type: "asterisk",
file: imp.file,
name: imp.asterisk,
declaration: true,
});
if (imp.default !== null)
this.internal({
type: "default",
file: imp.file,
name: imp.default,
declaration: true,
});
for (const elem of imp.elements) {
if (elem === "WebSocketAcceptor")
continue;
const imported = (_b = (_a = imp.elementAliases) === null || _a === void 0 ? void 0 : _a[elem]) !== null && _b !== void 0 ? _b : elem;
this.internal({
type: "element",
file: imp.file,
name: imported,
alias: imported === elem ? undefined : elem,
declaration: true,
});
}
}
}
external(props) {
const file = `node_modules/${props.file}`;
return this.internal(Object.assign(Object.assign({}, props), { file }));
}
internal(props) {
var _a, _b;
const file = normalize(trimSourceExtension(props.file));
const key = {
file: file,
declaration: props.declaration,
asterisk: props.type === "asterisk" ? props.name : null,
default: props.type === "default" ? props.name : null,
};
const value = this.components_.take(key, () => (Object.assign(Object.assign({}, key), { elements: new tstl_1.TreeMap() })));
if (props.type === "element") {
const local = (_a = props.alias) !== null && _a !== void 0 ? _a : props.name;
value.elements.set(local, props.name);
}
return props.type === "element" ? ((_b = props.alias) !== null && _b !== void 0 ? _b : props.name) : props.name;
}
toStatements(outDir) {
outDir = path_1.default.resolve(outDir);
const external = [];
const internal = [];
const locator = (str) => {
const location = path_1.default
.relative(outDir, str)
.split(path_1.default.sep)
.join("/");
const index = location.lastIndexOf(NODE_MODULES);
return index === -1
? location.startsWith("..")
? location
: `./${location}`
: location.substring(index + NODE_MODULES.length);
};
const enroll = (filter) => (container) => {
const compositions = this.components_
.toJSON()
.filter((c) => filter(c.second.file))
.map((e) => (Object.assign(Object.assign({}, e.second), { file: locator(e.second.file) })))
.sort((a, b) => a.file.localeCompare(b.file));
for (const c of compositions)
container.push(factory_1.factory.createImportDeclaration(undefined, this.toImportClaude(c), factory_1.factory.createStringLiteral(c.file)));
};
enroll((str) => str.indexOf(NODE_MODULES) !== -1)(external);
enroll((str) => str.indexOf(NODE_MODULES) === -1)(internal);
return [
...external,
...(external.length && internal.length ? [FilePrinter_1.FilePrinter.enter()] : []),
...internal,
];
}
toImportClaude(c) {
// A namespace binding cannot carry a per-binding `type` modifier, so the
// type-only flag goes on the clause itself (`import type * as X`) —
// generated SDK code references DTO namespaces only in type positions.
if (c.asterisk !== null)
return factory_1.factory.createImportClause(c.declaration ? factory_1.SyntaxKind.TypeKeyword : undefined, undefined, factory_1.factory.createNamespaceImport(factory_1.factory.createIdentifier(c.asterisk)));
// `c.declaration` (type-only) belongs on the import clause, not on each
// specifier — emitting both produces the invalid `import type { type X }`.
return factory_1.factory.createImportClause(c.declaration ? factory_1.SyntaxKind.TypeKeyword : undefined, c.default !== null ? factory_1.factory.createIdentifier(c.default) : undefined, c.elements.size() !== 0
? factory_1.factory.createNamedImports(Array.from(c.elements).map(({ first: local, second: imported }) => factory_1.factory.createImportSpecifier(false, imported !== local
? factory_1.factory.createIdentifier(imported)
: undefined, factory_1.factory.createIdentifier(local))))
: undefined);
}
}
exports.ImportDictionary = ImportDictionary;
const NODE_MODULES = "node_modules/";
const SOURCE_EXTENSIONS = [
".d.mts",
".d.cts",
".d.ts",
".mts",
".cts",
".tsx",
".ts",
".mjs",
".cjs",
".jsx",
".js",
];
const normalize = (file) => {
file = path_1.default.resolve(file);
if (file.includes(`node_modules${path_1.default.sep}`))
file =
"node_modules/" +
file.split(`node_modules${path_1.default.sep}`).at(-1).split(path_1.default.sep).join("/");
return file;
};
const trimSourceExtension = (file) => {
if (file.startsWith(`${NODE_MODULES}`))
return file;
for (const ext of SOURCE_EXTENSIONS)
if (file.endsWith(ext))
return file.substring(0, file.length - ext.length);
return file;
};
//# sourceMappingURL=ImportDictionary.js.map