SDK types
Complete public declarations from @backlit/sdk/types.
This page is generated from the built SDK declarations. Import these names
from @backlit/sdk/types. The signatures include overloads, type parameters,
options, and public members. Do not edit this page by hand.
Start with App and areas, Resources, Search state, or Extensions for usage.
ActionAddress
type ActionAddress = {
resource: string;
action: string;
args: string[];
key: string;
};
ActionHandler
type ActionHandler<Schema extends StandardSchemaV1, Params extends ParamNames = readonly [
]> = (ctx: RequestContext<'action', Params, StandardSchemaV1.InferOutput<Schema>>) => AsyncOrSync<void | Respondable<ValidActionResponse>>;
AgentOptions
type AgentOptions = {
description: string;
search?: boolean;
};
AgentTool
type AgentTool = {
name: string;
description: string;
source: AgentToolSource;
input: Record<string, unknown>;
mutates: boolean;
};
AgentToolResult
type AgentToolResult = {
kind: 'data';
value: unknown;
} | {
kind: 'address';
address: ViewAddress;
title?: string;
} | {
kind: 'response';
response: ValidActionResponse;
};
AgentToolSource
type AgentToolSource = LinkTargetAddress | LookupTarget | FormActionAddress;
AppConfig
type AppConfig<Areas extends {
[area: string]: {
[resource: string]: ResourceLoader;
};
}> = {
preferences?: AppPreferences;
extensions?: BacklitExtension[];
middleware?: MiddlewareLoader[];
areas: {
[Area in keyof Areas]: {
label: string;
icon?: string;
resources: Areas[Area];
navigation: NavigationItem<keyof Areas[Area] & string>[];
};
};
};
BacklitExtension
type BacklitExtension = () => ManifestExtension;
CardinalityValue
type CardinalityValue<Value, Card extends Cardinality> = [
Value
] extends [
never
] ? never : Card extends 'many' ? Value[] : Value;
ConditionableOptions
type ConditionableOptions<Options = {}> = Omit<Options, keyof Conditioned> & {
[Key in keyof Conditioned]?: Nodeable<Condition>;
};
Defect
interface Defect {
index?: number;
field?: string;
kind?: Field['kind'];
value?: unknown;
reason: string;
}
DefectReporter
type DefectReporter = (defect: Defect) => void;
ExtractFieldByName
type ExtractFieldByName<Fields extends readonly FieldBuilderContract<string, unknown, never>[], Name extends string> = Extract<Fields[number], FieldBuilderContract<Name>>;
ExtractFieldNames
type ExtractFieldNames<Fields extends readonly FieldBuilderContract<string, unknown, never>[]> = Fields[number][typeof FIELD_NAME];
ExtractFieldValue
type ExtractFieldValue<F> = F extends FieldBuilderContract<string, infer Value> ? Value : never;
ExtractFilterByName
type ExtractFilterByName<Filters extends readonly FilterBuilderContract<string>[], Name extends string> = Extract<Filters[number], FilterBuilderContract<Name>>;
ExtractFilterNames
type ExtractFilterNames<Filters extends readonly FilterBuilderContract<string>[]> = Filters[number][typeof FILTER_NAME];
ExtractFilterValue
type ExtractFilterValue<F> = F extends FilterBuilderContract<string, infer Value> ? Value : never;
ExtractRecordOf
type ExtractRecordOf<Fields extends readonly FieldBuilderContract<string, unknown, never>[]> = {
[F in Fields[number] as F[typeof FIELD_NAME]]: NonNullable<F[typeof FIELD_VALUE]>;
};
ExtractRepeaterKeys
type ExtractRepeaterKeys<Input> = {
[Key in Extract<keyof Input, string>]: NonNullable<Input[Key]> extends readonly object[] ? Key : never;
}[Extract<keyof Input, string>];
ExtractRepeaterRow
type ExtractRepeaterRow<Input, Key extends keyof Input> = NonNullable<Input[Key]> extends readonly (infer Row extends object)[] ? Row : never;
ExtractResourceFieldNames
type ExtractResourceFieldNames<Target> = Target extends Resource<string, infer Fields extends readonly FieldBuilderContract<string, unknown, never>[]> ? ExtractFieldNames<Fields> : never;
ExtractResourceLoader
type ExtractResourceLoader<Areas extends Record<string, Record<string, ResourceLoader>>, Name extends ExtractResourceNames<Areas>> = {
[Area in keyof Areas]: Name extends keyof Areas[Area] ? Areas[Area][Name] : never;
}[keyof Areas];
ExtractResourceNames
type ExtractResourceNames<Areas extends Record<string, Record<string, ResourceLoader>>> = {
[Area in keyof Areas]: keyof Areas[Area] & string;
}[keyof Areas];
ExtractResourceRecord
type ExtractResourceRecord<Target> = Target extends Resource<string, infer Fields extends readonly FieldBuilderContract<string, unknown, never>[]> ? ExtractRecordOf<Fields> : never;
ExtractStateBindings
type ExtractStateBindings<Atoms extends StateAtoms> = {
readonly [Key in keyof Atoms]: StateBinding<Atoms[Key]>;
};
ExtractViewFilters
type ExtractViewFilters<Atoms extends StateAtoms> = Atoms[keyof Atoms] extends (infer Atom) ? Atom extends FilterBar<infer Filters> ? Filters : never : never;
FieldBuilderContract
interface FieldBuilderContract<Name extends string, Value = unknown, in Row = unknown> extends Nodeable<Field> {
readonly [FIELD_NAME]: Name;
readonly [FIELD_VALUE]?: Value;
readonly [FIELD_ROW]?: (row: Row) => void;
[VALUE_FOR](record: never, node: Field, report: ReportDefect, options?: never): unknown;
}
FieldRemapper
type FieldRemapper<Role extends FieldRole, Kind extends GetFieldKindsForRole<Role>> = (value: unknown, field: Extract<Field, {
kind: Kind;
}>, record: Record<string, unknown>, parent: FieldRemappers, report: ReportDefect) => unknown;
FieldRemapperFallbackRole
type FieldRemapperFallbackRole = 'display' | 'input';
FieldRemapperMap
type FieldRemapperMap<Role extends FieldRole> = Prettify<{
[Kind in Exclude<GetFieldKindsForRole<Role>, 'ref' | 'has'>]: FieldRemapper<Role, Kind>;
}>;
FilterBuilderContract
interface FilterBuilderContract<Name extends string, Value = unknown> extends Nodeable<Filter> {
readonly [FILTER_NAME]: Name;
readonly [FILTER_VALUE]?: Value;
[PARSE](raw: unknown): Value | undefined;
[STRINGIFY](value: Value): string | string[];
}
FormInitialData
type FormInitialData<Input> = {
[Key in keyof Input]?: unknown;
};
GetArgsFor
type GetArgsFor<Params extends ParamNames> = {
readonly [K in keyof Params]: string | number;
};
GetFieldBuildersFor
type GetFieldBuildersFor<Input, Row = unknown> = {
[Name in Extract<keyof Input, string>]: FieldBuilderContract<Name, Input[Name], Row>;
}[Extract<keyof Input, string>];
GetFieldRoleSelectionsFor
type GetFieldRoleSelectionsFor<Fields extends readonly FieldBuilderContract<string, unknown, never>[]> = Prettify<{
[Name in ExtractFieldNames<Fields>]?: GetFieldRolesForKind<ExtractFieldByName<Fields, Name> extends Nodeable<infer Node extends Field> ? Node['kind'] : never>;
}>;
GetFiltersFor
type GetFiltersFor<View extends Linkable> = View extends ViewDefinition<string, string, ParamNames, infer Atoms> ? [
ExtractViewFilters<Atoms>
] extends [
never
] ? {
[name: string]: never;
} : Partial<ParseFilters<ExtractViewFilters<Atoms>>> : never;
GetLookupArgsFor
type GetLookupArgsFor<Params extends ParamNames> = {
readonly [K in keyof Params]: FieldBuilderContract<string, unknown, never> | string | number | boolean;
};
GetParamValuesFor
type GetParamValuesFor<Names extends ParamNames> = {
readonly [K in Names[number]]: string;
};
HttpRequestOptions
type HttpRequestOptions = {
query(): Record<string, string | string[]>;
headers(): Record<string, string>;
cookies(): Record<string, string>;
json(): Promise<unknown>;
formdata(): Promise<FormData>;
};
Linkable
type Linkable = ViewDefinition<string, string, ParamNames, any>;
LookupResolver
type LookupResolver<Fields extends readonly FieldBuilderContract<string, unknown, never>[], Params extends ParamNames = readonly [
]> = (ctx: RequestContext<'lookup', Params>, lookup: LookupBuilder) => AsyncOrSync<LookupBuilder<Fields> | Respondable<ErrorResponse>>;
Middleware
type Middleware = (ctx: RequestContext, request: HttpRequest | undefined, next: NextFn) => AsyncOrSync<void | Respondable<RedirectResponse | ErrorResponse>>;
MiddlewareLoader
type MiddlewareLoader = LazyImport<Middleware>;
NavigationEntry
type NavigationEntry<ResourceKey extends string> = {
label: string;
resource: ResourceKey;
view: string;
icon?: string;
};
NavigationGroup
type NavigationGroup<ResourceKey extends string> = {
label: string;
items: NavigationEntry<ResourceKey>[];
};
NavigationItem
type NavigationItem<ResourceKey extends string> = NavigationEntry<ResourceKey> | NavigationGroup<ResourceKey>;
Nodeable
interface Nodeable<T> {
[TO_NODE](ctx: RequestContext): T;
[VALUE_FOR]?(record: never, node: T, report: ReportDefect, options?: never): unknown;
}
PaginatorState
type PaginatorState = {
page: number;
perPage: number;
};
ParamNames
type ParamNames = readonly string[];
ParseFilters
type ParseFilters<Filters extends readonly FilterBuilderContract<string>[]> = {
readonly [Name in ExtractFilterNames<Filters>]: ExtractFilterValue<ExtractFilterByName<Filters, Name>> | undefined;
};
ParseState
type ParseState<Atoms extends StateAtoms> = {
readonly [Key in keyof Atoms]: Atoms[Key] extends StateAtomContract<infer Value> ? Value : never;
};
PickFieldBuilders
type PickFieldBuilders<Fields extends readonly FieldBuilderContract<string, unknown, never>[], Keys extends readonly string[]> = {
-readonly [Index in keyof Keys]: Extract<Fields[number], FieldBuilderContract<Keys[Index]>>;
};
Producer
type Producer<Node extends Block = Block> = Nodeable<Node> | Resolvable<Node> | ZoneBuilder<Node, any>;
ReportDefect
type ReportDefect = (reason: string) => undefined;
RequestContextOptions
type RequestContextOptions<Kind extends RequestKind, Params extends ParamNames = ParamNames, Data = Kind extends 'action' ? unknown : never, SearchQuery = Kind extends 'lookup' ? string : never> = {
kind: Kind;
resource: string;
name: string;
args?: string[];
paramValues?: GetParamValuesFor<Params>;
mode?: TargetMode;
search?: SearchParams;
} & (Kind extends 'action' ? {
data: Data;
} : Kind extends 'lookup' ? {
searchQuery: SearchQuery;
} : object);
RequestKind
type RequestKind = 'view' | 'zone' | 'action' | 'lookup';
Resolvable
interface Resolvable<Node> {
[RESOLVE](ctx: RequestContext<'view' | 'zone'>): Promise<Node>;
[RESOLVE_FOR](ctx: RequestContext<'view' | 'zone'>, zone: string): Promise<ZoneNode | undefined>;
}
ResourceLoader
type ResourceLoader = LazyImport<unknown>;
Respondable
interface Respondable<ResponseType extends Response = Response> {
[TO_RESPONSE](): ResponseType;
}
SorterState
type SorterState<Columns extends readonly string[] = readonly string[]> = {
column: Columns[number];
direction: 'asc' | 'desc';
}[];
StateAtomContract
interface StateAtomContract<Value = unknown> {
readonly [KEYWORD]: string;
readonly definesResult: boolean;
readonly dependsOnResult: boolean;
fieldNames(): string[];
[PARSE](values: SearchValues): Value;
}
StateAtoms
type StateAtoms = Record<string, StateAtomContract>;
StateBinding
type StateBinding<Atom extends StateAtomContract> = {
atom: Atom;
zone: string | undefined;
};
TableFooterRow
type TableFooterRow<FieldNames extends string> = {
label: string;
values: Partial<Record<FieldNames, unknown>>;
};
TargetBuilderContract
interface TargetBuilderContract<Row> {
[TO_NODE](ctx: RequestContext): TargetDefinition;
[VALUE_FOR](record: Row, report: ReportDefect, options: {
ctx: RequestContext;
onDefect: DefectReporter;
requireLabel?: boolean;
repeated?: boolean;
}): TargetValue | undefined;
}
Transport
type Transport = {
request: HttpRequest;
};
ValidActionResponse
type ValidActionResponse = (SuccessResponse & {
node?: undefined;
}) | RedirectResponse | RefreshResponse | ErrorResponse;
ValidLookupResponse
type ValidLookupResponse = (SuccessResponse & {
node: LookupNode;
}) | RedirectResponse | ErrorResponse;
ValidViewResponse
type ValidViewResponse = (SuccessResponse & {
node: ViewNode;
}) | RedirectResponse | ErrorResponse;
ValidZoneResponse
type ValidZoneResponse = (SuccessResponse & {
node: ZoneNode;
}) | RedirectResponse | ErrorResponse;
ViewAddress
type ViewAddress = {
resource: string;
view: string;
args: string[];
key: string;
};
ViewResolver
type ViewResolver<Params extends ParamNames = readonly [
], Atoms extends StateAtoms = {}> = (ctx: RequestContext<'view' | 'zone', Params>, view: ViewBuilder<Atoms>) => AsyncOrSync<OneOrMore<Producer> | Respondable<RedirectResponse | ErrorResponse>>;
ViewTargetOptions
type ViewTargetOptions<View extends Linkable, Row> = {
mode?: TargetMode;
filters?: GetFiltersFor<View> | ((record: Row) => GetFiltersFor<View>);
};
VisitPresentation
type VisitPresentation<View extends Linkable> = TargetPresentation & {
skip?: boolean;
filters?: GetFiltersFor<View>;
};
ZoneResolver
type ZoneResolver<Node extends Block, Atoms extends StateAtoms = {}> = (ctx: RequestContext<'view' | 'zone'>, zone: ZoneBuilder<Node, Atoms>) => AsyncOrSync<OneOrMore<Nodeable<Node> | Resolvable<Node>>>;