diff --git a/modules/index.d.ts b/modules/index.d.ts index 0fedae8..3244fab 100644 --- a/modules/index.d.ts +++ b/modules/index.d.ts @@ -33,5 +33,6 @@ export { __createBinding, __addDisposableResource, __disposeResources, + __rewriteRelativeImportExtension, } from '../tslib.js'; export * as default from '../tslib.js'; diff --git a/modules/index.js b/modules/index.js index af9f5ac..c91f618 100644 --- a/modules/index.js +++ b/modules/index.js @@ -31,6 +31,7 @@ const { __classPrivateFieldIn, __addDisposableResource, __disposeResources, + __rewriteRelativeImportExtension, } = tslib; export { __extends, @@ -64,5 +65,6 @@ export { __classPrivateFieldIn, __addDisposableResource, __disposeResources, + __rewriteRelativeImportExtension, }; export default tslib; diff --git a/test/node/rewriteRelativeImportExtension.test.js b/test/node/rewriteRelativeImportExtension.test.js new file mode 100644 index 0000000..6eb83d5 --- /dev/null +++ b/test/node/rewriteRelativeImportExtension.test.js @@ -0,0 +1,57 @@ +import assert from "node:assert"; +import { test } from "node:test"; +import { testHelper } from "./testHelper.js"; + +testHelper("__rewriteRelativeImportExtension", __rewriteRelativeImportExtension => { + test("rewrites relative .ts to .js", () => { + assert.equal(__rewriteRelativeImportExtension("./foo.ts"), "./foo.js"); + assert.equal(__rewriteRelativeImportExtension("../foo.ts"), "../foo.js"); + assert.equal(__rewriteRelativeImportExtension("../../foo.ts"), "../../foo.js"); + assert.equal(__rewriteRelativeImportExtension("./foo.TS"), "./foo.js"); + assert.equal(__rewriteRelativeImportExtension("./foo.Ts"), "./foo.js"); + assert.equal(__rewriteRelativeImportExtension("./foo/.hidden/foo.ts"), "./foo/.hidden/foo.js"); + }); + + test("rewrites other TypeScript extensions", () => { + assert.equal(__rewriteRelativeImportExtension("./foo.mts"), "./foo.mjs"); + assert.equal(__rewriteRelativeImportExtension("./foo.cts"), "./foo.cjs"); + assert.equal(__rewriteRelativeImportExtension("./foo.tsx"), "./foo.js"); + assert.equal(__rewriteRelativeImportExtension("./foo.tsx", true), "./foo.jsx"); + assert.equal(__rewriteRelativeImportExtension("./foo.Tsx", true), "./foo.jsx"); + assert.equal(__rewriteRelativeImportExtension("./foo.d.css.mts"), "./foo.d.css.mjs"); + assert.equal(__rewriteRelativeImportExtension("./foo.d.tsx"), "./foo.d.js"); + }); + + test("does not rewrite other extensions", () => { + assert.equal(__rewriteRelativeImportExtension("./foo.js"), "./foo.js"); + assert.equal(__rewriteRelativeImportExtension("./foo.mjs"), "./foo.mjs"); + assert.equal(__rewriteRelativeImportExtension("./foo.cjs"), "./foo.cjs"); + assert.equal(__rewriteRelativeImportExtension("./foo.jsx"), "./foo.jsx"); + assert.equal(__rewriteRelativeImportExtension("./foo.json"), "./foo.json"); + assert.equal(__rewriteRelativeImportExtension("./foo.css"), "./foo.css"); + assert.equal(__rewriteRelativeImportExtension("./foo"), "./foo"); + assert.equal(__rewriteRelativeImportExtension("./foo.d.php?q=1.ts"), "./foo.d.php?q=1.ts"); + }); + + test("does not rewrite non-relative imports", () => { + assert.equal(__rewriteRelativeImportExtension("foo.ts"), "foo.ts"); + assert.equal(__rewriteRelativeImportExtension("foo.mts"), "foo.mts"); + assert.equal(__rewriteRelativeImportExtension("foo.cts"), "foo.cts"); + assert.equal(__rewriteRelativeImportExtension("foo.tsx"), "foo.tsx"); + assert.equal(__rewriteRelativeImportExtension("foo.js"), "foo.js"); + assert.equal(__rewriteRelativeImportExtension("foo.mjs"), "foo.mjs"); + assert.equal(__rewriteRelativeImportExtension("foo.cjs"), "foo.cjs"); + assert.equal(__rewriteRelativeImportExtension("foo.jsx"), "foo.jsx"); + assert.equal(__rewriteRelativeImportExtension("foo.json"), "foo.json"); + assert.equal(__rewriteRelativeImportExtension("foo.css"), "foo.css"); + assert.equal(__rewriteRelativeImportExtension("foo"), "foo"); + }); + + test("does not rewrite declaration file extensions", () => { + assert.equal(__rewriteRelativeImportExtension("./foo.d.ts"), "./foo.d.ts"); + assert.equal(__rewriteRelativeImportExtension("./foo.d.mts"), "./foo.d.mts"); + assert.equal(__rewriteRelativeImportExtension("./foo.d.cts"), "./foo.d.cts"); + assert.equal(__rewriteRelativeImportExtension("./foo.d.css.ts"), "./foo.d.css.ts"); + assert.equal(__rewriteRelativeImportExtension("./foo.D.ts"), "./foo.D.ts"); + }); +}); diff --git a/tslib.d.ts b/tslib.d.ts index 4576221..f23df55 100644 --- a/tslib.d.ts +++ b/tslib.d.ts @@ -451,3 +451,10 @@ export declare function __addDisposableResource(env: { stack: { value?: unkno * @seealso {@link __addDisposableResource} */ export declare function __disposeResources(env: { stack: { value?: unknown, dispose?: Function, async: boolean }[]; error: unknown; hasError: boolean; }): any; + +/** + * Transforms a relative import specifier ending in a non-declaration TypeScript file extension to its JavaScript file extension counterpart. + * @param path The import specifier. + * @param preserveJsx Causes '*.tsx' to transform to '*.jsx' instead of '*.js'. Should be true when `--jsx` is set to `preserve`. + */ +export declare function __rewriteRelativeImportExtension(path: string, preserveJsx?: boolean): string; \ No newline at end of file diff --git a/tslib.es6.js b/tslib.es6.js index 9365006..ddd87f6 100644 --- a/tslib.es6.js +++ b/tslib.es6.js @@ -348,6 +348,15 @@ export function __disposeResources(env) { return next(); } +export function __rewriteRelativeImportExtension(path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; +} + export default { __extends: __extends, __assign: __assign, @@ -380,4 +389,5 @@ export default { __classPrivateFieldIn: __classPrivateFieldIn, __addDisposableResource: __addDisposableResource, __disposeResources: __disposeResources, + __rewriteRelativeImportExtension: __rewriteRelativeImportExtension, }; diff --git a/tslib.es6.mjs b/tslib.es6.mjs index e669963..a1d9ef5 100644 --- a/tslib.es6.mjs +++ b/tslib.es6.mjs @@ -347,6 +347,15 @@ export function __disposeResources(env) { return next(); } +export function __rewriteRelativeImportExtension(path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; +} + export default { __extends, __assign, @@ -379,4 +388,5 @@ export default { __classPrivateFieldIn, __addDisposableResource, __disposeResources, + __rewriteRelativeImportExtension, }; diff --git a/tslib.js b/tslib.js index e53dd2f..95beb91 100644 --- a/tslib.js +++ b/tslib.js @@ -44,6 +44,7 @@ var __classPrivateFieldIn; var __createBinding; var __addDisposableResource; var __disposeResources; +var __rewriteRelativeImportExtension; (function (factory) { var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; if (typeof define === "function" && define.amd) { @@ -395,6 +396,15 @@ var __disposeResources; return next(); }; + __rewriteRelativeImportExtension = function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; + }; + exporter("__extends", __extends); exporter("__assign", __assign); exporter("__rest", __rest); @@ -426,6 +436,7 @@ var __disposeResources; exporter("__classPrivateFieldIn", __classPrivateFieldIn); exporter("__addDisposableResource", __addDisposableResource); exporter("__disposeResources", __disposeResources); + exporter("__rewriteRelativeImportExtension", __rewriteRelativeImportExtension); }); 0 && (module.exports = { @@ -460,4 +471,5 @@ var __disposeResources; __classPrivateFieldIn, __addDisposableResource, __disposeResources, + __rewriteRelativeImportExtension, });