@cosmicdrift/kumiko-framework 0.73.0 → 0.75.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 +2 -2
- package/src/api/__tests__/auth-routes-cookie.test.ts +2 -3
- package/src/engine/__tests__/build-app-schema-settings-hub.test.ts +4 -4
- package/src/engine/__tests__/build-config-feature-schema.test.ts +1 -1
- package/src/engine/build-app-schema.ts +4 -4
- package/src/engine/build-config-feature-schema.ts +5 -5
- package/src/migrations/__tests__/pending-rebuilds.integration.test.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.75.0",
|
|
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>",
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"zod": "^4.4.3"
|
|
182
182
|
},
|
|
183
183
|
"devDependencies": {
|
|
184
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
184
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.75.0",
|
|
185
185
|
"bun-types": "^1.3.13",
|
|
186
186
|
"pino-pretty": "^13.1.3"
|
|
187
187
|
},
|
|
@@ -259,9 +259,8 @@ describe("auth-routes cookieDomain", () => {
|
|
|
259
259
|
});
|
|
260
260
|
expect(res.status).toBe(200);
|
|
261
261
|
expect(getSetCookieRaw(res, AUTH_COOKIE_NAME)).toMatch(/Domain=example\.eu/i);
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
// Cookie → der Double-Submit-Check läse umgebungsabhängig das falsche.
|
|
262
|
+
// CSRF cookie is rotated with the same common options as the auth cookie:
|
|
263
|
+
// without a Domain attribute it would be host-only and the double-submit check could read the wrong one.
|
|
265
264
|
expect(getSetCookieRaw(res, CSRF_COOKIE_NAME)).toMatch(/Domain=example\.eu/i);
|
|
266
265
|
});
|
|
267
266
|
|
|
@@ -201,10 +201,10 @@ describe("buildAppSchema — Settings-Hub inline placement", () => {
|
|
|
201
201
|
});
|
|
202
202
|
|
|
203
203
|
describe("buildAppSchema — dangling audience-ref dev-warning (#408/3)", () => {
|
|
204
|
-
// billing
|
|
205
|
-
//
|
|
206
|
-
// (
|
|
207
|
-
//
|
|
204
|
+
// billing registers only system+tenant keys → audience-user is NEVER
|
|
205
|
+
// generated. A workspace referencing config:nav:audience-user still boots
|
|
206
|
+
// (the boot-validator exempts the audience QNs), but the entry renders
|
|
207
|
+
// invisibly — the dev must see a warning, not silently nothing.
|
|
208
208
|
function warnsFor(scopes: string[]): string[] {
|
|
209
209
|
const prevEnv = process.env.NODE_ENV;
|
|
210
210
|
process.env.NODE_ENV = "development";
|
|
@@ -240,7 +240,7 @@ describe("buildConfigFeatureSchema — access + workspace", () => {
|
|
|
240
240
|
|
|
241
241
|
test("a screen mixing an openToAll key with role-restricted keys collapses to openToAll", () => {
|
|
242
242
|
// unionAccessRules short-circuits: one openToAll writer opens the whole gate,
|
|
243
|
-
// even next to role-restricted keys
|
|
243
|
+
// even next to role-restricted keys.
|
|
244
244
|
const mixedWrite = defineFeature("mixedwrite", (r) => {
|
|
245
245
|
r.config({
|
|
246
246
|
keys: {
|
|
@@ -156,10 +156,10 @@ function placeSettingsHub(
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
const placedAudiences = new Set<string>();
|
|
159
|
-
// Config-
|
|
160
|
-
//
|
|
161
|
-
//
|
|
162
|
-
//
|
|
159
|
+
// Config-hub navs a workspace references but that were never generated (no
|
|
160
|
+
// audience and no known child) — e.g. `config:nav:audience-user` without any
|
|
161
|
+
// registered user-scope config keys. Otherwise the reference vanishes
|
|
162
|
+
// silently (silent-skip).
|
|
163
163
|
const danglingRefs = new Set<string>();
|
|
164
164
|
const workspaces = appWorkspaces.map((ws) => {
|
|
165
165
|
const additions: string[] = [];
|
|
@@ -135,15 +135,15 @@ export function buildConfigFeatureSchema(registry: Registry): ConfigFeatureSchem
|
|
|
135
135
|
return { screens, navs, workspace: buildSettingsWorkspace(navs) };
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
// Keys
|
|
139
|
-
//
|
|
138
|
+
// Keys visible at `scope`, paired with their effective write roles AT that
|
|
139
|
+
// scope (Home = full write; broader = elevated ∩ write).
|
|
140
140
|
function scopedKeysAt(masked: readonly MaskedKey[], scope: ConfigScope): ScopedKey[] {
|
|
141
141
|
const out: ScopedKey[] = [];
|
|
142
142
|
for (const key of masked) {
|
|
143
143
|
const roles = effectiveWriteRoles(key.def, scope);
|
|
144
|
-
// MACHINE_WRITE_ROLE
|
|
145
|
-
//
|
|
146
|
-
//
|
|
144
|
+
// Strip MACHINE_WRITE_ROLE from the screen roles: a mixed write set
|
|
145
|
+
// (e.g. ["system", "SystemAdmin"]) must not leak "system" into the
|
|
146
|
+
// screen access gate — mirrors the machine-filtered workspace gate.
|
|
147
147
|
const humanRoles = roles.filter((r) => r !== MACHINE_WRITE_ROLE);
|
|
148
148
|
if (humanRoles.length > 0) out.push({ key, roles: humanRoles });
|
|
149
149
|
}
|
|
@@ -296,7 +296,7 @@ describe("enqueueProjectionRebuild — inline fallback (no jobs feature)", () =>
|
|
|
296
296
|
});
|
|
297
297
|
});
|
|
298
298
|
|
|
299
|
-
//
|
|
299
|
+
// jobRunner present but the projection-rebuild job not registered (a
|
|
300
300
|
// caller that wired a jobRunner yet forgot to compose createJobsFeature()). The
|
|
301
301
|
// getJob-capability guard must still fall to the inline rebuild — NOT dispatch
|
|
302
302
|
// onto a runner whose queue has no handler for the job (silent no-op forever).
|