@cosmicdrift/kumiko-dev-server 0.361.0 → 0.363.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/build-server-bundle.js +2 -2
- package/dist/compose-stacks.js +2 -2
- package/dist/create-kumiko-server.js +14 -19
- package/dist/few-shot-corpus.js +15 -13
- package/dist/run-dev-app.js +4 -1
- package/package.json +8 -6
- package/src/changes.json +12 -0
|
@@ -43,7 +43,7 @@ import { existsSync, readFileSync, statSync } from "node:fs";
|
|
|
43
43
|
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
44
44
|
import { dirname, join, resolve } from "node:path";
|
|
45
45
|
import { parseJsonOrThrow, parseJsonSafe } from "@cosmicdrift/kumiko-framework/utils";
|
|
46
|
-
const hasBun = typeof
|
|
46
|
+
const hasBun = typeof Bun !== "undefined";
|
|
47
47
|
// Pakete die das Bundle zur Laufzeit weiter referenziert (`from "<pkg>"` nach
|
|
48
48
|
// Tree-Shake). Native bindings (argon2), worker-thread-Loader (bullmq,
|
|
49
49
|
// ioredis), dynamic-require (postgres, temporal-polyfill) — alles was unter
|
|
@@ -118,7 +118,7 @@ export async function buildServerBundle(options = {}) {
|
|
|
118
118
|
entrypoints,
|
|
119
119
|
outdir: outDir,
|
|
120
120
|
target: "bun",
|
|
121
|
-
external: externals,
|
|
121
|
+
external: [...externals],
|
|
122
122
|
splitting: true,
|
|
123
123
|
sourcemap: "none",
|
|
124
124
|
naming: { entry: "[name].js", chunk: "chunk-[hash].js" },
|
package/dist/compose-stacks.js
CHANGED
|
@@ -25,12 +25,12 @@ import { mailTransportInMemoryFeature } from "@cosmicdrift/kumiko-bundled-featur
|
|
|
25
25
|
import { mailTransportSmtpFeature } from "@cosmicdrift/kumiko-bundled-features/mail-transport-smtp";
|
|
26
26
|
import { createRateLimitingFeature } from "@cosmicdrift/kumiko-bundled-features/rate-limiting";
|
|
27
27
|
import { createRendererFoundationFeature } from "@cosmicdrift/kumiko-bundled-features/renderer-foundation";
|
|
28
|
-
import { createRendererSimpleFeature } from "@cosmicdrift/kumiko-bundled-features/renderer-simple";
|
|
29
28
|
import { createSessionsFeature } from "@cosmicdrift/kumiko-bundled-features/sessions";
|
|
30
29
|
import { createTemplateResolverFeature } from "@cosmicdrift/kumiko-bundled-features/template-resolver";
|
|
31
30
|
import { createTenantLifecycleFeature } from "@cosmicdrift/kumiko-bundled-features/tenant-lifecycle";
|
|
32
31
|
import { createUserDataRightsFeature, } from "@cosmicdrift/kumiko-bundled-features/user-data-rights";
|
|
33
32
|
import { createUserDataRightsDefaultsFeature } from "@cosmicdrift/kumiko-bundled-features/user-data-rights-defaults";
|
|
33
|
+
import { createRendererMailHtmlFeature } from "@cosmicdrift/kumiko-renderer-mail-html";
|
|
34
34
|
export function stackFeatureNames(features) {
|
|
35
35
|
return features.map((f) => f.name);
|
|
36
36
|
}
|
|
@@ -48,7 +48,7 @@ export function composeRendererStack() {
|
|
|
48
48
|
return [
|
|
49
49
|
createTemplateResolverFeature(),
|
|
50
50
|
createRendererFoundationFeature(),
|
|
51
|
-
|
|
51
|
+
createRendererMailHtmlFeature(),
|
|
52
52
|
];
|
|
53
53
|
}
|
|
54
54
|
export function composeMailStack(options) {
|
|
@@ -32,13 +32,14 @@ import { RENDERER_WEB_FONT_FILE_PATTERN, RENDERER_WEB_FONTS_URL_PREFIX, resolveR
|
|
|
32
32
|
import { buildRequestBoundSystemQuery } from "@cosmicdrift/kumiko-server-runtime/request-bound-system-query";
|
|
33
33
|
import { canResolveTailwindStylesheet, resolveTailwindCli, } from "@cosmicdrift/kumiko-server-runtime/resolve-tailwind-cli";
|
|
34
34
|
import { stripNoRouteMatchHeader, tryHonoFirst, } from "@cosmicdrift/kumiko-server-runtime/try-hono-first";
|
|
35
|
+
import { errorCodeOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
35
36
|
import { isPersistentDevDb } from "./is-persistent-dev-db.js";
|
|
36
37
|
// Runtime-detection. The dev-server is meant to run under Bun (Kumiko's
|
|
37
38
|
// target runtime), but the test-suite runs under vitest on Node — we
|
|
38
39
|
// gate every Bun.* call so the module at least LOADS under Node, and
|
|
39
40
|
// tests drive the fetch-handler directly instead of going through
|
|
40
41
|
// Bun.serve + real sockets.
|
|
41
|
-
const hasBun = typeof
|
|
42
|
+
const hasBun = typeof Bun !== "undefined";
|
|
42
43
|
// @wrapper-known semantic-alias
|
|
43
44
|
// biome-ignore lint/suspicious/noConsole: dev-server status logging
|
|
44
45
|
export const logInfo = (msg) => console.log(msg);
|
|
@@ -243,7 +244,7 @@ async function servePublicFile(pathname, publicDir) {
|
|
|
243
244
|
return { bytes, mime: publicFileMimeType(filePath) };
|
|
244
245
|
}
|
|
245
246
|
catch (err) {
|
|
246
|
-
const code = err
|
|
247
|
+
const code = errorCodeOf(err);
|
|
247
248
|
if (code === "ENOENT" || code === "EISDIR" || code === "ENOTDIR" || code === "ENAMETOOLONG") {
|
|
248
249
|
return undefined;
|
|
249
250
|
}
|
|
@@ -292,7 +293,7 @@ async function watchDir(dir, onChange, signal, watchEvents) {
|
|
|
292
293
|
// signal.abort() wirft AbortError aus dem async-iterator; das ist
|
|
293
294
|
// gewollt und kein Fehler. Andere Errors weiterreichen.
|
|
294
295
|
// skip: AbortSignal fired the abort, this is expected teardown not a real error
|
|
295
|
-
if (err.name === "AbortError")
|
|
296
|
+
if (typeof err === "object" && err !== null && "name" in err && err.name === "AbortError")
|
|
296
297
|
return;
|
|
297
298
|
throw err;
|
|
298
299
|
}
|
|
@@ -370,14 +371,11 @@ function expandWatchPatterns(patterns) {
|
|
|
370
371
|
out.push(resolve(p));
|
|
371
372
|
continue;
|
|
372
373
|
}
|
|
373
|
-
//
|
|
374
|
-
//
|
|
375
|
-
|
|
376
|
-
// schon fail-fast unten in Bun.serve.
|
|
377
|
-
const BunRef = globalThis.Bun;
|
|
378
|
-
if (!BunRef)
|
|
374
|
+
// Only reachable under Bun (createKumikoServer is Bun-only); without Bun the
|
|
375
|
+
// call stack fails fast in Bun.serve anyway.
|
|
376
|
+
if (typeof Bun === "undefined")
|
|
379
377
|
throw new Error("expandWatchPatterns requires Bun.Glob");
|
|
380
|
-
const glob = new
|
|
378
|
+
const glob = new Bun.Glob(p);
|
|
381
379
|
const matches = Array.from(glob.scanSync({ onlyFiles: false, cwd: process.cwd() }));
|
|
382
380
|
for (const m of matches) {
|
|
383
381
|
const abs = resolve(m);
|
|
@@ -434,9 +432,8 @@ export function resolveStylesheet(options) {
|
|
|
434
432
|
return undefined;
|
|
435
433
|
}
|
|
436
434
|
try {
|
|
437
|
-
const resolved =
|
|
438
|
-
|
|
439
|
-
if (!canResolveTailwindStylesheet(resolved, { bun, cwd: process.cwd() })) {
|
|
435
|
+
const resolved = Bun.resolveSync("@cosmicdrift/kumiko-renderer-web/styles.css", process.cwd());
|
|
436
|
+
if (!canResolveTailwindStylesheet(resolved, { bun: Bun, cwd: process.cwd() })) {
|
|
440
437
|
return undefined;
|
|
441
438
|
}
|
|
442
439
|
return resolved;
|
|
@@ -460,9 +457,7 @@ export function resolveStylesheetWatch(options, env = process.env) {
|
|
|
460
457
|
// the initial build fails (flaky network, missing dependency), the server
|
|
461
458
|
// boots without CSS instead of dying.
|
|
462
459
|
async function startTailwindPipeline(entryCss, { watch }) {
|
|
463
|
-
const bunResolver = hasBun
|
|
464
|
-
? globalThis.Bun
|
|
465
|
-
: undefined;
|
|
460
|
+
const bunResolver = hasBun ? Bun : undefined;
|
|
466
461
|
const cliPath = resolveTailwindCli({ bun: bunResolver, cwd: process.cwd() });
|
|
467
462
|
if (cliPath === undefined) {
|
|
468
463
|
logError("[kumiko-server] @tailwindcss/cli nicht auflösbar — booting ohne CSS-Pipeline. " +
|
|
@@ -770,7 +765,7 @@ export async function createKumikoServer(options) {
|
|
|
770
765
|
content = await readFile(file, "utf-8");
|
|
771
766
|
}
|
|
772
767
|
catch (error) {
|
|
773
|
-
if (error
|
|
768
|
+
if (errorCodeOf(error) !== "ENOENT")
|
|
774
769
|
throw error;
|
|
775
770
|
return new Response(`hostDispatch: file not found: ${file}`, { status: 500 });
|
|
776
771
|
}
|
|
@@ -850,7 +845,7 @@ export async function createKumikoServer(options) {
|
|
|
850
845
|
});
|
|
851
846
|
}
|
|
852
847
|
catch (err) {
|
|
853
|
-
if (err
|
|
848
|
+
if (errorCodeOf(err) === "ENOENT") {
|
|
854
849
|
return new Response("not found", { status: 404 });
|
|
855
850
|
}
|
|
856
851
|
throw err;
|
|
@@ -963,7 +958,7 @@ export async function createKumikoServer(options) {
|
|
|
963
958
|
// damit Dev und Prod genau dieselben SSE-relevanten Defaults nutzen
|
|
964
959
|
// (idleTimeout: 0). Spec-Test in run-prod-app-spec.test.ts pinst das.
|
|
965
960
|
const server = hasBun
|
|
966
|
-
?
|
|
961
|
+
? Bun.serve(buildBunServeOptions(port, handleFetch, resolveDerivedMaxRequestBodySize(stack.registry), {
|
|
967
962
|
upgradeFetch: async (req, env) => stripNoRouteMatchHeader(await stack.app.fetch(req, env)),
|
|
968
963
|
}))
|
|
969
964
|
: undefined;
|
package/dist/few-shot-corpus.js
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
33
33
|
import { dirname, join, relative, resolve } from "node:path";
|
|
34
34
|
import { PATTERN_LIBRARY, parseFeatureFile, } from "@cosmicdrift/kumiko-framework/engine";
|
|
35
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
35
36
|
// =============================================================================
|
|
36
37
|
// Builder
|
|
37
38
|
// =============================================================================
|
|
@@ -155,16 +156,15 @@ function relativizeSources(value, repoRoot) {
|
|
|
155
156
|
if (Array.isArray(value)) {
|
|
156
157
|
return value.map((v) => relativizeSources(v, repoRoot));
|
|
157
158
|
}
|
|
158
|
-
if (value
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
typeof
|
|
162
|
-
typeof
|
|
163
|
-
|
|
164
|
-
return { ...obj, file: relative(repoRoot, obj["file"]) };
|
|
159
|
+
if (isPlainObject(value)) {
|
|
160
|
+
if (typeof value["file"] === "string" &&
|
|
161
|
+
typeof value["raw"] === "string" &&
|
|
162
|
+
typeof value["start"] === "object" &&
|
|
163
|
+
typeof value["end"] === "object") {
|
|
164
|
+
return { ...value, file: relative(repoRoot, value["file"]) };
|
|
165
165
|
}
|
|
166
166
|
const out = {};
|
|
167
|
-
for (const [k, v] of Object.entries(
|
|
167
|
+
for (const [k, v] of Object.entries(value)) {
|
|
168
168
|
out[k] = relativizeSources(v, repoRoot);
|
|
169
169
|
}
|
|
170
170
|
return out;
|
|
@@ -222,11 +222,13 @@ function findPackageJson(featureFile, repoRoot) {
|
|
|
222
222
|
if (existsSync(candidate)) {
|
|
223
223
|
try {
|
|
224
224
|
const pkg = JSON.parse(readFileSync(candidate, "utf8"));
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
225
|
+
if (isPlainObject(pkg)) {
|
|
226
|
+
return {
|
|
227
|
+
relPath: relative(repoRoot, candidate),
|
|
228
|
+
name: typeof pkg["name"] === "string" ? pkg["name"] : undefined,
|
|
229
|
+
description: typeof pkg["description"] === "string" ? pkg["description"] : undefined,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
230
232
|
}
|
|
231
233
|
catch {
|
|
232
234
|
// Malformed package.json — keep walking up.
|
package/dist/run-dev-app.js
CHANGED
|
@@ -22,7 +22,7 @@ import { TenantQueries } from "@cosmicdrift/kumiko-bundled-features/tenant";
|
|
|
22
22
|
import { createInMemoryLoginRateLimiter, parseTrustedProxyHopsEnv, TRUSTED_PROXY_HOPS_ENV, } from "@cosmicdrift/kumiko-framework/api";
|
|
23
23
|
import { configureBlindIndexKey, configurePiiSubjectKms, } from "@cosmicdrift/kumiko-framework/crypto";
|
|
24
24
|
import { configureEntityFieldEncryption } from "@cosmicdrift/kumiko-framework/db";
|
|
25
|
-
import { collectWriteHandlerQns, createRegistry, FILE_STORAGE_PROVIDER_BOOT_SENTINEL, FILE_STORAGE_PROVIDER_ENV, findTierResolverUsage, validateAppCustomScreenWriteQns, validateBoot, } from "@cosmicdrift/kumiko-framework/engine";
|
|
25
|
+
import { collectWriteHandlerQns, createRegistry, FILE_STORAGE_PROVIDER_BOOT_SENTINEL, FILE_STORAGE_PROVIDER_ENV, findTierResolverUsage, isTierResolverPlugin, validateAppCustomScreenWriteQns, validateBoot, } from "@cosmicdrift/kumiko-framework/engine";
|
|
26
26
|
import { warnIfNonUtcServerTimeZone } from "@cosmicdrift/kumiko-framework/time";
|
|
27
27
|
import { applyBootSeeds } from "@cosmicdrift/kumiko-server-runtime/boot/apply-boot-seeds";
|
|
28
28
|
import { resolveBootCrypto } from "@cosmicdrift/kumiko-server-runtime/boot/boot-crypto";
|
|
@@ -323,6 +323,9 @@ export async function runDevApp(options) {
|
|
|
323
323
|
// tier-assignment can immediately read tier-cuts).
|
|
324
324
|
if (tierResolverUsage) {
|
|
325
325
|
const plugin = tierResolverUsage.options;
|
|
326
|
+
if (!isTierResolverPlugin(plugin)) {
|
|
327
|
+
throw new Error("tier-resolver registration options must provide a build() factory");
|
|
328
|
+
}
|
|
326
329
|
tierResolverHolder.resolver = await plugin.build({
|
|
327
330
|
db: stack.db,
|
|
328
331
|
registry: stack.registry,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-dev-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.363.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>",
|
|
@@ -64,11 +64,13 @@
|
|
|
64
64
|
"kumiko-upgrade": "./bin/kumiko-upgrade.ts"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
68
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
69
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
70
|
-
"@cosmicdrift/kumiko-renderer-
|
|
71
|
-
"@cosmicdrift/kumiko-
|
|
67
|
+
"@cosmicdrift/kumiko-bundled-features": "0.363.0",
|
|
68
|
+
"@cosmicdrift/kumiko-framework": "0.363.0",
|
|
69
|
+
"@cosmicdrift/kumiko-headless": "0.363.0",
|
|
70
|
+
"@cosmicdrift/kumiko-renderer-mail-html": "0.363.0",
|
|
71
|
+
"@cosmicdrift/kumiko-renderer-web": "0.363.0",
|
|
72
|
+
"@cosmicdrift/kumiko-server-runtime": "0.363.0",
|
|
73
|
+
"@cosmicdrift/kumiko-types": "0.363.0",
|
|
72
74
|
"bun-types": "^1.3.13",
|
|
73
75
|
"ts-morph": "^28.0.0",
|
|
74
76
|
"zod": "^4.4.3"
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.363.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "composeRendererStack includes renderer-mail-html",
|
|
6
|
+
"detail": "The renderer stack now also mounts createRendererMailHtmlFeature, which the auth mails need. Apps that already list renderer-mail-html next to composeRendererStack() drop their own copy, createRegistry rejects duplicate features."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.363.0",
|
|
10
|
+
"type": "improvement",
|
|
11
|
+
"title": "composeRendererStack no longer mounts renderer-simple",
|
|
12
|
+
"detail": "renderer-simple is removed, so the renderer stack is template-resolver, renderer-foundation and renderer-mail-html."
|
|
13
|
+
},
|
|
2
14
|
{
|
|
3
15
|
"version": "0.361.0",
|
|
4
16
|
"type": "breaking",
|