@xylabs/ts-scripts-yarn3 7.3.2 → 7.4.1
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/actions/cycle.mjs +1 -1
- package/dist/actions/cycle.mjs.map +1 -1
- package/dist/actions/deplint/checkPackage/checkPackage.mjs +316 -35
- package/dist/actions/deplint/checkPackage/checkPackage.mjs.map +1 -1
- package/dist/actions/deplint/checkPackage/getUnlistedDependencies.mjs +13 -6
- package/dist/actions/deplint/checkPackage/getUnlistedDependencies.mjs.map +1 -1
- package/dist/actions/deplint/checkPackage/getUnlistedDevDependencies.mjs +3 -1
- package/dist/actions/deplint/checkPackage/getUnlistedDevDependencies.mjs.map +1 -1
- package/dist/actions/deplint/checkPackage/getUnusedDevDependencies.mjs +213 -0
- package/dist/actions/deplint/checkPackage/getUnusedDevDependencies.mjs.map +1 -0
- package/dist/actions/deplint/checkPackage/index.mjs +316 -35
- package/dist/actions/deplint/checkPackage/index.mjs.map +1 -1
- package/dist/actions/deplint/deplint.mjs +319 -38
- package/dist/actions/deplint/deplint.mjs.map +1 -1
- package/dist/actions/deplint/findFiles.mjs +8 -2
- package/dist/actions/deplint/findFiles.mjs.map +1 -1
- package/dist/actions/deplint/getExtendsFromTsconfigs.mjs +44 -0
- package/dist/actions/deplint/getExtendsFromTsconfigs.mjs.map +1 -0
- package/dist/actions/deplint/getExternalImportsFromFiles.mjs +15 -1
- package/dist/actions/deplint/getExternalImportsFromFiles.mjs.map +1 -1
- package/dist/actions/deplint/getRequiredPeerDependencies.mjs +36 -0
- package/dist/actions/deplint/getRequiredPeerDependencies.mjs.map +1 -0
- package/dist/actions/deplint/getScriptReferencedPackages.mjs +81 -0
- package/dist/actions/deplint/getScriptReferencedPackages.mjs.map +1 -0
- package/dist/actions/deplint/implicitDevDependencies.mjs +75 -0
- package/dist/actions/deplint/implicitDevDependencies.mjs.map +1 -0
- package/dist/actions/deplint/index.mjs +319 -38
- package/dist/actions/deplint/index.mjs.map +1 -1
- package/dist/actions/index.mjs +423 -142
- package/dist/actions/index.mjs.map +1 -1
- package/dist/bin/xy.mjs +366 -85
- package/dist/bin/xy.mjs.map +1 -1
- package/dist/index.mjs +435 -154
- package/dist/index.mjs.map +1 -1
- package/dist/xy/index.mjs +366 -85
- package/dist/xy/index.mjs.map +1 -1
- package/dist/xy/xy.mjs +366 -85
- package/dist/xy/xy.mjs.map +1 -1
- package/dist/xy/xyLintCommands.mjs +339 -58
- package/dist/xy/xyLintCommands.mjs.map +1 -1
- package/package.json +15 -16
package/dist/actions/cycle.mjs
CHANGED
|
@@ -123,7 +123,7 @@ var cycleAll = async ({ verbose = false }) => {
|
|
|
123
123
|
combinedDependencies: true,
|
|
124
124
|
outputType: verbose ? "text" : "err"
|
|
125
125
|
};
|
|
126
|
-
const target = "**/src";
|
|
126
|
+
const target = "**/packages/*/src";
|
|
127
127
|
console.log(`Checking for circular dependencies in ${target}...`);
|
|
128
128
|
const result = await cruise([target], cruiseOptions);
|
|
129
129
|
if (result.output) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/actions/cycle.ts","../../src/lib/checkResult.ts","../../src/lib/processEx.ts","../../src/lib/withError.ts","../../src/lib/withErrnoException.ts","../../src/lib/safeExit.ts","../../src/lib/runSteps.ts"],"sourcesContent":["import { cruise, type ICruiseOptions } from 'dependency-cruiser'\n\nimport { runSteps } from '../lib/index.ts'\n\nexport interface CycleParams {\n incremental?: boolean\n jobs?: number\n pkg?: string\n verbose?: boolean\n}\n\ninterface CyclePackageParams {\n pkg: string\n verbose?: boolean\n}\n\nexport const cycle = async ({ verbose, pkg }: CycleParams = {}) => {\n return pkg\n ? cyclePackage({ pkg, verbose })\n : await cycleAll({ verbose })\n}\n\nexport const cyclePackage = ({ pkg, verbose }: CyclePackageParams) => {\n const verboseOptions = verbose ? ['--verbose'] : ['--no-verbose']\n return runSteps(\n `Cycle [${pkg}]`,\n [['yarn', ['workspace', pkg, 'run', 'package-cycle', ...verboseOptions]]],\n )\n}\n\nexport const cycleAll = async ({ verbose = false }: { verbose?: boolean }) => {\n const pkgName = process.env.npm_package_name\n\n const cruiseOptions: ICruiseOptions = {\n ruleSet: {\n forbidden: [\n {\n name: 'no-circular',\n severity: 'error',\n comment: 'This dependency creates a circular reference',\n from: {},\n to: { circular: true },\n },\n ],\n },\n exclude: 'node_modules|packages/.*/packages',\n validate: true,\n doNotFollow: { path: 'node_modules|packages/.*/packages' },\n tsPreCompilationDeps: false,\n combinedDependencies: true,\n outputType: verbose ? 'text' : 'err',\n }\n\n const target = '**/src'\n\n console.log(`Checking for circular dependencies in ${target}...`)\n\n const result = await cruise([target], cruiseOptions)\n if (result.output) {\n console.log(result.output)\n }\n\n if (result.exitCode === 0) {\n console.log(`${pkgName} ✅ No dependency violations`)\n } else {\n console.error(`${pkgName} ❌ Dependency violations found`)\n }\n return result.exitCode\n}\n","import chalk from 'chalk'\n\nexport const checkResult = (name: string, result: number, level: 'error' | 'warn' = 'error', exitOnFail = false) => {\n if (result) {\n const exiting = exitOnFail ? '[Exiting Process]' : '[Continuing]'\n const chalkFunc = level === 'error' ? chalk.red : chalk.yellow\n console[level](chalkFunc(`${name} had ${result} failures ${exiting}`))\n if (exitOnFail) {\n process.exit(result)\n }\n }\n}\n","import chalk from 'chalk'\n\nimport { withErrnoException } from './withErrnoException.ts'\nimport { withError } from './withError.ts'\n\nexport const processEx = (ex: unknown) => {\n const error = typeof ex === 'string' ? new Error(ex) : ex\n const exitCode\n = withErrnoException(error, (error) => {\n if (error.code === 'ENOENT') {\n console.error(chalk.red(`'${error.path}' not found.`))\n } else {\n console.error(chalk.red(`Errno: ${error.code}`))\n }\n return error.errno ?? -1\n })\n ?? withError(error, (error) => {\n console.error(chalk.red(`${error.name}: ${error.message}`))\n return -1\n })\n ?? (() => {\n console.error(chalk.red(`Unexpected Error: ${JSON.stringify(ex, null, 2)}`))\n return -1\n })()\n // This allows us to use a previously set exit code\n process.exit(process.exitCode ?? exitCode)\n}\n","export const withError = <T extends Error = Error>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ex: any,\n closure: (error: T) => number,\n predicate = (ex: T) => (!!ex.name && !!ex.message),\n) => {\n return predicate(ex as T) ? closure(ex as T) : undefined\n}\n","import { withError } from './withError.ts'\n\nexport const withErrnoException = <T extends NodeJS.ErrnoException = NodeJS.ErrnoException>(\n ex: unknown, closure: (error: T) => number,\n) => {\n return withError<T>(ex, closure, (ex: unknown) => (ex as NodeJS.ErrnoException).errno !== undefined)\n}\n","/** Catch child process a crash and returns the code */\n\nimport { processEx } from './processEx.ts'\n\nconst safeExit = (func: () => number, exitOnFail = true): number => {\n try {\n const result = func()\n if (result && exitOnFail) {\n process.exit(result)\n }\n return result\n } catch (ex) {\n return processEx(ex)\n }\n}\n\nconst safeExitAsync = async (func: () => Promise<number>, exitOnFail = true): Promise<number> => {\n try {\n const result = await func()\n if (result && exitOnFail) {\n process.exit(result)\n }\n return result\n } catch (ex) {\n return processEx(ex)\n }\n}\n\nexport { safeExit, safeExitAsync }\n","import type { SpawnSyncOptionsWithBufferEncoding } from 'node:child_process'\nimport { spawnSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\n\nimport chalk from 'chalk'\n\nimport { checkResult } from './checkResult.ts'\nimport { safeExit } from './safeExit.ts'\n\nexport type ScriptStep\n = | [/* command */ 'yarn' | 'node' | 'ts-node-script' | 'tsc' | 'jest' | 'npm', /* arg */ string | string[]]\n | [/* command */ string, /* arg */ string | string[], /* config */ SpawnSyncOptionsWithBufferEncoding]\n\nexport const runSteps = (name: string, steps: ScriptStep[], exitOnFail = true, messages?: string[]): number => {\n return safeExit(() => {\n const pkgName = process.env.npm_package_name\n console.log(chalk.green(`${name} [${pkgName}]`))\n let totalStatus = 0\n for (const [i, [command, args, config]] of steps.entries()) {\n if (messages?.[i]) {\n console.log(chalk.gray(messages?.[i]))\n }\n const argList = Array.isArray(args) ? args : args.split(' ')\n if (command === 'node' && !existsSync(argList[0])) {\n throw new Error(`File not found [${argList[0]}]`)\n }\n const status\n = spawnSync(command, Array.isArray(args) ? args : args.split(' '), {\n ...config,\n encoding: 'utf8',\n env: { FORCE_COLOR: '3', ...process.env },\n shell: true,\n stdio: 'inherit',\n }).status ?? 0\n checkResult(name, status, 'error', exitOnFail)\n totalStatus += status ?? 0\n }\n return totalStatus\n }, !!exitOnFail)\n}\n"],"mappings":"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","names":["chalk","ex","ex","error","chalk","chalk","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../../src/actions/cycle.ts","../../src/lib/checkResult.ts","../../src/lib/processEx.ts","../../src/lib/withError.ts","../../src/lib/withErrnoException.ts","../../src/lib/safeExit.ts","../../src/lib/runSteps.ts"],"sourcesContent":["import { cruise, type ICruiseOptions } from 'dependency-cruiser'\n\nimport { runSteps } from '../lib/index.ts'\n\nexport interface CycleParams {\n incremental?: boolean\n jobs?: number\n pkg?: string\n verbose?: boolean\n}\n\ninterface CyclePackageParams {\n pkg: string\n verbose?: boolean\n}\n\nexport const cycle = async ({ verbose, pkg }: CycleParams = {}) => {\n return pkg\n ? cyclePackage({ pkg, verbose })\n : await cycleAll({ verbose })\n}\n\nexport const cyclePackage = ({ pkg, verbose }: CyclePackageParams) => {\n const verboseOptions = verbose ? ['--verbose'] : ['--no-verbose']\n return runSteps(\n `Cycle [${pkg}]`,\n [['yarn', ['workspace', pkg, 'run', 'package-cycle', ...verboseOptions]]],\n )\n}\n\nexport const cycleAll = async ({ verbose = false }: { verbose?: boolean }) => {\n const pkgName = process.env.npm_package_name\n\n const cruiseOptions: ICruiseOptions = {\n ruleSet: {\n forbidden: [\n {\n name: 'no-circular',\n severity: 'error',\n comment: 'This dependency creates a circular reference',\n from: {},\n to: { circular: true },\n },\n ],\n },\n exclude: 'node_modules|packages/.*/packages',\n validate: true,\n doNotFollow: { path: 'node_modules|packages/.*/packages' },\n tsPreCompilationDeps: false,\n combinedDependencies: true,\n outputType: verbose ? 'text' : 'err',\n }\n\n const target = '**/packages/*/src'\n\n console.log(`Checking for circular dependencies in ${target}...`)\n\n const result = await cruise([target], cruiseOptions)\n if (result.output) {\n console.log(result.output)\n }\n\n if (result.exitCode === 0) {\n console.log(`${pkgName} ✅ No dependency violations`)\n } else {\n console.error(`${pkgName} ❌ Dependency violations found`)\n }\n return result.exitCode\n}\n","import chalk from 'chalk'\n\nexport const checkResult = (name: string, result: number, level: 'error' | 'warn' = 'error', exitOnFail = false) => {\n if (result) {\n const exiting = exitOnFail ? '[Exiting Process]' : '[Continuing]'\n const chalkFunc = level === 'error' ? chalk.red : chalk.yellow\n console[level](chalkFunc(`${name} had ${result} failures ${exiting}`))\n if (exitOnFail) {\n process.exit(result)\n }\n }\n}\n","import chalk from 'chalk'\n\nimport { withErrnoException } from './withErrnoException.ts'\nimport { withError } from './withError.ts'\n\nexport const processEx = (ex: unknown) => {\n const error = typeof ex === 'string' ? new Error(ex) : ex\n const exitCode\n = withErrnoException(error, (error) => {\n if (error.code === 'ENOENT') {\n console.error(chalk.red(`'${error.path}' not found.`))\n } else {\n console.error(chalk.red(`Errno: ${error.code}`))\n }\n return error.errno ?? -1\n })\n ?? withError(error, (error) => {\n console.error(chalk.red(`${error.name}: ${error.message}`))\n return -1\n })\n ?? (() => {\n console.error(chalk.red(`Unexpected Error: ${JSON.stringify(ex, null, 2)}`))\n return -1\n })()\n // This allows us to use a previously set exit code\n process.exit(process.exitCode ?? exitCode)\n}\n","export const withError = <T extends Error = Error>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ex: any,\n closure: (error: T) => number,\n predicate = (ex: T) => (!!ex.name && !!ex.message),\n) => {\n return predicate(ex as T) ? closure(ex as T) : undefined\n}\n","import { withError } from './withError.ts'\n\nexport const withErrnoException = <T extends NodeJS.ErrnoException = NodeJS.ErrnoException>(\n ex: unknown, closure: (error: T) => number,\n) => {\n return withError<T>(ex, closure, (ex: unknown) => (ex as NodeJS.ErrnoException).errno !== undefined)\n}\n","/** Catch child process a crash and returns the code */\n\nimport { processEx } from './processEx.ts'\n\nconst safeExit = (func: () => number, exitOnFail = true): number => {\n try {\n const result = func()\n if (result && exitOnFail) {\n process.exit(result)\n }\n return result\n } catch (ex) {\n return processEx(ex)\n }\n}\n\nconst safeExitAsync = async (func: () => Promise<number>, exitOnFail = true): Promise<number> => {\n try {\n const result = await func()\n if (result && exitOnFail) {\n process.exit(result)\n }\n return result\n } catch (ex) {\n return processEx(ex)\n }\n}\n\nexport { safeExit, safeExitAsync }\n","import type { SpawnSyncOptionsWithBufferEncoding } from 'node:child_process'\nimport { spawnSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\n\nimport chalk from 'chalk'\n\nimport { checkResult } from './checkResult.ts'\nimport { safeExit } from './safeExit.ts'\n\nexport type ScriptStep\n = | [/* command */ 'yarn' | 'node' | 'ts-node-script' | 'tsc' | 'jest' | 'npm', /* arg */ string | string[]]\n | [/* command */ string, /* arg */ string | string[], /* config */ SpawnSyncOptionsWithBufferEncoding]\n\nexport const runSteps = (name: string, steps: ScriptStep[], exitOnFail = true, messages?: string[]): number => {\n return safeExit(() => {\n const pkgName = process.env.npm_package_name\n console.log(chalk.green(`${name} [${pkgName}]`))\n let totalStatus = 0\n for (const [i, [command, args, config]] of steps.entries()) {\n if (messages?.[i]) {\n console.log(chalk.gray(messages?.[i]))\n }\n const argList = Array.isArray(args) ? args : args.split(' ')\n if (command === 'node' && !existsSync(argList[0])) {\n throw new Error(`File not found [${argList[0]}]`)\n }\n const status\n = spawnSync(command, Array.isArray(args) ? args : args.split(' '), {\n ...config,\n encoding: 'utf8',\n env: { FORCE_COLOR: '3', ...process.env },\n shell: true,\n stdio: 'inherit',\n }).status ?? 0\n checkResult(name, status, 'error', exitOnFail)\n totalStatus += status ?? 0\n }\n return totalStatus\n }, !!exitOnFail)\n}\n"],"mappings":"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","names":["chalk","ex","ex","error","chalk","chalk","chalk"]}
|
|
@@ -5,12 +5,18 @@ function findFilesByGlob(cwd, pattern) {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
// src/actions/deplint/findFiles.ts
|
|
8
|
-
function findFiles(
|
|
9
|
-
const allSourceInclude = ["./src/**/*.{ts,tsx}"];
|
|
8
|
+
function findFiles(path5) {
|
|
9
|
+
const allSourceInclude = ["./src/**/*.{ts,tsx,mts,cts,js,mjs,cjs}"];
|
|
10
10
|
const allDistInclude = ["./dist/**/*.d.ts", "./dist/**/*.{mjs,js,cjs}"];
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
11
|
+
const allConfigInclude = ["./*.config.{ts,mts,mjs,js}"];
|
|
12
|
+
const srcFiles = allSourceInclude.flatMap((pattern) => findFilesByGlob(path5, pattern));
|
|
13
|
+
const distFiles = allDistInclude.flatMap((pattern) => findFilesByGlob(path5, pattern));
|
|
14
|
+
const configFiles = allConfigInclude.flatMap((pattern) => findFilesByGlob(path5, pattern));
|
|
15
|
+
return {
|
|
16
|
+
srcFiles,
|
|
17
|
+
distFiles,
|
|
18
|
+
configFiles
|
|
19
|
+
};
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
// src/actions/deplint/getDependenciesFromPackageJson.ts
|
|
@@ -30,10 +36,9 @@ function getDependenciesFromPackageJson(packageJsonPath) {
|
|
|
30
36
|
};
|
|
31
37
|
}
|
|
32
38
|
|
|
33
|
-
// src/actions/deplint/
|
|
39
|
+
// src/actions/deplint/getExtendsFromTsconfigs.ts
|
|
34
40
|
import fs2 from "fs";
|
|
35
|
-
import
|
|
36
|
-
import ts from "typescript";
|
|
41
|
+
import { globSync as globSync2 } from "glob";
|
|
37
42
|
|
|
38
43
|
// src/actions/deplint/getBasePackageName.ts
|
|
39
44
|
function getBasePackageName(importName) {
|
|
@@ -45,7 +50,37 @@ function getBasePackageName(importName) {
|
|
|
45
50
|
return importNameScrubbed.split("/")[0];
|
|
46
51
|
}
|
|
47
52
|
|
|
53
|
+
// src/actions/deplint/getExtendsFromTsconfigs.ts
|
|
54
|
+
var isExternalReference = (ref) => !ref.startsWith(".") && !ref.startsWith("/");
|
|
55
|
+
function parseExtendsField(value) {
|
|
56
|
+
if (typeof value === "string") return [value];
|
|
57
|
+
if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
function getExtendsFromTsconfigs(location) {
|
|
61
|
+
const tsconfigFiles = globSync2("./tsconfig*.json", { cwd: location, absolute: true });
|
|
62
|
+
const packages = /* @__PURE__ */ new Set();
|
|
63
|
+
for (const file of tsconfigFiles) {
|
|
64
|
+
try {
|
|
65
|
+
const content = fs2.readFileSync(file, "utf8");
|
|
66
|
+
const cleaned = content.replaceAll(/\/\/.*/g, "").replaceAll(/,\s*([}\]])/g, "$1");
|
|
67
|
+
const parsed = JSON.parse(cleaned);
|
|
68
|
+
const refs = parseExtendsField(parsed.extends);
|
|
69
|
+
for (const ref of refs) {
|
|
70
|
+
if (isExternalReference(ref)) {
|
|
71
|
+
packages.add(getBasePackageName(ref));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return [...packages];
|
|
78
|
+
}
|
|
79
|
+
|
|
48
80
|
// src/actions/deplint/getImportsFromFile.ts
|
|
81
|
+
import fs3 from "fs";
|
|
82
|
+
import path2 from "path";
|
|
83
|
+
import ts from "typescript";
|
|
49
84
|
function isTypeOnlyImportClause(clause) {
|
|
50
85
|
if (clause === void 0) {
|
|
51
86
|
return false;
|
|
@@ -58,7 +93,7 @@ function isTypeOnlyImportClause(clause) {
|
|
|
58
93
|
return clause.isTypeOnly;
|
|
59
94
|
}
|
|
60
95
|
function getImportsFromFile(filePath, importPaths, typeImportPaths) {
|
|
61
|
-
const sourceCode =
|
|
96
|
+
const sourceCode = fs3.readFileSync(filePath, "utf8");
|
|
62
97
|
const isMjsFile = filePath.endsWith(".mjs");
|
|
63
98
|
const sourceFile = ts.createSourceFile(
|
|
64
99
|
path2.basename(filePath),
|
|
@@ -111,24 +146,38 @@ var internalImportPrefixes = [".", "#", "node:"];
|
|
|
111
146
|
var removeInternalImports = (imports) => {
|
|
112
147
|
return imports.filter((imp) => !internalImportPrefixes.some((prefix) => imp.startsWith(prefix)));
|
|
113
148
|
};
|
|
114
|
-
function getExternalImportsFromFiles({
|
|
149
|
+
function getExternalImportsFromFiles({
|
|
150
|
+
srcFiles,
|
|
151
|
+
distFiles,
|
|
152
|
+
configFiles = [],
|
|
153
|
+
tsconfigExtends = []
|
|
154
|
+
}) {
|
|
115
155
|
const srcImportPaths = {};
|
|
116
156
|
const distImportPaths = {};
|
|
117
157
|
const distTypeImportPaths = {};
|
|
118
|
-
|
|
158
|
+
const configImportPaths = {};
|
|
159
|
+
for (const path5 of srcFiles) getImportsFromFile(path5, srcImportPaths, srcImportPaths).flat();
|
|
160
|
+
for (const path5 of configFiles) getImportsFromFile(path5, configImportPaths, configImportPaths).flat();
|
|
119
161
|
const distTypeFiles = distFiles.filter((file) => file.endsWith(".d.ts") || file.endsWith(".d.cts") || file.endsWith(".d.mts"));
|
|
120
162
|
const distCodeFiles = distFiles.filter((file) => !(file.endsWith(".d.ts") || file.endsWith(".d.cts") || file.endsWith(".d.mts")));
|
|
121
|
-
for (const
|
|
122
|
-
for (const
|
|
163
|
+
for (const path5 of distCodeFiles) getImportsFromFile(path5, distImportPaths, distImportPaths).flat();
|
|
164
|
+
for (const path5 of distTypeFiles) getImportsFromFile(path5, distTypeImportPaths, distTypeImportPaths).flat();
|
|
123
165
|
const srcImports = Object.keys(srcImportPaths);
|
|
124
166
|
const distImports = Object.keys(distImportPaths);
|
|
125
167
|
const distTypeImports = Object.keys(distTypeImportPaths);
|
|
126
168
|
const externalSrcImports = removeInternalImports(srcImports);
|
|
127
169
|
const externalDistImports = removeInternalImports(distImports);
|
|
128
170
|
const externalDistTypeImports = removeInternalImports(distTypeImports);
|
|
171
|
+
const externalConfigImports = removeInternalImports(Object.keys(configImportPaths));
|
|
172
|
+
for (const ext of tsconfigExtends) {
|
|
173
|
+
if (!externalSrcImports.includes(ext)) externalSrcImports.push(ext);
|
|
174
|
+
if (!externalConfigImports.includes(ext)) externalConfigImports.push(ext);
|
|
175
|
+
}
|
|
129
176
|
return {
|
|
177
|
+
configImportPaths,
|
|
130
178
|
srcImports,
|
|
131
179
|
srcImportPaths,
|
|
180
|
+
externalConfigImports,
|
|
132
181
|
externalSrcImports,
|
|
133
182
|
distImports,
|
|
134
183
|
distImportPaths,
|
|
@@ -140,6 +189,15 @@ function getExternalImportsFromFiles({ srcFiles, distFiles }) {
|
|
|
140
189
|
// src/actions/deplint/checkPackage/getUnlistedDependencies.ts
|
|
141
190
|
import { builtinModules } from "module";
|
|
142
191
|
import chalk from "chalk";
|
|
192
|
+
function isListedOrBuiltin(imp, name, dependencies, peerDependencies) {
|
|
193
|
+
return dependencies.includes(imp) || imp === name || dependencies.includes(`@types/${imp}`) || peerDependencies.includes(imp) || peerDependencies.includes(`@types/${imp}`) || builtinModules.includes(imp) || builtinModules.includes(`@types/${imp}`);
|
|
194
|
+
}
|
|
195
|
+
function logMissing(name, imp, importPaths) {
|
|
196
|
+
console.log(`[${chalk.blue(name)}] Missing dependency in package.json: ${chalk.red(imp)}`);
|
|
197
|
+
if (importPaths[imp]) {
|
|
198
|
+
console.log(` ${importPaths[imp].join("\n ")}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
143
201
|
function getUnlistedDependencies({ name, location }, { dependencies, peerDependencies }, {
|
|
144
202
|
externalDistImports,
|
|
145
203
|
externalDistTypeImports,
|
|
@@ -147,17 +205,15 @@ function getUnlistedDependencies({ name, location }, { dependencies, peerDepende
|
|
|
147
205
|
}) {
|
|
148
206
|
let unlistedDependencies = 0;
|
|
149
207
|
for (const imp of externalDistImports) {
|
|
150
|
-
if (!
|
|
208
|
+
if (!isListedOrBuiltin(imp, name, dependencies, peerDependencies)) {
|
|
151
209
|
unlistedDependencies++;
|
|
152
|
-
|
|
153
|
-
console.log(` ${distImportPaths[imp].join("\n ")}`);
|
|
210
|
+
logMissing(name, imp, distImportPaths);
|
|
154
211
|
}
|
|
155
212
|
}
|
|
156
213
|
for (const imp of externalDistTypeImports) {
|
|
157
|
-
if (!
|
|
214
|
+
if (!isListedOrBuiltin(imp, name, dependencies, peerDependencies)) {
|
|
158
215
|
unlistedDependencies++;
|
|
159
|
-
|
|
160
|
-
console.log(` ${distImportPaths[imp].join("\n ")}`);
|
|
216
|
+
logMissing(name, imp, distImportPaths);
|
|
161
217
|
}
|
|
162
218
|
}
|
|
163
219
|
if (unlistedDependencies > 0) {
|
|
@@ -185,7 +241,9 @@ function getUnlistedDevDependencies({ name, location }, {
|
|
|
185
241
|
if (!distImports.includes(imp) && imp !== name && !dependencies.includes(imp) && !dependencies.includes(`@types/${imp}`) && !peerDependencies.includes(imp) && !peerDependencies.includes(`@types/${imp}`) && !devDependencies.includes(imp) && !devDependencies.includes(`@types/${imp}`) && !builtinModules2.includes(imp)) {
|
|
186
242
|
unlistedDevDependencies++;
|
|
187
243
|
console.log(`[${chalk2.blue(name)}] Missing devDependency in package.json: ${chalk2.red(imp)}`);
|
|
188
|
-
|
|
244
|
+
if (srcImportPaths[imp]) {
|
|
245
|
+
console.log(` ${srcImportPaths[imp].join("\n ")}`);
|
|
246
|
+
}
|
|
189
247
|
}
|
|
190
248
|
}
|
|
191
249
|
if (unlistedDevDependencies > 0) {
|
|
@@ -222,29 +280,243 @@ function getUnusedDependencies({ name, location }, { dependencies }, {
|
|
|
222
280
|
return unusedDependencies;
|
|
223
281
|
}
|
|
224
282
|
|
|
225
|
-
// src/actions/deplint/checkPackage/
|
|
283
|
+
// src/actions/deplint/checkPackage/getUnusedDevDependencies.ts
|
|
226
284
|
import chalk4 from "chalk";
|
|
285
|
+
|
|
286
|
+
// src/actions/deplint/getRequiredPeerDependencies.ts
|
|
287
|
+
import fs4 from "fs";
|
|
288
|
+
import path3 from "path";
|
|
289
|
+
function findDepPackageJson(location, dep) {
|
|
290
|
+
let dir = location;
|
|
291
|
+
while (true) {
|
|
292
|
+
const candidate = path3.join(dir, "node_modules", dep, "package.json");
|
|
293
|
+
if (fs4.existsSync(candidate)) return candidate;
|
|
294
|
+
const parent = path3.dirname(dir);
|
|
295
|
+
if (parent === dir) return void 0;
|
|
296
|
+
dir = parent;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function getRequiredPeerDependencies(location, allDeps) {
|
|
300
|
+
const required = /* @__PURE__ */ new Set();
|
|
301
|
+
for (const dep of allDeps) {
|
|
302
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
303
|
+
if (!depPkgPath) continue;
|
|
304
|
+
try {
|
|
305
|
+
const raw = fs4.readFileSync(depPkgPath, "utf8");
|
|
306
|
+
const pkg = JSON.parse(raw);
|
|
307
|
+
if (pkg.peerDependencies) {
|
|
308
|
+
for (const peer of Object.keys(pkg.peerDependencies)) {
|
|
309
|
+
required.add(peer);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
} catch {
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return required;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/actions/deplint/getScriptReferencedPackages.ts
|
|
319
|
+
import fs5 from "fs";
|
|
320
|
+
import path4 from "path";
|
|
321
|
+
function getBinNames(location, dep) {
|
|
322
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
323
|
+
if (!depPkgPath) return [];
|
|
324
|
+
try {
|
|
325
|
+
const raw = fs5.readFileSync(depPkgPath, "utf8");
|
|
326
|
+
const pkg = JSON.parse(raw);
|
|
327
|
+
if (!pkg.bin) return [];
|
|
328
|
+
if (typeof pkg.bin === "string") return [pkg.name?.split("/").pop() ?? dep];
|
|
329
|
+
return Object.keys(pkg.bin);
|
|
330
|
+
} catch {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function tokenizeScript(script) {
|
|
335
|
+
return script.split(/[&|;$()"`\s]+/).map((t) => t.trim()).filter(Boolean);
|
|
336
|
+
}
|
|
337
|
+
function getScriptReferencedPackages(location, allDeps) {
|
|
338
|
+
const pkgPath = path4.join(location, "package.json");
|
|
339
|
+
let scripts = {};
|
|
340
|
+
try {
|
|
341
|
+
const raw = fs5.readFileSync(pkgPath, "utf8");
|
|
342
|
+
const pkg = JSON.parse(raw);
|
|
343
|
+
scripts = pkg.scripts ?? {};
|
|
344
|
+
} catch {
|
|
345
|
+
return /* @__PURE__ */ new Set();
|
|
346
|
+
}
|
|
347
|
+
const scriptText = Object.values(scripts).join(" ");
|
|
348
|
+
const tokens = new Set(tokenizeScript(scriptText));
|
|
349
|
+
const binToPackage = /* @__PURE__ */ new Map();
|
|
350
|
+
for (const dep of allDeps) {
|
|
351
|
+
const bins = getBinNames(location, dep);
|
|
352
|
+
for (const bin of bins) {
|
|
353
|
+
binToPackage.set(bin, dep);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
357
|
+
for (const token of tokens) {
|
|
358
|
+
const baseName = getBasePackageName(token);
|
|
359
|
+
if (allDeps.includes(baseName)) {
|
|
360
|
+
referenced.add(baseName);
|
|
361
|
+
}
|
|
362
|
+
const pkg = binToPackage.get(token);
|
|
363
|
+
if (pkg) {
|
|
364
|
+
referenced.add(pkg);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return referenced;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// src/actions/deplint/implicitDevDependencies.ts
|
|
371
|
+
import fs6 from "fs";
|
|
372
|
+
var hasFileWithExtension = (files, extensions) => files.some((f) => extensions.some((ext) => f.endsWith(ext)));
|
|
373
|
+
var tsExtensions = [".ts", ".tsx", ".mts", ".cts"];
|
|
374
|
+
var hasTypescriptFiles = ({ srcFiles, configFiles }) => hasFileWithExtension([...srcFiles, ...configFiles], tsExtensions);
|
|
375
|
+
var decoratorPattern = /^\s*@[A-Z]\w*/m;
|
|
376
|
+
var hasDecorators = ({ srcFiles }) => srcFiles.filter((f) => tsExtensions.some((ext) => f.endsWith(ext))).some((file) => {
|
|
377
|
+
try {
|
|
378
|
+
const content = fs6.readFileSync(file, "utf8");
|
|
379
|
+
return decoratorPattern.test(content);
|
|
380
|
+
} catch {
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
var importPlugins = /* @__PURE__ */ new Set(["eslint-plugin-import-x", "eslint-plugin-import"]);
|
|
385
|
+
function hasImportPlugin({ location, allDependencies }) {
|
|
386
|
+
if (allDependencies.some((d) => importPlugins.has(d))) return true;
|
|
387
|
+
for (const dep of allDependencies) {
|
|
388
|
+
const pkgPath = findDepPackageJson(location, dep);
|
|
389
|
+
if (!pkgPath) continue;
|
|
390
|
+
try {
|
|
391
|
+
const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf8"));
|
|
392
|
+
const transitiveDeps = [
|
|
393
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
394
|
+
...Object.keys(pkg.peerDependencies ?? {})
|
|
395
|
+
];
|
|
396
|
+
if (transitiveDeps.some((d) => importPlugins.has(d))) return true;
|
|
397
|
+
} catch {
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
var rules = [
|
|
403
|
+
{
|
|
404
|
+
package: "typescript",
|
|
405
|
+
isNeeded: hasTypescriptFiles
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
package: "eslint-import-resolver-typescript",
|
|
409
|
+
isNeeded: (context) => hasTypescriptFiles(context) && context.allDependencies.includes("eslint") && hasImportPlugin(context)
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
package: "tslib",
|
|
413
|
+
isNeeded: hasDecorators
|
|
414
|
+
}
|
|
415
|
+
];
|
|
416
|
+
function getImplicitDevDependencies(context) {
|
|
417
|
+
const implicit = /* @__PURE__ */ new Set();
|
|
418
|
+
for (const rule of rules) {
|
|
419
|
+
if (rule.isNeeded(context)) {
|
|
420
|
+
implicit.add(rule.package);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return implicit;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/actions/deplint/checkPackage/getUnusedDevDependencies.ts
|
|
427
|
+
var allExternalImports = ({
|
|
428
|
+
externalSrcImports,
|
|
429
|
+
externalDistImports,
|
|
430
|
+
externalDistTypeImports,
|
|
431
|
+
externalConfigImports
|
|
432
|
+
}) => {
|
|
433
|
+
const all = /* @__PURE__ */ new Set([
|
|
434
|
+
...externalSrcImports,
|
|
435
|
+
...externalDistImports,
|
|
436
|
+
...externalDistTypeImports,
|
|
437
|
+
...externalConfigImports
|
|
438
|
+
]);
|
|
439
|
+
return all;
|
|
440
|
+
};
|
|
441
|
+
function isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs) {
|
|
442
|
+
if (implicitDeps.has(dep)) return true;
|
|
443
|
+
if (requiredPeers.has(dep)) return true;
|
|
444
|
+
if (scriptRefs.has(dep)) return true;
|
|
445
|
+
if (dep.startsWith("@types/")) {
|
|
446
|
+
const baseName = dep.replace(/^@types\//, "");
|
|
447
|
+
return allImports.has(baseName) || allImports.has(dep) || implicitDeps.has(baseName);
|
|
448
|
+
}
|
|
449
|
+
return allImports.has(dep);
|
|
450
|
+
}
|
|
451
|
+
function getUnusedDevDependencies({ name, location }, {
|
|
452
|
+
devDependencies,
|
|
453
|
+
dependencies,
|
|
454
|
+
peerDependencies
|
|
455
|
+
}, sourceParams, fileContext) {
|
|
456
|
+
const allImports = allExternalImports(sourceParams);
|
|
457
|
+
const allDeps = [...dependencies, ...devDependencies, ...peerDependencies];
|
|
458
|
+
const implicitDeps = getImplicitDevDependencies({
|
|
459
|
+
...fileContext,
|
|
460
|
+
allDependencies: allDeps,
|
|
461
|
+
location
|
|
462
|
+
});
|
|
463
|
+
const requiredPeers = getRequiredPeerDependencies(location, allDeps);
|
|
464
|
+
const scriptRefs = getScriptReferencedPackages(location, allDeps);
|
|
465
|
+
let unusedDevDependencies = 0;
|
|
466
|
+
for (const dep of devDependencies) {
|
|
467
|
+
if (dependencies.includes(dep) || peerDependencies.includes(dep)) continue;
|
|
468
|
+
if (!isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs)) {
|
|
469
|
+
unusedDevDependencies++;
|
|
470
|
+
console.log(`[${chalk4.blue(name)}] Unused devDependency in package.json: ${chalk4.red(dep)}`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (unusedDevDependencies > 0) {
|
|
474
|
+
const packageLocation = `${location}/package.json`;
|
|
475
|
+
console.log(` ${chalk4.yellow(packageLocation)}
|
|
476
|
+
`);
|
|
477
|
+
}
|
|
478
|
+
return unusedDevDependencies;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// src/actions/deplint/checkPackage/getUnusedPeerDependencies.ts
|
|
482
|
+
import chalk5 from "chalk";
|
|
227
483
|
function getUnusedPeerDependencies({ name, location }, { peerDependencies, dependencies }, { externalDistImports, externalDistTypeImports }) {
|
|
228
484
|
let unusedDependencies = 0;
|
|
229
485
|
for (const dep of peerDependencies) {
|
|
230
486
|
if (!externalDistImports.includes(dep) && !externalDistImports.includes(dep.replace(/^@types\//, "")) && !externalDistTypeImports.includes(dep) && !externalDistTypeImports.includes(dep.replace(/^@types\//, ""))) {
|
|
231
487
|
unusedDependencies++;
|
|
232
488
|
if (dependencies.includes(dep)) {
|
|
233
|
-
console.log(`[${
|
|
489
|
+
console.log(`[${chalk5.blue(name)}] Unused peerDependency [already a dependency] in package.json: ${chalk5.red(dep)}`);
|
|
234
490
|
} else {
|
|
235
|
-
console.log(`[${
|
|
491
|
+
console.log(`[${chalk5.blue(name)}] Unused peerDependency in package.json: ${chalk5.red(dep)}`);
|
|
236
492
|
}
|
|
237
493
|
}
|
|
238
494
|
}
|
|
239
495
|
if (unusedDependencies > 0) {
|
|
240
496
|
const packageLocation = `${location}/package.json`;
|
|
241
|
-
console.log(` ${
|
|
497
|
+
console.log(` ${chalk5.yellow(packageLocation)}
|
|
242
498
|
`);
|
|
243
499
|
}
|
|
244
500
|
return unusedDependencies;
|
|
245
501
|
}
|
|
246
502
|
|
|
247
503
|
// src/actions/deplint/checkPackage/checkPackage.ts
|
|
504
|
+
function logVerbose(name, location, srcFiles, distFiles, configFiles, tsconfigExtends) {
|
|
505
|
+
console.info(`Checking package: ${name} at ${location}`);
|
|
506
|
+
console.info(`Source files: ${srcFiles.length}, Distribution files: ${distFiles.length}, Config files: ${configFiles.length}`);
|
|
507
|
+
for (const file of srcFiles) {
|
|
508
|
+
console.info(`Source file: ${file}`);
|
|
509
|
+
}
|
|
510
|
+
for (const file of distFiles) {
|
|
511
|
+
console.info(`Distribution file: ${file}`);
|
|
512
|
+
}
|
|
513
|
+
for (const file of configFiles) {
|
|
514
|
+
console.info(`Config file: ${file}`);
|
|
515
|
+
}
|
|
516
|
+
for (const ext of tsconfigExtends) {
|
|
517
|
+
console.info(`Tsconfig extends: ${ext}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
248
520
|
function checkPackage({
|
|
249
521
|
name,
|
|
250
522
|
location,
|
|
@@ -253,27 +525,36 @@ function checkPackage({
|
|
|
253
525
|
peerDeps = false,
|
|
254
526
|
verbose = false
|
|
255
527
|
}) {
|
|
256
|
-
const {
|
|
528
|
+
const {
|
|
529
|
+
srcFiles,
|
|
530
|
+
distFiles,
|
|
531
|
+
configFiles
|
|
532
|
+
} = findFiles(location);
|
|
533
|
+
const tsconfigExtends = getExtendsFromTsconfigs(location);
|
|
257
534
|
if (verbose) {
|
|
258
|
-
|
|
259
|
-
console.info(`Source files: ${srcFiles.length}, Distribution files: ${distFiles.length}`);
|
|
260
|
-
for (const file of srcFiles) {
|
|
261
|
-
console.info(`Source file: ${file}`);
|
|
262
|
-
}
|
|
263
|
-
for (const file of distFiles) {
|
|
264
|
-
console.info(`Distribution file: ${file}`);
|
|
265
|
-
}
|
|
535
|
+
logVerbose(name, location, srcFiles, distFiles, configFiles, tsconfigExtends);
|
|
266
536
|
}
|
|
267
537
|
const checkDeps = deps || !(deps || devDeps || peerDeps);
|
|
268
538
|
const checkDevDeps = devDeps || !(deps || devDeps || peerDeps);
|
|
269
539
|
const checkPeerDeps = peerDeps;
|
|
270
|
-
const sourceParams = getExternalImportsFromFiles({
|
|
540
|
+
const sourceParams = getExternalImportsFromFiles({
|
|
541
|
+
srcFiles,
|
|
542
|
+
distFiles,
|
|
543
|
+
configFiles,
|
|
544
|
+
tsconfigExtends
|
|
545
|
+
});
|
|
271
546
|
const packageParams = getDependenciesFromPackageJson(`${location}/package.json`);
|
|
272
547
|
const unlistedDependencies = checkDeps ? getUnlistedDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
273
548
|
const unusedDependencies = checkDeps ? getUnusedDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
274
549
|
const unlistedDevDependencies = checkDevDeps ? getUnlistedDevDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
550
|
+
const fileContext = {
|
|
551
|
+
configFiles,
|
|
552
|
+
distFiles,
|
|
553
|
+
srcFiles
|
|
554
|
+
};
|
|
555
|
+
const unusedDevDependencies = checkDevDeps ? getUnusedDevDependencies({ name, location }, packageParams, sourceParams, fileContext) : 0;
|
|
275
556
|
const unusedPeerDependencies = checkPeerDeps ? getUnusedPeerDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
276
|
-
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + unusedPeerDependencies;
|
|
557
|
+
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + unusedDevDependencies + unusedPeerDependencies;
|
|
277
558
|
return totalErrors;
|
|
278
559
|
}
|
|
279
560
|
export {
|