knip 2.0.0-alpha.9 → 2.0.0-beta.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.
@@ -1,11 +1,11 @@
1
1
  import parseArgs from 'minimist';
2
2
  import { isInNodeModules, join } from '../../util/path.js';
3
- import { tryResolve } from '../../util/require.js';
3
+ import { _tryResolve } from '../../util/require.js';
4
4
  const tryResolveFilePath = (cwd, specifier, fallback) => {
5
5
  if (specifier) {
6
6
  const filePath = join(cwd, specifier);
7
7
  if (!isInNodeModules(filePath)) {
8
- const resolvedFilePath = tryResolve(filePath);
8
+ const resolvedFilePath = _tryResolve(filePath, cwd);
9
9
  if (resolvedFilePath)
10
10
  return [resolvedFilePath];
11
11
  }
@@ -6,7 +6,7 @@ type ConfigurationManagerOptions = {
6
6
  cwd: string;
7
7
  isProduction: boolean;
8
8
  };
9
- type Workspace = {
9
+ export type Workspace = {
10
10
  name: string;
11
11
  pkgName?: string;
12
12
  dir: string;
@@ -41,13 +41,7 @@ export declare class ConfigurationChief {
41
41
  private getManifestWorkspaces;
42
42
  private getAdditionalWorkspaces;
43
43
  private getAllWorkspaces;
44
- getEnabledWorkspaces(): {
45
- name: string;
46
- pkgName: string | undefined;
47
- dir: string;
48
- config: WorkspaceConfiguration;
49
- ancestors: string[];
50
- }[];
44
+ getEnabledWorkspaces(): Workspace[];
51
45
  getDescendentWorkspaces(name: string): string[];
52
46
  getIgnoredWorkspaces(): string[];
53
47
  getIgnoredWorkspacesFor(name: string): string[];
@@ -191,7 +191,7 @@ export class ConfigurationChief {
191
191
  const workspaces = rawWorkspaceArg
192
192
  ? [workspace, ...allWorkspaces.reduce(getAncestors(workspace), [])]
193
193
  : allWorkspaces;
194
- return workspaces.sort(byPathDepth).map(name => ({
194
+ return workspaces.sort(byPathDepth).map((name) => ({
195
195
  name,
196
196
  pkgName: this.manifestWorkspaces.get(name) ?? this.manifest?.name,
197
197
  dir: join(this.cwd, name),
@@ -1,4 +1,4 @@
1
- import { WorkspaceConfiguration } from './types/config.js';
1
+ import { Workspace } from './configuration-chief.js';
2
2
  import type { Issue } from './types/issues.js';
3
3
  import type { WorkspaceManifests } from './types/workspace.js';
4
4
  import type { PeerDependencies, InstalledBinaries } from './types/workspace.js';
@@ -38,12 +38,7 @@ export declare class DependencyDeputy {
38
38
  addReferencedDependency(workspaceName: string, packageName: string): void;
39
39
  addPeerDependencies(workspaceName: string, peerDependencies: Map<string, Set<string>>): void;
40
40
  getPeerDependencies(workspaceName: string, dependency: string): string[];
41
- maybeAddReferencedExternalDependency(workspace: {
42
- name: string;
43
- dir: string;
44
- config: WorkspaceConfiguration;
45
- ancestors: string[];
46
- }, packageName: string): boolean;
41
+ maybeAddReferencedExternalDependency(workspace: Workspace, packageName: string): boolean;
47
42
  private isInDependencies;
48
43
  settleDependencyIssues(): {
49
44
  dependencyIssues: Issue[];
@@ -67,6 +67,8 @@ export class DependencyDeputy {
67
67
  maybeAddReferencedExternalDependency(workspace, packageName) {
68
68
  if (isBuiltin(packageName))
69
69
  return true;
70
+ if (packageName === workspace.pkgName)
71
+ return true;
70
72
  const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...[...workspace.ancestors].reverse()];
71
73
  const closestWorkspaceName = workspaceNames.find(name => this.isInDependencies(name, packageName));
72
74
  if (this.getWorkspaceManifest(workspace.name)?.ignoreDependencies.includes(packageName))
package/dist/index.js CHANGED
@@ -5,13 +5,14 @@ import { DependencyDeputy } from './dependency-deputy.js';
5
5
  import { IssueCollector } from './issue-collector.js';
6
6
  import { PrincipalFactory } from './principal-factory.js';
7
7
  import { compact } from './util/array.js';
8
- import { debugLogObject, debugLogArray } from './util/debug.js';
8
+ import { debugLogObject, debugLogArray, debugLog } from './util/debug.js';
9
9
  import { ConfigurationError } from './util/errors.js';
10
10
  import { findFile } from './util/fs.js';
11
11
  import { _glob } from './util/glob.js';
12
12
  import { getPackageNameFromFilePath, getPackageNameFromModuleSpecifier } from './util/modules.js';
13
13
  import { dirname, isInNodeModules, join, isInternal, isAbsolute } from './util/path.js';
14
- import { _require, _resolve } from './util/require.js';
14
+ import { _resolveSpecifier, _tryResolve } from './util/require.js';
15
+ import { _require } from './util/require.js';
15
16
  import { loadTSConfig as loadCompilerOptions } from './util/tsconfig-loader.js';
16
17
  import { WorkspaceWorker } from './workspace-worker.js';
17
18
  export const main = async (unresolvedConfiguration) => {
@@ -21,8 +22,8 @@ export const main = async (unresolvedConfiguration) => {
21
22
  const deputy = new DependencyDeputy({ isStrict });
22
23
  const factory = new PrincipalFactory();
23
24
  const collector = new IssueCollector({ cwd });
24
- const console = new ConsoleStreamer({ isEnabled: isShowProgress });
25
- console.cast('Reading workspace configuration(s)...');
25
+ const streamer = new ConsoleStreamer({ isEnabled: isShowProgress });
26
+ streamer.cast('Reading workspace configuration(s)...');
26
27
  await chief.init();
27
28
  const compilers = chief.getCompilers();
28
29
  const workspaces = chief.getEnabledWorkspaces();
@@ -33,7 +34,7 @@ export const main = async (unresolvedConfiguration) => {
33
34
  const { name, dir, config, ancestors } = workspace;
34
35
  const { paths, ignoreDependencies } = config;
35
36
  const isRoot = name === ROOT_WORKSPACE_NAME;
36
- console.cast(`Analyzing workspace (${name})...`);
37
+ streamer.cast(`Analyzing workspace (${name})...`);
37
38
  const manifestPath = isRoot ? chief.manifestPath : findFile(dir, 'package.json');
38
39
  const manifest = isRoot ? chief.manifest : manifestPath && _require(manifestPath);
39
40
  if (!manifestPath || !manifest)
@@ -122,9 +123,14 @@ export const main = async (unresolvedConfiguration) => {
122
123
  enabledPluginsStore.set(name, enabledPlugins);
123
124
  referencedDependencies.forEach(([containingFilePath, specifier]) => {
124
125
  if (isInternal(specifier)) {
125
- const filePath = _resolve(isAbsolute(specifier) ? specifier : join(dirname(containingFilePath), specifier));
126
- if (filePath)
126
+ const absSpecifier = isAbsolute(specifier) ? specifier : join(dirname(containingFilePath), specifier);
127
+ const filePath = _tryResolve(absSpecifier, containingFilePath);
128
+ if (filePath) {
127
129
  principal.addEntryPath(filePath);
130
+ }
131
+ else {
132
+ collector.addIssue({ type: 'unresolved', filePath: containingFilePath, symbol: specifier });
133
+ }
128
134
  }
129
135
  else {
130
136
  if (isInNodeModules(specifier)) {
@@ -139,17 +145,21 @@ export const main = async (unresolvedConfiguration) => {
139
145
  if (!isHandled)
140
146
  collector.addIssue({ type: 'unlisted', filePath: containingFilePath, symbol: specifier });
141
147
  const otherWorkspace = chief.findWorkspaceByPackageName(packageName);
142
- if (otherWorkspace && specifier !== packageName && workspace !== otherWorkspace) {
143
- const relativeSpecifier = specifier.replace(new RegExp(`^${packageName}`), '.');
144
- const filePath = _resolve(join(otherWorkspace.dir, relativeSpecifier));
145
- if (filePath)
148
+ if (otherWorkspace && specifier !== packageName) {
149
+ const filePath = _resolveSpecifier(otherWorkspace.dir, specifier);
150
+ if (filePath) {
146
151
  principal.addEntryPath(filePath);
152
+ }
153
+ else {
154
+ collector.addIssue({ type: 'unresolved', filePath: containingFilePath, symbol: specifier });
155
+ }
147
156
  }
148
157
  }
149
158
  }
150
159
  });
151
160
  }
152
161
  const principals = factory.getPrincipals();
162
+ debugLog(`Installed ${principals.length} principals for ${workspaces.length} workspaces`);
153
163
  for (const principal of principals) {
154
164
  const exportedSymbols = new Map();
155
165
  const importedSymbols = new Map();
@@ -164,8 +174,13 @@ export const main = async (unresolvedConfiguration) => {
164
174
  for (const [specifierFilePath, importItems] of internal.entries()) {
165
175
  const packageName = getPackageNameFromModuleSpecifier(importItems.specifier);
166
176
  const importedWorkspace = chief.findWorkspaceByPackageName(packageName);
167
- if (importedWorkspace && importedWorkspace !== workspace) {
168
- external.add(importItems.specifier);
177
+ if (importedWorkspace) {
178
+ if (importedWorkspace === workspace) {
179
+ principal.addEntryPath(specifierFilePath);
180
+ }
181
+ else {
182
+ external.add(importItems.specifier);
183
+ }
169
184
  }
170
185
  if (!importedSymbols.has(specifierFilePath)) {
171
186
  importedSymbols.set(specifierFilePath, importItems);
@@ -204,9 +219,9 @@ export const main = async (unresolvedConfiguration) => {
204
219
  const hasFile = (file) => entryPaths.has(file) || isExportedInEntryFile(importedSymbols.get(file));
205
220
  return isReExported ? Array.from(isReExportedBy).some(hasFile) : false;
206
221
  };
207
- console.cast('Running async compilers...');
222
+ streamer.cast('Running async compilers...');
208
223
  await principal.runAsyncCompilers();
209
- console.cast('Connecting the dots...');
224
+ streamer.cast('Connecting the dots...');
210
225
  const analyzedFiles = new Set();
211
226
  let size = principal.entryPaths.size;
212
227
  let round = 0;
@@ -214,7 +229,7 @@ export const main = async (unresolvedConfiguration) => {
214
229
  size = principal.entryPaths.size;
215
230
  const resolvedFiles = principal.getUsedResolvedFiles();
216
231
  const files = resolvedFiles.filter(filePath => !analyzedFiles.has(filePath));
217
- debugLogArray(`Analyzing used resolved files [${++round}/${principals.indexOf(principal) + 1}]`, files);
232
+ debugLogArray(`Analyzing used resolved files [P${principals.indexOf(principal) + 1}/${++round}]`, files);
218
233
  files.forEach(filePath => {
219
234
  analyzeSourceFile(filePath);
220
235
  analyzedFiles.add(filePath);
@@ -223,7 +238,7 @@ export const main = async (unresolvedConfiguration) => {
223
238
  const unusedFiles = principal.getUnreferencedFiles();
224
239
  collector.addFilesIssues(unusedFiles);
225
240
  collector.addTotalFileCount(analyzedFiles.size + unusedFiles.length);
226
- console.cast('Analyzing source files...');
241
+ streamer.cast('Analyzing source files...');
227
242
  for (const [filePath, exportItems] of exportedSymbols.entries()) {
228
243
  const importedModule = importedSymbols.get(filePath);
229
244
  if (importedModule) {
@@ -272,6 +287,6 @@ export const main = async (unresolvedConfiguration) => {
272
287
  devDependencyIssues.forEach(issue => collector.addIssue(issue));
273
288
  }
274
289
  const { issues, counters } = collector.getIssues();
275
- console.clear();
290
+ streamer.clear();
276
291
  return { report, issues, counters };
277
292
  };
@@ -36,6 +36,7 @@ export const getDependenciesDeep = async (configFilePath, dependencies = new Set
36
36
  if (isInternal(extend)) {
37
37
  const filePath = isAbsolute(extend) ? extend : join(dirname(configFilePath), extend);
38
38
  const extendConfigFilePath = _resolve(filePath);
39
+ dependencies.add(extendConfigFilePath);
39
40
  addAll(await getDependenciesDeep(extendConfigFilePath, dependencies, options));
40
41
  }
41
42
  }
@@ -7,7 +7,6 @@ type Principal = {
7
7
  principal: ProjectPrincipal;
8
8
  cwds: Set<string>;
9
9
  paths: Set<string>;
10
- isDefaultBaseUrl: boolean;
11
10
  };
12
11
  type Principals = Set<Principal>;
13
12
  type Options = {
@@ -9,7 +9,6 @@ const mergePaths = (cwd, compilerOptions = {}, paths = {}) => {
9
9
  }, {});
10
10
  return compilerOptions;
11
11
  };
12
- const hasDefaultBaseUrl = (compilerOptions) => !compilerOptions.baseUrl || /^\.\/?$/.test(compilerOptions.baseUrl);
13
12
  export class PrincipalFactory {
14
13
  principals = new Set();
15
14
  getPrincipal({ cwd, compilerOptions, report, paths, compilers }) {
@@ -24,10 +23,13 @@ export class PrincipalFactory {
24
23
  }
25
24
  }
26
25
  findReusablePrincipal(compilerOptions) {
27
- if (!hasDefaultBaseUrl(compilerOptions))
28
- return;
29
26
  const workspacePaths = compilerOptions?.paths ? Object.keys(compilerOptions.paths) : [];
30
- const principal = Array.from(this.principals).find(principal => principal.isDefaultBaseUrl && workspacePaths.every(p => !principal.paths.has(p)));
27
+ const principal = Array.from(this.principals).find(principal => {
28
+ if (compilerOptions.baseUrl === principal.principal.compilerOptions.baseUrl) {
29
+ return workspacePaths.every(p => !principal.paths.has(p));
30
+ }
31
+ return !compilerOptions.baseUrl;
32
+ });
31
33
  return principal;
32
34
  }
33
35
  linkPrincipal(principal, cwd, paths) {
@@ -38,9 +40,8 @@ export class PrincipalFactory {
38
40
  addNewPrincipal({ cwd, compilerOptions, report, compilers }) {
39
41
  const principal = new ProjectPrincipal({ cwd, compilerOptions, report, compilers });
40
42
  const paths = new Set(Object.keys(compilerOptions?.paths ?? {}));
41
- const isDefaultBaseUrl = hasDefaultBaseUrl(compilerOptions);
42
43
  compilerOptions.baseUrl = join(cwd, compilerOptions.baseUrl ?? '.');
43
- this.principals.add({ principal, cwds: new Set([cwd]), paths, isDefaultBaseUrl });
44
+ this.principals.add({ principal, cwds: new Set([cwd]), paths });
44
45
  return principal;
45
46
  }
46
47
  getPrincipals() {
@@ -1,5 +1,6 @@
1
1
  import { isBuiltin } from 'node:module';
2
2
  import ts from 'typescript';
3
+ import { isInNodeModules } from '../util/path.js';
3
4
  import * as ast from './ast-helpers.js';
4
5
  export const getImportsAndExports = (sourceFile, options) => {
5
6
  const internalImports = new Map();
@@ -8,6 +9,33 @@ export const getImportsAndExports = (sourceFile, options) => {
8
9
  const exports = new Map();
9
10
  const aliasedExports = {};
10
11
  const importedInternalSymbols = new Map();
12
+ const addInternalImport = ({ identifier = '__anonymous', specifier, symbol, filePath, }) => {
13
+ const isStar = identifier === '*';
14
+ const isReExported = Boolean(isStar && !symbol);
15
+ if (!internalImports.has(filePath)) {
16
+ internalImports.set(filePath, {
17
+ specifier,
18
+ isStar,
19
+ isReExported,
20
+ isReExportedBy: new Set(),
21
+ symbols: new Set(),
22
+ });
23
+ }
24
+ const internalImport = internalImports.get(filePath);
25
+ if (isReExported) {
26
+ internalImport.isReExported = isReExported;
27
+ internalImport.isReExportedBy.add(sourceFile.fileName);
28
+ }
29
+ if (isStar) {
30
+ internalImport.isStar = isStar;
31
+ }
32
+ if (!isStar) {
33
+ internalImport.symbols.add(identifier);
34
+ }
35
+ if (isStar && symbol) {
36
+ importedInternalSymbols.set(symbol, filePath);
37
+ }
38
+ };
11
39
  const addImport = ({ specifier, symbol, identifier = '__anonymous' }) => {
12
40
  if (isBuiltin(specifier))
13
41
  return;
@@ -16,7 +44,10 @@ export const getImportsAndExports = (sourceFile, options) => {
16
44
  const filePath = module.resolvedModule.resolvedFileName;
17
45
  if (filePath) {
18
46
  if (module.resolvedModule.isExternalLibraryImport) {
19
- if (ast.isDeclarationFileExtension(module.resolvedModule.extension)) {
47
+ if (!isInNodeModules(filePath)) {
48
+ addInternalImport({ identifier, specifier, symbol, filePath });
49
+ }
50
+ else if (ast.isDeclarationFileExtension(module.resolvedModule.extension)) {
20
51
  externalImports.add(specifier);
21
52
  }
22
53
  else {
@@ -24,31 +55,7 @@ export const getImportsAndExports = (sourceFile, options) => {
24
55
  }
25
56
  }
26
57
  else {
27
- const isStar = identifier === '*';
28
- const isReExported = Boolean(isStar && !symbol);
29
- if (!internalImports.has(filePath)) {
30
- internalImports.set(filePath, {
31
- specifier,
32
- isStar,
33
- isReExported,
34
- isReExportedBy: new Set(),
35
- symbols: new Set(),
36
- });
37
- }
38
- const internalImport = internalImports.get(filePath);
39
- if (isReExported) {
40
- internalImport.isReExported = isReExported;
41
- internalImport.isReExportedBy.add(sourceFile.fileName);
42
- }
43
- if (isStar) {
44
- internalImport.isStar = isStar;
45
- }
46
- if (!isStar) {
47
- internalImport.symbols.add(identifier);
48
- }
49
- if (isStar && symbol) {
50
- importedInternalSymbols.set(symbol, filePath);
51
- }
58
+ addInternalImport({ identifier, specifier, symbol, filePath });
52
59
  }
53
60
  }
54
61
  }
@@ -1,12 +1,13 @@
1
1
  import { createRequire } from 'node:module';
2
2
  import { EOL } from 'node:os';
3
3
  import path from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
4
5
  import ts from 'typescript';
5
6
  import { createCustomModuleResolver } from './resolveModuleNames.js';
6
7
  import { SourceFileManager } from './SourceFileManager.js';
7
8
  import { createCustomSys } from './sys.js';
8
9
  const cwd = process.cwd();
9
- const require = createRequire(import.meta.url);
10
+ const require = createRequire(pathToFileURL(import.meta.url));
10
11
  const libLocation = path.dirname(require.resolve('typescript', { paths: [cwd] }));
11
12
  const fileManager = new SourceFileManager();
12
13
  export const createHosts = ({ cwd, compilerOptions, entryPaths, compilers }) => {
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="nano-memoize" />
3
2
  export declare const prependDirToPattern: (workingDir: string, pattern: string) => string;
4
3
  export declare const negate: (pattern: string) => string;
5
4
  export declare const hasProductionSuffix: (pattern: string) => boolean;
@@ -13,8 +12,8 @@ interface GlobOptions extends BaseGlobOptions {
13
12
  workingDir?: string;
14
13
  gitignore?: boolean;
15
14
  }
16
- export declare const _glob: (({ cwd, workingDir, patterns, ignore, gitignore }: GlobOptions) => Promise<string[]>) & import("nano-memoize").nanomemoize;
15
+ export declare const _glob: ({ cwd, workingDir, patterns, ignore, gitignore }: GlobOptions) => Promise<string[]>;
17
16
  export declare const _pureGlob: ({ cwd, patterns, ignore }: BaseGlobOptions) => Promise<string[]>;
18
- export declare const _firstGlob: (({ cwd, patterns }: BaseGlobOptions) => Promise<string | Buffer | undefined>) & import("nano-memoize").nanomemoize;
17
+ export declare const _firstGlob: ({ cwd, patterns }: BaseGlobOptions) => Promise<string | Buffer | undefined>;
19
18
  export declare const _dirGlob: ({ cwd, patterns }: BaseGlobOptions) => Promise<string[]>;
20
19
  export {};
package/dist/util/glob.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import fg from 'fast-glob';
2
2
  import { globby } from 'globby';
3
- import memoize from 'nano-memoize';
4
3
  import { ROOT_WORKSPACE_NAME } from '../constants.js';
5
4
  import { compact } from './array.js';
6
5
  import { debugLogObject } from './debug.js';
@@ -45,12 +44,7 @@ const dirGlob = async ({ cwd, patterns }) => globby(patterns, {
45
44
  cwd,
46
45
  onlyDirectories: true,
47
46
  });
48
- const memoOptions = { serializer: JSON.stringify, callTimeout: 0 };
49
- const memoizedGlob = memoize(glob, memoOptions);
50
- Object.defineProperty(memoizedGlob, 'name', { value: 'glob' });
51
- const memoizedFirstGlob = memoize(firstGlob, memoOptions);
52
- Object.defineProperty(memoizedFirstGlob, 'name', { value: 'firstGlob' });
53
- export const _glob = timerify(memoizedGlob);
47
+ export const _glob = timerify(glob);
54
48
  export const _pureGlob = timerify(pureGlob);
55
- export const _firstGlob = timerify(memoizedFirstGlob);
49
+ export const _firstGlob = timerify(firstGlob);
56
50
  export const _dirGlob = timerify(dirGlob);
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
- export declare const tryResolve: (specifier: string) => string | undefined;
3
2
  export declare const _require: NodeRequire;
4
3
  export declare const _resolve: (specifier: string) => string;
4
+ export declare const _tryResolve: (specifier: string, from: string) => string | undefined;
5
+ export declare const _resolveSpecifier: (dir: string, specifier: string) => string | undefined;
@@ -1,14 +1,31 @@
1
- import { createRequire } from 'node:module';
2
- import { toPosix } from './path.js';
1
+ import { createRequire as nodeCreateRequire } from 'node:module';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { debugLog } from './debug.js';
4
+ import { getPackageNameFromModuleSpecifier } from './modules.js';
5
+ import { cwd, toPosix, join } from './path.js';
3
6
  import { timerify } from './performance.js';
4
- const require = createRequire(process.cwd());
7
+ const createRequire = (path) => nodeCreateRequire(pathToFileURL(path ?? cwd));
8
+ const require = createRequire();
5
9
  const resolve = (specifier) => toPosix(require.resolve(specifier));
6
- export const tryResolve = (specifier) => {
10
+ const tryResolve = (specifier, from) => {
7
11
  try {
8
12
  return resolve(specifier);
9
13
  }
10
- catch (error) {
14
+ catch {
15
+ debugLog(`Unable to resolve ${specifier} (from ${from})`);
16
+ }
17
+ };
18
+ const resolveSpecifier = (dir, specifier) => {
19
+ try {
20
+ const require = createRequire(join(dir, 'package.json'));
21
+ return toPosix(require.resolve(specifier));
22
+ }
23
+ catch {
24
+ const relativeSpecifier = specifier.replace(getPackageNameFromModuleSpecifier(specifier), '.');
25
+ return tryResolve(join(dir, relativeSpecifier), dir);
11
26
  }
12
27
  };
13
28
  export const _require = timerify(require);
14
29
  export const _resolve = timerify(resolve);
30
+ export const _tryResolve = timerify(tryResolve);
31
+ export const _resolveSpecifier = timerify(resolveSpecifier);
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "2.0.0-alpha.9";
1
+ export declare const version = "2.0.0-beta.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.0.0-alpha.9';
1
+ export const version = '2.0.0-beta.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0-beta.0",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",
@@ -51,7 +51,6 @@
51
51
  "js-yaml": "^4.1.0",
52
52
  "micromatch": "^4.0.5",
53
53
  "minimist": "^1.2.8",
54
- "nano-memoize": "^2.0.0",
55
54
  "pretty-ms": "^8.0.0",
56
55
  "strip-json-comments": "^5.0.0",
57
56
  "summary": "^2.1.0",