@cosmicdrift/kumiko-dev-server 0.145.0 → 0.146.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.145.0",
3
+ "version": "0.146.0",
4
4
  "description": "Development server bootstrap for Kumiko apps. Bundles the client, mints dev-JWTs, injects the resolved AppSchema, and seeds an admin. Not for production.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -58,8 +58,8 @@
58
58
  "kumiko-schema-check": "./bin/kumiko-schema-check.ts"
59
59
  },
60
60
  "dependencies": {
61
- "@cosmicdrift/kumiko-bundled-features": "0.145.0",
62
- "@cosmicdrift/kumiko-framework": "0.145.0",
61
+ "@cosmicdrift/kumiko-bundled-features": "0.146.0",
62
+ "@cosmicdrift/kumiko-framework": "0.146.0",
63
63
  "ts-morph": "^28.0.0"
64
64
  },
65
65
  "publishConfig": {
@@ -115,7 +115,10 @@ describe("scaffoldApp", () => {
115
115
  expect(client).toContain("createKumikoApp");
116
116
  expect(client).toContain("emailPasswordClient");
117
117
  expect(client).toContain("DefaultAppShell");
118
- expect(client).toContain("shell: DefaultAppShell");
118
+ expect(client).toContain("shell: AppShell");
119
+ expect(client).toContain("function AppShell(");
120
+ expect(client).toContain("brand={<span");
121
+ expect(client).toContain(">my-shop</span>");
119
122
  expect(client).toContain('from "@cosmicdrift/kumiko-renderer-web"');
120
123
  expect(client).toContain('from "@cosmicdrift/kumiko-bundled-features/auth-email-password/web"');
121
124
  });
@@ -121,7 +121,7 @@ export async function scaffoldApp(options: ScaffoldAppOptions): Promise<Scaffold
121
121
  write(join(destination, "bin", "kumiko.ts"), renderBinKumiko());
122
122
  files.push("bin/kumiko.ts");
123
123
 
124
- write(join(destination, "src", "client.tsx"), renderClient());
124
+ write(join(destination, "src", "client.tsx"), renderClient(options.name));
125
125
  files.push("src/client.tsx");
126
126
 
127
127
  write(join(destination, "src", "styles.css"), renderStylesCss());
@@ -184,6 +184,8 @@ function renderPackageJson(name: string, version: string): string {
184
184
  devDependencies: {
185
185
  "@biomejs/biome": "^2.4.15",
186
186
  "@tailwindcss/cli": "^4.3.0",
187
+ "@types/react": "^19.2.0",
188
+ "@types/react-dom": "^19.2.0",
187
189
  "bun-types": "^1.3.14",
188
190
  tailwindcss: "^4.3.0",
189
191
  typescript: "^6.0.3",
@@ -385,14 +387,14 @@ function renderRunConfig(features?: ReadonlyArray<ScaffoldFeatureEntry>): string
385
387
  sf.insertText(
386
388
  0,
387
389
  [
388
- "// Single source of truth für die Feature-Komposition deiner App.",
389
- "// config/user/tenant/auth-email-password werden via",
390
- "// composeFeatures(includeBundled:true) automatisch ergänzt wenn",
391
- "// runProdApp mit `auth: {…}` aufgerufen wird (siehe bin/main.ts).",
390
+ "// Single source of truth for your app's feature composition.",
391
+ "// config/user/tenant/auth-email-password are added automatically",
392
+ "// via composeFeatures(includeBundled:true) when runProdApp is called",
393
+ "// with `auth: {…}` (see bin/main.ts).",
392
394
  "//",
393
- "// Neue features hinzufügen:",
394
- "// - bunx @cosmicdrift/kumiko-cli add feature <name> (DX-2, automatisch)",
395
- "// - oder: hand-edit + import unten ergänzen",
395
+ "// Add new features:",
396
+ "// - bunx @cosmicdrift/kumiko-cli add feature <name> (DX-2, automatic)",
397
+ "// - or: hand-edit + add the import below",
396
398
  "",
397
399
  "",
398
400
  ].join("\n"),
@@ -493,9 +495,9 @@ function renderMain(appName: string): string {
493
495
  [
494
496
  "// Production-bootstrap. KUMIKO_DRY_RUN_ENV=boot exits after",
495
497
  "// composeFeatures + validateBoot + createRegistry without DB/Redis-connect",
496
- "// (siehe @cosmicdrift/kumiko-dev-server runProdApp). Echter Dev-Boot",
497
- "// passiert via `bunx kumiko dev` (in-repo dev-tool) mit Docker-stack — DX-1.0 deckt nur",
498
- "// den boot-mode-Pfad ab; `kumiko dev` kommt in einer späteren DX-Phase.",
498
+ "// (see @cosmicdrift/kumiko-dev-server runProdApp). The real dev boot",
499
+ "// runs via `bunx kumiko dev` (in-repo dev-tool) with a Docker stack — DX-1.0",
500
+ "// only covers the boot-mode path; `kumiko dev` lands in a later DX phase.",
499
501
  "",
500
502
  "",
501
503
  ].join("\n"),
@@ -570,12 +572,12 @@ function renderDev(appName: string): string {
570
572
  sf.insertText(
571
573
  0,
572
574
  [
573
- "// Dev-bootstrap. `bun --watch bin/dev.ts` (siehe package.json scripts.dev)",
574
- "// startet einen full-featured Dev-Server mit Auto-Reload bei Code-Änderungen.",
575
- "// setupTestStack legt fehlende Entity-Tabellen automatisch anneues",
576
- "// r.entity(...) in einem Feature führt beim nächsten Reboot zu CREATE TABLE,",
577
- "// kein manuelles `kumiko schema apply` nötig (das gilt nur für Prod).",
578
- "// Persistent-DB via KUMIKO_DEV_DB_NAME (.env) damit Admin + Daten Reboots überleben.",
575
+ "// Dev bootstrap. `bun --watch bin/dev.ts` (see package.json scripts.dev)",
576
+ "// starts a full-featured dev server with auto-reload on code changes.",
577
+ "// setupTestStack creates missing entity tables automaticallya new",
578
+ "// r.entity(...) in a feature becomes a CREATE TABLE on the next reboot,",
579
+ "// no manual `kumiko schema apply` needed (that's prod-only).",
580
+ "// Persistent DB via KUMIKO_DEV_DB_NAME (.env) so admin + data survive reboots.",
579
581
  "",
580
582
  "",
581
583
  ].join("\n"),
@@ -584,26 +586,37 @@ function renderDev(appName: string): string {
584
586
  return sf.getFullText();
585
587
  }
586
588
 
587
- function renderClient(): string {
589
+ function renderClient(appName: string): string {
588
590
  return [
589
- "// Browser-Entry. runDevApp's clientEntry-Option bundlet diese Datei zu",
590
- "// /client.js und das Default-HTML lädt sie. createKumikoApp liest das",
591
- "// Schema aus dem window-globalen (das injectSchema im dev-server setzt)",
592
- "// und mountet die Routen.",
591
+ "// Browser entry. runDevApp's clientEntry option bundles this file to",
592
+ "// /client.js and the default HTML loads it. createKumikoApp reads the",
593
+ "// schema from the window global (injectSchema in the dev-server sets it)",
594
+ "// and mounts the routes.",
593
595
  "//",
594
- "// DefaultAppShell liefert die Sidebar + Topbarohne `shell` rendert",
595
- "// createKumikoApp das aktive Screen ohne Layout-Wrapper (= nach Login",
596
- "// nur ein nackter Banner statt der App). emailPasswordClient() bringt",
597
- "// Login-Screen + Session-Provider ohne ihn bliebe /login leer.",
596
+ "// AppShell wraps DefaultAppShell to supply `brand`createKumikoApp's",
597
+ "// shell option only injects schema + children. Without `shell` the",
598
+ "// active screen renders with no layout wrapper (a bare banner after",
599
+ "// login instead of the app). emailPasswordClient() brings the login",
600
+ "// screen + session provider — without it /login stays empty.",
598
601
  "//",
599
- "// Neue Client-Plugins (z.B. notificationsClient()) hier in clientFeatures",
600
- "// hinzusymmetrisch zu APP_FEATURES auf der Server-Seite.",
602
+ "// Add new client plugins (e.g. notificationsClient()) to clientFeatures",
603
+ "// heresymmetric to APP_FEATURES on the server side.",
601
604
  "",
602
605
  'import { emailPasswordClient } from "@cosmicdrift/kumiko-bundled-features/auth-email-password/web";',
603
- 'import { createKumikoApp, DefaultAppShell } from "@cosmicdrift/kumiko-renderer-web";',
606
+ 'import { type AppSchema, createKumikoApp, DefaultAppShell } from "@cosmicdrift/kumiko-renderer-web";',
607
+ 'import type { ReactNode } from "react";',
608
+ "",
609
+ "function AppShell({ children, schema }: { children: ReactNode; schema: AppSchema }): ReactNode {",
610
+ " return (",
611
+ // html-ok: appName is kebab-validated (a-z/0-9/-); this is generated .tsx source, not runtime HTML.
612
+ ` <DefaultAppShell brand={<span className="font-semibold tracking-tight">${appName}</span>} schema={schema}>`,
613
+ " {children}",
614
+ " </DefaultAppShell>",
615
+ " );",
616
+ "}",
604
617
  "",
605
618
  "createKumikoApp({",
606
- " shell: DefaultAppShell,",
619
+ " shell: AppShell,",
607
620
  " clientFeatures: [emailPasswordClient()],",
608
621
  "});",
609
622
  "",
@@ -612,10 +625,10 @@ function renderClient(): string {
612
625
 
613
626
  function renderEnvExample(appName: string): string {
614
627
  const devDb = `${appName.replace(/-/g, "_")}_dev`;
615
- return `# bun dev (runDevApp → setupTestStack) braucht TEST_DATABASE_URL.
616
- # Production (bun bin/main.ts → runProdApp) braucht DATABASE_URL.
617
- # Beide zeigen im Default auf denselben lokalen Postgres — runDevApp legt
618
- # darunter eine eigene "<KUMIKO_DEV_DB_NAME>"-Datenbank an.
628
+ return `# bun dev (runDevApp → setupTestStack) needs TEST_DATABASE_URL.
629
+ # Production (bun bin/main.ts → runProdApp) needs DATABASE_URL.
630
+ # Both default to the same local Postgres — runDevApp creates its own
631
+ # "<KUMIKO_DEV_DB_NAME>" database underneath.
619
632
  TEST_DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/postgres
620
633
  DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/app
621
634
  REDIS_URL=redis://127.0.0.1:6379
@@ -627,9 +640,9 @@ JWT_SECRET=change-me-min-32-chars-change-me-min-32
627
640
  # Generate with: openssl rand -base64 32
628
641
  KUMIKO_SECRETS_MASTER_KEY_V1=
629
642
 
630
- # Dev-only: persistente DB für \`bun dev\`. Ohne diesen Var startet jeder Reboot
631
- # eine frische kumiko_test_<random>-DB → Admin-Login + Daten weg bei jedem Edit.
632
- # Mit Var bleibt die DB zwischen Reboots erhalten (Schema-Pushes sind idempotent).
643
+ # Dev-only: persistent DB for \`bun dev\`. Without this var every reboot starts
644
+ # a fresh kumiko_test_<random> DB → admin login + data gone on every edit.
645
+ # With it the DB persists across reboots (schema pushes are idempotent).
633
646
  KUMIKO_DEV_DB_NAME=${devDb}
634
647
  `;
635
648
  }
@@ -789,7 +802,7 @@ function renderBinKumiko(): string {
789
802
  "const [, , cmd, ...rest] = Bun.argv;",
790
803
  'if (cmd !== "schema") {',
791
804
  " // biome-ignore lint/suspicious/noConsole: CLI output is the feature.",
792
- ' console.error("\\n Unbekannt: kumiko " + (cmd ?? "") + " — nur \'kumiko schema <sub>\' im Standalone-Bundle.\\n");',
805
+ ' console.error("\\n Unknown: kumiko " + (cmd ?? "") + " — only \'kumiko schema <sub>\' in the standalone bundle.\\n");',
793
806
  " process.exit(1);",
794
807
  "}",
795
808
  "",