deslop-js 0.0.13 → 0.0.14-dev.bd94e5e
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 +267 -24
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +266 -23
- 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 = [
|
|
@@ -5492,7 +5714,7 @@ const FRAMEWORK_PATTERNS = [
|
|
|
5492
5714
|
"app/_layout.{ts,tsx,js,jsx}",
|
|
5493
5715
|
"app/index.{ts,tsx,js,jsx}"
|
|
5494
5716
|
],
|
|
5495
|
-
alwaysUsed: ["app.json", "app.config.{ts,js}"]
|
|
5717
|
+
alwaysUsed: ["app.json", "app.config.{ts,mts,cts,js,mjs,cjs}"]
|
|
5496
5718
|
},
|
|
5497
5719
|
{
|
|
5498
5720
|
enablers: ["wrangler"],
|
|
@@ -6499,9 +6721,10 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
|
|
|
6499
6721
|
try {
|
|
6500
6722
|
const resolverResult = activeResolver.sync(fromDir, cleanedSpecifier);
|
|
6501
6723
|
if (resolverResult.path) {
|
|
6502
|
-
const
|
|
6724
|
+
const normalizedResolvedPath = toPosixPath(resolverResult.path);
|
|
6725
|
+
const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
|
|
6503
6726
|
return {
|
|
6504
|
-
resolvedPath: isInsideNodeModules ? void 0 :
|
|
6727
|
+
resolvedPath: isInsideNodeModules ? void 0 : normalizedResolvedPath,
|
|
6505
6728
|
isExternal: isInsideNodeModules,
|
|
6506
6729
|
packageName: isInsideNodeModules ? extractPackageNameFromSpecifier(cleanedSpecifier) : void 0
|
|
6507
6730
|
};
|
|
@@ -6616,7 +6839,14 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
|
|
|
6616
6839
|
resolveResultCache.set(cacheKey, unresolvedResult);
|
|
6617
6840
|
return unresolvedResult;
|
|
6618
6841
|
};
|
|
6619
|
-
|
|
6842
|
+
const resolveModuleWithPosixPath = (specifier, fromFile) => {
|
|
6843
|
+
const resolved = resolveModule(specifier, fromFile);
|
|
6844
|
+
return resolved.resolvedPath ? {
|
|
6845
|
+
...resolved,
|
|
6846
|
+
resolvedPath: toPosixPath(resolved.resolvedPath)
|
|
6847
|
+
} : resolved;
|
|
6848
|
+
};
|
|
6849
|
+
return { resolveModule: resolveModuleWithPosixPath };
|
|
6620
6850
|
};
|
|
6621
6851
|
const stripJsonComments = (content) => {
|
|
6622
6852
|
let result = "";
|
|
@@ -6682,7 +6912,7 @@ const isConfigFile = (filePath) => {
|
|
|
6682
6912
|
//#region src/linker/build.ts
|
|
6683
6913
|
const buildDependencyGraph = (inputs) => {
|
|
6684
6914
|
const fileIdMap = /* @__PURE__ */ new Map();
|
|
6685
|
-
for (const input of inputs) fileIdMap.set(input.fileId.path, input.fileId.index);
|
|
6915
|
+
for (const input of inputs) fileIdMap.set(toPosixPath(input.fileId.path), input.fileId.index);
|
|
6686
6916
|
const modules = inputs.map((input) => ({
|
|
6687
6917
|
fileId: input.fileId,
|
|
6688
6918
|
imports: input.parsed.imports,
|
|
@@ -6728,7 +6958,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
6728
6958
|
const sourceDir = node_path.default.dirname(input.fileId.path);
|
|
6729
6959
|
const globPattern = importInfo.specifier;
|
|
6730
6960
|
for (const [filePath] of fileIdMap) {
|
|
6731
|
-
const relativePath = node_path.default.relative(sourceDir, filePath);
|
|
6961
|
+
const relativePath = toPosixPath(node_path.default.relative(sourceDir, filePath));
|
|
6732
6962
|
if ((0, minimatch.minimatch)(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
|
|
6733
6963
|
const targetIndex = fileIdMap.get(filePath);
|
|
6734
6964
|
if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
|
|
@@ -6738,7 +6968,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
6738
6968
|
}
|
|
6739
6969
|
const resolved = input.resolvedImports.get(importInfo.specifier);
|
|
6740
6970
|
if (!resolved?.resolvedPath) continue;
|
|
6741
|
-
const targetIndex = fileIdMap.get(resolved.resolvedPath);
|
|
6971
|
+
const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
|
|
6742
6972
|
if (targetIndex === void 0) continue;
|
|
6743
6973
|
addEdge(sourceIndex, targetIndex, importInfo.importedNames.map((importedName) => ({
|
|
6744
6974
|
importedName: importedName.name,
|
|
@@ -6753,7 +6983,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
6753
6983
|
if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
|
|
6754
6984
|
const resolved = input.resolvedImports.get(exportInfo.reExportSource);
|
|
6755
6985
|
if (!resolved?.resolvedPath) continue;
|
|
6756
|
-
const targetIndex = fileIdMap.get(resolved.resolvedPath);
|
|
6986
|
+
const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
|
|
6757
6987
|
if (targetIndex === void 0) continue;
|
|
6758
6988
|
const exportedName = exportInfo.isNamespaceReExport ? "*" : exportInfo.name;
|
|
6759
6989
|
const originalName = exportInfo.isNamespaceReExport ? "*" : exportInfo.reExportOriginalName ?? exportInfo.name;
|
|
@@ -9882,12 +10112,19 @@ const visitFlagPatternsInExpression = (node, context) => {
|
|
|
9882
10112
|
if (node.type === "CallExpression") {
|
|
9883
10113
|
const callee = node.callee;
|
|
9884
10114
|
let functionName;
|
|
10115
|
+
let calleeIsMemberExpression = false;
|
|
10116
|
+
let receiverIsItselfMemberExpression = false;
|
|
9885
10117
|
if (isAstNode(callee)) {
|
|
9886
10118
|
if (callee.type === "Identifier") functionName = getStaticName(callee);
|
|
9887
|
-
else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression")
|
|
10119
|
+
else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") {
|
|
10120
|
+
calleeIsMemberExpression = true;
|
|
10121
|
+
functionName = getStaticName(callee.property);
|
|
10122
|
+
const receiver = callee.object;
|
|
10123
|
+
if (isAstNode(receiver) && (receiver.type === "MemberExpression" || receiver.type === "StaticMemberExpression")) receiverIsItselfMemberExpression = true;
|
|
10124
|
+
}
|
|
9888
10125
|
}
|
|
9889
10126
|
if (functionName !== void 0) {
|
|
9890
|
-
if (context.vercelFlagsLocalNames.has(functionName)
|
|
10127
|
+
if (!calleeIsMemberExpression && context.vercelFlagsLocalNames.has(functionName)) {
|
|
9891
10128
|
const callArguments = node.arguments;
|
|
9892
10129
|
const flagName = extractStringArgument(callArguments, 0);
|
|
9893
10130
|
if (flagName !== void 0) {
|
|
@@ -9896,6 +10133,7 @@ const visitFlagPatternsInExpression = (node, context) => {
|
|
|
9896
10133
|
}
|
|
9897
10134
|
return;
|
|
9898
10135
|
}
|
|
10136
|
+
if (calleeIsMemberExpression && receiverIsItselfMemberExpression) return;
|
|
9899
10137
|
for (const sdkPattern of context.sdkPatterns) {
|
|
9900
10138
|
if (sdkPattern.functionName !== functionName) continue;
|
|
9901
10139
|
const callArguments = node.arguments;
|
|
@@ -10441,11 +10679,16 @@ const collectLocalTypeNames = (programNode) => {
|
|
|
10441
10679
|
*
|
|
10442
10680
|
* `Story` is intentionally a local alias — consumers don't import it; the
|
|
10443
10681
|
* Storybook runtime reads the default export. Flagging this as a leak
|
|
10444
|
-
* produces near-100% false positives on Storybook codebases, so skip
|
|
10445
|
-
*
|
|
10682
|
+
* produces near-100% false positives on Storybook codebases, so skip story
|
|
10683
|
+
* files entirely. Storybook supports both common glob conventions — match
|
|
10684
|
+
* the `*.stories.{ext}` style as well as a bare `stories.{ext}` basename.
|
|
10446
10685
|
*/
|
|
10447
|
-
const
|
|
10448
|
-
const isStorybookStoryFile = (filePath) =>
|
|
10686
|
+
const STORYBOOK_STORY_BASENAME_PATTERN = /^(?:.*\.)?stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/i;
|
|
10687
|
+
const isStorybookStoryFile = (filePath) => {
|
|
10688
|
+
const lastSlash = filePath.lastIndexOf("/");
|
|
10689
|
+
const basename = lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);
|
|
10690
|
+
return STORYBOOK_STORY_BASENAME_PATTERN.test(basename);
|
|
10691
|
+
};
|
|
10449
10692
|
/**
|
|
10450
10693
|
* Detect TypeScript "private type leak": an exported declaration's signature
|
|
10451
10694
|
* 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 = [
|
|
@@ -5461,7 +5683,7 @@ const FRAMEWORK_PATTERNS = [
|
|
|
5461
5683
|
"app/_layout.{ts,tsx,js,jsx}",
|
|
5462
5684
|
"app/index.{ts,tsx,js,jsx}"
|
|
5463
5685
|
],
|
|
5464
|
-
alwaysUsed: ["app.json", "app.config.{ts,js}"]
|
|
5686
|
+
alwaysUsed: ["app.json", "app.config.{ts,mts,cts,js,mjs,cjs}"]
|
|
5465
5687
|
},
|
|
5466
5688
|
{
|
|
5467
5689
|
enablers: ["wrangler"],
|
|
@@ -6468,9 +6690,10 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
|
|
|
6468
6690
|
try {
|
|
6469
6691
|
const resolverResult = activeResolver.sync(fromDir, cleanedSpecifier);
|
|
6470
6692
|
if (resolverResult.path) {
|
|
6471
|
-
const
|
|
6693
|
+
const normalizedResolvedPath = toPosixPath(resolverResult.path);
|
|
6694
|
+
const isInsideNodeModules = normalizedResolvedPath.includes("/node_modules/");
|
|
6472
6695
|
return {
|
|
6473
|
-
resolvedPath: isInsideNodeModules ? void 0 :
|
|
6696
|
+
resolvedPath: isInsideNodeModules ? void 0 : normalizedResolvedPath,
|
|
6474
6697
|
isExternal: isInsideNodeModules,
|
|
6475
6698
|
packageName: isInsideNodeModules ? extractPackageNameFromSpecifier(cleanedSpecifier) : void 0
|
|
6476
6699
|
};
|
|
@@ -6585,7 +6808,14 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
|
|
|
6585
6808
|
resolveResultCache.set(cacheKey, unresolvedResult);
|
|
6586
6809
|
return unresolvedResult;
|
|
6587
6810
|
};
|
|
6588
|
-
|
|
6811
|
+
const resolveModuleWithPosixPath = (specifier, fromFile) => {
|
|
6812
|
+
const resolved = resolveModule(specifier, fromFile);
|
|
6813
|
+
return resolved.resolvedPath ? {
|
|
6814
|
+
...resolved,
|
|
6815
|
+
resolvedPath: toPosixPath(resolved.resolvedPath)
|
|
6816
|
+
} : resolved;
|
|
6817
|
+
};
|
|
6818
|
+
return { resolveModule: resolveModuleWithPosixPath };
|
|
6589
6819
|
};
|
|
6590
6820
|
const stripJsonComments = (content) => {
|
|
6591
6821
|
let result = "";
|
|
@@ -6651,7 +6881,7 @@ const isConfigFile = (filePath) => {
|
|
|
6651
6881
|
//#region src/linker/build.ts
|
|
6652
6882
|
const buildDependencyGraph = (inputs) => {
|
|
6653
6883
|
const fileIdMap = /* @__PURE__ */ new Map();
|
|
6654
|
-
for (const input of inputs) fileIdMap.set(input.fileId.path, input.fileId.index);
|
|
6884
|
+
for (const input of inputs) fileIdMap.set(toPosixPath(input.fileId.path), input.fileId.index);
|
|
6655
6885
|
const modules = inputs.map((input) => ({
|
|
6656
6886
|
fileId: input.fileId,
|
|
6657
6887
|
imports: input.parsed.imports,
|
|
@@ -6697,7 +6927,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
6697
6927
|
const sourceDir = path.dirname(input.fileId.path);
|
|
6698
6928
|
const globPattern = importInfo.specifier;
|
|
6699
6929
|
for (const [filePath] of fileIdMap) {
|
|
6700
|
-
const relativePath = path.relative(sourceDir, filePath);
|
|
6930
|
+
const relativePath = toPosixPath(path.relative(sourceDir, filePath));
|
|
6701
6931
|
if (minimatch(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
|
|
6702
6932
|
const targetIndex = fileIdMap.get(filePath);
|
|
6703
6933
|
if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
|
|
@@ -6707,7 +6937,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
6707
6937
|
}
|
|
6708
6938
|
const resolved = input.resolvedImports.get(importInfo.specifier);
|
|
6709
6939
|
if (!resolved?.resolvedPath) continue;
|
|
6710
|
-
const targetIndex = fileIdMap.get(resolved.resolvedPath);
|
|
6940
|
+
const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
|
|
6711
6941
|
if (targetIndex === void 0) continue;
|
|
6712
6942
|
addEdge(sourceIndex, targetIndex, importInfo.importedNames.map((importedName) => ({
|
|
6713
6943
|
importedName: importedName.name,
|
|
@@ -6722,7 +6952,7 @@ const buildDependencyGraph = (inputs) => {
|
|
|
6722
6952
|
if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
|
|
6723
6953
|
const resolved = input.resolvedImports.get(exportInfo.reExportSource);
|
|
6724
6954
|
if (!resolved?.resolvedPath) continue;
|
|
6725
|
-
const targetIndex = fileIdMap.get(resolved.resolvedPath);
|
|
6955
|
+
const targetIndex = fileIdMap.get(toPosixPath(resolved.resolvedPath));
|
|
6726
6956
|
if (targetIndex === void 0) continue;
|
|
6727
6957
|
const exportedName = exportInfo.isNamespaceReExport ? "*" : exportInfo.name;
|
|
6728
6958
|
const originalName = exportInfo.isNamespaceReExport ? "*" : exportInfo.reExportOriginalName ?? exportInfo.name;
|
|
@@ -9851,12 +10081,19 @@ const visitFlagPatternsInExpression = (node, context) => {
|
|
|
9851
10081
|
if (node.type === "CallExpression") {
|
|
9852
10082
|
const callee = node.callee;
|
|
9853
10083
|
let functionName;
|
|
10084
|
+
let calleeIsMemberExpression = false;
|
|
10085
|
+
let receiverIsItselfMemberExpression = false;
|
|
9854
10086
|
if (isAstNode(callee)) {
|
|
9855
10087
|
if (callee.type === "Identifier") functionName = getStaticName(callee);
|
|
9856
|
-
else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression")
|
|
10088
|
+
else if (callee.type === "MemberExpression" || callee.type === "StaticMemberExpression") {
|
|
10089
|
+
calleeIsMemberExpression = true;
|
|
10090
|
+
functionName = getStaticName(callee.property);
|
|
10091
|
+
const receiver = callee.object;
|
|
10092
|
+
if (isAstNode(receiver) && (receiver.type === "MemberExpression" || receiver.type === "StaticMemberExpression")) receiverIsItselfMemberExpression = true;
|
|
10093
|
+
}
|
|
9857
10094
|
}
|
|
9858
10095
|
if (functionName !== void 0) {
|
|
9859
|
-
if (context.vercelFlagsLocalNames.has(functionName)
|
|
10096
|
+
if (!calleeIsMemberExpression && context.vercelFlagsLocalNames.has(functionName)) {
|
|
9860
10097
|
const callArguments = node.arguments;
|
|
9861
10098
|
const flagName = extractStringArgument(callArguments, 0);
|
|
9862
10099
|
if (flagName !== void 0) {
|
|
@@ -9865,6 +10102,7 @@ const visitFlagPatternsInExpression = (node, context) => {
|
|
|
9865
10102
|
}
|
|
9866
10103
|
return;
|
|
9867
10104
|
}
|
|
10105
|
+
if (calleeIsMemberExpression && receiverIsItselfMemberExpression) return;
|
|
9868
10106
|
for (const sdkPattern of context.sdkPatterns) {
|
|
9869
10107
|
if (sdkPattern.functionName !== functionName) continue;
|
|
9870
10108
|
const callArguments = node.arguments;
|
|
@@ -10410,11 +10648,16 @@ const collectLocalTypeNames = (programNode) => {
|
|
|
10410
10648
|
*
|
|
10411
10649
|
* `Story` is intentionally a local alias — consumers don't import it; the
|
|
10412
10650
|
* Storybook runtime reads the default export. Flagging this as a leak
|
|
10413
|
-
* produces near-100% false positives on Storybook codebases, so skip
|
|
10414
|
-
*
|
|
10651
|
+
* produces near-100% false positives on Storybook codebases, so skip story
|
|
10652
|
+
* files entirely. Storybook supports both common glob conventions — match
|
|
10653
|
+
* the `*.stories.{ext}` style as well as a bare `stories.{ext}` basename.
|
|
10415
10654
|
*/
|
|
10416
|
-
const
|
|
10417
|
-
const isStorybookStoryFile = (filePath) =>
|
|
10655
|
+
const STORYBOOK_STORY_BASENAME_PATTERN = /^(?:.*\.)?stories\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/i;
|
|
10656
|
+
const isStorybookStoryFile = (filePath) => {
|
|
10657
|
+
const lastSlash = filePath.lastIndexOf("/");
|
|
10658
|
+
const basename = lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);
|
|
10659
|
+
return STORYBOOK_STORY_BASENAME_PATTERN.test(basename);
|
|
10660
|
+
};
|
|
10418
10661
|
/**
|
|
10419
10662
|
* Detect TypeScript "private type leak": an exported declaration's signature
|
|
10420
10663
|
* 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.bd94e5e",
|
|
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",
|