@xylabs/ts-scripts-yarn3 7.4.10 → 7.4.11

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.
Files changed (32) hide show
  1. package/dist/actions/deplint/checkPackage/checkPackage.mjs +115 -16
  2. package/dist/actions/deplint/checkPackage/checkPackage.mjs.map +1 -1
  3. package/dist/actions/deplint/checkPackage/getUnusedDependencies.mjs +2 -1
  4. package/dist/actions/deplint/checkPackage/getUnusedDependencies.mjs.map +1 -1
  5. package/dist/actions/deplint/checkPackage/getUnusedDevDependencies.mjs +114 -20
  6. package/dist/actions/deplint/checkPackage/getUnusedDevDependencies.mjs.map +1 -1
  7. package/dist/actions/deplint/checkPackage/getUnusedPeerDependencies.mjs +2 -1
  8. package/dist/actions/deplint/checkPackage/getUnusedPeerDependencies.mjs.map +1 -1
  9. package/dist/actions/deplint/checkPackage/index.mjs +115 -16
  10. package/dist/actions/deplint/checkPackage/index.mjs.map +1 -1
  11. package/dist/actions/deplint/deplint.mjs +166 -38
  12. package/dist/actions/deplint/deplint.mjs.map +1 -1
  13. package/dist/actions/deplint/getCliReferencedPackagesFromFiles.mjs +140 -0
  14. package/dist/actions/deplint/getCliReferencedPackagesFromFiles.mjs.map +1 -0
  15. package/dist/actions/deplint/getScriptReferencedPackages.mjs +3 -1
  16. package/dist/actions/deplint/getScriptReferencedPackages.mjs.map +1 -1
  17. package/dist/actions/deplint/index.mjs +166 -38
  18. package/dist/actions/deplint/index.mjs.map +1 -1
  19. package/dist/actions/index.mjs +147 -40
  20. package/dist/actions/index.mjs.map +1 -1
  21. package/dist/bin/xy.mjs +251 -117
  22. package/dist/bin/xy.mjs.map +1 -1
  23. package/dist/index.d.ts +23 -2
  24. package/dist/index.mjs +155 -42
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/xy/index.mjs +251 -117
  27. package/dist/xy/index.mjs.map +1 -1
  28. package/dist/xy/xy.mjs +251 -117
  29. package/dist/xy/xy.mjs.map +1 -1
  30. package/dist/xy/xyLintCommands.mjs +205 -71
  31. package/dist/xy/xyLintCommands.mjs.map +1 -1
  32. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -173,14 +173,21 @@ declare const INIT_CWD: () => string | undefined;
173
173
  interface CheckPackageOptions {
174
174
  deps?: boolean;
175
175
  devDeps?: boolean;
176
+ /**
177
+ * Set of package names to exclude from unused-dependency checks.
178
+ * Loaded from xy.config's deplint.exclude field.
179
+ */
180
+ exclude?: Set<string>;
176
181
  peerDeps?: boolean;
177
182
  verbose?: boolean;
178
183
  }
179
184
 
180
185
  interface DepLintOptions extends CheckPackageOptions {
186
+ /** Package names to exclude, passed via --exclude on the command line */
187
+ cliExclude?: string[];
181
188
  pkg?: string;
182
189
  }
183
- declare const deplint: ({ pkg, deps, devDeps, peerDeps, verbose, }: DepLintOptions) => number;
190
+ declare const deplint: ({ pkg, deps, devDeps, peerDeps, verbose, cliExclude, }: DepLintOptions) => Promise<number>;
184
191
 
185
192
  declare const deploy: () => number;
186
193
 
@@ -281,8 +288,22 @@ type PackageCompileTsupConfig = CompileConfig & {
281
288
  type PackageCompileTscConfig = CompileConfig & {
282
289
  mode: 'tsc';
283
290
  };
291
+ /**
292
+ * Configuration for deplint (dependency linting).
293
+ */
294
+ interface DeplintConfig {
295
+ /**
296
+ * Package names to exclude from unused-dependency checks.
297
+ * Packages listed here will never be reported as "unused" by deplint,
298
+ * even if no import for them is detected in source or dist files.
299
+ * Useful for packages that are used implicitly (e.g. runtime plugins,
300
+ * CSS-in-JS themes, or polyfills that have side effects on import).
301
+ */
302
+ exclude?: string[];
303
+ }
284
304
  interface XyConfigBase {
285
305
  compile?: CompileConfig;
306
+ deplint?: DeplintConfig;
286
307
  dynamicShare?: DynamicShareConfig;
287
308
  liveShare?: LiveShareConfig;
288
309
  /** @deprecated */
@@ -444,4 +465,4 @@ declare const xyLintCommands: (args: Argv) => Argv<{}>;
444
465
 
445
466
  declare const xyParseOptions: () => Argv;
446
467
 
447
- export { type BuildParams, CROSS_PLATFORM_NEWLINE, type CleanPackageParams, type CleanParams, type CompileConfig, type CompileParams, type CopyAssetsParams, type CycleParams, type DepLintOptions, DuplicateDetector, type DynamicShareConfig, type EntryMode, type GenDocsPackageParams, type GenDocsParams, INIT_CWD, type LintPackageParams, type LintParams, type LiveShareConfig, type PackageCompileTscConfig, type PackageCompileTsupConfig, type PackageCopyAssetsParams, type PackageJsonEx, type PackagePublintParams, type PathConfig, type PublintPackageParams, type PublintParams, type ReadFileSyncOptions, type RebuildParams, type RecompilePackageParams, type RecompileParams, type RelintPackageParams, type RelintParams, type ScriptStep, WINDOWS_NEWLINE_REGEX, type Workspace, XYLABS_COMMANDS_PREFIX, XYLABS_RULES_PREFIX, type XyConfig, type XyConfigBase, type XyConfigLegacy, type XyTscConfig, type XyTsupConfig, build, bundleDts, checkResult, claudeCommandTemplates, claudeCommands, claudeMdProjectTemplate, claudeMdRuleTemplates, claudeRules, clean, cleanAll, cleanDocs, cleanPackage, compile, compileAll, compilePackage, copyAssets, createBuildConfig, cycle, cycleAll, cyclePackage, dead, defaultBuildConfig, defaultReadFileSyncOptions, deleteGlob, deplint, deploy, deployMajor, deployMinor, deployNext, detectDuplicateDependencies, dupdeps, empty, fix, genDocs, genDocsAll, genDocsPackage, generateIgnoreFiles, gitignoreGen, gitlint, gitlintFix, isYarnVersionOrGreater, knip, license, lint, lintAllPackages, lintPackage, loadConfig, loadPackageConfig, multiLineToJSONArray, notEmpty, npmignoreGen, packageClean, packageCleanOutputs, packageCleanTypescript, packageCompile, packageCompileTsc, packageCompileTscTypes, packageCompileTsup, packageCopyAssets, packageCycle, packageGenDocs, packageLint, packagePublint, packageRecompile, parsedPackageJSON, processEx, publint, publintAll, publintPackage, publish, readLines, readNonEmptyLines, rebuild, recompile, recompileAll, recompilePackage, reinstall, relint, relintAllPackages, relintPackage, retest, runStepAsync, runSteps, runStepsAsync, runXy, runXyWithWarning, safeExit, safeExitAsync, sonar, statics, test, tryReadFileSync, tsupOptions, union, up, updateYarnPlugins, updateYarnVersion, updo, withErrnoException, withError, writeLines, xy, xyBuildCommands, xyCommonCommands, xyDeployCommands, xyInstallCommands, xyLintCommands, xyParseOptions, yarn3Only, yarnWorkspace, yarnWorkspaces };
468
+ export { type BuildParams, CROSS_PLATFORM_NEWLINE, type CleanPackageParams, type CleanParams, type CompileConfig, type CompileParams, type CopyAssetsParams, type CycleParams, type DepLintOptions, type DeplintConfig, DuplicateDetector, type DynamicShareConfig, type EntryMode, type GenDocsPackageParams, type GenDocsParams, INIT_CWD, type LintPackageParams, type LintParams, type LiveShareConfig, type PackageCompileTscConfig, type PackageCompileTsupConfig, type PackageCopyAssetsParams, type PackageJsonEx, type PackagePublintParams, type PathConfig, type PublintPackageParams, type PublintParams, type ReadFileSyncOptions, type RebuildParams, type RecompilePackageParams, type RecompileParams, type RelintPackageParams, type RelintParams, type ScriptStep, WINDOWS_NEWLINE_REGEX, type Workspace, XYLABS_COMMANDS_PREFIX, XYLABS_RULES_PREFIX, type XyConfig, type XyConfigBase, type XyConfigLegacy, type XyTscConfig, type XyTsupConfig, build, bundleDts, checkResult, claudeCommandTemplates, claudeCommands, claudeMdProjectTemplate, claudeMdRuleTemplates, claudeRules, clean, cleanAll, cleanDocs, cleanPackage, compile, compileAll, compilePackage, copyAssets, createBuildConfig, cycle, cycleAll, cyclePackage, dead, defaultBuildConfig, defaultReadFileSyncOptions, deleteGlob, deplint, deploy, deployMajor, deployMinor, deployNext, detectDuplicateDependencies, dupdeps, empty, fix, genDocs, genDocsAll, genDocsPackage, generateIgnoreFiles, gitignoreGen, gitlint, gitlintFix, isYarnVersionOrGreater, knip, license, lint, lintAllPackages, lintPackage, loadConfig, loadPackageConfig, multiLineToJSONArray, notEmpty, npmignoreGen, packageClean, packageCleanOutputs, packageCleanTypescript, packageCompile, packageCompileTsc, packageCompileTscTypes, packageCompileTsup, packageCopyAssets, packageCycle, packageGenDocs, packageLint, packagePublint, packageRecompile, parsedPackageJSON, processEx, publint, publintAll, publintPackage, publish, readLines, readNonEmptyLines, rebuild, recompile, recompileAll, recompilePackage, reinstall, relint, relintAllPackages, relintPackage, retest, runStepAsync, runSteps, runStepsAsync, runXy, runXyWithWarning, safeExit, safeExitAsync, sonar, statics, test, tryReadFileSync, tsupOptions, union, up, updateYarnPlugins, updateYarnVersion, updo, withErrnoException, withError, writeLines, xy, xyBuildCommands, xyCommonCommands, xyDeployCommands, xyInstallCommands, xyLintCommands, xyParseOptions, yarn3Only, yarnWorkspace, yarnWorkspaces };
package/dist/index.mjs CHANGED
@@ -402,8 +402,8 @@ var loadConfig = async (params) => {
402
402
 
403
403
  // src/lib/parsedPackageJSON.ts
404
404
  import { readFileSync as readFileSync5 } from "fs";
405
- var parsedPackageJSON = (path13) => {
406
- const pathToPackageJSON = path13 ?? process.env.npm_package_json ?? "";
405
+ var parsedPackageJSON = (path14) => {
406
+ const pathToPackageJSON = path14 ?? process.env.npm_package_json ?? "";
407
407
  const packageJSON = readFileSync5(pathToPackageJSON).toString();
408
408
  return JSON.parse(packageJSON);
409
409
  };
@@ -1052,11 +1052,11 @@ function getExternalImportsFromFiles({
1052
1052
  const allImportPaths = {};
1053
1053
  const distImportPaths = {};
1054
1054
  const distTypeImportPaths = {};
1055
- for (const path13 of allFiles) getImportsFromFile(path13, allImportPaths, allImportPaths).flat();
1055
+ for (const path14 of allFiles) getImportsFromFile(path14, allImportPaths, allImportPaths).flat();
1056
1056
  const distTypeFiles = distFiles.filter(isDeclarationFile);
1057
1057
  const distCodeFiles = distFiles.filter((file) => !isDeclarationFile(file));
1058
- for (const path13 of distCodeFiles) getImportsFromFile(path13, distImportPaths, distImportPaths).flat();
1059
- for (const path13 of distTypeFiles) getImportsFromFile(path13, distTypeImportPaths, distTypeImportPaths).flat();
1058
+ for (const path14 of distCodeFiles) getImportsFromFile(path14, distImportPaths, distImportPaths).flat();
1059
+ for (const path14 of distTypeFiles) getImportsFromFile(path14, distTypeImportPaths, distTypeImportPaths).flat();
1060
1060
  const allImports = Object.keys(allImportPaths);
1061
1061
  const distImports = Object.keys(distImportPaths);
1062
1062
  const externalAllImports = removeInternalImports(allImports);
@@ -1150,9 +1150,10 @@ function getUnusedDependencies({ name, location }, { dependencies }, {
1150
1150
  externalDistImports,
1151
1151
  externalDistTypeImports,
1152
1152
  externalAllImports
1153
- }) {
1153
+ }, exclude) {
1154
1154
  let unusedDependencies = 0;
1155
1155
  for (const dep of dependencies) {
1156
+ if (exclude?.has(dep)) continue;
1156
1157
  if (!externalDistImports.includes(dep) && !externalDistImports.includes(dep.replace(/^@types\//, "")) && !externalDistTypeImports.includes(dep) && !externalDistTypeImports.includes(dep.replace(/^@types\//, ""))) {
1157
1158
  unusedDependencies++;
1158
1159
  if (externalAllImports.includes(dep)) {
@@ -1173,6 +1174,15 @@ function getUnusedDependencies({ name, location }, { dependencies }, {
1173
1174
  // src/actions/deplint/checkPackage/getUnusedDevDependencies.ts
1174
1175
  import chalk18 from "chalk";
1175
1176
 
1177
+ // src/actions/deplint/getCliReferencedPackagesFromFiles.ts
1178
+ import fs8 from "fs";
1179
+ import path7 from "path";
1180
+ import ts2 from "typescript";
1181
+
1182
+ // src/actions/deplint/getScriptReferencedPackages.ts
1183
+ import fs7 from "fs";
1184
+ import path6 from "path";
1185
+
1176
1186
  // src/actions/deplint/getRequiredPeerDependencies.ts
1177
1187
  import fs6 from "fs";
1178
1188
  import path5 from "path";
@@ -1206,8 +1216,6 @@ function getRequiredPeerDependencies(location, allDeps) {
1206
1216
  }
1207
1217
 
1208
1218
  // src/actions/deplint/getScriptReferencedPackages.ts
1209
- import fs7 from "fs";
1210
- import path6 from "path";
1211
1219
  function getBinNames(location, dep) {
1212
1220
  const depPkgPath = findDepPackageJson(location, dep);
1213
1221
  if (!depPkgPath) return [];
@@ -1257,15 +1265,101 @@ function getScriptReferencedPackages(location, allDeps) {
1257
1265
  return referenced;
1258
1266
  }
1259
1267
 
1268
+ // src/actions/deplint/getCliReferencedPackagesFromFiles.ts
1269
+ var shellCommandFunctions = /* @__PURE__ */ new Set(["execSync", "exec"]);
1270
+ var directExecFunctions = /* @__PURE__ */ new Set(["spawn", "spawnSync", "execFile", "execFileSync"]);
1271
+ var allExecFunctions = /* @__PURE__ */ new Set([...shellCommandFunctions, ...directExecFunctions]);
1272
+ function getCommandTokensFromFile(filePath) {
1273
+ const tokens = /* @__PURE__ */ new Set();
1274
+ let sourceCode;
1275
+ try {
1276
+ sourceCode = fs8.readFileSync(filePath, "utf8");
1277
+ } catch {
1278
+ return tokens;
1279
+ }
1280
+ const isMjsFile = filePath.endsWith(".mjs");
1281
+ const sourceFile = ts2.createSourceFile(
1282
+ path7.basename(filePath),
1283
+ sourceCode,
1284
+ ts2.ScriptTarget.Latest,
1285
+ true,
1286
+ isMjsFile ? ts2.ScriptKind.JS : void 0
1287
+ );
1288
+ function visit(node) {
1289
+ if (ts2.isCallExpression(node) && node.arguments.length > 0) {
1290
+ const fnName = getFunctionName(node.expression);
1291
+ if (fnName && allExecFunctions.has(fnName)) {
1292
+ const firstArg = node.arguments[0];
1293
+ if (ts2.isStringLiteral(firstArg) || ts2.isNoSubstitutionTemplateLiteral(firstArg)) {
1294
+ const value = firstArg.text;
1295
+ if (shellCommandFunctions.has(fnName)) {
1296
+ for (const token of tokenizeScript(value)) {
1297
+ tokens.add(token);
1298
+ }
1299
+ } else {
1300
+ tokens.add(value);
1301
+ }
1302
+ } else if (ts2.isTemplateExpression(firstArg)) {
1303
+ const head = firstArg.head.text;
1304
+ if (head) {
1305
+ for (const token of tokenizeScript(head)) {
1306
+ tokens.add(token);
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1311
+ }
1312
+ ts2.forEachChild(node, visit);
1313
+ }
1314
+ visit(sourceFile);
1315
+ return tokens;
1316
+ }
1317
+ function getFunctionName(expr) {
1318
+ if (ts2.isIdentifier(expr)) {
1319
+ return expr.text;
1320
+ }
1321
+ if (ts2.isPropertyAccessExpression(expr) && ts2.isIdentifier(expr.name)) {
1322
+ return expr.name.text;
1323
+ }
1324
+ return void 0;
1325
+ }
1326
+ function getCliReferencedPackagesFromFiles(allFiles, location, allDeps) {
1327
+ const allTokens = /* @__PURE__ */ new Set();
1328
+ for (const file of allFiles) {
1329
+ for (const token of getCommandTokensFromFile(file)) {
1330
+ allTokens.add(token);
1331
+ }
1332
+ }
1333
+ if (allTokens.size === 0) return /* @__PURE__ */ new Set();
1334
+ const binToPackage = /* @__PURE__ */ new Map();
1335
+ for (const dep of allDeps) {
1336
+ for (const bin of getBinNames(location, dep)) {
1337
+ binToPackage.set(bin, dep);
1338
+ }
1339
+ }
1340
+ const referenced = /* @__PURE__ */ new Set();
1341
+ for (const token of allTokens) {
1342
+ const baseName = getBasePackageName(token);
1343
+ if (allDeps.includes(baseName)) {
1344
+ referenced.add(baseName);
1345
+ }
1346
+ const pkg = binToPackage.get(token);
1347
+ if (pkg) {
1348
+ referenced.add(pkg);
1349
+ }
1350
+ }
1351
+ return referenced;
1352
+ }
1353
+
1260
1354
  // src/actions/deplint/implicitDevDependencies.ts
1261
- import fs8 from "fs";
1355
+ import fs9 from "fs";
1262
1356
  var hasFileWithExtension = (files, extensions) => files.some((f) => extensions.some((ext) => f.endsWith(ext)));
1263
1357
  var tsExtensions = [".ts", ".tsx", ".mts", ".cts"];
1264
1358
  var hasTypescriptFiles = ({ allFiles }) => hasFileWithExtension(allFiles, tsExtensions);
1265
1359
  var decoratorPattern = /^\s*@[a-zA-Z]\w*/m;
1266
1360
  var hasDecorators = ({ allFiles }) => allFiles.filter((f) => tsExtensions.some((ext) => f.endsWith(ext))).some((file) => {
1267
1361
  try {
1268
- const content = fs8.readFileSync(file, "utf8");
1362
+ const content = fs9.readFileSync(file, "utf8");
1269
1363
  return decoratorPattern.test(content);
1270
1364
  } catch {
1271
1365
  return false;
@@ -1278,7 +1372,7 @@ function hasImportPlugin({ location, allDependencies }) {
1278
1372
  const pkgPath = findDepPackageJson(location, dep);
1279
1373
  if (!pkgPath) continue;
1280
1374
  try {
1281
- const pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf8"));
1375
+ const pkg = JSON.parse(fs9.readFileSync(pkgPath, "utf8"));
1282
1376
  const transitiveDeps = [
1283
1377
  ...Object.keys(pkg.dependencies ?? {}),
1284
1378
  ...Object.keys(pkg.peerDependencies ?? {})
@@ -1330,10 +1424,11 @@ var allExternalImports = ({
1330
1424
  ...externalDistTypeImports
1331
1425
  ]);
1332
1426
  };
1333
- function isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs) {
1427
+ function isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs, cliRefs) {
1334
1428
  if (implicitDeps.has(dep)) return true;
1335
1429
  if (requiredPeers.has(dep)) return true;
1336
1430
  if (scriptRefs.has(dep)) return true;
1431
+ if (cliRefs.has(dep)) return true;
1337
1432
  if (dep.startsWith("@types/")) {
1338
1433
  const baseName = dep.replace(/^@types\//, "");
1339
1434
  return allImports.has(baseName) || allImports.has(dep) || implicitDeps.has(baseName);
@@ -1344,7 +1439,7 @@ function getUnusedDevDependencies({ name, location }, {
1344
1439
  devDependencies,
1345
1440
  dependencies,
1346
1441
  peerDependencies
1347
- }, sourceParams, fileContext) {
1442
+ }, sourceParams, fileContext, exclude) {
1348
1443
  const allImports = allExternalImports(sourceParams);
1349
1444
  const allDeps = [...dependencies, ...devDependencies, ...peerDependencies];
1350
1445
  const implicitDeps = getImplicitDevDependencies({
@@ -1354,10 +1449,12 @@ function getUnusedDevDependencies({ name, location }, {
1354
1449
  });
1355
1450
  const requiredPeers = getRequiredPeerDependencies(location, allDeps);
1356
1451
  const scriptRefs = getScriptReferencedPackages(location, allDeps);
1452
+ const cliRefs = getCliReferencedPackagesFromFiles(fileContext.allFiles, location, allDeps);
1357
1453
  let unusedDevDependencies = 0;
1358
1454
  for (const dep of devDependencies) {
1455
+ if (exclude?.has(dep)) continue;
1359
1456
  if (dependencies.includes(dep) || peerDependencies.includes(dep)) continue;
1360
- if (!isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs)) {
1457
+ if (!isDevDepUsed(dep, allImports, implicitDeps, requiredPeers, scriptRefs, cliRefs)) {
1361
1458
  unusedDevDependencies++;
1362
1459
  console.log(`[${chalk18.blue(name)}] Unused devDependency in package.json: ${chalk18.red(dep)}`);
1363
1460
  }
@@ -1372,9 +1469,10 @@ function getUnusedDevDependencies({ name, location }, {
1372
1469
 
1373
1470
  // src/actions/deplint/checkPackage/getUnusedPeerDependencies.ts
1374
1471
  import chalk19 from "chalk";
1375
- function getUnusedPeerDependencies({ name, location }, { peerDependencies, dependencies }, { externalDistImports, externalDistTypeImports }) {
1472
+ function getUnusedPeerDependencies({ name, location }, { peerDependencies, dependencies }, { externalDistImports, externalDistTypeImports }, exclude) {
1376
1473
  let unusedDependencies = 0;
1377
1474
  for (const dep of peerDependencies) {
1475
+ if (exclude?.has(dep)) continue;
1378
1476
  if (!externalDistImports.includes(dep) && !externalDistImports.includes(dep.replace(/^@types\//, "")) && !externalDistTypeImports.includes(dep) && !externalDistTypeImports.includes(dep.replace(/^@types\//, ""))) {
1379
1477
  unusedDependencies++;
1380
1478
  if (dependencies.includes(dep)) {
@@ -1411,6 +1509,7 @@ function checkPackage({
1411
1509
  location,
1412
1510
  deps = false,
1413
1511
  devDeps = false,
1512
+ exclude,
1414
1513
  peerDeps = false,
1415
1514
  verbose = false
1416
1515
  }) {
@@ -1429,23 +1528,29 @@ function checkPackage({
1429
1528
  });
1430
1529
  const packageParams = getDependenciesFromPackageJson(`${location}/package.json`);
1431
1530
  const unlistedDependencies = checkDeps ? getUnlistedDependencies({ name, location }, packageParams, sourceParams) : 0;
1432
- const unusedDependencies = checkDeps ? getUnusedDependencies({ name, location }, packageParams, sourceParams) : 0;
1531
+ const unusedDependencies = checkDeps ? getUnusedDependencies({ name, location }, packageParams, sourceParams, exclude) : 0;
1433
1532
  const unlistedDevDependencies = checkDevDeps ? getUnlistedDevDependencies({ name, location }, packageParams, sourceParams) : 0;
1434
1533
  const fileContext = { allFiles, distFiles };
1435
- const unusedDevDependencies = checkDevDeps ? getUnusedDevDependencies({ name, location }, packageParams, sourceParams, fileContext) : 0;
1436
- const unusedPeerDependencies = checkPeerDeps ? getUnusedPeerDependencies({ name, location }, packageParams, sourceParams) : 0;
1534
+ const unusedDevDependencies = checkDevDeps ? getUnusedDevDependencies({ name, location }, packageParams, sourceParams, fileContext, exclude) : 0;
1535
+ const unusedPeerDependencies = checkPeerDeps ? getUnusedPeerDependencies({ name, location }, packageParams, sourceParams, exclude) : 0;
1437
1536
  const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + unusedDevDependencies + unusedPeerDependencies;
1438
1537
  return totalErrors;
1439
1538
  }
1440
1539
 
1441
1540
  // src/actions/deplint/deplint.ts
1442
- var deplint = ({
1541
+ var deplint = async ({
1443
1542
  pkg,
1444
1543
  deps,
1445
1544
  devDeps,
1446
1545
  peerDeps,
1447
- verbose
1546
+ verbose,
1547
+ cliExclude
1448
1548
  }) => {
1549
+ const config2 = await loadConfig();
1550
+ const exclude = /* @__PURE__ */ new Set([
1551
+ ...config2.deplint?.exclude ?? [],
1552
+ ...cliExclude ?? []
1553
+ ]);
1449
1554
  let totalErrors = 0;
1450
1555
  if (pkg === void 0) {
1451
1556
  const workspaces = yarnWorkspaces();
@@ -1455,6 +1560,7 @@ var deplint = ({
1455
1560
  ...workspace,
1456
1561
  deps,
1457
1562
  devDeps,
1563
+ exclude,
1458
1564
  peerDeps,
1459
1565
  verbose
1460
1566
  });
@@ -1467,6 +1573,7 @@ var deplint = ({
1467
1573
  location,
1468
1574
  devDeps,
1469
1575
  deps,
1576
+ exclude,
1470
1577
  peerDeps,
1471
1578
  verbose
1472
1579
  });
@@ -1800,12 +1907,12 @@ var filename2 = ".npmignore";
1800
1907
  var npmignoreGen = (pkg) => generateIgnoreFiles(filename2, pkg);
1801
1908
 
1802
1909
  // src/actions/package/clean-outputs.ts
1803
- import path7 from "path";
1910
+ import path8 from "path";
1804
1911
  import chalk26 from "chalk";
1805
1912
  var packageCleanOutputs = () => {
1806
1913
  const pkg = process.env.INIT_CWD ?? ".";
1807
1914
  const pkgName = process.env.npm_package_name;
1808
- const folders = [path7.join(pkg, "dist"), path7.join(pkg, "build"), path7.join(pkg, "docs")];
1915
+ const folders = [path8.join(pkg, "dist"), path8.join(pkg, "build"), path8.join(pkg, "docs")];
1809
1916
  console.log(chalk26.green(`Cleaning Outputs [${pkgName}]`));
1810
1917
  for (let folder of folders) {
1811
1918
  deleteGlob(folder);
@@ -1814,13 +1921,13 @@ var packageCleanOutputs = () => {
1814
1921
  };
1815
1922
 
1816
1923
  // src/actions/package/clean-typescript.ts
1817
- import path8 from "path";
1924
+ import path9 from "path";
1818
1925
  import chalk27 from "chalk";
1819
1926
  var packageCleanTypescript = () => {
1820
1927
  const pkg = process.env.INIT_CWD ?? ".";
1821
1928
  const pkgName = process.env.npm_package_name;
1822
1929
  console.log(chalk27.green(`Cleaning Typescript [${pkgName}]`));
1823
- const files = [path8.join(pkg, "*.tsbuildinfo"), path8.join(pkg, ".tsconfig.*"), path8.join(pkg, ".eslintcache")];
1930
+ const files = [path9.join(pkg, "*.tsbuildinfo"), path9.join(pkg, ".tsconfig.*"), path9.join(pkg, ".eslintcache")];
1824
1931
  for (let file of files) {
1825
1932
  deleteGlob(file);
1826
1933
  }
@@ -1913,7 +2020,7 @@ function deepMergeObjects(objects) {
1913
2020
  import { cwd as cwd2 } from "process";
1914
2021
  import chalk29 from "chalk";
1915
2022
  import { createProgramFromConfig } from "tsc-prog";
1916
- import ts2, {
2023
+ import ts3, {
1917
2024
  DiagnosticCategory,
1918
2025
  formatDiagnosticsWithColorAndContext,
1919
2026
  getPreEmitDiagnostics,
@@ -1935,10 +2042,10 @@ var packageCompileTsc = (platform, entries, srcDir = "src", outDir = "dist", com
1935
2042
  if (verbose) {
1936
2043
  console.log(chalk29.cyan(`Validating code START: ${entries.length} files to ${outDir} from ${srcDir}`));
1937
2044
  }
1938
- const configFilePath = ts2.findConfigFile(
2045
+ const configFilePath = ts3.findConfigFile(
1939
2046
  "./",
1940
2047
  // search path
1941
- ts2.sys.fileExists,
2048
+ ts3.sys.fileExists,
1942
2049
  "tsconfig.json"
1943
2050
  );
1944
2051
  if (configFilePath === void 0) {
@@ -1988,7 +2095,7 @@ var packageCompileTsc = (platform, entries, srcDir = "src", outDir = "dist", com
1988
2095
  if (nonEmitPatterns.some((pattern) => fileName.includes(pattern))) {
1989
2096
  return;
1990
2097
  }
1991
- ts2.sys.writeFile(fileName, text, writeByteOrderMark);
2098
+ ts3.sys.writeFile(fileName, text, writeByteOrderMark);
1992
2099
  });
1993
2100
  return diagnostics.reduce((acc, diag) => acc + (diag.category === DiagnosticCategory.Error ? 1 : 0), 0);
1994
2101
  }
@@ -2001,7 +2108,7 @@ var packageCompileTsc = (platform, entries, srcDir = "src", outDir = "dist", com
2001
2108
  };
2002
2109
 
2003
2110
  // src/actions/package/compile/packageCompileTscTypes.ts
2004
- import path9 from "path";
2111
+ import path10 from "path";
2005
2112
  import { cwd as cwd3 } from "process";
2006
2113
  import chalk30 from "chalk";
2007
2114
  import { rollup } from "rollup";
@@ -2010,7 +2117,7 @@ import nodeExternals from "rollup-plugin-node-externals";
2010
2117
  var ignoredWarningCodes = /* @__PURE__ */ new Set(["EMPTY_BUNDLE", "UNRESOLVED_IMPORT"]);
2011
2118
  async function bundleDts(inputPath, outputPath, platform, options, verbose = false) {
2012
2119
  const pkg = process.env.INIT_CWD ?? cwd3();
2013
- const tsconfigPath = path9.resolve(pkg, "tsconfig.json");
2120
+ const tsconfigPath = path10.resolve(pkg, "tsconfig.json");
2014
2121
  const nodePlugIns = platform === "node" ? [nodeExternals()] : [];
2015
2122
  try {
2016
2123
  const bundle = await rollup({
@@ -2239,7 +2346,7 @@ var packageCompile = async (inConfig = {}) => {
2239
2346
  };
2240
2347
 
2241
2348
  // src/actions/package/copy-assets.ts
2242
- import path10 from "path/posix";
2349
+ import path11 from "path/posix";
2243
2350
  import chalk33 from "chalk";
2244
2351
  import cpy2 from "cpy";
2245
2352
  var copyTargetAssets2 = async (target, name, location) => {
@@ -2248,7 +2355,7 @@ var copyTargetAssets2 = async (target, name, location) => {
2248
2355
  ["**/*.jpg", "**/*.png", "**/*.gif", "**/*.svg", "**/*.webp", "**/*.sass", "**/*.scss", "**/*.gif", "**/*.css"],
2249
2356
  `../dist/${target}`,
2250
2357
  {
2251
- cwd: path10.join(location, "src"),
2358
+ cwd: path11.join(location, "src"),
2252
2359
  flat: false
2253
2360
  }
2254
2361
  );
@@ -2319,7 +2426,7 @@ var packageCycle = async () => {
2319
2426
 
2320
2427
  // src/actions/package/gen-docs.ts
2321
2428
  import { existsSync as existsSync7 } from "fs";
2322
- import path11 from "path";
2429
+ import path12 from "path";
2323
2430
  import chalk34 from "chalk";
2324
2431
  import {
2325
2432
  Application,
@@ -2338,7 +2445,7 @@ var ExitCodes = {
2338
2445
  };
2339
2446
  var packageGenDocs = async () => {
2340
2447
  const pkg = process.env.INIT_CWD;
2341
- if (pkg !== void 0 && !existsSync7(path11.join(pkg, "typedoc.json"))) {
2448
+ if (pkg !== void 0 && !existsSync7(path12.join(pkg, "typedoc.json"))) {
2342
2449
  return;
2343
2450
  }
2344
2451
  const app = await Application.bootstrap({
@@ -2430,7 +2537,7 @@ var runTypeDoc = async (app) => {
2430
2537
 
2431
2538
  // src/actions/package/lint.ts
2432
2539
  import { readdirSync as readdirSync4 } from "fs";
2433
- import path12 from "path";
2540
+ import path13 from "path";
2434
2541
  import { cwd as cwd4 } from "process";
2435
2542
  import { pathToFileURL } from "url";
2436
2543
  import chalk35 from "chalk";
@@ -2467,7 +2574,7 @@ function getFiles(dir, ignoreFolders) {
2467
2574
  const subDirectory = dir.split(currentDirectory)[1]?.split("/")[1];
2468
2575
  if (ignoreFolders.includes(subDirectory)) return [];
2469
2576
  return readdirSync4(dir, { withFileTypes: true }).flatMap((dirent) => {
2470
- const res = path12.resolve(dir, dirent.name);
2577
+ const res = path13.resolve(dir, dirent.name);
2471
2578
  const relativePath = subDirectory === void 0 ? dirent.name : `${subDirectory}/${dirent.name}`;
2472
2579
  const ignoreMatchers = ignoreFolders.map((pattern) => picomatch(pattern));
2473
2580
  if (ignoreMatchers.some((isMatch) => isMatch(relativePath))) return [];
@@ -2506,7 +2613,7 @@ var packageLint = async (fix2 = false, verbose = false, cache = true) => {
2506
2613
  };
2507
2614
 
2508
2615
  // src/actions/package/publint.ts
2509
- import { promises as fs9 } from "fs";
2616
+ import { promises as fs10 } from "fs";
2510
2617
  import chalk36 from "chalk";
2511
2618
  import sortPackageJson from "sort-package-json";
2512
2619
  var customPubLint = (pkg) => {
@@ -2533,9 +2640,9 @@ var customPubLint = (pkg) => {
2533
2640
  };
2534
2641
  var packagePublint = async ({ strict = true, verbose = false } = {}) => {
2535
2642
  const pkgDir = process.env.INIT_CWD;
2536
- const sortedPkg = sortPackageJson(await fs9.readFile(`${pkgDir}/package.json`, "utf8"));
2537
- await fs9.writeFile(`${pkgDir}/package.json`, sortedPkg);
2538
- const pkg = JSON.parse(await fs9.readFile(`${pkgDir}/package.json`, "utf8"));
2643
+ const sortedPkg = sortPackageJson(await fs10.readFile(`${pkgDir}/package.json`, "utf8"));
2644
+ await fs10.writeFile(`${pkgDir}/package.json`, sortedPkg);
2645
+ const pkg = JSON.parse(await fs10.readFile(`${pkgDir}/package.json`, "utf8"));
2539
2646
  console.log(chalk36.green(`Publint: ${pkg.name}`));
2540
2647
  console.log(chalk36.gray(pkgDir));
2541
2648
  const { publint: publint2 } = await import("publint");
@@ -3257,12 +3364,18 @@ var xyLintCommands = (args) => {
3257
3364
  default: false,
3258
3365
  description: "Check peerDependencies",
3259
3366
  type: "boolean"
3367
+ }).option("exclude", {
3368
+ alias: "e",
3369
+ description: "Package names to exclude from unused checks (comma-separated or repeated)",
3370
+ type: "array"
3260
3371
  });
3261
3372
  },
3262
- (argv) => {
3373
+ async (argv) => {
3263
3374
  if (argv.verbose) console.log("Deplint");
3264
3375
  const start = Date.now();
3265
- process.exitCode = deplint({
3376
+ const cliExclude = argv.exclude?.flatMap((v) => String(v).split(",")).map((v) => v.trim()).filter(Boolean);
3377
+ process.exitCode = await deplint({
3378
+ cliExclude,
3266
3379
  pkg: argv.package,
3267
3380
  deps: !!argv.deps,
3268
3381
  devDeps: !!argv.devDeps,