Skip to content

Commit 6fded2f

Browse files
committed
Introduce Manifest wrapper with scriptNames + getMajor helpers
1 parent 200db55 commit 6fded2f

13 files changed

Lines changed: 62 additions & 57 deletions

File tree

packages/knip/src/WorkspaceWorker.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type { ConfigurationHint } from './types/issues.ts';
1919
import type { PluginName } from './types/PluginNames.ts';
2020
import type { PackageJson } from './types/package-json.ts';
2121
import type { DependencySet } from './types/workspace.ts';
22+
import { createManifest, type Manifest } from './util/package-json.ts';
2223
import { collectStringLiterals, isExternalReExportsOnly } from './typescript/ast-helpers.ts';
2324
import { parseFile } from './typescript/visitors/helpers.ts';
2425
import { compact } from './util/array.ts';
@@ -50,7 +51,7 @@ type WorkspaceManagerOptions = {
5051
config: WorkspaceConfiguration;
5152
manifest: PackageJson;
5253
dependencies: DependencySet;
53-
rootManifest: PackageJson | undefined;
54+
rootManifest: Manifest | undefined;
5455
handleInput: HandleInput;
5556
findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
5657
readFile: (filePath: string) => string;
@@ -80,8 +81,8 @@ export class WorkspaceWorker {
8081
name: string;
8182
dir: string;
8283
config: WorkspaceConfiguration;
83-
manifest: PackageJson;
84-
rootManifest: PackageJson | undefined;
84+
manifest: Manifest;
85+
rootManifest: Manifest | undefined;
8586
dependencies: DependencySet;
8687
handleInput: HandleInput;
8788
findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
@@ -118,7 +119,7 @@ export class WorkspaceWorker {
118119
this.name = name;
119120
this.dir = dir;
120121
this.config = config;
121-
this.manifest = manifest;
122+
this.manifest = createManifest(manifest);
122123
this.rootManifest = rootManifest;
123124
this.dependencies = dependencies;
124125
this.negatedWorkspacePatterns = negatedWorkspacePatterns;
@@ -296,12 +297,11 @@ export class WorkspaceWorker {
296297
const isProduction = this.options.isProduction;
297298
const knownBinsOnly = false;
298299

299-
const manifestScriptNames = new Set(Object.keys(manifest.scripts ?? {}));
300300
const rootManifest = this.rootManifest;
301-
const baseOptions = { manifestScriptNames, rootManifest, cwd, rootCwd, containingFilePath, knownBinsOnly };
301+
const baseOptions = { manifest, rootManifest, cwd, rootCwd, containingFilePath, knownBinsOnly };
302302

303303
// Get dependencies from package.json#scripts
304-
const baseScriptOptions = { ...baseOptions, manifest, isProduction, enabledPlugins: this.enabledPlugins };
304+
const baseScriptOptions = { ...baseOptions, isProduction, enabledPlugins: this.enabledPlugins };
305305
const [productionScripts, developmentScripts] = getFilteredScripts(manifest.scripts ?? {});
306306
const inputsFromManifest = _getInputsFromScripts(Object.values(developmentScripts), baseOptions);
307307
const productionInputsFromManifest = _getInputsFromScripts(Object.values(productionScripts), baseOptions);

packages/knip/src/binaries/plugins.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const isGlobLike = (value: string) => isGlobLikeMatch.test(value);
1313
const nodeLoadersArgs = { import: ['r', 'experimental-loader', 'require', 'loader'] };
1414

1515
export const resolve: BinaryResolver = (binary, _args, options) => {
16-
const { cwd, fromArgs, containingFilePath } = options;
16+
const { cwd, fromArgs, containingFilePath, manifest } = options;
1717
const [pluginName, pluginArgs] = pluginArgsMap.get(binary) ?? [];
1818

1919
if (!pluginArgs) return fallbackResolve(binary, _args, options);
@@ -69,7 +69,7 @@ export const resolve: BinaryResolver = (binary, _args, options) => {
6969
};
7070
const configFilePaths = config.flatMap(mapToConfigPattern);
7171

72-
const inputs: Input[] = pluginArgs.resolveInputs?.(parsed, { args, cwd }) ?? [];
72+
const inputs: Input[] = pluginArgs.resolveInputs?.(parsed, { args, cwd, manifest }) ?? [];
7373

7474
return [
7575
toBinary(binary, inputOpts),

packages/knip/src/binaries/resolvers/bun.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ export const resolve: BinaryResolver = (_binary, args, options) => {
6262
return resolveX(argsForX, options);
6363
}
6464

65-
const { manifestScriptNames, cwd, fromArgs } = options;
65+
const { manifest, cwd, fromArgs } = options;
6666

67-
if (command === 'run' && manifestScriptNames.has(script)) return [];
68-
if (manifestScriptNames.has(command)) return [];
67+
if (command === 'run' && manifest.scriptNames.has(script)) return [];
68+
if (manifest.scriptNames.has(command)) return [];
6969
if (command !== 'run' && commands.has(command)) return [];
7070

7171
const filePath = command === 'run' ? script : command;

packages/knip/src/binaries/resolvers/npm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import parseArgs from 'minimist';
22
import type { BinaryResolver } from '../../types/config.ts';
33

44
export const resolve: BinaryResolver = (_binary, args, options) => {
5-
const { fromArgs, manifestScriptNames } = options;
5+
const { fromArgs, manifest } = options;
66
const parsed = parseArgs(args, { '--': true });
77
const [command, script] = parsed._;
88
const _childArgs = parsed['--'] && parsed['--'].length > 0 ? fromArgs(parsed['--'], { knownBinsOnly: true }) : [];
99
if (command === 'exec') return _childArgs;
10-
if (command === 'run' && manifestScriptNames.has(script)) return _childArgs;
10+
if (command === 'run' && manifest.scriptNames.has(script)) return _childArgs;
1111
return [];
1212
};

packages/knip/src/binaries/resolvers/pnpm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export const resolve: BinaryResolver = (_binary, args, options) => {
8080
return resolveDlx(argsForDlx, options);
8181
}
8282

83-
const { manifestScriptNames, fromArgs } = options;
83+
const { manifest, fromArgs } = options;
8484

8585
if (parsed.filter && !parsed.recursive) return [];
8686

@@ -90,7 +90,7 @@ export const resolve: BinaryResolver = (_binary, args, options) => {
9090
return childInputs.length > 0 ? childInputs : fromArgs(parsed._.slice(1));
9191
}
9292

93-
const isScript = manifestScriptNames.has(command);
93+
const isScript = manifest.scriptNames.has(command);
9494
if (isScript || commands.includes(command)) return childInputs;
9595

9696
return command && isValidBinary(command) ? [toBinary(command)] : [];

packages/knip/src/binaries/resolvers/yarn.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const resolveDlx = (args: string[], options: BinaryResolverOptions) => {
5757
};
5858

5959
export const resolve: BinaryResolver = (_binary, args, options) => {
60-
const { manifestScriptNames, fromArgs, cwd, rootCwd } = options;
60+
const { manifest, fromArgs, cwd, rootCwd } = options;
6161
const parsed = parseArgs(args, { boolean: ['top-level'], string: ['cwd'], '--': true });
6262
const dir = parsed['top-level'] ? rootCwd : parsed.cwd ? join(cwd, parsed.cwd) : undefined;
6363
const [command, binary] = parsed._;
@@ -67,7 +67,7 @@ export const resolve: BinaryResolver = (_binary, args, options) => {
6767
const _childArgs = parsed['--'] && parsed['--'].length > 0 ? fromArgs(parsed['--'], { knownBinsOnly: true }) : [];
6868

6969
if (command === 'run') {
70-
if (manifestScriptNames.has(binary)) return _childArgs;
70+
if (manifest.scriptNames.has(binary)) return _childArgs;
7171
const bin = toBinary(binary, { optional: true });
7272
if (dir) Object.assign(bin, { dir });
7373
return [bin, ..._childArgs];
@@ -80,7 +80,7 @@ export const resolve: BinaryResolver = (_binary, args, options) => {
8080
return resolveDlx(argsForDlx, options);
8181
}
8282

83-
if ((!dir && manifestScriptNames.has(command)) || commands.includes(command)) return _childArgs;
83+
if ((!dir && manifest.scriptNames.has(command)) || commands.includes(command)) return _childArgs;
8484

8585
const opts = dir ? { cwd: dir } : {};
8686
return fromArgs(argsFrom(args, command === 'exec' ? binary : command), opts);

packages/knip/src/graph/build.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type { MainOptions } from '../util/create-options.ts';
1717
import { debugLog, debugLogArray } from '../util/debug.ts';
1818
import { existsSync } from 'node:fs';
1919
import { tryRealpath } from '../util/fs.ts';
20+
import { createManifest } from '../util/package-json.ts';
2021
import { _glob, _syncGlob, negate, prependDirToPattern as prependDir } from '../util/glob.ts';
2122
import {
2223
type Input,
@@ -75,7 +76,8 @@ export async function build({
7576

7677
const handleInput = createInputHandler(deputy, chief, isGitIgnored, addIssue, externalRefsFromInputs, options);
7778

78-
const rootManifest = chief.getManifestForWorkspace('.');
79+
const rawRootManifest = chief.getManifestForWorkspace('.');
80+
const rootManifest = rawRootManifest ? createManifest(rawRootManifest) : undefined;
7981

8082
for (const workspace of workspaces) {
8183
const { name, dir, manifestPath, manifestStr } = workspace;
@@ -425,16 +427,16 @@ export async function build({
425427
}
426428
}
427429

428-
if (file.scripts && file.scripts.size > 0) {
430+
const manifest = chief.getManifestForWorkspace(workspace.name);
431+
if (manifest && file.scripts && file.scripts.size > 0) {
429432
const dependencies = deputy.getDependencies(workspace.name);
430-
const manifestScriptNames = new Set(Object.keys(chief.getManifestForWorkspace(workspace.name)?.scripts ?? {}));
431433
const dir = dirname(filePath);
432434
const opts = {
433435
cwd: dir,
434436
rootCwd: options.cwd,
435437
containingFilePath: filePath,
436438
dependencies,
437-
manifestScriptNames,
439+
manifest: createManifest(manifest),
438440
rootManifest,
439441
};
440442
const inputs = _getInputsFromScripts(file.scripts, opts);

packages/knip/src/plugins/eslint/index.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,7 @@ const config = [
3333
const isLoadConfig: IsLoadConfig = ({ configFileName, manifest }, dependencies) => {
3434
// Flat configs (eslint.config.*) are handled by resolveFromAST — skip loading
3535
if (isFlatConfig(configFileName)) return false;
36-
37-
const version = manifest.devDependencies?.['eslint'] || manifest.dependencies?.['eslint'];
38-
if (version) {
39-
const major = version.match(/\d+/);
40-
if (major && Number.parseInt(major[0], 10) === 9 && dependencies.has('eslint-config-next')) {
41-
return false;
42-
}
43-
}
36+
if (manifest.getMajor('eslint') === 9 && dependencies.has('eslint-config-next')) return false;
4437
return true;
4538
};
4639

packages/knip/src/plugins/react-email/index.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import { readFileSync } from 'node:fs';
21
import type { Args } from '../../types/args.ts';
32
import type { IsPluginEnabled, Plugin } from '../../types/config.ts';
4-
import type { PackageJson } from '../../types/package-json.ts';
53
import { toDependency, toEntry } from '../../util/input.ts';
6-
import { join } from '../../util/path.ts';
74
import { hasDependency } from '../../util/plugin.ts';
85

96
// https://react.email/docs/cli
@@ -18,21 +15,14 @@ const entry = ['emails/**/*.tsx'];
1815

1916
const previewCommands = new Set(['build', 'dev', 'start']);
2017

21-
const getPreviewDependency = (cwd: string): string => {
22-
try {
23-
const manifest: PackageJson = JSON.parse(readFileSync(join(cwd, 'package.json'), 'utf8'));
24-
const range = manifest.dependencies?.['react-email'] ?? manifest.devDependencies?.['react-email'];
25-
const major = range?.match(/\d+/)?.[0];
26-
if (major && Number.parseInt(major, 10) >= 6) return '@react-email/ui';
27-
} catch {}
28-
return '@react-email/preview-server';
29-
};
30-
3118
const args: Args = {
3219
binaries: ['email'],
33-
resolveInputs: (parsed, { cwd }) => {
20+
resolveInputs: (parsed, { manifest }) => {
3421
const inputs = [];
35-
if (previewCommands.has(parsed._[0])) inputs.push(toDependency(getPreviewDependency(cwd)));
22+
if (previewCommands.has(parsed._[0])) {
23+
const dep = (manifest.getMajor('react-email') ?? 0) >= 6 ? '@react-email/ui' : '@react-email/preview-server';
24+
inputs.push(toDependency(dep));
25+
}
3626
if (parsed.dir) inputs.push(toEntry(`${parsed.dir}/**/*.tsx`));
3727
return inputs;
3828
},

packages/knip/src/types/args.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ParsedArgs } from 'minimist';
22
import type { Input } from '../util/input.ts';
3+
import type { Manifest } from '../util/package-json.ts';
34

45
export type ConfigArg = boolean | (string | [string, (id: string) => string])[];
56

@@ -97,5 +98,5 @@ export type Args = {
9798
*
9899
* @default undefined
99100
*/
100-
resolveInputs?: (parsed: ParsedArgs, options: { cwd: string; args: string[] }) => Input[];
101+
resolveInputs?: (parsed: ParsedArgs, options: { cwd: string; args: string[]; manifest: Manifest }) => Input[];
101102
};

0 commit comments

Comments
 (0)