@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
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
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
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
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
import { href } from '@kovojs/core';
const url: string = href('/products/:id', { params: { id: 'p1' } });Signature
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;Link#
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
import { Link } from '@kovojs/core';
const link = <Link to="/products/:id" params={{ id: 'p1' }}>View</Link>;Signature
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
import { redirect } from '@kovojs/core';
const toProduct = redirect('/products/:id', { params: { id: 'p1' } });
// toProduct.status === 303Signature
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
import { form } from '@kovojs/core';
import { addToCart } from './mutations';
export const addToCartForm = form(addToCart);
export const search = form.get('/products');Signature
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
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
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
type JsonValue =
| null
| boolean
| number
| string
| JsonValue[]
| { [key: string]: JsonValue };Form#
A typed mutation form handle: its key, input shape, and failure type.
Signature
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
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
interface FormValidationFailure {
code: 'VALIDATION';
fieldErrors: Record<string, string>;
}ScopedKey#
A framework-minted logical key bound to one principal, public, or reviewed system posture.
Signature
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
type ComponentRenderResult =
| boolean
| null
| number
| readonly ComponentRenderResult[]
| undefined
| object;ComponentTextResult#
Escaped text/message content used by explicit text-oriented helpers.
Signature
type ComponentTextResult = ComponentRenderResult | string;ComponentChild#
Render-time child/slot composition value, including escaped text nodes (SPEC §4.5).
Signature
type ComponentChild = ComponentRenderResult | string;ErrorBoundaryProps#
Props accepted by the server-bound <ErrorBoundary /> render fallback helper.
Signature
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
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
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
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
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
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
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
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
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
type RouteSearchValue = JsonValue | undefined;Route#
A route descriptor: typed path, param/search shapes, and prefetch policy.
Signature
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
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
interface Redirect {
location: string;
status: 303;
}FieldErrorProps#
Props accepted by the compiler-bound <FieldError /> mutation failure helper.
Signature
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
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
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
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
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
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
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
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
function isSecret(value: unknown): value is SecretValue<unknown>;isUntrusted#
Runtime guard recognizing an {@link untrusted} box.
Signature
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
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
function redacted<T>(value: T, options: { mask?: string } = {}): RedactedValue<T>;revealRedacted#
Explicitly un-masks a {@link redacted} box and returns its real value.
Signature
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
function revealSecret<T>(value: Secret<T>, policy: DeclassifyPolicy<'revealSecret'>): T;revealUntrusted#
Explicitly unboxes an {@link untrusted} value after a validation/escaping reason.
Signature
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
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
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
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
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
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
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
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
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
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
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
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
function createMemoryStorage(options: MemoryStorageOptions = {}): StorageCapability;createS3CompatibleStorage#
Adapt one validated S3-compatible client to Kovo's scoped storage capability.
Signature
function createS3CompatibleStorage(options: S3CompatibleStorageOptions): StorageCapability;Supporting types#
FileSystemStorageOptions#
Options for the filesystem-backed storage adapter: the root directory objects are stored under.
Signature
interface FileSystemStorageOptions {
root: string;
}MemoryStorageOptions#
Options for the in-memory storage adapter: an optional clock used for deterministic modified times.
Signature
interface MemoryStorageOptions {
now?: () => Date;
}StorageBody#
The accepted body shapes when writing an object: a string, raw bytes, or a byte stream.
Signature
type StorageBody = string | ArrayBuffer | ArrayBufferView | ReadableStream<Uint8Array>;StorageCapability#
The full object-storage interface an app wires into upload, delete, and download surfaces.
Signature
interface StorageCapability
extends StorageDeleteCapability, StoragePutCapability, StorageReadCapability {}StorageDeleteCapability#
Write authority for deleting stored objects by key.
Signature
interface StorageDeleteCapability {
delete(key: ScopedKey): Promise<void>;
}StorageGetResult#
Result of reading an object fully into memory: its descriptive information plus the object bytes.
Signature
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
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
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
interface StoragePutOptions {
contentType?: string;
etag?: string;
metadata?: Readonly<Record<string, string>>;
}StoragePutResult#
Result of writing an object: the stored object's descriptive information.
Signature
interface StoragePutResult extends StorageObjectInfo {}StorageReadCapability#
Read-only object-storage authority: fetch, stat, and stream objects by key.
Signature
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
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
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
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
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
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
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
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
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
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
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
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
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
type WebhookHeaderValue = null | string | readonly string[] | undefined;WebhookPayload#
The raw request body a webhook verifier signs over: a string or raw bytes.
Signature
type WebhookPayload = string | ArrayBuffer | ArrayBufferView;WebhookVerificationRequest#
The inbound webhook request a verifier checks: its headers, raw payload, and an optional verification clock.
Signature
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
type WebhookVerifier = HmacSignatureVerifier | CustomWebhookVerifier;