okengine 0.18.5 → 0.19.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/AGENTS.md +18 -10
- package/README.md +2 -2
- package/package.json +51 -50
- package/site/content/docs/ai/llms-txt.mdx +1 -1
- package/site/content/docs/ai/meta.json +1 -1
- package/site/content/docs/ai/skills.mdx +4 -1
- package/site/content/docs/ai/try-it.mdx +58 -0
- package/site/content/docs/client/auth.mdx +208 -0
- package/site/content/docs/client/calling.mdx +451 -0
- package/site/content/docs/client/index.mdx +209 -0
- package/site/content/docs/client/live.mdx +234 -0
- package/site/content/docs/client/meta.json +5 -0
- package/site/content/docs/client/react.mdx +249 -0
- package/site/content/docs/elements/ai/agents.mdx +232 -0
- package/site/content/docs/elements/ai/index.mdx +341 -0
- package/site/content/docs/elements/ai/mcp.mdx +275 -0
- package/site/content/docs/elements/ai/meta.json +5 -0
- package/site/content/docs/elements/ai/models.mdx +283 -0
- package/site/content/docs/elements/ai/prompts.mdx +256 -0
- package/site/content/docs/elements/channel/email.mdx +266 -0
- package/site/content/docs/elements/channel/index.mdx +344 -0
- package/site/content/docs/elements/channel/meta.json +5 -0
- package/site/content/docs/elements/channel/push.mdx +218 -0
- package/site/content/docs/elements/channel/receipts.mdx +206 -0
- package/site/content/docs/elements/channel/sms.mdx +264 -0
- package/site/content/docs/elements/channel/whatsapp.mdx +220 -0
- package/site/content/docs/elements/clock/index.mdx +300 -0
- package/site/content/docs/elements/clock/meta.json +5 -0
- package/site/content/docs/elements/clock/schedules.mdx +508 -0
- package/site/content/docs/elements/clock/sleep.mdx +445 -0
- package/site/content/docs/elements/flow/consumers.mdx +707 -0
- package/site/content/docs/elements/flow/http.mdx +1080 -0
- package/site/content/docs/elements/flow/index.mdx +618 -0
- package/site/content/docs/elements/flow/meta.json +5 -0
- package/site/content/docs/elements/flow/routing.mdx +559 -0
- package/site/content/docs/elements/flow/workflows.mdx +640 -0
- package/site/content/docs/elements/gate/auth.mdx +371 -0
- package/site/content/docs/elements/gate/authorization.mdx +298 -0
- package/site/content/docs/elements/gate/index.mdx +418 -0
- package/site/content/docs/elements/gate/meta.json +5 -0
- package/site/content/docs/elements/gate/rate-limits.mdx +365 -0
- package/site/content/docs/elements/gate/rls.mdx +303 -0
- package/site/content/docs/elements/gate/tenancy.mdx +372 -0
- package/site/content/docs/elements/index.mdx +20 -10
- package/site/content/docs/elements/signal/broadcast.mdx +517 -0
- package/site/content/docs/elements/signal/index.mdx +352 -0
- package/site/content/docs/elements/signal/live.mdx +590 -0
- package/site/content/docs/elements/signal/meta.json +5 -0
- package/site/content/docs/elements/signal/once.mdx +596 -0
- package/site/content/docs/elements/store/files.mdx +659 -0
- package/site/content/docs/elements/store/index.mdx +310 -0
- package/site/content/docs/elements/store/kv.mdx +629 -0
- package/site/content/docs/elements/store/meta.json +5 -0
- package/site/content/docs/elements/store/search.mdx +946 -0
- package/site/content/docs/elements/store/sql.mdx +937 -0
- package/site/content/docs/elements/vault/config.mdx +256 -0
- package/site/content/docs/elements/vault/index.mdx +356 -0
- package/site/content/docs/elements/vault/meta.json +5 -0
- package/site/content/docs/elements/vault/rotation.mdx +273 -0
- package/site/content/docs/elements/vault/secrets.mdx +285 -0
- package/site/content/docs/index.mdx +63 -36
- package/site/content/docs/meta.json +8 -7
- package/site/content/docs/plugins/cors.mdx +2 -1
- package/site/content/docs/plugins/csrf.mdx +4 -1
- package/site/content/docs/plugins/headers.mdx +2 -1
- package/site/content/docs/plugins/ip-allowlist.mdx +2 -1
- package/site/content/docs/plugins/magic-link.mdx +6 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +2 -1
- package/site/content/docs/plugins/oauth.mdx +1 -1
- package/site/content/docs/plugins/otp.mdx +12 -1
- package/site/content/docs/plugins/passkey.mdx +39 -15
- package/site/content/docs/plugins/two-factor.mdx +91 -34
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +3 -3
- package/site/content/docs/recipes/index.mdx +18 -28
- package/site/content/docs/recipes/mailpit.mdx +1 -1
- package/site/content/docs/recipes/meilisearch.mdx +3 -3
- package/site/content/docs/recipes/meta.json +1 -4
- package/site/content/docs/recipes/nginx.mdx +2 -2
- package/site/content/docs/recipes/openrouter.mdx +283 -0
- package/site/content/docs/recipes/pgdog.mdx +3 -3
- package/site/content/docs/recipes/postgres.mdx +1 -2
- package/site/content/docs/recipes/rustfs.mdx +2 -2
- package/site/content/docs/recipes/traefik.mdx +3 -3
- package/site/content/docs/reference/cli.mdx +231 -0
- package/site/content/docs/reference/configuration.mdx +30 -10
- package/site/content/docs/reference/environment-variables.mdx +93 -20
- package/site/content/docs/reference/errors.mdx +132 -29
- package/site/content/docs/reference/fx.mdx +137 -73
- package/site/content/docs/reference/index.mdx +13 -21
- package/site/content/docs/reference/meta.json +4 -5
- package/site/content/docs/reference/okid.mdx +42 -17
- package/site/content/docs/reference/plugins.mdx +4 -3
- package/site/content/docs/reference/security.mdx +197 -0
- package/site/content/docs/understand/meta.json +5 -0
- package/site/content/docs/understand/the-anatomy.mdx +132 -0
- package/site/content/docs/understand/the-model.mdx +32 -0
- package/site/content/docs/understand/the-problem.mdx +74 -0
- package/site/content/docs/understand/the-vocabulary.mdx +26 -0
- package/src/auth/api-keys.ts +2 -1
- package/src/auth/bindings.ts +64 -16
- package/src/auth/gate-auth.test.ts +6 -1
- package/src/auth/identity.ts +152 -5
- package/src/auth/index.ts +29 -0
- package/src/auth/invites.ts +2 -1
- package/src/auth/method-context.ts +41 -0
- package/src/auth/oauth-as/crypto.ts +2 -1
- package/src/auth/oauth-as/stores.ts +2 -1
- package/src/auth/operator.ts +2 -1
- package/src/auth/sessions-jwt.test.ts +77 -0
- package/src/auth/sessions.ts +20 -4
- package/src/auth/tenants.ts +3 -2
- package/src/auth/two-factor-challenge.test.ts +61 -0
- package/src/auth/two-factor-challenge.ts +284 -0
- package/src/auth/verification.ts +5 -0
- package/src/bench/REPORT.md +49 -0
- package/src/bench/g03-signal-once.bench.ts +1 -1
- package/src/bench/g10-observability-contention.bench.ts +1 -1
- package/src/bench/g17-hybrid-search.bench.ts +572 -0
- package/src/bench/load-app.ts +2 -10
- package/src/cli/ai-setup/ai-setup.test.ts +331 -42
- package/src/cli/ai-setup/apply.ts +294 -52
- package/src/cli/ai-setup/catalog.ts +238 -1342
- package/src/cli/ai-setup/index.ts +14 -99
- package/src/cli/ai-setup/prompts.ts +60 -443
- package/src/cli/ask-seed.test.ts +96 -0
- package/src/cli/ask-seed.ts +82 -0
- package/src/cli/ask-vault-gaps.test.ts +84 -0
- package/src/cli/ask-vault-gaps.ts +146 -0
- package/src/cli/build.ts +2 -2
- package/src/cli/client-add.test.ts +26 -1
- package/src/cli/client-add.ts +106 -27
- package/src/cli/db-seed.ts +2 -0
- package/src/cli/db.ts +150 -11
- package/src/cli/dev.ts +119 -211
- package/src/cli/docker-clean.ts +2 -2
- package/src/cli/docker-cli.test.ts +1 -1
- package/src/cli/doctor-diff.ts +4 -2
- package/src/cli/doctor-pii.test.ts +1 -1
- package/src/cli/doctor.ts +14 -1
- package/src/cli/hero-meta.test.ts +4 -2
- package/src/cli/load-config.images.test.ts +8 -10
- package/src/cli/load-config.ts +1 -1
- package/src/cli/registry.ts +22 -10
- package/src/cli/replay.ts +3 -1
- package/src/cli/start.ts +1 -1
- package/src/cli/tui/keys.ts +2 -3
- package/src/client/auth/cookies.ts +74 -0
- package/src/client/auth/create-auth-client.ts +636 -0
- package/src/client/auth/denials.ts +99 -0
- package/src/client/auth/session.ts +283 -0
- package/src/client/auth.test.ts +251 -0
- package/src/client/auth.ts +39 -114
- package/src/client/create-with-session.ts +245 -0
- package/src/client/create.ts +51 -5
- package/src/client/index.ts +11 -1
- package/src/client/live.ts +11 -79
- package/src/client/notes-contract.test.ts +5 -10
- package/src/client/sse.ts +137 -0
- package/src/client/stream.ts +147 -0
- package/src/client/transport.test.ts +32 -0
- package/src/client/transport.ts +123 -26
- package/src/client/types.ts +118 -14
- package/src/client-react/index.ts +185 -24
- package/src/client-react/use-live-query.ts +13 -3
- package/src/compiler/aot.test.ts +7 -4
- package/src/compiler/effects-embed.test.ts +56 -0
- package/src/compiler/effects-fetch.test.ts +43 -0
- package/src/compiler/effects-infer.ts +58 -2
- package/src/compiler/extract.test.ts +257 -43
- package/src/compiler/extract.ts +566 -48
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -4
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +2 -8
- package/src/compiler/fixtures/skyport.expected.json +4 -4
- package/src/compiler/fixtures/triggers/five-triggers.ts +14 -10
- package/src/compiler/response.ts +2 -2
- package/src/compiler/search-writer-isolation.test.ts +40 -0
- package/src/config/index.ts +11 -0
- package/src/console/server/app.ts +17 -23
- package/src/console/server/bind.ts +4 -0
- package/src/console/server/console.test.ts +2 -2
- package/src/console/server/flows-invoke.test.ts +50 -34
- package/src/console/server/flows.ts +436 -255
- package/src/console/server/runs-ingest.test.ts +6 -3
- package/src/console/server/serve.ts +1 -1
- package/src/console/server/signals.test.ts +1 -5
- package/src/console/server/signals.ts +8 -6
- package/src/console/server/state.ts +6 -1
- package/src/console/server/store.ts +1 -1
- package/src/console/ui-next/dist/assets/FileExportIcon-Ck-5od4R.js +1 -0
- package/src/console/ui-next/dist/assets/MoreHorizontalCircle01Icon-gMNGsE37.js +1 -0
- package/src/console/ui-next/dist/assets/PlusSignIcon-CwG3nxfu.js +1 -0
- package/src/console/ui-next/dist/assets/UnavailableIcon-D9cvHVPr.js +1 -0
- package/src/console/ui-next/dist/assets/UserIcon-DaE2PB5_.js +1 -0
- package/src/console/ui-next/dist/assets/access-page-DFeymU07.js +4 -0
- package/src/console/ui-next/dist/assets/agent-disclosure-U1rdfblp.js +1 -0
- package/src/console/ui-next/dist/assets/cache-glyph-BeFJeqBG.js +1 -0
- package/src/console/ui-next/dist/assets/call-pii-button-CVAONPii.js +1 -0
- package/src/console/ui-next/dist/assets/collapsible-D2A6NJ-3.js +1 -0
- package/src/console/ui-next/dist/assets/copy-inline-button-CAYD18cr.js +1 -0
- package/src/console/ui-next/dist/assets/dagre.esm-B1_XeuLP.js +1 -0
- package/src/console/ui-next/dist/assets/detail-header-DVWNjWjg.js +1 -0
- package/src/console/ui-next/dist/assets/dropdown-menu-4h2LOVXM.js +1 -0
- package/src/console/ui-next/dist/assets/duration-tone-Cgk_h5ja.js +9 -0
- package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +1 -0
- package/src/console/ui-next/dist/assets/explorer-empty-CJs5A-wm.js +1 -0
- package/src/console/ui-next/dist/assets/flows-page-Dss7941e.js +1 -0
- package/src/console/ui-next/dist/assets/highlighted-json-MYZQtRnw.js +154 -0
- package/src/console/ui-next/dist/assets/http-method-Jrh39p7A.js +1 -0
- package/src/console/ui-next/dist/assets/index-D0zS5rKO.css +2 -0
- package/src/console/ui-next/dist/assets/index-DXP2dBIF.js +63 -0
- package/src/console/ui-next/dist/assets/observability-page-HvolXxTI.js +4 -0
- package/src/console/ui-next/dist/assets/react-dom-Ddte4I-Q.js +9 -0
- package/src/console/ui-next/dist/assets/replica-lag-CSh2dzrb.js +18 -0
- package/src/console/ui-next/dist/assets/request-meta-BatF8KrK.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +1 -0
- package/src/console/ui-next/dist/assets/{sql-BskegiFM.js → sql-BsFa4tDR.js} +1 -1
- package/src/console/ui-next/dist/assets/store-page-eiKiHnNe.js +41 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-CZkMeKS-.js +2 -0
- package/src/console/ui-next/dist/assets/tree-expand-toggle-CW8y5A2h.js +55 -0
- package/src/console/ui-next/dist/assets/units-page-B_RWJrEO.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-uk4WVboC.js → use-vault-list-CT4-gajj.js} +1 -1
- package/src/console/ui-next/dist/assets/vault-page-CWrg-A68.js +2 -0
- package/src/console/ui-next/dist/assets/xyflow-CSyC6ryz.css +1 -0
- package/src/console/ui-next/dist/assets/xyflow-yApv7D4e.js +7 -0
- package/src/console/ui-next/dist/index.html +6 -13
- package/src/console/ui-next/seed-invoke-host.ts +21 -18
- package/src/console/ui-next/src/client.ts +7 -2
- package/src/console/ui-next/src/features/flows/graph/element-map.ts +2 -0
- package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +12 -2
- package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +8 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +4 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +9 -3
- package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +7 -11
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +2 -2
- package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +2 -0
- package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +25 -1
- package/src/console/ui-next/src/features/store/lib/grid-model.ts +36 -1
- package/src/console/ui-next/src/features/store/query/query-results.tsx +3 -3
- package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +2 -0
- package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +3 -1
- package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +6 -0
- package/src/docker/ai-model-status.test.ts +1 -12
- package/src/docker/ai-model-status.ts +10 -38
- package/src/docker/compose-up.test.ts +100 -0
- package/src/docker/compose-up.ts +292 -0
- package/src/docker/compose.ts +4 -14
- package/src/docker/derive.ts +9 -34
- package/src/docker/docker.test.ts +16 -261
- package/src/docker/images-config.test.ts +13 -25
- package/src/docker/index.ts +1 -24
- package/src/docker/recipes/index.ts +0 -23
- package/src/docker/recipes/pgdog.ts +6 -4
- package/src/docker/stack-id.test.ts +2 -2
- package/src/docker/stack-id.ts +0 -1
- package/src/docker/types.ts +2 -2
- package/src/drivers/ai-anthropic.ts +10 -0
- package/src/drivers/ai-openai-compatible.ts +34 -7
- package/src/drivers/ai-providers.test.ts +0 -107
- package/src/drivers/ai-stream.test.ts +0 -34
- package/src/drivers/ai-types.ts +17 -8
- package/src/drivers/channel-fcm.ts +6 -1
- package/src/drivers/channel-msegat.ts +6 -1
- package/src/drivers/channel-resend.ts +5 -1
- package/src/drivers/channel-smtp.ts +5 -1
- package/src/drivers/channel-sndr.ts +10 -1
- package/src/drivers/channel-taqnyat-mail.ts +5 -1
- package/src/drivers/channel-taqnyat-whatsapp.ts +6 -1
- package/src/drivers/channel-taqnyat.ts +6 -1
- package/src/drivers/channel-types.ts +10 -0
- package/src/drivers/channel-unifonic.ts +6 -1
- package/src/drivers/channel-wa-cloud.ts +6 -1
- package/src/drivers/channel-webpush.ts +6 -1
- package/src/drivers/external.ts +33 -0
- package/src/drivers/index.ts +0 -10
- package/src/drivers/meilisearch.ts +6 -0
- package/src/drivers/oauth-types.ts +4 -0
- package/src/drivers/postgres.test.ts +74 -3
- package/src/drivers/postgres.ts +175 -6
- package/src/drivers/signal-types.ts +5 -5
- package/src/drivers/types.ts +7 -0
- package/src/drivers/vault-types.ts +5 -0
- package/src/elements/ai/declare.ts +17 -4
- package/src/elements/ai/eval.ts +1 -1
- package/src/elements/ai/mcp-http.ts +1 -1
- package/src/elements/ai/pii.ts +1 -1
- package/src/elements/ai/providers.test.ts +289 -0
- package/src/elements/ai/providers.ts +169 -0
- package/src/elements/ai/runtime.ts +68 -5
- package/src/elements/ai/schema.ts +2 -2
- package/src/elements/ai.test.ts +7 -7
- package/src/elements/ai.ts +17 -1
- package/src/elements/channel/runtime.ts +105 -12
- package/src/elements/clock/cron-fields.test.ts +144 -0
- package/src/elements/clock/cron-fields.ts +185 -0
- package/src/elements/clock/declare.ts +247 -3
- package/src/elements/clock.ts +21 -1
- package/src/elements/index.ts +15 -0
- package/src/elements/signal/chaos-child.ts +1 -2
- package/src/elements/signal/declare.ts +65 -37
- package/src/elements/signal/delivery-modes.test.ts +11 -31
- package/src/elements/signal/dry-run-replay.test.ts +1 -7
- package/src/elements/signal/dry-run-write-isolation.test.ts +1 -7
- package/src/elements/signal/key-ordering.test.ts +6 -26
- package/src/elements/signal/lease-reclaim.test.ts +2 -6
- package/src/elements/signal/optional-emit.test.ts +6 -9
- package/src/elements/signal/order-lifecycle.test.ts +4 -17
- package/src/elements/signal/orphan-messages.test.ts +4 -15
- package/src/elements/signal/reconcile.test.ts +2 -2
- package/src/elements/signal/runtime.ts +1 -1
- package/src/elements/signal/schema-emit.test.ts +4 -8
- package/src/elements/signal.test.ts +24 -49
- package/src/elements/signal.ts +9 -2
- package/src/elements/store/domain-ddl.test.ts +1 -1
- package/src/elements/store/live-http.test.ts +9 -4
- package/src/elements/store/prepare-row.test.ts +123 -0
- package/src/elements/store/resource.ts +43 -12
- package/src/elements/store/schema-decl.ts +117 -0
- package/src/elements/store/search-backfill.ts +205 -0
- package/src/elements/store/search-bind.ts +66 -0
- package/src/elements/store/search-bm25.ts +78 -0
- package/src/elements/store/search-ddl.ts +156 -0
- package/src/elements/store/search-embed-flow.ts +141 -0
- package/src/elements/store/search-errors.ts +34 -0
- package/src/elements/store/search-fusion.ts +112 -0
- package/src/elements/store/search-lsh.ts +179 -0
- package/src/elements/store/search-runtime.ts +300 -0
- package/src/elements/store/search.test.ts +144 -0
- package/src/elements/store/sql-session.test.ts +1 -0
- package/src/elements/store/sql-session.ts +83 -3
- package/src/elements/store/table.ts +23 -2
- package/src/elements/store/upsert-app.test.ts +1 -3
- package/src/elements/store.ts +50 -0
- package/src/full.ts +4 -2
- package/src/http.ts +4 -1
- package/src/i18n/catalogs/ar.ts +14 -6
- package/src/i18n/catalogs/en.ts +14 -6
- package/src/index.ts +6 -1
- package/src/kernel/adopt-barrel-fresh.test.ts +7 -7
- package/src/kernel/adopt-routes.ts +9 -1
- package/src/kernel/app-auth.ts +5 -0
- package/src/kernel/app.ts +102 -9
- package/src/kernel/auto-cache.test.ts +6 -12
- package/src/kernel/auto-registry.test.ts +3 -3
- package/src/kernel/boot-bind/ai.test.ts +22 -19
- package/src/kernel/boot-bind/ai.ts +5 -43
- package/src/kernel/boot-bind/clock.ts +23 -5
- package/src/kernel/boot-bind/honor-config.test.ts +4 -4
- package/src/kernel/boot.test.ts +11 -6
- package/src/kernel/boot.ts +66 -16
- package/src/kernel/boundary-contract.ts +93 -0
- package/src/kernel/budget.test.ts +1 -1
- package/src/kernel/call.ts +89 -0
- package/src/kernel/capability.ts +6 -0
- package/src/kernel/client-descriptor.ts +123 -0
- package/src/kernel/clock-timezone.test.ts +80 -0
- package/src/kernel/correlation.test.ts +1 -1
- package/src/kernel/dry-run.ts +11 -8
- package/src/kernel/effects-stamping.test.ts +42 -9
- package/src/kernel/effects.test.ts +4 -2
- package/src/kernel/effects.ts +51 -9
- package/src/kernel/errors-channel.ts +17 -0
- package/src/kernel/errors-live-resume.ts +3 -2
- package/src/kernel/errors-tenant.ts +7 -4
- package/src/kernel/errors.registry-helpers.ts +96 -0
- package/src/kernel/errors.registry.test.ts +139 -25
- package/src/kernel/errors.ts +102 -23
- package/src/kernel/external-effects.test.ts +196 -0
- package/src/kernel/flow.test.ts +13 -4
- package/src/kernel/flow.ts +69 -71
- package/src/kernel/fx-ask-telemetry.test.ts +2 -2
- package/src/kernel/fx-dead-letters.test.ts +3 -3
- package/src/kernel/fx-fetch.ts +55 -0
- package/src/kernel/fx-live-stream.ts +2 -2
- package/src/kernel/fx-live.test.ts +8 -8
- package/src/kernel/fx.test.ts +17 -11
- package/src/kernel/fx.ts +180 -57
- package/src/kernel/horizontal-child.ts +1 -1
- package/src/kernel/http-query.test.ts +3 -6
- package/src/kernel/index.ts +13 -3
- package/src/kernel/instance-id.ts +1 -1
- package/src/kernel/instances.test.ts +40 -0
- package/src/kernel/instances.ts +47 -9
- package/src/kernel/live-http.test.ts +6 -7
- package/src/kernel/live-http.ts +6 -2
- package/src/kernel/live-resume.test.ts +1 -1
- package/src/kernel/mcp-tool.test.ts +3 -3
- package/src/kernel/on.ts +98 -4
- package/src/kernel/pipeline.test.ts +12 -15
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/stamp-http.test.ts +3 -3
- package/src/kernel/triggers.ts +210 -95
- package/src/kernel-entry.ts +0 -1
- package/src/manifest/diff.ts +11 -1
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/types.ts +46 -2
- package/src/mcp/docs-index.ts +3 -3
- package/src/mcp/docs-mcp.test.ts +2 -2
- package/src/mcp/docs-tools.ts +1 -1
- package/src/okid.test.ts +56 -0
- package/src/okid.ts +55 -11
- package/src/plugins/anonymous.ts +8 -4
- package/src/plugins/auth/shared.ts +27 -3
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/auth-methods.security.test.ts +561 -23
- package/src/plugins/config-source.ts +1 -1
- package/src/plugins/csrf.test.ts +65 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/magic-link.ts +36 -16
- package/src/plugins/oauth/shared.ts +3 -1
- package/src/plugins/oauth.ts +22 -14
- package/src/plugins/otp.ts +37 -21
- package/src/plugins/passkey-webauthn.ts +9 -6
- package/src/plugins/passkey.ts +98 -26
- package/src/plugins/pre-account-hijack.test.ts +223 -0
- package/src/plugins/two-factor.ts +466 -37
- package/src/plugins/username.ts +19 -7
- package/src/release/build-lib.ts +1 -0
- package/src/release/limits.ts +2 -2
- package/src/release/measure.ts +1 -1
- package/src/runs/collect.test.ts +0 -2
- package/src/runtime/json-code-block.test.ts +250 -20
- package/src/runtime/json-code-block.ts +1261 -41
- package/src/term.test.ts +1 -1
- package/src/test/create-test-app.test.ts +12 -12
- package/src/test/live-signals.test.ts +6 -6
- package/src/test/provisions.integration.test.ts +10 -14
- package/src/test/reset-element-registries.ts +1 -1
- package/src/test/tenant-isolation.test.ts +12 -6
- package/site/content/docs/deployment/docker-swarm.mdx +0 -164
- package/site/content/docs/deployment/docker.mdx +0 -227
- package/site/content/docs/deployment/index.mdx +0 -83
- package/site/content/docs/deployment/kubernetes.mdx +0 -176
- package/site/content/docs/deployment/meta.json +0 -5
- package/site/content/docs/deployment/reverse-proxy.mdx +0 -234
- package/site/content/docs/elements/ai.mdx +0 -385
- package/site/content/docs/elements/channel.mdx +0 -346
- package/site/content/docs/elements/clock.mdx +0 -244
- package/site/content/docs/elements/flow.mdx +0 -420
- package/site/content/docs/elements/gate.mdx +0 -436
- package/site/content/docs/elements/signal.mdx +0 -380
- package/site/content/docs/elements/store.mdx +0 -1099
- package/site/content/docs/elements/vault.mdx +0 -405
- package/site/content/docs/get-started/basic-usage.mdx +0 -173
- package/site/content/docs/get-started/index.mdx +0 -43
- package/site/content/docs/get-started/installation.mdx +0 -220
- package/site/content/docs/get-started/introduction.mdx +0 -144
- package/site/content/docs/get-started/meta.json +0 -13
- package/site/content/docs/get-started/project-structure.mdx +0 -925
- package/site/content/docs/get-started/testing.mdx +0 -328
- package/site/content/docs/get-started/why.mdx +0 -114
- package/site/content/docs/recipes/llama-cpp.mdx +0 -151
- package/site/content/docs/recipes/ollama.mdx +0 -142
- package/site/content/docs/recipes/sglang.mdx +0 -105
- package/site/content/docs/recipes/vllm.mdx +0 -106
- package/site/content/docs/reference/cli.md +0 -232
- package/site/content/docs/reference/client.mdx +0 -469
- package/site/content/docs/reference/security.md +0 -74
- package/src/cli/ai-setup/detect-ollama.ts +0 -213
- package/src/cli/ai-setup/recommend.test.ts +0 -225
- package/src/cli/ai-setup/recommend.ts +0 -225
- package/src/cli/dev-controls.test.ts +0 -122
- package/src/cli/dev-controls.ts +0 -164
- package/src/cli/tui/DevLive.tsx +0 -126
- package/src/console/ui-next/dist/assets/access-page-3-EFj-2G.js +0 -4
- package/src/console/ui-next/dist/assets/agent-disclosure-BP0Y0Sux.js +0 -1
- package/src/console/ui-next/dist/assets/cache-glyph-B5X-NM0-.js +0 -1
- package/src/console/ui-next/dist/assets/call-pii-button-ChAUiLo9.js +0 -1
- package/src/console/ui-next/dist/assets/collapsible-DGnOM2ph.js +0 -1
- package/src/console/ui-next/dist/assets/copy-inline-button-DBHhgHKP.js +0 -1
- package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +0 -1
- package/src/console/ui-next/dist/assets/detail-header-DhHM1iaZ.js +0 -1
- package/src/console/ui-next/dist/assets/dropdown-menu-_NjTEo5_.js +0 -1
- package/src/console/ui-next/dist/assets/duration-tone-sC3lGABz.js +0 -9
- package/src/console/ui-next/dist/assets/element-icons-BVXtRyd3.js +0 -1
- package/src/console/ui-next/dist/assets/explorer-empty-2uIhBu0_.js +0 -1
- package/src/console/ui-next/dist/assets/flows-page-cVFnA4HH.js +0 -1
- package/src/console/ui-next/dist/assets/highlighted-json-Awq7gYdu.js +0 -154
- package/src/console/ui-next/dist/assets/http-method-_UHM2ODJ.js +0 -1
- package/src/console/ui-next/dist/assets/index-CMIgUbD0.js +0 -66
- package/src/console/ui-next/dist/assets/index-Ck88Jmv8.css +0 -2
- package/src/console/ui-next/dist/assets/link-BX6Vqztd.js +0 -1
- package/src/console/ui-next/dist/assets/observability-page-CQ3p34ip.js +0 -4
- package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +0 -1
- package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +0 -1
- package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +0 -9
- package/src/console/ui-next/dist/assets/replica-lag-DKRrbvdo.js +0 -18
- package/src/console/ui-next/dist/assets/request-meta-DV0ywz7t.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-JQIZlWfm.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-DKxNTe_m.js +0 -1
- package/src/console/ui-next/dist/assets/skeleton-D-czQJT6.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-02xOiqIK.js +0 -41
- package/src/console/ui-next/dist/assets/trace-detail-sheet-B09O8rA6.js +0 -2
- package/src/console/ui-next/dist/assets/tree-expand-toggle-BtyhmWb4.js +0 -55
- package/src/console/ui-next/dist/assets/units-page-l8FeKfnP.js +0 -1
- package/src/console/ui-next/dist/assets/useMutation-B8EO02Ej.js +0 -1
- package/src/console/ui-next/dist/assets/useRender-BE2A9BWC.js +0 -1
- package/src/console/ui-next/dist/assets/vault-page-CL-d_mLE.js +0 -2
- package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +0 -7
- package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +0 -1
- package/src/docker/ollama-pull.ts +0 -232
- package/src/docker/recipes/llama-cpp.ts +0 -298
- package/src/docker/recipes/ollama.ts +0 -44
- package/src/docker/recipes/sglang.ts +0 -55
- package/src/docker/recipes/vllm.ts +0 -44
- package/src/drivers/ai-ollama-tools.integration.test.ts +0 -109
- package/src/drivers/ai-ollama.integration.test.ts +0 -184
- package/src/drivers/ai-ollama.ts +0 -389
- package/src/drivers/ollama.ts +0 -14
package/src/mcp/docs-index.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { join } from "node:path";
|
|
|
12
12
|
export interface DocsPage {
|
|
13
13
|
/** URL slug under `/docs` (`""` for the index page). */
|
|
14
14
|
readonly slug: string;
|
|
15
|
-
/** Content-relative path (e.g. `
|
|
15
|
+
/** Content-relative path (e.g. `understand/the-problem.mdx`). */
|
|
16
16
|
readonly path: string;
|
|
17
17
|
/** Frontmatter title. */
|
|
18
18
|
readonly title: string;
|
|
@@ -39,7 +39,7 @@ export interface DocsIndex {
|
|
|
39
39
|
/**
|
|
40
40
|
* Look up a page by slug or content path.
|
|
41
41
|
*
|
|
42
|
-
* @param id - Slug (`
|
|
42
|
+
* @param id - Slug (`understand/the-problem`) or path (`…/the-problem.mdx`)
|
|
43
43
|
*/
|
|
44
44
|
readonly get: (id: string) => DocsPage | null;
|
|
45
45
|
/**
|
|
@@ -203,7 +203,7 @@ export async function loadDocsIndex(
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
|
-
* @param relativePath - e.g. `
|
|
206
|
+
* @param relativePath - e.g. `understand/the-problem.mdx`
|
|
207
207
|
*/
|
|
208
208
|
function pathToSlug(relativePath: string): string {
|
|
209
209
|
const noExt = relativePath.replace(/\.mdx?$/i, "");
|
package/src/mcp/docs-mcp.test.ts
CHANGED
|
@@ -112,7 +112,7 @@ describe("docs MCP tools", () => {
|
|
|
112
112
|
|
|
113
113
|
test("oke.docs.get returns body byte-identical to on-disk source", async () => {
|
|
114
114
|
const mcp = await createDocsMcpServer({ contentDir: CONTENT });
|
|
115
|
-
const slug = "
|
|
115
|
+
const slug = "understand/the-problem";
|
|
116
116
|
const res = await mcpPost(mcp.fetch, {
|
|
117
117
|
jsonrpc: "2.0",
|
|
118
118
|
id: 2,
|
|
@@ -133,7 +133,7 @@ describe("docs MCP tools", () => {
|
|
|
133
133
|
const content = envelope.content as { body: string; slug: string };
|
|
134
134
|
expect(content.slug).toBe(slug);
|
|
135
135
|
|
|
136
|
-
const raw = await Bun.file(join(CONTENT, "
|
|
136
|
+
const raw = await Bun.file(join(CONTENT, "understand", "the-problem.mdx")).text();
|
|
137
137
|
expect(content.body).toBe(stripYamlFrontmatter(raw));
|
|
138
138
|
});
|
|
139
139
|
|
package/src/mcp/docs-tools.ts
CHANGED
|
@@ -52,7 +52,7 @@ export const DOCS_MCP_TOOLS: readonly DocsToolDescriptor[] = [
|
|
|
52
52
|
properties: {
|
|
53
53
|
slug: {
|
|
54
54
|
type: "string",
|
|
55
|
-
description: "Page slug (e.g.
|
|
55
|
+
description: "Page slug (e.g. understand/the-problem) or path (…/the-problem.mdx)",
|
|
56
56
|
},
|
|
57
57
|
},
|
|
58
58
|
required: ["slug"],
|
package/src/okid.test.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
OKID_DEFAULT_LENGTH,
|
|
9
9
|
OKID_LOOKALIKE_CHARS,
|
|
10
10
|
OKID_MAX_LENGTH,
|
|
11
|
+
OKID_MAX_PREFIX_LENGTH,
|
|
11
12
|
OKID_MIN_LENGTH,
|
|
12
13
|
OKID_SORTABLE_ALPHABET,
|
|
13
14
|
OKID_SORTABLE_MIN_LENGTH,
|
|
@@ -304,6 +305,61 @@ describe("okid sortable mode", () => {
|
|
|
304
305
|
});
|
|
305
306
|
});
|
|
306
307
|
|
|
308
|
+
describe("okid semantic prefix", () => {
|
|
309
|
+
test("prepends the label and keeps body length", () => {
|
|
310
|
+
const id = okid({ prefix: "usr_" });
|
|
311
|
+
expect(id.startsWith("usr_")).toBe(true);
|
|
312
|
+
expect(id.length).toBe(4 + OKID_DEFAULT_LENGTH);
|
|
313
|
+
expect(id.slice(4).length).toBe(OKID_DEFAULT_LENGTH);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
test("honors length as the body size, not the total", () => {
|
|
317
|
+
const id = okid({ prefix: "evt_", length: 16 });
|
|
318
|
+
expect(id.startsWith("evt_")).toBe(true);
|
|
319
|
+
expect(id.length).toBe(4 + 16);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
test("combines with sortable: prefix + timestamp + random", () => {
|
|
323
|
+
const realNow = Date.now;
|
|
324
|
+
Date.now = () => 1_700_000_000_000;
|
|
325
|
+
try {
|
|
326
|
+
const a = okid({ prefix: "evt_", sortable: true, length: 16 });
|
|
327
|
+
const b = okid({ prefix: "evt_", sortable: true, length: 16 });
|
|
328
|
+
expect(a.startsWith("evt_")).toBe(true);
|
|
329
|
+
expect(a.length).toBe(4 + 16);
|
|
330
|
+
expect(a.slice(4, 12)).toBe(b.slice(4, 12));
|
|
331
|
+
expect(a.slice(12)).not.toBe(b.slice(12));
|
|
332
|
+
} finally {
|
|
333
|
+
Date.now = realNow;
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
test("empty / omitted prefix is a no-op", () => {
|
|
338
|
+
expect(okid({ prefix: "" }).length).toBe(OKID_DEFAULT_LENGTH);
|
|
339
|
+
expect(okid({}).length).toBe(OKID_DEFAULT_LENGTH);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
test("rejects characters outside OKID_ALPHABET", () => {
|
|
343
|
+
expect(() => okid({ prefix: "usr:" })).toThrow(RangeError);
|
|
344
|
+
expect(() => okid({ prefix: "usr " })).toThrow(RangeError);
|
|
345
|
+
expect(() => okid({ prefix: "usr." })).toThrow(RangeError);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test("rejects oversized prefixes", () => {
|
|
349
|
+
expect(() => okid({ prefix: "a".repeat(OKID_MAX_PREFIX_LENGTH + 1) })).toThrow(RangeError);
|
|
350
|
+
expect(okid({ prefix: "a".repeat(OKID_MAX_PREFIX_LENGTH) }).length).toBe(
|
|
351
|
+
OKID_MAX_PREFIX_LENGTH + OKID_DEFAULT_LENGTH,
|
|
352
|
+
);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
test("full id stays URL-safe", () => {
|
|
356
|
+
for (let i = 0; i < 200; i++) {
|
|
357
|
+
const id = okid({ prefix: "inst-" });
|
|
358
|
+
expect(encodeURIComponent(id)).toBe(id);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
307
363
|
describe("okid entropy math", () => {
|
|
308
364
|
const bitsPerChar = Math.log2;
|
|
309
365
|
|
package/src/okid.ts
CHANGED
|
@@ -16,8 +16,11 @@
|
|
|
16
16
|
* 48-bit epoch-millisecond timestamp encoded in exactly 8 chars, leaving
|
|
17
17
|
* `length − 8` random chars (78 bits at the default length). Lexicographic
|
|
18
18
|
* order equals time order across milliseconds; ids minted within the same
|
|
19
|
-
* millisecond tie on the
|
|
19
|
+
* millisecond tie on the timestamp and carry no intra-ms ordering. Clock skew
|
|
20
20
|
* distorts ordering but can never cause duplicates (the tail stays random).
|
|
21
|
+
* - **Semantic prefix** — `okid({ prefix: "usr_" })` prepends a fixed label
|
|
22
|
+
* from the OKID alphabet. `length` is always the generated body (random or
|
|
23
|
+
* sortable); the returned string is `prefix + body`.
|
|
21
24
|
* - **Alphabet control** — group toggles (`numbers`, `lowercase`,
|
|
22
25
|
* `uppercase`, `symbols`) and `lookAlikes` shrink the alphabet for
|
|
23
26
|
* human-transcribed codes. Non-power-of-two alphabets use rejection
|
|
@@ -38,7 +41,8 @@
|
|
|
38
41
|
*
|
|
39
42
|
* const userId = okid(); // 21 chars, 126 bits
|
|
40
43
|
* const requestId = okid(16); // explicit length
|
|
41
|
-
* const eventKey = okid({ sortable: true }); // time-prefixed
|
|
44
|
+
* const eventKey = okid({ sortable: true }); // time-prefixed body
|
|
45
|
+
* const typedId = okid({ prefix: "usr_" }); // usr_ + 21-char body
|
|
42
46
|
* const inviteCode = okid({
|
|
43
47
|
* lookAlikes: false,
|
|
44
48
|
* uppercase: false,
|
|
@@ -89,14 +93,27 @@ export const OKID_MAX_LENGTH = 128;
|
|
|
89
93
|
/** Sortable ids need ≥ 16: 8 timestamp chars alone would leave no randomness. */
|
|
90
94
|
export const OKID_SORTABLE_MIN_LENGTH = 16;
|
|
91
95
|
|
|
96
|
+
/** Longest permitted semantic {@link OkidOptions.prefix}. */
|
|
97
|
+
export const OKID_MAX_PREFIX_LENGTH = 32;
|
|
98
|
+
|
|
92
99
|
/** Options for {@link okid}. All alphabet toggles default to included. */
|
|
93
100
|
export interface OkidOptions {
|
|
94
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Generated body length (default {@link OKID_DEFAULT_LENGTH}). Does not
|
|
103
|
+
* include {@link prefix} — the returned string is `prefix + body`.
|
|
104
|
+
*/
|
|
95
105
|
readonly length?: number;
|
|
96
106
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
107
|
+
* Fixed semantic label prepended to the body (e.g. `"usr_"`, `"evt_"`).
|
|
108
|
+
* Characters must belong to {@link OKID_ALPHABET}; max
|
|
109
|
+
* {@link OKID_MAX_PREFIX_LENGTH}. Empty / omitted means no label.
|
|
110
|
+
*/
|
|
111
|
+
readonly prefix?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Prefix the body with a 48-bit epoch-ms timestamp (exactly 8 chars) so
|
|
114
|
+
* lexicographic order tracks creation time across milliseconds. Alphabet
|
|
115
|
+
* toggles are ignored under this mode — see {@link OKID_SORTABLE_ALPHABET}.
|
|
116
|
+
* Combines with {@link prefix}: `prefix + timestamp + random`.
|
|
100
117
|
*/
|
|
101
118
|
readonly sortable?: boolean;
|
|
102
119
|
/** Include `a-z` (default true). */
|
|
@@ -204,6 +221,26 @@ function assertLength(length: number, min: number, label: string): void {
|
|
|
204
221
|
}
|
|
205
222
|
}
|
|
206
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Assert a semantic prefix is within bounds and stays on the URL-safe alphabet.
|
|
226
|
+
*
|
|
227
|
+
* @param prefix - Caller-supplied label
|
|
228
|
+
*/
|
|
229
|
+
function assertPrefix(prefix: string): void {
|
|
230
|
+
if (prefix.length > OKID_MAX_PREFIX_LENGTH) {
|
|
231
|
+
throw new RangeError(
|
|
232
|
+
`okid: prefix length ${prefix.length} exceeds max ${OKID_MAX_PREFIX_LENGTH}`,
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
for (const char of prefix) {
|
|
236
|
+
if (!OKID_ALPHABET.includes(char)) {
|
|
237
|
+
throw new RangeError(
|
|
238
|
+
`okid: prefix contains invalid character ${JSON.stringify(char)} — use characters from OKID_ALPHABET`,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
207
244
|
/**
|
|
208
245
|
* Generate an OKE-native id.
|
|
209
246
|
*
|
|
@@ -211,9 +248,10 @@ function assertLength(length: number, min: number, label: string): void {
|
|
|
211
248
|
* the hot path and skips all option resolution beyond validation.
|
|
212
249
|
*
|
|
213
250
|
* @param options - Length in chars, or {@link OkidOptions}
|
|
214
|
-
* @returns A URL-safe id
|
|
251
|
+
* @returns A URL-safe id: the generated body, optionally preceded by
|
|
252
|
+
* {@link OkidOptions.prefix}
|
|
215
253
|
* @throws RangeError on invalid input (non-integer, out-of-range length,
|
|
216
|
-
* empty alphabet)
|
|
254
|
+
* invalid prefix, empty alphabet)
|
|
217
255
|
*/
|
|
218
256
|
export function okid(options: number | OkidOptions = OKID_DEFAULT_LENGTH): string {
|
|
219
257
|
if (typeof options === "number") {
|
|
@@ -223,6 +261,7 @@ export function okid(options: number | OkidOptions = OKID_DEFAULT_LENGTH): strin
|
|
|
223
261
|
|
|
224
262
|
const {
|
|
225
263
|
length = OKID_DEFAULT_LENGTH,
|
|
264
|
+
prefix = "",
|
|
226
265
|
sortable = false,
|
|
227
266
|
lowercase = true,
|
|
228
267
|
uppercase = true,
|
|
@@ -231,15 +270,20 @@ export function okid(options: number | OkidOptions = OKID_DEFAULT_LENGTH): strin
|
|
|
231
270
|
lookAlikes = true,
|
|
232
271
|
} = options;
|
|
233
272
|
|
|
273
|
+
if (prefix) assertPrefix(prefix);
|
|
274
|
+
|
|
275
|
+
let body: string;
|
|
234
276
|
if (sortable) {
|
|
235
277
|
assertLength(length, OKID_SORTABLE_MIN_LENGTH, "length");
|
|
236
278
|
// Time ordering requires lexicographic encoding, which requires the full
|
|
237
279
|
// codepoint-ordered alphabet — partial subsets cannot preserve both the
|
|
238
280
|
// caller's charset choice AND cross-ms ordering, so toggles are ignored.
|
|
239
281
|
const alphabet = resolveAlphabet(true, true, true, true, true);
|
|
240
|
-
|
|
282
|
+
body = encodeTimestamp(Date.now()) + encode(alphabet, length - 8);
|
|
283
|
+
} else {
|
|
284
|
+
assertLength(length, OKID_MIN_LENGTH, "length");
|
|
285
|
+
body = encode(resolveAlphabet(numbers, lowercase, uppercase, symbols, lookAlikes), length);
|
|
241
286
|
}
|
|
242
287
|
|
|
243
|
-
|
|
244
|
-
return encode(resolveAlphabet(numbers, lowercase, uppercase, symbols, lookAlikes), length);
|
|
288
|
+
return prefix ? prefix + body : body;
|
|
245
289
|
}
|
package/src/plugins/anonymous.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
resolveSharedIdentities,
|
|
17
17
|
type AuthMethodOptions,
|
|
18
18
|
} from "./auth/shared.ts";
|
|
19
|
+
import { okid } from "../okid.ts";
|
|
19
20
|
|
|
20
21
|
/** Options for {@link anonymous}. */
|
|
21
22
|
export interface AnonymousPluginOptions extends AuthMethodOptions {
|
|
@@ -34,17 +35,20 @@ export function anonymous(opts: AnonymousPluginOptions = {}): PluginDef {
|
|
|
34
35
|
const runtime = createMethodRuntime(opts);
|
|
35
36
|
const identities = resolveSharedIdentities(opts);
|
|
36
37
|
|
|
37
|
-
const
|
|
38
|
-
plane: "user",
|
|
38
|
+
const signInContract = {
|
|
39
39
|
out: SessionTokensOut,
|
|
40
40
|
errors: { AuthFailed, AuthRateLimited },
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const signIn = flow("auth.signInAnonymous", {
|
|
44
|
+
plane: "user",
|
|
41
45
|
do: async () => {
|
|
42
46
|
let userId: string;
|
|
43
47
|
try {
|
|
44
48
|
userId = (
|
|
45
49
|
await linkOrProvision(identities, {
|
|
46
50
|
provider: "anonymous",
|
|
47
|
-
providerAccountId:
|
|
51
|
+
providerAccountId: okid(),
|
|
48
52
|
now: runtime.now,
|
|
49
53
|
})
|
|
50
54
|
).user.id;
|
|
@@ -70,5 +74,5 @@ export function anonymous(opts: AnonymousPluginOptions = {}): PluginDef {
|
|
|
70
74
|
|
|
71
75
|
return plugin("anonymous", { version: "0.0.1", config: { method: "anonymous" } })
|
|
72
76
|
.needs("auth")
|
|
73
|
-
.binding(bindPublicAuth("/sign-in/anonymous", signIn, "signIn"));
|
|
77
|
+
.binding(bindPublicAuth("/sign-in/anonymous", signIn, "signIn", signInContract));
|
|
74
78
|
}
|
|
@@ -9,6 +9,7 @@ import { getActiveGateAuthContext } from "../../auth/method-context.ts";
|
|
|
9
9
|
import { createSessionStore, type SessionCrypto, type SessionStore } from "../../auth/sessions.ts";
|
|
10
10
|
import { gate } from "../../elements/gate.ts";
|
|
11
11
|
import type { GateDecl } from "../../elements/gate/declare.ts";
|
|
12
|
+
import type { BoundaryContract } from "../../kernel/boundary-contract.ts";
|
|
12
13
|
import { fail } from "../../kernel/errors.ts";
|
|
13
14
|
import { flow, type AnyFlowDef } from "../../kernel/flow.ts";
|
|
14
15
|
import type { Binding } from "../../kernel/on.ts";
|
|
@@ -21,6 +22,9 @@ export const AuthFailed = z.object({
|
|
|
21
22
|
reasons: z.array(z.string()).optional(),
|
|
22
23
|
});
|
|
23
24
|
export const AuthRateLimited = z.object({ reason: z.string() });
|
|
25
|
+
export const Forbidden = z.object({
|
|
26
|
+
reason: z.string().optional(),
|
|
27
|
+
});
|
|
24
28
|
|
|
25
29
|
export const SessionTokensOut = z.object({
|
|
26
30
|
accessToken: z.string(),
|
|
@@ -29,6 +33,18 @@ export const SessionTokensOut = z.object({
|
|
|
29
33
|
userId: z.string().optional(),
|
|
30
34
|
});
|
|
31
35
|
|
|
36
|
+
/** Sign-in may return tokens or a locked 2FA challenge. */
|
|
37
|
+
export const SignInOut = z.union([
|
|
38
|
+
SessionTokensOut,
|
|
39
|
+
z.object({
|
|
40
|
+
twoFactorRequired: z.literal(true),
|
|
41
|
+
challengeId: z.string(),
|
|
42
|
+
method: z.enum(["totp", "email_otp"]),
|
|
43
|
+
userId: z.string(),
|
|
44
|
+
devOtp: z.string().optional(),
|
|
45
|
+
}),
|
|
46
|
+
]);
|
|
47
|
+
|
|
32
48
|
/** Common options for auth method plugins (session issue). */
|
|
33
49
|
export interface AuthMethodOptions {
|
|
34
50
|
/** HMAC secret; falls back to `OKE_AUTH_SECRET`, then a dev default. */
|
|
@@ -120,9 +136,11 @@ export function bindPublicAuth(
|
|
|
120
136
|
path: string,
|
|
121
137
|
flowDef: AnyFlowDef,
|
|
122
138
|
kind: keyof typeof AUTH_RATE_PRESETS = "otp",
|
|
139
|
+
contract?: BoundaryContract,
|
|
123
140
|
): Binding {
|
|
124
141
|
const gates = authPublicGates(kind);
|
|
125
|
-
let trigger =
|
|
142
|
+
let trigger =
|
|
143
|
+
contract !== undefined ? http.post(`/auth${path}`, contract) : http.post(`/auth${path}`);
|
|
126
144
|
for (const g of gates) trigger = trigger.gate(g);
|
|
127
145
|
return bindAuthHttp(trigger, flowDef);
|
|
128
146
|
}
|
|
@@ -133,8 +151,14 @@ export function bindPublicAuth(
|
|
|
133
151
|
* @param path - Path under `/auth`
|
|
134
152
|
* @param flowDef - Flow
|
|
135
153
|
*/
|
|
136
|
-
export function bindSessionAuth(
|
|
137
|
-
|
|
154
|
+
export function bindSessionAuth(
|
|
155
|
+
path: string,
|
|
156
|
+
flowDef: AnyFlowDef,
|
|
157
|
+
contract?: BoundaryContract,
|
|
158
|
+
): Binding {
|
|
159
|
+
const trigger =
|
|
160
|
+
contract !== undefined ? http.post(`/auth${path}`, contract) : http.post(`/auth${path}`);
|
|
161
|
+
return bindAuthHttp(trigger.gate(AUTH_SESSION_GATE), flowDef);
|
|
138
162
|
}
|
|
139
163
|
|
|
140
164
|
export { AUTH_SESSION_GATE, fail, flow, http, z };
|
|
@@ -18,7 +18,7 @@ import { otp } from "./otp.ts";
|
|
|
18
18
|
import { magicLink } from "./magic-link.ts";
|
|
19
19
|
|
|
20
20
|
const SECRET = "test-secret-at-least-16";
|
|
21
|
-
const MAILPIT_IMAGE = "axllent/mailpit:v1.
|
|
21
|
+
const MAILPIT_IMAGE = "axllent/mailpit:v1.31.1";
|
|
22
22
|
|
|
23
23
|
afterEach(() => {
|
|
24
24
|
resetBindings();
|