okengine 0.17.2 → 0.18.4

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.
Files changed (209) hide show
  1. package/AGENTS.md +5 -3
  2. package/README.md +14 -10
  3. package/manifest.v1.schema.json +61 -2
  4. package/package.json +19 -5
  5. package/site/content/docs/ai/index.mdx +1 -1
  6. package/site/content/docs/ai/mcp.mdx +10 -1
  7. package/site/content/docs/ai/skills.mdx +9 -9
  8. package/site/content/docs/elements/ai.mdx +1 -1
  9. package/site/content/docs/elements/clock.mdx +1 -1
  10. package/site/content/docs/elements/flow.mdx +25 -1
  11. package/site/content/docs/elements/gate.mdx +3 -2
  12. package/site/content/docs/elements/store.mdx +289 -341
  13. package/site/content/docs/elements/vault.mdx +5 -5
  14. package/site/content/docs/get-started/basic-usage.mdx +3 -10
  15. package/site/content/docs/get-started/index.mdx +1 -1
  16. package/site/content/docs/get-started/installation.mdx +2 -3
  17. package/site/content/docs/get-started/introduction.mdx +58 -121
  18. package/site/content/docs/get-started/meta.json +9 -1
  19. package/site/content/docs/get-started/project-structure.mdx +4 -11
  20. package/site/content/docs/get-started/testing.mdx +328 -0
  21. package/site/content/docs/get-started/why.mdx +93 -71
  22. package/site/content/docs/index.mdx +44 -11
  23. package/site/content/docs/meta.json +8 -5
  24. package/site/content/docs/plugins/apple.mdx +151 -0
  25. package/site/content/docs/plugins/discord.mdx +139 -0
  26. package/site/content/docs/plugins/facebook.mdx +134 -0
  27. package/site/content/docs/plugins/figma.mdx +138 -0
  28. package/site/content/docs/plugins/github.mdx +138 -0
  29. package/site/content/docs/plugins/google.mdx +153 -0
  30. package/site/content/docs/plugins/index.mdx +47 -1
  31. package/site/content/docs/plugins/meta.json +10 -0
  32. package/site/content/docs/plugins/microsoft.mdx +151 -0
  33. package/site/content/docs/plugins/oauth.mdx +188 -0
  34. package/site/content/docs/plugins/x.mdx +125 -0
  35. package/site/content/docs/providers/index.mdx +2 -0
  36. package/site/content/docs/recipes/index.mdx +2 -0
  37. package/site/content/docs/reference/cli.md +3 -2
  38. package/site/content/docs/reference/client.mdx +58 -1
  39. package/site/content/docs/reference/configuration.mdx +2 -4
  40. package/site/content/docs/reference/fx.mdx +3 -1
  41. package/site/content/docs/reference/index.mdx +0 -5
  42. package/site/content/docs/reference/meta.json +2 -2
  43. package/site/content/docs/reference/okid.mdx +137 -0
  44. package/src/auth/bindings.ts +1 -1
  45. package/src/auth/config.ts +9 -0
  46. package/src/auth/identity-sql.ts +314 -0
  47. package/src/auth/identity.ts +140 -2
  48. package/src/auth/index.ts +17 -1
  49. package/src/auth/method-context.ts +3 -0
  50. package/src/auth/oauth-as/cimd.ts +132 -0
  51. package/src/auth/oauth-as/crypto.test.ts +101 -0
  52. package/src/auth/oauth-as/crypto.ts +393 -0
  53. package/src/auth/oauth-as/errors.ts +68 -0
  54. package/src/auth/oauth-as/http.test.ts +419 -0
  55. package/src/auth/oauth-as/http.ts +842 -0
  56. package/src/auth/oauth-as/stores.ts +61 -0
  57. package/src/auth/oauth-as/tables.ts +142 -0
  58. package/src/auth/tables.ts +0 -11
  59. package/src/bench/README.md +83 -0
  60. package/src/bench/REPORT.md +176 -0
  61. package/src/bench/g01-rls-stamp.bench.ts +194 -0
  62. package/src/bench/g02-clock-per-tenant.bench.ts +158 -0
  63. package/src/bench/g03-signal-once.bench.ts +157 -0
  64. package/src/bench/g03-signal-reconnect.bench.ts +254 -0
  65. package/src/bench/g03-signal-sse-memory.bench.ts +191 -0
  66. package/src/bench/g04-auth-vault-hotpath.bench.ts +170 -0
  67. package/src/bench/g05-sustained-full.bench.ts +265 -0
  68. package/src/bench/g06-mixed-load.bench.ts +260 -0
  69. package/src/bench/g07-vault-crypto.bench.ts +100 -0
  70. package/src/bench/g07-vault-rotate-under-read.bench.ts +285 -0
  71. package/src/bench/g08-conn-oversubscribe.bench.ts +194 -0
  72. package/src/bench/g08-store-kv-durable.bench.ts +133 -0
  73. package/src/bench/g08-store-sql.bench.ts +178 -0
  74. package/src/bench/g09-journal-sustained.bench.ts +203 -0
  75. package/src/bench/g10-observability-contention.bench.ts +246 -0
  76. package/src/bench/g11-cold-start-cycle.bench.ts +164 -0
  77. package/src/bench/g13-elements.bench.ts +427 -0
  78. package/src/bench/g14-graceful-shutdown.bench.ts +244 -0
  79. package/src/bench/g15-postgres-degradation.bench.ts +264 -0
  80. package/src/bench/g16-live-query-fanout.bench.ts +206 -0
  81. package/src/bench/lib/event-loop-lag.ts +26 -0
  82. package/src/bench/lib/infra.ts +60 -0
  83. package/src/bench/lib/report.ts +52 -0
  84. package/src/bench/lib/rss-sampler.ts +61 -0
  85. package/src/bench/lib/signal-pg.ts +88 -0
  86. package/src/bench/load-app.ts +337 -0
  87. package/src/bench/load-child.ts +108 -0
  88. package/src/bench/smoke.bench.ts +43 -0
  89. package/src/cli/competitor-mention-removal.test.ts +28 -0
  90. package/src/cli/doctor-fd.ts +117 -0
  91. package/src/cli/doctor.test.ts +192 -0
  92. package/src/cli/doctor.ts +129 -1
  93. package/src/client/create.ts +95 -1
  94. package/src/client/index.ts +9 -2
  95. package/src/client/transport.ts +11 -4
  96. package/src/client/use-live-query.ts +154 -0
  97. package/src/client-react/index.ts +15 -1
  98. package/src/client-react/live-resource.ts +246 -0
  99. package/src/client-react/use-live-query.test.ts +475 -0
  100. package/src/client-react/use-live-query.ts +530 -0
  101. package/src/compiler/extract.test.ts +518 -0
  102. package/src/compiler/extract.ts +386 -19
  103. package/src/console/server/invoke-user-flow.ts +2 -1
  104. package/src/console/ui-next/dist/assets/{access-page-DnWbnGzq.js → access-page-De7Lc2JC.js} +1 -1
  105. package/src/console/ui-next/dist/assets/{flows-page-BiZ4-6yQ.js → flows-page-RGy7VEA_.js} +1 -1
  106. package/src/console/ui-next/dist/assets/{index-C8NRK2R-.js → index-_rgpdVzo.js} +3 -3
  107. package/src/console/ui-next/dist/assets/{observability-page-CrB6vd1T.js → observability-page-Ds6pcnh-.js} +1 -1
  108. package/src/console/ui-next/dist/assets/{store-page-CS5-aETQ.js → store-page-02xOiqIK.js} +3 -3
  109. package/src/console/ui-next/dist/assets/{units-page-CjtdlW8l.js → units-page-4rHOePuE.js} +1 -1
  110. package/src/console/ui-next/dist/assets/{vault-page-C6Xxm9SA.js → vault-page-DISPgxLM.js} +1 -1
  111. package/src/console/ui-next/dist/index.html +1 -1
  112. package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +36 -2
  113. package/src/drivers/cdc-outbox.ts +389 -0
  114. package/src/drivers/memory.ts +20 -0
  115. package/src/drivers/oauth-apple.ts +156 -0
  116. package/src/drivers/oauth-discord.ts +79 -0
  117. package/src/drivers/oauth-facebook.ts +80 -0
  118. package/src/drivers/oauth-figma.ts +116 -0
  119. package/src/drivers/oauth-github.ts +92 -0
  120. package/src/drivers/oauth-google.ts +142 -0
  121. package/src/drivers/oauth-microsoft.ts +174 -0
  122. package/src/drivers/oauth-oidc.ts +293 -0
  123. package/src/drivers/oauth-shared.ts +326 -0
  124. package/src/drivers/oauth-types.ts +159 -0
  125. package/src/drivers/oauth-x.ts +77 -0
  126. package/src/drivers/oauth2-common.ts +95 -0
  127. package/src/drivers/oauth2-token.ts +61 -0
  128. package/src/drivers/pg-rls-row-passes.ts +251 -0
  129. package/src/drivers/pg-rls.ts +2 -0
  130. package/src/drivers/postgres.ts +45 -2
  131. package/src/drivers/signal-postgres.ts +2 -1
  132. package/src/elements/channel/runtime.ts +29 -2
  133. package/src/elements/channel.test.ts +52 -0
  134. package/src/elements/gate/boot.ts +29 -2
  135. package/src/elements/store/emit-drizzle.ts +147 -14
  136. package/src/elements/store/field-ddl.test.ts +118 -0
  137. package/src/elements/store/field-types.test.ts +455 -0
  138. package/src/elements/store/list-query.golden.json +777 -0
  139. package/src/elements/store/list-query.parity.test.ts +396 -0
  140. package/src/elements/store/list-query.ts +792 -0
  141. package/src/elements/store/live-default.test.ts +136 -0
  142. package/src/elements/store/live-http.test.ts +160 -0
  143. package/src/elements/store/live-isolation.test.ts +291 -0
  144. package/src/elements/store/live-query-runtime.test.ts +323 -0
  145. package/src/elements/store/live-query-runtime.ts +403 -0
  146. package/src/elements/store/live-query-server.test.ts +377 -0
  147. package/src/elements/store/live-query-server.ts +102 -0
  148. package/src/elements/store/live-query.ts +97 -0
  149. package/src/elements/store/resource.ts +189 -680
  150. package/src/elements/store/rls-row-passes-policies.parity.test.ts +665 -0
  151. package/src/elements/store/schema-decl.ts +539 -41
  152. package/src/elements/store/sql-rls-stamp.test.ts +27 -0
  153. package/src/elements/store/sql-session.ts +297 -35
  154. package/src/elements/store/table.ts +102 -21
  155. package/src/elements/store.test.ts +3 -1
  156. package/src/elements/store.ts +12 -1
  157. package/src/elements/vault/chaos-child.ts +74 -1
  158. package/src/elements/vault/chaos.test.ts +4 -2
  159. package/src/elements/vault/storage.ts +4 -2
  160. package/src/index.ts +5 -2
  161. package/src/kernel/app-auth.ts +1 -0
  162. package/src/kernel/app.ts +116 -2
  163. package/src/kernel/auth-sharing.test.ts +196 -0
  164. package/src/kernel/boot.test.ts +3 -3
  165. package/src/kernel/errors.ts +8 -0
  166. package/src/kernel/fx.test.ts +1 -0
  167. package/src/kernel/fx.ts +14 -2
  168. package/src/kernel/horizontal-child.ts +2 -1
  169. package/src/kernel/http-resource.ts +33 -7
  170. package/src/kernel/identity-host-persist.test.ts +119 -0
  171. package/src/kernel/instance-id.ts +4 -2
  172. package/src/kernel/journal.ts +2 -1
  173. package/src/kernel/mcp-tool.test.ts +95 -0
  174. package/src/kernel/on.ts +9 -0
  175. package/src/kernel/realtime-bind.ts +326 -0
  176. package/src/kernel/resource-live.ts +117 -0
  177. package/src/kernel/triggers.ts +86 -4
  178. package/src/manifest/diff.ts +37 -0
  179. package/src/manifest/types.ts +64 -2
  180. package/src/okid.bench.test.ts +64 -0
  181. package/src/okid.test.ts +338 -0
  182. package/src/okid.ts +245 -0
  183. package/src/plugins/anonymous.ts +19 -1
  184. package/src/plugins/auth/shared.ts +15 -0
  185. package/src/plugins/index.ts +2 -0
  186. package/src/plugins/magic-link.ts +10 -8
  187. package/src/plugins/mcp-oauth.ts +208 -0
  188. package/src/plugins/oauth/flow-store.ts +117 -0
  189. package/src/plugins/oauth/link.ts +69 -0
  190. package/src/plugins/oauth/shared.ts +108 -0
  191. package/src/plugins/oauth/token-vault.ts +100 -0
  192. package/src/plugins/oauth.security.test.ts +535 -0
  193. package/src/plugins/oauth.ts +532 -0
  194. package/src/plugins/otp.ts +48 -6
  195. package/src/plugins/passkey.ts +20 -1
  196. package/src/plugins/two-factor.ts +11 -0
  197. package/src/plugins/username.ts +40 -7
  198. package/src/release/build-lib.ts +7 -1
  199. package/src/release/measure.ts +1 -0
  200. package/src/release/official-plugins.ts +4 -1
  201. package/src/runs/collect.ts +2 -1
  202. package/src/runs/drivers/files.ts +2 -1
  203. package/src/test/create-test-app.ts +114 -5
  204. package/src/test/export-bundle.test.ts +33 -0
  205. package/src/test/live-signals.test.ts +83 -0
  206. package/src/test/tenant-isolation.test.ts +175 -0
  207. package/src/testing.ts +26 -0
  208. package/src/upgrade/codemods.ts +1 -1
  209. package/site/content/docs/reference/migrating-environments.mdx +0 -158
@@ -0,0 +1,175 @@
1
+ /**
2
+ * `createTestApp` multi-tenancy testing & real RLS isolation.
3
+ *
4
+ * RLS policies / helper functions are installed by `oke db push` in real apps;
5
+ * a test boot does not run migrations, so this harness test installs the
6
+ * tenant policy + `oke.tenant()` helper on the booted PGlite connection
7
+ * (mirroring `src/elements/store/sql-rls-isolation.test.ts`).
8
+ */
9
+
10
+ import { describe, expect, test } from "bun:test";
11
+ import { z } from "zod";
12
+ import { oke } from "../kernel/app.ts";
13
+ import { flow, resetFlowSeq } from "../kernel/flow.ts";
14
+ import { on, resetBindings } from "../kernel/on.ts";
15
+ import { http } from "../kernel/triggers.ts";
16
+ import { gate } from "../elements/gate.ts";
17
+ import { field } from "../elements/store/schema-decl.ts";
18
+ import { store } from "../elements/store.ts";
19
+ import { installOkeRlsHelpers } from "../drivers/pg-rls.ts";
20
+ import type { SqlConnection } from "../drivers/types.ts";
21
+ import { createTestApp } from "./create-test-app.ts";
22
+
23
+ describe("createTestApp tenancy testing & RLS isolation", () => {
24
+ test("loginAs with tenantId stamps fx.tenant.id and isolates queries via real RLS", async () => {
25
+ resetBindings();
26
+ resetFlowSeq();
27
+
28
+ const memberGate = gate.policy("member", ({ auth }) => !!auth.userId && !!auth.verified);
29
+
30
+ const documents = store.schema.table(
31
+ "documents",
32
+ {
33
+ id: field.text().primaryKey(),
34
+ tenant_id: field.text().notNull(),
35
+ title: field.text().notNull(),
36
+ },
37
+ [store.schema.policy.tenant("tenant_id", { for: "all" })],
38
+ );
39
+ const docStore = store.sql("docs", { schema: { documents } });
40
+
41
+ on(
42
+ http.post("/docs").gate(memberGate),
43
+ flow("docs.create", {
44
+ in: z.object({ title: z.string() }),
45
+ out: z.object({ id: z.string(), tenantId: z.string().nullable() }),
46
+ effects: { writes: ["sql:docs"], reads: ["sql:docs"] },
47
+ do: async (input, fx) => {
48
+ const id = fx.id();
49
+ await fx.store(docStore).insert(documents).values({
50
+ id,
51
+ tenant_id: fx.tenant.id!,
52
+ title: input.title,
53
+ });
54
+ return { id, tenantId: fx.tenant.id };
55
+ },
56
+ }),
57
+ );
58
+
59
+ on(
60
+ http.get("/docs").gate(memberGate),
61
+ flow("docs.list", {
62
+ in: z.void(),
63
+ out: z.array(z.object({ id: z.string(), title: z.string() })),
64
+ effects: { reads: ["sql:docs"] },
65
+ do: async (_input, fx) => {
66
+ const rows = await fx.store(docStore).select().from(documents);
67
+ return rows.map((r) => ({ id: r.id, title: r.title }));
68
+ },
69
+ }),
70
+ );
71
+
72
+ const app = oke({
73
+ name: "tenant-app",
74
+ gate: {
75
+ policies: [memberGate],
76
+ auth: { tenant: true },
77
+ },
78
+ stores: [docStore],
79
+ env: "test",
80
+ });
81
+
82
+ const t = await createTestApp(app, {
83
+ gates: [memberGate],
84
+ boot: {
85
+ config: {
86
+ drivers: {
87
+ store: {
88
+ sql: { test: "pglite" }, // Real PGlite RLS engine
89
+ },
90
+ },
91
+ },
92
+ },
93
+ });
94
+
95
+ const userAcme = await t.auth.loginAs({ id: "alice", tenantId: "acme" });
96
+ const userGlobex = await t.auth.loginAs({ id: "bob", tenantId: "globex" });
97
+
98
+ expect(userAcme.tenantId).toBe("acme");
99
+ expect(userGlobex.tenantId).toBe("globex");
100
+
101
+ // Install RLS helper functions + tenant policy on the booted connection.
102
+ // Real deployments get these via `oke db push`; the harness boot does not
103
+ // run migrations, so the test installs them explicitly (same as the
104
+ // codebase's own sql-rls-isolation tests).
105
+ const conn = (await app.bootResult?.store?.primarySql()) as SqlConnection | undefined;
106
+ if (!conn) throw new Error("no primary sql connection");
107
+ await conn.exec(`CREATE TABLE IF NOT EXISTS "documents" (
108
+ id text PRIMARY KEY,
109
+ tenant_id text NOT NULL,
110
+ title text NOT NULL
111
+ )`);
112
+ await conn.exec(`ALTER TABLE "documents" ENABLE ROW LEVEL SECURITY`);
113
+ await installOkeRlsHelpers((sql) => conn.exec(sql));
114
+ await conn.exec(
115
+ `CREATE POLICY tenant_tenant_id_all ON "documents"
116
+ AS PERMISSIVE FOR ALL TO public
117
+ USING (tenant_id = oke.tenant())
118
+ WITH CHECK (tenant_id = oke.tenant())`,
119
+ );
120
+
121
+ // Alice creates document in Acme
122
+ const createRes1 = await t.api.docs!.create!({ title: "Acme Roadmap" }, { as: userAcme });
123
+ expect(createRes1.error).toBeNull();
124
+ expect((createRes1.data as { tenantId: string | null }).tenantId).toBe("acme");
125
+
126
+ // Bob creates document in Globex
127
+ const createRes2 = await t.api.docs!.create!({ title: "Globex Secrets" }, { as: userGlobex });
128
+ expect(createRes2.error).toBeNull();
129
+ expect((createRes2.data as { tenantId: string | null }).tenantId).toBe("globex");
130
+
131
+ // Alice lists docs -> should only see Acme
132
+ const listAcme = await t.api.docs!.list!(undefined, { as: userAcme });
133
+ expect(listAcme.error).toBeNull();
134
+ expect(listAcme.data).toHaveLength(1);
135
+ expect((listAcme.data as { title: string }[])[0]!.title).toBe("Acme Roadmap");
136
+
137
+ // Bob lists docs -> should only see Globex
138
+ const listGlobex = await t.api.docs!.list!(undefined, { as: userGlobex });
139
+ expect(listGlobex.error).toBeNull();
140
+ expect(listGlobex.data).toHaveLength(1);
141
+ expect((listGlobex.data as { title: string }[])[0]!.title).toBe("Globex Secrets");
142
+
143
+ // The `{ tenant }` call override re-scopes RLS even when it differs from the
144
+ // principal's own `tenantId`. Carol belongs to Acme; forcing `tenant: "globex"`
145
+ // writes a Globex row (proving fx.tenant.id + RLS WITH CHECK re-scoped) and,
146
+ // through a distinct principal (no tier-1 cache-dim collision), reads only
147
+ // Globex rows back.
148
+ const carol = await t.auth.loginAs({ id: "carol", tenantId: "acme" });
149
+
150
+ const createOverride = await t.api.docs!.create!(
151
+ { title: "Globex Carol" },
152
+ { as: carol, tenant: "globex" },
153
+ );
154
+ expect(createOverride.error).toBeNull();
155
+ expect((createOverride.data as { tenantId: string | null }).tenantId).toBe("globex");
156
+
157
+ const listHome = await t.api.docs!.list!(undefined, { as: carol });
158
+ expect(listHome.error).toBeNull();
159
+ expect((listHome.data as { title: string }[]).length).toBe(1);
160
+ expect((listHome.data as { title: string }[])[0]!.title).toBe("Acme Roadmap");
161
+
162
+ // Distinct call identity keeps the tier-1 read-cache key apart from the
163
+ // acme-scoped list above (cache dims: flow, input, userId — tenant is a
164
+ // row-level RLS scope, not a cache dimension).
165
+ const dave = await t.auth.loginAs({ id: "dave", tenantId: "acme" });
166
+ const listOverride = await t.api.docs!.list!(undefined, { as: dave, tenant: "globex" });
167
+ expect(listOverride.error).toBeNull();
168
+ // Two Globex rows now: Bob's original + Carol's override write.
169
+ expect((listOverride.data as { title: string }[]).length).toBe(2);
170
+ const overrideTitles = (listOverride.data as { title: string }[]).map((r) => r.title).sort();
171
+ expect(overrideTitles).toEqual(["Globex Carol", "Globex Secrets"]);
172
+
173
+ await t.close();
174
+ });
175
+ });
package/src/testing.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Test harness (`createTestApp`). Subpath: `okengine/testing` or `okengine/test`.
3
+ *
4
+ * Kept out of core/client bundles via a dedicated `dist/testing.js` build.
5
+ * @module
6
+ */
7
+
8
+ export {
9
+ createTestApp,
10
+ type CreateTestAppOptions,
11
+ type LoginAsOptions,
12
+ type TestAi,
13
+ type TestApi,
14
+ type TestApiCall,
15
+ type TestApp,
16
+ type TestAuth,
17
+ type TestCallOptions,
18
+ type TestChannels,
19
+ type TestClock,
20
+ type TestCron,
21
+ type TestEffects,
22
+ type TestLiveHandlers,
23
+ type TestLiveUnsubscribe,
24
+ type TestSignals,
25
+ type TestUser,
26
+ } from "./test/create-test-app.ts";
@@ -6,7 +6,7 @@
6
6
  * registry is the checklist.
7
7
  *
8
8
  * Environment-model migrations (`local`/`docker` → `dev`, sqlite removal)
9
- * are documented only see site docs `reference/migrating-environments`.
9
+ * are documented only in the site docs configuration reference.
10
10
  * No soft-compat rewriter for those.
11
11
  */
12
12
 
@@ -1,158 +0,0 @@
1
- ---
2
- title: "Migrating environments"
3
- description: "Move from local/docker/test/prod driver maps to the Docker-first dev/test/prod model."
4
- icon: "ArrowRightLeft"
5
- ---
6
-
7
- Older projects used four driver-map keys (`local` · `docker` · `test` · `prod`) and an optional
8
- `oke mode` switch. Today there are three environments, `oke dev` always starts Docker Compose, and
9
- SQLite-family drivers (`sqlite`, `libsql`) are gone.
10
-
11
- There is **no** soft-compat and **no** upgrade codemod for this change. Edit `oke.config.ts` by
12
- hand using this page.
13
-
14
- <Callout title="The one rule">
15
- Rename maps to `dev` / `test` / `prod`, pin `pglite` for SQL tests, delete `.oke/mode`, then run
16
- `oke dev` / `oke test`.
17
- </Callout>
18
-
19
- ## Quick start
20
-
21
- <Steps>
22
-
23
- <Step>
24
- ### Edit the three-key shape
25
-
26
- ```typescript title="oke.config.ts"
27
- import { defineConfig } from "okengine/config";
28
-
29
- export default defineConfig({
30
- drivers: {
31
- store: {
32
- sql: { dev: "postgres", test: "pglite", prod: "postgres" },
33
- kv: { dev: "redis", test: "memory", prod: "redis" },
34
- },
35
- },
36
- });
37
- ```
38
-
39
- </Step>
40
-
41
- <Step>
42
- ### Drop mode and use the new commands
43
-
44
- ```bash title="Terminal"
45
- rm -f .oke/mode # no longer read
46
- oke dev # always Docker Compose
47
- oke test # PGLite test posture (no Compose)
48
- ```
49
-
50
- `oke mode` prints an error and exits — it was removed.
51
-
52
- </Step>
53
-
54
- </Steps>
55
-
56
- ## Key rename table
57
-
58
- | Old key | New key | Notes |
59
- | -------- | ------- | ------------------------------------------------ |
60
- | `local` | `dev` | Compose laptop |
61
- | `docker` | `dev` | Same Compose / prod-shaped protocols |
62
- | `stack` | `dev` | Legacy alias |
63
- | `test` | `test` | Unchanged; SQL must be `pglite` |
64
- | `prod` | `prod` | Unchanged; missing `dev` still fills from `prod` |
65
-
66
- ## sqlite / libsql removal
67
-
68
- | Old pin | Replacement |
69
- | --------------------------------- | --------------------------------------------- |
70
- | `sql.*: "sqlite"` / `"libsql"` | `dev` / `prod`: `postgres` |
71
- | `sql.test: "sqlite"` / `"libsql"` | `test: "pglite"` |
72
- | `sql.test: "memory"` | `test: "pglite"` (required by `defineConfig`) |
73
- | `index.*: "libsql"` | `dev` / `prod`: `pgvector`; `test`: `memory` |
74
-
75
- `OKE_SQLITE_URL` / `OKE_LIBSQL_URL` are unused — use `DATABASE_URL` (Compose Postgres) or
76
- `OKE_PGLITE_URL` (`memory://` under `oke test`).
77
-
78
- ## Before / after
79
-
80
- ```typescript title="Before (removed)"
81
- drivers: {
82
- store: {
83
- sql: { local: "sqlite", docker: "postgres", test: "memory", prod: "postgres" },
84
- kv: { local: "memory", docker: "redis", test: "memory", prod: "redis" },
85
- },
86
- },
87
- ```
88
-
89
- ```typescript title="After"
90
- drivers: {
91
- store: {
92
- sql: { dev: "postgres", test: "pglite", prod: "postgres" },
93
- kv: { dev: "redis", test: "memory", prod: "redis" },
94
- },
95
- },
96
- ```
97
-
98
- ## CLI changes
99
-
100
- | Old | New |
101
- | ------------------------- | ----------------------------------------------- |
102
- | `oke mode local\|docker` | Removed — error message points at `oke dev` |
103
- | `oke dev --local` / `-l` | Removed — exits with guidance to use `oke test` |
104
- | `oke dev` (local default) | Always Docker Compose |
105
- | `oke dev --docker` / `-d` | Optional **role filter** only (still Compose) |
106
- | — | `oke test` — `bun test` + PGLite posture |
107
-
108
- Loading `oke.config.ts` with a `local:` env key or a `"sqlite"` pin fails immediately:
109
-
110
- ```text
111
- Error: "local" is no longer a valid environment key in oke.config.ts.
112
- ```
113
-
114
- ```text
115
- Error: "sqlite" is no longer a valid driver in oke.config.ts.
116
- ```
117
-
118
- ## Troubleshooting
119
-
120
- <Accordions>
121
-
122
- <Accordion title='CLI says "local" / "sqlite" is no longer valid'>
123
- Edit `oke.config.ts` using the tables above. There is no automatic rewrite — fix the file, then
124
- re-run the command.
125
- </Accordion>
126
-
127
- <Accordion title="defineConfig throws on sqlite, libsql, or non-pglite test SQL">
128
- Those pins are hard errors. Fix the map, then restart `oke dev` / `oke test`. Exact messages are
129
- documented under [Configuration · Safety](/docs/reference/configuration#safety-rules).
130
- </Accordion>
131
-
132
- </Accordions>
133
-
134
- ## Learn more
135
-
136
- - [Configuration](/docs/reference/configuration) — full `oke.config.ts` reference
137
- - [CLI Reference](/docs/reference/cli) — `oke dev` · `oke test`
138
- - [Installation](/docs/get-started/installation) — Docker-first quick start
139
-
140
- ## Next
141
-
142
- <Cards>
143
- <Card
144
- title="Configuration"
145
- description="Drivers, images, db, ports."
146
- href="/docs/reference/configuration"
147
- />
148
- <Card
149
- title="CLI Reference"
150
- description="oke and create-oke commands."
151
- href="/docs/reference/cli"
152
- />
153
- <Card
154
- title="Docker deployment"
155
- description="Production compose shape."
156
- href="/docs/deployment/docker"
157
- />
158
- </Cards>