@cosmicdrift/kumiko-dev-server 0.343.0 → 0.345.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.
|
@@ -200,6 +200,7 @@ export type KumikoServerHandle = {
|
|
|
200
200
|
export declare const STYLESHEET_WATCH_ENV = "KUMIKO_DEV_STYLESHEET_WATCH";
|
|
201
201
|
export declare const PROD_BUNDLES_ENV = "KUMIKO_DEV_PROD_BUNDLES";
|
|
202
202
|
export declare function classifyChange(filename: string): "restart" | "hot-reload" | "ignore";
|
|
203
|
+
export declare function classifyWatchedChange(watchedDir: string, filename: string, entrySourceFiles: ReadonlySet<string>): ReturnType<typeof classifyChange>;
|
|
203
204
|
export declare function resolveStylesheet(options: CreateKumikoServerOptions): string | undefined;
|
|
204
205
|
export declare function resolveStylesheetWatch(options: Pick<CreateKumikoServerOptions, "stylesheetWatch">, env?: Readonly<Record<string, string | undefined>>): boolean;
|
|
205
206
|
export declare function createKumikoServer(options: CreateKumikoServerOptions): Promise<KumikoServerHandle>;
|
|
@@ -345,6 +345,14 @@ export function classifyChange(filename) {
|
|
|
345
345
|
}
|
|
346
346
|
return "restart";
|
|
347
347
|
}
|
|
348
|
+
// The watcher reports paths relative to the watched directory, so an entry arrives as a bare
|
|
349
|
+
// "client.tsx" (or a custom name like "client-admin.tsx") that classifyChange alone reads as a
|
|
350
|
+
// server file and answers with a restart.
|
|
351
|
+
export function classifyWatchedChange(watchedDir, filename, entrySourceFiles) {
|
|
352
|
+
return entrySourceFiles.has(resolve(watchedDir, filename))
|
|
353
|
+
? "hot-reload"
|
|
354
|
+
: classifyChange(filename);
|
|
355
|
+
}
|
|
348
356
|
// Expandiert watchDirs-Patterns auf konkrete Verzeichnisse. Ein Eintrag
|
|
349
357
|
// ohne `*` wird als gewöhnlicher Pfad resolved; mit `*` wird er per
|
|
350
358
|
// glob expanded und alle Treffer die Verzeichnisse sind übernommen.
|
|
@@ -683,8 +691,9 @@ export async function createKumikoServer(options) {
|
|
|
683
691
|
// RELOAD_SNIPPET oben.
|
|
684
692
|
const bootId = String(Date.now());
|
|
685
693
|
const reloadClients = new Set();
|
|
686
|
-
|
|
687
|
-
|
|
694
|
+
// JSON-encoded so a filename can never break the SSE framing.
|
|
695
|
+
const broadcastReload = (changedFile) => {
|
|
696
|
+
const payload = `event: reload\ndata: ${JSON.stringify(changedFile)}\n\n`;
|
|
688
697
|
for (const client of reloadClients) {
|
|
689
698
|
if (client.closed)
|
|
690
699
|
continue;
|
|
@@ -973,10 +982,11 @@ export async function createKumikoServer(options) {
|
|
|
973
982
|
const entryDirs = new Set();
|
|
974
983
|
for (const e of entries)
|
|
975
984
|
entryDirs.add(resolve(e.sourceFile, ".."));
|
|
985
|
+
const entrySourceFiles = new Set(entries.map((e) => resolve(e.sourceFile)));
|
|
976
986
|
const dirs = [...entryDirs, ...expandWatchPatterns(options.watchDirs ?? [])];
|
|
977
987
|
for (const dir of dirs) {
|
|
978
988
|
void watchDir(dir, async (filename) => {
|
|
979
|
-
const action =
|
|
989
|
+
const action = classifyWatchedChange(dir, filename, entrySourceFiles);
|
|
980
990
|
// skip: file change classified as ignore (test/css/json), nothing to rebuild
|
|
981
991
|
if (action === "ignore")
|
|
982
992
|
return;
|
|
@@ -998,7 +1008,7 @@ export async function createKumikoServer(options) {
|
|
|
998
1008
|
clientBundles.set(e.name, rebuilt);
|
|
999
1009
|
}
|
|
1000
1010
|
logInfo(`[kumiko-server] rebuilt on ${filename}, broadcasting reload`);
|
|
1001
|
-
broadcastReload();
|
|
1011
|
+
broadcastReload(filename);
|
|
1002
1012
|
}
|
|
1003
1013
|
catch {
|
|
1004
1014
|
// buildClient already logged the failure; keep serving the
|
package/dist/run-dev-app.js
CHANGED
|
@@ -269,6 +269,7 @@ export async function runDevApp(options) {
|
|
|
269
269
|
...patAuthFragment,
|
|
270
270
|
...(mfaFeature && {
|
|
271
271
|
mfaVerifyHandler: AuthMfaHandlers.verify,
|
|
272
|
+
switchTenantMfaGateHandler: AuthHandlers.switchTenantMfaGate,
|
|
272
273
|
mfaPreauthEnableStartHandler: AuthMfaHandlers.enableStartPreauth,
|
|
273
274
|
mfaPreauthConfirmHandler: AuthMfaHandlers.enableConfirmPreauth,
|
|
274
275
|
}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-dev-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.345.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,11 @@
|
|
|
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-web": "0.
|
|
71
|
-
"@cosmicdrift/kumiko-server-runtime": "0.
|
|
67
|
+
"@cosmicdrift/kumiko-bundled-features": "0.345.0",
|
|
68
|
+
"@cosmicdrift/kumiko-framework": "0.345.0",
|
|
69
|
+
"@cosmicdrift/kumiko-headless": "0.345.0",
|
|
70
|
+
"@cosmicdrift/kumiko-renderer-web": "0.345.0",
|
|
71
|
+
"@cosmicdrift/kumiko-server-runtime": "0.345.0",
|
|
72
72
|
"bun-types": "^1.3.13",
|
|
73
73
|
"ts-morph": "^28.0.0",
|
|
74
74
|
"zod": "^4.4.3"
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.345.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "generated migrate-step.sh honours COMPOSE_PROJECT_NAME from .env",
|
|
6
|
+
"detail": "The `migrate-step.sh` that `kumiko-init-deploy` generates now reads `.env` before it picks the stack network. Before, a `COMPOSE_PROJECT_NAME` set only in `.env` was ignored and the script fell back to the directory name, so on a shared host it could run the migration against another app's network and Postgres. The project name, from `.env` or the directory, is lowercased and stripped to `[a-z0-9_-]` as Compose does, and the script still stops when the network does not exist. Regenerate the script in existing apps to pick this up."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.345.0",
|
|
10
|
+
"type": "fix",
|
|
11
|
+
"title": "Client entry edits hot-reload instead of restarting",
|
|
12
|
+
"detail": "Editing a client entry file hot-reloads instead of restarting the dev server\nOn macOS the recursive file watcher reports paths relative to the watched directory. A change to a client entry such as `client.tsx` or a custom-named entry was therefore classified as a server change and restarted the process. The watcher now resolves the path and treats every configured entry source file as hot-reload."
|
|
13
|
+
},
|
|
2
14
|
{
|
|
3
15
|
"version": "0.341.0",
|
|
4
16
|
"type": "improvement",
|
|
@@ -15,14 +15,6 @@
|
|
|
15
15
|
|
|
16
16
|
set -euo pipefail
|
|
17
17
|
|
|
18
|
-
# Compose lowercases the project name and drops characters outside [a-z0-9_-].
|
|
19
|
-
COMPOSE_PROJECT="${COMPOSE_PROJECT_NAME:-$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9_-')}"
|
|
20
|
-
STACK_NETWORK="${COMPOSE_PROJECT}_stack"
|
|
21
|
-
if ! docker network inspect "$STACK_NETWORK" >/dev/null 2>&1; then
|
|
22
|
-
echo "Stack network '$STACK_NETWORK' not found (derived from COMPOSE_PROJECT_NAME or the directory name '$(basename "$PWD")') — compose project not running?" >&2
|
|
23
|
-
exit 1
|
|
24
|
-
fi
|
|
25
|
-
|
|
26
18
|
# Import .env as bash env. `set -a` marks subsequent variable assignments
|
|
27
19
|
# as auto-export. Bash's built-in parser respects quotes/escapes like
|
|
28
20
|
# compose does, without depending on compose-profile features.
|
|
@@ -30,6 +22,15 @@ set -a
|
|
|
30
22
|
. ./.env
|
|
31
23
|
set +a
|
|
32
24
|
|
|
25
|
+
# After the .env import, so a COMPOSE_PROJECT_NAME set there picks the network.
|
|
26
|
+
# Compose lowercases the project name and drops characters outside [a-z0-9_-].
|
|
27
|
+
COMPOSE_PROJECT="$(printf '%s' "${COMPOSE_PROJECT_NAME:-$(basename "$PWD")}" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9_-')"
|
|
28
|
+
STACK_NETWORK="${COMPOSE_PROJECT}_stack"
|
|
29
|
+
if ! docker network inspect "$STACK_NETWORK" >/dev/null 2>&1; then
|
|
30
|
+
echo "Stack network '$STACK_NETWORK' not found (derived from COMPOSE_PROJECT_NAME or the directory name '$(basename "$PWD")') — compose project not running?" >&2
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
33
34
|
# Percent-encode so '@', ':', '/', '#', '%' in the password cannot change how
|
|
34
35
|
# the URL is parsed. LC_ALL=C makes the loop walk bytes, not characters;
|
|
35
36
|
# bash sign-extends bytes >= 0x80 in "'$c", hence the & 255.
|