UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

126 lines 7.15 kB
/** Behavior when a query collection is empty. */ export type QueryEmptyBehavior = "omit" | "preserve"; /** Scalar query parameter transport supported by OpenAPI form encoding. */ export type QueryScalarTransport = { readonly kind: "string"; } | { readonly kind: "number"; } | { readonly kind: "integer"; } | { readonly kind: "boolean"; } | { readonly kind: "date-time"; } | { readonly kind: "date"; }; /** Repeated scalar query parameter transport. */ export type QueryArrayTransport<TItem extends QueryScalarTransport = QueryScalarTransport> = { readonly kind: "array"; readonly item: TItem; readonly empty: QueryEmptyBehavior; }; /** Fields supported inside one flat OpenAPI deepObject parameter. */ export type QueryDeepObjectFields = Readonly<Record<string, QueryScalarTransport>>; /** Flat OpenAPI deepObject query parameter transport. */ export type QueryDeepObjectTransport<TFields extends QueryDeepObjectFields = QueryDeepObjectFields> = { readonly kind: "deep-object"; readonly fields: TFields; readonly empty: QueryEmptyBehavior; }; /** Transport for one top-level query parameter. */ export type QueryFieldTransport = QueryScalarTransport | QueryArrayTransport | QueryDeepObjectTransport; /** Query field declarations keyed by their HTTP parameter names. */ export type QueryTransportFields = Readonly<Record<string, QueryFieldTransport>>; /** * Deterministic HTTP transport for a contract query schema. * * The same declaration drives server decoding, typed-client encoding, and * OpenAPI parameter serialization. */ export type QueryTransport<TFields extends QueryTransportFields = QueryTransportFields> = { readonly kind: "query-transport"; readonly fields: TFields; }; /** One deterministic query transport failure. */ export type QueryTransportIssue = { readonly message: string; readonly path: readonly (string | number)[]; }; /** Raised when an HTTP query cannot be encoded or decoded as declared. */ export declare class QueryTransportError extends Error { readonly issues: readonly QueryTransportIssue[]; constructor(issue: QueryTransportIssue); } /** Logical value encoded by one query field transport. */ export type QueryFieldTransportInput<TField extends QueryFieldTransport> = TField extends { readonly kind: "string" | "date-time"; } ? string : TField extends { readonly kind: "number" | "integer"; } ? number : TField extends { readonly kind: "boolean"; } ? boolean : TField extends { readonly kind: "date"; } ? Date : TField extends QueryArrayTransport<infer TItem> ? readonly QueryFieldTransportInput<TItem>[] : TField extends QueryDeepObjectTransport<infer TFields> ? { [K in keyof TFields]?: QueryFieldTransportInput<TFields[K]>; } : never; /** Logical values encoded by a query transport declaration. */ export type QueryTransportInput<TTransport extends QueryTransport> = { [K in keyof TTransport["fields"]]?: QueryFieldTransportInput<TTransport["fields"][K]>; }; type QueryKeys<T> = Extract<keyof T, string>; type DeclaredQueryTransportFields<TTransport extends QueryTransport> = TTransport extends QueryTransport<infer TFields> ? TFields : never; type QueryFieldMatches<TInput, TField extends QueryFieldTransport> = TField extends QueryArrayTransport<infer TItem> ? Exclude<TInput, undefined> extends readonly (infer TEntry)[] ? QueryFieldMatches<TEntry, TItem> : false : TField extends QueryDeepObjectTransport<infer TFields> ? Exclude<TInput, undefined> extends object ? Exclude<QueryKeys<Exclude<TInput, undefined>>, keyof TFields> extends never ? Exclude<keyof TFields, QueryKeys<Exclude<TInput, undefined>>> extends never ? false extends { [K in keyof TFields]: K extends keyof Exclude<TInput, undefined> ? QueryFieldMatches<Exclude<TInput, undefined>[K], TFields[K]> : false; }[keyof TFields] ? false : true : false : false : false : Exclude<TInput, undefined> extends QueryFieldTransportInput<TField> ? true : false; type QueryTransportMatchesInput<TInput, TTransport extends QueryTransport> = unknown extends TInput ? true : TInput extends object ? keyof DeclaredQueryTransportFields<TTransport> extends never ? QueryKeys<TInput> extends never ? true : TInput[QueryKeys<TInput>] extends never ? true : false : Exclude<QueryKeys<TInput>, keyof DeclaredQueryTransportFields<TTransport>> extends never ? Exclude<keyof DeclaredQueryTransportFields<TTransport>, QueryKeys<TInput>> extends never ? false extends { [K in keyof DeclaredQueryTransportFields<TTransport>]: K extends keyof TInput ? QueryFieldMatches<TInput[K], DeclaredQueryTransportFields<TTransport>[K]> : false; }[keyof DeclaredQueryTransportFields<TTransport>] ? false : true : false : false : false; /** * Type-level contract used by `.query(...)` to keep schema input fields and * transport declarations aligned. */ export type QueryTransportCompatibility<TInput, TTransport extends QueryTransport> = QueryTransportMatchesInput<TInput, TTransport> extends true ? unknown : { readonly __beignetQueryTransportMismatch: "Query transport fields and value kinds must match the Standard Schema input type."; }; type EmptyOptions = { /** * Empty collections are omitted by default because standard OpenAPI query * serialization cannot distinguish them from absent parameters. `preserve` * opts into Beignet's versioned typed-client extension. */ empty?: QueryEmptyBehavior; }; /** Built-in, OpenAPI-inspectable query parameter transports. */ export declare const query: { readonly string: () => QueryScalarTransport & { readonly kind: "string"; }; readonly number: () => QueryScalarTransport & { readonly kind: "number"; }; readonly integer: () => QueryScalarTransport & { readonly kind: "integer"; }; readonly boolean: () => QueryScalarTransport & { readonly kind: "boolean"; }; readonly dateTime: () => QueryScalarTransport & { readonly kind: "date-time"; }; readonly date: () => QueryScalarTransport & { readonly kind: "date"; }; readonly array: <const TItem extends QueryScalarTransport>(item: TItem, options?: EmptyOptions) => QueryArrayTransport<TItem>; readonly deepObject: <const TFields extends QueryDeepObjectFields>(fields: TFields, options?: EmptyOptions) => QueryDeepObjectTransport<TFields>; }; /** Define a reusable deterministic query transport. */ export declare function defineQueryTransport<const TFields extends QueryTransportFields>(fields: TFields): QueryTransport<TFields>; /** Decode URL query values exactly once according to a contract transport. */ export declare function decodeQueryTransport(transport: QueryTransport, searchParams: URLSearchParams): Record<string, unknown>; /** Encode typed query input according to the same contract transport. */ export declare function encodeQueryTransport(transport: QueryTransport, value: unknown): URLSearchParams; /** OpenAPI schema keywords implied by a query field transport. */ export declare function queryTransportSchema(field: QueryFieldTransport): Record<string, unknown>; export {}; //# sourceMappingURL=query-transport.d.ts.map