ts-transform-esm-import
Version:
Rewrite TypeScript import paths to ES Modules import paths
198 lines • 9.9 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.transform = transform;
const ts = __importStar(require("typescript"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const helper = __importStar(require("./helper"));
const rsv = __importStar(require("./resolve"));
const logger_1 = __importDefault(require("./logger"));
function positionIsReal(pos) {
return (pos >= 0);
}
function importExportVisitor(ctx, sfOrBundle, opts) {
const logger = opts.debug ? new logger_1.default() : null;
const log = opts.debug ? (s) => logger?.log(s) : () => {
};
let sf;
if (ts.isSourceFile(sfOrBundle)) {
sf = sfOrBundle;
}
else if (ts.isBundle(sfOrBundle)) {
const source = sfOrBundle.sourceFiles[0];
if (!source) {
throw new Error(`No source file found in bundle ${sfOrBundle.getText()}`);
}
sf = source;
}
const visitor = (node) => {
let importPath = '';
if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node))
&& node.moduleSpecifier && positionIsReal(node.pos) && positionIsReal(node.end)) {
const importPathWithQuotes = node.moduleSpecifier.getText(sf);
importPath = importPathWithQuotes.substr(1, importPathWithQuotes.length - 2);
}
else if (helper.isDynamicImport(node)) {
const importPathWithQuotes = node.arguments[0].getText(sf);
importPath = importPathWithQuotes.substr(1, importPathWithQuotes.length - 2);
}
else if (ts.isImportTypeNode(node) &&
ts.isLiteralTypeNode(node.argument) &&
ts.isStringLiteral(node.argument.literal)) {
importPath = node.argument.literal.text;
}
if (importPath && opts.rootDir && opts.outDir && opts.resolvers?.length) {
log(`Rewriting path "${importPath}"`);
if (importPath[0] === '/' || importPath[0] === '\\') {
throw new Error("Please don't use absolute file-system paths. They may only work on your local machine.");
}
let resolvedFile = null;
if (importPath[0] !== '.') {
log(`Resolving bare specifiers "${importPath}"`);
const { rootDir, outDir, resolvers } = opts;
const destFile = helper.getDestFile(sf, rootDir, outDir);
const destDir = path.dirname(destFile);
for (const resolver of resolvers) {
if (resolver.filter) {
log(`Got filter "${resolver.filter}"`);
if (!new RegExp(resolver.filter, 'i').test(importPath)) {
log('Filter testing failed. Skipping this resolver');
continue;
}
}
const { mode } = resolver;
if (mode) {
log(`Got mode "${mode}"`);
switch (mode) {
case 'addExt': {
resolvedFile = helper.jsPath(importPath);
log(`Import "${importPath}" resolved to "${resolvedFile}"`);
log(`✅ Updated import from "${importPath}" to "${resolvedFile}"`);
importPath = resolvedFile;
continue;
}
default: {
throw new Error(`Unknown mode "${mode}"`);
}
}
}
const resolveAsCommonJSFunc = () => (resolvedFile = rsv.resolveCJSImport(resolver.dir, importPath, !!resolver.sourceDir, logger));
if (resolver.sourceDir) {
log('`sourceDir` is true');
resolveAsCommonJSFunc();
}
else {
log('`sourceDir` is false');
const moduleName = helper.getModuleNameFromImport(importPath);
const modulePath = path.join(resolver.dir, moduleName);
const packagePath = path.join(modulePath, 'package.json');
if (helper.fileExists(packagePath)) {
log(`"${packagePath}" exists`);
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
if (typeof pkg !== 'object') {
throw new Error(`Fatal error: package.json at "${packagePath}" is not a valid object`);
}
const isESM = pkg.type === 'module';
log(`"${packagePath}" is ESM? ${isESM}`);
if (isESM) {
resolvedFile = rsv.resolveInESModule(resolver.dir, importPath, modulePath, packagePath, pkg, logger);
}
else {
resolvedFile = rsv.resolveInCJSModule(resolver.dir, importPath, modulePath, packagePath, pkg, logger);
}
}
else {
log(`"${packagePath}" doesn't exist`);
resolveAsCommonJSFunc();
}
}
log(`Resolver done with result: "${resolvedFile}"`);
if (resolvedFile) {
const getDestImport = resolver.sourceDir
? (s) => helper.getDestImportFromProjectTS(destDir, s, rootDir, outDir)
: (s) => helper.getDestImportFromExternalJS(destDir, s);
const newImportPath = getDestImport(resolvedFile);
log(`✅ Updated import from "${importPath}" to "${newImportPath}"`);
importPath = newImportPath;
break;
}
}
}
else {
resolvedFile = helper.jsPath(importPath);
log(`Relative path "${importPath}" resolved to "${resolvedFile}"`);
log(`✅ Updated import from "${importPath}" to "${resolvedFile}"`);
importPath = resolvedFile;
}
if (resolvedFile) {
importPath = importPath.replace(/\\/g, '/');
if (ts.isImportDeclaration(node)) {
return ctx.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ctx.factory.createStringLiteral(importPath, true), node.assertClause);
}
else if (ts.isExportDeclaration(node)) {
return ctx.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, ctx.factory.createStringLiteral(importPath, true), node.assertClause);
}
else if (helper.isDynamicImport(node)) {
return ctx.factory.updateCallExpression(node, node.expression, node.typeArguments, ctx.factory.createNodeArray([
ctx.factory.createStringLiteral(importPath, true),
]));
}
else if (ts.isImportTypeNode(node)) {
return ctx.factory.updateImportTypeNode(node, ctx.factory.createLiteralTypeNode(ctx.factory.createStringLiteral(importPath, true)), node.attributes, node.qualifier, node.typeArguments, node.isTypeOf);
}
}
return node;
}
return ts.visitEachChild(node, visitor, ctx);
};
return visitor;
}
function transform(opts) {
if (!opts.rootDir) {
throw new Error('Missing required argument `rootDir`');
}
if (!opts.outDir) {
throw new Error('Missing required argument `outDir`');
}
opts.rootDir = helper.pathMustExist(path.resolve(opts.rootDir));
opts.outDir = path.resolve(opts.outDir);
opts.resolvers ?? (opts.resolvers = []);
for (const r of opts.resolvers) {
r.dir = helper.pathMustExist(path.resolve(r.dir));
}
if (!opts.resolvers.length) {
console.warn('WARNING: No resolvers defined');
}
if (opts.debug) {
console.log(`🚄 ts-transform-esm-import arguments:\nrootDir: ${opts.rootDir}\noutDir: ${opts.outDir}\nresolvers: ${JSON.stringify(opts.resolvers)}`);
}
return (ctx) => (sf) => ts.visitNode(sf, importExportVisitor(ctx, sf, opts));
}
exports.default = transform;
//# sourceMappingURL=main.js.map