@cosmicdrift/kumiko-server-runtime 0.329.0 → 0.330.2
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/README.md +15 -0
- package/dist/boot/apply-boot-seeds.d.ts +8 -0
- package/{src/boot/apply-boot-seeds.ts → dist/boot/apply-boot-seeds.js} +2 -10
- package/dist/boot/boot-crypto.d.ts +9 -0
- package/dist/boot/boot-crypto.js +39 -0
- package/dist/boot/job-run-logger.d.ts +19 -0
- package/dist/boot/job-run-logger.js +44 -0
- package/dist/boot/pii-event-backfill-on-boot.d.ts +13 -0
- package/dist/boot/pii-event-backfill-on-boot.js +25 -0
- package/dist/build-prod-bundle.d.ts +103 -0
- package/dist/build-prod-bundle.js +751 -0
- package/dist/bun-serve-options.d.ts +32 -0
- package/dist/bun-serve-options.js +49 -0
- package/dist/compose-features.d.ts +31 -0
- package/dist/compose-features.js +124 -0
- package/dist/extra-routes-deps.d.ts +30 -0
- package/dist/extra-routes-deps.js +4 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/pii-boot-gate.d.ts +13 -0
- package/dist/pii-boot-gate.js +46 -0
- package/dist/renderer-web-fonts.d.ts +9 -0
- package/{src/renderer-web-fonts.ts → dist/renderer-web-fonts.js} +14 -18
- package/dist/resolve-tailwind-cli.d.ts +14 -0
- package/dist/resolve-tailwind-cli.js +36 -0
- package/dist/run-prod-app-boot-context.d.ts +43 -0
- package/dist/run-prod-app-boot-context.js +198 -0
- package/dist/run-prod-app-static-files.d.ts +32 -0
- package/dist/run-prod-app-static-files.js +280 -0
- package/dist/run-prod-app.d.ts +471 -0
- package/dist/run-prod-app.js +741 -0
- package/dist/run-worker-app.d.ts +92 -0
- package/dist/run-worker-app.js +220 -0
- package/dist/security-headers.d.ts +20 -0
- package/dist/security-headers.js +49 -0
- package/dist/session-boot-gate.d.ts +11 -0
- package/dist/session-boot-gate.js +22 -0
- package/dist/session-wiring.d.ts +11 -0
- package/{src/session-wiring.ts → dist/session-wiring.js} +2 -6
- package/dist/try-hono-first.d.ts +24 -0
- package/{src/try-hono-first.ts → dist/try-hono-first.js} +8 -36
- package/package.json +102 -36
- package/src/changes.json +6 -0
- package/src/__tests__/boot-extra-context.test.ts +0 -163
- package/src/__tests__/boot-probe-fixture.ts +0 -64
- package/src/__tests__/build-prod-bundle.inprocess.test.ts +0 -233
- package/src/__tests__/build-prod-bundle.test.ts +0 -724
- 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 -609
- package/src/__tests__/compose-features.test.ts +0 -206
- package/src/__tests__/config-seed-boot.integration.test.ts +0 -158
- package/src/__tests__/pii-boot-gate.test.ts +0 -112
- 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__/renderer-web-theme-plugin.integration.test.ts +0 -77
- package/src/__tests__/require-env.test.ts +0 -34
- package/src/__tests__/resolve-auth-mail.test.ts +0 -144
- package/src/__tests__/resolve-tailwind-cli.test.ts +0 -81
- package/src/__tests__/run-prod-app-dry-run.test.ts +0 -135
- package/src/__tests__/run-prod-app-env-source.test.ts +0 -118
- package/src/__tests__/run-prod-app-kms-slots.test.ts +0 -108
- package/src/__tests__/run-prod-app-spec.test.ts +0 -167
- package/src/__tests__/run-prod-app-static-files.test.ts +0 -298
- package/src/__tests__/run-prod-app.integration.test.ts +0 -1525
- package/src/__tests__/run-worker-app-boot.test.ts +0 -183
- package/src/__tests__/run-worker-app.integration.test.ts +0 -218
- package/src/__tests__/security-headers.test.ts +0 -88
- package/src/__tests__/session-boot-gate.test.ts +0 -70
- package/src/__tests__/session-wiring.test.ts +0 -16
- package/src/__tests__/try-hono-first.test.ts +0 -108
- package/src/__tests__/websocket-route.integration.test.ts +0 -695
- package/src/boot/__tests__/job-run-logger.integration.test.ts +0 -262
- package/src/boot/__tests__/job-run-logger.test.ts +0 -26
- package/src/boot/boot-crypto.ts +0 -67
- package/src/boot/job-run-logger.ts +0 -63
- package/src/boot/pii-event-backfill-on-boot.ts +0 -43
- package/src/build-prod-bundle.ts +0 -996
- package/src/bun-serve-options.ts +0 -110
- package/src/compose-features.ts +0 -197
- package/src/extra-routes-deps.ts +0 -38
- package/src/index.ts +0 -27
- package/src/pii-boot-gate.ts +0 -80
- package/src/resolve-tailwind-cli.ts +0 -45
- package/src/run-prod-app-boot-context.ts +0 -319
- package/src/run-prod-app-static-files.ts +0 -359
- package/src/run-prod-app.ts +0 -1420
- package/src/run-worker-app.ts +0 -366
- package/src/security-headers.ts +0 -67
- package/src/session-boot-gate.ts +0 -34
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @cosmicdrift/kumiko-server-runtime
|
|
2
|
+
|
|
3
|
+
Production server boot for Kumiko apps: connections, schema drift gate, seeds, lifecycle and graceful shutdown. The prod counterpart to `runDevApp` in `@cosmicdrift/kumiko-dev-server`, without dev, scaffold or codegen tooling.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @cosmicdrift/kumiko-server-runtime
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { runProdApp } from "@cosmicdrift/kumiko-server-runtime/run-prod-app";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Documentation: https://kumiko.rocks
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import type { Registry } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
+
import type { EnvelopeCipher } from "@cosmicdrift/kumiko-framework/secrets";
|
|
4
|
+
export declare function applyBootSeeds(deps: {
|
|
5
|
+
registry: Registry;
|
|
6
|
+
db: DbConnection;
|
|
7
|
+
cipher?: EnvelopeCipher;
|
|
8
|
+
}): Promise<void>;
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { seedAllConfigValues } from "@cosmicdrift/kumiko-bundled-features/config";
|
|
2
|
-
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
3
|
-
import type { Registry } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
|
-
import type { EnvelopeCipher } from "@cosmicdrift/kumiko-framework/secrets";
|
|
5
|
-
|
|
6
2
|
// Single boot-seed entry-point. runDevApp + runProdApp both call this
|
|
7
3
|
// from their post-stack hook, so the wiring lives in exactly one place
|
|
8
4
|
// — config-seed-boot.integration.ts pins this helper, which means a
|
|
@@ -10,10 +6,6 @@ import type { EnvelopeCipher } from "@cosmicdrift/kumiko-framework/secrets";
|
|
|
10
6
|
// surfaces as a missing-helper-use in code review rather than silently
|
|
11
7
|
// shipping a server that never seeds.
|
|
12
8
|
// @wrapper-known semantic-alias
|
|
13
|
-
export async function applyBootSeeds(deps
|
|
14
|
-
|
|
15
|
-
db: DbConnection;
|
|
16
|
-
cipher?: EnvelopeCipher;
|
|
17
|
-
}): Promise<void> {
|
|
18
|
-
await seedAllConfigValues(deps.registry, deps.db, deps.cipher);
|
|
9
|
+
export async function applyBootSeeds(deps) {
|
|
10
|
+
await seedAllConfigValues(deps.registry, deps.db, deps.cipher);
|
|
19
11
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type DekCache, type EnvelopeCipher, type MasterKeyProvider } from "@cosmicdrift/kumiko-framework/secrets";
|
|
2
|
+
export declare function envHasMasterKek(env: Record<string, string | undefined>): boolean;
|
|
3
|
+
export type BootCrypto = {
|
|
4
|
+
readonly masterKeyProvider?: MasterKeyProvider;
|
|
5
|
+
readonly configCipher?: EnvelopeCipher;
|
|
6
|
+
readonly entityFieldCipher?: EnvelopeCipher;
|
|
7
|
+
readonly dekCache: DekCache;
|
|
8
|
+
};
|
|
9
|
+
export declare function resolveBootCrypto(envSource: Record<string, string | undefined>, masterKeyOverride?: MasterKeyProvider): BootCrypto;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// One place that turns env/options into the app-wide crypto objects:
|
|
2
|
+
// the MasterKeyProvider (KUMIKO_SECRETS_MASTER_KEY_V<n> keyring) and the
|
|
3
|
+
// EnvelopeCipher for `encrypted: true` config keys. runProdApp and
|
|
4
|
+
// runDevApp both resolve this once and thread it into
|
|
5
|
+
// buildBootExtraContext + applyBootSeeds so resolver, set-handler and
|
|
6
|
+
// seeds share the same cipher instance (and DEK cache).
|
|
7
|
+
import { createDekCache, createEnvelopeCipher, createEnvMasterKeyProvider, } from "@cosmicdrift/kumiko-framework/secrets";
|
|
8
|
+
// Keyring detection without throwing: only build the env provider when at
|
|
9
|
+
// least one versioned KEK is actually set. Covers (a) apps without any
|
|
10
|
+
// encryption — no KEK requirement, and (b) dev with an app-supplied
|
|
11
|
+
// provider in options.masterKey — env stays irrelevant.
|
|
12
|
+
const MASTER_KEK_VAR = /^KUMIKO_SECRETS_MASTER_KEY_V\d+$/;
|
|
13
|
+
export function envHasMasterKek(env) {
|
|
14
|
+
return Object.entries(env).some(([k, v]) => MASTER_KEK_VAR.test(k) && !!v);
|
|
15
|
+
}
|
|
16
|
+
export function resolveBootCrypto(envSource, masterKeyOverride) {
|
|
17
|
+
const masterKeyProvider = masterKeyOverride ??
|
|
18
|
+
(envHasMasterKek(envSource)
|
|
19
|
+
? createEnvMasterKeyProvider({
|
|
20
|
+
// CURRENT_VERSION default "1" spiegelt secretsEnvSchema — ohne
|
|
21
|
+
// ihn wirft der raw-env-Provider, obwohl V1 gesetzt ist.
|
|
22
|
+
env: {
|
|
23
|
+
...envSource,
|
|
24
|
+
KUMIKO_SECRETS_MASTER_KEY_CURRENT_VERSION: envSource["KUMIKO_SECRETS_MASTER_KEY_CURRENT_VERSION"] ?? "1",
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
: undefined);
|
|
28
|
+
const dekCache = createDekCache();
|
|
29
|
+
const configCipher = masterKeyProvider
|
|
30
|
+
? createEnvelopeCipher(masterKeyProvider, { dekCache })
|
|
31
|
+
: undefined;
|
|
32
|
+
const entityFieldCipher = configCipher;
|
|
33
|
+
return {
|
|
34
|
+
...(masterKeyProvider && { masterKeyProvider }),
|
|
35
|
+
...(configCipher && { configCipher }),
|
|
36
|
+
...(entityFieldCipher && { entityFieldCipher }),
|
|
37
|
+
dekCache,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createJobRunLogger } from "@cosmicdrift/kumiko-bundled-features/jobs";
|
|
2
|
+
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
3
|
+
import type { Registry } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
|
+
import type { AppContext } from "@cosmicdrift/kumiko-framework/engine/types";
|
|
5
|
+
import { type JobRunner } from "@cosmicdrift/kumiko-framework/jobs";
|
|
6
|
+
import { type Dispatcher } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
7
|
+
export declare function jobRunLoggerCallbacks(registry: Registry, db: DbConnection): ReturnType<typeof createJobRunLogger> | undefined;
|
|
8
|
+
/** Dev-server parity: consume api + worker lanes when jobs are registered. */
|
|
9
|
+
export declare function startDevJobRunners(opts: {
|
|
10
|
+
readonly registry: Registry;
|
|
11
|
+
readonly db: DbConnection;
|
|
12
|
+
readonly context: AppContext;
|
|
13
|
+
readonly redisUrl: string;
|
|
14
|
+
readonly dispatcher: Dispatcher;
|
|
15
|
+
readonly queueNamePrefix: string;
|
|
16
|
+
}): Promise<{
|
|
17
|
+
readonly runners: readonly JobRunner[];
|
|
18
|
+
readonly stop: () => Promise<void>;
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createJobRunLogger } from "@cosmicdrift/kumiko-bundled-features/jobs";
|
|
2
|
+
import { createJobRunner } from "@cosmicdrift/kumiko-framework/jobs";
|
|
3
|
+
import { dispatcherToWriteRef } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
4
|
+
export function jobRunLoggerCallbacks(registry, db) {
|
|
5
|
+
if (registry.getFeature("jobs") === undefined)
|
|
6
|
+
return undefined;
|
|
7
|
+
return createJobRunLogger({ db, registry });
|
|
8
|
+
}
|
|
9
|
+
/** Dev-server parity: consume api + worker lanes when jobs are registered. */
|
|
10
|
+
export async function startDevJobRunners(opts) {
|
|
11
|
+
const jobs = [...opts.registry.getAllJobs().values()];
|
|
12
|
+
if (opts.registry.getFeature("jobs") === undefined || jobs.length === 0) {
|
|
13
|
+
return { runners: [], stop: async () => { } };
|
|
14
|
+
}
|
|
15
|
+
const logger = createJobRunLogger({ db: opts.db, registry: opts.registry });
|
|
16
|
+
const runners = [];
|
|
17
|
+
// `?? "worker"` mirrors job-runner's laneForJob: a job without an explicit
|
|
18
|
+
// runIn is enqueued onto the worker lane, so filtering those out would leave
|
|
19
|
+
// its queue without a consumer whenever no other job named the lane.
|
|
20
|
+
const lanes = new Set(jobs.map((j) => j.runIn ?? "worker"));
|
|
21
|
+
for (const lane of lanes) {
|
|
22
|
+
const jr = createJobRunner({
|
|
23
|
+
registry: opts.registry,
|
|
24
|
+
context: { ...opts.context, db: opts.db },
|
|
25
|
+
redisUrl: opts.redisUrl,
|
|
26
|
+
queueNamePrefix: opts.queueNamePrefix,
|
|
27
|
+
consumerLane: lane,
|
|
28
|
+
...logger,
|
|
29
|
+
});
|
|
30
|
+
// Without this, ctx.write/ctx.queryAs inside a dev-run job throw
|
|
31
|
+
// "dispatcher attached — call attachDispatcher() first" on their first
|
|
32
|
+
// call — the prod entrypoints attach automatically, dev boot must too.
|
|
33
|
+
jr.attachDispatcher(dispatcherToWriteRef(opts.dispatcher));
|
|
34
|
+
await jr.start();
|
|
35
|
+
runners.push(jr);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
runners,
|
|
39
|
+
stop: async () => {
|
|
40
|
+
for (const runner of runners)
|
|
41
|
+
await runner.stop();
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import type { Registry } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
+
export declare const SKIP_PII_BACKFILL_ENV = "KUMIKO_SKIP_PII_BACKFILL";
|
|
4
|
+
type ShutdownRegistry = {
|
|
5
|
+
registerShutdownHook(name: string, fn: () => Promise<void>): void;
|
|
6
|
+
};
|
|
7
|
+
export declare function startPiiEventBackfillOnBoot(opts: {
|
|
8
|
+
readonly db: DbConnection;
|
|
9
|
+
readonly registry: Registry;
|
|
10
|
+
readonly lifecycle: ShutdownRegistry;
|
|
11
|
+
readonly envSource: Readonly<Record<string, string | undefined>>;
|
|
12
|
+
}): void;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createFallbackLogger } from "@cosmicdrift/kumiko-framework/logging";
|
|
2
|
+
import { runPiiEventBackfill } from "@cosmicdrift/kumiko-framework/migrations";
|
|
3
|
+
export const SKIP_PII_BACKFILL_ENV = "KUMIKO_SKIP_PII_BACKFILL";
|
|
4
|
+
// Runs in the background instead of blocking boot: the first run after a bump
|
|
5
|
+
// scans the whole store and would delay readiness in proportion to its size.
|
|
6
|
+
// Every batch is its own transaction, so an abort at any point is safe.
|
|
7
|
+
export function startPiiEventBackfillOnBoot(opts) {
|
|
8
|
+
if (opts.envSource[SKIP_PII_BACKFILL_ENV] === "1") {
|
|
9
|
+
// skip: operator opted out via KUMIKO_SKIP_PII_BACKFILL
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const log = createFallbackLogger("pii-event-backfill");
|
|
13
|
+
const abortController = new AbortController();
|
|
14
|
+
const run = runPiiEventBackfill(opts.db, opts.registry, {
|
|
15
|
+
signal: abortController.signal,
|
|
16
|
+
}).then(() => undefined, (e) => {
|
|
17
|
+
log.error("PII event backfill crashed; it will be retried on the next boot", {
|
|
18
|
+
error: e instanceof Error ? e.message : String(e),
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
opts.lifecycle.registerShutdownHook("piiEventBackfill", async () => {
|
|
22
|
+
abortController.abort();
|
|
23
|
+
await run;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export type BuildProdBundleOptions = {
|
|
2
|
+
/** App-Root. Default: process.cwd(). */
|
|
3
|
+
readonly cwd?: string;
|
|
4
|
+
/** Output-Folder relativ zu cwd. Default: "dist". */
|
|
5
|
+
readonly outDir?: string;
|
|
6
|
+
/** Stylesheet-Override. Default: erst src/styles.css, dann
|
|
7
|
+
* @cosmicdrift/kumiko-renderer-web/styles.css wenn clientEntry da ist.
|
|
8
|
+
* `false` deaktiviert die CSS-Pipeline explizit. */
|
|
9
|
+
readonly stylesheet?: string | false;
|
|
10
|
+
} & ClientEntriesConfig;
|
|
11
|
+
/** One declared client entry, read from package.json `kumiko.clientEntries`.
|
|
12
|
+
* `name` becomes the output filename (`client-<name>.js` / `<name>.html`
|
|
13
|
+
* unless `htmlPath` overrides it). */
|
|
14
|
+
export type ClientEntryDeclaration = {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly sourceFile: string;
|
|
17
|
+
readonly htmlPath?: string;
|
|
18
|
+
};
|
|
19
|
+
/** The two mutually exclusive shapes read from package.json `kumiko.*`.
|
|
20
|
+
* Neither set → convention mode (src/client.tsx | src/client.ts). */
|
|
21
|
+
export type ClientEntriesConfig = {
|
|
22
|
+
readonly clientEntry?: string;
|
|
23
|
+
readonly clientEntries?: readonly ClientEntryDeclaration[];
|
|
24
|
+
};
|
|
25
|
+
export type BuildManifest = Readonly<Record<string, string>>;
|
|
26
|
+
export type BuildResult = {
|
|
27
|
+
readonly outDir: string;
|
|
28
|
+
/** Logical → hashed-URL mapping. Beispiel:
|
|
29
|
+
* { "client.js": "/assets/client-a3f2.js",
|
|
30
|
+
* "styles.css": "/assets/styles-9b4c.css" } */
|
|
31
|
+
readonly manifest: BuildManifest;
|
|
32
|
+
/** Build-Identität (Hash über die Asset-URLs) + lesbarer Zeitstempel.
|
|
33
|
+
* undefined bei vanilla public-only-Builds (kein Bundle). */
|
|
34
|
+
readonly buildInfo?: BuildInfo;
|
|
35
|
+
};
|
|
36
|
+
/** In index.html gebacken (`window.__KUMIKO_BUILD__`) UND als
|
|
37
|
+
* dist/build-info.json geschrieben. Der UpdateChecker pollt build-info.json
|
|
38
|
+
* und vergleicht `id` gegen den geladenen Stand → Reload-Banner bei Drift. */
|
|
39
|
+
export type BuildInfo = {
|
|
40
|
+
/** Hash über die sortierten (content-gehashten) Asset-URLs. Ändert sich
|
|
41
|
+
* gdw. sich ein Asset ändert — selbsttragend, kein Env-Var/Dockerfile. */
|
|
42
|
+
readonly id: string;
|
|
43
|
+
/** ISO-Zeitstempel des Builds, lesbare Anzeige-Version (ersetzt den rohen sha). */
|
|
44
|
+
readonly builtAt: string;
|
|
45
|
+
};
|
|
46
|
+
/** Folder name relative to dist/ for hashed assets (JS, CSS, file-loader
|
|
47
|
+
* outputs). Exported damit runProdApp dieselbe Konvention für Cache-
|
|
48
|
+
* Header nutzt — Drift verhindern. */
|
|
49
|
+
export declare const ASSETS_DIR = "assets";
|
|
50
|
+
export declare function buildProdBundle(options?: BuildProdBundleOptions): Promise<BuildResult>;
|
|
51
|
+
export type ClientEntry = {
|
|
52
|
+
/** Logical name. "client" for single-entry mode (package.json
|
|
53
|
+
* `kumiko.clientEntry` or the src/client.tsx convention); otherwise the
|
|
54
|
+
* `name` declared in package.json `kumiko.clientEntries[]`. */
|
|
55
|
+
readonly name: string;
|
|
56
|
+
/** Absolute path to the TypeScript entry module. */
|
|
57
|
+
readonly sourceFile: string;
|
|
58
|
+
/** Manifest key & logical asset path. "client.js" for single-entry mode,
|
|
59
|
+
* otherwise "client-<name>.js". */
|
|
60
|
+
readonly manifestKey: string;
|
|
61
|
+
/** HTML template path — absolute when declared or discovered on disk,
|
|
62
|
+
* otherwise a bare default filename ("index.html", "<name>.html")
|
|
63
|
+
* resolved against cwd by the caller. Naming is deliberately symmetric
|
|
64
|
+
* to `runDevApp.clientEntries[].htmlPath` so build and dev server agree
|
|
65
|
+
* on the same convention. */
|
|
66
|
+
readonly htmlPath: string;
|
|
67
|
+
};
|
|
68
|
+
/** Resolves the client entries to build. Public — also called from
|
|
69
|
+
* `kumiko-build`/`kumiko build` via `@cosmicdrift/kumiko-dev-server/build`,
|
|
70
|
+
* not just from unit tests.
|
|
71
|
+
*
|
|
72
|
+
* Precedence (fw#2320 — explicit declaration, no filename inference):
|
|
73
|
+
* 1. `declared.clientEntry` and `declared.clientEntries` both set → throw.
|
|
74
|
+
* 2. `declared.clientEntries` (non-empty) → one entry per declaration.
|
|
75
|
+
* 3. `declared.clientEntry` → single entry, name "client".
|
|
76
|
+
* 4. Neither → convention: src/client.tsx | src/client.ts (name "client").
|
|
77
|
+
* If that convention finds nothing but src/ still has legacy
|
|
78
|
+
* `client-<suffix>.tsx` files, throws a migration error instead of
|
|
79
|
+
* silently shipping a build without their bundles. */
|
|
80
|
+
export declare function resolveClientEntries(cwd: string, declared: ClientEntriesConfig): readonly ClientEntry[];
|
|
81
|
+
/** Reads package.json → `kumiko.clientEntry` / `kumiko.clientEntries`.
|
|
82
|
+
* Missing file or missing keys → `{}` (falls back to convention mode). A
|
|
83
|
+
* malformed value under either key throws — a typo here must fail the
|
|
84
|
+
* build loudly instead of silently dropping declared entries. */
|
|
85
|
+
export declare function readClientEntriesConfig(cwd: string): ClientEntriesConfig;
|
|
86
|
+
type ResolvedStylesheet = {
|
|
87
|
+
readonly path: string;
|
|
88
|
+
/** True nur wenn wir auf das gepackte renderer-web-styles.css zurückfallen
|
|
89
|
+
* (App hat clientEntry + renderer-web-Dep, aber kein eigenes src/styles.css).
|
|
90
|
+
* Steuert den Shell-Klassen-Sentinel im Build. */
|
|
91
|
+
readonly isRendererWebFallback: boolean;
|
|
92
|
+
};
|
|
93
|
+
export declare function assertRendererWebShellPresent(css: string, stylesheet: ResolvedStylesheet): void;
|
|
94
|
+
export declare function discoverHtmlTemplate(cwd: string): string | undefined;
|
|
95
|
+
export declare function runTailwindOnce(entry: string, cwd: string): Promise<string>;
|
|
96
|
+
export declare function buildMissingTemplateError(manifest: BuildManifest, entry: ClientEntry): string;
|
|
97
|
+
export declare function injectAssetTags(html: string, manifest: BuildManifest, entry: ClientEntry, buildInfo?: BuildInfo): string;
|
|
98
|
+
export declare function computeBuildId(manifest: BuildManifest): string;
|
|
99
|
+
/** Formatiert ein BuildResult als CLI-freundliche Mehrzeilen-Zusammenfassung
|
|
100
|
+
* mit ANSI-Farben. Wird sowohl von `kumiko build` als auch von dem
|
|
101
|
+
* hoisted `kumiko-build`-Bin verwendet, damit das Output konsistent ist. */
|
|
102
|
+
export declare function formatBuildResult(result: BuildResult, durationMs: number): string;
|
|
103
|
+
export {};
|