@cosmicdrift/kumiko-dev-server 0.328.1 → 0.330.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.
Files changed (125) hide show
  1. package/README.md +17 -0
  2. package/bin/kumiko-build.ts +3 -2
  3. package/bin/kumiko-dev.ts +1 -1
  4. package/bin/kumiko-init-deploy.ts +1 -1
  5. package/bin/kumiko-schema-check.ts +4 -1
  6. package/dist/build-server-bundle.d.ts +31 -0
  7. package/dist/build-server-bundle.js +282 -0
  8. package/dist/build.d.ts +2 -0
  9. package/dist/build.js +5 -0
  10. package/dist/cli.d.ts +5 -0
  11. package/dist/cli.js +9 -0
  12. package/dist/codegen/index.d.ts +4 -0
  13. package/dist/codegen/index.js +4 -0
  14. package/dist/codegen/render.d.ts +55 -0
  15. package/dist/codegen/render.js +273 -0
  16. package/dist/codegen/run-codegen.d.ts +20 -0
  17. package/dist/codegen/run-codegen.js +219 -0
  18. package/dist/codegen/scan-events.d.ts +76 -0
  19. package/dist/codegen/scan-events.js +447 -0
  20. package/dist/codegen/watch.d.ts +33 -0
  21. package/dist/codegen/watch.js +112 -0
  22. package/dist/compose-stacks.d.ts +60 -0
  23. package/dist/compose-stacks.js +127 -0
  24. package/dist/crash-tracker.d.ts +17 -0
  25. package/dist/crash-tracker.js +37 -0
  26. package/dist/create-kumiko-server.d.ts +195 -0
  27. package/dist/create-kumiko-server.js +1040 -0
  28. package/dist/env-schema.d.ts +15 -0
  29. package/dist/env-schema.js +60 -0
  30. package/dist/few-shot-corpus.d.ts +72 -0
  31. package/dist/few-shot-corpus.js +262 -0
  32. package/dist/framework-version.d.ts +1 -0
  33. package/dist/framework-version.js +31 -0
  34. package/dist/index.d.ts +22 -0
  35. package/dist/index.js +33 -0
  36. package/dist/init-deploy-cli.d.ts +10 -0
  37. package/dist/init-deploy-cli.js +111 -0
  38. package/dist/kebab.d.ts +1 -0
  39. package/{src/kebab.ts → dist/kebab.js} +2 -3
  40. package/dist/run-dev-app.d.ts +174 -0
  41. package/dist/run-dev-app.js +403 -0
  42. package/dist/scaffold-app-feature.d.ts +16 -0
  43. package/dist/scaffold-app-feature.js +240 -0
  44. package/dist/scaffold-app.d.ts +45 -0
  45. package/dist/scaffold-app.js +852 -0
  46. package/dist/scaffold-demo-tasks.d.ts +8 -0
  47. package/{src/scaffold-demo-tasks.ts → dist/scaffold-demo-tasks.js} +69 -98
  48. package/dist/scaffold-deploy.d.ts +92 -0
  49. package/dist/scaffold-deploy.js +254 -0
  50. package/dist/scaffold-feature.d.ts +26 -0
  51. package/dist/scaffold-feature.js +163 -0
  52. package/dist/schema-apply.d.ts +11 -0
  53. package/dist/schema-apply.js +95 -0
  54. package/dist/schema-check-core.d.ts +2 -0
  55. package/{src/schema-check-core.ts → dist/schema-check-core.js} +8 -10
  56. package/dist/schema-tables-auth-mode.d.ts +2 -0
  57. package/{src/schema-tables-auth-mode.ts → dist/schema-tables-auth-mode.js} +2 -10
  58. package/dist/schema-tables-minimal.d.ts +2 -0
  59. package/{src/schema-tables-minimal.ts → dist/schema-tables-minimal.js} +2 -11
  60. package/dist/setup-test-stack-from-features.d.ts +11 -0
  61. package/dist/setup-test-stack-from-features.js +42 -0
  62. package/dist/welcome-banner.d.ts +15 -0
  63. package/dist/welcome-banner.js +27 -0
  64. package/package.json +71 -24
  65. package/src/changes.json +6 -0
  66. package/src/__tests__/build-prod-bundle.integration.test.ts +0 -282
  67. package/src/__tests__/build-server-bundle.test.ts +0 -228
  68. package/src/__tests__/classify-change.test.ts +0 -87
  69. package/src/__tests__/compose-stacks.test.ts +0 -273
  70. package/src/__tests__/config-resolver-default.integration.test.ts +0 -165
  71. package/src/__tests__/crash-tracker.test.ts +0 -89
  72. package/src/__tests__/create-kumiko-server-errors.test.ts +0 -54
  73. package/src/__tests__/create-kumiko-server-options.test.ts +0 -33
  74. package/src/__tests__/create-kumiko-server.integration.test.ts +0 -1007
  75. package/src/__tests__/discover-format.test.ts +0 -32
  76. package/src/__tests__/env-schema.integration.test.ts +0 -248
  77. package/src/__tests__/env-schema.test.ts +0 -132
  78. package/src/__tests__/few-shot-corpus.test.ts +0 -316
  79. package/src/__tests__/framework-version.test.ts +0 -45
  80. package/src/__tests__/init-deploy-cli.test.ts +0 -113
  81. package/src/__tests__/kumiko-schema-check.test.ts +0 -56
  82. package/src/__tests__/merge-extra-context.test.ts +0 -67
  83. package/src/__tests__/resolve-stylesheet.test.ts +0 -132
  84. package/src/__tests__/run-dev-app-boot-validation.test.ts +0 -38
  85. package/src/__tests__/run-dev-app.integration.test.ts +0 -290
  86. package/src/__tests__/runtime-classification.test.ts +0 -26
  87. package/src/__tests__/saas-identity-wire.integration.test.ts +0 -427
  88. package/src/__tests__/scaffold-app-feature.test.ts +0 -216
  89. package/src/__tests__/scaffold-app.test.ts +0 -630
  90. package/src/__tests__/scaffold-demo-tasks.test.ts +0 -47
  91. package/src/__tests__/scaffold-deploy.test.ts +0 -464
  92. package/src/__tests__/scaffold-dev-cycle.integration.test.ts +0 -109
  93. package/src/__tests__/scaffold-feature.test.ts +0 -143
  94. package/src/__tests__/schema-apply.integration.test.ts +0 -191
  95. package/src/__tests__/setup-test-stack-from-features.integration.test.ts +0 -30
  96. package/src/__tests__/setup-test-stack-job-run-logger.integration.test.ts +0 -72
  97. package/src/__tests__/walkthrough.integration.test.ts +0 -140
  98. package/src/__tests__/welcome-banner.test.ts +0 -42
  99. package/src/build-server-bundle.ts +0 -346
  100. package/src/build.ts +0 -28
  101. package/src/codegen/__tests__/render-codegen.test.ts +0 -100
  102. package/src/codegen/__tests__/run-codegen.test.ts +0 -665
  103. package/src/codegen/__tests__/strict-mode-diagnostics.test.ts +0 -347
  104. package/src/codegen/__tests__/watch.test.ts +0 -222
  105. package/src/codegen/index.ts +0 -19
  106. package/src/codegen/render.ts +0 -305
  107. package/src/codegen/run-codegen.ts +0 -278
  108. package/src/codegen/scan-events.ts +0 -565
  109. package/src/codegen/watch.ts +0 -140
  110. package/src/compose-stacks.ts +0 -193
  111. package/src/crash-tracker.ts +0 -56
  112. package/src/create-kumiko-server.ts +0 -1397
  113. package/src/env-schema.ts +0 -72
  114. package/src/few-shot-corpus.ts +0 -370
  115. package/src/framework-version.ts +0 -39
  116. package/src/index.ts +0 -105
  117. package/src/init-deploy-cli.ts +0 -148
  118. package/src/run-dev-app.ts +0 -694
  119. package/src/scaffold-app-feature.ts +0 -283
  120. package/src/scaffold-app.ts +0 -1033
  121. package/src/scaffold-deploy.ts +0 -393
  122. package/src/scaffold-feature.ts +0 -226
  123. package/src/schema-apply.ts +0 -123
  124. package/src/setup-test-stack-from-features.ts +0 -80
  125. package/src/welcome-banner.ts +0 -43
@@ -1,346 +0,0 @@
1
- // buildServerBundle — Production-Server-Bundle für Kumiko-Apps. Pendant zu
2
- // buildProdBundle (Client). Convention-Driven Discovery liest bin/main.ts
3
- // (+ optional <repo>/bin/kumiko.ts) und produziert ein runtime-self-contained
4
- // dist-server/ aus dem ein Bun-Alpine-Container ohne Monorepo bootet.
5
- //
6
- // Convention:
7
- //
8
- // bin/main.ts → dist-server/server.js (App-Boot, ruft runProdApp)
9
- // <repo>/bin/kumiko.ts → dist-server/kumiko.js (Migrate-CLI: `schema apply`,
10
- // gefunden via walk-up bis bin/kumiko.ts)
11
- // dist-server/package.json → runtime-deps mit gepinnten Versionen
12
- //
13
- // Beide Entries werden in EINEM Bun.build-Call mit `splitting` gebaut: das
14
- // Framework landet als geteilte chunk-*.js, server.js + kumiko.js sind schlanke
15
- // Entries die sie importieren — statt das Framework pro Entry neu zu inlinen
16
- // (vorher ~14 MB × N separate Bundles).
17
- //
18
- // Output:
19
- //
20
- // dist-server/
21
- // server.js ← App-Boot-Entry
22
- // kumiko.js ← Migrate-CLI-Entry (wenn bin/kumiko.ts gefunden)
23
- // chunk-*.js ← geteilte Framework-Chunks
24
- // package.json ← runtime-deps mit gepinnten Versionen
25
- //
26
- // Externals — Pakete die NICHT ins Bundle gebakt werden, sondern via
27
- // `bun install` im Runtime-Container nachgeholt werden:
28
- //
29
- // RUNTIME_EXTERNALS — wird zur Laufzeit gebraucht (native bindings,
30
- // worker-threads, dynamic-require). Landet in
31
- // dist-server/package.json#dependencies.
32
- //
33
- // BUILD_ONLY_EXTERNALS — referenziert nur transitiv im Framework, vom
34
- // App-Code aber nie. Tree-Shake wirft sie aus dem
35
- // Bundle, der external-Marker schaltet nur das
36
- // resolution-during-build ab. NICHT in runtime-deps.
37
-
38
- import { existsSync, readFileSync, statSync } from "node:fs";
39
- import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
40
- import { dirname, join, resolve } from "node:path";
41
- import { parseJsonOrThrow, parseJsonSafe } from "@cosmicdrift/kumiko-framework/utils";
42
-
43
- const hasBun = typeof (globalThis as { Bun?: unknown }).Bun !== "undefined";
44
-
45
- // Pakete die das Bundle zur Laufzeit weiter referenziert (`from "<pkg>"` nach
46
- // Tree-Shake). Native bindings (argon2), worker-thread-Loader (bullmq,
47
- // ioredis), dynamic-require (postgres, temporal-polyfill) — alles was unter
48
- // Bun-bundling bricht. (drizzle-kit/drizzle-orm sind raus: der Migrate-Pfad
49
- // nutzt jetzt den framework-eigenen runMigrationsFromDir, kein drizzle-kit.)
50
- // meilisearch: deliberately here, not in BUILD_ONLY_EXTERNALS below — apps
51
- // that import createMeilisearchAdapter (kumiko-framework/search/meilisearch)
52
- // reference the package at runtime (no native binding, plain HTTP client,
53
- // but a real runtime import). Found 2026-07-19: money-horse prod crash
54
- // "Cannot find package 'meilisearch'" because it used to sit in
55
- // BUILD_ONLY_EXTERNALS instead.
56
- const RUNTIME_EXTERNALS = [
57
- "@node-rs/argon2",
58
- "sharp",
59
- "bullmq",
60
- "ioredis",
61
- "postgres",
62
- "temporal-polyfill",
63
- "pino",
64
- "pino-pretty",
65
- "meilisearch",
66
- ] as const;
67
-
68
- // Pakete die nur im Build-Stack erscheinen (transitive Imports im Framework),
69
- // aber vom App-Code nicht referenziert werden. Ohne external-Markierung
70
- // scheitert bun build an dynamic-imports. Tree-Shake wirft sie eh aus dem
71
- // Bundle — der Marker schaltet nur das resolution-during-build ab. NICHT in
72
- // runtime-deps.
73
- const BUILD_ONLY_EXTERNALS = [
74
- "@planetscale/database",
75
- "@libsql/client",
76
- "better-sqlite3",
77
- "@neondatabase/serverless",
78
- "@vercel/postgres",
79
- "mysql2",
80
- // ink (kumiko-tui) hat react-devtools-core als dev-only transitive import.
81
- "react-devtools-core",
82
- ] as const;
83
-
84
- export type BuildServerBundleOptions = {
85
- /** App-Root. Default: process.cwd(). */
86
- readonly cwd?: string;
87
- /** Output-Folder relativ zu cwd. Default: "dist-server". */
88
- readonly outDir?: string;
89
- /** Zusätzliche Pakete die zur Laufzeit installiert sein müssen
90
- * (beyond RUNTIME_EXTERNALS). App-spezifisch — Default leer. */
91
- readonly extraRuntimeExternals?: readonly string[];
92
- /** Zusätzliche Build-only-Externals. App-spezifisch — Default leer. */
93
- readonly extraBuildOnlyExternals?: readonly string[];
94
- };
95
-
96
- export type BuildServerBundleEntry = {
97
- readonly file: string;
98
- readonly sizeBytes: number;
99
- };
100
-
101
- export type BuildServerBundleResult = {
102
- readonly outDir: string;
103
- /** Benannte Entry-Files (server.js, ggf. kumiko.js). */
104
- readonly entries: readonly BuildServerBundleEntry[];
105
- /** Geteilte Framework-Chunks (von splitting). */
106
- readonly chunks: readonly BuildServerBundleEntry[];
107
- /** Gesamt-Größe aller Outputs (entries + chunks) in Bytes. */
108
- readonly totalBytes: number;
109
- readonly runtimeDeps: Readonly<Record<string, string>>;
110
- };
111
-
112
- // Bun benennt Entries nach Source-Basename (bin/main.ts → main.js). server.js
113
- // ist die Runtime-Convention; der Entry wird von nichts importiert (nur die
114
- // chunks werden referenziert, per relativem Pfad), darum ist der Rename sicher.
115
- const ENTRY_RENAMES: Readonly<Record<string, string>> = { "main.js": "server.js" };
116
-
117
- export async function buildServerBundle(
118
- options: BuildServerBundleOptions = {},
119
- ): Promise<BuildServerBundleResult> {
120
- if (!hasBun) {
121
- throw new Error("buildServerBundle requires Bun runtime (Bun.build is missing).");
122
- }
123
-
124
- const cwd = options.cwd ?? process.cwd();
125
- const outDir = resolve(cwd, options.outDir ?? "dist-server");
126
-
127
- const serverEntry = discoverServerEntry(cwd);
128
- if (!serverEntry) {
129
- throw new Error(
130
- `[buildServerBundle] Kein bin/main.ts in ${cwd}.\n Convention: bin/main.ts ist der Server-Bootstrap.`,
131
- );
132
- }
133
-
134
- const repoRoot = findRepoRoot(cwd);
135
- const kumikoCli = repoRoot ? join(repoRoot, "bin/kumiko.ts") : undefined;
136
- if (kumikoCli && !existsSync(kumikoCli)) {
137
- throw new Error(
138
- `[buildServerBundle] Repo-Root erkannt (${repoRoot}), aber bin/kumiko.ts fehlt — kann Migrate-CLI nicht bündeln.`,
139
- );
140
- }
141
-
142
- const externals = [
143
- ...RUNTIME_EXTERNALS,
144
- ...BUILD_ONLY_EXTERNALS,
145
- ...(options.extraRuntimeExternals ?? []),
146
- ...(options.extraBuildOnlyExternals ?? []),
147
- ];
148
-
149
- await rm(outDir, { recursive: true, force: true });
150
- await mkdir(outDir, { recursive: true });
151
-
152
- // Ein Bun.build-Call mit allen Entries + splitting → das Framework wird
153
- // einmal als shared chunk abgelegt statt pro Entry inlined.
154
- const entrypoints = kumikoCli ? [serverEntry, kumikoCli] : [serverEntry];
155
- const result = await Bun.build({
156
- entrypoints,
157
- outdir: outDir,
158
- target: "bun",
159
- external: externals as string[],
160
- splitting: true,
161
- sourcemap: "none",
162
- naming: { entry: "[name].js", chunk: "chunk-[hash].js" },
163
- minify: false,
164
- });
165
- if (!result.success) {
166
- const logs = result.logs.map(String).join("\n");
167
- throw new Error(`[buildServerBundle] build FAILED:\n${logs}`);
168
- }
169
-
170
- // Größe von Disk lesen, nicht aus out.size — letzteres ist für gesplittete
171
- // Entry-Points unzuverlässig (meldet teils ~0 für den Entry-Stub).
172
- const entries: BuildServerBundleEntry[] = [];
173
- const chunks: BuildServerBundleEntry[] = [];
174
- for (const out of result.outputs) {
175
- const base = out.path.split("/").pop() ?? out.path;
176
- if (out.kind === "entry-point") {
177
- const desired = ENTRY_RENAMES[base] ?? base;
178
- if (desired !== base) {
179
- await rename(join(outDir, base), join(outDir, desired));
180
- }
181
- entries.push({ file: desired, sizeBytes: statSync(join(outDir, desired)).size });
182
- } else if (out.kind === "chunk") {
183
- chunks.push({ file: base, sizeBytes: statSync(join(outDir, base)).size });
184
- }
185
- }
186
- entries.sort((a, b) => a.file.localeCompare(b.file));
187
- const totalBytes = [...entries, ...chunks].reduce((sum, e) => sum + e.sizeBytes, 0);
188
-
189
- const runtimeDeps = await resolveRuntimeDepsVersions(cwd, repoRoot, [
190
- ...RUNTIME_EXTERNALS,
191
- ...(options.extraRuntimeExternals ?? []),
192
- ]);
193
-
194
- const runtimePkg = {
195
- name: derivePkgName(cwd),
196
- private: true,
197
- type: "module",
198
- scripts: { start: "bun run server.js" },
199
- dependencies: runtimeDeps,
200
- };
201
- await writeFile(join(outDir, "package.json"), `${JSON.stringify(runtimePkg, null, 2)}\n`);
202
-
203
- return { outDir, entries, chunks, totalBytes, runtimeDeps };
204
- }
205
-
206
- export function discoverServerEntry(cwd: string): string | undefined {
207
- const tsEntry = join(cwd, "bin/main.ts");
208
- if (existsSync(tsEntry)) return tsEntry;
209
- const jsEntry = join(cwd, "bin/main.js");
210
- if (existsSync(jsEntry)) return jsEntry;
211
- return undefined;
212
- }
213
-
214
- // Walking up vom App-cwd bis ein Verzeichnis mit `bin/kumiko.ts` gefunden wird.
215
- // Failsafe: nach 8 Levels aufgeben — nichts gefunden, kein Repo-Root, dann
216
- // liefert die Funktion undefined und der Caller skippt das CLI-Bundle.
217
- function findRepoRoot(start: string): string | undefined {
218
- let cur = start;
219
- for (let i = 0; i < 8; i++) {
220
- if (existsSync(join(cur, "bin/kumiko.ts"))) return cur;
221
- const parent = dirname(cur);
222
- if (parent === cur) return undefined;
223
- cur = parent;
224
- }
225
- return undefined;
226
- }
227
-
228
- /** Read `package.json#kumiko.extraRuntimeExternals` for kumiko-build (#1484).
229
- * Invalid / missing shapes → empty list (CLI stays convention-driven). */
230
- export function readExtraRuntimeExternals(cwd: string): readonly string[] {
231
- const pkgJson = join(cwd, "package.json");
232
- if (!existsSync(pkgJson)) return [];
233
- let raw: string;
234
- try {
235
- raw = readFileSync(pkgJson, "utf-8");
236
- } catch {
237
- return [];
238
- }
239
- const parsed = parseJsonSafe<{
240
- kumiko?: { extraRuntimeExternals?: unknown };
241
- }>(raw, {});
242
- const list = parsed.kumiko?.extraRuntimeExternals;
243
- if (!Array.isArray(list)) return [];
244
- return list.filter((x): x is string => typeof x === "string" && x.trim().length > 0);
245
- }
246
-
247
- // Versionen für RUNTIME_EXTERNALS auflösen: erst aus den installierten
248
- // node_modules/@cosmicdrift/*-Packages (relativ zu cwd — funktioniert für
249
- // jede Consumer-App), dann als Zusatz aus packages/framework + bundled-
250
- // features (Workspace-Checkout des Frameworks selbst). Fallback auf "*"
251
- // wenn keine Quelle den Namen kennt.
252
- async function resolveRuntimeDepsVersions(
253
- cwd: string,
254
- repoRoot: string | undefined,
255
- packages: readonly string[],
256
- ): Promise<Record<string, string>> {
257
- const out: Record<string, string> = {};
258
-
259
- const pinSources = [
260
- ...(repoRoot
261
- ? [
262
- join(repoRoot, "packages/framework/package.json"),
263
- join(repoRoot, "packages/bundled-features/package.json"),
264
- ]
265
- : []),
266
- // node_modules applied last among framework sources so installed versions
267
- // win over the repo-root fallback (#1217).
268
- join(cwd, "node_modules/@cosmicdrift/kumiko-framework/package.json"),
269
- join(cwd, "node_modules/@cosmicdrift/kumiko-bundled-features/package.json"),
270
- ];
271
- const allDeps: Record<string, string> = {};
272
- for (const path of pinSources) {
273
- if (!existsSync(path)) continue;
274
- const raw = await readFile(path, "utf-8");
275
- const parsed = parseJsonOrThrow<{
276
- dependencies?: Record<string, string>;
277
- optionalDependencies?: Record<string, string>;
278
- }>(raw, path);
279
- Object.assign(allDeps, parsed.dependencies ?? {}, parsed.optionalDependencies ?? {});
280
- }
281
- // App package.json fills gaps only — pins extraRuntimeExternals without
282
- // overriding framework-native pins the app may also list (#1484 / review).
283
- const appPkg = join(cwd, "package.json");
284
- if (existsSync(appPkg)) {
285
- const raw = await readFile(appPkg, "utf-8");
286
- const parsed = parseJsonOrThrow<{
287
- dependencies?: Record<string, string>;
288
- optionalDependencies?: Record<string, string>;
289
- }>(raw, appPkg);
290
- for (const [name, ver] of Object.entries({
291
- ...(parsed.dependencies ?? {}),
292
- ...(parsed.optionalDependencies ?? {}),
293
- })) {
294
- if (allDeps[name] === undefined) allDeps[name] = ver;
295
- }
296
- }
297
- for (const pkg of packages) {
298
- out[pkg] = allDeps[pkg] ?? "*";
299
- }
300
- return out;
301
- }
302
-
303
- function derivePkgName(cwd: string): string {
304
- const pkgJson = join(cwd, "package.json");
305
- if (!existsSync(pkgJson)) return "kumiko-app-runtime";
306
- // existsSync/readFileSync race (deleted between the two calls) or a
307
- // permission error must fall back like a missing file, not crash the
308
- // build — read here too, not just the JSON.parse below.
309
- let raw: string;
310
- try {
311
- raw = readFileSync(pkgJson, "utf-8");
312
- } catch {
313
- return "kumiko-app-runtime";
314
- }
315
- const parsed = parseJsonSafe<{ name?: string }>(raw, {});
316
- return parsed.name ? `${parsed.name}-runtime` : "kumiko-app-runtime";
317
- }
318
-
319
- export function formatServerBuildResult(
320
- result: BuildServerBundleResult,
321
- durationMs: number,
322
- ): string {
323
- const cyan = "\x1b[36m";
324
- const dim = "\x1b[2m";
325
- const green = "\x1b[32m";
326
- const reset = "\x1b[0m";
327
- // @wrapper-known semantic-alias
328
- const mb = (bytes: number): string => (bytes / 1024 / 1024).toFixed(2);
329
- const lines: string[] = [];
330
- lines.push("");
331
- lines.push(` ${green}✓${reset} server bundle ${dim}(${durationMs}ms)${reset}`);
332
- for (const entry of result.entries) {
333
- lines.push(` ${cyan}→${reset} ${entry.file} ${mb(entry.sizeBytes)} MB`);
334
- }
335
- if (result.chunks.length > 0) {
336
- const chunkBytes = result.chunks.reduce((sum, c) => sum + c.sizeBytes, 0);
337
- lines.push(
338
- ` ${cyan}→${reset} ${result.chunks.length} shared chunk(s) ${mb(chunkBytes)} MB`,
339
- );
340
- }
341
- const depCount = Object.keys(result.runtimeDeps).length;
342
- lines.push(
343
- ` ${dim}total: ${mb(result.totalBytes)} MB · runtime-deps: ${depCount} packages${reset}`,
344
- );
345
- return lines.join("\n");
346
- }
package/src/build.ts DELETED
@@ -1,28 +0,0 @@
1
- // Build-Toolchain Public-API. Eigener Sub-Path-Export `@cosmicdrift/kumiko-dev-server/build`
2
- // damit der Main-Barrel kein Bun-Toolchain-Bundle in Production-Reads zieht
3
- // (z.B. wenn drizzle-kit die App-Config unter Node lädt).
4
-
5
- export {
6
- ASSETS_DIR,
7
- type BuildManifest,
8
- type BuildProdBundleOptions,
9
- type BuildResult,
10
- buildProdBundle,
11
- type ClientEntry,
12
- type ClientEntryDeclaration,
13
- discoverHtmlTemplate,
14
- formatBuildResult,
15
- injectAssetTags,
16
- readClientEntriesConfig,
17
- resolveClientEntries,
18
- } from "@cosmicdrift/kumiko-server-runtime/build-prod-bundle";
19
-
20
- export {
21
- type BuildServerBundleEntry,
22
- type BuildServerBundleOptions,
23
- type BuildServerBundleResult,
24
- buildServerBundle,
25
- discoverServerEntry,
26
- formatServerBuildResult,
27
- readExtraRuntimeExternals,
28
- } from "./build-server-bundle";
@@ -1,100 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import {
6
- renderDefineFile,
7
- renderInlineSchemasFile,
8
- renderTypesAugmentation,
9
- renderWriteHandlerTypes,
10
- } from "../render";
11
- import type { ScannedEvent } from "../scan-events";
12
-
13
- describe("renderTypesAugmentation", () => {
14
- test("emits empty augmentation when no events", () => {
15
- const out = renderTypesAugmentation([], "/tmp/app/.kumiko");
16
- expect(out).toContain("interface KumikoEventTypeMap");
17
- expect(out).toContain("no r.defineEvent calls discovered yet");
18
- });
19
- });
20
-
21
- describe("renderInlineSchemasFile", () => {
22
- test("returns undefined when no inline schemas", () => {
23
- expect(renderInlineSchemasFile([], "/tmp/app")).toBeUndefined();
24
- });
25
-
26
- test("uses app-root-relative paths in source comments", () => {
27
- const appRoot = mkdtempSync(join(tmpdir(), "kumiko-codegen-"));
28
- const featurePath = join(appRoot, "src", "feature.ts");
29
- mkdirSync(join(appRoot, "src"), { recursive: true });
30
- writeFileSync(featurePath, "// stub", "utf-8");
31
- const events: ScannedEvent[] = [
32
- {
33
- qualifiedName: "inventory:event:product-archived",
34
- schemaSource: {
35
- kind: "inline",
36
- schemaSource: "z.object({ reason: z.string() })",
37
- generatedConstName: "_kg_inventory__productArchived",
38
- },
39
- featureFilePath: featurePath,
40
- source: { file: featurePath, line: 92 },
41
- },
42
- ];
43
- const out = renderInlineSchemasFile(events, appRoot);
44
- expect(out).toContain("// inventory:event:product-archived — from src/feature.ts:92");
45
- expect(out).not.toContain(appRoot);
46
- });
47
-
48
- test("falls back to the bare filename when a feature file is outside the app root", () => {
49
- // A bundled-feature file lives in node_modules, outside the app root —
50
- // relative() would emit `../../..`. The comment falls back to basename.
51
- const appRoot = join(tmpdir(), "kumiko-codegen-app");
52
- const featurePath = join(tmpdir(), "node_modules", "pkg", "dist", "feature.ts");
53
- const events: ScannedEvent[] = [
54
- {
55
- qualifiedName: "bundled:event:thing-happened",
56
- schemaSource: {
57
- kind: "inline",
58
- schemaSource: "z.object({ id: z.string() })",
59
- generatedConstName: "_kg_bundled__thingHappened",
60
- },
61
- featureFilePath: featurePath,
62
- source: { file: featurePath, line: 7 },
63
- },
64
- ];
65
- const out = renderInlineSchemasFile(events, appRoot);
66
- expect(out).toContain("// bundled:event:thing-happened — from feature.ts:7");
67
- expect(out).not.toContain("..");
68
- });
69
- });
70
-
71
- describe("renderDefineFile", () => {
72
- test("emits defineWriteHandler wrapper with type reference", () => {
73
- const out = renderDefineFile();
74
- expect(out).toContain("defineWriteHandler");
75
- expect(out).toContain("types.generated.d.ts");
76
- });
77
-
78
- test("emits createTypedDispatcher when handler QNs provided", () => {
79
- const out = renderDefineFile(["tenant:write:create", "tenant:write:update"]);
80
- expect(out).toContain("export type TypedDispatcher");
81
- expect(out).toContain("export function createTypedDispatcher");
82
- expect(out).toContain('import type { WriteHandlerQn } from "./types.generated"');
83
- expect(out).toContain("export type { WriteHandlerQn };");
84
- });
85
- });
86
-
87
- describe("renderWriteHandlerTypes", () => {
88
- test("emits union type lines", () => {
89
- const out = renderWriteHandlerTypes(["tenant:write:create"]);
90
- expect(out).toContain("export type WriteHandlerQn =");
91
- expect(out).toContain('| "tenant:write:create"');
92
- });
93
-
94
- test("output does not depend on input order", () => {
95
- const out = renderWriteHandlerTypes(["a:write:x", "b:write:y"]);
96
-
97
- expect(renderWriteHandlerTypes(["b:write:y", "a:write:x"])).toBe(out);
98
- expect(out.indexOf('| "a:write:x"')).toBeLessThan(out.indexOf('| "b:write:y"'));
99
- });
100
- });