knip 5.22.3 → 5.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IssueCollector.d.ts +4 -1
- package/dist/IssueCollector.js +7 -2
- package/dist/WorkspaceWorker.d.ts +2 -2
- package/dist/cli.js +2 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +42 -10
- package/dist/reporters/index.d.ts +1 -1
- package/dist/reporters/symbols.d.ts +1 -1
- package/dist/reporters/symbols.js +18 -8
- package/dist/types/dependency-graph.d.ts +2 -2
- package/dist/types/issues.d.ts +9 -0
- package/dist/typescript/ast-helpers.d.ts +1 -0
- package/dist/typescript/ast-helpers.js +9 -0
- package/dist/typescript/getImportsAndExports.js +36 -24
- package/dist/util/regex.d.ts +1 -0
- package/dist/util/regex.js +2 -0
- package/dist/util/tag.d.ts +2 -1
- package/dist/util/tag.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/IssueCollector.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConfigurationHint, Issue, Rules } from './types/issues.js';
|
|
1
|
+
import type { ConfigurationHint, Issue, Rules, TagHint } from './types/issues.js';
|
|
2
2
|
type Filters = Partial<{
|
|
3
3
|
dir: string;
|
|
4
4
|
}>;
|
|
@@ -15,6 +15,7 @@ export declare class IssueCollector {
|
|
|
15
15
|
private counters;
|
|
16
16
|
private referencedFiles;
|
|
17
17
|
private configurationHints;
|
|
18
|
+
private tagHints;
|
|
18
19
|
private ignorePatterns;
|
|
19
20
|
private isMatch;
|
|
20
21
|
constructor({ cwd, rules, filters }: IssueCollectorOptions);
|
|
@@ -26,10 +27,12 @@ export declare class IssueCollector {
|
|
|
26
27
|
addFilesIssues(filePaths: string[]): void;
|
|
27
28
|
addIssue(issue: Issue): Issue | undefined;
|
|
28
29
|
addConfigurationHint(issue: ConfigurationHint): void;
|
|
30
|
+
addTagHint(issue: TagHint): void;
|
|
29
31
|
purge(): import("./types/issues.js").IssueSet;
|
|
30
32
|
getIssues(): {
|
|
31
33
|
issues: import("./types/issues.js").Issues;
|
|
32
34
|
counters: import("./types/issues.js").Counters;
|
|
35
|
+
tagHints: Set<TagHint>;
|
|
33
36
|
configurationHints: Set<ConfigurationHint>;
|
|
34
37
|
};
|
|
35
38
|
}
|
package/dist/IssueCollector.js
CHANGED
|
@@ -2,7 +2,7 @@ import picomatch from 'picomatch';
|
|
|
2
2
|
import { initCounters, initIssues } from './issues/initializers.js';
|
|
3
3
|
import { timerify } from './util/Performance.js';
|
|
4
4
|
import { relative } from './util/path.js';
|
|
5
|
-
const
|
|
5
|
+
const hasConfigurationHint = (hints, hint) => Array.from(hints).some(item => item.identifier === hint.identifier && item.type === hint.type && item.workspaceName === hint.workspaceName);
|
|
6
6
|
const isMatch = timerify(picomatch.isMatch, 'isMatch');
|
|
7
7
|
export class IssueCollector {
|
|
8
8
|
cwd;
|
|
@@ -12,6 +12,7 @@ export class IssueCollector {
|
|
|
12
12
|
counters = initCounters();
|
|
13
13
|
referencedFiles = new Set();
|
|
14
14
|
configurationHints = new Set();
|
|
15
|
+
tagHints = new Set();
|
|
15
16
|
ignorePatterns = new Set();
|
|
16
17
|
isMatch;
|
|
17
18
|
constructor({ cwd, rules, filters }) {
|
|
@@ -59,10 +60,13 @@ export class IssueCollector {
|
|
|
59
60
|
return issue;
|
|
60
61
|
}
|
|
61
62
|
addConfigurationHint(issue) {
|
|
62
|
-
if (!
|
|
63
|
+
if (!hasConfigurationHint(this.configurationHints, issue)) {
|
|
63
64
|
this.configurationHints.add(issue);
|
|
64
65
|
}
|
|
65
66
|
}
|
|
67
|
+
addTagHint(issue) {
|
|
68
|
+
this.tagHints.add(issue);
|
|
69
|
+
}
|
|
66
70
|
purge() {
|
|
67
71
|
const unusedFiles = this.issues.files;
|
|
68
72
|
this.issues = initIssues();
|
|
@@ -73,6 +77,7 @@ export class IssueCollector {
|
|
|
73
77
|
return {
|
|
74
78
|
issues: this.issues,
|
|
75
79
|
counters: this.counters,
|
|
80
|
+
tagHints: this.tagHints,
|
|
76
81
|
configurationHints: this.configurationHints,
|
|
77
82
|
};
|
|
78
83
|
}
|
|
@@ -32,7 +32,7 @@ export declare class WorkspaceWorker {
|
|
|
32
32
|
isStrict: boolean;
|
|
33
33
|
rootIgnore: Configuration['ignore'];
|
|
34
34
|
negatedWorkspacePatterns: string[];
|
|
35
|
-
enabledPluginsMap: Record<"
|
|
35
|
+
enabledPluginsMap: Record<"astro" | "angular" | "ava" | "babel" | "capacitor" | "changesets" | "commitizen" | "commitlint" | "cspell" | "cucumber" | "cypress" | "eleventy" | "eslint" | "gatsby" | "husky" | "jest" | "lefthook" | "linthtml" | "markdownlint" | "mocha" | "moonrepo" | "msw" | "netlify" | "next" | "nx" | "nyc" | "oclif" | "playwright" | "postcss" | "prettier" | "remark" | "remix" | "rollup" | "sentry" | "storybook" | "stryker" | "stylelint" | "svelte" | "syncpack" | "tailwind" | "tsup" | "typedoc" | "typescript" | "unbuild" | "unocss" | "vue" | "vite" | "vitest" | "webpack" | "wireit" | "wrangler" | "xo" | "yorkie" | "drizzle" | "githubActions" | "graphqlCodegen" | "lintStaged" | "lockfileLint" | "lostPixel" | "nodeTestRunner" | "npmPackageJsonLint" | "playwrightCt" | "releaseIt" | "semanticRelease" | "simpleGitHooks" | "sizeLimit" | "vercelOg" | "webdriverIo", boolean>;
|
|
36
36
|
enabledPlugins: PluginName[];
|
|
37
37
|
enabledPluginsInAncestors: string[];
|
|
38
38
|
cache: CacheConsultant<CacheItem>;
|
|
@@ -52,7 +52,7 @@ export declare class WorkspaceWorker {
|
|
|
52
52
|
entryFilePatterns: Set<string>;
|
|
53
53
|
productionEntryFilePatterns: Set<string>;
|
|
54
54
|
referencedDependencies: ReferencedDependencies;
|
|
55
|
-
enabledPlugins: ("
|
|
55
|
+
enabledPlugins: ("astro" | "angular" | "ava" | "babel" | "capacitor" | "changesets" | "commitizen" | "commitlint" | "cspell" | "cucumber" | "cypress" | "eleventy" | "eslint" | "gatsby" | "husky" | "jest" | "lefthook" | "linthtml" | "markdownlint" | "mocha" | "moonrepo" | "msw" | "netlify" | "next" | "nx" | "nyc" | "oclif" | "playwright" | "postcss" | "prettier" | "remark" | "remix" | "rollup" | "sentry" | "storybook" | "stryker" | "stylelint" | "svelte" | "syncpack" | "tailwind" | "tsup" | "typedoc" | "typescript" | "unbuild" | "unocss" | "vue" | "vite" | "vitest" | "webpack" | "wireit" | "wrangler" | "xo" | "yorkie" | "drizzle" | "githubActions" | "graphqlCodegen" | "lintStaged" | "lockfileLint" | "lostPixel" | "nodeTestRunner" | "npmPackageJsonLint" | "playwrightCt" | "releaseIt" | "semanticRelease" | "simpleGitHooks" | "sizeLimit" | "vercelOg" | "webdriverIo")[];
|
|
56
56
|
}>;
|
|
57
57
|
onDispose(): void;
|
|
58
58
|
}
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,7 @@ if (isVersion) {
|
|
|
21
21
|
const isShowProgress = isNoProgress === false && process.stdout.isTTY && typeof process.stdout.cursorTo === 'function';
|
|
22
22
|
const run = async () => {
|
|
23
23
|
try {
|
|
24
|
-
const { report, issues, counters, rules, configurationHints } = await main({
|
|
24
|
+
const { report, issues, counters, rules, tagHints, configurationHints } = await main({
|
|
25
25
|
cwd,
|
|
26
26
|
tsConfigFile: tsConfig,
|
|
27
27
|
gitignore: !isNoGitIgnore,
|
|
@@ -44,6 +44,7 @@ const run = async () => {
|
|
|
44
44
|
report,
|
|
45
45
|
issues,
|
|
46
46
|
counters,
|
|
47
|
+
tagHints,
|
|
47
48
|
configurationHints,
|
|
48
49
|
noConfigHints,
|
|
49
50
|
cwd,
|
package/dist/index.d.ts
CHANGED
|
@@ -6,5 +6,6 @@ export declare const main: (unresolvedConfiguration: CommandLineOptions) => Prom
|
|
|
6
6
|
issues: import("./types/issues.js").Issues;
|
|
7
7
|
counters: import("./types/issues.js").Counters;
|
|
8
8
|
rules: import("./types/issues.js").Rules;
|
|
9
|
+
tagHints: Set<import("./types/issues.js").TagHint>;
|
|
9
10
|
configurationHints: Set<import("./types/issues.js").ConfigurationHint>;
|
|
10
11
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { getIsIdentifierReferencedHandler } from './util/is-identifier-reference
|
|
|
22
22
|
import { getEntryPathFromManifest, getPackageNameFromModuleSpecifier } from './util/modules.js';
|
|
23
23
|
import { dirname, join, toPosix } from './util/path.js';
|
|
24
24
|
import { findMatch } from './util/regex.js';
|
|
25
|
-
import { getShouldIgnoreHandler } from './util/tag.js';
|
|
25
|
+
import { getShouldIgnoreHandler, getShouldIgnoreTagHandler } from './util/tag.js';
|
|
26
26
|
import { augmentWorkspace, getToSourcePathHandler } from './util/to-source-path.js';
|
|
27
27
|
import { createAndPrintTrace, printTrace } from './util/trace.js';
|
|
28
28
|
import { loadTSConfig } from './util/tsconfig-loader.js';
|
|
@@ -285,12 +285,15 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
285
285
|
if (isIsolateWorkspaces)
|
|
286
286
|
for (const principal of principals)
|
|
287
287
|
factory.deletePrincipal(principal);
|
|
288
|
-
const shouldIgnore = getShouldIgnoreHandler(
|
|
288
|
+
const shouldIgnore = getShouldIgnoreHandler(isProduction);
|
|
289
|
+
const shouldIgnoreTags = getShouldIgnoreTagHandler(tags);
|
|
289
290
|
const isIdentifierReferenced = getIsIdentifierReferencedHandler(graph, entryPaths);
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
291
|
+
const ignoreExportsUsedInFile = chief.config.ignoreExportsUsedInFile;
|
|
292
|
+
const isExportedItemReferenced = (exportedItem) => exportedItem.refs[1] ||
|
|
293
|
+
(exportedItem.refs[0] > 0 &&
|
|
294
|
+
(typeof ignoreExportsUsedInFile === 'object'
|
|
295
|
+
? exportedItem.type !== 'unknown' && !!ignoreExportsUsedInFile[exportedItem.type]
|
|
296
|
+
: ignoreExportsUsedInFile));
|
|
294
297
|
const findUnusedExports = async () => {
|
|
295
298
|
if (isReportValues || isReportTypes) {
|
|
296
299
|
streamer.cast('Connecting the dots...');
|
|
@@ -313,7 +316,8 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
313
316
|
continue;
|
|
314
317
|
if (shouldIgnore(exportedItem.jsDocTags))
|
|
315
318
|
continue;
|
|
316
|
-
|
|
319
|
+
const isIgnored = shouldIgnoreTags(exportedItem.jsDocTags);
|
|
320
|
+
if (!isIgnored && importsForExport) {
|
|
317
321
|
const { isReferenced, reExportingEntryFile, traceNode } = isIdentifierReferenced(filePath, identifier, isIncludeEntryExports);
|
|
318
322
|
if (reExportingEntryFile) {
|
|
319
323
|
if (!isIncludeEntryExports) {
|
|
@@ -333,10 +337,13 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
333
337
|
continue;
|
|
334
338
|
if (shouldIgnore(member.jsDocTags))
|
|
335
339
|
continue;
|
|
336
|
-
if (member.refs === 0) {
|
|
340
|
+
if (member.refs[0] === 0) {
|
|
337
341
|
const id = `${identifier}.${member.identifier}`;
|
|
338
342
|
const { isReferenced } = isIdentifierReferenced(filePath, id);
|
|
343
|
+
const isIgnored = shouldIgnoreTags(member.jsDocTags);
|
|
339
344
|
if (!isReferenced) {
|
|
345
|
+
if (isIgnored)
|
|
346
|
+
continue;
|
|
340
347
|
collector.addIssue({
|
|
341
348
|
type: 'enumMembers',
|
|
342
349
|
filePath,
|
|
@@ -348,12 +355,28 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
348
355
|
col: member.col,
|
|
349
356
|
});
|
|
350
357
|
}
|
|
358
|
+
else if (isIgnored) {
|
|
359
|
+
for (const tagName of exportedItem.jsDocTags) {
|
|
360
|
+
if (tags[1].includes(tagName.replace(/^\@/, ''))) {
|
|
361
|
+
collector.addTagHint({ type: 'tag', filePath, identifier: id, tagName });
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
351
365
|
}
|
|
352
366
|
}
|
|
353
367
|
}
|
|
354
368
|
if (principal && isReportClassMembers && exportedItem.type === 'class') {
|
|
355
369
|
const members = exportedItem.members.filter(member => !(findMatch(workspace.ignoreMembers, member.identifier) || shouldIgnore(member.jsDocTags)));
|
|
356
370
|
for (const member of principal.findUnusedMembers(filePath, members)) {
|
|
371
|
+
if (shouldIgnoreTags(member.jsDocTags)) {
|
|
372
|
+
const identifier = `${exportedItem.identifier}.${member.identifier}`;
|
|
373
|
+
for (const tagName of exportedItem.jsDocTags) {
|
|
374
|
+
if (tags[1].includes(tagName.replace(/^\@/, ''))) {
|
|
375
|
+
collector.addTagHint({ type: 'tag', filePath, identifier, tagName });
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
357
380
|
collector.addIssue({
|
|
358
381
|
type: 'classMembers',
|
|
359
382
|
filePath,
|
|
@@ -374,6 +397,8 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
374
397
|
if (hasStrictlyNsRefs && ((!report.nsTypes && isType) || !(report.nsExports || isType)))
|
|
375
398
|
continue;
|
|
376
399
|
if (!isExportedItemReferenced(exportedItem)) {
|
|
400
|
+
if (isIgnored)
|
|
401
|
+
continue;
|
|
377
402
|
if (!isSkipLibs && principal?.hasExternalReferences(filePath, exportedItem))
|
|
378
403
|
continue;
|
|
379
404
|
const type = getType(hasStrictlyNsRefs, isType);
|
|
@@ -395,6 +420,13 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
395
420
|
fixer.addUnusedExportNode(filePath, exportedItem.fixes);
|
|
396
421
|
}
|
|
397
422
|
}
|
|
423
|
+
else if (isIgnored) {
|
|
424
|
+
for (const tagName of exportedItem.jsDocTags) {
|
|
425
|
+
if (tags[1].includes(tagName.replace(/^\@/, ''))) {
|
|
426
|
+
collector.addTagHint({ type: 'tag', filePath, identifier, tagName });
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
398
430
|
}
|
|
399
431
|
}
|
|
400
432
|
}
|
|
@@ -523,7 +555,7 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
523
555
|
});
|
|
524
556
|
}
|
|
525
557
|
await findUnusedExports();
|
|
526
|
-
const { issues, counters, configurationHints } = collector.getIssues();
|
|
558
|
+
const { issues, counters, tagHints, configurationHints } = collector.getIssues();
|
|
527
559
|
if (isFix) {
|
|
528
560
|
await fixer.fixIssues(issues);
|
|
529
561
|
}
|
|
@@ -531,5 +563,5 @@ export const main = async (unresolvedConfiguration) => {
|
|
|
531
563
|
watchReporter({ report, issues, streamer, size: analyzedFiles.size, isDebug });
|
|
532
564
|
else
|
|
533
565
|
streamer.clear();
|
|
534
|
-
return { report, issues, counters, rules, configurationHints };
|
|
566
|
+
return { report, issues, counters, rules, tagHints, configurationHints };
|
|
535
567
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
|
-
symbols: ({ report, issues, configurationHints, noConfigHints, isShowProgress }: import("../index.js").ReporterOptions) => void;
|
|
2
|
+
symbols: ({ report, issues, tagHints, configurationHints, noConfigHints, isShowProgress }: import("../index.js").ReporterOptions) => void;
|
|
3
3
|
compact: ({ report, issues, isShowProgress }: import("../index.js").ReporterOptions) => void;
|
|
4
4
|
codeowners: ({ report, issues, isShowProgress, options }: import("../index.js").ReporterOptions) => void;
|
|
5
5
|
json: ({ report, issues, options }: import("../index.js").ReporterOptions) => Promise<void>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ReporterOptions } from '../types/issues.js';
|
|
2
|
-
declare const _default: ({ report, issues, configurationHints, noConfigHints, isShowProgress }: ReporterOptions) => void;
|
|
2
|
+
declare const _default: ({ report, issues, tagHints, configurationHints, noConfigHints, isShowProgress }: ReporterOptions) => void;
|
|
3
3
|
export default _default;
|
|
@@ -20,7 +20,7 @@ const logIssueRecord = (issues) => {
|
|
|
20
20
|
}
|
|
21
21
|
console.log(table.sort(['filePath', 'parentSymbol', 'symbol']).print().trim());
|
|
22
22
|
};
|
|
23
|
-
export default ({ report, issues, configurationHints, noConfigHints, isShowProgress }) => {
|
|
23
|
+
export default ({ report, issues, tagHints, configurationHints, noConfigHints, isShowProgress }) => {
|
|
24
24
|
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
25
25
|
let totalIssues = 0;
|
|
26
26
|
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
@@ -52,13 +52,23 @@ export default ({ report, issues, configurationHints, noConfigHints, isShowProgr
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
if (!noConfigHints
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
if (!noConfigHints) {
|
|
56
|
+
if (configurationHints.size > 0) {
|
|
57
|
+
logTitle('Configuration issues', configurationHints.size);
|
|
58
|
+
for (const hint of configurationHints) {
|
|
59
|
+
const { type, workspaceName, identifier } = hint;
|
|
60
|
+
const message = `Unused item in ${type}`;
|
|
61
|
+
const workspace = workspaceName && workspaceName !== ROOT_WORKSPACE_NAME ? ` (workspace: ${workspaceName})` : '';
|
|
62
|
+
console.warn(picocolors.gray(`${message}${workspace}:`), identifier);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (tagHints.size > 0) {
|
|
66
|
+
logTitle('Tag issues', tagHints.size);
|
|
67
|
+
for (const hint of tagHints) {
|
|
68
|
+
const { filePath, identifier, tagName } = hint;
|
|
69
|
+
const message = `Unused tag in ${toRelative(filePath)}:`;
|
|
70
|
+
console.warn(picocolors.gray(message), `${identifier} → ${tagName}`);
|
|
71
|
+
}
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
if (totalIssues === 0 && isShowProgress) {
|
|
@@ -33,7 +33,7 @@ export interface Export {
|
|
|
33
33
|
type: SymbolType;
|
|
34
34
|
members: ExportMember[];
|
|
35
35
|
jsDocTags: Tags;
|
|
36
|
-
refs: number;
|
|
36
|
+
refs: [number, boolean];
|
|
37
37
|
fixes: Fixes;
|
|
38
38
|
symbol?: ts.Symbol;
|
|
39
39
|
isReExport: boolean;
|
|
@@ -44,7 +44,7 @@ export type ExportMember = {
|
|
|
44
44
|
line: number;
|
|
45
45
|
col: number;
|
|
46
46
|
type: SymbolType;
|
|
47
|
-
refs: number;
|
|
47
|
+
refs: [number, boolean];
|
|
48
48
|
fix: Fix;
|
|
49
49
|
symbol?: ts.Symbol;
|
|
50
50
|
jsDocTags: Tags;
|
package/dist/types/issues.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ export type ReporterOptions = {
|
|
|
56
56
|
report: Report;
|
|
57
57
|
issues: Issues;
|
|
58
58
|
counters: Counters;
|
|
59
|
+
tagHints: TagHints;
|
|
59
60
|
configurationHints: ConfigurationHints;
|
|
60
61
|
noConfigHints: boolean;
|
|
61
62
|
cwd: string;
|
|
@@ -74,3 +75,11 @@ export type ConfigurationHint = {
|
|
|
74
75
|
identifier: string | RegExp;
|
|
75
76
|
workspaceName?: string;
|
|
76
77
|
};
|
|
78
|
+
type TagHints = Set<TagHint>;
|
|
79
|
+
export type TagHint = {
|
|
80
|
+
type: 'tag';
|
|
81
|
+
filePath: string;
|
|
82
|
+
identifier: string;
|
|
83
|
+
tagName: string;
|
|
84
|
+
};
|
|
85
|
+
export {};
|
|
@@ -23,3 +23,4 @@ export declare const isConsiderReferencedNS: (node: ts.Identifier) => boolean;
|
|
|
23
23
|
export declare const isTopLevel: (node: ts.Node) => boolean;
|
|
24
24
|
export declare const getTypeName: (node: ts.Identifier) => ts.QualifiedName | undefined;
|
|
25
25
|
export declare const isImportSpecifier: (node: ts.Node) => boolean;
|
|
26
|
+
export declare const isReferencedInExportedType: (node: ts.Node, symbol: ts.Symbol) => any;
|
|
@@ -151,3 +151,12 @@ export const isImportSpecifier = (node) => ts.isImportSpecifier(node.parent) ||
|
|
|
151
151
|
ts.isImportEqualsDeclaration(node.parent) ||
|
|
152
152
|
ts.isImportClause(node.parent) ||
|
|
153
153
|
ts.isNamespaceImport(node.parent);
|
|
154
|
+
const isExported = (node) => {
|
|
155
|
+
if (node.modifiers?.find(mod => mod.kind === ts.SyntaxKind.ExportKeyword))
|
|
156
|
+
return true;
|
|
157
|
+
return node.parent ? isExported(node.parent) : false;
|
|
158
|
+
};
|
|
159
|
+
export const isReferencedInExportedType = (node, symbol) => symbol.exportSymbol &&
|
|
160
|
+
!(node.transformFlags & ts.TransformFlags.ContainsTypeScript) &&
|
|
161
|
+
Boolean(node.parent.transformFlags & ts.TransformFlags.ContainsTypeScript) &&
|
|
162
|
+
isExported(node.parent);
|
|
@@ -5,8 +5,9 @@ import { timerify } from '../util/Performance.js';
|
|
|
5
5
|
import { addNsValue, addValue, createImports } from '../util/dependency-graph.js';
|
|
6
6
|
import { isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
|
|
7
7
|
import { extname, isInNodeModules } from '../util/path.js';
|
|
8
|
+
import { isIdChar } from '../util/regex.js';
|
|
8
9
|
import { shouldIgnore } from '../util/tag.js';
|
|
9
|
-
import { getAccessMembers, getDestructuredIds, getJSDocTags, getLineAndCharacterOfPosition, getTypeName, isAccessExpression, isConsiderReferencedNS, isDestructuring, isImportSpecifier, } from './ast-helpers.js';
|
|
10
|
+
import { getAccessMembers, getDestructuredIds, getJSDocTags, getLineAndCharacterOfPosition, getTypeName, isAccessExpression, isConsiderReferencedNS, isDestructuring, isImportSpecifier, isReferencedInExportedType, } from './ast-helpers.js';
|
|
10
11
|
import getDynamicImportVisitors from './visitors/dynamic-imports/index.js';
|
|
11
12
|
import getExportVisitors from './visitors/exports/index.js';
|
|
12
13
|
import { getImportsFromPragmas } from './visitors/helpers.js';
|
|
@@ -28,12 +29,13 @@ const createMember = (node, member, pos) => {
|
|
|
28
29
|
line: line + 1,
|
|
29
30
|
col: character + 1,
|
|
30
31
|
fix: member.fix,
|
|
31
|
-
refs: 0,
|
|
32
|
+
refs: [0, false],
|
|
32
33
|
jsDocTags: getJSDocTags(member.node),
|
|
33
34
|
};
|
|
34
35
|
};
|
|
36
|
+
const isType = (item) => item.type === 'type' || item.type === 'interface' || item.type === 'member';
|
|
35
37
|
const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) => {
|
|
36
|
-
const { skipTypeOnly, tags } = options;
|
|
38
|
+
const { skipTypeOnly, tags, ignoreExportsUsedInFile } = options;
|
|
37
39
|
const internalImports = new Map();
|
|
38
40
|
const externalImports = new Set();
|
|
39
41
|
const unresolvedImports = new Set();
|
|
@@ -44,6 +46,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
44
46
|
const scripts = new Set();
|
|
45
47
|
const traceRefs = new Set();
|
|
46
48
|
const importedInternalSymbols = new Map();
|
|
49
|
+
const referencedSymbolsInExportedTypes = new Set();
|
|
47
50
|
const visitors = getVisitors(sourceFile);
|
|
48
51
|
const addInternalImport = (options) => {
|
|
49
52
|
const { identifier, symbol, filePath, namespace, specifier, isReExport } = options;
|
|
@@ -186,7 +189,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
186
189
|
line: line + 1,
|
|
187
190
|
col: character + 1,
|
|
188
191
|
fixes: fix ? [fix] : [],
|
|
189
|
-
refs: 0,
|
|
192
|
+
refs: [0, false],
|
|
190
193
|
isReExport,
|
|
191
194
|
});
|
|
192
195
|
}
|
|
@@ -282,6 +285,9 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
282
285
|
}
|
|
283
286
|
}
|
|
284
287
|
}
|
|
288
|
+
if (ignoreExportsUsedInFile && !isTopLevel && isReferencedInExportedType(node, symbol)) {
|
|
289
|
+
referencedSymbolsInExportedTypes.add(symbol.exportSymbol);
|
|
290
|
+
}
|
|
285
291
|
}
|
|
286
292
|
}
|
|
287
293
|
if (isTopLevel &&
|
|
@@ -304,34 +310,40 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options) =
|
|
|
304
310
|
return;
|
|
305
311
|
const symbols = new Set();
|
|
306
312
|
let index = 0;
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
break;
|
|
313
|
+
const text = sourceFile.text;
|
|
314
|
+
const id = item.identifier;
|
|
315
|
+
while (index < text.length && (index = text.indexOf(id, index)) !== -1) {
|
|
316
|
+
if (!isIdChar(text.charAt(index - 1)) && !isIdChar(text.charAt(index + id.length))) {
|
|
317
|
+
const isDeclaration = index === item.pos || index === item.pos + 1;
|
|
318
|
+
if (!isDeclaration) {
|
|
319
|
+
const symbol = typeChecker.getSymbolAtLocation(ts.getTokenAtPosition(sourceFile, index));
|
|
320
|
+
if (symbol) {
|
|
321
|
+
const isInExportedType = referencedSymbolsInExportedTypes.has(symbol);
|
|
322
|
+
if (item.symbol === symbol) {
|
|
323
|
+
item.refs = [1, isInExportedType];
|
|
324
|
+
if (isInExportedType || isType(item))
|
|
325
|
+
break;
|
|
321
326
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
327
|
+
const declaration = symbol.declarations?.[0];
|
|
328
|
+
if (declaration) {
|
|
329
|
+
if (item.symbol === declaration.name?.flowNode?.node?.symbol) {
|
|
330
|
+
item.refs = [1, isInExportedType];
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
if (ts.isImportSpecifier(declaration) && symbols.has(symbol)) {
|
|
334
|
+
item.refs = [1, isInExportedType];
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
325
337
|
}
|
|
338
|
+
symbols.add(symbol);
|
|
326
339
|
}
|
|
327
|
-
symbols.add(symbol);
|
|
328
340
|
}
|
|
329
341
|
}
|
|
330
|
-
index +=
|
|
342
|
+
index += id.length;
|
|
331
343
|
}
|
|
332
344
|
};
|
|
333
345
|
for (const item of exports.values()) {
|
|
334
|
-
if (
|
|
346
|
+
if (ignoreExportsUsedInFile)
|
|
335
347
|
setRefs(item);
|
|
336
348
|
for (const member of item.members) {
|
|
337
349
|
setRefs(member);
|
package/dist/util/regex.d.ts
CHANGED
package/dist/util/regex.js
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export const toRegexOrString = (value) => typeof value === 'string' && /[*+\\(|{^$]/.test(value) ? new RegExp(value) : value;
|
|
2
2
|
export const findMatch = (haystack, needle) => haystack?.find(n => (typeof n === 'string' ? n === needle : n.test(needle)));
|
|
3
|
+
const idCharMatch = /[a-zA-Z0-9$_]/;
|
|
4
|
+
export const isIdChar = (text) => idCharMatch.test(text);
|
package/dist/util/tag.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Tags } from '../types/cli.js';
|
|
2
2
|
export declare const splitTags: (rawTags: string[]) => Tags;
|
|
3
3
|
export declare const shouldIgnore: (jsDocTags: Set<string>, tags: Tags) => boolean;
|
|
4
|
-
export declare const getShouldIgnoreHandler: (
|
|
4
|
+
export declare const getShouldIgnoreHandler: (isProduction: boolean) => (jsDocTags: Set<string>) => boolean;
|
|
5
|
+
export declare const getShouldIgnoreTagHandler: (tags: Tags) => (jsDocTags: Set<string>) => boolean;
|
package/dist/util/tag.js
CHANGED
|
@@ -16,8 +16,8 @@ export const shouldIgnore = (jsDocTags, tags) => {
|
|
|
16
16
|
return true;
|
|
17
17
|
return false;
|
|
18
18
|
};
|
|
19
|
-
export const getShouldIgnoreHandler = (
|
|
19
|
+
export const getShouldIgnoreHandler = (isProduction) => (jsDocTags) => jsDocTags.has('@public') ||
|
|
20
20
|
jsDocTags.has('@beta') ||
|
|
21
21
|
jsDocTags.has('@alias') ||
|
|
22
|
-
shouldIgnore(jsDocTags, tags) ||
|
|
23
22
|
(isProduction && jsDocTags.has('@internal'));
|
|
23
|
+
export const getShouldIgnoreTagHandler = (tags) => (jsDocTags) => shouldIgnore(jsDocTags, tags);
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "5.
|
|
1
|
+
export declare const version = "5.23.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '5.
|
|
1
|
+
export const version = '5.23.0';
|