create-oke 0.7.0 → 0.9.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 +1 -1
- package/src/drivers-catalog.ts +13 -3
- package/src/transform.ts +2 -1
- package/templates/advanced/README.md +7 -0
- package/templates/advanced/oke.config.ts +10 -2
- package/templates/advanced/src/seed/index.ts +67 -0
- package/templates/standard/README.md +2 -0
- package/templates/standard/oke.config.ts +10 -2
- package/templates/standard/src/seed/index.ts +56 -0
package/package.json
CHANGED
package/src/drivers-catalog.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Boot-implemented driver choices offered by the create-oke customize wizard.
|
|
3
3
|
*
|
|
4
|
-
* Never lists ids that fail loud at boot (signal postgres/nats,
|
|
5
|
-
* ai bedrock/vertex).
|
|
4
|
+
* Never lists ids that fail loud at boot (signal postgres/nats,
|
|
5
|
+
* ai bedrock/vertex). Clock + journal `postgres` are real (SKIP LOCKED
|
|
6
|
+
* CronStore / durable-run journal).
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
import type { CreateDefaults, CreateProfile, EnvDriverPins } from "./create-defaults.ts";
|
|
@@ -20,7 +21,7 @@ export const TEMPLATE_DOCKER_PROD = {
|
|
|
20
21
|
kv: "redis",
|
|
21
22
|
files: "s3",
|
|
22
23
|
signal: "redis",
|
|
23
|
-
clock: "
|
|
24
|
+
clock: "postgres",
|
|
24
25
|
vault: "openbao",
|
|
25
26
|
email: "smtp",
|
|
26
27
|
} as const;
|
|
@@ -81,9 +82,16 @@ export const SIGNAL_CHOICES: readonly DriverChoice[] = [
|
|
|
81
82
|
export const CLOCK_CHOICES: readonly DriverChoice[] = [
|
|
82
83
|
{ value: "memory", label: "memory" },
|
|
83
84
|
{ value: "file", label: "file" },
|
|
85
|
+
{ value: "postgres", label: "postgres" },
|
|
84
86
|
{ value: "frozen", label: "frozen" },
|
|
85
87
|
];
|
|
86
88
|
|
|
89
|
+
export const JOURNAL_CHOICES: readonly DriverChoice[] = [
|
|
90
|
+
{ value: "memory", label: "memory" },
|
|
91
|
+
{ value: "file", label: "file" },
|
|
92
|
+
{ value: "postgres", label: "postgres" },
|
|
93
|
+
];
|
|
94
|
+
|
|
87
95
|
export const VAULT_CHOICES: readonly DriverChoice[] = [
|
|
88
96
|
{ value: "env", label: "env" },
|
|
89
97
|
{ value: "openbao", label: "openbao" },
|
|
@@ -96,6 +104,7 @@ export const EMAIL_CHOICES: readonly DriverChoice[] = [
|
|
|
96
104
|
{ value: "smtp", label: "smtp" },
|
|
97
105
|
{ value: "resend", label: "resend" },
|
|
98
106
|
{ value: "sndr", label: "sndr" },
|
|
107
|
+
{ value: "taqnyat-mail", label: "taqnyat-mail" },
|
|
99
108
|
];
|
|
100
109
|
|
|
101
110
|
/** AI menu providers → protocol driver. */
|
|
@@ -208,6 +217,7 @@ export function aiDriverForProvider(provider: string): string {
|
|
|
208
217
|
/** Default image pins keyed by role (standard template). */
|
|
209
218
|
export const DEFAULT_IMAGES: Readonly<Record<string, string>> = {
|
|
210
219
|
"store.sql": "postgres:18-alpine",
|
|
220
|
+
pgdog: "ghcr.io/pgdogdev/pgdog:v0.1.51",
|
|
211
221
|
"store.kv": "redis:8-alpine",
|
|
212
222
|
"store.files": "rustfs/rustfs:1.0.0-beta.11",
|
|
213
223
|
"channel.email": "axllent/mailpit:v1.22.3",
|
package/src/transform.ts
CHANGED
|
@@ -286,7 +286,7 @@ ${close}}`;
|
|
|
286
286
|
const IMAGE_ENV_COLUMNS = new Set(["local", "docker", "test", "prod"]);
|
|
287
287
|
|
|
288
288
|
/** Known compose role keys written into `images`. */
|
|
289
|
-
const IMAGE_ROLE_KEY = /^(?:store\.(?:sql|kv|files|index)|channel\.email|vault|ai)$/;
|
|
289
|
+
const IMAGE_ROLE_KEY = /^(?:store\.(?:sql|kv|files|index)|channel\.email|vault|ai|pgdog)$/;
|
|
290
290
|
|
|
291
291
|
/**
|
|
292
292
|
* Keep `images` in sync with chosen docker drivers.
|
|
@@ -312,6 +312,7 @@ function syncImages(source: string, defaults: CreateDefaults): string {
|
|
|
312
312
|
d.store.sql.prod === "pgvector"
|
|
313
313
|
) {
|
|
314
314
|
pin("store.sql", DEFAULT_IMAGES["store.sql"]!);
|
|
315
|
+
pin("pgdog", DEFAULT_IMAGES.pgdog!);
|
|
315
316
|
}
|
|
316
317
|
if (d.store.kv.docker === "redis" || d.signal.docker === "redis") {
|
|
317
318
|
pin("store.kv", DEFAULT_IMAGES["store.kv"]!);
|
|
@@ -7,6 +7,7 @@ Docker-ready [okengine](https://oke.omqkhafi.dev) **Notes** starter — same dom
|
|
|
7
7
|
bun install
|
|
8
8
|
oke mode docker # seeded by create-oke recommended path
|
|
9
9
|
oke dev
|
|
10
|
+
oke db seed # essential welcome note + local/docker sample notes
|
|
10
11
|
```
|
|
11
12
|
|
|
12
13
|
| Surface | URL |
|
|
@@ -26,6 +27,12 @@ oke dev
|
|
|
26
27
|
Configure AI with `oke ai setup` or `create-oke --ai` (writes `src/ai.ts` + `drivers.ai`).
|
|
27
28
|
Without AI, summarize returns a local excerpt (`via: "fallback"`).
|
|
28
29
|
|
|
30
|
+
## Layout extras
|
|
31
|
+
|
|
32
|
+
| Path | Role |
|
|
33
|
+
| ---- | ---- |
|
|
34
|
+
| `src/seed/` | `oke db seed` — essential + dev sample notes |
|
|
35
|
+
|
|
29
36
|
## Drivers
|
|
30
37
|
|
|
31
38
|
See `oke.config.ts`: local sqlite/memory/fs · docker postgres/redis/s3/openbao/smtp.
|
|
@@ -41,9 +41,16 @@ export default defineConfig({
|
|
|
41
41
|
},
|
|
42
42
|
clock: {
|
|
43
43
|
local: "memory",
|
|
44
|
-
docker: "
|
|
44
|
+
docker: "postgres",
|
|
45
45
|
test: "frozen",
|
|
46
|
-
prod: "
|
|
46
|
+
prod: "postgres",
|
|
47
|
+
},
|
|
48
|
+
// Durable-flow journal (durable: true runs) — shared + leased in docker/prod.
|
|
49
|
+
journal: {
|
|
50
|
+
local: "memory",
|
|
51
|
+
docker: "postgres",
|
|
52
|
+
test: "memory",
|
|
53
|
+
prod: "postgres",
|
|
47
54
|
},
|
|
48
55
|
vault: {
|
|
49
56
|
local: "env",
|
|
@@ -63,6 +70,7 @@ export default defineConfig({
|
|
|
63
70
|
},
|
|
64
71
|
images: {
|
|
65
72
|
"store.sql": "postgres:18-alpine",
|
|
73
|
+
pgdog: "ghcr.io/pgdogdev/pgdog:v0.1.51",
|
|
66
74
|
"store.kv": "redis:8-alpine",
|
|
67
75
|
"store.files": "rustfs/rustfs:1.0.0-beta.11",
|
|
68
76
|
"channel.email": "axllent/mailpit:v1.22.3",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { defineSeed, type Fx } from "okengine";
|
|
2
|
+
import { db } from "../core";
|
|
3
|
+
import { notes } from "../schema.decl";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Seed data — run explicitly with `oke db seed` (never at boot).
|
|
7
|
+
*
|
|
8
|
+
* Categories: `essential` (every env) · `dev` (local|docker) · `prod` (prod only).
|
|
9
|
+
* For multi-file composition (`src/seed/essential/*.ts` + arrays here), see
|
|
10
|
+
* Store docs → Seeding.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
async function welcomeNote(fx: Fx) {
|
|
14
|
+
await fx.store(db).upsert(
|
|
15
|
+
notes,
|
|
16
|
+
{ id: "welcome" },
|
|
17
|
+
{
|
|
18
|
+
id: "welcome",
|
|
19
|
+
title: "Welcome",
|
|
20
|
+
body: "Advanced Notes starter — attach files, summarize with AI, daily digest clock.",
|
|
21
|
+
archivedAt: null,
|
|
22
|
+
createdAt: 1,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function sampleNotes(fx: Fx) {
|
|
28
|
+
await fx.store(db).upsert(
|
|
29
|
+
notes,
|
|
30
|
+
{ id: "sample-shipping" },
|
|
31
|
+
{
|
|
32
|
+
id: "sample-shipping",
|
|
33
|
+
title: "Shipping checklist",
|
|
34
|
+
body: "Confirm schema with oke db push (or migrate in docker), then oke db seed.",
|
|
35
|
+
archivedAt: null,
|
|
36
|
+
createdAt: 2,
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
await fx.store(db).upsert(
|
|
40
|
+
notes,
|
|
41
|
+
{ id: "sample-attach" },
|
|
42
|
+
{
|
|
43
|
+
id: "sample-attach",
|
|
44
|
+
title: "Try attach",
|
|
45
|
+
body: "POST /notes/:id/attach stores a text blob on files:uploads.",
|
|
46
|
+
archivedAt: null,
|
|
47
|
+
createdAt: 3,
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
await fx.store(db).upsert(
|
|
51
|
+
notes,
|
|
52
|
+
{ id: "sample-summarize" },
|
|
53
|
+
{
|
|
54
|
+
id: "sample-summarize",
|
|
55
|
+
title: "Try summarize",
|
|
56
|
+
body: "POST /notes/:id/summarize uses fx.ask when AI is configured, else a local excerpt.",
|
|
57
|
+
archivedAt: null,
|
|
58
|
+
createdAt: 4,
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default defineSeed({
|
|
64
|
+
essential: welcomeNote,
|
|
65
|
+
dev: sampleNotes,
|
|
66
|
+
// prod: async (fx) => { /* real production-only data, e.g. register a webhook */ },
|
|
67
|
+
});
|
|
@@ -6,6 +6,7 @@ named Flows, Store, Signal → email, and Vault.
|
|
|
6
6
|
```bash
|
|
7
7
|
bun install
|
|
8
8
|
oke dev
|
|
9
|
+
oke db seed # essential welcome note + local/docker sample notes
|
|
9
10
|
```
|
|
10
11
|
|
|
11
12
|
| Surface | URL |
|
|
@@ -32,6 +33,7 @@ never anonymous `flow_1`.
|
|
|
32
33
|
| Path | Role |
|
|
33
34
|
| ---- | ---- |
|
|
34
35
|
| `src/schema.decl.ts` | `notes` table |
|
|
36
|
+
| `src/seed/` | `oke db seed` — essential + dev sample notes |
|
|
35
37
|
| `src/flows/notes/` | list · create · get · archive · onCreated |
|
|
36
38
|
| `src/flows/main/` | root · health |
|
|
37
39
|
| `src/channels.ts` | `note-created` email template |
|
|
@@ -34,9 +34,16 @@ export default defineConfig({
|
|
|
34
34
|
},
|
|
35
35
|
clock: {
|
|
36
36
|
local: "memory",
|
|
37
|
-
docker: "
|
|
37
|
+
docker: "postgres",
|
|
38
38
|
test: "frozen",
|
|
39
|
-
prod: "
|
|
39
|
+
prod: "postgres",
|
|
40
|
+
},
|
|
41
|
+
// Durable-flow journal (durable: true runs) — shared + leased in docker/prod.
|
|
42
|
+
journal: {
|
|
43
|
+
local: "memory",
|
|
44
|
+
docker: "postgres",
|
|
45
|
+
test: "memory",
|
|
46
|
+
prod: "postgres",
|
|
40
47
|
},
|
|
41
48
|
vault: {
|
|
42
49
|
local: "env",
|
|
@@ -55,6 +62,7 @@ export default defineConfig({
|
|
|
55
62
|
},
|
|
56
63
|
images: {
|
|
57
64
|
"store.sql": "postgres:18-alpine",
|
|
65
|
+
pgdog: "ghcr.io/pgdogdev/pgdog:v0.1.51",
|
|
58
66
|
"store.kv": "redis:8-alpine",
|
|
59
67
|
"store.files": "rustfs/rustfs:1.0.0-beta.11",
|
|
60
68
|
"channel.email": "axllent/mailpit:v1.22.3",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { defineSeed, type Fx } from "okengine";
|
|
2
|
+
import { db } from "../core";
|
|
3
|
+
import { notes } from "../schema.decl";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Seed data — run explicitly with `oke db seed` (never at boot).
|
|
7
|
+
*
|
|
8
|
+
* Categories: `essential` (every env) · `dev` (local|docker) · `prod` (prod only).
|
|
9
|
+
* For multi-file composition (`src/seed/essential/*.ts` + arrays here), see
|
|
10
|
+
* Store docs → Seeding.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
async function welcomeNote(fx: Fx) {
|
|
14
|
+
await fx.store(db).upsert(
|
|
15
|
+
notes,
|
|
16
|
+
{ id: "welcome" },
|
|
17
|
+
{
|
|
18
|
+
id: "welcome",
|
|
19
|
+
title: "Welcome",
|
|
20
|
+
body: "Your Notes API is ready. Create, list, and archive notes over HTTP.",
|
|
21
|
+
archivedAt: null,
|
|
22
|
+
createdAt: 1,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function sampleNotes(fx: Fx) {
|
|
28
|
+
await fx.store(db).upsert(
|
|
29
|
+
notes,
|
|
30
|
+
{ id: "sample-shipping" },
|
|
31
|
+
{
|
|
32
|
+
id: "sample-shipping",
|
|
33
|
+
title: "Shipping checklist",
|
|
34
|
+
body: "Confirm schema with oke db push, then seed with oke db seed.",
|
|
35
|
+
archivedAt: null,
|
|
36
|
+
createdAt: 2,
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
await fx.store(db).upsert(
|
|
40
|
+
notes,
|
|
41
|
+
{ id: "sample-ideas" },
|
|
42
|
+
{
|
|
43
|
+
id: "sample-ideas",
|
|
44
|
+
title: "Ideas",
|
|
45
|
+
body: "Replace these seed rows with your own domain data.",
|
|
46
|
+
archivedAt: null,
|
|
47
|
+
createdAt: 3,
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default defineSeed({
|
|
53
|
+
essential: welcomeNote,
|
|
54
|
+
dev: sampleNotes,
|
|
55
|
+
// prod: async (fx) => { /* real production-only data, e.g. register a webhook */ },
|
|
56
|
+
});
|