Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@line/ts-remove-unused

Package Overview
Dependencies
Maintainers
0
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@line/ts-remove-unused - npm Package Compare versions

Comparing version 0.3.0 to 0.3.1

65

dist/cli.js

@@ -182,2 +182,3 @@ #!/usr/bin/env node

var isUsedFile = (languageService, sourceFile) => {
const { fileName } = sourceFile;
let isUsed = false;

@@ -196,7 +197,5 @@ const visit = (node) => {

}
const count = references.flatMap((v) => v.references).length;
if (ts.isExportSpecifier(node) && count > 2) {
const count = references.filter((v) => v.definition.fileName !== fileName).flatMap((v) => v.references).length;
if (count > 0) {
isUsed = true;
} else if (!ts.isExportSpecifier(node) && count > 1) {
isUsed = true;
}

@@ -211,2 +210,3 @@ return;

var getUnusedExports = (languageService, sourceFile) => {
const { fileName } = sourceFile;
const result = [];

@@ -219,7 +219,5 @@ const visit = (node) => {

}
const count = references.flatMap((v) => v.references).length;
if (ts.isExportSpecifier(node) && count === 2) {
const count = references.filter((v) => v.definition.fileName !== fileName).flatMap((v) => v.references).length;
if (count === 0) {
result.push(node);
} else if (!ts.isExportSpecifier(node) && count === 1) {
result.push(node);
}

@@ -252,5 +250,13 @@ return;

};
var getTextChanges = (languageService, sourceFile, editTracker) => {
var getTextChanges = (languageService, file, editTracker) => {
const sourceFile = languageService.getProgram()?.getSourceFile(file);
if (!sourceFile) {
throw new Error("source file not found");
}
const changes = [];
let aborted = false;
for (const node of getUnusedExports(languageService, sourceFile)) {
if (aborted === true) {
break;
}
if (ts.isExportSpecifier(node)) {

@@ -272,2 +278,3 @@ const specifierCount = Array.from(node.parent.elements).length;

}
aborted = true;
changes.push({

@@ -321,4 +328,6 @@ newText: getUpdatedExportDeclaration(node.parent.parent, node),

}
const syntaxList = node.getChildren().find((n) => n.kind === ts.SyntaxKind.SyntaxList);
if (!syntaxList) {
const syntaxListIndex = node.getChildren().findIndex((n) => n.kind === ts.SyntaxKind.SyntaxList);
const syntaxList = node.getChildren()[syntaxListIndex];
const syntaxListNextSibling = node.getChildren()[syntaxListIndex + 1];
if (!syntaxList || !syntaxListNextSibling) {
throw new Error("syntax list not found");

@@ -329,4 +338,4 @@ }

span: {
start: syntaxList.getFullStart(),
length: syntaxList.getFullWidth()
start: syntaxList.getStart(),
length: syntaxListNextSibling.getStart() - syntaxList.getStart()
}

@@ -339,3 +348,3 @@ });

}
return changes;
return { changes, done: !aborted };
};

@@ -378,9 +387,19 @@ var disabledEditTracker = {

}
const changes = getTextChanges(languageService, sourceFile, editTracker);
let content = fileService.get(file);
do {
const { changes, done } = getTextChanges(
languageService,
file,
editTracker
);
content = applyTextChanges(content, changes);
fileService.set(file, content);
if (done) {
break;
}
} while (true);
editTracker.end(file);
const oldContent = fileService.get(file);
let newContent = applyTextChanges(oldContent, changes);
if (enableCodeFix) {
while (true) {
fileService.set(file, newContent);
fileService.set(file, content);
const result = applyCodeFix({

@@ -391,9 +410,9 @@ fixId: fixIdDelete,

});
if (result === newContent) {
if (result === content) {
break;
}
newContent = result;
content = result;
}
fileService.set(file, newContent);
newContent = applyCodeFix({
fileService.set(file, content);
content = applyCodeFix({
fixId: fixIdDeleteImports,

@@ -404,3 +423,3 @@ fileName: file,

}
fileService.set(file, newContent);
fileService.set(file, content);
}

@@ -407,0 +426,0 @@ };

@@ -177,2 +177,3 @@ // lib/remove.ts

var isUsedFile = (languageService, sourceFile) => {
const { fileName } = sourceFile;
let isUsed = false;

@@ -191,7 +192,5 @@ const visit = (node) => {

}
const count = references.flatMap((v) => v.references).length;
if (ts.isExportSpecifier(node) && count > 2) {
const count = references.filter((v) => v.definition.fileName !== fileName).flatMap((v) => v.references).length;
if (count > 0) {
isUsed = true;
} else if (!ts.isExportSpecifier(node) && count > 1) {
isUsed = true;
}

@@ -206,2 +205,3 @@ return;

var getUnusedExports = (languageService, sourceFile) => {
const { fileName } = sourceFile;
const result = [];

@@ -214,7 +214,5 @@ const visit = (node) => {

}
const count = references.flatMap((v) => v.references).length;
if (ts.isExportSpecifier(node) && count === 2) {
const count = references.filter((v) => v.definition.fileName !== fileName).flatMap((v) => v.references).length;
if (count === 0) {
result.push(node);
} else if (!ts.isExportSpecifier(node) && count === 1) {
result.push(node);
}

@@ -247,5 +245,13 @@ return;

};
var getTextChanges = (languageService, sourceFile, editTracker) => {
var getTextChanges = (languageService, file, editTracker) => {
const sourceFile = languageService.getProgram()?.getSourceFile(file);
if (!sourceFile) {
throw new Error("source file not found");
}
const changes = [];
let aborted = false;
for (const node of getUnusedExports(languageService, sourceFile)) {
if (aborted === true) {
break;
}
if (ts.isExportSpecifier(node)) {

@@ -267,2 +273,3 @@ const specifierCount = Array.from(node.parent.elements).length;

}
aborted = true;
changes.push({

@@ -316,4 +323,6 @@ newText: getUpdatedExportDeclaration(node.parent.parent, node),

}
const syntaxList = node.getChildren().find((n) => n.kind === ts.SyntaxKind.SyntaxList);
if (!syntaxList) {
const syntaxListIndex = node.getChildren().findIndex((n) => n.kind === ts.SyntaxKind.SyntaxList);
const syntaxList = node.getChildren()[syntaxListIndex];
const syntaxListNextSibling = node.getChildren()[syntaxListIndex + 1];
if (!syntaxList || !syntaxListNextSibling) {
throw new Error("syntax list not found");

@@ -324,4 +333,4 @@ }

span: {
start: syntaxList.getFullStart(),
length: syntaxList.getFullWidth()
start: syntaxList.getStart(),
length: syntaxListNextSibling.getStart() - syntaxList.getStart()
}

@@ -334,3 +343,3 @@ });

}
return changes;
return { changes, done: !aborted };
};

@@ -373,9 +382,19 @@ var disabledEditTracker = {

}
const changes = getTextChanges(languageService, sourceFile, editTracker);
let content = fileService.get(file);
do {
const { changes, done } = getTextChanges(
languageService,
file,
editTracker
);
content = applyTextChanges(content, changes);
fileService.set(file, content);
if (done) {
break;
}
} while (true);
editTracker.end(file);
const oldContent = fileService.get(file);
let newContent = applyTextChanges(oldContent, changes);
if (enableCodeFix) {
while (true) {
fileService.set(file, newContent);
fileService.set(file, content);
const result = applyCodeFix({

@@ -386,9 +405,9 @@ fixId: fixIdDelete,

});
if (result === newContent) {
if (result === content) {
break;
}
newContent = result;
content = result;
}
fileService.set(file, newContent);
newContent = applyCodeFix({
fileService.set(file, content);
content = applyCodeFix({
fixId: fixIdDeleteImports,

@@ -399,3 +418,3 @@ fileName: file,

}
fileService.set(file, newContent);
fileService.set(file, content);
}

@@ -402,0 +421,0 @@ };

@@ -44,3 +44,3 @@ {

},
"version": "0.3.0"
"version": "0.3.1"
}
# ts-remove-unused
<div align="center">
<img width="480" src="./media/screenshot.png" />
</div>
[![npm version](https://badge.fury.io/js/@line%2Fts-remove-unused.svg)](https://badge.fury.io/js/@line%2Fts-remove-unused)
> Remove unused code from your TypeScript project
## Introduction
When you enable `compilerOptions.noUnusedLocals` for your TypeScript project, it's possible to detect declarations that are not referenced in your file.
```typescript
// TypeScript will throw error: 'a' is declared but its value is never read.
const a = 'a';
```
However when this declaration is exported and is not referenced by any file in the project, it's difficult to recognize this.
```typescript
// no errors will be reported even if the declaration is not used across the entire project.
export const a = 'a';
```
This is when ts-remove-unused comes in handy. ts-remove-unused is a CLI tools made on top of TypeScript that reports/fixes unused exports.
Let's say you have the following file:
```typescript
export const a = 'a';
export const b = 'b';
export const c = 'c';
console.log(b);
```
When `a` and `b` are not used in all other files across the project, ts-remove-unused will modify the file to be:
```typescript
const b = 'b';
export const c = 'c';
console.log(b);
```
If you have another file in your project:
```typescript
export const d = 'd';
export const e = 'e';
```
When `d` and `e` are not used in all other files across the project, ts-remove-unused will delete the file for you.
Now you don't have to worry about removing your unused code!
ts-remove-unused supports various exports including variable declarations (`export const`, `export let`), function declarations, class declarations, interface declarations, type alias declarations, default exports...
## Install

@@ -6,0 +66,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc