@line/ts-remove-unused
Advanced tools
Comparing version 0.9.0 to 0.10.0
276
dist/cli.js
@@ -411,12 +411,4 @@ #!/usr/bin/env node | ||
// lib/util/memoize.ts | ||
import { parentPort } from "node:worker_threads"; | ||
var memoize = (fn2, { key, name }) => { | ||
var memoize = (fn2, { key }) => { | ||
const cache = /* @__PURE__ */ new Map(); | ||
if (parentPort) { | ||
parentPort.on("message", (message) => { | ||
if ("broadcast" in message && message.broadcast.name === name) { | ||
cache.set(message.broadcast.key, message.broadcast.value); | ||
} | ||
}); | ||
} | ||
return (...args) => { | ||
@@ -429,11 +421,2 @@ const k = key(...args); | ||
cache.set(k, result); | ||
if (parentPort) { | ||
parentPort.postMessage({ | ||
broadcast: { | ||
name, | ||
key: k, | ||
value: result | ||
} | ||
}); | ||
} | ||
return result; | ||
@@ -550,3 +533,3 @@ }; | ||
} | ||
if (ts3.isFunctionDeclaration(node) || ts3.isInterfaceDeclaration(node) || ts3.isClassDeclaration(node)) { | ||
if (ts3.isFunctionDeclaration(node) || ts3.isInterfaceDeclaration(node) || ts3.isClassDeclaration(node) || ts3.isEnumDeclaration(node)) { | ||
const isExported = node.modifiers?.some( | ||
@@ -748,4 +731,3 @@ (m) => m.kind === ts3.SyntaxKind.ExportKeyword | ||
options: arg.options | ||
}), | ||
name: "parseFile" | ||
}) | ||
}); | ||
@@ -901,33 +883,56 @@ | ||
// lib/util/edit.ts | ||
var stripExportKeyword = (syntaxList) => { | ||
const file = ts6.createSourceFile( | ||
"tmp.ts", | ||
var transform = (source, transformer) => { | ||
const file = ts6.createSourceFile("file.ts", source, ts6.ScriptTarget.Latest); | ||
const result = ts6.transform(file, [transformer]).transformed[0]; | ||
const printer = ts6.createPrinter(); | ||
return result ? printer.printFile(result).trim() : ""; | ||
}; | ||
var stripFunctionExportKeyword = (syntaxList) => { | ||
const code = transform( | ||
`${syntaxList} function f() {}`, | ||
ts6.ScriptTarget.Latest | ||
(context) => (rootNode) => { | ||
const visitor = (node) => { | ||
if (ts6.isFunctionDeclaration(node)) { | ||
return ts6.factory.createFunctionDeclaration( | ||
node.modifiers?.filter( | ||
(v) => v.kind !== ts6.SyntaxKind.ExportKeyword && v.kind !== ts6.SyntaxKind.DefaultKeyword | ||
), | ||
node.asteriskToken, | ||
node.name, | ||
node.typeParameters, | ||
node.parameters, | ||
node.type, | ||
node.body | ||
); | ||
} | ||
return ts6.visitEachChild(node, visitor, context); | ||
}; | ||
return ts6.visitEachChild(rootNode, visitor, context); | ||
} | ||
); | ||
const transformer = (context) => (rootNode) => { | ||
const visitor = (node) => { | ||
if (ts6.isFunctionDeclaration(node)) { | ||
return ts6.factory.createFunctionDeclaration( | ||
node.modifiers?.filter( | ||
(v) => v.kind !== ts6.SyntaxKind.ExportKeyword && v.kind !== ts6.SyntaxKind.DefaultKeyword | ||
), | ||
node.asteriskToken, | ||
node.name, | ||
node.typeParameters, | ||
node.parameters, | ||
node.type, | ||
node.body | ||
); | ||
} | ||
return ts6.visitEachChild(node, visitor, context); | ||
}; | ||
return ts6.visitEachChild(rootNode, visitor, context); | ||
}; | ||
const result = ts6.transform(file, [transformer]).transformed[0]; | ||
const printer = ts6.createPrinter(); | ||
const code = result ? printer.printFile(result).trim() : ""; | ||
const pos = code.indexOf("function"); | ||
return code.slice(0, pos); | ||
}; | ||
var stripEnumExportKeyword = (syntaxList) => { | ||
const code = transform( | ||
`${syntaxList} enum E {}`, | ||
(context) => (rootNode) => { | ||
const visitor = (node) => { | ||
if (ts6.isEnumDeclaration(node)) { | ||
return ts6.factory.createEnumDeclaration( | ||
node.modifiers?.filter( | ||
(v) => v.kind !== ts6.SyntaxKind.ExportKeyword | ||
), | ||
node.name, | ||
node.members | ||
); | ||
} | ||
return ts6.visitEachChild(node, visitor, context); | ||
}; | ||
return ts6.visitEachChild(rootNode, visitor, context); | ||
} | ||
); | ||
const pos = code.indexOf("enum"); | ||
return code.slice(0, pos); | ||
}; | ||
var disabledEditTracker = { | ||
@@ -1078,3 +1083,3 @@ start: () => { | ||
changes.push({ | ||
newText: item.change.isUnnamedDefaultExport ? "" : stripExportKeyword(item.change.code), | ||
newText: item.change.isUnnamedDefaultExport ? "" : stripFunctionExportKeyword(item.change.code), | ||
span: item.change.span | ||
@@ -1119,2 +1124,17 @@ }); | ||
} | ||
case ts6.SyntaxKind.EnumDeclaration: { | ||
if (item.skip || usage.has(item.name)) { | ||
break; | ||
} | ||
changes.push({ | ||
newText: stripEnumExportKeyword(item.change.code), | ||
span: item.change.span | ||
}); | ||
logs.push({ | ||
fileName: targetFile, | ||
position: item.start, | ||
code: item.name | ||
}); | ||
break; | ||
} | ||
case ts6.SyntaxKind.ExportAssignment: { | ||
@@ -1325,3 +1345,2 @@ if (item.skip || usage.has("default")) { | ||
projectRoot = ".", | ||
pool, | ||
recursive | ||
@@ -1351,4 +1370,3 @@ }) => { | ||
} | ||
const fn2 = pool ? pool.run.bind(pool) : processFile; | ||
const result = await fn2({ | ||
const result = processFile({ | ||
targetFile: c.file, | ||
@@ -1582,146 +1600,2 @@ vertexes: dependencyGraph.eject(), | ||
// lib/util/WorkerPool.ts | ||
import { Worker } from "node:worker_threads"; | ||
import * as os from "node:os"; | ||
var generateCode = (url, name) => `data:text/javascript,import { parentPort } from 'node:worker_threads'; | ||
import { ${name} } from '${url}'; | ||
parentPort.on('message', async (message) => { | ||
if (!('arg' in message)) { | ||
return; | ||
} | ||
try { | ||
const result = await ${name}(message.arg); | ||
parentPort.postMessage({ result }); | ||
} catch (error) { | ||
parentPort.postMessage({ error }); | ||
} | ||
}); | ||
`; | ||
var PromiseWorker = class extends Worker { | ||
current = null; | ||
constructor(url, name) { | ||
super(new URL(generateCode(url, name))); | ||
} | ||
}; | ||
var WorkerPool = class { | ||
#url; | ||
#name; | ||
#queue = []; | ||
#working = []; | ||
#idle = []; | ||
constructor({ url, name }) { | ||
this.#url = url; | ||
this.#name = name; | ||
const max = os.availableParallelism?.() ?? os.cpus().length - 1; | ||
for (let i = 0; i < max; i++) { | ||
this.#setup(); | ||
} | ||
} | ||
run(arg) { | ||
return new Promise((resolve3, reject) => { | ||
const worker = this.#idle.pop(); | ||
if (!worker) { | ||
this.#queue.push({ resolve: resolve3, reject, arg }); | ||
return; | ||
} | ||
worker.current = { | ||
resolve: resolve3, | ||
reject | ||
}; | ||
this.#working.push(worker); | ||
worker.postMessage({ arg }); | ||
}); | ||
} | ||
close() { | ||
if (this.#working.length > 0) { | ||
throw new Error("Cannot close while there are working workers"); | ||
} | ||
return Promise.all( | ||
this.#idle.map((worker) => { | ||
worker.removeAllListeners(); | ||
return worker.terminate(); | ||
}) | ||
); | ||
} | ||
#assignTask() { | ||
if (this.#queue.length === 0) { | ||
return; | ||
} | ||
const worker = this.#idle.pop(); | ||
if (!worker) { | ||
return; | ||
} | ||
const { resolve: resolve3, reject, arg } = this.#queue.shift(); | ||
worker.current = { | ||
resolve: resolve3, | ||
reject | ||
}; | ||
worker.postMessage({ arg }); | ||
this.#working.push(worker); | ||
} | ||
#free(worker) { | ||
worker.current = null; | ||
const index = this.#working.indexOf(worker); | ||
if (index === -1) { | ||
return; | ||
} | ||
this.#working.splice(index, 1); | ||
this.#idle.push(worker); | ||
} | ||
#setup() { | ||
const worker = new PromiseWorker(this.#url, this.#name); | ||
worker.on("message", (message) => { | ||
if (!worker.current) { | ||
return; | ||
} | ||
switch (true) { | ||
case "broadcast" in message: { | ||
[...this.#working, ...this.#idle].forEach( | ||
(w) => w !== worker && w.postMessage(message) | ||
); | ||
return; | ||
} | ||
case "error" in message: { | ||
worker.current.reject(message.error); | ||
this.#free(worker); | ||
this.#assignTask(); | ||
return; | ||
} | ||
case "result" in message: { | ||
worker.current.resolve(message.result); | ||
this.#free(worker); | ||
this.#assignTask(); | ||
return; | ||
} | ||
} | ||
}); | ||
worker.on("error", (error) => { | ||
if (!worker.current) { | ||
return; | ||
} | ||
worker.current.reject(error); | ||
this.#free(worker); | ||
this.#assignTask(); | ||
}); | ||
worker.on("exit", (code) => { | ||
if (code === 0) { | ||
return; | ||
} | ||
if (worker.current) { | ||
worker.current.reject( | ||
new Error(`Worker stopped with exit code ${code}`) | ||
); | ||
this.#free(worker); | ||
worker.terminate(); | ||
this.#setup(); | ||
return; | ||
} | ||
worker.terminate(); | ||
this.#setup(); | ||
}); | ||
this.#idle.push(worker); | ||
} | ||
}; | ||
// lib/util/regex.ts | ||
@@ -1792,6 +1666,2 @@ var dts = /\.d\.ts$/; | ||
); | ||
const pool = new WorkerPool({ | ||
name: "processFile", | ||
url: globalThis.__INTERNAL_WORKER_URL__ || new URL("./worker.js", import.meta.url).href | ||
}); | ||
await edit({ | ||
@@ -1801,7 +1671,6 @@ fileService, | ||
deleteUnusedFile: true, | ||
enableCodeFix: true, | ||
enableCodeFix: mode === "write" || recursive, | ||
editTracker, | ||
options, | ||
projectRoot, | ||
pool, | ||
recursive | ||
@@ -1826,3 +1695,2 @@ }); | ||
editTracker.logResult(); | ||
await pool.close(); | ||
if (mode === "check" && !editTracker.isClean) { | ||
@@ -1838,3 +1706,3 @@ system.exit(1); | ||
var cli = cac("ts-remove-unused"); | ||
cli.command("", "There are no subcommands. Simply execute ts-remove-unused").option("--project <file>", "Path to your tsconfig.json").option( | ||
cli.command("", "There are no subcommands. Simply execute ts-remove-unused").option("-p, --project <file>", "Path to your tsconfig.json").option( | ||
"--skip <regexp_pattern>", | ||
@@ -1859,3 +1727,3 @@ "Specify the regexp pattern to match files that should be skipped from transforming" | ||
projectRoot: cwd2(), | ||
recursive: !!options.experimentalRecursive | ||
recursive: !!options.recursive | ||
}); | ||
@@ -1862,0 +1730,0 @@ }); |
272
dist/main.js
@@ -406,12 +406,4 @@ // lib/remove.ts | ||
// lib/util/memoize.ts | ||
import { parentPort } from "node:worker_threads"; | ||
var memoize = (fn2, { key, name }) => { | ||
var memoize = (fn2, { key }) => { | ||
const cache = /* @__PURE__ */ new Map(); | ||
if (parentPort) { | ||
parentPort.on("message", (message) => { | ||
if ("broadcast" in message && message.broadcast.name === name) { | ||
cache.set(message.broadcast.key, message.broadcast.value); | ||
} | ||
}); | ||
} | ||
return (...args) => { | ||
@@ -424,11 +416,2 @@ const k = key(...args); | ||
cache.set(k, result); | ||
if (parentPort) { | ||
parentPort.postMessage({ | ||
broadcast: { | ||
name, | ||
key: k, | ||
value: result | ||
} | ||
}); | ||
} | ||
return result; | ||
@@ -545,3 +528,3 @@ }; | ||
} | ||
if (ts3.isFunctionDeclaration(node) || ts3.isInterfaceDeclaration(node) || ts3.isClassDeclaration(node)) { | ||
if (ts3.isFunctionDeclaration(node) || ts3.isInterfaceDeclaration(node) || ts3.isClassDeclaration(node) || ts3.isEnumDeclaration(node)) { | ||
const isExported = node.modifiers?.some( | ||
@@ -743,4 +726,3 @@ (m) => m.kind === ts3.SyntaxKind.ExportKeyword | ||
options: arg.options | ||
}), | ||
name: "parseFile" | ||
}) | ||
}); | ||
@@ -896,33 +878,56 @@ | ||
// lib/util/edit.ts | ||
var stripExportKeyword = (syntaxList) => { | ||
const file = ts6.createSourceFile( | ||
"tmp.ts", | ||
var transform = (source, transformer) => { | ||
const file = ts6.createSourceFile("file.ts", source, ts6.ScriptTarget.Latest); | ||
const result = ts6.transform(file, [transformer]).transformed[0]; | ||
const printer = ts6.createPrinter(); | ||
return result ? printer.printFile(result).trim() : ""; | ||
}; | ||
var stripFunctionExportKeyword = (syntaxList) => { | ||
const code = transform( | ||
`${syntaxList} function f() {}`, | ||
ts6.ScriptTarget.Latest | ||
(context) => (rootNode) => { | ||
const visitor = (node) => { | ||
if (ts6.isFunctionDeclaration(node)) { | ||
return ts6.factory.createFunctionDeclaration( | ||
node.modifiers?.filter( | ||
(v) => v.kind !== ts6.SyntaxKind.ExportKeyword && v.kind !== ts6.SyntaxKind.DefaultKeyword | ||
), | ||
node.asteriskToken, | ||
node.name, | ||
node.typeParameters, | ||
node.parameters, | ||
node.type, | ||
node.body | ||
); | ||
} | ||
return ts6.visitEachChild(node, visitor, context); | ||
}; | ||
return ts6.visitEachChild(rootNode, visitor, context); | ||
} | ||
); | ||
const transformer = (context) => (rootNode) => { | ||
const visitor = (node) => { | ||
if (ts6.isFunctionDeclaration(node)) { | ||
return ts6.factory.createFunctionDeclaration( | ||
node.modifiers?.filter( | ||
(v) => v.kind !== ts6.SyntaxKind.ExportKeyword && v.kind !== ts6.SyntaxKind.DefaultKeyword | ||
), | ||
node.asteriskToken, | ||
node.name, | ||
node.typeParameters, | ||
node.parameters, | ||
node.type, | ||
node.body | ||
); | ||
} | ||
return ts6.visitEachChild(node, visitor, context); | ||
}; | ||
return ts6.visitEachChild(rootNode, visitor, context); | ||
}; | ||
const result = ts6.transform(file, [transformer]).transformed[0]; | ||
const printer = ts6.createPrinter(); | ||
const code = result ? printer.printFile(result).trim() : ""; | ||
const pos = code.indexOf("function"); | ||
return code.slice(0, pos); | ||
}; | ||
var stripEnumExportKeyword = (syntaxList) => { | ||
const code = transform( | ||
`${syntaxList} enum E {}`, | ||
(context) => (rootNode) => { | ||
const visitor = (node) => { | ||
if (ts6.isEnumDeclaration(node)) { | ||
return ts6.factory.createEnumDeclaration( | ||
node.modifiers?.filter( | ||
(v) => v.kind !== ts6.SyntaxKind.ExportKeyword | ||
), | ||
node.name, | ||
node.members | ||
); | ||
} | ||
return ts6.visitEachChild(node, visitor, context); | ||
}; | ||
return ts6.visitEachChild(rootNode, visitor, context); | ||
} | ||
); | ||
const pos = code.indexOf("enum"); | ||
return code.slice(0, pos); | ||
}; | ||
var disabledEditTracker = { | ||
@@ -1073,3 +1078,3 @@ start: () => { | ||
changes.push({ | ||
newText: item.change.isUnnamedDefaultExport ? "" : stripExportKeyword(item.change.code), | ||
newText: item.change.isUnnamedDefaultExport ? "" : stripFunctionExportKeyword(item.change.code), | ||
span: item.change.span | ||
@@ -1114,2 +1119,17 @@ }); | ||
} | ||
case ts6.SyntaxKind.EnumDeclaration: { | ||
if (item.skip || usage.has(item.name)) { | ||
break; | ||
} | ||
changes.push({ | ||
newText: stripEnumExportKeyword(item.change.code), | ||
span: item.change.span | ||
}); | ||
logs.push({ | ||
fileName: targetFile, | ||
position: item.start, | ||
code: item.name | ||
}); | ||
break; | ||
} | ||
case ts6.SyntaxKind.ExportAssignment: { | ||
@@ -1320,3 +1340,2 @@ if (item.skip || usage.has("default")) { | ||
projectRoot = ".", | ||
pool, | ||
recursive | ||
@@ -1346,4 +1365,3 @@ }) => { | ||
} | ||
const fn2 = pool ? pool.run.bind(pool) : processFile; | ||
const result = await fn2({ | ||
const result = processFile({ | ||
targetFile: c.file, | ||
@@ -1577,146 +1595,2 @@ vertexes: dependencyGraph.eject(), | ||
// lib/util/WorkerPool.ts | ||
import { Worker } from "node:worker_threads"; | ||
import * as os from "node:os"; | ||
var generateCode = (url, name) => `data:text/javascript,import { parentPort } from 'node:worker_threads'; | ||
import { ${name} } from '${url}'; | ||
parentPort.on('message', async (message) => { | ||
if (!('arg' in message)) { | ||
return; | ||
} | ||
try { | ||
const result = await ${name}(message.arg); | ||
parentPort.postMessage({ result }); | ||
} catch (error) { | ||
parentPort.postMessage({ error }); | ||
} | ||
}); | ||
`; | ||
var PromiseWorker = class extends Worker { | ||
current = null; | ||
constructor(url, name) { | ||
super(new URL(generateCode(url, name))); | ||
} | ||
}; | ||
var WorkerPool = class { | ||
#url; | ||
#name; | ||
#queue = []; | ||
#working = []; | ||
#idle = []; | ||
constructor({ url, name }) { | ||
this.#url = url; | ||
this.#name = name; | ||
const max = os.availableParallelism?.() ?? os.cpus().length - 1; | ||
for (let i = 0; i < max; i++) { | ||
this.#setup(); | ||
} | ||
} | ||
run(arg) { | ||
return new Promise((resolve2, reject) => { | ||
const worker = this.#idle.pop(); | ||
if (!worker) { | ||
this.#queue.push({ resolve: resolve2, reject, arg }); | ||
return; | ||
} | ||
worker.current = { | ||
resolve: resolve2, | ||
reject | ||
}; | ||
this.#working.push(worker); | ||
worker.postMessage({ arg }); | ||
}); | ||
} | ||
close() { | ||
if (this.#working.length > 0) { | ||
throw new Error("Cannot close while there are working workers"); | ||
} | ||
return Promise.all( | ||
this.#idle.map((worker) => { | ||
worker.removeAllListeners(); | ||
return worker.terminate(); | ||
}) | ||
); | ||
} | ||
#assignTask() { | ||
if (this.#queue.length === 0) { | ||
return; | ||
} | ||
const worker = this.#idle.pop(); | ||
if (!worker) { | ||
return; | ||
} | ||
const { resolve: resolve2, reject, arg } = this.#queue.shift(); | ||
worker.current = { | ||
resolve: resolve2, | ||
reject | ||
}; | ||
worker.postMessage({ arg }); | ||
this.#working.push(worker); | ||
} | ||
#free(worker) { | ||
worker.current = null; | ||
const index = this.#working.indexOf(worker); | ||
if (index === -1) { | ||
return; | ||
} | ||
this.#working.splice(index, 1); | ||
this.#idle.push(worker); | ||
} | ||
#setup() { | ||
const worker = new PromiseWorker(this.#url, this.#name); | ||
worker.on("message", (message) => { | ||
if (!worker.current) { | ||
return; | ||
} | ||
switch (true) { | ||
case "broadcast" in message: { | ||
[...this.#working, ...this.#idle].forEach( | ||
(w) => w !== worker && w.postMessage(message) | ||
); | ||
return; | ||
} | ||
case "error" in message: { | ||
worker.current.reject(message.error); | ||
this.#free(worker); | ||
this.#assignTask(); | ||
return; | ||
} | ||
case "result" in message: { | ||
worker.current.resolve(message.result); | ||
this.#free(worker); | ||
this.#assignTask(); | ||
return; | ||
} | ||
} | ||
}); | ||
worker.on("error", (error) => { | ||
if (!worker.current) { | ||
return; | ||
} | ||
worker.current.reject(error); | ||
this.#free(worker); | ||
this.#assignTask(); | ||
}); | ||
worker.on("exit", (code) => { | ||
if (code === 0) { | ||
return; | ||
} | ||
if (worker.current) { | ||
worker.current.reject( | ||
new Error(`Worker stopped with exit code ${code}`) | ||
); | ||
this.#free(worker); | ||
worker.terminate(); | ||
this.#setup(); | ||
return; | ||
} | ||
worker.terminate(); | ||
this.#setup(); | ||
}); | ||
this.#idle.push(worker); | ||
} | ||
}; | ||
// lib/util/regex.ts | ||
@@ -1787,6 +1661,2 @@ var dts = /\.d\.ts$/; | ||
); | ||
const pool = new WorkerPool({ | ||
name: "processFile", | ||
url: globalThis.__INTERNAL_WORKER_URL__ || new URL("./worker.js", import.meta.url).href | ||
}); | ||
await edit({ | ||
@@ -1796,7 +1666,6 @@ fileService, | ||
deleteUnusedFile: true, | ||
enableCodeFix: true, | ||
enableCodeFix: mode === "write" || recursive, | ||
editTracker, | ||
options, | ||
projectRoot, | ||
pool, | ||
recursive | ||
@@ -1821,3 +1690,2 @@ }); | ||
editTracker.logResult(); | ||
await pool.close(); | ||
if (mode === "check" && !editTracker.isClean) { | ||
@@ -1824,0 +1692,0 @@ system.exit(1); |
import ts from 'typescript'; | ||
import { FileService } from './FileService.js'; | ||
import { EditTracker } from './EditTracker.js'; | ||
import { Vertexes } from './DependencyGraph.js'; | ||
import { WorkerPool } from './WorkerPool.js'; | ||
export declare const processFile: ({ targetFile, files, vertexes, deleteUnusedFile, enableCodeFix, options, projectRoot, }: { | ||
targetFile: string; | ||
vertexes: Map<string, { | ||
to: Set<string>; | ||
from: Set<string>; | ||
data: { | ||
depth: number; | ||
}; | ||
}>; | ||
files: Map<string, string>; | ||
deleteUnusedFile: boolean; | ||
enableCodeFix: boolean; | ||
options: ts.CompilerOptions; | ||
projectRoot: string; | ||
}) => { | ||
operation: "edit"; | ||
content: string; | ||
removedExports: { | ||
fileName: string; | ||
position: number; | ||
code: string; | ||
}[]; | ||
} | { | ||
operation: "delete"; | ||
}; | ||
export declare const edit: ({ entrypoints, fileService, deleteUnusedFile, enableCodeFix, editTracker, options, projectRoot, pool, recursive, }: { | ||
export declare const edit: ({ entrypoints, fileService, deleteUnusedFile, enableCodeFix, editTracker, options, projectRoot, recursive, }: { | ||
entrypoints: string[]; | ||
@@ -40,27 +13,2 @@ fileService: FileService; | ||
recursive: boolean; | ||
pool?: WorkerPool<({ targetFile, files, vertexes, deleteUnusedFile, enableCodeFix, options, projectRoot, }: { | ||
targetFile: string; | ||
vertexes: Map<string, { | ||
to: Set<string>; | ||
from: Set<string>; | ||
data: { | ||
depth: number; | ||
}; | ||
}>; | ||
files: Map<string, string>; | ||
deleteUnusedFile: boolean; | ||
enableCodeFix: boolean; | ||
options: ts.CompilerOptions; | ||
projectRoot: string; | ||
}) => { | ||
operation: "edit"; | ||
content: string; | ||
removedExports: { | ||
fileName: string; | ||
position: number; | ||
code: string; | ||
}[]; | ||
} | { | ||
operation: "delete"; | ||
}> | undefined; | ||
}) => Promise<void>; |
@@ -1,4 +0,3 @@ | ||
export declare const memoize: <T extends (...args: any[]) => any>(fn: T, { key, name }: { | ||
export declare const memoize: <T extends (...args: any[]) => any>(fn: T, { key }: { | ||
key: (...args: Parameters<T>) => string; | ||
name: string; | ||
}) => (...args: Parameters<T>) => ReturnType<T>; |
@@ -114,2 +114,14 @@ import ts from 'typescript'; | ||
start: number; | ||
} | { | ||
kind: ts.SyntaxKind.EnumDeclaration; | ||
name: string; | ||
change: { | ||
code: string; | ||
span: { | ||
start: number; | ||
length: number; | ||
}; | ||
}; | ||
skip: boolean; | ||
start: number; | ||
}; | ||
@@ -116,0 +128,0 @@ type AmbientDeclaration = { |
@@ -44,3 +44,3 @@ { | ||
}, | ||
"version": "0.9.0" | ||
"version": "0.10.0" | ||
} |
@@ -8,2 +8,3 @@ <h1 align="center">ts-remove-unused</h1> | ||
[![npm version](https://badge.fury.io/js/@line%2Fts-remove-unused.svg)](https://badge.fury.io/js/@line%2Fts-remove-unused) | ||
[![install size](https://packagephobia.com/badge?p=ts-remove-unused)](https://packagephobia.com/result?p=ts-remove-unused) | ||
[![CI](https://github.com/line/ts-remove-unused/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/line/ts-remove-unused/actions/workflows/ci.yml) | ||
@@ -42,3 +43,3 @@ | ||
Here are some examples of how this tool will auto-fixe unused code. | ||
Here are some examples of how this tool will auto-fix unused code. | ||
@@ -127,3 +128,3 @@ <!-- prettier-ignore-start --> | ||
Options: | ||
--project <file> Path to your tsconfig.json | ||
-p, --project <file> Path to your tsconfig.json | ||
--skip <regexp_pattern> Specify the regexp pattern to match files that should be skipped from transforming | ||
@@ -138,3 +139,3 @@ --include-d-ts Include .d.ts files in target for transformation | ||
#### `--project` | ||
#### `-p`, `--project` | ||
@@ -144,3 +145,3 @@ Specifies the `tsconfig.json` that is used to analyze your codebase. Defaults to `tsconfig.json` in your project root. | ||
```bash | ||
npx @line/ts-remove-unused --skip tsconfig.client.json | ||
npx @line/ts-remove-unused --project tsconfig.client.json | ||
``` | ||
@@ -168,3 +169,3 @@ | ||
#### `-r, --recursive` | ||
#### `-r`, `--recursive` | ||
@@ -171,0 +172,0 @@ The default behavior of the CLI is to process all files once. Some issues may not be detected if the unused code is a result of the modification of another file in the project. When this option is enabled, ts-remove-unused will recursively re-edit/re-check files that may be affected by a file edit. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
256
122685
26
3669