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
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* flow under that unit — the stale/missing `.adopt()` barrel case.
|
|
4
4
|
*
|
|
5
5
|
* Mirrors `effects-stamping.test.ts`'s OKE1008 shape exactly: opt-in only
|
|
6
|
-
* via `rootDir`, `
|
|
7
|
-
* `
|
|
6
|
+
* via `rootDir`, `test` warns once (dev-loop stays unbroken),
|
|
7
|
+
* `dev`+compose / `prod` hard-fail (`OKE1009`) — never a silently-incomplete route
|
|
8
8
|
* table in a deploy-shaped environment.
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -41,23 +41,23 @@ describe("assertAdoptBarrelFresh — direct", () => {
|
|
|
41
41
|
try {
|
|
42
42
|
await makeUnitDir(root, "notes");
|
|
43
43
|
const notesFlow = flow("notes.create", { do: () => ({ ok: true as const }) });
|
|
44
|
-
await expect(assertAdoptBarrelFresh([notesFlow], "
|
|
44
|
+
await expect(assertAdoptBarrelFresh([notesFlow], "dev", root, true)).resolves.toBeUndefined();
|
|
45
45
|
} finally {
|
|
46
46
|
await rm(root, { recursive: true, force: true });
|
|
47
47
|
}
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
test("stale: unit on disk, zero adopted flows for it —
|
|
50
|
+
test("stale: unit on disk, zero adopted flows for it — dev+compose hard-fails OKE1009", async () => {
|
|
51
51
|
const root = await mkdtemp(join(tmpdir(), "oke-adopt-fresh-"));
|
|
52
52
|
try {
|
|
53
53
|
await makeUnitDir(root, "notes");
|
|
54
|
-
await expect(assertAdoptBarrelFresh([], "
|
|
54
|
+
await expect(assertAdoptBarrelFresh([], "dev", root, true)).rejects.toThrow(/OKE1009/);
|
|
55
55
|
} finally {
|
|
56
56
|
await rm(root, { recursive: true, force: true });
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
test("stale: prod — same posture as
|
|
60
|
+
test("stale: prod — same posture as dev+compose", async () => {
|
|
61
61
|
const root = await mkdtemp(join(tmpdir(), "oke-adopt-fresh-"));
|
|
62
62
|
try {
|
|
63
63
|
await makeUnitDir(root, "notes");
|
|
@@ -67,11 +67,11 @@ describe("assertAdoptBarrelFresh — direct", () => {
|
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
test("stale:
|
|
70
|
+
test("stale: test — warns, never throws (dev-loop stays unbroken)", async () => {
|
|
71
71
|
const root = await mkdtemp(join(tmpdir(), "oke-adopt-fresh-"));
|
|
72
72
|
try {
|
|
73
73
|
await makeUnitDir(root, "notes");
|
|
74
|
-
await expect(assertAdoptBarrelFresh([], "
|
|
74
|
+
await expect(assertAdoptBarrelFresh([], "test", root)).resolves.toBeUndefined();
|
|
75
75
|
} finally {
|
|
76
76
|
await rm(root, { recursive: true, force: true });
|
|
77
77
|
}
|
|
@@ -79,7 +79,7 @@ describe("assertAdoptBarrelFresh — direct", () => {
|
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
describe("boot-level: stale barrel through a real oke() boot", () => {
|
|
82
|
-
test("
|
|
82
|
+
test("dev+compose: real app.boot() hard-fails OKE1009 when a unit folder was never adopted", async () => {
|
|
83
83
|
const root = await mkdtemp(join(tmpdir(), "oke-adopt-fresh-"));
|
|
84
84
|
try {
|
|
85
85
|
// "notes" exists on disk but this app only ever adopted "main" —
|
|
@@ -94,7 +94,22 @@ describe("boot-level: stale barrel through a real oke() boot", () => {
|
|
|
94
94
|
const app = oke({ name: "stale-barrel", gate: { unguardedHttp: "allow" } });
|
|
95
95
|
|
|
96
96
|
await expect(
|
|
97
|
-
app.boot({
|
|
97
|
+
app.boot({
|
|
98
|
+
env: "dev",
|
|
99
|
+
docker: true,
|
|
100
|
+
rootDir: root,
|
|
101
|
+
unguardedHttp: "allow",
|
|
102
|
+
startScheduler: false,
|
|
103
|
+
config: {
|
|
104
|
+
drivers: {
|
|
105
|
+
store: {
|
|
106
|
+
sql: { dev: "memory" },
|
|
107
|
+
kv: { dev: "memory" },
|
|
108
|
+
},
|
|
109
|
+
channel: { email: { dev: "console" } },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
98
113
|
).rejects.toThrow(/OKE1009/);
|
|
99
114
|
} finally {
|
|
100
115
|
await rm(root, { recursive: true, force: true });
|
package/src/kernel/app.ts
CHANGED
|
@@ -41,6 +41,7 @@ import { runWithLocale } from "../i18n/locale-context.ts";
|
|
|
41
41
|
import { getMessageCatalogs, matchConfiguredLocale } from "../i18n/messages.ts";
|
|
42
42
|
import { runDurable } from "../elements/clock/durable.ts";
|
|
43
43
|
import { isFlow, type AnyFlowDef } from "./flow.ts";
|
|
44
|
+
import { failureCodeOf, runCompensationPhase } from "./compensate.ts";
|
|
44
45
|
import { fxRetry } from "./concurrency.ts";
|
|
45
46
|
import {
|
|
46
47
|
createFxContext,
|
|
@@ -85,6 +86,7 @@ import type { JournalRuntime } from "./boot-bind/journal.ts";
|
|
|
85
86
|
import { listBindings, resetBindings, type Binding } from "./on.ts";
|
|
86
87
|
import {
|
|
87
88
|
channelTemplateRegistry,
|
|
89
|
+
requiredEnvRegistry,
|
|
88
90
|
secretRegistry,
|
|
89
91
|
signalRegistry,
|
|
90
92
|
storeRegistry,
|
|
@@ -159,11 +161,11 @@ export interface OkeOptions {
|
|
|
159
161
|
* subject key.
|
|
160
162
|
*/
|
|
161
163
|
readonly archiveInputFields?: readonly string[];
|
|
162
|
-
/** Active environment for {@link OkeApp.boot} (
|
|
164
|
+
/** Active environment for {@link OkeApp.boot} (`dev` / `test` / `prod`). */
|
|
163
165
|
readonly env?: BootOptions["env"];
|
|
164
166
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
+
* Compose mode (`oke dev` / `OKE_DOCKER=1`) — select the `dev` driver
|
|
168
|
+
* profile at boot when `env` is omitted.
|
|
167
169
|
*/
|
|
168
170
|
readonly docker?: BootOptions["docker"];
|
|
169
171
|
/** Optional `oke.config.ts` document consumed at boot. */
|
|
@@ -485,22 +487,35 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
485
487
|
// explicitly-passed decl that is also in the registry is not doubled.
|
|
486
488
|
const registrySnapshot =
|
|
487
489
|
registry === "ignore"
|
|
488
|
-
? { stores: [], secrets: [], signals: [], channelTemplates: [] }
|
|
490
|
+
? { stores: [], secrets: [], requiredEnv: [], signals: [], channelTemplates: [] }
|
|
489
491
|
: {
|
|
490
492
|
stores: storeRegistry.slice(),
|
|
491
493
|
secrets: secretRegistry.slice(),
|
|
494
|
+
requiredEnv: requiredEnvRegistry.slice(),
|
|
492
495
|
signals: signalRegistry.slice(),
|
|
493
496
|
channelTemplates: channelTemplateRegistry.slice(),
|
|
494
497
|
};
|
|
495
498
|
if (registry === "consume") {
|
|
496
499
|
storeRegistry.length = 0;
|
|
497
500
|
secretRegistry.length = 0;
|
|
501
|
+
requiredEnvRegistry.length = 0;
|
|
498
502
|
signalRegistry.length = 0;
|
|
499
503
|
channelTemplateRegistry.length = 0;
|
|
500
504
|
}
|
|
501
505
|
const effectiveStores = mergeUnique(options.stores, registrySnapshot.stores);
|
|
502
506
|
const effectiveSecrets = mergeUnique(options.secrets, registrySnapshot.secrets);
|
|
503
507
|
const effectiveSignals = mergeUnique(options.signals, registrySnapshot.signals);
|
|
508
|
+
/**
|
|
509
|
+
* Fold registered `vault.env.required` names into the vault boot options so
|
|
510
|
+
* boot reports missing env vars in the same gap list as missing secrets.
|
|
511
|
+
*
|
|
512
|
+
* @param base - Vault options from `oke({ vault })` / a boot override
|
|
513
|
+
*/
|
|
514
|
+
const withRequiredEnv = (base: BootOptions["vault"]): BootOptions["vault"] => {
|
|
515
|
+
const names = [...new Set([...(base?.requiredEnv ?? []), ...registrySnapshot.requiredEnv])];
|
|
516
|
+
if (names.length === 0) return base;
|
|
517
|
+
return { ...(base ?? {}), requiredEnv: names };
|
|
518
|
+
};
|
|
504
519
|
// Stay `undefined` (never a defined-but-empty object) when neither an
|
|
505
520
|
// explicit `options.channel` nor a registered template exists — a defined
|
|
506
521
|
// object here would flip `resolveElementNeeds`'s `channel` need to `true`
|
|
@@ -655,7 +670,7 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
655
670
|
let bootResult: BootResult | undefined;
|
|
656
671
|
let bootPromise: Promise<BootResult> | undefined;
|
|
657
672
|
let readyState: ReadyState = "booting";
|
|
658
|
-
let bootEnv: BootOptions["env"] = options.env
|
|
673
|
+
let bootEnv: BootOptions["env"] = options.env;
|
|
659
674
|
let authBinding: AppAuthBinding | undefined =
|
|
660
675
|
gateConfig.auth !== undefined
|
|
661
676
|
? createAppAuthBinding({
|
|
@@ -787,7 +802,7 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
787
802
|
}
|
|
788
803
|
}
|
|
789
804
|
|
|
790
|
-
/** Boot-time orphan scan — `running`/`sleeping`
|
|
805
|
+
/** Boot-time orphan scan — `running`/`sleeping`/`compensating` with no live lease. */
|
|
791
806
|
async function resumeOrphanedDurableRuns(): Promise<void> {
|
|
792
807
|
const { store } = activeJournal();
|
|
793
808
|
if (!hasJournalLease(store)) return;
|
|
@@ -807,7 +822,15 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
807
822
|
const { bootApplication, resolveElementNeeds } = await import("./boot.ts");
|
|
808
823
|
const { assertHttpGatePosture } = await import("../elements/gate/boot.ts");
|
|
809
824
|
const { assertPluginNeeds, buildAvailableNeedTokens } = await import("./plugin-needs.ts");
|
|
810
|
-
|
|
825
|
+
const dockerFlag =
|
|
826
|
+
overrides?.docker === true ||
|
|
827
|
+
(overrides?.docker !== false &&
|
|
828
|
+
(options.docker === true || (options.docker !== false && process.env.OKE_DOCKER === "1")));
|
|
829
|
+
// Mirror bootApplication: prod / compose-dev / else test (PGLite + memory).
|
|
830
|
+
bootEnv =
|
|
831
|
+
overrides?.env ??
|
|
832
|
+
options.env ??
|
|
833
|
+
(process.env.NODE_ENV === "production" ? "prod" : dockerFlag ? "dev" : "test");
|
|
811
834
|
|
|
812
835
|
// Prod without a real secret fails even if construction minted a dev secret.
|
|
813
836
|
if (gateConfig.auth?.secretMinted && bootEnv === "prod") {
|
|
@@ -830,7 +853,7 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
830
853
|
config: overrides?.config ?? options.config,
|
|
831
854
|
elements: overrides?.elements ?? options.elements,
|
|
832
855
|
secrets: overrides?.secrets ?? effectiveSecrets,
|
|
833
|
-
vault: overrides?.vault ?? options.vault,
|
|
856
|
+
vault: withRequiredEnv(overrides?.vault ?? options.vault),
|
|
834
857
|
gates: [...baseGates, ...authGates],
|
|
835
858
|
signals: overrides?.signals ?? effectiveSignals,
|
|
836
859
|
clocks: overrides?.clocks ?? options.clocks,
|
|
@@ -900,7 +923,7 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
900
923
|
rootDir: overrides?.rootDir ?? options.rootDir,
|
|
901
924
|
elements: overrides?.elements ?? options.elements,
|
|
902
925
|
secrets: [...baseSecrets, ...pluginSecrets],
|
|
903
|
-
vault: overrides?.vault ?? options.vault,
|
|
926
|
+
vault: withRequiredEnv(overrides?.vault ?? options.vault),
|
|
904
927
|
gates: [...baseGates, ...authGates, ...pluginGates],
|
|
905
928
|
unguardedHttp,
|
|
906
929
|
signals: [...baseSignals, ...pluginSignals],
|
|
@@ -1013,7 +1036,7 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
1013
1036
|
registerFlow(flowDef);
|
|
1014
1037
|
|
|
1015
1038
|
const i18nConfig = options.config?.i18n;
|
|
1016
|
-
const configuredLocales = i18nConfig?.locales ?? ["en"
|
|
1039
|
+
const configuredLocales = i18nConfig?.locales ?? ["en"];
|
|
1017
1040
|
const defaultLocale = i18nConfig?.default ?? "en";
|
|
1018
1041
|
const acceptLanguage = extras?.request?.headers.get("accept-language") ?? undefined;
|
|
1019
1042
|
const resolvedLocale = matchConfiguredLocale(
|
|
@@ -1281,30 +1304,13 @@ export function oke(options: OkeOptions): OkeApp {
|
|
|
1281
1304
|
});
|
|
1282
1305
|
} else if (!sleeping && isTerminalFailure(result)) {
|
|
1283
1306
|
const terminalErr = result.failure ?? result.ctx.error;
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
input: ctx.input as never,
|
|
1292
|
-
error: terminalErr,
|
|
1293
|
-
completedSteps,
|
|
1294
|
-
},
|
|
1295
|
-
fx,
|
|
1296
|
-
);
|
|
1297
|
-
} catch (compErr) {
|
|
1298
|
-
await journalSession.commit("failed", {
|
|
1299
|
-
error: `compensate:${failureCodeOf(compErr)}`,
|
|
1300
|
-
});
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
if (journalSession.run.status === "running") {
|
|
1304
|
-
await journalSession.commit("failed", {
|
|
1305
|
-
error: failureCodeOf(terminalErr),
|
|
1306
|
-
});
|
|
1307
|
-
}
|
|
1307
|
+
await runCompensationPhase({
|
|
1308
|
+
flow: flowDef,
|
|
1309
|
+
input: ctx.input,
|
|
1310
|
+
session: journalSession,
|
|
1311
|
+
fx,
|
|
1312
|
+
error: terminalErr,
|
|
1313
|
+
});
|
|
1308
1314
|
} else if (!sleeping) {
|
|
1309
1315
|
await journalSession.commit("completed", { output: result.output });
|
|
1310
1316
|
}
|
|
@@ -1699,14 +1705,6 @@ function isTerminalFailure(result: PipelineResult): boolean {
|
|
|
1699
1705
|
return result.ctx.error !== undefined && !isJournalSuspend(result.ctx.error);
|
|
1700
1706
|
}
|
|
1701
1707
|
|
|
1702
|
-
/** Machine-readable code for journal / Runs failure fields. */
|
|
1703
|
-
function failureCodeOf(err: unknown): string {
|
|
1704
|
-
if (isFlowFailure(err)) return err.error.code;
|
|
1705
|
-
if (err instanceof Error && err.name && err.name !== "Error") return err.name;
|
|
1706
|
-
if (err instanceof Error && err.message) return err.message.slice(0, 120);
|
|
1707
|
-
return "Error";
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
1708
|
/** Coerce a thrown value into a FlowFailure for Runs wide events. */
|
|
1711
1709
|
function failureFromUnknown(err: unknown): FlowFailure {
|
|
1712
1710
|
if (isFlowFailure(err)) return err;
|
|
@@ -40,7 +40,7 @@ describe("oke() auto-registry — stores/secrets/signals/channel.templates", ()
|
|
|
40
40
|
sends: ["before-note-created"],
|
|
41
41
|
},
|
|
42
42
|
do: async (_input, fx) => {
|
|
43
|
-
const secret = fx.vault(secretBefore);
|
|
43
|
+
const secret = await fx.vault.get(secretBefore);
|
|
44
44
|
await fx.emit(signalBefore, {});
|
|
45
45
|
await fx.send(templateBefore, { to: "you@localhost", data: {} });
|
|
46
46
|
return { secret };
|
|
@@ -78,7 +78,7 @@ describe("oke() auto-registry — stores/secrets/signals/channel.templates", ()
|
|
|
78
78
|
sends: ["after-note-created"],
|
|
79
79
|
},
|
|
80
80
|
do: async (_input, fx) => {
|
|
81
|
-
const secret = fx.vault(secretAfter);
|
|
81
|
+
const secret = await fx.vault.get(secretAfter);
|
|
82
82
|
await fx.emit(signalAfter, {});
|
|
83
83
|
await fx.send(templateAfter, { to: "you@localhost", data: {} });
|
|
84
84
|
return { secret };
|
|
@@ -16,15 +16,15 @@ describe("ai boot binder", () => {
|
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
test("resolveAiDriverId defaults to mock; honours config + OKE_AI_DRIVER in docker", () => {
|
|
19
|
-
expect(resolveAiDriverId({}, "
|
|
20
|
-
expect(resolveAiDriverId({ config: { drivers: { ai: {
|
|
19
|
+
expect(resolveAiDriverId({}, "test")).toBe("mock");
|
|
20
|
+
expect(resolveAiDriverId({ config: { drivers: { ai: { test: "ollama" } } } }, "test")).toBe(
|
|
21
21
|
"ollama",
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
const prev = process.env.OKE_AI_DRIVER;
|
|
25
25
|
process.env.OKE_AI_DRIVER = "ollama";
|
|
26
26
|
try {
|
|
27
|
-
expect(resolveAiDriverId({}, "
|
|
27
|
+
expect(resolveAiDriverId({}, "test", true)).toBe("ollama");
|
|
28
28
|
} finally {
|
|
29
29
|
if (prev === undefined) delete process.env.OKE_AI_DRIVER;
|
|
30
30
|
else process.env.OKE_AI_DRIVER = prev;
|
|
@@ -48,12 +48,12 @@ describe("ai boot binder", () => {
|
|
|
48
48
|
test("bindAi uses injected defaultDriver over config (tests stay on mock)", () => {
|
|
49
49
|
const runtime = bindAi(
|
|
50
50
|
{
|
|
51
|
-
config: { drivers: { ai: {
|
|
51
|
+
config: { drivers: { ai: { test: "ollama" } } },
|
|
52
52
|
ai: { defaultDriver: mockAiDriver },
|
|
53
53
|
},
|
|
54
54
|
undefined,
|
|
55
55
|
() => 0,
|
|
56
|
-
"
|
|
56
|
+
"test",
|
|
57
57
|
);
|
|
58
58
|
expect(runtime.autoCacheDisabled).toBe(true);
|
|
59
59
|
});
|
|
@@ -33,7 +33,7 @@ export function bindAi(
|
|
|
33
33
|
options: BootOptions,
|
|
34
34
|
gate: GateRuntime | undefined,
|
|
35
35
|
now: () => number,
|
|
36
|
-
env: ConfigEnv = "
|
|
36
|
+
env: ConfigEnv = "test",
|
|
37
37
|
docker = false,
|
|
38
38
|
): AiRuntime {
|
|
39
39
|
const id = resolveAiDriverId(options, env, docker);
|
|
@@ -115,6 +115,7 @@ export function openDefaultsFor(id: string, docker = false): AiOpenOptions {
|
|
|
115
115
|
return {
|
|
116
116
|
...(apiKey ? { apiKey } : {}),
|
|
117
117
|
...(baseUrl ? { baseUrl } : {}),
|
|
118
|
+
...(process.env.OKE_AI_MODEL?.trim() ? { model: process.env.OKE_AI_MODEL.trim() } : {}),
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
121
|
return {};
|
|
@@ -58,23 +58,23 @@ describe("bindChannel driver resolution", () => {
|
|
|
58
58
|
config: {
|
|
59
59
|
drivers: {
|
|
60
60
|
channel: {
|
|
61
|
-
email: {
|
|
62
|
-
sms: {
|
|
61
|
+
email: { dev: "smtp", test: "console", prod: "sndr" },
|
|
62
|
+
sms: { dev: "taqnyat", test: "msegat", prod: "taqnyat" },
|
|
63
63
|
},
|
|
64
64
|
},
|
|
65
65
|
},
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
test("uses console locally and smtp in docker", () => {
|
|
69
|
-
expect(resolveEmailDriverId(options, "
|
|
70
|
-
expect(resolveEmailDriverId(options, "
|
|
69
|
+
expect(resolveEmailDriverId(options, "test", false)).toBe("console");
|
|
70
|
+
expect(resolveEmailDriverId(options, "dev", true)).toBe("smtp");
|
|
71
71
|
expect(resolveEmailDriverId(options, "prod", false)).toBe("sndr");
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
test("resolves sms driver ids", () => {
|
|
75
|
-
expect(resolveSmsDriverId(options, "local")).toBe("console");
|
|
76
|
-
expect(resolveSmsDriverId(options, "docker")).toBe("taqnyat");
|
|
77
75
|
expect(resolveSmsDriverId(options, "test")).toBe("msegat");
|
|
76
|
+
expect(resolveSmsDriverId(options, "dev")).toBe("taqnyat");
|
|
77
|
+
expect(resolveSmsDriverId(options, "prod")).toBe("taqnyat");
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
test("parses SMTP_URL and optional auth overrides", () => {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { resolveDriverId, type ConfigEnv } from "../../config/index.ts";
|
|
6
|
+
import { CHANNEL_EMAIL_DEFAULTS, CHANNEL_SMS_DEFAULTS } from "../../config/driver-defaults.ts";
|
|
6
7
|
import { openConsoleChannel } from "../../drivers/channel-console.ts";
|
|
7
8
|
import { openMsegatChannel } from "../../drivers/channel-msegat.ts";
|
|
8
9
|
import { openResendChannel } from "../../drivers/channel-resend.ts";
|
|
@@ -81,9 +82,9 @@ export function resolveEmailDriverId(
|
|
|
81
82
|
env: ConfigEnv,
|
|
82
83
|
docker: boolean,
|
|
83
84
|
): string {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
)
|
|
85
|
+
void docker;
|
|
86
|
+
// Defaults cover every ConfigEnv key, so this is never undefined.
|
|
87
|
+
return resolveDriverId(options.config?.drivers?.channel?.email, env, CHANNEL_EMAIL_DEFAULTS)!;
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
/**
|
|
@@ -93,7 +94,7 @@ export function resolveEmailDriverId(
|
|
|
93
94
|
* @param env - Active environment
|
|
94
95
|
*/
|
|
95
96
|
export function resolveSmsDriverId(options: BootOptions, env: ConfigEnv): string | undefined {
|
|
96
|
-
return resolveDriverId(options.config?.drivers?.channel?.sms, env);
|
|
97
|
+
return resolveDriverId(options.config?.drivers?.channel?.sms, env, CHANNEL_SMS_DEFAULTS);
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
/**
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "../../elements/clock.ts";
|
|
16
16
|
import { createPostgresCronStore } from "../../drivers/clock-postgres.ts";
|
|
17
17
|
import { resolveDriverId, type ConfigEnv } from "../../config/index.ts";
|
|
18
|
+
import { CLOCK_DEFAULTS } from "../../config/driver-defaults.ts";
|
|
18
19
|
import type { BootOptions } from "../boot.ts";
|
|
19
20
|
|
|
20
21
|
/** Result of binding a clock runtime. */
|
|
@@ -33,9 +34,8 @@ export const DEFAULT_FILE_CRON_PATH = ".oke/crons.json";
|
|
|
33
34
|
* @param env - Active environment
|
|
34
35
|
*/
|
|
35
36
|
export function resolveClockDriverId(options: BootOptions, env: ConfigEnv): string {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return env === "test" ? "frozen" : "memory";
|
|
37
|
+
// Defaults cover every ConfigEnv key, so this is never undefined.
|
|
38
|
+
return resolveDriverId(options.config?.drivers?.clock, env, CLOCK_DEFAULTS)!;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -79,8 +79,8 @@ export async function bindClock(
|
|
|
79
79
|
const url = process.env.DATABASE_URL ?? process.env.OKE_STORE_SQL_URL ?? undefined;
|
|
80
80
|
if (!url) {
|
|
81
81
|
throw new Error(
|
|
82
|
-
env === "
|
|
83
|
-
? 'oke boot: clock driver "postgres" needs DATABASE_URL (did `oke dev
|
|
82
|
+
env === "dev"
|
|
83
|
+
? 'oke boot: clock driver "postgres" needs DATABASE_URL (did `oke dev` write docker/.env.docker?)'
|
|
84
84
|
: 'oke boot: clock driver "postgres" needs DATABASE_URL',
|
|
85
85
|
);
|
|
86
86
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { resolveDriverId, type ConfigEnv } from "../../config/index.ts";
|
|
6
|
+
import { STORE_KV_DEFAULTS } from "../../config/driver-defaults.ts";
|
|
6
7
|
import { memoryDrivers } from "../../drivers/memory.ts";
|
|
7
8
|
import { redisDriver } from "../../drivers/redis.ts";
|
|
8
9
|
import type { KvClientLike } from "../../drivers/types.ts";
|
|
@@ -27,10 +28,8 @@ export function resolveGateKvDriverId(
|
|
|
27
28
|
const fromEnv = process.env.OKE_KV_DRIVER?.trim();
|
|
28
29
|
if (docker && fromEnv === "redis") return "redis";
|
|
29
30
|
if (docker && fromEnv === "memory") return "memory";
|
|
30
|
-
const resolved = resolveDriverId(options.config?.drivers?.store?.kv, env);
|
|
31
|
-
|
|
32
|
-
if (resolved === "memory") return "memory";
|
|
33
|
-
return docker ? "redis" : "memory";
|
|
31
|
+
const resolved = resolveDriverId(options.config?.drivers?.store?.kv, env, STORE_KV_DEFAULTS);
|
|
32
|
+
return resolved === "redis" ? "redis" : "memory";
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
function kvUrlFor(docker: boolean): string {
|
|
@@ -38,8 +37,8 @@ function kvUrlFor(docker: boolean): string {
|
|
|
38
37
|
if (!url) {
|
|
39
38
|
throw new Error(
|
|
40
39
|
docker
|
|
41
|
-
? "oke boot: gate redis kv needs REDIS_URL (did `oke dev
|
|
42
|
-
: "oke boot: gate redis kv needs REDIS_URL — declare drivers.store.kv memory for
|
|
40
|
+
? "oke boot: gate redis kv needs REDIS_URL (did `oke dev` write docker/.env.docker?)"
|
|
41
|
+
: "oke boot: gate redis kv needs REDIS_URL — declare drivers.store.kv memory for test, or set REDIS_URL",
|
|
43
42
|
);
|
|
44
43
|
}
|
|
45
44
|
return url;
|
|
@@ -56,7 +55,7 @@ function kvUrlFor(docker: boolean): string {
|
|
|
56
55
|
export async function bindGate(
|
|
57
56
|
options: BootOptions,
|
|
58
57
|
now: () => number,
|
|
59
|
-
env: ConfigEnv = "
|
|
58
|
+
env: ConfigEnv = "test",
|
|
60
59
|
docker = false,
|
|
61
60
|
): Promise<GateRuntime> {
|
|
62
61
|
const kvId = resolveGateKvDriverId(options, env, docker);
|