okengine 0.10.2 → 0.11.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/package.json +76 -10
- package/site/content/docs/ai/mcp.mdx +0 -1
- package/site/content/docs/deployment/docker-swarm.mdx +48 -111
- package/site/content/docs/deployment/docker.mdx +43 -36
- package/site/content/docs/deployment/index.mdx +9 -9
- package/site/content/docs/deployment/kubernetes.mdx +4 -4
- package/site/content/docs/elements/ai.mdx +7 -13
- package/site/content/docs/elements/channel.mdx +9 -13
- package/site/content/docs/elements/clock.mdx +8 -14
- package/site/content/docs/elements/flow.mdx +46 -54
- package/site/content/docs/elements/gate.mdx +6 -11
- package/site/content/docs/elements/signal.mdx +2 -8
- package/site/content/docs/elements/store.mdx +79 -93
- package/site/content/docs/elements/vault.mdx +89 -76
- package/site/content/docs/get-started/basic-usage.mdx +8 -14
- package/site/content/docs/get-started/installation.mdx +36 -36
- package/site/content/docs/get-started/introduction.mdx +11 -0
- package/site/content/docs/get-started/why.mdx +3 -4
- package/site/content/docs/index.mdx +0 -1
- package/site/content/docs/meta.json +0 -1
- package/site/content/docs/plugins/anonymous.mdx +1 -1
- package/site/content/docs/plugins/magic-link.mdx +11 -11
- package/site/content/docs/plugins/otp.mdx +2 -2
- package/site/content/docs/plugins/passkey.mdx +1 -1
- package/site/content/docs/plugins/two-factor.mdx +1 -1
- package/site/content/docs/plugins/username.mdx +1 -1
- package/site/content/docs/recipes/caddy.mdx +1 -1
- package/site/content/docs/recipes/cockroachdb.mdx +2 -2
- package/site/content/docs/recipes/dragonfly.mdx +1 -1
- package/site/content/docs/recipes/index.mdx +1 -2
- package/site/content/docs/recipes/llama-cpp.mdx +21 -23
- package/site/content/docs/recipes/mailpit.mdx +11 -11
- package/site/content/docs/recipes/meilisearch.mdx +10 -10
- package/site/content/docs/recipes/meta.json +0 -1
- package/site/content/docs/recipes/ollama.mdx +1 -1
- package/site/content/docs/recipes/pgdog.mdx +12 -9
- package/site/content/docs/recipes/postgres.mdx +3 -3
- package/site/content/docs/recipes/redis.mdx +2 -2
- package/site/content/docs/recipes/rustfs.mdx +10 -7
- package/site/content/docs/recipes/sglang.mdx +1 -1
- package/site/content/docs/recipes/supabase-docker.mdx +1 -1
- package/site/content/docs/recipes/timescale.mdx +2 -2
- package/site/content/docs/recipes/valkey.mdx +1 -1
- package/site/content/docs/recipes/vllm.mdx +1 -1
- package/site/content/docs/recipes/yugabytedb.mdx +2 -2
- package/site/content/docs/reference/cli.md +61 -38
- package/site/content/docs/reference/configuration.mdx +145 -70
- package/site/content/docs/reference/environment-variables.mdx +36 -28
- package/site/content/docs/reference/errors.mdx +28 -29
- package/site/content/docs/reference/fx.mdx +14 -7
- package/site/content/docs/reference/i18n.mdx +17 -6
- package/site/content/docs/reference/index.mdx +5 -0
- package/site/content/docs/reference/meta.json +1 -0
- package/site/content/docs/reference/migrating-environments.mdx +158 -0
- package/site/content/docs/reference/plugins.mdx +2 -2
- package/src/auth/gate-auth.test.ts +12 -10
- package/src/cli/ai-setup/ai-setup.test.ts +30 -16
- package/src/cli/ai-setup/apply.ts +111 -15
- package/src/cli/ai-setup/catalog.ts +3 -3
- package/src/cli/ai-setup/index.ts +1 -1
- package/src/cli/ai-setup/prompts.ts +1 -1
- package/src/cli/ai-setup/recommend.test.ts +1 -1
- package/src/cli/ask-seed.test.ts +3 -3
- package/src/cli/build.ts +8 -9
- package/src/cli/db-auto-push.test.ts +6 -3
- package/src/cli/db-auto-push.ts +7 -5
- package/src/cli/db-seed.ts +7 -8
- package/src/cli/db.test.ts +70 -71
- package/src/cli/db.ts +86 -12
- package/src/cli/dev-controller.test.ts +35 -0
- package/src/cli/dev-controller.ts +298 -0
- package/src/cli/dev-controls.ts +11 -65
- package/src/cli/dev-db-push.test.ts +47 -15
- package/src/cli/dev-schema-sync.test.ts +11 -11
- package/src/cli/dev-schema-sync.ts +10 -10
- package/src/cli/dev-session-lock.test.ts +106 -0
- package/src/cli/dev-session-lock.ts +209 -0
- package/src/cli/dev.test.ts +246 -114
- package/src/cli/dev.ts +153 -205
- package/src/cli/doc-staleness.test.ts +3 -6
- package/src/cli/docker-clean.test.ts +33 -1
- package/src/cli/docker-clean.ts +28 -33
- package/src/cli/docker-cli.test.ts +12 -11
- package/src/cli/docker.ts +95 -20
- package/src/cli/doctor.test.ts +40 -0
- package/src/cli/doctor.ts +142 -9
- package/src/cli/drizzle-env.test.ts +11 -13
- package/src/cli/drizzle-env.ts +18 -11
- package/src/cli/ensure-drizzle-config.ts +11 -14
- package/src/cli/hero-meta.test.ts +15 -15
- package/src/cli/hero-meta.ts +10 -9
- package/src/cli/index.ts +36 -6
- package/src/cli/load-config.images.test.ts +44 -10
- package/src/cli/load-config.source.test.ts +50 -0
- package/src/cli/load-config.ts +35 -29
- package/src/cli/meilisearch-local.ts +1 -2
- package/src/cli/mode.ts +7 -58
- package/src/cli/registry.ts +175 -19
- package/src/cli/resolve-dev-sql-env.test.ts +8 -16
- package/src/cli/resolve-dev-sql-env.ts +13 -15
- package/src/cli/safe-defaults.test.ts +29 -11
- package/src/cli/schema.ts +65 -16
- package/src/cli/test.ts +58 -0
- package/src/cli/tui/App.tsx +252 -0
- package/src/cli/tui/DevLive.tsx +116 -0
- package/src/cli/tui/components/ConfirmDialog.tsx +48 -0
- package/src/cli/tui/components/HeaderBar.tsx +67 -0
- package/src/cli/tui/components/LogStream.tsx +47 -0
- package/src/cli/tui/components/PanelCard.tsx +39 -0
- package/src/cli/tui/components/SelectRow.tsx +37 -0
- package/src/cli/tui/components/SlashPalette.tsx +172 -0
- package/src/cli/tui/components/Spinner.tsx +32 -0
- package/src/cli/tui/components/StatusBar.tsx +51 -0
- package/src/cli/tui/components/StatusDot.tsx +37 -0
- package/src/cli/tui/components/TabBar.tsx +49 -0
- package/src/cli/tui/components/Wordmark.tsx +43 -0
- package/src/cli/tui/format.ts +38 -0
- package/src/cli/tui/keys.test.ts +18 -0
- package/src/cli/tui/keys.ts +26 -0
- package/src/cli/tui/launch.test.ts +18 -0
- package/src/cli/tui/launch.ts +57 -0
- package/src/cli/tui/panels/Dashboard.tsx +201 -0
- package/src/cli/tui/panels/Database.tsx +198 -0
- package/src/cli/tui/panels/Dev.tsx +257 -0
- package/src/cli/tui/panels/Docker.tsx +357 -0
- package/src/cli/tui/panels/Navigator.test.ts +22 -0
- package/src/cli/tui/panels/Navigator.tsx +213 -0
- package/src/cli/tui/slash-catalog.test.ts +31 -0
- package/src/cli/tui/slash-catalog.ts +184 -0
- package/src/cli/tui/slash-run.ts +54 -0
- package/src/cli/tui/state/ports.ts +95 -0
- package/src/cli/tui/theme.ts +24 -0
- package/src/cli/vault-cmd.test.ts +402 -0
- package/src/cli/vault-cmd.ts +727 -69
- package/src/cli/vault-secure-input.test.ts +56 -0
- package/src/cli/vault-secure-input.ts +124 -0
- package/src/compiler/effects-infer.ts +7 -0
- package/src/compiler/extract.ts +12 -0
- package/src/compiler/fixtures/skyport/oke.config.ts +7 -5
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -1
- package/src/compiler/fixtures/skyport.expected.json +1 -1
- package/src/compiler/generate-adopt.ts +27 -1
- package/src/compiler-entry.ts +7 -0
- package/src/config/define-config.test.ts +111 -47
- package/src/config/driver-defaults.test.ts +115 -0
- package/src/config/driver-defaults.ts +156 -0
- package/src/config/index.ts +246 -131
- package/src/config/resolve-driver.test.ts +14 -19
- package/src/console/server/app.ts +4 -2
- package/src/console/server/console.test.ts +58 -1
- package/src/console/server/flows.ts +22 -2
- package/src/console/server/index.ts +3 -0
- package/src/console/server/operator-db.test.ts +55 -13
- package/src/console/server/operator-db.ts +305 -263
- package/src/console/server/serve.ts +16 -7
- package/src/console/server/state.ts +31 -9
- package/src/console/server/vault.test.ts +120 -5
- package/src/console/server/vault.ts +208 -12
- package/src/console/ui/dist/assets/{index-D-9KFce5.js → index--Y0Uaz-m.js} +2 -2
- package/src/console/ui/dist/assets/panel-vault-BkZdJPX8.js +1 -0
- package/src/console/ui/dist/assets/style-C3L349iZ.css +3 -0
- package/src/console/ui/dist/index.html +2 -2
- package/src/console/ui/shell/client.ts +16 -0
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +54 -1
- package/src/console/ui/vault/VaultA11yView.tsx +33 -1
- package/src/console/ui/vault/backend.test.ts +75 -0
- package/src/console/ui/vault/backend.ts +117 -0
- package/src/console/ui/vault/fixture.ts +21 -2
- package/src/console/ui/vault/index.ts +11 -1
- package/src/console/ui/vault/types.ts +26 -0
- package/src/docker/compose.ts +164 -61
- package/src/docker/derive.ts +106 -12
- package/src/docker/docker.test.ts +156 -110
- package/src/docker/helpers.ts +98 -0
- package/src/docker/images-config.test.ts +163 -0
- package/src/docker/index.ts +30 -5
- package/src/docker/recipes/index.ts +0 -3
- package/src/docker/recipes/llama-cpp.ts +4 -4
- package/src/docker/recipes/pgdog.ts +9 -2
- package/src/docker/resources.test.ts +71 -0
- package/src/docker/resources.ts +176 -0
- package/src/docker/stack-id.test.ts +11 -4
- package/src/docker/stack-id.ts +42 -32
- package/src/docker/stack.integration.test.ts +4 -15
- package/src/docker/types.ts +35 -3
- package/src/drivers/ai-ollama.integration.test.ts +2 -2
- package/src/drivers/conformance.test.ts +11 -12
- package/src/drivers/drizzle-dialect.test.ts +0 -4
- package/src/drivers/drizzle-dialect.ts +7 -13
- package/src/drivers/index.ts +24 -7
- package/src/drivers/journal-postgres.test.ts +3 -1
- package/src/drivers/journal-postgres.ts +4 -2
- package/src/drivers/meilisearch.ts +1 -1
- package/src/drivers/pglite.ts +28 -5
- package/src/drivers/types.ts +9 -11
- package/src/drivers/vault-aws-secrets-manager.test.ts +159 -0
- package/src/drivers/vault-aws-secrets-manager.ts +333 -0
- package/src/drivers/vault-builtin.test.ts +110 -0
- package/src/drivers/vault-builtin.ts +184 -0
- package/src/drivers/vault-driver-removal.test.ts +13 -0
- package/src/drivers/vault-managed.test.ts +95 -0
- package/src/drivers/vault-managed.ts +101 -25
- package/src/drivers/vault-types.ts +25 -5
- package/src/elements/ai/runtime.ts +1 -1
- package/src/elements/clock/chaos.test.ts +4 -1
- package/src/elements/clock/durable.ts +57 -4
- package/src/elements/clock.test.ts +13 -14
- package/src/elements/gate/constants.ts +18 -0
- package/src/elements/gate.test.ts +1 -1
- package/src/elements/gate.ts +2 -2
- package/src/elements/store/domain-ddl.test.ts +5 -12
- package/src/elements/store/emit-drizzle.ts +44 -19
- package/src/elements/store/index-boot.test.ts +15 -116
- package/src/elements/store/load-plugin-tables.ts +1 -1
- package/src/elements/store/resource-list-docs.fixture.ts +12 -6
- package/src/elements/store/resource-list-docs.test.ts +64 -44
- package/src/elements/store/resource.test.ts +17 -10
- package/src/elements/store/runtime.ts +9 -12
- package/src/elements/store/schema-decl.test.ts +16 -32
- package/src/elements/store/seed.test.ts +1 -2
- package/src/elements/store/seed.ts +7 -8
- package/src/elements/store/sql-condition.test.ts +2 -2
- package/src/elements/store/sql-session.test.ts +8 -10
- package/src/elements/store/sql-session.ts +10 -2
- package/src/elements/store.test.ts +13 -13
- package/src/elements/vault/audit.ts +233 -0
- package/src/elements/vault/boot-chain.test.ts +78 -0
- package/src/elements/vault/boot-chain.ts +43 -39
- package/src/elements/vault/builtin-adapter.test.ts +479 -0
- package/src/elements/vault/builtin-adapter.ts +1184 -0
- package/src/elements/vault/crypto.test.ts +237 -0
- package/src/elements/vault/crypto.ts +431 -0
- package/src/elements/vault/declare.ts +164 -3
- package/src/elements/vault/errors.ts +56 -0
- package/src/elements/vault/kms-unseal.test.ts +76 -0
- package/src/elements/vault/kms-unseal.ts +181 -0
- package/src/elements/vault/path.ts +90 -0
- package/src/elements/vault/resilience.test.ts +102 -0
- package/src/elements/vault/resilience.ts +107 -0
- package/src/elements/vault/runtime.ts +36 -4
- package/src/elements/vault/security-checklist.test.ts +130 -0
- package/src/elements/vault/storage.ts +448 -0
- package/src/elements/vault/types.ts +288 -0
- package/src/elements/vault/unseal.ts +150 -0
- package/src/elements/vault.test.ts +72 -4
- package/src/elements/vault.ts +91 -2
- package/src/full.ts +248 -0
- package/src/http.ts +41 -0
- package/src/i18n/interpolate-simple.ts +37 -0
- package/src/i18n/messages.ts +51 -4
- package/src/i18n-entry.ts +7 -0
- package/src/index.ts +35 -145
- package/src/journal-entry.ts +20 -0
- package/src/kernel/adopt-barrel-fresh.test.ts +25 -10
- package/src/kernel/app.ts +40 -42
- package/src/kernel/auto-registry.test.ts +2 -2
- package/src/kernel/boot-bind/ai.test.ts +5 -5
- package/src/kernel/boot-bind/ai.ts +2 -1
- package/src/kernel/boot-bind/channel.test.ts +6 -6
- package/src/kernel/boot-bind/channel.ts +5 -4
- package/src/kernel/boot-bind/clock.ts +5 -5
- package/src/kernel/boot-bind/gate.ts +6 -7
- package/src/kernel/boot-bind/honor-config.test.ts +42 -42
- package/src/kernel/boot-bind/journal.ts +5 -5
- package/src/kernel/boot-bind/signal.ts +3 -1
- package/src/kernel/boot-bind/store.test.ts +55 -37
- package/src/kernel/boot-bind/store.ts +24 -34
- package/src/kernel/boot-bind/vault.ts +19 -4
- package/src/kernel/boot.test.ts +12 -4
- package/src/kernel/boot.ts +31 -19
- package/src/kernel/budget-entry.ts +1 -1
- package/src/kernel/compensate.test.ts +288 -1
- package/src/kernel/compensate.ts +126 -0
- package/src/kernel/concurrency.test.ts +10 -9
- package/src/kernel/effects-stamping.test.ts +27 -2
- package/src/kernel/element-registries.ts +5 -3
- package/src/kernel/flow.ts +4 -2
- package/src/kernel/fx.test.ts +119 -3
- package/src/kernel/fx.ts +215 -40
- package/src/kernel/index.ts +14 -0
- package/src/kernel/journal.ts +130 -7
- package/src/kernel/pipeline.test.ts +20 -6
- package/src/kernel/redacted.test.ts +35 -0
- package/src/kernel/redacted.ts +24 -2
- package/src/kernel/router/create-default.ts +16 -0
- package/src/kernel/router/create-edge.ts +18 -0
- package/src/kernel/router/create.ts +23 -0
- package/src/kernel/router/index.ts +23 -0
- package/src/kernel/router/linear.ts +88 -0
- package/src/kernel/router/regexp.ts +188 -0
- package/src/kernel/router/smart.ts +120 -0
- package/src/kernel/router/trie.ts +108 -0
- package/src/kernel/router/types.ts +56 -0
- package/src/kernel/router.ts +18 -532
- package/src/kernel-entry.ts +43 -0
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/fixtures/skyport.manifest.json +1 -1
- package/src/plugins/config-source.test.ts +7 -7
- package/src/release/build-lib.ts +58 -0
- package/src/release/exports.test.ts +4 -2
- package/src/release/exports.ts +30 -4
- package/src/release/measure.ts +101 -22
- package/src/runs/duckdb.ts +7 -2
- package/src/shared/optional-peer.ts +41 -0
- package/src/term.test.ts +3 -44
- package/src/test/create-test-app.ts +12 -0
- package/src/test/provisions.integration.test.ts +1 -1
- package/src/test/reset-element-registries.ts +2 -0
- package/src/upgrade/codemods.test.ts +7 -20
- package/src/upgrade/codemods.ts +93 -60
- package/site/content/docs/console/access.mdx +0 -29
- package/site/content/docs/console/ai.mdx +0 -35
- package/site/content/docs/console/architecture.mdx +0 -35
- package/site/content/docs/console/channels.mdx +0 -37
- package/site/content/docs/console/clock.mdx +0 -51
- package/site/content/docs/console/flows.mdx +0 -31
- package/site/content/docs/console/gates.mdx +0 -73
- package/site/content/docs/console/index.mdx +0 -54
- package/site/content/docs/console/manifest-diff.mdx +0 -34
- package/site/content/docs/console/meta.json +0 -24
- package/site/content/docs/console/overview.mdx +0 -40
- package/site/content/docs/console/plugins.mdx +0 -41
- package/site/content/docs/console/privacy.mdx +0 -32
- package/site/content/docs/console/runs.mdx +0 -50
- package/site/content/docs/console/signals.mdx +0 -40
- package/site/content/docs/console/store.mdx +0 -32
- package/site/content/docs/console/tenancy.mdx +0 -32
- package/site/content/docs/console/traces.mdx +0 -38
- package/site/content/docs/console/vault.mdx +0 -41
- package/site/content/docs/recipes/openbao.mdx +0 -141
- package/src/cli/ask-dev-mode.ts +0 -40
- package/src/cli/dev-mode.test.ts +0 -45
- package/src/cli/dev-mode.ts +0 -78
- package/src/cli/openbao-bootstrap.test.ts +0 -150
- package/src/cli/openbao-bootstrap.ts +0 -321
- package/src/cli/openbao-restart.integration.test.ts +0 -145
- package/src/console/ui/dist/assets/panel-vault-Za1GyJfM.js +0 -1
- package/src/console/ui/dist/assets/style-C8MxEWPd.css +0 -3
- package/src/docker/recipes/openbao.ts +0 -47
- package/src/drivers/libsql.ts +0 -179
- package/src/drivers/sqlite.ts +0 -44
- package/src/drivers/vault-openbao.test.ts +0 -97
- package/src/drivers/vault-openbao.ts +0 -143
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real, already-established default driver ids per {@link ConfigEnv} —
|
|
3
|
+
* one source of truth for every driver map that has a single default table.
|
|
4
|
+
*
|
|
5
|
+
* Philosophy: we test on what we deploy. `dev`/`prod` share production
|
|
6
|
+
* protocols (Postgres, Redis, …); `test` uses PGLite for SQL and memory
|
|
7
|
+
* drivers where the protocol is simple.
|
|
8
|
+
*
|
|
9
|
+
* `store.index`, `channel.whatsapp` / `push`, and `ai` are intentionally
|
|
10
|
+
* absent — they don't have one established default across all three envs
|
|
11
|
+
* and keep using {@link resolveDriverId}'s legacy cascade.
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
mergeEnvDriverMap,
|
|
17
|
+
normalizeEnvDriverMap,
|
|
18
|
+
type DriversConfig,
|
|
19
|
+
type EnvDriverMap,
|
|
20
|
+
type EnvDriverInput,
|
|
21
|
+
} from "./index.ts";
|
|
22
|
+
|
|
23
|
+
/** `drivers.store.sql` — Postgres for dev/prod, PGLite for test. */
|
|
24
|
+
export const STORE_SQL_DEFAULTS: EnvDriverMap = {
|
|
25
|
+
dev: "postgres",
|
|
26
|
+
test: "pglite",
|
|
27
|
+
prod: "postgres",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** `drivers.store.kv` — Redis for dev/prod, in-memory for test. */
|
|
31
|
+
export const STORE_KV_DEFAULTS: EnvDriverMap = {
|
|
32
|
+
dev: "redis",
|
|
33
|
+
test: "memory",
|
|
34
|
+
prod: "redis",
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** `drivers.store.files` — S3 for dev/prod, in-memory for test. */
|
|
38
|
+
export const STORE_FILES_DEFAULTS: EnvDriverMap = {
|
|
39
|
+
dev: "s3",
|
|
40
|
+
test: "memory",
|
|
41
|
+
prod: "s3",
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** `drivers.signal` — Redis for dev/prod, in-memory for test. */
|
|
45
|
+
export const SIGNAL_DEFAULTS: EnvDriverMap = {
|
|
46
|
+
dev: "redis",
|
|
47
|
+
test: "memory",
|
|
48
|
+
prod: "redis",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** `drivers.clock` — Postgres cron for dev/prod, frozen clock in test. */
|
|
52
|
+
export const CLOCK_DEFAULTS: EnvDriverMap = {
|
|
53
|
+
dev: "postgres",
|
|
54
|
+
test: "frozen",
|
|
55
|
+
prod: "postgres",
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** `drivers.journal` — Postgres for dev/prod, in-memory for test. */
|
|
59
|
+
export const JOURNAL_DEFAULTS: EnvDriverMap = {
|
|
60
|
+
dev: "postgres",
|
|
61
|
+
test: "memory",
|
|
62
|
+
prod: "postgres",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* `drivers.vault` — OS env vars in dev, in-memory for test, and the built-in
|
|
67
|
+
* encrypted-at-rest store in prod (env layers still resolve first).
|
|
68
|
+
*/
|
|
69
|
+
export const VAULT_DEFAULTS: EnvDriverMap = {
|
|
70
|
+
dev: "env",
|
|
71
|
+
test: "memory",
|
|
72
|
+
prod: "vault",
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** `drivers.channel.email` — SMTP for dev/prod, console inbox for test. */
|
|
76
|
+
export const CHANNEL_EMAIL_DEFAULTS: EnvDriverMap = {
|
|
77
|
+
dev: "smtp",
|
|
78
|
+
test: "console",
|
|
79
|
+
prod: "smtp",
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* `drivers.channel.sms` — no default provider in any env; SMS is opt-in
|
|
84
|
+
* only (an unconfigured env simply gets no SMS channel).
|
|
85
|
+
*/
|
|
86
|
+
export const CHANNEL_SMS_DEFAULTS: EnvDriverMap = {};
|
|
87
|
+
|
|
88
|
+
/** Every driver map with one established default table, grouped by element. */
|
|
89
|
+
export const DRIVER_DEFAULTS = {
|
|
90
|
+
store: {
|
|
91
|
+
sql: STORE_SQL_DEFAULTS,
|
|
92
|
+
kv: STORE_KV_DEFAULTS,
|
|
93
|
+
files: STORE_FILES_DEFAULTS,
|
|
94
|
+
},
|
|
95
|
+
signal: SIGNAL_DEFAULTS,
|
|
96
|
+
clock: CLOCK_DEFAULTS,
|
|
97
|
+
journal: JOURNAL_DEFAULTS,
|
|
98
|
+
vault: VAULT_DEFAULTS,
|
|
99
|
+
channel: {
|
|
100
|
+
email: CHANNEL_EMAIL_DEFAULTS,
|
|
101
|
+
sms: CHANNEL_SMS_DEFAULTS,
|
|
102
|
+
},
|
|
103
|
+
} as const;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Every driver map from {@link DRIVER_DEFAULTS}, fully resolved — the
|
|
107
|
+
* developer's `oke.config.ts` override merged onto the real default,
|
|
108
|
+
* per-key, for all three {@link ConfigEnv} slots at once. This is the "full
|
|
109
|
+
* picture" `oke doctor` prints: what boot actually uses for every env, even
|
|
110
|
+
* when the config on disk only pins one key.
|
|
111
|
+
*/
|
|
112
|
+
export interface EffectiveDriversConfig {
|
|
113
|
+
readonly store: {
|
|
114
|
+
readonly sql: EnvDriverMap;
|
|
115
|
+
readonly kv: EnvDriverMap;
|
|
116
|
+
readonly files: EnvDriverMap;
|
|
117
|
+
};
|
|
118
|
+
readonly signal: EnvDriverMap;
|
|
119
|
+
readonly clock: EnvDriverMap;
|
|
120
|
+
readonly journal: EnvDriverMap;
|
|
121
|
+
readonly vault: EnvDriverMap;
|
|
122
|
+
readonly channel: {
|
|
123
|
+
readonly email: EnvDriverMap;
|
|
124
|
+
readonly sms: EnvDriverMap;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Merge every driver map in {@link DRIVER_DEFAULTS} against the matching
|
|
130
|
+
* slot of a loaded `oke.config.ts` `drivers` block.
|
|
131
|
+
*
|
|
132
|
+
* @param drivers - `drivers` block from a loaded `oke.config.ts` (already
|
|
133
|
+
* normalized if it came through `defineConfig`; normalized again here so
|
|
134
|
+
* an un-normalized/raw block is still handled)
|
|
135
|
+
*/
|
|
136
|
+
export function resolveEffectiveDrivers(
|
|
137
|
+
drivers: DriversConfig | undefined,
|
|
138
|
+
): EffectiveDriversConfig {
|
|
139
|
+
const merge = (map: EnvDriverInput | undefined, defaults: EnvDriverMap) =>
|
|
140
|
+
mergeEnvDriverMap(normalizeEnvDriverMap(map), defaults);
|
|
141
|
+
return {
|
|
142
|
+
store: {
|
|
143
|
+
sql: merge(drivers?.store?.sql, STORE_SQL_DEFAULTS),
|
|
144
|
+
kv: merge(drivers?.store?.kv, STORE_KV_DEFAULTS),
|
|
145
|
+
files: merge(drivers?.store?.files, STORE_FILES_DEFAULTS),
|
|
146
|
+
},
|
|
147
|
+
signal: merge(drivers?.signal, SIGNAL_DEFAULTS),
|
|
148
|
+
clock: merge(drivers?.clock, CLOCK_DEFAULTS),
|
|
149
|
+
journal: merge(drivers?.journal, JOURNAL_DEFAULTS),
|
|
150
|
+
vault: merge(drivers?.vault, VAULT_DEFAULTS),
|
|
151
|
+
channel: {
|
|
152
|
+
email: merge(drivers?.channel?.email, CHANNEL_EMAIL_DEFAULTS),
|
|
153
|
+
sms: merge(drivers?.channel?.sms, CHANNEL_SMS_DEFAULTS),
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
package/src/config/index.ts
CHANGED
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
* `oke.config.ts` surface. Subpath: `okengine/config`.
|
|
3
3
|
*
|
|
4
4
|
* Driver maps are protocol-named; vendor/image choice lives in `images`.
|
|
5
|
+
* Three environment targets: `dev` (Docker Compose), `test` (PGLite), `prod`.
|
|
5
6
|
* @module
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Environment role keys used in driver maps.
|
|
10
11
|
*
|
|
11
|
-
* - `
|
|
12
|
-
* - `
|
|
13
|
-
* - `test` — automated tests
|
|
12
|
+
* - `dev` — local development via Docker Compose (`oke dev`)
|
|
13
|
+
* - `test` — automated tests (`oke test` / PGLite)
|
|
14
14
|
* - `prod` — production deploy
|
|
15
15
|
*/
|
|
16
|
-
|
|
16
|
+
import type { VaultElementConfig } from "../elements/vault/types.ts";
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
export type { VaultElementConfig };
|
|
19
|
+
|
|
20
|
+
export type ConfigEnv = "dev" | "test" | "prod";
|
|
20
21
|
|
|
21
22
|
/** Pool options for SQL drivers. */
|
|
22
23
|
export interface DriverPoolOptions {
|
|
@@ -38,29 +39,26 @@ export type DriverRef =
|
|
|
38
39
|
readonly key?: unknown;
|
|
39
40
|
};
|
|
40
41
|
|
|
41
|
-
/** Map of env → driver ref. */
|
|
42
|
+
/** Map of env → driver ref (canonical three-key shape). */
|
|
42
43
|
export type EnvDriverMap = Partial<Record<ConfigEnv, DriverRef>>;
|
|
43
44
|
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
* Normalized by {@link normalizeEnvDriverMap}.
|
|
47
|
-
*/
|
|
48
|
-
export type RawEnvDriverMap = Partial<Record<ConfigEnv | LegacyConfigEnv, DriverRef>>;
|
|
45
|
+
/** Driver pin: bare ref (all envs) or per-env map (`dev` / `test` / `prod`). */
|
|
46
|
+
export type EnvDriverInput = DriverRef | EnvDriverMap;
|
|
49
47
|
|
|
50
48
|
/** Store facet driver maps. */
|
|
51
49
|
export interface StoreDriversConfig {
|
|
52
|
-
readonly sql?:
|
|
53
|
-
readonly kv?:
|
|
54
|
-
readonly files?:
|
|
55
|
-
readonly index?:
|
|
50
|
+
readonly sql?: EnvDriverInput;
|
|
51
|
+
readonly kv?: EnvDriverInput;
|
|
52
|
+
readonly files?: EnvDriverInput;
|
|
53
|
+
readonly index?: EnvDriverInput;
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
/** Channel medium → env driver map. */
|
|
59
57
|
export interface ChannelDriversConfig {
|
|
60
|
-
readonly email?:
|
|
61
|
-
readonly sms?:
|
|
62
|
-
readonly whatsapp?:
|
|
63
|
-
readonly push?:
|
|
58
|
+
readonly email?: EnvDriverInput;
|
|
59
|
+
readonly sms?: EnvDriverInput;
|
|
60
|
+
readonly whatsapp?: EnvDriverInput;
|
|
61
|
+
readonly push?: EnvDriverInput;
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
/** Top-level drivers block in {@link OkeConfig}. */
|
|
@@ -71,18 +69,65 @@ export interface DriversConfig {
|
|
|
71
69
|
*/
|
|
72
70
|
readonly prod?: readonly string[];
|
|
73
71
|
readonly store?: StoreDriversConfig;
|
|
74
|
-
readonly signal?:
|
|
75
|
-
readonly clock?:
|
|
72
|
+
readonly signal?: EnvDriverInput;
|
|
73
|
+
readonly clock?: EnvDriverInput;
|
|
76
74
|
/** Durable-run journal: `memory` · `file` · `postgres`. */
|
|
77
|
-
readonly journal?:
|
|
78
|
-
readonly vault?:
|
|
75
|
+
readonly journal?: EnvDriverInput;
|
|
76
|
+
readonly vault?: EnvDriverInput;
|
|
79
77
|
readonly channel?: ChannelDriversConfig;
|
|
80
|
-
readonly ai?:
|
|
81
|
-
readonly runs?:
|
|
78
|
+
readonly ai?: EnvDriverInput;
|
|
79
|
+
readonly runs?: EnvDriverInput;
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
/**
|
|
85
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Container image pins, nested the same way as {@link DriversConfig}:
|
|
84
|
+
* `store.*` / `channel.*` facets nest under their owning element; roles with
|
|
85
|
+
* no driver counterpart (`vault` picks a driver but pins its own image;
|
|
86
|
+
* `ai`, `pgdog`, `proxy` have no config-level element at all) stay flat.
|
|
87
|
+
*
|
|
88
|
+
* Always fully explicit — `images` has no hidden default merge. Omitted keys
|
|
89
|
+
* mean "no container for that role," never "inherit a default image."
|
|
90
|
+
*/
|
|
91
|
+
export interface ImagesConfig {
|
|
92
|
+
readonly store?: {
|
|
93
|
+
readonly sql?: string;
|
|
94
|
+
readonly kv?: string;
|
|
95
|
+
readonly files?: string;
|
|
96
|
+
readonly index?: string;
|
|
97
|
+
};
|
|
98
|
+
readonly channel?: {
|
|
99
|
+
readonly email?: string;
|
|
100
|
+
};
|
|
101
|
+
readonly vault?: string;
|
|
102
|
+
readonly ai?: string;
|
|
103
|
+
readonly pgdog?: string;
|
|
104
|
+
readonly proxy?: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Flatten {@link ImagesConfig} to the dotted-role `Record<string, string>`
|
|
109
|
+
* every internal consumer (compose role matching, credentials, env prefixes)
|
|
110
|
+
* has always kept working with — the nesting is a config-surface / type-safety
|
|
111
|
+
* concern only, not an internal representation change.
|
|
112
|
+
*
|
|
113
|
+
* @param images - Nested config-surface images (or `undefined`)
|
|
114
|
+
*/
|
|
115
|
+
export function flattenImagesConfig(
|
|
116
|
+
images: ImagesConfig | undefined,
|
|
117
|
+
): Readonly<Record<string, string>> {
|
|
118
|
+
if (!images) return {};
|
|
119
|
+
const out: Record<string, string> = {};
|
|
120
|
+
if (images.store?.sql) out["store.sql"] = images.store.sql;
|
|
121
|
+
if (images.store?.kv) out["store.kv"] = images.store.kv;
|
|
122
|
+
if (images.store?.files) out["store.files"] = images.store.files;
|
|
123
|
+
if (images.store?.index) out["store.index"] = images.store.index;
|
|
124
|
+
if (images.channel?.email) out["channel.email"] = images.channel.email;
|
|
125
|
+
if (images.vault) out.vault = images.vault;
|
|
126
|
+
if (images.ai) out.ai = images.ai;
|
|
127
|
+
if (images.pgdog) out.pgdog = images.pgdog;
|
|
128
|
+
if (images.proxy) out.proxy = images.proxy;
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
86
131
|
|
|
87
132
|
/** i18n config. */
|
|
88
133
|
export interface I18nConfig {
|
|
@@ -142,9 +187,9 @@ export type PrivacyConfig = Readonly<Record<string, unknown>>;
|
|
|
142
187
|
*/
|
|
143
188
|
export interface DbConfig {
|
|
144
189
|
/**
|
|
145
|
-
* Auto-run `oke db push` when domain schema files change under `oke dev
|
|
146
|
-
*
|
|
147
|
-
* Forced off for `
|
|
190
|
+
* Auto-run `oke db push` when domain schema files change under `oke dev`.
|
|
191
|
+
* Default `true`. Set `false` to opt out explicitly.
|
|
192
|
+
* Forced off for `prod`.
|
|
148
193
|
*/
|
|
149
194
|
readonly autoPush?: boolean;
|
|
150
195
|
/**
|
|
@@ -160,7 +205,8 @@ export interface DbConfig {
|
|
|
160
205
|
readonly declare?: string;
|
|
161
206
|
/**
|
|
162
207
|
* Generated Drizzle schema path written from abstract decls.
|
|
163
|
-
* Default `"src/db/schema.
|
|
208
|
+
* Default `"src/db/schema.drizzle.ts"` (prior `"src/db/schema.generated.ts"`;
|
|
209
|
+
* legacy `"src/schema.generated.ts"`).
|
|
164
210
|
* Point `drizzle.config.ts` `schema` at this file when using the abstract path.
|
|
165
211
|
*/
|
|
166
212
|
readonly generated?: string;
|
|
@@ -193,6 +239,11 @@ export interface OkeConfig {
|
|
|
193
239
|
* Domain Drizzle schema sync (`oke db …`). Not related to `oke schema`.
|
|
194
240
|
*/
|
|
195
241
|
readonly db?: DbConfig;
|
|
242
|
+
/**
|
|
243
|
+
* Encrypted-at-rest Vault settings (algorithm, master key, audit, seal).
|
|
244
|
+
* Contracts stay in code — this block only configures the backend.
|
|
245
|
+
*/
|
|
246
|
+
readonly vault?: VaultElementConfig;
|
|
196
247
|
readonly topology?: "monolith" | "services";
|
|
197
248
|
readonly ports?: PortsConfig;
|
|
198
249
|
readonly console?: ConsoleConfig;
|
|
@@ -201,8 +252,8 @@ export interface OkeConfig {
|
|
|
201
252
|
/**
|
|
202
253
|
* Whether domain auto-DDL (`ensureFromMeta`) should run for this env.
|
|
203
254
|
*
|
|
204
|
-
* - `ensure` — `CREATE TABLE IF NOT EXISTS` on first touch (test /
|
|
205
|
-
* - `off` — migrations / `oke db push` own DDL (
|
|
255
|
+
* - `ensure` — `CREATE TABLE IF NOT EXISTS` on first touch (test / dev opt-out)
|
|
256
|
+
* - `off` — migrations / `oke db push` own DDL (dev+autoPush, prod)
|
|
206
257
|
*/
|
|
207
258
|
export type DomainDdlMode = "ensure" | "off";
|
|
208
259
|
|
|
@@ -214,173 +265,237 @@ export type DomainDdlMode = "ensure" | "off";
|
|
|
214
265
|
*/
|
|
215
266
|
export function resolveDomainDdlMode(env: ConfigEnv, autoPush = true): DomainDdlMode {
|
|
216
267
|
if (env === "test") return "ensure";
|
|
217
|
-
if (env === "
|
|
268
|
+
if (env === "prod") return "off";
|
|
218
269
|
return autoPush ? "off" : "ensure";
|
|
219
270
|
}
|
|
220
271
|
|
|
221
|
-
/**
|
|
222
|
-
|
|
272
|
+
/**
|
|
273
|
+
* Extract the protocol id from a {@link DriverRef}.
|
|
274
|
+
*
|
|
275
|
+
* @param ref - Driver ref
|
|
276
|
+
*/
|
|
277
|
+
export function driverRefId(ref: DriverRef | undefined): string | undefined {
|
|
278
|
+
if (ref === undefined) return undefined;
|
|
279
|
+
return typeof ref === "string" ? ref : ref.driver;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* True when `value` is a bare driver pin (string or `{ driver, … }`), not an env map.
|
|
284
|
+
*
|
|
285
|
+
* @param value - Unknown driver input
|
|
286
|
+
*/
|
|
287
|
+
function isBareDriverRef(value: unknown): value is DriverRef {
|
|
288
|
+
if (typeof value === "string") return true;
|
|
289
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
290
|
+
const obj = value as Record<string, unknown>;
|
|
291
|
+
return typeof obj.driver === "string";
|
|
292
|
+
}
|
|
223
293
|
|
|
224
294
|
/**
|
|
225
|
-
*
|
|
295
|
+
* Expand a bare {@link DriverRef} to all three env keys.
|
|
226
296
|
*
|
|
227
|
-
*
|
|
297
|
+
* @param ref - Driver ref applied to every env
|
|
298
|
+
*/
|
|
299
|
+
export function expandDriverRefToMap(ref: DriverRef): EnvDriverMap {
|
|
300
|
+
return { dev: ref, test: ref, prod: ref };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Expand a bare driver pin to `{ dev, test, prod }`, or pass through a map.
|
|
228
305
|
*
|
|
229
|
-
* @param raw - Env → driver map
|
|
306
|
+
* @param raw - Env → driver map, bare ref, or undefined
|
|
230
307
|
*/
|
|
231
|
-
export function normalizeEnvDriverMap(
|
|
232
|
-
raw
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
console.warn(
|
|
240
|
-
"oke: driver map keys `dev`/`stack` are deprecated — use `local`/`docker` (run `oke upgrade`)",
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
const out: EnvDriverMap = { ...(raw as EnvDriverMap) };
|
|
244
|
-
const legacy = raw as RawEnvDriverMap;
|
|
245
|
-
if (legacy.local === undefined && legacy.dev !== undefined) {
|
|
246
|
-
out.local = legacy.dev;
|
|
247
|
-
}
|
|
248
|
-
if (legacy.docker === undefined && legacy.stack !== undefined) {
|
|
249
|
-
out.docker = legacy.stack;
|
|
250
|
-
}
|
|
251
|
-
delete (out as RawEnvDriverMap).dev;
|
|
252
|
-
delete (out as RawEnvDriverMap).stack;
|
|
308
|
+
export function normalizeEnvDriverMap(raw: EnvDriverInput | undefined): EnvDriverMap | undefined {
|
|
309
|
+
if (raw === undefined) return undefined;
|
|
310
|
+
if (isBareDriverRef(raw)) return expandDriverRefToMap(raw);
|
|
311
|
+
const record = raw as EnvDriverMap;
|
|
312
|
+
const out: EnvDriverMap = {};
|
|
313
|
+
if (record.dev !== undefined) out.dev = record.dev;
|
|
314
|
+
if (record.test !== undefined) out.test = record.test;
|
|
315
|
+
if (record.prod !== undefined) out.prod = record.prod;
|
|
253
316
|
return out;
|
|
254
317
|
}
|
|
255
318
|
|
|
256
319
|
/**
|
|
257
|
-
*
|
|
320
|
+
* Apply `fn` to every env-driver slot under a drivers block.
|
|
258
321
|
*
|
|
259
322
|
* @param drivers - Drivers block
|
|
323
|
+
* @param fn - Per-slot transform
|
|
260
324
|
*/
|
|
261
|
-
|
|
262
|
-
drivers: DriversConfig
|
|
263
|
-
|
|
264
|
-
|
|
325
|
+
function mapDriversSlots(
|
|
326
|
+
drivers: DriversConfig,
|
|
327
|
+
fn: (input: EnvDriverInput | undefined) => EnvDriverInput | undefined,
|
|
328
|
+
): DriversConfig {
|
|
265
329
|
const store = drivers.store
|
|
266
330
|
? {
|
|
267
331
|
...drivers.store,
|
|
268
|
-
sql:
|
|
269
|
-
kv:
|
|
270
|
-
files:
|
|
271
|
-
index:
|
|
332
|
+
sql: fn(drivers.store.sql),
|
|
333
|
+
kv: fn(drivers.store.kv),
|
|
334
|
+
files: fn(drivers.store.files),
|
|
335
|
+
index: fn(drivers.store.index),
|
|
272
336
|
}
|
|
273
337
|
: undefined;
|
|
274
338
|
const channel = drivers.channel
|
|
275
339
|
? {
|
|
276
340
|
...drivers.channel,
|
|
277
|
-
email:
|
|
278
|
-
sms:
|
|
279
|
-
whatsapp:
|
|
280
|
-
push:
|
|
341
|
+
email: fn(drivers.channel.email),
|
|
342
|
+
sms: fn(drivers.channel.sms),
|
|
343
|
+
whatsapp: fn(drivers.channel.whatsapp),
|
|
344
|
+
push: fn(drivers.channel.push),
|
|
281
345
|
}
|
|
282
346
|
: undefined;
|
|
283
347
|
return {
|
|
284
348
|
...drivers,
|
|
285
349
|
...(store !== undefined ? { store } : {}),
|
|
286
|
-
signal:
|
|
287
|
-
clock:
|
|
288
|
-
journal:
|
|
289
|
-
vault:
|
|
350
|
+
signal: fn(drivers.signal),
|
|
351
|
+
clock: fn(drivers.clock),
|
|
352
|
+
journal: fn(drivers.journal),
|
|
353
|
+
vault: fn(drivers.vault),
|
|
290
354
|
...(channel !== undefined ? { channel } : {}),
|
|
291
|
-
ai:
|
|
292
|
-
runs:
|
|
355
|
+
ai: fn(drivers.ai),
|
|
356
|
+
runs: fn(drivers.runs),
|
|
293
357
|
};
|
|
294
358
|
}
|
|
295
359
|
|
|
296
360
|
/**
|
|
297
|
-
*
|
|
361
|
+
* Normalize every env map under a drivers block (expand shorthand + rewrite keys).
|
|
362
|
+
*
|
|
363
|
+
* @param drivers - Drivers block
|
|
364
|
+
*/
|
|
365
|
+
export function normalizeDriversConfig(
|
|
366
|
+
drivers: DriversConfig | undefined,
|
|
367
|
+
): DriversConfig | undefined {
|
|
368
|
+
if (!drivers) return undefined;
|
|
369
|
+
return mapDriversSlots(drivers, normalizeEnvDriverMap);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Merge a developer's partial {@link EnvDriverMap} onto the real default map
|
|
374
|
+
* for one specific driver — per environment key, never a whole-object
|
|
375
|
+
* replace. An unset key keeps that driver's own real default; it never
|
|
376
|
+
* inherits a sibling key's value.
|
|
377
|
+
*
|
|
378
|
+
* @param override - Developer-supplied partial map (may be `undefined`)
|
|
379
|
+
* @param defaults - Real, already-established default map for this driver
|
|
380
|
+
*/
|
|
381
|
+
export function mergeEnvDriverMap(
|
|
382
|
+
override: EnvDriverMap | undefined,
|
|
383
|
+
defaults: EnvDriverMap,
|
|
384
|
+
): EnvDriverMap {
|
|
385
|
+
return {
|
|
386
|
+
dev: override?.dev ?? defaults.dev,
|
|
387
|
+
test: override?.test ?? defaults.test,
|
|
388
|
+
prod: override?.prod ?? defaults.prod,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Fill missing `dev` pins from `prod` (compose laptop ≈ production protocols).
|
|
298
394
|
*
|
|
299
395
|
* @param map - Env → driver map
|
|
300
396
|
*/
|
|
301
|
-
export function
|
|
397
|
+
export function fillDevFromProd(map: EnvDriverMap | undefined): EnvDriverMap | undefined {
|
|
302
398
|
if (!map) return undefined;
|
|
303
|
-
if (map.
|
|
304
|
-
return { ...map,
|
|
399
|
+
if (map.dev !== undefined || map.prod === undefined) return map;
|
|
400
|
+
return { ...map, dev: map.prod };
|
|
305
401
|
}
|
|
306
402
|
|
|
307
403
|
/**
|
|
308
|
-
* Copy production driver pins onto `
|
|
404
|
+
* Copy production driver pins onto `dev` wherever `dev` is omitted.
|
|
309
405
|
*
|
|
310
406
|
* @param drivers - Drivers block
|
|
311
407
|
*/
|
|
312
|
-
export function
|
|
408
|
+
export function fillDriversDevFromProd(
|
|
313
409
|
drivers: DriversConfig | undefined,
|
|
314
410
|
): DriversConfig | undefined {
|
|
315
411
|
if (!drivers) return undefined;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
412
|
+
return mapDriversSlots(drivers, (input) => fillDevFromProd(input as EnvDriverMap | undefined));
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Walk every driver pin and throw if `sqlite` appears or test SQL is not `pglite`.
|
|
417
|
+
*
|
|
418
|
+
* @param drivers - Normalized drivers block
|
|
419
|
+
*/
|
|
420
|
+
export function assertDriverSafety(drivers: DriversConfig | undefined): void {
|
|
421
|
+
if (!drivers) return;
|
|
422
|
+
const maps: readonly (EnvDriverMap | undefined)[] = [
|
|
423
|
+
drivers.store?.sql as EnvDriverMap | undefined,
|
|
424
|
+
drivers.store?.kv as EnvDriverMap | undefined,
|
|
425
|
+
drivers.store?.files as EnvDriverMap | undefined,
|
|
426
|
+
drivers.store?.index as EnvDriverMap | undefined,
|
|
427
|
+
drivers.signal as EnvDriverMap | undefined,
|
|
428
|
+
drivers.clock as EnvDriverMap | undefined,
|
|
429
|
+
drivers.journal as EnvDriverMap | undefined,
|
|
430
|
+
drivers.vault as EnvDriverMap | undefined,
|
|
431
|
+
drivers.channel?.email as EnvDriverMap | undefined,
|
|
432
|
+
drivers.channel?.sms as EnvDriverMap | undefined,
|
|
433
|
+
drivers.channel?.whatsapp as EnvDriverMap | undefined,
|
|
434
|
+
drivers.channel?.push as EnvDriverMap | undefined,
|
|
435
|
+
drivers.ai as EnvDriverMap | undefined,
|
|
436
|
+
drivers.runs as EnvDriverMap | undefined,
|
|
437
|
+
];
|
|
438
|
+
for (const map of maps) {
|
|
439
|
+
if (!map) continue;
|
|
440
|
+
for (const env of ["dev", "test", "prod"] as const) {
|
|
441
|
+
const id = driverRefId(map[env]);
|
|
442
|
+
if (id === "sqlite" || id === "libsql") {
|
|
443
|
+
throw new Error(
|
|
444
|
+
`oke.config: "${id}" was removed — use postgres (dev/prod) or pglite (test); index → pgvector/memory`,
|
|
445
|
+
);
|
|
332
446
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
journal: fillDockerFromProd(drivers.journal),
|
|
340
|
-
vault: fillDockerFromProd(drivers.vault),
|
|
341
|
-
...(channel !== undefined ? { channel } : {}),
|
|
342
|
-
ai: fillDockerFromProd(drivers.ai),
|
|
343
|
-
runs: fillDockerFromProd(drivers.runs),
|
|
344
|
-
};
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
const sqlTest = driverRefId((drivers.store?.sql as EnvDriverMap | undefined)?.test);
|
|
450
|
+
if (sqlTest !== undefined && sqlTest !== "pglite") {
|
|
451
|
+
throw new Error(`oke.config: drivers.store.sql.test must be "pglite" (got "${sqlTest}")`);
|
|
452
|
+
}
|
|
345
453
|
}
|
|
346
454
|
|
|
347
455
|
/**
|
|
348
456
|
* Define an `oke.config.ts` document.
|
|
349
457
|
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
* Legacy `dev`/`stack` keys are normalized to `local`/`docker`.
|
|
458
|
+
* Bare string pins expand to all three envs. Missing `dev` pins fill from
|
|
459
|
+
* `prod`. Rejects `sqlite` / `libsql` and non-`pglite` test SQL.
|
|
353
460
|
*
|
|
354
461
|
* @param config - Driver / tenancy / i18n / topology
|
|
355
462
|
*/
|
|
356
463
|
export function defineConfig(config: OkeConfig): OkeConfig {
|
|
357
464
|
if (!config.drivers) return config;
|
|
358
465
|
const normalized = normalizeDriversConfig(config.drivers);
|
|
466
|
+
const filled = fillDriversDevFromProd(normalized);
|
|
467
|
+
assertDriverSafety(filled);
|
|
359
468
|
return {
|
|
360
469
|
...config,
|
|
361
|
-
drivers:
|
|
470
|
+
drivers: filled,
|
|
362
471
|
};
|
|
363
472
|
}
|
|
364
473
|
|
|
365
474
|
/**
|
|
366
475
|
* Resolve a driver id for an env from an {@link EnvDriverMap}.
|
|
367
476
|
*
|
|
368
|
-
* `
|
|
369
|
-
*
|
|
477
|
+
* With `defaults` given, the developer's map is merged onto it per-key via
|
|
478
|
+
* {@link mergeEnvDriverMap} and the active env's slot is read directly — a
|
|
479
|
+
* key the developer never set keeps that driver's real default, full stop.
|
|
370
480
|
*
|
|
371
|
-
*
|
|
481
|
+
* Without `defaults` (legacy path — `store.index`, `channel.whatsapp` /
|
|
482
|
+
* `push`, `ai`): cascade is `env → dev → prod → test`.
|
|
483
|
+
*
|
|
484
|
+
* @param map - Env → driver map (or bare ref)
|
|
372
485
|
* @param env - Active environment
|
|
486
|
+
* @param defaults - Real default map for this specific driver (per-key merge)
|
|
373
487
|
*/
|
|
374
488
|
export function resolveDriverId(
|
|
375
|
-
map:
|
|
489
|
+
map: EnvDriverInput | undefined,
|
|
376
490
|
env: ConfigEnv,
|
|
491
|
+
defaults?: EnvDriverMap,
|
|
377
492
|
): string | undefined {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
env
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
return
|
|
493
|
+
const normalized = normalizeEnvDriverMap(map);
|
|
494
|
+
if (defaults) {
|
|
495
|
+
const merged = mergeEnvDriverMap(normalized, defaults);
|
|
496
|
+
return driverRefId(merged[env]);
|
|
497
|
+
}
|
|
498
|
+
if (!normalized) return undefined;
|
|
499
|
+
const ref = normalized[env] ?? normalized.dev ?? normalized.prod ?? normalized.test;
|
|
500
|
+
return driverRefId(ref);
|
|
386
501
|
}
|