deslop-js 0.0.13 → 0.0.14-dev.a6825a1

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
@@ -33,10 +33,10 @@ let fast_glob = require("fast-glob");
33
33
  fast_glob = __toESM(fast_glob, 1);
34
34
  let node_fs_promises = require("node:fs/promises");
35
35
  let oxc_parser = require("oxc-parser");
36
- let oxc_resolver = require("oxc-resolver");
37
- let minimatch = require("minimatch");
38
36
  let typescript = require("typescript");
39
37
  typescript = __toESM(typescript, 1);
38
+ let oxc_resolver = require("oxc-resolver");
39
+ let minimatch = require("minimatch");
40
40
 
41
41
  //#region src/constants.ts
42
42
  const DEFAULT_EXTENSIONS = [
@@ -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}"
@@ -3166,6 +3188,196 @@ const discoverMobileEntryPoints = (directory) => {
3166
3188
  }
3167
3189
  };
3168
3190
 
3191
+ //#endregion
3192
+ //#region src/collect/expo-config-plugin-entries.ts
3193
+ const EXPO_CONFIG_FILE_GLOBS = ["app.config.{ts,mts,cts,js,mjs,cjs}", "app.json"];
3194
+ const NESTED_EXPO_CONFIG_FILE_GLOBS = [
3195
+ ...EXPO_CONFIG_FILE_GLOBS,
3196
+ "**/app.config.{ts,mts,cts,js,mjs,cjs}",
3197
+ "**/app.json"
3198
+ ];
3199
+ const EXPO_REACT_NATIVE_DEPENDENCIES = new Set(["expo", "react-native"]);
3200
+ const EXPO_PLUGIN_RESOLVABLE_EXTENSIONS = SOURCE_EXTENSIONS$3.map((sourceExtension) => `.${sourceExtension}`);
3201
+ const isRecord = (value) => typeof value === "object" && value !== null;
3202
+ const isExpoOrReactNativeWorkspace = (dependencies) => [...EXPO_REACT_NATIVE_DEPENDENCIES].some((dependencyName) => dependencyName in dependencies);
3203
+ const isLocalExpoPluginPath = (value) => (value.startsWith("./") || value.startsWith("../")) && !value.includes("*") && !value.includes("?");
3204
+ const isFile = (filePath) => {
3205
+ try {
3206
+ return (0, node_fs.statSync)(filePath).isFile();
3207
+ } catch {
3208
+ return false;
3209
+ }
3210
+ };
3211
+ const resolveExpoPluginPath = (configDirectory, pluginPath) => {
3212
+ const candidatePath = (0, node_path.resolve)(configDirectory, pluginPath);
3213
+ if (isFile(candidatePath)) return candidatePath;
3214
+ for (const extension of EXPO_PLUGIN_RESOLVABLE_EXTENSIONS) {
3215
+ const candidatePathWithExtension = `${candidatePath}${extension}`;
3216
+ if (isFile(candidatePathWithExtension)) return candidatePathWithExtension;
3217
+ }
3218
+ for (const extension of EXPO_PLUGIN_RESOLVABLE_EXTENSIONS) {
3219
+ const indexCandidatePath = (0, node_path.join)(candidatePath, `index${extension}`);
3220
+ if (isFile(indexCandidatePath)) return indexCandidatePath;
3221
+ }
3222
+ };
3223
+ const addExpoPluginEntry = (entries, rootDirectory, configDirectory, pluginPath) => {
3224
+ if (!isLocalExpoPluginPath(pluginPath)) return;
3225
+ const resolvedPath = resolveExpoPluginPath(configDirectory, pluginPath);
3226
+ if (!resolvedPath) return;
3227
+ const relativePath = (0, node_path.relative)(rootDirectory, resolvedPath);
3228
+ if (relativePath !== "" && (relativePath.startsWith("..") || (0, node_path.isAbsolute)(relativePath))) return;
3229
+ entries.add(resolvedPath);
3230
+ };
3231
+ const getPropertyName = (name) => {
3232
+ if (typescript.default.isIdentifier(name) || typescript.default.isStringLiteral(name) || typescript.default.isNumericLiteral(name)) return name.text;
3233
+ };
3234
+ const unwrapExpression = (expression) => {
3235
+ let currentExpression = expression;
3236
+ while (typescript.default.isParenthesizedExpression(currentExpression)) currentExpression = currentExpression.expression;
3237
+ return currentExpression;
3238
+ };
3239
+ const collectExpoPluginPathsFromArray = (array, entries, rootDirectory, configDirectory) => {
3240
+ for (const element of array.elements) {
3241
+ if (typescript.default.isStringLiteral(element) || typescript.default.isNoSubstitutionTemplateLiteral(element)) {
3242
+ addExpoPluginEntry(entries, rootDirectory, configDirectory, element.text);
3243
+ continue;
3244
+ }
3245
+ if (typescript.default.isArrayLiteralExpression(element)) {
3246
+ const [pluginName] = element.elements;
3247
+ if (pluginName && (typescript.default.isStringLiteral(pluginName) || typescript.default.isNoSubstitutionTemplateLiteral(pluginName))) addExpoPluginEntry(entries, rootDirectory, configDirectory, pluginName.text);
3248
+ }
3249
+ }
3250
+ };
3251
+ const collectExpoPluginPathsFromConfigObject = (objectLiteral, entries, rootDirectory, configDirectory) => {
3252
+ for (const property of objectLiteral.properties) if (typescript.default.isPropertyAssignment(property) && getPropertyName(property.name) === "plugins" && typescript.default.isArrayLiteralExpression(property.initializer)) collectExpoPluginPathsFromArray(property.initializer, entries, rootDirectory, configDirectory);
3253
+ };
3254
+ const collectReturnedExpoConfigPluginPaths = (body, entries, rootDirectory, configDirectory) => {
3255
+ if (!typescript.default.isBlock(body)) {
3256
+ const expression = unwrapExpression(body);
3257
+ if (typescript.default.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, rootDirectory, configDirectory);
3258
+ return;
3259
+ }
3260
+ const visit = (node) => {
3261
+ if (typescript.default.isFunctionDeclaration(node) || typescript.default.isFunctionExpression(node) || typescript.default.isArrowFunction(node)) return;
3262
+ if (typescript.default.isReturnStatement(node) && node.expression) {
3263
+ const expression = unwrapExpression(node.expression);
3264
+ if (typescript.default.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, rootDirectory, configDirectory);
3265
+ return;
3266
+ }
3267
+ typescript.default.forEachChild(node, visit);
3268
+ };
3269
+ visit(body);
3270
+ };
3271
+ const collectExpoPluginPathsFromConfigExpression = (expression, entries, rootDirectory, configDirectory, bindings, seenIdentifiers = /* @__PURE__ */ new Set()) => {
3272
+ const configExpression = unwrapExpression(expression);
3273
+ if (typescript.default.isObjectLiteralExpression(configExpression)) {
3274
+ collectExpoPluginPathsFromConfigObject(configExpression, entries, rootDirectory, configDirectory);
3275
+ return;
3276
+ }
3277
+ if (typescript.default.isIdentifier(configExpression)) {
3278
+ if (seenIdentifiers.has(configExpression.text)) return;
3279
+ seenIdentifiers.add(configExpression.text);
3280
+ const boundExpression = bindings.expressions.get(configExpression.text);
3281
+ if (boundExpression) {
3282
+ collectExpoPluginPathsFromConfigExpression(boundExpression, entries, rootDirectory, configDirectory, bindings, seenIdentifiers);
3283
+ return;
3284
+ }
3285
+ const boundFunction = bindings.functions.get(configExpression.text);
3286
+ if (boundFunction?.body) collectReturnedExpoConfigPluginPaths(boundFunction.body, entries, rootDirectory, configDirectory);
3287
+ return;
3288
+ }
3289
+ if (typescript.default.isArrowFunction(configExpression)) {
3290
+ collectReturnedExpoConfigPluginPaths(configExpression.body, entries, rootDirectory, configDirectory);
3291
+ return;
3292
+ }
3293
+ if (typescript.default.isFunctionExpression(configExpression) && configExpression.body) collectReturnedExpoConfigPluginPaths(configExpression.body, entries, rootDirectory, configDirectory);
3294
+ };
3295
+ const hasDefaultExportModifier = (node) => Boolean(typescript.default.canHaveModifiers(node) && typescript.default.getModifiers(node)?.some((modifier) => modifier.kind === typescript.default.SyntaxKind.DefaultKeyword));
3296
+ const isModuleExportsAssignmentTarget = (node) => typescript.default.isPropertyAccessExpression(node) && typescript.default.isIdentifier(node.expression) && node.expression.text === "module" && node.name.text === "exports";
3297
+ const collectStaticConfigBindings = (sourceFile) => {
3298
+ const expressions = /* @__PURE__ */ new Map();
3299
+ const functions = /* @__PURE__ */ new Map();
3300
+ for (const statement of sourceFile.statements) {
3301
+ if (typescript.default.isVariableStatement(statement)) {
3302
+ for (const declaration of statement.declarationList.declarations) if (typescript.default.isIdentifier(declaration.name) && declaration.initializer) expressions.set(declaration.name.text, declaration.initializer);
3303
+ continue;
3304
+ }
3305
+ if (typescript.default.isFunctionDeclaration(statement) && statement.name) functions.set(statement.name.text, statement);
3306
+ }
3307
+ return {
3308
+ expressions,
3309
+ functions
3310
+ };
3311
+ };
3312
+ const collectExpoPluginPathsFromAppConfig = (configPath, entries, rootDirectory) => {
3313
+ const extension = (0, node_path.extname)(configPath);
3314
+ const sourceFile = typescript.default.createSourceFile(configPath, (0, node_fs.readFileSync)(configPath, "utf8"), typescript.default.ScriptTarget.Latest, true, extension === ".ts" || extension === ".mts" || extension === ".cts" ? typescript.default.ScriptKind.TS : typescript.default.ScriptKind.JS);
3315
+ const configDirectory = (0, node_path.dirname)(configPath);
3316
+ const bindings = collectStaticConfigBindings(sourceFile);
3317
+ const visit = (node) => {
3318
+ if (typescript.default.isExportAssignment(node)) {
3319
+ collectExpoPluginPathsFromConfigExpression(node.expression, entries, rootDirectory, configDirectory, bindings);
3320
+ return;
3321
+ }
3322
+ if (typescript.default.isFunctionDeclaration(node) && hasDefaultExportModifier(node) && node.body) {
3323
+ collectReturnedExpoConfigPluginPaths(node.body, entries, rootDirectory, configDirectory);
3324
+ return;
3325
+ }
3326
+ if (typescript.default.isBinaryExpression(node) && node.operatorToken.kind === typescript.default.SyntaxKind.EqualsToken && isModuleExportsAssignmentTarget(node.left)) {
3327
+ collectExpoPluginPathsFromConfigExpression(node.right, entries, rootDirectory, configDirectory, bindings);
3328
+ return;
3329
+ }
3330
+ typescript.default.forEachChild(node, visit);
3331
+ };
3332
+ visit(sourceFile);
3333
+ };
3334
+ const collectPluginPathsFromJsonValue = (value) => {
3335
+ if (!Array.isArray(value)) return [];
3336
+ const pluginPaths = [];
3337
+ for (const plugin of value) {
3338
+ if (typeof plugin === "string") {
3339
+ pluginPaths.push(plugin);
3340
+ continue;
3341
+ }
3342
+ if (Array.isArray(plugin) && typeof plugin[0] === "string") pluginPaths.push(plugin[0]);
3343
+ }
3344
+ return pluginPaths;
3345
+ };
3346
+ const collectExpoPluginPathsFromAppJson = (configPath, entries, rootDirectory) => {
3347
+ const parsedJson = JSON.parse((0, node_fs.readFileSync)(configPath, "utf8"));
3348
+ const configDirectory = (0, node_path.dirname)(configPath);
3349
+ if (!isRecord(parsedJson)) return;
3350
+ const expoConfig = parsedJson.expo;
3351
+ const expoPluginPaths = isRecord(expoConfig) ? collectPluginPathsFromJsonValue(expoConfig.plugins) : [];
3352
+ for (const pluginPath of [...expoPluginPaths, ...collectPluginPathsFromJsonValue(parsedJson.plugins)]) addExpoPluginEntry(entries, rootDirectory, configDirectory, pluginPath);
3353
+ };
3354
+ const collectExpoPluginPathsFromConfig = (configPath, entries, rootDirectory) => {
3355
+ try {
3356
+ if ((0, node_path.basename)(configPath) === "app.json") {
3357
+ collectExpoPluginPathsFromAppJson(configPath, entries, rootDirectory);
3358
+ return;
3359
+ }
3360
+ collectExpoPluginPathsFromAppConfig(configPath, entries, rootDirectory);
3361
+ } catch {}
3362
+ };
3363
+ const extractExpoConfigPluginEntries = (directory, dependencies, rootDirectory = directory, includeNestedConfigs = true) => {
3364
+ if (!isExpoOrReactNativeWorkspace(dependencies)) return [];
3365
+ const entries = /* @__PURE__ */ new Set();
3366
+ const configPaths = fast_glob.default.sync(includeNestedConfigs ? NESTED_EXPO_CONFIG_FILE_GLOBS : EXPO_CONFIG_FILE_GLOBS, {
3367
+ cwd: directory,
3368
+ absolute: true,
3369
+ onlyFiles: true,
3370
+ ignore: [
3371
+ "**/node_modules/**",
3372
+ "**/dist/**",
3373
+ "**/build/**"
3374
+ ],
3375
+ deep: 6
3376
+ });
3377
+ for (const configPath of configPaths) collectExpoPluginPathsFromConfig(configPath, entries, rootDirectory);
3378
+ return [...entries];
3379
+ };
3380
+
3169
3381
  //#endregion
3170
3382
  //#region src/resolver/source-path.ts
3171
3383
  const SOURCE_EXTENSIONS$1 = [
@@ -3473,6 +3685,10 @@ const extractSectionsModuleEntries = (directory) => {
3473
3685
  return [...entries];
3474
3686
  };
3475
3687
 
3688
+ //#endregion
3689
+ //#region src/utils/to-posix-path.ts
3690
+ const toPosixPath = (filePath) => filePath.replace(/\\/g, "/");
3691
+
3476
3692
  //#endregion
3477
3693
  //#region src/collect/entries.ts
3478
3694
  const collectSourceFiles = async (config) => {
@@ -3589,6 +3805,11 @@ const resolveEntries = async (config) => {
3589
3805
  for (const workspacePackage of entryEligiblePackages) tsConfigIncludeEntries.push(...extractTsConfigIncludeFilesEntries(workspacePackage.directory));
3590
3806
  const configStringEntries = extractConfigStringReferencedEntries(absoluteRoot);
3591
3807
  for (const workspacePackage of entryEligiblePackages) configStringEntries.push(...extractConfigStringReferencedEntries(workspacePackage.directory));
3808
+ const expoConfigPluginEntries = extractExpoConfigPluginEntries(absoluteRoot, readPackageJsonDependencies((0, node_path.join)(absoluteRoot, "package.json")), absoluteRoot, false);
3809
+ for (const workspacePackage of entryEligiblePackages) {
3810
+ const workspacePackageDependencies = readPackageJsonDependencies((0, node_path.join)(workspacePackage.directory, "package.json"));
3811
+ expoConfigPluginEntries.push(...extractExpoConfigPluginEntries(workspacePackage.directory, workspacePackageDependencies, absoluteRoot));
3812
+ }
3592
3813
  const sectionsModuleEntries = extractSectionsModuleEntries(absoluteRoot);
3593
3814
  const wranglerEntries = extractWranglerEntries(absoluteRoot);
3594
3815
  for (const workspacePackage of entryEligiblePackages) wranglerEntries.push(...extractWranglerEntries(workspacePackage.directory));
@@ -3599,7 +3820,7 @@ const resolveEntries = async (config) => {
3599
3820
  const testRunnerDiscovery = discoverTestRunnerEntryPoints(absoluteRoot, entryEligiblePackages);
3600
3821
  const toolingDiscovery = discoverToolingEntryPoints(absoluteRoot, entryEligiblePackages);
3601
3822
  const ciEntries = extractCiWorkflowEntries(absoluteRoot);
3602
- const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries])];
3823
+ const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries].map(toPosixPath))];
3603
3824
  const testEntryPathSet = new Set(testEntries);
3604
3825
  return {
3605
3826
  productionEntries: [...new Set([
@@ -3617,14 +3838,15 @@ const resolveEntries = async (config) => {
3617
3838
  ...webWorkerEntries,
3618
3839
  ...tsConfigIncludeEntries,
3619
3840
  ...configStringEntries,
3841
+ ...expoConfigPluginEntries,
3620
3842
  ...sectionsModuleEntries,
3621
3843
  ...wranglerEntries,
3622
3844
  ...pluginFileEntries,
3623
3845
  ...toolingDiscovery.entryFiles,
3624
3846
  ...ciEntries
3625
- ])].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3847
+ ].map(toPosixPath))].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3626
3848
  testEntries,
3627
- alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles])]
3849
+ alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles].map(toPosixPath))]
3628
3850
  };
3629
3851
  };
3630
3852
  const DEFAULT_INDEX_PATTERNS = [
@@ -4917,6 +5139,9 @@ const TEST_FRAMEWORK_PATTERNS = [
4917
5139
  alwaysUsed: ["cypress.config.{ts,js}", "cypress.config.*.{ts,js}"]
4918
5140
  }
4919
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}";
4920
5145
  const FRAMEWORK_PATTERNS = [
4921
5146
  {
4922
5147
  enablers: ["storybook"],
@@ -5036,6 +5261,50 @@ const FRAMEWORK_PATTERNS = [
5036
5261
  ],
5037
5262
  alwaysUsed: ["angular.json", "**/karma.conf.js"]
5038
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
+ },
5039
5308
  {
5040
5309
  enablers: ["react-scripts", "react-app-rewired"],
5041
5310
  enablerPrefixes: [],
@@ -5281,6 +5550,48 @@ const FRAMEWORK_PATTERNS = [
5281
5550
  ],
5282
5551
  alwaysUsed: ["tsr.config.json", "app.config.{ts,js}"]
5283
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
+ },
5284
5595
  {
5285
5596
  enablers: [
5286
5597
  "vite",
@@ -5492,7 +5803,7 @@ const FRAMEWORK_PATTERNS = [
5492
5803
  "app/_layout.{ts,tsx,js,jsx}",
5493
5804
  "app/index.{ts,tsx,js,jsx}"
5494
5805
  ],
5495
- alwaysUsed: ["app.json", "app.config.{ts,js}"]
5806
+ alwaysUsed: ["app.json", "app.config.{ts,mts,cts,js,mjs,cjs}"]
5496
5807
  },
5497
5808
  {
5498
5809
  enablers: ["wrangler"],
@@ -5711,7 +6022,8 @@ const FRAMEWORK_SCRIPT_BINARIES = {
5711
6022
  nuxt: ["nuxt"],
5712
6023
  astro: ["astro"],
5713
6024
  gatsby: ["gatsby"],
5714
- remix: ["remix"],
6025
+ "@remix-run/dev": ["remix"],
6026
+ "@react-router/dev": ["react-router"],
5715
6027
  "@sveltejs/kit": ["svelte-kit", "vite-svelte-kit"],
5716
6028
  "@docusaurus/core": ["docusaurus"],
5717
6029
  "@angular/core": ["ng"],
@@ -5780,7 +6092,7 @@ const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
5780
6092
  const scriptDetectedEnablers = detectFrameworkFromScripts(readPackageScripts(directory));
5781
6093
  const mergedDependencies = { ...workspaceDependencies };
5782
6094
  if (directory === rootDir) Object.assign(mergedDependencies, rootDependencies);
5783
- 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] = "*";
5784
6096
  const activatedPatterns = [];
5785
6097
  const activatedAlwaysUsed = [];
5786
6098
  for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, mergedDependencies)) {
@@ -6499,9 +6811,10 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6499
6811
  try {
6500
6812
  const resolverResult = activeResolver.sync(fromDir, cleanedSpecifier);
6501
6813
  if (resolverResult.path) {
6502
- const isInsideNodeModules = resolverResult.path.includes("/node_modules/");
6814
+ const normalizedResolvedPath = toPosixPath(resolverResult.path);
6815
+ const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
6503
6816
  return {
6504
- resolvedPath: isInsideNodeModules ? void 0 : resolverResult.path,
6817
+ resolvedPath: isInsideNodeModules ? void 0 : normalizedResolvedPath,
6505
6818
  isExternal: isInsideNodeModules,
6506
6819
  packageName: isInsideNodeModules ? extractPackageNameFromSpecifier(cleanedSpecifier) : void 0
6507
6820
  };
@@ -6616,7 +6929,14 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6616
6929
  resolveResultCache.set(cacheKey, unresolvedResult);
6617
6930
  return unresolvedResult;
6618
6931
  };
6619
- 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 };
6620
6940
  };
6621
6941
  const stripJsonComments = (content) => {
6622
6942
  let result = "";
@@ -6682,7 +7002,7 @@ const isConfigFile = (filePath) => {
6682
7002
  //#region src/linker/build.ts
6683
7003
  const buildDependencyGraph = (inputs) => {
6684
7004
  const fileIdMap = /* @__PURE__ */ new Map();
6685
- for (const input of inputs) fileIdMap.set(input.fileId.path, input.fileId.index);
7005
+ for (const input of inputs) fileIdMap.set(toPosixPath(input.fileId.path), input.fileId.index);
6686
7006
  const modules = inputs.map((input) => ({
6687
7007
  fileId: input.fileId,
6688
7008
  imports: input.parsed.imports,
@@ -6728,7 +7048,7 @@ const buildDependencyGraph = (inputs) => {
6728
7048
  const sourceDir = node_path.default.dirname(input.fileId.path);
6729
7049
  const globPattern = importInfo.specifier;
6730
7050
  for (const [filePath] of fileIdMap) {
6731
- const relativePath = node_path.default.relative(sourceDir, filePath);
7051
+ const relativePath = toPosixPath(node_path.default.relative(sourceDir, filePath));
6732
7052
  if ((0, minimatch.minimatch)(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
6733
7053
  const targetIndex = fileIdMap.get(filePath);
6734
7054
  if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
@@ -6738,7 +7058,7 @@ const buildDependencyGraph = (inputs) => {
6738
7058
  }
6739
7059
  const resolved = input.resolvedImports.get(importInfo.specifier);
6740
7060
  if (!resolved?.resolvedPath) continue;
6741
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7061
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6742
7062
  if (targetIndex === void 0) continue;
6743
7063
  addEdge(sourceIndex, targetIndex, importInfo.importedNames.map((importedName) => ({
6744
7064
  importedName: importedName.name,
@@ -6753,7 +7073,7 @@ const buildDependencyGraph = (inputs) => {
6753
7073
  if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
6754
7074
  const resolved = input.resolvedImports.get(exportInfo.reExportSource);
6755
7075
  if (!resolved?.resolvedPath) continue;
6756
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7076
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6757
7077
  if (targetIndex === void 0) continue;
6758
7078
  const exportedName = exportInfo.isNamespaceReExport ? "*" : exportInfo.name;
6759
7079
  const originalName = exportInfo.isNamespaceReExport ? "*" : exportInfo.reExportOriginalName ?? exportInfo.name;
@@ -9882,12 +10202,19 @@ const visitFlagPatternsInExpression = (node, context) => {
9882
10202
  if (node.type === "CallExpression") {
9883
10203
  const callee = node.callee;
9884
10204
  let functionName;
10205
+ let calleeIsMemberExpression = false;
10206
+ let receiverIsItselfMemberExpression = false;
9885
10207
  if (isAstNode(callee)) {
9886
10208
  if (callee.type === "Identifier") functionName = getStaticName(callee);
9887
- else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") functionName = getStaticName(callee.property);
10209
+ else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") {
10210
+ calleeIsMemberExpression = true;
10211
+ functionName = getStaticName(callee.property);
10212
+ const receiver = callee.object;
10213
+ if (isAstNode(receiver) && (receiver.type === "MemberExpression" || receiver.type === "StaticMemberExpression")) receiverIsItselfMemberExpression = true;
10214
+ }
9888
10215
  }
9889
10216
  if (functionName !== void 0) {
9890
- if (context.vercelFlagsLocalNames.has(functionName) || VERCEL_FLAGS_FUNCTION_NAMES.has(functionName)) {
10217
+ if (!calleeIsMemberExpression && context.vercelFlagsLocalNames.has(functionName)) {
9891
10218
  const callArguments = node.arguments;
9892
10219
  const flagName = extractStringArgument(callArguments, 0);
9893
10220
  if (flagName !== void 0) {
@@ -9896,6 +10223,7 @@ const visitFlagPatternsInExpression = (node, context) => {
9896
10223
  }
9897
10224
  return;
9898
10225
  }
10226
+ if (calleeIsMemberExpression && receiverIsItselfMemberExpression) return;
9899
10227
  for (const sdkPattern of context.sdkPatterns) {
9900
10228
  if (sdkPattern.functionName !== functionName) continue;
9901
10229
  const callArguments = node.arguments;
@@ -10441,11 +10769,16 @@ const collectLocalTypeNames = (programNode) => {
10441
10769
  *
10442
10770
  * `Story` is intentionally a local alias — consumers don't import it; the
10443
10771
  * Storybook runtime reads the default export. Flagging this as a leak
10444
- * produces near-100% false positives on Storybook codebases, so skip
10445
- * `*.stories.{ts,tsx,js,jsx,mts,mjs,cts,cjs}` files entirely.
10772
+ * produces near-100% false positives on Storybook codebases, so skip story
10773
+ * files entirely. Storybook supports both common glob conventions — match
10774
+ * the `*.stories.{ext}` style as well as a bare `stories.{ext}` basename.
10446
10775
  */
10447
- const STORYBOOK_STORY_FILE_PATTERN = /\.stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/;
10448
- const isStorybookStoryFile = (filePath) => STORYBOOK_STORY_FILE_PATTERN.test(filePath);
10776
+ const STORYBOOK_STORY_BASENAME_PATTERN = /^(?:.*\.)?stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/i;
10777
+ const isStorybookStoryFile = (filePath) => {
10778
+ const lastSlash = filePath.lastIndexOf("/");
10779
+ const basename = lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);
10780
+ return STORYBOOK_STORY_BASENAME_PATTERN.test(basename);
10781
+ };
10449
10782
  /**
10450
10783
  * Detect TypeScript "private type leak": an exported declaration's signature
10451
10784
  * 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
@@ -3,9 +3,9 @@ import { existsSync, readFileSync, statSync } from "node:fs";
3
3
  import fg from "fast-glob";
4
4
  import { readFile } from "node:fs/promises";
5
5
  import { parseSync } from "oxc-parser";
6
+ import ts from "typescript";
6
7
  import { ResolverFactory } from "oxc-resolver";
7
8
  import { minimatch } from "minimatch";
8
- import ts from "typescript";
9
9
 
10
10
  //#region src/constants.ts
11
11
  const DEFAULT_EXTENSIONS = [
@@ -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}"
@@ -3135,6 +3157,196 @@ const discoverMobileEntryPoints = (directory) => {
3135
3157
  }
3136
3158
  };
3137
3159
 
3160
+ //#endregion
3161
+ //#region src/collect/expo-config-plugin-entries.ts
3162
+ const EXPO_CONFIG_FILE_GLOBS = ["app.config.{ts,mts,cts,js,mjs,cjs}", "app.json"];
3163
+ const NESTED_EXPO_CONFIG_FILE_GLOBS = [
3164
+ ...EXPO_CONFIG_FILE_GLOBS,
3165
+ "**/app.config.{ts,mts,cts,js,mjs,cjs}",
3166
+ "**/app.json"
3167
+ ];
3168
+ const EXPO_REACT_NATIVE_DEPENDENCIES = new Set(["expo", "react-native"]);
3169
+ const EXPO_PLUGIN_RESOLVABLE_EXTENSIONS = SOURCE_EXTENSIONS$3.map((sourceExtension) => `.${sourceExtension}`);
3170
+ const isRecord = (value) => typeof value === "object" && value !== null;
3171
+ const isExpoOrReactNativeWorkspace = (dependencies) => [...EXPO_REACT_NATIVE_DEPENDENCIES].some((dependencyName) => dependencyName in dependencies);
3172
+ const isLocalExpoPluginPath = (value) => (value.startsWith("./") || value.startsWith("../")) && !value.includes("*") && !value.includes("?");
3173
+ const isFile = (filePath) => {
3174
+ try {
3175
+ return statSync(filePath).isFile();
3176
+ } catch {
3177
+ return false;
3178
+ }
3179
+ };
3180
+ const resolveExpoPluginPath = (configDirectory, pluginPath) => {
3181
+ const candidatePath = resolve(configDirectory, pluginPath);
3182
+ if (isFile(candidatePath)) return candidatePath;
3183
+ for (const extension of EXPO_PLUGIN_RESOLVABLE_EXTENSIONS) {
3184
+ const candidatePathWithExtension = `${candidatePath}${extension}`;
3185
+ if (isFile(candidatePathWithExtension)) return candidatePathWithExtension;
3186
+ }
3187
+ for (const extension of EXPO_PLUGIN_RESOLVABLE_EXTENSIONS) {
3188
+ const indexCandidatePath = join(candidatePath, `index${extension}`);
3189
+ if (isFile(indexCandidatePath)) return indexCandidatePath;
3190
+ }
3191
+ };
3192
+ const addExpoPluginEntry = (entries, rootDirectory, configDirectory, pluginPath) => {
3193
+ if (!isLocalExpoPluginPath(pluginPath)) return;
3194
+ const resolvedPath = resolveExpoPluginPath(configDirectory, pluginPath);
3195
+ if (!resolvedPath) return;
3196
+ const relativePath = relative(rootDirectory, resolvedPath);
3197
+ if (relativePath !== "" && (relativePath.startsWith("..") || isAbsolute(relativePath))) return;
3198
+ entries.add(resolvedPath);
3199
+ };
3200
+ const getPropertyName = (name) => {
3201
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) return name.text;
3202
+ };
3203
+ const unwrapExpression = (expression) => {
3204
+ let currentExpression = expression;
3205
+ while (ts.isParenthesizedExpression(currentExpression)) currentExpression = currentExpression.expression;
3206
+ return currentExpression;
3207
+ };
3208
+ const collectExpoPluginPathsFromArray = (array, entries, rootDirectory, configDirectory) => {
3209
+ for (const element of array.elements) {
3210
+ if (ts.isStringLiteral(element) || ts.isNoSubstitutionTemplateLiteral(element)) {
3211
+ addExpoPluginEntry(entries, rootDirectory, configDirectory, element.text);
3212
+ continue;
3213
+ }
3214
+ if (ts.isArrayLiteralExpression(element)) {
3215
+ const [pluginName] = element.elements;
3216
+ if (pluginName && (ts.isStringLiteral(pluginName) || ts.isNoSubstitutionTemplateLiteral(pluginName))) addExpoPluginEntry(entries, rootDirectory, configDirectory, pluginName.text);
3217
+ }
3218
+ }
3219
+ };
3220
+ const collectExpoPluginPathsFromConfigObject = (objectLiteral, entries, rootDirectory, configDirectory) => {
3221
+ for (const property of objectLiteral.properties) if (ts.isPropertyAssignment(property) && getPropertyName(property.name) === "plugins" && ts.isArrayLiteralExpression(property.initializer)) collectExpoPluginPathsFromArray(property.initializer, entries, rootDirectory, configDirectory);
3222
+ };
3223
+ const collectReturnedExpoConfigPluginPaths = (body, entries, rootDirectory, configDirectory) => {
3224
+ if (!ts.isBlock(body)) {
3225
+ const expression = unwrapExpression(body);
3226
+ if (ts.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, rootDirectory, configDirectory);
3227
+ return;
3228
+ }
3229
+ const visit = (node) => {
3230
+ if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) return;
3231
+ if (ts.isReturnStatement(node) && node.expression) {
3232
+ const expression = unwrapExpression(node.expression);
3233
+ if (ts.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, rootDirectory, configDirectory);
3234
+ return;
3235
+ }
3236
+ ts.forEachChild(node, visit);
3237
+ };
3238
+ visit(body);
3239
+ };
3240
+ const collectExpoPluginPathsFromConfigExpression = (expression, entries, rootDirectory, configDirectory, bindings, seenIdentifiers = /* @__PURE__ */ new Set()) => {
3241
+ const configExpression = unwrapExpression(expression);
3242
+ if (ts.isObjectLiteralExpression(configExpression)) {
3243
+ collectExpoPluginPathsFromConfigObject(configExpression, entries, rootDirectory, configDirectory);
3244
+ return;
3245
+ }
3246
+ if (ts.isIdentifier(configExpression)) {
3247
+ if (seenIdentifiers.has(configExpression.text)) return;
3248
+ seenIdentifiers.add(configExpression.text);
3249
+ const boundExpression = bindings.expressions.get(configExpression.text);
3250
+ if (boundExpression) {
3251
+ collectExpoPluginPathsFromConfigExpression(boundExpression, entries, rootDirectory, configDirectory, bindings, seenIdentifiers);
3252
+ return;
3253
+ }
3254
+ const boundFunction = bindings.functions.get(configExpression.text);
3255
+ if (boundFunction?.body) collectReturnedExpoConfigPluginPaths(boundFunction.body, entries, rootDirectory, configDirectory);
3256
+ return;
3257
+ }
3258
+ if (ts.isArrowFunction(configExpression)) {
3259
+ collectReturnedExpoConfigPluginPaths(configExpression.body, entries, rootDirectory, configDirectory);
3260
+ return;
3261
+ }
3262
+ if (ts.isFunctionExpression(configExpression) && configExpression.body) collectReturnedExpoConfigPluginPaths(configExpression.body, entries, rootDirectory, configDirectory);
3263
+ };
3264
+ const hasDefaultExportModifier = (node) => Boolean(ts.canHaveModifiers(node) && ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword));
3265
+ const isModuleExportsAssignmentTarget = (node) => ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "module" && node.name.text === "exports";
3266
+ const collectStaticConfigBindings = (sourceFile) => {
3267
+ const expressions = /* @__PURE__ */ new Map();
3268
+ const functions = /* @__PURE__ */ new Map();
3269
+ for (const statement of sourceFile.statements) {
3270
+ if (ts.isVariableStatement(statement)) {
3271
+ for (const declaration of statement.declarationList.declarations) if (ts.isIdentifier(declaration.name) && declaration.initializer) expressions.set(declaration.name.text, declaration.initializer);
3272
+ continue;
3273
+ }
3274
+ if (ts.isFunctionDeclaration(statement) && statement.name) functions.set(statement.name.text, statement);
3275
+ }
3276
+ return {
3277
+ expressions,
3278
+ functions
3279
+ };
3280
+ };
3281
+ const collectExpoPluginPathsFromAppConfig = (configPath, entries, rootDirectory) => {
3282
+ const extension = extname(configPath);
3283
+ const sourceFile = ts.createSourceFile(configPath, readFileSync(configPath, "utf8"), ts.ScriptTarget.Latest, true, extension === ".ts" || extension === ".mts" || extension === ".cts" ? ts.ScriptKind.TS : ts.ScriptKind.JS);
3284
+ const configDirectory = dirname(configPath);
3285
+ const bindings = collectStaticConfigBindings(sourceFile);
3286
+ const visit = (node) => {
3287
+ if (ts.isExportAssignment(node)) {
3288
+ collectExpoPluginPathsFromConfigExpression(node.expression, entries, rootDirectory, configDirectory, bindings);
3289
+ return;
3290
+ }
3291
+ if (ts.isFunctionDeclaration(node) && hasDefaultExportModifier(node) && node.body) {
3292
+ collectReturnedExpoConfigPluginPaths(node.body, entries, rootDirectory, configDirectory);
3293
+ return;
3294
+ }
3295
+ if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExportsAssignmentTarget(node.left)) {
3296
+ collectExpoPluginPathsFromConfigExpression(node.right, entries, rootDirectory, configDirectory, bindings);
3297
+ return;
3298
+ }
3299
+ ts.forEachChild(node, visit);
3300
+ };
3301
+ visit(sourceFile);
3302
+ };
3303
+ const collectPluginPathsFromJsonValue = (value) => {
3304
+ if (!Array.isArray(value)) return [];
3305
+ const pluginPaths = [];
3306
+ for (const plugin of value) {
3307
+ if (typeof plugin === "string") {
3308
+ pluginPaths.push(plugin);
3309
+ continue;
3310
+ }
3311
+ if (Array.isArray(plugin) && typeof plugin[0] === "string") pluginPaths.push(plugin[0]);
3312
+ }
3313
+ return pluginPaths;
3314
+ };
3315
+ const collectExpoPluginPathsFromAppJson = (configPath, entries, rootDirectory) => {
3316
+ const parsedJson = JSON.parse(readFileSync(configPath, "utf8"));
3317
+ const configDirectory = dirname(configPath);
3318
+ if (!isRecord(parsedJson)) return;
3319
+ const expoConfig = parsedJson.expo;
3320
+ const expoPluginPaths = isRecord(expoConfig) ? collectPluginPathsFromJsonValue(expoConfig.plugins) : [];
3321
+ for (const pluginPath of [...expoPluginPaths, ...collectPluginPathsFromJsonValue(parsedJson.plugins)]) addExpoPluginEntry(entries, rootDirectory, configDirectory, pluginPath);
3322
+ };
3323
+ const collectExpoPluginPathsFromConfig = (configPath, entries, rootDirectory) => {
3324
+ try {
3325
+ if (basename(configPath) === "app.json") {
3326
+ collectExpoPluginPathsFromAppJson(configPath, entries, rootDirectory);
3327
+ return;
3328
+ }
3329
+ collectExpoPluginPathsFromAppConfig(configPath, entries, rootDirectory);
3330
+ } catch {}
3331
+ };
3332
+ const extractExpoConfigPluginEntries = (directory, dependencies, rootDirectory = directory, includeNestedConfigs = true) => {
3333
+ if (!isExpoOrReactNativeWorkspace(dependencies)) return [];
3334
+ const entries = /* @__PURE__ */ new Set();
3335
+ const configPaths = fg.sync(includeNestedConfigs ? NESTED_EXPO_CONFIG_FILE_GLOBS : EXPO_CONFIG_FILE_GLOBS, {
3336
+ cwd: directory,
3337
+ absolute: true,
3338
+ onlyFiles: true,
3339
+ ignore: [
3340
+ "**/node_modules/**",
3341
+ "**/dist/**",
3342
+ "**/build/**"
3343
+ ],
3344
+ deep: 6
3345
+ });
3346
+ for (const configPath of configPaths) collectExpoPluginPathsFromConfig(configPath, entries, rootDirectory);
3347
+ return [...entries];
3348
+ };
3349
+
3138
3350
  //#endregion
3139
3351
  //#region src/resolver/source-path.ts
3140
3352
  const SOURCE_EXTENSIONS$1 = [
@@ -3442,6 +3654,10 @@ const extractSectionsModuleEntries = (directory) => {
3442
3654
  return [...entries];
3443
3655
  };
3444
3656
 
3657
+ //#endregion
3658
+ //#region src/utils/to-posix-path.ts
3659
+ const toPosixPath = (filePath) => filePath.replace(/\\/g, "/");
3660
+
3445
3661
  //#endregion
3446
3662
  //#region src/collect/entries.ts
3447
3663
  const collectSourceFiles = async (config) => {
@@ -3558,6 +3774,11 @@ const resolveEntries = async (config) => {
3558
3774
  for (const workspacePackage of entryEligiblePackages) tsConfigIncludeEntries.push(...extractTsConfigIncludeFilesEntries(workspacePackage.directory));
3559
3775
  const configStringEntries = extractConfigStringReferencedEntries(absoluteRoot);
3560
3776
  for (const workspacePackage of entryEligiblePackages) configStringEntries.push(...extractConfigStringReferencedEntries(workspacePackage.directory));
3777
+ const expoConfigPluginEntries = extractExpoConfigPluginEntries(absoluteRoot, readPackageJsonDependencies(join(absoluteRoot, "package.json")), absoluteRoot, false);
3778
+ for (const workspacePackage of entryEligiblePackages) {
3779
+ const workspacePackageDependencies = readPackageJsonDependencies(join(workspacePackage.directory, "package.json"));
3780
+ expoConfigPluginEntries.push(...extractExpoConfigPluginEntries(workspacePackage.directory, workspacePackageDependencies, absoluteRoot));
3781
+ }
3561
3782
  const sectionsModuleEntries = extractSectionsModuleEntries(absoluteRoot);
3562
3783
  const wranglerEntries = extractWranglerEntries(absoluteRoot);
3563
3784
  for (const workspacePackage of entryEligiblePackages) wranglerEntries.push(...extractWranglerEntries(workspacePackage.directory));
@@ -3568,7 +3789,7 @@ const resolveEntries = async (config) => {
3568
3789
  const testRunnerDiscovery = discoverTestRunnerEntryPoints(absoluteRoot, entryEligiblePackages);
3569
3790
  const toolingDiscovery = discoverToolingEntryPoints(absoluteRoot, entryEligiblePackages);
3570
3791
  const ciEntries = extractCiWorkflowEntries(absoluteRoot);
3571
- const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries])];
3792
+ const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries].map(toPosixPath))];
3572
3793
  const testEntryPathSet = new Set(testEntries);
3573
3794
  return {
3574
3795
  productionEntries: [...new Set([
@@ -3586,14 +3807,15 @@ const resolveEntries = async (config) => {
3586
3807
  ...webWorkerEntries,
3587
3808
  ...tsConfigIncludeEntries,
3588
3809
  ...configStringEntries,
3810
+ ...expoConfigPluginEntries,
3589
3811
  ...sectionsModuleEntries,
3590
3812
  ...wranglerEntries,
3591
3813
  ...pluginFileEntries,
3592
3814
  ...toolingDiscovery.entryFiles,
3593
3815
  ...ciEntries
3594
- ])].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3816
+ ].map(toPosixPath))].filter((entryPath) => !testEntryPathSet.has(entryPath)),
3595
3817
  testEntries,
3596
- alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles])]
3818
+ alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles].map(toPosixPath))]
3597
3819
  };
3598
3820
  };
3599
3821
  const DEFAULT_INDEX_PATTERNS = [
@@ -4886,6 +5108,9 @@ const TEST_FRAMEWORK_PATTERNS = [
4886
5108
  alwaysUsed: ["cypress.config.{ts,js}", "cypress.config.*.{ts,js}"]
4887
5109
  }
4888
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}";
4889
5114
  const FRAMEWORK_PATTERNS = [
4890
5115
  {
4891
5116
  enablers: ["storybook"],
@@ -5005,6 +5230,50 @@ const FRAMEWORK_PATTERNS = [
5005
5230
  ],
5006
5231
  alwaysUsed: ["angular.json", "**/karma.conf.js"]
5007
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
+ },
5008
5277
  {
5009
5278
  enablers: ["react-scripts", "react-app-rewired"],
5010
5279
  enablerPrefixes: [],
@@ -5250,6 +5519,48 @@ const FRAMEWORK_PATTERNS = [
5250
5519
  ],
5251
5520
  alwaysUsed: ["tsr.config.json", "app.config.{ts,js}"]
5252
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
+ },
5253
5564
  {
5254
5565
  enablers: [
5255
5566
  "vite",
@@ -5461,7 +5772,7 @@ const FRAMEWORK_PATTERNS = [
5461
5772
  "app/_layout.{ts,tsx,js,jsx}",
5462
5773
  "app/index.{ts,tsx,js,jsx}"
5463
5774
  ],
5464
- alwaysUsed: ["app.json", "app.config.{ts,js}"]
5775
+ alwaysUsed: ["app.json", "app.config.{ts,mts,cts,js,mjs,cjs}"]
5465
5776
  },
5466
5777
  {
5467
5778
  enablers: ["wrangler"],
@@ -5680,7 +5991,8 @@ const FRAMEWORK_SCRIPT_BINARIES = {
5680
5991
  nuxt: ["nuxt"],
5681
5992
  astro: ["astro"],
5682
5993
  gatsby: ["gatsby"],
5683
- remix: ["remix"],
5994
+ "@remix-run/dev": ["remix"],
5995
+ "@react-router/dev": ["react-router"],
5684
5996
  "@sveltejs/kit": ["svelte-kit", "vite-svelte-kit"],
5685
5997
  "@docusaurus/core": ["docusaurus"],
5686
5998
  "@angular/core": ["ng"],
@@ -5749,7 +6061,7 @@ const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
5749
6061
  const scriptDetectedEnablers = detectFrameworkFromScripts(readPackageScripts(directory));
5750
6062
  const mergedDependencies = { ...workspaceDependencies };
5751
6063
  if (directory === rootDir) Object.assign(mergedDependencies, rootDependencies);
5752
- 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] = "*";
5753
6065
  const activatedPatterns = [];
5754
6066
  const activatedAlwaysUsed = [];
5755
6067
  for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, mergedDependencies)) {
@@ -6468,9 +6780,10 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6468
6780
  try {
6469
6781
  const resolverResult = activeResolver.sync(fromDir, cleanedSpecifier);
6470
6782
  if (resolverResult.path) {
6471
- const isInsideNodeModules = resolverResult.path.includes("/node_modules/");
6783
+ const normalizedResolvedPath = toPosixPath(resolverResult.path);
6784
+ const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
6472
6785
  return {
6473
- resolvedPath: isInsideNodeModules ? void 0 : resolverResult.path,
6786
+ resolvedPath: isInsideNodeModules ? void 0 : normalizedResolvedPath,
6474
6787
  isExternal: isInsideNodeModules,
6475
6788
  packageName: isInsideNodeModules ? extractPackageNameFromSpecifier(cleanedSpecifier) : void 0
6476
6789
  };
@@ -6585,7 +6898,14 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
6585
6898
  resolveResultCache.set(cacheKey, unresolvedResult);
6586
6899
  return unresolvedResult;
6587
6900
  };
6588
- 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 };
6589
6909
  };
6590
6910
  const stripJsonComments = (content) => {
6591
6911
  let result = "";
@@ -6651,7 +6971,7 @@ const isConfigFile = (filePath) => {
6651
6971
  //#region src/linker/build.ts
6652
6972
  const buildDependencyGraph = (inputs) => {
6653
6973
  const fileIdMap = /* @__PURE__ */ new Map();
6654
- for (const input of inputs) fileIdMap.set(input.fileId.path, input.fileId.index);
6974
+ for (const input of inputs) fileIdMap.set(toPosixPath(input.fileId.path), input.fileId.index);
6655
6975
  const modules = inputs.map((input) => ({
6656
6976
  fileId: input.fileId,
6657
6977
  imports: input.parsed.imports,
@@ -6697,7 +7017,7 @@ const buildDependencyGraph = (inputs) => {
6697
7017
  const sourceDir = path.dirname(input.fileId.path);
6698
7018
  const globPattern = importInfo.specifier;
6699
7019
  for (const [filePath] of fileIdMap) {
6700
- const relativePath = path.relative(sourceDir, filePath);
7020
+ const relativePath = toPosixPath(path.relative(sourceDir, filePath));
6701
7021
  if (minimatch(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
6702
7022
  const targetIndex = fileIdMap.get(filePath);
6703
7023
  if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
@@ -6707,7 +7027,7 @@ const buildDependencyGraph = (inputs) => {
6707
7027
  }
6708
7028
  const resolved = input.resolvedImports.get(importInfo.specifier);
6709
7029
  if (!resolved?.resolvedPath) continue;
6710
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7030
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6711
7031
  if (targetIndex === void 0) continue;
6712
7032
  addEdge(sourceIndex, targetIndex, importInfo.importedNames.map((importedName) => ({
6713
7033
  importedName: importedName.name,
@@ -6722,7 +7042,7 @@ const buildDependencyGraph = (inputs) => {
6722
7042
  if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
6723
7043
  const resolved = input.resolvedImports.get(exportInfo.reExportSource);
6724
7044
  if (!resolved?.resolvedPath) continue;
6725
- const targetIndex = fileIdMap.get(resolved.resolvedPath);
7045
+ const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
6726
7046
  if (targetIndex === void 0) continue;
6727
7047
  const exportedName = exportInfo.isNamespaceReExport ? "*" : exportInfo.name;
6728
7048
  const originalName = exportInfo.isNamespaceReExport ? "*" : exportInfo.reExportOriginalName ?? exportInfo.name;
@@ -9851,12 +10171,19 @@ const visitFlagPatternsInExpression = (node, context) => {
9851
10171
  if (node.type === "CallExpression") {
9852
10172
  const callee = node.callee;
9853
10173
  let functionName;
10174
+ let calleeIsMemberExpression = false;
10175
+ let receiverIsItselfMemberExpression = false;
9854
10176
  if (isAstNode(callee)) {
9855
10177
  if (callee.type === "Identifier") functionName = getStaticName(callee);
9856
- else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") functionName = getStaticName(callee.property);
10178
+ else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") {
10179
+ calleeIsMemberExpression = true;
10180
+ functionName = getStaticName(callee.property);
10181
+ const receiver = callee.object;
10182
+ if (isAstNode(receiver) && (receiver.type === "MemberExpression" || receiver.type === "StaticMemberExpression")) receiverIsItselfMemberExpression = true;
10183
+ }
9857
10184
  }
9858
10185
  if (functionName !== void 0) {
9859
- if (context.vercelFlagsLocalNames.has(functionName) || VERCEL_FLAGS_FUNCTION_NAMES.has(functionName)) {
10186
+ if (!calleeIsMemberExpression && context.vercelFlagsLocalNames.has(functionName)) {
9860
10187
  const callArguments = node.arguments;
9861
10188
  const flagName = extractStringArgument(callArguments, 0);
9862
10189
  if (flagName !== void 0) {
@@ -9865,6 +10192,7 @@ const visitFlagPatternsInExpression = (node, context) => {
9865
10192
  }
9866
10193
  return;
9867
10194
  }
10195
+ if (calleeIsMemberExpression && receiverIsItselfMemberExpression) return;
9868
10196
  for (const sdkPattern of context.sdkPatterns) {
9869
10197
  if (sdkPattern.functionName !== functionName) continue;
9870
10198
  const callArguments = node.arguments;
@@ -10410,11 +10738,16 @@ const collectLocalTypeNames = (programNode) => {
10410
10738
  *
10411
10739
  * `Story` is intentionally a local alias — consumers don't import it; the
10412
10740
  * Storybook runtime reads the default export. Flagging this as a leak
10413
- * produces near-100% false positives on Storybook codebases, so skip
10414
- * `*.stories.{ts,tsx,js,jsx,mts,mjs,cts,cjs}` files entirely.
10741
+ * produces near-100% false positives on Storybook codebases, so skip story
10742
+ * files entirely. Storybook supports both common glob conventions — match
10743
+ * the `*.stories.{ext}` style as well as a bare `stories.{ext}` basename.
10415
10744
  */
10416
- const STORYBOOK_STORY_FILE_PATTERN = /\.stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/;
10417
- const isStorybookStoryFile = (filePath) => STORYBOOK_STORY_FILE_PATTERN.test(filePath);
10745
+ const STORYBOOK_STORY_BASENAME_PATTERN = /^(?:.*\.)?stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/i;
10746
+ const isStorybookStoryFile = (filePath) => {
10747
+ const lastSlash = filePath.lastIndexOf("/");
10748
+ const basename = lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);
10749
+ return STORYBOOK_STORY_BASENAME_PATTERN.test(basename);
10750
+ };
10418
10751
  /**
10419
10752
  * Detect TypeScript "private type leak": an exported declaration's signature
10420
10753
  * 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.13",
3
+ "version": "0.0.14-dev.a6825a1",
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",