@allbluecn/web-app 0.22.4 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -14
- package/src/__tests__/integration/login-email-acceptance.test.ts +16 -0
- package/src/__tests__/story-view.test.ts +33 -1
- package/src/components/agents/__tests__/agent-bindings-tab.test.tsx +221 -0
- package/src/components/agents/__tests__/agents-page.test.tsx +284 -0
- package/src/components/agents/agent-bindings-tab.tsx +59 -45
- package/src/components/agents/agent-form-dialog.tsx +3 -3
- package/src/components/agents/agent-selector.tsx +2 -3
- package/src/components/agents/agents-page.tsx +66 -31
- package/src/components/agents/slash-skill-menu.tsx +2 -3
- package/src/components/auth/__tests__/session-guard.test.tsx +74 -0
- package/src/components/auth/session-guard.tsx +8 -0
- package/src/components/billing/login-prompt-dialog.tsx +1 -1
- package/src/components/billing/subscription-provider.tsx +2 -16
- package/src/components/bug/__tests__/peek-modes.test.tsx +8 -0
- package/src/components/bug/__tests__/subgroup-header.test.tsx +202 -40
- package/src/components/bug/peek-panel.tsx +5 -3
- package/src/components/bug/views/bug-list/group.tsx +12 -2
- package/src/components/bug/views/bug-list/index.tsx +94 -67
- package/src/components/command/command-palette.tsx +10 -9
- package/src/components/design/canvas/document/frame-custom-presets.ts +9 -1
- package/src/components/design/canvas/panels/toolbar.tsx +21 -22
- package/src/components/design/canvas/react/__tests__/canvas-context-load-echo.test.tsx +199 -0
- package/src/components/design/canvas/react/__tests__/hooks.test.tsx +17 -3
- package/src/components/design/canvas/react/canvas-context.tsx +47 -26
- package/src/components/design/canvas/react/hooks.ts +39 -34
- package/src/components/design/editor/layout/__tests__/collab-param-wiring.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/context-menu.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/no-page-save-toast.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/persistence-restore.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/ssr-localstorage-smoke.test.tsx +17 -1
- package/src/components/design/editor/layout/design-editor-layout.tsx +13 -2
- package/src/components/design/editor/layout/hooks/use-design-auto-save.ts +3 -19
- package/src/components/devtools/devtools-panel.tsx +56 -0
- package/src/components/forms/__tests__/create-app-form.test.tsx +131 -0
- package/src/components/forms/app-field-error.tsx +21 -1
- package/src/components/forms/app-field.tsx +8 -8
- package/src/components/forms/app-submit.tsx +12 -9
- package/src/components/forms/create-app-form.tsx +124 -0
- package/src/components/forms/index.ts +2 -3
- package/src/components/harness/__tests__/gallery-behavior.test.tsx +37 -1
- package/src/components/harness/__tests__/harness-workbench-first-send.test.tsx +4 -1
- package/src/components/harness/__tests__/message-actions.test.tsx +7 -6
- package/src/components/harness/__tests__/use-video-generation.test.tsx +165 -0
- package/src/components/harness/ai-chat-history/index.tsx +5 -3
- package/src/components/harness/gallery/gallery-card.tsx +57 -35
- package/src/components/harness/gallery/gallery-grid.tsx +32 -15
- package/src/components/harness/gallery/gallery-types.ts +19 -0
- package/src/components/harness/gallery/gallery-video-card.tsx +54 -0
- package/src/components/harness/gallery/types.ts +2 -0
- package/src/components/harness/gallery/use-video-generation.ts +95 -0
- package/src/components/harness/harness-workbench-page.tsx +2 -3
- package/src/components/harness/message-actions.tsx +5 -3
- package/src/components/hotkeys/shortcuts-panel.tsx +28 -13
- package/src/components/iteration/__tests__/burndown-chart.test.tsx +118 -0
- package/src/components/iteration/burndown-chart.tsx +54 -23
- package/src/components/knowledge/editor/__tests__/knowledge-doc-editor-collab.test.tsx +96 -0
- package/src/components/knowledge/editor/knowledge-doc-editor.tsx +56 -1
- package/src/components/knowledge/editor/mindmap-doc-editor.tsx +12 -0
- package/src/components/knowledge/editor/use-auto-save-channels.ts +3 -1
- package/src/components/layout/sidebar-03/__tests__/nav-workspace.test.tsx +0 -4
- package/src/components/layout/sidebar-03/nav-knowledge.tsx +11 -11
- package/src/components/layout/sidebar-03/nav-main.tsx +12 -15
- package/src/components/layout/sidebar-03/nav-notifications.tsx +5 -8
- package/src/components/layout/sidebar-03/nav-workspace.tsx +11 -9
- package/src/components/notifications/__tests__/settings-notifications.test.tsx +158 -0
- package/src/components/notifications/settings-notifications.tsx +37 -13
- package/src/components/notifications/team-notifications.tsx +10 -14
- package/src/components/settings/personal-team/account/__tests__/account-client.test.tsx +170 -0
- package/src/components/settings/personal-team/account/account-client.tsx +44 -7
- package/src/components/settings/personal-team/team/team-client.tsx +17 -19
- package/src/components/shared-kit/list-kit/__tests__/frozen-header.test.ts +210 -41
- package/src/components/shared-kit/list-kit/frozen-header.ts +134 -21
- package/src/components/shared-kit/list-kit/kanban/frozen-header.ts +20 -27
- package/src/components/story/__tests__/peek-panel-patch-sync.test.tsx +8 -0
- package/src/components/story/__tests__/story-list-table.test.tsx +214 -0
- package/src/components/story/columns.tsx +11 -2
- package/src/components/story/peek-panel.tsx +4 -2
- package/src/components/story/story-list-table.tsx +16 -1
- package/src/components/story/views/story-list/__tests__/frozen-headers.test.tsx +186 -0
- package/src/components/story/views/story-list/group.tsx +12 -1
- package/src/components/story/views/story-list/index.tsx +101 -68
- package/src/components/testcase/__tests__/case-row.test.tsx +134 -2
- package/src/components/testcase/__tests__/peek-panel.test.tsx +8 -0
- package/src/components/testcase/__tests__/step-editor.test.tsx +106 -0
- package/src/components/testcase/list/grouped-list.tsx +50 -22
- package/src/components/testcase/peek-panel.tsx +7 -4
- package/src/components/testcase/step-editor.tsx +196 -150
- package/src/components/tiptap/notion-like/editor-extensions.ts +0 -3
- package/src/components/tiptap/notion-like/notion-like-editor-header.tsx +1 -31
- package/src/components/tiptap/notion-like/notion-like-editor.tsx +32 -1
- package/src/components/workspace/__tests__/dialogs/create-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/__tests__/dialogs/edit-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/dialogs/create-workspace-dialog.tsx +45 -43
- package/src/components/workspace/dialogs/edit-workspace-dialog.tsx +38 -36
- package/src/design-engine/engine/engine-decor.ts +2 -0
- package/src/design-engine/engine/engine-path.ts +2 -0
- package/src/hooks/__tests__/use-unsaved-guard.test.tsx +180 -0
- package/src/hooks/use-notifications.ts +9 -16
- package/src/hooks/use-unsaved-guard.tsx +87 -0
- package/src/lib/__tests__/pacer.test.ts +33 -96
- package/src/lib/__tests__/query-defaults.test.ts +169 -0
- package/src/lib/__tests__/query-global-error.test.ts +256 -0
- package/src/lib/anyhub/anyhub-store.ts +2 -2
- package/src/lib/changelog/sdk-versions.ts +2 -10
- package/src/lib/collab/presence-store.ts +5 -5
- package/src/lib/collab/use-presence-list-refresh.ts +2 -2
- package/src/lib/collab/use-share-presence.ts +2 -2
- package/src/lib/collections/query-keys.ts +7 -2
- package/src/lib/commands/__tests__/command-palette-state.test.ts +12 -14
- package/src/lib/commands/__tests__/registry.test.ts +6 -3
- package/src/lib/commands/command-palette-state.ts +8 -31
- package/src/lib/hotkeys/__tests__/registry.test.ts +71 -18
- package/src/lib/hotkeys/registry.ts +188 -85
- package/src/lib/hotkeys/types.ts +1 -13
- package/src/lib/pacer.ts +1 -79
- package/src/lib/queries/README.md +67 -0
- package/src/lib/queries/__tests__/agents-queries.test.ts +101 -0
- package/src/lib/queries/__tests__/compliance-queries.test.ts +136 -0
- package/src/lib/queries/__tests__/notifications-queries.test.ts +175 -0
- package/src/lib/queries/__tests__/team-queries.test.ts +87 -0
- package/src/lib/queries/agents.ts +40 -0
- package/src/lib/queries/compliance.ts +69 -0
- package/src/lib/queries/notifications.ts +63 -0
- package/src/lib/queries/team.ts +39 -0
- package/src/lib/query-defaults.ts +8 -0
- package/src/lib/query-global-error.ts +128 -0
- package/src/lib/remote-auth-client.ts +16 -0
- package/src/paraglide/README.md +1 -1
- package/src/paraglide/messages/_index.d.ts +11 -0
- package/src/paraglide/messages/_index.js +5659 -88285
- package/src/paraglide/messages/common_error_generic.d.ts +16 -0
- package/src/paraglide/messages/common_error_generic.js +29 -0
- package/src/paraglide/messages/common_unsaved_body.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_body.js +29 -0
- package/src/paraglide/messages/common_unsaved_leave.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_leave.js +29 -0
- package/src/paraglide/messages/common_unsaved_stay.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_stay.js +29 -0
- package/src/paraglide/messages/common_unsaved_title.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_title.js +29 -0
- package/src/paraglide/messages/gallery_videofailed1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videofailed1.js +30 -0
- package/src/paraglide/messages/gallery_videogenerating1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videogenerating1.js +30 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.d.ts +17 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.js +30 -0
- package/src/paraglide/messages/gallery_videoprogress1.d.ts +19 -0
- package/src/paraglide/messages/gallery_videoprogress1.js +30 -0
- package/src/paraglide/messages/gallery_videostop1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videostop1.js +30 -0
- package/src/paraglide/messages/story_table_resizecolumn1.d.ts +17 -0
- package/src/paraglide/messages/story_table_resizecolumn1.js +30 -0
- package/src/providers/index.tsx +5 -50
- package/src/routeTree.gen.ts +21 -0
- package/src/router.tsx +21 -8
- package/src/routes/__root.tsx +2 -1
- package/src/routes/__tests__/-edition-routing.test.tsx +6 -1
- package/src/routes/_login/forgot-password/route.lazy.tsx +7 -6
- package/src/routes/_login/login/route.lazy.tsx +10 -9
- package/src/routes/_login/register/route.lazy.tsx +19 -18
- package/src/routes/_login/reset-password/route.lazy.tsx +10 -9
- package/src/routes/_nav/knowledge/compliance/$id.lazy.tsx +9 -12
- package/src/routes/_nav/knowledge/compliance/index.lazy.tsx +16 -13
- package/src/routes/_nav/knowledge/laws/$id.lazy.tsx +1 -1
- package/src/routes/_nav/notifications/route.tsx +6 -16
- package/src/routes/_nav/settings/-settings-tabs.tsx +9 -12
- package/src/routes/api/generate/__tests__/media.test.ts +378 -0
- package/src/routes/api/generate/media.ts +179 -0
- package/src/server/__tests__/agent-client-graph.test.ts +0 -1
- package/src/server/__tests__/agent-crud.test.ts +37 -4
- package/src/server/__tests__/bug-groups-two-level.test.ts +34 -1
- package/src/server/__tests__/chat-conversations.test.ts +37 -4
- package/src/server/__tests__/chat-list-messages.test.ts +40 -7
- package/src/server/__tests__/csv-export.test.ts +36 -3
- package/src/server/__tests__/desktop-bootstrap.test.ts +189 -0
- package/src/server/__tests__/remote-auth.test.ts +72 -0
- package/src/server/__tests__/skill-crud.test.ts +37 -4
- package/src/server/__tests__/sso-domain.test.ts +1 -1
- package/src/server/__tests__/sso-rate-limit-singleton.test.ts +123 -0
- package/src/server/__tests__/task-serverfn-crud.test.ts +35 -2
- package/src/server/__tests__/task-serverfn-queries.test.ts +35 -2
- package/src/server/__tests__/testcase-board.test.ts +38 -5
- package/src/server/__tests__/testcase-bulk.test.ts +38 -5
- package/src/server/__tests__/testcase-list-scope.test.ts +38 -5
- package/src/server/ai-gateway/__tests__/ai-output-guard.test.ts +126 -2
- package/src/server/ai-gateway/__tests__/chat-stream-builder-code-mode.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-memory.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-sandbox.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-skills.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-adapter.test.ts +30 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-conformance.test.ts +92 -0
- package/src/server/ai-gateway/__tests__/source-mode.test.ts +49 -8
- package/src/server/ai-gateway/ai-output-guard.ts +50 -2
- package/src/server/ai-gateway/chat-stream-builder.ts +3 -0
- package/src/server/ai-gateway/media/index.ts +36 -29
- package/src/server/ai-gateway/media/trim-input.ts +52 -0
- package/src/server/ai-gateway/memory/pgvector-adapter.ts +27 -13
- package/src/server/ai-gateway/sandbox/__tests__/harness-sandbox.test.ts +252 -41
- package/src/server/ai-gateway/sandbox/harness-sandbox.ts +6 -67
- package/src/server/ai-gateway/source-mode.ts +24 -8
- package/src/server/desktop-bootstrap.ts +74 -0
- package/src/server/lib/__tests__/rate-limit.test.ts +0 -1
- package/src/server/lib/rate-limit.ts +0 -2
- package/src/server/middlewares/__tests__/auth-context.test.ts +156 -0
- package/src/server/middlewares/auth-context.ts +62 -0
- package/src/server/remote-auth.ts +58 -31
- package/src/server/serverFns/__tests__/ai-hosted-models.test.ts +47 -15
- package/src/server/serverFns/__tests__/ai-source-mode.test.ts +45 -15
- package/src/server/serverFns/__tests__/billing.test.ts +37 -2
- package/src/server/serverFns/__tests__/collab-snapshot.test.ts +41 -14
- package/src/server/serverFns/__tests__/collab.test.ts +41 -14
- package/src/server/serverFns/__tests__/compliance.test.ts +33 -1
- package/src/server/serverFns/__tests__/email-verification.test.ts +35 -1
- package/src/server/serverFns/__tests__/knowledge-breadcrumb.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-delete.test.ts +42 -14
- package/src/server/serverFns/__tests__/knowledge-kb-projects.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-public-compliance.test.ts +36 -2
- package/src/server/serverFns/__tests__/knowledge-readable-kb.test.ts +42 -10
- package/src/server/serverFns/__tests__/knowledge-search.test.ts +45 -9
- package/src/server/serverFns/__tests__/legal-code-canonical.test.ts +36 -2
- package/src/server/serverFns/__tests__/link-preview.test.ts +38 -4
- package/src/server/serverFns/__tests__/notifications-list.test.ts +36 -3
- package/src/server/serverFns/__tests__/ownership-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/project-delete-transaction.test.ts +39 -2
- package/src/server/serverFns/__tests__/project-kb.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-member-idor.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-team-assign.test.ts +34 -1
- package/src/server/serverFns/__tests__/read-write-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-comments.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-archive-detail.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-labels-users.test.ts +37 -3
- package/src/server/serverFns/__tests__/story-crud.test.ts +36 -3
- package/src/server/serverFns/__tests__/story-links.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-reactions.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-tree.test.ts +38 -4
- package/src/server/serverFns/__tests__/team-accept.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-invitation.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-join-request.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-members.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-ownership-merge.test.ts +34 -1
- package/src/server/serverFns/__tests__/update-bug-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/update-document-guard.test.ts +38 -4
- package/src/server/serverFns/__tests__/update-page-guard.test.ts +40 -4
- package/src/server/serverFns/__tests__/update-seats.test.ts +33 -1
- package/src/server/serverFns/__tests__/update-story-guard.test.ts +36 -3
- package/src/server/serverFns/__tests__/update-testcase-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/workspace-kb-idor.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace-kb.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace.test.ts +34 -1
- package/src/server/serverFns/activity.ts +10 -14
- package/src/server/serverFns/agents/agent-crud.ts +16 -15
- package/src/server/serverFns/agents/bindings.ts +12 -13
- package/src/server/serverFns/agents/skill-crud.ts +16 -15
- package/src/server/serverFns/ai/code-mode-readiness.ts +3 -4
- package/src/server/serverFns/ai/search-capability.ts +3 -4
- package/src/server/serverFns/anyhub/app.ts +10 -14
- package/src/server/serverFns/anyhub/index.ts +7 -10
- package/src/server/serverFns/anyhub/install.ts +4 -4
- package/src/server/serverFns/anyhub/permissions.ts +10 -14
- package/src/server/serverFns/anyhub/proxy.ts +4 -6
- package/src/server/serverFns/auth/email-verification.ts +4 -5
- package/src/server/serverFns/auth/session.ts +9 -0
- package/src/server/serverFns/billing.ts +18 -28
- package/src/server/serverFns/blob-upload.ts +6 -9
- package/src/server/serverFns/bug/__tests__/bug-access-tokens.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-activities.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-comments.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-crud.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-fix.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-groups.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reactions.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reorder.test.ts +39 -5
- package/src/server/serverFns/bug/__tests__/bug-repro.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-story.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-webhooks.test.ts +34 -1
- package/src/server/serverFns/bug/bug-access-tokens.ts +16 -22
- package/src/server/serverFns/bug/bug-activities.ts +4 -6
- package/src/server/serverFns/bug/bug-collect-tokens.ts +13 -18
- package/src/server/serverFns/bug/bug-comments.ts +13 -18
- package/src/server/serverFns/bug/bug-crud/detail.ts +10 -14
- package/src/server/serverFns/bug/bug-crud.ts +28 -38
- package/src/server/serverFns/bug/bug-display-options.ts +8 -11
- package/src/server/serverFns/bug/bug-export.ts +5 -7
- package/src/server/serverFns/bug/bug-fix.ts +10 -14
- package/src/server/serverFns/bug/bug-groups.ts +10 -14
- package/src/server/serverFns/bug/bug-reactions.ts +10 -14
- package/src/server/serverFns/bug/bug-reorder.ts +4 -6
- package/src/server/serverFns/bug/bug-repro.ts +8 -11
- package/src/server/serverFns/bug/bug-story-bulk.ts +13 -18
- package/src/server/serverFns/bug/bug-story.ts +10 -14
- package/src/server/serverFns/bug/bug-views.ts +12 -18
- package/src/server/serverFns/bug/bug-webhooks.ts +13 -18
- package/src/server/serverFns/bug/test-bug-confirm.ts +7 -10
- package/src/server/serverFns/changelog/__tests__/fetch.test.ts +40 -1
- package/src/server/serverFns/changelog/fetch.ts +4 -6
- package/src/server/serverFns/chat/conversations.ts +17 -28
- package/src/server/serverFns/chat/list-messages.ts +4 -7
- package/src/server/serverFns/collab-presence.ts +11 -13
- package/src/server/serverFns/collab-snapshot.ts +6 -7
- package/src/server/serverFns/collab.ts +7 -7
- package/src/server/serverFns/compliance.ts +8 -8
- package/src/server/serverFns/design/__tests__/comments.test.ts +54 -10
- package/src/server/serverFns/design/__tests__/designs.test.ts +39 -16
- package/src/server/serverFns/design/__tests__/page-versions.test.ts +52 -14
- package/src/server/serverFns/design/__tests__/shares-password.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/shares.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/versions.test.ts +44 -14
- package/src/server/serverFns/design/ai/__tests__/agent-conversations.test.ts +50 -21
- package/src/server/serverFns/design/ai/__tests__/providers.test.ts +42 -8
- package/src/server/serverFns/design/ai/agent-conversations.ts +19 -26
- package/src/server/serverFns/design/ai/fill-annotation.ts +5 -7
- package/src/server/serverFns/design/ai/generate-prototype.ts +5 -7
- package/src/server/serverFns/design/ai/hosted-models.ts +4 -5
- package/src/server/serverFns/design/ai/providers.ts +30 -39
- package/src/server/serverFns/design/ai/source-mode.ts +10 -12
- package/src/server/serverFns/design/comments.ts +14 -13
- package/src/server/serverFns/design/designs.ts +13 -19
- package/src/server/serverFns/design/page-versions.ts +17 -18
- package/src/server/serverFns/design/pages.ts +17 -18
- package/src/server/serverFns/design/reviews.ts +8 -9
- package/src/server/serverFns/design/shares-password.ts +13 -19
- package/src/server/serverFns/design/shares.ts +22 -31
- package/src/server/serverFns/design/versions.ts +8 -9
- package/src/server/serverFns/harness/__tests__/attach-prototype.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-kb.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story-ssrf.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/cancel-run.test.ts +40 -15
- package/src/server/serverFns/harness/__tests__/extract-attachment.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/gallery.spec.ts +76 -12
- package/src/server/serverFns/harness/__tests__/github-workspace.spec.ts +38 -6
- package/src/server/serverFns/harness/__tests__/media-prototype.spec.ts +50 -6
- package/src/server/serverFns/harness/__tests__/media.spec.ts +55 -11
- package/src/server/serverFns/harness/__tests__/sandbox-policy.test.ts +41 -16
- package/src/server/serverFns/harness/__tests__/workspace-files.test.ts +41 -16
- package/src/server/serverFns/harness/attach-prototype.ts +4 -4
- package/src/server/serverFns/harness/attach-to-kb.ts +4 -4
- package/src/server/serverFns/harness/attach-to-story.ts +4 -4
- package/src/server/serverFns/harness/cancel-run.ts +4 -6
- package/src/server/serverFns/harness/extract-attachment.ts +3 -4
- package/src/server/serverFns/harness/gallery.ts +19 -23
- package/src/server/serverFns/harness/github-workspace.ts +14 -21
- package/src/server/serverFns/harness/media.ts +18 -117
- package/src/server/serverFns/harness/sandbox-policy.ts +11 -10
- package/src/server/serverFns/harness/search-mention-candidates.ts +4 -6
- package/src/server/serverFns/harness/workspace-files.ts +19 -26
- package/src/server/serverFns/iteration/__tests__/iteration-auto-schedule.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-crud.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-stories.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-transfer.test.ts +35 -3
- package/src/server/serverFns/iteration/iteration-auto-schedule.ts +7 -10
- package/src/server/serverFns/iteration/iteration-burndown.ts +4 -6
- package/src/server/serverFns/iteration/iteration-crud.ts +26 -35
- package/src/server/serverFns/iteration/iteration-stories.ts +10 -14
- package/src/server/serverFns/iteration/iteration-transfer.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/categories.ts +11 -15
- package/src/server/serverFns/knowledge/public/bookmarks/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/favorite.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/refresh-favicon.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/sync-github.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/update.ts +6 -8
- package/src/server/serverFns/knowledge/public/compliance/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/compliance/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/entity-tags.ts +4 -6
- package/src/server/serverFns/knowledge/public/favorite.ts +7 -10
- package/src/server/serverFns/knowledge/public/legal/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/legal/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/update.ts +5 -7
- package/src/server/serverFns/knowledge-index.ts +12 -16
- package/src/server/serverFns/knowledge.ts +50 -67
- package/src/server/serverFns/notifications.ts +25 -34
- package/src/server/serverFns/plugins/harness-plugins.ts +16 -23
- package/src/server/serverFns/project/module-overview.ts +7 -10
- package/src/server/serverFns/project.ts +48 -68
- package/src/server/serverFns/references/create.ts +4 -6
- package/src/server/serverFns/references/resolve.ts +4 -6
- package/src/server/serverFns/references/search.ts +4 -6
- package/src/server/serverFns/share/design/[designId]/events.ts +4 -6
- package/src/server/serverFns/sso.ts +1 -1
- package/src/server/serverFns/story/__tests__/bulk.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-assoc.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-attachments.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-crud-date-key.test.ts +42 -17
- package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-gantt-deps.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-groups.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-read-path-authz.test.ts +40 -4
- package/src/server/serverFns/story/__tests__/story-search.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-transfer.test.ts +34 -1
- package/src/server/serverFns/story/link-preview.ts +5 -7
- package/src/server/serverFns/story/story-assoc.ts +28 -38
- package/src/server/serverFns/story/story-attachments.ts +7 -10
- package/src/server/serverFns/story/story-children.ts +4 -6
- package/src/server/serverFns/story/story-comments.ts +13 -18
- package/src/server/serverFns/story/story-crud/activities.ts +4 -6
- package/src/server/serverFns/story/story-crud/archive.ts +7 -10
- package/src/server/serverFns/story/story-crud/bulk.ts +10 -14
- package/src/server/serverFns/story/story-crud/detail.ts +7 -10
- package/src/server/serverFns/story/story-crud/label-suggest.ts +4 -6
- package/src/server/serverFns/story/story-crud/labels.ts +6 -9
- package/src/server/serverFns/story/story-crud/user-brief.ts +4 -6
- package/src/server/serverFns/story/story-crud.ts +13 -18
- package/src/server/serverFns/story/story-dependencies.ts +16 -22
- package/src/server/serverFns/story/story-groups.ts +10 -14
- package/src/server/serverFns/story/story-links.ts +13 -18
- package/src/server/serverFns/story/story-reactions.ts +13 -18
- package/src/server/serverFns/story/story-search.ts +7 -10
- package/src/server/serverFns/story/story-transfer.ts +10 -14
- package/src/server/serverFns/story/story-tree.ts +7 -10
- package/src/server/serverFns/story-display-options.ts +7 -8
- package/src/server/serverFns/story-view.ts +12 -18
- package/src/server/serverFns/tasks/task-crud.ts +13 -17
- package/src/server/serverFns/tasks/task-queries.ts +12 -18
- package/src/server/serverFns/team.ts +46 -66
- package/src/server/serverFns/testcase/__tests__/automation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/evidence-upload.test.ts +37 -3
- package/src/server/serverFns/testcase/__tests__/generation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/plans.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/regression.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/run-cases.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/runs.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/stats.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-board.test.ts +39 -5
- package/src/server/serverFns/testcase/__tests__/testcase-crud.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-folders.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-groups.test.ts +38 -5
- package/src/server/serverFns/testcase/automation.ts +13 -17
- package/src/server/serverFns/testcase/bulk.ts +10 -14
- package/src/server/serverFns/testcase/evidence-upload.ts +5 -7
- package/src/server/serverFns/testcase/generation.ts +10 -13
- package/src/server/serverFns/testcase/plans.ts +23 -31
- package/src/server/serverFns/testcase/regression.ts +7 -10
- package/src/server/serverFns/testcase/run-cases.ts +13 -18
- package/src/server/serverFns/testcase/runs.ts +13 -18
- package/src/server/serverFns/testcase/stats.ts +13 -18
- package/src/server/serverFns/testcase/testcase-activities.ts +4 -6
- package/src/server/serverFns/testcase/testcase-board.ts +4 -6
- package/src/server/serverFns/testcase/testcase-crud.ts +20 -27
- package/src/server/serverFns/testcase/testcase-display-options.ts +8 -11
- package/src/server/serverFns/testcase/testcase-export.ts +5 -7
- package/src/server/serverFns/testcase/testcase-filter-views.ts +12 -18
- package/src/server/serverFns/testcase/testcase-folders.ts +16 -22
- package/src/server/serverFns/testcase/testcase-groups.ts +4 -6
- package/src/server/serverFns/testcase/testcase-reorder.ts +4 -6
- package/src/server/serverFns/translation.ts +4 -6
- package/src/server/serverFns/user/avatar.ts +4 -6
- package/src/server/serverFns/user/settings.ts +4 -6
- package/src/server/serverFns/user/update-locale.ts +4 -6
- package/src/server/serverFns/workspace-kb.ts +26 -35
- package/src/server/serverFns/workspace.ts +43 -59
- package/src/server/serverFns/ws.ts +4 -6
- package/src/server/serverfn-public-allowlist.ts +117 -0
- package/src/server/story/types.ts +0 -1
- package/src/server/sync/__tests__/scopes.test.ts +64 -0
- package/src/server/sync/scopes.ts +7 -0
- package/src/server/testcase/__tests__/auto-bug.test.ts +44 -12
- package/src/__tests__/bench/baselines/format-timestamp.json +0 -44
- package/src/__typeprobe__.d.ts +0 -4
- package/src/components/forms/app-form-dialog.tsx +0 -126
- package/src/components/forms/hooks/use-form-submit.ts +0 -57
- package/src/components/forms/types.ts +0 -34
- package/src/components/harness/code/workspace-picker.tsx +0 -239
- package/src/components/tiptap/extensions/local-file/insert-local-file.ts +0 -35
- package/src/components/tiptap/extensions/local-file/local-file-node.ts +0 -71
- package/src/devframe-docks/ai-chat-iframe.tsx +0 -29
- package/src/devframe-docks/session-iframe.tsx +0 -90
- package/src/lib/__tests__/desktop-detect.test.ts +0 -19
- package/src/lib/collections/index.ts +0 -22
- package/src/lib/collections/knowledge/index.ts +0 -18
- package/src/lib/collections/knowledge/knowledge-bases-collection.ts +0 -34
- package/src/lib/collections/reference/bookmark-categories-collection.ts +0 -31
- package/src/lib/collections/reference/labels-collection.ts +0 -31
- package/src/lib/collections/reference/projects-collection.ts +0 -31
- package/src/lib/collections/reference/users-brief-collection.ts +0 -35
- package/src/lib/collections/reference/workspaces-collection.ts +0 -34
- package/src/lib/desktop-detect.ts +0 -29
- package/src/paraglide/messages/en.js +0 -28260
- package/src/paraglide/messages/zh.js +0 -28258
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
19
19
|
import { createServerFn } from "@tanstack/react-start"
|
|
20
|
+
import { authContextMiddleware } from "@/server/middlewares/auth-context"
|
|
20
21
|
import { getRequest } from "@tanstack/react-start/server"
|
|
21
22
|
import { z } from "zod"
|
|
22
23
|
import { requireFeature } from "@/server/entitlements"
|
|
23
24
|
import { requireResource } from "@/server/resources"
|
|
24
|
-
import { requireUserId } from "@/server/auth-helpers"
|
|
25
25
|
import { SKILL_NAME_CONFLICT_CODE } from "@/lib/agents/skill-errors"
|
|
26
26
|
|
|
27
27
|
const NAME_REGEX = /^[a-z0-9-]+$/
|
|
@@ -64,10 +64,10 @@ const SKILL_DTO_SELECT = {
|
|
|
64
64
|
updatedAt: true,
|
|
65
65
|
} as const
|
|
66
66
|
|
|
67
|
-
export const listSkillsFn = createServerFn({ method: "GET" })
|
|
67
|
+
export const listSkillsFn = createServerFn({ method: "GET" })
|
|
68
|
+
.middleware([authContextMiddleware]).handler(async ({ context }) => {
|
|
68
69
|
const prisma = await getPrisma()
|
|
69
|
-
const
|
|
70
|
-
const userId = await requireUserId(request)
|
|
70
|
+
const userId = context.user.id
|
|
71
71
|
|
|
72
72
|
const skills = await prisma.userSkill.findMany({
|
|
73
73
|
where: { userId, isDeleted: false },
|
|
@@ -79,11 +79,12 @@ export const listSkillsFn = createServerFn({ method: "GET" }).handler(async () =
|
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
export const createSkillFn = createServerFn({ method: "POST" })
|
|
82
|
+
.middleware([authContextMiddleware])
|
|
82
83
|
.validator(skillInputSchema)
|
|
83
|
-
.handler(async ({ data }) => {
|
|
84
|
+
.handler(async ({ data, context }) => {
|
|
84
85
|
const prisma = await getPrisma()
|
|
85
86
|
const request = getRequest()
|
|
86
|
-
const userId =
|
|
87
|
+
const userId = context.user.id
|
|
87
88
|
|
|
88
89
|
await requireFeature(request, "customAgents")
|
|
89
90
|
await requireResource(request, "skillQuota", 1)
|
|
@@ -112,11 +113,11 @@ export const createSkillFn = createServerFn({ method: "POST" })
|
|
|
112
113
|
const getSkillSchema = z.object({ id: z.string() })
|
|
113
114
|
|
|
114
115
|
export const getSkillFn = createServerFn({ method: "GET" })
|
|
116
|
+
.middleware([authContextMiddleware])
|
|
115
117
|
.validator(getSkillSchema)
|
|
116
|
-
.handler(async ({ data }) => {
|
|
118
|
+
.handler(async ({ data, context }) => {
|
|
117
119
|
const prisma = await getPrisma()
|
|
118
|
-
const
|
|
119
|
-
const userId = await requireUserId(request)
|
|
120
|
+
const userId = context.user.id
|
|
120
121
|
|
|
121
122
|
const skill = await prisma.userSkill.findFirst({
|
|
122
123
|
where: { id: data.id, userId, isDeleted: false },
|
|
@@ -149,11 +150,11 @@ function buildSkillUpdatePayload(input: SkillUpdateInput): Record<string, unknow
|
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
export const updateSkillFn = createServerFn({ method: "POST" })
|
|
153
|
+
.middleware([authContextMiddleware])
|
|
152
154
|
.validator(skillUpdateSchema)
|
|
153
|
-
.handler(async ({ data }) => {
|
|
155
|
+
.handler(async ({ data, context }) => {
|
|
154
156
|
const prisma = await getPrisma()
|
|
155
|
-
const
|
|
156
|
-
const userId = await requireUserId(request)
|
|
157
|
+
const userId = context.user.id
|
|
157
158
|
|
|
158
159
|
// DB-03:属主校验合并进写入(updateMany 计数判定),1 次查询替代 2 次
|
|
159
160
|
const update = buildSkillUpdatePayload(data)
|
|
@@ -171,11 +172,11 @@ export const updateSkillFn = createServerFn({ method: "POST" })
|
|
|
171
172
|
const deleteSkillSchema = z.object({ id: z.string() })
|
|
172
173
|
|
|
173
174
|
export const deleteSkillFn = createServerFn({ method: "POST" })
|
|
175
|
+
.middleware([authContextMiddleware])
|
|
174
176
|
.validator(deleteSkillSchema)
|
|
175
|
-
.handler(async ({ data }) => {
|
|
177
|
+
.handler(async ({ data, context }) => {
|
|
176
178
|
const prisma = await getPrisma()
|
|
177
|
-
const
|
|
178
|
-
const userId = await requireUserId(request)
|
|
179
|
+
const userId = context.user.id
|
|
179
180
|
|
|
180
181
|
// DB-03:属主校验合并进写入(updateMany 计数判定)
|
|
181
182
|
const res = await prisma.userSkill.updateMany({
|
|
@@ -16,14 +16,13 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from "@tanstack/react-start"
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from "@/server/middlewares/auth-context"
|
|
20
20
|
import { getCodeModeReadiness } from "@/server/ai-gateway/code-mode"
|
|
21
|
-
import { requireUserId } from "@/server/auth-helpers"
|
|
22
21
|
|
|
23
22
|
// 仅面向已登录的 harness 工作台(useCodeModeReadiness 消费方),非公开端点
|
|
24
|
-
export const getCodeModeReadinessFn = createServerFn({ method: "GET" })
|
|
23
|
+
export const getCodeModeReadinessFn = createServerFn({ method: "GET" })
|
|
24
|
+
.middleware([authContextMiddleware]).handler(
|
|
25
25
|
async () => {
|
|
26
|
-
await requireUserId(getRequest())
|
|
27
26
|
return getCodeModeReadiness()
|
|
28
27
|
},
|
|
29
28
|
)
|
|
@@ -16,14 +16,13 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from "@tanstack/react-start"
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from "@/server/middlewares/auth-context"
|
|
20
20
|
import { isSearxngEnabled } from "@/server/web-search"
|
|
21
|
-
import { requireUserId } from "@/server/auth-helpers"
|
|
22
21
|
|
|
23
22
|
// 仅面向已登录的 harness 对话 UI(useSearchCapability 消费方),非公开端点
|
|
24
|
-
export const getSearchCapabilityFn = createServerFn({ method: "GET" })
|
|
23
|
+
export const getSearchCapabilityFn = createServerFn({ method: "GET" })
|
|
24
|
+
.middleware([authContextMiddleware]).handler(
|
|
25
25
|
async () => {
|
|
26
|
-
await requireUserId(getRequest())
|
|
27
26
|
return { searxngEnabled: isSearxngEnabled() }
|
|
28
27
|
},
|
|
29
28
|
)
|
|
@@ -17,9 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
19
19
|
import { createServerFn } from '@tanstack/react-start'
|
|
20
|
-
import {
|
|
20
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
21
21
|
import { z } from 'zod'
|
|
22
|
-
import { requireAuth } from '@/server/auth-helpers'
|
|
23
22
|
|
|
24
23
|
// DB-05:白名单 select(与 index.ts listAnyHubAppsFn 同一口径,防未来新增敏感列外泄)
|
|
25
24
|
const ANY_HUB_APP_SELECT = {
|
|
@@ -42,13 +41,12 @@ const ANY_HUB_APP_SELECT = {
|
|
|
42
41
|
} as const
|
|
43
42
|
|
|
44
43
|
export const getAnyHubAppFn = createServerFn({ method: 'GET' })
|
|
44
|
+
.middleware([authContextMiddleware])
|
|
45
45
|
.validator(z.object({ id: z.string() }))
|
|
46
|
-
.handler(async ({ data }) => {
|
|
46
|
+
.handler(async ({ data, context }) => {
|
|
47
47
|
const prisma = await getPrisma()
|
|
48
|
-
const request = getRequest()
|
|
49
|
-
const session = await requireAuth(request)
|
|
50
48
|
const app = await prisma.anyHubApp.findFirst({
|
|
51
|
-
where: { id: data.id, userId:
|
|
49
|
+
where: { id: data.id, userId: context.user.id },
|
|
52
50
|
select: ANY_HUB_APP_SELECT,
|
|
53
51
|
})
|
|
54
52
|
if (!app) throw new Error('应用不存在')
|
|
@@ -56,14 +54,13 @@ export const getAnyHubAppFn = createServerFn({ method: 'GET' })
|
|
|
56
54
|
})
|
|
57
55
|
|
|
58
56
|
export const updateAnyHubAppFn = createServerFn({ method: 'POST' })
|
|
57
|
+
.middleware([authContextMiddleware])
|
|
59
58
|
.validator(z.object({ id: z.string() }))
|
|
60
|
-
.handler(async ({ data }) => {
|
|
59
|
+
.handler(async ({ data, context }) => {
|
|
61
60
|
const prisma = await getPrisma()
|
|
62
|
-
const request = getRequest()
|
|
63
|
-
const session = await requireAuth(request)
|
|
64
61
|
// DB-03:属主校验合并进写入(updateMany 计数判定);version 由安装流程维护,此处不再回写原值
|
|
65
62
|
const res = await prisma.anyHubApp.updateMany({
|
|
66
|
-
where: { id: data.id, userId:
|
|
63
|
+
where: { id: data.id, userId: context.user.id },
|
|
67
64
|
data: {
|
|
68
65
|
status: 'updating',
|
|
69
66
|
updatedAt: new Date(),
|
|
@@ -74,14 +71,13 @@ export const updateAnyHubAppFn = createServerFn({ method: 'POST' })
|
|
|
74
71
|
})
|
|
75
72
|
|
|
76
73
|
export const deleteAnyHubAppFn = createServerFn({ method: 'POST' })
|
|
74
|
+
.middleware([authContextMiddleware])
|
|
77
75
|
.validator(z.object({ id: z.string() }))
|
|
78
|
-
.handler(async ({ data }) => {
|
|
76
|
+
.handler(async ({ data, context }) => {
|
|
79
77
|
const prisma = await getPrisma()
|
|
80
|
-
const request = getRequest()
|
|
81
|
-
const session = await requireAuth(request)
|
|
82
78
|
// DB-03:属主校验合并进删除(deleteMany 计数判定)
|
|
83
79
|
const res = await prisma.anyHubApp.deleteMany({
|
|
84
|
-
where: { id: data.id, userId:
|
|
80
|
+
where: { id: data.id, userId: context.user.id },
|
|
85
81
|
})
|
|
86
82
|
if (res.count === 0) throw new Error('应用不存在')
|
|
87
83
|
return { success: true }
|
|
@@ -18,9 +18,8 @@
|
|
|
18
18
|
import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
19
19
|
import type { Prisma } from "@allbluecn/database"
|
|
20
20
|
import { createServerFn } from '@tanstack/react-start'
|
|
21
|
-
import {
|
|
21
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
22
22
|
import { z } from 'zod'
|
|
23
|
-
import { requireAuth } from '@/server/auth-helpers'
|
|
24
23
|
|
|
25
24
|
// DB-05:白名单 select(消费方 AnyHubAppData 覆盖全部标量列,防未来新增敏感列外泄)
|
|
26
25
|
const ANY_HUB_APP_SELECT = {
|
|
@@ -43,13 +42,12 @@ const ANY_HUB_APP_SELECT = {
|
|
|
43
42
|
} as const
|
|
44
43
|
|
|
45
44
|
export const listAnyHubAppsFn = createServerFn({ method: 'GET' })
|
|
46
|
-
.
|
|
45
|
+
.middleware([authContextMiddleware])
|
|
46
|
+
.handler(async ({ context }) => {
|
|
47
47
|
const prisma = await getPrisma()
|
|
48
|
-
const request = getRequest()
|
|
49
|
-
const session = await requireAuth(request)
|
|
50
48
|
// DB-05:白名单 select(消费方 AnyHubAppData 覆盖全部标量列,防未来新增敏感列外泄)
|
|
51
49
|
return prisma.anyHubApp.findMany({
|
|
52
|
-
where: { userId:
|
|
50
|
+
where: { userId: context.user.id },
|
|
53
51
|
orderBy: { createdAt: 'desc' },
|
|
54
52
|
select: ANY_HUB_APP_SELECT,
|
|
55
53
|
})
|
|
@@ -91,12 +89,11 @@ export const listMarketplaceAppsFn = createServerFn({ method: 'GET' })
|
|
|
91
89
|
})
|
|
92
90
|
|
|
93
91
|
export const togglePinFn = createServerFn({ method: 'POST' })
|
|
92
|
+
.middleware([authContextMiddleware])
|
|
94
93
|
.validator(z.object({ appId: z.string() }))
|
|
95
|
-
.handler(async ({ data }) => {
|
|
94
|
+
.handler(async ({ data, context }) => {
|
|
96
95
|
const prisma = await getPrisma()
|
|
97
|
-
const
|
|
98
|
-
const session = await requireAuth(request)
|
|
99
|
-
const userId = session.user.id
|
|
96
|
+
const userId = context.user.id
|
|
100
97
|
// DB-03:读回 pinned + 条件写收进事务,写路径带 userId 谓词消除 TOCTOU
|
|
101
98
|
return prisma.$transaction(async (tx) => {
|
|
102
99
|
const app = await tx.anyHubApp.findFirst({
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
19
19
|
import { createServerFn } from '@tanstack/react-start'
|
|
20
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
21
|
import { getRequest } from '@tanstack/react-start/server'
|
|
21
22
|
import { z } from 'zod'
|
|
22
23
|
import path from 'node:path'
|
|
23
|
-
import { requireAuth } from '@/server/auth-helpers'
|
|
24
24
|
import { requireResource } from '@/server/resources'
|
|
25
25
|
import { isLocalPathAllowed } from '@/lib/anyhub/local-path'
|
|
26
26
|
|
|
@@ -48,11 +48,11 @@ function assertGithubUrl(githubUrl: string): void {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export const installAnyHubAppFn = createServerFn({ method: 'POST' })
|
|
51
|
+
.middleware([authContextMiddleware])
|
|
51
52
|
.validator(installSchema)
|
|
52
|
-
.handler(async ({ data }) => {
|
|
53
|
+
.handler(async ({ data, context }) => {
|
|
53
54
|
const prisma = await getPrisma()
|
|
54
55
|
const request = getRequest()
|
|
55
|
-
const session = await requireAuth(request)
|
|
56
56
|
// S6:安装按尝试计(含 installing/failed),超档拒绝(裁决:三档 200/1000/5000)
|
|
57
57
|
await requireResource(request, 'installQuota', 1)
|
|
58
58
|
|
|
@@ -81,7 +81,7 @@ export const installAnyHubAppFn = createServerFn({ method: 'POST' })
|
|
|
81
81
|
marketplaceAppId: data.source === 'marketplace' ? data.marketplaceAppId : undefined,
|
|
82
82
|
githubUrl: data.source === 'github' ? data.githubUrl : undefined,
|
|
83
83
|
localPath: resolvedLocalPath,
|
|
84
|
-
userId:
|
|
84
|
+
userId: context.user.id,
|
|
85
85
|
status: 'installing',
|
|
86
86
|
},
|
|
87
87
|
})
|
|
@@ -16,18 +16,16 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import {
|
|
19
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
20
20
|
import { z } from 'zod'
|
|
21
|
-
import { requireAuth } from '@/server/auth-helpers'
|
|
22
21
|
import { getAppPermissions, grantPermission, checkPermission } from '@/lib/anyhub/permissions'
|
|
23
22
|
import { ALL_CAPABILITIES } from '@/lib/anyhub/capabilities'
|
|
24
23
|
|
|
25
24
|
export const getAnyHubPermissionsFn = createServerFn({ method: 'GET' })
|
|
25
|
+
.middleware([authContextMiddleware])
|
|
26
26
|
.validator(z.object({ id: z.string() }))
|
|
27
|
-
.handler(async ({ data }) => {
|
|
28
|
-
|
|
29
|
-
const session = await requireAuth(request)
|
|
30
|
-
return getAppPermissions(data.id, session.user.id)
|
|
27
|
+
.handler(async ({ data, context }) => {
|
|
28
|
+
return getAppPermissions(data.id, context.user.id)
|
|
31
29
|
})
|
|
32
30
|
|
|
33
31
|
const updatePermissionSchema = z.object({
|
|
@@ -38,11 +36,10 @@ const updatePermissionSchema = z.object({
|
|
|
38
36
|
})
|
|
39
37
|
|
|
40
38
|
export const updateAnyHubPermissionFn = createServerFn({ method: 'POST' })
|
|
39
|
+
.middleware([authContextMiddleware])
|
|
41
40
|
.validator(updatePermissionSchema)
|
|
42
|
-
.handler(async ({ data }) => {
|
|
43
|
-
|
|
44
|
-
const session = await requireAuth(request)
|
|
45
|
-
await grantPermission(data.id, data.capability, session.user.id, data.granted)
|
|
41
|
+
.handler(async ({ data, context }) => {
|
|
42
|
+
await grantPermission(data.id, data.capability, context.user.id, data.granted)
|
|
46
43
|
return { success: true }
|
|
47
44
|
})
|
|
48
45
|
|
|
@@ -58,9 +55,8 @@ const checkPermissionSchema = z.object({
|
|
|
58
55
|
* userId 以 session 为准,不信任客户端传入值。
|
|
59
56
|
*/
|
|
60
57
|
export const checkAnyHubPermissionFn = createServerFn({ method: 'POST' })
|
|
58
|
+
.middleware([authContextMiddleware])
|
|
61
59
|
.validator(checkPermissionSchema)
|
|
62
|
-
.handler(async ({ data }) => {
|
|
63
|
-
|
|
64
|
-
const session = await requireAuth(request)
|
|
65
|
-
return checkPermission(data.appId, data.method, session.user.id)
|
|
60
|
+
.handler(async ({ data, context }) => {
|
|
61
|
+
return checkPermission(data.appId, data.method, context.user.id)
|
|
66
62
|
})
|
|
@@ -17,9 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
19
19
|
import { createServerFn } from '@tanstack/react-start'
|
|
20
|
-
import {
|
|
20
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
21
21
|
import { z } from 'zod'
|
|
22
|
-
import { requireAuth } from '@/server/auth-helpers'
|
|
23
22
|
import { ProxyAdapter } from '@/lib/anyhub/proxy'
|
|
24
23
|
import { isLocalPathAllowed } from '@/lib/anyhub/local-path'
|
|
25
24
|
|
|
@@ -29,13 +28,12 @@ const serveFileSchema = z.object({
|
|
|
29
28
|
})
|
|
30
29
|
|
|
31
30
|
export const serveAnyHubFileFn = createServerFn({ method: 'POST' })
|
|
31
|
+
.middleware([authContextMiddleware])
|
|
32
32
|
.validator(serveFileSchema)
|
|
33
|
-
.handler(async ({ data }) => {
|
|
33
|
+
.handler(async ({ data, context }) => {
|
|
34
34
|
const prisma = await getPrisma()
|
|
35
|
-
const request = getRequest()
|
|
36
|
-
const session = await requireAuth(request)
|
|
37
35
|
const app = await prisma.anyHubApp.findFirst({
|
|
38
|
-
where: { id: data.appId, userId:
|
|
36
|
+
where: { id: data.appId, userId: context.user.id },
|
|
39
37
|
select: { localPath: true },
|
|
40
38
|
})
|
|
41
39
|
if (!app) throw new Error('应用不存在')
|
|
@@ -20,6 +20,7 @@ import { createServerFn } from '@tanstack/react-start'
|
|
|
20
20
|
import { getRequest } from '@tanstack/react-start/server'
|
|
21
21
|
import { z } from 'zod'
|
|
22
22
|
import { getCurrentSession } from '@/lib/session'
|
|
23
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
23
24
|
import { checkAuthRateLimit } from '@/server/middlewares/rate-limit'
|
|
24
25
|
import { sendTemplateEmail, generateEmailToken } from '@/server/email'
|
|
25
26
|
|
|
@@ -78,13 +79,11 @@ export const confirmEmailVerificationFn = createServerFn({ method: 'GET' })
|
|
|
78
79
|
})
|
|
79
80
|
|
|
80
81
|
export const resendVerificationEmailFn = createServerFn({ method: 'POST' })
|
|
82
|
+
.middleware([authContextMiddleware])
|
|
81
83
|
.validator(z.object({}))
|
|
82
|
-
.handler(async () => {
|
|
84
|
+
.handler(async ({ context }) => {
|
|
83
85
|
const prisma = await getPrisma()
|
|
84
|
-
const
|
|
85
|
-
const session = await getCurrentSession(request)
|
|
86
|
-
const userId = session?.user?.id
|
|
87
|
-
if (!userId) throw new Error('请先登录')
|
|
86
|
+
const userId = context.user.id
|
|
88
87
|
|
|
89
88
|
await checkAuthRateLimit('resendVerify', 5, 15 * 60 * 1000)
|
|
90
89
|
|
|
@@ -23,6 +23,7 @@ import type { FeatureKey } from '@allbluecn/kernel'
|
|
|
23
23
|
import type { Session } from '@/lib/session'
|
|
24
24
|
import { getCurrentSession } from '@/lib/session'
|
|
25
25
|
import { buildGuestSession, isDesktopServer } from '@/server/desktop-guest'
|
|
26
|
+
import { ensureLocalShadowUser } from '@/server/desktop-bootstrap'
|
|
26
27
|
import { readRemoteAuth, writeRemoteAuth, writeRemoteSession, clearRemoteAuth } from '@/server/remote-auth'
|
|
27
28
|
import { generateEntitlementsToken } from '@/server/entitlements-token'
|
|
28
29
|
import type { RemoteAuthData } from '@/server/remote-auth'
|
|
@@ -76,6 +77,14 @@ export const getSessionFn = createServerFn({ method: 'GET' })
|
|
|
76
77
|
if (!isDesktopServer()) return null
|
|
77
78
|
const remoteAuth = await readRemoteAuth()
|
|
78
79
|
if (remoteAuth) return buildRemoteSession(remoteAuth)
|
|
80
|
+
// 桌面 guest 分支懒 seed 影子用户(本地优先 P1):首启为 local-guest 落库,
|
|
81
|
+
// 使 assertOwned/requireUserInDb/FK 全链可写。失败仅 warn 不阻断会话发放
|
|
82
|
+
// ——首启体验优先(规格 §3.1),下一请求再重试。
|
|
83
|
+
try {
|
|
84
|
+
await ensureLocalShadowUser()
|
|
85
|
+
} catch (err) {
|
|
86
|
+
console.warn('[getSessionFn] 本地影子用户落库失败(不阻断 guest 会话):', err)
|
|
87
|
+
}
|
|
79
88
|
return buildGuestSession()
|
|
80
89
|
})
|
|
81
90
|
|
|
@@ -20,7 +20,7 @@ import { createServerFn } from '@tanstack/react-start'
|
|
|
20
20
|
import { getRequest } from '@tanstack/react-start/server'
|
|
21
21
|
import { z } from 'zod'
|
|
22
22
|
import { getProService } from '@/server/pro-services'
|
|
23
|
-
import {
|
|
23
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
24
24
|
import { BillingUnavailableError } from '@allbluecn/kernel'
|
|
25
25
|
import { getEntitlements } from '@/server/entitlements'
|
|
26
26
|
import { getResourceSnapshots } from '@/server/resources'
|
|
@@ -31,9 +31,8 @@ const requireBilling = () => {
|
|
|
31
31
|
return billing
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export const getEffectivePlanFn = createServerFn({ method: 'GET' }).handler(async () => {
|
|
34
|
+
export const getEffectivePlanFn = createServerFn({ method: 'GET' }).middleware([authContextMiddleware]).handler(async () => {
|
|
35
35
|
const request = getRequest()
|
|
36
|
-
const session = await requireAuth(request)
|
|
37
36
|
|
|
38
37
|
const { planName, enabled, unavailable, source } = await getEntitlements(request)
|
|
39
38
|
const resources = await getResourceSnapshots(request)
|
|
@@ -47,10 +46,8 @@ export const getEffectivePlanFn = createServerFn({ method: 'GET' }).handler(asyn
|
|
|
47
46
|
}
|
|
48
47
|
})
|
|
49
48
|
|
|
50
|
-
export const getSubscriptionFn = createServerFn({ method: 'GET' }).handler(async () => {
|
|
51
|
-
const
|
|
52
|
-
const session = await requireAuth(request)
|
|
53
|
-
const userId = session.user.id
|
|
49
|
+
export const getSubscriptionFn = createServerFn({ method: 'GET' }).middleware([authContextMiddleware]).handler(async ({ context }) => {
|
|
50
|
+
const userId = context.user.id
|
|
54
51
|
return requireBilling().getSubscription(userId)
|
|
55
52
|
})
|
|
56
53
|
|
|
@@ -63,16 +60,15 @@ export const listPublicPlansFn = createServerFn({ method: 'GET' })
|
|
|
63
60
|
})
|
|
64
61
|
|
|
65
62
|
export const createCheckoutSessionFn = createServerFn({ method: 'POST' })
|
|
63
|
+
.middleware([authContextMiddleware])
|
|
66
64
|
.validator(
|
|
67
65
|
z.object({
|
|
68
66
|
planId: z.string(),
|
|
69
67
|
currency: z.enum(['usd', 'cny']),
|
|
70
68
|
}),
|
|
71
69
|
)
|
|
72
|
-
.handler(async ({ data }) => {
|
|
73
|
-
const
|
|
74
|
-
const session = await requireAuth(request)
|
|
75
|
-
const userId = session.user.id
|
|
70
|
+
.handler(async ({ data, context }) => {
|
|
71
|
+
const userId = context.user.id
|
|
76
72
|
|
|
77
73
|
const baseUrl = process.env.VITE_APP_URL ?? 'http://localhost:3000'
|
|
78
74
|
return requireBilling().createCheckoutSession({
|
|
@@ -85,11 +81,9 @@ export const createCheckoutSessionFn = createServerFn({ method: 'POST' })
|
|
|
85
81
|
})
|
|
86
82
|
})
|
|
87
83
|
|
|
88
|
-
export const createCustomerPortalSessionFn = createServerFn({ method: 'POST' }).validator(z.object({})).handler(
|
|
89
|
-
async () => {
|
|
90
|
-
const
|
|
91
|
-
const session = await requireAuth(request)
|
|
92
|
-
const userId = session.user.id
|
|
84
|
+
export const createCustomerPortalSessionFn = createServerFn({ method: 'POST' }).middleware([authContextMiddleware]).validator(z.object({})).handler(
|
|
85
|
+
async ({ context }) => {
|
|
86
|
+
const userId = context.user.id
|
|
93
87
|
|
|
94
88
|
const baseUrl = process.env.VITE_APP_URL ?? 'http://localhost:3000'
|
|
95
89
|
return requireBilling().createCustomerPortalSession({
|
|
@@ -99,20 +93,17 @@ export const createCustomerPortalSessionFn = createServerFn({ method: 'POST' }).
|
|
|
99
93
|
},
|
|
100
94
|
)
|
|
101
95
|
|
|
102
|
-
export const listInvoicesFn = createServerFn({ method: 'GET' }).handler(async () => {
|
|
103
|
-
const
|
|
104
|
-
const session = await requireAuth(request)
|
|
105
|
-
const userId = session.user.id
|
|
96
|
+
export const listInvoicesFn = createServerFn({ method: 'GET' }).middleware([authContextMiddleware]).handler(async ({ context }) => {
|
|
97
|
+
const userId = context.user.id
|
|
106
98
|
return requireBilling().listInvoices(userId, 20)
|
|
107
99
|
})
|
|
108
100
|
|
|
109
101
|
export const updatePreferredCurrencyFn = createServerFn({ method: 'POST' })
|
|
102
|
+
.middleware([authContextMiddleware])
|
|
110
103
|
.validator(z.object({ currency: z.enum(['usd', 'cny']) }))
|
|
111
|
-
.handler(async ({ data }) => {
|
|
104
|
+
.handler(async ({ data, context }) => {
|
|
112
105
|
const prisma = await getPrisma()
|
|
113
|
-
const
|
|
114
|
-
const session = await requireAuth(request)
|
|
115
|
-
const userId = session.user.id
|
|
106
|
+
const userId = context.user.id
|
|
116
107
|
await prisma.user.update({
|
|
117
108
|
where: { id: userId },
|
|
118
109
|
data: { preferredCurrency: data.currency },
|
|
@@ -120,17 +111,16 @@ export const updatePreferredCurrencyFn = createServerFn({ method: 'POST' })
|
|
|
120
111
|
})
|
|
121
112
|
|
|
122
113
|
export const updateSeatsFn = createServerFn({ method: 'POST' })
|
|
114
|
+
.middleware([authContextMiddleware])
|
|
123
115
|
.validator(
|
|
124
116
|
z.object({
|
|
125
117
|
addonSeats: z.number().int().min(0).max(100),
|
|
126
118
|
successUrl: z.string().url().optional(),
|
|
127
119
|
}),
|
|
128
120
|
)
|
|
129
|
-
.handler(async ({ data }) => {
|
|
121
|
+
.handler(async ({ data, context }) => {
|
|
130
122
|
const prisma = await getPrisma()
|
|
131
|
-
const
|
|
132
|
-
const session = await requireAuth(request)
|
|
133
|
-
const userId = session.user.id
|
|
123
|
+
const userId = context.user.id
|
|
134
124
|
const baseUrl = process.env.VITE_APP_URL ?? 'http://localhost:3000'
|
|
135
125
|
|
|
136
126
|
const subscription = await prisma.subscription.findUnique({
|
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from "@tanstack/react-start"
|
|
19
|
-
import { getRequest } from "@tanstack/react-start/server"
|
|
20
19
|
import { z } from "zod"
|
|
21
|
-
import {
|
|
20
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
22
21
|
import { getPorts } from "@/server/ai-gateway/runtime"
|
|
23
22
|
|
|
24
23
|
// 与 attachment-policy.ts 的 SUPPORTED_MIME_TYPES 对齐(服务端独立 fail-closed 白名单)。
|
|
@@ -48,14 +47,12 @@ const UploadBlobSchema = z.object({
|
|
|
48
47
|
* 客户端不接触 BlobStore 实现,不 import @allbluecn/database。
|
|
49
48
|
*/
|
|
50
49
|
export const uploadBlobFn = createServerFn({ method: "POST" })
|
|
50
|
+
.middleware([authContextMiddleware])
|
|
51
51
|
.validator(UploadBlobSchema)
|
|
52
|
-
.handler(async ({ data }) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return { error: "Unauthorized" as const }
|
|
57
|
-
}
|
|
58
|
-
const userId = session.user.id
|
|
52
|
+
.handler(async ({ data, context }) => {
|
|
53
|
+
// 原 requireAuth 后的 !session?.user?.id 软分支不可达(requireAuth 已抛),
|
|
54
|
+
// 迁移后由 middleware 统一抛 UnauthorizedError,死分支一并移除
|
|
55
|
+
const userId = context.user.id
|
|
59
56
|
|
|
60
57
|
if (!BLOB_MIME_TYPES.has(data.mimeType)) {
|
|
61
58
|
return { error: "UnsupportedMimeType" as const }
|
|
@@ -25,6 +25,11 @@ vi.mock("@tanstack/react-start", () => ({
|
|
|
25
25
|
createServerFn: (config: any) => {
|
|
26
26
|
const api: any = {
|
|
27
27
|
_validator: undefined,
|
|
28
|
+
_middlewares: [] as any[],
|
|
29
|
+
middleware(mws: any[]) {
|
|
30
|
+
this._middlewares.push(...mws);
|
|
31
|
+
return this;
|
|
32
|
+
},
|
|
28
33
|
validator(schema: any) {
|
|
29
34
|
this._validator = schema;
|
|
30
35
|
return this;
|
|
@@ -35,13 +40,41 @@ vi.mock("@tanstack/react-start", () => ({
|
|
|
35
40
|
if (this._validator && data !== undefined) {
|
|
36
41
|
data = this._validator.parse ? this._validator.parse(data) : data;
|
|
37
42
|
}
|
|
38
|
-
|
|
43
|
+
// 迁移后经 .middleware([authContextMiddleware]) 注入 context.user:
|
|
44
|
+
// mock 依序执行 middleware 的 server 段(复现框架 executeMiddleware 的
|
|
45
|
+
// context 合并语义),真实鉴权链由被 mock 的 auth-helpers/getRequest 承接
|
|
46
|
+
let context: any = {};
|
|
47
|
+
for (const mw of this._middlewares) {
|
|
48
|
+
const serverFn = mw?.options?.server;
|
|
49
|
+
if (!serverFn) continue;
|
|
50
|
+
const result = await serverFn({
|
|
51
|
+
data,
|
|
52
|
+
context,
|
|
53
|
+
method: 'POST',
|
|
54
|
+
serverFnMeta: {},
|
|
55
|
+
signal: new AbortController().signal,
|
|
56
|
+
next: async (inner: any) => ({ context: { ...context, ...(inner?.context ?? {}) } }),
|
|
57
|
+
});
|
|
58
|
+
context = result.context;
|
|
59
|
+
}
|
|
60
|
+
return fn({ data, context });
|
|
39
61
|
};
|
|
40
62
|
return wrapped;
|
|
41
63
|
},
|
|
42
64
|
};
|
|
43
65
|
return api;
|
|
44
66
|
},
|
|
67
|
+
// auth-context.ts 依赖 createMiddleware({ type: 'function' }).server(fn):
|
|
68
|
+
// mock 产出与真实 middleware 同构的 { options: { server } } 形状,
|
|
69
|
+
// 供上方 handler 包装器执行 server 段注入 context.user
|
|
70
|
+
createMiddleware: (opts: any) => {
|
|
71
|
+
const mw: any = { options: { type: opts?.type } };
|
|
72
|
+
mw.server = (fn: Function) => {
|
|
73
|
+
mw.options.server = fn;
|
|
74
|
+
return mw;
|
|
75
|
+
};
|
|
76
|
+
return mw;
|
|
77
|
+
},
|
|
45
78
|
}));
|
|
46
79
|
|
|
47
80
|
vi.mock("@tanstack/react-start/server", () => ({
|
|
@@ -24,6 +24,11 @@ vi.mock("@tanstack/react-start", () => ({
|
|
|
24
24
|
createServerFn: (config: any) => {
|
|
25
25
|
const api: any = {
|
|
26
26
|
_validator: undefined,
|
|
27
|
+
_middlewares: [] as any[],
|
|
28
|
+
middleware(mws: any[]) {
|
|
29
|
+
this._middlewares.push(...mws);
|
|
30
|
+
return this;
|
|
31
|
+
},
|
|
27
32
|
validator(schema: any) {
|
|
28
33
|
this._validator = schema;
|
|
29
34
|
return this;
|
|
@@ -34,13 +39,41 @@ vi.mock("@tanstack/react-start", () => ({
|
|
|
34
39
|
if (this._validator && data !== undefined) {
|
|
35
40
|
data = this._validator.parse ? this._validator.parse(data) : data;
|
|
36
41
|
}
|
|
37
|
-
|
|
42
|
+
// 迁移后经 .middleware([authContextMiddleware]) 注入 context.user:
|
|
43
|
+
// mock 依序执行 middleware 的 server 段(复现框架 executeMiddleware 的
|
|
44
|
+
// context 合并语义),真实鉴权链由被 mock 的 auth-helpers/getRequest 承接
|
|
45
|
+
let context: any = {};
|
|
46
|
+
for (const mw of this._middlewares) {
|
|
47
|
+
const serverFn = mw?.options?.server;
|
|
48
|
+
if (!serverFn) continue;
|
|
49
|
+
const result = await serverFn({
|
|
50
|
+
data,
|
|
51
|
+
context,
|
|
52
|
+
method: 'POST',
|
|
53
|
+
serverFnMeta: {},
|
|
54
|
+
signal: new AbortController().signal,
|
|
55
|
+
next: async (inner: any) => ({ context: { ...context, ...(inner?.context ?? {}) } }),
|
|
56
|
+
});
|
|
57
|
+
context = result.context;
|
|
58
|
+
}
|
|
59
|
+
return fn({ data, context });
|
|
38
60
|
};
|
|
39
61
|
return wrapped;
|
|
40
62
|
},
|
|
41
63
|
};
|
|
42
64
|
return api;
|
|
43
65
|
},
|
|
66
|
+
// auth-context.ts 依赖 createMiddleware({ type: 'function' }).server(fn):
|
|
67
|
+
// mock 产出与真实 middleware 同构的 { options: { server } } 形状,
|
|
68
|
+
// 供上方 handler 包装器执行 server 段注入 context.user
|
|
69
|
+
createMiddleware: (opts: any) => {
|
|
70
|
+
const mw: any = { options: { type: opts?.type } };
|
|
71
|
+
mw.server = (fn: Function) => {
|
|
72
|
+
mw.options.server = fn;
|
|
73
|
+
return mw;
|
|
74
|
+
};
|
|
75
|
+
return mw;
|
|
76
|
+
},
|
|
44
77
|
}));
|
|
45
78
|
|
|
46
79
|
vi.mock("@tanstack/react-start/server", () => ({
|