import { type SeedAdminOptions } from "@cosmicdrift/kumiko-bundled-features/auth-email-password/seeding"; import type { PostAuthLandingResolver } from "@cosmicdrift/kumiko-framework/api"; import { type KmsAdapter } from "@cosmicdrift/kumiko-framework/crypto"; import { type FeatureDefinition, type Registry, type ValidateBootOptions } from "@cosmicdrift/kumiko-framework/engine"; import type { ErrorDocsConfig } from "@cosmicdrift/kumiko-framework/errors"; import type { EnvelopeCipher, MasterKeyProvider } from "@cosmicdrift/kumiko-framework/secrets"; import type { TestStack } from "@cosmicdrift/kumiko-framework/stack"; import type { PageHeadResolver } from "@cosmicdrift/kumiko-headless/apex"; import { type CreateKumikoServerOptions, type KumikoServerHandle } from "./create-kumiko-server.js"; export type { AccountLockoutSetup, AccountUnlockSetup, AuthMailOptions, EmailVerificationSetup, InviteSetup, PasswordResetSetup, SignupSetup, } from "@cosmicdrift/kumiko-server-runtime/run-prod-app"; import type { AccountLockoutSetup, AccountUnlockSetup, AuthMailOptions, EmailVerificationSetup, InviteSetup, PasswordResetSetup, SignupSetup } from "@cosmicdrift/kumiko-server-runtime/run-prod-app"; export type RunDevAppAuthOptions = { /** Admin user to seed at boot. Idempotent — re-runs in persistent-DB * mode reuse the existing user. */ readonly admin: SeedAdminOptions; /** Optional override of the login error → HTTP status map. Default * maps invalidCredentials → 401, noMembership → 403. */ readonly loginErrorStatusMap?: Readonly>; /** Auth-Mail-Convenience — symmetrisch zu RunProdAppAuthOptions.mail. * Verdrahtet alle 4 Mail-Flows aus env-SMTP + Standard-Templates; * hmacSecret = `JWT_SECRET`-env (Dev-Fallback wenn ungesetzt). Ohne * `SMTP_HOST`-env bleiben die Flows unverdrahtet (Null-Transport-Guard). * Explizite Flow-Setups gewinnen über den mail-Default. */ readonly mail?: AuthMailOptions; /** Password-reset flow. Wenn gesetzt werden /api/auth/request-password- * reset + /api/auth/reset-password als Public-Routes gemounted UND * der request/confirm-Handler im auth-email-password-Feature wird * registriert. Symmetrisch zu RunProdAppAuthOptions.passwordReset. */ readonly passwordReset?: PasswordResetSetup; /** Email-verification flow. Symmetric to passwordReset. */ readonly emailVerification?: EmailVerificationSetup; /** Self-signup flow (magic link). Symmetric to RunProdAppAuthOptions. */ readonly signup?: SignupSetup; /** Tenant-invite flow (magic link). Symmetric. */ readonly invite?: InviteSetup; /** Account-unlock flow (#1266). Symmetric to RunProdAppAuthOptions. */ readonly accountUnlock?: AccountUnlockSetup; /** Brute-force guard on the login handler (maxFailedAttempts, * lockoutDurationMinutes). Mounts no routes. Symmetric to * RunProdAppAuthOptions.accountLockout (kumiko-framework#1627). */ readonly accountLockout?: AccountLockoutSetup; /** Domain attribute for both auth cookies (see * AuthRoutesConfig.cookieDomain). Symmetric to RunProdAppAuthOptions. */ readonly cookieDomain?: string; /** Former cookie domains cleared on login/logout (see * AuthRoutesConfig.retiredCookieDomains). */ readonly retiredCookieDomains?: readonly string[]; /** Server-side Origin allowlist for the CSRF guard (see * AuthRoutesConfig.allowedOrigins). Symmetric to RunProdAppAuthOptions — * required once `cookieDomain` is set. */ readonly allowedOrigins?: readonly string[]; /** Opt out of the Origin guard. Symmetric to RunProdAppAuthOptions. */ readonly unsafeSkipOriginCheck?: boolean; /** Number of trusted reverse-proxy hops for client-IP derivation (see * AuthRoutesConfig.trustedProxyHops, kumiko-framework#1539). Symmetric to * RunProdAppAuthOptions — dev usually runs unproxied, so this is normally * left unset (default 0). */ readonly trustedProxyHops?: number; /** Server-computed post-auth redirect (see AuthRoutesConfig.postAuthLanding). * Result lands in the login/signup/invite response as `landingPath`; an * invalid path or a throwing resolver just omits the field. */ readonly postAuthLanding?: PostAuthLandingResolver; }; /** Hook for app-specific seeding (demo data, fixtures). Runs after the * admin (when auth is active) in declared order. */ export type SeedFn = (stack: TestStack) => Promise; export type RunDevAppOptions = { /** App-spezifische Features. Im auth-mode werden config/user/tenant/ * auth-email-password automatisch dazu gemischt — KEIN doppeltes * manuelles Hinzufügen nötig. */ readonly features: readonly FeatureDefinition[]; /** Opt-in boot-validator warnings — see ValidateBootOptions. */ readonly validateBootOptions?: ValidateBootOptions; /** Browser entry module, bundled to /client.js. Mutually exclusive with * `clientEntries`. */ readonly clientEntry?: string; /** Multi-entry mode: one bundle (`/client-.js`) and one HTML template * per entry; `hostDispatch` picks the entry per request. kumiko-build reads * the same list from package.json `kumiko.clientEntries`. Mutually exclusive * with `clientEntry`. */ readonly clientEntries?: CreateKumikoServerOptions["clientEntries"]; /** Multi-entry mode: per-request routing. Required with `clientEntries`, * otherwise the server cannot tell which HTML to serve. */ readonly hostDispatch?: CreateKumikoServerOptions["hostDispatch"]; /** Per-request head-metadata resolver — same option, same signature as * `runProdApp`'s `resolvePageHead`, so `bun dev` and every e2e that boots * through `runDevApp` show the same resolved head prod does. See * `CreateKumikoServerOptions.resolvePageHead` for the full contract. */ readonly resolvePageHead?: PageHeadResolver; /** CSS-Entry. Default: package-export `@cosmicdrift/kumiko-renderer-web/styles.css` * wenn ein client-Entry gesetzt ist. `false` deaktiviert die CSS-Pipeline. */ readonly stylesheet?: string | false; /** Tailwind `--watch` process on/off, see `CreateKumikoServerOptions.stylesheetWatch`. */ readonly stylesheetWatch?: boolean; /** Eigenes HTML-Template; sonst minimal-Default (#root + client.js). * Im Multi-Entry-Mode ist es das Fallback-Template, wenn ein einzelner * Entry kein eigenes htmlPath setzt. */ readonly htmlPath?: string; /** Listen-Port. Default 4173 (oder $PORT). */ readonly port?: number; /** Extra-Verzeichnisse für den File-Watcher (Trigger Hot-Reload). */ readonly watchDirs?: readonly string[]; /** SIGINT/SIGTERM-Handler installieren (Default true; in Tests auf * false damit repeated boots keine Listener akkumulieren). */ readonly installSignalHandlers?: boolean; /** Auth mode: standard features mixed in, auth routes wired, seedAdminGuarded * runs in onAfterSetup. Without `auth` the server stays in auto-mint JWT mode. */ readonly auth?: RunDevAppAuthOptions; /** Eigene Seed-Funktionen, laufen nach dem Admin (wenn auth) in * Array-Reihenfolge. */ readonly seeds?: readonly SeedFn[]; /** Extra-AppContext-Keys. `templateResolver` (immer) + `secrets` (wenn das * secrets-Feature gemountet ist) + `configResolver` (auth-mode) werden * automatisch ergänzt — App-Werte gewinnen. Symmetrisch zu runProdApp. */ /** Boot default locale (BCP-47) for ctx.locale when the request carries * no locale signal. Merged into AppContext before extraContext (app wins). */ readonly defaultLocale?: string; readonly extraContext?: CreateKumikoServerOptions["extraContext"]; /** MasterKeyProvider für die auto-verdrahtete `ctx.secrets`. Default: * `createEnvMasterKeyProvider`. Override für KMS-Backends. Nur relevant * wenn das secrets-Feature gemountet ist. Symmetrisch zu runProdApp. */ readonly masterKey?: MasterKeyProvider; /** Subject-Key-KMS für pii-annotierte Felder (Crypto-Shredding) — dev- * Pendant zu runProdApp({ kms }). Ephemere DB: InMemoryKmsAdapter reicht. * Persistente Dev-DB: createPgKmsAdapter gegen dieselbe DB, sonst sind * alte Rows nach dem Restart unlesbar (DEKs weg). Ohne Adapter: Klartext * + Boot-Warnung. */ readonly kms?: KmsAdapter; /** 32-Byte-Key (base64) für Blind-Index-HMACs — Pflicht sobald `kms` * gesetzt ist und lookupable-Felder gemountet sind (sonst Boot-Abbruch, * symmetrisch zu runProdApp). */ readonly blindIndexKey?: string; /** Env-Quelle für die ENV→config-app-override-Brücke (Keys mit `env:` * bekommen ihren env-Wert als app-override-Default — symmetrisch zu * runProdApp). Default `process.env`. Injizierbar als Test-Seam, damit * Tests eigene env-Werte reichen statt `process.env` global zu mutieren. */ readonly envSource?: Record; /** Anonymous-Access für Public-Endpoints — Requests ohne JWT laufen * als Pseudo-User mit Rolle `anonymous` durch, wenn der Handler die * Rolle in `access.roles` führt. */ readonly anonymousAccess?: CreateKumikoServerOptions["anonymousAccess"]; /** File-Storage-Provider — aktiviert die Upload-Routes (/api/files) + * `ctx.files`. Demos: `{ storageProvider: createInMemoryFileProvider() }`. */ readonly files?: CreateKumikoServerOptions["files"]; /** App-eigene HTTP-Routes (z.B. /feed.xml, /sitemap.xml) — wird ans * Hono-app gehängt, läuft VOR dem static-asset-Pfad. Symmetrisch zur * gleichnamigen Option in runProdApp. */ readonly extraRoutes?: CreateKumikoServerOptions["extraRoutes"]; /** Hook for app-wired co-running components — symmetric to * runProdApp.wire (kumiko-framework#3050). */ readonly wire?: CreateKumikoServerOptions["wire"]; /** Feature-toggle resolver — durchgereicht an createKumikoServer → * setupTestStack. Sprint-8 Tier-Composition: per-Tenant unterschied- * liche features aktiv via globalFeatureToggleRuntime. Pattern in * bin/server.ts: createLateBoundHolder + post-boot runtime.initialize * in einem seed-fn, weil die runtime stack.db braucht und die seed- * Funktionen nach setupTestStack laufen. */ readonly effectiveFeatures?: CreateKumikoServerOptions["effectiveFeatures"]; /** Print a first-run banner after the server starts (URL, admin login, * hot-reload hint, docs link). Default: off — apps that already log * their own startup shouldn't get double-printed. The scaffold template * (create-kumiko-app) flips this on so the first `bun dev` ends on * something the user can click. Pass an object to override the * features-dir hint or the docs URL. */ readonly welcomeBanner?: boolean | { readonly featuresDir?: string; readonly docsUrl?: string; }; /** Forwarded to createKumikoServer → setupTestStack's top-level * `trustedProxyHops` — symmetric to * RunProdAppOptions.trustedProxyHops. Wins over the deprecated * `auth.trustedProxyHops`, which wins over the `KUMIKO_TRUSTED_PROXY_HOPS` * env var. Dev usually runs unproxied, so this is normally left unset * (default 0). */ readonly trustedProxyHops?: number; /** Links the app's own error reasons to its own docs (`docsUrl` in error responses); framework reasons keep the framework docs link. */ readonly errorDocs?: ErrorDocsConfig; }; export declare function runDevApp(options: RunDevAppOptions): Promise; export declare function mergeConfigResolverDefault(ctx: CreateKumikoServerOptions["extraContext"], registry: Registry, envSource: Record, cipher?: EnvelopeCipher): CreateKumikoServerOptions["extraContext"];