New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ts-unused-exports

Package Overview
Dependencies
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ts-unused-exports - npm Package Compare versions

Comparing version 2.1.0 to 2.2.0

7

CHANGELOG.md
## [Unreleased] - ReleaseDate
### Added
- If the option --showLineNumber is given, then output 1 line per unused export, with the location in the file (line number, column)
### Changed
- Fix the --ignorePaths option (it was incorrectly filtering the parsed files, instead of filtering the output)
## [2.1.0] - 20 Oct 2019
### Added
- Add comment flag to ignore some exports

@@ -4,0 +11,0 @@ - Add tsconfig paths aliases support

4

lib/analyzer.d.ts

@@ -1,4 +0,4 @@

import { File, Analysis } from './types';
import { Analysis, ExtraCommandLineOptions, File } from './types';
export { Analysis } from './types';
declare const _default: (files: File[]) => Analysis;
declare const _default: (files: File[], extraOptions?: ExtraCommandLineOptions | undefined) => Analysis;
export default _default;

@@ -5,3 +5,8 @@ "use strict";

var exports = {};
file.exports.forEach(function (e) { return exports[e] = 0; });
file.exports.forEach(function (e, index) {
exports[e] = {
usageCount: 0,
location: file.exportLocations[index]
};
});
return { exports: exports, path: file.fullPath };

@@ -23,4 +28,4 @@ };

return imp == '*'
? Object.keys(ex).filter(function (e) { return e != 'default'; }).forEach(function (e) { return ++ex[e]; })
: ++ex[imp];
? Object.keys(ex).filter(function (e) { return e != 'default'; }).forEach(function (e) { return ex[e].usageCount++; })
: ex[imp].usageCount++;
});

@@ -39,7 +44,23 @@ });

.filter(function (e) { return e != 'default'; })
.forEach(function (key) { return fileExports.exports[key] = 0; });
.forEach(function (key) {
if (!fileExports.exports[key]) {
var export1 = exportMap[ex.slice(2)].exports[key];
fileExports.exports[key] = {
usageCount: 0,
location: export1.location
};
}
fileExports.exports[key].usageCount = 0;
});
});
});
};
exports.default = (function (files) {
// Allow disabling of results, by path from command line (useful for large projects)
var shouldPathBeIgnored = function (path, extraOptions) {
if (!extraOptions || !extraOptions.pathsToIgnore) {
return false;
}
return extraOptions.pathsToIgnore.some(function (ignore) { return path.indexOf(ignore) >= 0; });
};
exports.default = (function (files, extraOptions) {
var exportMap = getExportMap(files);

@@ -52,7 +73,17 @@ expandExportFromStar(files, exportMap);

var exports = expItem.exports, path = expItem.path;
var unused = Object.keys(exports).filter(function (k) { return exports[k] === 0; });
if (unused.length)
analysis[path] = unused;
if (shouldPathBeIgnored(path, extraOptions))
return;
var unusedExports = Object.keys(exports).filter(function (k) { return exports[k].usageCount === 0; });
if (unusedExports.length === 0) {
return;
}
analysis[path] = [];
unusedExports.forEach(function (e) {
analysis[path].push({
exportName: e,
location: exports[e].location
});
});
});
return analysis;
});
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var fs_1 = require("fs");
var ts = require("typescript");
var analyzer_1 = require("./analyzer");
var path_1 = require("path");
var argsParser_1 = require("./argsParser");
var parser_1 = require("./parser");
var analyzer_1 = require("./analyzer");
var argsParser_1 = require("./argsParser");
var fs_1 = require("fs");
var parseTsConfig = function (tsconfigPath) {

@@ -39,3 +39,3 @@ var basePath = path_1.resolve(path_1.dirname(tsconfigPath));

var tsConfig = exports.loadTsConfig(tsconfigPath, args.tsFiles);
return analyzer_1.default(parser_1.default(path_1.dirname(tsconfigPath), tsConfig, args.options));
return analyzer_1.default(parser_1.default(path_1.dirname(tsconfigPath), tsConfig), args.options);
});
import { ExtraCommandLineOptions } from "./types";
declare type TsFilesAndOptions = {
tsFiles?: string[];
options: ExtraCommandLineOptions;
options?: ExtraCommandLineOptions;
};

@@ -6,0 +6,0 @@ export declare function extractOptionsFromFiles(files?: string[]): TsFilesAndOptions;

@@ -53,2 +53,5 @@ "use strict";

break;
case "--showLineNumber":
newFilesAndOptions.options.showLineNumber = true;
break;
default:

@@ -55,0 +58,0 @@ throw new Error("Not a recognised option '" + optionName + "'");

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var argsParser_1 = require("./argsParser");
var app_1 = require("./app");
var chalk_1 = require("chalk");
var app_1 = require("./app");
var usage_1 = require("./usage");
var argsParser_1 = require("./argsParser");
var _a = process.argv.slice(2), tsconfig = _a[0], tsFiles = _a.slice(1);

@@ -18,4 +18,20 @@ if (!argsParser_1.hasValidArgs()) {

console.log(chalk_1.default.red(chalk_1.default.bold(files.length.toString()) + " module" + (files.length == 1 ? '' : 's') + " with unused exports"));
files.forEach(function (path) { return console.log(path + ": " + chalk_1.default.bold.yellow(analysis_1[path].join(", "))); });
if (argsParser_1.extractOptionsFromFiles(tsFiles).options.exitWithCount) {
var getLocationInFile_1 = function (location) {
if (!location) {
return "";
}
return "[" + location.line + "," + location.character + "]";
};
var options = argsParser_1.extractOptionsFromFiles(tsFiles).options;
if (options && options.showLineNumber) {
files.forEach(function (path) {
analysis_1[path].forEach(function (unusedExport) {
console.log("" + path + getLocationInFile_1(unusedExport.location) + ": " + chalk_1.default.bold.yellow(unusedExport.exportName));
});
});
}
else {
files.forEach(function (path) { return console.log(path + ": " + chalk_1.default.bold.yellow(analysis_1[path].map(function (r) { return r.exportName; }).join(", "))); });
}
if (options && options.exitWithCount) {
process.exit(files.length);

@@ -22,0 +38,0 @@ }

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var argsParser_1 = require("./argsParser");
var path_1 = require("path");
var app_1 = require("./app");
var argsParser_1 = require("./argsParser");
var parser_1 = require("./parser");

@@ -35,5 +35,5 @@ var usage_1 = require("./usage");

;
var analyzeDeps = function (tsconfigPath, extraOptions) {
var analyzeDeps = function (tsconfigPath) {
var tsConfig = app_1.loadTsConfig(tsconfigPath);
var files = parser_1.default(path_1.dirname(tsconfigPath), tsConfig, extraOptions);
var files = parser_1.default(path_1.dirname(tsconfigPath), tsConfig);
var fileMap = getFileMap(files);

@@ -44,3 +44,4 @@ var analysis = {};

};
var _a = process.argv.slice(2), tsconfig = _a[0], filter = _a[1], options = _a.slice(2);
// Not using options here
var _a = process.argv.slice(2), tsconfig = _a[0], filter = _a[1];
if (!argsParser_1.hasValidArgs()) {

@@ -53,4 +54,3 @@ usage_1.showUsage();

};
var parsedOptions = argsParser_1.extractOptionsFromFiles(options).options;
var analysis = analyzeDeps(tsconfig, parsedOptions);
var analysis = analyzeDeps(tsconfig);
var deps = getValues(analysis);

@@ -57,0 +57,0 @@ deps.sort(function (a, b) { return a.depth - b.depth; });

@@ -1,3 +0,3 @@

import { File, TsConfig, ExtraCommandLineOptions } from './types';
declare const _default: (rootDir: string, TsConfig: TsConfig, extraOptions?: ExtraCommandLineOptions | undefined) => File[];
import { File, TsConfig } from './types';
declare const _default: (rootDir: string, TsConfig: TsConfig) => File[];
export default _default;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var fs_1 = require("fs");
var path_1 = require("path");
var ts = require("typescript");
var tsconfigPaths = require("tsconfig-paths");
var path_1 = require("path");
var fs_1 = require("fs");
var TRIM_QUOTES = /^['"](.*)['"]$/;

@@ -103,5 +103,14 @@ var EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx'];

var exports = [];
var exportLocations = [];
var name = path_1.relative(rootDir, path).replace(/([\\/]index)?\.[^.]*$/, '');
var baseDir = baseUrl && path_1.resolve(rootDir, baseUrl);
var tsconfigPathsMatcher = baseDir && paths && tsconfigPaths.createMatchPath(baseDir, paths);
var addExport = function (exportName, file, node) {
exports.push(exportName);
var location = file.getLineAndCharacterOfPosition(node.getStart());
exportLocations.push({
line: location.line + 1,
character: location.character
});
};
var addImport = function (fw) {

@@ -148,3 +157,3 @@ var from = fw.from, what = fw.what;

if (kind === ts.SyntaxKind.ExportAssignment) {
exports.push('default');
addExport('default', file, node);
return;

@@ -154,3 +163,3 @@ }

if (node.moduleSpecifier === undefined) {
exports.push.apply(exports, extractExportStatement(node));
extractExportStatement(node).forEach(function (e) { return addExport(e, file, node); });
return;

@@ -164,3 +173,3 @@ }

if (what == star) {
exports.push("*:" + key);
addExport("*:" + key, file, node);
}

@@ -176,3 +185,3 @@ else {

if (hasModifier(node, ts.SyntaxKind.DefaultKeyword)) {
exports.push('default');
addExport('default', file, node);
return;

@@ -185,3 +194,3 @@ }

if (name_2)
exports.push(name_2);
addExport(name_2, file, node);
}

@@ -193,3 +202,4 @@ });

imports: imports,
exports: exports
exports: exports,
exportLocations: exportLocations
};

@@ -201,19 +211,11 @@ };

};
var parsePaths = function (rootDir, _a, extraOptions) {
var parsePaths = function (rootDir, _a) {
var baseUrl = _a.baseUrl, filePaths = _a.files, paths = _a.paths;
var files = filePaths
.filter(function (p) { return p.indexOf('.d.') == -1 && !shouldPathBeIgnored(p, extraOptions.pathsToIgnore); })
.filter(function (p) { return p.indexOf('.d.') == -1; })
.map(function (path) { return parseFile(rootDir, path_1.resolve(rootDir, path), baseUrl, paths); });
return files;
};
// Allow disabling of results, by path from command line (useful for large projects)
var shouldPathBeIgnored = function (path, pathsToIgnore) {
if (!pathsToIgnore) {
return false;
}
return pathsToIgnore.some(function (ignore) { return path.indexOf(ignore) >= 0; });
};
exports.default = (function (rootDir, TsConfig, extraOptions) {
var activeExtraOptions = extraOptions || {};
return parsePaths(rootDir, TsConfig, activeExtraOptions);
exports.default = (function (rootDir, TsConfig) {
return parsePaths(rootDir, TsConfig);
});

@@ -9,5 +9,15 @@ export interface Imports {

exports: string[];
exportLocations: LocationInFile[];
}
export interface LocationInFile {
/** 1-based. */
line: number;
character: number;
}
export interface ExportNameAndLocation {
exportName: string;
location: LocationInFile;
}
export interface Analysis {
[index: string]: string[];
[index: string]: ExportNameAndLocation[];
}

@@ -25,2 +35,3 @@ export interface TsConfigPaths {

pathsToIgnore?: string[];
showLineNumber?: boolean;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function showUsage() {
console.error("\n usage: ts-unused-exports path/to/tsconfig.json [file1.ts file2.ts] [--exitWithCount][--ignorePaths=path1;path2]\n \n Note: if no file is specified after tsconfig, the files will be read from the\n tsconfig's \"files\" key which must be present.\n \n If the files are specified, their path must be relative to the tsconfig file.\n For example, given:\n /\n |-- config\n | -- tsconfig.json\n -- src\n -- file.ts\n \n Then the usage would be:\n ts-unused-exports config/tsconfig.json ../src/file.ts\n ");
console.error("\n usage: ts-unused-exports path/to/tsconfig.json [file1.ts file2.ts] [--exitWithCount][--ignorePaths=path1;path2][--showLineNumber]\n \n Note: if no file is specified after tsconfig, the files will be read from the\n tsconfig's \"files\" key which must be present.\n \n If the files are specified, their path must be relative to the tsconfig file.\n For example, given:\n /\n |-- config\n | -- tsconfig.json\n -- src\n -- file.ts\n \n Then the usage would be:\n ts-unused-exports config/tsconfig.json ../src/file.ts\n ");
}
exports.showUsage = showUsage;
{
"name": "ts-unused-exports",
"version": "2.1.0",
"version": "2.2.0",
"description": "ts-unused-exports finds unused exported symbols in your Typescript project",

@@ -27,3 +27,3 @@ "main": "lib/app.js",

"test:unit": "jasmine",
"test:itest": "./bin/ts-unused-exports ./example/tsconfig.json",
"test:itest": "cd ispec && bash ./run.sh",
"exec": "bin/ts-unused-exports"

@@ -30,0 +30,0 @@ },

@@ -47,4 +47,5 @@ ts-unused-exports

|---|---|---|
| `exitWithCount` | Set the process exit code to be the count of files that have unused exports. | `--exitWithCount` |
| `ignorePaths` | Exclude files that match the given path segments. | `--ignorePaths=math;utils` |
| `exitWithCount` | Set the process exit code to be the count of files that have unused exports. | `--exitWithCount` |
| `showLineNumber` | Show the line number and column of the unused export. | `--showLineNumber` |

@@ -80,3 +81,3 @@ Note that if `ts-unused-exports` is called without files, the files will be read from the tsconfig's `files` or `include` key which must be present. If called with files, then those file paths should be relative to the `tsconfig.json`, just like you would specifie them in your tsconfig's `files` key.

There is a (very silly) example in the [example/](https://github.com/pzavolinsky/ts-unused-exports/blob/master/example) directory.
There is a (very silly) example in the [example/](https://github.com/pzavolinsky/ts-unused-exports/blob/master/example/simple) directory.

@@ -89,4 +90,4 @@ If you want to run it you can:

./bin/ts-unused-exports example/tsconfig.json
# or: node ./bin/ts-unused-exports example/tsconfig.json
# or: node bin\ts-unused-exports example\tsconfig.json
# or: node ./bin/ts-unused-exports example/simple/tsconfig.json
# or: node bin\ts-unused-exports example\simple\tsconfig.json
```

@@ -111,3 +112,3 @@

```shell
./bin/ts-unused-exports example/tsconfig.json app.ts math.ts
./bin/ts-unused-exports example/simple/tsconfig.json app.ts math.ts
```

@@ -118,3 +119,3 @@

```shell
./bin/ts-unused-exports example/tsconfig.json $(cd example; find -name '*.ts')
./bin/ts-unused-exports example/simple/tsconfig.json $(cd example/simple; find -name '*.ts')
```

@@ -121,0 +122,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