import { mapKeyValues } from "../internal/object-utils"; import { Simplify } from "../internal/types"; import { inputBrand, outputBrand, validateServiceDefinition } from "./service-definition"; import { OperationDefinition, ServiceDefinition } from "./service-definition"; /** * Construct a service definition for a collection of operations. * * @experimental */ export function service( name: string, operations: Ops, ): ServiceDefinition>> { const service = { name, operations: mapKeyValues(operations, (key, op: PartialOperation) => ({ ...op, name: op.name || key, })), } as ServiceDefinition>; validateServiceDefinition(service); return service; } /** * Construct an operation definition as part of a service contract. * * @experimental */ export function operation(op?: OperationOptions): PartialOperation { return { ...op } as PartialOperation; } /** * Options for the {@link operation} function. * * @experimental */ export interface OperationOptions<_I, _O> { name?: string; } /** * A named collection of partial operation handlers. Input for the {@link service} function. * * @experimental */ export type PartialOperationMap = Record>; /** * A type that transforms a {@link PartialOperationMap} into an {@link OperationMap}. * * @experimental */ export type OperationMapFromPartial = { [K in keyof T & string]: T[K] extends PartialOperation ? OperationDefinition : never; }; /** * A partial {@link OperationDefinition} that is used to define an operation in a {@link ServiceDefinition}. * * The difference between this and {@link OperationDefinition} is that the name is optional. * * @experimental */ export interface PartialOperation { name?: string; [inputBrand]: I; [outputBrand]: O; }