spine-framework 0.1.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/.framework/README.md +129 -0
- package/.framework/cli/bin.cjs +14 -0
- package/.framework/cli/commands/agents.ts +153 -0
- package/.framework/cli/commands/auth.ts +94 -0
- package/.framework/cli/commands/create-app.ts +185 -0
- package/.framework/cli/commands/dev.ts +295 -0
- package/.framework/cli/commands/doctor.ts +442 -0
- package/.framework/cli/commands/generate.ts +332 -0
- package/.framework/cli/commands/init.ts +272 -0
- package/.framework/cli/commands/install-app.ts +391 -0
- package/.framework/cli/commands/items.ts +253 -0
- package/.framework/cli/commands/migrations.ts +141 -0
- package/.framework/cli/commands/pipelines.ts +166 -0
- package/.framework/cli/commands/status.ts +197 -0
- package/.framework/cli/commands/system.ts +184 -0
- package/.framework/cli/commands/test.ts +227 -0
- package/.framework/cli/commands/uninstall-app.ts +166 -0
- package/.framework/cli/context.ts +268 -0
- package/.framework/cli/env-loader.ts +36 -0
- package/.framework/cli/index.ts +106 -0
- package/.framework/cli/welcome.cjs +45 -0
- package/.framework/docs/API.md +384 -0
- package/.framework/docs/STABILITY.md +52 -0
- package/.framework/docs/admin-routes.md +76 -0
- package/.framework/docs/api-docs-progress.md +38 -0
- package/.framework/docs/api-governance.md +146 -0
- package/.framework/docs/api-testing-results.md +212 -0
- package/.framework/docs/apis/admin-configs.md +567 -0
- package/.framework/docs/apis/admin-data.md +272 -0
- package/.framework/docs/apis/index.md +231 -0
- package/.framework/docs/apis/internal.md +295 -0
- package/.framework/docs/apis/runtime.md +537 -0
- package/.framework/docs/assembly-launch-guide.md +138 -0
- package/.framework/docs/audit-results.md +590 -0
- package/.framework/docs/authorization-model.md +170 -0
- package/.framework/docs/db-api-inventory.md +95 -0
- package/.framework/docs/examples/custom-app/README.md +77 -0
- package/.framework/docs/examples/custom-function/README.md +27 -0
- package/.framework/docs/examples/custom-function/handler.ts +48 -0
- package/.framework/docs/examples/custom-webhook/README.md +68 -0
- package/.framework/docs/gap-remediation-backlog.md +103 -0
- package/.framework/docs/guides/cli-guide.md +224 -0
- package/.framework/docs/guides/getting-started.md +103 -0
- package/.framework/docs/guides/import-guide.md +193 -0
- package/.framework/docs/guides/testing-guide.md +229 -0
- package/.framework/docs/permission-examples.md +326 -0
- package/.framework/docs/ui-adoption-verification.md +111 -0
- package/.framework/docs/ui-api-coverage.md +84 -0
- package/.framework/docs/v2-compatibility-audit.md +228 -0
- package/.framework/functions/.gitkeep +1 -0
- package/.framework/functions/_shared/agent-runner.ts +1097 -0
- package/.framework/functions/_shared/app-manifest.ts +184 -0
- package/.framework/functions/_shared/audit.ts +150 -0
- package/.framework/functions/_shared/db.ts +174 -0
- package/.framework/functions/_shared/index.ts +382 -0
- package/.framework/functions/_shared/middleware.ts +490 -0
- package/.framework/functions/_shared/permissions.ts +1325 -0
- package/.framework/functions/_shared/pipeline-runner.ts +731 -0
- package/.framework/functions/_shared/principal.ts +760 -0
- package/.framework/functions/_shared/schema-utils.ts +967 -0
- package/.framework/functions/_shared/testing.ts +258 -0
- package/.framework/functions/_shared/trigger-engine.ts +425 -0
- package/.framework/functions/_shared/webhook-registration.ts +168 -0
- package/.framework/functions/_shared/webhook-registry.ts +129 -0
- package/.framework/functions/account-nodes.ts +111 -0
- package/.framework/functions/admin-data.ts +606 -0
- package/.framework/functions/ai-agents.ts +323 -0
- package/.framework/functions/api-keys.ts +376 -0
- package/.framework/functions/apps.ts +483 -0
- package/.framework/functions/auth.ts +196 -0
- package/.framework/functions/debug-auth.ts +107 -0
- package/.framework/functions/embeddings.ts +556 -0
- package/.framework/functions/integration-routes.ts +523 -0
- package/.framework/functions/integrations.ts +319 -0
- package/.framework/functions/item-progress.ts +272 -0
- package/.framework/functions/logs.ts +438 -0
- package/.framework/functions/observability.ts +275 -0
- package/.framework/functions/pipeline-executions.ts +494 -0
- package/.framework/functions/pipelines.ts +485 -0
- package/.framework/functions/prompt-configs.ts +339 -0
- package/.framework/functions/roles.ts +387 -0
- package/.framework/functions/system-cron.ts +742 -0
- package/.framework/functions/system.ts +323 -0
- package/.framework/functions/tests.ts +119 -0
- package/.framework/functions/timers.ts +357 -0
- package/.framework/functions/triggers.ts +563 -0
- package/.framework/functions/types.ts +604 -0
- package/.framework/migrations/000_foundation.sql +1256 -0
- package/.framework/migrations/001_seed.sql +92 -0
- package/.framework/migrations/002_seed_constraints.sql +13 -0
- package/.framework/migrations/003_auth_user_trigger.sql +59 -0
- package/.framework/src/App.tsx +126 -0
- package/.framework/src/apps/admin/index.tsx +173 -0
- package/.framework/src/components/AppWrapper.tsx +56 -0
- package/.framework/src/components/CustomAppLoader.tsx +116 -0
- package/.framework/src/components/admin/AdminListPage.tsx +151 -0
- package/.framework/src/components/admin/AdminSidebar.tsx +166 -0
- package/.framework/src/components/admin/AdminStatsCard.tsx +62 -0
- package/.framework/src/components/admin/SortableTableHeader.tsx +42 -0
- package/.framework/src/components/app-shell/GenericAppShell.tsx +181 -0
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +200 -0
- package/.framework/src/components/app-shell/GenericListPage.tsx +116 -0
- package/.framework/src/components/app-sidebar.tsx +228 -0
- package/.framework/src/components/auth/ProtectedRoute.tsx +88 -0
- package/.framework/src/components/layout/AppShell.tsx +91 -0
- package/.framework/src/components/layout/Header.tsx +88 -0
- package/.framework/src/components/layout/Layout.tsx +95 -0
- package/.framework/src/components/layout/Sidebar.tsx +329 -0
- package/.framework/src/components/runtime/DataDetailHeader.tsx +77 -0
- package/.framework/src/components/runtime/DataDetailPage.tsx +171 -0
- package/.framework/src/components/runtime/DataFilters.tsx +91 -0
- package/.framework/src/components/runtime/DataHeader.tsx +68 -0
- package/.framework/src/components/runtime/DataListPage.tsx +124 -0
- package/.framework/src/components/runtime/DataStats.tsx +70 -0
- package/.framework/src/components/runtime/DataTable.tsx +174 -0
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +134 -0
- package/.framework/src/components/runtime/index.ts +18 -0
- package/.framework/src/components/search-form.tsx +29 -0
- package/.framework/src/components/shared/AgentView.tsx +213 -0
- package/.framework/src/components/shared/FieldRenderer.tsx +478 -0
- package/.framework/src/components/shared/SchemaFields.tsx +226 -0
- package/.framework/src/components/ui/DataTable.tsx +343 -0
- package/.framework/src/components/ui/Form.tsx +281 -0
- package/.framework/src/components/ui/ItemCard.tsx +296 -0
- package/.framework/src/components/ui/ItemListView.tsx +308 -0
- package/.framework/src/components/ui/LoadingSpinner.tsx +52 -0
- package/.framework/src/components/ui/Modal.tsx +61 -0
- package/.framework/src/components/ui/RichTextEditor.tsx +210 -0
- package/.framework/src/components/ui/accordion.tsx +82 -0
- package/.framework/src/components/ui/alert-dialog.tsx +197 -0
- package/.framework/src/components/ui/alert.tsx +76 -0
- package/.framework/src/components/ui/aspect-ratio.tsx +11 -0
- package/.framework/src/components/ui/avatar.tsx +110 -0
- package/.framework/src/components/ui/badge.tsx +49 -0
- package/.framework/src/components/ui/breadcrumb.tsx +122 -0
- package/.framework/src/components/ui/button-group.tsx +83 -0
- package/.framework/src/components/ui/button.tsx +65 -0
- package/.framework/src/components/ui/calendar.tsx +222 -0
- package/.framework/src/components/ui/card.tsx +100 -0
- package/.framework/src/components/ui/carousel.tsx +240 -0
- package/.framework/src/components/ui/chart.tsx +373 -0
- package/.framework/src/components/ui/checkbox.tsx +31 -0
- package/.framework/src/components/ui/collapsible.tsx +33 -0
- package/.framework/src/components/ui/combobox.tsx +299 -0
- package/.framework/src/components/ui/command.tsx +193 -0
- package/.framework/src/components/ui/context-menu.tsx +261 -0
- package/.framework/src/components/ui/dialog.tsx +165 -0
- package/.framework/src/components/ui/direction.tsx +22 -0
- package/.framework/src/components/ui/drawer.tsx +132 -0
- package/.framework/src/components/ui/dropdown-menu.tsx +269 -0
- package/.framework/src/components/ui/empty.tsx +104 -0
- package/.framework/src/components/ui/field.tsx +238 -0
- package/.framework/src/components/ui/hover-card.tsx +42 -0
- package/.framework/src/components/ui/input-group.tsx +153 -0
- package/.framework/src/components/ui/input-otp.tsx +87 -0
- package/.framework/src/components/ui/input.tsx +19 -0
- package/.framework/src/components/ui/item.tsx +196 -0
- package/.framework/src/components/ui/kbd.tsx +26 -0
- package/.framework/src/components/ui/label.tsx +22 -0
- package/.framework/src/components/ui/menubar.tsx +277 -0
- package/.framework/src/components/ui/native-select.tsx +61 -0
- package/.framework/src/components/ui/navigation-menu.tsx +164 -0
- package/.framework/src/components/ui/pagination.tsx +129 -0
- package/.framework/src/components/ui/popover.tsx +87 -0
- package/.framework/src/components/ui/progress.tsx +31 -0
- package/.framework/src/components/ui/radio-group.tsx +42 -0
- package/.framework/src/components/ui/resizable.tsx +50 -0
- package/.framework/src/components/ui/scroll-area.tsx +53 -0
- package/.framework/src/components/ui/select.tsx +195 -0
- package/.framework/src/components/ui/separator.tsx +26 -0
- package/.framework/src/components/ui/sheet.tsx +145 -0
- package/.framework/src/components/ui/sidebar.tsx +706 -0
- package/.framework/src/components/ui/skeleton.tsx +13 -0
- package/.framework/src/components/ui/slider.tsx +59 -0
- package/.framework/src/components/ui/sonner.tsx +47 -0
- package/.framework/src/components/ui/spinner.tsx +10 -0
- package/.framework/src/components/ui/switch.tsx +33 -0
- package/.framework/src/components/ui/table-primitives.tsx +141 -0
- package/.framework/src/components/ui/table.tsx +114 -0
- package/.framework/src/components/ui/tabs.tsx +90 -0
- package/.framework/src/components/ui/textarea.tsx +18 -0
- package/.framework/src/components/ui/toggle-group.tsx +89 -0
- package/.framework/src/components/ui/toggle.tsx +45 -0
- package/.framework/src/components/ui/tooltip.tsx +57 -0
- package/.framework/src/contexts/AppContext.tsx +133 -0
- package/.framework/src/contexts/AuthContext.tsx +371 -0
- package/.framework/src/hooks/use-mobile.ts +19 -0
- package/.framework/src/hooks/useApi.ts +526 -0
- package/.framework/src/hooks/useApps.ts +114 -0
- package/.framework/src/hooks/useEntityList.ts +190 -0
- package/.framework/src/hooks/useEntityRecord.ts +308 -0
- package/.framework/src/hooks/useForm.ts +307 -0
- package/.framework/src/hooks/useListSchema.ts +264 -0
- package/.framework/src/hooks/useSchemaRecord.ts +223 -0
- package/.framework/src/index.css +128 -0
- package/.framework/src/lib/api.ts +156 -0
- package/.framework/src/lib/supabase.ts +94 -0
- package/.framework/src/lib/utils.ts +317 -0
- package/.framework/src/main.tsx +27 -0
- package/.framework/src/pages/DashboardPage.tsx +181 -0
- package/.framework/src/pages/NotFoundPage.tsx +39 -0
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +161 -0
- package/.framework/src/pages/admin/AIAgentsPage.tsx +318 -0
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +199 -0
- package/.framework/src/pages/admin/APIKeysPage.tsx +303 -0
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +523 -0
- package/.framework/src/pages/admin/AppDetailPage.tsx +493 -0
- package/.framework/src/pages/admin/AppsPage.tsx +355 -0
- package/.framework/src/pages/admin/DesignedPage.tsx +491 -0
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +534 -0
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +424 -0
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +176 -0
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +109 -0
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +402 -0
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +187 -0
- package/.framework/src/pages/admin/IntegrationsPage.tsx +301 -0
- package/.framework/src/pages/admin/LogsPage.tsx +283 -0
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +85 -0
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +470 -0
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +183 -0
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +279 -0
- package/.framework/src/pages/admin/PipelinesPage.tsx +390 -0
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +299 -0
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +292 -0
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +434 -0
- package/.framework/src/pages/admin/RoleDetailPage.tsx +273 -0
- package/.framework/src/pages/admin/RolesPage.tsx +292 -0
- package/.framework/src/pages/admin/SelectTestPage.tsx +61 -0
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +588 -0
- package/.framework/src/pages/admin/SimpleDashboard.tsx +387 -0
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +172 -0
- package/.framework/src/pages/admin/TestingDashboard.tsx +257 -0
- package/.framework/src/pages/admin/TimerDetailPage.tsx +151 -0
- package/.framework/src/pages/admin/TimersPage.tsx +376 -0
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +149 -0
- package/.framework/src/pages/admin/TriggersPage.tsx +381 -0
- package/.framework/src/pages/admin/TypeDetailPage.tsx +694 -0
- package/.framework/src/pages/admin/TypesPage.tsx +295 -0
- package/.framework/src/pages/auth/LoginPage.tsx +188 -0
- package/.framework/src/pages/auth/RegisterPage.tsx +163 -0
- package/.framework/src/pages/spine-framework/APIPage.tsx +17 -0
- package/.framework/src/pages/spine-framework/CLIPage.tsx +25 -0
- package/.framework/src/types/auth.ts +125 -0
- package/.framework/src/types/types.ts +407 -0
- package/STRUCTURE.md +150 -0
- package/config/components.json +25 -0
- package/config/deno.lock +108 -0
- package/config/package-lock.json +17183 -0
- package/config/postcss.config.cjs +10 -0
- package/config/tailwind.config.cjs +78 -0
- package/config/tsconfig.build.json +32 -0
- package/config/tsconfig.cli.json +18 -0
- package/config/tsconfig.json +41 -0
- package/config/tsconfig.node.json +17 -0
- package/config/tsconfig.node.tsbuildinfo +1 -0
- package/config/tsconfig.tsbuildinfo +1 -0
- package/config/typedoc.json +16 -0
- package/config/vite.config.d.ts +2 -0
- package/config/vite.config.ts +72 -0
- package/dist/cli/commands/agents.d.ts +39 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/auth.d.ts +36 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/create-app.d.ts +23 -0
- package/dist/cli/commands/create-app.d.ts.map +1 -0
- package/dist/cli/commands/dev.d.ts +39 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/doctor.d.ts +42 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/generate.d.ts +36 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/init.d.ts +30 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/install-app.d.ts +30 -0
- package/dist/cli/commands/install-app.d.ts.map +1 -0
- package/dist/cli/commands/items.d.ts +45 -0
- package/dist/cli/commands/items.d.ts.map +1 -0
- package/dist/cli/commands/migrations.d.ts +41 -0
- package/dist/cli/commands/migrations.d.ts.map +1 -0
- package/dist/cli/commands/pipelines.d.ts +40 -0
- package/dist/cli/commands/pipelines.d.ts.map +1 -0
- package/dist/cli/commands/status.d.ts +23 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/system.d.ts +29 -0
- package/dist/cli/commands/system.d.ts.map +1 -0
- package/dist/cli/commands/test.d.ts +46 -0
- package/dist/cli/commands/test.d.ts.map +1 -0
- package/dist/cli/commands/uninstall-app.d.ts +23 -0
- package/dist/cli/commands/uninstall-app.d.ts.map +1 -0
- package/dist/cli/context.d.ts +88 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/env-loader.d.ts +14 -0
- package/dist/cli/env-loader.d.ts.map +1 -0
- package/dist/cli/index.d.ts +41 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/functions/_shared/agent-runner.d.ts +156 -0
- package/dist/functions/_shared/agent-runner.d.ts.map +1 -0
- package/dist/functions/_shared/app-manifest.d.ts +68 -0
- package/dist/functions/_shared/app-manifest.d.ts.map +1 -0
- package/dist/functions/_shared/audit.d.ts +91 -0
- package/dist/functions/_shared/audit.d.ts.map +1 -0
- package/dist/functions/_shared/db.d.ts +125 -0
- package/dist/functions/_shared/db.d.ts.map +1 -0
- package/dist/functions/_shared/index.d.ts +298 -0
- package/dist/functions/_shared/index.d.ts.map +1 -0
- package/dist/functions/_shared/middleware.d.ts +315 -0
- package/dist/functions/_shared/middleware.d.ts.map +1 -0
- package/dist/functions/_shared/permissions.d.ts +626 -0
- package/dist/functions/_shared/permissions.d.ts.map +1 -0
- package/dist/functions/_shared/pipeline-runner.d.ts +124 -0
- package/dist/functions/_shared/pipeline-runner.d.ts.map +1 -0
- package/dist/functions/_shared/principal.d.ts +284 -0
- package/dist/functions/_shared/principal.d.ts.map +1 -0
- package/dist/functions/_shared/schema-utils.d.ts +181 -0
- package/dist/functions/_shared/schema-utils.d.ts.map +1 -0
- package/dist/functions/_shared/testing.d.ts +172 -0
- package/dist/functions/_shared/testing.d.ts.map +1 -0
- package/dist/functions/_shared/trigger-engine.d.ts +140 -0
- package/dist/functions/_shared/trigger-engine.d.ts.map +1 -0
- package/dist/functions/_shared/webhook-registration.d.ts +81 -0
- package/dist/functions/_shared/webhook-registration.d.ts.map +1 -0
- package/dist/functions/_shared/webhook-registry.d.ts +57 -0
- package/dist/functions/_shared/webhook-registry.d.ts.map +1 -0
- package/dist/functions/account-nodes.d.ts +48 -0
- package/dist/functions/account-nodes.d.ts.map +1 -0
- package/dist/functions/admin-data.d.ts +178 -0
- package/dist/functions/admin-data.d.ts.map +1 -0
- package/dist/functions/ai-agents.d.ts +125 -0
- package/dist/functions/ai-agents.d.ts.map +1 -0
- package/dist/functions/api-keys.d.ts +140 -0
- package/dist/functions/api-keys.d.ts.map +1 -0
- package/dist/functions/apps.d.ts +163 -0
- package/dist/functions/apps.d.ts.map +1 -0
- package/dist/functions/auth.d.ts +74 -0
- package/dist/functions/auth.d.ts.map +1 -0
- package/dist/functions/debug-auth.d.ts +33 -0
- package/dist/functions/debug-auth.d.ts.map +1 -0
- package/dist/functions/embeddings.d.ts +205 -0
- package/dist/functions/embeddings.d.ts.map +1 -0
- package/dist/functions/integration-routes.d.ts +45 -0
- package/dist/functions/integration-routes.d.ts.map +1 -0
- package/dist/functions/integrations.d.ts +124 -0
- package/dist/functions/integrations.d.ts.map +1 -0
- package/dist/functions/item-progress.d.ts +41 -0
- package/dist/functions/item-progress.d.ts.map +1 -0
- package/dist/functions/logs.d.ts +162 -0
- package/dist/functions/logs.d.ts.map +1 -0
- package/dist/functions/observability.d.ts +123 -0
- package/dist/functions/observability.d.ts.map +1 -0
- package/dist/functions/pipeline-executions.d.ts +190 -0
- package/dist/functions/pipeline-executions.d.ts.map +1 -0
- package/dist/functions/pipelines.d.ts +171 -0
- package/dist/functions/pipelines.d.ts.map +1 -0
- package/dist/functions/prompt-configs.d.ts +125 -0
- package/dist/functions/prompt-configs.d.ts.map +1 -0
- package/dist/functions/roles.d.ts +118 -0
- package/dist/functions/roles.d.ts.map +1 -0
- package/dist/functions/system-cron.d.ts +65 -0
- package/dist/functions/system-cron.d.ts.map +1 -0
- package/dist/functions/system.d.ts +29 -0
- package/dist/functions/system.d.ts.map +1 -0
- package/dist/functions/tests.d.ts +28 -0
- package/dist/functions/tests.d.ts.map +1 -0
- package/dist/functions/timers.d.ts +139 -0
- package/dist/functions/timers.d.ts.map +1 -0
- package/dist/functions/triggers.d.ts +203 -0
- package/dist/functions/triggers.d.ts.map +1 -0
- package/dist/functions/types.d.ts +151 -0
- package/dist/functions/types.d.ts.map +1 -0
- package/dist/src/types/types.d.ts +364 -0
- package/dist/src/types/types.d.ts.map +1 -0
- package/package.json +192 -0
- package/scripts/app-install-cli.ts +286 -0
- package/scripts/assemble-frontend.sh +79 -0
- package/scripts/assemble-functions.sh +62 -0
- package/scripts/assemble.sh +35 -0
- package/scripts/boundary-check.sh +106 -0
- package/scripts/build-manifest.sh +80 -0
- package/scripts/check-core-integrity.sh +82 -0
- package/scripts/ingest-chunks.cjs +202 -0
- package/scripts/kb-chunk-parser.cjs +312 -0
- package/scripts/kb-chunk-parser.ts +330 -0
- package/scripts/load-test-app-install.ts +484 -0
- package/scripts/netlify-dev-wrapper.sh +22 -0
- package/scripts/verify-integrity.sh +69 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module pipeline-runner
|
|
3
|
+
* @audience both
|
|
4
|
+
* @layer shared-core
|
|
5
|
+
* @stability stable
|
|
6
|
+
*
|
|
7
|
+
* Sequential pipeline execution engine. A pipeline is a named list of stages
|
|
8
|
+
* (`PipelineStage[]`) stored in `pipelines.stages`. Each stage references an
|
|
9
|
+
* `action` record by `stage_type` slug. Stages run sequentially; a failed stage
|
|
10
|
+
* halts execution unless `stage.continue_on_error` is set.
|
|
11
|
+
*
|
|
12
|
+
* Every execution creates a `pipeline_executions` row (status: running →
|
|
13
|
+
* completed | failed) and emits an audit log on completion or failure.
|
|
14
|
+
*
|
|
15
|
+
* Built-in stage handlers (no external config required):
|
|
16
|
+
* - `update_item` — update a record by ID
|
|
17
|
+
* - `create_record` — insert a new record
|
|
18
|
+
* - `http_request` — fetch any HTTP endpoint
|
|
19
|
+
* - `send_notification`— insert watchers notification rows
|
|
20
|
+
* - `run_pipeline` — trigger a nested pipeline (self-recursion blocked)
|
|
21
|
+
* - `search_knowledge` — full-text + fallback search on embeddings table
|
|
22
|
+
* - `query_items` — filtered query on any table
|
|
23
|
+
* - `agent_inference` — call an external LLM webhook or return a mock
|
|
24
|
+
*
|
|
25
|
+
* INVARIANT: `adminDb` (service role) is used for all DB writes — stage
|
|
26
|
+
* execution runs as the pipeline's machine principal, not the end user.
|
|
27
|
+
* INVARIANT: `run_pipeline` handler blocks self-referential execution
|
|
28
|
+
* (`config._pipelineId === pipeline_id`) to prevent infinite loops.
|
|
29
|
+
* INVARIANT: `runPipeline` never throws — failures are captured in the
|
|
30
|
+
* returned `ExecutionResult` with `status: 'failed'`.
|
|
31
|
+
*
|
|
32
|
+
* @seeAlso trigger-engine.ts (calls runPipeline when a trigger fires)
|
|
33
|
+
* @seeAlso agent-runner.ts (calls runPipeline for agentic tool calls)
|
|
34
|
+
* @seeAlso audit.ts (emitAudit called on pipeline.completed / pipeline.failed)
|
|
35
|
+
* @seeAlso index.ts (runPipeline re-exported for v2-custom/ and CLI)
|
|
36
|
+
*/
|
|
37
|
+
import { CoreContext } from './middleware';
|
|
38
|
+
/**
|
|
39
|
+
* Result of a single pipeline stage execution.
|
|
40
|
+
*
|
|
41
|
+
* @outputSpec stageIndex: number — 0-based position in the pipeline's stages array
|
|
42
|
+
* @outputSpec stageType: string — action slug (e.g. 'update_item', 'http_request')
|
|
43
|
+
* @outputSpec status: 'success' | 'failed' | 'skipped'
|
|
44
|
+
* @outputSpec output: any | undefined — handler return value on success
|
|
45
|
+
* @outputSpec error: string | undefined — error message on failure
|
|
46
|
+
* @outputSpec durationMs: number — wall-clock time for this stage
|
|
47
|
+
*/
|
|
48
|
+
export interface StageResult {
|
|
49
|
+
stageIndex: number;
|
|
50
|
+
stageType: string;
|
|
51
|
+
status: 'success' | 'failed' | 'skipped';
|
|
52
|
+
output?: any;
|
|
53
|
+
error?: string;
|
|
54
|
+
durationMs: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Top-level result of a `runPipeline` call. Stored in `pipeline_executions.result`.
|
|
58
|
+
*
|
|
59
|
+
* @outputSpec executionId: string — UUID of the pipeline_executions row
|
|
60
|
+
* @outputSpec pipelineId: string — UUID of the pipeline that was run
|
|
61
|
+
* @outputSpec status: 'completed' | 'failed' | 'cancelled'
|
|
62
|
+
* @outputSpec stages: StageResult[] — per-stage results in execution order
|
|
63
|
+
* @outputSpec durationMs: number — total wall-clock time
|
|
64
|
+
* @outputSpec error: string | undefined — top-level error message on failure
|
|
65
|
+
*/
|
|
66
|
+
export interface ExecutionResult {
|
|
67
|
+
executionId: string;
|
|
68
|
+
pipelineId: string;
|
|
69
|
+
status: 'completed' | 'failed' | 'cancelled';
|
|
70
|
+
stages: StageResult[];
|
|
71
|
+
durationMs: number;
|
|
72
|
+
error?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Executes a pipeline by ID, running its stages sequentially.
|
|
76
|
+
*
|
|
77
|
+
* Execution lifecycle:
|
|
78
|
+
* 1. Load pipeline record (`pipelines` table, `is_active = true`)
|
|
79
|
+
* 2. Insert `pipeline_executions` row with `status: 'running'`
|
|
80
|
+
* 3. For each stage: load action → merge config → call `executeStage`
|
|
81
|
+
* 4. On stage failure: push failed StageResult; stop unless `continue_on_error`
|
|
82
|
+
* 5. Update `pipeline_executions` to `completed` or `failed`
|
|
83
|
+
* 6. Emit `pipeline.completed` or `pipeline.failed` audit log
|
|
84
|
+
* 7. Return `ExecutionResult` (never throws; failures are in result.status)
|
|
85
|
+
*
|
|
86
|
+
* @param pipelineId - UUID of the pipeline to run (must be active)
|
|
87
|
+
* @param triggerData - Arbitrary context passed to each stage as `_triggerData`
|
|
88
|
+
* @param ctx - CoreContext with principal and accountId for audit and stage writes
|
|
89
|
+
* @returns Promise<ExecutionResult> — always resolves; never throws
|
|
90
|
+
* @throws Error('Pipeline not found or inactive') — only if pipeline lookup fails
|
|
91
|
+
* before execution begins (throws before creating the execution row)
|
|
92
|
+
* @throws Error('Failed to create execution') — if execution row insert fails
|
|
93
|
+
* @inputSpec pipelineId: string — valid UUID of a pipeline in pipelines table
|
|
94
|
+
* @inputSpec triggerData: any — JSON-serializable; stored in trigger_data column
|
|
95
|
+
* @inputSpec ctx.accountId: string | null — stamped on execution row
|
|
96
|
+
* @inputSpec ctx.principal.id: string — stamped as created_by on execution row
|
|
97
|
+
* @outputSpec ExecutionResult with status, stages, durationMs
|
|
98
|
+
* @sideEffects DB write: inserts pipeline_executions row; updates it on completion
|
|
99
|
+
* @sideEffects DB write: emitAudit to logs table
|
|
100
|
+
* @calledBy trigger-engine.ts (on trigger fire)
|
|
101
|
+
* @calledBy agent-runner.ts (tool call dispatch)
|
|
102
|
+
* @calledBy stageHandlers.run_pipeline (nested execution)
|
|
103
|
+
* @calledBy v2-custom/ import callers and CLI
|
|
104
|
+
* @calls executeStage, adminDb, emitAudit
|
|
105
|
+
* @testUnit tests/unit/pipeline-runner.test.ts
|
|
106
|
+
* @testIntegration tests/integration/pipeline-runner.test.ts
|
|
107
|
+
*
|
|
108
|
+
* @example API handler trigger
|
|
109
|
+
* ```ts
|
|
110
|
+
* import { runPipeline } from './_shared/index'
|
|
111
|
+
* const result = await runPipeline(body.pipeline_id, body.data, ctx)
|
|
112
|
+
* if (result.status === 'failed') return error(result.error!, 500)
|
|
113
|
+
* return result
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* @example Import usage (v2-custom/)
|
|
117
|
+
* ```ts
|
|
118
|
+
* import { runPipeline, SYSTEM_PRINCIPAL, adminDb, CoreContext } from '../_shared/index'
|
|
119
|
+
* const ctx: CoreContext = { principal: SYSTEM_PRINCIPAL, accountId: MY_ACCOUNT, db: adminDb, requestId: crypto.randomUUID() }
|
|
120
|
+
* const result = await runPipeline('pipeline-uuid', { source: 'import' }, ctx)
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function runPipeline(pipelineId: string, triggerData: any, ctx: CoreContext): Promise<ExecutionResult>;
|
|
124
|
+
//# sourceMappingURL=pipeline-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-runner.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/pipeline-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAS1C;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;IACxC,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAA;IAC5C,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,GAAG,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,eAAe,CAAC,CAgK1B"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module principal
|
|
3
|
+
* @audience both
|
|
4
|
+
* @layer shared-core
|
|
5
|
+
* @stability stable
|
|
6
|
+
*
|
|
7
|
+
* Unified identity abstraction for all actors in Spine v2. Every request —
|
|
8
|
+
* whether from a human via JWT, an integration via API key, a scheduled cron
|
|
9
|
+
* job, or an internal trigger — resolves to a single `Principal` object before
|
|
10
|
+
* any permission check or DB query occurs.
|
|
11
|
+
*
|
|
12
|
+
* Resolution order in `resolvePrincipal`:
|
|
13
|
+
* 1. `x-api-key` header → machine principal (external integration)
|
|
14
|
+
* 2. `x-cron-id` header → machine principal (scheduled job)
|
|
15
|
+
* 3. `x-trigger-id` header → machine principal (event trigger)
|
|
16
|
+
* 4. `Authorization: Bearer <jwt>` → human principal
|
|
17
|
+
* 5. (none) → ANONYMOUS_PRINCIPAL (rejected by createHandler)
|
|
18
|
+
*
|
|
19
|
+
* INVARIANT: `resolvePrincipal` always returns a Principal, never null.
|
|
20
|
+
* ANONYMOUS_PRINCIPAL is the sentinel for unauthenticated requests and is
|
|
21
|
+
* rejected by `createHandler` before the handler runs.
|
|
22
|
+
* INVARIANT: `adminDb` is used for all principal resolution lookups to avoid
|
|
23
|
+
* circular dependencies with RLS (which itself depends on the resolved principal).
|
|
24
|
+
* INVARIANT: never store `authContext.jwt` or `authContext.apiKey` in logs.
|
|
25
|
+
* Use `formatPrincipalForAudit` which strips these fields.
|
|
26
|
+
*
|
|
27
|
+
* @seeAlso db.ts (adminDb, getUserDb — used for resolution and client selection)
|
|
28
|
+
* @seeAlso middleware.ts (createHandler calls resolvePrincipal, getPrincipalDb)
|
|
29
|
+
* @seeAlso permissions.ts (PermissionEngine.isSystemAdmin, canPrincipalAccessRecord)
|
|
30
|
+
* @seeAlso audit.ts (formatPrincipalForAudit — safe audit serialization)
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Unified identity abstraction for all actors in Spine.
|
|
34
|
+
*
|
|
35
|
+
* Every request resolves to a `Principal` before any permission or DB access.
|
|
36
|
+
* The `type` field gates which optional fields are populated:
|
|
37
|
+
* - `'human'` → `roles`, `displayName`, `email`, `authContext.jwt`
|
|
38
|
+
* - `'machine'` → `scopes`, `machineType`, `isInternal`, `authContext.apiKey`
|
|
39
|
+
*
|
|
40
|
+
* The `provenance` object is always populated and is the primary audit trail
|
|
41
|
+
* field. It must not be modified after resolution.
|
|
42
|
+
*
|
|
43
|
+
* @inputSpec none — this is a pure type definition
|
|
44
|
+
* @calledBy middleware.ts (RequestContext.principal), permissions.ts (all methods),
|
|
45
|
+
* audit.ts (formatPrincipalForAudit), tests/integration/helpers.ts (makeTestCtx)
|
|
46
|
+
*/
|
|
47
|
+
export interface Principal {
|
|
48
|
+
/** Unique identifier — person UUID (human) or machine principal UUID (machine) */
|
|
49
|
+
id: string;
|
|
50
|
+
/** Actor type — gates which optional fields are populated */
|
|
51
|
+
type: 'human' | 'machine';
|
|
52
|
+
/** Primary account context; null for internal system principals */
|
|
53
|
+
accountId: string | null;
|
|
54
|
+
/** Role slugs from people.role_id → roles.slug; used by PermissionEngine */
|
|
55
|
+
roles?: string[];
|
|
56
|
+
/** Display name from people.display_name or people.email */
|
|
57
|
+
displayName?: string;
|
|
58
|
+
/** Email address from people.email or Supabase auth user */
|
|
59
|
+
email?: string;
|
|
60
|
+
/** Explicit permission grants (e.g., ['items:read', 'people:write', '*:*']) */
|
|
61
|
+
scopes?: string[];
|
|
62
|
+
/** Machine classification — determines UI visibility and default scopes */
|
|
63
|
+
machineType?: 'integration' | 'service_account' | 'internal' | 'timer';
|
|
64
|
+
/** Internal machines (cron, trigger, pipeline) are hidden from the UI */
|
|
65
|
+
isInternal?: boolean;
|
|
66
|
+
provenance: {
|
|
67
|
+
/** How this principal was authenticated */
|
|
68
|
+
sourceType: 'jwt' | 'api_key' | 'cron' | 'trigger' | 'manual' | 'webhook' | 'timer';
|
|
69
|
+
/** Person who authorized this principal (may be self for humans) */
|
|
70
|
+
createdBy: string | null;
|
|
71
|
+
/** Chain ID for trigger/pipeline sequences */
|
|
72
|
+
parentExecutionId?: string;
|
|
73
|
+
/** When this principal context was created */
|
|
74
|
+
invokedAt: string;
|
|
75
|
+
/** API key ID (for api_key source) */
|
|
76
|
+
apiKeyId?: string;
|
|
77
|
+
/** Schedule ID (for cron source) */
|
|
78
|
+
cronId?: string;
|
|
79
|
+
/** Trigger ID (for trigger source) */
|
|
80
|
+
triggerId?: string;
|
|
81
|
+
/** Timer ID (for timer source) */
|
|
82
|
+
timerId?: string;
|
|
83
|
+
/** Event ID that triggered this execution */
|
|
84
|
+
eventId?: string;
|
|
85
|
+
/** IP address of the requester */
|
|
86
|
+
ipAddress?: string;
|
|
87
|
+
/** User agent string */
|
|
88
|
+
userAgent?: string;
|
|
89
|
+
};
|
|
90
|
+
authContext?: {
|
|
91
|
+
/** JWT token for human-scoped DB client */
|
|
92
|
+
jwt?: string;
|
|
93
|
+
/** API key value for machine verification */
|
|
94
|
+
apiKey?: string;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Sentinel principal for unauthenticated requests.
|
|
99
|
+
*
|
|
100
|
+
* Returned by `resolvePrincipal` when no auth header is present. `createHandler`
|
|
101
|
+
* checks for `principal.id === 'anonymous'` and rejects the request with 401.
|
|
102
|
+
* Never use this principal for any DB access — it has no scopes or accountId.
|
|
103
|
+
*
|
|
104
|
+
* @stability stable
|
|
105
|
+
* @calledBy resolvePrincipal (returned when no auth header is present)
|
|
106
|
+
* @calledBy middleware.ts, requireUserContext, requireSystemContextWithAudit (checked against)
|
|
107
|
+
* @calledBy permissions.ts (all surface methods check for 'anonymous' and deny)
|
|
108
|
+
*/
|
|
109
|
+
export declare const ANONYMOUS_PRINCIPAL: Principal;
|
|
110
|
+
/**
|
|
111
|
+
* System principal for internal Spine operations (cron, pipeline runner, trigger engine).
|
|
112
|
+
*
|
|
113
|
+
* Has `'*:*'` scope (all resources, all actions) and `isInternal: true`. When
|
|
114
|
+
* a `CoreContext` is constructed for a system operation (e.g. in v2-custom/ or
|
|
115
|
+
* the CLI), use `SYSTEM_PRINCIPAL` as the principal and `adminDb` as the db.
|
|
116
|
+
*
|
|
117
|
+
* Never expose this principal in an HTTP response or log the `authContext` field.
|
|
118
|
+
*
|
|
119
|
+
* @stability stable
|
|
120
|
+
* @calledBy tests/integration/helpers.ts (makeTestCtx)
|
|
121
|
+
* @calledBy CLI context construction
|
|
122
|
+
* @calledBy v2-custom/ system-level import callers
|
|
123
|
+
*
|
|
124
|
+
* @example Import usage (v2-custom/)
|
|
125
|
+
* ```ts
|
|
126
|
+
* import { CoreContext, SYSTEM_PRINCIPAL, adminDb } from '../_shared/index'
|
|
127
|
+
* const ctx: CoreContext = {
|
|
128
|
+
* principal: SYSTEM_PRINCIPAL,
|
|
129
|
+
* accountId: MY_ACCOUNT_ID,
|
|
130
|
+
* db: adminDb,
|
|
131
|
+
* requestId: crypto.randomUUID()
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export declare const SYSTEM_PRINCIPAL: Principal;
|
|
136
|
+
/**
|
|
137
|
+
* Main entry point for principal resolution. Called by `createHandler` on every
|
|
138
|
+
* HTTP request before the handler runs.
|
|
139
|
+
*
|
|
140
|
+
* Examines request headers in priority order and delegates to the appropriate
|
|
141
|
+
* resolver. Always returns a `Principal` — never throws for missing auth
|
|
142
|
+
* (returns `ANONYMOUS_PRINCIPAL` instead). Throws only on invalid/expired
|
|
143
|
+
* credentials (invalid API key, expired JWT, etc.).
|
|
144
|
+
*
|
|
145
|
+
* Resolution order:
|
|
146
|
+
* 1. `x-api-key` / `X-Api-Key` header → `resolveMachinePrincipal`
|
|
147
|
+
* 2. `x-cron-id` / `X-Cron-Id` header → `resolveCronPrincipal`
|
|
148
|
+
* 3. `x-trigger-id` / `X-Trigger-Id` header → `resolveTriggerPrincipal`
|
|
149
|
+
* 4. `Authorization: Bearer <jwt>` → `resolveHumanPrincipal`
|
|
150
|
+
* 5. (none matched) → `ANONYMOUS_PRINCIPAL`
|
|
151
|
+
*
|
|
152
|
+
* @param event - Raw Netlify event object with `headers` and optional `body`
|
|
153
|
+
* @returns Promise<Principal> — always resolves; throws on invalid credentials
|
|
154
|
+
* @throws Error — on invalid API key, invalid JWT, or missing DB records
|
|
155
|
+
* @inputSpec event.headers: Record<string, string> — HTTP request headers
|
|
156
|
+
* @outputSpec Principal — fully resolved principal with provenance populated
|
|
157
|
+
* @sideEffects DB reads: api_keys, schedules, triggers, people tables via sub-resolvers
|
|
158
|
+
* @calledBy middleware.ts (createHandler) — once per HTTP request
|
|
159
|
+
* @calls resolveMachinePrincipal | resolveCronPrincipal | resolveTriggerPrincipal |
|
|
160
|
+
* resolveHumanPrincipal
|
|
161
|
+
* @testUnit tests/unit/principal.test.ts — 'resolvePrincipal' describe block
|
|
162
|
+
* @testIntegration tests/integration/auth.test.ts
|
|
163
|
+
*/
|
|
164
|
+
export declare function resolvePrincipal(event: any): Promise<Principal>;
|
|
165
|
+
/**
|
|
166
|
+
* Checks whether a machine principal has been granted a specific scope.
|
|
167
|
+
*
|
|
168
|
+
* Scope matching supports three patterns:
|
|
169
|
+
* 1. Exact: `'items:read'` matches only `'items:read'`
|
|
170
|
+
* 2. Wildcard action: `'items:*'` matches `'items:read'`, `'items:write'`, etc.
|
|
171
|
+
* 3. Global wildcard: `'*:*'` matches any scope
|
|
172
|
+
*
|
|
173
|
+
* Returns `false` for non-machine principals — role-based checks use `humanHasRole`.
|
|
174
|
+
*
|
|
175
|
+
* @param principal - The principal to check
|
|
176
|
+
* @param scope - The required scope string in `'resource:action'` format
|
|
177
|
+
* @returns boolean — true if any of the principal's scopes grant the required scope
|
|
178
|
+
* @throws never
|
|
179
|
+
* @inputSpec principal.type: 'machine' — returns false for human principals
|
|
180
|
+
* @inputSpec scope: string — must be in 'resource:action' format
|
|
181
|
+
* @inputSpec principal.scopes: string[] — list of granted scope strings
|
|
182
|
+
* @outputSpec boolean
|
|
183
|
+
* @sideEffects none
|
|
184
|
+
* @calledBy permissions.ts (checkMachineScope), any custom code doing scope checks
|
|
185
|
+
* @testUnit tests/unit/principal.test.ts — 'machineHasScope' describe block
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* import { machineHasScope } from '../_shared/index'
|
|
190
|
+
* if (!machineHasScope(principal, 'items:write')) {
|
|
191
|
+
* return { error: 'Insufficient scope' }
|
|
192
|
+
* }
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
export declare function machineHasScope(principal: Principal, scope: string): boolean;
|
|
196
|
+
/**
|
|
197
|
+
* Checks whether a human principal has been assigned a specific role.
|
|
198
|
+
*
|
|
199
|
+
* Returns `false` for non-human (machine) principals — scope checks use
|
|
200
|
+
* `machineHasScope`. Role slugs come from `people.role_id → roles.slug`
|
|
201
|
+
* and are loaded at resolution time in `resolveHumanPrincipal`.
|
|
202
|
+
*
|
|
203
|
+
* @param principal - The principal to check
|
|
204
|
+
* @param roleSlug - The role slug to look for (e.g. 'system_admin', 'agent')
|
|
205
|
+
* @returns boolean — true if principal.roles includes the given slug
|
|
206
|
+
* @throws never
|
|
207
|
+
* @inputSpec principal.type: 'human' — returns false for machine principals
|
|
208
|
+
* @inputSpec roleSlug: string — must match exactly (case-sensitive)
|
|
209
|
+
* @inputSpec principal.roles: string[] | undefined
|
|
210
|
+
* @outputSpec boolean
|
|
211
|
+
* @sideEffects none
|
|
212
|
+
* @calledBy isSystemAdmin, permissions.ts (PermissionEngine.isSystemAdmin)
|
|
213
|
+
* @testUnit tests/unit/principal.test.ts — 'humanHasRole' describe block
|
|
214
|
+
*/
|
|
215
|
+
export declare function humanHasRole(principal: Principal, roleSlug: string): boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Returns true if the principal holds the `system_admin` role.
|
|
218
|
+
*
|
|
219
|
+
* This is the canonical system admin check used by `middleware.ts`
|
|
220
|
+
* (`requireSystemContextWithAudit`) and re-exported from `permissions.ts`
|
|
221
|
+
* (`PermissionEngine.isSystemAdmin`). system_admin bypasses all three
|
|
222
|
+
* permission surfaces.
|
|
223
|
+
*
|
|
224
|
+
* @param principal - The principal to check
|
|
225
|
+
* @returns boolean — true only if type='human' and roles includes 'system_admin'
|
|
226
|
+
* @throws never
|
|
227
|
+
* @inputSpec principal: Principal — any resolved principal
|
|
228
|
+
* @outputSpec boolean — false for machine principals, anonymous, or missing roles
|
|
229
|
+
* @sideEffects none
|
|
230
|
+
* @calledBy middleware.ts (requireSystemContextWithAudit), permissions.ts (PermissionEngine),
|
|
231
|
+
* any handler doing system-admin-only checks
|
|
232
|
+
* @calls humanHasRole
|
|
233
|
+
* @testUnit tests/unit/principal.test.ts — 'isSystemAdmin' describe block
|
|
234
|
+
*/
|
|
235
|
+
export declare function isSystemAdmin(principal: Principal): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Selects the correct Supabase database client for the given principal.
|
|
238
|
+
*
|
|
239
|
+
* This is the only place in the codebase where the two-client selection
|
|
240
|
+
* decision is made. The result is stored in `ctx.db` and used for all
|
|
241
|
+
* subsequent DB queries in the request.
|
|
242
|
+
*
|
|
243
|
+
* Selection logic:
|
|
244
|
+
* - Human principal with JWT → `getUserDb(jwt)` — enforces RLS
|
|
245
|
+
* - Machine principal → `adminDb` — RLS policies check machine ID in policies
|
|
246
|
+
* - Anonymous → `adminDb` (but anonymous requests are rejected before DB access)
|
|
247
|
+
*
|
|
248
|
+
* @param principal - The resolved principal
|
|
249
|
+
* @returns SupabaseClient — RLS-scoped for humans, admin for machines
|
|
250
|
+
* @throws never
|
|
251
|
+
* @inputSpec principal.type: 'human' | 'machine'
|
|
252
|
+
* @inputSpec principal.authContext.jwt: string | undefined — required for human client
|
|
253
|
+
* @outputSpec SupabaseClient — getUserDb result (human) or adminDb (machine)
|
|
254
|
+
* @sideEffects none (client construction only)
|
|
255
|
+
* @calledBy middleware.ts (createHandler — `const ctxDb = getPrincipalDb(principal)`)
|
|
256
|
+
* @calls getUserDb (db.ts), adminDb (db.ts)
|
|
257
|
+
* @testUnit tests/unit/principal.test.ts — 'getPrincipalDb' describe block
|
|
258
|
+
*/
|
|
259
|
+
export declare function getPrincipalDb(principal: Principal): import("@supabase/supabase-js").SupabaseClient<any, "public", string, any, any>;
|
|
260
|
+
/**
|
|
261
|
+
* Serializes a principal into a safe, structured object for audit log entries.
|
|
262
|
+
*
|
|
263
|
+
* Strips `authContext` entirely (never log JWT or API key values). The returned
|
|
264
|
+
* object is safe to store in the `metadata` JSONB column of the `logs` table.
|
|
265
|
+
*
|
|
266
|
+
* @param principal - Any resolved principal including ANONYMOUS_PRINCIPAL
|
|
267
|
+
* @returns object — audit-safe principal summary
|
|
268
|
+
* @throws never
|
|
269
|
+
* @inputSpec principal: Principal — any resolved principal
|
|
270
|
+
* @outputSpec { id, type, account_id } + role/scope fields depending on type
|
|
271
|
+
* @outputSpec authContext is NEVER included in output
|
|
272
|
+
* @sideEffects none
|
|
273
|
+
* @calledBy audit.ts (emitAudit — in metadata.principal)
|
|
274
|
+
* @testUnit tests/unit/principal.test.ts — 'formatPrincipalForAudit' describe block
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```ts
|
|
278
|
+
* await emitAudit(ctx, 'items.delete', { type: 'item', id }, {
|
|
279
|
+
* principal_snapshot: formatPrincipalForAudit(ctx.principal)
|
|
280
|
+
* })
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
export declare function formatPrincipalForAudit(principal: Principal): object;
|
|
284
|
+
//# sourceMappingURL=principal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principal.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/principal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAwBH;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,SAAS;IACxB,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAA;IAEV,6DAA6D;IAC7D,IAAI,EAAE,OAAO,GAAG,SAAS,CAAA;IAEzB,mEAAmE;IACnE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAGxB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAEhB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAA;IAGd,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IAEjB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,aAAa,GAAG,iBAAiB,GAAG,UAAU,GAAG,OAAO,CAAA;IAEtE,yEAAyE;IACzE,UAAU,CAAC,EAAE,OAAO,CAAA;IAGpB,UAAU,EAAE;QACV,2CAA2C;QAC3C,UAAU,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAA;QAEnF,oEAAoE;QACpE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;QAExB,8CAA8C;QAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAE1B,8CAA8C;QAC9C,SAAS,EAAE,MAAM,CAAA;QAGjB,sCAAsC;QACtC,QAAQ,CAAC,EAAE,MAAM,CAAA;QAEjB,oCAAoC;QACpC,MAAM,CAAC,EAAE,MAAM,CAAA;QAEf,sCAAsC;QACtC,SAAS,CAAC,EAAE,MAAM,CAAA;QAElB,kCAAkC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAA;QAEhB,6CAA6C;QAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;QAEhB,kCAAkC;QAClC,SAAS,CAAC,EAAE,MAAM,CAAA;QAElB,wBAAwB;QACxB,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,CAAA;IAKD,WAAW,CAAC,EAAE;QACZ,2CAA2C;QAC3C,GAAG,CAAC,EAAE,MAAM,CAAA;QAEZ,6CAA6C;QAC7C,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF;AAID;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAUjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAY9B,CAAA;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CA2BrE;AAmUD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAgB5E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG5E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAE3D;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,mFAOlD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAgBpE"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module schema-utils
|
|
3
|
+
* @audience both
|
|
4
|
+
* @layer shared-core
|
|
5
|
+
* @stability stable
|
|
6
|
+
*
|
|
7
|
+
* Schema generation and field-level data transformation for all Spine types.
|
|
8
|
+
*
|
|
9
|
+
* Three public functions form the core contract:
|
|
10
|
+
* - `generateValidationSchema` — derives a runtime validation schema from a
|
|
11
|
+
* `design_schema`, stripping display/permission info and keeping only
|
|
12
|
+
* structural constraints.
|
|
13
|
+
* - `sanitizeFieldData` — coerces and validates a single field value for
|
|
14
|
+
* write (create/update) operations. Throws on invalid data.
|
|
15
|
+
* - `formatFieldData` — converts a stored field value to a human-readable
|
|
16
|
+
* display string for read operations. Never throws.
|
|
17
|
+
* - `transformRecordData` — applies sanitize or format to all fields in a
|
|
18
|
+
* record using a pre-generated ValidationSchema.
|
|
19
|
+
*
|
|
20
|
+
* These are called by `permissions.ts` (`validateFirstSurfaceUpdatePermissions`
|
|
21
|
+
* and `sanitizeFirstSurfaceRecordData`) — do not call them directly from API
|
|
22
|
+
* handlers. Use `PermissionEngine.sanitizeRecordData` / `validateUpdatePermissions`.
|
|
23
|
+
*
|
|
24
|
+
* INVARIANT: all sanitize functions throw on invalid data. Callers must catch
|
|
25
|
+
* errors and convert them to field-level validation error messages.
|
|
26
|
+
* INVARIANT: all format functions return the raw data unchanged if formatting
|
|
27
|
+
* is not applicable (never throw, never return null for non-null input).
|
|
28
|
+
*
|
|
29
|
+
* @seeAlso permissions.ts (primary caller of sanitizeFieldData, formatFieldData)
|
|
30
|
+
* @seeAlso src/types/types.ts (FieldDefinition interface)
|
|
31
|
+
* @seeAlso index.ts (not re-exported — internal to core; use PermissionEngine)
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Structural-only validation schema derived from a `design_schema`.
|
|
35
|
+
*
|
|
36
|
+
* Contains one entry per field with the field's `data_type` and any explicit
|
|
37
|
+
* `validation` constraints. Display properties (`display_type`, views, sections)
|
|
38
|
+
* and permission properties are stripped. Used as input to `sanitizeFieldData`
|
|
39
|
+
* and `formatFieldData`.
|
|
40
|
+
*
|
|
41
|
+
* @inputSpec none — output type of generateValidationSchema
|
|
42
|
+
* @outputSpec fields: Record<fieldName, { data_type, required?, ...constraints }>
|
|
43
|
+
* @calledBy generateValidationSchema (producer), transformRecordData,
|
|
44
|
+
* permissions.ts validateFirstSurfaceUpdatePermissions (consumer)
|
|
45
|
+
*/
|
|
46
|
+
export interface ValidationSchema {
|
|
47
|
+
fields: Record<string, {
|
|
48
|
+
data_type: string;
|
|
49
|
+
required?: boolean;
|
|
50
|
+
[key: string]: any;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Derives a `ValidationSchema` from a `design_schema` by extracting only
|
|
55
|
+
* structural constraints (data_type, required, validation.*) and discarding
|
|
56
|
+
* display, permission, and view configuration.
|
|
57
|
+
*
|
|
58
|
+
* The resulting schema is used to drive `sanitizeFieldData` and
|
|
59
|
+
* `formatFieldData` for every field in a record. It is generated once per
|
|
60
|
+
* type and passed to `transformRecordData` for bulk field processing.
|
|
61
|
+
*
|
|
62
|
+
* @param designSchema - The full design_schema object from a type record
|
|
63
|
+
* @returns ValidationSchema with one entry per field
|
|
64
|
+
* @throws never — returns empty schema if designSchema.fields is missing
|
|
65
|
+
* @inputSpec designSchema.fields: Record<fieldName, FieldDefinition> — must match
|
|
66
|
+
* the FieldDefinition interface from src/types/types.ts
|
|
67
|
+
* @inputSpec designSchema.fields[x].data_type: string — required in every field
|
|
68
|
+
* @outputSpec ValidationSchema.fields: Record<string, { data_type, required, ...constraints }>
|
|
69
|
+
* @sideEffects none
|
|
70
|
+
* @calledBy permissions.ts (validateFirstSurfaceUpdatePermissions), any caller
|
|
71
|
+
* needing a validation schema without the full design_schema overhead
|
|
72
|
+
* @testUnit tests/unit/schema-utils.test.ts — 'generateValidationSchema' describe block
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const schema = generateValidationSchema(record.design_schema)
|
|
77
|
+
* const cleaned = transformRecordData(record.data, schema, 'sanitize')
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function generateValidationSchema(designSchema: any): ValidationSchema;
|
|
81
|
+
/**
|
|
82
|
+
* Coerces and validates a single field value for a write (create/update) operation.
|
|
83
|
+
*
|
|
84
|
+
* Dispatches to a type-specific sanitizer based on `data_type`. Every sanitizer:
|
|
85
|
+
* - Coerces the input to the correct type
|
|
86
|
+
* - Applies constraint validation (min/max/length/pattern/options)
|
|
87
|
+
* - Throws a descriptive `Error` on the first validation failure
|
|
88
|
+
* - Returns the cleaned value on success
|
|
89
|
+
*
|
|
90
|
+
* Unknown `data_type` values pass through unchanged (no throw).
|
|
91
|
+
*
|
|
92
|
+
* @param data - Raw field value from the request body
|
|
93
|
+
* @param data_type - The field's declared data_type from design_schema.fields[x]
|
|
94
|
+
* @param validation - Optional validation constraints from the field definition
|
|
95
|
+
* @returns Sanitized value in the correct type for storage
|
|
96
|
+
* @throws Error — descriptive message naming the field constraint violated
|
|
97
|
+
* @inputSpec data: any — null and undefined are returned as-is without sanitization
|
|
98
|
+
* @inputSpec data_type: string — one of the 21 supported type keys (see switch below)
|
|
99
|
+
* @inputSpec validation: object | undefined — type-specific constraints
|
|
100
|
+
* @outputSpec any — coerced value matching the data_type storage format
|
|
101
|
+
* @sideEffects none
|
|
102
|
+
* @calledBy permissions.ts (validateFirstSurfaceUpdatePermissions, per-field loop)
|
|
103
|
+
* @calls sanitizeText | sanitizeTextarea | sanitizeEmail | sanitizeNumber | etc.
|
|
104
|
+
* @testUnit tests/unit/schema-utils.test.ts — 'sanitizeFieldData' describe block
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* const clean = sanitizeFieldData('hello@EXAMPLE.COM', 'email')
|
|
109
|
+
* // → 'hello@example.com'
|
|
110
|
+
*
|
|
111
|
+
* sanitizeFieldData('not-a-url', 'url')
|
|
112
|
+
* // throws Error('Invalid URL format')
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export declare function sanitizeFieldData(data: any, data_type: string, validation?: any): any;
|
|
116
|
+
/**
|
|
117
|
+
* Converts a stored field value to a human-readable display string.
|
|
118
|
+
*
|
|
119
|
+
* Dispatches to a type-specific formatter based on `data_type`. Formatters
|
|
120
|
+
* never throw — if the data cannot be formatted, the raw value is returned.
|
|
121
|
+
* Only types with meaningful display transformations have a case; all others
|
|
122
|
+
* fall through to the default (return data unchanged).
|
|
123
|
+
*
|
|
124
|
+
* @param data - Stored field value (from DB, post-sanitization)
|
|
125
|
+
* @param data_type - The field's declared data_type
|
|
126
|
+
* @param context - Optional context for type-specific formatting (e.g.
|
|
127
|
+
* `context.currency_code` for currency fields, `context.field` for boolean
|
|
128
|
+
* contextual labels like 'Active'/'Inactive')
|
|
129
|
+
* @returns Formatted display value
|
|
130
|
+
* @throws never
|
|
131
|
+
* @inputSpec data: any — null and undefined are returned as-is
|
|
132
|
+
* @inputSpec data_type: string — one of 21 supported keys; unknown → pass-through
|
|
133
|
+
* @inputSpec context: object | undefined — type-specific display hints
|
|
134
|
+
* @outputSpec any — display-ready value; string for most types, raw data for pass-through
|
|
135
|
+
* @sideEffects none
|
|
136
|
+
* @calledBy permissions.ts (sanitizeFirstSurfaceRecordData, per-field loop)
|
|
137
|
+
* @calls formatJson | formatDate | formatDatetime | formatCurrency | etc.
|
|
138
|
+
* @testUnit tests/unit/schema-utils.test.ts — 'formatFieldData' describe block
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* formatFieldData('2024-01-15', 'date')
|
|
143
|
+
* // → 'January 15, 2024'
|
|
144
|
+
*
|
|
145
|
+
* formatFieldData(1234.5, 'currency', { currency_code: 'USD' })
|
|
146
|
+
* // → '$1,234.50'
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
export declare function formatFieldData(data: any, data_type: string, context?: any): any;
|
|
150
|
+
/**
|
|
151
|
+
* Applies `sanitizeFieldData` or `formatFieldData` to all fields in a record,
|
|
152
|
+
* using the ValidationSchema for per-field type and constraint information.
|
|
153
|
+
*
|
|
154
|
+
* Fields not present in the schema are passed through unchanged. This is
|
|
155
|
+
* intentional — unknown fields are not rejected here; the PermissionEngine
|
|
156
|
+
* handles field-level access control separately.
|
|
157
|
+
*
|
|
158
|
+
* @param data - Key/value record of field names to raw or stored values
|
|
159
|
+
* @param validationSchema - Schema from `generateValidationSchema`
|
|
160
|
+
* @param operation - 'sanitize' for write path; 'format' for display path
|
|
161
|
+
* @param context - Optional context passed through to formatFieldData
|
|
162
|
+
* @returns Transformed record with the same keys
|
|
163
|
+
* @throws Error (sanitize mode only) — if any field fails validation
|
|
164
|
+
* @inputSpec data: Record<string, any> — flat field map
|
|
165
|
+
* @inputSpec validationSchema: ValidationSchema — from generateValidationSchema
|
|
166
|
+
* @inputSpec operation: 'sanitize' | 'format'
|
|
167
|
+
* @outputSpec Record<string, any> — same keys, transformed values
|
|
168
|
+
* @sideEffects none
|
|
169
|
+
* @calledBy Custom code in v2-custom/ that needs bulk field transformation
|
|
170
|
+
* @calls sanitizeFieldData | formatFieldData (per field)
|
|
171
|
+
* @testUnit tests/unit/schema-utils.test.ts — 'transformRecordData' describe block
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* const schema = generateValidationSchema(type.design_schema)
|
|
176
|
+
* const sanitized = transformRecordData(body.data, schema, 'sanitize')
|
|
177
|
+
* const formatted = transformRecordData(record.data, schema, 'format', ctx)
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
export declare function transformRecordData(data: Record<string, any>, validationSchema: ValidationSchema, operation: 'sanitize' | 'format', context?: any): Record<string, any>;
|
|
181
|
+
//# sourceMappingURL=schema-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-utils.d.ts","sourceRoot":"","sources":["../../../.framework/functions/_shared/schema-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAMH;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QACrB,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KACnB,CAAC,CAAA;CACH;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,GAAG,GAAG,gBAAgB,CAsC5E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,GAAG,EACT,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,GAAG,GACf,GAAG,CAqDL;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,GAAG,EACT,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,GAAG,GACZ,GAAG,CA6BL;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,UAAU,GAAG,QAAQ,EAChC,OAAO,CAAC,EAAE,GAAG,GACZ,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA4BrB"}
|