tempest-express-sdk 0.24.0 → 0.26.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.
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  export { z } from 'zod';
3
3
  import * as tempest_db_js from 'tempest-db-js';
4
- import { Model, ModelClass, BaseRepository, WhereInput, InferModel, InferInsert, PaginationFilter as PaginationFilter$1, PaginationResult, AsyncDriver, Column, AsyncSession, AsyncEngine } from 'tempest-db-js';
4
+ import { Model, ModelClass, BaseRepository, WhereInput, InferModel, InferInsert, PaginationFilter as PaginationFilter$1, PaginationResult, AsyncDriver, AsyncSession, Column, AsyncEngine } from 'tempest-db-js';
5
5
  export { AsyncDriver, AsyncEngine, AsyncResult, AsyncSession, BaseRepository, BelongsTo, ColType, Column, ColumnFlags, CompiledQuery, CondNode, Condition, DeleteBuilder, DeleteNode, Dialect, EngineOptions, Executable, HasMany, InferInsert, InferModel, InsertBuilder, InsertNode, Model, ModelClass, NoResultError, NodeSqliteDriver, Operator, OrderTerm, PaginationResult, ParsedDatabaseUrl, PostgresDialect, QueryNode, RecordNotFound, Relation, RelationValue, PaginationFilter as RepositoryPaginationFilter, Returning, RowOf, SelectBuilder, SelectNode, SortDirection, SqliteDialect, SyncEngine, SyncSession, UpdateBuilder, UpdateNode, WhereArg, WhereInput, WithRelations, and, belongsTo, column, columnsOf, createEngine, createSyncEngine, del, detectDialect, getDialect, hasMany, insert, join, loadRelations, not, or, parseDatabaseUrl, select, sql, update } from 'tempest-db-js';
6
6
  import { Request, Response as Response$1, RequestHandler, Router, ErrorRequestHandler, Express } from 'express';
7
7
  import * as ws from 'ws';
@@ -3493,88 +3493,352 @@ declare class MessagingHub {
3493
3493
  }
3494
3494
 
3495
3495
  /**
3496
- * Column introspection for the admin panel, mirroring `admin.forms`' widget
3497
- * derivation.
3496
+ * Business-metric cards for the admin dashboard, mirroring `admin.dashboard`.
3498
3497
  *
3499
- * `tempest-db-js` keeps rich runtime metadata on every column the canonical
3500
- * type kind, enum members, `varchar` length, the not-null/default/primary-key
3501
- * flags and the foreign-key reference so the admin derives its form widgets
3502
- * and list filters from the model itself instead of asking the project to
3503
- * restate them. Kept separate from the router so the (fiddly) type handling is
3504
- * unit-testable in isolation.
3498
+ * Distinct from the system panel (CPU/memory): these are value / trend /
3499
+ * partition cards computed from the application's own data — "orders today",
3500
+ * "revenue vs last week", "users by plan". Register them on the
3501
+ * {@link AdminSite} and they render above the model cards.
3502
+ *
3503
+ * ```ts
3504
+ * const site = new AdminSite({
3505
+ * title: "Shop",
3506
+ * dashboardCards: [
3507
+ * metricCard("Orders today", async (session) => ({
3508
+ * kind: "value",
3509
+ * value: await new BaseRepository(OrderModel, session).count(),
3510
+ * unit: "orders",
3511
+ * })),
3512
+ * ],
3513
+ * });
3514
+ * ```
3505
3515
  */
3506
3516
 
3507
- /** The set of form controls the admin knows how to render. */
3508
- type AdminWidget = "text" | "textarea" | "number" | "checkbox" | "datetime" | "date" | "time" | "select" | "json";
3509
- /** A `(value, label)` pair for a `select` widget. */
3510
- interface AdminSelectOption {
3511
- value: string;
3512
- label: string;
3517
+ /** A single headline number. */
3518
+ interface MetricValue {
3519
+ kind: "value";
3520
+ /** The value to show — a number, or a preformatted string. */
3521
+ value: number | string;
3522
+ /** Optional unit suffix (`"orders"`, `"BRL"`). */
3523
+ unit?: string;
3524
+ }
3525
+ /** A number compared against a previous period. */
3526
+ interface MetricTrend {
3527
+ kind: "trend";
3528
+ /** The current value. */
3529
+ value: number;
3530
+ /** The value for the comparison period. */
3531
+ previous: number;
3532
+ /** Optional unit suffix. */
3533
+ unit?: string;
3534
+ }
3535
+ /** A breakdown of a total across labeled segments. */
3536
+ interface MetricPartition {
3537
+ kind: "partition";
3538
+ /** `(label, value)` pairs. */
3539
+ segments: {
3540
+ label: string;
3541
+ value: number;
3542
+ }[];
3513
3543
  }
3514
- /** The widget a column maps to, plus the attributes that render it. */
3515
- interface WidgetSpec {
3516
- /** The control to render. */
3517
- widget: AdminWidget;
3518
- /** `step` attribute for `number` widgets, or `null`. */
3519
- step: string | null;
3520
- /** Options for `select` widgets (empty otherwise). */
3521
- options: AdminSelectOption[];
3544
+ /** What a card's `compute` returns. */
3545
+ type CardData = MetricValue | MetricTrend | MetricPartition;
3546
+ /** Async function computing one card from a DB session. */
3547
+ type CardCompute = (session: AsyncSession) => Promise<CardData>;
3548
+ /** A dashboard business-metric card. */
3549
+ interface MetricCard {
3550
+ /** The card heading. */
3551
+ label: string;
3552
+ /** Async function returning the card data. */
3553
+ compute: CardCompute;
3554
+ /** Optional sub-label shown under the value. */
3555
+ helpText?: string;
3522
3556
  }
3523
- /** How a column is surfaced in the list view's filter bar. */
3524
- type AdminFilterKind = "select" | "daterange" | "text";
3525
3557
  /**
3526
- * Humanize a column key into a form label (`lastLoginAt` → `Last Login At`).
3558
+ * Describe a dashboard card.
3527
3559
  *
3528
- * @param name - The column key.
3529
- * @returns A title-cased label.
3560
+ * @param label - The card heading.
3561
+ * @param compute - Async function returning the card data.
3562
+ * @param helpText - Optional sub-label.
3563
+ * @returns The card descriptor to pass to `new AdminSite({ dashboardCards })`.
3530
3564
  */
3531
- declare function humanizeField(name: string): string;
3565
+ declare function metricCard(label: string, compute: CardCompute, helpText?: string): MetricCard;
3532
3566
  /**
3533
- * Return every column of a model, keyed by field name in declaration order.
3567
+ * Return the percentage change a trend represents.
3534
3568
  *
3535
- * @param model - The model class.
3536
- * @returns The column map (do not mutate).
3569
+ * @param trend - The computed trend.
3570
+ * @returns `delta / previous * 100`, or `null` when there is no baseline to
3571
+ * divide by — a percentage against zero is undefined, not infinite.
3537
3572
  */
3538
- declare function adminColumns(model: ModelClass): Record<string, Column<unknown>>;
3573
+ declare function trendPercent(trend: MetricTrend): number | null;
3539
3574
  /**
3540
- * Map a column to the widget that edits it.
3575
+ * Return which way a trend moved.
3541
3576
  *
3542
- * `json` is matched before anything else because a JSON column carries no
3543
- * useful scalar type, and `enum` is matched before the string kinds so its
3544
- * members become a dropdown rather than a free-text input.
3577
+ * @param trend - The computed trend.
3578
+ * @returns `"up"`, `"down"` or `"flat"`.
3579
+ */
3580
+ declare function trendDirection(trend: MetricTrend): "up" | "down" | "flat";
3581
+ /**
3582
+ * Return the sum of a partition's segment values.
3545
3583
  *
3546
- * @param column - The column to inspect.
3547
- * @returns The widget, its `number` step (or `null`) and its `select` options.
3584
+ * @param partition - The computed partition.
3585
+ * @returns The total across segments.
3548
3586
  */
3549
- declare function widgetForColumn(column: Column<unknown>): WidgetSpec;
3587
+ declare function partitionTotal(partition: MetricPartition): number;
3588
+
3550
3589
  /**
3551
- * Whether a column may be left blank on submit it is nullable, carries a
3552
- * default, or is the primary key the database fills in.
3590
+ * Named, saved list-view presetsLaravel Nova's "lenses", mirroring
3591
+ * `admin.config.Lens`.
3553
3592
  *
3554
- * @param column - The column to inspect.
3555
- * @returns `true` when the field is optional.
3593
+ * A lens bundles a set of filters and an optional ordering under a label. On
3594
+ * the list view lenses render as tabs; clicking one applies its filters (ANDed
3595
+ * with whatever the operator typed) and its ordering. A "support triage" lens
3596
+ * pinning `{ status: "open", priority: { gte: 3 } }` sorted oldest-first gets
3597
+ * an operator to the working set in one click instead of re-entering filters
3598
+ * every morning.
3556
3599
  */
3557
- declare function isColumnOptional(column: Column<unknown>): boolean;
3600
+
3601
+ /** Options accepted by {@link adminLens}. */
3602
+ interface AdminLensOptions {
3603
+ /** Lens identifier; its slug is the `?lens=` value. */
3604
+ name: string;
3605
+ /** Conditions merged into the query, in repository `where` shape. */
3606
+ filters?: WhereInput<Record<string, unknown>>;
3607
+ /** Ordering column; prefix with `-` for descending. */
3608
+ orderBy?: string;
3609
+ /** Tab label. Defaults to `name`. */
3610
+ label?: string;
3611
+ }
3612
+ /** A registered lens. */
3613
+ interface AdminLens {
3614
+ /** Lens identifier. */
3615
+ name: string;
3616
+ /** URL slug — the `?lens=` value. */
3617
+ slug: string;
3618
+ /** Tab label. */
3619
+ label: string;
3620
+ /** Conditions merged into the query. */
3621
+ filters: WhereInput<Record<string, unknown>>;
3622
+ /** Ordering column, or `null`. `-column` means descending. */
3623
+ orderBy: string | null;
3624
+ }
3558
3625
  /**
3559
- * Map a column to the filter control the list view shows for it.
3626
+ * Describe a saved list-view preset.
3560
3627
  *
3561
- * Booleans and enums become dropdowns, date-like columns become a from/to pair
3562
- * of date inputs, and anything else falls back to an equality text input.
3628
+ * @param options - Name, filters, ordering and label.
3629
+ * @returns The lens descriptor to pass to `AdminModel({ lenses: [...] })`.
3630
+ */
3631
+ declare function adminLens(options: AdminLensOptions): AdminLens;
3632
+
3633
+ /**
3634
+ * Signed-cookie sessions for the admin panel, mirroring `admin.session`.
3563
3635
  *
3564
- * @param column - The column to inspect.
3565
- * @returns The filter kind and, for `select`, its options.
3636
+ * The panel's session is **stateless**: the principal id, display name, CSRF
3637
+ * token and expiry travel in the cookie itself, signed with HMAC-SHA256 over
3638
+ * the caller's secret. Nothing is kept server-side, so the panel survives a
3639
+ * restart and works across replicas without a shared store — the property that
3640
+ * matters most for an operator tool that is used in bursts and left open.
3641
+ *
3642
+ * The CSRF token lives inside the session payload, so every write form can
3643
+ * carry it and the server compares it against the cookie it already trusts.
3566
3644
  */
3567
- declare function filterForColumn(column: Column<unknown>): {
3568
- kind: AdminFilterKind;
3569
- options: AdminSelectOption[];
3570
- };
3645
+
3646
+ /** The payload carried by the admin session cookie. */
3647
+ interface AdminSession {
3648
+ /** Stable id of the authenticated principal. */
3649
+ subject: string;
3650
+ /** Display name shown in the header. */
3651
+ displayName: string;
3652
+ /** Token every write form echoes back for CSRF validation. */
3653
+ csrfToken: string;
3654
+ /** Expiry, in epoch seconds. */
3655
+ expiresAt: number;
3656
+ /**
3657
+ * `true` once the second factor was accepted. Sessions issued for a
3658
+ * principal without MFA are complete from the start.
3659
+ */
3660
+ mfaPassed: boolean;
3661
+ }
3662
+ /** Options for {@link AdminSessionStore}. */
3663
+ interface AdminSessionStoreOptions {
3664
+ /** HMAC key signing the cookie. At least 32 characters. */
3665
+ secret: string;
3666
+ /** Cookie name. Default `tempest_admin_session`. */
3667
+ cookieName?: string;
3668
+ /** Session lifetime in seconds. Default `28800` (8 hours). */
3669
+ maxAgeSeconds?: number;
3670
+ /** Send the cookie with `Secure` (HTTPS only). Default `true`. */
3671
+ cookieSecure?: boolean;
3672
+ /** Cookie `Path`. Default `/`. */
3673
+ cookiePath?: string;
3674
+ }
3571
3675
  /**
3572
- * Whether a column holds free text a `LIKE '%…%'` search can match.
3676
+ * Issues, verifies and clears the admin session cookie.
3573
3677
  *
3574
- * @param column - The column to inspect.
3575
- * @returns `true` for `varchar` / `text` / `char` columns.
3678
+ * The cookie value is `<base64url payload>.<base64url signature>`; a payload
3679
+ * whose signature does not verify, or whose expiry has passed, resolves to
3680
+ * `null` — an operator with a tampered or stale cookie is simply logged out.
3576
3681
  */
3577
- declare function isSearchableColumn(column: Column<unknown>): boolean;
3682
+ declare class AdminSessionStore {
3683
+ private readonly secret;
3684
+ private readonly cookieName;
3685
+ private readonly maxAgeSeconds;
3686
+ private readonly cookieSecure;
3687
+ private readonly cookiePath;
3688
+ /**
3689
+ * Build the store.
3690
+ *
3691
+ * @param options - Secret, cookie name, lifetime and cookie flags.
3692
+ * @throws Error When the secret is shorter than 32 characters.
3693
+ */
3694
+ constructor(options: AdminSessionStoreOptions);
3695
+ /**
3696
+ * Sign a payload.
3697
+ *
3698
+ * @param payload - The base64url payload to sign.
3699
+ * @returns The base64url signature.
3700
+ */
3701
+ private sign;
3702
+ /**
3703
+ * Mint a fresh session for an authenticated principal.
3704
+ *
3705
+ * @param subject - The principal id.
3706
+ * @param displayName - The name shown in the header.
3707
+ * @param mfaPassed - Whether the second factor is already satisfied.
3708
+ * @returns The new session payload (not yet written to a response).
3709
+ */
3710
+ issue(subject: string, displayName: string, mfaPassed?: boolean): AdminSession;
3711
+ /**
3712
+ * Read and verify the session carried by a request.
3713
+ *
3714
+ * @param req - The inbound request.
3715
+ * @returns The session, or `null` when absent, tampered with or expired.
3716
+ */
3717
+ load(req: Request): AdminSession | null;
3718
+ /**
3719
+ * Write a session to the response as a signed cookie.
3720
+ *
3721
+ * @param res - The outbound response.
3722
+ * @param session - The session to persist.
3723
+ */
3724
+ save(res: Response$1, session: AdminSession): void;
3725
+ /**
3726
+ * Drop the session cookie.
3727
+ *
3728
+ * @param res - The outbound response.
3729
+ */
3730
+ clear(res: Response$1): void;
3731
+ /**
3732
+ * Render a `Set-Cookie` value with the configured flags.
3733
+ *
3734
+ * @param value - The cookie value.
3735
+ * @param maxAge - Lifetime in seconds (`0` expires it immediately).
3736
+ * @returns The header value.
3737
+ */
3738
+ private cookie;
3739
+ }
3740
+ /**
3741
+ * Compare a submitted CSRF token against the session's, in constant time.
3742
+ *
3743
+ * @param session - The active session.
3744
+ * @param submitted - The `csrf_token` field from the form body.
3745
+ * @returns `true` when the tokens match.
3746
+ */
3747
+ declare function csrfTokenMatches(session: AdminSession, submitted: unknown): boolean;
3748
+
3749
+ /**
3750
+ * Custom admin actions — operator-defined bulk operations, mirroring
3751
+ * `admin.actions`.
3752
+ *
3753
+ * The panel ships three built-in bulk operations (activate / deactivate /
3754
+ * delete). Anything domain-specific — "send welcome email", "mark as shipped",
3755
+ * "recalculate totals" — is a *custom action*: a handler registered on an
3756
+ * {@link AdminModel} through `actions`, which shows up in the list view's
3757
+ * bulk-action dropdown and runs against the checked rows.
3758
+ *
3759
+ * ```ts
3760
+ * const sendWelcome = adminAction(
3761
+ * { label: "Send welcome email" },
3762
+ * async ({ ids, repository }) => {
3763
+ * const users = await repository.list({ id: { in: ids } });
3764
+ * for (const user of users) await mailer.sendWelcome(user.email);
3765
+ * return { message: `Sent ${users.length} welcome emails.` };
3766
+ * },
3767
+ * );
3768
+ *
3769
+ * site.register(new AdminModel({ model: UserModel, actions: [sendWelcome] }));
3770
+ * ```
3771
+ *
3772
+ * The Python SDK attaches this metadata with an `@admin_action` decorator.
3773
+ * Here {@link adminAction} returns the descriptor instead: the handler stays a
3774
+ * plain function you can call and unit-test directly (`action.handler(ctx)`),
3775
+ * and there is no decorator syntax to enable in a consumer's build.
3776
+ */
3777
+
3778
+ /** Banner style a custom action's message is flashed with. */
3779
+ type AdminActionCategory = "success" | "error" | "warning";
3780
+ /** Everything a custom action handler needs to do its work. */
3781
+ interface AdminActionContext<C extends ModelClass = ModelClass> {
3782
+ /** Identity values of the rows the operator checked. */
3783
+ ids: string[];
3784
+ /** Repository for this admin's model, bound to the request's DB session. */
3785
+ repository: BaseRepository<C>;
3786
+ /** The request's DB session, for work beyond the repository. */
3787
+ dbSession: AsyncSession;
3788
+ /** The inbound request. */
3789
+ request: Request;
3790
+ /** The authenticated admin session. */
3791
+ session: AdminSession;
3792
+ /** The resolved admin principal that triggered the action. */
3793
+ principal: unknown;
3794
+ }
3795
+ /** The outcome of a custom action, flashed on the list view. */
3796
+ interface AdminActionResult {
3797
+ /** Human-readable result shown to the operator. */
3798
+ message: string;
3799
+ /** Banner style. Default `"success"`. */
3800
+ category?: AdminActionCategory;
3801
+ }
3802
+ /** The function a custom action runs. Return `null` to flash nothing. */
3803
+ type AdminActionHandler<C extends ModelClass = ModelClass> = (context: AdminActionContext<C>) => Promise<AdminActionResult | null>;
3804
+ /** A registered custom action: metadata plus handler. */
3805
+ interface AdminAction<C extends ModelClass = ModelClass> {
3806
+ /** Stable identifier (the submitted form value); unique per model. */
3807
+ name: string;
3808
+ /** Text shown in the bulk-action dropdown. */
3809
+ label: string;
3810
+ /** The handler to run against the checked rows. */
3811
+ handler: AdminActionHandler<C>;
3812
+ /** Whether the UI marks this as destructive (a stronger confirm prompt). */
3813
+ dangerous: boolean;
3814
+ }
3815
+ /** Metadata accepted by {@link adminAction}. */
3816
+ interface AdminActionOptions {
3817
+ /** Dropdown label shown to the operator. */
3818
+ label: string;
3819
+ /** Stable identifier (the submitted form value). Defaults to a slug of `label`. */
3820
+ name?: string;
3821
+ /** Flag a destructive action, for a stronger confirm prompt. */
3822
+ dangerous?: boolean;
3823
+ }
3824
+ /**
3825
+ * Describe a custom bulk action.
3826
+ *
3827
+ * @param options - Label, optional stable name and the destructive flag.
3828
+ * @param handler - The async function run against the checked rows.
3829
+ * @returns The action descriptor to pass to `AdminModel({ actions: [...] })`.
3830
+ * @throws Error When the resolved name is empty.
3831
+ */
3832
+ declare function adminAction<C extends ModelClass = ModelClass>(options: AdminActionOptions, handler: AdminActionHandler<C>): AdminAction<C>;
3833
+ /** A bulk-action option rendered in the list view's dropdown. */
3834
+ interface BulkActionOption {
3835
+ /** Submitted form value. Custom actions are namespaced `custom:<name>`. */
3836
+ value: string;
3837
+ /** Dropdown label. */
3838
+ label: string;
3839
+ /** Whether the action is destructive. */
3840
+ dangerous: boolean;
3841
+ }
3578
3842
 
3579
3843
  /**
3580
3844
  * Declarative admin configuration for one model, mirroring `admin.config`.
@@ -3616,6 +3880,22 @@ interface AdminModelOptions<C extends ModelClass> {
3616
3880
  canEdit?: boolean;
3617
3881
  /** Whether the delete action is exposed. Default `true`. */
3618
3882
  canDelete?: boolean;
3883
+ /**
3884
+ * Custom bulk actions, built with `adminAction`. Each one joins the list
3885
+ * view's action dropdown alongside the built-in activate / deactivate /
3886
+ * delete and runs against the checked rows.
3887
+ */
3888
+ actions?: readonly AdminAction<C>[];
3889
+ /**
3890
+ * Audit-log model backing the detail view's change timeline. Pair it with a
3891
+ * repository that actually writes the rows — the panel only reads them.
3892
+ */
3893
+ auditModel?: ModelClass;
3894
+ /**
3895
+ * Saved list-view presets rendered as tabs above the table, each applying
3896
+ * its filters and ordering through `?lens=<slug>`.
3897
+ */
3898
+ lenses?: readonly AdminLens[];
3619
3899
  }
3620
3900
  /**
3621
3901
  * The admin configuration for one model.
@@ -3653,6 +3933,11 @@ declare class AdminModel<C extends ModelClass = ModelClass> {
3653
3933
  readonly canEdit: boolean;
3654
3934
  /** Whether the delete action is exposed. */
3655
3935
  readonly canDelete: boolean;
3936
+ /** Audit-log model backing the detail timeline, or `null`. */
3937
+ readonly auditModel: ModelClass | null;
3938
+ /** Saved list-view presets, in declaration order. */
3939
+ readonly lenses: AdminLens[];
3940
+ private readonly actions;
3656
3941
  private readonly slugOverride;
3657
3942
  private readonly listDisplayOverride;
3658
3943
  private readonly verboseNameOverride;
@@ -3695,6 +3980,20 @@ declare class AdminModel<C extends ModelClass = ModelClass> {
3695
3980
  * @returns The configured `listDisplay`, or every column but the password hash.
3696
3981
  */
3697
3982
  listDisplayNames(): string[];
3983
+ /**
3984
+ * Look a lens up by its slug.
3985
+ *
3986
+ * @param slug - The `?lens=` value.
3987
+ * @returns The lens, or `null` when nothing matches.
3988
+ */
3989
+ getLens(slug: string): AdminLens | null;
3990
+ /**
3991
+ * Return the audit/timestamp columns the model actually declares.
3992
+ *
3993
+ * @returns The subset of `createdAt` / `updatedAt` / `createdBy` /
3994
+ * `updatedBy` present on the model, in that order.
3995
+ */
3996
+ auditFieldNames(): string[];
3698
3997
  /**
3699
3998
  * Return the columns the detail view renders.
3700
3999
  *
@@ -3703,7 +4002,11 @@ declare class AdminModel<C extends ModelClass = ModelClass> {
3703
4002
  * where an operator goes to see the whole record, so trimming it there would
3704
4003
  * hide data with nowhere else to read it.
3705
4004
  *
3706
- * @returns Every column but the password hash, in declaration order.
4005
+ * The audit/timestamp columns are held back too — they render in the detail
4006
+ * view's own audit panel, next to the change history, rather than scattered
4007
+ * among the domain fields.
4008
+ *
4009
+ * @returns Every domain column, in declaration order.
3707
4010
  */
3708
4011
  detailFieldNames(): string[];
3709
4012
  /**
@@ -3716,6 +4019,21 @@ declare class AdminModel<C extends ModelClass = ModelClass> {
3716
4019
  * @returns The editable column keys, in declaration order.
3717
4020
  */
3718
4021
  editableFieldNames(): string[];
4022
+ /**
4023
+ * Return the registered custom actions, in declaration order.
4024
+ *
4025
+ * @returns The actions passed via `actions` (empty when none). The model
4026
+ * type is erased here, the way {@link AdminSite} erases it when it stores a
4027
+ * configuration — a registry keyed by slug cannot stay generic.
4028
+ */
4029
+ customActions(): AdminAction[];
4030
+ /**
4031
+ * Look a custom action up by name.
4032
+ *
4033
+ * @param name - The action identifier (its submitted form value).
4034
+ * @returns The action, or `null` when nothing matches.
4035
+ */
4036
+ getAction(name: string): AdminAction | null;
3719
4037
  /**
3720
4038
  * Build a repository for this model bound to a session.
3721
4039
  *
@@ -3727,6 +4045,138 @@ declare class AdminModel<C extends ModelClass = ModelClass> {
3727
4045
  /** The row type a configured {@link AdminModel} reads and writes. */
3728
4046
  type AdminRow<A> = A extends AdminModel<infer C> ? InferModel<C> : never;
3729
4047
 
4048
+ /**
4049
+ * Granular per-model, per-action access control, mirroring
4050
+ * `admin.permissions`.
4051
+ *
4052
+ * Out of the box every operator who can sign in (`isAdmin`) can do everything
4053
+ * the {@link AdminModel} flags allow. To narrow a principal to a subset of
4054
+ * models or actions — a "support" role that may view orders but never delete
4055
+ * them, an "editor" who may touch content models only — hand an
4056
+ * {@link AdminAccessPolicy} to `makeAdminRouter`.
4057
+ *
4058
+ * ```ts
4059
+ * const policy: AdminAccessPolicy = (user, admin, action) => {
4060
+ * if (user.role === "superadmin") return true;
4061
+ * if (user.role === "support") return action === AdminPermission.VIEW;
4062
+ * return false;
4063
+ * };
4064
+ *
4065
+ * makeAdminRouter(site, { ..., accessPolicy: policy });
4066
+ * ```
4067
+ *
4068
+ * The policy **composes with** the `canCreate` / `canEdit` / `canDelete` flags
4069
+ * rather than replacing them: both have to allow an action. A denied `VIEW`
4070
+ * also hides the model from the dashboard and the sidebar, so an operator is
4071
+ * never shown a door that will answer `403`.
4072
+ */
4073
+
4074
+ /** An admin action gated by an {@link AdminAccessPolicy}. */
4075
+ declare const AdminPermission: {
4076
+ readonly VIEW: "view";
4077
+ readonly CREATE: "create";
4078
+ readonly EDIT: "edit";
4079
+ readonly DELETE: "delete";
4080
+ };
4081
+ /** An {@link AdminPermission} value. */
4082
+ type AdminPermission = (typeof AdminPermission)[keyof typeof AdminPermission];
4083
+ /**
4084
+ * Decides whether `principal` may perform `action` on the model behind
4085
+ * `admin`. Sync or async; return truthy to allow.
4086
+ */
4087
+ type AdminAccessPolicy = (principal: unknown, admin: AdminModel, action: AdminPermission) => boolean | Promise<boolean>;
4088
+
4089
+ /**
4090
+ * Column introspection for the admin panel, mirroring `admin.forms`' widget
4091
+ * derivation.
4092
+ *
4093
+ * `tempest-db-js` keeps rich runtime metadata on every column — the canonical
4094
+ * type kind, enum members, `varchar` length, the not-null/default/primary-key
4095
+ * flags and the foreign-key reference — so the admin derives its form widgets
4096
+ * and list filters from the model itself instead of asking the project to
4097
+ * restate them. Kept separate from the router so the (fiddly) type handling is
4098
+ * unit-testable in isolation.
4099
+ */
4100
+
4101
+ /** The set of form controls the admin knows how to render. */
4102
+ type AdminWidget = "text" | "textarea" | "number" | "checkbox" | "datetime" | "date" | "time" | "select" | "json";
4103
+ /** A `(value, label)` pair for a `select` widget. */
4104
+ interface AdminSelectOption {
4105
+ value: string;
4106
+ label: string;
4107
+ }
4108
+ /** The widget a column maps to, plus the attributes that render it. */
4109
+ interface WidgetSpec {
4110
+ /** The control to render. */
4111
+ widget: AdminWidget;
4112
+ /** `step` attribute for `number` widgets, or `null`. */
4113
+ step: string | null;
4114
+ /** Options for `select` widgets (empty otherwise). */
4115
+ options: AdminSelectOption[];
4116
+ }
4117
+ /** How a column is surfaced in the list view's filter bar. */
4118
+ type AdminFilterKind = "select" | "daterange" | "text";
4119
+ /**
4120
+ * Humanize a column key into a form label (`lastLoginAt` → `Last Login At`).
4121
+ *
4122
+ * @param name - The column key.
4123
+ * @returns A title-cased label.
4124
+ */
4125
+ declare function humanizeField(name: string): string;
4126
+ /**
4127
+ * Return every column of a model, keyed by field name in declaration order.
4128
+ *
4129
+ * @param model - The model class.
4130
+ * @returns The column map (do not mutate).
4131
+ */
4132
+ declare function adminColumns(model: ModelClass): Record<string, Column<unknown>>;
4133
+ /**
4134
+ * Map a column to the widget that edits it.
4135
+ *
4136
+ * `json` is matched before anything else because a JSON column carries no
4137
+ * useful scalar type, and `enum` is matched before the string kinds so its
4138
+ * members become a dropdown rather than a free-text input.
4139
+ *
4140
+ * @param column - The column to inspect.
4141
+ * @returns The widget, its `number` step (or `null`) and its `select` options.
4142
+ */
4143
+ declare function widgetForColumn(column: Column<unknown>): WidgetSpec;
4144
+ /**
4145
+ * Whether a column may be left blank on submit — it is nullable, carries a
4146
+ * default, or is the primary key the database fills in.
4147
+ *
4148
+ * @param column - The column to inspect.
4149
+ * @returns `true` when the field is optional.
4150
+ */
4151
+ declare function isColumnOptional(column: Column<unknown>): boolean;
4152
+ /**
4153
+ * Map a column to the filter control the list view shows for it.
4154
+ *
4155
+ * Booleans and enums become dropdowns, date-like columns become a from/to pair
4156
+ * of date inputs, and anything else falls back to an equality text input.
4157
+ *
4158
+ * @param column - The column to inspect.
4159
+ * @returns The filter kind and, for `select`, its options.
4160
+ */
4161
+ declare function filterForColumn(column: Column<unknown>): {
4162
+ kind: AdminFilterKind;
4163
+ options: AdminSelectOption[];
4164
+ };
4165
+ /**
4166
+ * Return the table a column points at, when it carries a foreign key.
4167
+ *
4168
+ * @param column - The column to inspect.
4169
+ * @returns The referenced table name, or `null` for a plain column.
4170
+ */
4171
+ declare function foreignKeyTable(column: Column<unknown>): string | null;
4172
+ /**
4173
+ * Whether a column holds free text a `LIKE '%…%'` search can match.
4174
+ *
4175
+ * @param column - The column to inspect.
4176
+ * @returns `true` for `varchar` / `text` / `char` columns.
4177
+ */
4178
+ declare function isSearchableColumn(column: Column<unknown>): boolean;
4179
+
3730
4180
  /**
3731
4181
  * Form building and submission parsing for the admin CRUD views, mirroring
3732
4182
  * `admin.forms`.
@@ -3771,6 +4221,12 @@ interface BuildFormFieldsOptions {
3771
4221
  values?: Record<string, unknown>;
3772
4222
  /** Per-field errors to surface, keyed by column. */
3773
4223
  errors?: Record<string, string>;
4224
+ /**
4225
+ * Options for foreign-key columns whose target model is registered, keyed by
4226
+ * column. A field listed here renders as a `<select>` of related rows instead
4227
+ * of a raw identity text input.
4228
+ */
4229
+ foreignKeyOptions?: Record<string, AdminSelectOption[]>;
3774
4230
  }
3775
4231
  /**
3776
4232
  * Render a stored value into the string a control pre-fills with.
@@ -3814,6 +4270,25 @@ declare function parseFormBody(admin: AdminModel, body: Record<string, unknown>)
3814
4270
  * @returns A display string (empty for `null`/`undefined`).
3815
4271
  */
3816
4272
  declare function formatCellValue(value: unknown): string;
4273
+ /**
4274
+ * Return the editable foreign-key columns of an admin, as `field → table`.
4275
+ *
4276
+ * @param admin - The model configuration.
4277
+ * @returns One entry per editable column that references another table.
4278
+ */
4279
+ declare function foreignKeyFields(admin: AdminModel): Record<string, string>;
4280
+ /**
4281
+ * Build a human label for a referenced row — the analog of Django's `__str__`.
4282
+ *
4283
+ * Prefers the referenced admin's first search field, then a conventional
4284
+ * display attribute, then the row's identity, so a dropdown of related rows
4285
+ * reads as names rather than as a column of UUIDs.
4286
+ *
4287
+ * @param admin - The **referenced** model's configuration.
4288
+ * @param row - The referenced row.
4289
+ * @returns A label for the option.
4290
+ */
4291
+ declare function foreignKeyLabel(admin: AdminModel, row: Record<string, unknown>): string;
3817
4292
 
3818
4293
  /**
3819
4294
  * Authentication backends for the admin panel, mirroring `admin.auth`.
@@ -3996,122 +4471,6 @@ declare class UserModelAuthBackend implements AdminAuthBackend<UserPrincipalRow>
3996
4471
  verifyMfa(principal: UserPrincipalRow, code: string): Promise<boolean>;
3997
4472
  }
3998
4473
 
3999
- /**
4000
- * Signed-cookie sessions for the admin panel, mirroring `admin.session`.
4001
- *
4002
- * The panel's session is **stateless**: the principal id, display name, CSRF
4003
- * token and expiry travel in the cookie itself, signed with HMAC-SHA256 over
4004
- * the caller's secret. Nothing is kept server-side, so the panel survives a
4005
- * restart and works across replicas without a shared store — the property that
4006
- * matters most for an operator tool that is used in bursts and left open.
4007
- *
4008
- * The CSRF token lives inside the session payload, so every write form can
4009
- * carry it and the server compares it against the cookie it already trusts.
4010
- */
4011
-
4012
- /** The payload carried by the admin session cookie. */
4013
- interface AdminSession {
4014
- /** Stable id of the authenticated principal. */
4015
- subject: string;
4016
- /** Display name shown in the header. */
4017
- displayName: string;
4018
- /** Token every write form echoes back for CSRF validation. */
4019
- csrfToken: string;
4020
- /** Expiry, in epoch seconds. */
4021
- expiresAt: number;
4022
- /**
4023
- * `true` once the second factor was accepted. Sessions issued for a
4024
- * principal without MFA are complete from the start.
4025
- */
4026
- mfaPassed: boolean;
4027
- }
4028
- /** Options for {@link AdminSessionStore}. */
4029
- interface AdminSessionStoreOptions {
4030
- /** HMAC key signing the cookie. At least 32 characters. */
4031
- secret: string;
4032
- /** Cookie name. Default `tempest_admin_session`. */
4033
- cookieName?: string;
4034
- /** Session lifetime in seconds. Default `28800` (8 hours). */
4035
- maxAgeSeconds?: number;
4036
- /** Send the cookie with `Secure` (HTTPS only). Default `true`. */
4037
- cookieSecure?: boolean;
4038
- /** Cookie `Path`. Default `/`. */
4039
- cookiePath?: string;
4040
- }
4041
- /**
4042
- * Issues, verifies and clears the admin session cookie.
4043
- *
4044
- * The cookie value is `<base64url payload>.<base64url signature>`; a payload
4045
- * whose signature does not verify, or whose expiry has passed, resolves to
4046
- * `null` — an operator with a tampered or stale cookie is simply logged out.
4047
- */
4048
- declare class AdminSessionStore {
4049
- private readonly secret;
4050
- private readonly cookieName;
4051
- private readonly maxAgeSeconds;
4052
- private readonly cookieSecure;
4053
- private readonly cookiePath;
4054
- /**
4055
- * Build the store.
4056
- *
4057
- * @param options - Secret, cookie name, lifetime and cookie flags.
4058
- * @throws Error When the secret is shorter than 32 characters.
4059
- */
4060
- constructor(options: AdminSessionStoreOptions);
4061
- /**
4062
- * Sign a payload.
4063
- *
4064
- * @param payload - The base64url payload to sign.
4065
- * @returns The base64url signature.
4066
- */
4067
- private sign;
4068
- /**
4069
- * Mint a fresh session for an authenticated principal.
4070
- *
4071
- * @param subject - The principal id.
4072
- * @param displayName - The name shown in the header.
4073
- * @param mfaPassed - Whether the second factor is already satisfied.
4074
- * @returns The new session payload (not yet written to a response).
4075
- */
4076
- issue(subject: string, displayName: string, mfaPassed?: boolean): AdminSession;
4077
- /**
4078
- * Read and verify the session carried by a request.
4079
- *
4080
- * @param req - The inbound request.
4081
- * @returns The session, or `null` when absent, tampered with or expired.
4082
- */
4083
- load(req: Request): AdminSession | null;
4084
- /**
4085
- * Write a session to the response as a signed cookie.
4086
- *
4087
- * @param res - The outbound response.
4088
- * @param session - The session to persist.
4089
- */
4090
- save(res: Response$1, session: AdminSession): void;
4091
- /**
4092
- * Drop the session cookie.
4093
- *
4094
- * @param res - The outbound response.
4095
- */
4096
- clear(res: Response$1): void;
4097
- /**
4098
- * Render a `Set-Cookie` value with the configured flags.
4099
- *
4100
- * @param value - The cookie value.
4101
- * @param maxAge - Lifetime in seconds (`0` expires it immediately).
4102
- * @returns The header value.
4103
- */
4104
- private cookie;
4105
- }
4106
- /**
4107
- * Compare a submitted CSRF token against the session's, in constant time.
4108
- *
4109
- * @param session - The active session.
4110
- * @param submitted - The `csrf_token` field from the form body.
4111
- * @returns `true` when the tokens match.
4112
- */
4113
- declare function csrfTokenMatches(session: AdminSession, submitted: unknown): boolean;
4114
-
4115
4474
  /**
4116
4475
  * Typed theming for the server-rendered admin panel, mirroring `admin.theme`.
4117
4476
  *
@@ -4218,6 +4577,11 @@ interface AdminSiteOptions {
4218
4577
  siteUrl?: string;
4219
4578
  /** Typed appearance overrides. Omitted keeps the stock look. */
4220
4579
  theme?: AdminTheme;
4580
+ /**
4581
+ * Business-metric cards rendered at the top of the dashboard, each computed
4582
+ * from the database on load. Distinct from the system CPU/memory panel.
4583
+ */
4584
+ dashboardCards?: readonly MetricCard[];
4221
4585
  }
4222
4586
  /** Options accepted by {@link AdminSite.automap}. */
4223
4587
  interface AdminAutomapOptions extends Omit<AdminModelOptions<ModelClass>, "model"> {
@@ -4250,6 +4614,8 @@ declare class AdminSite {
4250
4614
  readonly siteUrl: string | null;
4251
4615
  /** Typed appearance overrides. */
4252
4616
  readonly theme: AdminTheme;
4617
+ /** Business-metric cards rendered at the top of the dashboard. */
4618
+ readonly dashboardCards: MetricCard[];
4253
4619
  private readonly registry;
4254
4620
  /**
4255
4621
  * Initialize the site.
@@ -4419,6 +4785,33 @@ interface AdminDashboardCard {
4419
4785
  /** URL of the create form, or `null` when creation is disabled. */
4420
4786
  newUrl: string | null;
4421
4787
  }
4788
+ /** One business-metric card, already computed and formatted for rendering. */
4789
+ interface AdminBusinessCardView {
4790
+ /** The card heading. */
4791
+ label: string;
4792
+ /** Which shape to render. */
4793
+ kind: "value" | "trend" | "partition";
4794
+ /** Headline value (`value` and `trend` cards). */
4795
+ value: string;
4796
+ /** Optional unit suffix. */
4797
+ unit: string | null;
4798
+ /** Trend direction (`trend` cards). */
4799
+ direction: "up" | "down" | "flat";
4800
+ /** Formatted percentage change, or `null` when there is no baseline. */
4801
+ percent: string | null;
4802
+ /** Previous-period value, as text (`trend` cards). */
4803
+ previous: string;
4804
+ /** Segments with their share of the total (`partition` cards). */
4805
+ segments: {
4806
+ label: string;
4807
+ value: string;
4808
+ percent: number;
4809
+ }[];
4810
+ /** Optional sub-label. */
4811
+ helpText: string | null;
4812
+ /** Set when the card's compute threw, so the dashboard still renders. */
4813
+ error: string | null;
4814
+ }
4422
4815
  /** The system metrics panel on the dashboard. */
4423
4816
  interface AdminDashboardMetrics {
4424
4817
  /** CPU load as a percentage of available cores. */
@@ -4439,7 +4832,7 @@ interface AdminDashboardMetrics {
4439
4832
  * @param metrics - The system metrics panel, or `null` when disabled.
4440
4833
  * @returns The full page.
4441
4834
  */
4442
- declare function renderDashboardPage(context: AdminRenderContext, cards: AdminDashboardCard[], metrics: AdminDashboardMetrics | null): string;
4835
+ declare function renderDashboardPage(context: AdminRenderContext, cards: AdminDashboardCard[], metrics: AdminDashboardMetrics | null, businessCards?: AdminBusinessCardView[]): string;
4443
4836
  /** A filter control rendered above the list view. */
4444
4837
  interface AdminFilterView {
4445
4838
  /** Column key the control filters on. */
@@ -4502,6 +4895,20 @@ interface AdminListView {
4502
4895
  sort: Record<string, AdminSortView>;
4503
4896
  /** URL of the create form, or `null` when creation is disabled. */
4504
4897
  newUrl: string | null;
4898
+ /** Bulk actions offered above the table. Empty hides the whole bulk UI. */
4899
+ bulkActions: BulkActionOption[];
4900
+ /** URL the bulk form posts to. */
4901
+ bulkUrl: string;
4902
+ /** URL exporting the current result set as CSV. */
4903
+ exportCsvUrl: string;
4904
+ /** URL exporting the current result set as JSON. */
4905
+ exportJsonUrl: string;
4906
+ /** Saved-preset tabs rendered above the table. Empty hides the strip. */
4907
+ lenses: {
4908
+ label: string;
4909
+ url: string;
4910
+ active: boolean;
4911
+ }[];
4505
4912
  }
4506
4913
  /**
4507
4914
  * Render the paginated list view, with its search box, filters and sortable
@@ -4512,6 +4919,33 @@ interface AdminListView {
4512
4919
  * @returns The full page.
4513
4920
  */
4514
4921
  declare function renderListPage(context: AdminRenderContext, view: AdminListView): string;
4922
+ /** One entry in the detail view's change timeline. */
4923
+ interface AdminAuditEntryView {
4924
+ /** The mutation kind (`create` / `update` / `delete`). */
4925
+ action: string;
4926
+ /** When it happened, already formatted. */
4927
+ at: string;
4928
+ /** Who did it — a resolved display name, or the raw actor id. */
4929
+ actor: string;
4930
+ /** The per-field diff. */
4931
+ changes: {
4932
+ field: string;
4933
+ before: string;
4934
+ after: string;
4935
+ }[];
4936
+ /** Extra metadata the writer recorded, as JSON text, or `null`. */
4937
+ context: string | null;
4938
+ }
4939
+ /** The "who and when" panel below a record's fields. */
4940
+ interface AdminAuditView {
4941
+ /** Timestamp and actor rows, already resolved and formatted. */
4942
+ fields: {
4943
+ label: string;
4944
+ value: string;
4945
+ }[];
4946
+ /** The change timeline, newest first. Empty when there is none to show. */
4947
+ history: AdminAuditEntryView[];
4948
+ }
4515
4949
  /** The view model the detail page renders. */
4516
4950
  interface AdminDetailView {
4517
4951
  /** Singular display name. */
@@ -4529,6 +4963,8 @@ interface AdminDetailView {
4529
4963
  editUrl: string | null;
4530
4964
  /** URL the delete form posts to, or `null` when deletion is disabled. */
4531
4965
  deleteUrl: string | null;
4966
+ /** The audit panel, or `null` when the model carries no audit columns. */
4967
+ audit: AdminAuditView | null;
4532
4968
  }
4533
4969
  /**
4534
4970
  * Render the single-record detail view.
@@ -4612,6 +5048,17 @@ interface AdminRouterOptions {
4612
5048
  sessionMaxAgeSeconds?: number;
4613
5049
  /** Show the CPU/memory panel on the dashboard. Default `true`. */
4614
5050
  showMetrics?: boolean;
5051
+ /**
5052
+ * Hard cap on rows the CSV/JSON export writes. Default `5000`. An export is
5053
+ * a full table scan streamed to a browser, so the cap is what keeps a curious
5054
+ * click on a large table from becoming an outage.
5055
+ */
5056
+ exportMaxRows?: number;
5057
+ /**
5058
+ * Granular access control layered on top of the `AdminModel` flags. Omitted
5059
+ * lets every signed-in operator do whatever those flags allow.
5060
+ */
5061
+ accessPolicy?: AdminAccessPolicy;
4615
5062
  }
4616
5063
  /**
4617
5064
  * Build the admin panel router.
@@ -6393,6 +6840,6 @@ declare function createTestDatabase(models: readonly ModelClass[]): TestDatabase
6393
6840
  declare function withTestDatabase<T>(models: readonly ModelClass[], fn: (db: TestDatabase) => Promise<T>): Promise<T>;
6394
6841
 
6395
6842
  /** The installed SDK version. Single source of truth for the barrel + CLI. */
6396
- declare const VERSION = "0.24.0";
6843
+ declare const VERSION = "0.26.0";
6397
6844
 
6398
- export { ADMIN_CSS, type ActivationInput, ActivationService, type ActivationServiceOptions, type ActivationStore, type AdminAuthBackend, type AdminAutomapOptions, type AdminDashboardCard, type AdminDashboardMetrics, type AdminDetailView, type AdminFilterKind, type AdminFilterView, type AdminFormField, type AdminFormView, type AdminJsonField, type AdminJsonListQuery, type AdminJsonListResult, type AdminJsonResource, type AdminJsonRouterOptions, AdminJsonSite, type AdminListView, type AdminMessage, type AdminMfaVerifier, AdminModel, type AdminModelOptions, type AdminNavEntry, type AdminRenderContext, type AdminRouterOptions, type AdminRow, type AdminSelectOption, type AdminSession, AdminSessionStore, type AdminSessionStoreOptions, AdminSite, type AdminSiteOptions, type AdminSortView, type AdminTheme, type AdminWidget, AppException, type AppExceptionHandlerOptions, type AppExceptionOptions, type AttachWebSocketOptions, AttemptThrottle, type AttemptThrottleOptions, AuditAction, type AuthResponse, type AuthResultPageOptions, type AuthRouterOptions, type AuthUser, type BackupOptions, type BaseAppSettings, BaseAuditLogModel, BaseController, BaseModel, BaseOAuthClient, BaseOutboxModel, type BaseResponse, BaseService, BaseUserModel, BaseUserRefreshTokenModel, BaseUserTokenModel, type BodySizeLimitOptions, type BroadcastOptions, type BroadcastResult, type BrokerManager, type BuildFormFieldsOptions, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, type CPUMetrics, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, type CacheManager, type CachedOptions, type CachedResponse, type CatalogData, CircuitOpenError, type ClientIpOptions, CompositeFeatureFlagBackend, ConflictException, type CreateAppOpenApi, type CreateAppOptions, type CsrfOptions, type CursorPaginationFilter, DEFAULT_DOCS_FAVICON, DEFAULT_LOCALE, type DownloadOptions, type EmailMessage, type EmailOptions, EmailProvider, type EmailProviderOptions, EmailUtils, type Enum, type EnumHelpers, type EnumSpec, EnvFeatureFlagBackend, EventStream, type EventStreamOptions, type ExceptionDetails, ExpiredTokenException, type FeatureFlagBackend, FeatureFlags, type FieldChange, type FileLoggingHandle, type FileLoggingOptions, type FlagContext, ForbiddenException, type GPUMetrics, type GenerateOpenApiOptions, GitHubOAuthClient, GoogleOAuthClient, GracefulShutdown, type GracefulShutdownOptions, HTTPClient, type HTTPClientOptions, HTTP_500_LOG_FILE, HTTP_500_MARKER, type HandshakeInfo, type HealthCheck, type HealthRouterOptions, HttpMetrics, IDEMPOTENCY_HEADER, type IdempotencyOptions, type IdempotencyRedisLike, type IdempotencyStore, type InboundHandler, type InboundMessage, InvalidTokenException, type IssuedSession, JSONLogger, JWTUtils, type JWTUtilsOptions, type JwtAuthOptions, type JwtClaims, type JwtDecoderLike, LEVEL_LOG_FILES, LocalUploadStorage, type LocalUploadStorageOptions, type LogEntry, type LogExtra, type LogLevel, type LogSink, type LogSource, type LoginInput, type LoginResult, type LogsRouterOptions, type MediaKind, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemoryIdempotencyStore, type MemoryMetrics, MemoryRateLimitStore, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, type MessageHandler, MessagingHub, type MessagingProvider, type MetricsRouterOptions, MetricsUtils, type MfaChallenge, type MfaChallengeInput, type MfaCodeInput, type MfaEnrollment, MfaService, type MfaServiceOptions, type MfaStore, NotFoundException, type OAuthClientOptions, OAuthError, type OAuthTokens, type OAuthUser, OIDCProvider, type OIDCProviderOptions, type OpenApiDocument, type OpenApiInfo, type OutboundMedia, type OutboundResult, type OutboxPublisher, OutboxRelay, type OutboxRelayOptions, OutboxStatus, PHONE_BR_PATTERN, type PaginationFilter, type PaginationLinkOptions, type ParsedAdminForm, type PasswordResetConfirmInput, type PasswordResetFormOptions, type PasswordResetRequestInput, PasswordResetService, type PasswordResetServiceOptions, type PasswordResetStore, PasswordUtils, REDOC_CDN_URL, REQUEST_ID_HEADER, RabbitBroker, type RabbitBrokerOptions, type RateLimitKeyFunc, type RateLimitOptions, type RateLimitRedisLike, type RateLimitResult, type RateLimitStore, RedisCacheManager, RedisIdempotencyStore, type RedisLike, type RedisPublisherLike, RedisRateLimitStore, RedisSSEBroker, type RedisSSEBrokerOptions, RedisSessionStore, type RedisSubscriberLike, type RedocBundleSource, type RedocOptions, type RefreshInput, Region, type RegionValue, type RegisterExceptionHandlersOptions, type RequestContext, type RequestTracingOptions, type ResolvedAdminTheme, type ResponseMapper, RetryPolicy, type RunServerOptions, type S3ClientLike, S3UploadStorage, type S3UploadStorageOptions, SSEBroker, type SaveOptions, type SendOptions, ServerSentEvent, type ServerSentEventInit, type Session, type SessionMiddlewareOptions, type SessionRedisLike, SessionService, type SessionServiceOptions, type SessionStore, type SignupInput, type SlowQueryOptions, type SpecProvider, type StateBR, type SwaggerOptions, type SyncFilter, type SystemMetrics, TOTPHelper, type TOTPOptions, type TaskHandler, TaskManager, type TaskManagerOptions, TelegramProvider, type TelegramProviderOptions, TenantScopedRepository, type TestDatabase, type ThrottleBackend, type ThrottleStatus, type ToDictOptions, type TokenPair, TooManyRequestsException, type TooManyRequestsOptions, type ToolSpecOptions, TwilioSmsProvider, type TwilioSmsProviderOptions, type TwilioWebhookOptions, UF, type UFValue, UnauthorizedException, type UnhandledExceptionHandlerOptions, type UploadResult, type UploadStorage, UserAuthService, type UserAuthServiceOptions, UserModelAuthBackend, type UserModelAuthBackendOptions, type UserPublic, type UserStore, UserTokenPurpose, VERSION, ValidationException, type WSEnvelope, WebPushDispatcher, type WebPushDispatcherOptions, WebPushError, WebPushGoneError, type WebPushKeys, type WebPushPayload, type WebPushSubscription, type WebSocketConnection, WebSocketHub, type WebSocketHubOptions, type WebSocketLike, type WebhookSignatureOptions, WebhookSignatureVerifier, WhatsAppProvider, type WhatsAppProviderOptions, type WhatsAppWebhookOptions, type WidgetSpec, activationSchema, addLogSink, adminColumns, adminThemeCss, attachWebSocketHub, authResponseSchema, authSettingsShape, backupDatabase, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, bearerToken, bodySizeLimitMiddleware, broadcastText, buildContentDisposition, buildFormFields, buildPaginationLinkHeader, cached, centsField, cepField, citiesByUf, cnpjField, coerceFlag, configureFileLogging, configureLogging, corsSettingsShape, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createTestDatabase, createdByColumn, csrfMiddleware, csrfTokenMatches, cursorPaginationFilterSchema, cursorPaginationSchema, databaseSettingsShape, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, diffSnapshots, emailSettingsShape, encodeCursor, looseBoolean as envBoolean, envList, escapeHtml, filterForColumn, formatCellValue, formatFieldValue, generateCsrfToken, generateOAuthState, generateOpaqueToken, generateOpenApiDocument, getAuth, getClientIp, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, hexColorField, humanizeField, idempotencyMiddleware, inboundMessageSchema, isColumnOptional, isSearchableColumn, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, jwtSettingsShape, keyByHeader, keyByIp, keyByJwtClaim, keyByJwtSubject, latitudeField, listStates, loadSettings, logEntrySchema, logSettingsShape, loginSchema, longitudeField, looseBoolean, makeAdminJsonRouter, makeAdminRouter, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeLogsRouter, makeMetricsRouter, makeSessionMiddleware, makeToolSpecRouter, makeTwilioWebhookRouter, makeUnhandledExceptionHandler, makeWhatsAppWebhookRouter, mfaChallengeSchema, mfaCodeSchema, mfaEnrollResponseSchema, minioSettingsShape, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, nonEmptyStrField, nonNegativeFloatField, nonNegativeIntField, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, parseFormBody, passwordResetConfirmSchema, passwordResetRequestSchema, percentField, phoneBrField, portField, positiveFloatField, positiveIntField, priceField, prometheusMiddleware, rabbitmqSettingsShape, rateLimitMiddleware, ratingField, ratioField, redisSettingsShape, refreshSchema, registerExceptionHandlers, renderAuthResultPage, renderDashboardPage, renderDetailPage, renderFormPage, renderLayout, renderListPage, renderLoginPage, renderMfaPage, renderPasswordResetFormPage, requestIdMiddleware, requestTracingMiddleware, requireRoles, resolveAdminTheme, resolveDownloadPath, resolveRedocBundle, runServer, runWithRequestContext, sendBytesDownload, sendFileDownload, serverSettingsShape, sessionCookie, sessionSettingsShape, setRequestId, signupSchema, slugField, snapshot, sseResponse, statesByRegion, syncFilterSchema, syncPaginationSchema, tableNameFor, toDict, toUtc, tokenFromUrl, tokenPairSchema, tokenSettingsShape, ufField, updatedByColumn, uploadSettingsShape, userPublicSchema, utcnow, validateTwilioSignature, verifyOpaqueToken, webPushKeysSchema, webPushPayloadSchema, webPushSettingsShape, webPushSubscriptionSchema, webSocketSettingsShape, widgetForColumn, withTestDatabase, wrapWithSlowQueryLog, wsEnvelopeSchema };
6845
+ export { ADMIN_CSS, type ActivationInput, ActivationService, type ActivationServiceOptions, type ActivationStore, type AdminAccessPolicy, type AdminAction, type AdminActionCategory, type AdminActionContext, type AdminActionHandler, type AdminActionOptions, type AdminActionResult, type AdminAuditEntryView, type AdminAuditView, type AdminAuthBackend, type AdminAutomapOptions, type AdminBusinessCardView, type AdminDashboardCard, type AdminDashboardMetrics, type AdminDetailView, type AdminFilterKind, type AdminFilterView, type AdminFormField, type AdminFormView, type AdminJsonField, type AdminJsonListQuery, type AdminJsonListResult, type AdminJsonResource, type AdminJsonRouterOptions, AdminJsonSite, type AdminLens, type AdminLensOptions, type AdminListView, type AdminMessage, type AdminMfaVerifier, AdminModel, type AdminModelOptions, type AdminNavEntry, AdminPermission, type AdminRenderContext, type AdminRouterOptions, type AdminRow, type AdminSelectOption, type AdminSession, AdminSessionStore, type AdminSessionStoreOptions, AdminSite, type AdminSiteOptions, type AdminSortView, type AdminTheme, type AdminWidget, AppException, type AppExceptionHandlerOptions, type AppExceptionOptions, type AttachWebSocketOptions, AttemptThrottle, type AttemptThrottleOptions, AuditAction, type AuthResponse, type AuthResultPageOptions, type AuthRouterOptions, type AuthUser, type BackupOptions, type BaseAppSettings, BaseAuditLogModel, BaseController, BaseModel, BaseOAuthClient, BaseOutboxModel, type BaseResponse, BaseService, BaseUserModel, BaseUserRefreshTokenModel, BaseUserTokenModel, type BodySizeLimitOptions, type BroadcastOptions, type BroadcastResult, type BrokerManager, type BuildFormFieldsOptions, type BulkActionOption, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, type CPUMetrics, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, type CacheManager, type CachedOptions, type CachedResponse, type CardCompute, type CardData, type CatalogData, CircuitOpenError, type ClientIpOptions, CompositeFeatureFlagBackend, ConflictException, type CreateAppOpenApi, type CreateAppOptions, type CsrfOptions, type CursorPaginationFilter, DEFAULT_DOCS_FAVICON, DEFAULT_LOCALE, type DownloadOptions, type EmailMessage, type EmailOptions, EmailProvider, type EmailProviderOptions, EmailUtils, type Enum, type EnumHelpers, type EnumSpec, EnvFeatureFlagBackend, EventStream, type EventStreamOptions, type ExceptionDetails, ExpiredTokenException, type FeatureFlagBackend, FeatureFlags, type FieldChange, type FileLoggingHandle, type FileLoggingOptions, type FlagContext, ForbiddenException, type GPUMetrics, type GenerateOpenApiOptions, GitHubOAuthClient, GoogleOAuthClient, GracefulShutdown, type GracefulShutdownOptions, HTTPClient, type HTTPClientOptions, HTTP_500_LOG_FILE, HTTP_500_MARKER, type HandshakeInfo, type HealthCheck, type HealthRouterOptions, HttpMetrics, IDEMPOTENCY_HEADER, type IdempotencyOptions, type IdempotencyRedisLike, type IdempotencyStore, type InboundHandler, type InboundMessage, InvalidTokenException, type IssuedSession, JSONLogger, JWTUtils, type JWTUtilsOptions, type JwtAuthOptions, type JwtClaims, type JwtDecoderLike, LEVEL_LOG_FILES, LocalUploadStorage, type LocalUploadStorageOptions, type LogEntry, type LogExtra, type LogLevel, type LogSink, type LogSource, type LoginInput, type LoginResult, type LogsRouterOptions, type MediaKind, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemoryIdempotencyStore, type MemoryMetrics, MemoryRateLimitStore, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, type MessageHandler, MessagingHub, type MessagingProvider, type MetricCard, type MetricPartition, type MetricTrend, type MetricValue, type MetricsRouterOptions, MetricsUtils, type MfaChallenge, type MfaChallengeInput, type MfaCodeInput, type MfaEnrollment, MfaService, type MfaServiceOptions, type MfaStore, NotFoundException, type OAuthClientOptions, OAuthError, type OAuthTokens, type OAuthUser, OIDCProvider, type OIDCProviderOptions, type OpenApiDocument, type OpenApiInfo, type OutboundMedia, type OutboundResult, type OutboxPublisher, OutboxRelay, type OutboxRelayOptions, OutboxStatus, PHONE_BR_PATTERN, type PaginationFilter, type PaginationLinkOptions, type ParsedAdminForm, type PasswordResetConfirmInput, type PasswordResetFormOptions, type PasswordResetRequestInput, PasswordResetService, type PasswordResetServiceOptions, type PasswordResetStore, PasswordUtils, REDOC_CDN_URL, REQUEST_ID_HEADER, RabbitBroker, type RabbitBrokerOptions, type RateLimitKeyFunc, type RateLimitOptions, type RateLimitRedisLike, type RateLimitResult, type RateLimitStore, RedisCacheManager, RedisIdempotencyStore, type RedisLike, type RedisPublisherLike, RedisRateLimitStore, RedisSSEBroker, type RedisSSEBrokerOptions, RedisSessionStore, type RedisSubscriberLike, type RedocBundleSource, type RedocOptions, type RefreshInput, Region, type RegionValue, type RegisterExceptionHandlersOptions, type RequestContext, type RequestTracingOptions, type ResolvedAdminTheme, type ResponseMapper, RetryPolicy, type RunServerOptions, type S3ClientLike, S3UploadStorage, type S3UploadStorageOptions, SSEBroker, type SaveOptions, type SendOptions, ServerSentEvent, type ServerSentEventInit, type Session, type SessionMiddlewareOptions, type SessionRedisLike, SessionService, type SessionServiceOptions, type SessionStore, type SignupInput, type SlowQueryOptions, type SpecProvider, type StateBR, type SwaggerOptions, type SyncFilter, type SystemMetrics, TOTPHelper, type TOTPOptions, type TaskHandler, TaskManager, type TaskManagerOptions, TelegramProvider, type TelegramProviderOptions, TenantScopedRepository, type TestDatabase, type ThrottleBackend, type ThrottleStatus, type ToDictOptions, type TokenPair, TooManyRequestsException, type TooManyRequestsOptions, type ToolSpecOptions, TwilioSmsProvider, type TwilioSmsProviderOptions, type TwilioWebhookOptions, UF, type UFValue, UnauthorizedException, type UnhandledExceptionHandlerOptions, type UploadResult, type UploadStorage, UserAuthService, type UserAuthServiceOptions, UserModelAuthBackend, type UserModelAuthBackendOptions, type UserPublic, type UserStore, UserTokenPurpose, VERSION, ValidationException, type WSEnvelope, WebPushDispatcher, type WebPushDispatcherOptions, WebPushError, WebPushGoneError, type WebPushKeys, type WebPushPayload, type WebPushSubscription, type WebSocketConnection, WebSocketHub, type WebSocketHubOptions, type WebSocketLike, type WebhookSignatureOptions, WebhookSignatureVerifier, WhatsAppProvider, type WhatsAppProviderOptions, type WhatsAppWebhookOptions, type WidgetSpec, activationSchema, addLogSink, adminAction, adminColumns, adminLens, adminThemeCss, attachWebSocketHub, authResponseSchema, authSettingsShape, backupDatabase, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, bearerToken, bodySizeLimitMiddleware, broadcastText, buildContentDisposition, buildFormFields, buildPaginationLinkHeader, cached, centsField, cepField, citiesByUf, cnpjField, coerceFlag, configureFileLogging, configureLogging, corsSettingsShape, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createTestDatabase, createdByColumn, csrfMiddleware, csrfTokenMatches, cursorPaginationFilterSchema, cursorPaginationSchema, databaseSettingsShape, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, diffSnapshots, emailSettingsShape, encodeCursor, looseBoolean as envBoolean, envList, escapeHtml, filterForColumn, foreignKeyFields, foreignKeyLabel, foreignKeyTable, formatCellValue, formatFieldValue, generateCsrfToken, generateOAuthState, generateOpaqueToken, generateOpenApiDocument, getAuth, getClientIp, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, hexColorField, humanizeField, idempotencyMiddleware, inboundMessageSchema, isColumnOptional, isSearchableColumn, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, jwtSettingsShape, keyByHeader, keyByIp, keyByJwtClaim, keyByJwtSubject, latitudeField, listStates, loadSettings, logEntrySchema, logSettingsShape, loginSchema, longitudeField, looseBoolean, makeAdminJsonRouter, makeAdminRouter, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeLogsRouter, makeMetricsRouter, makeSessionMiddleware, makeToolSpecRouter, makeTwilioWebhookRouter, makeUnhandledExceptionHandler, makeWhatsAppWebhookRouter, metricCard, mfaChallengeSchema, mfaCodeSchema, mfaEnrollResponseSchema, minioSettingsShape, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, nonEmptyStrField, nonNegativeFloatField, nonNegativeIntField, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, parseFormBody, partitionTotal, passwordResetConfirmSchema, passwordResetRequestSchema, percentField, phoneBrField, portField, positiveFloatField, positiveIntField, priceField, prometheusMiddleware, rabbitmqSettingsShape, rateLimitMiddleware, ratingField, ratioField, redisSettingsShape, refreshSchema, registerExceptionHandlers, renderAuthResultPage, renderDashboardPage, renderDetailPage, renderFormPage, renderLayout, renderListPage, renderLoginPage, renderMfaPage, renderPasswordResetFormPage, requestIdMiddleware, requestTracingMiddleware, requireRoles, resolveAdminTheme, resolveDownloadPath, resolveRedocBundle, runServer, runWithRequestContext, sendBytesDownload, sendFileDownload, serverSettingsShape, sessionCookie, sessionSettingsShape, setRequestId, signupSchema, slugField, snapshot, sseResponse, statesByRegion, syncFilterSchema, syncPaginationSchema, tableNameFor, toDict, toUtc, tokenFromUrl, tokenPairSchema, tokenSettingsShape, trendDirection, trendPercent, ufField, updatedByColumn, uploadSettingsShape, userPublicSchema, utcnow, validateTwilioSignature, verifyOpaqueToken, webPushKeysSchema, webPushPayloadSchema, webPushSettingsShape, webPushSubscriptionSchema, webSocketSettingsShape, widgetForColumn, withTestDatabase, wrapWithSlowQueryLog, wsEnvelopeSchema };