diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..cd47115 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,41 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "deno run", + "request": "launch", + "type": "node", + "runtimeExecutable": "deno", + "cwd": "${workspaceFolder}", + "program": "${file}", + "runtimeArgs": [ + "run", + "--inspect-wait", + "--allow-all" + ], + "env": {}, + "attachSimplePort": 9229, + "experimentalNetworking": "off" + }, + { + "name": "deno test", + "request": "launch", + "type": "node", + "runtimeExecutable": "deno", + "cwd": "${workspaceFolder}", + "program": "${file}", + "runtimeArgs": [ + "test", + "--inspect-wait", + "--allow-all", + "--no-check" + ], + "env": {}, + "attachSimplePort": 9229, + "experimentalNetworking": "off" + } + ] +} diff --git a/index.ts b/index.ts index 8555622..ae35c4f 100644 --- a/index.ts +++ b/index.ts @@ -320,24 +320,51 @@ const visitor = (node: ts.Node) => { }; const visitExportDeclaration = (node: ts.ExportDeclaration) => { + let skipAll: boolean = false; + if (node.isTypeOnly) { + skipAll = true; strip.push({ start: node.pos, end: node.end }); } else if (node.exportClause && ts.isNamedExports(node.exportClause)) { const exportsToSkip = node.exportClause.elements.map(visitExportSpecifier) .filter(isNotUndefined); if (exportsToSkip?.length === node.exportClause.elements.length) { - // skip the whole import declaration + skipAll = true; strip.push({ start: node.pos, end: node.end }); } else { - for (let i = 0; i < exportsToSkip.length; i++) { - strip.push(exportsToSkip[i]); - } + strip.push(...exportsToSkip); } } const moduleSpecifier = node.moduleSpecifier; - if (pathRewriting && moduleSpecifier) { - if (ts.isStringLiteral(moduleSpecifier)) { + + if ( + moduleSpecifier && ts.isStringLiteral(moduleSpecifier) && + (!node.exportClause || skipAll === false) + ) { + if (imports) { + const match = imports.find(([alias]) => + moduleSpecifier.text.startsWith(alias) + ); + + if (match) { + let replacement = match[1]; + + // relative path: non absolute path that's not an @alias + if (!isAbsolute(replacement) && replacement.startsWith(".")) { + replacement = relative(dirname(filePath), replacement) + + (replacement.endsWith("/") ? "/" : ""); + } + + transformSpecifiers.push({ + pos: moduleSpecifier.pos, + alias: new RegExp("(['\"])" + RegExp.escape(match[0])), + replacement, + }); + } + } + + if (pathRewriting) { sourceCode = sourceCode.slice(0, moduleSpecifier.pos) + ` "${moduleSpecifier.text.replace(/\.ts$/, ".js")}"` + sourceCode.slice(moduleSpecifier.end); @@ -416,9 +443,7 @@ const visitImportClause = (node: ts.ImportClause) => { if (importsToSkip?.length === node.namedBindings?.elements.length) { return true; // skip the whole import declaration } else { - for (let i = 0; i < importsToSkip.length; i++) { - strip.push(importsToSkip[i]); - } + strip.push(...importsToSkip); } } }; diff --git a/tests/supported/cases/option-imports/input.ts b/tests/supported/cases/option-imports/input.ts index 3292037..63222f6 100644 --- a/tests/supported/cases/option-imports/input.ts +++ b/tests/supported/cases/option-imports/input.ts @@ -2,4 +2,8 @@ import a from "$foo/bar.ts"; import type A from "$foo/bar.d.ts"; import { b } from "$fiz/bar.ts"; import { type B } from "$foo/bar.d.ts"; -import { c, type C } from "$baz/bar"; \ No newline at end of file +import { c, type C } from "$baz/bar"; + +export { b } from "$fiz/bar.ts"; +export { type B } from "$foo/bar.d.ts"; +export { c, type C } from "$baz/bar"; \ No newline at end of file diff --git a/tests/supported/cases/option-imports/output.js b/tests/supported/cases/option-imports/output.js index aa8bbdc..12eaddc 100644 --- a/tests/supported/cases/option-imports/output.js +++ b/tests/supported/cases/option-imports/output.js @@ -1,3 +1,6 @@ import a from "../foo/bar.js"; import { b } from "../fiz/bar.js"; -import { c, } from "@baz/bar"; \ No newline at end of file +import { c,} from "@baz/bar"; + +export { b } from "../fiz/bar.js"; +export { c, } from "@baz/bar"; \ No newline at end of file diff --git a/tests/supported/suite.test.ts b/tests/supported/suite.test.ts index 278b38f..7e82910 100644 --- a/tests/supported/suite.test.ts +++ b/tests/supported/suite.test.ts @@ -1,7 +1,7 @@ import { assertEquals } from "@std/assert"; import { walk } from "@std/fs"; import { basename, join } from "@std/path"; -import TypeStrip, { type TypeStripOptions } from "../../index.ts"; +import stripTypes, { type TypeStripOptions } from "../../index.ts"; const only = [/.*/]; const skip = undefined; @@ -33,7 +33,7 @@ for await ( ? (await import(optionsEntry.path)).options : { removeComments: false, pathRewriting: false }; - const stripped = TypeStrip(inputCode, options); + const stripped = stripTypes(inputCode, options); Deno.test(`handles ${testCase}`, () => { assertEquals(stripped, outputCode);