~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atlibs

0
0
main
73 lines · 3.9 KB Raw History
// Types for build.js: a route's NSID is one of the caller's hooks and its target's module implements it; an
// instance's input is its module's config.

type Type = "string" | "integer" | "number" | "boolean" | "object" | "array";
type ValueOf<T> = T extends "integer" | "number" ? number : T extends "boolean" ? boolean : T extends "array" ? unknown[] : T extends "object" ? Record<string, unknown> : string;

export interface Field {
	readonly key: string;
	readonly type?: Type;
	readonly required?: boolean;
}
export interface Binding {
	readonly key: string;
	readonly pin?: string;
	readonly hooks?: readonly { readonly nsid: string; readonly reason: string }[];
	readonly implements?: readonly { readonly nsid: string; readonly entry: string }[];
	readonly config?: readonly Field[];
	readonly entries: readonly string[];
}
type Of<L, K extends string> = L extends readonly (infer X)[] ? (X extends { readonly [P in K]: infer V } ? V : never) : never;
export type HookOf<M> = M extends { readonly hooks: infer H } ? Of<H, "nsid"> : never;
export type ImplOf<M> = M extends { readonly implements: infer I } ? Of<I, "nsid"> : never;
export type EntryOf<M> = M extends { readonly entries: readonly (infer E)[] } ? E : never;

/** A parameter's placeholder, typed by the parameter's type; a host value fits any field. */
export interface Param<T extends Type = Type> {
	readonly $param: string;
	readonly __type?: T;
}
export interface Host {
	readonly $host: string;
}
type FieldsOf<M> = M extends { readonly config: readonly (infer F)[] } ? F : never;
type Arg<F> = F extends { readonly type: infer T } ? ValueOf<T> | Param<T & Type> | Host : string | Param<"string"> | Host;
/** The input an instance of M may have: its config fields, a required one required. */
type KeyOf<F> = F extends { readonly key: infer K extends string } ? K : never;
export type InputOf<M> = { [F in FieldsOf<M> as F extends { readonly required: true } ? KeyOf<F> : never]: Arg<F> } & {
	[F in FieldsOf<M> as F extends { readonly required: true } ? never : KeyOf<F>]?: Arg<F>;
};

export interface Instance<M extends Binding> {
	readonly name: string;
	readonly module: M;
}
export interface Handler {
	readonly handler: string;
}
export interface Policy {
	readonly instance: string;
	readonly entry?: string;
	readonly args?: unknown;
}
/** A target `T` for contract `N`: a type error names what is missing. */
type Serves<N extends string, T extends Binding> = [N] extends [ImplOf<T>] ? unknown : { readonly [K in `${T["key"]} does not implement ${N}`]: true };

export interface Composition {
	param<const T extends Type = "string">(
		key: string,
		opts?: { label?: string; type?: T; required?: boolean; description?: string; secret?: boolean; minimum?: number; maximum?: number; values?: { default?: ValueOf<T>; enum?: ValueOf<T>[] } },
	): Param<T>;
	instance<M extends Binding>(name: string, mod: M, opts?: { pin?: string | false; session?: string; input?: InputOf<M>; calls?: string[]; policies?: Policy[]; budget?: Record<string, number> }): Instance<M>;
	handler(name: string, description?: string): Handler;
	route<F extends Binding, const N extends HookOf<F>, T extends Binding>(from: Instance<F>, nsid: N, to: Instance<T> & Serves<NoInfer<N>, NoInfer<T>>, reason?: string, opts?: { policies?: Policy[] }): void;
	route<F extends Binding, const N extends HookOf<F>>(from: Instance<F>, nsid: N, to: Handler, reason?: string, opts?: { policies?: Policy[] }): void;
	export<T extends Binding, const N extends ImplOf<T>>(nsid: N, inst: Instance<T>): void;
	export<T extends Binding>(nsid: string, inst: Instance<T>, entry: EntryOf<T>): void;
	build(): Promise<Record<string, unknown>>;
	json(): Promise<string>;
}

export function composition(head: { name: string; description?: string; limits?: { depth?: number; calls?: number } }): Composition;
export function host(name: string): Host;
export function policy<M extends Binding>(inst: Instance<M>, entry?: EntryOf<M>, args?: unknown): Policy;