UNPKG

ts-add-js-extension

Version:

Add .js extension to each relative ESM import and export statement in JavaScript file

235 lines 8.85 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var fs_1 = __importDefault(require("fs")); var path_1 = __importDefault(require("path")); var typescript_1 = __importDefault(require("typescript")); var const_1 = require("./const"); var type_1 = require("./type"); var formProperFilePath = function (props) { return props.filePath.split(const_1.separator).filter(Boolean).join(const_1.separator); }; var checkJavaScriptFileExistByAppend = function (props) { var result = const_1.extensions.javaScript .map(function (extension) { return { extension: extension, filePath: "".concat(props.filePath).concat(extension), }; }) .find(function (filePath) { return fs_1.default.existsSync(filePath.filePath); }); return result !== null && result !== void 0 ? result : false; }; var checkTypeDefinitionFileExistByAppend = function (props) { var _a = const_1.extensions.javaScript, js = _a[0], mjs = _a[1]; var _b = const_1.extensions.typeDefinition, dts = _b[0], mdts = _b[1]; var dtsFilePath = "".concat(props.filePath).concat(dts); if (fs_1.default.existsSync(dtsFilePath)) { return { extension: js, filePath: dtsFilePath }; } var mdtsFilePath = "".concat(props.filePath).concat(mdts); if (fs_1.default.existsSync(mdtsFilePath)) { return { extension: mjs, filePath: mdtsFilePath }; } return false; }; var isDirectory = function (path) { return fs_1.default.existsSync(path) && fs_1.default.lstatSync(path).isDirectory(); }; var addJSExtensionConditionally = function (props) { var check = props.checkType === 'js' ? checkJavaScriptFileExistByAppend : checkTypeDefinitionFileExistByAppend; var skip = { procedure: 'skip', }; if (isDirectory(props.filePath)) { var result_1 = check({ filePath: path_1.default.posix.join(props.filePath, 'index'), }); if (!result_1) { return skip; } var file = "index".concat(result_1.extension); return { procedure: 'proceed', absolutePath: result_1.filePath, importPath: formProperFilePath({ filePath: "".concat(props.importPath).concat(const_1.separator).concat(file), }), }; } var result = check({ filePath: props.filePath, }); if (!result) { return skip; } return { procedure: 'proceed', absolutePath: result.filePath, importPath: formProperFilePath({ filePath: "".concat(props.importPath).concat(result.extension), }), }; }; var addJSExtension = function (props) { if ((0, const_1.matchJs)(props.filePath)) { return { procedure: 'skip', }; } var result = addJSExtensionConditionally(__assign(__assign({}, props), { checkType: 'js' })); switch (result.procedure) { case 'proceed': { return result; } case 'skip': { return addJSExtensionConditionally(__assign(__assign({}, props), { checkType: 'dts' })); } } }; var generateModuleSpecifier = function (props) { if (!props.moduleSpecifier.startsWith('.')) { return undefined; } var result = addJSExtension({ importPath: props.moduleSpecifier, filePath: path_1.default.posix.join(props.file, '..', props.moduleSpecifier), }); switch (result.procedure) { case 'proceed': { if (props.files.find(function (file) { return file.endsWith(result.absolutePath); })) { return result.importPath; } } } return undefined; }; var nodeIsStringLiteral = function (node) { return (typescript_1.default.isStringLiteral(node) || typescript_1.default.isNoSubstitutionTemplateLiteral(node)); }; var dynamicJsImport = function (props) { var node = props.node; if (node.expression.kind === typescript_1.default.SyntaxKind.ImportKeyword) { var argument = (0, type_1.guard)({ value: node.arguments[0], error: new Error("Dynamic import must have a path"), }); if (nodeIsStringLiteral(argument)) { var text = generateModuleSpecifier(__assign(__assign({}, props.fileInfo), { moduleSpecifier: argument.text })); if (!text) { return node; } props.fileInfo.updateFile(); return props.factory.updateCallExpression(node, node.expression, node.typeArguments, [props.factory.createStringLiteral(text)]); } } return node; }; var dynamicDtsImport = function (props) { var node = props.node; var argument = node.argument; if (typescript_1.default.isLiteralTypeNode(argument)) { var literal = argument.literal; if (nodeIsStringLiteral(literal)) { var text = generateModuleSpecifier(__assign(__assign({}, props.fileInfo), { moduleSpecifier: literal.text })); if (!text) { return node; } props.fileInfo.updateFile(); return props.factory.updateImportTypeNode(node, props.factory.updateLiteralTypeNode(argument, props.factory.createStringLiteral(text)), node.attributes, node.qualifier, node.typeArguments, node.isTypeOf); } } return node; }; var staticImportExport = function (props) { var node = props.node; var moduleSpecifier = node.moduleSpecifier; if (!moduleSpecifier || !typescript_1.default.isStringLiteral(moduleSpecifier)) { return node; } var text = generateModuleSpecifier(__assign(__assign({}, props.fileInfo), { moduleSpecifier: moduleSpecifier.text })); if (!text) { return node; } props.fileInfo.updateFile(); if (typescript_1.default.isImportDeclaration(node)) { return props.factory.updateImportDeclaration(node, node.modifiers, node.importClause, props.factory.createStringLiteral(text), node.attributes); } return props.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, props.factory.createStringLiteral(text), node.attributes); }; var updateImportExport = function (props) { return function (parent) { var node = typescript_1.default.visitEachChild(parent, updateImportExport(props), props.context); var parameters = { fileInfo: props.fileInfo, factory: props.context.factory, }; if (typescript_1.default.isImportDeclaration(node) || typescript_1.default.isExportDeclaration(node)) { return staticImportExport(__assign(__assign({}, parameters), { node: node })); } else if (typescript_1.default.isCallExpression(node)) { return dynamicJsImport(__assign(__assign({}, parameters), { node: node })); } else if (typescript_1.default.isImportTypeNode(node)) { return dynamicDtsImport(__assign(__assign({}, parameters), { node: node })); } return node; }; }; var traverse = function (props) { return function (context) { return function (rootNode) { return typescript_1.default.visitNode(rootNode, updateImportExport(__assign(__assign({}, props), { context: context }))); }; }; }; var traverseAndUpdateFile = function (metainfo) { var printer = typescript_1.default.createPrinter(); var fileUpdated = false; var file = metainfo.sourceFile.fileName; var transformer = traverse({ fileInfo: { files: metainfo.files, file: file, updateFile: function () { fileUpdated = true; }, }, }); var code = printer.printNode(typescript_1.default.EmitHint.Unspecified, (0, type_1.guard)({ value: typescript_1.default .transform(metainfo.sourceFile, [transformer]) .transformed.at(0), error: new Error('Transformer should have a transformed value'), }), metainfo.sourceFile); if (!fileUpdated) { return []; } return [ { file: file, code: code, }, ]; }; exports.default = traverseAndUpdateFile; //# sourceMappingURL=traverse-and-update.js.map