@cosmicdrift/kumiko-dev-server 0.371.1 → 0.372.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.
@@ -1,20 +1,24 @@
1
1
  #!/usr/bin/env bun
2
- // kumiko-build — Production-Build für Kumiko-Apps. Convention-driven:
2
+ // kumiko-build — production build for Kumiko apps. Convention-driven:
3
3
  //
4
4
  // package.json "kumiko.clientEntries"/"kumiko.clientEntry",
5
- // or src/client.tsx | src/styles.css | public/ → Client-Bundle (dist/)
6
- // bin/main.ts → Server-Bundle (dist-server/)
5
+ // or src/client.tsx | src/styles.css | public/ → client bundle (dist/)
6
+ // bin/main.ts → server bundle (dist-server/)
7
7
  //
8
- // Beide werden gebaut wenn die jeweiligen Conventions getroffen sind, sonst
9
- // übersprungen. Ein Workspace mit nur bin/main.ts kriegt nur den Server-
10
- // Bundle, ein Browser-only-Sample nur den Client.
8
+ // Both are built when their conventions match, otherwise skipped. A workspace
9
+ // with only bin/main.ts gets just the server bundle, a browser-only sample
10
+ // just the client.
11
11
  //
12
12
  // {
13
13
  // "scripts": { "build": "kumiko-build" }
14
14
  // }
15
15
  //
16
- // Optionaler Pfad-Parameter überschreibt cwd:
16
+ // An optional path argument overrides cwd:
17
17
  // kumiko-build samples/apps/showcase
18
+ //
19
+ // Extra server entry points (repeatable, paths relative to the app dir), each
20
+ // emitted as dist-server/<basename>.js:
21
+ // kumiko-build --entry bin/remote-probe.ts
18
22
 
19
23
  import { existsSync } from "node:fs";
20
24
  import { join, resolve } from "node:path";
@@ -24,6 +28,7 @@ import {
24
28
  discoverServerEntry,
25
29
  formatBuildResult,
26
30
  formatServerBuildResult,
31
+ parseKumikoBuildArgs,
27
32
  readClientEntriesConfig,
28
33
  readExtraRuntimeExternals,
29
34
  resolveClientEntries,
@@ -31,19 +36,19 @@ import {
31
36
 
32
37
  if (process.argv.slice(2).some((arg) => arg === "--help" || arg === "-h")) {
33
38
  process.stdout.write(
34
- "Usage: kumiko-build [app-dir] build client (dist/) and server (dist-server/) bundles\n",
39
+ "Usage: kumiko-build [app-dir] [--entry <path>]... build client (dist/) and server (dist-server/) bundles; --entry adds a server entry point (dist-server/<basename>.js)\n",
35
40
  );
36
41
  process.exit(0);
37
42
  }
38
43
 
39
- const explicit = process.argv.slice(2).find((arg) => !arg.startsWith("-"));
40
- const cwd = explicit ? resolve(process.cwd(), explicit) : process.cwd();
41
-
42
44
  const red = "\x1b[31m";
43
45
  const yellow = "\x1b[33m";
44
46
  const reset = "\x1b[0m";
45
47
 
46
48
  try {
49
+ const buildArgs = parseKumikoBuildArgs(process.argv.slice(2));
50
+ const cwd = buildArgs.appDir ? resolve(process.cwd(), buildArgs.appDir) : process.cwd();
51
+
47
52
  // Read once up front — resolveClientEntries can throw (mutual exclusion,
48
53
  // malformed declaration, unmigrated legacy client-*.tsx files) and that
49
54
  // must surface through the same ✗/exit(1) path as every other build error.
@@ -77,6 +82,7 @@ try {
77
82
  const result = await buildServerBundle({
78
83
  cwd,
79
84
  ...(extraRuntimeExternals.length > 0 && { extraRuntimeExternals }),
85
+ ...(buildArgs.extraEntries.length > 0 && { extraEntries: buildArgs.extraEntries }),
80
86
  });
81
87
  const ms = Math.round(performance.now() - t0);
82
88
  // biome-ignore lint/suspicious/noConsole: CLI-Output, einziger Weg
@@ -8,6 +8,11 @@ export type BuildServerBundleOptions = {
8
8
  readonly extraRuntimeExternals?: readonly string[];
9
9
  /** Zusätzliche Build-only-Externals. App-spezifisch — Default leer. */
10
10
  readonly extraBuildOnlyExternals?: readonly string[];
11
+ /** Additional entry points (paths relative to cwd, e.g. "bin/remote-probe.ts"),
12
+ * each emitted as `<basename>.js` next to server.js and sharing its chunks.
13
+ * A missing file or a basename that collides with a built-in entry or another
14
+ * extra entry throws. */
15
+ readonly extraEntries?: readonly string[];
11
16
  };
12
17
  export type BuildServerBundleEntry = {
13
18
  readonly file: string;
@@ -15,7 +20,7 @@ export type BuildServerBundleEntry = {
15
20
  };
16
21
  export type BuildServerBundleResult = {
17
22
  readonly outDir: string;
18
- /** Named entry files (server.js, plus kumiko.js, worker.js and bootstrap.js when present). */
23
+ /** Named entry files (server.js, plus kumiko.js, worker.js, bootstrap.js and extra entries when present). */
19
24
  readonly entries: readonly BuildServerBundleEntry[];
20
25
  /** Geteilte Framework-Chunks (von splitting). */
21
26
  readonly chunks: readonly BuildServerBundleEntry[];
@@ -25,6 +30,13 @@ export type BuildServerBundleResult = {
25
30
  };
26
31
  export declare function buildServerBundle(options?: BuildServerBundleOptions): Promise<BuildServerBundleResult>;
27
32
  export declare function discoverServerEntry(cwd: string): string | undefined;
33
+ export type KumikoBuildArgs = {
34
+ readonly appDir: string | undefined;
35
+ readonly extraEntries: readonly string[];
36
+ };
37
+ /** Parse `kumiko-build [app-dir] [--entry <path>]...` (also `--entry=<path>`).
38
+ * Unknown flags and a missing `--entry` value throw instead of being ignored. */
39
+ export declare function parseKumikoBuildArgs(args: readonly string[]): KumikoBuildArgs;
28
40
  /** Read `package.json#kumiko.extraRuntimeExternals` for kumiko-build (#1484).
29
41
  * Invalid / missing shapes → empty list (CLI stays convention-driven). */
30
42
  export declare function readExtraRuntimeExternals(cwd: string): readonly string[];
@@ -12,11 +12,14 @@
12
12
  // background worker as its own process from the same image)
13
13
  // bin/bootstrap.ts → dist-server/bootstrap.js (optional, next to bin/main.ts:
14
14
  // one-shot runBootstrap provisioning, run as a k8s Job)
15
+ // extraEntries[i] → dist-server/<basename>.js (opt-in, e.g. a probe script
16
+ // `bin/remote-probe.ts`; CLI: repeatable `--entry <path>`)
15
17
  // dist-server/package.json → runtime-deps mit gepinnten Versionen
16
18
  //
17
19
  // All entries are built in ONE Bun.build call with `splitting`: the framework
18
- // lands once as shared chunk-*.js and server.js, kumiko.js, worker.js and
19
- // bootstrap.js are thin entries importing it. Separate bundles would inline ~14 MB per entry.
20
+ // lands once as shared chunk-*.js and server.js, kumiko.js, worker.js,
21
+ // bootstrap.js and the extra entries are thin entries importing it. Separate
22
+ // bundles would inline ~14 MB per entry.
20
23
  //
21
24
  // Output:
22
25
  //
@@ -25,6 +28,7 @@
25
28
  // kumiko.js ← Migrate-CLI-Entry (wenn bin/kumiko.ts gefunden)
26
29
  // worker.js ← worker entry (if bin/worker.ts sits next to main.ts)
27
30
  // bootstrap.js ← provisioning entry (if bin/bootstrap.ts sits next to main.ts)
31
+ // <basename>.js ← one per extraEntries path
28
32
  // chunk-*.js ← geteilte Framework-Chunks
29
33
  // package.json ← runtime-deps mit gepinnten Versionen
30
34
  //
@@ -41,7 +45,7 @@
41
45
  // resolution-during-build ab. NICHT in runtime-deps.
42
46
  import { existsSync, readFileSync, statSync } from "node:fs";
43
47
  import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
44
- import { dirname, join, resolve } from "node:path";
48
+ import { basename, dirname, extname, join, resolve } from "node:path";
45
49
  import { parseJsonOrThrow, parseJsonSafe } from "@cosmicdrift/kumiko-framework/utils";
46
50
  const hasBun = typeof Bun !== "undefined";
47
51
  // Pakete die das Bundle zur Laufzeit weiter referenziert (`from "<pkg>"` nach
@@ -85,6 +89,33 @@ const BUILD_ONLY_EXTERNALS = [
85
89
  // ist die Runtime-Convention; der Entry wird von nichts importiert (nur die
86
90
  // chunks werden referenziert, per relativem Pfad), darum ist der Rename sicher.
87
91
  const ENTRY_RENAMES = { "main.js": "server.js" };
92
+ const OPTIONAL_SIBLING_ENTRY_NAMES = ["worker", "bootstrap"];
93
+ // Output names the built-in entries occupy ("main" is renamed to server.js).
94
+ const RESERVED_ENTRY_OUTPUT_NAMES = new Set([
95
+ "server.js",
96
+ "main.js",
97
+ "kumiko.js",
98
+ ...OPTIONAL_SIBLING_ENTRY_NAMES.map((name) => `${name}.js`),
99
+ ]);
100
+ function resolveExtraEntries(cwd, extraEntries) {
101
+ const claimedOutputNames = new Map();
102
+ return extraEntries.map((entry) => {
103
+ const absolute = resolve(cwd, entry);
104
+ if (!existsSync(absolute) || !statSync(absolute).isFile()) {
105
+ throw new Error(`[buildServerBundle] extra entry "${entry}" does not exist (resolved to ${absolute}).`);
106
+ }
107
+ const outputName = `${basename(absolute, extname(absolute))}.js`;
108
+ if (RESERVED_ENTRY_OUTPUT_NAMES.has(outputName)) {
109
+ throw new Error(`[buildServerBundle] extra entry "${entry}" would emit ${outputName}, which a built-in entry already uses. Rename the file.`);
110
+ }
111
+ const previous = claimedOutputNames.get(outputName);
112
+ if (previous !== undefined) {
113
+ throw new Error(`[buildServerBundle] extra entries "${previous}" and "${entry}" both emit ${outputName}. Rename one of the files.`);
114
+ }
115
+ claimedOutputNames.set(outputName, entry);
116
+ return absolute;
117
+ });
118
+ }
88
119
  export async function buildServerBundle(options = {}) {
89
120
  if (!hasBun) {
90
121
  throw new Error("buildServerBundle requires Bun runtime (Bun.build is missing).");
@@ -100,6 +131,7 @@ export async function buildServerBundle(options = {}) {
100
131
  if (kumikoCli && !existsSync(kumikoCli)) {
101
132
  throw new Error(`[buildServerBundle] Repo-Root erkannt (${repoRoot}), aber bin/kumiko.ts fehlt — kann Migrate-CLI nicht bündeln.`);
102
133
  }
134
+ const extraEntryPaths = resolveExtraEntries(cwd, options.extraEntries ?? []);
103
135
  const externals = [
104
136
  ...RUNTIME_EXTERNALS,
105
137
  ...BUILD_ONLY_EXTERNALS,
@@ -110,10 +142,13 @@ export async function buildServerBundle(options = {}) {
110
142
  await mkdir(outDir, { recursive: true });
111
143
  // Ein Bun.build-Call mit allen Entries + splitting → das Framework wird
112
144
  // einmal als shared chunk abgelegt statt pro Entry inlined.
113
- const optionalSiblingEntries = ["worker", "bootstrap"]
114
- .map((baseName) => discoverSiblingEntry(dirname(serverEntry), baseName))
115
- .filter((path) => path !== undefined);
116
- const entrypoints = [serverEntry, ...(kumikoCli ? [kumikoCli] : []), ...optionalSiblingEntries];
145
+ const optionalSiblingEntries = OPTIONAL_SIBLING_ENTRY_NAMES.map((baseName) => discoverSiblingEntry(dirname(serverEntry), baseName)).filter((path) => path !== undefined);
146
+ const entrypoints = [
147
+ serverEntry,
148
+ ...(kumikoCli ? [kumikoCli] : []),
149
+ ...optionalSiblingEntries,
150
+ ...extraEntryPaths,
151
+ ];
117
152
  const result = await Bun.build({
118
153
  entrypoints,
119
154
  outdir: outDir,
@@ -188,6 +223,34 @@ function findRepoRoot(start) {
188
223
  }
189
224
  return undefined;
190
225
  }
226
+ /** Parse `kumiko-build [app-dir] [--entry <path>]...` (also `--entry=<path>`).
227
+ * Unknown flags and a missing `--entry` value throw instead of being ignored. */
228
+ export function parseKumikoBuildArgs(args) {
229
+ let appDir;
230
+ const extraEntries = [];
231
+ for (let i = 0; i < args.length; i++) {
232
+ const arg = args[i];
233
+ if (arg === undefined)
234
+ break;
235
+ if (arg === "--entry" || arg.startsWith("--entry=")) {
236
+ const value = arg === "--entry" ? args[++i] : arg.slice("--entry=".length);
237
+ if (value === undefined || value === "") {
238
+ throw new Error("kumiko-build: --entry needs a path, e.g. --entry bin/remote-probe.ts");
239
+ }
240
+ extraEntries.push(value);
241
+ }
242
+ else if (arg.startsWith("-")) {
243
+ throw new Error(`kumiko-build: unknown option ${arg}`);
244
+ }
245
+ else if (appDir === undefined) {
246
+ appDir = arg;
247
+ }
248
+ else {
249
+ throw new Error(`kumiko-build: unexpected argument ${arg}`);
250
+ }
251
+ }
252
+ return { appDir, extraEntries };
253
+ }
191
254
  /** Read `package.json#kumiko.extraRuntimeExternals` for kumiko-build (#1484).
192
255
  * Invalid / missing shapes → empty list (CLI stays convention-driven). */
193
256
  export function readExtraRuntimeExternals(cwd) {
package/dist/build.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { ASSETS_DIR, type BuildManifest, type BuildProdBundleOptions, type BuildResult, buildProdBundle, type ClientEntry, type ClientEntryDeclaration, discoverHtmlTemplate, formatBuildResult, injectAssetTags, readClientEntriesConfig, resolveClientEntries, } from "@cosmicdrift/kumiko-server-runtime/build-prod-bundle";
2
- export { type BuildServerBundleEntry, type BuildServerBundleOptions, type BuildServerBundleResult, buildServerBundle, discoverServerEntry, formatServerBuildResult, readExtraRuntimeExternals, } from "./build-server-bundle.ts";
2
+ export { type BuildServerBundleEntry, type BuildServerBundleOptions, type BuildServerBundleResult, buildServerBundle, discoverServerEntry, formatServerBuildResult, type KumikoBuildArgs, parseKumikoBuildArgs, readExtraRuntimeExternals, } from "./build-server-bundle.ts";
package/dist/build.js CHANGED
@@ -2,4 +2,4 @@
2
2
  // damit der Main-Barrel kein Bun-Toolchain-Bundle in Production-Reads zieht
3
3
  // (z.B. wenn drizzle-kit die App-Config unter Node lädt).
4
4
  export { ASSETS_DIR, buildProdBundle, discoverHtmlTemplate, formatBuildResult, injectAssetTags, readClientEntriesConfig, resolveClientEntries, } from "@cosmicdrift/kumiko-server-runtime/build-prod-bundle";
5
- export { buildServerBundle, discoverServerEntry, formatServerBuildResult, readExtraRuntimeExternals, } from "./build-server-bundle.js";
5
+ export { buildServerBundle, discoverServerEntry, formatServerBuildResult, parseKumikoBuildArgs, readExtraRuntimeExternals, } from "./build-server-bundle.js";
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, } from "./build.ts";
1
+ export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, parseKumikoBuildArgs, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, } from "./build.ts";
2
2
  export { createCrashTracker } from "./crash-tracker.ts";
3
3
  export { runInitDeployCli } from "./init-deploy-cli.ts";
package/dist/cli.js CHANGED
@@ -2,6 +2,6 @@
2
2
  // the package self-reference (`@cosmicdrift/kumiko-dev-server/cli`) so they
3
3
  // resolve to src in the workspace and to dist once installed from the
4
4
  // tarball, where `src` is not shipped.
5
- export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, } from "./build.js";
5
+ export { buildProdBundle, buildServerBundle, discoverServerEntry, formatBuildResult, formatServerBuildResult, parseKumikoBuildArgs, readClientEntriesConfig, readExtraRuntimeExternals, resolveClientEntries, } from "./build.js";
6
6
  export { createCrashTracker } from "./crash-tracker.js";
7
7
  export { runInitDeployCli } from "./init-deploy-cli.js";
@@ -23,12 +23,13 @@ import { resolveAnonymousAccessFromRegistry } from "@cosmicdrift/kumiko-bundled-
23
23
  import { AUTH_COOKIE_BASE, CSRF_COOKIE_BASE, createClientIpResolver, generateToken, sessionCookieName, } from "@cosmicdrift/kumiko-framework/api";
24
24
  import { buildAppSchema } from "@cosmicdrift/kumiko-framework/engine";
25
25
  import { createEventsTable } from "@cosmicdrift/kumiko-framework/event-store";
26
+ import { rankPreferredLocales } from "@cosmicdrift/kumiko-framework/i18n";
26
27
  import { createMetricsForFactory } from "@cosmicdrift/kumiko-framework/observability";
27
28
  import { TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
28
29
  import { resolveAndInjectPageHead, } from "@cosmicdrift/kumiko-headless/apex";
29
30
  import { startDevJobRunners } from "@cosmicdrift/kumiko-server-runtime/boot/job-run-logger";
30
31
  import { buildBunServeOptions, resolveDerivedMaxRequestBodySize, } from "@cosmicdrift/kumiko-server-runtime/bun-serve-options";
31
- import { makeDispatchSystemWrite, } from "@cosmicdrift/kumiko-server-runtime/extra-routes-deps";
32
+ import { makeDispatchSystemQuery, makeDispatchSystemWrite, } from "@cosmicdrift/kumiko-server-runtime/extra-routes-deps";
32
33
  import { RENDERER_WEB_FONT_FILE_PATTERN, RENDERER_WEB_FONTS_URL_PREFIX, resolveRendererWebFontsDir, } from "@cosmicdrift/kumiko-server-runtime/renderer-web-fonts";
33
34
  import { buildRequestBoundSystemQuery } from "@cosmicdrift/kumiko-server-runtime/request-bound-system-query";
34
35
  import { canResolveTailwindStylesheet, resolveTailwindCli, } from "@cosmicdrift/kumiko-server-runtime/resolve-tailwind-cli";
@@ -633,6 +634,7 @@ export async function createKumikoServer(options) {
633
634
  registry: stack.registry,
634
635
  metricsFor: createMetricsForFactory(stack.observability.meter),
635
636
  dispatchSystemWrite: makeDispatchSystemWrite(stack.dispatcher),
637
+ dispatchSystemQuery: makeDispatchSystemQuery(stack.dispatcher),
636
638
  });
637
639
  }
638
640
  // Hook für Caller-spezifische Tables + Seed. Läuft nach den Entity-
@@ -755,6 +757,10 @@ export async function createKumikoServer(options) {
755
757
  html = await resolveAndInjectPageHead(html, options.resolvePageHead, {
756
758
  path: url.pathname,
757
759
  host,
760
+ preferredLocales: rankPreferredLocales({
761
+ queryLang: url.searchParams.get("lang"),
762
+ acceptLanguage: req.headers.get("accept-language"),
763
+ }),
758
764
  systemQuery: buildDevSystemQuery(req, socketAddress),
759
765
  requestSignal: req.signal,
760
766
  });
@@ -211,7 +211,9 @@ function compareImportKeys(a, b) {
211
211
  function isRelativeSpecifier(specifier) {
212
212
  return specifier.startsWith("./") || specifier.startsWith("../");
213
213
  }
214
- function renderImportLine({ specifier, names, typeOnly }) {
214
+ function renderImportLine({ specifier, names, typeOnly, defaultName }) {
215
+ if (defaultName !== undefined)
216
+ return `import ${defaultName} from "${specifier}";`;
215
217
  const sorted = [...names].sort(compareImportKeys);
216
218
  const keyword = typeOnly === true ? "import type" : "import";
217
219
  const oneLine = `${keyword} { ${sorted.join(", ")} } from "${specifier}";`;
@@ -355,6 +357,7 @@ function renderMain(appName) {
355
357
  names: ["requireKmsWiring", "resolveKmsWiring"],
356
358
  },
357
359
  { specifier: "../src/run-config", names: ["APP_FEATURES"] },
360
+ { specifier: "../kumiko.config", names: [], defaultName: "appConfig" },
358
361
  { specifier: "./env-schema", names: ["envSchema"] },
359
362
  ]);
360
363
  const authBlock = renderAdminAuthBlock(appName, [
@@ -385,6 +388,7 @@ const kmsWiring =
385
388
 
386
389
  await runProdApp({
387
390
  features: APP_FEATURES,
391
+ ...(appConfig.validateBootOptions && { validateBootOptions: appConfig.validateBootOptions }),
388
392
  envSchema,
389
393
  staticDir: "./dist",
390
394
  ...kmsWiring,
@@ -398,6 +402,7 @@ function renderServer(appName) {
398
402
  { specifier: "@cosmicdrift/kumiko-dev-server", names: ["runDevApp"] },
399
403
  { specifier: "@cosmicdrift/kumiko-framework/engine", names: ["TenantId"], typeOnly: true },
400
404
  { specifier: "../src/run-config", names: ["APP_FEATURES"] },
405
+ { specifier: "../kumiko.config", names: [], defaultName: "appConfig" },
401
406
  { specifier: "../src/seed", names: ["seedDemoTasks"] },
402
407
  ]);
403
408
  // Dev-only emailVerified skips the login verify gate for the seeded admin;
@@ -420,6 +425,7 @@ const DEFAULT_TENANT_ID = "${tenantId}" as TenantId;
420
425
 
421
426
  await runDevApp({
422
427
  features: APP_FEATURES,
428
+ ...(appConfig.validateBootOptions && { validateBootOptions: appConfig.validateBootOptions }),
423
429
  welcomeBanner: true,
424
430
  clientEntry: "./src/client.tsx",
425
431
  seeds: [seedDemoTasks],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.371.1",
3
+ "version": "0.372.0",
4
4
  "description": "Dev-tooling for Kumiko apps: local dev-server bootstrap (runDevApp), scaffolding. 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>",
@@ -72,14 +72,14 @@
72
72
  "kumiko-upgrade": "./bin/kumiko-upgrade.ts"
73
73
  },
74
74
  "dependencies": {
75
- "@cosmicdrift/kumiko-bundled-features": "0.371.1",
76
- "@cosmicdrift/kumiko-framework": "0.371.1",
77
- "@cosmicdrift/kumiko-headless": "0.371.1",
78
- "@cosmicdrift/kumiko-renderer-mail-html": "0.371.1",
79
- "@cosmicdrift/kumiko-renderer-web": "0.371.1",
80
- "@cosmicdrift/kumiko-server-runtime": "0.371.1",
81
- "@cosmicdrift/kumiko-testing": "0.371.1",
82
- "@cosmicdrift/kumiko-types": "0.371.1",
75
+ "@cosmicdrift/kumiko-bundled-features": "0.372.0",
76
+ "@cosmicdrift/kumiko-framework": "0.372.0",
77
+ "@cosmicdrift/kumiko-headless": "0.372.0",
78
+ "@cosmicdrift/kumiko-renderer-mail-html": "0.372.0",
79
+ "@cosmicdrift/kumiko-renderer-web": "0.372.0",
80
+ "@cosmicdrift/kumiko-server-runtime": "0.372.0",
81
+ "@cosmicdrift/kumiko-testing": "0.372.0",
82
+ "@cosmicdrift/kumiko-types": "0.372.0",
83
83
  "bun-types": "^1.3.13",
84
84
  "ts-morph": "^28.0.0",
85
85
  "zod": "^4.4.3"
package/src/changes.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.372.0",
4
+ "type": "improvement",
5
+ "title": "kumiko-build --entry and buildServerBundle extraEntries bundle additional server entry points as dist-server/<basename>.js",
6
+ "detail": "Opt-in per file, not every bin/ helper module; the output shares the chunk files with server.js. Unknown kumiko-build options now fail the build."
7
+ },
2
8
  {
3
9
  "version": "0.371.0",
4
10
  "type": "improvement",
@@ -9,4 +9,7 @@ import appConfig from "../kumiko.config";
9
9
 
10
10
  export const FEATURES: readonly FeatureDefinition[] = allAppFeatures(appConfig);
11
11
 
12
+ // `kumiko check` validates the boot with the options kumiko.config.ts declares.
13
+ export const VALIDATE_BOOT_OPTIONS = appConfig.validateBootOptions;
14
+
12
15
  export const ENTITY_METAS: readonly EntityTableMeta[] = collectTableMetas(FEATURES);