@cosmicdrift/kumiko-dev-server 0.152.0 → 0.153.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 +5 -8
- package/src/__tests__/build-prod-bundle.integration.test.ts +1 -1
- package/src/__tests__/compose-stacks.test.ts +1 -1
- package/src/__tests__/discover-format.test.ts +1 -1
- package/src/__tests__/env-schema.integration.test.ts +1 -1
- package/src/__tests__/walkthrough.integration.test.ts +1 -1
- package/src/build.ts +1 -1
- package/src/create-kumiko-server.ts +12 -6
- package/src/index.ts +4 -12
- package/src/run-dev-app.ts +12 -8
- package/src/scaffold-app.ts +9 -4
- package/src/schema-apply.ts +4 -1
- package/src/schema-check-core.ts +1 -1
- package/src/setup-test-stack-from-features.ts +4 -1
- package/src/__tests__/boot-extra-context.test.ts +0 -140
- package/src/__tests__/build-prod-bundle.test.ts +0 -278
- package/src/__tests__/cache-headers.test.ts +0 -83
- package/src/__tests__/compose-features-mfa-wiring.integration.test.ts +0 -308
- package/src/__tests__/compose-features-wiring.integration.test.ts +0 -382
- package/src/__tests__/compose-features.test.ts +0 -128
- package/src/__tests__/config-seed-boot.integration.test.ts +0 -158
- package/src/__tests__/inject-schema.test.ts +0 -62
- package/src/__tests__/pii-boot-gate.test.ts +0 -68
- package/src/__tests__/renderer-web-css-relocation.integration.test.ts +0 -85
- package/src/__tests__/renderer-web-shell-sentinel.test.ts +0 -35
- package/src/__tests__/require-env.test.ts +0 -29
- package/src/__tests__/resolve-auth-mail.test.ts +0 -69
- package/src/__tests__/resolve-tailwind-cli.test.ts +0 -81
- package/src/__tests__/run-prod-app-env-source.test.ts +0 -157
- package/src/__tests__/run-prod-app-spec.test.ts +0 -57
- package/src/__tests__/run-prod-app.integration.test.ts +0 -915
- package/src/__tests__/session-wiring.test.ts +0 -51
- package/src/__tests__/try-hono-first.test.ts +0 -63
- package/src/boot/__tests__/job-run-logger.test.ts +0 -26
- package/src/boot/apply-boot-seeds.ts +0 -19
- package/src/boot/boot-crypto.ts +0 -82
- package/src/boot/job-run-logger.ts +0 -51
- package/src/build-prod-bundle.ts +0 -692
- package/src/compose-features.ts +0 -164
- package/src/extra-routes-deps.ts +0 -47
- package/src/inject-schema.ts +0 -30
- package/src/pii-boot-gate.ts +0 -62
- package/src/resolve-tailwind-cli.ts +0 -45
- package/src/run-prod-app-boot-context.ts +0 -241
- package/src/run-prod-app-static-files.ts +0 -273
- package/src/run-prod-app.ts +0 -1158
- package/src/session-wiring.ts +0 -29
- package/src/try-hono-first.ts +0 -46
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-dev-server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.153.0",
|
|
4
|
+
"description": "Dev-tooling for Kumiko apps: local dev-server bootstrap (runDevApp), scaffolding, codegen. Not shipped into production node_modules — see @cosmicdrift/kumiko-server-runtime for the prod boot path.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
7
7
|
"repository": {
|
|
@@ -26,10 +26,6 @@
|
|
|
26
26
|
"types": "./src/build.ts",
|
|
27
27
|
"default": "./src/build.ts"
|
|
28
28
|
},
|
|
29
|
-
"./compose-features": {
|
|
30
|
-
"types": "./src/compose-features.ts",
|
|
31
|
-
"default": "./src/compose-features.ts"
|
|
32
|
-
},
|
|
33
29
|
"./compose-stacks": {
|
|
34
30
|
"types": "./src/compose-stacks.ts",
|
|
35
31
|
"default": "./src/compose-stacks.ts"
|
|
@@ -58,8 +54,9 @@
|
|
|
58
54
|
"kumiko-schema-check": "./bin/kumiko-schema-check.ts"
|
|
59
55
|
},
|
|
60
56
|
"dependencies": {
|
|
61
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
62
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
57
|
+
"@cosmicdrift/kumiko-bundled-features": "0.153.0",
|
|
58
|
+
"@cosmicdrift/kumiko-framework": "0.153.0",
|
|
59
|
+
"@cosmicdrift/kumiko-server-runtime": "0.153.0",
|
|
63
60
|
"ts-morph": "^28.0.0"
|
|
64
61
|
},
|
|
65
62
|
"publishConfig": {
|
|
@@ -19,7 +19,7 @@ import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import { dirname, join, resolve } from "node:path";
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
22
|
-
import { buildProdBundle } from "
|
|
22
|
+
import { buildProdBundle } from "@cosmicdrift/kumiko-server-runtime/build-prod-bundle";
|
|
23
23
|
|
|
24
24
|
const __filename = fileURLToPath(import.meta.url);
|
|
25
25
|
const __dirname = dirname(__filename);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import { validateBoot } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import { composeFeatures } from "
|
|
3
|
+
import { composeFeatures } from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
4
4
|
import {
|
|
5
5
|
composeFileStack,
|
|
6
6
|
composeGdprStack,
|
|
@@ -2,7 +2,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
2
2
|
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import { formatBuildResult } from "
|
|
5
|
+
import { formatBuildResult } from "@cosmicdrift/kumiko-server-runtime/build-prod-bundle";
|
|
6
6
|
import { discoverServerEntry } from "../build-server-bundle";
|
|
7
7
|
|
|
8
8
|
describe("discoverServerEntry", () => {
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
import { describe, expect, it } from "bun:test";
|
|
8
8
|
import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
|
|
9
9
|
import { composeEnvSchema, KumikoBootError } from "@cosmicdrift/kumiko-framework/env";
|
|
10
|
+
import { runProdApp } from "@cosmicdrift/kumiko-server-runtime/run-prod-app";
|
|
10
11
|
import { z } from "zod";
|
|
11
12
|
import { frameworkCoreEnvSchema } from "../env-schema";
|
|
12
13
|
import * as devServerPublicApi from "../index";
|
|
13
|
-
import { runProdApp } from "../run-prod-app";
|
|
14
14
|
|
|
15
15
|
const secretsFeature = defineFeature("secrets", (r) => {
|
|
16
16
|
r.envSchema(
|
|
@@ -16,7 +16,7 @@ import { join } from "node:path";
|
|
|
16
16
|
import { createSecretsFeature } from "@cosmicdrift/kumiko-bundled-features/secrets";
|
|
17
17
|
import { createSessionsFeature } from "@cosmicdrift/kumiko-bundled-features/sessions";
|
|
18
18
|
import { createRegistry, defineFeature, validateBoot } from "@cosmicdrift/kumiko-framework/engine";
|
|
19
|
-
import { composeFeatures } from "
|
|
19
|
+
import { composeFeatures } from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
20
20
|
import { scaffoldApp } from "../scaffold-app";
|
|
21
21
|
import { scaffoldAppFeature } from "../scaffold-app-feature";
|
|
22
22
|
|
package/src/build.ts
CHANGED
|
@@ -29,12 +29,18 @@ import {
|
|
|
29
29
|
type TestStackOptions,
|
|
30
30
|
TestUsers,
|
|
31
31
|
} from "@cosmicdrift/kumiko-framework/stack";
|
|
32
|
-
import { startDevJobRunners } from "
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
import { startDevJobRunners } from "@cosmicdrift/kumiko-server-runtime/boot/job-run-logger";
|
|
33
|
+
import { buildBunServeOptions } from "@cosmicdrift/kumiko-server-runtime/bun-serve-options";
|
|
34
|
+
import {
|
|
35
|
+
type ExtraRoutesSystemDeps,
|
|
36
|
+
makeDispatchSystemWrite,
|
|
37
|
+
} from "@cosmicdrift/kumiko-server-runtime/extra-routes-deps";
|
|
38
|
+
import { injectSchema } from "@cosmicdrift/kumiko-server-runtime/inject-schema";
|
|
39
|
+
import {
|
|
40
|
+
canResolveTailwindStylesheet,
|
|
41
|
+
resolveTailwindCli,
|
|
42
|
+
} from "@cosmicdrift/kumiko-server-runtime/resolve-tailwind-cli";
|
|
43
|
+
import { tryHonoFirst } from "@cosmicdrift/kumiko-server-runtime/try-hono-first";
|
|
38
44
|
|
|
39
45
|
// Runtime-detection. The dev-server is meant to run under Bun (Kumiko's
|
|
40
46
|
// target runtime), but the test-suite runs under vitest on Node — we
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
// Login-Routes + Error-Map, ruft seedAdmin im onAfterSetup. Default
|
|
14
14
|
// für Sample-Apps und Showcases — 5-10 Zeilen Bootstrap statt 50.
|
|
15
15
|
|
|
16
|
+
export {
|
|
17
|
+
type ComposeFeaturesOptions,
|
|
18
|
+
composeFeatures,
|
|
19
|
+
} from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
16
20
|
// Build-Toolchain (buildProdBundle, Bun.build, Tailwind-Pipeline, ts-morph) lebt
|
|
17
21
|
// im Sub-Path-Export `@cosmicdrift/kumiko-dev-server/build`. Damit zieht der Main-Barrel
|
|
18
22
|
// kein Bun-Toolchain-Bundle mehr in Production-Reads (z.B. wenn drizzle-kit
|
|
@@ -25,7 +29,6 @@ export {
|
|
|
25
29
|
type ScanWarning,
|
|
26
30
|
scanEvents,
|
|
27
31
|
} from "./codegen";
|
|
28
|
-
export { type ComposeFeaturesOptions, composeFeatures } from "./compose-features";
|
|
29
32
|
export {
|
|
30
33
|
composeFileStack,
|
|
31
34
|
composeGdprStack,
|
|
@@ -62,17 +65,6 @@ export type {
|
|
|
62
65
|
export { buildFewShotCorpus, pathToId } from "./few-shot-corpus";
|
|
63
66
|
export type { RunDevAppAuthOptions, RunDevAppOptions, SeedFn } from "./run-dev-app";
|
|
64
67
|
export { runDevApp } from "./run-dev-app";
|
|
65
|
-
export type {
|
|
66
|
-
EmailVerificationSetup,
|
|
67
|
-
InviteSetup,
|
|
68
|
-
PasswordResetSetup,
|
|
69
|
-
ProdAppHandle,
|
|
70
|
-
ProdSeedFn,
|
|
71
|
-
RunProdAppAuthOptions,
|
|
72
|
-
RunProdAppOptions,
|
|
73
|
-
SignupSetup,
|
|
74
|
-
} from "./run-prod-app";
|
|
75
|
-
export { runProdApp } from "./run-prod-app";
|
|
76
68
|
export type {
|
|
77
69
|
ScaffoldAppOptions,
|
|
78
70
|
ScaffoldAppResult,
|
package/src/run-dev-app.ts
CHANGED
|
@@ -69,28 +69,32 @@ import {
|
|
|
69
69
|
import type { EnvelopeCipher, MasterKeyProvider } from "@cosmicdrift/kumiko-framework/secrets";
|
|
70
70
|
import type { TestStack } from "@cosmicdrift/kumiko-framework/stack";
|
|
71
71
|
import { warnIfNonUtcServerTimeZone } from "@cosmicdrift/kumiko-framework/time";
|
|
72
|
-
import { applyBootSeeds } from "
|
|
73
|
-
import { resolveBootCrypto } from "
|
|
72
|
+
import { applyBootSeeds } from "@cosmicdrift/kumiko-server-runtime/boot/apply-boot-seeds";
|
|
73
|
+
import { resolveBootCrypto } from "@cosmicdrift/kumiko-server-runtime/boot/boot-crypto";
|
|
74
|
+
import {
|
|
75
|
+
buildComposeAuthOptions,
|
|
76
|
+
composeFeatures,
|
|
77
|
+
} from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
78
|
+
import { assertPiiBootInvariants } from "@cosmicdrift/kumiko-server-runtime/pii-boot-gate";
|
|
74
79
|
import { watchAndRegenerate } from "./codegen";
|
|
75
|
-
import { buildComposeAuthOptions, composeFeatures } from "./compose-features";
|
|
76
80
|
import {
|
|
77
81
|
type CreateKumikoServerOptions,
|
|
78
82
|
createKumikoServer,
|
|
79
83
|
type KumikoServerHandle,
|
|
80
84
|
} from "./create-kumiko-server";
|
|
81
|
-
import { assertPiiBootInvariants } from "./pii-boot-gate";
|
|
82
85
|
import { renderWelcomeBanner } from "./welcome-banner";
|
|
83
86
|
|
|
84
87
|
// Re-export der shared Auth-Setup-Types damit Apps nur einen Import-Pfad
|
|
85
88
|
// brauchen. PasswordResetSetup / EmailVerificationSetup leben in
|
|
86
|
-
//
|
|
89
|
+
// @cosmicdrift/kumiko-server-runtime (single source of truth) — hier nur
|
|
90
|
+
// durchgereicht.
|
|
87
91
|
export type {
|
|
88
92
|
AuthMailOptions,
|
|
89
93
|
EmailVerificationSetup,
|
|
90
94
|
InviteSetup,
|
|
91
95
|
PasswordResetSetup,
|
|
92
96
|
SignupSetup,
|
|
93
|
-
} from "
|
|
97
|
+
} from "@cosmicdrift/kumiko-server-runtime/run-prod-app";
|
|
94
98
|
|
|
95
99
|
import type {
|
|
96
100
|
AuthMailOptions,
|
|
@@ -98,13 +102,13 @@ import type {
|
|
|
98
102
|
InviteSetup,
|
|
99
103
|
PasswordResetSetup,
|
|
100
104
|
SignupSetup,
|
|
101
|
-
} from "
|
|
105
|
+
} from "@cosmicdrift/kumiko-server-runtime/run-prod-app";
|
|
102
106
|
import {
|
|
103
107
|
addConfigAccessorFactory,
|
|
104
108
|
buildBootExtraContext,
|
|
105
109
|
requireEnv,
|
|
106
110
|
resolveAuthMail,
|
|
107
|
-
} from "
|
|
111
|
+
} from "@cosmicdrift/kumiko-server-runtime/run-prod-app";
|
|
108
112
|
|
|
109
113
|
export type RunDevAppAuthOptions = {
|
|
110
114
|
/** Admin user to seed at boot. Idempotent — re-runs in persistent-DB
|
package/src/scaffold-app.ts
CHANGED
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
writeSnapshotJson,
|
|
20
20
|
} from "@cosmicdrift/kumiko-framework/db";
|
|
21
21
|
import type { FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
|
|
22
|
+
import { composeFeatures } from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
22
23
|
import { IndentationText, Project, VariableDeclarationKind } from "ts-morph";
|
|
23
|
-
import { composeFeatures } from "./compose-features";
|
|
24
24
|
import { isKebabSegment } from "./kebab";
|
|
25
25
|
import {
|
|
26
26
|
createDemoTasksFeature,
|
|
@@ -177,6 +177,7 @@ function renderPackageJson(name: string, version: string): string {
|
|
|
177
177
|
"@cosmicdrift/kumiko-dev-server": version,
|
|
178
178
|
"@cosmicdrift/kumiko-framework": version,
|
|
179
179
|
"@cosmicdrift/kumiko-renderer-web": version,
|
|
180
|
+
"@cosmicdrift/kumiko-server-runtime": version,
|
|
180
181
|
react: "^19.2.6",
|
|
181
182
|
"react-dom": "^19.2.6",
|
|
182
183
|
zod: "^4.4.3",
|
|
@@ -410,7 +411,11 @@ function renderMain(appName: string): string {
|
|
|
410
411
|
|
|
411
412
|
sf.addImportDeclaration({
|
|
412
413
|
moduleSpecifier: "@cosmicdrift/kumiko-dev-server",
|
|
413
|
-
namedImports: ["
|
|
414
|
+
namedImports: ["frameworkCoreEnvSchema"],
|
|
415
|
+
});
|
|
416
|
+
sf.addImportDeclaration({
|
|
417
|
+
moduleSpecifier: "@cosmicdrift/kumiko-server-runtime",
|
|
418
|
+
namedImports: ["composeFeatures", "runProdApp"],
|
|
414
419
|
});
|
|
415
420
|
sf.addImportDeclaration({
|
|
416
421
|
moduleSpecifier: "@cosmicdrift/kumiko-framework/engine",
|
|
@@ -773,7 +778,7 @@ function renderKumikoSchema(): string {
|
|
|
773
778
|
"// Computes table-metas from the SAME composeFeatures(APP_FEATURES) the",
|
|
774
779
|
"// runtime sees (runProdApp/runDevApp) — migration and runtime cannot drift.",
|
|
775
780
|
"",
|
|
776
|
-
'import { composeFeatures } from "@cosmicdrift/kumiko-
|
|
781
|
+
'import { composeFeatures } from "@cosmicdrift/kumiko-server-runtime/compose-features";',
|
|
777
782
|
'import { collectTableMetas, type EntityTableMeta } from "@cosmicdrift/kumiko-framework/db";',
|
|
778
783
|
'import type { FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";',
|
|
779
784
|
'import { APP_FEATURES, HAS_AUTH } from "../src/run-config";',
|
|
@@ -795,7 +800,7 @@ function renderBinKumiko(): string {
|
|
|
795
800
|
"// migrate-step runs `bun /app/kumiko.js schema apply`; kumiko-build bundles",
|
|
796
801
|
"// this file to dist-server/kumiko.js.",
|
|
797
802
|
"",
|
|
798
|
-
'import { composeFeatures } from "@cosmicdrift/kumiko-
|
|
803
|
+
'import { composeFeatures } from "@cosmicdrift/kumiko-server-runtime/compose-features";',
|
|
799
804
|
'import { runSchemaCli } from "@cosmicdrift/kumiko-framework/schema-cli";',
|
|
800
805
|
'import { APP_FEATURES, HAS_AUTH } from "../src/run-config";',
|
|
801
806
|
"",
|
package/src/schema-apply.ts
CHANGED
|
@@ -22,7 +22,10 @@ import {
|
|
|
22
22
|
createProjectionStateTable,
|
|
23
23
|
rebuildProjection,
|
|
24
24
|
} from "@cosmicdrift/kumiko-framework/pipeline";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
type ComposeFeaturesOptions,
|
|
27
|
+
composeFeatures,
|
|
28
|
+
} from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
26
29
|
|
|
27
30
|
export type SchemaApplyOptions = ComposeFeaturesOptions & {
|
|
28
31
|
/** App-Features (z.B. APP_FEATURES aus run-config) — composed mit den
|
package/src/schema-check-core.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { resolve } from "node:path";
|
|
7
|
-
import { composeFeatures } from "
|
|
7
|
+
import { composeFeatures } from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
8
8
|
|
|
9
9
|
// The generate-script lives under different roots across apps: publicstatus
|
|
10
10
|
// uses `drizzle/generate.ts`, the framework's own sample-apps use
|
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
type TestStack,
|
|
10
10
|
type TestStackOptions,
|
|
11
11
|
} from "@cosmicdrift/kumiko-framework/stack";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
type ComposeFeaturesOptions,
|
|
14
|
+
composeFeatures,
|
|
15
|
+
} from "@cosmicdrift/kumiko-server-runtime/compose-features";
|
|
13
16
|
|
|
14
17
|
export type TestStackPreset = "config" | "text-content";
|
|
15
18
|
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { createDeliveryFeature } from "@cosmicdrift/kumiko-bundled-features/delivery";
|
|
3
|
-
import { createSecretsFeature } from "@cosmicdrift/kumiko-bundled-features/secrets";
|
|
4
|
-
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
5
|
-
import { createRegistry, defineFeature } from "@cosmicdrift/kumiko-framework/engine";
|
|
6
|
-
import type { MasterKeyProvider } from "@cosmicdrift/kumiko-framework/secrets";
|
|
7
|
-
import { buildBootExtraContext } from "../run-prod-app";
|
|
8
|
-
|
|
9
|
-
// Pins runProdApp's framework-default-provider autowire (buildBootExtraContext):
|
|
10
|
-
// textContent unconditional, secrets feature-gated, KEK-env trap avoided, the
|
|
11
|
-
// money-horse regression (no secrets feature → no forced KEK → no throw), and
|
|
12
|
-
// the delivery _notifyFactory wiring that makes ctx.notify work in prod (only
|
|
13
|
-
// test-wired before — runProdApp/runDevApp call THIS, not createDeliveryTestContext).
|
|
14
|
-
|
|
15
|
-
// db is never touched at construction time — createTextContentApi /
|
|
16
|
-
// createSecretsContext only store the handle and query lazily. A bare stub
|
|
17
|
-
// keeps this a fast unit test (no Postgres) instead of a full boot.
|
|
18
|
-
const fakeDb = {} as unknown as DbConnection;
|
|
19
|
-
const registry = createRegistry([]);
|
|
20
|
-
const KEK = Buffer.alloc(32, 7).toString("base64");
|
|
21
|
-
|
|
22
|
-
const otherFeature = defineFeature("widgets", () => {});
|
|
23
|
-
|
|
24
|
-
describe("buildBootExtraContext — framework-default provider autowire", () => {
|
|
25
|
-
test("textContent is wired unconditionally (no secrets feature, no auth)", () => {
|
|
26
|
-
const ctx = buildBootExtraContext({
|
|
27
|
-
db: fakeDb,
|
|
28
|
-
features: [otherFeature],
|
|
29
|
-
envSource: {},
|
|
30
|
-
registry,
|
|
31
|
-
hasAuth: false,
|
|
32
|
-
});
|
|
33
|
-
expect(typeof (ctx["textContent"] as { getBlock?: unknown }).getBlock).toBe("function");
|
|
34
|
-
expect(ctx["secrets"]).toBeUndefined();
|
|
35
|
-
expect(ctx["configResolver"]).toBeUndefined();
|
|
36
|
-
expect(ctx["_notifyFactory"]).toBeUndefined();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test("delivery feature mounted → _notifyFactory wired (ctx.notify works in prod)", () => {
|
|
40
|
-
const ctx = buildBootExtraContext({
|
|
41
|
-
db: fakeDb,
|
|
42
|
-
features: [createDeliveryFeature()],
|
|
43
|
-
envSource: {},
|
|
44
|
-
registry,
|
|
45
|
-
hasAuth: false,
|
|
46
|
-
});
|
|
47
|
-
expect(typeof ctx["_notifyFactory"]).toBe("function");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("no delivery feature → _notifyFactory not wired", () => {
|
|
51
|
-
const ctx = buildBootExtraContext({
|
|
52
|
-
db: fakeDb,
|
|
53
|
-
features: [otherFeature],
|
|
54
|
-
envSource: {},
|
|
55
|
-
registry,
|
|
56
|
-
hasAuth: false,
|
|
57
|
-
});
|
|
58
|
-
expect(ctx["_notifyFactory"]).toBeUndefined();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test("secrets feature mounted + valid KEK env → ctx.secrets wired", () => {
|
|
62
|
-
const ctx = buildBootExtraContext({
|
|
63
|
-
db: fakeDb,
|
|
64
|
-
features: [createSecretsFeature()],
|
|
65
|
-
envSource: {
|
|
66
|
-
KUMIKO_SECRETS_MASTER_KEY_V1: KEK,
|
|
67
|
-
KUMIKO_SECRETS_MASTER_KEY_CURRENT_VERSION: "1",
|
|
68
|
-
},
|
|
69
|
-
registry,
|
|
70
|
-
hasAuth: false,
|
|
71
|
-
});
|
|
72
|
-
const secrets = ctx["secrets"] as {
|
|
73
|
-
get?: unknown;
|
|
74
|
-
set?: unknown;
|
|
75
|
-
has?: unknown;
|
|
76
|
-
delete?: unknown;
|
|
77
|
-
};
|
|
78
|
-
expect(typeof secrets.get).toBe("function");
|
|
79
|
-
expect(typeof secrets.set).toBe("function");
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("secrets feature mounted, only V1 set (no CURRENT_VERSION) → wired (default '1')", () => {
|
|
83
|
-
const ctx = buildBootExtraContext({
|
|
84
|
-
db: fakeDb,
|
|
85
|
-
features: [createSecretsFeature()],
|
|
86
|
-
envSource: { KUMIKO_SECRETS_MASTER_KEY_V1: KEK },
|
|
87
|
-
registry,
|
|
88
|
-
hasAuth: false,
|
|
89
|
-
});
|
|
90
|
-
expect(ctx["secrets"]).toBeDefined();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test("secrets feature mounted but NO KEK + no override → skipped, no throw (dev DEV_KEY path)", () => {
|
|
94
|
-
// dev wires its own DEV_KEY secrets explicitly; the auto-wire must not
|
|
95
|
-
// eagerly construct an env-provider and crash the boot when no env KEK
|
|
96
|
-
// exists. ctx.secrets stays unset so the app's explicit wiring wins.
|
|
97
|
-
let ctx: Record<string, unknown> | undefined;
|
|
98
|
-
expect(() => {
|
|
99
|
-
ctx = buildBootExtraContext({
|
|
100
|
-
db: fakeDb,
|
|
101
|
-
features: [createSecretsFeature()],
|
|
102
|
-
envSource: {},
|
|
103
|
-
registry,
|
|
104
|
-
hasAuth: false,
|
|
105
|
-
});
|
|
106
|
-
}).not.toThrow();
|
|
107
|
-
expect(ctx?.["secrets"]).toBeUndefined();
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test("no secrets feature → no KEK ever read, boots green (money-horse regression)", () => {
|
|
111
|
-
const ctx = buildBootExtraContext({
|
|
112
|
-
db: fakeDb,
|
|
113
|
-
features: [otherFeature],
|
|
114
|
-
envSource: {}, // no KEK — must NOT matter when secrets isn't mounted
|
|
115
|
-
registry,
|
|
116
|
-
hasAuth: false,
|
|
117
|
-
});
|
|
118
|
-
expect(ctx["secrets"]).toBeUndefined();
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
test("masterKey override is used verbatim — no env-provider built", () => {
|
|
122
|
-
const override: MasterKeyProvider = {
|
|
123
|
-
wrapDek: async () => ({ encryptedDek: Buffer.alloc(0), kekVersion: 1 }),
|
|
124
|
-
unwrapDek: async () => Buffer.alloc(0),
|
|
125
|
-
currentVersion: () => 1,
|
|
126
|
-
isAvailable: async () => true,
|
|
127
|
-
};
|
|
128
|
-
// envSource is empty: if the override weren't honoured, createEnvMasterKeyProvider
|
|
129
|
-
// would throw "no KEK". It doesn't → the override path is taken.
|
|
130
|
-
const ctx = buildBootExtraContext({
|
|
131
|
-
db: fakeDb,
|
|
132
|
-
features: [createSecretsFeature()],
|
|
133
|
-
envSource: {},
|
|
134
|
-
registry,
|
|
135
|
-
hasAuth: false,
|
|
136
|
-
masterKey: override,
|
|
137
|
-
});
|
|
138
|
-
expect(ctx["secrets"]).toBeDefined();
|
|
139
|
-
});
|
|
140
|
-
});
|