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 +359 -26
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +358 -25
- package/package.json +10 -1
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
|
|
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 (
|
|
1581
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
6814
|
+
const normalizedResolvedPath = toPosixPath(resolverResult.path);
|
|
6815
|
+
const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
|
|
6503
6816
|
return {
|
|
6504
|
-
resolvedPath: isInsideNodeModules ? void 0 :
|
|
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
|
-
|
|
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")
|
|
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)
|
|
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
|
-
*
|
|
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
|
|
10448
|
-
const isStorybookStoryFile = (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
|
|
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 (
|
|
1550
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
6783
|
+
const normalizedResolvedPath = toPosixPath(resolverResult.path);
|
|
6784
|
+
const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
|
|
6472
6785
|
return {
|
|
6473
|
-
resolvedPath: isInsideNodeModules ? void 0 :
|
|
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
|
-
|
|
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")
|
|
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)
|
|
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
|
-
*
|
|
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
|
|
10417
|
-
const isStorybookStoryFile = (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.
|
|
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",
|