@superblocksteam/vite-plugin-file-sync 2.0.167-next.0 → 2.0.168-next.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/ai-service/agent/middleware.d.ts.map +1 -1
- package/dist/ai-service/agent/middleware.js +23 -0
- package/dist/ai-service/agent/middleware.js.map +1 -1
- package/dist/ai-service/agent/tool-message-utils.d.ts +1 -1
- package/dist/ai-service/agent/tool-message-utils.d.ts.map +1 -1
- package/dist/ai-service/agent/tool-message-utils.js.map +1 -1
- package/dist/ai-service/agent/tool-permission-delivery.d.ts +5 -4
- package/dist/ai-service/agent/tool-permission-delivery.d.ts.map +1 -1
- package/dist/ai-service/agent/tool-permission-delivery.js +22 -28
- package/dist/ai-service/agent/tool-permission-delivery.js.map +1 -1
- package/dist/ai-service/agent/tool-permission-outcome-metrics.d.ts +9 -0
- package/dist/ai-service/agent/tool-permission-outcome-metrics.d.ts.map +1 -0
- package/dist/ai-service/agent/tool-permission-outcome-metrics.js +23 -0
- package/dist/ai-service/agent/tool-permission-outcome-metrics.js.map +1 -0
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts +44 -0
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-capture-screenshot.js +198 -18
- package/dist/ai-service/agent/tools/build-capture-screenshot.js.map +1 -1
- package/dist/ai-service/agent/tools/build-manage-checklist.d.ts +2 -0
- package/dist/ai-service/agent/tools/build-manage-checklist.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-manage-checklist.js.map +1 -1
- package/dist/ai-service/agent/tools/build-reload-file.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-reload-file.js +32 -19
- package/dist/ai-service/agent/tools/build-reload-file.js.map +1 -1
- package/dist/ai-service/agent/tools/get-security-findings.d.ts +45 -0
- package/dist/ai-service/agent/tools/get-security-findings.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/get-security-findings.js +74 -0
- package/dist/ai-service/agent/tools/get-security-findings.js.map +1 -0
- package/dist/ai-service/agent/tools/integrations/integration-setup.d.ts +2 -2
- package/dist/ai-service/agent/tools/integrations/integration-setup.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/integration-setup.js +24 -2
- package/dist/ai-service/agent/tools/integrations/integration-setup.js.map +1 -1
- package/dist/ai-service/agent/tools/report-security-findings.d.ts +20 -20
- package/dist/ai-service/agent/tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools.js +13 -2
- package/dist/ai-service/agent/tools.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +14 -0
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/git.d.ts +2 -1
- package/dist/ai-service/agent/tools2/tools/git.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/git.js +1 -1
- package/dist/ai-service/agent/tools2/tools/git.js.map +1 -1
- package/dist/ai-service/agent/utils.d.ts.map +1 -1
- package/dist/ai-service/agent/utils.js +5 -0
- package/dist/ai-service/agent/utils.js.map +1 -1
- package/dist/ai-service/app-interface/app-package-manager.d.ts +43 -0
- package/dist/ai-service/app-interface/app-package-manager.d.ts.map +1 -0
- package/dist/ai-service/app-interface/app-package-manager.js +82 -0
- package/dist/ai-service/app-interface/app-package-manager.js.map +1 -0
- package/dist/ai-service/app-interface/constants.d.ts +2 -2
- package/dist/ai-service/app-interface/constants.d.ts.map +1 -1
- package/dist/ai-service/app-interface/constants.js +5 -0
- package/dist/ai-service/app-interface/constants.js.map +1 -1
- package/dist/ai-service/app-interface/file-system-interface.d.ts.map +1 -1
- package/dist/ai-service/app-interface/file-system-interface.js +0 -3
- package/dist/ai-service/app-interface/file-system-interface.js.map +1 -1
- package/dist/ai-service/app-interface/npm-error-parser.d.ts +1 -1
- package/dist/ai-service/app-interface/npm-error-parser.d.ts.map +1 -1
- package/dist/ai-service/app-interface/npm-error-parser.js +42 -8
- package/dist/ai-service/app-interface/npm-error-parser.js.map +1 -1
- package/dist/ai-service/app-interface/npm-registry.d.ts +30 -0
- package/dist/ai-service/app-interface/npm-registry.d.ts.map +1 -1
- package/dist/ai-service/app-interface/npm-registry.js +108 -1
- package/dist/ai-service/app-interface/npm-registry.js.map +1 -1
- package/dist/ai-service/app-interface/pnpm-lockfile.d.ts +28 -0
- package/dist/ai-service/app-interface/pnpm-lockfile.d.ts.map +1 -0
- package/dist/ai-service/app-interface/pnpm-lockfile.js +89 -0
- package/dist/ai-service/app-interface/pnpm-lockfile.js.map +1 -0
- package/dist/ai-service/app-interface/shell.d.ts +43 -7
- package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
- package/dist/ai-service/app-interface/shell.js +252 -119
- package/dist/ai-service/app-interface/shell.js.map +1 -1
- package/dist/ai-service/app-interface/vulnerability-gate.d.ts +5 -0
- package/dist/ai-service/app-interface/vulnerability-gate.d.ts.map +1 -1
- package/dist/ai-service/app-interface/vulnerability-gate.js +3 -0
- package/dist/ai-service/app-interface/vulnerability-gate.js.map +1 -1
- package/dist/ai-service/app-skills/helpers.d.ts.map +1 -1
- package/dist/ai-service/app-skills/helpers.js +9 -9
- package/dist/ai-service/app-skills/helpers.js.map +1 -1
- package/dist/ai-service/chat/chat-session-store.d.ts +4 -1
- package/dist/ai-service/chat/chat-session-store.d.ts.map +1 -1
- package/dist/ai-service/chat/chat-session-store.js +4 -0
- package/dist/ai-service/chat/chat-session-store.js.map +1 -1
- package/dist/ai-service/checklist/persisted-checklist-store.d.ts +66 -1
- package/dist/ai-service/checklist/persisted-checklist-store.d.ts.map +1 -1
- package/dist/ai-service/checklist/persisted-checklist-store.js +274 -4
- package/dist/ai-service/checklist/persisted-checklist-store.js.map +1 -1
- package/dist/ai-service/checklist/policy-remediation.d.ts +8 -0
- package/dist/ai-service/checklist/policy-remediation.d.ts.map +1 -0
- package/dist/ai-service/checklist/policy-remediation.js +46 -0
- package/dist/ai-service/checklist/policy-remediation.js.map +1 -0
- package/dist/ai-service/checklist/remediation-findings-client.d.ts +31 -0
- package/dist/ai-service/checklist/remediation-findings-client.d.ts.map +1 -0
- package/dist/ai-service/checklist/remediation-findings-client.js +117 -0
- package/dist/ai-service/checklist/remediation-findings-client.js.map +1 -0
- package/dist/ai-service/context-download.d.ts.map +1 -1
- package/dist/ai-service/context-download.js +76 -37
- package/dist/ai-service/context-download.js.map +1 -1
- package/dist/ai-service/dev-database-file-sync.d.ts +2 -1
- package/dist/ai-service/dev-database-file-sync.d.ts.map +1 -1
- package/dist/ai-service/dev-database-file-sync.js.map +1 -1
- package/dist/ai-service/index.d.ts +59 -9
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +1191 -479
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/integrations/store.d.ts.map +1 -1
- package/dist/ai-service/integrations/store.js +11 -2
- package/dist/ai-service/integrations/store.js.map +1 -1
- package/dist/ai-service/llm/context-v2/adapter.d.ts +3 -0
- package/dist/ai-service/llm/context-v2/adapter.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/adapter.js +6 -0
- package/dist/ai-service/llm/context-v2/adapter.js.map +1 -1
- package/dist/ai-service/llm/context-v2/context.d.ts +22 -1
- package/dist/ai-service/llm/context-v2/context.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/context.js +185 -30
- package/dist/ai-service/llm/context-v2/context.js.map +1 -1
- package/dist/ai-service/llm/context-v2/conversation-context.d.ts +7 -0
- package/dist/ai-service/llm/context-v2/conversation-context.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/manager.d.ts +11 -10
- package/dist/ai-service/llm/context-v2/manager.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/manager.js +128 -85
- package/dist/ai-service/llm/context-v2/manager.js.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/event-store.d.ts +73 -1
- package/dist/ai-service/llm/context-v2/storage/event-store.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/event-types.d.ts +152 -24
- package/dist/ai-service/llm/context-v2/storage/event-types.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/event-types.js +141 -0
- package/dist/ai-service/llm/context-v2/storage/event-types.js.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts +20 -2
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js +111 -49
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/migration.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/migration.js +31 -4
- package/dist/ai-service/llm/context-v2/storage/migration.js.map +1 -1
- package/dist/ai-service/llm/context-v2/token-tracker.d.ts +34 -0
- package/dist/ai-service/llm/context-v2/token-tracker.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/token-tracker.js +164 -0
- package/dist/ai-service/llm/context-v2/token-tracker.js.map +1 -1
- package/dist/ai-service/llm/context-v2/types.d.ts +5 -2
- package/dist/ai-service/llm/context-v2/types.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/types.js +1 -1
- package/dist/ai-service/llm/context-v2/types.js.map +1 -1
- package/dist/ai-service/llm/stream/config.d.ts +7 -0
- package/dist/ai-service/llm/stream/config.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/config.js +20 -2
- package/dist/ai-service/llm/stream/config.js.map +1 -1
- package/dist/ai-service/llm/stream/orchestrator.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/orchestrator.js +30 -14
- package/dist/ai-service/llm/stream/orchestrator.js.map +1 -1
- package/dist/ai-service/llm/stream/session.d.ts +1 -1
- package/dist/ai-service/llm/stream/session.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/session.js +1 -1
- package/dist/ai-service/llm/stream/session.js.map +1 -1
- package/dist/ai-service/security/secret-scanner-service.d.ts.map +1 -1
- package/dist/ai-service/security/secret-scanner-service.js +12 -2
- package/dist/ai-service/security/secret-scanner-service.js.map +1 -1
- package/dist/ai-service/security/secret-scanner.d.ts +1 -1
- package/dist/ai-service/security/secret-scanner.d.ts.map +1 -1
- package/dist/ai-service/security/secret-scanner.js +4 -1
- package/dist/ai-service/security/secret-scanner.js.map +1 -1
- package/dist/ai-service/security/vulnerability-triage.d.ts +2 -2
- package/dist/ai-service/state-machine/clark-fsm.d.ts +17 -1
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.js +85 -8
- package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.js +97 -47
- package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.js +68 -50
- package/dist/ai-service/state-machine/handlers/awaiting-user.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.js +91 -73
- package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-failure.d.ts +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-failure.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-failure.js +1 -0
- package/dist/ai-service/state-machine/helpers/prompt-failure.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts +2 -1
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js +1 -0
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/user-response-message.d.ts +4 -0
- package/dist/ai-service/state-machine/helpers/user-response-message.d.ts.map +1 -0
- package/dist/ai-service/state-machine/helpers/user-response-message.js +37 -0
- package/dist/ai-service/state-machine/helpers/user-response-message.js.map +1 -0
- package/dist/ai-service/template-renderer.d.ts.map +1 -1
- package/dist/ai-service/template-renderer.js +22 -9
- package/dist/ai-service/template-renderer.js.map +1 -1
- package/dist/ai-service/types.d.ts +2 -1
- package/dist/ai-service/types.d.ts.map +1 -1
- package/dist/ai-service/types.js.map +1 -1
- package/dist/components-manager.d.ts +9 -2
- package/dist/components-manager.d.ts.map +1 -1
- package/dist/components-manager.js +0 -4
- package/dist/components-manager.js.map +1 -1
- package/dist/file-sync-vite-plugin.d.ts.map +1 -1
- package/dist/file-sync-vite-plugin.js +2 -1
- package/dist/file-sync-vite-plugin.js.map +1 -1
- package/dist/file-system-helpers.d.ts +7 -0
- package/dist/file-system-helpers.d.ts.map +1 -1
- package/dist/file-system-helpers.js +9 -1
- package/dist/file-system-helpers.js.map +1 -1
- package/dist/file-system-manager.d.ts +12 -1
- package/dist/file-system-manager.d.ts.map +1 -1
- package/dist/file-system-manager.js +37 -22
- package/dist/file-system-manager.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/lock-service/index.d.ts +20 -0
- package/dist/lock-service/index.d.ts.map +1 -1
- package/dist/lock-service/index.js +53 -5
- package/dist/lock-service/index.js.map +1 -1
- package/dist/migration/get-fullstack-template-dir.js +2 -2
- package/dist/migration/get-fullstack-template-dir.js.map +1 -1
- package/dist/migration/migration-routes.d.ts.map +1 -1
- package/dist/migration/migration-routes.js +8 -2
- package/dist/migration/migration-routes.js.map +1 -1
- package/dist/plugin-options.d.ts +1 -0
- package/dist/plugin-options.d.ts.map +1 -1
- package/dist/plugin-options.js.map +1 -1
- package/dist/router-parser.d.ts.map +1 -1
- package/dist/router-parser.js +336 -65
- package/dist/router-parser.js.map +1 -1
- package/dist/socket-manager.d.ts +25 -2
- package/dist/socket-manager.d.ts.map +1 -1
- package/dist/socket-manager.js +270 -55
- package/dist/socket-manager.js.map +1 -1
- package/dist/split-edit-after-clark.d.ts +14 -0
- package/dist/split-edit-after-clark.d.ts.map +1 -0
- package/dist/split-edit-after-clark.js +40 -0
- package/dist/split-edit-after-clark.js.map +1 -0
- package/dist/sync-service/index.d.ts +2 -1
- package/dist/sync-service/index.d.ts.map +1 -1
- package/dist/sync-service/index.js +5 -0
- package/dist/sync-service/index.js.map +1 -1
- package/dist/sync-service/list-dir.d.ts.map +1 -1
- package/dist/sync-service/list-dir.js +9 -4
- package/dist/sync-service/list-dir.js.map +1 -1
- package/dist/util/log-sanitizer.d.ts.map +1 -1
- package/dist/util/log-sanitizer.js +4 -0
- package/dist/util/log-sanitizer.js.map +1 -1
- package/dist/vite-module-reload.d.ts +34 -0
- package/dist/vite-module-reload.d.ts.map +1 -0
- package/dist/vite-module-reload.js +121 -0
- package/dist/vite-module-reload.js.map +1 -0
- package/package.json +9 -8
package/dist/router-parser.js
CHANGED
|
@@ -23,8 +23,7 @@ function countRouteObjects(routes) {
|
|
|
23
23
|
count += 1;
|
|
24
24
|
for (const property of element.properties) {
|
|
25
25
|
if (property.type === "ObjectProperty" &&
|
|
26
|
-
property
|
|
27
|
-
property.key.name === "children" &&
|
|
26
|
+
getStaticPropertyKey(property) === "children" &&
|
|
28
27
|
property.value.type === "ArrayExpression") {
|
|
29
28
|
count += countRouteObjects(property.value);
|
|
30
29
|
}
|
|
@@ -121,7 +120,6 @@ function extractReactRouterImports(content) {
|
|
|
121
120
|
throw new Error("react-router import not found");
|
|
122
121
|
}
|
|
123
122
|
const parsedReactRouterImport = parseStaticImport(reactRouterImport);
|
|
124
|
-
// loop over named imports
|
|
125
123
|
if (parsedReactRouterImport.namedImports) {
|
|
126
124
|
// for each named import
|
|
127
125
|
for (const [name, alias] of Object.entries(parsedReactRouterImport.namedImports)) {
|
|
@@ -245,7 +243,6 @@ async function findAllTsFiles(rootDir) {
|
|
|
245
243
|
* Find the router file in the project (React Router v7)
|
|
246
244
|
*/
|
|
247
245
|
export async function findRouterFile(rootDir) {
|
|
248
|
-
// Check cache first with mtime validation
|
|
249
246
|
if (cachedRouterFileLocation) {
|
|
250
247
|
try {
|
|
251
248
|
const stats = await stat(cachedRouterFileLocation.path);
|
|
@@ -394,9 +391,72 @@ function resolveCallableMemberExpression(member, callableImportMap) {
|
|
|
394
391
|
* () => obj.prop() (when obj.prop is a known import-returning callable)
|
|
395
392
|
* () => obj.prop().then(mod => (...)) (same, with .then() chained)
|
|
396
393
|
*/
|
|
397
|
-
function extractImportPathFromFunction(node,
|
|
394
|
+
function extractImportPathFromFunction(node, ctx = {}, enclosingBindings) {
|
|
395
|
+
const { callableImportMap, unwrapHelpers } = ctx;
|
|
398
396
|
const body = node.body;
|
|
397
|
+
const localBindings = new Map(enclosingBindings);
|
|
398
|
+
for (const param of node.params) {
|
|
399
|
+
for (const name of collectPatternNames(param)) {
|
|
400
|
+
localBindings.set(name, null);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
399
403
|
if (body.type === "BlockStatement") {
|
|
404
|
+
const returnArgs = [];
|
|
405
|
+
for (const statement of body.body) {
|
|
406
|
+
if (statement.type === "FunctionDeclaration" ||
|
|
407
|
+
statement.type === "ClassDeclaration") {
|
|
408
|
+
if (statement.id)
|
|
409
|
+
localBindings.set(statement.id.name, null);
|
|
410
|
+
}
|
|
411
|
+
else if (statement.type === "VariableDeclaration") {
|
|
412
|
+
for (const decl of statement.declarations) {
|
|
413
|
+
let init = decl.init;
|
|
414
|
+
if (init?.type === "AwaitExpression")
|
|
415
|
+
init = init.argument;
|
|
416
|
+
if (decl.id.type === "Identifier") {
|
|
417
|
+
localBindings.set(decl.id.name, init ?? null);
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
const traceable = init &&
|
|
421
|
+
extractImportSpecifierFromExpression(init, callableImportMap)
|
|
422
|
+
? init
|
|
423
|
+
: null;
|
|
424
|
+
for (const name of collectPatternNames(decl.id)) {
|
|
425
|
+
localBindings.set(name, traceable);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
else if (statement.type === "ReturnStatement") {
|
|
431
|
+
let arg = statement.argument;
|
|
432
|
+
if (arg?.type === "AwaitExpression")
|
|
433
|
+
arg = arg.argument;
|
|
434
|
+
if (arg)
|
|
435
|
+
returnArgs.push(arg);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const ambiguity = ctx.ambiguity;
|
|
439
|
+
const ambiguitySeenOnEntry = ambiguity?.seen ?? false;
|
|
440
|
+
if (ambiguity)
|
|
441
|
+
ambiguity.seen = false;
|
|
442
|
+
if (unwrapHelpers) {
|
|
443
|
+
for (const arg of returnArgs) {
|
|
444
|
+
const path = extractImportPathFromLazyValue(arg, ctx, localBindings);
|
|
445
|
+
if (path) {
|
|
446
|
+
if (ambiguity)
|
|
447
|
+
ambiguity.seen = ambiguitySeenOnEntry;
|
|
448
|
+
return path;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
const returnWasAmbiguous = ambiguity?.seen ?? false;
|
|
453
|
+
if (ambiguity)
|
|
454
|
+
ambiguity.seen = ambiguitySeenOnEntry || returnWasAmbiguous;
|
|
455
|
+
if (returnWasAmbiguous) {
|
|
456
|
+
getLogger().debug("Router parser: the return traced through an ambiguous helper call; " +
|
|
457
|
+
"suppressing the source-order declaration fallback so the route drops instead of guessing.");
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
400
460
|
for (const statement of body.body) {
|
|
401
461
|
if (statement.type === "VariableDeclaration") {
|
|
402
462
|
for (const decl of statement.declarations) {
|
|
@@ -421,8 +481,51 @@ function extractImportPathFromFunction(node, callableImportMap) {
|
|
|
421
481
|
}
|
|
422
482
|
// Expression body — possibly wrapped in `await`
|
|
423
483
|
const expr = body.type === "AwaitExpression" && body.argument ? body.argument : body;
|
|
484
|
+
if (unwrapHelpers) {
|
|
485
|
+
return extractImportPathFromLazyValue(expr, ctx, localBindings);
|
|
486
|
+
}
|
|
424
487
|
return extractImportSpecifierFromExpression(expr, callableImportMap);
|
|
425
488
|
}
|
|
489
|
+
const LAZY_RESOLUTION_VISIT_BUDGET = 10_000;
|
|
490
|
+
function newLazyResolutionBudget() {
|
|
491
|
+
return { remaining: LAZY_RESOLUTION_VISIT_BUDGET };
|
|
492
|
+
}
|
|
493
|
+
function collectPatternNames(pattern, names = []) {
|
|
494
|
+
switch (pattern.type) {
|
|
495
|
+
case "Identifier":
|
|
496
|
+
names.push(pattern.name);
|
|
497
|
+
break;
|
|
498
|
+
case "ObjectPattern":
|
|
499
|
+
for (const prop of pattern.properties) {
|
|
500
|
+
collectPatternNames(prop.type === "RestElement" ? prop.argument : prop.value, names);
|
|
501
|
+
}
|
|
502
|
+
break;
|
|
503
|
+
case "ArrayPattern":
|
|
504
|
+
for (const element of pattern.elements) {
|
|
505
|
+
if (element)
|
|
506
|
+
collectPatternNames(element, names);
|
|
507
|
+
}
|
|
508
|
+
break;
|
|
509
|
+
case "AssignmentPattern":
|
|
510
|
+
collectPatternNames(pattern.left, names);
|
|
511
|
+
break;
|
|
512
|
+
case "RestElement":
|
|
513
|
+
collectPatternNames(pattern.argument, names);
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
return names;
|
|
517
|
+
}
|
|
518
|
+
const STATIC_PAGE_KEYS = new Set(["Component", "element"]);
|
|
519
|
+
const ROUTE_METADATA_KEYS = new Set([
|
|
520
|
+
"loader",
|
|
521
|
+
"action",
|
|
522
|
+
"ErrorBoundary",
|
|
523
|
+
"errorElement",
|
|
524
|
+
"handle",
|
|
525
|
+
"shouldRevalidate",
|
|
526
|
+
"HydrateFallback",
|
|
527
|
+
"hydrateFallbackElement",
|
|
528
|
+
]);
|
|
426
529
|
/**
|
|
427
530
|
* Extract the page import specifier from a route loader expression: a `lazy:`
|
|
428
531
|
* property value, a top-level const initializer bound as a loader, or a
|
|
@@ -443,23 +546,75 @@ function extractImportPathFromFunction(node, callableImportMap) {
|
|
|
443
546
|
* route and the editor renders the "404 / route has been deleted" overlay over
|
|
444
547
|
* an app that actually works.
|
|
445
548
|
*
|
|
446
|
-
* An `Identifier` resolves through `lazyLoaderBindings` (a const bound to a
|
|
447
|
-
* loader, e.g. `const overview = lazyPage(...); { lazy: overview }`), at any
|
|
448
|
-
* nesting depth — `overview`, `(overview as any)`, `withAuth(overview)`.
|
|
449
549
|
*
|
|
450
|
-
* Limitation: when a helper receives multiple import-bearing arguments (e.g.
|
|
451
|
-
* `withFallback(() => import("./a"), () => import("./b"))`), the first import
|
|
452
|
-
* found wins. Every real/tested loader shape carries exactly one importer.
|
|
453
550
|
*/
|
|
454
|
-
function extractImportPathFromLazyValue(node,
|
|
551
|
+
function extractImportPathFromLazyValue(node, ctx = {}, localBindings) {
|
|
552
|
+
const { callableImportMap, lazyLoaderBindings, allImports, unwrapHelpers } = ctx;
|
|
553
|
+
if (ctx.budget) {
|
|
554
|
+
if (ctx.budget.remaining <= 0)
|
|
555
|
+
return null;
|
|
556
|
+
ctx.budget.remaining -= 1;
|
|
557
|
+
if (ctx.budget.remaining === 0) {
|
|
558
|
+
getLogger().debug("Router parser: lazy-value resolution visit budget exhausted; giving up on this value.");
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const recurse = (child, bindings = localBindings) => extractImportPathFromLazyValue(child, ctx, bindings);
|
|
455
562
|
node = unwrapTsWrappers(node);
|
|
456
|
-
// `lazy: overview` — a const bound to a loader elsewhere in the file.
|
|
457
563
|
if (node.type === "Identifier") {
|
|
458
|
-
|
|
564
|
+
if (localBindings?.has(node.name)) {
|
|
565
|
+
const localInit = localBindings.get(node.name);
|
|
566
|
+
if (!localInit)
|
|
567
|
+
return null;
|
|
568
|
+
const withoutSelf = new Map(localBindings);
|
|
569
|
+
withoutSelf.delete(node.name);
|
|
570
|
+
return recurse(localInit, withoutSelf);
|
|
571
|
+
}
|
|
572
|
+
return (lazyLoaderBindings?.get(node.name) ?? allImports?.get(node.name) ?? null);
|
|
573
|
+
}
|
|
574
|
+
if (node.type === "AwaitExpression" && node.argument) {
|
|
575
|
+
return recurse(node.argument);
|
|
459
576
|
}
|
|
460
577
|
if (node.type === "ArrowFunctionExpression" ||
|
|
461
578
|
node.type === "FunctionExpression") {
|
|
462
|
-
return extractImportPathFromFunction(node,
|
|
579
|
+
return extractImportPathFromFunction(node, ctx, localBindings);
|
|
580
|
+
}
|
|
581
|
+
if (unwrapHelpers && node.type === "ObjectExpression") {
|
|
582
|
+
const resolveValue = (value, valueCtx, bindings = localBindings) => {
|
|
583
|
+
if (value.type === "ArrowFunctionExpression" ||
|
|
584
|
+
value.type === "FunctionExpression") {
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
return extractImportPathFromLazyValue(value, valueCtx, bindings);
|
|
588
|
+
};
|
|
589
|
+
const pageKeys = resolveReturnedObjectPageKeys(node, (value, bindings) => resolveValue(value, ctx, bindings), localBindings);
|
|
590
|
+
if (pageKeys.sawStaticPageKey)
|
|
591
|
+
return pageKeys.path;
|
|
592
|
+
const fallbackCtx = { ...ctx, allImports: undefined };
|
|
593
|
+
for (const prop of node.properties) {
|
|
594
|
+
let value = null;
|
|
595
|
+
if (prop.type === "SpreadElement") {
|
|
596
|
+
value = prop.argument;
|
|
597
|
+
}
|
|
598
|
+
else if (prop.type === "ObjectProperty") {
|
|
599
|
+
const key = getStaticPropertyKey(prop);
|
|
600
|
+
if (key !== null &&
|
|
601
|
+
(STATIC_PAGE_KEYS.has(key) || ROUTE_METADATA_KEYS.has(key))) {
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
value = prop.value;
|
|
605
|
+
}
|
|
606
|
+
if (!value)
|
|
607
|
+
continue;
|
|
608
|
+
const path = resolveValue(value, fallbackCtx);
|
|
609
|
+
if (path)
|
|
610
|
+
return path;
|
|
611
|
+
}
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
614
|
+
if (unwrapHelpers &&
|
|
615
|
+
node.type === "MemberExpression" &&
|
|
616
|
+
(!node.computed || node.property.type === "StringLiteral")) {
|
|
617
|
+
return recurse(node.object);
|
|
463
618
|
}
|
|
464
619
|
if (node.type === "CallExpression") {
|
|
465
620
|
// The call itself may already resolve to an import: `import("...")`,
|
|
@@ -472,18 +627,74 @@ function extractImportPathFromLazyValue(node, callableImportMap, lazyLoaderBindi
|
|
|
472
627
|
// callee's object (the wrapper call), not in this call's arguments.
|
|
473
628
|
if (node.callee.type === "MemberExpression" &&
|
|
474
629
|
node.callee.object.type === "CallExpression") {
|
|
475
|
-
const fromWrapper =
|
|
630
|
+
const fromWrapper = recurse(node.callee.object);
|
|
476
631
|
if (fromWrapper)
|
|
477
632
|
return fromWrapper;
|
|
478
633
|
}
|
|
479
634
|
// Helper-wrapped importer, possibly nested (e.g.
|
|
480
|
-
|
|
481
|
-
|
|
635
|
+
const argCtx = { ...ctx, allImports: undefined };
|
|
636
|
+
const argSpecifiers = [];
|
|
482
637
|
for (const arg of node.arguments) {
|
|
483
|
-
const path = extractImportPathFromLazyValue(arg,
|
|
484
|
-
if (path)
|
|
485
|
-
|
|
638
|
+
const path = extractImportPathFromLazyValue(arg, argCtx, localBindings);
|
|
639
|
+
if (path && !argSpecifiers.includes(path))
|
|
640
|
+
argSpecifiers.push(path);
|
|
486
641
|
}
|
|
642
|
+
if (argSpecifiers.length > 1) {
|
|
643
|
+
if (ctx.ambiguity)
|
|
644
|
+
ctx.ambiguity.seen = true;
|
|
645
|
+
if (unwrapHelpers) {
|
|
646
|
+
getLogger().debug(`Router parser: helper call carries ${argSpecifiers.length} distinct import specifiers (${argSpecifiers.join(", ")}); treating the call as unresolved.`);
|
|
647
|
+
}
|
|
648
|
+
return null;
|
|
649
|
+
}
|
|
650
|
+
if (ctx.ambiguity?.seen)
|
|
651
|
+
return null;
|
|
652
|
+
if (argSpecifiers.length === 1)
|
|
653
|
+
return argSpecifiers[0] ?? null;
|
|
654
|
+
}
|
|
655
|
+
return null;
|
|
656
|
+
}
|
|
657
|
+
function resolveReturnedObjectPageKeys(obj, resolveValue, localBindings) {
|
|
658
|
+
let sawStaticPageKey = false;
|
|
659
|
+
let path = null;
|
|
660
|
+
for (const prop of obj.properties) {
|
|
661
|
+
if (prop.type === "SpreadElement") {
|
|
662
|
+
const literal = resolveSpreadObjectLiteral(prop.argument, localBindings);
|
|
663
|
+
if (!literal)
|
|
664
|
+
continue;
|
|
665
|
+
const inner = resolveReturnedObjectPageKeys(literal.object, resolveValue, literal.bindings);
|
|
666
|
+
if (inner.sawStaticPageKey) {
|
|
667
|
+
sawStaticPageKey = true;
|
|
668
|
+
path = inner.path;
|
|
669
|
+
}
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
const key = getStaticPropertyKey(prop);
|
|
673
|
+
if (key === null || !STATIC_PAGE_KEYS.has(key))
|
|
674
|
+
continue;
|
|
675
|
+
sawStaticPageKey = true;
|
|
676
|
+
path =
|
|
677
|
+
prop.type === "ObjectProperty"
|
|
678
|
+
? resolveValue(prop.value, localBindings)
|
|
679
|
+
: null;
|
|
680
|
+
}
|
|
681
|
+
return { sawStaticPageKey, path };
|
|
682
|
+
}
|
|
683
|
+
function resolveSpreadObjectLiteral(argument, localBindings) {
|
|
684
|
+
const unwrapped = unwrapTsWrappers(argument);
|
|
685
|
+
if (unwrapped.type === "ObjectExpression") {
|
|
686
|
+
return { object: unwrapped, bindings: localBindings };
|
|
687
|
+
}
|
|
688
|
+
if (unwrapped.type === "Identifier" && localBindings?.has(unwrapped.name)) {
|
|
689
|
+
const init = localBindings.get(unwrapped.name);
|
|
690
|
+
if (!init)
|
|
691
|
+
return null;
|
|
692
|
+
const literal = unwrapTsWrappers(init);
|
|
693
|
+
if (literal.type !== "ObjectExpression")
|
|
694
|
+
return null;
|
|
695
|
+
const withoutSelf = new Map(localBindings);
|
|
696
|
+
withoutSelf.delete(unwrapped.name);
|
|
697
|
+
return { object: literal, bindings: withoutSelf };
|
|
487
698
|
}
|
|
488
699
|
return null;
|
|
489
700
|
}
|
|
@@ -502,6 +713,14 @@ function unwrapTsWrappers(node) {
|
|
|
502
713
|
}
|
|
503
714
|
return node;
|
|
504
715
|
}
|
|
716
|
+
function isUntraceableLazyModuleReference(node, allImports, lazyLoaderBindings) {
|
|
717
|
+
if (node.type === "Identifier") {
|
|
718
|
+
return !(lazyLoaderBindings?.has(node.name) ?? false);
|
|
719
|
+
}
|
|
720
|
+
return (node.type === "MemberExpression" &&
|
|
721
|
+
node.object.type === "Identifier" &&
|
|
722
|
+
allImports.has(node.object.name));
|
|
723
|
+
}
|
|
505
724
|
/**
|
|
506
725
|
* Static key of an object member: identifier (`lazy:`) or string literal
|
|
507
726
|
* (`"lazy":`). Computed keys are not statically knowable and return null.
|
|
@@ -542,6 +761,16 @@ function classifyRouteFragment(obj) {
|
|
|
542
761
|
}
|
|
543
762
|
return sawUnknowableKey ? "unknown" : "non-page";
|
|
544
763
|
}
|
|
764
|
+
function fragmentHasStaticPageKey(obj) {
|
|
765
|
+
for (const prop of obj.properties) {
|
|
766
|
+
if (prop.type === "SpreadElement")
|
|
767
|
+
continue;
|
|
768
|
+
const name = getStaticPropertyKey(prop);
|
|
769
|
+
if (name && STATIC_PAGE_KEYS.has(name))
|
|
770
|
+
return true;
|
|
771
|
+
}
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
545
774
|
/**
|
|
546
775
|
* Classify a local factory by the object literal it returns. Only bodies
|
|
547
776
|
* made of straight-line statements are inspected; anything that could hide
|
|
@@ -573,17 +802,16 @@ function classifyLocalFactory(fn) {
|
|
|
573
802
|
}
|
|
574
803
|
return { shape: "unknown", fragment: null };
|
|
575
804
|
}
|
|
576
|
-
/**
|
|
577
|
-
* Extract the page import from an object literal spread into a route
|
|
578
|
-
* (`...{ lazy: () => import("...") }` or a const bound to one). Later page
|
|
579
|
-
* keys override earlier ones, matching runtime object semantics. Broader
|
|
580
|
-
* than the explicit-property loop by design: classifyRouteFragment counts
|
|
581
|
-
* method shorthand and string-literal keys as page-bearing, so extraction
|
|
582
|
-
* must recognize the same shapes or a "page" fragment would silently
|
|
583
|
-
* extract nothing.
|
|
584
|
-
*/
|
|
585
805
|
function extractPageImportFromFragment(fragment, allImports, callableImportMap, lazyLoaderBindings) {
|
|
586
806
|
let importPath = null;
|
|
807
|
+
const lazyCtx = {
|
|
808
|
+
callableImportMap,
|
|
809
|
+
lazyLoaderBindings,
|
|
810
|
+
allImports,
|
|
811
|
+
unwrapHelpers: true,
|
|
812
|
+
budget: newLazyResolutionBudget(),
|
|
813
|
+
ambiguity: { seen: false },
|
|
814
|
+
};
|
|
587
815
|
for (const prop of fragment.properties) {
|
|
588
816
|
if (prop.type === "SpreadElement")
|
|
589
817
|
continue;
|
|
@@ -592,14 +820,17 @@ function extractPageImportFromFragment(fragment, allImports, callableImportMap,
|
|
|
592
820
|
continue;
|
|
593
821
|
if (prop.type === "ObjectMethod") {
|
|
594
822
|
if (key === "lazy") {
|
|
595
|
-
const path = extractImportPathFromFunction(prop,
|
|
823
|
+
const path = extractImportPathFromFunction(prop, lazyCtx);
|
|
596
824
|
if (path)
|
|
597
825
|
importPath = path;
|
|
598
826
|
}
|
|
599
827
|
continue;
|
|
600
828
|
}
|
|
601
829
|
if (key === "lazy") {
|
|
602
|
-
const
|
|
830
|
+
const lazyValue = unwrapTsWrappers(prop.value);
|
|
831
|
+
const path = isUntraceableLazyModuleReference(lazyValue, allImports, lazyLoaderBindings)
|
|
832
|
+
? null
|
|
833
|
+
: extractImportPathFromLazyValue(prop.value, lazyCtx);
|
|
603
834
|
if (path)
|
|
604
835
|
importPath = path;
|
|
605
836
|
}
|
|
@@ -614,20 +845,6 @@ function extractPageImportFromFragment(fragment, allImports, callableImportMap,
|
|
|
614
845
|
}
|
|
615
846
|
return importPath;
|
|
616
847
|
}
|
|
617
|
-
/**
|
|
618
|
-
* Resolve what a route-object spread contributes to the route's page.
|
|
619
|
-
*
|
|
620
|
-
* "page": the spread verifiably carries a page key (an object literal, a
|
|
621
|
-
* const bound to one, or a local factory call, direct or through a const,
|
|
622
|
-
* whose return shape is inspectable); its import participates like an
|
|
623
|
-
* explicit property.
|
|
624
|
-
* "none": the spread verifiably carries no page key and must be ignored, so
|
|
625
|
-
* a loader-only helper's import is never mistaken for the page.
|
|
626
|
-
* "heuristic": the parser cannot classify the contribution (an imported
|
|
627
|
-
* factory, or an indirection it does not chase); the first import found in
|
|
628
|
-
* the expression is offered as a fallback for the caller to use only when
|
|
629
|
-
* nothing verified resolves.
|
|
630
|
-
*/
|
|
631
848
|
function resolveSpreadContribution(argument, allImports, callableImportMap, lazyLoaderBindings, spreadBindings) {
|
|
632
849
|
const unwrapped = unwrapTsWrappers(argument);
|
|
633
850
|
let fragment = null;
|
|
@@ -656,6 +873,7 @@ function resolveSpreadContribution(argument, allImports, callableImportMap, lazy
|
|
|
656
873
|
return {
|
|
657
874
|
kind: "page",
|
|
658
875
|
importPath: localOnly(extractPageImportFromFragment(fragment, allImports, callableImportMap, lazyLoaderBindings)),
|
|
876
|
+
hasStaticPageKey: fragmentHasStaticPageKey(fragment),
|
|
659
877
|
};
|
|
660
878
|
}
|
|
661
879
|
if (shape === "non-page")
|
|
@@ -667,18 +885,34 @@ function resolveSpreadContribution(argument, allImports, callableImportMap, lazy
|
|
|
667
885
|
if (factory?.shape === "page") {
|
|
668
886
|
// The importer is usually passed in through the call's arguments; a
|
|
669
887
|
// zero-argument factory instead hardcodes it in the returned fragment.
|
|
670
|
-
const fromArguments = localOnly(extractImportPathFromLazyValue(argument,
|
|
888
|
+
const fromArguments = localOnly(extractImportPathFromLazyValue(argument, {
|
|
889
|
+
callableImportMap,
|
|
890
|
+
lazyLoaderBindings,
|
|
891
|
+
budget: newLazyResolutionBudget(),
|
|
892
|
+
ambiguity: { seen: false },
|
|
893
|
+
}));
|
|
671
894
|
const fromFragment = factory.fragment
|
|
672
895
|
? localOnly(extractPageImportFromFragment(factory.fragment, allImports, callableImportMap, lazyLoaderBindings))
|
|
673
896
|
: null;
|
|
674
|
-
return {
|
|
897
|
+
return {
|
|
898
|
+
kind: "page",
|
|
899
|
+
importPath: fromArguments ?? fromFragment,
|
|
900
|
+
hasStaticPageKey: factory.fragment
|
|
901
|
+
? fragmentHasStaticPageKey(factory.fragment)
|
|
902
|
+
: false,
|
|
903
|
+
};
|
|
675
904
|
}
|
|
676
905
|
if (factory?.shape === "non-page")
|
|
677
906
|
return { kind: "none" };
|
|
678
907
|
}
|
|
679
908
|
return {
|
|
680
909
|
kind: "heuristic",
|
|
681
|
-
importPath: localOnly(extractImportPathFromLazyValue(argument,
|
|
910
|
+
importPath: localOnly(extractImportPathFromLazyValue(argument, {
|
|
911
|
+
callableImportMap,
|
|
912
|
+
lazyLoaderBindings,
|
|
913
|
+
budget: newLazyResolutionBudget(),
|
|
914
|
+
ambiguity: { seen: false },
|
|
915
|
+
})),
|
|
682
916
|
};
|
|
683
917
|
}
|
|
684
918
|
/**
|
|
@@ -710,7 +944,11 @@ function extractLazyImportPath(node) {
|
|
|
710
944
|
arg.type !== "FunctionExpression")) {
|
|
711
945
|
return null;
|
|
712
946
|
}
|
|
713
|
-
return extractImportPathFromFunction(arg
|
|
947
|
+
return extractImportPathFromFunction(arg, {
|
|
948
|
+
unwrapHelpers: true,
|
|
949
|
+
budget: newLazyResolutionBudget(),
|
|
950
|
+
ambiguity: { seen: false },
|
|
951
|
+
});
|
|
714
952
|
}
|
|
715
953
|
/**
|
|
716
954
|
* Extract all static imports
|
|
@@ -874,7 +1112,12 @@ export async function parseRouterFile(routerFilePath, rootDir, onDiagnostic) {
|
|
|
874
1112
|
// from allImports so Component/element identifier resolution stays
|
|
875
1113
|
// limited to actual component bindings.
|
|
876
1114
|
if (isTopLevel && !lazyLoaderBindings.has(node.id.name)) {
|
|
877
|
-
const loaderImportPath = extractImportPathFromLazyValue(node.init,
|
|
1115
|
+
const loaderImportPath = extractImportPathFromLazyValue(node.init, {
|
|
1116
|
+
callableImportMap,
|
|
1117
|
+
lazyLoaderBindings,
|
|
1118
|
+
budget: newLazyResolutionBudget(),
|
|
1119
|
+
ambiguity: { seen: false },
|
|
1120
|
+
});
|
|
878
1121
|
if (loaderImportPath && isLocalModuleSpecifier(loaderImportPath)) {
|
|
879
1122
|
lazyLoaderBindings.set(node.id.name, loaderImportPath);
|
|
880
1123
|
}
|
|
@@ -916,7 +1159,6 @@ export async function parseRouterFile(routerFilePath, rootDir, onDiagnostic) {
|
|
|
916
1159
|
}
|
|
917
1160
|
},
|
|
918
1161
|
});
|
|
919
|
-
// Process routes asynchronously after traverse
|
|
920
1162
|
if (routesArray) {
|
|
921
1163
|
await extractRoutesFromArray(routesArray, routes, routerFilePath, rootDir, "", allImports, callableImportMap, lazyLoaderBindings, spreadBindings);
|
|
922
1164
|
if (routeObjectCount > 0 && routes.length === 0) {
|
|
@@ -954,8 +1196,10 @@ async function extractRouteFromObject(node, routes, routerFilePath, rootDir, par
|
|
|
954
1196
|
let pageImportPath = null;
|
|
955
1197
|
let children = null;
|
|
956
1198
|
let hasIndex = false;
|
|
1199
|
+
let unresolvedLazy = null;
|
|
957
1200
|
let heuristicSpreadImportPath = null;
|
|
958
1201
|
let sawUnresolvedPageSpread = false;
|
|
1202
|
+
let hasAuthoritativeStaticPage = false;
|
|
959
1203
|
for (const prop of node.properties) {
|
|
960
1204
|
// A route may receive its page property through a spread instead of a
|
|
961
1205
|
// literal key: `{ path: "/home", ...gatedLazy(() => import("...")) }`.
|
|
@@ -966,16 +1210,14 @@ async function extractRouteFromObject(node, routes, routerFilePath, rootDir, par
|
|
|
966
1210
|
if (prop.type === "SpreadElement") {
|
|
967
1211
|
const contribution = resolveSpreadContribution(prop.argument, allImports, callableImportMap, lazyLoaderBindings, spreadBindings);
|
|
968
1212
|
if (contribution.kind === "page") {
|
|
1213
|
+
if (!contribution.hasStaticPageKey && hasAuthoritativeStaticPage) {
|
|
1214
|
+
continue;
|
|
1215
|
+
}
|
|
1216
|
+
hasAuthoritativeStaticPage = false;
|
|
969
1217
|
if (contribution.importPath) {
|
|
970
1218
|
pageImportPath = contribution.importPath;
|
|
971
1219
|
}
|
|
972
1220
|
else {
|
|
973
|
-
// The spread verifiably carries the route's page and it could not
|
|
974
|
-
// be resolved. At runtime it overrides whatever came before it, so
|
|
975
|
-
// an earlier contributor's import is discarded and the heuristic
|
|
976
|
-
// fallback suppressed; mapping either would point the route at a
|
|
977
|
-
// file the router no longer renders. The route drops unless a
|
|
978
|
-
// later contributor resolves.
|
|
979
1221
|
pageImportPath = null;
|
|
980
1222
|
sawUnresolvedPageSpread = true;
|
|
981
1223
|
getLogger().debug(`Router parser: a spread on route "${routePath ?? "(index)"}" in ${routerFilePath} ` +
|
|
@@ -990,7 +1232,7 @@ async function extractRouteFromObject(node, routes, routerFilePath, rootDir, par
|
|
|
990
1232
|
}
|
|
991
1233
|
if (prop.type !== "ObjectProperty")
|
|
992
1234
|
continue;
|
|
993
|
-
const key = prop
|
|
1235
|
+
const key = getStaticPropertyKey(prop);
|
|
994
1236
|
if (key === "path" && prop.value.type === "StringLiteral") {
|
|
995
1237
|
routePath = prop.value.value;
|
|
996
1238
|
}
|
|
@@ -998,15 +1240,40 @@ async function extractRouteFromObject(node, routes, routerFilePath, rootDir, par
|
|
|
998
1240
|
hasIndex = prop.value.value;
|
|
999
1241
|
}
|
|
1000
1242
|
else if (key === "lazy") {
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
|
|
1243
|
+
const lazyValue = unwrapTsWrappers(prop.value);
|
|
1244
|
+
const isUntraceableModuleReference = isUntraceableLazyModuleReference(lazyValue, allImports, lazyLoaderBindings);
|
|
1245
|
+
const path = isUntraceableModuleReference
|
|
1246
|
+
? null
|
|
1247
|
+
: extractImportPathFromLazyValue(prop.value, {
|
|
1248
|
+
callableImportMap,
|
|
1249
|
+
lazyLoaderBindings,
|
|
1250
|
+
allImports,
|
|
1251
|
+
unwrapHelpers: true,
|
|
1252
|
+
budget: newLazyResolutionBudget(),
|
|
1253
|
+
ambiguity: { seen: false },
|
|
1254
|
+
});
|
|
1255
|
+
if (path) {
|
|
1256
|
+
if (!hasAuthoritativeStaticPage) {
|
|
1257
|
+
pageImportPath = path;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
else {
|
|
1261
|
+
unresolvedLazy = {
|
|
1262
|
+
type: prop.value.type,
|
|
1263
|
+
line: prop.value.loc?.start.line ?? null,
|
|
1264
|
+
};
|
|
1265
|
+
if (!hasAuthoritativeStaticPage) {
|
|
1266
|
+
pageImportPath = null;
|
|
1267
|
+
heuristicSpreadImportPath = null;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1004
1270
|
}
|
|
1005
1271
|
else if (key === "Component" && prop.value.type === "Identifier") {
|
|
1006
1272
|
// Component property uses an identifier: Component: HomePage
|
|
1007
1273
|
const componentName = prop.value.name;
|
|
1008
1274
|
if (allImports.has(componentName)) {
|
|
1009
1275
|
pageImportPath = allImports.get(componentName);
|
|
1276
|
+
hasAuthoritativeStaticPage = true;
|
|
1010
1277
|
}
|
|
1011
1278
|
else {
|
|
1012
1279
|
logUnresolvedComponent("Component", componentName, routerFilePath);
|
|
@@ -1016,6 +1283,7 @@ async function extractRouteFromObject(node, routes, routerFilePath, rootDir, par
|
|
|
1016
1283
|
const elementImportPath = resolveElementImportPath(prop.value, allImports);
|
|
1017
1284
|
if (elementImportPath) {
|
|
1018
1285
|
pageImportPath = elementImportPath;
|
|
1286
|
+
hasAuthoritativeStaticPage = true;
|
|
1019
1287
|
}
|
|
1020
1288
|
else if (prop.value.type === "CallExpression") {
|
|
1021
1289
|
const callee = prop.value.callee.type === "Identifier"
|
|
@@ -1039,10 +1307,14 @@ async function extractRouteFromObject(node, routes, routerFilePath, rootDir, par
|
|
|
1039
1307
|
heuristicSpreadImportPath &&
|
|
1040
1308
|
!sawUnresolvedPageSpread) {
|
|
1041
1309
|
pageImportPath = heuristicSpreadImportPath;
|
|
1042
|
-
getLogger().debug(`Router parser: route "${routePath ?? "(index)"}" in ${routerFilePath} has no
|
|
1310
|
+
getLogger().debug(`Router parser: route "${routePath ?? "(index)"}" in ${routerFilePath} has no page property the parser could resolve; ` +
|
|
1043
1311
|
`treating import "${heuristicSpreadImportPath}" from a spread the parser could not classify as the page. ` +
|
|
1044
1312
|
`If that spread contributes a loader rather than a page, the mapping will be wrong.`);
|
|
1045
1313
|
}
|
|
1314
|
+
if (!pageImportPath && unresolvedLazy) {
|
|
1315
|
+
const routeLabel = routePath ?? `index under "${parentPath || "/"}"`;
|
|
1316
|
+
getLogger().debug(`Router parser: could not resolve lazy value (${unresolvedLazy.type}) for route "${routeLabel}" at line ${unresolvedLazy.line ?? "?"} in ${routerFilePath}; the route will not appear in the page list.`);
|
|
1317
|
+
}
|
|
1046
1318
|
// Check if any children have index: true
|
|
1047
1319
|
let hasIndexChild = false;
|
|
1048
1320
|
if (children) {
|
|
@@ -1050,8 +1322,7 @@ async function extractRouteFromObject(node, routes, routerFilePath, rootDir, par
|
|
|
1050
1322
|
if (child && child.type === "ObjectExpression") {
|
|
1051
1323
|
for (const prop of child.properties) {
|
|
1052
1324
|
if (prop.type === "ObjectProperty" &&
|
|
1053
|
-
prop
|
|
1054
|
-
prop.key.name === "index" &&
|
|
1325
|
+
getStaticPropertyKey(prop) === "index" &&
|
|
1055
1326
|
prop.value.type === "BooleanLiteral" &&
|
|
1056
1327
|
prop.value.value === true) {
|
|
1057
1328
|
hasIndexChild = true;
|