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,12 +3,46 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
|
+
import { flattenImagesConfig } from "../config/index.ts";
|
|
6
7
|
import {
|
|
7
8
|
defaultImagesFromConfig,
|
|
8
9
|
resolveImages,
|
|
9
10
|
dockerDevDriverMismatches,
|
|
10
11
|
} from "./load-config.ts";
|
|
11
12
|
|
|
13
|
+
describe("flattenImagesConfig", () => {
|
|
14
|
+
test("flattens store/channel nesting to dotted keys; flat roles pass through", () => {
|
|
15
|
+
expect(
|
|
16
|
+
flattenImagesConfig({
|
|
17
|
+
store: {
|
|
18
|
+
sql: "postgres:18-alpine",
|
|
19
|
+
kv: "redis:8-alpine",
|
|
20
|
+
files: "rustfs/rustfs:1.0.0",
|
|
21
|
+
index: "getmeili/meilisearch:v1.37",
|
|
22
|
+
},
|
|
23
|
+
channel: { email: "axllent/mailpit:v1.22.3" },
|
|
24
|
+
ai: "ollama/ollama:0.32.6",
|
|
25
|
+
pgdog: "ghcr.io/pgdogdev/pgdog:v0.1.51",
|
|
26
|
+
proxy: "caddy:2-alpine",
|
|
27
|
+
}),
|
|
28
|
+
).toEqual({
|
|
29
|
+
"store.sql": "postgres:18-alpine",
|
|
30
|
+
"store.kv": "redis:8-alpine",
|
|
31
|
+
"store.files": "rustfs/rustfs:1.0.0",
|
|
32
|
+
"store.index": "getmeili/meilisearch:v1.37",
|
|
33
|
+
"channel.email": "axllent/mailpit:v1.22.3",
|
|
34
|
+
ai: "ollama/ollama:0.32.6",
|
|
35
|
+
pgdog: "ghcr.io/pgdogdev/pgdog:v0.1.51",
|
|
36
|
+
proxy: "caddy:2-alpine",
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("undefined / empty input yields empty map", () => {
|
|
41
|
+
expect(flattenImagesConfig(undefined)).toEqual({});
|
|
42
|
+
expect(flattenImagesConfig({})).toEqual({});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
12
46
|
describe("defaultImagesFromConfig", () => {
|
|
13
47
|
test("maps postgres + redis prod drivers", () => {
|
|
14
48
|
const images = defaultImagesFromConfig({
|
|
@@ -67,7 +101,7 @@ describe("defaultImagesFromConfig", () => {
|
|
|
67
101
|
expect(defaultImagesFromConfig({})).toEqual({});
|
|
68
102
|
expect(
|
|
69
103
|
defaultImagesFromConfig({
|
|
70
|
-
drivers: { store: { sql: { prod: "
|
|
104
|
+
drivers: { store: { sql: { prod: "memory" } } },
|
|
71
105
|
}),
|
|
72
106
|
).toEqual({});
|
|
73
107
|
});
|
|
@@ -82,7 +116,7 @@ describe("resolveImages", () => {
|
|
|
82
116
|
kv: { prod: "redis" },
|
|
83
117
|
},
|
|
84
118
|
},
|
|
85
|
-
images: {
|
|
119
|
+
images: { store: { sql: "pgvector/pgvector:pg17" } },
|
|
86
120
|
});
|
|
87
121
|
expect(images).toEqual({ "store.sql": "pgvector/pgvector:pg17" });
|
|
88
122
|
});
|
|
@@ -102,20 +136,20 @@ describe("resolveImages", () => {
|
|
|
102
136
|
});
|
|
103
137
|
|
|
104
138
|
describe("dockerDevDriverMismatches", () => {
|
|
105
|
-
test("flags
|
|
139
|
+
test("flags dev pglite/memory when containers are up", () => {
|
|
106
140
|
const mismatches = dockerDevDriverMismatches(
|
|
107
141
|
{
|
|
108
142
|
drivers: {
|
|
109
143
|
store: {
|
|
110
|
-
sql: {
|
|
111
|
-
kv: {
|
|
144
|
+
sql: { dev: "pglite", test: "pglite", prod: "postgres" },
|
|
145
|
+
kv: { test: "memory", dev: "memory", prod: "memory" },
|
|
112
146
|
},
|
|
113
147
|
},
|
|
114
148
|
},
|
|
115
149
|
["store.sql", "store.kv"],
|
|
116
150
|
);
|
|
117
151
|
expect(mismatches).toEqual([
|
|
118
|
-
{ label: "sql", using: "
|
|
152
|
+
{ label: "sql", using: "pglite", container: "postgres" },
|
|
119
153
|
{ label: "kv", using: "memory", container: "redis" },
|
|
120
154
|
]);
|
|
121
155
|
});
|
|
@@ -125,8 +159,8 @@ describe("dockerDevDriverMismatches", () => {
|
|
|
125
159
|
{
|
|
126
160
|
drivers: {
|
|
127
161
|
store: {
|
|
128
|
-
sql: {
|
|
129
|
-
kv: {
|
|
162
|
+
sql: { dev: "postgres", test: "pglite", prod: "postgres" },
|
|
163
|
+
kv: { dev: "redis", test: "memory", prod: "redis" },
|
|
130
164
|
},
|
|
131
165
|
},
|
|
132
166
|
},
|
|
@@ -140,8 +174,8 @@ describe("dockerDevDriverMismatches", () => {
|
|
|
140
174
|
{
|
|
141
175
|
drivers: {
|
|
142
176
|
store: {
|
|
143
|
-
sql: {
|
|
144
|
-
kv: {
|
|
177
|
+
sql: { dev: "postgres", test: "pglite", prod: "postgres" },
|
|
178
|
+
kv: { dev: "redis", test: "memory", prod: "redis" },
|
|
145
179
|
},
|
|
146
180
|
},
|
|
147
181
|
},
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI rejects removed env keys / drivers in oke.config source.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, test } from "bun:test";
|
|
6
|
+
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { assertOkeConfigSource, loadOkeConfig } from "./load-config.ts";
|
|
10
|
+
|
|
11
|
+
describe("assertOkeConfigSource", () => {
|
|
12
|
+
test("rejects local: env keys", () => {
|
|
13
|
+
expect(() =>
|
|
14
|
+
assertOkeConfigSource(`drivers: { store: { sql: { local: "postgres" } } }`),
|
|
15
|
+
).toThrow(`"local" is no longer a valid environment key in oke.config.ts.`);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('rejects "sqlite" driver pins', () => {
|
|
19
|
+
expect(() => assertOkeConfigSource(`drivers: { store: { sql: { dev: "sqlite" } } }`)).toThrow(
|
|
20
|
+
`"sqlite" is no longer a valid driver in oke.config.ts.`,
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("allows modern three-key maps", () => {
|
|
25
|
+
expect(() =>
|
|
26
|
+
assertOkeConfigSource(`sql: { dev: "postgres", test: "pglite", prod: "postgres" }`),
|
|
27
|
+
).not.toThrow();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("does not false-positive on localhost", () => {
|
|
31
|
+
expect(() => assertOkeConfigSource(`url: "http://localhost:5432"`)).not.toThrow();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("loadOkeConfig source gate", () => {
|
|
36
|
+
test("fails before import when local: is present", async () => {
|
|
37
|
+
const dir = await mkdtemp(join(tmpdir(), "oke-cfg-local-"));
|
|
38
|
+
try {
|
|
39
|
+
await writeFile(
|
|
40
|
+
join(dir, "oke.config.ts"),
|
|
41
|
+
`export default { drivers: { store: { sql: { local: "postgres", test: "pglite", prod: "postgres" } } } };\n`,
|
|
42
|
+
);
|
|
43
|
+
await expect(loadOkeConfig(dir)).rejects.toThrow(
|
|
44
|
+
`"local" is no longer a valid environment key in oke.config.ts.`,
|
|
45
|
+
);
|
|
46
|
+
} finally {
|
|
47
|
+
await rm(dir, { recursive: true, force: true });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
package/src/cli/load-config.ts
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
driverRefId,
|
|
8
|
+
flattenImagesConfig,
|
|
9
|
+
normalizeEnvDriverMap,
|
|
10
|
+
type EnvDriverInput,
|
|
11
|
+
type OkeConfig,
|
|
12
|
+
} from "../config/index.ts";
|
|
7
13
|
import type { Manifest } from "../manifest/types.ts";
|
|
8
14
|
|
|
9
15
|
/** Default image pins when `images` is omitted but prod drivers need containers. */
|
|
@@ -11,27 +17,15 @@ const DEFAULT_SQL_IMAGE = "postgres:18-alpine";
|
|
|
11
17
|
const DEFAULT_PGVECTOR_IMAGE = "pgvector/pgvector:pg17";
|
|
12
18
|
const DEFAULT_PGDOG_IMAGE = "ghcr.io/pgdogdev/pgdog:v0.1.51";
|
|
13
19
|
const DEFAULT_KV_IMAGE = "redis:8-alpine";
|
|
14
|
-
const DEFAULT_VAULT_IMAGE = "openbao/openbao:2.6.1";
|
|
15
20
|
|
|
16
21
|
/**
|
|
17
|
-
*
|
|
22
|
+
* Prefer `dev` then `prod` for a driver map (compose infra ≈ production).
|
|
18
23
|
*
|
|
19
|
-
* @param
|
|
24
|
+
* @param map - Env driver input (normalized first)
|
|
20
25
|
*/
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Prefer `docker` then `prod` for a driver map (compose infra ≈ production).
|
|
28
|
-
*
|
|
29
|
-
* @param map - Env driver map
|
|
30
|
-
*/
|
|
31
|
-
function dockerOrProdId(
|
|
32
|
-
map: { readonly docker?: DriverRef; readonly prod?: DriverRef } | undefined,
|
|
33
|
-
): string | undefined {
|
|
34
|
-
return driverId(map?.docker) ?? driverId(map?.prod);
|
|
26
|
+
function dockerOrProdId(map: EnvDriverInput | undefined): string | undefined {
|
|
27
|
+
const normalized = normalizeEnvDriverMap(map);
|
|
28
|
+
return driverRefId(normalized?.dev) ?? driverRefId(normalized?.prod);
|
|
35
29
|
}
|
|
36
30
|
|
|
37
31
|
/**
|
|
@@ -75,11 +69,6 @@ export function defaultImagesFromConfig(config: OkeConfig): Readonly<Record<stri
|
|
|
75
69
|
out["store.kv"] = DEFAULT_KV_IMAGE;
|
|
76
70
|
}
|
|
77
71
|
|
|
78
|
-
const vault = dockerOrProdId(config.drivers?.vault);
|
|
79
|
-
if (vault === "openbao") {
|
|
80
|
-
out.vault = DEFAULT_VAULT_IMAGE;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
72
|
return out;
|
|
84
73
|
}
|
|
85
74
|
|
|
@@ -89,6 +78,21 @@ export interface LoadedConfig {
|
|
|
89
78
|
readonly path: string;
|
|
90
79
|
}
|
|
91
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Reject removed env keys / drivers in `oke.config.*` source.
|
|
83
|
+
* Migration is documented — no soft-compat rewrite.
|
|
84
|
+
*
|
|
85
|
+
* @param source - File contents
|
|
86
|
+
*/
|
|
87
|
+
export function assertOkeConfigSource(source: string): void {
|
|
88
|
+
if (/(^|[^\w.])local\s*:/.test(source)) {
|
|
89
|
+
throw new Error(`"local" is no longer a valid environment key in oke.config.ts.`);
|
|
90
|
+
}
|
|
91
|
+
if (/(["'])sqlite\1/.test(source)) {
|
|
92
|
+
throw new Error(`"sqlite" is no longer a valid driver in oke.config.ts.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
92
96
|
/**
|
|
93
97
|
* Load `oke.config.ts` (or `.js` / `.mts`) from a directory.
|
|
94
98
|
*
|
|
@@ -110,6 +114,8 @@ export async function loadOkeConfig(
|
|
|
110
114
|
for (const path of candidates) {
|
|
111
115
|
const file = Bun.file(path);
|
|
112
116
|
if (!(await file.exists())) continue;
|
|
117
|
+
const source = await file.text();
|
|
118
|
+
assertOkeConfigSource(source);
|
|
113
119
|
const mod = (await import(path)) as { default?: OkeConfig };
|
|
114
120
|
if (!mod.default || typeof mod.default !== "object") {
|
|
115
121
|
throw new Error(`oke: ${path} must default-export defineConfig({...})`);
|
|
@@ -145,7 +151,7 @@ export function resolveImages(
|
|
|
145
151
|
config?: OkeConfig,
|
|
146
152
|
manifest?: Manifest,
|
|
147
153
|
): Readonly<Record<string, string>> {
|
|
148
|
-
const explicit = config?.images
|
|
154
|
+
const explicit = config?.images ? flattenImagesConfig(config.images) : manifest?.images;
|
|
149
155
|
if (explicit && Object.keys(explicit).length > 0) return explicit;
|
|
150
156
|
if (config) return defaultImagesFromConfig(config);
|
|
151
157
|
return {};
|
|
@@ -174,14 +180,14 @@ export function dockerDevDriverMismatches(
|
|
|
174
180
|
): readonly StackDriverMismatch[] {
|
|
175
181
|
const roles = new Set(stackRoles);
|
|
176
182
|
const out: StackDriverMismatch[] = [];
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
183
|
+
const sqlMap = normalizeEnvDriverMap(config.drivers?.store?.sql);
|
|
184
|
+
const kvMap = normalizeEnvDriverMap(config.drivers?.store?.kv);
|
|
185
|
+
const sqlDocker = driverRefId(sqlMap?.dev) ?? driverRefId(sqlMap?.prod);
|
|
186
|
+
const kvDocker = driverRefId(kvMap?.dev) ?? driverRefId(kvMap?.prod);
|
|
181
187
|
|
|
182
188
|
if (
|
|
183
189
|
roles.has("store.sql") &&
|
|
184
|
-
(sqlDocker === "
|
|
190
|
+
(sqlDocker === "memory" || sqlDocker === "pglite" || sqlDocker === undefined)
|
|
185
191
|
) {
|
|
186
192
|
out.push({
|
|
187
193
|
label: "sql",
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* opts into the `meilisearch` store.index driver. This module:
|
|
6
6
|
*
|
|
7
7
|
* - generates the master key once and persists it under `.oke/meilisearch/`
|
|
8
|
-
* (`0700` dir / `0600` file, atomic write —
|
|
9
|
-
* OpenBao, minus the init/unseal ceremony: a single static key),
|
|
8
|
+
* (`0700` dir / `0600` file, atomic write — a single static key),
|
|
10
9
|
* - resolves the `meilisearch` binary from `PATH` (a documented prerequisite,
|
|
11
10
|
* like Docker for `--docker`; we never auto-download binaries),
|
|
12
11
|
* - spawns it via `Bun.spawn` with its own data dir + port, polls `/health`,
|
package/src/cli/mode.ts
CHANGED
|
@@ -1,65 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `oke mode
|
|
3
|
-
* Setting a mode also syncs domain schema for that env (emit + push).
|
|
2
|
+
* `oke mode` — removed. `oke dev` always uses Docker Compose.
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
|
-
import { parseDevMode, readDevMode, writeDevMode, type DevMode } from "./dev-mode.ts";
|
|
7
|
-
import { sqlDialectForEnv, syncDevSchema } from "./dev-schema-sync.ts";
|
|
8
|
-
import { loadOkeConfig } from "./load-config.ts";
|
|
9
|
-
|
|
10
5
|
/**
|
|
11
|
-
* CLI entry for `oke mode`.
|
|
6
|
+
* CLI entry for deprecated `oke mode`.
|
|
12
7
|
*
|
|
13
|
-
* @param
|
|
8
|
+
* @param _args - Ignored
|
|
14
9
|
*/
|
|
15
|
-
export async function modeCli(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
console.log(`oke mode [local|docker]
|
|
20
|
-
|
|
21
|
-
Get or set the default infrastructure mode for \`oke dev\`
|
|
22
|
-
(saved in .oke/mode). Setting a mode syncs domain schema for that env:
|
|
23
|
-
emits schema.generated.ts for the active dialect, then runs \`oke db push\`.
|
|
24
|
-
Data planes stay isolated — switching modes never copies rows.
|
|
25
|
-
Session flags \`oke dev --local\` / \`oke dev --docker\` never change this
|
|
26
|
-
preference.
|
|
27
|
-
`);
|
|
28
|
-
return 0;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const positional = args.filter((a) => !a.startsWith("-"));
|
|
33
|
-
if (positional.length === 0) {
|
|
34
|
-
const saved = await readDevMode(cwd);
|
|
35
|
-
if (saved === null) {
|
|
36
|
-
console.log("oke mode: unset (default local until chosen)");
|
|
37
|
-
return 0;
|
|
38
|
-
}
|
|
39
|
-
console.log(saved);
|
|
40
|
-
return 0;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const next = parseDevMode(positional[0]);
|
|
44
|
-
if (next === null) {
|
|
45
|
-
console.error(`oke mode: expected local|docker, got ${JSON.stringify(positional[0])}`);
|
|
46
|
-
return 1;
|
|
47
|
-
}
|
|
48
|
-
await writeDevMode(cwd, next satisfies DevMode);
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const result = await syncDevSchema(cwd, next);
|
|
52
|
-
console.log(`oke mode: saved ${next} · dialect ${result.dialect}`);
|
|
53
|
-
return result.code;
|
|
54
|
-
} catch (err) {
|
|
55
|
-
const loaded = await loadOkeConfig(cwd).catch(() => null);
|
|
56
|
-
const dialect = loaded?.config
|
|
57
|
-
? sqlDialectForEnv(loaded.config, next).dialect
|
|
58
|
-
: next === "docker"
|
|
59
|
-
? "postgresql"
|
|
60
|
-
: "sqlite";
|
|
61
|
-
console.error(`oke mode: saved ${next} · dialect ${dialect}`);
|
|
62
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
63
|
-
return 1;
|
|
64
|
-
}
|
|
10
|
+
export async function modeCli(_args: readonly string[]): Promise<number> {
|
|
11
|
+
void _args;
|
|
12
|
+
console.error("oke mode was removed — `oke dev` always uses Docker Compose");
|
|
13
|
+
return 1;
|
|
65
14
|
}
|
package/src/cli/registry.ts
CHANGED
|
@@ -84,6 +84,27 @@ const HELP: CliFlag = {
|
|
|
84
84
|
summary: "Show help",
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
+
const VAULT_KEY: CliFlag = {
|
|
88
|
+
long: "--key",
|
|
89
|
+
takesValue: true,
|
|
90
|
+
valueName: "base64|-",
|
|
91
|
+
summary: "Master key (`-` = stdin; else env / interactive prompt)",
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const VAULT_NEW_KEY: CliFlag = {
|
|
95
|
+
long: "--new-key",
|
|
96
|
+
takesValue: true,
|
|
97
|
+
valueName: "base64|-",
|
|
98
|
+
summary: "New master key for resume (`-` = stdin)",
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const VAULT_URL: CliFlag = {
|
|
102
|
+
long: "--url",
|
|
103
|
+
takesValue: true,
|
|
104
|
+
valueName: "url",
|
|
105
|
+
summary: "SQL URL (else DATABASE_URL)",
|
|
106
|
+
};
|
|
107
|
+
|
|
87
108
|
/**
|
|
88
109
|
* Canonical `oke` command catalogue.
|
|
89
110
|
*
|
|
@@ -93,24 +114,19 @@ const HELP: CliFlag = {
|
|
|
93
114
|
export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
94
115
|
{
|
|
95
116
|
name: "dev",
|
|
96
|
-
summary: "watch · hot reload · Console · client types",
|
|
117
|
+
summary: "watch · hot reload · Console · client types (Docker Compose)",
|
|
97
118
|
leaf: true,
|
|
98
119
|
flags: [
|
|
99
|
-
{
|
|
100
|
-
long: "--local",
|
|
101
|
-
short: "-l",
|
|
102
|
-
summary: "Session-only local mode (in-memory; no compose)",
|
|
103
|
-
},
|
|
104
120
|
{
|
|
105
121
|
long: "--docker",
|
|
106
122
|
short: "-d",
|
|
107
123
|
takesValue: true,
|
|
108
124
|
valueName: "roles",
|
|
109
|
-
summary: "
|
|
125
|
+
summary: "Optional compose role filter (default: all roles)",
|
|
110
126
|
},
|
|
111
127
|
{
|
|
112
128
|
long: "--no-db-push",
|
|
113
|
-
summary: "Disable auto `oke db push` on schema change
|
|
129
|
+
summary: "Disable auto `oke db push` on schema change",
|
|
114
130
|
},
|
|
115
131
|
ENTRY,
|
|
116
132
|
HELP,
|
|
@@ -118,7 +134,13 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
118
134
|
},
|
|
119
135
|
{
|
|
120
136
|
name: "mode",
|
|
121
|
-
summary: "
|
|
137
|
+
summary: "deprecated — oke dev always uses Docker Compose",
|
|
138
|
+
leaf: true,
|
|
139
|
+
flags: [HELP],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "test",
|
|
143
|
+
summary: "run bun test with PGLite test posture",
|
|
122
144
|
leaf: true,
|
|
123
145
|
flags: [HELP],
|
|
124
146
|
},
|
|
@@ -182,11 +204,11 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
182
204
|
},
|
|
183
205
|
{
|
|
184
206
|
name: "schema",
|
|
185
|
-
summary: "core + plugin tables → schema/oke.ts",
|
|
207
|
+
summary: "core + plugin tables → .oke/schema/oke.ts",
|
|
186
208
|
subcommands: [
|
|
187
209
|
{
|
|
188
210
|
name: "generate",
|
|
189
|
-
summary: "Emit schema/oke.ts",
|
|
211
|
+
summary: "Emit .oke/schema/oke.ts",
|
|
190
212
|
flags: [
|
|
191
213
|
{
|
|
192
214
|
long: "--check",
|
|
@@ -202,7 +224,7 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
202
224
|
},
|
|
203
225
|
{
|
|
204
226
|
name: "db",
|
|
205
|
-
summary: "domain schema — push · generate · migrate · seed",
|
|
227
|
+
summary: "domain schema — push · generate · migrate · seed · studio",
|
|
206
228
|
subcommands: [
|
|
207
229
|
{
|
|
208
230
|
name: "push",
|
|
@@ -219,7 +241,7 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
219
241
|
long: "--env",
|
|
220
242
|
takesValue: true,
|
|
221
243
|
valueName: "name",
|
|
222
|
-
summary: "Config env (
|
|
244
|
+
summary: "Config env (dev|test|prod)",
|
|
223
245
|
},
|
|
224
246
|
HELP,
|
|
225
247
|
],
|
|
@@ -239,7 +261,7 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
239
261
|
long: "--env",
|
|
240
262
|
takesValue: true,
|
|
241
263
|
valueName: "name",
|
|
242
|
-
summary: "Config env (
|
|
264
|
+
summary: "Config env (dev|test|prod)",
|
|
243
265
|
},
|
|
244
266
|
HELP,
|
|
245
267
|
],
|
|
@@ -259,7 +281,7 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
259
281
|
long: "--env",
|
|
260
282
|
takesValue: true,
|
|
261
283
|
valueName: "name",
|
|
262
|
-
summary: "Config env (
|
|
284
|
+
summary: "Config env (dev|test|prod)",
|
|
263
285
|
},
|
|
264
286
|
HELP,
|
|
265
287
|
],
|
|
@@ -272,7 +294,7 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
272
294
|
long: "--env",
|
|
273
295
|
takesValue: true,
|
|
274
296
|
valueName: "name",
|
|
275
|
-
summary: "Config env (
|
|
297
|
+
summary: "Config env (dev|test|prod)",
|
|
276
298
|
},
|
|
277
299
|
{
|
|
278
300
|
long: "--force",
|
|
@@ -282,6 +304,26 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
282
304
|
HELP,
|
|
283
305
|
],
|
|
284
306
|
},
|
|
307
|
+
{
|
|
308
|
+
name: "studio",
|
|
309
|
+
summary: "Open drizzle-kit Studio (long-running)",
|
|
310
|
+
flags: [
|
|
311
|
+
{
|
|
312
|
+
long: "--config",
|
|
313
|
+
short: "-c",
|
|
314
|
+
takesValue: true,
|
|
315
|
+
valueName: "path",
|
|
316
|
+
summary: "drizzle.config.ts path",
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
long: "--env",
|
|
320
|
+
takesValue: true,
|
|
321
|
+
valueName: "name",
|
|
322
|
+
summary: "Config env (dev|test|prod)",
|
|
323
|
+
},
|
|
324
|
+
HELP,
|
|
325
|
+
],
|
|
326
|
+
},
|
|
285
327
|
],
|
|
286
328
|
},
|
|
287
329
|
{
|
|
@@ -298,7 +340,7 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
298
340
|
},
|
|
299
341
|
{
|
|
300
342
|
name: "vault",
|
|
301
|
-
summary: "set · list ·
|
|
343
|
+
summary: "secrets — set · list · seal/unseal · rotate · audit · backup",
|
|
302
344
|
subcommands: [
|
|
303
345
|
{
|
|
304
346
|
name: "set",
|
|
@@ -319,6 +361,96 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
319
361
|
positionals: "rotate",
|
|
320
362
|
flags: [HELP],
|
|
321
363
|
},
|
|
364
|
+
{
|
|
365
|
+
name: "init",
|
|
366
|
+
summary: "Create the builtin vault; print the master key once",
|
|
367
|
+
flags: [VAULT_URL, HELP],
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
name: "status",
|
|
371
|
+
summary: "Seal state · KEK generation · secret count",
|
|
372
|
+
flags: [VAULT_KEY, VAULT_URL, JSON_FLAG, HELP],
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: "seal",
|
|
376
|
+
summary: "Drop the master key; reads fail until unsealed",
|
|
377
|
+
flags: [VAULT_URL, HELP],
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
name: "unseal",
|
|
381
|
+
summary: "Verify the master key and clear the sealed flag",
|
|
382
|
+
flags: [VAULT_KEY, VAULT_URL, HELP],
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
name: "rotate",
|
|
386
|
+
summary: "New version of a secret under a fresh data key",
|
|
387
|
+
positionals: "<path> [value]",
|
|
388
|
+
flags: [VAULT_KEY, VAULT_URL, HELP],
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
name: "rotate-master",
|
|
392
|
+
summary: "New master key; re-wrap every data key",
|
|
393
|
+
flags: [VAULT_KEY, VAULT_NEW_KEY, VAULT_URL, HELP],
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: "audit",
|
|
397
|
+
summary: "Read · verify · purge the tamper-evident chain",
|
|
398
|
+
positionals: "[verify|purge]",
|
|
399
|
+
flags: [
|
|
400
|
+
{
|
|
401
|
+
long: "--limit",
|
|
402
|
+
takesValue: true,
|
|
403
|
+
valueName: "n",
|
|
404
|
+
summary: "Rows to show (default 50)",
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
long: "--path",
|
|
408
|
+
takesValue: true,
|
|
409
|
+
valueName: "path",
|
|
410
|
+
summary: "Restrict to one secret path",
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
long: "--before",
|
|
414
|
+
takesValue: true,
|
|
415
|
+
valueName: "iso",
|
|
416
|
+
summary: "Purge rows older than this instant",
|
|
417
|
+
},
|
|
418
|
+
VAULT_URL,
|
|
419
|
+
JSON_FLAG,
|
|
420
|
+
HELP,
|
|
421
|
+
],
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: "purge-expired",
|
|
425
|
+
summary: "Hard-delete secret rows past expires_at",
|
|
426
|
+
flags: [
|
|
427
|
+
VAULT_KEY,
|
|
428
|
+
VAULT_URL,
|
|
429
|
+
{
|
|
430
|
+
long: "--dry-run",
|
|
431
|
+
summary: "Count expired rows without deleting",
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
long: "--before",
|
|
435
|
+
takesValue: true,
|
|
436
|
+
valueName: "iso",
|
|
437
|
+
summary: "Exclusive upper bound (default: now)",
|
|
438
|
+
},
|
|
439
|
+
HELP,
|
|
440
|
+
],
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: "backup",
|
|
444
|
+
summary: "Write every live secret as one encrypted bundle",
|
|
445
|
+
positionals: "<file>",
|
|
446
|
+
flags: [VAULT_KEY, VAULT_URL, HELP],
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
name: "restore",
|
|
450
|
+
summary: "Replay a bundle as new versions",
|
|
451
|
+
positionals: "<file>",
|
|
452
|
+
flags: [VAULT_KEY, VAULT_URL, HELP],
|
|
453
|
+
},
|
|
322
454
|
],
|
|
323
455
|
},
|
|
324
456
|
{
|
|
@@ -549,7 +681,15 @@ export const OKE_COMMANDS: readonly CliCommand[] = [
|
|
|
549
681
|
* @returns Help text (no trailing exit-code block)
|
|
550
682
|
*/
|
|
551
683
|
export function formatOkeHelp(): string {
|
|
552
|
-
const lines = [
|
|
684
|
+
const lines = [
|
|
685
|
+
"oke — okengine CLI",
|
|
686
|
+
"",
|
|
687
|
+
" oke Interactive TUI (TTY). Non-TTY prints this help.",
|
|
688
|
+
" oke --tui Force the interactive TUI",
|
|
689
|
+
" oke --help This command list",
|
|
690
|
+
"",
|
|
691
|
+
"Commands:",
|
|
692
|
+
];
|
|
553
693
|
for (const cmd of OKE_COMMANDS) {
|
|
554
694
|
const usage = formatCommandUsage(cmd);
|
|
555
695
|
lines.push(` ${pad(usage, 34)} ${cmd.summary}`);
|
|
@@ -608,7 +748,7 @@ function formatCommandUsage(cmd: CliCommand): string {
|
|
|
608
748
|
return `oke ${cmd.name} ${sub.name}${pos}${flagHint ? ` ${flagHint}` : ""}`;
|
|
609
749
|
}
|
|
610
750
|
if (cmd.subcommands && cmd.subcommands.length > 1) {
|
|
611
|
-
const subs = cmd.subcommands
|
|
751
|
+
const subs = summarizeSubcommands(cmd.subcommands);
|
|
612
752
|
// Prefer shared JSON flag hint when every list-like sub supports it.
|
|
613
753
|
const jsonHint = cmd.subcommands.some((s) => s.flags?.some((f) => f.long === "--json"))
|
|
614
754
|
? " [--json|-j]"
|
|
@@ -624,6 +764,22 @@ function formatCommandUsage(cmd: CliCommand): string {
|
|
|
624
764
|
return `oke ${cmd.name}${pos}${flagHint ? ` ${flagHint}` : ""}`;
|
|
625
765
|
}
|
|
626
766
|
|
|
767
|
+
/** Longest `a|b|c` sub list the one-line help layout can carry. */
|
|
768
|
+
const MAX_SUBCOMMAND_HINTS = 4;
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Join subcommand names for the one-line usage, eliding a long tail.
|
|
772
|
+
*
|
|
773
|
+
* Commands with a large surface (`vault`) would otherwise push the summary
|
|
774
|
+
* column off screen; the full list still reaches completion and `--help`.
|
|
775
|
+
*
|
|
776
|
+
* @param subs - Subcommands in registry order
|
|
777
|
+
*/
|
|
778
|
+
function summarizeSubcommands(subs: readonly CliSubcommand[]): string {
|
|
779
|
+
const shown = subs.slice(0, MAX_SUBCOMMAND_HINTS).map((s) => s.name);
|
|
780
|
+
return subs.length > MAX_SUBCOMMAND_HINTS ? `${shown.join("|")}|…` : shown.join("|");
|
|
781
|
+
}
|
|
782
|
+
|
|
627
783
|
function formatFlagHint(f: CliFlag): string {
|
|
628
784
|
const name = f.short ? `${f.long}|${f.short}` : f.long;
|
|
629
785
|
if (f.takesValue) {
|