Menu

API Reference

View as Markdown

@kovojs/core

Generated from 5 public subpaths — 82 exports, 82 documented. Do not edit by hand.

@kovojs/core#

Task: Daily component, route, query, form, and serializable authoring values.

Source: packages/core/src/index.ts

Values#

publicScopedKey#

Deliberately place an object in the application-wide public namespace.

Principal-owned state should instead use scopedKey(request, key) from @kovojs/server (or a task principal scope). This named public posture is a visible capability choice, not a reason string that can accidentally masquerade as authority (SPEC §6.6).

Signature

ts
function publicScopedKey(key: string): ScopedKey;

component#

Declare a UI component with optional query bindings, optional serializable island state, and a render function. The compiler derives the component's load-bearing name and live refresh target from the exported binding, module path, queries, and authored keys; queries and state are passed to render at runtime. Authored components are plain TSX — the compiler derives stamps, bindings, names, and the client module, so you never write derivable data-bind/kovo-* attributes by hand (SPEC §4.1, §4.8).

Parameter Type Description
definition { /** Declared clock inputs for time-dependent rendered positions and derives (SPEC §4.8/§4.9). */ clocks?: Record<stri… render plus optional queries, state, and disableServerRefresh.
(returns) Component< (0 extends 1 & RenderInput ? Record<never, never> : unknown extends RenderInput ? Record<never, never> : Omi… A Component descriptor the compiler lowers and the server renders.

Copyable example

ts
import { component } from '@kovojs/core';

type CounterState = { count: number };

export const Counter = component({
  state: (): CounterState => ({ count: 0 }),
  render: (_queries: Record<string, never>, state: CounterState) =>
    <button>{state.count}</button>,
});

Signature

ts
function component<
  const State = undefined,
  const Mutations extends Record<string, { key: string }> = Record<never, never>,
  const Queries extends Readonly<Record<string, unknown>> = Record<never, never>,
  const RenderInput extends object = Record<never, never>,
>(definition: {
  /** Declared clock inputs for time-dependent rendered positions and derives (SPEC §4.8/§4.9). */
  clocks?: Record<string, unknown>;
  /** Co-located component CSS scoped by the compiler to this component's host. */
  css?: string;
  /** Force-off escape hatch for inferred server refresh targets (SPEC §4.1). */
  disableServerRefresh?: boolean;
  /** Removed: query-backed components infer refresh targets; use `disableServerRefresh`. */
  fragmentTarget?: never;
  /** Unexpected render-error fallback for full-page and live-target renders (SPEC §9.2). */
  errorBoundary?: ComponentErrorBoundary;
  /** Force the compiler to keep server and client render output equivalent. */
  isomorphic?: boolean;
  mutations?: Mutations;
  /** Static metadata used by generated live-target renderers to serialize component props. */
  props?: Record<
    string,
    | ArrayConstructor
    | BooleanConstructor
    | NumberConstructor
    | ObjectConstructor
    | StringConstructor
  >;
  queries?: Queries;
  render: (
    queries: RenderInput,
    state: State,
    slots: {
      children?: ComponentChild;
      [slot: string]: unknown;
    } & (keyof Mutations extends never
      ? {
          forms?: {
            [Name in keyof Mutations]: Mutations[Name] extends { key: string }
              ? {
                  failure: FormFailure<Mutations[Name]> | null;
                  submitted?: Partial<
                    Mutations[Name] extends {
                      input: { parse(input: unknown): infer Input };
                    }
                      ? Input extends Record<string, unknown>
                        ? Input
                        : Record<string, unknown>
                      : Mutations[Name] extends Form<string, infer Input, unknown>
                        ? Input
                        : Record<string, unknown>
                  >;
                }
              : never;
          };
        }
      : {
          forms: {
            [Name in keyof Mutations]: Mutations[Name] extends { key: string }
              ? {
                  failure: FormFailure<Mutations[Name]> | null;
                  submitted?: Partial<
                    Mutations[Name] extends {
                      input: { parse(input: unknown): infer Input };
                    }
                      ? Input extends Record<string, unknown>
                        ? Input
                        : Record<string, unknown>
                      : Mutations[Name] extends Form<string, infer Input, unknown>
                        ? Input
                        : Record<string, unknown>
                  >;
                }
              : never;
          };
        }),
  ) => ComponentRenderResult;
  state?: State extends Serializable<State> ? () => State : () => never;
}): Component<
  (0 extends 1 & RenderInput
    ? Record<never, never>
    : unknown extends RenderInput
      ? Record<never, never>
      : Omit<RenderInput, Extract<keyof Queries, string>>) & {
    [attribute: `aria-${string}`]: unknown;
    [attribute: `data-${string}`]: unknown;
    [attribute: `on${string}`]: unknown;
    checked?: unknown;
    class?: string;
    className?: string;
    disabled?: unknown;
    form?: unknown;
    hidden?: unknown;
    id?: unknown;
    'kovo-key'?: number | string;
    key?: number | string;
    name?: unknown;
    required?: unknown;
    role?: unknown;
    style?: unknown;
    styles?: unknown;
    tabIndex?: unknown;
    value?: unknown;
  }
>;

ErrorBoundary#

Declare a tree-local unexpected-error boundary. Server JSX catches descendant render failures and renders fallback; typed mutation failures remain normal <FieldError> / <FormError> state (SPEC §9.2).

Signature

ts
function ErrorBoundary(props: ErrorBoundaryProps): ComponentRenderResult;

href#

Build a URL string for a registered route, substituting :param segments and appending typed search values. Params for the path are required and type-checked against the route's declared shape (SPEC §6.4).

Parameter Type Description
path Path A registered route path.
options params for the path segments and optional search.
(returns) string The encoded URL string.

Copyable example

ts
import { href } from '@kovojs/core';

const url: string = href('/products/:id', { params: { id: 'p1' } });

Signature

ts
function href<const Path extends string>(
  path: Path,
  ...args: PathParamNames<Path> extends never
    ? [
        options?: {
          params?: PathParams<Path>;
          search?: Record<string, RouteSearchValue>;
        },
      ]
    : [
        options: {
          params: PathParams<Path>;
          search?: Record<string, RouteSearchValue>;
        },
      ]
): string;

Compiler-bound JSX navigation sugar. Use {@link href} when imperative code needs a URL string (SPEC §6.4).

Parameter Type Description
props Registered route, params/search, children, and anchor attributes.
(returns) ComponentRenderResult Compiler-rendered link output.

Copyable example

ts
import { Link } from '@kovojs/core';

const link = <Link to="/products/:id" params={{ id: 'p1' }}>View</Link>;

Signature

ts
function Link(_props: LinkProps): ComponentRenderResult;

redirect#

Build a 303 redirect to a registered route. Return it from a route page or mutation handler to send the browser to a typed destination (SPEC §6.4).

Parameter Type Description
path Path A registered route path.
options params for the path segments and optional search.
(returns) Redirect A Redirect with status: 303 and the resolved location.

Copyable example

ts
import { redirect } from '@kovojs/core';

const toProduct = redirect('/products/:id', { params: { id: 'p1' } });
// toProduct.status === 303

Signature

ts
function redirect<const Path extends string>(
  path: Path,
  ...args: PathParamNames<Path> extends never
    ? [
        options?: {
          params?: PathParams<Path>;
          search?: Record<string, RouteSearchValue>;
        },
      ]
    : [
        options: {
          params: PathParams<Path>;
          search?: Record<string, RouteSearchValue>;
        },
      ]
): Redirect;

form#

Reference a registered mutation value as a typed form, or a GET route as a search form via form.get. form(addMutation) returns a Form whose input and failure types come from the mutation definition; form.get(path) returns a descriptor with typed input(name) accessors for the route's search fields (SPEC §6.3).

Copyable example

ts
import { form } from '@kovojs/core';
import { addToCart } from './mutations';

export const addToCartForm = form(addToCart);
export const search = form.get('/products');

Signature

ts
const form = Object.assign(createMutationForm, {
  get: getRouteForm,
});

FieldError#

Render a field-scoped mutation failure message. The compiler injects the enclosing typed form's failure slot and validates name against the mutation input schema (SPEC §6.3 / §9.2).

Signature

ts
function FieldError<Failure = unknown>(props: FieldErrorProps<Failure>): string;

FormError#

Render a form-scoped mutation failure message. Validation failures stay field-scoped; declared coded failures render here by default (SPEC §9.2).

Signature

ts
function FormError<
  Failure = unknown,
  const Code extends string | readonly string[] | undefined = undefined,
>(props: FormErrorProps<Failure, Code>): string;

Supporting types#

JsonValue#

Any value that survives a JSON round-trip; the boundary type for island state and wire payloads (SPEC §4.1).

Signature

ts
type JsonValue =
  | null
  | boolean
  | number
  | string
  | JsonValue[]
  | { [key: string]: JsonValue };

Form#

A typed mutation form handle: its key, input shape, and failure type.

Signature

ts
interface Form<
  Key extends string,
  Input extends Record<string, JsonValue> = Record<string, JsonValue>,
  Failure = JsonValue,
> {
  failure?: Failure;
  input?: Input;
  key: Key;
}

FormFailure#

Extract a form or declaration-handle failure union, including validation failure.

Signature

ts
type FormFailure<Definition> = Definition extends {
  input: { parse(input: unknown): unknown };
  errors?: infer Errors;
}
  ?
      | (NonNullable<Errors> extends Record<string, { parse(input: unknown): unknown }>
          ? {
              [Code in Extract<keyof NonNullable<Errors>, string>]: {
                code: Code;
                payload: NonNullable<Errors>[Code] extends {
                  parse(input: unknown): infer Payload;
                }
                  ? Payload
                  : never;
              };
            }[Extract<keyof NonNullable<Errors>, string>]
          : never)
      | FormValidationFailure
  : Definition extends Form<string, infer _Input, infer Failure>
    ? Failure | FormValidationFailure
    : FormValidationFailure;

FormValidationFailure#

The built-in validation failure shape returned when form input fails parsing.

Signature

ts
interface FormValidationFailure {
  code: 'VALIDATION';
  fieldErrors: Record<string, string>;
}

ScopedKey#

A framework-minted logical key bound to one principal, public, or reviewed system posture.

Signature

ts
interface ScopedKey {
  readonly [scopedKeyBrand]: 'kovo-scoped-key';
}

ComponentRenderResult#

Opaque non-string result of a component's render — the compiler lowers TSX to HTML/IR (SPEC §4.1, §4.8).

Signature

ts
type ComponentRenderResult =
  | boolean
  | null
  | number
  | readonly ComponentRenderResult[]
  | undefined
  | object;

ComponentTextResult#

Escaped text/message content used by explicit text-oriented helpers.

Signature

ts
type ComponentTextResult = ComponentRenderResult | string;

ComponentChild#

Render-time child/slot composition value, including escaped text nodes (SPEC §4.5).

Signature

ts
type ComponentChild = ComponentRenderResult | string;

ErrorBoundaryProps#

Props accepted by the server-bound <ErrorBoundary /> render fallback helper.

Signature

ts
interface ErrorBoundaryProps {
  children?: ComponentRenderResult;
  fallback: ComponentRenderResult | ((error: unknown) => ComponentRenderResult);
  target?: string;
}

ComponentErrorBoundary#

Component-local fallback used by generated live-target renderers for unexpected errors.

Signature

ts
interface ComponentErrorBoundary {
  fallback: ComponentRenderResult | ((error: unknown) => ComponentRenderResult);
  target?: string;
}

Component#

Opaque callable component handle. Props is the complete JSX/call-site contract; the authored definition is retained only in a module-private framework registry. The unexported unique-symbol witness prevents ordinary functions from structurally matching this author-time handle; exact WeakMap membership remains the runtime authority (SPEC §4.1/§6.6).

Signature

ts
interface Component<Props extends object = Record<string, never>> {
  <const Input extends Props>(
    ...args: {
      [Key in keyof Props]-?: {} extends Pick<Props, Key> ? never : Key;
    }[keyof Props] extends never
      ? [props?: Input & Record<Exclude<keyof Input, keyof Props>, never>]
      : [props: Input & Record<Exclude<keyof Input, keyof Props>, never>]
  ): ComponentRenderResult;
  readonly [componentHandleWitness]: typeof componentHandleWitness;
  name?: string;
}

Serializable#

Recursive JSON-serializability guardrail for authored state/query payload types (SPEC §4.1).

Signature

ts
type Serializable<T> = T extends JsonValue
  ? T
  : T extends (...args: never[]) => unknown
    ? never
    : T extends readonly (infer Item)[]
      ? readonly Serializable<Item>[]
      : T extends object
        ? { [Key in keyof T]: Serializable<T[Key]> }
        : never;

QueryRefreshSpec#

Per-use query freshness cadence for clock-like server values (SPEC §4.9).

Signature

ts
interface QueryRefreshSpec<Result> {
  at?: (value: Result) => unknown;
  every?: string;
  renderOnce?: true;
  until?: (value: Result) => unknown;
}

QueryRefreshBinding#

A typed query binding with a per-use refresh cadence.

Signature

ts
type QueryRefreshBinding<
  Key extends string,
  Result,
  Spec extends QueryRefreshSpec<Result>,
> = Query<Key, Result, never, never, Spec>;

Query#

A typed query handle: a key and the result type it resolves to.

Signature

ts
interface Query<
  Key extends string,
  Result,
  Props extends Record<string, JsonValue> = never,
  Args = never,
  Spec extends QueryRefreshSpec<Result> | undefined = undefined,
> {
  args: [Props] extends [never]
    ? <NextProps extends Record<string, JsonValue>, NextArgs extends Record<string, JsonValue>>(
        mapper: (props: NextProps) => NextArgs,
      ) => Query<Key, Result, NextProps, NextArgs, Spec>
    : (props: Props) => Args;
  key: Key;
  /**
   * Declarative per-query opt-out from refetch-on-focus (SPEC §9.3/§9.4). Refetch-on-focus
   * is on by default; an app-owned query declaration may set `refetchOnFocus: false` to exclude
   * this query from the visible-return/bfcache typed-read refetch (§9.4). Only `false` is accepted:
   * `true` would be the default and a no-op field.
   */
  refetchOnFocus?: false;
  refresh<NextSpec extends QueryRefreshSpec<Result>>(
    spec: NextSpec,
  ): Query<Key, Result, Props, Args, NextSpec>;
  refreshSpec?: Spec;
  result?: Result;
}

PathParamNames#

URL path parameter names parsed from :param route segments.

Signature

ts
type PathParamNames<Path extends string> = Path extends `${string}:${infer Rest}`
  ? Rest extends `${infer Param}/${infer Tail}`
    ? Param | PathParamNames<Tail>
    : Rest extends `${infer Param}?${string}`
      ? Param
      : Rest extends `${infer Param}#${string}`
        ? Param
        : Rest
  : never;

PathParams#

Route params object inferred from a path pattern.

Signature

ts
type PathParams<Path extends string> =
  PathParamNames<Path> extends never ? {} : Record<PathParamNames<Path>, string>;

RouteSearchValue#

JSON URL search values accepted by typed routes; undefined means omit the key.

Signature

ts
type RouteSearchValue = JsonValue | undefined;

Route#

A route descriptor: typed path, param/search shapes, and prefetch policy.

Signature

ts
interface Route<
  Path extends string,
  Params extends Record<string, string> = PathParams<Path>,
  Search extends Record<string, RouteSearchValue> = Record<string, JsonValue>,
> {
  path: Path;
  params?: Params;
  prefetch?: 'conservative' | 'moderate' | false;
  search?: Search;
}

LinkProps#

Props accepted by the compiler-bound <Link /> navigation sugar (SPEC §6.4).

Signature

ts
interface LinkProps {
  children?: ComponentChild;
  params?: Record<string, string>;
  search?: Record<string, RouteSearchValue>;
  to: string;
  [attribute: string]: unknown;
}

Redirect#

A 303 redirect outcome returned by redirect().

Signature

ts
interface Redirect {
  location: string;
  status: 303;
}

FieldErrorProps#

Props accepted by the compiler-bound <FieldError /> mutation failure helper.

Signature

ts
interface FieldErrorProps<Failure = unknown> {
  children?: unknown;
  class?: string;
  code?: string | readonly string[];
  failure?: Failure | null;
  id?: string;
  message?: ComponentTextResult | ((failure: Failure) => ComponentTextResult);
  name: string;
  role?: string;
  [attribute: string]: unknown;
}

FormErrorProps#

Props accepted by the compiler-bound <FormError /> mutation failure helper.

Signature

ts
interface FormErrorProps<
  Failure = unknown,
  Code extends string | readonly string[] | undefined = string | readonly string[] | undefined,
> {
  children?: unknown;
  class?: string;
  code?: Code;
  failure?: Failure | null;
  id?: string;
  message?:
    | ComponentTextResult
    | ((
        failure: Code extends readonly (infer Item extends string)[]
          ? Extract<NoInfer<Failure>, { code: Item }>
          : Code extends string
            ? Extract<NoInfer<Failure>, { code: Code }>
            : NoInfer<Failure>,
      ) => ComponentTextResult);
  role?: string;
  [attribute: string]: unknown;
}

FormInput#

Extract the input shape of a Form definition.

Signature

ts
type FormInput<Definition> =
  Definition extends Form<string, infer Input, unknown> ? Input : never;

@kovojs/core/diagnostics#

Task: Component model, routes, queries, forms, and render contracts.

Source: packages/core/src/diagnostics-public.ts

Supporting types#

DiagnosticCode#

The string-literal union of every KV### diagnostic code the framework can emit.

Signature

ts
type DiagnosticCode =
  | 'KV201'
  | 'KV210'
  | 'KV211'
  | 'KV212'
  | 'KV220'
  | 'KV221'
  | 'KV222'
  | 'KV223'
  | 'KV224'
  | 'KV225'
  | 'KV226'
  | 'KV227'
  | 'KV228'
  | 'KV229'
  | 'KV230'
  | 'KV231'
  | 'KV232'
  | 'KV233'
  | 'KV234'
  | 'KV235'
  | 'KV236'
  | 'KV237'
  | 'KV238'
  | 'KV239'
  | 'KV240'
  | 'KV241'
  | 'KV242'
  | 'KV243'
  | 'KV244'
  | 'KV245'
  | 'KV246'
  | 'KV247'
  | 'KV301'
  | 'KV302'
  | 'KV303'
  | 'KV304'
  | 'KV310'
  | 'KV311'
  | 'KV312'
  | 'KV313'
  | 'KV314'
  | 'KV315'
  | 'KV316'
  | 'KV317'
  | 'KV318'
  | 'KV320'
  | 'KV330'
  | 'KV402'
  | 'KV403'
  | 'KV404'
  | 'KV405'
  | 'KV406'
  | 'KV407'
  | 'KV408'
  | 'KV409'
  | 'KV410'
  | 'KV411'
  | 'KV412'
  | 'KV413'
  | 'KV414'
  | 'KV415'
  | 'KV416'
  | 'KV417'
  | 'KV418'
  | 'KV419'
  | 'KV420'
  | 'KV421'
  | 'KV422'
  | 'KV423'
  | 'KV424'
  | 'KV425'
  | 'KV426'
  | 'KV428'
  | 'KV429'
  | 'KV430'
  | 'KV431'
  | 'KV432'
  | 'KV433'
  | 'KV434'
  | 'KV435'
  | 'KV436'
  | 'KV437'
  | 'KV438'
  | 'KV439'
  | 'KV445'
  | 'KV446'
  | 'KV447'
  | 'KV448'
  | 'KV449'
  | 'KV450'
  | 'KV451'
  | 'KV452';

DiagnosticSeverity#

Severity tier of a diagnostic, from blocking error down to advisory notice.

Signature

ts
type DiagnosticSeverity = 'error' | 'warn' | 'lint' | 'notice';

RegisteredDiagnostic#

Constructor-authenticated Kovo diagnostic identity.

The nominal property is an author-time guardrail. Runtime consumers still verify exact object identity through the framework-owned diagnostic registry before trusting or rendering a record (SPEC §2/§11).

Signature

ts
interface RegisteredDiagnostic<Code extends DiagnosticCode = DiagnosticCode> {
  /** Module-private nominal witness; runtime authority lives in registeredDiagnosticRegistry. */
  readonly [registeredDiagnosticBrand]: true;
  code: Code;
  help?: string;
  message: string;
  severity: (typeof diagnosticDefinitions)[Code]['severity'];
}

@kovojs/core/security#

Task: Component model, routes, queries, forms, and render contracts.

Source: packages/core/src/security.ts

Values#

declareOffWire#

Audited declaration that a server-side computation using confidential values is intentionally off the client wire (SPEC §6.2/§10.2/§11.3).

This is not a runtime taint proof and it does not return a value, deliberately: the wrapped block cannot be assigned and later returned to the client. Static analyzers may recognize the call as a reviewable escape for helper calls that touch secret projections but do not affect the query or mutation response.

Signature

ts
function declareOffWire(run: () => void, options: { justification: string }): void;

isRedacted#

Runtime guard recognizing a {@link redacted} box. Returns false for a {@link secret} box. Cannot be forged: the brand is a module-private symbol.

Signature

ts
function isRedacted(value: unknown): value is RedactedValue<unknown>;

isSecret#

Runtime guard recognizing a {@link secret} box. Framework sinks (and app code) use it to detect-and-refuse a confidential value before serialization. Cannot be forged: the brand is a module-private symbol. Returns false for a {@link redacted} box — use {@link isRedacted} for that.

Signature

ts
function isSecret(value: unknown): value is SecretValue<unknown>;

isUntrusted#

Runtime guard recognizing an {@link untrusted} box.

Signature

ts
function isUntrusted(value: unknown): value is UntrustedValue<unknown>;

publishToClient#

Audited escape for the client-handler secret-emit gate (SPEC §6.6/§6.2; secure-framework Phase 4 / Tier 0 item 3, KV437).

A client event handler that captures a cross-module import in value position would otherwise evaluate that module in the browser, so the compiler refuses it even when wrapped. The only accepted client-handler shape is a unique, pristine same-file const initialized directly from the finite primitive grammar; the compiler snapshots that literal and records the site + reason for kovo explain capabilities.

This is the analogue of {@link trustedReveal} for the closure-capture channel: an assertion the reviewer can see. Reach for it only for inert same-file constants the handler needs in the browser (a public label or build protocol version); never to ship a real secret or runtime config.

Runtime behavior is identity for the exact string | number | boolean | null data union. Every other value is rejected without reflection, excluding proxies, accessors, nested callables, coercion hooks, iterators, thenables, symbols, bigint, and undefined without executing them during validation. The matching input type is defense-in-depth; the compiler's same-file literal gate is the no-import-execution proof.

Signature

ts
function publishToClient<T extends string | number | boolean | null>(
  value: T,
  options: { reason: string },
): T;

redacted#

Wraps a PII / sensitive value that legitimately travels to the database, client, or UI but must never be logged or surfaced in an error verbatim. The box renders its the optional mask (default "[redacted]") on every accidental coercion; call .reveal() at the DB/render sink that needs the real value. Idempotent.

Sibling of {@link secret}: secret is for values that must never leave the server (API keys, tokens); redacted is for values that DO travel but must not leak into logs (emails, names, card suffixes). Both are defense-in-depth (SPEC §6.6), not the by-construction confidentiality proof (KV435).

Signature

ts
function redacted<T>(value: T, options: { mask?: string } = {}): RedactedValue<T>;

revealRedacted#

Explicitly un-masks a {@link redacted} box and returns its real value.

Signature

ts
function revealRedacted<T>(value: Redacted<T>): T;

revealSecret#

Explicitly unboxes a {@link secret} box and returns its value. A value that is typed Secret<T> but is not a runtime box is returned unchanged.

Signature

ts
function revealSecret<T>(value: Secret<T>, policy: DeclassifyPolicy<'revealSecret'>): T;

revealUntrusted#

Explicitly unboxes an {@link untrusted} value after a validation/escaping reason.

Signature

ts
function revealUntrusted<T>(
  value: Untrusted<T>,
  policy: DeclassifyPolicy<'revealUntrusted'>,
): T;

secret#

Wraps a confidential server-side value in a runtime {@link SecretValue}. The box is non-coercible and can be unboxed only through an audited reveal.

Signature

ts
function secret<T>(value: T): SecretValue<T>;

trustedReveal#

Audited confidentiality escape hatch for query projections that intentionally expose a redacted or otherwise safe representation of a secret-classified value.

The static Drizzle projection analyzer recognizes this function only with an inline, compiler-visible DeclassifyPolicy.forTrustedReveal({ ownerScope: ... }) call and records the reveal for kovo explain revealed. A policy cannot be selected by request data, reused at a different door, or replaced by caller prose. The runtime constructor/registry is a fail-closed floor; compiler provenance and capability closure own the by-construction checks (SPEC §6.6).

Signature

ts
function trustedReveal<T>(
  value: T,
  policy: DeclassifyPolicy<'trustedReveal'>,
): T extends Secret<infer Value> ? Value : T;

untrusted#

Wraps a request-derived value in a non-coercible DX provenance tag.

Signature

ts
function untrusted<T>(value: T): UntrustedValue<T>;

Supporting types#

DeclassifyPolicy#

Nominal, runtime-validated declassification policy. Use the exact static constructor for the reveal door being called; object literals, casts, subclasses, copied fields, and policies constructed for a different door are rejected.

The type is author-time ergonomics. The private runtime registry and exact-door check own the fail-closed floor (SPEC §2 and §6.6).

Signature

ts
class DeclassifyPolicy<
  Door extends
    | 'revealSecret'
    | 'revealUntrusted'
    | 'secret.reveal'
    | 'trustedReveal'
    | 'untrusted.reveal' =
    | 'revealSecret'
    | 'revealUntrusted'
    | 'secret.reveal'
    | 'trustedReveal'
    | 'untrusted.reveal',
> {
  readonly #kovoDeclassifyPolicy: Door;

  private constructor(
    token: typeof declassifyPolicyConstructorToken,
    door: Door,
    options: unknown,
    fixedPurpose?: 'public-projection' | 'request-validation',
  ) {
    if (token !== declassifyPolicyConstructorToken) {
      throw new TypeError(
        'DeclassifyPolicy must be created by its exact door-specific constructor.',
      );
    }
    const { ownerScope, purpose } = validateDeclassifyPolicyOptions(door, options, fixedPurpose);
    this.#kovoDeclassifyPolicy = door;
    if (this.#kovoDeclassifyPolicy !== door) {
      throw new TypeError('DeclassifyPolicy nominal initialization failed.');
    }
    securityWeakSetAdd(declassifyPolicies, this);
    securityWeakMapSet(
      declassifyPolicyRecords,
      this,
      freezeSecurityValue({ door, ownerScope, purpose }),
    );
    freezeSecurityValue(this);
  }

  /** Construct a policy accepted only by the standalone {@link revealSecret} door. */
  static forRevealSecret(options: {
    ownerScope: 'application' | 'current-principal' | 'current-tenant' | 'framework';
    purpose: 'credential-use' | 'server-computation';
  }): DeclassifyPolicy<'revealSecret'> {
    return new DeclassifyPolicy(declassifyPolicyConstructorToken, 'revealSecret', options);
  }

  /** Construct a policy accepted only by {@link SecretValue.reveal}. */
  static forSecretValue(options: {
    ownerScope: 'application' | 'current-principal' | 'current-tenant' | 'framework';
    purpose: 'credential-use' | 'server-computation';
  }): DeclassifyPolicy<'secret.reveal'> {
    return new DeclassifyPolicy(declassifyPolicyConstructorToken, 'secret.reveal', options);
  }

  /** Construct a policy accepted only by the audited {@link trustedReveal} projection door. */
  static forTrustedReveal(options: {
    ownerScope: 'application' | 'current-principal' | 'current-tenant' | 'framework';
  }): DeclassifyPolicy<'trustedReveal'> {
    return new DeclassifyPolicy(
      declassifyPolicyConstructorToken,
      'trustedReveal',
      options,
      'public-projection',
    );
  }

  /** Construct a policy accepted only by the standalone {@link revealUntrusted} door. */
  static forRevealUntrusted(options: {
    ownerScope: 'application' | 'current-principal' | 'current-tenant' | 'framework';
  }): DeclassifyPolicy<'revealUntrusted'> {
    return new DeclassifyPolicy(
      declassifyPolicyConstructorToken,
      'revealUntrusted',
      options,
      'request-validation',
    );
  }

  /** Construct a policy accepted only by {@link UntrustedValue.reveal}. */
  static forUntrustedValue(options: {
    ownerScope: 'application' | 'current-principal' | 'current-tenant' | 'framework';
  }): DeclassifyPolicy<'untrusted.reveal'> {
    return new DeclassifyPolicy(
      declassifyPolicyConstructorToken,
      'untrusted.reveal',
      options,
      'request-validation',
    );
  }
}

Redacted#

Type-level marker for personally-identifiable or otherwise sensitive values that may legitimately travel to the database, client, or UI, but must never appear verbatim in a log line or error payload. Like {@link Secret}, a Redacted<T> is intentionally not assignable to JsonValue, so reaching a client-bound sink with the raw box is a type error — send .reveal() (the real value) or .mask (the safe display form) explicitly.

Signature

ts
interface Redacted<T> {
  readonly [redactedBrand]: {
    readonly kind: 'redacted';
    readonly value: T;
  };
  /** Keeps `Redacted<T>` outside JsonValue; not a trust proof (SPEC §6.6). */
  readonly __kovoRedactedJsonBoundary?: undefined;
}

RedactedValue#

Runtime PII wrapper produced by {@link redacted}. Distinct from {@link SecretValue} in policy, not mechanism: a redacted value renders its mask (a safe-to-display partial such as j•••@example.com, default "[redacted]") on every accidental-egress path (toString/JSON.stringify/coercion/util.inspect), so logs and error payloads show the mask, never the raw PII — while .reveal() returns the real value for the DB/render path that legitimately needs it. Defense-in-depth, not a proof (SPEC §6.6).

Signature

ts
interface RedactedValue<T> extends Redacted<T> {
  /** Returns the real (unmasked) value — the explicit reveal at a DB/render sink. */
  reveal(): T;
  /** The safe-to-display masked representation (what every poisoned coercion yields). */
  readonly mask: string;
  /** Derives a new redacted value, preserving the mask, without un-poisoning. */
  map<U>(fn: (value: T) => U): RedactedValue<U>;
  /** Constant-time equality against another value or redacted/secret box. */
  equals(other: T | Redacted<T> | Secret<T>): boolean;
}

Secret#

Type-level marker for values classified as confidential. Secret<T> is an author-time guardrail; runtime egress chokes and non-coercible boxes own the enforcement boundary (SPEC §10.2/§11.2).

Signature

ts
interface Secret<T> {
  readonly [secretBrand]: {
    readonly kind: 'secret';
    readonly value: T;
  };
  /** Keeps `Secret<T>` outside JsonValue; not a trust proof (SPEC §6.6). */
  readonly __kovoSecretJsonBoundary?: undefined;
}

SecretValue#

Runtime confidential value produced by {@link secret}. A SecretValue<T> is a non-coercible runtime box: string conversion, JSON conversion, numeric conversion, template literals, and accidental concatenation throw instead of laundering the tag off. util.inspect renders a fixed redaction marker so console.log(secret(...)) stays non-leaking.

Signature

ts
interface SecretValue<T> extends Secret<T> {
  /**
   * Returns the wrapped value through an exact validated declassification policy. The returned
   * value is an ordinary primitive/object with no further runtime tag.
   */
  reveal(policy: DeclassifyPolicy<'secret.reveal'>): T;
  /**
   * Derives a new secret from this one _without_ un-poisoning. `apiKey.map(k =>
   * k.slice(0, 4))` yields a `SecretValue<string>` for the prefix, so the derived
   * value keeps its poison instead of decaying to a bare string.
   */
  map<U>(fn: (value: T) => U): SecretValue<U>;
  /**
   * Constant-time equality against another value or secret. Use this for token /
   * signature checks instead of `reveal() === other`, which both leaks via timing
   * and un-poisons the value. Strings and byte-like operands compare through a
   * fixed-width digest; other operands fall back to `Object.is`.
   */
  equals(other: T | Secret<T>): boolean;
}

Untrusted#

Type-level marker for request-derived or otherwise untrusted values. This tag is DX/provenance only; contextual render and protocol chokes remain the enforcement boundary (SPEC §5.2 rule 11).

Signature

ts
interface Untrusted<T> {
  readonly [untrustedBrand]: {
    readonly kind: 'untrusted';
    readonly value: T;
  };
  /** Keeps `Untrusted<T>` outside JsonValue until it is validated or escaped. */
  readonly __kovoUntrustedJsonBoundary?: undefined;
}

UntrustedValue#

Runtime non-coercible value produced by {@link untrusted}.

Signature

ts
interface UntrustedValue<T> extends Untrusted<T> {
  /** Returns the wrapped value through an exact request-validation policy. */
  reveal(policy: DeclassifyPolicy<'untrusted.reveal'>): T;
  /** Derives another untrusted value without losing provenance. */
  map<U>(fn: (value: T) => U): UntrustedValue<U>;
  /** Constant-time equality for string/byte-like values where possible. */
  equals(other: T | Untrusted<T>): boolean;
}

@kovojs/core/storage#

Task: Component model, routes, queries, forms, and render contracts.

Source: packages/core/src/storage-public.ts

Values#

createFileSystemStorage#

Create an object store backed by a directory on the local filesystem. Object metadata is kept in sidecar JSON files alongside each blob. Apps can pass the returned capability to upload and download sinks.

Parameter Type Description
options FileSystemStorageOptions The root directory under which objects are stored.
(returns) StorageCapability A StorageCapability backed by the filesystem.

Signature

ts
function createFileSystemStorage(options: FileSystemStorageOptions): StorageCapability;

createMemoryStorage#

Create an in-memory object store implementing StorageCapability. Useful for tests and local development where uploads should not touch disk or a bucket. Apps can pass the returned capability to upload and download sinks.

Parameter Type Description
options MemoryStorageOptions Optional now clock for deterministic lastModified values.
(returns) StorageCapability A StorageCapability backed by a Map.

Signature

ts
function createMemoryStorage(options: MemoryStorageOptions = {}): StorageCapability;

createS3CompatibleStorage#

Adapt one validated S3-compatible client to Kovo's scoped storage capability.

Signature

ts
function createS3CompatibleStorage(options: S3CompatibleStorageOptions): StorageCapability;

Supporting types#

FileSystemStorageOptions#

Options for the filesystem-backed storage adapter: the root directory objects are stored under.

Signature

ts
interface FileSystemStorageOptions {
  root: string;
}

MemoryStorageOptions#

Options for the in-memory storage adapter: an optional clock used for deterministic modified times.

Signature

ts
interface MemoryStorageOptions {
  now?: () => Date;
}

StorageBody#

The accepted body shapes when writing an object: a string, raw bytes, or a byte stream.

Signature

ts
type StorageBody = string | ArrayBuffer | ArrayBufferView | ReadableStream<Uint8Array>;

StorageCapability#

The full object-storage interface an app wires into upload, delete, and download surfaces.

Signature

ts
interface StorageCapability
  extends StorageDeleteCapability, StoragePutCapability, StorageReadCapability {}

StorageDeleteCapability#

Write authority for deleting stored objects by key.

Signature

ts
interface StorageDeleteCapability {
  delete(key: ScopedKey): Promise<void>;
}

StorageGetResult#

Result of reading an object fully into memory: its descriptive information plus the object bytes.

Signature

ts
interface StorageGetResult extends StorageObjectInfo {
  body: Uint8Array;
}

StorageObjectInfo#

Descriptive information about a stored object: its key and optional size, content type, etag, modified time, and metadata.

size is the object's byte length when known. It is undefined only when a backend genuinely cannot report it (e.g. an S3-compatible client that omits contentLength on a head/stream, where no body is materialized); the framework never fabricates size: 0 for a non-empty object so that the memory, filesystem, and S3 adapters agree on observable info (SPEC §12/§13 parity; Part 3 bug L2-storage-3). Memory and filesystem always know the length, so size is always present there.

Signature

ts
interface StorageObjectInfo {
  contentType?: string;
  etag?: string;
  key: string;
  lastModified?: Date;
  metadata?: Readonly<Record<string, string>>;
  size?: number;
}

StoragePutCapability#

Write authority for storing upload bytes by key.

Signature

ts
interface StoragePutCapability {
  put(key: ScopedKey, body: StorageBody, options?: StoragePutOptions): Promise<StoragePutResult>;
}

StoragePutOptions#

Optional metadata to attach when writing an object: content type, etag, and custom key/value metadata.

Signature

ts
interface StoragePutOptions {
  contentType?: string;
  etag?: string;
  metadata?: Readonly<Record<string, string>>;
}

StoragePutResult#

Result of writing an object: the stored object's descriptive information.

Signature

ts
interface StoragePutResult extends StorageObjectInfo {}

StorageReadCapability#

Read-only object-storage authority: fetch, stat, and stream objects by key.

Signature

ts
interface StorageReadCapability {
  get(key: ScopedKey): Promise<StorageGetResult | undefined>;
  stat(key: ScopedKey): Promise<StorageObjectInfo | undefined>;
  stream(key: ScopedKey): Promise<StorageStreamResult | undefined>;
}

StorageStreamResult#

Result of opening an object as a stream: its descriptive information plus a readable byte stream of the body.

Signature

ts
interface StorageStreamResult extends StorageObjectInfo {
  body: ReadableStream<Uint8Array>;
}

S3CompatibleObjectClient#

Opaque, runtime-validated adapter for an S3-compatible object service.

App adapters translate their SDK into Kovo's stable storage records once. Raw SDK request/response and inspection records never become recursively public through the retained client (SPEC §6.6 and §10.3).

Signature

ts
class S3CompatibleObjectClient {
  private constructor(token: typeof s3CompatibleClientConstructorToken) {
    if (token !== s3CompatibleClientConstructorToken) {
      throw new TypeError(
        'S3CompatibleObjectClient must be created by S3CompatibleObjectClient.create().',
      );
    }
    freezeSecurityValue(this);
  }

  /**
   * Validate and snapshot the five operations Kovo needs from an object SDK.
   *
   * The operation methods use positional bucket/key arguments and Kovo storage
   * results, so provider-specific request and metadata carriers stay local.
   */
  static create(operations: {
    delete(bucket: string, key: string): Promise<void>;
    get(bucket: string, key: string): Promise<StorageGetResult | StorageStreamResult | undefined>;
    list(
      bucket: string,
      prefix: string,
      cursor?: string,
    ): Promise<{ cursor?: string; keys: readonly string[] }>;
    put(
      bucket: string,
      key: string,
      body: StorageBody,
      options?: StoragePutOptions,
    ): Promise<StoragePutResult>;
    stat(bucket: string, key: string): Promise<StorageObjectInfo | undefined>;
  }): S3CompatibleObjectClient {
    const client = new S3CompatibleObjectClient(s3CompatibleClientConstructorToken);
    return registerS3CompatibleClient(client, operations);
  }
}

S3CompatibleStorageOptions#

App wiring for one S3-compatible bucket and optional physical-key prefix.

Signature

ts
interface S3CompatibleStorageOptions {
  bucket: string;
  client: S3CompatibleObjectClient;
  prefix?: string;
}

@kovojs/core/webhooks#

Task: Component model, routes, queries, forms, and render contracts.

Source: packages/core/src/webhooks.ts

Values#

customVerifier#

Wrap a custom verification function as a named webhook verifier, for schemes that HMAC presets do not cover.

Parameter Type Description
name string Identifier recorded on the verifier and its custom:<name> scheme.
verify (request: WebhookVerificationRequest) => Promise<boolean> | boolean Predicate over the raw request returning whether it is authentic.
(returns) CustomWebhookVerifier A CustomWebhookVerifier.

Copyable example

ts
import { customVerifier, type WebhookHeaders } from '@kovojs/core/webhooks';

function tokenFrom(headers: WebhookHeaders): string | undefined {
  if ('get' in headers && typeof headers.get === 'function') {
    const value = headers.get('x-token');
    return typeof value === 'string' ? value : undefined;
  }
  return undefined;
}

export const verifier = customVerifier(
  'static-token',
  (request) => tokenFrom(request.headers) === 'expected',
);

Signature

ts
function customVerifier(
  name: string,
  verify: (request: WebhookVerificationRequest) => Promise<boolean> | boolean,
): CustomWebhookVerifier;

hmacSignature#

Build an HMAC webhook verifier that checks a signature header against the raw payload bytes before any parsing — the default for machine endpoints (SPEC §9.1). Provider-specific recipes can be written locally on top of this helper; standardWebhooks remains the shared non-vendor preset.

Parameter Type Description
options { encoding: 'base64' | 'base64url' | 'hex'; header: string; multiSig?: boolean | ((signatureHeader: string) => readonly… Secret(s), header name, encoding, payload derivation, and tolerance.
(returns) HmacSignatureVerifier An HmacSignatureVerifier with an async verify.

Copyable example

ts
import { hmacSignature } from '@kovojs/core/webhooks';

const secret = process.env.PROVIDER_WEBHOOK_SECRET;
if (secret === undefined) throw new Error('Missing provider webhook signing material');

export const verifier = hmacSignature({
  encoding: 'hex',
  header: 'x-signature',
  payload: (request) => request.payload,
  secret,
});

Signature

ts
function hmacSignature(options: {
  encoding: 'base64' | 'base64url' | 'hex';
  header: string;
  multiSig?: boolean | ((signatureHeader: string) => readonly string[]);
  name?: string;
  payload:
    | WebhookPayload
    | ((
        request: WebhookVerificationRequest,
        context: {
          header(name: string): string | undefined;
          signatureHeader: string;
        },
      ) => Promise<WebhookPayload> | WebhookPayload);
  scheme?: string;
  secret:
    | string
    | Uint8Array
    | {
        encoding?: 'base64' | 'base64url' | 'utf8';
        value: string | Uint8Array;
      }
    | readonly (
        | string
        | Uint8Array
        | {
            encoding?: 'base64' | 'base64url' | 'utf8';
            value: string | Uint8Array;
          }
      )[];
  tolerance?: {
    header?: string;
    seconds: number;
    timestamp?: (
      request: WebhookVerificationRequest,
      context: {
        header(name: string): string | undefined;
        signatureHeader: string;
      },
    ) => number | string | undefined;
  };
}): HmacSignatureVerifier;

standardWebhooks#

Preset HMAC verifier for the Standard Webhooks spec (webhook-id, webhook-timestamp, webhook-signature headers).

Parameter Type Description
options { secret: | string | Uint8Array | { encoding?: 'base64' | 'base64url' | 'utf8'; value: string | Uint8Array; } | readonl… The Standard Webhooks signing secret(s).
(returns) HmacSignatureVerifier An HmacSignatureVerifier configured for Standard Webhooks.

Copyable example

ts
import { standardWebhooks } from '@kovojs/core/webhooks';

const secret = process.env.STANDARD_WEBHOOK_SECRET;
if (secret === undefined) throw new Error('Missing Standard Webhooks signing material');

export const verifier = standardWebhooks({
  secret,
});

Signature

ts
function standardWebhooks(options: {
  secret:
    | string
    | Uint8Array
    | {
        encoding?: 'base64' | 'base64url' | 'utf8';
        value: string | Uint8Array;
      }
    | readonly (
        | string
        | Uint8Array
        | {
            encoding?: 'base64' | 'base64url' | 'utf8';
            value: string | Uint8Array;
          }
      )[];
}): HmacSignatureVerifier;

Supporting types#

CustomWebhookVerifier#

A verifier for a bespoke webhook scheme: a named scheme plus an async verify of the request.

Signature

ts
interface CustomWebhookVerifier {
  kind: 'custom';
  name: string;
  scheme: string;
  verify(request: WebhookVerificationRequest): Promise<boolean>;
}

HmacSignatureVerifier#

A configured HMAC-signature verifier.

Provider signing material and resolved inspection records remain framework-internal. App code receives only the scheme identity and verify operation it can act on (SPEC §6.6/§9.1).

Signature

ts
interface HmacSignatureVerifier {
  kind: 'hmac';
  name: string;
  scheme: string;
  verify(request: WebhookVerificationRequest): Promise<boolean>;
}

WebhookHeaders#

The request headers a verifier reads, accepted as a Headers, a Map, a record, or any object exposing get.

Signature

ts
type WebhookHeaders =
  | Headers
  | Map<string, string>
  | Record<string, WebhookHeaderValue>
  | { get(name: string): WebhookHeaderValue };

WebhookHeaderValue#

A single header value as seen by a verifier: a string, a list of strings, or absent.

Signature

ts
type WebhookHeaderValue = null | string | readonly string[] | undefined;

WebhookPayload#

The raw request body a webhook verifier signs over: a string or raw bytes.

Signature

ts
type WebhookPayload = string | ArrayBuffer | ArrayBufferView;

WebhookVerificationRequest#

The inbound webhook request a verifier checks: its headers, raw payload, and an optional verification clock.

Signature

ts
interface WebhookVerificationRequest {
  headers: WebhookHeaders;
  now?: Date | number;
  payload: WebhookPayload;
}

WebhookVerifier#

A configured webhook verifier: either an HMAC-signature verifier or a custom-scheme verifier.

Signature

ts
type WebhookVerifier = HmacSignatureVerifier | CustomWebhookVerifier;