UNPKG

ts-transform-esm-import

Version:

Rewrite TypeScript import paths to ES Modules import paths

198 lines 9.9 kB
"use strict"; 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