import './assert_dev_env.js';
/**
 * Bootstrapped app server factory for integration tests.
 *
 * Creates a keeper account, API token, and signed session cookie on a
 * database. By default uses a cached in-memory PGlite (shared WASM instance
 * per vitest worker thread via `test_db.ts` module cache); pass `db` to use
 * an existing database (any driver) instead.
 *
 * Also provides `create_test_app` — a combined helper that creates both
 * a `TestAppServer` and a fully assembled Hono app with middleware and routes.
 *
 * @module
 */
import type { Hono } from 'hono';
import type { Uuid } from '@fuzdev/fuz_util/id.js';
import { type Keyring } from '../auth/keyring.js';
import type { Db, DbType } from '../db/db.js';
import type { PasswordHashDeps } from '../auth/password.js';
import { type SessionOptions } from '../auth/session_cookie.js';
import { type MigrationNamespace } from '../db/migrate.js';
import { type AppBackend, type AuditFactory } from '../server/app_backend.js';
import { type AppServerOptions, type AppServerContext, type BootstrapServerOptions, type BootstrapLiveOptions } from '../server/app_server.js';
import type { AppSurface, AppSurfaceSpec } from '../http/surface.js';
import type { RouteSpec } from '../http/route_spec.js';
import type { RpcEndpointsSuiteOption } from './rpc_helpers.js';
/**
 * Fast password stub for tests that don't exercise login/password flows.
 *
 * Hashes are deterministic (`stub_hash_<password>`) and verify correctly,
 * so auth bootstrap and session creation work without Argon2 overhead.
 */
export declare const stub_password_deps: PasswordHashDeps;
/** 64-hex-char test cookie secret — deterministic, never used in production. */
export declare const TEST_COOKIE_SECRET: string;
/**
 * Default password for bootstrapped test accounts. Shared between the
 * in-process keeper bootstrap (`bootstrap_test_keeper`,
 * `create_test_account_with_credentials`, `create_test_app_server`,
 * `TestApp.create_account`) and the cross-process bootstrap
 * (`cross_backend/setup.ts`). The two paths MUST agree — when they
 * diverged during the 3d cross-process lift, ~20 login tests 401'd
 * silently against the cross-process backend because the per-test
 * fixture minted accounts under a different default than the
 * integration suite's hardcoded login bodies expected. Consumers
 * hardcoding the literal string in test bodies should import this
 * constant instead so a future divergence becomes a typecheck miss
 * rather than a runtime password mismatch.
 */
export declare const DEFAULT_TEST_PASSWORD = "test-password-123";
/**
 * Options for `bootstrap_test_keeper` and `create_test_account_with_credentials`.
 *
 * Same shape for both — the data inserted is identical; the only behavioral
 * difference is the lock flip on the keeper path.
 */
export interface CreateTestAccountWithCredentialsOptions {
    db: Db;
    keyring: Keyring;
    session_options: SessionOptions<string>;
    password: PasswordHashDeps;
    username?: string;
    password_value?: string;
    roles?: Array<string>;
}
/** Alias for the keeper-flavored call site. Same shape. */
export type BootstrapTestKeeperOptions = CreateTestAccountWithCredentialsOptions;
/**
 * Create a test account with credentials. Use for additional accounts
 * minted alongside the keeper (e.g. `TestApp.create_account` for
 * cross-account / multi-user tests). Does NOT flip `bootstrap_lock` —
 * non-keeper accounts should not appear to the system as bootstrap
 * having happened.
 *
 * Creates an account with actor, grants roles, creates an API token,
 * creates a session, and signs a session cookie.
 *
 * @mutates the underlying `options.db` — inserts rows into `account`, `actor`,
 *   `role_grant` (one per role), `api_token`, and `auth_session`.
 */
export declare const create_test_account_with_credentials: (options: CreateTestAccountWithCredentialsOptions) => Promise<{
    account: {
        id: Uuid;
        username: string;
    };
    actor: {
        id: Uuid;
    };
    api_token: string;
    session_cookie: string;
}>;
/** Options for `mint_test_session`. */
export interface MintTestSessionOptions {
    db: Db;
    keyring: Keyring;
    session_options: SessionOptions<string>;
    /** Account the minted session belongs to. */
    account_id: string;
    /**
     * Session lifetime offset in seconds applied to `NOW()` for the
     * `auth_session.expires_at` row. A negative value backdates the row so
     * the authoritative DB-row expiry gate (`query_session_get_valid` —
     * `WHERE expires_at > NOW()`) rejects it, while the returned cookie's
     * own signed payload stays valid (future). Resolution therefore passes
     * the cookie-payload check in `parse_session` and is refused at the
     * DB-row gate — the gate the in-process payload-expiry tests never
     * reach and the one that structurally needs a server-side mint.
     */
    expires_in_seconds: number;
}
/**
 * Mint a real `auth_session` row for an existing account and return a
 * validly-signed session cookie value referencing it. Test-only — the
 * forge behind the cross-backend expiry conformance cases (the
 * `expired_session` principal): pass a negative `expires_in_seconds` to
 * produce an *expired server-side session* whose signed cookie envelope is
 * still well-formed. Both the TS `_testing_mint_session` action and the
 * in-process `fixture.mint_expired_session()` seam call this so the write
 * semantics match across transports.
 *
 * @mutates `options.db` — inserts one `auth_session` row.
 */
export declare const mint_test_session: (options: MintTestSessionOptions) => Promise<{
    session_cookie: string;
}>;
/**
 * Bootstrap the test-DB keeper. Direct-query shortcut for the default
 * `create_test_app` path — bootstrap is not what most tests exercise, so
 * we skip the real `bootstrap_account` flow (no audit row, no
 * `on_bootstrap` callback). Tests that need the full success-path flow
 * use `create_test_app_for_bootstrap` instead.
 *
 * Flips `bootstrap_lock.bootstrapped = true` so the post-insert DB state
 * matches a real bootstrap completion — production code can trust the
 * lock as the single signal without a belt-and-suspenders
 * `query_account_has_any` defense.
 *
 * @mutates the underlying `options.db` — inserts the account/actor/roles/
 *   API token/session_cookie rows AND flips `bootstrap_lock.bootstrapped`.
 */
export declare const bootstrap_test_keeper: (options: BootstrapTestKeeperOptions) => Promise<{
    account: {
        id: Uuid;
        username: string;
    };
    actor: {
        id: Uuid;
    };
    api_token: string;
    session_cookie: string;
}>;
/**
 * An `AppBackend` with a bootstrapped account, API token, and session cookie.
 */
export interface TestAppServer extends AppBackend {
    /** The bootstrapped account. */
    account: {
        id: Uuid;
        username: string;
    };
    /** The actor linked to the account. */
    actor: {
        id: Uuid;
    };
    /** Raw API token for Bearer auth. */
    api_token: string;
    /** Signed session cookie value for cookie auth. */
    session_cookie: string;
    /** Keyring used for cookie signing — exposed for forging expired/tampered cookies in tests. */
    keyring: Keyring;
    /** Release test resources (no-op when DB is injected or factory-cached). */
    cleanup: () => Promise<void>;
}
/**
 * Configuration for `create_test_app_server`.
 */
export interface TestAppServerOptions {
    /** Session options — needed for cookie signing. */
    session_options: SessionOptions<string>;
    /** Existing database — skips internal DB creation when provided. Caller owns the DB lifecycle. */
    db?: Db;
    /** Database driver type — only used when `db` is provided. Default: `'pglite-memory'`. */
    db_type?: DbType;
    /**
     * Extra migration namespaces run after the builtin auth namespace in the
     * auto-created in-memory PGlite, mirroring `create_app_backend`'s
     * `migration_namespaces`. For suites whose backend needs tables beyond
     * auth — the cell parity suite passes `[CELL_MIGRATION_NS]`. The harness
     * builds + caches a fresh-per-test factory migrating
     * `[auth_migration_ns, ...migration_namespaces]`; the reset-on-`create`
     * gives the same fresh-db isolation as the auth-only default. Mutually
     * exclusive with `db` (which assumes the caller already migrated).
     */
    migration_namespaces?: ReadonlyArray<MigrationNamespace>;
    /** Password implementation. Default: `stub_password_deps`. Pass `argon2_password_deps` for tests that exercise login. */
    password?: PasswordHashDeps;
    /** Username for the bootstrapped account. Default: `'keeper'`. */
    username?: string;
    /** Password for the bootstrapped account. Default: `DEFAULT_TEST_PASSWORD`. */
    password_value?: string;
    /** Roles to grant. Default: `[ROLE_KEEPER]`. */
    roles?: Array<string>;
    /**
     * Build the bound `AuditEmitter` used by the test backend. Defaults to
     * `default_audit_factory` (a no-listener `create_audit_emitter` over
     * the test backend's `{db, log}`). Pass a custom factory when a test
     * needs:
     * - to capture audit events (compose `on_audit_event` inside the body)
     * - to register consumer event-type schemas (pass `audit_log_config`)
     * - to instrument `emit` ordering (`create_emit_ordering_audit_factory`)
     * - to wrap or replace the emitter for some other reason
     *
     * Matches the production shape — `create_app_backend` requires an
     * `audit_factory` and `create_test_app_server` mirrors that contract
     * end-to-end. The earlier `on_audit_event` / `audit_log_config` sugar
     * fields were removed alongside the `CreateAppBackendOptions` rename.
     */
    audit_factory?: AuditFactory;
}
export declare const create_test_app_server: (options: TestAppServerOptions) => Promise<TestAppServer>;
/**
 * Configuration for `create_test_app`.
 */
export interface CreateTestAppOptions extends TestAppServerOptions {
    /** Route spec factory — called with the assembled `AppServerContext`. */
    create_route_specs: (context: AppServerContext) => Array<RouteSpec>;
    /**
     * RPC endpoints mounted by `create_app_server` — eager array or
     * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` factory. Single
     * source of truth; the equivalent slot under `app_options` is `Omit`'d
     * so setup-time path lookup and runtime dispatch read from one place.
     * Symmetric with the suite-level `rpc_endpoints` option on
     * `describe_standard_admin_integration_tests` etc.
     */
    rpc_endpoints?: RpcEndpointsSuiteOption;
    /**
     * Bootstrap config — symmetric with `AppServerOptions.bootstrap`. Same
     * single-source-of-truth precedent as `rpc_endpoints`: setup-time surface
     * generation and runtime dispatch both read this slot, so the equivalent
     * field under `app_options` is `Omit`'d. Discriminated union over
     * `{mode: 'disabled' | 'surface_only' | 'live'}`. Omit (or pass
     * `{mode: 'disabled'}`) for the default — no bootstrap route mounted.
     *
     * For tests that exercise the bootstrap success path against a real
     * token + empty DB, use `create_test_app_for_bootstrap` instead — it
     * skips the keeper pre-creation that blocks the success branch.
     */
    bootstrap?: BootstrapServerOptions;
    /**
     * Optional overrides for `AppServerOptions`. Excludes fields
     * `create_test_app` manages directly: `backend`, `session_options`,
     * `create_route_specs`, `rpc_endpoints`, `bootstrap` (top-level slots
     * above).
     */
    app_options?: SuiteAppOptions;
}
/**
 * `app_options` shape accepted by `create_test_app` and the DB-backed suite
 * helpers. Excludes fields the helpers manage directly — `backend` /
 * `session_options` / `create_route_specs` are constructed by the helper
 * itself; `rpc_endpoints` and `bootstrap` live on top-level options so
 * setup-time surface lookup and runtime dispatch read from one source of
 * truth.
 */
export type SuiteAppOptions = Partial<Omit<AppServerOptions, 'backend' | 'session_options' | 'create_route_specs' | 'rpc_endpoints' | 'bootstrap'>>;
/**
 * A bootstrapped test account with credentials.
 */
export interface TestAccount {
    account: {
        id: Uuid;
        username: string;
    };
    actor: {
        id: Uuid;
    };
    /** Signed session cookie value. */
    session_cookie: string;
    /** Raw API token for Bearer auth. */
    api_token: string;
    /** Build request headers with this account's session cookie. */
    create_session_headers: (extra?: Record<string, string>) => Record<string, string>;
    /** Build request headers with this account's Bearer token. */
    create_bearer_headers: (extra?: Record<string, string>) => Record<string, string>;
}
/**
 * A fully assembled test app — Hono app + backend + helpers.
 */
export interface TestApp {
    app: Hono;
    backend: TestAppServer;
    surface_spec: AppSurfaceSpec;
    surface: AppSurface;
    route_specs: Array<RouteSpec>;
    /** Build request headers with the bootstrapped session cookie. */
    create_session_headers: (extra?: Record<string, string>) => Record<string, string>;
    /** Build request headers with the bootstrapped Bearer token. */
    create_bearer_headers: (extra?: Record<string, string>) => Record<string, string>;
    /** Build request headers with the daemon token (keeper auth). */
    create_daemon_token_headers: (extra?: Record<string, string>) => Record<string, string>;
    /** Create an additional account with credentials. */
    create_account: (options?: {
        username?: string;
        password_value?: string;
        roles?: Array<string>;
    }) => Promise<TestAccount>;
    /** Cleanup resources (delegates to TestAppServer.cleanup). */
    cleanup: () => Promise<void>;
}
/**
 * Create a fully assembled test app with a Hono server, middleware, and routes.
 *
 * Combines `create_test_app_server` + `create_app_server` into a single call.
 * Disables rate limiters and logging by default (test-friendly).
 *
 * A fresh Hono app is created each call — middleware closures bind to the
 * server's deps (db, keyring), so reuse across servers is unsafe.
 * The expensive resource (PGlite WASM) is cached separately in `test_db.ts`.
 *
 * @param options - test app configuration
 * @returns a `TestApp` ready for HTTP testing
 */
export declare const create_test_app: (options: CreateTestAppOptions) => Promise<TestApp>;
/**
 * Configuration for `create_test_app_for_bootstrap`. Like
 * `CreateTestAppOptions` but the keeper-related fields drop (no
 * pre-bootstrap keeper) and `bootstrap` is required + narrowed to
 * `live` mode (the helper exists specifically to drive the success
 * path).
 */
export interface CreateTestAppForBootstrapOptions {
    session_options: SessionOptions<string>;
    create_route_specs: (context: AppServerContext) => Array<RouteSpec>;
    rpc_endpoints?: RpcEndpointsSuiteOption;
    app_options?: SuiteAppOptions;
    /** Live bootstrap config — the test drives `POST /bootstrap` against this. */
    bootstrap: BootstrapLiveOptions;
    /**
     * Token contents the stub fs returns when reading `bootstrap.token_path`.
     * The test posts a body containing this same value as `token` to satisfy
     * the timing-safe equality check inside `bootstrap_account`.
     */
    bootstrap_token: string;
    db?: Db;
    db_type?: DbType;
    password?: PasswordHashDeps;
    audit_factory?: AuditFactory;
}
/**
 * A fully assembled test app in the pre-bootstrap state — empty DB,
 * `bootstrap_lock.bootstrapped = false`, no keeper account. Test drives
 * `POST /bootstrap` itself.
 */
export interface TestAppForBootstrap {
    app: Hono;
    backend: AppBackend;
    surface_spec: AppSurfaceSpec;
    surface: AppSurface;
    route_specs: Array<RouteSpec>;
    /** Build host/origin request headers for the anonymous bootstrap POST. */
    create_request_headers: (extra?: Record<string, string>) => Record<string, string>;
    /** Release test resources (no-op when DB is injected or factory-cached). */
    cleanup: () => Promise<void>;
}
/**
 * Create a test app in the pre-bootstrap state for exercising the
 * bootstrap success path end-to-end.
 *
 * Skips the keeper pre-creation `create_test_app` does by default —
 * `bootstrap_lock.bootstrapped` stays at `false` and the DB has no
 * accounts. The fs stubs return `options.bootstrap_token` when the
 * bootstrap handler reads `bootstrap.token_path`, so a `POST /bootstrap`
 * with `{token: bootstrap_token, username, password}` reaches the
 * success branch.
 *
 * Pair with `describe_bootstrap_success_tests` for the consumer-runnable
 * suite that drives the full happy path + adjacent assertions on
 * observable state (account exists, audit row emitted, on_bootstrap
 * callback fired).
 *
 * @param options - bootstrap config + factory inputs
 * @returns a `TestAppForBootstrap` ready for the test to drive bootstrap
 */
export declare const create_test_app_for_bootstrap: (options: CreateTestAppForBootstrapOptions) => Promise<TestAppForBootstrap>;
//# sourceMappingURL=app_server.d.ts.map