@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/actions/deplint/deplint.ts
|
|
2
|
-
import
|
|
2
|
+
import chalk6 from "chalk";
|
|
3
3
|
|
|
4
4
|
// src/lib/yarn/workspace/yarnWorkspaces.ts
|
|
5
5
|
import { spawnSync } from "child_process";
|
|
@@ -27,12 +27,18 @@ function findFilesByGlob(cwd, pattern) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// src/actions/deplint/findFiles.ts
|
|
30
|
-
function findFiles(
|
|
31
|
-
const allSourceInclude = ["./src/**/*.{ts,tsx}"];
|
|
30
|
+
function findFiles(path5) {
|
|
31
|
+
const allSourceInclude = ["./src/**/*.{ts,tsx,mts,cts,js,mjs,cjs}"];
|
|
32
32
|
const allDistInclude = ["./dist/**/*.d.ts", "./dist/**/*.{mjs,js,cjs}"];
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
33
|
+
const allConfigInclude = ["./*.config.{ts,mts,mjs,js}"];
|
|
34
|
+
const srcFiles = allSourceInclude.flatMap((pattern) => findFilesByGlob(path5, pattern));
|
|
35
|
+
const distFiles = allDistInclude.flatMap((pattern) => findFilesByGlob(path5, pattern));
|
|
36
|
+
const configFiles = allConfigInclude.flatMap((pattern) => findFilesByGlob(path5, pattern));
|
|
37
|
+
return {
|
|
38
|
+
srcFiles,
|
|
39
|
+
distFiles,
|
|
40
|
+
configFiles
|
|
41
|
+
};
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
// src/actions/deplint/getDependenciesFromPackageJson.ts
|
|
@@ -52,10 +58,9 @@ function getDependenciesFromPackageJson(packageJsonPath) {
|
|
|
52
58
|
};
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
// src/actions/deplint/
|
|
61
|
+
// src/actions/deplint/getExtendsFromTsconfigs.ts
|
|
56
62
|
import fs2 from "fs";
|
|
57
|
-
import
|
|
58
|
-
import ts from "typescript";
|
|
63
|
+
import { globSync as globSync2 } from "glob";
|
|
59
64
|
|
|
60
65
|
// src/actions/deplint/getBasePackageName.ts
|
|
61
66
|
function getBasePackageName(importName) {
|
|
@@ -67,7 +72,37 @@ function getBasePackageName(importName) {
|
|
|
67
72
|
return importNameScrubbed.split("/")[0];
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
// src/actions/deplint/getExtendsFromTsconfigs.ts
|
|
76
|
+
var isExternalReference = (ref) => !ref.startsWith(".") && !ref.startsWith("/");
|
|
77
|
+
function parseExtendsField(value) {
|
|
78
|
+
if (typeof value === "string") return [value];
|
|
79
|
+
if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
function getExtendsFromTsconfigs(location) {
|
|
83
|
+
const tsconfigFiles = globSync2("./tsconfig*.json", { cwd: location, absolute: true });
|
|
84
|
+
const packages = /* @__PURE__ */ new Set();
|
|
85
|
+
for (const file of tsconfigFiles) {
|
|
86
|
+
try {
|
|
87
|
+
const content = fs2.readFileSync(file, "utf8");
|
|
88
|
+
const cleaned = content.replaceAll(/\/\/.*/g, "").replaceAll(/,\s*([}\]])/g, "$1");
|
|
89
|
+
const parsed = JSON.parse(cleaned);
|
|
90
|
+
const refs = parseExtendsField(parsed.extends);
|
|
91
|
+
for (const ref of refs) {
|
|
92
|
+
if (isExternalReference(ref)) {
|
|
93
|
+
packages.add(getBasePackageName(ref));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return [...packages];
|
|
100
|
+
}
|
|
101
|
+
|
|
70
102
|
// src/actions/deplint/getImportsFromFile.ts
|
|
103
|
+
import fs3 from "fs";
|
|
104
|
+
import path2 from "path";
|
|
105
|
+
import ts from "typescript";
|
|
71
106
|
function isTypeOnlyImportClause(clause) {
|
|
72
107
|
if (clause === void 0) {
|
|
73
108
|
return false;
|
|
@@ -80,7 +115,7 @@ function isTypeOnlyImportClause(clause) {
|
|
|
80
115
|
return clause.isTypeOnly;
|
|
81
116
|
}
|
|
82
117
|
function getImportsFromFile(filePath, importPaths, typeImportPaths) {
|
|
83
|
-
const sourceCode =
|
|
118
|
+
const sourceCode = fs3.readFileSync(filePath, "utf8");
|
|
84
119
|
const isMjsFile = filePath.endsWith(".mjs");
|
|
85
120
|
const sourceFile = ts.createSourceFile(
|
|
86
121
|
path2.basename(filePath),
|
|
@@ -133,24 +168,38 @@ var internalImportPrefixes = [".", "#", "node:"];
|
|
|
133
168
|
var removeInternalImports = (imports) => {
|
|
134
169
|
return imports.filter((imp) => !internalImportPrefixes.some((prefix) => imp.startsWith(prefix)));
|
|
135
170
|
};
|
|
136
|
-
function getExternalImportsFromFiles({
|
|
171
|
+
function getExternalImportsFromFiles({
|
|
172
|
+
srcFiles,
|
|
173
|
+
distFiles,
|
|
174
|
+
configFiles = [],
|
|
175
|
+
tsconfigExtends = []
|
|
176
|
+
}) {
|
|
137
177
|
const srcImportPaths = {};
|
|
138
178
|
const distImportPaths = {};
|
|
139
179
|
const distTypeImportPaths = {};
|
|
140
|
-
|
|
180
|
+
const configImportPaths = {};
|
|
181
|
+
for (const path5 of srcFiles) getImportsFromFile(path5, srcImportPaths, srcImportPaths).flat();
|
|
182
|
+
for (const path5 of configFiles) getImportsFromFile(path5, configImportPaths, configImportPaths).flat();
|
|
141
183
|
const distTypeFiles = distFiles.filter((file) => file.endsWith(".d.ts") || file.endsWith(".d.cts") || file.endsWith(".d.mts"));
|
|
142
184
|
const distCodeFiles = distFiles.filter((file) => !(file.endsWith(".d.ts") || file.endsWith(".d.cts") || file.endsWith(".d.mts")));
|
|
143
|
-
for (const
|
|
144
|
-
for (const
|
|
185
|
+
for (const path5 of distCodeFiles) getImportsFromFile(path5, distImportPaths, distImportPaths).flat();
|
|
186
|
+
for (const path5 of distTypeFiles) getImportsFromFile(path5, distTypeImportPaths, distTypeImportPaths).flat();
|
|
145
187
|
const srcImports = Object.keys(srcImportPaths);
|
|
146
188
|
const distImports = Object.keys(distImportPaths);
|
|
147
189
|
const distTypeImports = Object.keys(distTypeImportPaths);
|
|
148
190
|
const externalSrcImports = removeInternalImports(srcImports);
|
|
149
191
|
const externalDistImports = removeInternalImports(distImports);
|
|
150
192
|
const externalDistTypeImports = removeInternalImports(distTypeImports);
|
|
193
|
+
const externalConfigImports = removeInternalImports(Object.keys(configImportPaths));
|
|
194
|
+
for (const ext of tsconfigExtends) {
|
|
195
|
+
if (!externalSrcImports.includes(ext)) externalSrcImports.push(ext);
|
|
196
|
+
if (!externalConfigImports.includes(ext)) externalConfigImports.push(ext);
|
|
197
|
+
}
|
|
151
198
|
return {
|
|
199
|
+
configImportPaths,
|
|
152
200
|
srcImports,
|
|
153
201
|
srcImportPaths,
|
|
202
|
+
externalConfigImports,
|
|
154
203
|
externalSrcImports,
|
|
155
204
|
distImports,
|
|
156
205
|
distImportPaths,
|
|
@@ -162,6 +211,15 @@ function getExternalImportsFromFiles({ srcFiles, distFiles }) {
|
|
|
162
211
|
// src/actions/deplint/checkPackage/getUnlistedDependencies.ts
|
|
163
212
|
import { builtinModules } from "module";
|
|
164
213
|
import chalk from "chalk";
|
|
214
|
+
function isListedOrBuiltin(imp, name, dependencies, peerDependencies) {
|
|
215
|
+
return dependencies.includes(imp) || imp === name || dependencies.includes(`@types/${imp}`) || peerDependencies.includes(imp) || peerDependencies.includes(`@types/${imp}`) || builtinModules.includes(imp) || builtinModules.includes(`@types/${imp}`);
|
|
216
|
+
}
|
|
217
|
+
function logMissing(name, imp, importPaths) {
|
|
218
|
+
console.log(`[${chalk.blue(name)}] Missing dependency in package.json: ${chalk.red(imp)}`);
|
|
219
|
+
if (importPaths[imp]) {
|
|
220
|
+
console.log(` ${importPaths[imp].join("\n ")}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
165
223
|
function getUnlistedDependencies({ name, location }, { dependencies, peerDependencies }, {
|
|
166
224
|
externalDistImports,
|
|
167
225
|
externalDistTypeImports,
|
|
@@ -169,17 +227,15 @@ function getUnlistedDependencies({ name, location }, { dependencies, peerDepende
|
|
|
169
227
|
}) {
|
|
170
228
|
let unlistedDependencies = 0;
|
|
171
229
|
for (const imp of externalDistImports) {
|
|
172
|
-
if (!
|
|
230
|
+
if (!isListedOrBuiltin(imp, name, dependencies, peerDependencies)) {
|
|
173
231
|
unlistedDependencies++;
|
|
174
|
-
|
|
175
|
-
console.log(` ${distImportPaths[imp].join("\n ")}`);
|
|
232
|
+
logMissing(name, imp, distImportPaths);
|
|
176
233
|
}
|
|
177
234
|
}
|
|
178
235
|
for (const imp of externalDistTypeImports) {
|
|
179
|
-
if (!
|
|
236
|
+
if (!isListedOrBuiltin(imp, name, dependencies, peerDependencies)) {
|
|
180
237
|
unlistedDependencies++;
|
|
181
|
-
|
|
182
|
-
console.log(` ${distImportPaths[imp].join("\n ")}`);
|
|
238
|
+
logMissing(name, imp, distImportPaths);
|
|
183
239
|
}
|
|
184
240
|
}
|
|
185
241
|
if (unlistedDependencies > 0) {
|
|
@@ -207,7 +263,9 @@ function getUnlistedDevDependencies({ name, location }, {
|
|
|
207
263
|
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)) {
|
|
208
264
|
unlistedDevDependencies++;
|
|
209
265
|
console.log(`[${chalk2.blue(name)}] Missing devDependency in package.json: ${chalk2.red(imp)}`);
|
|
210
|
-
|
|
266
|
+
if (srcImportPaths[imp]) {
|
|
267
|
+
console.log(` ${srcImportPaths[imp].join("\n ")}`);
|
|
268
|
+
}
|
|
211
269
|
}
|
|
212
270
|
}
|
|
213
271
|
if (unlistedDevDependencies > 0) {
|
|
@@ -244,29 +302,243 @@ function getUnusedDependencies({ name, location }, { dependencies }, {
|
|
|
244
302
|
return unusedDependencies;
|
|
245
303
|
}
|
|
246
304
|
|
|
247
|
-
// src/actions/deplint/checkPackage/
|
|
305
|
+
// src/actions/deplint/checkPackage/getUnusedDevDependencies.ts
|
|
248
306
|
import chalk4 from "chalk";
|
|
307
|
+
|
|
308
|
+
// src/actions/deplint/getRequiredPeerDependencies.ts
|
|
309
|
+
import fs4 from "fs";
|
|
310
|
+
import path3 from "path";
|
|
311
|
+
function findDepPackageJson(location, dep) {
|
|
312
|
+
let dir = location;
|
|
313
|
+
while (true) {
|
|
314
|
+
const candidate = path3.join(dir, "node_modules", dep, "package.json");
|
|
315
|
+
if (fs4.existsSync(candidate)) return candidate;
|
|
316
|
+
const parent = path3.dirname(dir);
|
|
317
|
+
if (parent === dir) return void 0;
|
|
318
|
+
dir = parent;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function getRequiredPeerDependencies(location, allDeps) {
|
|
322
|
+
const required = /* @__PURE__ */ new Set();
|
|
323
|
+
for (const dep of allDeps) {
|
|
324
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
325
|
+
if (!depPkgPath) continue;
|
|
326
|
+
try {
|
|
327
|
+
const raw = fs4.readFileSync(depPkgPath, "utf8");
|
|
328
|
+
const pkg = JSON.parse(raw);
|
|
329
|
+
if (pkg.peerDependencies) {
|
|
330
|
+
for (const peer of Object.keys(pkg.peerDependencies)) {
|
|
331
|
+
required.add(peer);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
} catch {
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return required;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/actions/deplint/getScriptReferencedPackages.ts
|
|
341
|
+
import fs5 from "fs";
|
|
342
|
+
import path4 from "path";
|
|
343
|
+
function getBinNames(location, dep) {
|
|
344
|
+
const depPkgPath = findDepPackageJson(location, dep);
|
|
345
|
+
if (!depPkgPath) return [];
|
|
346
|
+
try {
|
|
347
|
+
const raw = fs5.readFileSync(depPkgPath, "utf8");
|
|
348
|
+
const pkg = JSON.parse(raw);
|
|
349
|
+
if (!pkg.bin) return [];
|
|
350
|
+
if (typeof pkg.bin === "string") return [pkg.name?.split("/").pop() ?? dep];
|
|
351
|
+
return Object.keys(pkg.bin);
|
|
352
|
+
} catch {
|
|
353
|
+
return [];
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function tokenizeScript(script) {
|
|
357
|
+
return script.split(/[&|;$()"`\s]+/).map((t) => t.trim()).filter(Boolean);
|
|
358
|
+
}
|
|
359
|
+
function getScriptReferencedPackages(location, allDeps) {
|
|
360
|
+
const pkgPath = path4.join(location, "package.json");
|
|
361
|
+
let scripts = {};
|
|
362
|
+
try {
|
|
363
|
+
const raw = fs5.readFileSync(pkgPath, "utf8");
|
|
364
|
+
const pkg = JSON.parse(raw);
|
|
365
|
+
scripts = pkg.scripts ?? {};
|
|
366
|
+
} catch {
|
|
367
|
+
return /* @__PURE__ */ new Set();
|
|
368
|
+
}
|
|
369
|
+
const scriptText = Object.values(scripts).join(" ");
|
|
370
|
+
const tokens = new Set(tokenizeScript(scriptText));
|
|
371
|
+
const binToPackage = /* @__PURE__ */ new Map();
|
|
372
|
+
for (const dep of allDeps) {
|
|
373
|
+
const bins = getBinNames(location, dep);
|
|
374
|
+
for (const bin of bins) {
|
|
375
|
+
binToPackage.set(bin, dep);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
379
|
+
for (const token of tokens) {
|
|
380
|
+
const baseName = getBasePackageName(token);
|
|
381
|
+
if (allDeps.includes(baseName)) {
|
|
382
|
+
referenced.add(baseName);
|
|
383
|
+
}
|
|
384
|
+
const pkg = binToPackage.get(token);
|
|
385
|
+
if (pkg) {
|
|
386
|
+
referenced.add(pkg);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return referenced;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// src/actions/deplint/implicitDevDependencies.ts
|
|
393
|
+
import fs6 from "fs";
|
|
394
|
+
var hasFileWithExtension = (files, extensions) => files.some((f) => extensions.some((ext) => f.endsWith(ext)));
|
|
395
|
+
var tsExtensions = [".ts", ".tsx", ".mts", ".cts"];
|
|
396
|
+
var hasTypescriptFiles = ({ srcFiles, configFiles }) => hasFileWithExtension([...srcFiles, ...configFiles], tsExtensions);
|
|
397
|
+
var decoratorPattern = /^\s*@[A-Z]\w*/m;
|
|
398
|
+
var hasDecorators = ({ srcFiles }) => srcFiles.filter((f) => tsExtensions.some((ext) => f.endsWith(ext))).some((file) => {
|
|
399
|
+
try {
|
|
400
|
+
const content = fs6.readFileSync(file, "utf8");
|
|
401
|
+
return decoratorPattern.test(content);
|
|
402
|
+
} catch {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
var importPlugins = /* @__PURE__ */ new Set(["eslint-plugin-import-x", "eslint-plugin-import"]);
|
|
407
|
+
function hasImportPlugin({ location, allDependencies }) {
|
|
408
|
+
if (allDependencies.some((d) => importPlugins.has(d))) return true;
|
|
409
|
+
for (const dep of allDependencies) {
|
|
410
|
+
const pkgPath = findDepPackageJson(location, dep);
|
|
411
|
+
if (!pkgPath) continue;
|
|
412
|
+
try {
|
|
413
|
+
const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf8"));
|
|
414
|
+
const transitiveDeps = [
|
|
415
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
416
|
+
...Object.keys(pkg.peerDependencies ?? {})
|
|
417
|
+
];
|
|
418
|
+
if (transitiveDeps.some((d) => importPlugins.has(d))) return true;
|
|
419
|
+
} catch {
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
var rules = [
|
|
425
|
+
{
|
|
426
|
+
package: "typescript",
|
|
427
|
+
isNeeded: hasTypescriptFiles
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
package: "eslint-import-resolver-typescript",
|
|
431
|
+
isNeeded: (context) => hasTypescriptFiles(context) && context.allDependencies.includes("eslint") && hasImportPlugin(context)
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
package: "tslib",
|
|
435
|
+
isNeeded: hasDecorators
|
|
436
|
+
}
|
|
437
|
+
];
|
|
438
|
+
function getImplicitDevDependencies(context) {
|
|
439
|
+
const implicit = /* @__PURE__ */ new Set();
|
|
440
|
+
for (const rule of rules) {
|
|
441
|
+
if (rule.isNeeded(context)) {
|
|
442
|
+
implicit.add(rule.package);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return implicit;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// src/actions/deplint/checkPackage/getUnusedDevDependencies.ts
|
|
449
|
+
var allExternalImports = ({
|
|
450
|
+
externalSrcImports,
|
|
451
|
+
externalDistImports,
|
|
452
|
+
externalDistTypeImports,
|
|
453
|
+
externalConfigImports
|
|
454
|
+
}) => {
|
|
455
|
+
const all = /* @__PURE__ */ new Set([
|
|
456
|
+
...externalSrcImports,
|
|
457
|
+
...externalDistImports,
|
|
458
|
+
...externalDistTypeImports,
|
|
459
|
+
...externalConfigImports
|
|
460
|
+
]);
|
|
461
|
+
return all;
|
|
462
|
+
};
|
|
463
|
+
function isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs) {
|
|
464
|
+
if (implicitDeps.has(dep)) return true;
|
|
465
|
+
if (requiredPeers.has(dep)) return true;
|
|
466
|
+
if (scriptRefs.has(dep)) return true;
|
|
467
|
+
if (dep.startsWith("@types/")) {
|
|
468
|
+
const baseName = dep.replace(/^@types\//, "");
|
|
469
|
+
return allImports.has(baseName) || allImports.has(dep) || implicitDeps.has(baseName);
|
|
470
|
+
}
|
|
471
|
+
return allImports.has(dep);
|
|
472
|
+
}
|
|
473
|
+
function getUnusedDevDependencies({ name, location }, {
|
|
474
|
+
devDependencies,
|
|
475
|
+
dependencies,
|
|
476
|
+
peerDependencies
|
|
477
|
+
}, sourceParams, fileContext) {
|
|
478
|
+
const allImports = allExternalImports(sourceParams);
|
|
479
|
+
const allDeps = [...dependencies, ...devDependencies, ...peerDependencies];
|
|
480
|
+
const implicitDeps = getImplicitDevDependencies({
|
|
481
|
+
...fileContext,
|
|
482
|
+
allDependencies: allDeps,
|
|
483
|
+
location
|
|
484
|
+
});
|
|
485
|
+
const requiredPeers = getRequiredPeerDependencies(location, allDeps);
|
|
486
|
+
const scriptRefs = getScriptReferencedPackages(location, allDeps);
|
|
487
|
+
let unusedDevDependencies = 0;
|
|
488
|
+
for (const dep of devDependencies) {
|
|
489
|
+
if (dependencies.includes(dep) || peerDependencies.includes(dep)) continue;
|
|
490
|
+
if (!isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs)) {
|
|
491
|
+
unusedDevDependencies++;
|
|
492
|
+
console.log(`[${chalk4.blue(name)}] Unused devDependency in package.json: ${chalk4.red(dep)}`);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (unusedDevDependencies > 0) {
|
|
496
|
+
const packageLocation = `${location}/package.json`;
|
|
497
|
+
console.log(` ${chalk4.yellow(packageLocation)}
|
|
498
|
+
`);
|
|
499
|
+
}
|
|
500
|
+
return unusedDevDependencies;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// src/actions/deplint/checkPackage/getUnusedPeerDependencies.ts
|
|
504
|
+
import chalk5 from "chalk";
|
|
249
505
|
function getUnusedPeerDependencies({ name, location }, { peerDependencies, dependencies }, { externalDistImports, externalDistTypeImports }) {
|
|
250
506
|
let unusedDependencies = 0;
|
|
251
507
|
for (const dep of peerDependencies) {
|
|
252
508
|
if (!externalDistImports.includes(dep) && !externalDistImports.includes(dep.replace(/^@types\//, "")) && !externalDistTypeImports.includes(dep) && !externalDistTypeImports.includes(dep.replace(/^@types\//, ""))) {
|
|
253
509
|
unusedDependencies++;
|
|
254
510
|
if (dependencies.includes(dep)) {
|
|
255
|
-
console.log(`[${
|
|
511
|
+
console.log(`[${chalk5.blue(name)}] Unused peerDependency [already a dependency] in package.json: ${chalk5.red(dep)}`);
|
|
256
512
|
} else {
|
|
257
|
-
console.log(`[${
|
|
513
|
+
console.log(`[${chalk5.blue(name)}] Unused peerDependency in package.json: ${chalk5.red(dep)}`);
|
|
258
514
|
}
|
|
259
515
|
}
|
|
260
516
|
}
|
|
261
517
|
if (unusedDependencies > 0) {
|
|
262
518
|
const packageLocation = `${location}/package.json`;
|
|
263
|
-
console.log(` ${
|
|
519
|
+
console.log(` ${chalk5.yellow(packageLocation)}
|
|
264
520
|
`);
|
|
265
521
|
}
|
|
266
522
|
return unusedDependencies;
|
|
267
523
|
}
|
|
268
524
|
|
|
269
525
|
// src/actions/deplint/checkPackage/checkPackage.ts
|
|
526
|
+
function logVerbose(name, location, srcFiles, distFiles, configFiles, tsconfigExtends) {
|
|
527
|
+
console.info(`Checking package: ${name} at ${location}`);
|
|
528
|
+
console.info(`Source files: ${srcFiles.length}, Distribution files: ${distFiles.length}, Config files: ${configFiles.length}`);
|
|
529
|
+
for (const file of srcFiles) {
|
|
530
|
+
console.info(`Source file: ${file}`);
|
|
531
|
+
}
|
|
532
|
+
for (const file of distFiles) {
|
|
533
|
+
console.info(`Distribution file: ${file}`);
|
|
534
|
+
}
|
|
535
|
+
for (const file of configFiles) {
|
|
536
|
+
console.info(`Config file: ${file}`);
|
|
537
|
+
}
|
|
538
|
+
for (const ext of tsconfigExtends) {
|
|
539
|
+
console.info(`Tsconfig extends: ${ext}`);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
270
542
|
function checkPackage({
|
|
271
543
|
name,
|
|
272
544
|
location,
|
|
@@ -275,27 +547,36 @@ function checkPackage({
|
|
|
275
547
|
peerDeps = false,
|
|
276
548
|
verbose = false
|
|
277
549
|
}) {
|
|
278
|
-
const {
|
|
550
|
+
const {
|
|
551
|
+
srcFiles,
|
|
552
|
+
distFiles,
|
|
553
|
+
configFiles
|
|
554
|
+
} = findFiles(location);
|
|
555
|
+
const tsconfigExtends = getExtendsFromTsconfigs(location);
|
|
279
556
|
if (verbose) {
|
|
280
|
-
|
|
281
|
-
console.info(`Source files: ${srcFiles.length}, Distribution files: ${distFiles.length}`);
|
|
282
|
-
for (const file of srcFiles) {
|
|
283
|
-
console.info(`Source file: ${file}`);
|
|
284
|
-
}
|
|
285
|
-
for (const file of distFiles) {
|
|
286
|
-
console.info(`Distribution file: ${file}`);
|
|
287
|
-
}
|
|
557
|
+
logVerbose(name, location, srcFiles, distFiles, configFiles, tsconfigExtends);
|
|
288
558
|
}
|
|
289
559
|
const checkDeps = deps || !(deps || devDeps || peerDeps);
|
|
290
560
|
const checkDevDeps = devDeps || !(deps || devDeps || peerDeps);
|
|
291
561
|
const checkPeerDeps = peerDeps;
|
|
292
|
-
const sourceParams = getExternalImportsFromFiles({
|
|
562
|
+
const sourceParams = getExternalImportsFromFiles({
|
|
563
|
+
srcFiles,
|
|
564
|
+
distFiles,
|
|
565
|
+
configFiles,
|
|
566
|
+
tsconfigExtends
|
|
567
|
+
});
|
|
293
568
|
const packageParams = getDependenciesFromPackageJson(`${location}/package.json`);
|
|
294
569
|
const unlistedDependencies = checkDeps ? getUnlistedDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
295
570
|
const unusedDependencies = checkDeps ? getUnusedDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
296
571
|
const unlistedDevDependencies = checkDevDeps ? getUnlistedDevDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
572
|
+
const fileContext = {
|
|
573
|
+
configFiles,
|
|
574
|
+
distFiles,
|
|
575
|
+
srcFiles
|
|
576
|
+
};
|
|
577
|
+
const unusedDevDependencies = checkDevDeps ? getUnusedDevDependencies({ name, location }, packageParams, sourceParams, fileContext) : 0;
|
|
297
578
|
const unusedPeerDependencies = checkPeerDeps ? getUnusedPeerDependencies({ name, location }, packageParams, sourceParams) : 0;
|
|
298
|
-
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + unusedPeerDependencies;
|
|
579
|
+
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + unusedDevDependencies + unusedPeerDependencies;
|
|
299
580
|
return totalErrors;
|
|
300
581
|
}
|
|
301
582
|
|
|
@@ -333,9 +614,9 @@ var deplint = ({
|
|
|
333
614
|
});
|
|
334
615
|
}
|
|
335
616
|
if (totalErrors > 0) {
|
|
336
|
-
console.warn(`Deplint: Found ${
|
|
617
|
+
console.warn(`Deplint: Found ${chalk6.red(totalErrors)} dependency problems. ${chalk6.red("\u2716")}`);
|
|
337
618
|
} else {
|
|
338
|
-
console.info(`Deplint: Found no dependency problems. ${
|
|
619
|
+
console.info(`Deplint: Found no dependency problems. ${chalk6.green("\u2714")}`);
|
|
339
620
|
}
|
|
340
621
|
return 0;
|
|
341
622
|
};
|