deslop-js 0.0.20-dev.9342b67 → 0.0.21-dev.3d2e8a1

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/index.cjs CHANGED
@@ -4883,7 +4883,7 @@ const extractNextConfigPluginFiles = (directory) => {
4883
4883
  const VITEST_INCLUDE_ITEM_PATTERN = /['"]([^'"]+)['"]/g;
4884
4884
  const COVERAGE_BLOCK_PATTERN = /coverage\s*:\s*\{/g;
4885
4885
  const TEST_MATCH_ARRAY_PATTERN = /testMatch\s*:\s*\[([^\]]*)\]/;
4886
- const STRING_LITERAL_PATTERN = /['"]([^'"]+)['"]/g;
4886
+ const STRING_LITERAL_PATTERN$1 = /['"]([^'"]+)['"]/g;
4887
4887
  const extractJestTestMatchPatterns = (directory) => {
4888
4888
  const configPaths = fast_glob.default.sync(["jest.config.{ts,js,mjs,cjs}"], {
4889
4889
  cwd: directory,
@@ -4905,9 +4905,9 @@ const extractJestTestMatchPatterns = (directory) => {
4905
4905
  if (!testMatchMatch) continue;
4906
4906
  const arrayContent = testMatchMatch[1];
4907
4907
  const patterns = [];
4908
- STRING_LITERAL_PATTERN.lastIndex = 0;
4908
+ STRING_LITERAL_PATTERN$1.lastIndex = 0;
4909
4909
  let itemMatch;
4910
- while ((itemMatch = STRING_LITERAL_PATTERN.exec(arrayContent)) !== null) patterns.push(itemMatch[1]);
4910
+ while ((itemMatch = STRING_LITERAL_PATTERN$1.exec(arrayContent)) !== null) patterns.push(itemMatch[1]);
4911
4911
  if (patterns.length > 0) return convertJestTestMatchToGlobs(patterns);
4912
4912
  } catch {}
4913
4913
  return [];
@@ -6324,6 +6324,19 @@ const isPlatformBuiltinOrVirtualSpecifier = (specifier) => {
6324
6324
  return BUILTIN_SUBPATH_NODE_MODULES.has(baseName);
6325
6325
  };
6326
6326
 
6327
+ //#endregion
6328
+ //#region src/utils/sanitize-import-specifier.ts
6329
+ const sanitizeImportSpecifier = (specifier) => {
6330
+ if (specifier.startsWith("node:") || specifier.startsWith("data:") || specifier.includes("://")) return specifier;
6331
+ const lastLoaderSeparator = specifier.lastIndexOf("!");
6332
+ let cleaned = lastLoaderSeparator === -1 ? specifier : specifier.slice(lastLoaderSeparator + 1);
6333
+ const queryIndex = cleaned.indexOf("?");
6334
+ if (queryIndex !== -1) cleaned = cleaned.slice(0, queryIndex);
6335
+ const fragmentIndex = cleaned.indexOf("#", 1);
6336
+ if (fragmentIndex !== -1) cleaned = cleaned.slice(0, fragmentIndex);
6337
+ return cleaned || specifier;
6338
+ };
6339
+
6327
6340
  //#endregion
6328
6341
  //#region src/resolver/resolve.ts
6329
6342
  const fileExistsCache = /* @__PURE__ */ new Map();
@@ -6388,6 +6401,50 @@ const resolvePathWithExtensionFallback = (candidatePath) => {
6388
6401
  }
6389
6402
  return candidatePath;
6390
6403
  };
6404
+ const resolveAliasTarget = (target) => {
6405
+ if (existsAsFile(target)) return target;
6406
+ for (const extension of RESOLVER_EXTENSIONS) if (cachedExistsSync(target + extension)) return target + extension;
6407
+ const sourceTarget = target.replace(/\.[cm]?js$/, "");
6408
+ if (sourceTarget !== target) {
6409
+ for (const extension of RESOLVER_EXTENSIONS) if (cachedExistsSync(sourceTarget + extension)) return sourceTarget + extension;
6410
+ }
6411
+ const indexCandidate = (0, node_path.join)(target, "index");
6412
+ for (const extension of RESOLVER_EXTENSIONS) if (cachedExistsSync(indexCandidate + extension)) return indexCandidate + extension;
6413
+ };
6414
+ const pathMappingSpecificity = (mapping) => mapping.isWildcard ? mapping.prefix.length + mapping.suffix.length : Number.MAX_SAFE_INTEGER;
6415
+ const compilePathMappings = (entries) => {
6416
+ const compiled = [];
6417
+ for (const [pattern, targets] of entries) {
6418
+ const wildcardIndex = pattern.indexOf("*");
6419
+ if (wildcardIndex === -1) compiled.push({
6420
+ prefix: pattern,
6421
+ suffix: "",
6422
+ isWildcard: false,
6423
+ targets
6424
+ });
6425
+ else compiled.push({
6426
+ prefix: pattern.slice(0, wildcardIndex),
6427
+ suffix: pattern.slice(wildcardIndex + 1),
6428
+ isWildcard: true,
6429
+ targets
6430
+ });
6431
+ }
6432
+ compiled.sort((left, right) => pathMappingSpecificity(right) - pathMappingSpecificity(left));
6433
+ return compiled;
6434
+ };
6435
+ const matchCompiledMapping = (specifier, mappings) => {
6436
+ for (const mapping of mappings) {
6437
+ let matchedWildcard = "";
6438
+ if (mapping.isWildcard) {
6439
+ if (!specifier.startsWith(mapping.prefix) || !specifier.endsWith(mapping.suffix)) continue;
6440
+ matchedWildcard = specifier.slice(mapping.prefix.length, specifier.length - mapping.suffix.length);
6441
+ } else if (specifier !== mapping.prefix) continue;
6442
+ for (const target of mapping.targets) {
6443
+ const resolved = resolveAliasTarget(target.replace("*", matchedWildcard));
6444
+ if (resolved) return resolved;
6445
+ }
6446
+ }
6447
+ };
6391
6448
  const COMMON_RESOLVER_OPTIONS = {
6392
6449
  conditionNames: [
6393
6450
  "import",
@@ -6419,11 +6476,26 @@ const WEBPACK_CONFIG_GLOBS = [
6419
6476
  "**/webpack.config*.{js,ts,mjs,cjs}",
6420
6477
  "**/webpack*.config*.babel.{js,ts}"
6421
6478
  ];
6422
- const WEBPACK_ALIAS_BLOCK_PATTERN = /alias\s*:\s*\{([\s\S]*?)\}/g;
6423
- const WEBPACK_ALIAS_ENTRY_PATTERN = /["']?([@\w$./-]+)["']?\s*:\s*(?:path\.(?:resolve|join)\(\s*__dirname\s*,\s*((?:["'][^"']+["']\s*,?\s*)+)\)|["']([^"']+)["'])/g;
6479
+ const VITE_CONFIG_GLOBS = [
6480
+ "vite.config.{js,ts,mjs,cjs,mts,cts}",
6481
+ "vitest.config.{js,ts,mjs,cjs,mts,cts}",
6482
+ "**/vite.config.{js,ts,mjs,cjs,mts,cts}",
6483
+ "**/vitest.config.{js,ts,mjs,cjs,mts,cts}"
6484
+ ];
6485
+ const BABEL_CONFIG_GLOBS = [
6486
+ "babel.config.{js,cjs,mjs,json}",
6487
+ ".babelrc",
6488
+ ".babelrc.{js,cjs,mjs,json}",
6489
+ "**/babel.config.{js,cjs,mjs,json}"
6490
+ ];
6491
+ const JEST_CONFIG_GLOBS = ["jest.config.{js,ts,mjs,cjs,json}", "**/jest.config.{js,ts,mjs,cjs,json}"];
6492
+ const ALIAS_BLOCK_PATTERN = /alias\s*:\s*\{([\s\S]*?)\}/g;
6493
+ const ALIAS_ENTRY_PATTERN = /["']?([@\w$./-]+)["']?\s*:\s*(?:path\.(?:resolve|join)\(\s*__dirname\s*,\s*((?:["'][^"']+["']\s*,?\s*)+)\)|fileURLToPath\(\s*new URL\(\s*["']([^"']+)["']\s*,\s*import\.meta\.url\s*\)\s*\)|["']([^"']+)["'])/g;
6494
+ const JEST_MODULE_NAME_MAPPER_BLOCK_PATTERN = /moduleNameMapper\s*:\s*\{([\s\S]*?)\}/g;
6495
+ const JEST_MODULE_NAME_MAPPER_ENTRY_PATTERN = /["']([^"']+)["']\s*:\s*["']([^"']+)["']/g;
6424
6496
  const WEBPACK_MODULES_BLOCK_PATTERN = /modules\s*:\s*\[([\s\S]*?)\]/g;
6425
6497
  const WEBPACK_PATH_CALL_PATTERN = /path\.(?:resolve|join)\(\s*__dirname\s*,\s*((?:["'][^"']+["']\s*,?\s*)+)\)/g;
6426
- const WEBPACK_STRING_LITERAL_PATTERN = /["']([^"']+)["']/g;
6498
+ const STRING_LITERAL_PATTERN = /["']([^"']+)["']/g;
6427
6499
  const TSCONFIG_FILENAMES = [
6428
6500
  "tsconfig.json",
6429
6501
  "tsconfig.web.json",
@@ -6480,15 +6552,15 @@ const isInsideDirectory = (filePath, directory) => {
6480
6552
  const extractQuotedSegments = (value) => {
6481
6553
  const segments = [];
6482
6554
  let segmentMatch;
6483
- WEBPACK_STRING_LITERAL_PATTERN.lastIndex = 0;
6484
- while ((segmentMatch = WEBPACK_STRING_LITERAL_PATTERN.exec(value)) !== null) segments.push(segmentMatch[1]);
6555
+ STRING_LITERAL_PATTERN.lastIndex = 0;
6556
+ while ((segmentMatch = STRING_LITERAL_PATTERN.exec(value)) !== null) segments.push(segmentMatch[1]);
6485
6557
  return segments;
6486
6558
  };
6487
- const resolveWebpackPathValue = (value, configDirectory) => {
6559
+ const resolveConfigPathValue = (value, configDirectory) => {
6488
6560
  if ((0, node_path.isAbsolute)(value)) return value;
6489
6561
  return (0, node_path.resolve)(configDirectory, value);
6490
6562
  };
6491
- const findWebpackConfigScope = (configPath, rootDir) => {
6563
+ const findConfigScope = (configPath, rootDir) => {
6492
6564
  let currentDirectory = (0, node_path.dirname)(configPath);
6493
6565
  const absoluteRoot = (0, node_path.resolve)(rootDir);
6494
6566
  while (currentDirectory.length >= absoluteRoot.length) {
@@ -6499,24 +6571,25 @@ const findWebpackConfigScope = (configPath, rootDir) => {
6499
6571
  }
6500
6572
  return absoluteRoot;
6501
6573
  };
6502
- const extractWebpackAliases = (content, configDirectory) => {
6574
+ const extractBundlerAliases = (content, configDirectory) => {
6503
6575
  const aliases = [];
6504
6576
  let aliasBlockMatch;
6505
- WEBPACK_ALIAS_BLOCK_PATTERN.lastIndex = 0;
6506
- while ((aliasBlockMatch = WEBPACK_ALIAS_BLOCK_PATTERN.exec(content)) !== null) {
6577
+ ALIAS_BLOCK_PATTERN.lastIndex = 0;
6578
+ while ((aliasBlockMatch = ALIAS_BLOCK_PATTERN.exec(content)) !== null) {
6507
6579
  const aliasBlock = aliasBlockMatch[1];
6508
6580
  let aliasEntryMatch;
6509
- WEBPACK_ALIAS_ENTRY_PATTERN.lastIndex = 0;
6510
- while ((aliasEntryMatch = WEBPACK_ALIAS_ENTRY_PATTERN.exec(aliasBlock)) !== null) {
6581
+ ALIAS_ENTRY_PATTERN.lastIndex = 0;
6582
+ while ((aliasEntryMatch = ALIAS_ENTRY_PATTERN.exec(aliasBlock)) !== null) {
6511
6583
  const rawName = aliasEntryMatch[1];
6512
6584
  const pathCallSegments = aliasEntryMatch[2];
6513
- const stringTarget = aliasEntryMatch[3];
6514
- if (!pathCallSegments && !stringTarget) continue;
6585
+ const fileUrlTarget = aliasEntryMatch[3];
6586
+ const stringTarget = aliasEntryMatch[4];
6515
6587
  const isExact = rawName.endsWith("$");
6516
6588
  const name = isExact ? rawName.slice(0, -1) : rawName.replace(/\/$/, "");
6517
6589
  let targetDirectory;
6518
6590
  if (pathCallSegments) targetDirectory = (0, node_path.resolve)(configDirectory, ...extractQuotedSegments(pathCallSegments));
6519
- else if (stringTarget) targetDirectory = resolveWebpackPathValue(stringTarget, configDirectory);
6591
+ else if (fileUrlTarget) targetDirectory = (0, node_path.resolve)(configDirectory, fileUrlTarget);
6592
+ else if (stringTarget) targetDirectory = resolveConfigPathValue(stringTarget, configDirectory);
6520
6593
  else continue;
6521
6594
  aliases.push({
6522
6595
  name,
@@ -6527,6 +6600,32 @@ const extractWebpackAliases = (content, configDirectory) => {
6527
6600
  }
6528
6601
  return aliases;
6529
6602
  };
6603
+ const compileJestModuleNameMapperAlias = (pattern, target, configDirectory) => {
6604
+ if (!target.includes("<rootDir>")) return void 0;
6605
+ const isWildcard = pattern.includes("(.*)") || pattern.includes("(.+)");
6606
+ const aliasName = pattern.replace(/^\^/, "").replace(/\$$/, "").replace(/\\(.)/g, "$1").replace(/\/?\((?:\.\*|\.\+)\)$/, "").replace(/\/$/, "");
6607
+ if (!aliasName) return void 0;
6608
+ return {
6609
+ name: aliasName,
6610
+ targetDirectory: (0, node_path.resolve)(target.replace(/<rootDir>/g, configDirectory).replace(/\/?\$\d+$/, "")),
6611
+ isExact: !isWildcard
6612
+ };
6613
+ };
6614
+ const extractJestModuleNameMapperAliases = (content, configDirectory) => {
6615
+ const aliases = [];
6616
+ let blockMatch;
6617
+ JEST_MODULE_NAME_MAPPER_BLOCK_PATTERN.lastIndex = 0;
6618
+ while ((blockMatch = JEST_MODULE_NAME_MAPPER_BLOCK_PATTERN.exec(content)) !== null) {
6619
+ const block = blockMatch[1];
6620
+ let entryMatch;
6621
+ JEST_MODULE_NAME_MAPPER_ENTRY_PATTERN.lastIndex = 0;
6622
+ while ((entryMatch = JEST_MODULE_NAME_MAPPER_ENTRY_PATTERN.exec(block)) !== null) {
6623
+ const alias = compileJestModuleNameMapperAlias(entryMatch[1], entryMatch[2], configDirectory);
6624
+ if (alias) aliases.push(alias);
6625
+ }
6626
+ }
6627
+ return aliases;
6628
+ };
6530
6629
  const extractWebpackModuleDirectories = (content, configDirectory) => {
6531
6630
  const moduleDirectories = [];
6532
6631
  let modulesBlockMatch;
@@ -6537,17 +6636,39 @@ const extractWebpackModuleDirectories = (content, configDirectory) => {
6537
6636
  WEBPACK_PATH_CALL_PATTERN.lastIndex = 0;
6538
6637
  while ((pathCallMatch = WEBPACK_PATH_CALL_PATTERN.exec(modulesBlock)) !== null) moduleDirectories.push((0, node_path.resolve)(configDirectory, ...extractQuotedSegments(pathCallMatch[1])));
6539
6638
  let stringMatch;
6540
- WEBPACK_STRING_LITERAL_PATTERN.lastIndex = 0;
6541
- while ((stringMatch = WEBPACK_STRING_LITERAL_PATTERN.exec(modulesBlock)) !== null) {
6639
+ STRING_LITERAL_PATTERN.lastIndex = 0;
6640
+ while ((stringMatch = STRING_LITERAL_PATTERN.exec(modulesBlock)) !== null) {
6542
6641
  const moduleDirectory = stringMatch[1];
6543
6642
  if (moduleDirectory === "node_modules") continue;
6544
- moduleDirectories.push(resolveWebpackPathValue(moduleDirectory, configDirectory));
6643
+ moduleDirectories.push(resolveConfigPathValue(moduleDirectory, configDirectory));
6545
6644
  }
6546
6645
  }
6547
6646
  return [...new Set(moduleDirectories)];
6548
6647
  };
6549
- const loadWebpackResolverConfigs = (rootDir) => {
6550
- const configPaths = fast_glob.default.sync(WEBPACK_CONFIG_GLOBS, {
6648
+ const isJestConfigPath = (configPath) => /(?:^|[\\/])jest\.config\.[^\\/]+$/.test(configPath);
6649
+ const isWebpackConfigPath = (configPath) => /webpack/.test(configPath);
6650
+ const extractPackageJsonJestAliases = (rootDir) => {
6651
+ try {
6652
+ const moduleNameMapper = JSON.parse(cachedReadFileSync((0, node_path.join)(rootDir, "package.json")))?.jest?.moduleNameMapper;
6653
+ if (!moduleNameMapper || typeof moduleNameMapper !== "object") return [];
6654
+ const aliases = [];
6655
+ for (const [pattern, target] of Object.entries(moduleNameMapper)) {
6656
+ if (typeof target !== "string") continue;
6657
+ const alias = compileJestModuleNameMapperAlias(pattern, target, rootDir);
6658
+ if (alias) aliases.push(alias);
6659
+ }
6660
+ return aliases;
6661
+ } catch {
6662
+ return [];
6663
+ }
6664
+ };
6665
+ const loadBundlerAliasConfigs = (rootDir) => {
6666
+ const configPaths = fast_glob.default.sync([
6667
+ ...WEBPACK_CONFIG_GLOBS,
6668
+ ...VITE_CONFIG_GLOBS,
6669
+ ...BABEL_CONFIG_GLOBS,
6670
+ ...JEST_CONFIG_GLOBS
6671
+ ], {
6551
6672
  cwd: rootDir,
6552
6673
  absolute: true,
6553
6674
  onlyFiles: true,
@@ -6562,17 +6683,24 @@ const loadWebpackResolverConfigs = (rootDir) => {
6562
6683
  for (const configPath of configPaths) try {
6563
6684
  const content = cachedReadFileSync(configPath);
6564
6685
  const configDirectory = (0, node_path.dirname)(configPath);
6565
- const aliases = extractWebpackAliases(content, configDirectory);
6566
- const moduleDirectories = extractWebpackModuleDirectories(content, configDirectory);
6686
+ const aliases = extractBundlerAliases(content, configDirectory);
6687
+ if (isJestConfigPath(configPath)) aliases.push(...extractJestModuleNameMapperAliases(content, configDirectory));
6688
+ const moduleDirectories = isWebpackConfigPath(configPath) ? extractWebpackModuleDirectories(content, configDirectory) : [];
6567
6689
  if (aliases.length === 0 && moduleDirectories.length === 0) continue;
6568
6690
  configs.push({
6569
- scopeDirectory: findWebpackConfigScope(configPath, rootDir),
6691
+ scopeDirectory: findConfigScope(configPath, rootDir),
6570
6692
  aliases,
6571
6693
  moduleDirectories
6572
6694
  });
6573
6695
  } catch {
6574
6696
  continue;
6575
6697
  }
6698
+ const packageJsonJestAliases = extractPackageJsonJestAliases(rootDir);
6699
+ if (packageJsonJestAliases.length > 0) configs.push({
6700
+ scopeDirectory: (0, node_path.resolve)(rootDir),
6701
+ aliases: packageJsonJestAliases,
6702
+ moduleDirectories: []
6703
+ });
6576
6704
  return configs;
6577
6705
  };
6578
6706
  const createResolver = (config, workspacePackages = [], options = {}) => {
@@ -6611,7 +6739,36 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6611
6739
  };
6612
6740
  const workspaceNameToDirectory = /* @__PURE__ */ new Map();
6613
6741
  for (const workspacePackage of workspacePackages) workspaceNameToDirectory.set(workspacePackage.name, workspacePackage.directory);
6614
- const webpackResolverConfigs = (options.monorepoRoot && options.monorepoRoot !== config.rootDir ? [config.rootDir, options.monorepoRoot] : [config.rootDir]).flatMap(loadWebpackResolverConfigs).sort((leftConfig, rightConfig) => rightConfig.scopeDirectory.length - leftConfig.scopeDirectory.length);
6742
+ const structuralAliasToDirectory = /* @__PURE__ */ new Map();
6743
+ const workspaceScopes = /* @__PURE__ */ new Set();
6744
+ for (const workspacePackage of workspacePackages) {
6745
+ if (!workspacePackage.name.startsWith("@")) continue;
6746
+ const slashIndex = workspacePackage.name.indexOf("/");
6747
+ if (slashIndex !== -1) workspaceScopes.add(workspacePackage.name.slice(0, slashIndex));
6748
+ }
6749
+ if (workspaceScopes.size > 0) {
6750
+ const ambiguousStructuralKeys = /* @__PURE__ */ new Set();
6751
+ const registerStructuralAlias = (aliasKey, directory) => {
6752
+ if (workspaceNameToDirectory.has(aliasKey)) return;
6753
+ const existing = structuralAliasToDirectory.get(aliasKey);
6754
+ if (existing !== void 0 && existing !== directory) {
6755
+ ambiguousStructuralKeys.add(aliasKey);
6756
+ return;
6757
+ }
6758
+ structuralAliasToDirectory.set(aliasKey, directory);
6759
+ };
6760
+ for (const workspacePackage of workspacePackages) {
6761
+ const directoryBasename = (0, node_path.basename)(workspacePackage.directory);
6762
+ const slashIndex = workspacePackage.name.indexOf("/");
6763
+ const unscopedName = workspacePackage.name.startsWith("@") && slashIndex !== -1 ? workspacePackage.name.slice(slashIndex + 1) : workspacePackage.name;
6764
+ for (const scope of workspaceScopes) {
6765
+ registerStructuralAlias(`${scope}/${directoryBasename}`, workspacePackage.directory);
6766
+ if (unscopedName && unscopedName !== directoryBasename) registerStructuralAlias(`${scope}/${unscopedName}`, workspacePackage.directory);
6767
+ }
6768
+ }
6769
+ for (const ambiguousKey of ambiguousStructuralKeys) structuralAliasToDirectory.delete(ambiguousKey);
6770
+ }
6771
+ const bundlerAliasConfigs = (options.monorepoRoot && options.monorepoRoot !== config.rootDir ? [config.rootDir, options.monorepoRoot] : [config.rootDir]).flatMap(loadBundlerAliasConfigs).sort((leftConfig, rightConfig) => rightConfig.scopeDirectory.length - leftConfig.scopeDirectory.length);
6615
6772
  let rootTsconfigPath;
6616
6773
  if (config.tsConfigPath) rootTsconfigPath = (0, node_path.resolve)(config.rootDir, config.tsConfigPath);
6617
6774
  else {
@@ -6629,6 +6786,7 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6629
6786
  }
6630
6787
  const tsconfigPathCache = /* @__PURE__ */ new Map();
6631
6788
  const tsconfigPathAliasCache = /* @__PURE__ */ new Map();
6789
+ const tsconfigCompiledAliasCache = /* @__PURE__ */ new Map();
6632
6790
  const findTsconfigForFile = (filePath) => {
6633
6791
  const fileDir = (0, node_path.dirname)(filePath);
6634
6792
  const cached = tsconfigPathCache.get(fileDir);
@@ -6775,64 +6933,127 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6775
6933
  tsconfigPathAliasCache.set(tsconfigFile, aliasMap);
6776
6934
  return aliasMap;
6777
6935
  };
6936
+ const getCompiledPathAliases = (tsconfigFile) => {
6937
+ const cached = tsconfigCompiledAliasCache.get(tsconfigFile);
6938
+ if (cached) return cached;
6939
+ const compiled = compilePathMappings(getPathAliases(tsconfigFile));
6940
+ tsconfigCompiledAliasCache.set(tsconfigFile, compiled);
6941
+ return compiled;
6942
+ };
6778
6943
  const tryResolveViaPathAlias = (specifier, fromFile) => {
6779
6944
  const tsconfigFile = findTsconfigForFile(fromFile);
6780
6945
  if (!tsconfigFile) return void 0;
6781
- const aliases = getPathAliases(tsconfigFile);
6782
- for (const [pattern, targetPatterns] of aliases) {
6783
- const wildcardIndex = pattern.indexOf("*");
6784
- if (wildcardIndex === -1) {
6785
- if (specifier === pattern) for (const targetPattern of targetPatterns) {
6786
- const candidate = targetPattern.replace("*", "");
6787
- if (existsAsFile(candidate)) return candidate;
6788
- for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(candidate + ext)) return candidate + ext;
6789
- const indexCandidate = (0, node_path.join)(candidate, "index");
6790
- for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(indexCandidate + ext)) return indexCandidate + ext;
6791
- }
6792
- continue;
6793
- }
6794
- const prefix = pattern.slice(0, wildcardIndex);
6795
- const suffix = pattern.slice(wildcardIndex + 1);
6796
- if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix)) continue;
6797
- const matchedWildcard = specifier.slice(prefix.length, specifier.length - suffix.length);
6798
- for (const targetPattern of targetPatterns) {
6799
- const resolvedTarget = targetPattern.replace("*", matchedWildcard);
6800
- if (existsAsFile(resolvedTarget)) return resolvedTarget;
6801
- for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(resolvedTarget + ext)) return resolvedTarget + ext;
6802
- const strippedTarget = resolvedTarget.replace(/\.[cm]?js$/, "");
6803
- if (strippedTarget !== resolvedTarget) {
6804
- for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(strippedTarget + ext)) return strippedTarget + ext;
6805
- }
6806
- const indexCandidate = (0, node_path.join)(resolvedTarget, "index");
6807
- for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(indexCandidate + ext)) return indexCandidate + ext;
6808
- }
6809
- }
6946
+ return matchCompiledMapping(specifier, getCompiledPathAliases(tsconfigFile));
6810
6947
  };
6811
6948
  const tryResolveFromDirectory = (directory, specifier) => {
6812
6949
  const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(directory, specifier));
6813
6950
  if (existsAsFile(candidatePath)) return candidatePath;
6814
6951
  };
6815
- const tryResolveViaWebpackConfig = (specifier, fromFile) => {
6816
- if (webpackResolverConfigs.length === 0) return void 0;
6952
+ const tryResolveViaBundlerAlias = (specifier, fromFile) => {
6953
+ if (bundlerAliasConfigs.length === 0) return void 0;
6817
6954
  if (!isBareSpecifier(specifier)) return void 0;
6818
- for (const webpackConfig of webpackResolverConfigs) {
6819
- if (!isInsideDirectory(fromFile, webpackConfig.scopeDirectory)) continue;
6820
- for (const alias of webpackConfig.aliases) {
6955
+ for (const bundlerConfig of bundlerAliasConfigs) {
6956
+ if (!isInsideDirectory(fromFile, bundlerConfig.scopeDirectory)) continue;
6957
+ for (const alias of bundlerConfig.aliases) {
6821
6958
  if (alias.isExact && specifier !== alias.name) continue;
6822
6959
  const suffix = specifier === alias.name ? "" : specifier.startsWith(`${alias.name}/`) ? specifier.slice(alias.name.length + 1) : void 0;
6823
6960
  if (suffix === void 0) continue;
6824
6961
  const aliasCandidate = tryResolveFromDirectory(alias.targetDirectory, suffix);
6825
6962
  if (aliasCandidate) return aliasCandidate;
6826
6963
  }
6827
- for (const moduleDirectory of webpackConfig.moduleDirectories) {
6964
+ for (const moduleDirectory of bundlerConfig.moduleDirectories) {
6828
6965
  const moduleCandidate = tryResolveFromDirectory(moduleDirectory, specifier);
6829
6966
  if (moduleCandidate) return moduleCandidate;
6830
6967
  }
6831
6968
  }
6832
6969
  };
6970
+ const compiledConfigPaths = config.paths ? compilePathMappings(Object.entries(config.paths).map(([pattern, targets]) => [pattern, targets.map((target) => (0, node_path.resolve)(config.rootDir, target))])) : [];
6971
+ const tryResolveViaConfigPaths = (specifier) => compiledConfigPaths.length === 0 ? void 0 : matchCompiledMapping(specifier, compiledConfigPaths);
6972
+ const resolveWorkspaceSubpath = (workspaceDirectory, subpath) => {
6973
+ const workspacePackageJsonPath = (0, node_path.join)(workspaceDirectory, "package.json");
6974
+ try {
6975
+ const workspacePackageContent = cachedReadFileSync(workspacePackageJsonPath);
6976
+ const workspacePackageJson = JSON.parse(workspacePackageContent);
6977
+ let resolvedEntryPath;
6978
+ if (subpath && workspacePackageJson.exports) {
6979
+ const exportKey = `./${subpath}`;
6980
+ const exportValue = workspacePackageJson.exports[exportKey];
6981
+ if (typeof exportValue === "string") {
6982
+ const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, exportValue));
6983
+ resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
6984
+ } else if (typeof exportValue === "object" && exportValue !== null) {
6985
+ const conditionValue = exportValue.import ?? exportValue.require ?? exportValue.default ?? exportValue.types;
6986
+ if (typeof conditionValue === "string") {
6987
+ const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, conditionValue));
6988
+ resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
6989
+ }
6990
+ }
6991
+ if (!resolvedEntryPath) for (const [wildcardPattern, wildcardTarget] of Object.entries(workspacePackageJson.exports)) {
6992
+ if (typeof wildcardPattern !== "string" || !wildcardPattern.includes("*")) continue;
6993
+ const wildcardTargetRecord = typeof wildcardTarget === "object" && wildcardTarget !== null ? wildcardTarget : void 0;
6994
+ const wildcardTargetValue = typeof wildcardTarget === "string" ? wildcardTarget : wildcardTargetRecord ? String(wildcardTargetRecord["import"] ?? wildcardTargetRecord["require"] ?? wildcardTargetRecord["default"] ?? wildcardTargetRecord["types"] ?? "") : void 0;
6995
+ if (typeof wildcardTargetValue !== "string") continue;
6996
+ const wildcardPrefix = wildcardPattern.slice(0, wildcardPattern.indexOf("*"));
6997
+ const wildcardSuffix = wildcardPattern.slice(wildcardPattern.indexOf("*") + 1);
6998
+ if (exportKey.startsWith(wildcardPrefix) && exportKey.endsWith(wildcardSuffix)) {
6999
+ const matchedSegment = exportKey.slice(wildcardPrefix.length, exportKey.length - wildcardSuffix.length || void 0);
7000
+ const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, wildcardTargetValue.replace("*", matchedSegment)));
7001
+ resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
7002
+ break;
7003
+ }
7004
+ }
7005
+ }
7006
+ if (subpath && !resolvedEntryPath) {
7007
+ const subpathCandidates = [(0, node_path.resolve)(workspaceDirectory, subpath), (0, node_path.resolve)(workspaceDirectory, "src", subpath)];
7008
+ for (const directSubpath of subpathCandidates) {
7009
+ for (const candidateExtension of RESOLVER_EXTENSIONS) {
7010
+ const candidate = directSubpath + candidateExtension;
7011
+ if (cachedExistsSync(candidate)) {
7012
+ resolvedEntryPath = candidate;
7013
+ break;
7014
+ }
7015
+ }
7016
+ if (resolvedEntryPath) break;
7017
+ for (const candidateExtension of RESOLVER_EXTENSIONS) {
7018
+ const indexCandidate = (0, node_path.join)(directSubpath, `index${candidateExtension}`);
7019
+ if (cachedExistsSync(indexCandidate)) {
7020
+ resolvedEntryPath = indexCandidate;
7021
+ break;
7022
+ }
7023
+ }
7024
+ if (resolvedEntryPath) break;
7025
+ }
7026
+ }
7027
+ if (!subpath) {
7028
+ const mainField = workspacePackageJson.main ?? workspacePackageJson.module;
7029
+ if (typeof mainField === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, mainField);
7030
+ if (!resolvedEntryPath && workspacePackageJson.exports?.["."]) {
7031
+ const dotExport = workspacePackageJson.exports["."];
7032
+ if (typeof dotExport === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, dotExport);
7033
+ else if (typeof dotExport === "object" && dotExport !== null) {
7034
+ const conditionValue = dotExport.import ?? dotExport.require ?? dotExport.default ?? dotExport.types;
7035
+ if (typeof conditionValue === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, conditionValue);
7036
+ }
7037
+ }
7038
+ }
7039
+ if (resolvedEntryPath) {
7040
+ const finalPath = resolveSourcePath(resolvedEntryPath, workspaceDirectory) ?? resolvedEntryPath;
7041
+ if (cachedExistsSync(finalPath)) return finalPath;
7042
+ const sourceFallbackPath = trySourceFallback(resolvedEntryPath);
7043
+ if (sourceFallbackPath) return sourceFallbackPath;
7044
+ }
7045
+ } catch {}
7046
+ };
7047
+ const tryResolveViaWorkspaceStructure = (specifier) => {
7048
+ if (structuralAliasToDirectory.size === 0) return void 0;
7049
+ if (!isBareSpecifier(specifier)) return void 0;
7050
+ const packageKey = extractPackageNameFromSpecifier(specifier);
7051
+ const directory = structuralAliasToDirectory.get(packageKey);
7052
+ if (!directory) return void 0;
7053
+ return resolveWorkspaceSubpath(directory, specifier.length > packageKey.length ? specifier.slice(packageKey.length + 1) : "");
7054
+ };
6833
7055
  const resolveModule = (specifier, fromFile) => {
6834
- const queryIndex = specifier.indexOf("?");
6835
- const cleanedSpecifier = queryIndex !== -1 ? specifier.slice(0, queryIndex) : specifier;
7056
+ const cleanedSpecifier = sanitizeImportSpecifier(specifier);
6836
7057
  const fromDir = (0, node_path.dirname)(fromFile);
6837
7058
  const cacheKey = `${fromDir}::${cleanedSpecifier}`;
6838
7059
  const cached = resolveResultCache.get(cacheKey);
@@ -6862,96 +7083,16 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6862
7083
  const packageName = extractPackageNameFromSpecifier(cleanedSpecifier);
6863
7084
  const workspaceDirectory = workspaceNameToDirectory.get(packageName);
6864
7085
  if (workspaceDirectory) {
6865
- const subpath = cleanedSpecifier.slice(packageName.length + 1);
6866
- const workspacePackageJsonPath = (0, node_path.join)(workspaceDirectory, "package.json");
6867
- try {
6868
- const workspacePackageContent = cachedReadFileSync(workspacePackageJsonPath);
6869
- const workspacePackageJson = JSON.parse(workspacePackageContent);
6870
- let resolvedEntryPath;
6871
- if (subpath && workspacePackageJson.exports) {
6872
- const exportKey = `./${subpath}`;
6873
- const exportValue = workspacePackageJson.exports[exportKey];
6874
- if (typeof exportValue === "string") {
6875
- const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, exportValue));
6876
- resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
6877
- } else if (typeof exportValue === "object" && exportValue !== null) {
6878
- const conditionValue = exportValue.import ?? exportValue.require ?? exportValue.default ?? exportValue.types;
6879
- if (typeof conditionValue === "string") {
6880
- const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, conditionValue));
6881
- resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
6882
- }
6883
- }
6884
- if (!resolvedEntryPath) for (const [wildcardPattern, wildcardTarget] of Object.entries(workspacePackageJson.exports)) {
6885
- if (typeof wildcardPattern !== "string" || !wildcardPattern.includes("*")) continue;
6886
- const wildcardTargetRecord = typeof wildcardTarget === "object" && wildcardTarget !== null ? wildcardTarget : void 0;
6887
- const wildcardTargetValue = typeof wildcardTarget === "string" ? wildcardTarget : wildcardTargetRecord ? String(wildcardTargetRecord["import"] ?? wildcardTargetRecord["require"] ?? wildcardTargetRecord["default"] ?? wildcardTargetRecord["types"] ?? "") : void 0;
6888
- if (typeof wildcardTargetValue !== "string") continue;
6889
- const wildcardPrefix = wildcardPattern.slice(0, wildcardPattern.indexOf("*"));
6890
- const wildcardSuffix = wildcardPattern.slice(wildcardPattern.indexOf("*") + 1);
6891
- if (exportKey.startsWith(wildcardPrefix) && exportKey.endsWith(wildcardSuffix)) {
6892
- const matchedSegment = exportKey.slice(wildcardPrefix.length, exportKey.length - wildcardSuffix.length || void 0);
6893
- const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, wildcardTargetValue.replace("*", matchedSegment)));
6894
- resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
6895
- break;
6896
- }
6897
- }
6898
- }
6899
- if (subpath && !resolvedEntryPath) {
6900
- const subpathCandidates = [(0, node_path.resolve)(workspaceDirectory, subpath), (0, node_path.resolve)(workspaceDirectory, "src", subpath)];
6901
- for (const directSubpath of subpathCandidates) {
6902
- for (const candidateExtension of RESOLVER_EXTENSIONS) {
6903
- const candidate = directSubpath + candidateExtension;
6904
- if (cachedExistsSync(candidate)) {
6905
- resolvedEntryPath = candidate;
6906
- break;
6907
- }
6908
- }
6909
- if (resolvedEntryPath) break;
6910
- for (const candidateExtension of RESOLVER_EXTENSIONS) {
6911
- const indexCandidate = (0, node_path.join)(directSubpath, `index${candidateExtension}`);
6912
- if (cachedExistsSync(indexCandidate)) {
6913
- resolvedEntryPath = indexCandidate;
6914
- break;
6915
- }
6916
- }
6917
- if (resolvedEntryPath) break;
6918
- }
6919
- }
6920
- if (!subpath) {
6921
- const mainField = workspacePackageJson.main ?? workspacePackageJson.module;
6922
- if (typeof mainField === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, mainField);
6923
- if (!resolvedEntryPath && workspacePackageJson.exports?.["."]) {
6924
- const dotExport = workspacePackageJson.exports["."];
6925
- if (typeof dotExport === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, dotExport);
6926
- else if (typeof dotExport === "object" && dotExport !== null) {
6927
- const conditionValue = dotExport.import ?? dotExport.require ?? dotExport.default ?? dotExport.types;
6928
- if (typeof conditionValue === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, conditionValue);
6929
- }
6930
- }
6931
- }
6932
- if (resolvedEntryPath) {
6933
- const finalPath = resolveSourcePath(resolvedEntryPath, workspaceDirectory) ?? resolvedEntryPath;
6934
- if (cachedExistsSync(finalPath)) {
6935
- const resolvedResult = {
6936
- resolvedPath: finalPath,
6937
- isExternal: false,
6938
- packageName: void 0
6939
- };
6940
- resolveResultCache.set(cacheKey, resolvedResult);
6941
- return resolvedResult;
6942
- }
6943
- const sourceFallbackPath = trySourceFallback(resolvedEntryPath);
6944
- if (sourceFallbackPath) {
6945
- const resolvedResult = {
6946
- resolvedPath: sourceFallbackPath,
6947
- isExternal: false,
6948
- packageName: void 0
6949
- };
6950
- resolveResultCache.set(cacheKey, resolvedResult);
6951
- return resolvedResult;
6952
- }
6953
- }
6954
- } catch {}
7086
+ const resolvedWorkspacePath = resolveWorkspaceSubpath(workspaceDirectory, cleanedSpecifier.slice(packageName.length + 1));
7087
+ if (resolvedWorkspacePath) {
7088
+ const resolvedResult = {
7089
+ resolvedPath: resolvedWorkspacePath,
7090
+ isExternal: false,
7091
+ packageName: void 0
7092
+ };
7093
+ resolveResultCache.set(cacheKey, resolvedResult);
7094
+ return resolvedResult;
7095
+ }
6955
7096
  }
6956
7097
  }
6957
7098
  const tsconfigForFile = findTsconfigForFile(fromFile);
@@ -6994,10 +7135,30 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6994
7135
  resolveResultCache.set(cacheKey, resolvedResult);
6995
7136
  return resolvedResult;
6996
7137
  }
6997
- const webpackResolved = tryResolveViaWebpackConfig(cleanedSpecifier, fromFile);
6998
- if (webpackResolved) {
7138
+ const configPathResolved = tryResolveViaConfigPaths(cleanedSpecifier);
7139
+ if (configPathResolved) {
7140
+ const resolvedResult = {
7141
+ resolvedPath: configPathResolved,
7142
+ isExternal: false,
7143
+ packageName: void 0
7144
+ };
7145
+ resolveResultCache.set(cacheKey, resolvedResult);
7146
+ return resolvedResult;
7147
+ }
7148
+ const bundlerAliasResolved = tryResolveViaBundlerAlias(cleanedSpecifier, fromFile);
7149
+ if (bundlerAliasResolved) {
7150
+ const resolvedResult = {
7151
+ resolvedPath: bundlerAliasResolved,
7152
+ isExternal: false,
7153
+ packageName: void 0
7154
+ };
7155
+ resolveResultCache.set(cacheKey, resolvedResult);
7156
+ return resolvedResult;
7157
+ }
7158
+ const structuralResolved = tryResolveViaWorkspaceStructure(cleanedSpecifier);
7159
+ if (structuralResolved) {
6999
7160
  const resolvedResult = {
7000
- resolvedPath: webpackResolved,
7161
+ resolvedPath: structuralResolved,
7001
7162
  isExternal: false,
7002
7163
  packageName: void 0
7003
7164
  };
@@ -7941,9 +8102,11 @@ const detectStalePackages = (graph, config) => {
7941
8102
  const unusedDependencies = [];
7942
8103
  for (const dependencyName of candidateUnused) {
7943
8104
  const isDevDependency = declaredDependencies.get(dependencyName) ?? false;
8105
+ const dependencySection = isDevDependency ? "devDependencies" : "dependencies";
7944
8106
  unusedDependencies.push({
7945
8107
  name: dependencyName,
7946
- isDevDependency
8108
+ isDevDependency,
8109
+ reason: `"${dependencyName}" is declared in ${dependencySection} but is never imported or referenced by any source file, script, or config — remove it from package.json if it is genuinely unused`
7947
8110
  });
7948
8111
  }
7949
8112
  return unusedDependencies;
@@ -12680,6 +12843,7 @@ const defineConfig = (options) => ({
12680
12843
  ignorePatterns: options.ignorePatterns ?? [],
12681
12844
  includeExtensions: options.includeExtensions ?? DEFAULT_EXTENSIONS,
12682
12845
  tsConfigPath: options.tsConfigPath,
12846
+ paths: options.paths,
12683
12847
  reportTypes: options.reportTypes ?? false,
12684
12848
  includeEntryExports: options.includeEntryExports ?? false,
12685
12849
  reportRedundancy: options.reportRedundancy ?? true,
package/dist/index.d.cts CHANGED
@@ -47,6 +47,7 @@ interface UnusedExport {
47
47
  interface UnusedDependency {
48
48
  name: string;
49
49
  isDevDependency: boolean;
50
+ reason: string;
50
51
  }
51
52
  interface CircularDependency {
52
53
  files: string[];
@@ -416,6 +417,7 @@ interface DeslopConfig {
416
417
  ignorePatterns: string[];
417
418
  includeExtensions: string[];
418
419
  tsConfigPath: string | undefined;
420
+ paths: Record<string, string[]> | undefined;
419
421
  reportTypes: boolean;
420
422
  includeEntryExports: boolean;
421
423
  reportRedundancy: boolean;