@cosmicdrift/kumiko-dev-server 0.289.0 → 0.291.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.
|
|
3
|
+
"version": "0.291.0",
|
|
4
4
|
"description": "Dev-tooling for Kumiko apps: local dev-server bootstrap (runDevApp), scaffolding, codegen. Its compose-stacks/env-schema subpaths are consumed at prod boot too — see @cosmicdrift/kumiko-server-runtime for the prod runner itself.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
"kumiko-upgrade": "./bin/kumiko-upgrade.ts"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
63
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
64
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
65
|
-
"@cosmicdrift/kumiko-server-runtime": "0.
|
|
62
|
+
"@cosmicdrift/kumiko-bundled-features": "0.291.0",
|
|
63
|
+
"@cosmicdrift/kumiko-framework": "0.291.0",
|
|
64
|
+
"@cosmicdrift/kumiko-headless": "0.291.0",
|
|
65
|
+
"@cosmicdrift/kumiko-server-runtime": "0.291.0",
|
|
66
66
|
"ts-morph": "^28.0.0"
|
|
67
67
|
},
|
|
68
68
|
"publishConfig": {
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.291.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "renderWriteHandlerTypes emits the WriteHandlerQn union in stable order",
|
|
6
|
+
"detail": "`renderWriteHandlerTypes` now sorts `handlerQns` before rendering, like its sibling renderers in the same file. The dev-server passes registration order (`collectWriteHandlerQns`) while the CLI/build path passes manifest order, so the same feature set produced a differently ordered `WriteHandlerQn` union in `.kumiko/define.ts` and `.kumiko/types.generated.d.ts` depending on which one ran last. Consumer apps that commit those generated files no longer get order-only diffs after a local `bun dev`."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.289.0",
|
|
4
10
|
"type": "improvement",
|
|
@@ -90,4 +90,11 @@ describe("renderWriteHandlerTypes", () => {
|
|
|
90
90
|
expect(out).toContain("export type WriteHandlerQn =");
|
|
91
91
|
expect(out).toContain('| "tenant:write:create"');
|
|
92
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
|
+
});
|
|
93
100
|
});
|
package/src/codegen/render.ts
CHANGED
|
@@ -296,7 +296,9 @@ export function renderDefineFile(handlerQns: readonly string[] = []): string {
|
|
|
296
296
|
export function renderWriteHandlerTypes(handlerQns: readonly string[]): string {
|
|
297
297
|
if (handlerQns.length === 0) return "";
|
|
298
298
|
|
|
299
|
-
|
|
299
|
+
// Stable order — callers pass registration order (dev-server) or manifest
|
|
300
|
+
// order (CLI); bare sort keeps both byte-identical.
|
|
301
|
+
const lines = [...handlerQns].sort().map((qn) => ` | "${qn}"`);
|
|
300
302
|
return ["", WRITE_HANDLER_QN_MARKER, `export type WriteHandlerQn =`, ...lines, ";", ""].join(
|
|
301
303
|
"\n",
|
|
302
304
|
);
|
package/src/run-dev-app.ts
CHANGED
|
@@ -45,10 +45,6 @@ import {
|
|
|
45
45
|
SESSIONS_FEATURE,
|
|
46
46
|
} from "@cosmicdrift/kumiko-bundled-features/sessions";
|
|
47
47
|
import { TenantQueries } from "@cosmicdrift/kumiko-bundled-features/tenant";
|
|
48
|
-
import {
|
|
49
|
-
resolveTenantLifecycleGate,
|
|
50
|
-
TENANT_LIFECYCLE_FEATURE,
|
|
51
|
-
} from "@cosmicdrift/kumiko-bundled-features/tenant-lifecycle";
|
|
52
48
|
import type { SessionMetadata, TokenVerifier } from "@cosmicdrift/kumiko-framework/api";
|
|
53
49
|
import { createInMemoryLoginRateLimiter } from "@cosmicdrift/kumiko-framework/api";
|
|
54
50
|
import {
|
|
@@ -56,7 +52,6 @@ import {
|
|
|
56
52
|
configurePiiSubjectKms,
|
|
57
53
|
type KmsAdapter,
|
|
58
54
|
} from "@cosmicdrift/kumiko-framework/crypto";
|
|
59
|
-
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
60
55
|
import { configureEntityFieldEncryption } from "@cosmicdrift/kumiko-framework/db";
|
|
61
56
|
import {
|
|
62
57
|
collectWriteHandlerQns,
|
|
@@ -68,6 +63,7 @@ import {
|
|
|
68
63
|
type SessionUser,
|
|
69
64
|
type TenantId,
|
|
70
65
|
type TierResolverPlugin,
|
|
66
|
+
type ValidateBootOptions,
|
|
71
67
|
validateAppCustomScreenWriteQns,
|
|
72
68
|
validateBoot,
|
|
73
69
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
@@ -176,6 +172,8 @@ export type RunDevAppOptions = {
|
|
|
176
172
|
* auth-email-password automatisch dazu gemischt — KEIN doppeltes
|
|
177
173
|
* manuelles Hinzufügen nötig. */
|
|
178
174
|
readonly features: readonly FeatureDefinition[];
|
|
175
|
+
/** Opt-in boot-validator warnings — see ValidateBootOptions. */
|
|
176
|
+
readonly validateBootOptions?: ValidateBootOptions;
|
|
179
177
|
/** Pfad zum Browser-Entry-Modul. Bun.build bündelt es zu /client.js.
|
|
180
178
|
* Mutually exclusive mit `clientEntries`. */
|
|
181
179
|
readonly clientEntry?: string;
|
|
@@ -302,7 +300,7 @@ export async function runDevApp(options: RunDevAppOptions): Promise<KumikoServer
|
|
|
302
300
|
// CrashLoopBackOff sterben ließ (#359). Wirft synchron, bevor ein
|
|
303
301
|
// Socket oder Watcher (codegen-Write) aufgeht.
|
|
304
302
|
try {
|
|
305
|
-
validateBoot(features);
|
|
303
|
+
validateBoot(features, options.validateBootOptions);
|
|
306
304
|
} finally {
|
|
307
305
|
if (setFileStorageProviderEnv) delete process.env["FILE_STORAGE_PROVIDER"];
|
|
308
306
|
}
|
|
@@ -437,10 +435,8 @@ export async function runDevApp(options: RunDevAppOptions): Promise<KumikoServer
|
|
|
437
435
|
// needs the real db+registry (only concrete after setupTestStack). Wired
|
|
438
436
|
// whenever a provider feature (personal-access-tokens today) is mounted.
|
|
439
437
|
let tokenVerifier: TokenVerifier | undefined;
|
|
440
|
-
let lifecycleDb: DbConnection | undefined;
|
|
441
438
|
const patFeature = features.find((f) => f.name === PAT_FEATURE);
|
|
442
439
|
const mfaFeature = features.find((f) => f.name === AUTH_MFA_FEATURE);
|
|
443
|
-
const tenantLifecycleFeature = features.find((f) => f.name === TENANT_LIFECYCLE_FEATURE);
|
|
444
440
|
const patAuthFragment = patFeature
|
|
445
441
|
? {
|
|
446
442
|
tokenVerifier: (rawToken: string) => {
|
|
@@ -456,18 +452,6 @@ export async function runDevApp(options: RunDevAppOptions): Promise<KumikoServer
|
|
|
456
452
|
}
|
|
457
453
|
: {};
|
|
458
454
|
|
|
459
|
-
const tenantLifecycleAuthFragment = tenantLifecycleFeature
|
|
460
|
-
? {
|
|
461
|
-
resolveTenantLifecycleStatus: async (tenantId: string) => {
|
|
462
|
-
if (!lifecycleDb) {
|
|
463
|
-
throw new Error("[runDevApp] tenant-lifecycle gate accessed before onAfterSetup");
|
|
464
|
-
}
|
|
465
|
-
const gate = await resolveTenantLifecycleGate(lifecycleDb, tenantId);
|
|
466
|
-
return gate ? { status: gate.status } : null;
|
|
467
|
-
},
|
|
468
|
-
}
|
|
469
|
-
: {};
|
|
470
|
-
|
|
471
455
|
// Parity with runProdApp (#1372 review): gate on sessionStore provider, not
|
|
472
456
|
// the sessions feature name — a custom provider must also wire auth
|
|
473
457
|
// callbacks. sessionStoreProviderMounted computed above via the registry
|
|
@@ -525,7 +509,6 @@ export async function runDevApp(options: RunDevAppOptions): Promise<KumikoServer
|
|
|
525
509
|
}),
|
|
526
510
|
...sessionAuthFragment,
|
|
527
511
|
...patAuthFragment,
|
|
528
|
-
...tenantLifecycleAuthFragment,
|
|
529
512
|
...(mfaFeature && {
|
|
530
513
|
mfaVerifyHandler: AuthMfaHandlers.verify,
|
|
531
514
|
mfaPreauthEnableStartHandler: AuthMfaHandlers.enableStartPreauth,
|
|
@@ -565,7 +548,6 @@ export async function runDevApp(options: RunDevAppOptions): Promise<KumikoServer
|
|
|
565
548
|
},
|
|
566
549
|
}),
|
|
567
550
|
onAfterSetup: async (stack) => {
|
|
568
|
-
lifecycleDb = stack.db;
|
|
569
551
|
// Sprint-8a: build tier-resolver BEFORE any seeds so seeds can rely
|
|
570
552
|
// on the resolver being live (e.g. seed that writes a SystemAdmin's
|
|
571
553
|
// tier-assignment can immediately read tier-cuts).
|