deslop-js 0.6.3 → 0.7.1
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/analyzed-inputs.cjs +5 -0
- package/dist/analyzed-inputs.d.cts +5 -0
- package/dist/analyzed-inputs.d.mts +5 -0
- package/dist/analyzed-inputs.mjs +3 -0
- package/dist/constants-CD9NXHxi.cjs +530 -0
- package/dist/constants-oYYofMhb.mjs +344 -0
- package/dist/entries-worker.mjs +3736 -0
- package/dist/index.cjs +672 -476
- package/dist/index.d.cts +22 -0
- package/dist/index.d.mts +22 -0
- package/dist/index.mjs +625 -430
- package/dist/parse-worker.mjs +1 -2212
- package/dist/parse-xkrZfjHl.mjs +2308 -0
- package/package.json +11 -1
|
@@ -0,0 +1,3736 @@
|
|
|
1
|
+
import { a as OUTPUT_DIRECTORIES, c as SCRIPT_ENTRY_PATTERNS, d as SOURCE_EXTENSIONS$3, f as STANDALONE_PROJECT_LOCKFILES, i as MONOREPO_ROOT_MARKERS, l as SCRIPT_EXTENSIONLESS_FILE_PATTERN, o as RESOLVER_EXTENSIONS, r as LOCKFILE_MARKERS, s as SCRIPT_CONFIG_FILE_PATTERN, t as extractReactRouterRouteModuleEntries, u as SCRIPT_FILE_PATTERN } from "./parse-xkrZfjHl.mjs";
|
|
2
|
+
import { parentPort } from "node:worker_threads";
|
|
3
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
4
|
+
import fg from "fast-glob";
|
|
5
|
+
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import ts from "typescript";
|
|
8
|
+
import "oxc-resolver";
|
|
9
|
+
|
|
10
|
+
//#region src/collect/workspaces.ts
|
|
11
|
+
const resolveWorkspaces = (rootDir) => {
|
|
12
|
+
const rootPatterns = collectWorkspacePatterns(rootDir);
|
|
13
|
+
const hasRootLevelWorkspacePatterns = rootPatterns.length > 0;
|
|
14
|
+
let expandedDirectories = hasRootLevelWorkspacePatterns ? expandWorkspaceGlobs(rootPatterns, rootDir) : [];
|
|
15
|
+
const implicitSubProjects = discoverImplicitSubProjects(rootDir, expandedDirectories);
|
|
16
|
+
if (expandedDirectories.length === 0 && implicitSubProjects.length > 0) for (const subProjectDirectory of implicitSubProjects) {
|
|
17
|
+
const subPatterns = collectWorkspacePatterns(subProjectDirectory);
|
|
18
|
+
if (subPatterns.length > 0) {
|
|
19
|
+
const subExpanded = expandWorkspaceGlobs(subPatterns, subProjectDirectory);
|
|
20
|
+
expandedDirectories.push(subProjectDirectory, ...subExpanded);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const declaredDirectorySet = new Set(expandedDirectories);
|
|
24
|
+
const excludedDirectories = [];
|
|
25
|
+
const filteredImplicitSubProjects = implicitSubProjects;
|
|
26
|
+
const allDirectories = [...new Set([...expandedDirectories, ...filteredImplicitSubProjects])];
|
|
27
|
+
const workspacePackages = [];
|
|
28
|
+
for (const directory of allDirectories) {
|
|
29
|
+
const packageJsonPath = join(directory, "package.json");
|
|
30
|
+
if (!existsSync(packageJsonPath)) continue;
|
|
31
|
+
try {
|
|
32
|
+
const packageContent = readFileSync(packageJsonPath, "utf-8");
|
|
33
|
+
const packageJson = JSON.parse(packageContent);
|
|
34
|
+
const packageName = packageJson.name || relative(rootDir, directory);
|
|
35
|
+
const entryFiles = extractWorkspaceEntries(packageJson, directory);
|
|
36
|
+
const depthFromRoot = relative(rootDir, directory).split("/").filter(Boolean).length;
|
|
37
|
+
workspacePackages.push({
|
|
38
|
+
name: packageName,
|
|
39
|
+
directory,
|
|
40
|
+
entryFiles,
|
|
41
|
+
isDeclaredWorkspace: declaredDirectorySet.has(directory),
|
|
42
|
+
depthFromRoot
|
|
43
|
+
});
|
|
44
|
+
} catch {}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
packages: workspacePackages,
|
|
48
|
+
excludedDirectories,
|
|
49
|
+
hasRootLevelWorkspacePatterns
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
const IMPLICIT_SUB_PROJECT_SEARCH_DEPTH = 3;
|
|
53
|
+
const isStandaloneProject = (directory) => STANDALONE_PROJECT_LOCKFILES.some((lockfile) => existsSync(join(directory, lockfile)));
|
|
54
|
+
const discoverImplicitSubProjects = (rootDir, alreadyDiscoveredDirectories) => {
|
|
55
|
+
const knownDirectories = new Set(alreadyDiscoveredDirectories);
|
|
56
|
+
const hasDeclaredWorkspaces = alreadyDiscoveredDirectories.length > 0;
|
|
57
|
+
const subProjectDirectories = [];
|
|
58
|
+
const subPackageJsonPaths = fg.sync("**/package.json", {
|
|
59
|
+
cwd: rootDir,
|
|
60
|
+
absolute: true,
|
|
61
|
+
onlyFiles: true,
|
|
62
|
+
ignore: [
|
|
63
|
+
"**/node_modules/**",
|
|
64
|
+
"**/dist/**",
|
|
65
|
+
"**/build/**",
|
|
66
|
+
"**/.git/**"
|
|
67
|
+
],
|
|
68
|
+
deep: IMPLICIT_SUB_PROJECT_SEARCH_DEPTH + 1
|
|
69
|
+
});
|
|
70
|
+
for (const packageJsonPath of subPackageJsonPaths) {
|
|
71
|
+
const directory = packageJsonPath.replace(/\/package\.json$/, "");
|
|
72
|
+
if (directory === rootDir) continue;
|
|
73
|
+
if (knownDirectories.has(directory)) continue;
|
|
74
|
+
if (hasDeclaredWorkspaces && isStandaloneProject(directory)) continue;
|
|
75
|
+
subProjectDirectories.push(directory);
|
|
76
|
+
}
|
|
77
|
+
return subProjectDirectories;
|
|
78
|
+
};
|
|
79
|
+
const collectWorkspacePatterns = (rootDir) => {
|
|
80
|
+
const patterns = [];
|
|
81
|
+
const packageJsonPath = join(rootDir, "package.json");
|
|
82
|
+
if (existsSync(packageJsonPath)) try {
|
|
83
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
84
|
+
const packageJson = JSON.parse(content);
|
|
85
|
+
if (Array.isArray(packageJson.workspaces)) patterns.push(...packageJson.workspaces);
|
|
86
|
+
else if (packageJson.workspaces?.packages) patterns.push(...packageJson.workspaces.packages);
|
|
87
|
+
} catch {}
|
|
88
|
+
const pnpmWorkspacePath = join(rootDir, "pnpm-workspace.yaml");
|
|
89
|
+
if (existsSync(pnpmWorkspacePath)) try {
|
|
90
|
+
const packageLines = extractPnpmWorkspacePackages(readFileSync(pnpmWorkspacePath, "utf-8"));
|
|
91
|
+
patterns.push(...packageLines);
|
|
92
|
+
} catch {}
|
|
93
|
+
const lernaJsonPath = join(rootDir, "lerna.json");
|
|
94
|
+
if (existsSync(lernaJsonPath)) try {
|
|
95
|
+
const content = readFileSync(lernaJsonPath, "utf-8");
|
|
96
|
+
const lernaJson = JSON.parse(content);
|
|
97
|
+
if (Array.isArray(lernaJson.packages)) patterns.push(...lernaJson.packages.filter((pattern) => typeof pattern === "string" && !pattern.startsWith("!")));
|
|
98
|
+
} catch {}
|
|
99
|
+
return patterns;
|
|
100
|
+
};
|
|
101
|
+
const extractPnpmWorkspacePackages = (yamlContent) => {
|
|
102
|
+
const packages = [];
|
|
103
|
+
let inPackagesSection = false;
|
|
104
|
+
for (const line of yamlContent.split("\n")) {
|
|
105
|
+
const trimmedLine = line.trim();
|
|
106
|
+
if (trimmedLine === "packages:") {
|
|
107
|
+
inPackagesSection = true;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (inPackagesSection) {
|
|
111
|
+
if (trimmedLine.startsWith("- ")) {
|
|
112
|
+
const pattern = trimmedLine.slice(2).trim().replace(/^["']|["']$/g, "");
|
|
113
|
+
if (pattern && !pattern.startsWith("!")) packages.push(pattern);
|
|
114
|
+
} else if (trimmedLine && !trimmedLine.startsWith("#")) break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return packages;
|
|
118
|
+
};
|
|
119
|
+
const expandWorkspaceGlobs = (patterns, rootDir) => {
|
|
120
|
+
const directories = [];
|
|
121
|
+
for (const pattern of patterns) if (pattern.includes("*")) {
|
|
122
|
+
const globPattern = pattern.endsWith("/") ? `${pattern}package.json` : `${pattern}/package.json`;
|
|
123
|
+
try {
|
|
124
|
+
const matchedFiles = fg.sync(globPattern, {
|
|
125
|
+
cwd: rootDir,
|
|
126
|
+
absolute: true,
|
|
127
|
+
onlyFiles: true
|
|
128
|
+
});
|
|
129
|
+
for (const matchedPath of matchedFiles) directories.push(matchedPath.replace(/\/package\.json$/, ""));
|
|
130
|
+
} catch {}
|
|
131
|
+
} else {
|
|
132
|
+
const absoluteDirectory = resolve(rootDir, pattern);
|
|
133
|
+
if (existsSync(join(absoluteDirectory, "package.json"))) directories.push(absoluteDirectory);
|
|
134
|
+
}
|
|
135
|
+
return [...new Set(directories)];
|
|
136
|
+
};
|
|
137
|
+
const SOURCE_EXTENSIONS$2 = [
|
|
138
|
+
".ts",
|
|
139
|
+
".tsx",
|
|
140
|
+
".js",
|
|
141
|
+
".jsx",
|
|
142
|
+
".mts",
|
|
143
|
+
".mjs",
|
|
144
|
+
".cts",
|
|
145
|
+
".cjs"
|
|
146
|
+
];
|
|
147
|
+
const OUTPUT_DIR_PREFIXES$1 = [
|
|
148
|
+
"dist/",
|
|
149
|
+
"build/",
|
|
150
|
+
"lib/",
|
|
151
|
+
"lib-dist/",
|
|
152
|
+
"esm/",
|
|
153
|
+
"cjs/",
|
|
154
|
+
"out/",
|
|
155
|
+
"./dist/",
|
|
156
|
+
"./lib-dist/"
|
|
157
|
+
];
|
|
158
|
+
const SOURCE_INDEX_FALLBACK_STEMS$1 = [
|
|
159
|
+
"src/index",
|
|
160
|
+
"src/main",
|
|
161
|
+
"index",
|
|
162
|
+
"main"
|
|
163
|
+
];
|
|
164
|
+
const resolveSourcePath$1 = (distPath, directory) => {
|
|
165
|
+
const relativeToDist = relative(directory, distPath);
|
|
166
|
+
if (OUTPUT_DIR_PREFIXES$1.some((prefix) => relativeToDist.startsWith(prefix))) {
|
|
167
|
+
const sourceVariants = OUTPUT_DIR_PREFIXES$1.map((prefix) => relativeToDist.replace(new RegExp(`^${prefix.replace(".", "\\.")}`), "src/")).filter((variant) => variant !== relativeToDist);
|
|
168
|
+
for (const variant of sourceVariants) {
|
|
169
|
+
const withoutExtension = variant.replace(/\.[^.]+$/, "");
|
|
170
|
+
for (const sourceExtension of SOURCE_EXTENSIONS$2) {
|
|
171
|
+
const sourceCandidate = resolve(directory, withoutExtension + sourceExtension);
|
|
172
|
+
if (existsSync(sourceCandidate)) return [sourceCandidate];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
for (const stem of SOURCE_INDEX_FALLBACK_STEMS$1) for (const sourceExtension of SOURCE_EXTENSIONS$2) {
|
|
176
|
+
const fallbackCandidate = resolve(directory, stem + sourceExtension);
|
|
177
|
+
if (existsSync(fallbackCandidate)) return [fallbackCandidate];
|
|
178
|
+
}
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
const resolvedDistPath = resolve(directory, relativeToDist);
|
|
182
|
+
const candidates = [];
|
|
183
|
+
const withoutJsExtension = relativeToDist.replace(/\.[cm]?js$/, "");
|
|
184
|
+
if (withoutJsExtension !== relativeToDist) {
|
|
185
|
+
for (const sourceExtension of SOURCE_EXTENSIONS$2) {
|
|
186
|
+
const directSourceCandidate = resolve(directory, withoutJsExtension + sourceExtension);
|
|
187
|
+
if (existsSync(directSourceCandidate)) candidates.push(directSourceCandidate);
|
|
188
|
+
}
|
|
189
|
+
const indexCandidate = resolve(directory, withoutJsExtension, "index.ts");
|
|
190
|
+
if (existsSync(indexCandidate) && !candidates.includes(indexCandidate)) candidates.push(indexCandidate);
|
|
191
|
+
}
|
|
192
|
+
const withoutTsExtension = relativeToDist.replace(/\.ts$/, "");
|
|
193
|
+
if (withoutTsExtension !== relativeToDist && !existsSync(resolvedDistPath)) {
|
|
194
|
+
const tsxCandidate = resolve(directory, withoutTsExtension + ".tsx");
|
|
195
|
+
if (existsSync(tsxCandidate) && !candidates.includes(tsxCandidate)) candidates.push(tsxCandidate);
|
|
196
|
+
}
|
|
197
|
+
if (candidates.length === 0 && existsSync(resolvedDistPath)) candidates.push(resolvedDistPath);
|
|
198
|
+
return candidates;
|
|
199
|
+
};
|
|
200
|
+
const extractWorkspaceEntries = (packageJson, directory) => {
|
|
201
|
+
const entries = [];
|
|
202
|
+
const addWithSourceResolution = (filePath) => {
|
|
203
|
+
const resolved = resolve(directory, filePath);
|
|
204
|
+
const sourceVariants = resolveSourcePath$1(resolved, directory);
|
|
205
|
+
if (sourceVariants.length > 0) entries.push(...sourceVariants);
|
|
206
|
+
else entries.push(resolved);
|
|
207
|
+
};
|
|
208
|
+
for (const field of [
|
|
209
|
+
"main",
|
|
210
|
+
"module",
|
|
211
|
+
"browser",
|
|
212
|
+
"types",
|
|
213
|
+
"typings",
|
|
214
|
+
"source"
|
|
215
|
+
]) {
|
|
216
|
+
const fieldValue = packageJson[field];
|
|
217
|
+
if (typeof fieldValue === "string") addWithSourceResolution(fieldValue);
|
|
218
|
+
}
|
|
219
|
+
if (packageJson.exports) {
|
|
220
|
+
const exportPaths = [];
|
|
221
|
+
collectExportPaths$1(packageJson.exports, directory, exportPaths);
|
|
222
|
+
for (const exportPath of exportPaths) {
|
|
223
|
+
const sourceVariants = resolveSourcePath$1(exportPath, directory);
|
|
224
|
+
if (sourceVariants.length > 0) entries.push(...sourceVariants);
|
|
225
|
+
else entries.push(exportPath);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (packageJson.bin) {
|
|
229
|
+
if (typeof packageJson.bin === "string") addWithSourceResolution(packageJson.bin);
|
|
230
|
+
else if (typeof packageJson.bin === "object" && packageJson.bin !== null) {
|
|
231
|
+
for (const binPath of Object.values(packageJson.bin)) if (typeof binPath === "string") addWithSourceResolution(binPath);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return [...new Set(entries)];
|
|
235
|
+
};
|
|
236
|
+
const collectExportPaths$1 = (exportValue, rootDir, entries) => {
|
|
237
|
+
if (typeof exportValue === "string") {
|
|
238
|
+
if (exportValue.startsWith(".")) if (exportValue.includes("*")) {
|
|
239
|
+
const globPattern = exportValue.replace(/^\.\/?/, "");
|
|
240
|
+
try {
|
|
241
|
+
const expandedFiles = fg.sync(globPattern, {
|
|
242
|
+
cwd: rootDir,
|
|
243
|
+
absolute: true,
|
|
244
|
+
onlyFiles: true,
|
|
245
|
+
ignore: ["**/node_modules/**"]
|
|
246
|
+
});
|
|
247
|
+
entries.push(...expandedFiles);
|
|
248
|
+
} catch {}
|
|
249
|
+
} else entries.push(resolve(rootDir, exportValue));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (typeof exportValue !== "object" || exportValue === null) return;
|
|
253
|
+
for (const nestedValue of Object.values(exportValue)) collectExportPaths$1(nestedValue, rootDir, entries);
|
|
254
|
+
};
|
|
255
|
+
const NEXTJS_APP_ROUTER_CONVENTIONS = [
|
|
256
|
+
"page",
|
|
257
|
+
"layout",
|
|
258
|
+
"loading",
|
|
259
|
+
"error",
|
|
260
|
+
"not-found",
|
|
261
|
+
"template",
|
|
262
|
+
"default",
|
|
263
|
+
"route",
|
|
264
|
+
"global-error",
|
|
265
|
+
"forbidden",
|
|
266
|
+
"unauthorized",
|
|
267
|
+
"middleware",
|
|
268
|
+
"instrumentation",
|
|
269
|
+
"manifest",
|
|
270
|
+
"robots",
|
|
271
|
+
"sitemap",
|
|
272
|
+
"opengraph-image",
|
|
273
|
+
"twitter-image",
|
|
274
|
+
"icon",
|
|
275
|
+
"apple-icon",
|
|
276
|
+
"actions"
|
|
277
|
+
];
|
|
278
|
+
const FRAMEWORK_FILE_GLOB = "**/*.{ts,tsx,js,jsx,mjs,cjs}";
|
|
279
|
+
const FRAMEWORK_FILE_GLOB_WITH_MDX = "**/*.{ts,tsx,js,jsx,mdx,md,mjs,cjs}";
|
|
280
|
+
const NEXTJS_ENABLERS = ["next"];
|
|
281
|
+
const REACT_ROUTER_ENABLERS = ["@react-router/dev"];
|
|
282
|
+
const REMIX_ENABLERS = [
|
|
283
|
+
"@remix-run/node",
|
|
284
|
+
"@remix-run/react",
|
|
285
|
+
"@remix-run/cloudflare",
|
|
286
|
+
"@remix-run/cloudflare-pages",
|
|
287
|
+
"@remix-run/deno"
|
|
288
|
+
];
|
|
289
|
+
const NUXT_ENABLERS = ["nuxt"];
|
|
290
|
+
const SVELTEKIT_ENABLERS = ["@sveltejs/kit"];
|
|
291
|
+
const ASTRO_ENABLERS = ["astro"];
|
|
292
|
+
const GATSBY_ENABLERS = ["gatsby"];
|
|
293
|
+
const readDependencies = (directory) => {
|
|
294
|
+
const packageJsonPath = join(directory, "package.json");
|
|
295
|
+
if (!existsSync(packageJsonPath)) return {};
|
|
296
|
+
try {
|
|
297
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
298
|
+
const packageJson = JSON.parse(content);
|
|
299
|
+
return {
|
|
300
|
+
...packageJson.dependencies,
|
|
301
|
+
...packageJson.devDependencies,
|
|
302
|
+
...packageJson.optionalDependencies
|
|
303
|
+
};
|
|
304
|
+
} catch {
|
|
305
|
+
return {};
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
const hasAnyEnabler = (dependencies, enablers) => enablers.some((enabler) => enabler in dependencies);
|
|
309
|
+
const extractReactRouterAppDirectory = (directory) => {
|
|
310
|
+
for (const configFile of [
|
|
311
|
+
"react-router.config.ts",
|
|
312
|
+
"react-router.config.js",
|
|
313
|
+
"react-router.config.mjs",
|
|
314
|
+
"react-router.config.cjs"
|
|
315
|
+
]) {
|
|
316
|
+
const configPath = join(directory, configFile);
|
|
317
|
+
if (!existsSync(configPath)) continue;
|
|
318
|
+
try {
|
|
319
|
+
const appDirectoryMatch = readFileSync(configPath, "utf-8").match(/appDirectory\s*:\s*['"`]([^'"`]+)['"`]/);
|
|
320
|
+
if (appDirectoryMatch) return appDirectoryMatch[1].replace(/^\.\//, "");
|
|
321
|
+
} catch {}
|
|
322
|
+
}
|
|
323
|
+
return "app";
|
|
324
|
+
};
|
|
325
|
+
const ROUTE_FILE_EXTENSIONS = [
|
|
326
|
+
".ts",
|
|
327
|
+
".tsx",
|
|
328
|
+
".js",
|
|
329
|
+
".jsx"
|
|
330
|
+
];
|
|
331
|
+
const resolveRouteModulePath = (modulePath, routesFileDirectory) => {
|
|
332
|
+
const normalizedPath = modulePath.startsWith("./") ? modulePath.slice(2) : modulePath;
|
|
333
|
+
if (ROUTE_FILE_EXTENSIONS.some((extension) => normalizedPath.endsWith(extension))) {
|
|
334
|
+
const absolutePath = resolve(routesFileDirectory, normalizedPath);
|
|
335
|
+
if (existsSync(absolutePath)) return absolutePath;
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
for (const extension of ROUTE_FILE_EXTENSIONS) {
|
|
339
|
+
const absolutePath = resolve(routesFileDirectory, normalizedPath + extension);
|
|
340
|
+
if (existsSync(absolutePath)) return absolutePath;
|
|
341
|
+
}
|
|
342
|
+
for (const extension of ROUTE_FILE_EXTENSIONS) {
|
|
343
|
+
const absolutePath = resolve(routesFileDirectory, normalizedPath, `index${extension}`);
|
|
344
|
+
if (existsSync(absolutePath)) return absolutePath;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
const extractRouteModuleEntriesFromRoutesFiles = (rootDir, appDirectory) => {
|
|
348
|
+
const routesFileCandidates = fg.sync([
|
|
349
|
+
`${appDirectory}/routes.{ts,js,mts,mjs}`,
|
|
350
|
+
`${appDirectory}/routes/**/*.{ts,js,mts,mjs}`,
|
|
351
|
+
`src/routes.{ts,js,mts,mjs}`
|
|
352
|
+
], {
|
|
353
|
+
cwd: rootDir,
|
|
354
|
+
absolute: true,
|
|
355
|
+
onlyFiles: true,
|
|
356
|
+
ignore: ["**/node_modules/**"]
|
|
357
|
+
});
|
|
358
|
+
const resolvedEntries = [];
|
|
359
|
+
for (const routesFilePath of routesFileCandidates) {
|
|
360
|
+
const routesFileDirectory = dirname(routesFilePath);
|
|
361
|
+
const modulePaths = extractReactRouterRouteModuleEntries(routesFilePath);
|
|
362
|
+
for (const modulePath of modulePaths) {
|
|
363
|
+
const resolvedPath = resolveRouteModulePath(modulePath, routesFileDirectory);
|
|
364
|
+
if (resolvedPath) resolvedEntries.push(resolvedPath);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return resolvedEntries;
|
|
368
|
+
};
|
|
369
|
+
const detectFrameworkEntries = (rootDir) => {
|
|
370
|
+
const entryPoints = [];
|
|
371
|
+
const dependencies = readDependencies(rootDir);
|
|
372
|
+
const isNextjs = hasAnyEnabler(dependencies, NEXTJS_ENABLERS);
|
|
373
|
+
const isReactRouter = hasAnyEnabler(dependencies, REACT_ROUTER_ENABLERS);
|
|
374
|
+
const isRemix = hasAnyEnabler(dependencies, REMIX_ENABLERS);
|
|
375
|
+
const isNuxt = hasAnyEnabler(dependencies, NUXT_ENABLERS);
|
|
376
|
+
const isSvelteKit = hasAnyEnabler(dependencies, SVELTEKIT_ENABLERS);
|
|
377
|
+
const isAstro = hasAnyEnabler(dependencies, ASTRO_ENABLERS);
|
|
378
|
+
const isGatsby = hasAnyEnabler(dependencies, GATSBY_ENABLERS);
|
|
379
|
+
if (isNextjs) {
|
|
380
|
+
const appRouterConventionGlob = NEXTJS_APP_ROUTER_CONVENTIONS.map((convention) => `**/${convention}.{ts,tsx,js,jsx,mdx}`).join(",");
|
|
381
|
+
const appDirs = [join(rootDir, "app"), join(rootDir, "src", "app")];
|
|
382
|
+
for (const appDir of appDirs) if (existsSync(appDir) && statSync(appDir).isDirectory()) entryPoints.push(...fg.sync(`{${appRouterConventionGlob}}`, {
|
|
383
|
+
cwd: appDir,
|
|
384
|
+
absolute: true,
|
|
385
|
+
onlyFiles: true,
|
|
386
|
+
ignore: ["**/node_modules/**"]
|
|
387
|
+
}));
|
|
388
|
+
const pagesDirs = [join(rootDir, "pages"), join(rootDir, "src", "pages")];
|
|
389
|
+
for (const pagesDir of pagesDirs) if (existsSync(pagesDir) && statSync(pagesDir).isDirectory()) entryPoints.push(...fg.sync(FRAMEWORK_FILE_GLOB, {
|
|
390
|
+
cwd: pagesDir,
|
|
391
|
+
absolute: true,
|
|
392
|
+
onlyFiles: true,
|
|
393
|
+
ignore: ["**/node_modules/**"]
|
|
394
|
+
}));
|
|
395
|
+
entryPoints.push(...fg.sync([
|
|
396
|
+
"middleware.{ts,js}",
|
|
397
|
+
"src/middleware.{ts,js}",
|
|
398
|
+
"instrumentation.{ts,js}",
|
|
399
|
+
"instrumentation-client.{ts,js}",
|
|
400
|
+
"src/instrumentation.{ts,js}",
|
|
401
|
+
"src/instrumentation-client.{ts,js}",
|
|
402
|
+
"mdx-components.{ts,tsx,js,jsx}",
|
|
403
|
+
"src/mdx-components.{ts,tsx,js,jsx}"
|
|
404
|
+
], {
|
|
405
|
+
cwd: rootDir,
|
|
406
|
+
absolute: true,
|
|
407
|
+
onlyFiles: true,
|
|
408
|
+
ignore: ["**/node_modules/**"]
|
|
409
|
+
}));
|
|
410
|
+
}
|
|
411
|
+
if (isReactRouter || isRemix) {
|
|
412
|
+
const reactRouterAppDirectory = extractReactRouterAppDirectory(rootDir);
|
|
413
|
+
entryPoints.push(...fg.sync([
|
|
414
|
+
`${reactRouterAppDirectory}/routes/**/*.{ts,tsx,js,jsx}`,
|
|
415
|
+
`${reactRouterAppDirectory}/root.{ts,tsx,js,jsx}`,
|
|
416
|
+
`${reactRouterAppDirectory}/entry.client.{ts,tsx,js,jsx}`,
|
|
417
|
+
`${reactRouterAppDirectory}/entry.server.{ts,tsx,js,jsx}`,
|
|
418
|
+
`${reactRouterAppDirectory}/routes.{ts,js,mts,mjs}`
|
|
419
|
+
], {
|
|
420
|
+
cwd: rootDir,
|
|
421
|
+
absolute: true,
|
|
422
|
+
onlyFiles: true,
|
|
423
|
+
ignore: ["**/node_modules/**"]
|
|
424
|
+
}));
|
|
425
|
+
const routeModuleEntries = extractRouteModuleEntriesFromRoutesFiles(rootDir, reactRouterAppDirectory);
|
|
426
|
+
entryPoints.push(...routeModuleEntries);
|
|
427
|
+
}
|
|
428
|
+
if (isNuxt) for (const nuxtDir of [
|
|
429
|
+
"pages",
|
|
430
|
+
"layouts",
|
|
431
|
+
"middleware",
|
|
432
|
+
"server",
|
|
433
|
+
"composables",
|
|
434
|
+
"plugins"
|
|
435
|
+
]) {
|
|
436
|
+
const dirPath = join(rootDir, nuxtDir);
|
|
437
|
+
if (existsSync(dirPath) && statSync(dirPath).isDirectory()) entryPoints.push(...fg.sync("**/*.{ts,tsx,js,jsx,vue}", {
|
|
438
|
+
cwd: dirPath,
|
|
439
|
+
absolute: true,
|
|
440
|
+
onlyFiles: true,
|
|
441
|
+
ignore: ["**/node_modules/**"]
|
|
442
|
+
}));
|
|
443
|
+
}
|
|
444
|
+
if (isSvelteKit) {
|
|
445
|
+
const svelteDirs = [
|
|
446
|
+
join(rootDir, "src", "routes"),
|
|
447
|
+
join(rootDir, "src", "lib"),
|
|
448
|
+
join(rootDir, "src", "params")
|
|
449
|
+
];
|
|
450
|
+
for (const svelteDir of svelteDirs) if (existsSync(svelteDir) && statSync(svelteDir).isDirectory()) entryPoints.push(...fg.sync("**/*.{ts,tsx,js,jsx,svelte}", {
|
|
451
|
+
cwd: svelteDir,
|
|
452
|
+
absolute: true,
|
|
453
|
+
onlyFiles: true,
|
|
454
|
+
ignore: ["**/node_modules/**"]
|
|
455
|
+
}));
|
|
456
|
+
}
|
|
457
|
+
if (isAstro) {
|
|
458
|
+
const astroDirs = [
|
|
459
|
+
join(rootDir, "src", "pages"),
|
|
460
|
+
join(rootDir, "src", "layouts"),
|
|
461
|
+
join(rootDir, "src", "content")
|
|
462
|
+
];
|
|
463
|
+
for (const astroDir of astroDirs) if (existsSync(astroDir) && statSync(astroDir).isDirectory()) entryPoints.push(...fg.sync(FRAMEWORK_FILE_GLOB_WITH_MDX, {
|
|
464
|
+
cwd: astroDir,
|
|
465
|
+
absolute: true,
|
|
466
|
+
onlyFiles: true,
|
|
467
|
+
ignore: ["**/node_modules/**"]
|
|
468
|
+
}));
|
|
469
|
+
}
|
|
470
|
+
if (isGatsby) {
|
|
471
|
+
const gatsbyDirs = [join(rootDir, "src", "pages"), join(rootDir, "src", "templates")];
|
|
472
|
+
for (const gatsbyDir of gatsbyDirs) if (existsSync(gatsbyDir) && statSync(gatsbyDir).isDirectory()) entryPoints.push(...fg.sync(FRAMEWORK_FILE_GLOB, {
|
|
473
|
+
cwd: gatsbyDir,
|
|
474
|
+
absolute: true,
|
|
475
|
+
onlyFiles: true,
|
|
476
|
+
ignore: ["**/node_modules/**"]
|
|
477
|
+
}));
|
|
478
|
+
}
|
|
479
|
+
entryPoints.push(...fg.sync([
|
|
480
|
+
"**/*.stories.{ts,tsx,js,jsx,mts,mjs}",
|
|
481
|
+
"**/*.story.{ts,tsx,js,jsx,mts,mjs}",
|
|
482
|
+
".storybook/**/*.{ts,tsx,js,jsx,mts,mjs}"
|
|
483
|
+
], {
|
|
484
|
+
cwd: rootDir,
|
|
485
|
+
absolute: true,
|
|
486
|
+
onlyFiles: true,
|
|
487
|
+
ignore: ["**/node_modules/**"],
|
|
488
|
+
dot: true
|
|
489
|
+
}));
|
|
490
|
+
entryPoints.push(...fg.sync([
|
|
491
|
+
"env.{ts,js,mjs}",
|
|
492
|
+
"src/env.{ts,js,mjs}",
|
|
493
|
+
"src/routeTree.gen.{ts,tsx}",
|
|
494
|
+
"src/router.{ts,tsx}"
|
|
495
|
+
], {
|
|
496
|
+
cwd: rootDir,
|
|
497
|
+
absolute: true,
|
|
498
|
+
onlyFiles: true,
|
|
499
|
+
ignore: ["**/node_modules/**"],
|
|
500
|
+
dot: true
|
|
501
|
+
}));
|
|
502
|
+
for (const entryDir of ["e2e", "cypress"]) {
|
|
503
|
+
const dirPath = join(rootDir, entryDir);
|
|
504
|
+
if (existsSync(dirPath) && statSync(dirPath).isDirectory()) entryPoints.push(...fg.sync(FRAMEWORK_FILE_GLOB, {
|
|
505
|
+
cwd: dirPath,
|
|
506
|
+
absolute: true,
|
|
507
|
+
onlyFiles: true,
|
|
508
|
+
dot: entryDir.startsWith(".")
|
|
509
|
+
}));
|
|
510
|
+
}
|
|
511
|
+
entryPoints.push(...discoverElectronEntryPoints(rootDir));
|
|
512
|
+
entryPoints.push(...discoverMobileEntryPoints(rootDir));
|
|
513
|
+
return [...new Set(entryPoints)];
|
|
514
|
+
};
|
|
515
|
+
const ELECTRON_ENABLERS = [
|
|
516
|
+
"electron",
|
|
517
|
+
"electron-builder",
|
|
518
|
+
"@electron-forge/cli",
|
|
519
|
+
"electron-vite"
|
|
520
|
+
];
|
|
521
|
+
const ELECTRON_ENTRY_PATTERNS = [
|
|
522
|
+
"src/main/**/*.{ts,js}",
|
|
523
|
+
"src/preload/**/*.{ts,js}",
|
|
524
|
+
"electron/main.{ts,js}",
|
|
525
|
+
"electron.vite.config.{ts,js,mjs}",
|
|
526
|
+
"forge.config.{ts,js,cjs}",
|
|
527
|
+
"electron-builder.{yml,yaml,json,json5,toml}"
|
|
528
|
+
];
|
|
529
|
+
const discoverElectronEntryPoints = (rootDir) => {
|
|
530
|
+
const packageJsonPath = join(rootDir, "package.json");
|
|
531
|
+
if (!existsSync(packageJsonPath)) return [];
|
|
532
|
+
try {
|
|
533
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
534
|
+
const packageJson = JSON.parse(content);
|
|
535
|
+
const allDependencies = {
|
|
536
|
+
...packageJson.dependencies,
|
|
537
|
+
...packageJson.devDependencies,
|
|
538
|
+
...packageJson.optionalDependencies
|
|
539
|
+
};
|
|
540
|
+
if (!ELECTRON_ENABLERS.some((enabler) => enabler in allDependencies)) return [];
|
|
541
|
+
return fg.sync(ELECTRON_ENTRY_PATTERNS, {
|
|
542
|
+
cwd: rootDir,
|
|
543
|
+
absolute: true,
|
|
544
|
+
onlyFiles: true,
|
|
545
|
+
ignore: ["**/node_modules/**"]
|
|
546
|
+
});
|
|
547
|
+
} catch {
|
|
548
|
+
return [];
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
const EXPO_ENABLERS = ["expo"];
|
|
552
|
+
const EXPO_ROUTER_ENABLERS = ["expo-router"];
|
|
553
|
+
const EXPO_ENTRY_PATTERNS = [
|
|
554
|
+
"App.{ts,tsx,js,jsx}",
|
|
555
|
+
"src/App.{ts,tsx,js,jsx}",
|
|
556
|
+
"app.config.{ts,js,mjs,cjs}",
|
|
557
|
+
"metro.config.{ts,js,mjs,cjs}",
|
|
558
|
+
"babel.config.{ts,js,mjs,cjs}"
|
|
559
|
+
];
|
|
560
|
+
const EXPO_ROUTER_ENTRY_PATTERNS = [
|
|
561
|
+
"app/**/*.{ts,tsx,js,jsx}",
|
|
562
|
+
"src/app/**/*.{ts,tsx,js,jsx}",
|
|
563
|
+
"app.config.{ts,js,mjs,cjs}",
|
|
564
|
+
"metro.config.{ts,js,mjs,cjs}",
|
|
565
|
+
"babel.config.{ts,js,mjs,cjs}"
|
|
566
|
+
];
|
|
567
|
+
const REACT_NATIVE_ENABLERS = ["react-native"];
|
|
568
|
+
const REACT_NATIVE_ENTRY_PATTERNS = [
|
|
569
|
+
"index.{ts,tsx,js,jsx}",
|
|
570
|
+
"index.android.{ts,tsx,js,jsx}",
|
|
571
|
+
"index.ios.{ts,tsx,js,jsx}",
|
|
572
|
+
"index.native.{ts,tsx,js,jsx}",
|
|
573
|
+
"App.{ts,tsx,js,jsx}",
|
|
574
|
+
"src/App.{ts,tsx,js,jsx}",
|
|
575
|
+
"metro.config.{ts,js}",
|
|
576
|
+
"react-native.config.{ts,js}"
|
|
577
|
+
];
|
|
578
|
+
const discoverMobileEntryPoints = (directory) => {
|
|
579
|
+
const packageJsonPath = join(directory, "package.json");
|
|
580
|
+
if (!existsSync(packageJsonPath)) return [];
|
|
581
|
+
try {
|
|
582
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
583
|
+
const packageJson = JSON.parse(content);
|
|
584
|
+
const allDependencies = {
|
|
585
|
+
...packageJson.dependencies,
|
|
586
|
+
...packageJson.devDependencies,
|
|
587
|
+
...packageJson.optionalDependencies
|
|
588
|
+
};
|
|
589
|
+
const detectedPatterns = [];
|
|
590
|
+
if (EXPO_ROUTER_ENABLERS.some((enabler) => enabler in allDependencies)) detectedPatterns.push(...EXPO_ROUTER_ENTRY_PATTERNS);
|
|
591
|
+
else if (EXPO_ENABLERS.some((enabler) => enabler in allDependencies)) detectedPatterns.push(...EXPO_ENTRY_PATTERNS);
|
|
592
|
+
if (REACT_NATIVE_ENABLERS.some((enabler) => enabler in allDependencies)) detectedPatterns.push(...REACT_NATIVE_ENTRY_PATTERNS);
|
|
593
|
+
if (detectedPatterns.length === 0) return [];
|
|
594
|
+
return fg.sync(detectedPatterns, {
|
|
595
|
+
cwd: directory,
|
|
596
|
+
absolute: true,
|
|
597
|
+
onlyFiles: true,
|
|
598
|
+
ignore: ["**/node_modules/**"]
|
|
599
|
+
});
|
|
600
|
+
} catch {
|
|
601
|
+
return [];
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
//#endregion
|
|
606
|
+
//#region src/collect/expo-config-plugin-entries.ts
|
|
607
|
+
const EXPO_CONFIG_FILE_GLOBS = ["app.config.{ts,mts,cts,js,mjs,cjs}", "app.json"];
|
|
608
|
+
const NESTED_EXPO_CONFIG_FILE_GLOBS = [
|
|
609
|
+
...EXPO_CONFIG_FILE_GLOBS,
|
|
610
|
+
"**/app.config.{ts,mts,cts,js,mjs,cjs}",
|
|
611
|
+
"**/app.json"
|
|
612
|
+
];
|
|
613
|
+
const EXPO_REACT_NATIVE_DEPENDENCIES = new Set(["expo", "react-native"]);
|
|
614
|
+
const EXPO_PLUGIN_RESOLVABLE_EXTENSIONS = SOURCE_EXTENSIONS$3.map((sourceExtension) => `.${sourceExtension}`);
|
|
615
|
+
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
616
|
+
const isExpoOrReactNativeWorkspace = (dependencies) => [...EXPO_REACT_NATIVE_DEPENDENCIES].some((dependencyName) => dependencyName in dependencies);
|
|
617
|
+
const isLocalExpoPluginPath = (value) => (value.startsWith("./") || value.startsWith("../")) && !value.includes("*") && !value.includes("?");
|
|
618
|
+
const isFile = (filePath) => {
|
|
619
|
+
try {
|
|
620
|
+
return statSync(filePath).isFile();
|
|
621
|
+
} catch {
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
const resolveExpoPluginPath = (configDirectory, pluginPath) => {
|
|
626
|
+
const candidatePath = resolve(configDirectory, pluginPath);
|
|
627
|
+
if (isFile(candidatePath)) return candidatePath;
|
|
628
|
+
for (const extension of EXPO_PLUGIN_RESOLVABLE_EXTENSIONS) {
|
|
629
|
+
const candidatePathWithExtension = `${candidatePath}${extension}`;
|
|
630
|
+
if (isFile(candidatePathWithExtension)) return candidatePathWithExtension;
|
|
631
|
+
}
|
|
632
|
+
for (const extension of EXPO_PLUGIN_RESOLVABLE_EXTENSIONS) {
|
|
633
|
+
const indexCandidatePath = join(candidatePath, `index${extension}`);
|
|
634
|
+
if (isFile(indexCandidatePath)) return indexCandidatePath;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
const addExpoPluginEntry = (entries, packageNamePlugins, rootDirectory, configDirectory, pluginPath) => {
|
|
638
|
+
if (!isLocalExpoPluginPath(pluginPath)) {
|
|
639
|
+
packageNamePlugins.add(pluginPath);
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const resolvedPath = resolveExpoPluginPath(configDirectory, pluginPath);
|
|
643
|
+
if (!resolvedPath) return;
|
|
644
|
+
const relativePath = relative(rootDirectory, resolvedPath);
|
|
645
|
+
if (relativePath !== "" && (relativePath.startsWith("..") || isAbsolute(relativePath))) return;
|
|
646
|
+
entries.add(resolvedPath);
|
|
647
|
+
};
|
|
648
|
+
const getPropertyName = (name) => {
|
|
649
|
+
if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) return name.text;
|
|
650
|
+
};
|
|
651
|
+
const unwrapExpression = (expression) => {
|
|
652
|
+
let currentExpression = expression;
|
|
653
|
+
while (ts.isParenthesizedExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
654
|
+
return currentExpression;
|
|
655
|
+
};
|
|
656
|
+
const collectExpoPluginPathsFromArray = (array, entries, packageNamePlugins, rootDirectory, configDirectory) => {
|
|
657
|
+
for (const element of array.elements) {
|
|
658
|
+
if (ts.isStringLiteral(element) || ts.isNoSubstitutionTemplateLiteral(element)) {
|
|
659
|
+
addExpoPluginEntry(entries, packageNamePlugins, rootDirectory, configDirectory, element.text);
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
if (ts.isArrayLiteralExpression(element)) {
|
|
663
|
+
const [pluginName] = element.elements;
|
|
664
|
+
if (pluginName && (ts.isStringLiteral(pluginName) || ts.isNoSubstitutionTemplateLiteral(pluginName))) addExpoPluginEntry(entries, packageNamePlugins, rootDirectory, configDirectory, pluginName.text);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
const collectExpoPluginPathsFromConfigObject = (objectLiteral, entries, packageNamePlugins, rootDirectory, configDirectory) => {
|
|
669
|
+
for (const property of objectLiteral.properties) {
|
|
670
|
+
if (!ts.isPropertyAssignment(property)) continue;
|
|
671
|
+
const propertyName = getPropertyName(property.name);
|
|
672
|
+
if (propertyName === "plugins" && ts.isArrayLiteralExpression(property.initializer)) collectExpoPluginPathsFromArray(property.initializer, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
673
|
+
if (propertyName === "expo" && ts.isObjectLiteralExpression(property.initializer)) collectExpoPluginPathsFromConfigObject(property.initializer, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
const collectReturnedExpoConfigPluginPaths = (body, entries, packageNamePlugins, rootDirectory, configDirectory) => {
|
|
677
|
+
if (!ts.isBlock(body)) {
|
|
678
|
+
const expression = unwrapExpression(body);
|
|
679
|
+
if (ts.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
const visit = (node) => {
|
|
683
|
+
if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) return;
|
|
684
|
+
if (ts.isReturnStatement(node) && node.expression) {
|
|
685
|
+
const expression = unwrapExpression(node.expression);
|
|
686
|
+
if (ts.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
ts.forEachChild(node, visit);
|
|
690
|
+
};
|
|
691
|
+
visit(body);
|
|
692
|
+
};
|
|
693
|
+
const collectExpoPluginPathsFromConfigExpression = (expression, entries, packageNamePlugins, rootDirectory, configDirectory, bindings, seenIdentifiers = /* @__PURE__ */ new Set()) => {
|
|
694
|
+
const configExpression = unwrapExpression(expression);
|
|
695
|
+
if (ts.isObjectLiteralExpression(configExpression)) {
|
|
696
|
+
collectExpoPluginPathsFromConfigObject(configExpression, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
if (ts.isIdentifier(configExpression)) {
|
|
700
|
+
if (seenIdentifiers.has(configExpression.text)) return;
|
|
701
|
+
seenIdentifiers.add(configExpression.text);
|
|
702
|
+
const boundExpression = bindings.expressions.get(configExpression.text);
|
|
703
|
+
if (boundExpression) {
|
|
704
|
+
collectExpoPluginPathsFromConfigExpression(boundExpression, entries, packageNamePlugins, rootDirectory, configDirectory, bindings, seenIdentifiers);
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
const boundFunction = bindings.functions.get(configExpression.text);
|
|
708
|
+
if (boundFunction?.body) collectReturnedExpoConfigPluginPaths(boundFunction.body, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
if (ts.isArrowFunction(configExpression)) {
|
|
712
|
+
collectReturnedExpoConfigPluginPaths(configExpression.body, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
if (ts.isFunctionExpression(configExpression) && configExpression.body) collectReturnedExpoConfigPluginPaths(configExpression.body, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
716
|
+
};
|
|
717
|
+
const hasDefaultExportModifier = (node) => Boolean(ts.canHaveModifiers(node) && ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword));
|
|
718
|
+
const isModuleExportsAssignmentTarget = (node) => ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "module" && node.name.text === "exports";
|
|
719
|
+
const collectStaticConfigBindings = (sourceFile) => {
|
|
720
|
+
const expressions = /* @__PURE__ */ new Map();
|
|
721
|
+
const functions = /* @__PURE__ */ new Map();
|
|
722
|
+
for (const statement of sourceFile.statements) {
|
|
723
|
+
if (ts.isVariableStatement(statement)) {
|
|
724
|
+
for (const declaration of statement.declarationList.declarations) if (ts.isIdentifier(declaration.name) && declaration.initializer) expressions.set(declaration.name.text, declaration.initializer);
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
if (ts.isFunctionDeclaration(statement) && statement.name) functions.set(statement.name.text, statement);
|
|
728
|
+
}
|
|
729
|
+
return {
|
|
730
|
+
expressions,
|
|
731
|
+
functions
|
|
732
|
+
};
|
|
733
|
+
};
|
|
734
|
+
const collectExpoPluginPathsFromAppConfig = (configPath, entries, packageNamePlugins, rootDirectory) => {
|
|
735
|
+
const extension = extname(configPath);
|
|
736
|
+
const sourceFile = ts.createSourceFile(configPath, readFileSync(configPath, "utf8"), ts.ScriptTarget.Latest, true, extension === ".ts" || extension === ".mts" || extension === ".cts" ? ts.ScriptKind.TS : ts.ScriptKind.JS);
|
|
737
|
+
const configDirectory = dirname(configPath);
|
|
738
|
+
const bindings = collectStaticConfigBindings(sourceFile);
|
|
739
|
+
const visit = (node) => {
|
|
740
|
+
if (ts.isExportAssignment(node)) {
|
|
741
|
+
collectExpoPluginPathsFromConfigExpression(node.expression, entries, packageNamePlugins, rootDirectory, configDirectory, bindings);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
if (ts.isFunctionDeclaration(node) && hasDefaultExportModifier(node) && node.body) {
|
|
745
|
+
collectReturnedExpoConfigPluginPaths(node.body, entries, packageNamePlugins, rootDirectory, configDirectory);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExportsAssignmentTarget(node.left)) {
|
|
749
|
+
collectExpoPluginPathsFromConfigExpression(node.right, entries, packageNamePlugins, rootDirectory, configDirectory, bindings);
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
ts.forEachChild(node, visit);
|
|
753
|
+
};
|
|
754
|
+
visit(sourceFile);
|
|
755
|
+
};
|
|
756
|
+
const collectPluginPathsFromJsonValue = (value) => {
|
|
757
|
+
if (!Array.isArray(value)) return [];
|
|
758
|
+
const pluginPaths = [];
|
|
759
|
+
for (const plugin of value) {
|
|
760
|
+
if (typeof plugin === "string") {
|
|
761
|
+
pluginPaths.push(plugin);
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
if (Array.isArray(plugin) && typeof plugin[0] === "string") pluginPaths.push(plugin[0]);
|
|
765
|
+
}
|
|
766
|
+
return pluginPaths;
|
|
767
|
+
};
|
|
768
|
+
const collectExpoPluginPathsFromAppJson = (configPath, entries, packageNamePlugins, rootDirectory) => {
|
|
769
|
+
const parsedJson = JSON.parse(readFileSync(configPath, "utf8"));
|
|
770
|
+
const configDirectory = dirname(configPath);
|
|
771
|
+
if (!isRecord(parsedJson)) return;
|
|
772
|
+
const expoConfig = parsedJson.expo;
|
|
773
|
+
const expoPluginPaths = isRecord(expoConfig) ? collectPluginPathsFromJsonValue(expoConfig.plugins) : [];
|
|
774
|
+
for (const pluginPath of [...expoPluginPaths, ...collectPluginPathsFromJsonValue(parsedJson.plugins)]) addExpoPluginEntry(entries, packageNamePlugins, rootDirectory, configDirectory, pluginPath);
|
|
775
|
+
};
|
|
776
|
+
const collectExpoPluginPathsFromConfig = (configPath, entries, packageNamePlugins, rootDirectory) => {
|
|
777
|
+
try {
|
|
778
|
+
if (basename(configPath) === "app.json") {
|
|
779
|
+
collectExpoPluginPathsFromAppJson(configPath, entries, packageNamePlugins, rootDirectory);
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
collectExpoPluginPathsFromAppConfig(configPath, entries, packageNamePlugins, rootDirectory);
|
|
783
|
+
} catch {}
|
|
784
|
+
};
|
|
785
|
+
const extractExpoConfigPluginEntries = (directory, dependencies, rootDirectory = directory, includeNestedConfigs = true) => {
|
|
786
|
+
if (!isExpoOrReactNativeWorkspace(dependencies)) return {
|
|
787
|
+
filePaths: [],
|
|
788
|
+
packageNames: []
|
|
789
|
+
};
|
|
790
|
+
const entries = /* @__PURE__ */ new Set();
|
|
791
|
+
const packageNamePlugins = /* @__PURE__ */ new Set();
|
|
792
|
+
const configPaths = fg.sync(includeNestedConfigs ? NESTED_EXPO_CONFIG_FILE_GLOBS : EXPO_CONFIG_FILE_GLOBS, {
|
|
793
|
+
cwd: directory,
|
|
794
|
+
absolute: true,
|
|
795
|
+
onlyFiles: true,
|
|
796
|
+
ignore: [
|
|
797
|
+
"**/node_modules/**",
|
|
798
|
+
"**/dist/**",
|
|
799
|
+
"**/build/**"
|
|
800
|
+
],
|
|
801
|
+
deep: 6
|
|
802
|
+
});
|
|
803
|
+
for (const configPath of configPaths) collectExpoPluginPathsFromConfig(configPath, entries, packageNamePlugins, rootDirectory);
|
|
804
|
+
return {
|
|
805
|
+
filePaths: [...entries],
|
|
806
|
+
packageNames: [...packageNamePlugins]
|
|
807
|
+
};
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
//#endregion
|
|
811
|
+
//#region src/resolver/source-path.ts
|
|
812
|
+
const SOURCE_EXTENSIONS$1 = [
|
|
813
|
+
".ts",
|
|
814
|
+
".tsx",
|
|
815
|
+
".js",
|
|
816
|
+
".jsx",
|
|
817
|
+
".mts",
|
|
818
|
+
".mjs"
|
|
819
|
+
];
|
|
820
|
+
const OUTPUT_DIR_PREFIXES = [
|
|
821
|
+
"dist/esm/",
|
|
822
|
+
"dist/cjs/",
|
|
823
|
+
"dist/es/",
|
|
824
|
+
"dist/lib/",
|
|
825
|
+
"dist/",
|
|
826
|
+
"build/",
|
|
827
|
+
"lib/",
|
|
828
|
+
"lib-dist/",
|
|
829
|
+
"esm/",
|
|
830
|
+
"cjs/",
|
|
831
|
+
"out/"
|
|
832
|
+
];
|
|
833
|
+
const DIST_WILDCARD_PATTERN = /^dist-[^/]+\//;
|
|
834
|
+
const SOURCE_INDEX_FALLBACK_STEMS = ["src/index", "src/main"];
|
|
835
|
+
const matchesOutputDirectory = (relativePath) => OUTPUT_DIR_PREFIXES.some((prefix) => relativePath.startsWith(prefix)) || DIST_WILDCARD_PATTERN.test(relativePath);
|
|
836
|
+
const resolveSourcePath = (distPath, directory) => {
|
|
837
|
+
if (existsSync(distPath)) return distPath;
|
|
838
|
+
const relativeToDist = relative(directory, distPath);
|
|
839
|
+
const sourceReplacements = ["src/"];
|
|
840
|
+
const allPrefixes = [...OUTPUT_DIR_PREFIXES];
|
|
841
|
+
const wildcardMatch = DIST_WILDCARD_PATTERN.exec(relativeToDist);
|
|
842
|
+
if (wildcardMatch) allPrefixes.push(wildcardMatch[0]);
|
|
843
|
+
const sourceVariants = allPrefixes.flatMap((prefix) => sourceReplacements.map((replacement) => relativeToDist.replace(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`), replacement))).filter((variant) => variant !== relativeToDist);
|
|
844
|
+
for (const variant of sourceVariants) {
|
|
845
|
+
const withoutExtension = variant.replace(/\.[^.]+$/, "");
|
|
846
|
+
for (const sourceExtension of SOURCE_EXTENSIONS$1) {
|
|
847
|
+
const sourceCandidate = resolve(directory, withoutExtension + sourceExtension);
|
|
848
|
+
if (existsSync(sourceCandidate)) return sourceCandidate;
|
|
849
|
+
}
|
|
850
|
+
const indexPrefixedCandidate = resolveWithIndexPrefix(withoutExtension, directory);
|
|
851
|
+
if (indexPrefixedCandidate) return indexPrefixedCandidate;
|
|
852
|
+
}
|
|
853
|
+
if (matchesOutputDirectory(relativeToDist)) for (const stem of SOURCE_INDEX_FALLBACK_STEMS) for (const sourceExtension of SOURCE_EXTENSIONS$1) {
|
|
854
|
+
const fallbackCandidate = resolve(directory, stem + sourceExtension);
|
|
855
|
+
if (existsSync(fallbackCandidate)) return fallbackCandidate;
|
|
856
|
+
}
|
|
857
|
+
const withoutExtension = relativeToDist.replace(/\.[cm]?js$/, "");
|
|
858
|
+
if (withoutExtension !== relativeToDist) {
|
|
859
|
+
for (const sourceExtension of SOURCE_EXTENSIONS$1) {
|
|
860
|
+
const directSourceCandidate = resolve(directory, withoutExtension + sourceExtension);
|
|
861
|
+
if (existsSync(directSourceCandidate)) return directSourceCandidate;
|
|
862
|
+
}
|
|
863
|
+
const indexCandidate = resolve(directory, withoutExtension, "index.ts");
|
|
864
|
+
if (existsSync(indexCandidate)) return indexCandidate;
|
|
865
|
+
const indexPrefixedCandidate = resolveWithIndexPrefix(withoutExtension, directory);
|
|
866
|
+
if (indexPrefixedCandidate) return indexPrefixedCandidate;
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
const resolveWithIndexPrefix = (stemPath, directory) => {
|
|
870
|
+
const indexPrefixedStem = `${dirname(stemPath)}/index.${basename(stemPath)}`;
|
|
871
|
+
for (const sourceExtension of SOURCE_EXTENSIONS$1) {
|
|
872
|
+
const candidate = resolve(directory, indexPrefixedStem + sourceExtension);
|
|
873
|
+
if (existsSync(candidate)) return candidate;
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
//#endregion
|
|
878
|
+
//#region src/utils/find-monorepo-root.ts
|
|
879
|
+
const MAX_MONOREPO_WALK_DEPTH = 5;
|
|
880
|
+
const findMonorepoRoot = (rootDir) => {
|
|
881
|
+
let currentDirectory = resolve(rootDir);
|
|
882
|
+
let walkedDepth = 0;
|
|
883
|
+
while (walkedDepth < MAX_MONOREPO_WALK_DEPTH) {
|
|
884
|
+
const parentDirectory = dirname(currentDirectory);
|
|
885
|
+
if (parentDirectory === currentDirectory) break;
|
|
886
|
+
currentDirectory = parentDirectory;
|
|
887
|
+
walkedDepth++;
|
|
888
|
+
if (existsSync(join(currentDirectory, ".git"))) {
|
|
889
|
+
for (const marker of MONOREPO_ROOT_MARKERS) if (existsSync(join(currentDirectory, marker))) return currentDirectory;
|
|
890
|
+
const packageJsonPath = join(currentDirectory, "package.json");
|
|
891
|
+
if (existsSync(packageJsonPath)) try {
|
|
892
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
893
|
+
if (JSON.parse(content).workspaces) return currentDirectory;
|
|
894
|
+
} catch {}
|
|
895
|
+
for (const lockfile of LOCKFILE_MARKERS) if (existsSync(join(currentDirectory, lockfile))) return currentDirectory;
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
for (const marker of MONOREPO_ROOT_MARKERS) if (existsSync(join(currentDirectory, marker))) return currentDirectory;
|
|
899
|
+
const packageJsonPath = join(currentDirectory, "package.json");
|
|
900
|
+
if (existsSync(packageJsonPath)) try {
|
|
901
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
902
|
+
if (JSON.parse(content).workspaces) return currentDirectory;
|
|
903
|
+
} catch {
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
for (const lockfile of LOCKFILE_MARKERS) if (existsSync(join(currentDirectory, lockfile))) return currentDirectory;
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
//#endregion
|
|
911
|
+
//#region src/utils/resolve-entry-with-extensions.ts
|
|
912
|
+
const RESOLVABLE_EXTENSIONS = [
|
|
913
|
+
".ts",
|
|
914
|
+
".tsx",
|
|
915
|
+
".js",
|
|
916
|
+
".jsx",
|
|
917
|
+
".mjs",
|
|
918
|
+
".mts",
|
|
919
|
+
".cjs",
|
|
920
|
+
".cts"
|
|
921
|
+
];
|
|
922
|
+
const resolveEntryWithExtensions = (basePath) => {
|
|
923
|
+
if (existsSync(basePath)) return basePath;
|
|
924
|
+
for (const extension of RESOLVABLE_EXTENSIONS) {
|
|
925
|
+
const withExtension = basePath + extension;
|
|
926
|
+
if (existsSync(withExtension)) return withExtension;
|
|
927
|
+
}
|
|
928
|
+
for (const extension of RESOLVABLE_EXTENSIONS) {
|
|
929
|
+
const indexCandidate = join(basePath, `index${extension}`);
|
|
930
|
+
if (existsSync(indexCandidate)) return indexCandidate;
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
const resolveEntryPathWithExtensions = (entryPath, rootDirectory) => {
|
|
934
|
+
return resolveEntryWithExtensions(resolve(rootDirectory, entryPath));
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
//#endregion
|
|
938
|
+
//#region src/collect/config-string-entries.ts
|
|
939
|
+
const CONFIG_STRING_ENTRY_GLOBS = [
|
|
940
|
+
"webpack.config.{js,ts,mjs,cjs}",
|
|
941
|
+
"**/webpack*.config.{js,ts,mjs,cjs,babel.js}",
|
|
942
|
+
"**/configs/webpack.config.{js,ts,mjs,cjs,babel.js}",
|
|
943
|
+
"**/configs/webpack*.config.{js,ts,mjs,cjs,babel.js}",
|
|
944
|
+
"jest.config.{js,ts,mjs,cjs,cts}",
|
|
945
|
+
"**/jest.config.{js,ts,mjs,cjs,cts}",
|
|
946
|
+
"vitest.config.{js,ts,mjs,mts}",
|
|
947
|
+
"**/vitest.config.{js,ts,mjs,mts}",
|
|
948
|
+
"**/vitest.*.config.{js,ts,mjs,mts}",
|
|
949
|
+
"vite.config.{js,ts,mjs,mts}",
|
|
950
|
+
"tailwind.config.{js,ts,cjs,mjs}",
|
|
951
|
+
"**/tailwind.config.{js,ts,cjs,mjs}",
|
|
952
|
+
"electron.vite.config.{js,ts,mjs}",
|
|
953
|
+
"electron-builder.config.{js,ts,cjs}",
|
|
954
|
+
"esbuild*.ts",
|
|
955
|
+
"**/esbuild.entrypoints.ts",
|
|
956
|
+
"metro.config.{js,ts}",
|
|
957
|
+
"playwright.config.{js,ts}",
|
|
958
|
+
"cypress.config.{js,ts}",
|
|
959
|
+
"rollup.config.{js,ts,mjs,cjs}",
|
|
960
|
+
"rollup.*.config.js",
|
|
961
|
+
"**/.erb/configs/webpack*.config.{js,ts}",
|
|
962
|
+
"**/.erb/configs/webpack.config.*.{js,ts}",
|
|
963
|
+
"**/astro-tina-directive/register.js",
|
|
964
|
+
"rspack.config.{js,ts,mjs,cjs}",
|
|
965
|
+
"rsbuild.config.{js,ts,mjs,cjs}",
|
|
966
|
+
"**/scripts/build.ts",
|
|
967
|
+
"**/scripts/utils/createJestConfig.js"
|
|
968
|
+
];
|
|
969
|
+
const CONFIG_RELATIVE_PATH_PATTERN = /['"`]((\.{1,2}\/|\.\.\/)[^'"`\n]+?|\.\/[^'"`\n]+?)['"`]/g;
|
|
970
|
+
const JEST_ROOT_DIR_PATH_PATTERN = /<rootDir>\/([^'"`\n]+?)(?:['"`]|$)/g;
|
|
971
|
+
const RESOLVE_CALL_PATH_PATTERN = /resolve\s*\(\s*['"`]([^'"`\n]+?)['"`]\s*\)/g;
|
|
972
|
+
const PATH_JOIN_STRING_PATTERN = /path\.(?:join|resolve)\(\s*[^,]+,\s*['"`]([^'"`\n]+?)['"`]/g;
|
|
973
|
+
const ENTRY_POINTS_STRING_PATTERN = /entryPoints:\s*\[\s*['"`]([^'"`\n]+?)['"`]/g;
|
|
974
|
+
const ADD_PREAMBLE_PATTERN = /addPreamble\s*\(\s*['"`]([^'"`\n]+?)['"`]\s*\)/g;
|
|
975
|
+
const ROLLUP_INPUT_PATTERN = /\binput\s*:\s*['"`]([^'"`\n]+?)['"`]/g;
|
|
976
|
+
const VITEST_ENVIRONMENT_PATTERN = /environment\s*:\s*['"`](\.\/[^'"`\n]+?)['"`]/g;
|
|
977
|
+
const ASTRO_ENTRYPOINT_PATTERN = /entrypoint\s*:\s*['"`](\.\/[^'"`\n]+?)['"`]/g;
|
|
978
|
+
const WEBPACK_PATH_JOIN_ENTRY_PATTERN = /path\.join\(\s*[^,]+,\s*['"`]([^'"`\n]+?)['"`]\s*\)/g;
|
|
979
|
+
const WEBPACK_RENDERER_PATH_JOIN_PATTERN = /path\.join\(\s*webpackPaths\.srcRendererPath\s*,\s*['"`]([^'"`\n]+?)['"`]\s*\)/g;
|
|
980
|
+
const WEBPACK_MAIN_PATH_JOIN_PATTERN = /path\.join\(\s*webpackPaths\.srcMainPath\s*,\s*['"`]([^'"`\n]+?)['"`]\s*\)/g;
|
|
981
|
+
const BARE_CONFIG_PATH_PATTERN = /['"`](config\/[^'"`\n]+?)['"`]/g;
|
|
982
|
+
const stripModuleImportStatements = (content) => content.replace(/^\s*import\s+(?:type\s+)?[\s\S]*?\sfrom\s+['"`][^'"`\n]+['"`]\s*;?\s*$/gm, "").replace(/^\s*import\s+['"`][^'"`\n]+['"`]\s*;?\s*$/gm, "");
|
|
983
|
+
const shouldSkipConfigPath = (rawPath) => {
|
|
984
|
+
if (rawPath.includes("*") || rawPath.includes("?")) return true;
|
|
985
|
+
if (rawPath.endsWith(".json") && !rawPath.includes("/src/")) return true;
|
|
986
|
+
if (rawPath.startsWith("node:")) return true;
|
|
987
|
+
if (rawPath.startsWith("@")) return true;
|
|
988
|
+
return false;
|
|
989
|
+
};
|
|
990
|
+
const addResolvedConfigPath = (rawPath, configDirectory, projectRootDirectory, entries) => {
|
|
991
|
+
if (shouldSkipConfigPath(rawPath)) return;
|
|
992
|
+
const resolvedEntry = resolveEntryWithExtensions(resolve(rawPath.startsWith(".") ? configDirectory : projectRootDirectory, rawPath.startsWith(".") ? rawPath : `./${rawPath}`));
|
|
993
|
+
if (resolvedEntry) {
|
|
994
|
+
entries.add(resolvedEntry);
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
if (rawPath.startsWith(".")) {
|
|
998
|
+
const projectRootResolvedEntry = resolveEntryWithExtensions(resolve(projectRootDirectory, rawPath));
|
|
999
|
+
if (projectRootResolvedEntry) entries.add(projectRootResolvedEntry);
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
const collectResolvedPathsFromStrings = (content, configDirectory, projectRootDirectory, entries) => {
|
|
1003
|
+
const contentWithoutImports = stripModuleImportStatements(content);
|
|
1004
|
+
const patterns = [
|
|
1005
|
+
CONFIG_RELATIVE_PATH_PATTERN,
|
|
1006
|
+
RESOLVE_CALL_PATH_PATTERN,
|
|
1007
|
+
PATH_JOIN_STRING_PATTERN,
|
|
1008
|
+
ENTRY_POINTS_STRING_PATTERN,
|
|
1009
|
+
ADD_PREAMBLE_PATTERN,
|
|
1010
|
+
ROLLUP_INPUT_PATTERN,
|
|
1011
|
+
VITEST_ENVIRONMENT_PATTERN,
|
|
1012
|
+
ASTRO_ENTRYPOINT_PATTERN,
|
|
1013
|
+
WEBPACK_PATH_JOIN_ENTRY_PATTERN,
|
|
1014
|
+
BARE_CONFIG_PATH_PATTERN
|
|
1015
|
+
];
|
|
1016
|
+
for (const pattern of patterns) {
|
|
1017
|
+
let pathMatch;
|
|
1018
|
+
pattern.lastIndex = 0;
|
|
1019
|
+
while ((pathMatch = pattern.exec(contentWithoutImports)) !== null) addResolvedConfigPath(pathMatch[1], configDirectory, projectRootDirectory, entries);
|
|
1020
|
+
}
|
|
1021
|
+
let rendererEntryMatch;
|
|
1022
|
+
WEBPACK_RENDERER_PATH_JOIN_PATTERN.lastIndex = 0;
|
|
1023
|
+
while ((rendererEntryMatch = WEBPACK_RENDERER_PATH_JOIN_PATTERN.exec(contentWithoutImports)) !== null) addResolvedConfigPath(`src/renderer/${rendererEntryMatch[1]}`, configDirectory, projectRootDirectory, entries);
|
|
1024
|
+
let mainEntryMatch;
|
|
1025
|
+
WEBPACK_MAIN_PATH_JOIN_PATTERN.lastIndex = 0;
|
|
1026
|
+
while ((mainEntryMatch = WEBPACK_MAIN_PATH_JOIN_PATTERN.exec(contentWithoutImports)) !== null) addResolvedConfigPath(`src/main/${mainEntryMatch[1]}`, configDirectory, projectRootDirectory, entries);
|
|
1027
|
+
let rootDirMatch;
|
|
1028
|
+
JEST_ROOT_DIR_PATH_PATTERN.lastIndex = 0;
|
|
1029
|
+
while ((rootDirMatch = JEST_ROOT_DIR_PATH_PATTERN.exec(content)) !== null) addResolvedConfigPath(rootDirMatch[1], configDirectory, projectRootDirectory, entries);
|
|
1030
|
+
};
|
|
1031
|
+
const extractConfigStringReferencedEntries = (directory) => {
|
|
1032
|
+
const entries = /* @__PURE__ */ new Set();
|
|
1033
|
+
const configPaths = fg.sync(CONFIG_STRING_ENTRY_GLOBS, {
|
|
1034
|
+
cwd: directory,
|
|
1035
|
+
absolute: true,
|
|
1036
|
+
onlyFiles: true,
|
|
1037
|
+
ignore: [
|
|
1038
|
+
"**/node_modules/**",
|
|
1039
|
+
"**/dist/**",
|
|
1040
|
+
"**/build/**"
|
|
1041
|
+
],
|
|
1042
|
+
deep: 6
|
|
1043
|
+
});
|
|
1044
|
+
for (const configPath of configPaths) try {
|
|
1045
|
+
collectResolvedPathsFromStrings(readFileSync(configPath, "utf-8"), dirname(configPath), directory, entries);
|
|
1046
|
+
} catch {
|
|
1047
|
+
continue;
|
|
1048
|
+
}
|
|
1049
|
+
return [...entries];
|
|
1050
|
+
};
|
|
1051
|
+
|
|
1052
|
+
//#endregion
|
|
1053
|
+
//#region src/collect/sections-module-entries.ts
|
|
1054
|
+
const SECTIONS_FILE_GLOBS = ["sections.js", "**/sections.js"];
|
|
1055
|
+
const CALYPSO_MODULE_PATTERN = /module:\s*['"]calypso\/([^'"]+)['"]/g;
|
|
1056
|
+
const SECTION_BOOTSTRAP_SUFFIXES = [
|
|
1057
|
+
"",
|
|
1058
|
+
"/index",
|
|
1059
|
+
"/index.js",
|
|
1060
|
+
"/index.jsx",
|
|
1061
|
+
"/index.ts",
|
|
1062
|
+
"/index.tsx",
|
|
1063
|
+
"/main",
|
|
1064
|
+
"/controller",
|
|
1065
|
+
"/controller.js",
|
|
1066
|
+
"/controller.jsx"
|
|
1067
|
+
];
|
|
1068
|
+
const addSectionModuleEntry = (modulePath, projectRootDirectory, entries) => {
|
|
1069
|
+
const moduleBasePath = resolve(projectRootDirectory, modulePath.replace(/^calypso\//, ""));
|
|
1070
|
+
for (const suffix of SECTION_BOOTSTRAP_SUFFIXES) {
|
|
1071
|
+
const resolvedEntry = resolveEntryWithExtensions(suffix ? `${moduleBasePath}${suffix}` : moduleBasePath);
|
|
1072
|
+
if (resolvedEntry) entries.add(resolvedEntry);
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
const extractSectionsModuleEntries = (directory) => {
|
|
1076
|
+
const entries = /* @__PURE__ */ new Set();
|
|
1077
|
+
const sectionsFilePaths = fg.sync(SECTIONS_FILE_GLOBS, {
|
|
1078
|
+
cwd: directory,
|
|
1079
|
+
absolute: true,
|
|
1080
|
+
onlyFiles: true,
|
|
1081
|
+
ignore: [
|
|
1082
|
+
"**/node_modules/**",
|
|
1083
|
+
"**/dist/**",
|
|
1084
|
+
"**/build/**"
|
|
1085
|
+
],
|
|
1086
|
+
deep: 4
|
|
1087
|
+
});
|
|
1088
|
+
for (const sectionsFilePath of sectionsFilePaths) {
|
|
1089
|
+
if (!sectionsFilePath.endsWith("/client/sections.js")) continue;
|
|
1090
|
+
try {
|
|
1091
|
+
const content = readFileSync(sectionsFilePath, "utf-8");
|
|
1092
|
+
let moduleMatch;
|
|
1093
|
+
CALYPSO_MODULE_PATTERN.lastIndex = 0;
|
|
1094
|
+
while ((moduleMatch = CALYPSO_MODULE_PATTERN.exec(content)) !== null) addSectionModuleEntry(moduleMatch[1], directory, entries);
|
|
1095
|
+
} catch {
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
return [...entries];
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
//#endregion
|
|
1103
|
+
//#region src/utils/to-posix-path.ts
|
|
1104
|
+
const toPosixPath = (filePath) => filePath.replace(/\\/g, "/");
|
|
1105
|
+
|
|
1106
|
+
//#endregion
|
|
1107
|
+
//#region src/resolver/resolve.ts
|
|
1108
|
+
const fileExistsCache = /* @__PURE__ */ new Map();
|
|
1109
|
+
const pathExistsCache = /* @__PURE__ */ new Map();
|
|
1110
|
+
const fileContentCache = /* @__PURE__ */ new Map();
|
|
1111
|
+
const cachedReadFileSync = (filePath) => {
|
|
1112
|
+
const cached = fileContentCache.get(filePath);
|
|
1113
|
+
if (cached !== void 0) return cached;
|
|
1114
|
+
const content = readFileSync(filePath, "utf-8");
|
|
1115
|
+
fileContentCache.set(filePath, content);
|
|
1116
|
+
return content;
|
|
1117
|
+
};
|
|
1118
|
+
const cachedExistsSync = (targetPath) => {
|
|
1119
|
+
const cached = pathExistsCache.get(targetPath);
|
|
1120
|
+
if (cached !== void 0) return cached;
|
|
1121
|
+
const result = existsSync(targetPath);
|
|
1122
|
+
pathExistsCache.set(targetPath, result);
|
|
1123
|
+
return result;
|
|
1124
|
+
};
|
|
1125
|
+
const existsAsFile = (filePath) => {
|
|
1126
|
+
const cached = fileExistsCache.get(filePath);
|
|
1127
|
+
if (cached !== void 0) return cached;
|
|
1128
|
+
try {
|
|
1129
|
+
const result = cachedExistsSync(filePath) && statSync(filePath).isFile();
|
|
1130
|
+
fileExistsCache.set(filePath, result);
|
|
1131
|
+
return result;
|
|
1132
|
+
} catch {
|
|
1133
|
+
fileExistsCache.set(filePath, false);
|
|
1134
|
+
return false;
|
|
1135
|
+
}
|
|
1136
|
+
};
|
|
1137
|
+
const trySourceFallback = (resolvedPath) => {
|
|
1138
|
+
const segments = resolvedPath.split(sep);
|
|
1139
|
+
const isOutputDirectory = (segment) => OUTPUT_DIRECTORIES.some((outputDirectory) => segment === outputDirectory || segment.startsWith(`${outputDirectory}-`));
|
|
1140
|
+
let lastOutputPosition = -1;
|
|
1141
|
+
for (let index = segments.length - 1; index >= 0; index--) if (isOutputDirectory(segments[index])) {
|
|
1142
|
+
lastOutputPosition = index;
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
if (lastOutputPosition === -1) return void 0;
|
|
1146
|
+
let firstOutputPosition = lastOutputPosition;
|
|
1147
|
+
while (firstOutputPosition > 0 && isOutputDirectory(segments[firstOutputPosition - 1])) firstOutputPosition--;
|
|
1148
|
+
const prefix = segments.slice(0, firstOutputPosition).join(sep);
|
|
1149
|
+
const suffix = segments.slice(lastOutputPosition + 1).join(sep);
|
|
1150
|
+
if (!suffix) return void 0;
|
|
1151
|
+
const fileExtension = extname(basename(suffix));
|
|
1152
|
+
const stemmedSuffix = fileExtension ? suffix.slice(0, suffix.length - fileExtension.length) : suffix;
|
|
1153
|
+
for (const sourceExtension of SOURCE_EXTENSIONS$3) {
|
|
1154
|
+
const sourceCandidate = join(prefix, "src", `${stemmedSuffix}.${sourceExtension}`);
|
|
1155
|
+
if (existsAsFile(sourceCandidate)) return sourceCandidate;
|
|
1156
|
+
}
|
|
1157
|
+
};
|
|
1158
|
+
const resolvePathWithExtensionFallback = (candidatePath) => {
|
|
1159
|
+
if (existsAsFile(candidatePath)) return candidatePath;
|
|
1160
|
+
for (const extension of RESOLVER_EXTENSIONS) {
|
|
1161
|
+
const withExtension = candidatePath + extension;
|
|
1162
|
+
if (existsAsFile(withExtension)) return withExtension;
|
|
1163
|
+
}
|
|
1164
|
+
for (const extension of RESOLVER_EXTENSIONS) {
|
|
1165
|
+
const indexCandidate = join(candidatePath, `index${extension}`);
|
|
1166
|
+
if (existsAsFile(indexCandidate)) return indexCandidate;
|
|
1167
|
+
}
|
|
1168
|
+
return candidatePath;
|
|
1169
|
+
};
|
|
1170
|
+
const isExportConditionRecord = (value) => typeof value === "object" && value !== null;
|
|
1171
|
+
const EXPORT_CONDITION_PRIORITY = [
|
|
1172
|
+
"import",
|
|
1173
|
+
"require",
|
|
1174
|
+
"default",
|
|
1175
|
+
"types"
|
|
1176
|
+
];
|
|
1177
|
+
const resolveExportConditionTarget = (exportValue) => {
|
|
1178
|
+
if (typeof exportValue === "string") return exportValue;
|
|
1179
|
+
if (!isExportConditionRecord(exportValue)) return void 0;
|
|
1180
|
+
for (const condition of EXPORT_CONDITION_PRIORITY) {
|
|
1181
|
+
const conditionTarget = resolveExportConditionTarget(exportValue[condition]);
|
|
1182
|
+
if (conditionTarget) return conditionTarget;
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
const resolveWorkspaceSubpath = (workspaceDirectory, subpath) => {
|
|
1186
|
+
const workspacePackageJsonPath = join(workspaceDirectory, "package.json");
|
|
1187
|
+
try {
|
|
1188
|
+
const workspacePackageContent = cachedReadFileSync(workspacePackageJsonPath);
|
|
1189
|
+
const workspacePackageJson = JSON.parse(workspacePackageContent);
|
|
1190
|
+
let resolvedEntryPath;
|
|
1191
|
+
if (subpath && workspacePackageJson.exports) {
|
|
1192
|
+
const exportKey = `./${subpath}`;
|
|
1193
|
+
const exactExportTarget = resolveExportConditionTarget(workspacePackageJson.exports[exportKey]);
|
|
1194
|
+
if (exactExportTarget) {
|
|
1195
|
+
const candidatePath = resolvePathWithExtensionFallback(resolve(workspaceDirectory, exactExportTarget));
|
|
1196
|
+
resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
|
|
1197
|
+
}
|
|
1198
|
+
if (!resolvedEntryPath) for (const [wildcardPattern, wildcardTarget] of Object.entries(workspacePackageJson.exports)) {
|
|
1199
|
+
if (!wildcardPattern.includes("*")) continue;
|
|
1200
|
+
const wildcardTargetValue = resolveExportConditionTarget(wildcardTarget);
|
|
1201
|
+
if (!wildcardTargetValue) continue;
|
|
1202
|
+
const wildcardPrefix = wildcardPattern.slice(0, wildcardPattern.indexOf("*"));
|
|
1203
|
+
const wildcardSuffix = wildcardPattern.slice(wildcardPattern.indexOf("*") + 1);
|
|
1204
|
+
if (exportKey.startsWith(wildcardPrefix) && exportKey.endsWith(wildcardSuffix)) {
|
|
1205
|
+
const matchedSegment = exportKey.slice(wildcardPrefix.length, exportKey.length - wildcardSuffix.length || void 0);
|
|
1206
|
+
const candidatePath = resolvePathWithExtensionFallback(resolve(workspaceDirectory, wildcardTargetValue.split("*").join(matchedSegment)));
|
|
1207
|
+
resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
|
|
1208
|
+
break;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
if (subpath && !resolvedEntryPath) {
|
|
1213
|
+
const subpathCandidates = [resolve(workspaceDirectory, subpath), resolve(workspaceDirectory, "src", subpath)];
|
|
1214
|
+
for (const directSubpath of subpathCandidates) {
|
|
1215
|
+
for (const candidateExtension of RESOLVER_EXTENSIONS) {
|
|
1216
|
+
const candidate = directSubpath + candidateExtension;
|
|
1217
|
+
if (cachedExistsSync(candidate)) {
|
|
1218
|
+
resolvedEntryPath = candidate;
|
|
1219
|
+
break;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (resolvedEntryPath) break;
|
|
1223
|
+
for (const candidateExtension of RESOLVER_EXTENSIONS) {
|
|
1224
|
+
const indexCandidate = join(directSubpath, `index${candidateExtension}`);
|
|
1225
|
+
if (cachedExistsSync(indexCandidate)) {
|
|
1226
|
+
resolvedEntryPath = indexCandidate;
|
|
1227
|
+
break;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
if (resolvedEntryPath) break;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
if (!subpath) {
|
|
1234
|
+
const mainField = workspacePackageJson.main ?? workspacePackageJson.module;
|
|
1235
|
+
if (typeof mainField === "string") resolvedEntryPath = resolve(workspaceDirectory, mainField);
|
|
1236
|
+
if (!resolvedEntryPath && workspacePackageJson.exports?.["."]) {
|
|
1237
|
+
const dotExportTarget = resolveExportConditionTarget(workspacePackageJson.exports["."]);
|
|
1238
|
+
if (dotExportTarget) resolvedEntryPath = resolve(workspaceDirectory, dotExportTarget);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
if (resolvedEntryPath) {
|
|
1242
|
+
const finalPath = resolveSourcePath(resolvedEntryPath, workspaceDirectory) ?? resolvedEntryPath;
|
|
1243
|
+
if (cachedExistsSync(finalPath)) return finalPath;
|
|
1244
|
+
const sourceFallbackPath = trySourceFallback(resolvedEntryPath);
|
|
1245
|
+
if (sourceFallbackPath) return sourceFallbackPath;
|
|
1246
|
+
}
|
|
1247
|
+
} catch {}
|
|
1248
|
+
};
|
|
1249
|
+
|
|
1250
|
+
//#endregion
|
|
1251
|
+
//#region src/collect/sibling-workspace-import-entries.ts
|
|
1252
|
+
const IMPORT_SPECIFIER_PATTERN = /(?:\bfrom\s*|\bimport\s*\(\s*|\brequire\s*\(\s*|\bimport\s+)["']([^"'\n]+)["']/g;
|
|
1253
|
+
const SIBLING_SOURCE_GLOB = "**/*.{ts,tsx,js,jsx,mts,mjs,cts,cjs}";
|
|
1254
|
+
const SIBLING_IGNORE_PATTERNS = [
|
|
1255
|
+
"**/node_modules/**",
|
|
1256
|
+
"**/dist/**",
|
|
1257
|
+
"**/build/**",
|
|
1258
|
+
"**/.git/**"
|
|
1259
|
+
];
|
|
1260
|
+
const readPackageName = (directory) => {
|
|
1261
|
+
try {
|
|
1262
|
+
const content = readFileSync(join(directory, "package.json"), "utf-8");
|
|
1263
|
+
const packageJson = JSON.parse(content);
|
|
1264
|
+
return typeof packageJson.name === "string" ? packageJson.name : void 0;
|
|
1265
|
+
} catch {
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
};
|
|
1269
|
+
const extractImportSpecifiers = (sourceText) => {
|
|
1270
|
+
const specifiers = [];
|
|
1271
|
+
for (const specifierMatch of sourceText.matchAll(IMPORT_SPECIFIER_PATTERN)) specifiers.push(specifierMatch[1]);
|
|
1272
|
+
return specifiers;
|
|
1273
|
+
};
|
|
1274
|
+
const extractSiblingWorkspaceImportEntries = (absoluteRoot) => {
|
|
1275
|
+
const monorepoRoot = findMonorepoRoot(absoluteRoot);
|
|
1276
|
+
if (!monorepoRoot || monorepoRoot === absoluteRoot) return [];
|
|
1277
|
+
const packageName = readPackageName(absoluteRoot);
|
|
1278
|
+
if (!packageName) return [];
|
|
1279
|
+
const siblingDirectories = resolveWorkspaces(monorepoRoot).packages.map((workspacePackage) => workspacePackage.directory).filter((workspaceDirectory) => workspaceDirectory !== absoluteRoot && !workspaceDirectory.startsWith(`${absoluteRoot}/`) && !absoluteRoot.startsWith(`${workspaceDirectory}/`));
|
|
1280
|
+
if (siblingDirectories.length === 0) return [];
|
|
1281
|
+
const importedEntries = [];
|
|
1282
|
+
for (const siblingDirectory of siblingDirectories) {
|
|
1283
|
+
const siblingSourceFiles = fg.sync(SIBLING_SOURCE_GLOB, {
|
|
1284
|
+
cwd: siblingDirectory,
|
|
1285
|
+
absolute: true,
|
|
1286
|
+
onlyFiles: true,
|
|
1287
|
+
ignore: SIBLING_IGNORE_PATTERNS
|
|
1288
|
+
});
|
|
1289
|
+
for (const siblingSourceFile of siblingSourceFiles) {
|
|
1290
|
+
let sourceText;
|
|
1291
|
+
try {
|
|
1292
|
+
sourceText = readFileSync(siblingSourceFile, "utf-8");
|
|
1293
|
+
} catch {
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
if (!sourceText.includes(packageName)) continue;
|
|
1297
|
+
for (const importSpecifier of extractImportSpecifiers(sourceText)) {
|
|
1298
|
+
if (importSpecifier !== packageName && !importSpecifier.startsWith(`${packageName}/`)) continue;
|
|
1299
|
+
const subpath = importSpecifier.slice(packageName.length + 1);
|
|
1300
|
+
if (!subpath) continue;
|
|
1301
|
+
const resolvedEntry = resolveWorkspaceSubpath(absoluteRoot, subpath);
|
|
1302
|
+
if (resolvedEntry) importedEntries.push(trySourceFallback(resolvedEntry) ?? resolvedEntry);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
return [...new Set(importedEntries)];
|
|
1307
|
+
};
|
|
1308
|
+
|
|
1309
|
+
//#endregion
|
|
1310
|
+
//#region src/collect/entries.ts
|
|
1311
|
+
const resolveEntries = async (config) => {
|
|
1312
|
+
const absoluteRoot = resolve(config.rootDir);
|
|
1313
|
+
const entryFiles = config.entryPatterns.length > 0 ? await fg(config.entryPatterns, {
|
|
1314
|
+
cwd: absoluteRoot,
|
|
1315
|
+
absolute: true,
|
|
1316
|
+
onlyFiles: true
|
|
1317
|
+
}) : [];
|
|
1318
|
+
const packageJsonEntries = await extractPackageJsonEntries(resolve(absoluteRoot, "package.json"));
|
|
1319
|
+
const workspaceDiscovery = resolveWorkspaces(absoluteRoot);
|
|
1320
|
+
const workspacePackages = workspaceDiscovery.packages;
|
|
1321
|
+
const isEntryEligible = (workspacePackage) => {
|
|
1322
|
+
if (workspaceDiscovery.hasRootLevelWorkspacePatterns) return true;
|
|
1323
|
+
return workspacePackage.depthFromRoot <= 2;
|
|
1324
|
+
};
|
|
1325
|
+
const hasDeclaredWorkspaces = workspacePackages.some((workspacePackage) => workspacePackage.isDeclaredWorkspace);
|
|
1326
|
+
const workspaceEntries = [];
|
|
1327
|
+
for (const workspacePackage of workspacePackages) {
|
|
1328
|
+
const isEligible = isEntryEligible(workspacePackage);
|
|
1329
|
+
if (workspaceDiscovery.hasRootLevelWorkspacePatterns && hasDeclaredWorkspaces ? workspacePackage.isDeclaredWorkspace && isEligible : isEligible) {
|
|
1330
|
+
const workspaceFrameworkEntries = detectFrameworkEntries(workspacePackage.directory);
|
|
1331
|
+
workspaceEntries.push(...workspaceFrameworkEntries);
|
|
1332
|
+
}
|
|
1333
|
+
if (isEligible && (workspacePackage.isDeclaredWorkspace || !workspaceDiscovery.hasRootLevelWorkspacePatterns)) {
|
|
1334
|
+
const workspacePackageJsonEntries = await extractPackageJsonEntries(resolve(workspacePackage.directory, "package.json"));
|
|
1335
|
+
if (workspacePackageJsonEntries.some((entryPath) => existsSync(entryPath))) workspaceEntries.push(...workspacePackageJsonEntries);
|
|
1336
|
+
else {
|
|
1337
|
+
const defaultFallback = findDefaultIndexEntry(workspacePackage.directory);
|
|
1338
|
+
if (defaultFallback) workspaceEntries.push(defaultFallback);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
const frameworkEntries = detectFrameworkEntries(absoluteRoot);
|
|
1343
|
+
const entryEligiblePackages = workspacePackages.filter(isEntryEligible);
|
|
1344
|
+
const monorepoRootForEntries = findMonorepoRoot(absoluteRoot);
|
|
1345
|
+
const ancestorPackageJsonRoots = monorepoRootForEntries && monorepoRootForEntries !== absoluteRoot ? [monorepoRootForEntries] : [];
|
|
1346
|
+
const scriptEntries = extractScriptEntries(absoluteRoot);
|
|
1347
|
+
for (const workspacePackage of entryEligiblePackages) scriptEntries.push(...extractScriptEntries(workspacePackage.directory));
|
|
1348
|
+
for (const ancestorRoot of ancestorPackageJsonRoots) for (const entryPath of extractScriptEntries(ancestorRoot)) if (entryPath.startsWith(`${absoluteRoot}/`)) scriptEntries.push(entryPath);
|
|
1349
|
+
const webpackEntries = extractWebpackEntryPoints(absoluteRoot);
|
|
1350
|
+
for (const workspacePackage of entryEligiblePackages) webpackEntries.push(...extractWebpackEntryPoints(workspacePackage.directory));
|
|
1351
|
+
const viteEntries = extractViteEntryPoints(absoluteRoot);
|
|
1352
|
+
for (const workspacePackage of entryEligiblePackages) viteEntries.push(...extractViteEntryPoints(workspacePackage.directory));
|
|
1353
|
+
const bundlerConfigEntries = extractBundlerConfigEntryPoints(absoluteRoot);
|
|
1354
|
+
for (const workspacePackage of entryEligiblePackages) bundlerConfigEntries.push(...extractBundlerConfigEntryPoints(workspacePackage.directory));
|
|
1355
|
+
const htmlScriptEntries = extractHtmlScriptEntries(absoluteRoot);
|
|
1356
|
+
for (const workspacePackage of entryEligiblePackages) htmlScriptEntries.push(...extractHtmlScriptEntries(workspacePackage.directory));
|
|
1357
|
+
const allDiscoveredEntries = [
|
|
1358
|
+
...scriptEntries,
|
|
1359
|
+
...webpackEntries,
|
|
1360
|
+
...viteEntries,
|
|
1361
|
+
...bundlerConfigEntries
|
|
1362
|
+
];
|
|
1363
|
+
for (const entryPath of allDiscoveredEntries) if (entryPath.endsWith(".html") && existsSync(entryPath)) htmlScriptEntries.push(...extractScriptTagsFromHtmlFile(entryPath));
|
|
1364
|
+
const angularEntries = extractAngularEntryPoints(absoluteRoot);
|
|
1365
|
+
for (const workspacePackage of entryEligiblePackages) angularEntries.push(...extractAngularEntryPoints(workspacePackage.directory));
|
|
1366
|
+
const browserExtensionEntries = extractBrowserExtensionEntries(absoluteRoot);
|
|
1367
|
+
for (const workspacePackage of entryEligiblePackages) browserExtensionEntries.push(...extractBrowserExtensionEntries(workspacePackage.directory));
|
|
1368
|
+
const webWorkerEntries = extractWebWorkerEntries(absoluteRoot);
|
|
1369
|
+
for (const workspacePackage of entryEligiblePackages) webWorkerEntries.push(...extractWebWorkerEntries(workspacePackage.directory));
|
|
1370
|
+
const tsConfigIncludeEntries = extractTsConfigIncludeFilesEntries(absoluteRoot);
|
|
1371
|
+
for (const workspacePackage of entryEligiblePackages) tsConfigIncludeEntries.push(...extractTsConfigIncludeFilesEntries(workspacePackage.directory));
|
|
1372
|
+
const configStringEntries = extractConfigStringReferencedEntries(absoluteRoot);
|
|
1373
|
+
for (const workspacePackage of entryEligiblePackages) configStringEntries.push(...extractConfigStringReferencedEntries(workspacePackage.directory));
|
|
1374
|
+
const expoConfigPluginEntries = [...extractExpoConfigPluginEntries(absoluteRoot, readPackageJsonDependencies(join(absoluteRoot, "package.json")), absoluteRoot, false).filePaths];
|
|
1375
|
+
for (const workspacePackage of entryEligiblePackages) {
|
|
1376
|
+
const workspacePackageDependencies = readPackageJsonDependencies(join(workspacePackage.directory, "package.json"));
|
|
1377
|
+
const workspaceExpoCollection = extractExpoConfigPluginEntries(workspacePackage.directory, workspacePackageDependencies, absoluteRoot);
|
|
1378
|
+
expoConfigPluginEntries.push(...workspaceExpoCollection.filePaths);
|
|
1379
|
+
}
|
|
1380
|
+
const sectionsModuleEntries = extractSectionsModuleEntries(absoluteRoot);
|
|
1381
|
+
const siblingWorkspaceImportEntries = extractSiblingWorkspaceImportEntries(absoluteRoot);
|
|
1382
|
+
const wranglerEntries = extractWranglerEntries(absoluteRoot);
|
|
1383
|
+
for (const workspacePackage of entryEligiblePackages) wranglerEntries.push(...extractWranglerEntries(workspacePackage.directory));
|
|
1384
|
+
const testSetupEntries = extractTestSetupFiles(absoluteRoot);
|
|
1385
|
+
for (const workspacePackage of entryEligiblePackages) testSetupEntries.push(...extractTestSetupFiles(workspacePackage.directory));
|
|
1386
|
+
const pluginFileEntries = extractNextConfigPluginFiles(absoluteRoot);
|
|
1387
|
+
for (const workspacePackage of entryEligiblePackages) pluginFileEntries.push(...extractNextConfigPluginFiles(workspacePackage.directory));
|
|
1388
|
+
const testRunnerDiscovery = discoverTestRunnerEntryPoints(absoluteRoot, entryEligiblePackages);
|
|
1389
|
+
const toolingDiscovery = discoverToolingEntryPoints(absoluteRoot, entryEligiblePackages);
|
|
1390
|
+
const ciEntries = extractCiWorkflowEntries(absoluteRoot);
|
|
1391
|
+
const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries].map(toPosixPath))];
|
|
1392
|
+
const testEntryPathSet = new Set(testEntries);
|
|
1393
|
+
return {
|
|
1394
|
+
productionEntries: [...new Set([
|
|
1395
|
+
...entryFiles,
|
|
1396
|
+
...packageJsonEntries,
|
|
1397
|
+
...workspaceEntries,
|
|
1398
|
+
...frameworkEntries,
|
|
1399
|
+
...scriptEntries,
|
|
1400
|
+
...webpackEntries,
|
|
1401
|
+
...viteEntries,
|
|
1402
|
+
...bundlerConfigEntries,
|
|
1403
|
+
...htmlScriptEntries,
|
|
1404
|
+
...angularEntries,
|
|
1405
|
+
...browserExtensionEntries,
|
|
1406
|
+
...webWorkerEntries,
|
|
1407
|
+
...tsConfigIncludeEntries,
|
|
1408
|
+
...configStringEntries,
|
|
1409
|
+
...expoConfigPluginEntries,
|
|
1410
|
+
...sectionsModuleEntries,
|
|
1411
|
+
...siblingWorkspaceImportEntries,
|
|
1412
|
+
...wranglerEntries,
|
|
1413
|
+
...pluginFileEntries,
|
|
1414
|
+
...toolingDiscovery.entryFiles,
|
|
1415
|
+
...ciEntries
|
|
1416
|
+
].map(toPosixPath))].filter((entryPath) => !testEntryPathSet.has(entryPath)),
|
|
1417
|
+
testEntries,
|
|
1418
|
+
alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles].map(toPosixPath))]
|
|
1419
|
+
};
|
|
1420
|
+
};
|
|
1421
|
+
const DEFAULT_INDEX_PATTERNS = [
|
|
1422
|
+
"src/index.ts",
|
|
1423
|
+
"src/index.tsx",
|
|
1424
|
+
"src/index.js",
|
|
1425
|
+
"src/index.jsx",
|
|
1426
|
+
"src/main.ts",
|
|
1427
|
+
"src/main.tsx",
|
|
1428
|
+
"src/main.js",
|
|
1429
|
+
"src/main.jsx",
|
|
1430
|
+
"index.ts",
|
|
1431
|
+
"index.tsx",
|
|
1432
|
+
"index.js",
|
|
1433
|
+
"index.jsx",
|
|
1434
|
+
"main.ts",
|
|
1435
|
+
"main.tsx",
|
|
1436
|
+
"main.js",
|
|
1437
|
+
"main.jsx"
|
|
1438
|
+
];
|
|
1439
|
+
const findDefaultIndexEntry = (directory) => {
|
|
1440
|
+
for (const pattern of DEFAULT_INDEX_PATTERNS) {
|
|
1441
|
+
const candidatePath = resolve(directory, pattern);
|
|
1442
|
+
if (existsSync(candidatePath)) return candidatePath;
|
|
1443
|
+
}
|
|
1444
|
+
};
|
|
1445
|
+
const SOURCE_EXTENSIONS = [
|
|
1446
|
+
".ts",
|
|
1447
|
+
".tsx",
|
|
1448
|
+
".mts",
|
|
1449
|
+
".cts"
|
|
1450
|
+
];
|
|
1451
|
+
const COMMON_SOURCE_DIRECTORIES = [
|
|
1452
|
+
"src",
|
|
1453
|
+
"lib",
|
|
1454
|
+
"main",
|
|
1455
|
+
"app",
|
|
1456
|
+
"source"
|
|
1457
|
+
];
|
|
1458
|
+
const BUILD_OUTPUT_DIRECTORY_PATTERN = /^(?:\.\/)?(?:dist(?:-[a-z]+)?|build|out|esm|cjs)\/(?:(?:esm|cjs|es|lib|commonjs|module)\/)?/;
|
|
1459
|
+
const findSourceFile = (baseDir, relativePath) => {
|
|
1460
|
+
const pathWithoutExtension = join(baseDir, relativePath).replace(/\.[cm]?js(x?)$/, "");
|
|
1461
|
+
for (const sourceExtension of SOURCE_EXTENSIONS) {
|
|
1462
|
+
const candidatePath = pathWithoutExtension + sourceExtension;
|
|
1463
|
+
if (existsSync(candidatePath)) return candidatePath;
|
|
1464
|
+
}
|
|
1465
|
+
const indexCandidate = join(pathWithoutExtension, "index.ts");
|
|
1466
|
+
if (existsSync(indexCandidate)) return indexCandidate;
|
|
1467
|
+
};
|
|
1468
|
+
const findSourceFileStrict = (baseDir, relativePath) => {
|
|
1469
|
+
const pathWithoutExtension = join(baseDir, relativePath).replace(/\.[cm]?js(x?)$/, "");
|
|
1470
|
+
for (const sourceExtension of SOURCE_EXTENSIONS) {
|
|
1471
|
+
const candidatePath = pathWithoutExtension + sourceExtension;
|
|
1472
|
+
if (existsSync(candidatePath)) return candidatePath;
|
|
1473
|
+
}
|
|
1474
|
+
const exactPath = join(baseDir, relativePath);
|
|
1475
|
+
if (existsSync(exactPath)) return exactPath;
|
|
1476
|
+
};
|
|
1477
|
+
const resolveBuiltPathToSource = (builtAbsolutePath, rootDir) => {
|
|
1478
|
+
if (existsSync(builtAbsolutePath)) return void 0;
|
|
1479
|
+
try {
|
|
1480
|
+
const tsconfigPath = join(rootDir, "tsconfig.json");
|
|
1481
|
+
if (!existsSync(tsconfigPath)) return void 0;
|
|
1482
|
+
const tsconfigContent = readFileSync(tsconfigPath, "utf-8").replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
1483
|
+
const tsconfig = JSON.parse(tsconfigContent);
|
|
1484
|
+
const outDir = tsconfig?.compilerOptions?.outDir;
|
|
1485
|
+
if (!outDir) return void 0;
|
|
1486
|
+
const absoluteOutDir = resolve(rootDir, outDir);
|
|
1487
|
+
const relativeToBuild = builtAbsolutePath.startsWith(absoluteOutDir) ? builtAbsolutePath.slice(absoluteOutDir.length) : void 0;
|
|
1488
|
+
if (!relativeToBuild) return void 0;
|
|
1489
|
+
const rootDirOption = tsconfig?.compilerOptions?.rootDir;
|
|
1490
|
+
const sourceRoot = rootDirOption ? resolve(rootDir, rootDirOption) : rootDir;
|
|
1491
|
+
const sourceFileMatch = findSourceFile(sourceRoot, relativeToBuild);
|
|
1492
|
+
if (sourceFileMatch) return sourceFileMatch;
|
|
1493
|
+
const directCandidate = join(sourceRoot, relativeToBuild);
|
|
1494
|
+
if (existsSync(directCandidate)) return directCandidate;
|
|
1495
|
+
if (!rootDirOption) for (const sourceDir of COMMON_SOURCE_DIRECTORIES) {
|
|
1496
|
+
const candidate = findSourceFile(resolve(rootDir, sourceDir), relativeToBuild);
|
|
1497
|
+
if (candidate) return candidate;
|
|
1498
|
+
}
|
|
1499
|
+
} catch {}
|
|
1500
|
+
};
|
|
1501
|
+
const resolveEntryPathViaHeuristic = (entryPath, rootDir) => {
|
|
1502
|
+
if (!BUILD_OUTPUT_DIRECTORY_PATTERN.test(entryPath)) return void 0;
|
|
1503
|
+
const buildDirMatch = entryPath.match(BUILD_OUTPUT_DIRECTORY_PATTERN);
|
|
1504
|
+
if (!buildDirMatch) return void 0;
|
|
1505
|
+
const relativeToBuildDir = entryPath.slice(buildDirMatch[0].length);
|
|
1506
|
+
for (const sourceDir of COMMON_SOURCE_DIRECTORIES) {
|
|
1507
|
+
const sourceBaseDir = resolve(rootDir, sourceDir);
|
|
1508
|
+
if (!existsSync(sourceBaseDir)) continue;
|
|
1509
|
+
const sourceFileMatch = findSourceFileStrict(sourceBaseDir, relativeToBuildDir);
|
|
1510
|
+
if (sourceFileMatch) return sourceFileMatch;
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
const resolveEntryPath = (entryPath, rootDir) => {
|
|
1514
|
+
const absolutePath = resolve(rootDir, entryPath);
|
|
1515
|
+
const normalizedEntry = entryPath.replace(/^\.\//, "");
|
|
1516
|
+
if (BUILD_OUTPUT_DIRECTORY_PATTERN.test(normalizedEntry)) {
|
|
1517
|
+
const sourcePath = resolveBuiltPathToSource(absolutePath, rootDir);
|
|
1518
|
+
if (sourcePath) return sourcePath;
|
|
1519
|
+
const heuristicMatch = resolveEntryPathViaHeuristic(normalizedEntry, rootDir);
|
|
1520
|
+
if (heuristicMatch) return heuristicMatch;
|
|
1521
|
+
}
|
|
1522
|
+
if (existsSync(absolutePath)) return absolutePath;
|
|
1523
|
+
const sourcePath = resolveBuiltPathToSource(absolutePath, rootDir);
|
|
1524
|
+
if (sourcePath) return sourcePath;
|
|
1525
|
+
const directSourceMatch = findSourceFile(rootDir, normalizedEntry);
|
|
1526
|
+
if (directSourceMatch) return directSourceMatch;
|
|
1527
|
+
const heuristicMatch = resolveEntryPathViaHeuristic(normalizedEntry, rootDir);
|
|
1528
|
+
if (heuristicMatch) return heuristicMatch;
|
|
1529
|
+
return absolutePath;
|
|
1530
|
+
};
|
|
1531
|
+
const extractPackageJsonEntries = async (packageJsonPath) => {
|
|
1532
|
+
const entries = [];
|
|
1533
|
+
try {
|
|
1534
|
+
const content = await readFile(packageJsonPath, "utf-8");
|
|
1535
|
+
const packageJson = JSON.parse(content);
|
|
1536
|
+
const rootDir = packageJsonPath.replace(/\/package\.json$/, "");
|
|
1537
|
+
for (const field of [
|
|
1538
|
+
"main",
|
|
1539
|
+
"module",
|
|
1540
|
+
"browser",
|
|
1541
|
+
"types",
|
|
1542
|
+
"typings",
|
|
1543
|
+
"style",
|
|
1544
|
+
"source"
|
|
1545
|
+
]) if (typeof packageJson[field] === "string") entries.push(resolveEntryPath(packageJson[field], rootDir));
|
|
1546
|
+
if (packageJson.exports) {
|
|
1547
|
+
const exportEntries = [];
|
|
1548
|
+
collectExportPaths(packageJson.exports, rootDir, exportEntries);
|
|
1549
|
+
for (const exportEntry of exportEntries) {
|
|
1550
|
+
const resolvedExportEntry = resolveEntryWithExtensions(exportEntry) ?? resolveEntryPathWithExtensions(exportEntry, rootDir) ?? resolveSourcePath(exportEntry, rootDir);
|
|
1551
|
+
if (resolvedExportEntry && existsSync(resolvedExportEntry)) {
|
|
1552
|
+
entries.push(resolvedExportEntry);
|
|
1553
|
+
continue;
|
|
1554
|
+
}
|
|
1555
|
+
if (exportEntry.endsWith(".ts")) {
|
|
1556
|
+
const tsxFallback = exportEntry.replace(/\.ts$/, ".tsx");
|
|
1557
|
+
if (existsSync(tsxFallback)) {
|
|
1558
|
+
entries.push(tsxFallback);
|
|
1559
|
+
continue;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
if (existsSync(exportEntry)) entries.push(exportEntry);
|
|
1563
|
+
else entries.push(resolveEntryPath(exportEntry, rootDir));
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
if (packageJson.bin) {
|
|
1567
|
+
if (typeof packageJson.bin === "string") entries.push(resolveEntryPath(packageJson.bin, rootDir));
|
|
1568
|
+
else if (typeof packageJson.bin === "object") {
|
|
1569
|
+
for (const binPath of Object.values(packageJson.bin)) if (typeof binPath === "string") entries.push(resolveEntryPath(binPath, rootDir));
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
if (Array.isArray(packageJson.sideEffects)) for (const sideEffectPattern of packageJson.sideEffects) {
|
|
1573
|
+
if (typeof sideEffectPattern !== "string") continue;
|
|
1574
|
+
const sourcePatterns = expandSideEffectGlobToSourcePatterns(sideEffectPattern);
|
|
1575
|
+
for (const sourcePattern of sourcePatterns) {
|
|
1576
|
+
const matchedSideEffectFiles = fg.sync(sourcePattern, {
|
|
1577
|
+
cwd: rootDir,
|
|
1578
|
+
absolute: true,
|
|
1579
|
+
onlyFiles: true,
|
|
1580
|
+
ignore: [
|
|
1581
|
+
"**/node_modules/**",
|
|
1582
|
+
"**/dist/**",
|
|
1583
|
+
"**/build/**"
|
|
1584
|
+
]
|
|
1585
|
+
});
|
|
1586
|
+
for (const matchedSideEffectFile of matchedSideEffectFiles) if (isImportableSourceFile(matchedSideEffectFile)) entries.push(matchedSideEffectFile);
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
if (packageJson.build && typeof packageJson.build === "object") {
|
|
1590
|
+
const buildConfig = packageJson.build;
|
|
1591
|
+
if (Array.isArray(buildConfig.files)) for (const buildFileEntry of buildConfig.files) {
|
|
1592
|
+
if (typeof buildFileEntry !== "string") continue;
|
|
1593
|
+
if (buildFileEntry.includes("*")) continue;
|
|
1594
|
+
const resolvedBuildFile = resolveEntryWithExtensions(resolve(rootDir, buildFileEntry)) ?? resolveEntryPathWithExtensions(buildFileEntry, rootDir);
|
|
1595
|
+
if (resolvedBuildFile && existsSync(resolvedBuildFile)) entries.push(resolvedBuildFile);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
if (packageJson.jest && typeof packageJson.jest === "object") {
|
|
1599
|
+
const jestRootDirMatches = JSON.stringify(packageJson.jest).matchAll(/<rootDir>\/([^"\\]+)/g);
|
|
1600
|
+
for (const jestRootDirMatch of jestRootDirMatches) {
|
|
1601
|
+
const resolvedJestFile = resolveEntryPathWithExtensions(jestRootDirMatch[1], rootDir);
|
|
1602
|
+
if (resolvedJestFile && existsSync(resolvedJestFile)) entries.push(resolvedJestFile);
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
} catch {}
|
|
1606
|
+
return entries;
|
|
1607
|
+
};
|
|
1608
|
+
const expandSideEffectGlobToSourcePatterns = (pattern) => {
|
|
1609
|
+
const patterns = new Set([pattern]);
|
|
1610
|
+
if (pattern.endsWith(".js")) {
|
|
1611
|
+
patterns.add(pattern.replace(/\.js$/, ".ts"));
|
|
1612
|
+
patterns.add(pattern.replace(/\.js$/, ".tsx"));
|
|
1613
|
+
}
|
|
1614
|
+
if (pattern.includes("/lib/") || pattern.startsWith("lib/")) patterns.add(pattern.replace(/\blib\b/g, "src"));
|
|
1615
|
+
if (pattern.includes("/esm/") || pattern.startsWith("esm/")) patterns.add(pattern.replace(/\besm\b/g, "src"));
|
|
1616
|
+
return [...patterns];
|
|
1617
|
+
};
|
|
1618
|
+
const SHELL_OPERATORS_PATTERN = /\s*(?:&&|\|\||[;&|])\s*/;
|
|
1619
|
+
const SCRIPT_MULTIPLEXERS = new Set([
|
|
1620
|
+
"concurrently",
|
|
1621
|
+
"run-s",
|
|
1622
|
+
"run-p",
|
|
1623
|
+
"npm-run-all",
|
|
1624
|
+
"npm-run-all2",
|
|
1625
|
+
"wireit",
|
|
1626
|
+
"turbo",
|
|
1627
|
+
"lerna",
|
|
1628
|
+
"ultra"
|
|
1629
|
+
]);
|
|
1630
|
+
const TSCONFIG_PROJECT_FLAGS = new Set(["--project", "-p"]);
|
|
1631
|
+
const CONFIG_LIKE_FLAGS = new Set([
|
|
1632
|
+
"--config",
|
|
1633
|
+
"-c",
|
|
1634
|
+
"--format",
|
|
1635
|
+
"--formatter",
|
|
1636
|
+
"--tsconfig",
|
|
1637
|
+
"--project",
|
|
1638
|
+
"-p",
|
|
1639
|
+
"--setup",
|
|
1640
|
+
"--global-setup"
|
|
1641
|
+
]);
|
|
1642
|
+
const ENV_WRAPPER_BINARIES = new Set([
|
|
1643
|
+
"cross-env",
|
|
1644
|
+
"dotenv",
|
|
1645
|
+
"dotenv-flow",
|
|
1646
|
+
"env-cmd"
|
|
1647
|
+
]);
|
|
1648
|
+
const IGNORED_CLI_TOOLS = new Set([
|
|
1649
|
+
"prettier",
|
|
1650
|
+
"eslint",
|
|
1651
|
+
"tslint",
|
|
1652
|
+
"stylelint",
|
|
1653
|
+
"biome",
|
|
1654
|
+
"oxlint",
|
|
1655
|
+
"oxfmt",
|
|
1656
|
+
"tsc",
|
|
1657
|
+
"tsup",
|
|
1658
|
+
"tsdown",
|
|
1659
|
+
"rollup",
|
|
1660
|
+
"webpack",
|
|
1661
|
+
"rimraf",
|
|
1662
|
+
"del-cli",
|
|
1663
|
+
"shx",
|
|
1664
|
+
"cpy-cli",
|
|
1665
|
+
"cpx",
|
|
1666
|
+
"echo",
|
|
1667
|
+
"cat",
|
|
1668
|
+
"mkdir",
|
|
1669
|
+
"rm",
|
|
1670
|
+
"cp",
|
|
1671
|
+
"mv",
|
|
1672
|
+
"ls",
|
|
1673
|
+
"pwd",
|
|
1674
|
+
"test",
|
|
1675
|
+
"husky",
|
|
1676
|
+
"lint-staged",
|
|
1677
|
+
"commitlint",
|
|
1678
|
+
"changeset",
|
|
1679
|
+
"changesets",
|
|
1680
|
+
"typedoc",
|
|
1681
|
+
"api-extractor",
|
|
1682
|
+
"madge",
|
|
1683
|
+
"depcheck",
|
|
1684
|
+
"deslop",
|
|
1685
|
+
"sort-package-json",
|
|
1686
|
+
"pnpm",
|
|
1687
|
+
"npm",
|
|
1688
|
+
"yarn",
|
|
1689
|
+
"ni",
|
|
1690
|
+
"nr",
|
|
1691
|
+
"nun",
|
|
1692
|
+
"next",
|
|
1693
|
+
"nuxt",
|
|
1694
|
+
"astro",
|
|
1695
|
+
"vite",
|
|
1696
|
+
"svelte-kit",
|
|
1697
|
+
"prisma",
|
|
1698
|
+
"drizzle-kit",
|
|
1699
|
+
"formatjs",
|
|
1700
|
+
"i18next",
|
|
1701
|
+
"i18next-parser",
|
|
1702
|
+
"lingui",
|
|
1703
|
+
"storybook",
|
|
1704
|
+
"chromatic",
|
|
1705
|
+
"msw",
|
|
1706
|
+
"patch-package",
|
|
1707
|
+
"syncpack",
|
|
1708
|
+
"manypkg",
|
|
1709
|
+
"jest",
|
|
1710
|
+
"vitest",
|
|
1711
|
+
"mocha",
|
|
1712
|
+
"ava",
|
|
1713
|
+
"tap",
|
|
1714
|
+
"c8",
|
|
1715
|
+
"nyc",
|
|
1716
|
+
"playwright",
|
|
1717
|
+
"cypress",
|
|
1718
|
+
"puppeteer",
|
|
1719
|
+
"webdriver",
|
|
1720
|
+
"sequelize",
|
|
1721
|
+
"typeorm",
|
|
1722
|
+
"mikro-orm",
|
|
1723
|
+
"wait-on",
|
|
1724
|
+
"start-server-and-test",
|
|
1725
|
+
"remark",
|
|
1726
|
+
"markdownlint",
|
|
1727
|
+
"markdownlint-cli2",
|
|
1728
|
+
"textlint",
|
|
1729
|
+
"alex",
|
|
1730
|
+
"cspell",
|
|
1731
|
+
"ncu",
|
|
1732
|
+
"npm-check-updates",
|
|
1733
|
+
"size-limit",
|
|
1734
|
+
"bundlewatch",
|
|
1735
|
+
"dbdocs",
|
|
1736
|
+
"lobe-i18n",
|
|
1737
|
+
"lobe-seo"
|
|
1738
|
+
]);
|
|
1739
|
+
const looksLikeFilePath = (token) => {
|
|
1740
|
+
if (token.startsWith("-") || token.includes("${{") || token.includes("://")) return false;
|
|
1741
|
+
if (token.includes("}}") && !token.includes("{{")) return false;
|
|
1742
|
+
if (/\.(?:[cm]?[jt]sx?|css|scss|json|yaml|yml|toml|html|mjs|cjs|mts|cts|graphql|gql|mdx|astro|vue|svelte)$/.test(token)) return true;
|
|
1743
|
+
if (/\.\{[^}]+\}$/.test(token)) return true;
|
|
1744
|
+
if (token.startsWith("./") || token.startsWith("../")) return true;
|
|
1745
|
+
return token.includes("/") && !token.startsWith("@");
|
|
1746
|
+
};
|
|
1747
|
+
const isGlobPattern = (token) => {
|
|
1748
|
+
return token.includes("*") || token.includes("{") || token.includes("?");
|
|
1749
|
+
};
|
|
1750
|
+
const extractScriptFileArguments = (scriptCommand, directory) => {
|
|
1751
|
+
const entries = [];
|
|
1752
|
+
const segments = scriptCommand.split(SHELL_OPERATORS_PATTERN);
|
|
1753
|
+
for (const segment of segments) {
|
|
1754
|
+
const trimmedSegment = segment.trim();
|
|
1755
|
+
if (!trimmedSegment) continue;
|
|
1756
|
+
const tokens = trimmedSegment.split(/\s+/);
|
|
1757
|
+
if (tokens.length === 0) continue;
|
|
1758
|
+
let startIndex = 0;
|
|
1759
|
+
const firstBinary = tokens[0].replace(/^.*\//, "");
|
|
1760
|
+
if (ENV_WRAPPER_BINARIES.has(firstBinary)) {
|
|
1761
|
+
startIndex = 1;
|
|
1762
|
+
while (startIndex < tokens.length && /^[A-Z_][A-Z0-9_]*=/.test(tokens[startIndex])) startIndex++;
|
|
1763
|
+
if (startIndex >= tokens.length) continue;
|
|
1764
|
+
}
|
|
1765
|
+
const binaryName = tokens[startIndex].replace(/^.*\//, "");
|
|
1766
|
+
if (SCRIPT_MULTIPLEXERS.has(binaryName)) continue;
|
|
1767
|
+
const effectiveBinaryName = binaryName === "npx" || binaryName === "pnpx" || binaryName === "bunx" ? tokens[startIndex + 1]?.replace(/^.*\//, "") ?? "" : binaryName;
|
|
1768
|
+
const isNonEntryBinary = IGNORED_CLI_TOOLS.has(binaryName) || effectiveBinaryName !== "" && IGNORED_CLI_TOOLS.has(effectiveBinaryName);
|
|
1769
|
+
for (let tokenIndex = startIndex + 1; tokenIndex < tokens.length; tokenIndex++) {
|
|
1770
|
+
const token = tokens[tokenIndex].replace(/^['"]|['"]$/g, "");
|
|
1771
|
+
if (CONFIG_LIKE_FLAGS.has(token)) {
|
|
1772
|
+
if (tokenIndex + 1 < tokens.length && !tokens[tokenIndex + 1].startsWith("-")) {
|
|
1773
|
+
const configPath = tokens[tokenIndex + 1].replace(/^['"]|['"]$/g, "");
|
|
1774
|
+
if (looksLikeFilePath(configPath)) {
|
|
1775
|
+
const absoluteConfigPath = resolve(directory, configPath);
|
|
1776
|
+
if (existsSync(absoluteConfigPath)) if (TSCONFIG_PROJECT_FLAGS.has(token) && TSCONFIG_PROJECT_PATTERN.test(absoluteConfigPath)) entries.push(...expandTsConfigProjectEntries(absoluteConfigPath));
|
|
1777
|
+
else entries.push(absoluteConfigPath);
|
|
1778
|
+
}
|
|
1779
|
+
tokenIndex++;
|
|
1780
|
+
}
|
|
1781
|
+
continue;
|
|
1782
|
+
}
|
|
1783
|
+
const equalsIndex = token.indexOf("=");
|
|
1784
|
+
if (equalsIndex > 0 && CONFIG_LIKE_FLAGS.has(token.slice(0, equalsIndex))) {
|
|
1785
|
+
const configValue = token.slice(equalsIndex + 1);
|
|
1786
|
+
const flagName = token.slice(0, equalsIndex);
|
|
1787
|
+
if (configValue && looksLikeFilePath(configValue)) {
|
|
1788
|
+
const absoluteConfigPath = resolve(directory, configValue);
|
|
1789
|
+
if (existsSync(absoluteConfigPath)) if (TSCONFIG_PROJECT_FLAGS.has(flagName) && TSCONFIG_PROJECT_PATTERN.test(absoluteConfigPath)) entries.push(...expandTsConfigProjectEntries(absoluteConfigPath));
|
|
1790
|
+
else entries.push(absoluteConfigPath);
|
|
1791
|
+
}
|
|
1792
|
+
continue;
|
|
1793
|
+
}
|
|
1794
|
+
if (token.startsWith("-")) continue;
|
|
1795
|
+
if (isNonEntryBinary) continue;
|
|
1796
|
+
if (!looksLikeFilePath(token)) continue;
|
|
1797
|
+
if (isGlobPattern(token)) {
|
|
1798
|
+
const expandedFiles = fg.sync(token, {
|
|
1799
|
+
cwd: directory,
|
|
1800
|
+
absolute: true,
|
|
1801
|
+
onlyFiles: true,
|
|
1802
|
+
ignore: ["**/node_modules/**"]
|
|
1803
|
+
});
|
|
1804
|
+
entries.push(...expandedFiles);
|
|
1805
|
+
} else {
|
|
1806
|
+
const absoluteFilePath = resolve(directory, token);
|
|
1807
|
+
if (existsSync(absoluteFilePath)) entries.push(absoluteFilePath);
|
|
1808
|
+
else {
|
|
1809
|
+
const sourcePath = resolveSourcePath(absoluteFilePath, directory);
|
|
1810
|
+
if (sourcePath) entries.push(sourcePath);
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
return entries;
|
|
1816
|
+
};
|
|
1817
|
+
const EXTENSIONLESS_SCRIPT_EXTENSIONS = [
|
|
1818
|
+
".ts",
|
|
1819
|
+
".tsx",
|
|
1820
|
+
".js",
|
|
1821
|
+
".jsx",
|
|
1822
|
+
".mts",
|
|
1823
|
+
".mjs",
|
|
1824
|
+
".cjs"
|
|
1825
|
+
];
|
|
1826
|
+
const resolveExtensionlessScriptPath = (basePath) => {
|
|
1827
|
+
for (const extension of EXTENSIONLESS_SCRIPT_EXTENSIONS) {
|
|
1828
|
+
const candidate = basePath + extension;
|
|
1829
|
+
if (existsSync(candidate)) return candidate;
|
|
1830
|
+
}
|
|
1831
|
+
const indexCandidate = resolve(basePath, "index.ts");
|
|
1832
|
+
if (existsSync(indexCandidate)) return indexCandidate;
|
|
1833
|
+
};
|
|
1834
|
+
const extractScriptEntries = (directory) => {
|
|
1835
|
+
const packageJsonPath = resolve(directory, "package.json");
|
|
1836
|
+
if (!existsSync(packageJsonPath)) return [];
|
|
1837
|
+
const entries = [];
|
|
1838
|
+
try {
|
|
1839
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
1840
|
+
const scripts = JSON.parse(content).scripts;
|
|
1841
|
+
if (scripts && typeof scripts === "object") for (const scriptCommand of Object.values(scripts)) {
|
|
1842
|
+
if (typeof scriptCommand !== "string") continue;
|
|
1843
|
+
const match = scriptCommand.match(SCRIPT_FILE_PATTERN);
|
|
1844
|
+
if (match?.[1]) {
|
|
1845
|
+
const scriptFilePath = resolve(directory, match[1]);
|
|
1846
|
+
if (existsSync(scriptFilePath)) entries.push(scriptFilePath);
|
|
1847
|
+
else {
|
|
1848
|
+
const sourcePath = resolveSourcePath(scriptFilePath, directory);
|
|
1849
|
+
if (sourcePath) entries.push(sourcePath);
|
|
1850
|
+
}
|
|
1851
|
+
} else {
|
|
1852
|
+
const extensionlessMatch = scriptCommand.match(SCRIPT_EXTENSIONLESS_FILE_PATTERN);
|
|
1853
|
+
if (extensionlessMatch?.[1]) {
|
|
1854
|
+
const extensionlessPath = extensionlessMatch[1];
|
|
1855
|
+
const resolved = resolveExtensionlessScriptPath(resolve(directory, extensionlessPath));
|
|
1856
|
+
if (resolved) entries.push(resolved);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
const configMatch = scriptCommand.match(SCRIPT_CONFIG_FILE_PATTERN);
|
|
1860
|
+
if (configMatch?.[1]) {
|
|
1861
|
+
const configFilePath = resolve(directory, configMatch[1]);
|
|
1862
|
+
if (existsSync(configFilePath)) entries.push(configFilePath);
|
|
1863
|
+
else {
|
|
1864
|
+
const sourcePath = resolveSourcePath(configFilePath, directory);
|
|
1865
|
+
if (sourcePath) entries.push(sourcePath);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
entries.push(...extractScriptFileArguments(scriptCommand, directory));
|
|
1869
|
+
}
|
|
1870
|
+
} catch {}
|
|
1871
|
+
const scriptDirectoryFiles = fg.sync(SCRIPT_ENTRY_PATTERNS, {
|
|
1872
|
+
cwd: directory,
|
|
1873
|
+
absolute: true,
|
|
1874
|
+
onlyFiles: true,
|
|
1875
|
+
ignore: ["**/node_modules/**"]
|
|
1876
|
+
});
|
|
1877
|
+
entries.push(...scriptDirectoryFiles);
|
|
1878
|
+
return entries;
|
|
1879
|
+
};
|
|
1880
|
+
const isYamlMapping = (line) => {
|
|
1881
|
+
const firstWord = line.split(/\s/)[0];
|
|
1882
|
+
if (!firstWord) return false;
|
|
1883
|
+
return firstWord.endsWith(":") && !firstWord.startsWith("http") && !firstWord.startsWith("ftp");
|
|
1884
|
+
};
|
|
1885
|
+
const extractCiRunCommands = (content) => {
|
|
1886
|
+
const commands = [];
|
|
1887
|
+
let inMultilineRun = false;
|
|
1888
|
+
let multilineIndent = 0;
|
|
1889
|
+
for (const line of content.split("\n")) {
|
|
1890
|
+
const trimmedLine = line.trim();
|
|
1891
|
+
if (trimmedLine === "" || trimmedLine.startsWith("#")) continue;
|
|
1892
|
+
if (inMultilineRun) {
|
|
1893
|
+
if (line.length - line.trimStart().length > multilineIndent && trimmedLine !== "") {
|
|
1894
|
+
commands.push(trimmedLine);
|
|
1895
|
+
continue;
|
|
1896
|
+
}
|
|
1897
|
+
inMultilineRun = false;
|
|
1898
|
+
}
|
|
1899
|
+
const runMatch = trimmedLine.match(/^(?:-\s+)?run:\s*(.*)$/);
|
|
1900
|
+
if (runMatch) {
|
|
1901
|
+
const runValue = runMatch[1].trim();
|
|
1902
|
+
if (runValue === "|" || runValue === "|-" || runValue === "|+") {
|
|
1903
|
+
inMultilineRun = true;
|
|
1904
|
+
multilineIndent = line.length - line.trimStart().length;
|
|
1905
|
+
} else if (runValue !== "") commands.push(runValue);
|
|
1906
|
+
continue;
|
|
1907
|
+
}
|
|
1908
|
+
if (trimmedLine.startsWith("- ")) {
|
|
1909
|
+
const listItem = trimmedLine.slice(2).trim();
|
|
1910
|
+
if (listItem !== "" && !listItem.startsWith("{") && !listItem.startsWith("[") && !isYamlMapping(listItem)) commands.push(listItem);
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
return commands;
|
|
1914
|
+
};
|
|
1915
|
+
const extractCiWorkflowEntries = (rootDir) => {
|
|
1916
|
+
const entries = [];
|
|
1917
|
+
const workflowsDir = join(rootDir, ".github", "workflows");
|
|
1918
|
+
if (!existsSync(workflowsDir)) return entries;
|
|
1919
|
+
const workflowFiles = fg.sync("*.{yml,yaml}", {
|
|
1920
|
+
cwd: workflowsDir,
|
|
1921
|
+
absolute: true,
|
|
1922
|
+
onlyFiles: true
|
|
1923
|
+
});
|
|
1924
|
+
for (const workflowFile of workflowFiles) try {
|
|
1925
|
+
const runCommands = extractCiRunCommands(readFileSync(workflowFile, "utf-8"));
|
|
1926
|
+
for (const command of runCommands) {
|
|
1927
|
+
const scriptMatch = command.match(SCRIPT_FILE_PATTERN);
|
|
1928
|
+
if (scriptMatch?.[1]) {
|
|
1929
|
+
const scriptFilePath = resolve(rootDir, scriptMatch[1]);
|
|
1930
|
+
if (existsSync(scriptFilePath)) entries.push(scriptFilePath);
|
|
1931
|
+
}
|
|
1932
|
+
const configMatch = command.match(SCRIPT_CONFIG_FILE_PATTERN);
|
|
1933
|
+
if (configMatch?.[1]) {
|
|
1934
|
+
const configFilePath = resolve(rootDir, configMatch[1]);
|
|
1935
|
+
if (existsSync(configFilePath)) entries.push(configFilePath);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
} catch {}
|
|
1939
|
+
return entries;
|
|
1940
|
+
};
|
|
1941
|
+
const VITE_INPUT_BLOCK_PATTERN = /input\s*:\s*(?:\{[^}]*\}|\[[^\]]*\]|['"][^'"]+['"])/gs;
|
|
1942
|
+
const BUNDLER_ENTRY_FILE_PATTERN = /['"]([^'"]+\.(?:js|ts|tsx|jsx|mjs|mts|less|scss|css|sass|html))['"]/g;
|
|
1943
|
+
const extractViteEntryPoints = (directory) => {
|
|
1944
|
+
const entries = [];
|
|
1945
|
+
const viteConfigPaths = fg.sync("vite.config.{js,ts,mjs,mts}", {
|
|
1946
|
+
cwd: directory,
|
|
1947
|
+
absolute: true,
|
|
1948
|
+
onlyFiles: true
|
|
1949
|
+
});
|
|
1950
|
+
for (const configPath of viteConfigPaths) try {
|
|
1951
|
+
const content = readFileSync(configPath, "utf-8");
|
|
1952
|
+
let inputMatch;
|
|
1953
|
+
VITE_INPUT_BLOCK_PATTERN.lastIndex = 0;
|
|
1954
|
+
while ((inputMatch = VITE_INPUT_BLOCK_PATTERN.exec(content)) !== null) {
|
|
1955
|
+
const inputBlock = inputMatch[0];
|
|
1956
|
+
let valueMatch;
|
|
1957
|
+
BUNDLER_ENTRY_FILE_PATTERN.lastIndex = 0;
|
|
1958
|
+
while ((valueMatch = BUNDLER_ENTRY_FILE_PATTERN.exec(inputBlock)) !== null) {
|
|
1959
|
+
const entryPath = valueMatch[1];
|
|
1960
|
+
if (entryPath.startsWith("./") || entryPath.startsWith("../") || !entryPath.startsWith("/")) {
|
|
1961
|
+
const absoluteEntryPath = resolve(directory, entryPath);
|
|
1962
|
+
if (existsSync(absoluteEntryPath)) entries.push(absoluteEntryPath);
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
} catch {}
|
|
1967
|
+
return entries;
|
|
1968
|
+
};
|
|
1969
|
+
const BUNDLER_CONFIG_ENTRY_BLOCK_PATTERN = /entry\s*:\s*\[([^\]]*)\]/gs;
|
|
1970
|
+
const BUNDLER_CONFIG_ENTRY_STRING_PATTERN = /['"]([^'"]+)['"]/g;
|
|
1971
|
+
const extractBundlerConfigEntryPoints = (directory) => {
|
|
1972
|
+
const entries = [];
|
|
1973
|
+
const configPaths = fg.sync(["tsdown.config.{ts,js,cjs,mjs}", "tsup.config.{ts,js,cjs,mjs}"], {
|
|
1974
|
+
cwd: directory,
|
|
1975
|
+
absolute: true,
|
|
1976
|
+
onlyFiles: true
|
|
1977
|
+
});
|
|
1978
|
+
for (const configPath of configPaths) try {
|
|
1979
|
+
const content = readFileSync(configPath, "utf-8");
|
|
1980
|
+
let blockMatch;
|
|
1981
|
+
BUNDLER_CONFIG_ENTRY_BLOCK_PATTERN.lastIndex = 0;
|
|
1982
|
+
while ((blockMatch = BUNDLER_CONFIG_ENTRY_BLOCK_PATTERN.exec(content)) !== null) {
|
|
1983
|
+
const arrayContent = blockMatch[1];
|
|
1984
|
+
let stringMatch;
|
|
1985
|
+
BUNDLER_CONFIG_ENTRY_STRING_PATTERN.lastIndex = 0;
|
|
1986
|
+
while ((stringMatch = BUNDLER_CONFIG_ENTRY_STRING_PATTERN.exec(arrayContent)) !== null) {
|
|
1987
|
+
const entryPath = stringMatch[1];
|
|
1988
|
+
const resolvedPath = resolveEntryWithExtensions(resolve(directory, entryPath));
|
|
1989
|
+
if (resolvedPath) entries.push(resolvedPath);
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
} catch {}
|
|
1993
|
+
return entries;
|
|
1994
|
+
};
|
|
1995
|
+
const WEBPACK_ENTRY_BLOCK_PATTERN = /entry\s*:\s*(?:\{[^}]*\}|\[[^\]]*\]|['"][^'"]+['"]|path\.(?:join|resolve)\([^)]*\))/gs;
|
|
1996
|
+
const WEBPACK_ENTRY_FILE_PATTERN = /['"]([^'"]+)['"]/g;
|
|
1997
|
+
const WEBPACK_PATH_JOIN_PATTERN = /path\.(?:join|resolve)\(\s*__dirname\s*,\s*((?:['"][^'"]*['"][\s,]*)+)\)/g;
|
|
1998
|
+
const REQUIRE_RESOLVE_PATTERN = /require\.resolve\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
1999
|
+
const extractWebpackEntryPoints = (directory) => {
|
|
2000
|
+
const entries = [];
|
|
2001
|
+
const webpackConfigPaths = fg.sync([
|
|
2002
|
+
"webpack.config.{js,ts,mjs,cjs}",
|
|
2003
|
+
"**/webpack*.config.{js,ts,mjs,cjs}",
|
|
2004
|
+
"**/webpack.config*.{js,ts,mjs,cjs}",
|
|
2005
|
+
"**/webpack*.config*.babel.{js,ts}"
|
|
2006
|
+
], {
|
|
2007
|
+
cwd: directory,
|
|
2008
|
+
absolute: true,
|
|
2009
|
+
onlyFiles: true,
|
|
2010
|
+
ignore: ["**/node_modules/**"],
|
|
2011
|
+
deep: 3
|
|
2012
|
+
});
|
|
2013
|
+
for (const configPath of webpackConfigPaths) try {
|
|
2014
|
+
const content = readFileSync(configPath, "utf-8");
|
|
2015
|
+
const configDirectory = dirname(configPath);
|
|
2016
|
+
let pathJoinMatch;
|
|
2017
|
+
WEBPACK_PATH_JOIN_PATTERN.lastIndex = 0;
|
|
2018
|
+
while ((pathJoinMatch = WEBPACK_PATH_JOIN_PATTERN.exec(content)) !== null) {
|
|
2019
|
+
const segments = [...pathJoinMatch[1].matchAll(/['"]([^'"]*)['"]/g)].map((match) => match[1]);
|
|
2020
|
+
if (segments.length > 0) {
|
|
2021
|
+
const resolvedEntry = resolveEntryWithExtensions(resolve(configDirectory, ...segments));
|
|
2022
|
+
if (resolvedEntry) entries.push(resolvedEntry);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
let requireResolveMatch;
|
|
2026
|
+
REQUIRE_RESOLVE_PATTERN.lastIndex = 0;
|
|
2027
|
+
while ((requireResolveMatch = REQUIRE_RESOLVE_PATTERN.exec(content)) !== null) {
|
|
2028
|
+
const requirePath = requireResolveMatch[1];
|
|
2029
|
+
if (requirePath.startsWith("./") || requirePath.startsWith("../")) {
|
|
2030
|
+
const resolvedEntry = resolveEntryWithExtensions(resolve(configDirectory, requirePath));
|
|
2031
|
+
if (resolvedEntry) entries.push(resolvedEntry);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
let entryMatch;
|
|
2035
|
+
WEBPACK_ENTRY_BLOCK_PATTERN.lastIndex = 0;
|
|
2036
|
+
while ((entryMatch = WEBPACK_ENTRY_BLOCK_PATTERN.exec(content)) !== null) {
|
|
2037
|
+
const entryBlock = entryMatch[0];
|
|
2038
|
+
if (entryBlock.includes("path.join") || entryBlock.includes("path.resolve")) continue;
|
|
2039
|
+
let valueMatch;
|
|
2040
|
+
WEBPACK_ENTRY_FILE_PATTERN.lastIndex = 0;
|
|
2041
|
+
while ((valueMatch = WEBPACK_ENTRY_FILE_PATTERN.exec(entryBlock)) !== null) {
|
|
2042
|
+
const entryPath = valueMatch[1];
|
|
2043
|
+
if (entryPath.startsWith("./") || entryPath.startsWith("../") || !entryPath.startsWith("/")) {
|
|
2044
|
+
const resolvedEntry = resolveEntryWithExtensions(resolve(configDirectory, entryPath));
|
|
2045
|
+
if (resolvedEntry) entries.push(resolvedEntry);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
} catch {}
|
|
2050
|
+
return entries;
|
|
2051
|
+
};
|
|
2052
|
+
const HTML_SCRIPT_SRC_PATTERN = /<script[^>]+src=["']([^"']+\.(?:ts|tsx|js|jsx|mts|mjs))["'][^>]*>/gi;
|
|
2053
|
+
const extractHtmlScriptEntries = (directory) => {
|
|
2054
|
+
const entries = [];
|
|
2055
|
+
const htmlFiles = fg.sync(["index.html", "*.html"], {
|
|
2056
|
+
cwd: directory,
|
|
2057
|
+
absolute: true,
|
|
2058
|
+
onlyFiles: true,
|
|
2059
|
+
ignore: [
|
|
2060
|
+
"**/node_modules/**",
|
|
2061
|
+
"**/dist/**",
|
|
2062
|
+
"**/build/**"
|
|
2063
|
+
],
|
|
2064
|
+
deep: 1
|
|
2065
|
+
});
|
|
2066
|
+
for (const htmlPath of htmlFiles) try {
|
|
2067
|
+
const content = readFileSync(htmlPath, "utf-8");
|
|
2068
|
+
let scriptMatch;
|
|
2069
|
+
HTML_SCRIPT_SRC_PATTERN.lastIndex = 0;
|
|
2070
|
+
while ((scriptMatch = HTML_SCRIPT_SRC_PATTERN.exec(content)) !== null) {
|
|
2071
|
+
const scriptSrc = scriptMatch[1].replace(/^\//, "");
|
|
2072
|
+
const absoluteScriptPath = resolve(htmlPath.replace(/\/[^/]+$/, ""), scriptSrc);
|
|
2073
|
+
if (existsSync(absoluteScriptPath)) entries.push(absoluteScriptPath);
|
|
2074
|
+
}
|
|
2075
|
+
} catch {}
|
|
2076
|
+
return entries;
|
|
2077
|
+
};
|
|
2078
|
+
const extractScriptTagsFromHtmlFile = (htmlFilePath) => {
|
|
2079
|
+
const entries = [];
|
|
2080
|
+
try {
|
|
2081
|
+
const content = readFileSync(htmlFilePath, "utf-8");
|
|
2082
|
+
let scriptMatch;
|
|
2083
|
+
HTML_SCRIPT_SRC_PATTERN.lastIndex = 0;
|
|
2084
|
+
while ((scriptMatch = HTML_SCRIPT_SRC_PATTERN.exec(content)) !== null) {
|
|
2085
|
+
const scriptSrc = scriptMatch[1].replace(/^\//, "");
|
|
2086
|
+
const absoluteScriptPath = resolve(dirname(htmlFilePath), scriptSrc);
|
|
2087
|
+
if (existsSync(absoluteScriptPath)) entries.push(absoluteScriptPath);
|
|
2088
|
+
}
|
|
2089
|
+
} catch {}
|
|
2090
|
+
return entries;
|
|
2091
|
+
};
|
|
2092
|
+
const TSCONFIG_FILENAME_GLOBS = ["tsconfig.json", "tsconfig.*.json"];
|
|
2093
|
+
const TSCONFIG_PROJECT_PATTERN = /(?:^|[\\/])tsconfig(?:\.[^.]+)?\.json$/;
|
|
2094
|
+
const stripJsoncCommentsLocal = (sourceText) => {
|
|
2095
|
+
let result = "";
|
|
2096
|
+
let insideString = false;
|
|
2097
|
+
let index = 0;
|
|
2098
|
+
while (index < sourceText.length) {
|
|
2099
|
+
const ch = sourceText[index];
|
|
2100
|
+
if (insideString) {
|
|
2101
|
+
if (ch === "\\" && index + 1 < sourceText.length) {
|
|
2102
|
+
result += sourceText[index] + sourceText[index + 1];
|
|
2103
|
+
index += 2;
|
|
2104
|
+
continue;
|
|
2105
|
+
}
|
|
2106
|
+
if (ch === "\"") insideString = false;
|
|
2107
|
+
result += ch;
|
|
2108
|
+
index++;
|
|
2109
|
+
continue;
|
|
2110
|
+
}
|
|
2111
|
+
if (ch === "\"") {
|
|
2112
|
+
insideString = true;
|
|
2113
|
+
result += ch;
|
|
2114
|
+
index++;
|
|
2115
|
+
continue;
|
|
2116
|
+
}
|
|
2117
|
+
if (ch === "/" && index + 1 < sourceText.length) {
|
|
2118
|
+
if (sourceText[index + 1] === "/") {
|
|
2119
|
+
while (index < sourceText.length && sourceText[index] !== "\n") index++;
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
2122
|
+
if (sourceText[index + 1] === "*") {
|
|
2123
|
+
index += 2;
|
|
2124
|
+
while (index + 1 < sourceText.length && !(sourceText[index] === "*" && sourceText[index + 1] === "/")) index++;
|
|
2125
|
+
index += 2;
|
|
2126
|
+
continue;
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
result += ch;
|
|
2130
|
+
index++;
|
|
2131
|
+
}
|
|
2132
|
+
return result.replace(/,(\s*[}\]])/g, "$1");
|
|
2133
|
+
};
|
|
2134
|
+
const extractTsConfigIncludeFilesEntries = (directory) => {
|
|
2135
|
+
const entries = [];
|
|
2136
|
+
const tsconfigPaths = fg.sync(TSCONFIG_FILENAME_GLOBS, {
|
|
2137
|
+
cwd: directory,
|
|
2138
|
+
absolute: true,
|
|
2139
|
+
onlyFiles: true,
|
|
2140
|
+
ignore: [
|
|
2141
|
+
"**/node_modules/**",
|
|
2142
|
+
"**/dist/**",
|
|
2143
|
+
"**/build/**"
|
|
2144
|
+
],
|
|
2145
|
+
deep: 1
|
|
2146
|
+
});
|
|
2147
|
+
for (const tsconfigPath of tsconfigPaths) try {
|
|
2148
|
+
const cleaned = stripJsoncCommentsLocal(readFileSync(tsconfigPath, "utf-8"));
|
|
2149
|
+
const tsconfigJson = JSON.parse(cleaned);
|
|
2150
|
+
const tsconfigDir = dirname(tsconfigPath);
|
|
2151
|
+
const collectPaths = (rawList) => {
|
|
2152
|
+
if (!Array.isArray(rawList)) return;
|
|
2153
|
+
for (const item of rawList) {
|
|
2154
|
+
if (typeof item !== "string") continue;
|
|
2155
|
+
if (item.includes("*") || item.includes("?")) continue;
|
|
2156
|
+
const candidatePath = resolve(tsconfigDir, item);
|
|
2157
|
+
if (existsSync(candidatePath)) entries.push(candidatePath);
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2160
|
+
collectPaths(tsconfigJson.include);
|
|
2161
|
+
collectPaths(tsconfigJson.files);
|
|
2162
|
+
} catch {}
|
|
2163
|
+
return entries;
|
|
2164
|
+
};
|
|
2165
|
+
const expandTsConfigProjectEntries = (tsconfigAbsolutePath) => {
|
|
2166
|
+
const entries = [];
|
|
2167
|
+
try {
|
|
2168
|
+
const cleaned = stripJsoncCommentsLocal(readFileSync(tsconfigAbsolutePath, "utf-8"));
|
|
2169
|
+
const tsconfigJson = JSON.parse(cleaned);
|
|
2170
|
+
const tsconfigDir = dirname(tsconfigAbsolutePath);
|
|
2171
|
+
if (Array.isArray(tsconfigJson.files)) for (const fileItem of tsconfigJson.files) {
|
|
2172
|
+
if (typeof fileItem !== "string") continue;
|
|
2173
|
+
const candidatePath = resolve(tsconfigDir, fileItem);
|
|
2174
|
+
if (existsSync(candidatePath)) entries.push(candidatePath);
|
|
2175
|
+
}
|
|
2176
|
+
if (Array.isArray(tsconfigJson.include)) for (const includePattern of tsconfigJson.include) {
|
|
2177
|
+
if (typeof includePattern !== "string") continue;
|
|
2178
|
+
const expandedFiles = fg.sync(includePattern, {
|
|
2179
|
+
cwd: tsconfigDir,
|
|
2180
|
+
absolute: true,
|
|
2181
|
+
onlyFiles: true,
|
|
2182
|
+
ignore: [
|
|
2183
|
+
"**/node_modules/**",
|
|
2184
|
+
"**/dist/**",
|
|
2185
|
+
"**/build/**"
|
|
2186
|
+
]
|
|
2187
|
+
});
|
|
2188
|
+
entries.push(...expandedFiles);
|
|
2189
|
+
}
|
|
2190
|
+
} catch {}
|
|
2191
|
+
return entries;
|
|
2192
|
+
};
|
|
2193
|
+
const WRANGLER_TOML_MAIN_PATTERN = /^\s*main\s*=\s*['"]([^'"\n]+)['"]/m;
|
|
2194
|
+
const WRANGLER_JSON_MAIN_PATTERN = /"main"\s*:\s*"([^"]+)"/;
|
|
2195
|
+
const WRANGLER_SERVICE_BINDINGS_PATTERN = /entry_point\s*=\s*['"]([^'"\n]+)['"]/g;
|
|
2196
|
+
const extractWranglerEntries = (directory) => {
|
|
2197
|
+
const entries = [];
|
|
2198
|
+
const wranglerPaths = fg.sync([
|
|
2199
|
+
"wrangler.toml",
|
|
2200
|
+
"wrangler.json",
|
|
2201
|
+
"wrangler.jsonc"
|
|
2202
|
+
], {
|
|
2203
|
+
cwd: directory,
|
|
2204
|
+
absolute: true,
|
|
2205
|
+
onlyFiles: true,
|
|
2206
|
+
ignore: ["**/node_modules/**"],
|
|
2207
|
+
deep: 1
|
|
2208
|
+
});
|
|
2209
|
+
for (const wranglerPath of wranglerPaths) try {
|
|
2210
|
+
const content = readFileSync(wranglerPath, "utf-8");
|
|
2211
|
+
const wranglerDir = dirname(wranglerPath);
|
|
2212
|
+
const mainMatch = wranglerPath.endsWith(".toml") ? content.match(WRANGLER_TOML_MAIN_PATTERN) : content.match(WRANGLER_JSON_MAIN_PATTERN);
|
|
2213
|
+
if (mainMatch?.[1]) {
|
|
2214
|
+
const candidatePath = resolve(wranglerDir, mainMatch[1]);
|
|
2215
|
+
if (existsSync(candidatePath)) entries.push(candidatePath);
|
|
2216
|
+
else {
|
|
2217
|
+
const sourceCandidate = resolveSourcePath(candidatePath, wranglerDir);
|
|
2218
|
+
if (sourceCandidate) entries.push(sourceCandidate);
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
let entryPointMatch;
|
|
2222
|
+
WRANGLER_SERVICE_BINDINGS_PATTERN.lastIndex = 0;
|
|
2223
|
+
while ((entryPointMatch = WRANGLER_SERVICE_BINDINGS_PATTERN.exec(content)) !== null) {
|
|
2224
|
+
const candidatePath = resolve(wranglerDir, entryPointMatch[1]);
|
|
2225
|
+
if (existsSync(candidatePath)) entries.push(candidatePath);
|
|
2226
|
+
}
|
|
2227
|
+
} catch {}
|
|
2228
|
+
return entries;
|
|
2229
|
+
};
|
|
2230
|
+
const WORKER_FILE_GLOBS = [
|
|
2231
|
+
"**/*.worker.{ts,tsx,js,jsx,mts,mjs,cts,cjs}",
|
|
2232
|
+
"**/*.sw.{ts,tsx,js,jsx,mts,mjs,cts,cjs}",
|
|
2233
|
+
"**/sw.{ts,tsx,js,jsx,mts,mjs,cts,cjs}",
|
|
2234
|
+
"**/service-worker.{ts,tsx,js,jsx,mts,mjs,cts,cjs}"
|
|
2235
|
+
];
|
|
2236
|
+
const extractWebWorkerEntries = (directory) => {
|
|
2237
|
+
return fg.sync(WORKER_FILE_GLOBS, {
|
|
2238
|
+
cwd: directory,
|
|
2239
|
+
absolute: true,
|
|
2240
|
+
onlyFiles: true,
|
|
2241
|
+
ignore: [
|
|
2242
|
+
"**/node_modules/**",
|
|
2243
|
+
"**/dist/**",
|
|
2244
|
+
"**/build/**",
|
|
2245
|
+
"**/.next/**",
|
|
2246
|
+
"**/out/**"
|
|
2247
|
+
],
|
|
2248
|
+
deep: 8
|
|
2249
|
+
});
|
|
2250
|
+
};
|
|
2251
|
+
const collectBrowserExtensionManifestPaths = (manifest) => {
|
|
2252
|
+
const candidatePaths = [];
|
|
2253
|
+
if (typeof manifest !== "object" || manifest === null) return candidatePaths;
|
|
2254
|
+
const manifestRecord = manifest;
|
|
2255
|
+
const background = manifestRecord.background;
|
|
2256
|
+
if (typeof background === "object" && background !== null) {
|
|
2257
|
+
const backgroundRecord = background;
|
|
2258
|
+
if (typeof backgroundRecord.service_worker === "string") candidatePaths.push(backgroundRecord.service_worker);
|
|
2259
|
+
if (typeof backgroundRecord.page === "string") candidatePaths.push(backgroundRecord.page);
|
|
2260
|
+
if (typeof backgroundRecord.scripts === "string") candidatePaths.push(backgroundRecord.scripts);
|
|
2261
|
+
if (Array.isArray(backgroundRecord.scripts)) {
|
|
2262
|
+
for (const scriptPath of backgroundRecord.scripts) if (typeof scriptPath === "string") candidatePaths.push(scriptPath);
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
const contentScripts = manifestRecord.content_scripts;
|
|
2266
|
+
if (Array.isArray(contentScripts)) for (const contentScript of contentScripts) {
|
|
2267
|
+
if (typeof contentScript !== "object" || contentScript === null) continue;
|
|
2268
|
+
const contentScriptRecord = contentScript;
|
|
2269
|
+
if (Array.isArray(contentScriptRecord.js)) {
|
|
2270
|
+
for (const scriptPath of contentScriptRecord.js) if (typeof scriptPath === "string") candidatePaths.push(scriptPath);
|
|
2271
|
+
}
|
|
2272
|
+
if (Array.isArray(contentScriptRecord.css)) {
|
|
2273
|
+
for (const stylePath of contentScriptRecord.css) if (typeof stylePath === "string") candidatePaths.push(stylePath);
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
const action = manifestRecord.action ?? manifestRecord.browser_action ?? manifestRecord.page_action;
|
|
2277
|
+
if (typeof action === "object" && action !== null) {
|
|
2278
|
+
const actionRecord = action;
|
|
2279
|
+
if (typeof actionRecord.default_popup === "string") candidatePaths.push(actionRecord.default_popup);
|
|
2280
|
+
}
|
|
2281
|
+
if (typeof manifestRecord.devtools_page === "string") candidatePaths.push(manifestRecord.devtools_page);
|
|
2282
|
+
if (typeof manifestRecord.options_page === "string") candidatePaths.push(manifestRecord.options_page);
|
|
2283
|
+
if (typeof manifestRecord.options_ui === "object" && manifestRecord.options_ui !== null) {
|
|
2284
|
+
const optionsRecord = manifestRecord.options_ui;
|
|
2285
|
+
if (typeof optionsRecord.page === "string") candidatePaths.push(optionsRecord.page);
|
|
2286
|
+
}
|
|
2287
|
+
if (typeof manifestRecord.sandbox === "object" && manifestRecord.sandbox !== null) {
|
|
2288
|
+
const sandboxRecord = manifestRecord.sandbox;
|
|
2289
|
+
if (Array.isArray(sandboxRecord.pages)) {
|
|
2290
|
+
for (const pagePath of sandboxRecord.pages) if (typeof pagePath === "string") candidatePaths.push(pagePath);
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
return candidatePaths;
|
|
2294
|
+
};
|
|
2295
|
+
const isLikelyBrowserExtensionManifest = (manifest) => {
|
|
2296
|
+
if (typeof manifest !== "object" || manifest === null) return false;
|
|
2297
|
+
return typeof manifest.manifest_version === "number";
|
|
2298
|
+
};
|
|
2299
|
+
const extractBrowserExtensionEntries = (directory) => {
|
|
2300
|
+
const entries = [];
|
|
2301
|
+
const manifestPaths = fg.sync([
|
|
2302
|
+
"manifest.json",
|
|
2303
|
+
"manifest.*.json",
|
|
2304
|
+
"src/manifest.json",
|
|
2305
|
+
"src/manifest.*.json",
|
|
2306
|
+
"public/manifest.json",
|
|
2307
|
+
"public/manifest.*.json",
|
|
2308
|
+
"static/manifest.json"
|
|
2309
|
+
], {
|
|
2310
|
+
cwd: directory,
|
|
2311
|
+
absolute: true,
|
|
2312
|
+
onlyFiles: true,
|
|
2313
|
+
ignore: [
|
|
2314
|
+
"**/node_modules/**",
|
|
2315
|
+
"**/dist/**",
|
|
2316
|
+
"**/build/**"
|
|
2317
|
+
],
|
|
2318
|
+
deep: 3
|
|
2319
|
+
});
|
|
2320
|
+
for (const manifestPath of manifestPaths) try {
|
|
2321
|
+
const content = readFileSync(manifestPath, "utf-8");
|
|
2322
|
+
const manifest = JSON.parse(content);
|
|
2323
|
+
if (!isLikelyBrowserExtensionManifest(manifest)) continue;
|
|
2324
|
+
const manifestDir = dirname(manifestPath);
|
|
2325
|
+
const candidatePaths = collectBrowserExtensionManifestPaths(manifest);
|
|
2326
|
+
const resolutionRoots = [
|
|
2327
|
+
manifestDir,
|
|
2328
|
+
resolve(manifestDir, ".."),
|
|
2329
|
+
directory
|
|
2330
|
+
];
|
|
2331
|
+
for (const candidatePath of candidatePaths) for (const resolutionRoot of resolutionRoots) {
|
|
2332
|
+
const candidateAbsolutePath = resolve(resolutionRoot, candidatePath);
|
|
2333
|
+
if (existsSync(candidateAbsolutePath)) {
|
|
2334
|
+
entries.push(candidateAbsolutePath);
|
|
2335
|
+
break;
|
|
2336
|
+
}
|
|
2337
|
+
const sourceFile = resolveSourcePath(candidateAbsolutePath, resolutionRoot);
|
|
2338
|
+
if (sourceFile) {
|
|
2339
|
+
entries.push(sourceFile);
|
|
2340
|
+
break;
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
} catch {}
|
|
2344
|
+
return entries;
|
|
2345
|
+
};
|
|
2346
|
+
const ANGULAR_ENTRY_KEYS = [
|
|
2347
|
+
"main",
|
|
2348
|
+
"polyfills",
|
|
2349
|
+
"styles"
|
|
2350
|
+
];
|
|
2351
|
+
const extractAngularEntryPoints = (directory) => {
|
|
2352
|
+
const entries = [];
|
|
2353
|
+
const angularJsonPaths = fg.sync(["angular.json", ".angular-cli.json"], {
|
|
2354
|
+
cwd: directory,
|
|
2355
|
+
absolute: true,
|
|
2356
|
+
onlyFiles: true
|
|
2357
|
+
});
|
|
2358
|
+
for (const angularJsonPath of angularJsonPaths) try {
|
|
2359
|
+
const content = readFileSync(angularJsonPath, "utf-8");
|
|
2360
|
+
const projects = JSON.parse(content).projects ?? {};
|
|
2361
|
+
const angularDir = angularJsonPath.replace(/\/[^/]+$/, "");
|
|
2362
|
+
for (const projectConfig of Object.values(projects)) {
|
|
2363
|
+
const projectRecord = projectConfig;
|
|
2364
|
+
const architect = projectRecord.architect;
|
|
2365
|
+
if (architect) for (const targetConfig of Object.values(architect)) {
|
|
2366
|
+
const options = targetConfig.options;
|
|
2367
|
+
if (!options) continue;
|
|
2368
|
+
for (const entryKey of ANGULAR_ENTRY_KEYS) {
|
|
2369
|
+
const entryValue = options[entryKey];
|
|
2370
|
+
if (typeof entryValue === "string") {
|
|
2371
|
+
const absolutePath = resolve(angularDir, entryValue);
|
|
2372
|
+
if (existsSync(absolutePath)) entries.push(absolutePath);
|
|
2373
|
+
}
|
|
2374
|
+
if (Array.isArray(entryValue)) {
|
|
2375
|
+
for (const entryItem of entryValue) if (typeof entryItem === "string") {
|
|
2376
|
+
const absolutePath = resolve(angularDir, entryItem);
|
|
2377
|
+
if (existsSync(absolutePath)) entries.push(absolutePath);
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
const projectDir = resolve(angularDir, typeof projectRecord.root === "string" ? projectRecord.root : "");
|
|
2383
|
+
const ngPackagePaths = fg.sync(["ng-package.json", "**/ng-package.json"], {
|
|
2384
|
+
cwd: projectDir,
|
|
2385
|
+
absolute: true,
|
|
2386
|
+
onlyFiles: true,
|
|
2387
|
+
deep: 2,
|
|
2388
|
+
ignore: ["**/node_modules/**"]
|
|
2389
|
+
});
|
|
2390
|
+
for (const ngPackagePath of ngPackagePaths) try {
|
|
2391
|
+
const ngContent = readFileSync(ngPackagePath, "utf-8");
|
|
2392
|
+
const ngPackage = JSON.parse(ngContent);
|
|
2393
|
+
const ngDir = ngPackagePath.replace(/\/[^/]+$/, "");
|
|
2394
|
+
const libEntry = ngPackage?.lib?.entryFile;
|
|
2395
|
+
if (typeof libEntry === "string") {
|
|
2396
|
+
const absoluteEntry = resolve(ngDir, libEntry);
|
|
2397
|
+
if (existsSync(absoluteEntry)) entries.push(absoluteEntry);
|
|
2398
|
+
}
|
|
2399
|
+
} catch {}
|
|
2400
|
+
}
|
|
2401
|
+
} catch {}
|
|
2402
|
+
return entries;
|
|
2403
|
+
};
|
|
2404
|
+
const PLUGIN_FILE_ARGUMENT_PATTERN = /(?:createNextIntlPlugin|createMDX|withContentlayer|withPlaiceholder)\s*\(\s*['"]([^'"]+)['"]/g;
|
|
2405
|
+
const NEXT_INTL_IMPORT_PATTERN = /createNextIntlPlugin/;
|
|
2406
|
+
const NEXT_INTL_DEFAULT_PATHS = [
|
|
2407
|
+
"src/i18n/request.ts",
|
|
2408
|
+
"src/i18n/request.tsx",
|
|
2409
|
+
"src/i18n/request.js",
|
|
2410
|
+
"i18n/request.ts",
|
|
2411
|
+
"i18n/request.tsx",
|
|
2412
|
+
"i18n/request.js",
|
|
2413
|
+
"i18n.ts",
|
|
2414
|
+
"i18n.tsx"
|
|
2415
|
+
];
|
|
2416
|
+
const extractNextConfigPluginFiles = (directory) => {
|
|
2417
|
+
const entries = [];
|
|
2418
|
+
const nextConfigPaths = fg.sync(["next.config.{ts,js,mjs,mts}"], {
|
|
2419
|
+
cwd: directory,
|
|
2420
|
+
absolute: true,
|
|
2421
|
+
onlyFiles: true,
|
|
2422
|
+
ignore: ["**/node_modules/**"]
|
|
2423
|
+
});
|
|
2424
|
+
for (const configPath of nextConfigPaths) try {
|
|
2425
|
+
const content = readFileSync(configPath, "utf-8");
|
|
2426
|
+
const configDirectory = configPath.replace(/\/[^/]+$/, "");
|
|
2427
|
+
let pluginMatch;
|
|
2428
|
+
PLUGIN_FILE_ARGUMENT_PATTERN.lastIndex = 0;
|
|
2429
|
+
let didMatchNextIntlWithPath = false;
|
|
2430
|
+
while ((pluginMatch = PLUGIN_FILE_ARGUMENT_PATTERN.exec(content)) !== null) {
|
|
2431
|
+
const filePath = pluginMatch[1];
|
|
2432
|
+
const absolutePath = resolve(configDirectory, filePath);
|
|
2433
|
+
if (existsSync(absolutePath)) entries.push(absolutePath);
|
|
2434
|
+
if (pluginMatch[0].includes("createNextIntlPlugin")) didMatchNextIntlWithPath = true;
|
|
2435
|
+
}
|
|
2436
|
+
if (!didMatchNextIntlWithPath && NEXT_INTL_IMPORT_PATTERN.test(content)) for (const defaultPath of NEXT_INTL_DEFAULT_PATHS) {
|
|
2437
|
+
const absolutePath = resolve(configDirectory, defaultPath);
|
|
2438
|
+
if (existsSync(absolutePath)) {
|
|
2439
|
+
entries.push(absolutePath);
|
|
2440
|
+
break;
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
} catch {}
|
|
2444
|
+
return entries;
|
|
2445
|
+
};
|
|
2446
|
+
const VITEST_INCLUDE_ITEM_PATTERN = /['"]([^'"]+)['"]/g;
|
|
2447
|
+
const COVERAGE_BLOCK_PATTERN = /coverage\s*:\s*\{/g;
|
|
2448
|
+
const TEST_MATCH_ARRAY_PATTERN = /testMatch\s*:\s*\[([^\]]*)\]/;
|
|
2449
|
+
const STRING_LITERAL_PATTERN = /['"]([^'"]+)['"]/g;
|
|
2450
|
+
const extractJestTestMatchPatterns = (directory) => {
|
|
2451
|
+
const configPaths = fg.sync(["jest.config.{ts,js,mjs,cjs}"], {
|
|
2452
|
+
cwd: directory,
|
|
2453
|
+
absolute: true,
|
|
2454
|
+
onlyFiles: true,
|
|
2455
|
+
ignore: ["**/node_modules/**"]
|
|
2456
|
+
});
|
|
2457
|
+
if (configPaths.length === 0) {
|
|
2458
|
+
try {
|
|
2459
|
+
const packageContent = readFileSync(join(directory, "package.json"), "utf-8");
|
|
2460
|
+
const packageJson = JSON.parse(packageContent);
|
|
2461
|
+
if (packageJson.jest?.testMatch) return convertJestTestMatchToGlobs(packageJson.jest.testMatch);
|
|
2462
|
+
} catch {}
|
|
2463
|
+
return [];
|
|
2464
|
+
}
|
|
2465
|
+
for (const configPath of configPaths) try {
|
|
2466
|
+
const content = readFileSync(configPath, "utf-8");
|
|
2467
|
+
const testMatchMatch = TEST_MATCH_ARRAY_PATTERN.exec(content);
|
|
2468
|
+
if (!testMatchMatch) continue;
|
|
2469
|
+
const arrayContent = testMatchMatch[1];
|
|
2470
|
+
const patterns = [];
|
|
2471
|
+
STRING_LITERAL_PATTERN.lastIndex = 0;
|
|
2472
|
+
let itemMatch;
|
|
2473
|
+
while ((itemMatch = STRING_LITERAL_PATTERN.exec(arrayContent)) !== null) patterns.push(itemMatch[1]);
|
|
2474
|
+
if (patterns.length > 0) return convertJestTestMatchToGlobs(patterns);
|
|
2475
|
+
} catch {}
|
|
2476
|
+
return [];
|
|
2477
|
+
};
|
|
2478
|
+
const convertJestTestMatchToGlobs = (patterns) => {
|
|
2479
|
+
return patterns.map((pattern) => {
|
|
2480
|
+
let converted = pattern.replace(/<rootDir>\/?/g, "");
|
|
2481
|
+
converted = converted.replace(/\?\(\*\.\)/g, "*.");
|
|
2482
|
+
converted = converted.replace(/\?\(([^)]+)\)/g, (_, group) => {
|
|
2483
|
+
return `{${[...group.includes("|") ? group.split("|") : [group], ""].join(",")}}`;
|
|
2484
|
+
});
|
|
2485
|
+
converted = converted.replace(/\+\(([^)]+)\)/g, (_, group) => {
|
|
2486
|
+
return group.includes("|") ? `{${group.replace(/\|/g, ",")}}` : group;
|
|
2487
|
+
});
|
|
2488
|
+
converted = converted.replace(/\(([^)]+)\)/g, (_, group) => {
|
|
2489
|
+
return group.includes("|") ? `{${group.replace(/\|/g, ",")}}` : group;
|
|
2490
|
+
});
|
|
2491
|
+
return converted;
|
|
2492
|
+
});
|
|
2493
|
+
};
|
|
2494
|
+
const extractVitestIncludePatterns = (directory) => {
|
|
2495
|
+
const configPaths = fg.sync(["vitest.config.{ts,js,mts,mjs}", "vitest.web.config.{ts,js,mts,mjs}"], {
|
|
2496
|
+
cwd: directory,
|
|
2497
|
+
absolute: true,
|
|
2498
|
+
onlyFiles: true,
|
|
2499
|
+
ignore: ["**/node_modules/**"]
|
|
2500
|
+
});
|
|
2501
|
+
const patterns = [];
|
|
2502
|
+
for (const configPath of configPaths) try {
|
|
2503
|
+
const content = readFileSync(configPath, "utf-8");
|
|
2504
|
+
const coverageBlockRanges = findNestedBlockRanges(content, COVERAGE_BLOCK_PATTERN);
|
|
2505
|
+
const includePattern = /include\s*:\s*\[([^\]]*)\]/g;
|
|
2506
|
+
includePattern.lastIndex = 0;
|
|
2507
|
+
let includeMatch;
|
|
2508
|
+
while ((includeMatch = includePattern.exec(content)) !== null) {
|
|
2509
|
+
const matchStart = includeMatch.index;
|
|
2510
|
+
if (coverageBlockRanges.some(([blockStart, blockEnd]) => matchStart > blockStart && matchStart < blockEnd)) continue;
|
|
2511
|
+
const arrayContent = includeMatch[1];
|
|
2512
|
+
VITEST_INCLUDE_ITEM_PATTERN.lastIndex = 0;
|
|
2513
|
+
let itemMatch;
|
|
2514
|
+
while ((itemMatch = VITEST_INCLUDE_ITEM_PATTERN.exec(arrayContent)) !== null) patterns.push(itemMatch[1]);
|
|
2515
|
+
}
|
|
2516
|
+
} catch {}
|
|
2517
|
+
return patterns;
|
|
2518
|
+
};
|
|
2519
|
+
const findNestedBlockRanges = (content, blockStartPattern) => {
|
|
2520
|
+
const ranges = [];
|
|
2521
|
+
blockStartPattern.lastIndex = 0;
|
|
2522
|
+
let blockMatch;
|
|
2523
|
+
while ((blockMatch = blockStartPattern.exec(content)) !== null) {
|
|
2524
|
+
const openBraceIndex = content.indexOf("{", blockMatch.index);
|
|
2525
|
+
if (openBraceIndex === -1) continue;
|
|
2526
|
+
let braceDepth = 1;
|
|
2527
|
+
let position = openBraceIndex + 1;
|
|
2528
|
+
while (position < content.length && braceDepth > 0) {
|
|
2529
|
+
if (content[position] === "{") braceDepth++;
|
|
2530
|
+
if (content[position] === "}") braceDepth--;
|
|
2531
|
+
position++;
|
|
2532
|
+
}
|
|
2533
|
+
ranges.push([blockMatch.index, position]);
|
|
2534
|
+
}
|
|
2535
|
+
return ranges;
|
|
2536
|
+
};
|
|
2537
|
+
const SETUP_FILES_PATTERN = /(?:setupFiles|setupFilesAfterEnv|globalSetup|globalTeardown)\s*:\s*(?:\[([^\]]*)\]|['"]([^'"]+)['"])/gs;
|
|
2538
|
+
const SETUP_FILE_PATH_PATTERN = /['"]([^'"]+)['"]/g;
|
|
2539
|
+
const extractTestSetupFiles = (directory) => {
|
|
2540
|
+
const entries = [];
|
|
2541
|
+
const configPaths = fg.sync([
|
|
2542
|
+
"vitest.config.{ts,js,mts,mjs}",
|
|
2543
|
+
"vitest.web.config.{ts,js,mts,mjs}",
|
|
2544
|
+
"vite.config.{ts,js,mts,mjs}",
|
|
2545
|
+
"jest.config.{ts,js,mjs,cjs}",
|
|
2546
|
+
"**/vitest.config.{ts,js,mts,mjs}"
|
|
2547
|
+
], {
|
|
2548
|
+
cwd: directory,
|
|
2549
|
+
absolute: true,
|
|
2550
|
+
onlyFiles: true,
|
|
2551
|
+
ignore: ["**/node_modules/**"],
|
|
2552
|
+
deep: 3
|
|
2553
|
+
});
|
|
2554
|
+
for (const configPath of configPaths) try {
|
|
2555
|
+
const content = readFileSync(configPath, "utf-8");
|
|
2556
|
+
const configDirectory = configPath.replace(/\/[^/]+$/, "");
|
|
2557
|
+
let setupMatch;
|
|
2558
|
+
SETUP_FILES_PATTERN.lastIndex = 0;
|
|
2559
|
+
while ((setupMatch = SETUP_FILES_PATTERN.exec(content)) !== null) {
|
|
2560
|
+
const arrayContent = setupMatch[1];
|
|
2561
|
+
const singleValue = setupMatch[2];
|
|
2562
|
+
if (singleValue) {
|
|
2563
|
+
const resolvedPath = resolveEntryWithExtensions(resolve(configDirectory, singleValue));
|
|
2564
|
+
if (resolvedPath) entries.push(resolvedPath);
|
|
2565
|
+
}
|
|
2566
|
+
if (arrayContent) {
|
|
2567
|
+
let pathMatch;
|
|
2568
|
+
SETUP_FILE_PATH_PATTERN.lastIndex = 0;
|
|
2569
|
+
while ((pathMatch = SETUP_FILE_PATH_PATTERN.exec(arrayContent)) !== null) {
|
|
2570
|
+
const resolvedPath = resolveEntryWithExtensions(resolve(configDirectory, pathMatch[1]));
|
|
2571
|
+
if (resolvedPath) entries.push(resolvedPath);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
} catch {}
|
|
2576
|
+
return entries;
|
|
2577
|
+
};
|
|
2578
|
+
const IMPORTABLE_EXTENSION_SET = new Set(SOURCE_EXTENSIONS$3.map((extension) => `.${extension}`));
|
|
2579
|
+
const isImportableSourceFile = (filePath) => IMPORTABLE_EXTENSION_SET.has(filePath.slice(filePath.lastIndexOf(".")));
|
|
2580
|
+
const expandWildcardExportPattern = (pattern, rootDir) => {
|
|
2581
|
+
const normalized = pattern.startsWith("./") ? pattern.slice(2) : pattern;
|
|
2582
|
+
return fg.sync(normalized, {
|
|
2583
|
+
cwd: rootDir,
|
|
2584
|
+
absolute: true,
|
|
2585
|
+
onlyFiles: true,
|
|
2586
|
+
ignore: ["**/node_modules/**"]
|
|
2587
|
+
}).filter(isImportableSourceFile);
|
|
2588
|
+
};
|
|
2589
|
+
const collectExportPaths = (exportValue, rootDir, entries) => {
|
|
2590
|
+
if (typeof exportValue === "string") {
|
|
2591
|
+
if (exportValue.includes("*")) {
|
|
2592
|
+
const expandedFiles = expandWildcardExportPattern(exportValue, rootDir);
|
|
2593
|
+
entries.push(...expandedFiles);
|
|
2594
|
+
return;
|
|
2595
|
+
}
|
|
2596
|
+
entries.push(resolveEntryPath(exportValue, rootDir));
|
|
2597
|
+
return;
|
|
2598
|
+
}
|
|
2599
|
+
if (typeof exportValue !== "object" || exportValue === null) return;
|
|
2600
|
+
for (const [, nestedValue] of Object.entries(exportValue)) collectExportPaths(nestedValue, rootDir, entries);
|
|
2601
|
+
};
|
|
2602
|
+
const TEST_FRAMEWORK_PATTERNS = [
|
|
2603
|
+
{
|
|
2604
|
+
enablers: [
|
|
2605
|
+
"vitest",
|
|
2606
|
+
"@vitest/runner",
|
|
2607
|
+
"vite-plus"
|
|
2608
|
+
],
|
|
2609
|
+
configFileActivators: [
|
|
2610
|
+
"vitest.config.ts",
|
|
2611
|
+
"vitest.config.js",
|
|
2612
|
+
"vitest.config.mts",
|
|
2613
|
+
"vitest.config.mjs"
|
|
2614
|
+
],
|
|
2615
|
+
entryPatterns: [
|
|
2616
|
+
"**/*.test.{ts,tsx,js,jsx}",
|
|
2617
|
+
"**/*.spec.{ts,tsx,js,jsx}",
|
|
2618
|
+
"**/__tests__/**/*.{ts,tsx,js,jsx}",
|
|
2619
|
+
"**/*.bench.{ts,tsx,js,jsx}"
|
|
2620
|
+
],
|
|
2621
|
+
fixturePatterns: ["**/__fixtures__/**/*.{ts,tsx,js,jsx,json}", "**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
|
|
2622
|
+
alwaysUsed: [
|
|
2623
|
+
"vitest.config.{ts,js,mts,mjs}",
|
|
2624
|
+
"vitest.setup.{ts,js}",
|
|
2625
|
+
"vitest.workspace.{ts,js}",
|
|
2626
|
+
"**/src/setupTests.{ts,tsx,js,jsx}",
|
|
2627
|
+
"**/src/test-setup.{ts,tsx,js,jsx}"
|
|
2628
|
+
]
|
|
2629
|
+
},
|
|
2630
|
+
{
|
|
2631
|
+
enablers: [
|
|
2632
|
+
"jest",
|
|
2633
|
+
"@jest/core",
|
|
2634
|
+
"ts-jest",
|
|
2635
|
+
"react-scripts",
|
|
2636
|
+
"react-app-rewired"
|
|
2637
|
+
],
|
|
2638
|
+
configFileActivators: [
|
|
2639
|
+
"jest.config.ts",
|
|
2640
|
+
"jest.config.js",
|
|
2641
|
+
"jest.config.mjs",
|
|
2642
|
+
"jest.config.cjs"
|
|
2643
|
+
],
|
|
2644
|
+
entryPatterns: [
|
|
2645
|
+
"**/*.test.{ts,tsx,js,jsx}",
|
|
2646
|
+
"**/*.spec.{ts,tsx,js,jsx}",
|
|
2647
|
+
"**/__tests__/**/*.{ts,tsx,js,jsx}",
|
|
2648
|
+
"**/__mocks__/**/*.{ts,tsx,js,jsx,mjs,cjs}"
|
|
2649
|
+
],
|
|
2650
|
+
fixturePatterns: ["**/__fixtures__/**/*.{ts,tsx,js,jsx,json}", "**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
|
|
2651
|
+
alwaysUsed: ["jest.config.{ts,js,mjs,cjs}", "jest.setup.{ts,js,tsx,jsx}"]
|
|
2652
|
+
},
|
|
2653
|
+
{
|
|
2654
|
+
enablers: ["@playwright/test", "playwright"],
|
|
2655
|
+
configFileActivators: ["playwright.config.ts", "playwright.config.js"],
|
|
2656
|
+
entryPatterns: [
|
|
2657
|
+
"**/*.spec.{ts,tsx,js,jsx}",
|
|
2658
|
+
"**/*.test.{ts,tsx,js,jsx}",
|
|
2659
|
+
"tests/**/*.{ts,tsx,js,jsx}",
|
|
2660
|
+
"e2e/**/*.{ts,tsx,js,jsx}"
|
|
2661
|
+
],
|
|
2662
|
+
fixturePatterns: ["**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
|
|
2663
|
+
alwaysUsed: ["playwright.config.{ts,js}"]
|
|
2664
|
+
},
|
|
2665
|
+
{
|
|
2666
|
+
enablers: ["mocha"],
|
|
2667
|
+
configFileActivators: [
|
|
2668
|
+
".mocharc.js",
|
|
2669
|
+
".mocharc.yaml",
|
|
2670
|
+
".mocharc.yml",
|
|
2671
|
+
".mocharc.json"
|
|
2672
|
+
],
|
|
2673
|
+
entryPatterns: [
|
|
2674
|
+
"test/**/*.{ts,tsx,js,jsx}",
|
|
2675
|
+
"tests/**/*.{ts,tsx,js,jsx}",
|
|
2676
|
+
"spec/**/*.{ts,tsx,js,jsx}",
|
|
2677
|
+
"**/*.test.{ts,tsx,js,jsx}",
|
|
2678
|
+
"**/*.spec.{ts,tsx,js,jsx}"
|
|
2679
|
+
],
|
|
2680
|
+
fixturePatterns: [],
|
|
2681
|
+
alwaysUsed: [".mocharc.*"]
|
|
2682
|
+
},
|
|
2683
|
+
{
|
|
2684
|
+
enablers: ["ava", "@ava/typescript"],
|
|
2685
|
+
configFileActivators: [
|
|
2686
|
+
"ava.config.js",
|
|
2687
|
+
"ava.config.cjs",
|
|
2688
|
+
"ava.config.mjs"
|
|
2689
|
+
],
|
|
2690
|
+
entryPatterns: [
|
|
2691
|
+
"test/**/*.{ts,tsx,js,jsx}",
|
|
2692
|
+
"tests/**/*.{ts,tsx,js,jsx}",
|
|
2693
|
+
"**/*.test.{ts,tsx,js,jsx}",
|
|
2694
|
+
"**/*.spec.{ts,tsx,js,jsx}"
|
|
2695
|
+
],
|
|
2696
|
+
fixturePatterns: [],
|
|
2697
|
+
alwaysUsed: ["ava.config.{js,cjs,mjs}"]
|
|
2698
|
+
},
|
|
2699
|
+
{
|
|
2700
|
+
enablers: ["cypress"],
|
|
2701
|
+
configFileActivators: ["cypress.config.ts", "cypress.config.js"],
|
|
2702
|
+
entryPatterns: [
|
|
2703
|
+
"**/*.cy.{ts,tsx,js,jsx}",
|
|
2704
|
+
"cypress/**/*.{ts,tsx,js,jsx}",
|
|
2705
|
+
"cypress/support/**/*.{ts,js}"
|
|
2706
|
+
],
|
|
2707
|
+
fixturePatterns: ["**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
|
|
2708
|
+
alwaysUsed: ["cypress.config.{ts,js}", "cypress.config.*.{ts,js}"]
|
|
2709
|
+
}
|
|
2710
|
+
];
|
|
2711
|
+
const JS_TS_COMPONENT_EXTENSIONS = "{ts,tsx,js,jsx}";
|
|
2712
|
+
const INERTIA_COMPONENT_EXTENSIONS = "{ts,tsx,js,jsx,vue,svelte}";
|
|
2713
|
+
const VIKE_ROUTE_EXTENSIONS = "{ts,tsx,js,jsx,md,mdx}";
|
|
2714
|
+
const FRAMEWORK_PATTERNS = [
|
|
2715
|
+
{
|
|
2716
|
+
enablers: ["storybook"],
|
|
2717
|
+
enablerPrefixes: ["@storybook/"],
|
|
2718
|
+
entryPatterns: ["**/*.stories.{ts,tsx,js,jsx,mdx}", ".storybook/**/*.{ts,tsx,js,jsx}"],
|
|
2719
|
+
alwaysUsed: [
|
|
2720
|
+
".storybook/main.{ts,js,mjs,cjs}",
|
|
2721
|
+
".storybook/preview.{ts,tsx,js,jsx}",
|
|
2722
|
+
".storybook/manager.{ts,tsx,js,jsx}"
|
|
2723
|
+
]
|
|
2724
|
+
},
|
|
2725
|
+
{
|
|
2726
|
+
enablers: ["msw"],
|
|
2727
|
+
enablerPrefixes: [],
|
|
2728
|
+
entryPatterns: [
|
|
2729
|
+
"mocks/**/*.{ts,tsx,js,jsx}",
|
|
2730
|
+
"src/mocks/**/*.{ts,tsx,js,jsx}",
|
|
2731
|
+
"**/mocks/**/*.{ts,tsx,js,jsx}"
|
|
2732
|
+
],
|
|
2733
|
+
alwaysUsed: []
|
|
2734
|
+
},
|
|
2735
|
+
{
|
|
2736
|
+
enablers: ["typeorm"],
|
|
2737
|
+
enablerPrefixes: [],
|
|
2738
|
+
entryPatterns: [
|
|
2739
|
+
"migrations/**/*.{ts,js}",
|
|
2740
|
+
"src/migrations/**/*.{ts,js}",
|
|
2741
|
+
"src/migration/**/*.{ts,js}",
|
|
2742
|
+
"migration/**/*.{ts,js}",
|
|
2743
|
+
"src/entity/**/*.{ts,js}"
|
|
2744
|
+
],
|
|
2745
|
+
alwaysUsed: ["ormconfig.{ts,js,json}"]
|
|
2746
|
+
},
|
|
2747
|
+
{
|
|
2748
|
+
enablers: ["knex"],
|
|
2749
|
+
enablerPrefixes: [],
|
|
2750
|
+
entryPatterns: ["migrations/**/*.{ts,js}", "seeds/**/*.{ts,js}"],
|
|
2751
|
+
alwaysUsed: ["knexfile.{ts,js}"]
|
|
2752
|
+
},
|
|
2753
|
+
{
|
|
2754
|
+
enablers: ["drizzle-orm"],
|
|
2755
|
+
enablerPrefixes: [],
|
|
2756
|
+
entryPatterns: ["drizzle/**/*.{ts,js}"],
|
|
2757
|
+
alwaysUsed: ["drizzle.config.{ts,js,mjs}"]
|
|
2758
|
+
},
|
|
2759
|
+
{
|
|
2760
|
+
enablers: ["kysely"],
|
|
2761
|
+
enablerPrefixes: [],
|
|
2762
|
+
entryPatterns: ["migrations/**/*.{ts,js}", "src/migrations/**/*.{ts,js}"],
|
|
2763
|
+
alwaysUsed: []
|
|
2764
|
+
},
|
|
2765
|
+
{
|
|
2766
|
+
enablers: ["prisma", "@prisma/client"],
|
|
2767
|
+
enablerPrefixes: [],
|
|
2768
|
+
entryPatterns: ["prisma/**/*.{ts,js}", "prisma/seed.{ts,js}"],
|
|
2769
|
+
alwaysUsed: [
|
|
2770
|
+
"prisma/schema.prisma",
|
|
2771
|
+
"schema.prisma",
|
|
2772
|
+
"prisma/schema/*.prisma",
|
|
2773
|
+
"prisma.config.{ts,mts,cts,js,mjs,cjs}",
|
|
2774
|
+
".config/prisma.{ts,mts,cts,js,mjs,cjs}"
|
|
2775
|
+
]
|
|
2776
|
+
},
|
|
2777
|
+
{
|
|
2778
|
+
enablers: ["@nestjs/core"],
|
|
2779
|
+
enablerPrefixes: ["@nestjs/"],
|
|
2780
|
+
entryPatterns: [
|
|
2781
|
+
"src/main.ts",
|
|
2782
|
+
"src/**/*.module.ts",
|
|
2783
|
+
"src/**/*.controller.ts",
|
|
2784
|
+
"src/**/*.service.ts",
|
|
2785
|
+
"src/**/*.guard.ts",
|
|
2786
|
+
"src/**/*.interceptor.ts",
|
|
2787
|
+
"src/**/*.pipe.ts",
|
|
2788
|
+
"src/**/*.filter.ts",
|
|
2789
|
+
"src/**/*.middleware.ts",
|
|
2790
|
+
"src/**/*.decorator.ts",
|
|
2791
|
+
"src/**/*.gateway.ts",
|
|
2792
|
+
"src/**/*.resolver.ts"
|
|
2793
|
+
],
|
|
2794
|
+
alwaysUsed: ["nest-cli.json"]
|
|
2795
|
+
},
|
|
2796
|
+
{
|
|
2797
|
+
enablers: ["wrangler"],
|
|
2798
|
+
enablerPrefixes: ["@cloudflare/"],
|
|
2799
|
+
entryPatterns: [
|
|
2800
|
+
"src/index.{ts,js}",
|
|
2801
|
+
"src/worker.{ts,js}",
|
|
2802
|
+
"functions/**/*.{ts,js}"
|
|
2803
|
+
],
|
|
2804
|
+
alwaysUsed: []
|
|
2805
|
+
},
|
|
2806
|
+
{
|
|
2807
|
+
enablers: ["gatsby"],
|
|
2808
|
+
enablerPrefixes: ["gatsby-"],
|
|
2809
|
+
entryPatterns: [
|
|
2810
|
+
"src/pages/**/*.{ts,tsx,js,jsx}",
|
|
2811
|
+
"src/templates/**/*.{ts,tsx,js,jsx}",
|
|
2812
|
+
"src/api/**/*.{ts,js}"
|
|
2813
|
+
],
|
|
2814
|
+
alwaysUsed: [
|
|
2815
|
+
"gatsby-config.{ts,js,mjs}",
|
|
2816
|
+
"gatsby-node.{ts,js,mjs}",
|
|
2817
|
+
"gatsby-browser.{ts,tsx,js,jsx}",
|
|
2818
|
+
"gatsby-ssr.{ts,tsx,js,jsx}"
|
|
2819
|
+
]
|
|
2820
|
+
},
|
|
2821
|
+
{
|
|
2822
|
+
enablers: ["@angular/core"],
|
|
2823
|
+
enablerPrefixes: ["@angular/"],
|
|
2824
|
+
entryPatterns: [
|
|
2825
|
+
"src/main.ts",
|
|
2826
|
+
"src/app/**/*.ts",
|
|
2827
|
+
"src/environments/**/*.ts",
|
|
2828
|
+
"src/polyfills.ts",
|
|
2829
|
+
"src/test.ts"
|
|
2830
|
+
],
|
|
2831
|
+
alwaysUsed: ["angular.json", "**/karma.conf.js"]
|
|
2832
|
+
},
|
|
2833
|
+
{
|
|
2834
|
+
enablers: [
|
|
2835
|
+
"@inertiajs/react",
|
|
2836
|
+
"@inertiajs/inertia-react",
|
|
2837
|
+
"@inertiajs/vue3",
|
|
2838
|
+
"@inertiajs/inertia-vue3",
|
|
2839
|
+
"@inertiajs/svelte",
|
|
2840
|
+
"@inertiajs/inertia-svelte",
|
|
2841
|
+
"@inertiajs/inertia"
|
|
2842
|
+
],
|
|
2843
|
+
enablerPrefixes: [],
|
|
2844
|
+
entryPatterns: [
|
|
2845
|
+
`resources/js/app.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2846
|
+
`resources/js/App.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2847
|
+
`resources/js/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2848
|
+
`resources/js/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2849
|
+
`app/frontend/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2850
|
+
`app/frontend/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2851
|
+
`app/frontend/entrypoints/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2852
|
+
`app/javascript/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2853
|
+
`app/javascript/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2854
|
+
`frontend/src/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2855
|
+
`frontend/src/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2856
|
+
`inertia/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2857
|
+
`inertia/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2858
|
+
`src/app.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2859
|
+
`src/App.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2860
|
+
`src/Pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`,
|
|
2861
|
+
`src/pages/**/*.${INERTIA_COMPONENT_EXTENSIONS}`
|
|
2862
|
+
],
|
|
2863
|
+
alwaysUsed: []
|
|
2864
|
+
},
|
|
2865
|
+
{
|
|
2866
|
+
enablers: ["@redwoodjs/router", "@redwoodjs/web"],
|
|
2867
|
+
enablerPrefixes: [],
|
|
2868
|
+
entryPatterns: [
|
|
2869
|
+
`web/src/App.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
2870
|
+
`web/src/Routes.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
2871
|
+
`web/src/index.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
2872
|
+
`web/src/layouts/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
2873
|
+
`web/src/pages/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
|
|
2874
|
+
],
|
|
2875
|
+
alwaysUsed: []
|
|
2876
|
+
},
|
|
2877
|
+
{
|
|
2878
|
+
enablers: ["react-scripts", "react-app-rewired"],
|
|
2879
|
+
enablerPrefixes: [],
|
|
2880
|
+
entryPatterns: ["src/index.{ts,tsx,js,jsx}"],
|
|
2881
|
+
alwaysUsed: [
|
|
2882
|
+
"src/setupTests.{ts,tsx,js,jsx}",
|
|
2883
|
+
"src/reportWebVitals.{ts,tsx,js,jsx}",
|
|
2884
|
+
"src/react-app-env.d.ts"
|
|
2885
|
+
]
|
|
2886
|
+
},
|
|
2887
|
+
{
|
|
2888
|
+
enablers: [
|
|
2889
|
+
"@remix-run/node",
|
|
2890
|
+
"@remix-run/react",
|
|
2891
|
+
"@remix-run/cloudflare",
|
|
2892
|
+
"@react-router/node",
|
|
2893
|
+
"@react-router/serve",
|
|
2894
|
+
"@react-router/dev"
|
|
2895
|
+
],
|
|
2896
|
+
enablerPrefixes: ["@remix-run/", "@react-router/"],
|
|
2897
|
+
entryPatterns: [
|
|
2898
|
+
"app/routes/**/*.{ts,tsx,js,jsx}",
|
|
2899
|
+
"app/root.{ts,tsx,js,jsx}",
|
|
2900
|
+
"app/entry.client.{ts,tsx,js,jsx}",
|
|
2901
|
+
"app/entry.server.{ts,tsx,js,jsx}",
|
|
2902
|
+
"app/routes.{ts,js,mts,mjs}",
|
|
2903
|
+
"src/routes.{ts,js,mts,mjs}"
|
|
2904
|
+
],
|
|
2905
|
+
alwaysUsed: ["react-router.config.{ts,js,mjs}", "remix.config.{ts,js,mjs}"]
|
|
2906
|
+
},
|
|
2907
|
+
{
|
|
2908
|
+
enablers: ["@docusaurus/core"],
|
|
2909
|
+
enablerPrefixes: ["@docusaurus/"],
|
|
2910
|
+
entryPatterns: [
|
|
2911
|
+
"**/*.{md,mdx}",
|
|
2912
|
+
"src/pages/**/*.{ts,tsx,js,jsx}",
|
|
2913
|
+
"src/theme/**/*.{ts,tsx,js,jsx}",
|
|
2914
|
+
"src/theme/**/index.{ts,tsx,js,jsx}",
|
|
2915
|
+
"plugins/**/*.{ts,js,mjs}"
|
|
2916
|
+
],
|
|
2917
|
+
alwaysUsed: [
|
|
2918
|
+
"docusaurus.config.{ts,js,mjs}",
|
|
2919
|
+
"sidebars.{ts,js,mjs,cjs}",
|
|
2920
|
+
"sidebar*.{ts,js,mjs,cjs}",
|
|
2921
|
+
"*-sidebar.{ts,js,mjs,cjs}",
|
|
2922
|
+
"*-sidebars.{ts,js,mjs,cjs}",
|
|
2923
|
+
"*Sidebar*.{ts,js,mjs,cjs}",
|
|
2924
|
+
"*sidebar*.{ts,js,mjs,cjs}"
|
|
2925
|
+
],
|
|
2926
|
+
contentIgnorePatterns: ["versioned_sidebars/**"]
|
|
2927
|
+
},
|
|
2928
|
+
{
|
|
2929
|
+
enablers: [
|
|
2930
|
+
"fumadocs-core",
|
|
2931
|
+
"fumadocs-ui",
|
|
2932
|
+
"fumadocs-mdx"
|
|
2933
|
+
],
|
|
2934
|
+
enablerPrefixes: ["fumadocs-"],
|
|
2935
|
+
entryPatterns: ["content/**/*.{md,mdx}", "content/**/*.{ts,tsx,js,jsx}"],
|
|
2936
|
+
alwaysUsed: ["source.config.{ts,js,mjs}"]
|
|
2937
|
+
},
|
|
2938
|
+
{
|
|
2939
|
+
enablers: [
|
|
2940
|
+
"nextra",
|
|
2941
|
+
"nextra-theme-docs",
|
|
2942
|
+
"nextra-theme-blog"
|
|
2943
|
+
],
|
|
2944
|
+
enablerPrefixes: ["nextra-"],
|
|
2945
|
+
entryPatterns: [
|
|
2946
|
+
"pages/**/*.{md,mdx}",
|
|
2947
|
+
"src/pages/**/*.{md,mdx}",
|
|
2948
|
+
"content/**/*.{md,mdx}"
|
|
2949
|
+
],
|
|
2950
|
+
alwaysUsed: []
|
|
2951
|
+
},
|
|
2952
|
+
{
|
|
2953
|
+
enablers: [
|
|
2954
|
+
"contentlayer",
|
|
2955
|
+
"contentlayer2",
|
|
2956
|
+
"contentlayer-source-files"
|
|
2957
|
+
],
|
|
2958
|
+
enablerPrefixes: ["contentlayer"],
|
|
2959
|
+
entryPatterns: ["content/**/*.{md,mdx}", "posts/**/*.{md,mdx}"],
|
|
2960
|
+
alwaysUsed: ["contentlayer.config.{ts,js,mjs}"]
|
|
2961
|
+
},
|
|
2962
|
+
{
|
|
2963
|
+
enablers: ["@graphql-codegen/cli", "@graphql-codegen/core"],
|
|
2964
|
+
enablerPrefixes: ["@graphql-codegen/"],
|
|
2965
|
+
entryPatterns: ["**/*.graphql", "**/*.gql"],
|
|
2966
|
+
alwaysUsed: [
|
|
2967
|
+
"codegen.{ts,js,yml,yaml}",
|
|
2968
|
+
"codegen.config.{ts,js}",
|
|
2969
|
+
".graphqlrc.{ts,js,json,yml,yaml}",
|
|
2970
|
+
"graphql.config.{ts,js,json,yml,yaml}"
|
|
2971
|
+
]
|
|
2972
|
+
},
|
|
2973
|
+
{
|
|
2974
|
+
enablers: ["eslint", "@eslint/js"],
|
|
2975
|
+
enablerPrefixes: [],
|
|
2976
|
+
entryPatterns: [],
|
|
2977
|
+
alwaysUsed: ["eslint.config.{js,mjs,cjs,ts,mts,cts}", ".eslintrc.{js,cjs,mjs,json,yaml,yml}"]
|
|
2978
|
+
},
|
|
2979
|
+
{
|
|
2980
|
+
enablers: ["prettier"],
|
|
2981
|
+
enablerPrefixes: [],
|
|
2982
|
+
entryPatterns: [],
|
|
2983
|
+
alwaysUsed: [".prettierrc.{js,cjs,mjs,json,yaml,yml}", "prettier.config.{js,mjs,cjs,ts}"]
|
|
2984
|
+
},
|
|
2985
|
+
{
|
|
2986
|
+
enablers: ["tailwindcss", "@tailwindcss/postcss"],
|
|
2987
|
+
enablerPrefixes: [],
|
|
2988
|
+
entryPatterns: [],
|
|
2989
|
+
alwaysUsed: ["tailwind.config.{ts,js,cjs,mjs}"]
|
|
2990
|
+
},
|
|
2991
|
+
{
|
|
2992
|
+
enablers: ["postcss"],
|
|
2993
|
+
enablerPrefixes: [],
|
|
2994
|
+
entryPatterns: [],
|
|
2995
|
+
alwaysUsed: ["postcss.config.{ts,js,cjs,mjs}"]
|
|
2996
|
+
},
|
|
2997
|
+
{
|
|
2998
|
+
enablers: ["typescript"],
|
|
2999
|
+
enablerPrefixes: [],
|
|
3000
|
+
entryPatterns: [],
|
|
3001
|
+
alwaysUsed: ["tsconfig.json", "tsconfig.*.json"]
|
|
3002
|
+
},
|
|
3003
|
+
{
|
|
3004
|
+
enablers: ["lint-staged"],
|
|
3005
|
+
enablerPrefixes: [],
|
|
3006
|
+
entryPatterns: [],
|
|
3007
|
+
alwaysUsed: [".lintstagedrc.{js,cjs,mjs,json}", "lint-staged.config.{js,mjs,cjs}"]
|
|
3008
|
+
},
|
|
3009
|
+
{
|
|
3010
|
+
enablers: ["husky"],
|
|
3011
|
+
enablerPrefixes: [],
|
|
3012
|
+
entryPatterns: [],
|
|
3013
|
+
alwaysUsed: [".husky/**/*"]
|
|
3014
|
+
},
|
|
3015
|
+
{
|
|
3016
|
+
enablers: ["@biomejs/biome"],
|
|
3017
|
+
enablerPrefixes: [],
|
|
3018
|
+
entryPatterns: [],
|
|
3019
|
+
alwaysUsed: ["biome.json", "biome.jsonc"]
|
|
3020
|
+
},
|
|
3021
|
+
{
|
|
3022
|
+
enablers: ["@commitlint/cli"],
|
|
3023
|
+
enablerPrefixes: [],
|
|
3024
|
+
entryPatterns: [],
|
|
3025
|
+
alwaysUsed: ["commitlint.config.{js,cjs,mjs,ts}", ".commitlintrc.{js,cjs,mjs,json,yaml,yml}"]
|
|
3026
|
+
},
|
|
3027
|
+
{
|
|
3028
|
+
enablers: ["semantic-release"],
|
|
3029
|
+
enablerPrefixes: [],
|
|
3030
|
+
entryPatterns: [],
|
|
3031
|
+
alwaysUsed: [".releaserc.{js,cjs,mjs,json,yaml,yml}", "release.config.{js,cjs,mjs,ts}"]
|
|
3032
|
+
},
|
|
3033
|
+
{
|
|
3034
|
+
enablers: ["@changesets/cli"],
|
|
3035
|
+
enablerPrefixes: [],
|
|
3036
|
+
entryPatterns: [],
|
|
3037
|
+
alwaysUsed: [".changeset/**/*"]
|
|
3038
|
+
},
|
|
3039
|
+
{
|
|
3040
|
+
enablers: ["next"],
|
|
3041
|
+
enablerPrefixes: [],
|
|
3042
|
+
entryPatterns: [
|
|
3043
|
+
"app/**/page.{ts,tsx,js,jsx}",
|
|
3044
|
+
"app/**/layout.{ts,tsx,js,jsx}",
|
|
3045
|
+
"app/**/loading.{ts,tsx,js,jsx}",
|
|
3046
|
+
"app/**/error.{ts,tsx,js,jsx}",
|
|
3047
|
+
"app/**/not-found.{ts,tsx,js,jsx}",
|
|
3048
|
+
"app/**/template.{ts,tsx,js,jsx}",
|
|
3049
|
+
"app/**/default.{ts,tsx,js,jsx}",
|
|
3050
|
+
"app/**/route.{ts,tsx,js,jsx}",
|
|
3051
|
+
"app/**/global-error.{ts,tsx,js,jsx}",
|
|
3052
|
+
"app/**/forbidden.{ts,tsx,js,jsx}",
|
|
3053
|
+
"app/**/unauthorized.{ts,tsx,js,jsx}",
|
|
3054
|
+
"app/global-not-found.{ts,tsx,js,jsx}",
|
|
3055
|
+
"app/**/opengraph-image.{ts,tsx,js,jsx}",
|
|
3056
|
+
"app/**/twitter-image.{ts,tsx,js,jsx}",
|
|
3057
|
+
"app/**/icon.{ts,tsx,js,jsx}",
|
|
3058
|
+
"app/**/apple-icon.{ts,tsx,js,jsx}",
|
|
3059
|
+
"app/**/manifest.{ts,tsx,js,jsx}",
|
|
3060
|
+
"app/**/sitemap.{ts,tsx,js,jsx}",
|
|
3061
|
+
"app/**/robots.{ts,tsx,js,jsx}",
|
|
3062
|
+
"pages/**/*.{ts,tsx,js,jsx}",
|
|
3063
|
+
"src/app/**/page.{ts,tsx,js,jsx}",
|
|
3064
|
+
"src/app/**/layout.{ts,tsx,js,jsx}",
|
|
3065
|
+
"src/app/**/loading.{ts,tsx,js,jsx}",
|
|
3066
|
+
"src/app/**/error.{ts,tsx,js,jsx}",
|
|
3067
|
+
"src/app/**/not-found.{ts,tsx,js,jsx}",
|
|
3068
|
+
"src/app/**/template.{ts,tsx,js,jsx}",
|
|
3069
|
+
"src/app/**/default.{ts,tsx,js,jsx}",
|
|
3070
|
+
"src/app/**/route.{ts,tsx,js,jsx}",
|
|
3071
|
+
"src/app/**/global-error.{ts,tsx,js,jsx}",
|
|
3072
|
+
"src/app/**/forbidden.{ts,tsx,js,jsx}",
|
|
3073
|
+
"src/app/**/unauthorized.{ts,tsx,js,jsx}",
|
|
3074
|
+
"src/app/global-not-found.{ts,tsx,js,jsx}",
|
|
3075
|
+
"src/app/**/opengraph-image.{ts,tsx,js,jsx}",
|
|
3076
|
+
"src/app/**/twitter-image.{ts,tsx,js,jsx}",
|
|
3077
|
+
"src/app/**/icon.{ts,tsx,js,jsx}",
|
|
3078
|
+
"src/app/**/apple-icon.{ts,tsx,js,jsx}",
|
|
3079
|
+
"src/app/**/manifest.{ts,tsx,js,jsx}",
|
|
3080
|
+
"src/app/**/sitemap.{ts,tsx,js,jsx}",
|
|
3081
|
+
"src/app/**/robots.{ts,tsx,js,jsx}",
|
|
3082
|
+
"src/pages/**/*.{ts,tsx,js,jsx}",
|
|
3083
|
+
"middleware.{ts,js}",
|
|
3084
|
+
"src/middleware.{ts,js}",
|
|
3085
|
+
"proxy.{ts,js}",
|
|
3086
|
+
"src/proxy.{ts,js}",
|
|
3087
|
+
"instrumentation.{ts,js}",
|
|
3088
|
+
"instrumentation-client.{ts,js}",
|
|
3089
|
+
"src/instrumentation.{ts,js}",
|
|
3090
|
+
"src/instrumentation-client.{ts,js}"
|
|
3091
|
+
],
|
|
3092
|
+
alwaysUsed: [
|
|
3093
|
+
"next.config.{ts,js,mjs,mts}",
|
|
3094
|
+
"next-env.d.ts",
|
|
3095
|
+
"mdx-components.{ts,tsx,js,jsx}",
|
|
3096
|
+
"src/mdx-components.{ts,tsx,js,jsx}",
|
|
3097
|
+
"src/i18n/request.{ts,js}",
|
|
3098
|
+
"src/i18n/routing.{ts,js}",
|
|
3099
|
+
"i18n/request.{ts,js}",
|
|
3100
|
+
"i18n/routing.{ts,js}"
|
|
3101
|
+
]
|
|
3102
|
+
},
|
|
3103
|
+
{
|
|
3104
|
+
enablers: [
|
|
3105
|
+
"@tanstack/react-router",
|
|
3106
|
+
"@tanstack/react-start",
|
|
3107
|
+
"@tanstack/start",
|
|
3108
|
+
"@tanstack/solid-router",
|
|
3109
|
+
"@tanstack/solid-start"
|
|
3110
|
+
],
|
|
3111
|
+
enablerPrefixes: ["@tanstack/router"],
|
|
3112
|
+
entryPatterns: [
|
|
3113
|
+
"src/routes/**/*.{ts,tsx,js,jsx}",
|
|
3114
|
+
"app/routes/**/*.{ts,tsx,js,jsx}",
|
|
3115
|
+
"src/server.{ts,tsx,js,jsx}",
|
|
3116
|
+
"src/client.{ts,tsx,js,jsx}",
|
|
3117
|
+
"src/router.{ts,tsx,js,jsx}",
|
|
3118
|
+
"src/routeTree.gen.{ts,js}"
|
|
3119
|
+
],
|
|
3120
|
+
alwaysUsed: ["tsr.config.json", "app.config.{ts,js}"]
|
|
3121
|
+
},
|
|
3122
|
+
{
|
|
3123
|
+
enablers: ["waku"],
|
|
3124
|
+
enablerPrefixes: [],
|
|
3125
|
+
entryPatterns: [
|
|
3126
|
+
`src/pages/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
3127
|
+
`src/waku.client.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
3128
|
+
`src/waku.server.${JS_TS_COMPONENT_EXTENSIONS}`
|
|
3129
|
+
],
|
|
3130
|
+
alwaysUsed: []
|
|
3131
|
+
},
|
|
3132
|
+
{
|
|
3133
|
+
enablers: ["vike", "vite-plugin-ssr"],
|
|
3134
|
+
enablerPrefixes: [],
|
|
3135
|
+
entryPatterns: [
|
|
3136
|
+
`pages/**/*.${VIKE_ROUTE_EXTENSIONS}`,
|
|
3137
|
+
`renderer/**/*.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
3138
|
+
`src/pages/**/*.${VIKE_ROUTE_EXTENSIONS}`,
|
|
3139
|
+
`src/renderer/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
|
|
3140
|
+
],
|
|
3141
|
+
alwaysUsed: []
|
|
3142
|
+
},
|
|
3143
|
+
{
|
|
3144
|
+
enablers: ["rakkasjs"],
|
|
3145
|
+
enablerPrefixes: [],
|
|
3146
|
+
entryPatterns: [
|
|
3147
|
+
`src/client.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
3148
|
+
`src/server.${JS_TS_COMPONENT_EXTENSIONS}`,
|
|
3149
|
+
`src/routes/**/*.${JS_TS_COMPONENT_EXTENSIONS}`
|
|
3150
|
+
],
|
|
3151
|
+
alwaysUsed: []
|
|
3152
|
+
},
|
|
3153
|
+
{
|
|
3154
|
+
enablers: [
|
|
3155
|
+
"@module-federation/enhanced",
|
|
3156
|
+
"@module-federation/node",
|
|
3157
|
+
"@module-federation/vite",
|
|
3158
|
+
"@originjs/vite-plugin-federation"
|
|
3159
|
+
],
|
|
3160
|
+
enablerPrefixes: [],
|
|
3161
|
+
entryPatterns: ["federation.config.{ts,js,mjs,cjs,mts,cts}", "module-federation.config.{ts,js,mjs,cjs,mts,cts}"],
|
|
3162
|
+
alwaysUsed: []
|
|
3163
|
+
},
|
|
3164
|
+
{
|
|
3165
|
+
enablers: [
|
|
3166
|
+
"vite",
|
|
3167
|
+
"rolldown-vite",
|
|
3168
|
+
"vite-plus",
|
|
3169
|
+
"@voidzero-dev/vite-plus-core",
|
|
3170
|
+
"@voidzero-dev/vite-plus-test"
|
|
3171
|
+
],
|
|
3172
|
+
enablerPrefixes: ["@vitejs/", "@voidzero-dev/vite-plus"],
|
|
3173
|
+
entryPatterns: [
|
|
3174
|
+
"src/main.{ts,tsx,js,jsx}",
|
|
3175
|
+
"src/index.{ts,tsx,js,jsx}",
|
|
3176
|
+
"index.html"
|
|
3177
|
+
],
|
|
3178
|
+
alwaysUsed: ["vite.config.{ts,js,mts,mjs}"]
|
|
3179
|
+
},
|
|
3180
|
+
{
|
|
3181
|
+
enablers: ["vue", "@vue/cli-service"],
|
|
3182
|
+
enablerPrefixes: ["@vue/"],
|
|
3183
|
+
entryPatterns: ["src/main.{ts,js}", "src/App.vue"],
|
|
3184
|
+
alwaysUsed: ["vue.config.{ts,js,mjs,cjs}"]
|
|
3185
|
+
},
|
|
3186
|
+
{
|
|
3187
|
+
enablers: ["nuxt", "nuxt3"],
|
|
3188
|
+
enablerPrefixes: ["@nuxt/"],
|
|
3189
|
+
entryPatterns: [
|
|
3190
|
+
"pages/**/*.vue",
|
|
3191
|
+
"layouts/**/*.vue",
|
|
3192
|
+
"components/**/*.vue",
|
|
3193
|
+
"composables/**/*.{ts,js}",
|
|
3194
|
+
"plugins/**/*.{ts,js}",
|
|
3195
|
+
"middleware/**/*.{ts,js}",
|
|
3196
|
+
"server/**/*.{ts,js}",
|
|
3197
|
+
"app.vue"
|
|
3198
|
+
],
|
|
3199
|
+
alwaysUsed: ["nuxt.config.{ts,js,mjs}"]
|
|
3200
|
+
},
|
|
3201
|
+
{
|
|
3202
|
+
enablers: ["svelte", "@sveltejs/kit"],
|
|
3203
|
+
enablerPrefixes: ["@sveltejs/"],
|
|
3204
|
+
entryPatterns: [
|
|
3205
|
+
"src/routes/**/*.svelte",
|
|
3206
|
+
"src/lib/**/*.svelte",
|
|
3207
|
+
"src/routes/**/+page.{ts,js,svelte}",
|
|
3208
|
+
"src/routes/**/+layout.{ts,js,svelte}",
|
|
3209
|
+
"src/routes/**/+server.{ts,js}"
|
|
3210
|
+
],
|
|
3211
|
+
alwaysUsed: ["svelte.config.{ts,js,mjs}"]
|
|
3212
|
+
},
|
|
3213
|
+
{
|
|
3214
|
+
enablers: ["webpack", "webpack-cli"],
|
|
3215
|
+
enablerPrefixes: [],
|
|
3216
|
+
entryPatterns: [],
|
|
3217
|
+
alwaysUsed: ["webpack.config.{ts,js,mjs,cjs}", "webpack.*.config.{ts,js,mjs,cjs}"]
|
|
3218
|
+
},
|
|
3219
|
+
{
|
|
3220
|
+
enablers: ["rollup"],
|
|
3221
|
+
enablerPrefixes: [],
|
|
3222
|
+
entryPatterns: [],
|
|
3223
|
+
alwaysUsed: ["rollup.config.{ts,js,mjs,cjs}", "rollup.*.config.{ts,js,mjs,cjs}"]
|
|
3224
|
+
},
|
|
3225
|
+
{
|
|
3226
|
+
enablers: ["@rspack/core", "@rspack/cli"],
|
|
3227
|
+
enablerPrefixes: ["@rspack/"],
|
|
3228
|
+
entryPatterns: ["src/index.{ts,tsx,js,jsx}"],
|
|
3229
|
+
alwaysUsed: ["rspack.config.{ts,js,mjs,cjs}", "rspack.*.config.{ts,js,mjs,cjs}"]
|
|
3230
|
+
},
|
|
3231
|
+
{
|
|
3232
|
+
enablers: ["@rsbuild/core"],
|
|
3233
|
+
enablerPrefixes: ["@rsbuild/"],
|
|
3234
|
+
entryPatterns: ["src/index.{ts,tsx,js,jsx}"],
|
|
3235
|
+
alwaysUsed: ["rsbuild.config.{ts,js,mjs,cjs}"]
|
|
3236
|
+
},
|
|
3237
|
+
{
|
|
3238
|
+
enablers: ["tsup"],
|
|
3239
|
+
enablerPrefixes: [],
|
|
3240
|
+
entryPatterns: [],
|
|
3241
|
+
alwaysUsed: ["tsup.config.{ts,js,cjs,mjs}"]
|
|
3242
|
+
},
|
|
3243
|
+
{
|
|
3244
|
+
enablers: ["tsdown"],
|
|
3245
|
+
enablerPrefixes: [],
|
|
3246
|
+
entryPatterns: [],
|
|
3247
|
+
alwaysUsed: ["tsdown.config.{ts,js,cjs,mjs}"]
|
|
3248
|
+
},
|
|
3249
|
+
{
|
|
3250
|
+
enablers: ["@trigger.dev/sdk"],
|
|
3251
|
+
enablerPrefixes: ["@trigger.dev/"],
|
|
3252
|
+
entryPatterns: [],
|
|
3253
|
+
alwaysUsed: ["trigger.config.{ts,js,mjs,mts}"]
|
|
3254
|
+
},
|
|
3255
|
+
{
|
|
3256
|
+
enablers: ["@swc/core"],
|
|
3257
|
+
enablerPrefixes: [],
|
|
3258
|
+
entryPatterns: [],
|
|
3259
|
+
alwaysUsed: [".swcrc"]
|
|
3260
|
+
},
|
|
3261
|
+
{
|
|
3262
|
+
enablers: ["@babel/core"],
|
|
3263
|
+
enablerPrefixes: [],
|
|
3264
|
+
entryPatterns: [],
|
|
3265
|
+
alwaysUsed: ["babel.config.{js,cjs,mjs,json}", ".babelrc.{js,cjs,mjs,json}"]
|
|
3266
|
+
},
|
|
3267
|
+
{
|
|
3268
|
+
enablers: ["sanity", "@sanity/cli"],
|
|
3269
|
+
enablerPrefixes: ["@sanity/"],
|
|
3270
|
+
entryPatterns: [],
|
|
3271
|
+
alwaysUsed: ["sanity.config.{ts,js}", "sanity.cli.{ts,js}"]
|
|
3272
|
+
},
|
|
3273
|
+
{
|
|
3274
|
+
enablers: ["astro"],
|
|
3275
|
+
enablerPrefixes: ["@astrojs/"],
|
|
3276
|
+
entryPatterns: [
|
|
3277
|
+
"src/pages/**/*.{astro,ts,tsx,js,jsx,mts,mjs,cts,cjs,md,mdx}",
|
|
3278
|
+
"src/content/**/*.{ts,js,mts,mjs,cts,cjs,md,mdx}",
|
|
3279
|
+
"src/layouts/**/*.astro",
|
|
3280
|
+
"src/middleware.{js,ts,mjs,mts,cjs,cts}",
|
|
3281
|
+
"src/middleware/index.{js,ts,mjs,mts,cjs,cts}",
|
|
3282
|
+
"src/actions/index.{js,ts,mjs,mts,cjs,cts}"
|
|
3283
|
+
],
|
|
3284
|
+
alwaysUsed: [
|
|
3285
|
+
"astro.config.{ts,js,mjs,cjs}",
|
|
3286
|
+
"src/content/config.{js,ts,mjs,mts,cjs,cts}",
|
|
3287
|
+
"src/content.config.{js,ts,mjs,mts,cjs,cts}",
|
|
3288
|
+
"src/live.config.{js,ts,mjs,mts,cjs,cts}"
|
|
3289
|
+
]
|
|
3290
|
+
},
|
|
3291
|
+
{
|
|
3292
|
+
enablers: [
|
|
3293
|
+
"i18next",
|
|
3294
|
+
"react-i18next",
|
|
3295
|
+
"vue-i18n",
|
|
3296
|
+
"next-i18next"
|
|
3297
|
+
],
|
|
3298
|
+
enablerPrefixes: [],
|
|
3299
|
+
entryPatterns: [
|
|
3300
|
+
"src/i18n.{ts,js,mjs}",
|
|
3301
|
+
"src/i18n/index.{ts,js}",
|
|
3302
|
+
"i18n.{ts,js,mjs}",
|
|
3303
|
+
"i18n/index.{ts,js}"
|
|
3304
|
+
],
|
|
3305
|
+
alwaysUsed: [
|
|
3306
|
+
"src/i18n.{ts,js,mjs}",
|
|
3307
|
+
"src/i18n/index.{ts,js}",
|
|
3308
|
+
"i18n.{ts,js,mjs}",
|
|
3309
|
+
"i18n/index.{ts,js}",
|
|
3310
|
+
"i18next.config.{js,ts,mjs}",
|
|
3311
|
+
"next-i18next.config.{js,mjs}",
|
|
3312
|
+
"locales/**/*.json",
|
|
3313
|
+
"public/locales/**/*.json",
|
|
3314
|
+
"src/locales/**/*.json"
|
|
3315
|
+
]
|
|
3316
|
+
},
|
|
3317
|
+
{
|
|
3318
|
+
enablers: ["turbo"],
|
|
3319
|
+
enablerPrefixes: [],
|
|
3320
|
+
entryPatterns: [],
|
|
3321
|
+
alwaysUsed: ["turbo.json", "turbo/generators/config.{ts,js}"]
|
|
3322
|
+
},
|
|
3323
|
+
{
|
|
3324
|
+
enablers: [
|
|
3325
|
+
"@sentry/nextjs",
|
|
3326
|
+
"@sentry/react",
|
|
3327
|
+
"@sentry/node",
|
|
3328
|
+
"@sentry/browser"
|
|
3329
|
+
],
|
|
3330
|
+
enablerPrefixes: ["@sentry/"],
|
|
3331
|
+
entryPatterns: [],
|
|
3332
|
+
alwaysUsed: [
|
|
3333
|
+
"sentry.client.config.{ts,js,mjs}",
|
|
3334
|
+
"sentry.server.config.{ts,js,mjs}",
|
|
3335
|
+
"sentry.edge.config.{ts,js,mjs}"
|
|
3336
|
+
]
|
|
3337
|
+
},
|
|
3338
|
+
{
|
|
3339
|
+
enablers: ["nodemon"],
|
|
3340
|
+
enablerPrefixes: [],
|
|
3341
|
+
entryPatterns: [],
|
|
3342
|
+
alwaysUsed: [
|
|
3343
|
+
"nodemon.json",
|
|
3344
|
+
".nodemonrc",
|
|
3345
|
+
".nodemonrc.{json,yml,yaml}"
|
|
3346
|
+
]
|
|
3347
|
+
},
|
|
3348
|
+
{
|
|
3349
|
+
enablers: ["nx"],
|
|
3350
|
+
enablerPrefixes: ["@nx/"],
|
|
3351
|
+
entryPatterns: [],
|
|
3352
|
+
alwaysUsed: ["nx.json", "**/project.json"]
|
|
3353
|
+
},
|
|
3354
|
+
{
|
|
3355
|
+
enablers: ["react-native"],
|
|
3356
|
+
enablerPrefixes: ["@react-native/", "@react-native-community/"],
|
|
3357
|
+
entryPatterns: [
|
|
3358
|
+
"index.{ts,tsx,js,jsx}",
|
|
3359
|
+
"App.{ts,tsx,js,jsx}",
|
|
3360
|
+
"src/App.{ts,tsx,js,jsx}"
|
|
3361
|
+
],
|
|
3362
|
+
alwaysUsed: [
|
|
3363
|
+
"metro.config.{ts,js}",
|
|
3364
|
+
"react-native.config.{ts,js}",
|
|
3365
|
+
"app.json"
|
|
3366
|
+
]
|
|
3367
|
+
},
|
|
3368
|
+
{
|
|
3369
|
+
enablers: ["expo"],
|
|
3370
|
+
enablerPrefixes: ["@expo/"],
|
|
3371
|
+
entryPatterns: [
|
|
3372
|
+
"App.{ts,tsx,js,jsx}",
|
|
3373
|
+
"app/_layout.{ts,tsx,js,jsx}",
|
|
3374
|
+
"app/index.{ts,tsx,js,jsx}"
|
|
3375
|
+
],
|
|
3376
|
+
alwaysUsed: ["app.json", "app.config.{ts,mts,cts,js,mjs,cjs}"]
|
|
3377
|
+
},
|
|
3378
|
+
{
|
|
3379
|
+
enablers: ["wrangler"],
|
|
3380
|
+
enablerPrefixes: ["@cloudflare/"],
|
|
3381
|
+
entryPatterns: [
|
|
3382
|
+
"src/index.{ts,js}",
|
|
3383
|
+
"src/worker.{ts,js}",
|
|
3384
|
+
"functions/**/*.{ts,js}"
|
|
3385
|
+
],
|
|
3386
|
+
alwaysUsed: [
|
|
3387
|
+
"wrangler.toml",
|
|
3388
|
+
"wrangler.json",
|
|
3389
|
+
"wrangler.jsonc"
|
|
3390
|
+
]
|
|
3391
|
+
},
|
|
3392
|
+
{
|
|
3393
|
+
enablers: [
|
|
3394
|
+
"electron",
|
|
3395
|
+
"electron-builder",
|
|
3396
|
+
"@electron-forge/cli",
|
|
3397
|
+
"electron-vite",
|
|
3398
|
+
"electron-webpack",
|
|
3399
|
+
"electron-next"
|
|
3400
|
+
],
|
|
3401
|
+
enablerPrefixes: ["@electron-forge/", "@electron/"],
|
|
3402
|
+
entryPatterns: [
|
|
3403
|
+
"src/main/**/*.{ts,tsx,js,jsx}",
|
|
3404
|
+
"src/preload/**/*.{ts,tsx,js,jsx}",
|
|
3405
|
+
"electron/main.{ts,js}",
|
|
3406
|
+
"main/index.{ts,tsx,js,jsx}",
|
|
3407
|
+
"renderer/pages/**/*.{ts,tsx,js,jsx}"
|
|
3408
|
+
],
|
|
3409
|
+
alwaysUsed: [
|
|
3410
|
+
"electron-builder.{yml,yaml,json,json5,toml}",
|
|
3411
|
+
"forge.config.{ts,js,cjs}",
|
|
3412
|
+
"electron.vite.config.{ts,js,mjs}"
|
|
3413
|
+
]
|
|
3414
|
+
},
|
|
3415
|
+
{
|
|
3416
|
+
enablers: ["lefthook"],
|
|
3417
|
+
enablerPrefixes: [],
|
|
3418
|
+
entryPatterns: [],
|
|
3419
|
+
alwaysUsed: [
|
|
3420
|
+
"lefthook.yml",
|
|
3421
|
+
"lefthook.yaml",
|
|
3422
|
+
".lefthook.yml"
|
|
3423
|
+
]
|
|
3424
|
+
},
|
|
3425
|
+
{
|
|
3426
|
+
enablers: ["syncpack"],
|
|
3427
|
+
enablerPrefixes: [],
|
|
3428
|
+
entryPatterns: [],
|
|
3429
|
+
alwaysUsed: [
|
|
3430
|
+
".syncpackrc",
|
|
3431
|
+
".syncpackrc.{json,yaml,yml}",
|
|
3432
|
+
"syncpack.config.{js,mjs,cjs}"
|
|
3433
|
+
]
|
|
3434
|
+
},
|
|
3435
|
+
{
|
|
3436
|
+
enablers: ["@capacitor/core", "@capacitor/cli"],
|
|
3437
|
+
enablerPrefixes: ["@capacitor/"],
|
|
3438
|
+
entryPatterns: [],
|
|
3439
|
+
alwaysUsed: ["capacitor.config.{ts,js,json}"]
|
|
3440
|
+
}
|
|
3441
|
+
];
|
|
3442
|
+
const detectNodeTestRunner = (directory) => {
|
|
3443
|
+
try {
|
|
3444
|
+
const packageJsonPath = join(directory, "package.json");
|
|
3445
|
+
if (!existsSync(packageJsonPath)) return false;
|
|
3446
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
3447
|
+
const scripts = JSON.parse(content).scripts ?? {};
|
|
3448
|
+
return Object.values(scripts).some((scriptValue) => typeof scriptValue === "string" && /\bnode\b.*\s--test\b/.test(scriptValue));
|
|
3449
|
+
} catch {
|
|
3450
|
+
return false;
|
|
3451
|
+
}
|
|
3452
|
+
};
|
|
3453
|
+
const detectBunTestRunner = (directory) => {
|
|
3454
|
+
try {
|
|
3455
|
+
const packageJsonPath = join(directory, "package.json");
|
|
3456
|
+
if (!existsSync(packageJsonPath)) return false;
|
|
3457
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
3458
|
+
const scripts = JSON.parse(content).scripts ?? {};
|
|
3459
|
+
return Object.values(scripts).some((scriptValue) => typeof scriptValue === "string" && /\bbun\s+test\b/.test(scriptValue));
|
|
3460
|
+
} catch {
|
|
3461
|
+
return false;
|
|
3462
|
+
}
|
|
3463
|
+
};
|
|
3464
|
+
const readPackageJsonDependencies = (packageJsonPath) => {
|
|
3465
|
+
try {
|
|
3466
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
3467
|
+
const packageJson = JSON.parse(content);
|
|
3468
|
+
return {
|
|
3469
|
+
...packageJson.dependencies,
|
|
3470
|
+
...packageJson.devDependencies,
|
|
3471
|
+
...packageJson.optionalDependencies
|
|
3472
|
+
};
|
|
3473
|
+
} catch {
|
|
3474
|
+
return {};
|
|
3475
|
+
}
|
|
3476
|
+
};
|
|
3477
|
+
const discoverTestRunnerEntryPoints = (rootDir, workspacePackages) => {
|
|
3478
|
+
const allEntries = [];
|
|
3479
|
+
const allAlwaysUsed = [];
|
|
3480
|
+
const directoriesToCheck = [rootDir, ...workspacePackages.map((workspacePackage) => workspacePackage.directory)];
|
|
3481
|
+
const monorepoRoot = findMonorepoRoot(rootDir);
|
|
3482
|
+
const monorepoRootDeps = monorepoRoot && monorepoRoot !== rootDir ? readPackageJsonDependencies(join(monorepoRoot, "package.json")) : {};
|
|
3483
|
+
for (const directory of directoriesToCheck) {
|
|
3484
|
+
const packageJsonPath = join(directory, "package.json");
|
|
3485
|
+
if (!existsSync(packageJsonPath)) continue;
|
|
3486
|
+
let allDependencies = {};
|
|
3487
|
+
try {
|
|
3488
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
3489
|
+
const packageJson = JSON.parse(content);
|
|
3490
|
+
allDependencies = {
|
|
3491
|
+
...packageJson.dependencies,
|
|
3492
|
+
...packageJson.devDependencies,
|
|
3493
|
+
...packageJson.optionalDependencies
|
|
3494
|
+
};
|
|
3495
|
+
} catch {
|
|
3496
|
+
continue;
|
|
3497
|
+
}
|
|
3498
|
+
const activatedPatterns = [];
|
|
3499
|
+
const activatedFixturePatterns = [];
|
|
3500
|
+
const activatedAlwaysUsed = [];
|
|
3501
|
+
const isRunnerEnabled = (runner, dependencies, checkDirectory) => {
|
|
3502
|
+
if (runner.enablers.some((enabler) => {
|
|
3503
|
+
return enabler in dependencies;
|
|
3504
|
+
})) return true;
|
|
3505
|
+
return runner.configFileActivators.some((configFile) => existsSync(join(checkDirectory, configFile)));
|
|
3506
|
+
};
|
|
3507
|
+
for (const runner of TEST_FRAMEWORK_PATTERNS) {
|
|
3508
|
+
const enabledLocally = isRunnerEnabled(runner, allDependencies, directory);
|
|
3509
|
+
const enabledViaMonorepo = !enabledLocally && monorepoRoot && (isRunnerEnabled(runner, monorepoRootDeps, monorepoRoot) || runner.configFileActivators.some((configFile) => existsSync(join(monorepoRoot, configFile))));
|
|
3510
|
+
if (enabledLocally || enabledViaMonorepo) {
|
|
3511
|
+
const isVitestRunner = runner.enablers.includes("vitest");
|
|
3512
|
+
const isJestRunner = runner.enablers.includes("jest");
|
|
3513
|
+
let customPatterns = [];
|
|
3514
|
+
if (isVitestRunner) {
|
|
3515
|
+
customPatterns = extractVitestIncludePatterns(directory);
|
|
3516
|
+
if (customPatterns.length === 0 && monorepoRoot) customPatterns = extractVitestIncludePatterns(monorepoRoot);
|
|
3517
|
+
} else if (isJestRunner) {
|
|
3518
|
+
customPatterns = extractJestTestMatchPatterns(directory);
|
|
3519
|
+
if (customPatterns.length === 0 && monorepoRoot) customPatterns = extractJestTestMatchPatterns(monorepoRoot);
|
|
3520
|
+
}
|
|
3521
|
+
if (customPatterns.length > 0) activatedPatterns.push(...customPatterns);
|
|
3522
|
+
else activatedPatterns.push(...runner.entryPatterns);
|
|
3523
|
+
activatedFixturePatterns.push(...runner.fixturePatterns);
|
|
3524
|
+
activatedAlwaysUsed.push(...runner.alwaysUsed);
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
if (activatedPatterns.length === 0 && directory !== rootDir) {
|
|
3528
|
+
const rootPackageJsonPath = join(rootDir, "package.json");
|
|
3529
|
+
if (existsSync(rootPackageJsonPath)) try {
|
|
3530
|
+
const rootContent = readFileSync(rootPackageJsonPath, "utf-8");
|
|
3531
|
+
const rootPackageJson = JSON.parse(rootContent);
|
|
3532
|
+
const rootDeps = {
|
|
3533
|
+
...rootPackageJson.dependencies,
|
|
3534
|
+
...rootPackageJson.devDependencies,
|
|
3535
|
+
...rootPackageJson.optionalDependencies
|
|
3536
|
+
};
|
|
3537
|
+
for (const runner of TEST_FRAMEWORK_PATTERNS) if (isRunnerEnabled(runner, rootDeps, rootDir)) {
|
|
3538
|
+
activatedPatterns.push(...runner.entryPatterns);
|
|
3539
|
+
activatedFixturePatterns.push(...runner.fixturePatterns);
|
|
3540
|
+
activatedAlwaysUsed.push(...runner.alwaysUsed);
|
|
3541
|
+
}
|
|
3542
|
+
} catch {}
|
|
3543
|
+
}
|
|
3544
|
+
if (detectNodeTestRunner(directory) || detectNodeTestRunner(rootDir)) activatedPatterns.push("**/*.test.{ts,tsx,js,jsx,mts,mjs,cts,cjs}", "**/*.spec.{ts,tsx,js,jsx,mts,mjs,cts,cjs}", "**/__tests__/**/*.{ts,tsx,js,jsx,mts,mjs,cts,cjs}");
|
|
3545
|
+
if (detectBunTestRunner(directory) || detectBunTestRunner(rootDir)) activatedPatterns.push("**/*.test.{ts,tsx,js,jsx,mts,mjs}", "**/*.spec.{ts,tsx,js,jsx,mts,mjs}", "**/*_test.{ts,tsx,js,jsx,mts,mjs}", "**/*_spec.{ts,tsx,js,jsx,mts,mjs}", "**/__tests__/**/*.{ts,tsx,js,jsx,mts,mjs}");
|
|
3546
|
+
if (activatedPatterns.length === 0) continue;
|
|
3547
|
+
const uniquePatterns = [...new Set(activatedPatterns)];
|
|
3548
|
+
const testFiles = fg.sync(uniquePatterns, {
|
|
3549
|
+
cwd: directory,
|
|
3550
|
+
absolute: true,
|
|
3551
|
+
onlyFiles: true,
|
|
3552
|
+
ignore: ["**/node_modules/**", "**/*.gen.{ts,tsx,js,jsx}"]
|
|
3553
|
+
});
|
|
3554
|
+
allEntries.push(...testFiles);
|
|
3555
|
+
const uniqueFixturePatterns = [...new Set(activatedFixturePatterns)];
|
|
3556
|
+
if (uniqueFixturePatterns.length > 0) {
|
|
3557
|
+
const fixtureFiles = fg.sync(uniqueFixturePatterns, {
|
|
3558
|
+
cwd: directory,
|
|
3559
|
+
absolute: true,
|
|
3560
|
+
onlyFiles: true,
|
|
3561
|
+
ignore: ["**/node_modules/**"]
|
|
3562
|
+
});
|
|
3563
|
+
allEntries.push(...fixtureFiles);
|
|
3564
|
+
}
|
|
3565
|
+
const uniqueAlwaysUsed = [...new Set(activatedAlwaysUsed)];
|
|
3566
|
+
if (uniqueAlwaysUsed.length > 0) {
|
|
3567
|
+
const alwaysUsedFiles = fg.sync(uniqueAlwaysUsed, {
|
|
3568
|
+
cwd: directory,
|
|
3569
|
+
absolute: true,
|
|
3570
|
+
onlyFiles: true,
|
|
3571
|
+
ignore: ["**/node_modules/**"],
|
|
3572
|
+
dot: true
|
|
3573
|
+
});
|
|
3574
|
+
allAlwaysUsed.push(...alwaysUsedFiles);
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
return {
|
|
3578
|
+
entryFiles: allEntries,
|
|
3579
|
+
alwaysUsedFiles: allAlwaysUsed
|
|
3580
|
+
};
|
|
3581
|
+
};
|
|
3582
|
+
const isToolingPluginEnabled = (plugin, dependencies) => {
|
|
3583
|
+
if (plugin.enablers.some((enabler) => enabler in dependencies)) return true;
|
|
3584
|
+
if (plugin.enablerPrefixes.length > 0) {
|
|
3585
|
+
const depNames = Object.keys(dependencies);
|
|
3586
|
+
return plugin.enablerPrefixes.some((prefix) => depNames.some((depName) => depName.startsWith(prefix)));
|
|
3587
|
+
}
|
|
3588
|
+
return false;
|
|
3589
|
+
};
|
|
3590
|
+
const FRAMEWORK_SCRIPT_BINARIES = {
|
|
3591
|
+
next: ["next"],
|
|
3592
|
+
nuxt: ["nuxt"],
|
|
3593
|
+
astro: ["astro"],
|
|
3594
|
+
gatsby: ["gatsby"],
|
|
3595
|
+
"@remix-run/dev": ["remix"],
|
|
3596
|
+
"@react-router/dev": ["react-router"],
|
|
3597
|
+
"@sveltejs/kit": ["svelte-kit", "vite-svelte-kit"],
|
|
3598
|
+
"@docusaurus/core": ["docusaurus"],
|
|
3599
|
+
"@angular/core": ["ng"],
|
|
3600
|
+
"@nestjs/core": ["nest"],
|
|
3601
|
+
storybook: [
|
|
3602
|
+
"storybook",
|
|
3603
|
+
"start-storybook",
|
|
3604
|
+
"build-storybook"
|
|
3605
|
+
]
|
|
3606
|
+
};
|
|
3607
|
+
const detectFrameworkFromScripts = (scripts) => {
|
|
3608
|
+
const enabledEnablers = /* @__PURE__ */ new Set();
|
|
3609
|
+
if (!scripts || typeof scripts !== "object") return enabledEnablers;
|
|
3610
|
+
for (const scriptValue of Object.values(scripts)) {
|
|
3611
|
+
if (typeof scriptValue !== "string") continue;
|
|
3612
|
+
const tokenized = scriptValue.split(/[\s|&;]+/);
|
|
3613
|
+
for (const token of tokenized) {
|
|
3614
|
+
const cleaned = token.replace(/^.*\//, "");
|
|
3615
|
+
for (const [enabler, binaries] of Object.entries(FRAMEWORK_SCRIPT_BINARIES)) if (binaries.includes(cleaned)) enabledEnablers.add(enabler);
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
return enabledEnablers;
|
|
3619
|
+
};
|
|
3620
|
+
const readPackageScripts = (directory) => {
|
|
3621
|
+
const packageJsonPath = join(directory, "package.json");
|
|
3622
|
+
if (!existsSync(packageJsonPath)) return void 0;
|
|
3623
|
+
try {
|
|
3624
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
3625
|
+
return JSON.parse(content).scripts;
|
|
3626
|
+
} catch {
|
|
3627
|
+
return;
|
|
3628
|
+
}
|
|
3629
|
+
};
|
|
3630
|
+
const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
|
|
3631
|
+
const allEntries = [];
|
|
3632
|
+
const allAlwaysUsed = [];
|
|
3633
|
+
const directoriesToCheck = [rootDir, ...workspacePackages.map((workspacePackage) => workspacePackage.directory)];
|
|
3634
|
+
let rootDependencies = {};
|
|
3635
|
+
const rootPackageJsonPath = join(rootDir, "package.json");
|
|
3636
|
+
if (existsSync(rootPackageJsonPath)) try {
|
|
3637
|
+
const rootContent = readFileSync(rootPackageJsonPath, "utf-8");
|
|
3638
|
+
const rootPackageJson = JSON.parse(rootContent);
|
|
3639
|
+
rootDependencies = {
|
|
3640
|
+
...rootPackageJson.dependencies,
|
|
3641
|
+
...rootPackageJson.devDependencies,
|
|
3642
|
+
...rootPackageJson.optionalDependencies
|
|
3643
|
+
};
|
|
3644
|
+
} catch {}
|
|
3645
|
+
const monorepoRoot = findMonorepoRoot(rootDir);
|
|
3646
|
+
const monorepoRootDeps = monorepoRoot && monorepoRoot !== rootDir ? readPackageJsonDependencies(join(monorepoRoot, "package.json")) : {};
|
|
3647
|
+
for (const directory of directoriesToCheck) {
|
|
3648
|
+
const packageJsonPath = join(directory, "package.json");
|
|
3649
|
+
if (!existsSync(packageJsonPath)) continue;
|
|
3650
|
+
let workspaceDependencies = {};
|
|
3651
|
+
try {
|
|
3652
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
3653
|
+
const packageJson = JSON.parse(content);
|
|
3654
|
+
workspaceDependencies = {
|
|
3655
|
+
...packageJson.dependencies,
|
|
3656
|
+
...packageJson.devDependencies,
|
|
3657
|
+
...packageJson.optionalDependencies
|
|
3658
|
+
};
|
|
3659
|
+
} catch {
|
|
3660
|
+
continue;
|
|
3661
|
+
}
|
|
3662
|
+
const scriptDetectedEnablers = detectFrameworkFromScripts(readPackageScripts(directory));
|
|
3663
|
+
const mergedDependencies = { ...workspaceDependencies };
|
|
3664
|
+
if (directory === rootDir) Object.assign(mergedDependencies, rootDependencies);
|
|
3665
|
+
for (const enabler of scriptDetectedEnablers) if (enabler in workspaceDependencies || enabler in rootDependencies || enabler in monorepoRootDeps) mergedDependencies[enabler] = "*";
|
|
3666
|
+
const activatedPatterns = [];
|
|
3667
|
+
const activatedAlwaysUsed = [];
|
|
3668
|
+
for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, mergedDependencies)) {
|
|
3669
|
+
activatedPatterns.push(...plugin.entryPatterns);
|
|
3670
|
+
activatedAlwaysUsed.push(...plugin.alwaysUsed);
|
|
3671
|
+
}
|
|
3672
|
+
if (activatedPatterns.length === 0 && activatedAlwaysUsed.length === 0) continue;
|
|
3673
|
+
const uniquePatterns = [...new Set(activatedPatterns)];
|
|
3674
|
+
const toolingFiles = fg.sync(uniquePatterns, {
|
|
3675
|
+
cwd: directory,
|
|
3676
|
+
absolute: true,
|
|
3677
|
+
onlyFiles: true,
|
|
3678
|
+
ignore: ["**/node_modules/**"],
|
|
3679
|
+
dot: true
|
|
3680
|
+
});
|
|
3681
|
+
allEntries.push(...toolingFiles);
|
|
3682
|
+
const uniqueAlwaysUsed = [...new Set(activatedAlwaysUsed)];
|
|
3683
|
+
if (uniqueAlwaysUsed.length > 0) {
|
|
3684
|
+
const alwaysUsedFiles = fg.sync(uniqueAlwaysUsed, {
|
|
3685
|
+
cwd: directory,
|
|
3686
|
+
absolute: true,
|
|
3687
|
+
onlyFiles: true,
|
|
3688
|
+
ignore: ["**/node_modules/**"],
|
|
3689
|
+
dot: true
|
|
3690
|
+
});
|
|
3691
|
+
allAlwaysUsed.push(...alwaysUsedFiles);
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
const rootActivatedGlobalPatterns = [];
|
|
3695
|
+
for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, rootDependencies)) {
|
|
3696
|
+
for (const pattern of plugin.alwaysUsed) if (!pattern.startsWith("**/")) rootActivatedGlobalPatterns.push(`**/${pattern}`);
|
|
3697
|
+
}
|
|
3698
|
+
if (rootActivatedGlobalPatterns.length > 0) {
|
|
3699
|
+
const globalAlwaysUsedFiles = fg.sync([...new Set(rootActivatedGlobalPatterns)], {
|
|
3700
|
+
cwd: rootDir,
|
|
3701
|
+
absolute: true,
|
|
3702
|
+
onlyFiles: true,
|
|
3703
|
+
ignore: ["**/node_modules/**"],
|
|
3704
|
+
dot: true
|
|
3705
|
+
});
|
|
3706
|
+
allAlwaysUsed.push(...globalAlwaysUsedFiles);
|
|
3707
|
+
}
|
|
3708
|
+
return {
|
|
3709
|
+
entryFiles: allEntries,
|
|
3710
|
+
alwaysUsedFiles: allAlwaysUsed
|
|
3711
|
+
};
|
|
3712
|
+
};
|
|
3713
|
+
|
|
3714
|
+
//#endregion
|
|
3715
|
+
//#region src/collect/entries-worker.ts
|
|
3716
|
+
const port = parentPort;
|
|
3717
|
+
port.on("message", (message) => {
|
|
3718
|
+
if (message.type !== "resolve-entries") return;
|
|
3719
|
+
resolveEntries(message.config).then((entries) => {
|
|
3720
|
+
const response = {
|
|
3721
|
+
type: "result",
|
|
3722
|
+
entries
|
|
3723
|
+
};
|
|
3724
|
+
port.postMessage(response);
|
|
3725
|
+
}, (taskError) => {
|
|
3726
|
+
const response = {
|
|
3727
|
+
type: "error",
|
|
3728
|
+
errorMessage: taskError instanceof Error ? taskError.message : String(taskError)
|
|
3729
|
+
};
|
|
3730
|
+
port.postMessage(response);
|
|
3731
|
+
});
|
|
3732
|
+
});
|
|
3733
|
+
port.postMessage({ type: "ready" });
|
|
3734
|
+
|
|
3735
|
+
//#endregion
|
|
3736
|
+
export { };
|