UNPKG

@codeforbreakfast/eventsourcing-commands

Version:

Wire command validation and dispatch for event sourcing systems - External boundary layer with schema validation

233 lines 10.1 kB
import { Schema, Effect } from 'effect'; import type { ReadonlyDeep } from 'type-fest'; /** * Wire command for transport/serialization * Used by APIs, message queues, and other external interfaces */ export declare const WireCommand: Schema.Struct<{ id: typeof Schema.String; target: typeof Schema.String; name: typeof Schema.String; payload: typeof Schema.Unknown; }>; export type WireCommand = typeof WireCommand.Type; /** * Base domain command interface * The validated internal representation */ export interface DomainCommand<TPayload> { readonly id: string; readonly target: string; readonly name: string; readonly payload: TPayload; } declare const CommandValidationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & { readonly _tag: "CommandValidationError"; } & Readonly<A>; export declare class CommandValidationError extends CommandValidationError_base<{ readonly commandId: string; readonly commandName: string; readonly validationErrors: ReadonlyArray<string>; }> { } declare const CommandHandlerNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & { readonly _tag: "CommandHandlerNotFoundError"; } & Readonly<A>; export declare class CommandHandlerNotFoundError extends CommandHandlerNotFoundError_base<{ readonly commandId: string; readonly commandName: string; readonly availableHandlers: ReadonlyArray<string>; }> { } declare const CommandExecutionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & { readonly _tag: "CommandExecutionError"; } & Readonly<A>; export declare class CommandExecutionError extends CommandExecutionError_base<{ readonly commandId: string; readonly commandName: string; readonly cause: unknown; }> { } declare const AggregateNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & { readonly _tag: "AggregateNotFoundError"; } & Readonly<A>; export declare class AggregateNotFoundError extends AggregateNotFoundError_base<{ readonly commandId: string; readonly aggregateId: string; readonly aggregateType: string; }> { } declare const ConcurrencyConflictError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & { readonly _tag: "ConcurrencyConflictError"; } & Readonly<A>; export declare class ConcurrencyConflictError extends ConcurrencyConflictError_base<{ readonly commandId: string; readonly expectedVersion: number; readonly actualVersion: number; }> { } export declare const CommandSuccess: Schema.Struct<{ _tag: Schema.Literal<["Success"]>; position: Schema.Struct<{ streamId: Schema.brand<Schema.filter<typeof Schema.String>, "EventStreamId">; eventNumber: Schema.filter<typeof Schema.Number>; }>; }>; export type CommandSuccess = typeof CommandSuccess.Type; export declare const CommandFailure: Schema.Struct<{ _tag: Schema.Literal<["Failure"]>; error: Schema.Union<[Schema.Struct<{ _tag: Schema.Literal<["ValidationError"]>; commandId: typeof Schema.String; commandName: typeof Schema.String; validationErrors: Schema.Array$<typeof Schema.String>; }>, Schema.Struct<{ _tag: Schema.Literal<["HandlerNotFound"]>; commandId: typeof Schema.String; commandName: typeof Schema.String; availableHandlers: Schema.Array$<typeof Schema.String>; }>, Schema.Struct<{ _tag: Schema.Literal<["ExecutionError"]>; commandId: typeof Schema.String; commandName: typeof Schema.String; message: typeof Schema.String; }>, Schema.Struct<{ _tag: Schema.Literal<["AggregateNotFound"]>; commandId: typeof Schema.String; aggregateId: typeof Schema.String; aggregateType: typeof Schema.String; }>, Schema.Struct<{ _tag: Schema.Literal<["ConcurrencyConflict"]>; commandId: typeof Schema.String; expectedVersion: typeof Schema.Number; actualVersion: typeof Schema.Number; }>, Schema.Struct<{ _tag: Schema.Literal<["UnknownError"]>; commandId: typeof Schema.String; message: typeof Schema.String; }>]>; }>; export type CommandFailure = typeof CommandFailure.Type; export declare const CommandResult: Schema.Union<[Schema.Struct<{ _tag: Schema.Literal<["Success"]>; position: Schema.Struct<{ streamId: Schema.brand<Schema.filter<typeof Schema.String>, "EventStreamId">; eventNumber: Schema.filter<typeof Schema.Number>; }>; }>, Schema.Struct<{ _tag: Schema.Literal<["Failure"]>; error: Schema.Union<[Schema.Struct<{ _tag: Schema.Literal<["ValidationError"]>; commandId: typeof Schema.String; commandName: typeof Schema.String; validationErrors: Schema.Array$<typeof Schema.String>; }>, Schema.Struct<{ _tag: Schema.Literal<["HandlerNotFound"]>; commandId: typeof Schema.String; commandName: typeof Schema.String; availableHandlers: Schema.Array$<typeof Schema.String>; }>, Schema.Struct<{ _tag: Schema.Literal<["ExecutionError"]>; commandId: typeof Schema.String; commandName: typeof Schema.String; message: typeof Schema.String; }>, Schema.Struct<{ _tag: Schema.Literal<["AggregateNotFound"]>; commandId: typeof Schema.String; aggregateId: typeof Schema.String; aggregateType: typeof Schema.String; }>, Schema.Struct<{ _tag: Schema.Literal<["ConcurrencyConflict"]>; commandId: typeof Schema.String; expectedVersion: typeof Schema.Number; actualVersion: typeof Schema.Number; }>, Schema.Struct<{ _tag: Schema.Literal<["UnknownError"]>; commandId: typeof Schema.String; message: typeof Schema.String; }>]>; }>]>; export type CommandResult = typeof CommandResult.Type; export declare const isCommandSuccess: (u: unknown, overrideOptions?: import("effect/SchemaAST").ParseOptions | number) => u is { readonly _tag: "Success"; readonly position: { readonly streamId: string & import("effect/Brand").Brand<"EventStreamId">; readonly eventNumber: number; }; }; export declare const isCommandFailure: (u: unknown, overrideOptions?: import("effect/SchemaAST").ParseOptions | number) => u is { readonly _tag: "Failure"; readonly error: { readonly commandId: string; readonly commandName: string; readonly validationErrors: readonly string[]; readonly _tag: "ValidationError"; } | { readonly commandId: string; readonly commandName: string; readonly availableHandlers: readonly string[]; readonly _tag: "HandlerNotFound"; } | { readonly commandId: string; readonly commandName: string; readonly _tag: "ExecutionError"; readonly message: string; } | { readonly commandId: string; readonly aggregateId: string; readonly aggregateType: string; readonly _tag: "AggregateNotFound"; } | { readonly commandId: string; readonly expectedVersion: number; readonly actualVersion: number; readonly _tag: "ConcurrencyConflict"; } | { readonly commandId: string; readonly _tag: "UnknownError"; readonly message: string; }; }; /** * Command definition that pairs a name with its payload schema */ export interface CommandDefinition<TName extends string, TPayload> { readonly name: TName; readonly payloadSchema: Schema.Schema<TPayload, any>; } /** * Creates a command definition */ export declare const defineCommand: <TName extends string, TPayload, TPayloadInput>(name: TName, payloadSchema: Schema.Schema<TPayload, TPayloadInput>) => CommandDefinition<TName, TPayload>; /** * Helper type to extract command union from command definitions */ export type CommandFromDefinitions<T extends readonly CommandDefinition<string, any>[]> = { readonly [K in keyof T]: T[K] extends CommandDefinition<infer Name, infer Payload> ? { readonly id: string; readonly target: string; readonly name: Name; readonly payload: Payload; } : never; }[number]; /** * Builds a discriminated union schema from command definitions * This creates an exhaustive schema that can parse any registered command */ export declare const buildCommandSchema: <const T extends readonly CommandDefinition<string, any>[]>(commands: ReadonlyDeep<T>) => Schema.Schema<CommandFromDefinitions<T>, { readonly id: string; readonly target: string; readonly name: string; readonly payload: unknown; }>; /** * Validates and transforms a wire command into a domain command */ export declare const validateCommand: <TPayload, TPayloadInput>(payloadSchema: Schema.Schema<TPayload, TPayloadInput>) => (wireCommand: ReadonlyDeep<WireCommand>) => Effect.Effect<DomainCommand<TPayload>, CommandValidationError, never>; /** * Command matcher function type * Uses Effect's pattern matching for exhaustive command handling */ export type CommandMatcher<TCommands extends DomainCommand<any>> = (command: ReadonlyDeep<TCommands>) => Effect.Effect<CommandResult, never, never>; export {}; //# sourceMappingURL=commands.d.ts.map