@posthog/wizard 2.49.0 → 2.51.0
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/{add-mcp-server-to-clients-DnyxFVhW.js → add-mcp-server-to-clients-C1f2al7N.js} +5 -5
- package/dist/{add-mcp-server-to-clients-DnyxFVhW.js.map → add-mcp-server-to-clients-C1f2al7N.js.map} +1 -1
- package/dist/{agent-interface-Doo3apDE.js → agent-interface-BL2wCV3b.js} +33 -71
- package/dist/agent-interface-BL2wCV3b.js.map +1 -0
- package/dist/agent-prompt-loader-CEWWA98d.js +275 -0
- package/dist/agent-prompt-loader-CEWWA98d.js.map +1 -0
- package/dist/{agent-runner-D7OZPgIV.js → agent-runner-DSKXFDXa.js} +101 -319
- package/dist/agent-runner-DSKXFDXa.js.map +1 -0
- package/dist/{analytics-D6gRGiqt.js → analytics-Ddf3zJgF.js} +20 -2
- package/dist/analytics-Ddf3zJgF.js.map +1 -0
- package/dist/analytics-GD_xM1XO.js +2 -0
- package/dist/{api-ZT2Zd5yp.js → api-BdanR3Zp.js} +3 -3
- package/dist/{api-ZT2Zd5yp.js.map → api-BdanR3Zp.js.map} +1 -1
- package/dist/bin.js +89 -90
- package/dist/bin.js.map +1 -1
- package/dist/bounded-fs-d0dw1Qv5.js +242 -0
- package/dist/bounded-fs-d0dw1Qv5.js.map +1 -0
- package/dist/{ci-install-CQWSPGdM.js → ci-install-DnVNVs0f.js} +4 -4
- package/dist/{ci-install-CQWSPGdM.js.map → ci-install-DnVNVs0f.js.map} +1 -1
- package/dist/commandments-BagyrYRW.js +2 -0
- package/dist/{commandments-DSNrOeOC.js → commandments-DiMtIz1o.js} +1 -1
- package/dist/{commandments-DSNrOeOC.js.map → commandments-DiMtIz1o.js.map} +1 -1
- package/dist/{debug-D8AJ_YCW.js → debug-By1_VtgZ.js} +1 -1
- package/dist/{debug-DF51kDvZ.js → debug-DaXKSXEy.js} +8 -27
- package/dist/debug-DaXKSXEy.js.map +1 -0
- package/dist/{defaults-CtWMmC8s.js → defaults-DAE9_QMn.js} +1 -1
- package/dist/{defaults-CtWMmC8s.js.map → defaults-DAE9_QMn.js.map} +1 -1
- package/dist/{env-api-key-C3LzH8Lr.js → env-api-key-DDVkPQmo.js} +1 -1
- package/dist/{env-api-key-C3LzH8Lr.js.map → env-api-key-DDVkPQmo.js.map} +1 -1
- package/dist/{environment-Csj7vBHM.js → environment-DJQOs7MR.js} +4 -4
- package/dist/environment-DJQOs7MR.js.map +1 -0
- package/dist/{file-watcher-CQB00KDS.js → file-watcher-LZe_W3hM.js} +2 -2
- package/dist/{file-watcher-CQB00KDS.js.map → file-watcher-LZe_W3hM.js.map} +1 -1
- package/dist/{headless-ui-DfSOfXEo.js → headless-ui-wIeUgvJ8.js} +2 -2
- package/dist/{headless-ui-DfSOfXEo.js.map → headless-ui-wIeUgvJ8.js.map} +1 -1
- package/dist/{interactive-DmRqhAUD.js → interactive-j4DoJDnk.js} +2 -2
- package/dist/{interactive-DmRqhAUD.js.map → interactive-j4DoJDnk.js.map} +1 -1
- package/dist/{mcp-B_ycbOus.js → mcp-Butt7ktW.js} +2 -2
- package/dist/{mcp-B_ycbOus.js.map → mcp-Butt7ktW.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-ChEBHPQ-.js → mcp-prompt-streaming-D25BQfRa.js} +3 -3
- package/dist/{mcp-prompt-streaming-ChEBHPQ-.js.map → mcp-prompt-streaming-D25BQfRa.js.map} +1 -1
- package/dist/{non-interactive-ViR2FrQC.js → non-interactive-Cpof2JsA.js} +2 -2
- package/dist/{non-interactive-ViR2FrQC.js.map → non-interactive-Cpof2JsA.js.map} +1 -1
- package/dist/{orchestrator-tools-B0vrJlpS.js → orchestrator-tools-CsJizPpV.js} +3 -3
- package/dist/{orchestrator-tools-B0vrJlpS.js.map → orchestrator-tools-CsJizPpV.js.map} +1 -1
- package/dist/{package-json-DCuoye-H.js → package-json-CDs1ZVKu.js} +1 -1
- package/dist/{package-json-DCuoye-H.js.map → package-json-CDs1ZVKu.js.map} +1 -1
- package/dist/{package-manager-B6QAvLyt.js → package-manager-DnzNEjci.js} +2 -2
- package/dist/{package-manager-B6QAvLyt.js.map → package-manager-DnzNEjci.js.map} +1 -1
- package/dist/{pi-CXhGyUbi.js → pi-DE2cAVfO.js} +89 -138
- package/dist/pi-DE2cAVfO.js.map +1 -0
- package/dist/{playground-D_cP2oXt.js → playground-C3sLBq6A.js} +7 -7
- package/dist/{playground-D_cP2oXt.js.map → playground-C3sLBq6A.js.map} +1 -1
- package/dist/{posthog-integration-Bt8jQC7c.js → posthog-integration-_GSKRotZ.js} +45 -38
- package/dist/posthog-integration-_GSKRotZ.js.map +1 -0
- package/dist/{posthog-DZZbziJ1.js → posthog-mgz-FQlS.js} +1 -1
- package/dist/{posthog-DZZbziJ1.js.map → posthog-mgz-FQlS.js.map} +1 -1
- package/dist/{provisioning-By5DVLJr.js → provisioning-BndgugFk.js} +3 -3
- package/dist/{provisioning-By5DVLJr.js.map → provisioning-BndgugFk.js.map} +1 -1
- package/dist/{queue-tools-3iQHCpWF.js → queue-tools-DZjAjiqk.js} +97 -10
- package/dist/queue-tools-DZjAjiqk.js.map +1 -0
- package/dist/{registry-DG8r_Wks.js → registry-BMjfECF2.js} +272 -429
- package/dist/registry-BMjfECF2.js.map +1 -0
- package/dist/{security-BpbwefgM.js → security-D5hjYVFi.js} +4 -4
- package/dist/{security-BpbwefgM.js.map → security-D5hjYVFi.js.map} +1 -1
- package/dist/{setup-utils-CFejYe1M.js → setup-utils-ZKEk71yV.js} +14 -17
- package/dist/setup-utils-ZKEk71yV.js.map +1 -0
- package/dist/smoke-test.sh +1 -1
- package/dist/{start-tui-BINHq3Yp.js → start-tui-B2Tb427o.js} +19 -19
- package/dist/{start-tui-BINHq3Yp.js.map → start-tui-B2Tb427o.js.map} +1 -1
- package/dist/{steps-DhmMIChh.js → steps-ClMZ6MZd.js} +7 -7
- package/dist/{steps-DhmMIChh.js.map → steps-ClMZ6MZd.js.map} +1 -1
- package/dist/{store-Bj1m0ws-.js → store-Db77bfRv.js} +5 -5
- package/dist/{store-Bj1m0ws-.js.map → store-Db77bfRv.js.map} +1 -1
- package/dist/{subagent-DND7lZg6.js → subagent--VXEEc8S.js} +2 -2
- package/dist/{subagent-DND7lZg6.js.map → subagent--VXEEc8S.js.map} +1 -1
- package/dist/{task-CsAczwW6.js → task-CBQfx_f5.js} +30 -45
- package/dist/task-CBQfx_f5.js.map +1 -0
- package/dist/{task-stream-BaiI6TNY.js → task-stream-DCrqCmFa.js} +5 -5
- package/dist/{task-stream-BaiI6TNY.js.map → task-stream-DCrqCmFa.js.map} +1 -1
- package/dist/{tasks-DqDHx5pW.js → tasks-BJuz1XQ1.js} +2 -2
- package/dist/{tasks-DqDHx5pW.js.map → tasks-BJuz1XQ1.js.map} +1 -1
- package/dist/{telemetry-DXzPfSXl.js → telemetry-tdU6F90U.js} +3 -3
- package/dist/{telemetry-DXzPfSXl.js.map → telemetry-tdU6F90U.js.map} +1 -1
- package/dist/{terminal-DKsibL3T.js → terminal-ClWui_UN.js} +13 -13
- package/dist/{terminal-DKsibL3T.js.map → terminal-ClWui_UN.js.map} +1 -1
- package/dist/{tools-D5pL_r3K.js → tools-DwpaEyEv.js} +10 -8
- package/dist/tools-DwpaEyEv.js.map +1 -0
- package/dist/{wizard-abort-Br1Dps20.js → wizard-abort-B1iPXM3K.js} +4 -4
- package/dist/{wizard-abort-Br1Dps20.js.map → wizard-abort-B1iPXM3K.js.map} +1 -1
- package/dist/{wizard-abort-DG6Atd5I.js → wizard-abort-cX4Kytai.js} +1 -1
- package/dist/{wizard-session-tp4Zdbwl.js → wizard-session-BAZql11N.js} +1 -1
- package/dist/{wizard-session-tp4Zdbwl.js.map → wizard-session-BAZql11N.js.map} +1 -1
- package/dist/{wizard-session-DWHe83uk.js → wizard-session-C5lZPPEc.js} +1 -1
- package/dist/{yara-hooks-DEHfsDSF.js → yara-hooks-CEs3jx7j.js} +139 -56
- package/dist/yara-hooks-CEs3jx7j.js.map +1 -0
- package/dist/yara-hooks-gz4AceFG.js +2 -0
- package/package.json +2 -2
- package/dist/agent-interface-Doo3apDE.js.map +0 -1
- package/dist/agent-runner-D7OZPgIV.js.map +0 -1
- package/dist/analytics-AOHLZy1k.js +0 -2
- package/dist/analytics-D6gRGiqt.js.map +0 -1
- package/dist/commandments-qTW7pwaT.js +0 -2
- package/dist/debug-DF51kDvZ.js.map +0 -1
- package/dist/environment-Csj7vBHM.js.map +0 -1
- package/dist/file-utils-Dj3UqDJz.js +0 -116
- package/dist/file-utils-Dj3UqDJz.js.map +0 -1
- package/dist/pi-CXhGyUbi.js.map +0 -1
- package/dist/posthog-integration-Bt8jQC7c.js.map +0 -1
- package/dist/queue-tools-3iQHCpWF.js.map +0 -1
- package/dist/registry-DG8r_Wks.js.map +0 -1
- package/dist/setup-utils-CFejYe1M.js.map +0 -1
- package/dist/task-CsAczwW6.js.map +0 -1
- package/dist/tools-D5pL_r3K.js.map +0 -1
- package/dist/yara-hooks-BExxs6sG.js +0 -2
- package/dist/yara-hooks-DEHfsDSF.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import { f as getUI } from "./debug-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { f as getUI } from "./debug-DaXKSXEy.js";
|
|
3
|
+
import { r as readProjectFile, t as boundedGlob } from "./bounded-fs-d0dw1Qv5.js";
|
|
4
|
+
import { a as createVersionBucket, c as detectAllPackageManagers, i as tryGetPackageJson } from "./setup-utils-ZKEk71yV.js";
|
|
5
|
+
import { n as getInstalledPackageVersion, r as hasDeclaredDependency, t as getDeclaredVersion } from "./package-json-CDs1ZVKu.js";
|
|
6
|
+
import { a as gradlePackageManager, c as getPackageManagerName$1, i as detectPythonPackageManagers, l as getPythonVersion, n as composerPackageManager, o as swiftPackageManager, r as detectNodePackageManagers, s as detectPackageManager$1, t as bundlerPackageManager, u as getPythonVersionBucket } from "./package-manager-DnzNEjci.js";
|
|
6
7
|
import * as semver from "semver";
|
|
7
8
|
import { major, minVersion } from "semver";
|
|
8
9
|
import path from "path";
|
|
@@ -12,26 +13,20 @@ import fg from "fast-glob";
|
|
|
12
13
|
import fs from "fs/promises";
|
|
13
14
|
//#region src/frameworks/nextjs/utils.ts
|
|
14
15
|
const getNextJsVersionBucket = createVersionBucket();
|
|
15
|
-
const IGNORE_PATTERNS$
|
|
16
|
-
"**/node_modules/**",
|
|
17
|
-
"**/dist/**",
|
|
18
|
-
"**/build/**",
|
|
19
|
-
"**/public/**",
|
|
20
|
-
"**/.next/**"
|
|
21
|
-
];
|
|
16
|
+
const IGNORE_PATTERNS$1 = ["**/public/**"];
|
|
22
17
|
/**
|
|
23
18
|
* Detect Next.js router type. Pure — returns null if ambiguous.
|
|
24
19
|
*/
|
|
25
20
|
async function getNextJsRouter({ installDir }) {
|
|
26
|
-
const hasPagesDir = (await
|
|
27
|
-
dot: true,
|
|
21
|
+
const hasPagesDir = (await boundedGlob("**/pages/_app.@(ts|tsx|js|jsx)", {
|
|
28
22
|
cwd: installDir,
|
|
29
|
-
|
|
23
|
+
extraIgnore: IGNORE_PATTERNS$1,
|
|
24
|
+
limit: 1
|
|
30
25
|
})).length > 0;
|
|
31
|
-
const hasAppDir = (await
|
|
32
|
-
dot: true,
|
|
26
|
+
const hasAppDir = (await boundedGlob("**/app/**/layout.@(ts|tsx|js|jsx)", {
|
|
33
27
|
cwd: installDir,
|
|
34
|
-
|
|
28
|
+
extraIgnore: IGNORE_PATTERNS$1,
|
|
29
|
+
limit: 1
|
|
35
30
|
})).length > 0;
|
|
36
31
|
if (hasPagesDir && !hasAppDir) return "pages-router";
|
|
37
32
|
if (hasAppDir && !hasPagesDir) return "app-router";
|
|
@@ -215,47 +210,42 @@ const VUE_AGENT_CONFIG = {
|
|
|
215
210
|
};
|
|
216
211
|
//#endregion
|
|
217
212
|
//#region src/frameworks/react-router/utils.ts
|
|
218
|
-
const
|
|
219
|
-
"**/node_modules/**",
|
|
220
|
-
"**/dist/**",
|
|
221
|
-
"**/build/**",
|
|
222
|
-
"**/public/**",
|
|
223
|
-
"**/.next/**"
|
|
224
|
-
];
|
|
213
|
+
const EXTRA_IGNORE$11 = ["**/public/**"];
|
|
225
214
|
const getReactRouterVersionBucket = createVersionBucket();
|
|
215
|
+
/** Content probes read at most this many files, one in memory at a time. */
|
|
216
|
+
const SOURCE_PROBE_LIMIT$5 = 200;
|
|
217
|
+
/** Files that set up a React Router — never a blanket source sweep. */
|
|
218
|
+
const ROUTER_FILE_GLOBS = [
|
|
219
|
+
"**/routes/**/*.@(ts|tsx|js|jsx)",
|
|
220
|
+
"**/*[Rr]out*.@(ts|tsx|js|jsx)",
|
|
221
|
+
"**/@(main|app|App|index|root).@(ts|tsx|js|jsx)"
|
|
222
|
+
];
|
|
226
223
|
async function hasReactRouterConfig({ installDir }) {
|
|
227
|
-
return (await
|
|
228
|
-
dot: true,
|
|
224
|
+
return (await boundedGlob("**/react-router.config.@(ts|js|tsx|jsx)", {
|
|
229
225
|
cwd: installDir,
|
|
230
|
-
|
|
226
|
+
extraIgnore: EXTRA_IGNORE$11,
|
|
227
|
+
limit: 1
|
|
231
228
|
})).length > 0;
|
|
232
229
|
}
|
|
233
230
|
async function hasCreateBrowserRouter({ installDir }) {
|
|
234
|
-
const sourceFiles = await
|
|
235
|
-
dot: true,
|
|
231
|
+
const sourceFiles = await boundedGlob(ROUTER_FILE_GLOBS, {
|
|
236
232
|
cwd: installDir,
|
|
237
|
-
|
|
233
|
+
extraIgnore: EXTRA_IGNORE$11,
|
|
234
|
+
limit: SOURCE_PROBE_LIMIT$5
|
|
238
235
|
});
|
|
239
|
-
for (const file of sourceFiles)
|
|
240
|
-
const filePath = path$1.join(installDir, file);
|
|
241
|
-
if (fs$1.readFileSync(filePath, "utf-8").includes("createBrowserRouter")) return true;
|
|
242
|
-
} catch {
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
236
|
+
for (const file of sourceFiles) if (readProjectFile(path$1.join(installDir, file))?.includes("createBrowserRouter")) return true;
|
|
245
237
|
return false;
|
|
246
238
|
}
|
|
247
239
|
async function hasDeclarativeRouter({ installDir }) {
|
|
248
|
-
const sourceFiles = await
|
|
249
|
-
dot: true,
|
|
240
|
+
const sourceFiles = await boundedGlob(ROUTER_FILE_GLOBS, {
|
|
250
241
|
cwd: installDir,
|
|
251
|
-
|
|
242
|
+
extraIgnore: EXTRA_IGNORE$11,
|
|
243
|
+
limit: SOURCE_PROBE_LIMIT$5
|
|
252
244
|
});
|
|
253
|
-
for (const file of sourceFiles)
|
|
254
|
-
const
|
|
255
|
-
|
|
245
|
+
for (const file of sourceFiles) {
|
|
246
|
+
const content = readProjectFile(path$1.join(installDir, file));
|
|
247
|
+
if (!content) continue;
|
|
256
248
|
if (content.includes("<BrowserRouter") || content.includes("BrowserRouter") && (content.includes("from \"react-router-dom\"") || content.includes("from 'react-router-dom'"))) return true;
|
|
257
|
-
} catch {
|
|
258
|
-
continue;
|
|
259
249
|
}
|
|
260
250
|
return false;
|
|
261
251
|
}
|
|
@@ -354,20 +344,25 @@ const REACT_ROUTER_AGENT_CONFIG = {
|
|
|
354
344
|
};
|
|
355
345
|
//#endregion
|
|
356
346
|
//#region src/frameworks/tanstack-router/utils.ts
|
|
357
|
-
const
|
|
358
|
-
"**/node_modules/**",
|
|
359
|
-
"**/dist/**",
|
|
360
|
-
"**/build/**",
|
|
347
|
+
const EXTRA_IGNORE$10 = [
|
|
361
348
|
"**/public/**",
|
|
362
349
|
"**/.vinxi/**",
|
|
363
350
|
"**/.output/**"
|
|
364
351
|
];
|
|
365
352
|
const getTanStackRouterVersionBucket = createVersionBucket();
|
|
353
|
+
/** Content probes read at most this many files, one in memory at a time. */
|
|
354
|
+
const SOURCE_PROBE_LIMIT$4 = 200;
|
|
355
|
+
/** Files that define TanStack routes — never a blanket source sweep. */
|
|
356
|
+
const ROUTE_FILE_GLOBS = [
|
|
357
|
+
"**/routes/**/*.@(ts|tsx|js|jsx)",
|
|
358
|
+
"**/*[Rr]oute*.@(ts|tsx|js|jsx)",
|
|
359
|
+
"**/@(main|router|app|App|index).@(ts|tsx|js|jsx)"
|
|
360
|
+
];
|
|
366
361
|
async function hasFileBasedRouting({ installDir }) {
|
|
367
|
-
if ((await
|
|
368
|
-
dot: true,
|
|
362
|
+
if ((await boundedGlob("**/routeTree.gen.@(ts|tsx|js|jsx)", {
|
|
369
363
|
cwd: installDir,
|
|
370
|
-
|
|
364
|
+
extraIgnore: EXTRA_IGNORE$10,
|
|
365
|
+
limit: 1
|
|
371
366
|
})).length > 0) return true;
|
|
372
367
|
try {
|
|
373
368
|
const packageJsonPath = path$1.join(installDir, "package.json");
|
|
@@ -375,34 +370,27 @@ async function hasFileBasedRouting({ installDir }) {
|
|
|
375
370
|
const packageJson = JSON.parse(content);
|
|
376
371
|
if (hasDeclaredDependency("@tanstack/router-plugin", packageJson) || hasDeclaredDependency("@tanstack/router-vite-plugin", packageJson)) return true;
|
|
377
372
|
} catch {}
|
|
378
|
-
const sourceFiles = await
|
|
379
|
-
dot: true,
|
|
373
|
+
const sourceFiles = await boundedGlob(ROUTE_FILE_GLOBS, {
|
|
380
374
|
cwd: installDir,
|
|
381
|
-
|
|
375
|
+
extraIgnore: EXTRA_IGNORE$10,
|
|
376
|
+
limit: SOURCE_PROBE_LIMIT$4
|
|
382
377
|
});
|
|
383
|
-
for (const file of sourceFiles)
|
|
384
|
-
const filePath = path$1.join(installDir, file);
|
|
385
|
-
if (fs$1.readFileSync(filePath, "utf-8").includes("createFileRoute")) return true;
|
|
386
|
-
} catch {
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
378
|
+
for (const file of sourceFiles) if (readProjectFile(path$1.join(installDir, file))?.includes("createFileRoute")) return true;
|
|
389
379
|
return false;
|
|
390
380
|
}
|
|
391
381
|
async function hasCodeBasedRouting({ installDir }) {
|
|
392
|
-
const sourceFiles = await
|
|
393
|
-
dot: true,
|
|
382
|
+
const sourceFiles = await boundedGlob(ROUTE_FILE_GLOBS, {
|
|
394
383
|
cwd: installDir,
|
|
395
|
-
|
|
384
|
+
extraIgnore: EXTRA_IGNORE$10,
|
|
385
|
+
limit: SOURCE_PROBE_LIMIT$4
|
|
396
386
|
});
|
|
397
387
|
let hasCreateRoute = false;
|
|
398
388
|
let hasCreateFileRoute = false;
|
|
399
|
-
for (const file of sourceFiles)
|
|
400
|
-
const
|
|
401
|
-
|
|
389
|
+
for (const file of sourceFiles) {
|
|
390
|
+
const content = readProjectFile(path$1.join(installDir, file));
|
|
391
|
+
if (!content) continue;
|
|
402
392
|
if (content.includes("createRoute(")) hasCreateRoute = true;
|
|
403
393
|
if (content.includes("createFileRoute")) hasCreateFileRoute = true;
|
|
404
|
-
} catch {
|
|
405
|
-
continue;
|
|
406
394
|
}
|
|
407
395
|
return hasCreateRoute && !hasCreateFileRoute;
|
|
408
396
|
}
|
|
@@ -663,19 +651,15 @@ const ANGULAR_AGENT_CONFIG = {
|
|
|
663
651
|
//#endregion
|
|
664
652
|
//#region src/frameworks/astro/utils.ts
|
|
665
653
|
const getAstroVersionBucket = createVersionBucket();
|
|
666
|
-
const
|
|
667
|
-
"**/node_modules/**",
|
|
668
|
-
"**/dist/**",
|
|
669
|
-
"**/.astro/**"
|
|
670
|
-
];
|
|
654
|
+
const EXTRA_IGNORE$9 = ["**/.astro/**"];
|
|
671
655
|
/**
|
|
672
656
|
* Detect the Astro rendering mode. Pure — always resolves (Astro detection is reliable).
|
|
673
657
|
*/
|
|
674
658
|
async function getAstroRenderingMode({ installDir }) {
|
|
675
|
-
const configMatches = await
|
|
676
|
-
dot: true,
|
|
659
|
+
const configMatches = await boundedGlob("astro.config.@(mjs|ts|js)", {
|
|
677
660
|
cwd: installDir,
|
|
678
|
-
|
|
661
|
+
extraIgnore: EXTRA_IGNORE$9,
|
|
662
|
+
limit: 1
|
|
679
663
|
});
|
|
680
664
|
let hasAdapter = false;
|
|
681
665
|
let outputMode = null;
|
|
@@ -695,19 +679,19 @@ async function getAstroRenderingMode({ installDir }) {
|
|
|
695
679
|
const outputMatch = (await fs.readFile(configPath, "utf-8")).match(/output:\s*['"](\w+)['"]/);
|
|
696
680
|
if (outputMatch) outputMode = outputMatch[1];
|
|
697
681
|
} catch {}
|
|
698
|
-
const viewTransitionMatches = await
|
|
699
|
-
dot: true,
|
|
682
|
+
const viewTransitionMatches = await boundedGlob("**/*.@(astro|ts|tsx|js|jsx)", {
|
|
700
683
|
cwd: installDir,
|
|
701
|
-
|
|
684
|
+
extraIgnore: EXTRA_IGNORE$9,
|
|
685
|
+
limit: 20
|
|
702
686
|
});
|
|
703
|
-
for (const file of viewTransitionMatches
|
|
704
|
-
const
|
|
705
|
-
|
|
687
|
+
for (const file of viewTransitionMatches) {
|
|
688
|
+
const content = readProjectFile(path.join(installDir, file));
|
|
689
|
+
if (!content) continue;
|
|
706
690
|
if (content.includes("ClientRouter") || content.includes("ViewTransitions") || content.includes("astro:transitions")) {
|
|
707
691
|
usesViewTransitions = true;
|
|
708
692
|
break;
|
|
709
693
|
}
|
|
710
|
-
}
|
|
694
|
+
}
|
|
711
695
|
if (usesViewTransitions) return "view-transitions";
|
|
712
696
|
if (outputMode === "server" && hasAdapter) return "ssr";
|
|
713
697
|
if (hasAdapter) return "hybrid";
|
|
@@ -811,15 +795,9 @@ const PYTHON_PACKAGE_INSTALLATION = "Use the detect_package_manager tool to dete
|
|
|
811
795
|
const SPINNER_MESSAGE = "Writing your PostHog setup with events, error capture and more...";
|
|
812
796
|
//#endregion
|
|
813
797
|
//#region src/frameworks/django/utils.ts
|
|
814
|
-
const
|
|
815
|
-
"**/node_modules/**",
|
|
816
|
-
"**/dist/**",
|
|
817
|
-
"**/build/**",
|
|
818
|
-
"**/venv/**",
|
|
819
|
-
"**/.venv/**",
|
|
798
|
+
const EXTRA_IGNORE$8 = [
|
|
820
799
|
"**/env/**",
|
|
821
800
|
"**/.env/**",
|
|
822
|
-
"**/__pycache__/**",
|
|
823
801
|
"**/migrations/**"
|
|
824
802
|
];
|
|
825
803
|
/**
|
|
@@ -831,89 +809,72 @@ const getDjangoVersionBucket = createVersionBucket();
|
|
|
831
809
|
*/
|
|
832
810
|
async function getDjangoVersion(options) {
|
|
833
811
|
const { installDir } = options;
|
|
834
|
-
const requirementsFiles = await
|
|
812
|
+
const requirementsFiles = await boundedGlob([
|
|
835
813
|
"**/requirements*.txt",
|
|
836
814
|
"**/pyproject.toml",
|
|
837
815
|
"**/setup.py",
|
|
838
816
|
"**/Pipfile"
|
|
839
817
|
], {
|
|
840
818
|
cwd: installDir,
|
|
841
|
-
|
|
819
|
+
extraIgnore: EXTRA_IGNORE$8
|
|
842
820
|
});
|
|
843
|
-
for (const reqFile of requirementsFiles)
|
|
844
|
-
const content =
|
|
821
|
+
for (const reqFile of requirementsFiles) {
|
|
822
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
823
|
+
if (!content) continue;
|
|
845
824
|
const requirementsMatch = content.match(/[Dd]jango[=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
846
825
|
if (requirementsMatch) return requirementsMatch[1];
|
|
847
826
|
const pyprojectMatch = content.match(/[Dd]jango["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
848
827
|
if (pyprojectMatch) return pyprojectMatch[1];
|
|
849
|
-
} catch {
|
|
850
|
-
continue;
|
|
851
828
|
}
|
|
852
829
|
}
|
|
853
830
|
/**
|
|
854
831
|
* Check if Django REST Framework is installed
|
|
855
832
|
*/
|
|
856
833
|
async function hasDRF({ installDir }) {
|
|
857
|
-
const requirementsFiles = await
|
|
834
|
+
const requirementsFiles = await boundedGlob([
|
|
858
835
|
"**/requirements*.txt",
|
|
859
836
|
"**/pyproject.toml",
|
|
860
837
|
"**/Pipfile"
|
|
861
838
|
], {
|
|
862
839
|
cwd: installDir,
|
|
863
|
-
|
|
840
|
+
extraIgnore: EXTRA_IGNORE$8
|
|
864
841
|
});
|
|
865
|
-
for (const reqFile of requirementsFiles)
|
|
866
|
-
|
|
867
|
-
} catch {
|
|
868
|
-
continue;
|
|
869
|
-
}
|
|
870
|
-
const settingsFiles = await fg("**/settings.py", {
|
|
842
|
+
for (const reqFile of requirementsFiles) if (readProjectFile(path$1.join(installDir, reqFile))?.includes("djangorestframework")) return true;
|
|
843
|
+
const settingsFiles = await boundedGlob("**/settings.py", {
|
|
871
844
|
cwd: installDir,
|
|
872
|
-
|
|
845
|
+
extraIgnore: EXTRA_IGNORE$8
|
|
873
846
|
});
|
|
874
|
-
for (const settingsFile of settingsFiles)
|
|
875
|
-
if (fs$1.readFileSync(path$1.join(installDir, settingsFile), "utf-8").includes("rest_framework")) return true;
|
|
876
|
-
} catch {
|
|
877
|
-
continue;
|
|
878
|
-
}
|
|
847
|
+
for (const settingsFile of settingsFiles) if (readProjectFile(path$1.join(installDir, settingsFile))?.includes("rest_framework")) return true;
|
|
879
848
|
return false;
|
|
880
849
|
}
|
|
881
850
|
/**
|
|
882
851
|
* Check if Wagtail is installed
|
|
883
852
|
*/
|
|
884
853
|
async function hasWagtail({ installDir }) {
|
|
885
|
-
const requirementsFiles = await
|
|
854
|
+
const requirementsFiles = await boundedGlob([
|
|
886
855
|
"**/requirements*.txt",
|
|
887
856
|
"**/pyproject.toml",
|
|
888
857
|
"**/Pipfile"
|
|
889
858
|
], {
|
|
890
859
|
cwd: installDir,
|
|
891
|
-
|
|
860
|
+
extraIgnore: EXTRA_IGNORE$8
|
|
892
861
|
});
|
|
893
|
-
for (const reqFile of requirementsFiles)
|
|
894
|
-
if (fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8").includes("wagtail")) return true;
|
|
895
|
-
} catch {
|
|
896
|
-
continue;
|
|
897
|
-
}
|
|
862
|
+
for (const reqFile of requirementsFiles) if (readProjectFile(path$1.join(installDir, reqFile))?.includes("wagtail")) return true;
|
|
898
863
|
return false;
|
|
899
864
|
}
|
|
900
865
|
/**
|
|
901
866
|
* Check if Django Channels is installed
|
|
902
867
|
*/
|
|
903
868
|
async function hasChannels({ installDir }) {
|
|
904
|
-
const requirementsFiles = await
|
|
869
|
+
const requirementsFiles = await boundedGlob([
|
|
905
870
|
"**/requirements*.txt",
|
|
906
871
|
"**/pyproject.toml",
|
|
907
872
|
"**/Pipfile"
|
|
908
873
|
], {
|
|
909
874
|
cwd: installDir,
|
|
910
|
-
|
|
875
|
+
extraIgnore: EXTRA_IGNORE$8
|
|
911
876
|
});
|
|
912
|
-
for (const reqFile of requirementsFiles)
|
|
913
|
-
if (fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8").includes("channels")) return true;
|
|
914
|
-
} catch {
|
|
915
|
-
continue;
|
|
916
|
-
}
|
|
877
|
+
for (const reqFile of requirementsFiles) if (readProjectFile(path$1.join(installDir, reqFile))?.includes("channels")) return true;
|
|
917
878
|
return false;
|
|
918
879
|
}
|
|
919
880
|
/**
|
|
@@ -952,28 +913,26 @@ function getDjangoProjectTypeName(projectType) {
|
|
|
952
913
|
*/
|
|
953
914
|
async function findDjangoSettingsFile(options) {
|
|
954
915
|
const { installDir } = options;
|
|
955
|
-
const settingsFiles = await
|
|
916
|
+
const settingsFiles = await boundedGlob("**/settings.py", {
|
|
956
917
|
cwd: installDir,
|
|
957
|
-
|
|
918
|
+
extraIgnore: EXTRA_IGNORE$8
|
|
958
919
|
});
|
|
959
920
|
if (settingsFiles.length === 0) {
|
|
960
|
-
const splitSettingsFiles = await
|
|
921
|
+
const splitSettingsFiles = await boundedGlob("**/settings/__init__.py", {
|
|
961
922
|
cwd: installDir,
|
|
962
|
-
|
|
923
|
+
extraIgnore: EXTRA_IGNORE$8,
|
|
924
|
+
limit: 1
|
|
963
925
|
});
|
|
964
926
|
if (splitSettingsFiles.length > 0) return splitSettingsFiles[0];
|
|
965
927
|
return;
|
|
966
928
|
}
|
|
967
929
|
if (settingsFiles.length === 1) return settingsFiles[0];
|
|
968
|
-
for (const settingsFile of settingsFiles)
|
|
969
|
-
if (fs$1.readFileSync(path$1.join(installDir, settingsFile), "utf-8").includes("ROOT_URLCONF")) return settingsFile;
|
|
970
|
-
} catch {
|
|
971
|
-
continue;
|
|
972
|
-
}
|
|
930
|
+
for (const settingsFile of settingsFiles) if (readProjectFile(path$1.join(installDir, settingsFile))?.includes("ROOT_URLCONF")) return settingsFile;
|
|
973
931
|
return settingsFiles[0];
|
|
974
932
|
}
|
|
975
933
|
//#endregion
|
|
976
934
|
//#region src/frameworks/django/django-wizard-agent.ts
|
|
935
|
+
const EXTRA_IGNORE$7 = ["**/env/**", "**/.env/**"];
|
|
977
936
|
const DJANGO_AGENT_CONFIG = {
|
|
978
937
|
metadata: {
|
|
979
938
|
name: "Django",
|
|
@@ -997,39 +956,27 @@ const DJANGO_AGENT_CONFIG = {
|
|
|
997
956
|
getInstalledVersion: (options) => getDjangoVersion(options),
|
|
998
957
|
detect: async (options) => {
|
|
999
958
|
const { installDir } = options;
|
|
1000
|
-
const managePyMatches = await
|
|
959
|
+
const managePyMatches = await boundedGlob("**/manage.py", {
|
|
1001
960
|
cwd: installDir,
|
|
1002
|
-
|
|
1003
|
-
"**/venv/**",
|
|
1004
|
-
"**/.venv/**",
|
|
1005
|
-
"**/env/**",
|
|
1006
|
-
"**/.env/**"
|
|
1007
|
-
]
|
|
961
|
+
extraIgnore: EXTRA_IGNORE$7
|
|
1008
962
|
});
|
|
1009
|
-
if (managePyMatches.length > 0) for (const match of managePyMatches)
|
|
1010
|
-
const content =
|
|
963
|
+
if (managePyMatches.length > 0) for (const match of managePyMatches) {
|
|
964
|
+
const content = readProjectFile(path$1.join(installDir, match));
|
|
965
|
+
if (!content) continue;
|
|
1011
966
|
if (content.includes("from django") || content.includes("import django") || content.includes("DJANGO_SETTINGS_MODULE") || /execute_from_command_line/.test(content)) return true;
|
|
1012
|
-
} catch {
|
|
1013
|
-
continue;
|
|
1014
967
|
}
|
|
1015
|
-
const requirementsFiles = await
|
|
968
|
+
const requirementsFiles = await boundedGlob([
|
|
1016
969
|
"**/requirements*.txt",
|
|
1017
970
|
"**/pyproject.toml",
|
|
1018
971
|
"**/setup.py"
|
|
1019
972
|
], {
|
|
1020
973
|
cwd: installDir,
|
|
1021
|
-
|
|
1022
|
-
"**/venv/**",
|
|
1023
|
-
"**/.venv/**",
|
|
1024
|
-
"**/env/**",
|
|
1025
|
-
"**/.env/**"
|
|
1026
|
-
]
|
|
974
|
+
extraIgnore: EXTRA_IGNORE$7
|
|
1027
975
|
});
|
|
1028
|
-
for (const reqFile of requirementsFiles)
|
|
1029
|
-
const content =
|
|
976
|
+
for (const reqFile of requirementsFiles) {
|
|
977
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
978
|
+
if (!content) continue;
|
|
1030
979
|
if (/^django([>=~!<\s]|$)/im.test(content) || /["']django["']/i.test(content)) return true;
|
|
1031
|
-
} catch {
|
|
1032
|
-
continue;
|
|
1033
980
|
}
|
|
1034
981
|
return false;
|
|
1035
982
|
},
|
|
@@ -1079,18 +1026,14 @@ const DJANGO_AGENT_CONFIG = {
|
|
|
1079
1026
|
};
|
|
1080
1027
|
//#endregion
|
|
1081
1028
|
//#region src/frameworks/flask/utils.ts
|
|
1082
|
-
const
|
|
1083
|
-
"**/node_modules/**",
|
|
1084
|
-
"**/dist/**",
|
|
1085
|
-
"**/build/**",
|
|
1086
|
-
"**/venv/**",
|
|
1087
|
-
"**/.venv/**",
|
|
1029
|
+
const EXTRA_IGNORE$6 = [
|
|
1088
1030
|
"**/env/**",
|
|
1089
1031
|
"**/.env/**",
|
|
1090
|
-
"**/__pycache__/**",
|
|
1091
1032
|
"**/migrations/**",
|
|
1092
1033
|
"**/instance/**"
|
|
1093
1034
|
];
|
|
1035
|
+
/** Content probes read at most this many files, one in memory at a time. */
|
|
1036
|
+
const SOURCE_PROBE_LIMIT$3 = 200;
|
|
1094
1037
|
/**
|
|
1095
1038
|
* Get Flask version bucket for analytics
|
|
1096
1039
|
*/
|
|
@@ -1100,52 +1043,50 @@ const getFlaskVersionBucket = createVersionBucket();
|
|
|
1100
1043
|
*/
|
|
1101
1044
|
async function getFlaskVersion(options) {
|
|
1102
1045
|
const { installDir } = options;
|
|
1103
|
-
const requirementsFiles = await
|
|
1046
|
+
const requirementsFiles = await boundedGlob([
|
|
1104
1047
|
"**/requirements*.txt",
|
|
1105
1048
|
"**/pyproject.toml",
|
|
1106
1049
|
"**/setup.py",
|
|
1107
1050
|
"**/Pipfile"
|
|
1108
1051
|
], {
|
|
1109
1052
|
cwd: installDir,
|
|
1110
|
-
|
|
1053
|
+
extraIgnore: EXTRA_IGNORE$6
|
|
1111
1054
|
});
|
|
1112
|
-
for (const reqFile of requirementsFiles)
|
|
1113
|
-
const content =
|
|
1055
|
+
for (const reqFile of requirementsFiles) {
|
|
1056
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
1057
|
+
if (!content) continue;
|
|
1114
1058
|
const requirementsMatch = content.match(/[Ff]lask[=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1115
1059
|
if (requirementsMatch) return requirementsMatch[1];
|
|
1116
1060
|
const pyprojectMatch = content.match(/[Ff]lask["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1117
1061
|
if (pyprojectMatch) return pyprojectMatch[1];
|
|
1118
|
-
} catch {
|
|
1119
|
-
continue;
|
|
1120
1062
|
}
|
|
1121
1063
|
}
|
|
1122
1064
|
/**
|
|
1123
1065
|
* Check if Flask-RESTful is installed
|
|
1124
1066
|
*/
|
|
1125
1067
|
async function hasFlaskRESTful({ installDir }) {
|
|
1126
|
-
const requirementsFiles = await
|
|
1068
|
+
const requirementsFiles = await boundedGlob([
|
|
1127
1069
|
"**/requirements*.txt",
|
|
1128
1070
|
"**/pyproject.toml",
|
|
1129
1071
|
"**/Pipfile"
|
|
1130
1072
|
], {
|
|
1131
1073
|
cwd: installDir,
|
|
1132
|
-
|
|
1074
|
+
extraIgnore: EXTRA_IGNORE$6
|
|
1133
1075
|
});
|
|
1134
|
-
for (const reqFile of requirementsFiles)
|
|
1135
|
-
const content =
|
|
1076
|
+
for (const reqFile of requirementsFiles) {
|
|
1077
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
1078
|
+
if (!content) continue;
|
|
1136
1079
|
if (content.includes("flask-restful") || content.includes("Flask-RESTful")) return true;
|
|
1137
|
-
} catch {
|
|
1138
|
-
continue;
|
|
1139
1080
|
}
|
|
1140
|
-
const pyFiles = await
|
|
1081
|
+
const pyFiles = await boundedGlob(["**/*.py"], {
|
|
1141
1082
|
cwd: installDir,
|
|
1142
|
-
|
|
1083
|
+
extraIgnore: EXTRA_IGNORE$6,
|
|
1084
|
+
limit: SOURCE_PROBE_LIMIT$3
|
|
1143
1085
|
});
|
|
1144
|
-
for (const pyFile of pyFiles)
|
|
1145
|
-
const content =
|
|
1086
|
+
for (const pyFile of pyFiles) {
|
|
1087
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1088
|
+
if (!content) continue;
|
|
1146
1089
|
if (content.includes("from flask_restful import") || content.includes("import flask_restful")) return true;
|
|
1147
|
-
} catch {
|
|
1148
|
-
continue;
|
|
1149
1090
|
}
|
|
1150
1091
|
return false;
|
|
1151
1092
|
}
|
|
@@ -1153,29 +1094,28 @@ async function hasFlaskRESTful({ installDir }) {
|
|
|
1153
1094
|
* Check if Flask-RESTX is installed
|
|
1154
1095
|
*/
|
|
1155
1096
|
async function hasFlaskRESTX({ installDir }) {
|
|
1156
|
-
const requirementsFiles = await
|
|
1097
|
+
const requirementsFiles = await boundedGlob([
|
|
1157
1098
|
"**/requirements*.txt",
|
|
1158
1099
|
"**/pyproject.toml",
|
|
1159
1100
|
"**/Pipfile"
|
|
1160
1101
|
], {
|
|
1161
1102
|
cwd: installDir,
|
|
1162
|
-
|
|
1103
|
+
extraIgnore: EXTRA_IGNORE$6
|
|
1163
1104
|
});
|
|
1164
|
-
for (const reqFile of requirementsFiles)
|
|
1165
|
-
const content =
|
|
1105
|
+
for (const reqFile of requirementsFiles) {
|
|
1106
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
1107
|
+
if (!content) continue;
|
|
1166
1108
|
if (content.includes("flask-restx") || content.includes("Flask-RESTX")) return true;
|
|
1167
|
-
} catch {
|
|
1168
|
-
continue;
|
|
1169
1109
|
}
|
|
1170
|
-
const pyFiles = await
|
|
1110
|
+
const pyFiles = await boundedGlob(["**/*.py"], {
|
|
1171
1111
|
cwd: installDir,
|
|
1172
|
-
|
|
1112
|
+
extraIgnore: EXTRA_IGNORE$6,
|
|
1113
|
+
limit: SOURCE_PROBE_LIMIT$3
|
|
1173
1114
|
});
|
|
1174
|
-
for (const pyFile of pyFiles)
|
|
1175
|
-
const content =
|
|
1115
|
+
for (const pyFile of pyFiles) {
|
|
1116
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1117
|
+
if (!content) continue;
|
|
1176
1118
|
if (content.includes("from flask_restx import") || content.includes("import flask_restx")) return true;
|
|
1177
|
-
} catch {
|
|
1178
|
-
continue;
|
|
1179
1119
|
}
|
|
1180
1120
|
return false;
|
|
1181
1121
|
}
|
|
@@ -1183,28 +1123,28 @@ async function hasFlaskRESTX({ installDir }) {
|
|
|
1183
1123
|
* Check if flask-smorest is installed
|
|
1184
1124
|
*/
|
|
1185
1125
|
async function hasFlaskSmorest({ installDir }) {
|
|
1186
|
-
const requirementsFiles = await
|
|
1126
|
+
const requirementsFiles = await boundedGlob([
|
|
1187
1127
|
"**/requirements*.txt",
|
|
1188
1128
|
"**/pyproject.toml",
|
|
1189
1129
|
"**/Pipfile"
|
|
1190
1130
|
], {
|
|
1191
1131
|
cwd: installDir,
|
|
1192
|
-
|
|
1132
|
+
extraIgnore: EXTRA_IGNORE$6
|
|
1193
1133
|
});
|
|
1194
|
-
for (const reqFile of requirementsFiles)
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1134
|
+
for (const reqFile of requirementsFiles) {
|
|
1135
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
1136
|
+
if (!content) continue;
|
|
1137
|
+
if (content.includes("flask-smorest")) return true;
|
|
1198
1138
|
}
|
|
1199
|
-
const pyFiles = await
|
|
1139
|
+
const pyFiles = await boundedGlob(["**/*.py"], {
|
|
1200
1140
|
cwd: installDir,
|
|
1201
|
-
|
|
1141
|
+
extraIgnore: EXTRA_IGNORE$6,
|
|
1142
|
+
limit: SOURCE_PROBE_LIMIT$3
|
|
1202
1143
|
});
|
|
1203
|
-
for (const pyFile of pyFiles)
|
|
1204
|
-
const content =
|
|
1144
|
+
for (const pyFile of pyFiles) {
|
|
1145
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1146
|
+
if (!content) continue;
|
|
1205
1147
|
if (content.includes("from flask_smorest import") || content.includes("import flask_smorest")) return true;
|
|
1206
|
-
} catch {
|
|
1207
|
-
continue;
|
|
1208
1148
|
}
|
|
1209
1149
|
return false;
|
|
1210
1150
|
}
|
|
@@ -1212,15 +1152,15 @@ async function hasFlaskSmorest({ installDir }) {
|
|
|
1212
1152
|
* Check if app uses Flask Blueprints
|
|
1213
1153
|
*/
|
|
1214
1154
|
async function hasBlueprints({ installDir }) {
|
|
1215
|
-
const pyFiles = await
|
|
1155
|
+
const pyFiles = await boundedGlob(["**/*.py"], {
|
|
1216
1156
|
cwd: installDir,
|
|
1217
|
-
|
|
1157
|
+
extraIgnore: EXTRA_IGNORE$6,
|
|
1158
|
+
limit: SOURCE_PROBE_LIMIT$3
|
|
1218
1159
|
});
|
|
1219
|
-
for (const pyFile of pyFiles)
|
|
1220
|
-
const content =
|
|
1160
|
+
for (const pyFile of pyFiles) {
|
|
1161
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1162
|
+
if (!content) continue;
|
|
1221
1163
|
if (content.includes("Blueprint(") || content.includes("register_blueprint(") || content.includes("from flask import Blueprint")) return true;
|
|
1222
|
-
} catch {
|
|
1223
|
-
continue;
|
|
1224
1164
|
}
|
|
1225
1165
|
return false;
|
|
1226
1166
|
}
|
|
@@ -1265,7 +1205,7 @@ function getFlaskProjectTypeName(projectType) {
|
|
|
1265
1205
|
*/
|
|
1266
1206
|
async function findFlaskAppFile(options) {
|
|
1267
1207
|
const { installDir } = options;
|
|
1268
|
-
const appFiles = await
|
|
1208
|
+
const appFiles = await boundedGlob([
|
|
1269
1209
|
"**/app.py",
|
|
1270
1210
|
"**/wsgi.py",
|
|
1271
1211
|
"**/application.py",
|
|
@@ -1274,28 +1214,28 @@ async function findFlaskAppFile(options) {
|
|
|
1274
1214
|
"**/__init__.py"
|
|
1275
1215
|
], {
|
|
1276
1216
|
cwd: installDir,
|
|
1277
|
-
|
|
1217
|
+
extraIgnore: EXTRA_IGNORE$6
|
|
1278
1218
|
});
|
|
1279
|
-
for (const appFile of appFiles)
|
|
1280
|
-
const content =
|
|
1219
|
+
for (const appFile of appFiles) {
|
|
1220
|
+
const content = readProjectFile(path$1.join(installDir, appFile));
|
|
1221
|
+
if (!content) continue;
|
|
1281
1222
|
if (content.includes("Flask(__name__)") || content.includes("Flask(") || content.includes("def create_app(")) return appFile;
|
|
1282
|
-
} catch {
|
|
1283
|
-
continue;
|
|
1284
1223
|
}
|
|
1285
|
-
const allPyFiles = await
|
|
1224
|
+
const allPyFiles = await boundedGlob(["**/*.py"], {
|
|
1286
1225
|
cwd: installDir,
|
|
1287
|
-
|
|
1226
|
+
extraIgnore: EXTRA_IGNORE$6,
|
|
1227
|
+
limit: SOURCE_PROBE_LIMIT$3
|
|
1288
1228
|
});
|
|
1289
|
-
for (const pyFile of allPyFiles)
|
|
1290
|
-
const content =
|
|
1229
|
+
for (const pyFile of allPyFiles) {
|
|
1230
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1231
|
+
if (!content) continue;
|
|
1291
1232
|
if (content.includes("Flask(__name__)") || content.includes("def create_app(")) return pyFile;
|
|
1292
|
-
} catch {
|
|
1293
|
-
continue;
|
|
1294
1233
|
}
|
|
1295
1234
|
if (appFiles.length > 0) return appFiles[0];
|
|
1296
1235
|
}
|
|
1297
1236
|
//#endregion
|
|
1298
1237
|
//#region src/frameworks/flask/flask-wizard-agent.ts
|
|
1238
|
+
const EXTRA_IGNORE$5 = ["**/env/**", "**/.env/**"];
|
|
1299
1239
|
const FLASK_AGENT_CONFIG = {
|
|
1300
1240
|
metadata: {
|
|
1301
1241
|
name: "Flask",
|
|
@@ -1319,46 +1259,33 @@ const FLASK_AGENT_CONFIG = {
|
|
|
1319
1259
|
getInstalledVersion: (options) => getFlaskVersion(options),
|
|
1320
1260
|
detect: async (options) => {
|
|
1321
1261
|
const { installDir } = options;
|
|
1322
|
-
const requirementsFiles = await
|
|
1262
|
+
const requirementsFiles = await boundedGlob([
|
|
1323
1263
|
"**/requirements*.txt",
|
|
1324
1264
|
"**/pyproject.toml",
|
|
1325
1265
|
"**/setup.py",
|
|
1326
1266
|
"**/Pipfile"
|
|
1327
1267
|
], {
|
|
1328
1268
|
cwd: installDir,
|
|
1329
|
-
|
|
1330
|
-
"**/venv/**",
|
|
1331
|
-
"**/.venv/**",
|
|
1332
|
-
"**/env/**",
|
|
1333
|
-
"**/.env/**"
|
|
1334
|
-
]
|
|
1269
|
+
extraIgnore: EXTRA_IGNORE$5
|
|
1335
1270
|
});
|
|
1336
|
-
for (const reqFile of requirementsFiles)
|
|
1337
|
-
const content =
|
|
1271
|
+
for (const reqFile of requirementsFiles) {
|
|
1272
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
1273
|
+
if (!content) continue;
|
|
1338
1274
|
if (/^flask([<>=~!]|$|\s)/im.test(content) || /["']flask["']/i.test(content)) return true;
|
|
1339
|
-
} catch {
|
|
1340
|
-
continue;
|
|
1341
1275
|
}
|
|
1342
|
-
const pyFiles = await
|
|
1276
|
+
const pyFiles = await boundedGlob([
|
|
1343
1277
|
"**/app.py",
|
|
1344
1278
|
"**/wsgi.py",
|
|
1345
1279
|
"**/application.py",
|
|
1346
1280
|
"**/__init__.py"
|
|
1347
1281
|
], {
|
|
1348
1282
|
cwd: installDir,
|
|
1349
|
-
|
|
1350
|
-
"**/venv/**",
|
|
1351
|
-
"**/.venv/**",
|
|
1352
|
-
"**/env/**",
|
|
1353
|
-
"**/.env/**",
|
|
1354
|
-
"**/__pycache__/**"
|
|
1355
|
-
]
|
|
1283
|
+
extraIgnore: EXTRA_IGNORE$5
|
|
1356
1284
|
});
|
|
1357
|
-
for (const pyFile of pyFiles)
|
|
1358
|
-
const content =
|
|
1285
|
+
for (const pyFile of pyFiles) {
|
|
1286
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1287
|
+
if (!content) continue;
|
|
1359
1288
|
if (content.includes("from flask import") || content.includes("import flask") || /Flask\s*\(/.test(content)) return true;
|
|
1360
|
-
} catch {
|
|
1361
|
-
continue;
|
|
1362
1289
|
}
|
|
1363
1290
|
return false;
|
|
1364
1291
|
},
|
|
@@ -1409,17 +1336,13 @@ const FLASK_AGENT_CONFIG = {
|
|
|
1409
1336
|
};
|
|
1410
1337
|
//#endregion
|
|
1411
1338
|
//#region src/frameworks/fastapi/utils.ts
|
|
1412
|
-
const
|
|
1413
|
-
"**/node_modules/**",
|
|
1414
|
-
"**/dist/**",
|
|
1415
|
-
"**/build/**",
|
|
1416
|
-
"**/venv/**",
|
|
1417
|
-
"**/.venv/**",
|
|
1339
|
+
const EXTRA_IGNORE$4 = [
|
|
1418
1340
|
"**/env/**",
|
|
1419
1341
|
"**/.env/**",
|
|
1420
|
-
"**/__pycache__/**",
|
|
1421
1342
|
"**/migrations/**"
|
|
1422
1343
|
];
|
|
1344
|
+
/** Content probes read at most this many files, one in memory at a time. */
|
|
1345
|
+
const SOURCE_PROBE_LIMIT$2 = 200;
|
|
1423
1346
|
/**
|
|
1424
1347
|
* Get FastAPI version bucket for analytics
|
|
1425
1348
|
*/
|
|
@@ -1440,38 +1363,37 @@ function getFastAPIVersionBucket(version) {
|
|
|
1440
1363
|
*/
|
|
1441
1364
|
async function getFastAPIVersion(options) {
|
|
1442
1365
|
const { installDir } = options;
|
|
1443
|
-
const requirementsFiles = await
|
|
1366
|
+
const requirementsFiles = await boundedGlob([
|
|
1444
1367
|
"**/requirements*.txt",
|
|
1445
1368
|
"**/pyproject.toml",
|
|
1446
1369
|
"**/setup.py",
|
|
1447
1370
|
"**/Pipfile"
|
|
1448
1371
|
], {
|
|
1449
1372
|
cwd: installDir,
|
|
1450
|
-
|
|
1373
|
+
extraIgnore: EXTRA_IGNORE$4
|
|
1451
1374
|
});
|
|
1452
|
-
for (const reqFile of requirementsFiles)
|
|
1453
|
-
const content =
|
|
1375
|
+
for (const reqFile of requirementsFiles) {
|
|
1376
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
1377
|
+
if (!content) continue;
|
|
1454
1378
|
const requirementsMatch = content.match(/[Ff]ast[Aa][Pp][Ii][=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1455
1379
|
if (requirementsMatch) return requirementsMatch[1];
|
|
1456
1380
|
const pyprojectMatch = content.match(/[Ff]ast[Aa][Pp][Ii]["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1457
1381
|
if (pyprojectMatch) return pyprojectMatch[1];
|
|
1458
|
-
} catch {
|
|
1459
|
-
continue;
|
|
1460
1382
|
}
|
|
1461
1383
|
}
|
|
1462
1384
|
/**
|
|
1463
1385
|
* Check if app uses FastAPI APIRouter
|
|
1464
1386
|
*/
|
|
1465
1387
|
async function hasAPIRouter({ installDir }) {
|
|
1466
|
-
const pyFiles = await
|
|
1388
|
+
const pyFiles = await boundedGlob(["**/*.py"], {
|
|
1467
1389
|
cwd: installDir,
|
|
1468
|
-
|
|
1390
|
+
extraIgnore: EXTRA_IGNORE$4,
|
|
1391
|
+
limit: SOURCE_PROBE_LIMIT$2
|
|
1469
1392
|
});
|
|
1470
|
-
for (const pyFile of pyFiles)
|
|
1471
|
-
const content =
|
|
1393
|
+
for (const pyFile of pyFiles) {
|
|
1394
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1395
|
+
if (!content) continue;
|
|
1472
1396
|
if (content.includes("APIRouter(") || content.includes("include_router(") || content.includes("from fastapi import APIRouter")) return true;
|
|
1473
|
-
} catch {
|
|
1474
|
-
continue;
|
|
1475
1397
|
}
|
|
1476
1398
|
return false;
|
|
1477
1399
|
}
|
|
@@ -1479,20 +1401,20 @@ async function hasAPIRouter({ installDir }) {
|
|
|
1479
1401
|
* Check if app uses Jinja2 templates (fullstack pattern)
|
|
1480
1402
|
*/
|
|
1481
1403
|
async function hasTemplates({ installDir }) {
|
|
1482
|
-
const pyFiles = await
|
|
1404
|
+
const pyFiles = await boundedGlob(["**/*.py"], {
|
|
1483
1405
|
cwd: installDir,
|
|
1484
|
-
|
|
1406
|
+
extraIgnore: EXTRA_IGNORE$4,
|
|
1407
|
+
limit: SOURCE_PROBE_LIMIT$2
|
|
1485
1408
|
});
|
|
1486
|
-
for (const pyFile of pyFiles)
|
|
1487
|
-
const content =
|
|
1409
|
+
for (const pyFile of pyFiles) {
|
|
1410
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1411
|
+
if (!content) continue;
|
|
1488
1412
|
if (content.includes("Jinja2Templates") || content.includes("from fastapi.templating import")) return true;
|
|
1489
|
-
} catch {
|
|
1490
|
-
continue;
|
|
1491
1413
|
}
|
|
1492
|
-
return (await
|
|
1414
|
+
return (await boundedGlob(["**/templates/**"], {
|
|
1493
1415
|
cwd: installDir,
|
|
1494
|
-
|
|
1495
|
-
|
|
1416
|
+
extraIgnore: EXTRA_IGNORE$4,
|
|
1417
|
+
limit: 1
|
|
1496
1418
|
})).length > 0;
|
|
1497
1419
|
}
|
|
1498
1420
|
/**
|
|
@@ -1526,7 +1448,7 @@ function getFastAPIProjectTypeName(projectType) {
|
|
|
1526
1448
|
*/
|
|
1527
1449
|
async function findFastAPIAppFile(options) {
|
|
1528
1450
|
const { installDir } = options;
|
|
1529
|
-
const appFiles = await
|
|
1451
|
+
const appFiles = await boundedGlob([
|
|
1530
1452
|
"**/main.py",
|
|
1531
1453
|
"**/app.py",
|
|
1532
1454
|
"**/application.py",
|
|
@@ -1534,27 +1456,24 @@ async function findFastAPIAppFile(options) {
|
|
|
1534
1456
|
"**/__init__.py"
|
|
1535
1457
|
], {
|
|
1536
1458
|
cwd: installDir,
|
|
1537
|
-
|
|
1459
|
+
extraIgnore: EXTRA_IGNORE$4
|
|
1538
1460
|
});
|
|
1539
|
-
for (const appFile of appFiles)
|
|
1540
|
-
const content =
|
|
1461
|
+
for (const appFile of appFiles) {
|
|
1462
|
+
const content = readProjectFile(path$1.join(installDir, appFile));
|
|
1463
|
+
if (!content) continue;
|
|
1541
1464
|
if (content.includes("FastAPI(") || content.includes("from fastapi import FastAPI")) return appFile;
|
|
1542
|
-
} catch {
|
|
1543
|
-
continue;
|
|
1544
1465
|
}
|
|
1545
|
-
const allPyFiles = await
|
|
1466
|
+
const allPyFiles = await boundedGlob(["**/*.py"], {
|
|
1546
1467
|
cwd: installDir,
|
|
1547
|
-
|
|
1468
|
+
extraIgnore: EXTRA_IGNORE$4,
|
|
1469
|
+
limit: SOURCE_PROBE_LIMIT$2
|
|
1548
1470
|
});
|
|
1549
|
-
for (const pyFile of allPyFiles)
|
|
1550
|
-
if (fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8").includes("FastAPI(")) return pyFile;
|
|
1551
|
-
} catch {
|
|
1552
|
-
continue;
|
|
1553
|
-
}
|
|
1471
|
+
for (const pyFile of allPyFiles) if (readProjectFile(path$1.join(installDir, pyFile))?.includes("FastAPI(")) return pyFile;
|
|
1554
1472
|
if (appFiles.length > 0) return appFiles[0];
|
|
1555
1473
|
}
|
|
1556
1474
|
//#endregion
|
|
1557
1475
|
//#region src/frameworks/fastapi/fastapi-wizard-agent.ts
|
|
1476
|
+
const EXTRA_IGNORE$3 = ["**/env/**", "**/.env/**"];
|
|
1558
1477
|
/**
|
|
1559
1478
|
* FastAPI framework configuration for the universal agent runner
|
|
1560
1479
|
*/
|
|
@@ -1580,46 +1499,33 @@ const FASTAPI_AGENT_CONFIG = {
|
|
|
1580
1499
|
getInstalledVersion: getFastAPIVersion,
|
|
1581
1500
|
detect: async (options) => {
|
|
1582
1501
|
const { installDir } = options;
|
|
1583
|
-
const requirementsFiles = await
|
|
1502
|
+
const requirementsFiles = await boundedGlob([
|
|
1584
1503
|
"**/requirements*.txt",
|
|
1585
1504
|
"**/pyproject.toml",
|
|
1586
1505
|
"**/setup.py",
|
|
1587
1506
|
"**/Pipfile"
|
|
1588
1507
|
], {
|
|
1589
1508
|
cwd: installDir,
|
|
1590
|
-
|
|
1591
|
-
"**/venv/**",
|
|
1592
|
-
"**/.venv/**",
|
|
1593
|
-
"**/env/**",
|
|
1594
|
-
"**/.env/**"
|
|
1595
|
-
]
|
|
1509
|
+
extraIgnore: EXTRA_IGNORE$3
|
|
1596
1510
|
});
|
|
1597
|
-
for (const reqFile of requirementsFiles)
|
|
1598
|
-
const content =
|
|
1511
|
+
for (const reqFile of requirementsFiles) {
|
|
1512
|
+
const content = readProjectFile(path$1.join(installDir, reqFile));
|
|
1513
|
+
if (!content) continue;
|
|
1599
1514
|
if (/^fastapi([<>=~!]|$|\s)/im.test(content) || /["']fastapi["']/i.test(content)) return true;
|
|
1600
|
-
} catch {
|
|
1601
|
-
continue;
|
|
1602
1515
|
}
|
|
1603
|
-
const pyFiles = await
|
|
1516
|
+
const pyFiles = await boundedGlob([
|
|
1604
1517
|
"**/main.py",
|
|
1605
1518
|
"**/app.py",
|
|
1606
1519
|
"**/application.py",
|
|
1607
1520
|
"**/__init__.py"
|
|
1608
1521
|
], {
|
|
1609
1522
|
cwd: installDir,
|
|
1610
|
-
|
|
1611
|
-
"**/venv/**",
|
|
1612
|
-
"**/.venv/**",
|
|
1613
|
-
"**/env/**",
|
|
1614
|
-
"**/.env/**",
|
|
1615
|
-
"**/__pycache__/**"
|
|
1616
|
-
]
|
|
1523
|
+
extraIgnore: EXTRA_IGNORE$3
|
|
1617
1524
|
});
|
|
1618
|
-
for (const pyFile of pyFiles)
|
|
1619
|
-
const content =
|
|
1525
|
+
for (const pyFile of pyFiles) {
|
|
1526
|
+
const content = readProjectFile(path$1.join(installDir, pyFile));
|
|
1527
|
+
if (!content) continue;
|
|
1620
1528
|
if (content.includes("from fastapi import") || content.includes("import fastapi") || /FastAPI\s*\(/.test(content)) return true;
|
|
1621
|
-
} catch {
|
|
1622
|
-
continue;
|
|
1623
1529
|
}
|
|
1624
1530
|
return false;
|
|
1625
1531
|
},
|
|
@@ -1672,18 +1578,15 @@ const FASTAPI_AGENT_CONFIG = {
|
|
|
1672
1578
|
};
|
|
1673
1579
|
//#endregion
|
|
1674
1580
|
//#region src/frameworks/laravel/utils.ts
|
|
1675
|
-
|
|
1676
|
-
* Ignore patterns for Laravel projects
|
|
1677
|
-
*/
|
|
1678
|
-
const LARAVEL_IGNORE_PATTERNS = [
|
|
1679
|
-
"**/node_modules/**",
|
|
1680
|
-
"**/vendor/**",
|
|
1581
|
+
const EXTRA_IGNORE$2 = [
|
|
1681
1582
|
"**/storage/**",
|
|
1682
1583
|
"**/bootstrap/cache/**",
|
|
1683
1584
|
"**/.phpunit.cache/**",
|
|
1684
1585
|
"**/public/build/**",
|
|
1685
1586
|
"**/public/hot/**"
|
|
1686
1587
|
];
|
|
1588
|
+
/** Content probes read at most this many files, one in memory at a time. */
|
|
1589
|
+
const SOURCE_PROBE_LIMIT$1 = 200;
|
|
1687
1590
|
/**
|
|
1688
1591
|
* Get Laravel version bucket for analytics
|
|
1689
1592
|
*/
|
|
@@ -1723,16 +1626,16 @@ function getComposerPackageVersion(packageName, options) {
|
|
|
1723
1626
|
*/
|
|
1724
1627
|
async function hasLaravelCodePattern(pattern, options, filePatterns = ["**/*.php"]) {
|
|
1725
1628
|
const { installDir } = options;
|
|
1726
|
-
const phpFiles = await
|
|
1629
|
+
const phpFiles = await boundedGlob(filePatterns, {
|
|
1727
1630
|
cwd: installDir,
|
|
1728
|
-
|
|
1631
|
+
extraIgnore: EXTRA_IGNORE$2,
|
|
1632
|
+
limit: SOURCE_PROBE_LIMIT$1
|
|
1729
1633
|
});
|
|
1730
1634
|
const searchPattern = typeof pattern === "string" ? new RegExp(pattern) : pattern;
|
|
1731
|
-
for (const phpFile of phpFiles)
|
|
1732
|
-
const content =
|
|
1635
|
+
for (const phpFile of phpFiles) {
|
|
1636
|
+
const content = readProjectFile(path$1.join(installDir, phpFile));
|
|
1637
|
+
if (!content) continue;
|
|
1733
1638
|
if (searchPattern.test(content)) return true;
|
|
1734
|
-
} catch {
|
|
1735
|
-
continue;
|
|
1736
1639
|
}
|
|
1737
1640
|
return false;
|
|
1738
1641
|
}
|
|
@@ -1787,9 +1690,10 @@ async function findLaravelServiceProvider(options) {
|
|
|
1787
1690
|
const { installDir } = options;
|
|
1788
1691
|
const appServiceProvider = path$1.join(installDir, "app/Providers/AppServiceProvider.php");
|
|
1789
1692
|
if (fs$1.existsSync(appServiceProvider)) return "app/Providers/AppServiceProvider.php";
|
|
1790
|
-
return (await
|
|
1693
|
+
return (await boundedGlob(["**/app/Providers/*ServiceProvider.php"], {
|
|
1791
1694
|
cwd: installDir,
|
|
1792
|
-
|
|
1695
|
+
extraIgnore: EXTRA_IGNORE$2,
|
|
1696
|
+
limit: 1
|
|
1793
1697
|
}))[0];
|
|
1794
1698
|
}
|
|
1795
1699
|
/**
|
|
@@ -1855,9 +1759,9 @@ const LARAVEL_AGENT_CONFIG = {
|
|
|
1855
1759
|
const composer = JSON.parse(content);
|
|
1856
1760
|
if (composer.require?.["laravel/framework"] || composer["require-dev"]?.["laravel/framework"]) return true;
|
|
1857
1761
|
} catch {}
|
|
1858
|
-
return (await
|
|
1762
|
+
return (await boundedGlob(["**/bootstrap/app.php", "**/app/Http/Kernel.php"], {
|
|
1859
1763
|
cwd: installDir,
|
|
1860
|
-
|
|
1764
|
+
limit: 1
|
|
1861
1765
|
})).length > 0;
|
|
1862
1766
|
},
|
|
1863
1767
|
detectPackageManager: composerPackageManager
|
|
@@ -1957,6 +1861,9 @@ const SVELTEKIT_AGENT_CONFIG = {
|
|
|
1957
1861
|
};
|
|
1958
1862
|
//#endregion
|
|
1959
1863
|
//#region src/frameworks/swift/utils.ts
|
|
1864
|
+
const EXTRA_IGNORE$1 = ["**/.build/**", "**/*.xcodeproj/**"];
|
|
1865
|
+
/** Content probes read at most this many files, one in memory at a time. */
|
|
1866
|
+
const SOURCE_PROBE_LIMIT = 200;
|
|
1960
1867
|
function getSwiftProjectTypeName(projectType) {
|
|
1961
1868
|
switch (projectType) {
|
|
1962
1869
|
case "swiftui": return "SwiftUI";
|
|
@@ -1973,24 +1880,18 @@ async function detectSwiftProjectType(options) {
|
|
|
1973
1880
|
onlyDirectories: true
|
|
1974
1881
|
});
|
|
1975
1882
|
if (hasPackageSwift && xcodeProjects.length === 0 && !hasXcodeGenSpec) return "spm";
|
|
1976
|
-
const swiftFiles = await
|
|
1883
|
+
const swiftFiles = await boundedGlob("**/*.swift", {
|
|
1977
1884
|
cwd: installDir,
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
"**/DerivedData/**",
|
|
1981
|
-
"**/build/**",
|
|
1982
|
-
"**/*.xcodeproj/**",
|
|
1983
|
-
"**/Pods/**"
|
|
1984
|
-
]
|
|
1885
|
+
extraIgnore: EXTRA_IGNORE$1,
|
|
1886
|
+
limit: SOURCE_PROBE_LIMIT
|
|
1985
1887
|
});
|
|
1986
1888
|
let hasSwiftUI = false;
|
|
1987
1889
|
let hasUIKit = false;
|
|
1988
|
-
for (const file of swiftFiles)
|
|
1989
|
-
const content =
|
|
1890
|
+
for (const file of swiftFiles) {
|
|
1891
|
+
const content = readProjectFile(path$1.join(installDir, file));
|
|
1892
|
+
if (!content) continue;
|
|
1990
1893
|
if (content.includes("import SwiftUI")) hasSwiftUI = true;
|
|
1991
1894
|
if (content.includes("import UIKit")) hasUIKit = true;
|
|
1992
|
-
} catch {
|
|
1993
|
-
continue;
|
|
1994
1895
|
}
|
|
1995
1896
|
if (hasSwiftUI) return "swiftui";
|
|
1996
1897
|
if (hasUIKit) return "uikit";
|
|
@@ -2020,15 +1921,10 @@ const SWIFT_AGENT_CONFIG = {
|
|
|
2020
1921
|
});
|
|
2021
1922
|
const hasXcodeGenSpec = fs$1.existsSync(path$1.join(installDir, "project.yml"));
|
|
2022
1923
|
if (xcodeProjects.length > 0 || hasXcodeGenSpec) {
|
|
2023
|
-
if ((await
|
|
1924
|
+
if ((await boundedGlob("**/*.swift", {
|
|
2024
1925
|
cwd: installDir,
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
"**/DerivedData/**",
|
|
2028
|
-
"**/build/**",
|
|
2029
|
-
"**/*.xcodeproj/**",
|
|
2030
|
-
"**/Pods/**"
|
|
2031
|
-
]
|
|
1926
|
+
extraIgnore: ["**/.build/**", "**/*.xcodeproj/**"],
|
|
1927
|
+
limit: 1
|
|
2032
1928
|
})).length > 0) return true;
|
|
2033
1929
|
}
|
|
2034
1930
|
const packageSwiftPath = path$1.join(installDir, "Package.swift");
|
|
@@ -2088,26 +1984,15 @@ const KMP_AGENT_CONFIG = {
|
|
|
2088
1984
|
detectPackageManager: gradlePackageManager,
|
|
2089
1985
|
detect: async (options) => {
|
|
2090
1986
|
const { installDir } = options;
|
|
2091
|
-
const buildFiles = await
|
|
2092
|
-
cwd: installDir,
|
|
2093
|
-
ignore: [
|
|
2094
|
-
"**/build/**",
|
|
2095
|
-
"**/node_modules/**",
|
|
2096
|
-
"**/.gradle/**"
|
|
2097
|
-
]
|
|
2098
|
-
});
|
|
1987
|
+
const buildFiles = await boundedGlob(["**/build.gradle", "**/build.gradle.kts"], { cwd: installDir });
|
|
2099
1988
|
for (const file of buildFiles) {
|
|
2100
|
-
const content =
|
|
1989
|
+
const content = readProjectFile(path$1.join(installDir, file));
|
|
1990
|
+
if (!content) continue;
|
|
2101
1991
|
if (content.includes("kotlin(\"multiplatform\")") || content.includes("org.jetbrains.kotlin.multiplatform") || content.includes("kotlin-multiplatform")) return true;
|
|
2102
1992
|
}
|
|
2103
|
-
return (await
|
|
1993
|
+
return (await boundedGlob("**/src/commonMain/**", {
|
|
2104
1994
|
cwd: installDir,
|
|
2105
|
-
|
|
2106
|
-
ignore: [
|
|
2107
|
-
"**/build/**",
|
|
2108
|
-
"**/node_modules/**",
|
|
2109
|
-
"**/.gradle/**"
|
|
2110
|
-
]
|
|
1995
|
+
limit: 1
|
|
2111
1996
|
})).length > 0;
|
|
2112
1997
|
}
|
|
2113
1998
|
},
|
|
@@ -2149,26 +2034,18 @@ const KMP_AGENT_CONFIG = {
|
|
|
2149
2034
|
};
|
|
2150
2035
|
//#endregion
|
|
2151
2036
|
//#region src/frameworks/android/utils.ts
|
|
2152
|
-
const IGNORE_PATTERNS$2 = [
|
|
2153
|
-
"**/build/**",
|
|
2154
|
-
"**/.gradle/**",
|
|
2155
|
-
"**/node_modules/**"
|
|
2156
|
-
];
|
|
2157
2037
|
/**
|
|
2158
2038
|
* Extract minSdk from the app-level build.gradle(.kts).
|
|
2159
2039
|
* Returns the value as a semver-like string (e.g. "24" from minSdk = 24).
|
|
2160
2040
|
*/
|
|
2161
2041
|
async function getMinSdkVersion(options) {
|
|
2162
2042
|
const { installDir } = options;
|
|
2163
|
-
const buildFiles = await
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
const match = fs$1.readFileSync(path$1.join(installDir, file), "utf-8").match(/minSdk(?:Version)?\s*=?\s*(\d+)/);
|
|
2043
|
+
const buildFiles = await boundedGlob(["**/build.gradle", "**/build.gradle.kts"], { cwd: installDir });
|
|
2044
|
+
for (const file of buildFiles) {
|
|
2045
|
+
const content = readProjectFile(path$1.join(installDir, file));
|
|
2046
|
+
if (!content) continue;
|
|
2047
|
+
const match = content.match(/minSdk(?:Version)?\s*=?\s*(\d+)/);
|
|
2169
2048
|
if (match) return match[1];
|
|
2170
|
-
} catch {
|
|
2171
|
-
continue;
|
|
2172
2049
|
}
|
|
2173
2050
|
}
|
|
2174
2051
|
const getKotlinVersionBucket = createVersionBucket();
|
|
@@ -2222,21 +2099,13 @@ const ANDROID_AGENT_CONFIG = {
|
|
|
2222
2099
|
if (content.includes("com.android.application") || content.includes("com.android.library") || content.includes("com.android.tools.build:gradle")) return true;
|
|
2223
2100
|
}
|
|
2224
2101
|
}
|
|
2225
|
-
if ((await
|
|
2102
|
+
if ((await boundedGlob("**/AndroidManifest.xml", {
|
|
2226
2103
|
cwd: installDir,
|
|
2227
|
-
|
|
2228
|
-
"**/build/**",
|
|
2229
|
-
"**/node_modules/**",
|
|
2230
|
-
"**/.gradle/**"
|
|
2231
|
-
]
|
|
2104
|
+
limit: 1
|
|
2232
2105
|
})).length > 0) {
|
|
2233
|
-
if ((await
|
|
2106
|
+
if ((await boundedGlob("**/*.kt", {
|
|
2234
2107
|
cwd: installDir,
|
|
2235
|
-
|
|
2236
|
-
"**/build/**",
|
|
2237
|
-
"**/node_modules/**",
|
|
2238
|
-
"**/.gradle/**"
|
|
2239
|
-
]
|
|
2108
|
+
limit: 1
|
|
2240
2109
|
})).length > 0) return true;
|
|
2241
2110
|
}
|
|
2242
2111
|
return false;
|
|
@@ -2277,7 +2146,7 @@ const ANDROID_AGENT_CONFIG = {
|
|
|
2277
2146
|
};
|
|
2278
2147
|
//#endregion
|
|
2279
2148
|
//#region src/frameworks/rails/utils.ts
|
|
2280
|
-
const IGNORE_PATTERNS
|
|
2149
|
+
const IGNORE_PATTERNS = [
|
|
2281
2150
|
"**/node_modules/**",
|
|
2282
2151
|
"**/vendor/**",
|
|
2283
2152
|
"**/vendor/bundle/**",
|
|
@@ -2371,7 +2240,7 @@ async function isRailsProject(options) {
|
|
|
2371
2240
|
if (hasGem("rails", options)) return true;
|
|
2372
2241
|
return (await fg(["config/routes.rb", "config/environment.rb"], {
|
|
2373
2242
|
cwd: installDir,
|
|
2374
|
-
ignore: IGNORE_PATTERNS
|
|
2243
|
+
ignore: IGNORE_PATTERNS
|
|
2375
2244
|
})).length >= 2;
|
|
2376
2245
|
}
|
|
2377
2246
|
//#endregion
|
|
@@ -2568,13 +2437,7 @@ const PYTHON_AGENT_CONFIG = {
|
|
|
2568
2437
|
};
|
|
2569
2438
|
//#endregion
|
|
2570
2439
|
//#region src/frameworks/ruby/utils.ts
|
|
2571
|
-
const
|
|
2572
|
-
"**/node_modules/**",
|
|
2573
|
-
"**/vendor/**",
|
|
2574
|
-
"**/vendor/bundle/**",
|
|
2575
|
-
"**/tmp/**",
|
|
2576
|
-
"**/log/**"
|
|
2577
|
-
];
|
|
2440
|
+
const EXTRA_IGNORE = ["**/tmp/**", "**/log/**"];
|
|
2578
2441
|
/**
|
|
2579
2442
|
* Get Ruby version bucket for analytics
|
|
2580
2443
|
*/
|
|
@@ -2628,17 +2491,19 @@ async function isRubyProject(options) {
|
|
|
2628
2491
|
}
|
|
2629
2492
|
const rubyVersionPath = path$1.join(installDir, ".ruby-version");
|
|
2630
2493
|
if (fs$1.existsSync(rubyVersionPath)) return true;
|
|
2631
|
-
if ((await
|
|
2494
|
+
if ((await boundedGlob("*.gemspec", {
|
|
2632
2495
|
cwd: installDir,
|
|
2633
|
-
|
|
2496
|
+
extraIgnore: EXTRA_IGNORE,
|
|
2497
|
+
limit: 1
|
|
2634
2498
|
})).length > 0) return true;
|
|
2635
|
-
return (await
|
|
2499
|
+
return (await boundedGlob([
|
|
2636
2500
|
"*.rb",
|
|
2637
2501
|
"lib/**/*.rb",
|
|
2638
2502
|
"bin/**/*.rb"
|
|
2639
2503
|
], {
|
|
2640
2504
|
cwd: installDir,
|
|
2641
|
-
|
|
2505
|
+
extraIgnore: EXTRA_IGNORE,
|
|
2506
|
+
limit: 1
|
|
2642
2507
|
})).length > 0;
|
|
2643
2508
|
}
|
|
2644
2509
|
//#endregion
|
|
@@ -2787,15 +2652,6 @@ const JAVASCRIPT_NODE_AGENT_CONFIG = {
|
|
|
2787
2652
|
//#endregion
|
|
2788
2653
|
//#region src/frameworks/javascript-web/utils.ts
|
|
2789
2654
|
const INDEX_HTML_MAX_DEPTH = 6;
|
|
2790
|
-
const INDEX_HTML_IGNORE_DIRS = new Set([
|
|
2791
|
-
"node_modules",
|
|
2792
|
-
".git",
|
|
2793
|
-
".next",
|
|
2794
|
-
"dist",
|
|
2795
|
-
"build",
|
|
2796
|
-
".turbo",
|
|
2797
|
-
".cache"
|
|
2798
|
-
]);
|
|
2799
2655
|
/**
|
|
2800
2656
|
* Packages that indicate a specific framework integration exists.
|
|
2801
2657
|
* If any of these are in package.json, we should NOT match as generic JavaScript.
|
|
@@ -2849,25 +2705,12 @@ function detectBundler(options) {
|
|
|
2849
2705
|
* Heuristic: check if there is an index.html anywhere in the project,
|
|
2850
2706
|
* ignoring common build and dependency directories.
|
|
2851
2707
|
*/
|
|
2852
|
-
function hasIndexHtml(options) {
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
let entries;
|
|
2859
|
-
try {
|
|
2860
|
-
entries = fs$1.readdirSync(dir, { withFileTypes: true });
|
|
2861
|
-
} catch {
|
|
2862
|
-
return false;
|
|
2863
|
-
}
|
|
2864
|
-
for (const entry of entries) if (entry.isFile() && entry.name.toLowerCase() === "index.html") return true;
|
|
2865
|
-
for (const entry of entries) if (entry.isDirectory()) {
|
|
2866
|
-
if (search(path$1.join(dir, entry.name), depth + 1)) return true;
|
|
2867
|
-
}
|
|
2868
|
-
return false;
|
|
2869
|
-
}
|
|
2870
|
-
return search(root, 0);
|
|
2708
|
+
async function hasIndexHtml(options) {
|
|
2709
|
+
return (await boundedGlob("**/index.html", {
|
|
2710
|
+
cwd: options.installDir,
|
|
2711
|
+
deep: INDEX_HTML_MAX_DEPTH,
|
|
2712
|
+
limit: 1
|
|
2713
|
+
})).length > 0;
|
|
2871
2714
|
}
|
|
2872
2715
|
//#endregion
|
|
2873
2716
|
//#region src/frameworks/javascript-web/javascript-web-wizard-agent.ts
|
|
@@ -2898,7 +2741,7 @@ const JAVASCRIPT_WEB_AGENT_CONFIG = {
|
|
|
2898
2741
|
if (!packageJson) return false;
|
|
2899
2742
|
for (const frameworkPkg of FRAMEWORK_PACKAGES) if (hasDeclaredDependency(frameworkPkg, packageJson)) return false;
|
|
2900
2743
|
const { installDir } = options;
|
|
2901
|
-
const hasIndexHtmlFlag = hasIndexHtml(options);
|
|
2744
|
+
const hasIndexHtmlFlag = await hasIndexHtml(options);
|
|
2902
2745
|
const hasBundler = !!detectBundler(options);
|
|
2903
2746
|
if ([
|
|
2904
2747
|
"package-lock.json",
|
|
@@ -2987,4 +2830,4 @@ const FRAMEWORK_REGISTRY = {
|
|
|
2987
2830
|
//#endregion
|
|
2988
2831
|
export { SPINNER_MESSAGE as i, registry_exports as n, DEFAULT_PACKAGE_INSTALLATION as r, FRAMEWORK_REGISTRY as t };
|
|
2989
2832
|
|
|
2990
|
-
//# sourceMappingURL=registry-
|
|
2833
|
+
//# sourceMappingURL=registry-BMjfECF2.js.map
|