@cosmicdrift/kumiko-dev-server 0.104.0 → 0.105.1

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.104.0",
3
+ "version": "0.105.1",
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>",
@@ -50,8 +50,8 @@
50
50
  "kumiko-schema-check": "./bin/kumiko-schema-check.ts"
51
51
  },
52
52
  "dependencies": {
53
- "@cosmicdrift/kumiko-bundled-features": "0.104.0",
54
- "@cosmicdrift/kumiko-framework": "0.104.0",
53
+ "@cosmicdrift/kumiko-bundled-features": "0.105.1",
54
+ "@cosmicdrift/kumiko-framework": "0.105.1",
55
55
  "ts-morph": "^28.0.0"
56
56
  },
57
57
  "publishConfig": {
@@ -5,7 +5,7 @@
5
5
  // run-prod-app forwarding pair. Without it a typo or wrong spread-key on the dev
6
6
  // path would silently drop the fail-closed guard and dev/prod would diverge.
7
7
 
8
- import { afterEach, describe, expect, test } from "bun:test";
8
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
9
9
  import { createEntity, createTextField, defineFeature } from "@cosmicdrift/kumiko-framework/engine";
10
10
  import type { KumikoServerHandle } from "../create-kumiko-server";
11
11
  import { runDevApp } from "../run-dev-app";
@@ -24,10 +24,17 @@ const ADMIN = {
24
24
  };
25
25
 
26
26
  let handle: KumikoServerHandle | undefined;
27
+ const savedJwtSecret = process.env["JWT_SECRET"];
28
+
29
+ beforeEach(() => {
30
+ process.env["JWT_SECRET"] = "test-rundev-secret-32-chars-min!!!!";
31
+ });
27
32
 
28
33
  afterEach(async () => {
29
34
  await handle?.stop();
30
35
  handle = undefined;
36
+ if (savedJwtSecret === undefined) delete process.env["JWT_SECRET"];
37
+ else process.env["JWT_SECRET"] = savedJwtSecret;
31
38
  });
32
39
 
33
40
  describe("runDevApp — auth allowedOrigins forwarding (#399/1)", () => {
@@ -73,7 +73,12 @@ import type {
73
73
  PasswordResetSetup,
74
74
  SignupSetup,
75
75
  } from "./run-prod-app";
76
- import { addConfigAccessorFactory, buildBootExtraContext, resolveAuthMail } from "./run-prod-app";
76
+ import {
77
+ addConfigAccessorFactory,
78
+ buildBootExtraContext,
79
+ requireEnv,
80
+ resolveAuthMail,
81
+ } from "./run-prod-app";
77
82
 
78
83
  export type RunDevAppAuthOptions = {
79
84
  /** Admin user to seed at boot. Idempotent — re-runs in persistent-DB
@@ -210,15 +215,10 @@ export async function runDevApp(options: RunDevAppOptions): Promise<KumikoServer
210
215
  // auseinanderdriften können).
211
216
  const envSource = options.envSource ?? process.env;
212
217
  // auth.mail → normalisiert in die expliziten Flow-Felder (symmetrisch zu
213
- // runProdApp). hmacSecret = JWT_SECRET-env mit Dev-Fallback (der Dev-Server
214
- // mintet JWTs selbst; der Reset-Token-HMAC teilt denselben Key wie in den
215
- // Apps). Ab hier IMMER effectiveAuth statt options.auth.
218
+ // runProdApp). hmacSecret = JWT_SECRET-env (fail-fast, symmetrisch zu
219
+ // runProdApp). Ab hier IMMER effectiveAuth statt options.auth.
216
220
  const effectiveAuth = options.auth
217
- ? resolveAuthMail(
218
- options.auth,
219
- envSource["JWT_SECRET"] ?? "kumiko-dev-auth-mail-hmac-fallback-secret",
220
- envSource,
221
- )
221
+ ? resolveAuthMail(options.auth, requireEnv("JWT_SECRET", envSource, "runDevApp"), envSource)
222
222
  : undefined;
223
223
  const composeAuthOptions = buildComposeAuthOptions(effectiveAuth);
224
224
  const features = composeFeatures(options.features, {
@@ -163,11 +163,15 @@ export function buildBunServeOptions(
163
163
  // `src` defaults to process.env but is threaded from the caller's envSource
164
164
  // so the boot-path reads the SAME env-quelle that was validated above —
165
165
  // injected dummies in test-mode must not silently fall back to process.env.
166
- function requireEnv(name: string, src: Record<string, string | undefined> = process.env): string {
166
+ export function requireEnv(
167
+ name: string,
168
+ src: Record<string, string | undefined> = process.env,
169
+ context = "runProdApp",
170
+ ): string {
167
171
  const value = src[name];
168
172
  if (value === undefined || value === "") {
169
173
  throw new Error(
170
- `runProdApp: required env var "${name}" is missing or empty. ` +
174
+ `${context}: required env var "${name}" is missing or empty. ` +
171
175
  `Set it in your container env / .env.production / Coolify secrets.`,
172
176
  );
173
177
  }