diff --git a/lib/rules/file-extension-in-import.js b/lib/rules/file-extension-in-import.js index 529433aa..ce63f2aa 100644 --- a/lib/rules/file-extension-in-import.js +++ b/lib/rules/file-extension-in-import.js @@ -10,6 +10,11 @@ const getTryExtensions = require("../util/get-try-extensions") const visitImport = require("../util/visit-import") const packageNamePattern = /^(?:@[^/\\]+[/\\])?[^/\\]+$/u const corePackageOverridePattern = /^(?:assert|async_hooks|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|http2|https|inspector|module|net|os|path|perf_hooks|process|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|trace_events|tty|url|util|v8|vm|worker_threads|zlib)[/\\]$/u +const typescriptFileExtensionsMapping = { + ".ts": ".js", + ".cts": ".cjs", + ".mts": ".mjs", +} /** * Get all file extensions of the files which have the same basename. @@ -31,6 +36,27 @@ function getExistingExtensions(filePath) { } } +/** + * Get the file extension that should be added in an import statement, + * based on the given file extension of the referenced file. + * + * For example, in typescript, when referencing another typescript from a typescript file, + * a .js extension should be used instead of the original .ts extension of the referenced file. + * @param {string} referencedFileExt The original file extension of the referenced file. + * @param {string} referencingFileExt The original file extension of the file the contains the import statement. + * @returns {string} The file extension to append to the import statement. + */ +function getFileExtensionToAdd(referencedFileExt, referencingFileExt) { + if ( + referencingFileExt in typescriptFileExtensionsMapping && + referencedFileExt in typescriptFileExtensionsMapping + ) { + return typescriptFileExtensionsMapping[referencedFileExt] + } + + return referencedFileExt +} + module.exports = { meta: { docs: { @@ -92,16 +118,26 @@ module.exports = { // Verify. if (style === "always" && ext !== originalExt) { + const referencingFileExt = path.extname( + context.getPhysicalFilename() + ) + const fileExtensionToAdd = getFileExtensionToAdd( + ext, + referencingFileExt + ) context.report({ node, messageId: "requireExt", - data: { ext }, + data: { ext: fileExtensionToAdd }, fix(fixer) { if (existingExts.length !== 1) { return null } const index = node.range[1] - 1 - return fixer.insertTextBeforeRange([index, index], ext) + return fixer.insertTextBeforeRange( + [index, index], + fileExtensionToAdd + ) }, }) } else if (style === "never" && ext === originalExt) {