@cosmicdrift/kumiko-framework 0.294.0 → 0.294.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-framework",
3
- "version": "0.294.0",
3
+ "version": "0.294.1",
4
4
  "description": "Framework core — engine, pipeline, API, DB, and every other bit that makes Kumiko go.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -198,8 +198,8 @@
198
198
  "./package.json": "./package.json"
199
199
  },
200
200
  "dependencies": {
201
- "@cosmicdrift/kumiko-http": "0.294.0",
202
- "@cosmicdrift/kumiko-types": "0.294.0",
201
+ "@cosmicdrift/kumiko-http": "0.294.1",
202
+ "@cosmicdrift/kumiko-types": "0.294.1",
203
203
  "bullmq": "^5.76.7",
204
204
  "bun-types": "^1.3.13",
205
205
  "hono": "^4.13.1",
@@ -215,7 +215,7 @@
215
215
  "zod": "^4.4.3"
216
216
  },
217
217
  "devDependencies": {
218
- "@cosmicdrift/kumiko-dispatcher-live": "0.294.0",
218
+ "@cosmicdrift/kumiko-dispatcher-live": "0.294.1",
219
219
  "bun-types": "^1.3.13",
220
220
  "pino-pretty": "^13.1.3"
221
221
  },
package/src/changes.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.294.1",
4
+ "type": "fix",
5
+ "title": "Fix parseEnv for refined env schemas with ciphertext-only Key Manager slots",
6
+ "detail": "Relaxing a `kms` slot that is present only as `<NAME>_CIPHERTEXT` used `schema.extend`, which Zod 4 rejects for object schemas carrying refinements (\"Cannot overwrite keys on object schemas containing refinements\"). An app whose composed env schema ends in `.superRefine(...)` therefore failed at boot as soon as its slots were delivered as ciphertext. The relaxation now uses `safeExtend`, which keeps the refinements running."
7
+ },
2
8
  {
3
9
  "version": "0.294.0",
4
10
  "type": "improvement",
@@ -334,6 +334,23 @@ describe("kms env slots", () => {
334
334
  it("parseEnv still validates a kms slot that is set", () => {
335
335
  expect(() => parseEnv(schema, { MASTER_KEY: "" })).toThrow(KumikoBootError);
336
336
  });
337
+
338
+ describe("schema carrying a refinement", () => {
339
+ const refined = schema.superRefine((value, ctx) => {
340
+ if (value.PLAIN === "forbidden") {
341
+ ctx.addIssue({ code: "custom", path: ["PLAIN"], message: "PLAIN is forbidden" });
342
+ }
343
+ });
344
+
345
+ it("parseEnv relaxes a ciphertext-only slot without dropping the refinement", () => {
346
+ expect(parseEnv(refined, { MASTER_KEY_CIPHERTEXT: "abc" })["MASTER_KEY_CIPHERTEXT"]).toBe(
347
+ "abc",
348
+ );
349
+ expect(() => parseEnv(refined, { MASTER_KEY_CIPHERTEXT: "abc", PLAIN: "forbidden" })).toThrow(
350
+ KumikoBootError,
351
+ );
352
+ });
353
+ });
337
354
  });
338
355
 
339
356
  describe("composeEnvSchema kms twins", () => {
package/src/env/index.ts CHANGED
@@ -76,7 +76,8 @@ export function kmsSlotsOf(schema: z.ZodObject<z.ZodRawShape>): readonly string[
76
76
 
77
77
  // A ciphertext-only slot is satisfied by its `_CIPHERTEXT` twin: the plaintext
78
78
  // only exists after the boot-time decrypt, so requiring it here would reject
79
- // exactly the deployment this meta enables.
79
+ // exactly the deployment this meta enables. safeExtend, not extend: Zod 4 throws
80
+ // on extend for schemas carrying refinements (app-level superRefine).
80
81
  function relaxCiphertextOnlySlots<S extends z.ZodObject<z.ZodRawShape>>(
81
82
  schema: S,
82
83
  env: Readonly<Record<string, string>>,
@@ -88,7 +89,7 @@ function relaxCiphertextOnlySlots<S extends z.ZodObject<z.ZodRawShape>>(
88
89
  if (field && env[name] === undefined && env[`${name}_CIPHERTEXT`])
89
90
  relaxed[name] = field.optional();
90
91
  }
91
- return Object.keys(relaxed).length === 0 ? schema : schema.extend(relaxed);
92
+ return Object.keys(relaxed).length === 0 ? schema : schema.safeExtend(relaxed);
92
93
  }
93
94
 
94
95
  // --- Field-classification helpers (Zod v4 introspection) ---