@cosmicdrift/kumiko-server-runtime 0.352.0 → 0.354.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/dist/boot/worker-boot-core.js +1 -0
- package/dist/build-prod-bundle.d.ts +1 -1
- package/dist/build-prod-bundle.js +4 -5
- package/dist/pii-boot-gate.js +1 -1
- package/dist/request-bound-system-query.d.ts +12 -0
- package/dist/request-bound-system-query.js +15 -0
- package/dist/run-prod-app-boot-context.d.ts +3 -0
- package/dist/run-prod-app-boot-context.js +12 -5
- package/dist/run-prod-app-static-files.d.ts +1 -5
- package/dist/run-prod-app-static-files.js +15 -6
- package/dist/run-prod-app.js +30 -16
- package/package.json +14 -6
- package/src/changes.json +19 -0
|
@@ -139,6 +139,7 @@ export async function bootWorkerProcess(options, envSource, profile) {
|
|
|
139
139
|
envSource,
|
|
140
140
|
registry,
|
|
141
141
|
hasAuth: includeBundled,
|
|
142
|
+
redis,
|
|
142
143
|
crypto: bootCrypto,
|
|
143
144
|
...(options.kms && { kms: options.kms }),
|
|
144
145
|
...(profile.deliverQueuedInline === true && { deliverQueuedInline: true }),
|
|
@@ -43,6 +43,7 @@ export type BuildInfo = {
|
|
|
43
43
|
/** ISO-Zeitstempel des Builds, lesbare Anzeige-Version (ersetzt den rohen sha). */
|
|
44
44
|
readonly builtAt: string;
|
|
45
45
|
};
|
|
46
|
+
export declare const DEFAULT_HTML = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1,interactive-widget=resizes-content\" />\n <title>Kumiko</title>\n </head>\n <body>\n <div id=\"root\"></div>\n </body>\n</html>\n";
|
|
46
47
|
/** Folder name relative to dist/ for hashed assets (JS, CSS, file-loader
|
|
47
48
|
* outputs). Exported damit runProdApp dieselbe Konvention für Cache-
|
|
48
49
|
* Header nutzt — Drift verhindern. */
|
|
@@ -94,7 +95,6 @@ export declare function assertRendererWebShellPresent(css: string, stylesheet: R
|
|
|
94
95
|
export declare function discoverHtmlTemplate(cwd: string): string | undefined;
|
|
95
96
|
export declare function runTailwindOnce(entry: string, cwd: string): Promise<string>;
|
|
96
97
|
export declare function isEntryOutputFor(outName: string, baseName: string): boolean;
|
|
97
|
-
export declare function buildMissingTemplateError(manifest: BuildManifest, entry: ClientEntry): string;
|
|
98
98
|
export declare function injectAssetTags(html: string, manifest: BuildManifest, entry: ClientEntry, buildInfo?: BuildInfo): string;
|
|
99
99
|
export declare function computeBuildId(manifest: BuildManifest): string;
|
|
100
100
|
/** Formatiert ein BuildResult als CLI-freundliche Mehrzeilen-Zusammenfassung
|
|
@@ -67,7 +67,7 @@ const hasBun = typeof globalThis.Bun !== "undefined";
|
|
|
67
67
|
// index.html mit den richtigen Placeholder-Tags.
|
|
68
68
|
// interactive-widget=resizes-content (fw#1918): keeps `position: fixed`
|
|
69
69
|
// bottom bars anchored above a mobile keyboard instead of behind it.
|
|
70
|
-
const DEFAULT_HTML = `<!doctype html>
|
|
70
|
+
export const DEFAULT_HTML = `<!doctype html>
|
|
71
71
|
<html lang="en">
|
|
72
72
|
<head>
|
|
73
73
|
<meta charset="utf-8" />
|
|
@@ -672,10 +672,9 @@ async function renderHtml(templatePath, manifest, entry, buildInfo) {
|
|
|
672
672
|
const template = templatePath ? await readFile(templatePath, "utf8") : DEFAULT_HTML;
|
|
673
673
|
return injectAssetTags(template, manifest, entry, buildInfo);
|
|
674
674
|
}
|
|
675
|
-
//
|
|
676
|
-
//
|
|
677
|
-
|
|
678
|
-
export function buildMissingTemplateError(manifest, entry) {
|
|
675
|
+
// The message must name the source file and, for a declared multi-entry,
|
|
676
|
+
// which package.json "kumiko.clientEntries" entry it came from.
|
|
677
|
+
function buildMissingTemplateError(manifest, entry) {
|
|
679
678
|
const cssLine = manifest["styles.css"]
|
|
680
679
|
? ` <link rel="stylesheet" href="/styles.css" />\n`
|
|
681
680
|
: "";
|
package/dist/pii-boot-gate.js
CHANGED
|
@@ -17,7 +17,7 @@ export function assertPiiBootInvariants(features, opts) {
|
|
|
17
17
|
// encryptEventPayloadPii no-ops without a KMS, so a catalogued event writes
|
|
18
18
|
// plaintext PII into kumiko_events with nothing to crypto-shred later.
|
|
19
19
|
const piiEvents = features.flatMap((feature) => Object.values(feature.events ?? {})
|
|
20
|
-
.filter((event) => event.piiFields !==
|
|
20
|
+
.filter((event) => event.piiFields !== "none")
|
|
21
21
|
.map((event) => event.name));
|
|
22
22
|
// skip: nothing PII-annotated is mounted — plaintext gate is moot.
|
|
23
23
|
if (piiEntities.length === 0 && piiEvents.length === 0)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ClientIpResolver } from "@cosmicdrift/kumiko-framework/api";
|
|
2
|
+
import { type SessionUser } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
+
import type { PageHeadSystemQuery } from "@cosmicdrift/kumiko-headless/apex";
|
|
4
|
+
export type QueryDispatcher = {
|
|
5
|
+
readonly query: (type: string, payload: unknown, user: SessionUser) => Promise<unknown>;
|
|
6
|
+
};
|
|
7
|
+
export declare function buildRequestBoundSystemQuery(params: {
|
|
8
|
+
readonly req: Request;
|
|
9
|
+
readonly dispatcher: QueryDispatcher;
|
|
10
|
+
readonly resolver: ClientIpResolver;
|
|
11
|
+
readonly socketAddress?: string;
|
|
12
|
+
}): PageHeadSystemQuery;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { buildRequestContextDataFromRequest, } from "@cosmicdrift/kumiko-framework/api";
|
|
2
|
+
import { createAnonymousUser } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
+
import { requestContext } from "@cosmicdrift/kumiko-framework/internal/request-context";
|
|
4
|
+
// Single wiring for the anonymous-role systemQuery that page-head and
|
|
5
|
+
// hostDispatch resolvers receive, shared by runProdApp and the dev server so
|
|
6
|
+
// the anonymous role / request-context / client-IP resolution can't drift.
|
|
7
|
+
export function buildRequestBoundSystemQuery(params) {
|
|
8
|
+
const { req, dispatcher, resolver, socketAddress } = params;
|
|
9
|
+
return (type, payload, tenantId, options) => {
|
|
10
|
+
const base = requestContext.get() ?? buildRequestContextDataFromRequest(req, { resolver, socketAddress });
|
|
11
|
+
// The caller's signal replaces the request's: it already folds the request signal in.
|
|
12
|
+
const data = options?.signal ? { ...base, signal: options.signal } : base;
|
|
13
|
+
return requestContext.run(data, () => dispatcher.query(type, payload, createAnonymousUser(tenantId)));
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -6,6 +6,7 @@ import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
|
6
6
|
import type { ConfigResolver, FeatureDefinition, Registry } from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
import type { Logger } from "@cosmicdrift/kumiko-framework/logging";
|
|
8
8
|
import type { MasterKeyProvider } from "@cosmicdrift/kumiko-framework/secrets";
|
|
9
|
+
import type { Redis } from "ioredis";
|
|
9
10
|
import { type BootCrypto } from "./boot/boot-crypto.js";
|
|
10
11
|
import type { AuthMailOptions, EmailVerificationSetup, InviteSetup, PasswordResetSetup, SignupSetup } from "./run-prod-app.js";
|
|
11
12
|
export declare function addConfigAccessorFactory<T extends {
|
|
@@ -21,6 +22,8 @@ export declare function buildBootExtraContext(opts: {
|
|
|
21
22
|
readonly crypto?: BootCrypto;
|
|
22
23
|
readonly masterKey?: MasterKeyProvider;
|
|
23
24
|
readonly sseBroker?: SseBroker;
|
|
25
|
+
/** Backs notify's idempotencyKey dedup; without it such a notify throws. */
|
|
26
|
+
readonly redis?: Redis;
|
|
24
27
|
readonly kms?: KmsAdapter;
|
|
25
28
|
/** One-shot process (runBootstrap): nothing drains its job queue once it
|
|
26
29
|
* exits, so queued channels must send inline instead of enqueueing. */
|
|
@@ -49,6 +49,7 @@ function buildDeliveryNotifyFactory(opts) {
|
|
|
49
49
|
db: opts.db,
|
|
50
50
|
registry: opts.registry,
|
|
51
51
|
channels: collectChannels(opts.registry),
|
|
52
|
+
...(opts.redis && { idempotencyRedis: opts.redis }),
|
|
52
53
|
...(opts.secrets && { secrets: opts.secrets }),
|
|
53
54
|
...(opts.sseBroker && { sseBroker: opts.sseBroker }),
|
|
54
55
|
...(opts.escapeHatchAuditSink && { escapeHatchAuditSink: opts.escapeHatchAuditSink }),
|
|
@@ -83,6 +84,15 @@ function resolveBootSecrets(db, features, crypto, registry) {
|
|
|
83
84
|
dekCache: crypto.dekCache,
|
|
84
85
|
});
|
|
85
86
|
}
|
|
87
|
+
function bootCryptoContext(crypto) {
|
|
88
|
+
return {
|
|
89
|
+
...(crypto.masterKeyProvider && { masterKeyProvider: crypto.masterKeyProvider }),
|
|
90
|
+
// Encrypt/decrypt partner for `encrypted: true` config keys. Wired
|
|
91
|
+
// whenever a master key exists — NOT gated on the secrets feature,
|
|
92
|
+
// config encryption must work without mounting ctx.secrets.
|
|
93
|
+
...(crypto.configCipher && { configEncryption: crypto.configCipher }),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
86
96
|
export function buildBootExtraContext(opts) {
|
|
87
97
|
const crypto = opts.crypto ?? resolveBootCrypto(opts.envSource, opts.masterKey);
|
|
88
98
|
const hasDeliveryFeature = opts.features.some((f) => f.name === DELIVERY_FEATURE);
|
|
@@ -98,6 +108,7 @@ export function buildBootExtraContext(opts) {
|
|
|
98
108
|
registry: opts.registry,
|
|
99
109
|
...(secrets && { secrets }),
|
|
100
110
|
...(opts.sseBroker && { sseBroker: opts.sseBroker }),
|
|
111
|
+
...(opts.redis && { redis: opts.redis }),
|
|
101
112
|
...(escapeHatchAuditSink && { escapeHatchAuditSink }),
|
|
102
113
|
...(opts.log && { log: opts.log }),
|
|
103
114
|
deliverQueuedInline: opts.deliverQueuedInline,
|
|
@@ -105,11 +116,7 @@ export function buildBootExtraContext(opts) {
|
|
|
105
116
|
}),
|
|
106
117
|
// Top-level provider so feature jobs (secrets rotate, config reencrypt)
|
|
107
118
|
// reach it via ctx — previously only test-stack wired it.
|
|
108
|
-
...(crypto
|
|
109
|
-
// Encrypt/decrypt partner for `encrypted: true` config keys. Wired
|
|
110
|
-
// whenever a master key exists — NOT gated on the secrets feature,
|
|
111
|
-
// config encryption must work without mounting ctx.secrets.
|
|
112
|
-
...(crypto.configCipher && { configEncryption: crypto.configCipher }),
|
|
119
|
+
...bootCryptoContext(crypto),
|
|
113
120
|
...(secrets && { secrets }),
|
|
114
121
|
...(opts.hasAuth && {
|
|
115
122
|
configResolver: createConfigResolver({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CachePolicy } from "@cosmicdrift/kumiko-framework/api";
|
|
2
|
-
import { type
|
|
2
|
+
import { type QueryDispatcher } from "./request-bound-system-query.js";
|
|
3
3
|
import type { HostDispatchFn, PageHeadResolver } from "./run-prod-app.js";
|
|
4
4
|
export declare function readStaticFile(filePath: string): Promise<{
|
|
5
5
|
readonly bytes: Uint8Array;
|
|
@@ -12,9 +12,6 @@ export declare function serveDiskFile(req: Request, pathname: string, file: {
|
|
|
12
12
|
readonly mtimeMs: number;
|
|
13
13
|
}): Response;
|
|
14
14
|
export declare function mimeTypeFor(filePath: string): string;
|
|
15
|
-
type QueryDispatcher = {
|
|
16
|
-
readonly query: (type: string, payload: unknown, user: SessionUser) => Promise<unknown>;
|
|
17
|
-
};
|
|
18
15
|
export type PageHeadOptions = {
|
|
19
16
|
readonly resolvePageHead: PageHeadResolver;
|
|
20
17
|
readonly dispatcher: QueryDispatcher;
|
|
@@ -29,4 +26,3 @@ hostDispatchDispatcher?: QueryDispatcher,
|
|
|
29
26
|
* 1:1 with runProdApp's effective value. */
|
|
30
27
|
trustedProxyHops?: number): (req: Request, socketAddress?: string) => Promise<Response>;
|
|
31
28
|
export declare function staticCachePolicy(pathname: string): CachePolicy;
|
|
32
|
-
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { resolve, sep } from "node:path";
|
|
2
|
-
import {
|
|
3
|
-
import { createAnonymousUser } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
import { cachedResponse, computeStrongEtag, computeWeakEtag, createClientIpResolver, } from "@cosmicdrift/kumiko-framework/api";
|
|
4
3
|
import { resolveAndInjectPageHead } from "@cosmicdrift/kumiko-headless/apex";
|
|
5
4
|
import { ASSETS_DIR } from "./build-prod-bundle.js";
|
|
6
5
|
import { BUNDLED_ASSETS_DIST_DIR } from "./bundled-assets.js";
|
|
6
|
+
import { buildRequestBoundSystemQuery, } from "./request-bound-system-query.js";
|
|
7
7
|
import { stripNoRouteMatchHeader, tryHonoFirst } from "./try-hono-first.js";
|
|
8
8
|
// Static-asset + SPA-fallback serving for runProdApp's HTTP handler. Split
|
|
9
9
|
// out of run-prod-app.ts (#1005, Welle 2) — mechanical relocation, these
|
|
@@ -162,13 +162,18 @@ trustedProxyHops = 0) {
|
|
|
162
162
|
return html;
|
|
163
163
|
const url = new URL(req.url);
|
|
164
164
|
const host = req.headers.get("host") ?? url.host;
|
|
165
|
-
const systemQuery = (
|
|
166
|
-
|
|
165
|
+
const systemQuery = buildRequestBoundSystemQuery({
|
|
166
|
+
req,
|
|
167
|
+
dispatcher: pageHead.dispatcher,
|
|
168
|
+
resolver: clientIpResolver,
|
|
169
|
+
socketAddress,
|
|
170
|
+
});
|
|
167
171
|
const text = new TextDecoder().decode(html.bytes);
|
|
168
172
|
const injected = await resolveAndInjectPageHead(text, pageHead.resolvePageHead, {
|
|
169
173
|
path: url.pathname,
|
|
170
174
|
host,
|
|
171
175
|
systemQuery,
|
|
176
|
+
requestSignal: req.signal,
|
|
172
177
|
});
|
|
173
178
|
if (injected === text)
|
|
174
179
|
return html;
|
|
@@ -192,8 +197,12 @@ trustedProxyHops = 0) {
|
|
|
192
197
|
if (!hostDispatchDispatcher) {
|
|
193
198
|
throw new Error("hostDispatch called deps.systemQuery but buildStaticFallback got no hostDispatchDispatcher");
|
|
194
199
|
}
|
|
195
|
-
return
|
|
196
|
-
|
|
200
|
+
return buildRequestBoundSystemQuery({
|
|
201
|
+
req,
|
|
202
|
+
dispatcher: hostDispatchDispatcher,
|
|
203
|
+
resolver: clientIpResolver,
|
|
204
|
+
socketAddress,
|
|
205
|
+
})(type, payload, tenantId);
|
|
197
206
|
};
|
|
198
207
|
const result = await hostDispatch({ host, path: url.pathname, search: url.search }, { systemQuery });
|
|
199
208
|
if (result.kind === "redirect") {
|
package/dist/run-prod-app.js
CHANGED
|
@@ -176,6 +176,28 @@ export async function runProdApp(options) {
|
|
|
176
176
|
// needed in 9.1's audit (37 references, 25 distinct vars).
|
|
177
177
|
const rawEnvSource = options.envSource ?? process.env;
|
|
178
178
|
const runMode = parseRunMode(rawEnvSource["KUMIKO_DRY_RUN_ENV"]);
|
|
179
|
+
const composedEnvSchema = options.envSchema;
|
|
180
|
+
const validateEnv = (source) => {
|
|
181
|
+
// skip: app declares no env schema, nothing to validate
|
|
182
|
+
if (!composedEnvSchema)
|
|
183
|
+
return;
|
|
184
|
+
try {
|
|
185
|
+
const schema = options.masterKey
|
|
186
|
+
? withOptionalEnvKeys(composedEnvSchema.schema, SECRETS_MASTER_KEK_ENV_KEYS)
|
|
187
|
+
: composedEnvSchema.schema;
|
|
188
|
+
parseEnv(schema, source, {
|
|
189
|
+
sources: composedEnvSchema.sources,
|
|
190
|
+
...(options.pulumiPrefix ? { pulumiPrefix: options.pulumiPrefix } : {}),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
if (err instanceof KumikoBootError) {
|
|
195
|
+
const reporter = options.bootErrorReporter ?? defaultBootErrorReporter;
|
|
196
|
+
reporter(err);
|
|
197
|
+
}
|
|
198
|
+
throw err;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
179
201
|
if (options.envSchema) {
|
|
180
202
|
if (isRenderMode(runMode)) {
|
|
181
203
|
// biome-ignore lint/suspicious/noConsole: dry-run output IS the deliverable
|
|
@@ -194,22 +216,7 @@ export async function runProdApp(options) {
|
|
|
194
216
|
// boot-mode AND normal-boot both run env-validation. boot-mode wants
|
|
195
217
|
// a real env-check (all required vars present + schema-valid) before
|
|
196
218
|
// it asserts feature-wiring works.
|
|
197
|
-
|
|
198
|
-
const envSchema = options.masterKey
|
|
199
|
-
? withOptionalEnvKeys(options.envSchema.schema, SECRETS_MASTER_KEK_ENV_KEYS)
|
|
200
|
-
: options.envSchema.schema;
|
|
201
|
-
parseEnv(envSchema, rawEnvSource, {
|
|
202
|
-
sources: options.envSchema.sources,
|
|
203
|
-
...(options.pulumiPrefix ? { pulumiPrefix: options.pulumiPrefix } : {}),
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
catch (err) {
|
|
207
|
-
if (err instanceof KumikoBootError) {
|
|
208
|
-
const reporter = options.bootErrorReporter ?? defaultBootErrorReporter;
|
|
209
|
-
reporter(err);
|
|
210
|
-
}
|
|
211
|
-
throw err;
|
|
212
|
-
}
|
|
219
|
+
validateEnv(rawEnvSource);
|
|
213
220
|
}
|
|
214
221
|
// Slots the schema marks `kms` are decrypted once here so every consumer
|
|
215
222
|
// below (boot probe, master-key keyring, config) sees the same resolved env.
|
|
@@ -219,6 +226,12 @@ export async function runProdApp(options) {
|
|
|
219
226
|
logPrefix: "[runProdApp]",
|
|
220
227
|
})
|
|
221
228
|
: rawEnvSource;
|
|
229
|
+
// The first parse relaxes ciphertext-only slots, so their decrypted
|
|
230
|
+
// plaintext never met the slot's own validators (.regex/.min/.refine).
|
|
231
|
+
if (options.envSchema &&
|
|
232
|
+
kmsSlotsOf(options.envSchema.schema).some((slot) => rawEnvSource[slot] === undefined && envSource[slot] !== undefined)) {
|
|
233
|
+
validateEnv(envSource);
|
|
234
|
+
}
|
|
222
235
|
// 1. Polyfill before anything else — feature code references Temporal.
|
|
223
236
|
const { ensureTemporalPolyfill } = await import("@cosmicdrift/kumiko-framework/time");
|
|
224
237
|
await ensureTemporalPolyfill();
|
|
@@ -418,6 +431,7 @@ export async function runProdApp(options) {
|
|
|
418
431
|
registry,
|
|
419
432
|
hasAuth: !!effectiveAuth,
|
|
420
433
|
sseBroker,
|
|
434
|
+
redis,
|
|
421
435
|
crypto: bootCrypto,
|
|
422
436
|
...(options.kms && { kms: options.kms }),
|
|
423
437
|
...(bootLogger && { log: bootLogger }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-server-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.354.0",
|
|
4
4
|
"description": "Production server-boot runtime for Kumiko apps: connections, schema-drift-gate, seeds, lifecycle, graceful shutdown. Symmetric to kumiko-dev-server's runDevApp, without dev/scaffold/codegen tooling.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -74,17 +74,21 @@
|
|
|
74
74
|
"types": "./dist/try-hono-first.d.ts",
|
|
75
75
|
"default": "./dist/try-hono-first.js"
|
|
76
76
|
},
|
|
77
|
+
"./request-bound-system-query": {
|
|
78
|
+
"types": "./dist/request-bound-system-query.d.ts",
|
|
79
|
+
"default": "./dist/request-bound-system-query.js"
|
|
80
|
+
},
|
|
77
81
|
"./build-prod-bundle": {
|
|
78
82
|
"types": "./dist/build-prod-bundle.d.ts",
|
|
79
83
|
"default": "./dist/build-prod-bundle.js"
|
|
80
84
|
}
|
|
81
85
|
},
|
|
82
86
|
"dependencies": {
|
|
83
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
84
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
85
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
86
|
-
"@cosmicdrift/kumiko-renderer-web": "0.
|
|
87
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
87
|
+
"@cosmicdrift/kumiko-bundled-features": "0.354.0",
|
|
88
|
+
"@cosmicdrift/kumiko-framework": "0.354.0",
|
|
89
|
+
"@cosmicdrift/kumiko-headless": "0.354.0",
|
|
90
|
+
"@cosmicdrift/kumiko-renderer-web": "0.354.0",
|
|
91
|
+
"@cosmicdrift/kumiko-types": "0.354.0",
|
|
88
92
|
"bun-types": "^1.3.13",
|
|
89
93
|
"ioredis": "^5.10.1",
|
|
90
94
|
"temporal-polyfill": "^0.3.2"
|
|
@@ -149,6 +153,10 @@
|
|
|
149
153
|
"types": "./dist/try-hono-first.d.ts",
|
|
150
154
|
"default": "./dist/try-hono-first.js"
|
|
151
155
|
},
|
|
156
|
+
"./request-bound-system-query": {
|
|
157
|
+
"types": "./dist/request-bound-system-query.d.ts",
|
|
158
|
+
"default": "./dist/request-bound-system-query.js"
|
|
159
|
+
},
|
|
152
160
|
"./build-prod-bundle": {
|
|
153
161
|
"types": "./dist/build-prod-bundle.d.ts",
|
|
154
162
|
"default": "./dist/build-prod-bundle.js"
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.354.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "Boot context passes Redis to the delivery service",
|
|
6
|
+
"detail": "notify with an idempotencyKey used to throw because the delivery service had no idempotencyRedis. Production boot, dev boot and the worker boot now hand over the existing Redis.",
|
|
7
|
+
"migration": "No action needed."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.353.0",
|
|
11
|
+
"type": "fix",
|
|
12
|
+
"title": "Boot rejects decrypted kms env slots that violate their schema validators",
|
|
13
|
+
"detail": "runProdApp validates Key-Manager-decrypted env slots against their schema\nA `kms` slot delivered only as `_CIPHERTEXT` skipped its own `.regex`/`.min`/`.refine` because the first parse relaxes it. After decryption the env is now parsed again, so a malformed plaintext aborts the boot with a `KumikoBootError` naming the slot."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"version": "0.353.0",
|
|
17
|
+
"type": "improvement",
|
|
18
|
+
"title": "Prod static files and the dev server share one request-bound systemQuery wiring",
|
|
19
|
+
"detail": "Shared request-bound systemQuery wiring and clearer deploy scaffold warnings\n`@cosmicdrift/kumiko-server-runtime/request-bound-system-query` exports the systemQuery wiring that the prod static-file path and the dev server previously each copied. `scaffoldDeploy` now tells a broken `package.json` (deploy settings fall back to defaults) apart from an unexpected `dependencies`/`workspaces` shape in its warning."
|
|
20
|
+
},
|
|
2
21
|
{
|
|
3
22
|
"version": "0.347.0",
|
|
4
23
|
"type": "fix",
|