deslop-js 0.0.14 → 0.0.15-dev.44dfc04

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
@@ -1575,10 +1575,24 @@ const extractMdxImportsExports = (sourceText) => {
1575
1575
  return statements.join("\n");
1576
1576
  };
1577
1577
  const ASTRO_FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---/;
1578
- const extractAstroFrontmatter = (sourceText) => {
1578
+ const ASTRO_SCRIPT_TAG_PATTERN = /<script\b([^>]*?)\/>|<script\b([^>]*)>([\s\S]*?)<\/script>/gi;
1579
+ const ASTRO_SCRIPT_SRC_ATTRIBUTE_PATTERN = /\bsrc\s*=\s*["']([^"']+)["']/i;
1580
+ const extractAstroSources = (sourceText) => {
1581
+ const sections = [];
1579
1582
  const frontmatterMatch = sourceText.match(ASTRO_FRONTMATTER_PATTERN);
1580
- if (!frontmatterMatch) return "";
1581
- return frontmatterMatch[1];
1583
+ if (frontmatterMatch) sections.push(frontmatterMatch[1]);
1584
+ ASTRO_SCRIPT_TAG_PATTERN.lastIndex = 0;
1585
+ let scriptMatch;
1586
+ while ((scriptMatch = ASTRO_SCRIPT_TAG_PATTERN.exec(sourceText)) !== null) {
1587
+ const selfClosingAttributes = scriptMatch[1];
1588
+ const pairedAttributes = scriptMatch[2];
1589
+ const attributes = selfClosingAttributes ?? pairedAttributes ?? "";
1590
+ const body = selfClosingAttributes === void 0 ? scriptMatch[3] ?? "" : "";
1591
+ const srcMatch = attributes.match(ASTRO_SCRIPT_SRC_ATTRIBUTE_PATTERN);
1592
+ if (srcMatch) sections.push(`import ${JSON.stringify(srcMatch[1])};`);
1593
+ if (body) sections.push(body);
1594
+ }
1595
+ return sections.join("\n");
1582
1596
  };
1583
1597
  const VUE_SCRIPT_PATTERN = /<script[^>]*(?:lang=["'](?:ts|tsx)["'][^>]*)?>([\s\S]*?)<\/script>/gi;
1584
1598
  const extractVueScriptContent = (sourceText) => {
@@ -1796,7 +1810,8 @@ const parseSourceFile = (filePath) => {
1796
1810
  const isAstro = filePath.endsWith(".astro");
1797
1811
  const isVue = filePath.endsWith(".vue");
1798
1812
  const isSvelte = filePath.endsWith(".svelte");
1799
- const textToParse = isMdx ? extractMdxImportsExports(sourceText) : isAstro ? extractAstroFrontmatter(sourceText) : isVue ? extractVueScriptContent(sourceText) : isSvelte ? extractSvelteScriptContent(sourceText) : sourceText;
1813
+ const isPreprocessed = isMdx || isAstro || isVue || isSvelte;
1814
+ const textToParse = isMdx ? extractMdxImportsExports(sourceText) : isAstro ? extractAstroSources(sourceText) : isVue ? extractVueScriptContent(sourceText) : isSvelte ? extractSvelteScriptContent(sourceText) : sourceText;
1800
1815
  const parseFileName = isMdx || isAstro || isVue || isSvelte ? filePath.replace(/\.(mdx|astro|vue|svelte)$/, ".tsx") : filePath;
1801
1816
  let result;
1802
1817
  try {
@@ -1820,7 +1835,7 @@ const parseSourceFile = (filePath) => {
1820
1835
  if (tsxResult.errors.length === 0) result = tsxResult;
1821
1836
  }
1822
1837
  } catch {}
1823
- if (result.errors.length > 0) return {
1838
+ if (result.errors.length > 0 && !isPreprocessed) return {
1824
1839
  ...createEmptyParsedSource(),
1825
1840
  imports,
1826
1841
  exports,
@@ -1832,6 +1847,12 @@ const parseSourceFile = (filePath) => {
1832
1847
  path: filePath
1833
1848
  })]
1834
1849
  };
1850
+ if (result.errors.length > 0) earlyErrors.push(new ParseError({
1851
+ code: "parse-recovered-partial",
1852
+ severity: "info",
1853
+ message: `oxc-parser reported ${result.errors.length} syntax issue(s) in extracted ${isAstro ? "Astro" : isVue ? "Vue" : isSvelte ? "Svelte" : "MDX"} sources; continuing with partial AST`,
1854
+ path: filePath
1855
+ }));
1835
1856
  const program = result.program;
1836
1857
  if (!program?.body) return {
1837
1858
  ...createEmptyParsedSource(),
@@ -3124,6 +3145,7 @@ const EXPO_ENTRY_PATTERNS = [
3124
3145
  ];
3125
3146
  const EXPO_ROUTER_ENTRY_PATTERNS = [
3126
3147
  "app/**/*.{ts,tsx,js,jsx}",
3148
+ "src/app/**/*.{ts,tsx,js,jsx}",
3127
3149
  "app.config.{ts,js,mjs,cjs}",
3128
3150
  "metro.config.{ts,js,mjs,cjs}",
3129
3151
  "babel.config.{ts,js,mjs,cjs}"
@@ -3663,12 +3685,16 @@ const extractSectionsModuleEntries = (directory) => {
3663
3685
  return [...entries];
3664
3686
  };
3665
3687
 
3688
+ //#endregion
3689
+ //#region src/utils/to-posix-path.ts
3690
+ const toPosixPath = (filePath) => filePath.replace(/\\/g, "/");
3691
+
3666
3692
  //#endregion
3667
3693
  //#region src/collect/entries.ts
3668
3694
  const collectSourceFiles = async (config) => {
3669
3695
  const extensions = config.includeExtensions.length > 0 ? config.includeExtensions : DEFAULT_EXTENSIONS;
3670
3696
  const extensionGlob = extensions.length === 1 ? `**/*${extensions[0]}` : `**/*{${extensions.join(",")}}`;
3671
- const ignorePatterns = [...DEFAULT_EXCLUSIONS, ...config.ignorePatterns];
3697
+ const ignorePatterns = [...DEFAULT_EXCLUSIONS, ...config.ignorePatterns].map(toPosixPath);
3672
3698
  const absoluteRoot = (0, node_path.resolve)(config.rootDir);
3673
3699
  const mainFiles = await (0, fast_glob.default)(extensionGlob, {
3674
3700
  cwd: absoluteRoot,
@@ -3685,7 +3711,7 @@ const collectSourceFiles = async (config) => {
3685
3711
  dot: true,
3686
3712
  onlyFiles: true
3687
3713
  }) : [];
3688
- return [...mainFiles, ...hiddenFiles].sort().map((filePath, fileIndex) => ({
3714
+ return [...new Set([...mainFiles, ...hiddenFiles].map(toPosixPath))].sort().map((filePath, fileIndex) => ({
3689
3715
  index: fileIndex,
3690
3716
  path: filePath
3691
3717
  }));
@@ -3794,7 +3820,7 @@ const resolveEntries = async (config) => {
3794
3820
  const testRunnerDiscovery = discoverTestRunnerEntryPoints(absoluteRoot, entryEligiblePackages);
3795
3821
  const toolingDiscovery = discoverToolingEntryPoints(absoluteRoot, entryEligiblePackages);
3796
3822
  const ciEntries = extractCiWorkflowEntries(absoluteRoot);
3797
- const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries])];
3823
+ const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries].map(toPosixPath))];
3798
3824
  const testEntryPathSet = new Set(testEntries);
3799
3825
  return {
3800
3826
  productionEntries: [...new Set([
@@ -3818,9 +3844,9 @@ const resolveEntries = async (config) => {
3818
3844
  ...pluginFileEntries,
3819
3845
  ...toolingDiscovery.entryFiles,
3820
3846
  ...ciEntries
3821
- ])].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3847
+ ].map(toPosixPath))].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3822
3848
  testEntries,
3823
- alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles])]
3849
+ alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles].map(toPosixPath))]
3824
3850
  };
3825
3851
  };
3826
3852
  const DEFAULT_INDEX_PATTERNS = [
@@ -5113,6 +5139,9 @@ const TEST_FRAMEWORK_PATTERNS = [
5113
5139
  alwaysUsed: ["cypress.config.{ts,js}", "cypress.config.*.{ts,js}"]
5114
5140
  }
5115
5141
  ];
5142
+ const JS_TS_COMPONENT_EXTENSIONS = "{ts,tsx,js,jsx}";
5143
+ const INERTIA_COMPONENT_EXTENSIONS = "{ts,tsx,js,jsx,vue,svelte}";
5144
+ const VIKE_ROUTE_EXTENSIONS = "{ts,tsx,js,jsx,md,mdx}";
5116
5145
  const FRAMEWORK_PATTERNS = [
5117
5146
  {
5118
5147
  enablers: ["storybook"],
@@ -5232,6 +5261,50 @@ const FRAMEWORK_PATTERNS = [
5232
5261
  ],
5233
5262
  alwaysUsed: ["angular.json", "**/karma.conf.js"]
5234
5263
  },
5264
+ {
5265
+ enablers: [
5266
+ "@inertiajs/react",
5267
+ "@inertiajs/inertia-react",
5268
+ "@inertiajs/vue3",
5269
+ "@inertiajs/inertia-vue3",
5270
+ "@inertiajs/svelte",
5271
+ "@inertiajs/inertia-svelte",
5272
+ "@inertiajs/inertia"
5273
+ ],
5274
+ enablerPrefixes: [],
5275
+ entryPatterns: [
5276
+ `resources/js/app.${INERTIA_COMPONENT_EXTENSIONS}`,
5277
+ `resources/js/App.${INERTIA_COMPONENT_EXTENSIONS}`,
5278
+ `resources/js/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5279
+ `resources/js/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5280
+ `app/frontend/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5281
+ `app/frontend/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5282
+ `app/frontend/entrypoints/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5283
+ `app/javascript/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5284
+ `app/javascript/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5285
+ `frontend/src/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5286
+ `frontend/src/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5287
+ `inertia/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5288
+ `inertia/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5289
+ `src/app.${INERTIA_COMPONENT_EXTENSIONS}`,
5290
+ `src/App.${INERTIA_COMPONENT_EXTENSIONS}`,
5291
+ `src/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5292
+ `src/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`
5293
+ ],
5294
+ alwaysUsed: []
5295
+ },
5296
+ {
5297
+ enablers: ["@redwoodjs/router", "@redwoodjs/web"],
5298
+ enablerPrefixes: [],
5299
+ entryPatterns: [
5300
+ `web/src/App.${JS_TS_COMPONENT_EXTENSIONS}`,
5301
+ `web/src/Routes.${JS_TS_COMPONENT_EXTENSIONS}`,
5302
+ `web/src/index.${JS_TS_COMPONENT_EXTENSIONS}`,
5303
+ `web/src/layouts/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
5304
+ `web/src/pages/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
5305
+ ],
5306
+ alwaysUsed: []
5307
+ },
5235
5308
  {
5236
5309
  enablers: ["react-scripts", "react-app-rewired"],
5237
5310
  enablerPrefixes: [],
@@ -5477,6 +5550,48 @@ const FRAMEWORK_PATTERNS = [
5477
5550
  ],
5478
5551
  alwaysUsed: ["tsr.config.json", "app.config.{ts,js}"]
5479
5552
  },
5553
+ {
5554
+ enablers: ["waku"],
5555
+ enablerPrefixes: [],
5556
+ entryPatterns: [
5557
+ `src/pages/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
5558
+ `src/waku.client.${JS_TS_COMPONENT_EXTENSIONS}`,
5559
+ `src/waku.server.${JS_TS_COMPONENT_EXTENSIONS}`
5560
+ ],
5561
+ alwaysUsed: []
5562
+ },
5563
+ {
5564
+ enablers: ["vike", "vite-plugin-ssr"],
5565
+ enablerPrefixes: [],
5566
+ entryPatterns: [
5567
+ `pages/**/*.${VIKE_ROUTE_EXTENSIONS}`,
5568
+ `renderer/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
5569
+ `src/pages/**/*.${VIKE_ROUTE_EXTENSIONS}`,
5570
+ `src/renderer/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
5571
+ ],
5572
+ alwaysUsed: []
5573
+ },
5574
+ {
5575
+ enablers: ["rakkasjs"],
5576
+ enablerPrefixes: [],
5577
+ entryPatterns: [
5578
+ `src/client.${JS_TS_COMPONENT_EXTENSIONS}`,
5579
+ `src/server.${JS_TS_COMPONENT_EXTENSIONS}`,
5580
+ `src/routes/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
5581
+ ],
5582
+ alwaysUsed: []
5583
+ },
5584
+ {
5585
+ enablers: [
5586
+ "@module-federation/enhanced",
5587
+ "@module-federation/node",
5588
+ "@module-federation/vite",
5589
+ "@originjs/vite-plugin-federation"
5590
+ ],
5591
+ enablerPrefixes: [],
5592
+ entryPatterns: ["federation.config.{ts,js,mjs,cjs,mts,cts}", "module-federation.config.{ts,js,mjs,cjs,mts,cts}"],
5593
+ alwaysUsed: []
5594
+ },
5480
5595
  {
5481
5596
  enablers: [
5482
5597
  "vite",
@@ -5907,7 +6022,8 @@ const FRAMEWORK_SCRIPT_BINARIES = {
5907
6022
  nuxt: ["nuxt"],
5908
6023
  astro: ["astro"],
5909
6024
  gatsby: ["gatsby"],
5910
- remix: ["remix"],
6025
+ "@remix-run/dev": ["remix"],
6026
+ "@react-router/dev": ["react-router"],
5911
6027
  "@sveltejs/kit": ["svelte-kit", "vite-svelte-kit"],
5912
6028
  "@docusaurus/core": ["docusaurus"],
5913
6029
  "@angular/core": ["ng"],
@@ -5976,7 +6092,7 @@ const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
5976
6092
  const scriptDetectedEnablers = detectFrameworkFromScripts(readPackageScripts(directory));
5977
6093
  const mergedDependencies = { ...workspaceDependencies };
5978
6094
  if (directory === rootDir) Object.assign(mergedDependencies, rootDependencies);
5979
- else for (const enabler of scriptDetectedEnablers) if (enabler in monorepoRootDeps || enabler in rootDependencies) mergedDependencies[enabler] = "*";
6095
+ for (const enabler of scriptDetectedEnablers) if (enabler in workspaceDependencies || enabler in rootDependencies || enabler in monorepoRootDeps) mergedDependencies[enabler] = "*";
5980
6096
  const activatedPatterns = [];
5981
6097
  const activatedAlwaysUsed = [];
5982
6098
  for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, mergedDependencies)) {
@@ -6695,9 +6811,10 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6695
6811
  try {
6696
6812
  const resolverResult = activeResolver.sync(fromDir, cleanedSpecifier);
6697
6813
  if (resolverResult.path) {
6698
- const isInsideNodeModules = resolverResult.path.includes("/node_modules/");
6814
+ const normalizedResolvedPath = toPosixPath(resolverResult.path);
6815
+ const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
6699
6816
  return {
6700
- resolvedPath: isInsideNodeModules ? void 0 : resolverResult.path,
6817
+ resolvedPath: isInsideNodeModules ? void 0 : normalizedResolvedPath,
6701
6818
  isExternal: isInsideNodeModules,
6702
6819
  packageName: isInsideNodeModules ? extractPackageNameFromSpecifier(cleanedSpecifier) : void 0
6703
6820
  };
@@ -6812,7 +6929,14 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6812
6929
  resolveResultCache.set(cacheKey, unresolvedResult);
6813
6930
  return unresolvedResult;
6814
6931
  };
6815
- return { resolveModule };
6932
+ const resolveModuleWithPosixPath = (specifier, fromFile) => {
6933
+ const resolved = resolveModule(specifier, fromFile);
6934
+ return resolved.resolvedPath ? {
6935
+ ...resolved,
6936
+ resolvedPath: toPosixPath(resolved.resolvedPath)
6937
+ } : resolved;
6938
+ };
6939
+ return { resolveModule: resolveModuleWithPosixPath };
6816
6940
  };
6817
6941
  const stripJsonComments = (content) => {
6818
6942
  let result = "";
@@ -6877,9 +7001,16 @@ const isConfigFile = (filePath) => {
6877
7001
  //#endregion
6878
7002
  //#region src/linker/build.ts
6879
7003
  const buildDependencyGraph = (inputs) => {
7004
+ const normalizedInputs = inputs.map((input) => ({
7005
+ ...input,
7006
+ fileId: {
7007
+ ...input.fileId,
7008
+ path: toPosixPath(input.fileId.path)
7009
+ }
7010
+ }));
6880
7011
  const fileIdMap = /* @__PURE__ */ new Map();
6881
- for (const input of inputs) fileIdMap.set(input.fileId.path, input.fileId.index);
6882
- const modules = inputs.map((input) => ({
7012
+ for (const input of normalizedInputs) fileIdMap.set(input.fileId.path, input.fileId.index);
7013
+ const modules = normalizedInputs.map((input) => ({
6883
7014
  fileId: input.fileId,
6884
7015
  imports: input.parsed.imports,
6885
7016
  exports: input.parsed.exports,
@@ -6917,14 +7048,14 @@ const buildDependencyGraph = (inputs) => {
6917
7048
  if (!existingReverseEdges.includes(sourceIndex)) existingReverseEdges.push(sourceIndex);
6918
7049
  } else reverseEdges.set(targetIndex, [sourceIndex]);
6919
7050
  };
6920
- for (const input of inputs) {
7051
+ for (const input of normalizedInputs) {
6921
7052
  const sourceIndex = input.fileId.index;
6922
7053
  for (const importInfo of input.parsed.imports) {
6923
7054
  if (importInfo.isGlob) {
6924
7055
  const sourceDir = node_path.default.dirname(input.fileId.path);
6925
7056
  const globPattern = importInfo.specifier;
6926
7057
  for (const [filePath] of fileIdMap) {
6927
- const relativePath = node_path.default.relative(sourceDir, filePath);
7058
+ const relativePath = toPosixPath(node_path.default.relative(sourceDir, filePath));
6928
7059
  if ((0, minimatch.minimatch)(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
6929
7060
  const targetIndex = fileIdMap.get(filePath);
6930
7061
  if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
@@ -6934,7 +7065,7 @@ const buildDependencyGraph = (inputs) => {
6934
7065
  }
6935
7066
  const resolved = input.resolvedImports.get(importInfo.specifier);
6936
7067
  if (!resolved?.resolvedPath) continue;
6937
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7068
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6938
7069
  if (targetIndex === void 0) continue;
6939
7070
  addEdge(sourceIndex, targetIndex, importInfo.importedNames.map((importedName) => ({
6940
7071
  importedName: importedName.name,
@@ -6949,7 +7080,7 @@ const buildDependencyGraph = (inputs) => {
6949
7080
  if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
6950
7081
  const resolved = input.resolvedImports.get(exportInfo.reExportSource);
6951
7082
  if (!resolved?.resolvedPath) continue;
6952
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7083
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6953
7084
  if (targetIndex === void 0) continue;
6954
7085
  const exportedName = exportInfo.isNamespaceReExport ? "*" : exportInfo.name;
6955
7086
  const originalName = exportInfo.isNamespaceReExport ? "*" : exportInfo.reExportOriginalName ?? exportInfo.name;
@@ -10078,12 +10209,19 @@ const visitFlagPatternsInExpression = (node, context) => {
10078
10209
  if (node.type === "CallExpression") {
10079
10210
  const callee = node.callee;
10080
10211
  let functionName;
10212
+ let calleeIsMemberExpression = false;
10213
+ let receiverIsItselfMemberExpression = false;
10081
10214
  if (isAstNode(callee)) {
10082
10215
  if (callee.type === "Identifier") functionName = getStaticName(callee);
10083
- else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") functionName = getStaticName(callee.property);
10216
+ else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") {
10217
+ calleeIsMemberExpression = true;
10218
+ functionName = getStaticName(callee.property);
10219
+ const receiver = callee.object;
10220
+ if (isAstNode(receiver) && (receiver.type === "MemberExpression" || receiver.type === "StaticMemberExpression")) receiverIsItselfMemberExpression = true;
10221
+ }
10084
10222
  }
10085
10223
  if (functionName !== void 0) {
10086
- if (context.vercelFlagsLocalNames.has(functionName) || VERCEL_FLAGS_FUNCTION_NAMES.has(functionName)) {
10224
+ if (!calleeIsMemberExpression && context.vercelFlagsLocalNames.has(functionName)) {
10087
10225
  const callArguments = node.arguments;
10088
10226
  const flagName = extractStringArgument(callArguments, 0);
10089
10227
  if (flagName !== void 0) {
@@ -10092,6 +10230,7 @@ const visitFlagPatternsInExpression = (node, context) => {
10092
10230
  }
10093
10231
  return;
10094
10232
  }
10233
+ if (calleeIsMemberExpression && receiverIsItselfMemberExpression) return;
10095
10234
  for (const sdkPattern of context.sdkPatterns) {
10096
10235
  if (sdkPattern.functionName !== functionName) continue;
10097
10236
  const callArguments = node.arguments;
@@ -10637,11 +10776,16 @@ const collectLocalTypeNames = (programNode) => {
10637
10776
  *
10638
10777
  * `Story` is intentionally a local alias — consumers don't import it; the
10639
10778
  * Storybook runtime reads the default export. Flagging this as a leak
10640
- * produces near-100% false positives on Storybook codebases, so skip
10641
- * `*.stories.{ts,tsx,js,jsx,mts,mjs,cts,cjs}` files entirely.
10779
+ * produces near-100% false positives on Storybook codebases, so skip story
10780
+ * files entirely. Storybook supports both common glob conventions — match
10781
+ * the `*.stories.{ext}` style as well as a bare `stories.{ext}` basename.
10642
10782
  */
10643
- const STORYBOOK_STORY_FILE_PATTERN = /\.stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/;
10644
- const isStorybookStoryFile = (filePath) => STORYBOOK_STORY_FILE_PATTERN.test(filePath);
10783
+ const STORYBOOK_STORY_BASENAME_PATTERN = /^(?:.*\.)?stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/i;
10784
+ const isStorybookStoryFile = (filePath) => {
10785
+ const lastSlash = filePath.lastIndexOf("/");
10786
+ const basename = lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);
10787
+ return STORYBOOK_STORY_BASENAME_PATTERN.test(basename);
10788
+ };
10645
10789
  /**
10646
10790
  * Detect TypeScript "private type leak": an exported declaration's signature
10647
10791
  * references a type that was declared locally in the same module but is not
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/errors.d.ts
2
- type DeslopErrorCode = "file-read-failed" | "file-too-large" | "file-empty" | "file-binary" | "file-minified" | "parse-failed" | "parse-recovered" | "ast-walk-failed" | "ast-walk-depth-exceeded" | "tsconfig-not-found" | "tsconfig-parse-failed" | "ts-program-creation-failed" | "ts-program-too-large" | "ts-not-loadable" | "package-json-not-found" | "package-json-parse-failed" | "workspace-discovery-failed" | "resolver-init-failed" | "monorepo-discovery-failed" | "detector-failed" | "config-invalid" | "system-out-of-memory" | "unknown";
2
+ type DeslopErrorCode = "file-read-failed" | "file-too-large" | "file-empty" | "file-binary" | "file-minified" | "parse-failed" | "parse-recovered" | "parse-recovered-partial" | "ast-walk-failed" | "ast-walk-depth-exceeded" | "tsconfig-not-found" | "tsconfig-parse-failed" | "ts-program-creation-failed" | "ts-program-too-large" | "ts-not-loadable" | "package-json-not-found" | "package-json-parse-failed" | "workspace-discovery-failed" | "resolver-init-failed" | "monorepo-discovery-failed" | "detector-failed" | "config-invalid" | "system-out-of-memory" | "unknown";
3
3
  type DeslopErrorModule = "collect" | "parse" | "linker" | "resolver" | "report" | "semantic" | "config";
4
4
  type DeslopErrorSeverity = "fatal" | "warning" | "info";
5
5
  interface DeslopErrorInput {
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/errors.d.ts
2
- type DeslopErrorCode = "file-read-failed" | "file-too-large" | "file-empty" | "file-binary" | "file-minified" | "parse-failed" | "parse-recovered" | "ast-walk-failed" | "ast-walk-depth-exceeded" | "tsconfig-not-found" | "tsconfig-parse-failed" | "ts-program-creation-failed" | "ts-program-too-large" | "ts-not-loadable" | "package-json-not-found" | "package-json-parse-failed" | "workspace-discovery-failed" | "resolver-init-failed" | "monorepo-discovery-failed" | "detector-failed" | "config-invalid" | "system-out-of-memory" | "unknown";
2
+ type DeslopErrorCode = "file-read-failed" | "file-too-large" | "file-empty" | "file-binary" | "file-minified" | "parse-failed" | "parse-recovered" | "parse-recovered-partial" | "ast-walk-failed" | "ast-walk-depth-exceeded" | "tsconfig-not-found" | "tsconfig-parse-failed" | "ts-program-creation-failed" | "ts-program-too-large" | "ts-not-loadable" | "package-json-not-found" | "package-json-parse-failed" | "workspace-discovery-failed" | "resolver-init-failed" | "monorepo-discovery-failed" | "detector-failed" | "config-invalid" | "system-out-of-memory" | "unknown";
3
3
  type DeslopErrorModule = "collect" | "parse" | "linker" | "resolver" | "report" | "semantic" | "config";
4
4
  type DeslopErrorSeverity = "fatal" | "warning" | "info";
5
5
  interface DeslopErrorInput {
package/dist/index.mjs CHANGED
@@ -1544,10 +1544,24 @@ const extractMdxImportsExports = (sourceText) => {
1544
1544
  return statements.join("\n");
1545
1545
  };
1546
1546
  const ASTRO_FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---/;
1547
- const extractAstroFrontmatter = (sourceText) => {
1547
+ const ASTRO_SCRIPT_TAG_PATTERN = /<script\b([^>]*?)\/>|<script\b([^>]*)>([\s\S]*?)<\/script>/gi;
1548
+ const ASTRO_SCRIPT_SRC_ATTRIBUTE_PATTERN = /\bsrc\s*=\s*["']([^"']+)["']/i;
1549
+ const extractAstroSources = (sourceText) => {
1550
+ const sections = [];
1548
1551
  const frontmatterMatch = sourceText.match(ASTRO_FRONTMATTER_PATTERN);
1549
- if (!frontmatterMatch) return "";
1550
- return frontmatterMatch[1];
1552
+ if (frontmatterMatch) sections.push(frontmatterMatch[1]);
1553
+ ASTRO_SCRIPT_TAG_PATTERN.lastIndex = 0;
1554
+ let scriptMatch;
1555
+ while ((scriptMatch = ASTRO_SCRIPT_TAG_PATTERN.exec(sourceText)) !== null) {
1556
+ const selfClosingAttributes = scriptMatch[1];
1557
+ const pairedAttributes = scriptMatch[2];
1558
+ const attributes = selfClosingAttributes ?? pairedAttributes ?? "";
1559
+ const body = selfClosingAttributes === void 0 ? scriptMatch[3] ?? "" : "";
1560
+ const srcMatch = attributes.match(ASTRO_SCRIPT_SRC_ATTRIBUTE_PATTERN);
1561
+ if (srcMatch) sections.push(`import ${JSON.stringify(srcMatch[1])};`);
1562
+ if (body) sections.push(body);
1563
+ }
1564
+ return sections.join("\n");
1551
1565
  };
1552
1566
  const VUE_SCRIPT_PATTERN = /<script[^>]*(?:lang=["'](?:ts|tsx)["'][^>]*)?>([\s\S]*?)<\/script>/gi;
1553
1567
  const extractVueScriptContent = (sourceText) => {
@@ -1765,7 +1779,8 @@ const parseSourceFile = (filePath) => {
1765
1779
  const isAstro = filePath.endsWith(".astro");
1766
1780
  const isVue = filePath.endsWith(".vue");
1767
1781
  const isSvelte = filePath.endsWith(".svelte");
1768
- const textToParse = isMdx ? extractMdxImportsExports(sourceText) : isAstro ? extractAstroFrontmatter(sourceText) : isVue ? extractVueScriptContent(sourceText) : isSvelte ? extractSvelteScriptContent(sourceText) : sourceText;
1782
+ const isPreprocessed = isMdx || isAstro || isVue || isSvelte;
1783
+ const textToParse = isMdx ? extractMdxImportsExports(sourceText) : isAstro ? extractAstroSources(sourceText) : isVue ? extractVueScriptContent(sourceText) : isSvelte ? extractSvelteScriptContent(sourceText) : sourceText;
1769
1784
  const parseFileName = isMdx || isAstro || isVue || isSvelte ? filePath.replace(/\.(mdx|astro|vue|svelte)$/, ".tsx") : filePath;
1770
1785
  let result;
1771
1786
  try {
@@ -1789,7 +1804,7 @@ const parseSourceFile = (filePath) => {
1789
1804
  if (tsxResult.errors.length === 0) result = tsxResult;
1790
1805
  }
1791
1806
  } catch {}
1792
- if (result.errors.length > 0) return {
1807
+ if (result.errors.length > 0 && !isPreprocessed) return {
1793
1808
  ...createEmptyParsedSource(),
1794
1809
  imports,
1795
1810
  exports,
@@ -1801,6 +1816,12 @@ const parseSourceFile = (filePath) => {
1801
1816
  path: filePath
1802
1817
  })]
1803
1818
  };
1819
+ if (result.errors.length > 0) earlyErrors.push(new ParseError({
1820
+ code: "parse-recovered-partial",
1821
+ severity: "info",
1822
+ message: `oxc-parser reported ${result.errors.length} syntax issue(s) in extracted ${isAstro ? "Astro" : isVue ? "Vue" : isSvelte ? "Svelte" : "MDX"} sources; continuing with partial AST`,
1823
+ path: filePath
1824
+ }));
1804
1825
  const program = result.program;
1805
1826
  if (!program?.body) return {
1806
1827
  ...createEmptyParsedSource(),
@@ -3093,6 +3114,7 @@ const EXPO_ENTRY_PATTERNS = [
3093
3114
  ];
3094
3115
  const EXPO_ROUTER_ENTRY_PATTERNS = [
3095
3116
  "app/**/*.{ts,tsx,js,jsx}",
3117
+ "src/app/**/*.{ts,tsx,js,jsx}",
3096
3118
  "app.config.{ts,js,mjs,cjs}",
3097
3119
  "metro.config.{ts,js,mjs,cjs}",
3098
3120
  "babel.config.{ts,js,mjs,cjs}"
@@ -3632,12 +3654,16 @@ const extractSectionsModuleEntries = (directory) => {
3632
3654
  return [...entries];
3633
3655
  };
3634
3656
 
3657
+ //#endregion
3658
+ //#region src/utils/to-posix-path.ts
3659
+ const toPosixPath = (filePath) => filePath.replace(/\\/g, "/");
3660
+
3635
3661
  //#endregion
3636
3662
  //#region src/collect/entries.ts
3637
3663
  const collectSourceFiles = async (config) => {
3638
3664
  const extensions = config.includeExtensions.length > 0 ? config.includeExtensions : DEFAULT_EXTENSIONS;
3639
3665
  const extensionGlob = extensions.length === 1 ? `**/*${extensions[0]}` : `**/*{${extensions.join(",")}}`;
3640
- const ignorePatterns = [...DEFAULT_EXCLUSIONS, ...config.ignorePatterns];
3666
+ const ignorePatterns = [...DEFAULT_EXCLUSIONS, ...config.ignorePatterns].map(toPosixPath);
3641
3667
  const absoluteRoot = resolve(config.rootDir);
3642
3668
  const mainFiles = await fg(extensionGlob, {
3643
3669
  cwd: absoluteRoot,
@@ -3654,7 +3680,7 @@ const collectSourceFiles = async (config) => {
3654
3680
  dot: true,
3655
3681
  onlyFiles: true
3656
3682
  }) : [];
3657
- return [...mainFiles, ...hiddenFiles].sort().map((filePath, fileIndex) => ({
3683
+ return [...new Set([...mainFiles, ...hiddenFiles].map(toPosixPath))].sort().map((filePath, fileIndex) => ({
3658
3684
  index: fileIndex,
3659
3685
  path: filePath
3660
3686
  }));
@@ -3763,7 +3789,7 @@ const resolveEntries = async (config) => {
3763
3789
  const testRunnerDiscovery = discoverTestRunnerEntryPoints(absoluteRoot, entryEligiblePackages);
3764
3790
  const toolingDiscovery = discoverToolingEntryPoints(absoluteRoot, entryEligiblePackages);
3765
3791
  const ciEntries = extractCiWorkflowEntries(absoluteRoot);
3766
- const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries])];
3792
+ const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries].map(toPosixPath))];
3767
3793
  const testEntryPathSet = new Set(testEntries);
3768
3794
  return {
3769
3795
  productionEntries: [...new Set([
@@ -3787,9 +3813,9 @@ const resolveEntries = async (config) => {
3787
3813
  ...pluginFileEntries,
3788
3814
  ...toolingDiscovery.entryFiles,
3789
3815
  ...ciEntries
3790
- ])].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3816
+ ].map(toPosixPath))].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3791
3817
  testEntries,
3792
- alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles])]
3818
+ alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles].map(toPosixPath))]
3793
3819
  };
3794
3820
  };
3795
3821
  const DEFAULT_INDEX_PATTERNS = [
@@ -5082,6 +5108,9 @@ const TEST_FRAMEWORK_PATTERNS = [
5082
5108
  alwaysUsed: ["cypress.config.{ts,js}", "cypress.config.*.{ts,js}"]
5083
5109
  }
5084
5110
  ];
5111
+ const JS_TS_COMPONENT_EXTENSIONS = "{ts,tsx,js,jsx}";
5112
+ const INERTIA_COMPONENT_EXTENSIONS = "{ts,tsx,js,jsx,vue,svelte}";
5113
+ const VIKE_ROUTE_EXTENSIONS = "{ts,tsx,js,jsx,md,mdx}";
5085
5114
  const FRAMEWORK_PATTERNS = [
5086
5115
  {
5087
5116
  enablers: ["storybook"],
@@ -5201,6 +5230,50 @@ const FRAMEWORK_PATTERNS = [
5201
5230
  ],
5202
5231
  alwaysUsed: ["angular.json", "**/karma.conf.js"]
5203
5232
  },
5233
+ {
5234
+ enablers: [
5235
+ "@inertiajs/react",
5236
+ "@inertiajs/inertia-react",
5237
+ "@inertiajs/vue3",
5238
+ "@inertiajs/inertia-vue3",
5239
+ "@inertiajs/svelte",
5240
+ "@inertiajs/inertia-svelte",
5241
+ "@inertiajs/inertia"
5242
+ ],
5243
+ enablerPrefixes: [],
5244
+ entryPatterns: [
5245
+ `resources/js/app.${INERTIA_COMPONENT_EXTENSIONS}`,
5246
+ `resources/js/App.${INERTIA_COMPONENT_EXTENSIONS}`,
5247
+ `resources/js/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5248
+ `resources/js/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5249
+ `app/frontend/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5250
+ `app/frontend/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5251
+ `app/frontend/entrypoints/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5252
+ `app/javascript/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5253
+ `app/javascript/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5254
+ `frontend/src/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5255
+ `frontend/src/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5256
+ `inertia/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5257
+ `inertia/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5258
+ `src/app.${INERTIA_COMPONENT_EXTENSIONS}`,
5259
+ `src/App.${INERTIA_COMPONENT_EXTENSIONS}`,
5260
+ `src/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
5261
+ `src/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`
5262
+ ],
5263
+ alwaysUsed: []
5264
+ },
5265
+ {
5266
+ enablers: ["@redwoodjs/router", "@redwoodjs/web"],
5267
+ enablerPrefixes: [],
5268
+ entryPatterns: [
5269
+ `web/src/App.${JS_TS_COMPONENT_EXTENSIONS}`,
5270
+ `web/src/Routes.${JS_TS_COMPONENT_EXTENSIONS}`,
5271
+ `web/src/index.${JS_TS_COMPONENT_EXTENSIONS}`,
5272
+ `web/src/layouts/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
5273
+ `web/src/pages/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
5274
+ ],
5275
+ alwaysUsed: []
5276
+ },
5204
5277
  {
5205
5278
  enablers: ["react-scripts", "react-app-rewired"],
5206
5279
  enablerPrefixes: [],
@@ -5446,6 +5519,48 @@ const FRAMEWORK_PATTERNS = [
5446
5519
  ],
5447
5520
  alwaysUsed: ["tsr.config.json", "app.config.{ts,js}"]
5448
5521
  },
5522
+ {
5523
+ enablers: ["waku"],
5524
+ enablerPrefixes: [],
5525
+ entryPatterns: [
5526
+ `src/pages/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
5527
+ `src/waku.client.${JS_TS_COMPONENT_EXTENSIONS}`,
5528
+ `src/waku.server.${JS_TS_COMPONENT_EXTENSIONS}`
5529
+ ],
5530
+ alwaysUsed: []
5531
+ },
5532
+ {
5533
+ enablers: ["vike", "vite-plugin-ssr"],
5534
+ enablerPrefixes: [],
5535
+ entryPatterns: [
5536
+ `pages/**/*.${VIKE_ROUTE_EXTENSIONS}`,
5537
+ `renderer/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
5538
+ `src/pages/**/*.${VIKE_ROUTE_EXTENSIONS}`,
5539
+ `src/renderer/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
5540
+ ],
5541
+ alwaysUsed: []
5542
+ },
5543
+ {
5544
+ enablers: ["rakkasjs"],
5545
+ enablerPrefixes: [],
5546
+ entryPatterns: [
5547
+ `src/client.${JS_TS_COMPONENT_EXTENSIONS}`,
5548
+ `src/server.${JS_TS_COMPONENT_EXTENSIONS}`,
5549
+ `src/routes/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
5550
+ ],
5551
+ alwaysUsed: []
5552
+ },
5553
+ {
5554
+ enablers: [
5555
+ "@module-federation/enhanced",
5556
+ "@module-federation/node",
5557
+ "@module-federation/vite",
5558
+ "@originjs/vite-plugin-federation"
5559
+ ],
5560
+ enablerPrefixes: [],
5561
+ entryPatterns: ["federation.config.{ts,js,mjs,cjs,mts,cts}", "module-federation.config.{ts,js,mjs,cjs,mts,cts}"],
5562
+ alwaysUsed: []
5563
+ },
5449
5564
  {
5450
5565
  enablers: [
5451
5566
  "vite",
@@ -5876,7 +5991,8 @@ const FRAMEWORK_SCRIPT_BINARIES = {
5876
5991
  nuxt: ["nuxt"],
5877
5992
  astro: ["astro"],
5878
5993
  gatsby: ["gatsby"],
5879
- remix: ["remix"],
5994
+ "@remix-run/dev": ["remix"],
5995
+ "@react-router/dev": ["react-router"],
5880
5996
  "@sveltejs/kit": ["svelte-kit", "vite-svelte-kit"],
5881
5997
  "@docusaurus/core": ["docusaurus"],
5882
5998
  "@angular/core": ["ng"],
@@ -5945,7 +6061,7 @@ const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
5945
6061
  const scriptDetectedEnablers = detectFrameworkFromScripts(readPackageScripts(directory));
5946
6062
  const mergedDependencies = { ...workspaceDependencies };
5947
6063
  if (directory === rootDir) Object.assign(mergedDependencies, rootDependencies);
5948
- else for (const enabler of scriptDetectedEnablers) if (enabler in monorepoRootDeps || enabler in rootDependencies) mergedDependencies[enabler] = "*";
6064
+ for (const enabler of scriptDetectedEnablers) if (enabler in workspaceDependencies || enabler in rootDependencies || enabler in monorepoRootDeps) mergedDependencies[enabler] = "*";
5949
6065
  const activatedPatterns = [];
5950
6066
  const activatedAlwaysUsed = [];
5951
6067
  for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, mergedDependencies)) {
@@ -6664,9 +6780,10 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6664
6780
  try {
6665
6781
  const resolverResult = activeResolver.sync(fromDir, cleanedSpecifier);
6666
6782
  if (resolverResult.path) {
6667
- const isInsideNodeModules = resolverResult.path.includes("/node_modules/");
6783
+ const normalizedResolvedPath = toPosixPath(resolverResult.path);
6784
+ const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
6668
6785
  return {
6669
- resolvedPath: isInsideNodeModules ? void 0 : resolverResult.path,
6786
+ resolvedPath: isInsideNodeModules ? void 0 : normalizedResolvedPath,
6670
6787
  isExternal: isInsideNodeModules,
6671
6788
  packageName: isInsideNodeModules ? extractPackageNameFromSpecifier(cleanedSpecifier) : void 0
6672
6789
  };
@@ -6781,7 +6898,14 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6781
6898
  resolveResultCache.set(cacheKey, unresolvedResult);
6782
6899
  return unresolvedResult;
6783
6900
  };
6784
- return { resolveModule };
6901
+ const resolveModuleWithPosixPath = (specifier, fromFile) => {
6902
+ const resolved = resolveModule(specifier, fromFile);
6903
+ return resolved.resolvedPath ? {
6904
+ ...resolved,
6905
+ resolvedPath: toPosixPath(resolved.resolvedPath)
6906
+ } : resolved;
6907
+ };
6908
+ return { resolveModule: resolveModuleWithPosixPath };
6785
6909
  };
6786
6910
  const stripJsonComments = (content) => {
6787
6911
  let result = "";
@@ -6846,9 +6970,16 @@ const isConfigFile = (filePath) => {
6846
6970
  //#endregion
6847
6971
  //#region src/linker/build.ts
6848
6972
  const buildDependencyGraph = (inputs) => {
6973
+ const normalizedInputs = inputs.map((input) => ({
6974
+ ...input,
6975
+ fileId: {
6976
+ ...input.fileId,
6977
+ path: toPosixPath(input.fileId.path)
6978
+ }
6979
+ }));
6849
6980
  const fileIdMap = /* @__PURE__ */ new Map();
6850
- for (const input of inputs) fileIdMap.set(input.fileId.path, input.fileId.index);
6851
- const modules = inputs.map((input) => ({
6981
+ for (const input of normalizedInputs) fileIdMap.set(input.fileId.path, input.fileId.index);
6982
+ const modules = normalizedInputs.map((input) => ({
6852
6983
  fileId: input.fileId,
6853
6984
  imports: input.parsed.imports,
6854
6985
  exports: input.parsed.exports,
@@ -6886,14 +7017,14 @@ const buildDependencyGraph = (inputs) => {
6886
7017
  if (!existingReverseEdges.includes(sourceIndex)) existingReverseEdges.push(sourceIndex);
6887
7018
  } else reverseEdges.set(targetIndex, [sourceIndex]);
6888
7019
  };
6889
- for (const input of inputs) {
7020
+ for (const input of normalizedInputs) {
6890
7021
  const sourceIndex = input.fileId.index;
6891
7022
  for (const importInfo of input.parsed.imports) {
6892
7023
  if (importInfo.isGlob) {
6893
7024
  const sourceDir = path.dirname(input.fileId.path);
6894
7025
  const globPattern = importInfo.specifier;
6895
7026
  for (const [filePath] of fileIdMap) {
6896
- const relativePath = path.relative(sourceDir, filePath);
7027
+ const relativePath = toPosixPath(path.relative(sourceDir, filePath));
6897
7028
  if (minimatch(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
6898
7029
  const targetIndex = fileIdMap.get(filePath);
6899
7030
  if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
@@ -6903,7 +7034,7 @@ const buildDependencyGraph = (inputs) => {
6903
7034
  }
6904
7035
  const resolved = input.resolvedImports.get(importInfo.specifier);
6905
7036
  if (!resolved?.resolvedPath) continue;
6906
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7037
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6907
7038
  if (targetIndex === void 0) continue;
6908
7039
  addEdge(sourceIndex, targetIndex, importInfo.importedNames.map((importedName) => ({
6909
7040
  importedName: importedName.name,
@@ -6918,7 +7049,7 @@ const buildDependencyGraph = (inputs) => {
6918
7049
  if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
6919
7050
  const resolved = input.resolvedImports.get(exportInfo.reExportSource);
6920
7051
  if (!resolved?.resolvedPath) continue;
6921
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7052
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6922
7053
  if (targetIndex === void 0) continue;
6923
7054
  const exportedName = exportInfo.isNamespaceReExport ? "*" : exportInfo.name;
6924
7055
  const originalName = exportInfo.isNamespaceReExport ? "*" : exportInfo.reExportOriginalName ?? exportInfo.name;
@@ -10047,12 +10178,19 @@ const visitFlagPatternsInExpression = (node, context) => {
10047
10178
  if (node.type === "CallExpression") {
10048
10179
  const callee = node.callee;
10049
10180
  let functionName;
10181
+ let calleeIsMemberExpression = false;
10182
+ let receiverIsItselfMemberExpression = false;
10050
10183
  if (isAstNode(callee)) {
10051
10184
  if (callee.type === "Identifier") functionName = getStaticName(callee);
10052
- else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") functionName = getStaticName(callee.property);
10185
+ else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") {
10186
+ calleeIsMemberExpression = true;
10187
+ functionName = getStaticName(callee.property);
10188
+ const receiver = callee.object;
10189
+ if (isAstNode(receiver) && (receiver.type === "MemberExpression" || receiver.type === "StaticMemberExpression")) receiverIsItselfMemberExpression = true;
10190
+ }
10053
10191
  }
10054
10192
  if (functionName !== void 0) {
10055
- if (context.vercelFlagsLocalNames.has(functionName) || VERCEL_FLAGS_FUNCTION_NAMES.has(functionName)) {
10193
+ if (!calleeIsMemberExpression && context.vercelFlagsLocalNames.has(functionName)) {
10056
10194
  const callArguments = node.arguments;
10057
10195
  const flagName = extractStringArgument(callArguments, 0);
10058
10196
  if (flagName !== void 0) {
@@ -10061,6 +10199,7 @@ const visitFlagPatternsInExpression = (node, context) => {
10061
10199
  }
10062
10200
  return;
10063
10201
  }
10202
+ if (calleeIsMemberExpression && receiverIsItselfMemberExpression) return;
10064
10203
  for (const sdkPattern of context.sdkPatterns) {
10065
10204
  if (sdkPattern.functionName !== functionName) continue;
10066
10205
  const callArguments = node.arguments;
@@ -10606,11 +10745,16 @@ const collectLocalTypeNames = (programNode) => {
10606
10745
  *
10607
10746
  * `Story` is intentionally a local alias — consumers don't import it; the
10608
10747
  * Storybook runtime reads the default export. Flagging this as a leak
10609
- * produces near-100% false positives on Storybook codebases, so skip
10610
- * `*.stories.{ts,tsx,js,jsx,mts,mjs,cts,cjs}` files entirely.
10748
+ * produces near-100% false positives on Storybook codebases, so skip story
10749
+ * files entirely. Storybook supports both common glob conventions — match
10750
+ * the `*.stories.{ext}` style as well as a bare `stories.{ext}` basename.
10611
10751
  */
10612
- const STORYBOOK_STORY_FILE_PATTERN = /\.stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/;
10613
- const isStorybookStoryFile = (filePath) => STORYBOOK_STORY_FILE_PATTERN.test(filePath);
10752
+ const STORYBOOK_STORY_BASENAME_PATTERN = /^(?:.*\.)?stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/i;
10753
+ const isStorybookStoryFile = (filePath) => {
10754
+ const lastSlash = filePath.lastIndexOf("/");
10755
+ const basename = lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);
10756
+ return STORYBOOK_STORY_BASENAME_PATTERN.test(basename);
10757
+ };
10614
10758
  /**
10615
10759
  * Detect TypeScript "private type leak": an exported declaration's signature
10616
10760
  * references a type that was declared locally in the same module but is not
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deslop-js",
3
- "version": "0.0.14",
3
+ "version": "0.0.15-dev.44dfc04",
4
4
  "description": "Deslop JavaScript code",
5
5
  "keywords": [
6
6
  "dead-code",
@@ -12,11 +12,20 @@
12
12
  "typescript",
13
13
  "unused"
14
14
  ],
15
+ "homepage": "https://github.com/millionco/deslop-js#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/millionco/deslop-js/issues"
18
+ },
15
19
  "license": "MIT",
16
20
  "author": {
17
21
  "name": "Aiden Bai",
18
22
  "email": "aiden@million.dev"
19
23
  },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/millionco/deslop-js.git",
27
+ "directory": "packages/deslop-js"
28
+ },
20
29
  "files": [
21
30
  "dist",
22
31
  "package.json",