cvx-kit 0.1.8 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +28 -28
- package/dist/agent-tools.d.mts +5 -5
- package/dist/agent-tools.mjs.map +1 -1
- package/dist/auth.d.mts +39 -289
- package/dist/auth.mjs.map +1 -1
- package/dist/components/approvals/_generated/api.d.mts +3 -4
- package/dist/components/approvals/_generated/api.mjs.map +1 -1
- package/dist/components/approvals/_generated/component.d.mts +1 -2
- package/dist/components/approvals/_generated/dataModel.d.mts +4 -5
- package/dist/components/approvals/_generated/server.d.mts +12 -13
- package/dist/components/approvals/_generated/server.mjs.map +1 -1
- package/dist/components/approvals/audit.d.mts +8 -8
- package/dist/components/approvals/audit.mjs +1 -1
- package/dist/components/approvals/audit.mjs.map +1 -1
- package/dist/components/approvals/client.d.mts +10 -10
- package/dist/components/approvals/client.mjs.map +1 -1
- package/dist/components/approvals/constants.d.mts +30 -30
- package/dist/components/approvals/constants.mjs.map +1 -1
- package/dist/components/approvals/convex.config.mjs.map +1 -1
- package/dist/components/approvals/decisions.d.mts +6 -6
- package/dist/components/approvals/decisions.mjs.map +1 -1
- package/dist/components/approvals/functions.d.mts +3 -3
- package/dist/components/approvals/functions.mjs.map +1 -1
- package/dist/components/approvals/health.d.mts +2 -2
- package/dist/components/approvals/health.mjs.map +1 -1
- package/dist/components/approvals/requests.d.mts +8 -8
- package/dist/components/approvals/requests.mjs.map +1 -1
- package/dist/components/approvals/validators.d.mts +29 -29
- package/dist/components/approvals/validators.mjs +1 -1
- package/dist/components/approvals/validators.mjs.map +1 -1
- package/dist/components/approvals/workflow.d.mts +3 -3
- package/dist/components/approvals/workflow.mjs.map +1 -1
- package/dist/components/approvals/workflow_steps.d.mts +15 -15
- package/dist/components/approvals/workflow_steps.mjs.map +1 -1
- package/dist/components/foundation/_generated/api.d.mts +3 -4
- package/dist/components/foundation/_generated/api.mjs.map +1 -1
- package/dist/components/foundation/_generated/component.d.mts +1 -2
- package/dist/components/foundation/_generated/dataModel.d.mts +4 -5
- package/dist/components/foundation/_generated/server.d.mts +12 -13
- package/dist/components/foundation/_generated/server.mjs.map +1 -1
- package/dist/components/foundation/client.d.mts +13 -13
- package/dist/components/foundation/client.mjs.map +1 -1
- package/dist/components/foundation/convex.config.mjs.map +1 -1
- package/dist/components/foundation/functions.d.mts +2 -2
- package/dist/components/foundation/functions.mjs.map +1 -1
- package/dist/components/foundation/modules/command/command.d.mts +14 -14
- package/dist/components/foundation/modules/command/command.mjs.map +1 -1
- package/dist/components/foundation/modules/command/lifecycle.d.mts +12 -13
- package/dist/components/foundation/modules/command/lifecycle.mjs.map +1 -1
- package/dist/components/foundation/modules/observability/observability.d.mts +4 -4
- package/dist/components/foundation/modules/observability/observability.mjs.map +1 -1
- package/dist/components/foundation/modules/query/query.d.mts +5 -5
- package/dist/components/foundation/modules/query/query.mjs.map +1 -1
- package/dist/components/foundation/operation.d.mts +5 -6
- package/dist/components/foundation/operation.mjs.map +1 -1
- package/dist/components/foundation/result.d.mts +6 -6
- package/dist/components/foundation/result.mjs.map +1 -1
- package/dist/components/foundation/telemetry.d.mts +2 -2
- package/dist/components/foundation/telemetry.mjs.map +1 -1
- package/dist/crud.d.mts +6 -5
- package/dist/crud.mjs.map +1 -1
- package/dist/effect.d.mts +3 -2
- package/dist/effect.mjs +1 -1
- package/dist/errors.d.mts +4 -4
- package/dist/errors.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/middleware.d.mts +2 -3
- package/dist/middleware.mjs.map +1 -1
- package/dist/modules/contracts/contract.d.mts +12 -13
- package/dist/modules/contracts/contract.mjs.map +1 -1
- package/dist/modules/contracts/convex.d.mts +3 -5
- package/dist/modules/contracts/convex.mjs.map +1 -1
- package/dist/modules/contracts/errors.d.mts +8 -9
- package/dist/modules/contracts/errors.mjs +1 -1
- package/dist/modules/contracts/errors.mjs.map +1 -1
- package/dist/modules/contracts/exposure.d.mts +13 -14
- package/dist/modules/contracts/exposure.mjs +1 -1
- package/dist/modules/contracts/exposure.mjs.map +1 -1
- package/dist/modules/contracts/idempotency.d.mts +15 -16
- package/dist/modules/contracts/idempotency.mjs +1 -1
- package/dist/modules/contracts/idempotency.mjs.map +1 -1
- package/dist/modules/contracts/standard.d.mts +2 -3
- package/dist/modules/contracts/standard.mjs.map +1 -1
- package/dist/modules/contracts/workflow.d.mts +26 -27
- package/dist/modules/contracts/workflow.mjs.map +1 -1
- package/dist/modules/effect/api-runtime.d.mts +10 -11
- package/dist/modules/effect/api-runtime.mjs +1 -1
- package/dist/modules/effect/api-runtime.mjs.map +1 -1
- package/dist/modules/effect/api-zod.d.mts +2 -3
- package/dist/modules/effect/api-zod.mjs.map +1 -1
- package/dist/modules/effect/api.d.mts +4 -5
- package/dist/modules/effect/api.mjs.map +1 -1
- package/dist/modules/effect/auth.d.mts +43 -0
- package/dist/modules/effect/auth.mjs +2 -0
- package/dist/modules/effect/auth.mjs.map +1 -0
- package/dist/modules/effect/client.d.mts +1 -1
- package/dist/modules/effect/client.mjs +1 -1
- package/dist/modules/effect/command.d.mts +4 -5
- package/dist/modules/effect/command.mjs +1 -1
- package/dist/modules/effect/command.mjs.map +1 -1
- package/dist/modules/effect/crud.d.mts +7 -8
- package/dist/modules/effect/crud.mjs +1 -1
- package/dist/modules/effect/crud.mjs.map +1 -1
- package/dist/modules/effect/errors.d.mts +1 -2
- package/dist/modules/effect/errors.mjs.map +1 -1
- package/dist/modules/effect/foundation.d.mts +3 -4
- package/dist/modules/effect/foundation.mjs.map +1 -1
- package/dist/modules/effect/idempotency.d.mts +2 -3
- package/dist/modules/effect/idempotency.mjs.map +1 -1
- package/dist/modules/effect/normalize.d.mts +2 -3
- package/dist/modules/effect/normalize.mjs.map +1 -1
- package/dist/modules/effect/operation.d.mts +17 -18
- package/dist/modules/effect/operation.mjs.map +1 -1
- package/dist/modules/effect/query.d.mts +3 -4
- package/dist/modules/effect/query.mjs +1 -1
- package/dist/modules/effect/query.mjs.map +1 -1
- package/dist/modules/effect/schema.d.mts +8 -9
- package/dist/modules/effect/schema.mjs.map +1 -1
- package/dist/modules/effect/workflow.d.mts +5 -6
- package/dist/modules/effect/workflow.mjs +1 -1
- package/dist/modules/effect/workflow.mjs.map +1 -1
- package/dist/oxlint/architecture.d.mts +6 -7
- package/dist/oxlint/architecture.mjs +1 -1
- package/dist/oxlint/architecture.mjs.map +1 -1
- package/dist/oxlint/ast.d.mts +22 -23
- package/dist/oxlint/ast.mjs +1 -1
- package/dist/oxlint/ast.mjs.map +1 -1
- package/dist/oxlint/ownership.d.mts +2 -3
- package/dist/oxlint/ownership.mjs +1 -1
- package/dist/oxlint/ownership.mjs.map +1 -1
- package/dist/oxlint.d.mts +4 -4
- package/dist/oxlint.mjs +1 -1
- package/dist/oxlint.mjs.map +1 -1
- package/dist/state-machine.d.mts +1 -2
- package/dist/state-machine.mjs.map +1 -1
- package/dist/tenancy.d.mts +6 -6
- package/dist/tenancy.mjs.map +1 -1
- package/dist/triggers.d.mts +6 -6
- package/dist/triggers.mjs.map +1 -1
- package/dist/webhooks.d.mts +5 -6
- package/dist/webhooks.mjs.map +1 -1
- package/dist/zod-table.d.mts +10 -10
- package/dist/zod-table.mjs.map +1 -1
- package/docs/auth.md +131 -1
- package/docs/effect.md +8 -2
- package/docs/llms.md +41 -20
- package/docs/oxlint.md +1 -1
- package/docs/upgrading.md +9 -1
- package/docs/zod-table.md +1 -1
- package/package.json +21 -15
- package/scripts/test-packed-auth.mjs +72 -0
- package/scripts/test-packed-effect.mjs +2 -1
- package/scripts/test-packed-ids.mjs +2 -2
- package/dist/node_modules/@standard-schema/spec/dist/index.d.mts +0 -79
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":["#kernel","#observability","#writeAudit","#checkPermission","#defaults","CommandKernelClass","#execute"],"sources":["../../../src/components/foundation/client.ts"],"sourcesContent":["import type { Value } from 'convex/values'\nimport {\n\tCommand as CommandKernelClass,\n\ttype CommandExecution,\n\ttype CommandHandlerResult,\n\ttype CommandInput,\n\ttype CommandRegistry,\n\ttype CommandResult,\n\ttype CommandSchema,\n\tdecodeCommandSchema,\n\tparseCommandSchema,\n} from './modules/command/command'\nimport { Observability, type ObservabilityOptions } from './modules/observability/observability'\nimport { Query } from './modules/query/query'\nimport {\n\texecuteCommandLifecycle,\n\tpromiseLifecycle,\n\tCommandPermissionError,\n\ttype PromiseExecution,\n} from './modules/command/lifecycle'\nimport { executeResultBoundary, projectResult } from './result'\nimport { emitSemanticEvent } from './telemetry'\nimport {\n\toperationFactory,\n\ttype CommandPreparation,\n\ttype OperationExtension,\n\ttype OperationHostContext,\n} from './operation'\n\n/** Shape handed to the injected audit writer; classification comes from the operation. */\nexport type AuditEntryInput = {\n\toperation: string\n\tactorId: string\n\taggregate: { type: string; id: string }\n\tmetadata?: Record<string, Value>\n\tclassification: string\n}\n\nexport type AuditWriter<Result = unknown> = (\n\tcontext: never,\n\tentry: AuditEntryInput,\n) => MaybePromise<Result>\n\ntype MaybePromise<Value> = Value | Promise<Value>\ntype OperationKey<Operations extends CommandRegistry> = Extract<keyof Operations, string>\n\nexport type AuditedOperation = Readonly<{\n\tcommand: CommandSchema\n\tresult: CommandSchema\n\tclassification: string\n\t/**\n\t * Permission slug required to execute this operation. Checked through the\n\t * Foundation's injected checkPermission BEFORE guards and the handler;\n\t * declaring a permission without injecting a checker fails closed.\n\t */\n\tpermission?: string\n\tprepare?: (context: never, command: never) => MaybePromise<CommandPreparation<never>>\n\treplayResult?: CommandSchema\n\t/**\n\t * Per-operation precondition, after the permission check and the registry\n\t * default guard, before the handler. Throw to deny — nothing has run yet.\n\t */\n\tguard?: (context: never, command: never) => MaybePromise<void>\n\t/**\n\t * Allowlist of aggregate types this operation's audit may reference. When\n\t * declared, an audit entry whose aggregate.type is not listed throws —\n\t * the audit vocabulary is enforced, not advisory.\n\t */\n\taggregates?: readonly string[]\n\t/** Per-operation middleware, inside the registry-wide chain. */\n\tmiddleware?: readonly AnyCommandMiddleware[]\n\taudit: (\n\t\tresolution: Readonly<{ command: never; result: never }>,\n\t\tcontext: never,\n\t) => MaybePromise<Omit<AuditEntryInput, 'classification'> | null>\n}>\n\n/**\n * Composable, next()-based middleware wrapping [guards → handler]. Runs\n * INSIDE the pipeline's invariants: after the permission check, before the\n * result-schema parse, aggregate allowlist, and audit — so middleware can\n * time, trace, enrich context (`next({ context })`), short-circuit, or\n * transform results, but can never skip authorization, return an invalid\n * result, or desynchronize audit from effects.\n */\nexport type CommandMiddleware<\n\tContext = never,\n\tExtension extends object = object,\n\tInput = unknown,\n\tResult = unknown,\n> = (input: {\n\toperation: string\n\tcommand: Input\n\tcontext: Context\n\tnext: (options?: {\n\t\t/** Merged into the context handed to inner middleware, guards, handler. */\n\t\tcontext?: Extension\n\t}) => Promise<Result>\n}) => Promise<Result>\n\n/** Any-context middleware — what registries and operations accept. */\n// Contravariant seam: the supertype every typed CommandMiddleware<C, E>\n// assigns to. Context, command, and next are contravariant storage slots;\n// dispatch restores the selected operation's types before invocation.\nexport type AnyCommandMiddleware<Input = never, Result = unknown, NextResult = never> = (input: {\n\toperation: string\n\tdefinition?: AuditedOperation\n\tcommand: Input\n\tcontext: never\n\tnext: (options?: { context?: object }) => Promise<NextResult>\n}) => Promise<Result>\n\n/** Registry-wide defaults applied to every operation of one Command. */\nexport type CommandDefaults = Readonly<{\n\t/** Runs before every operation's own guard. Throw to deny. */\n\tguard?: (context: never) => MaybePromise<void>\n\t/** Outermost middleware, in array order, around every operation. */\n\tmiddleware?: readonly AnyCommandMiddleware[]\n}>\n\n/** Injected permission policy: throw to deny. Host semantics, kit ordering. */\nexport type PermissionChecker = (\n\tcontext: never,\n\tinput: Readonly<{ permission: string; operation: string }>,\n) => MaybePromise<void>\n\nexport type AuditedRegistry = Readonly<Record<string, AuditedOperation>>\n\nexport type FoundationOptions = Readonly<{\n\tobservability: ObservabilityOptions &\n\t\tReadonly<{\n\t\t\t/**\n\t\t\t * In-transaction audit writer used by Command. Operations that\n\t\t\t * return an audit record get it written here automatically.\n\t\t\t */\n\t\t\twriteAudit?: AuditWriter\n\t\t}>\n\t/**\n\t * Permission policy for operations that declare a `permission`. Runs\n\t * before guards and the handler; throw to deny. An operation with a\n\t * permission but no injected checker fails closed.\n\t */\n\tcheckPermission?: PermissionChecker\n}>\n\ntype FoundationComponentApi = Readonly<{\n\tfunctions: Readonly<{ status: unknown }>\n}>\n\n/**\n * Application command protocol bound to a Foundation instance:\n * validate, observe, execute, and audit. `classification` and `audit()`\n * are mandatory per operation — auditing is type-enforced, not opt-in.\n * Obtain it by destructuring the Foundation: `const { Command } = new Foundation(...)`.\n */\nclass BoundCommand<Context, const Operations extends AuditedRegistry> {\n\tstatic withContext = operationFactory\n\treadonly #kernel: CommandKernelClass<Context, Operations>\n\treadonly #observability: Observability\n\treadonly #writeAudit: AuditWriter\n\treadonly #checkPermission: PermissionChecker | undefined\n\treadonly #defaults: CommandDefaults\n\n\t/** Declared aggregate types per operation — introspectable for tests. */\n\treadonly aggregates: Readonly<{\n\t\t[Key in OperationKey<Operations>]: Operations[Key]['aggregates']\n\t}>\n\n\tstatic operation<const Definition extends AuditedOperation>(definition: Definition): Definition {\n\t\treturn definition\n\t}\n\n\t/**\n\t * Identity helper that types a middleware against its context and the\n\t * context extension it passes downstream via next({ context }).\n\t */\n\tstatic middleware<\n\t\tContext = never,\n\t\tconst Extension extends object = object,\n\t\tInput = unknown,\n\t\tResult = unknown,\n\t>(\n\t\tmiddleware: CommandMiddleware<Context, Extension, Input, Result>,\n\t): CommandMiddleware<Context, Extension, Input, Result> {\n\t\treturn middleware\n\t}\n\n\tconstructor(\n\t\toperations: Operations,\n\t\tdeps: {\n\t\t\tobservability: Observability\n\t\t\twriteAudit: AuditWriter\n\t\t\tcheckPermission?: PermissionChecker\n\t\t\tdefaults?: CommandDefaults\n\t\t},\n\t) {\n\t\tthis.#observability = deps.observability\n\t\tthis.#writeAudit = deps.writeAudit\n\t\tthis.#checkPermission = deps.checkPermission\n\t\tthis.#defaults = deps.defaults ?? {}\n\t\t// SAFETY: this map preserves every operations key and selects its aggregates property.\n\t\tthis.aggregates = Object.freeze(\n\t\t\tObject.fromEntries(\n\t\t\t\tObject.entries(operations).map(([operation, definition]) => [\n\t\t\t\t\toperation,\n\t\t\t\t\tdefinition.aggregates,\n\t\t\t\t]),\n\t\t\t),\n\t\t) as this['aggregates']\n\t\tthis.#kernel = new CommandKernelClass<Context, Operations>({\n\t\t\toperations,\n\t\t\texecute: (execution) => this.#execute(execution),\n\t\t})\n\t}\n\n\t/**\n\t * @deprecated Declare handlers inside command({...}) using createEffectFoundation\n\t * from cvx-kit/effect, then call exec(operation, input, host).\n\t */\n\texec<const Key extends OperationKey<Operations>>(executor: {\n\t\toperation: Key\n\t\thandler: (\n\t\t\tcontext: Context & OperationExtension<Operations[Key]>,\n\t\t\tcommand: CommandInput<Operations, Key>,\n\t\t) => MaybePromise<CommandHandlerResult<Operations, Key>>\n\t}) {\n\t\treturn this.#kernel.exec({\n\t\t\toperation: executor.operation,\n\t\t\thandler: (context, command) =>\n\t\t\t\texecutor.handler(\n\t\t\t\t\t// SAFETY: operationFactory requires enrichment middleware before this handler.\n\t\t\t\t\tcontext as Context & OperationExtension<Operations[Key]>,\n\t\t\t\t\tcommand,\n\t\t\t\t),\n\t\t})\n\t}\n\n\tasync #execute<Key extends OperationKey<Operations>>(\n\t\texecution: CommandExecution<Context, Operations, Key>,\n\t): Promise<CommandResult<Operations, Key>> {\n\t\tconst definition = execution.definition\n\t\treturn this.#observability.observe(\n\t\t\t{ operation: execution.operation, classification: definition.classification },\n\t\t\t() =>\n\t\t\t\texecuteCommandLifecycle<\n\t\t\t\t\tPromiseExecution,\n\t\t\t\t\tContext,\n\t\t\t\t\tCommandInput<Operations, Key>,\n\t\t\t\t\tCommandHandlerResult<Operations, Key>,\n\t\t\t\t\tCommandResult<Operations, Key>\n\t\t\t\t>(promiseLifecycle, {\n\t\t\t\t\toperation: execution.operation,\n\t\t\t\t\tclassification: definition.classification,\n\t\t\t\t\tcontext: execution.context,\n\t\t\t\t\tcommand: execution.command,\n\t\t\t\t\tpermission:\n\t\t\t\t\t\tdefinition.permission === undefined\n\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t: async () => {\n\t\t\t\t\t\t\t\t\tif (!this.#checkPermission) throw new CommandPermissionError(execution.operation)\n\t\t\t\t\t\t\t\t\t// SAFETY: injected policy consumes this invocation's original host context.\n\t\t\t\t\t\t\t\t\tawait this.#checkPermission(execution.context as never, {\n\t\t\t\t\t\t\t\t\t\tpermission: definition.permission!,\n\t\t\t\t\t\t\t\t\t\toperation: execution.operation,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\tprepare: async () => {\n\t\t\t\t\t\t// SAFETY: selected definition and parsed input are paired by the kernel.\n\t\t\t\t\t\tconst preparation = await definition.prepare?.(\n\t\t\t\t\t\t\texecution.context as never,\n\t\t\t\t\t\t\texecution.command as never,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (preparation?.kind !== 'execute') return preparation\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tkind: 'execute' as const,\n\t\t\t\t\t\t\tcomplete: preparation.complete\n\t\t\t\t\t\t\t\t? async (result: CommandResult<Operations, Key>) => {\n\t\t\t\t\t\t\t\t\t\t// SAFETY: completion belongs to this operation's validated final result.\n\t\t\t\t\t\t\t\t\t\tawait preparation.complete!(result as never)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tparseReplay: (value) => {\n\t\t\t\t\t\tif (!definition.replayResult) return execution.parseResult(value)\n\t\t\t\t\t\t// SAFETY: selected replay schema validates this operation's stored output.\n\t\t\t\t\t\treturn parseCommandSchema(definition.replayResult, value) as CommandResult<\n\t\t\t\t\t\t\tOperations,\n\t\t\t\t\t\t\tKey\n\t\t\t\t\t\t>\n\t\t\t\t\t},\n\t\t\t\t\tdecodeReplay: async (value) => {\n\t\t\t\t\t\tif (!definition.replayResult) {\n\t\t\t\t\t\t\treturn execution.decodeResult\n\t\t\t\t\t\t\t\t? execution.decodeResult(value)\n\t\t\t\t\t\t\t\t: execution.parseResult(value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst replay = definition.replayResult\n\t\t\t\t\t\t// SAFETY: selected replay decoder owns the final output representation.\n\t\t\t\t\t\treturn (await decodeCommandSchema(replay, value)) as CommandResult<Operations, Key>\n\t\t\t\t\t},\n\t\t\t\t\tmiddleware: [...(this.#defaults.middleware ?? []), ...(definition.middleware ?? [])].map(\n\t\t\t\t\t\t(layer) => async (input) => {\n\t\t\t\t\t\t\t// SAFETY: selected definition owns this heterogeneous middleware's pre-validation output.\n\t\t\t\t\t\t\treturn layer({\n\t\t\t\t\t\t\t\t...input,\n\t\t\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\t\t\t// SAFETY: selected command schema owns this heterogeneous storage value.\n\t\t\t\t\t\t\t\tcommand: input.command as never,\n\t\t\t\t\t\t\t\t// SAFETY: only heterogeneous storage erases the selected middleware context.\n\t\t\t\t\t\t\t\tcontext: input.context as never,\n\t\t\t\t\t\t\t\t// SAFETY: selected operation pairs downstream output with its final schema.\n\t\t\t\t\t\t\t\tnext: input.next as (options?: { context?: object }) => Promise<never>,\n\t\t\t\t\t\t\t}) as Promise<CommandHandlerResult<Operations, Key>>\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tdefaultGuard: async (context) => {\n\t\t\t\t\t\t// SAFETY: default guards consume the downstream middleware context.\n\t\t\t\t\t\tawait this.#defaults.guard?.(context as never)\n\t\t\t\t\t},\n\t\t\t\t\tguard: async (context) => {\n\t\t\t\t\t\t// SAFETY: selected guard consumes its parsed input and enriched context.\n\t\t\t\t\t\tawait definition.guard?.(context as never, execution.command as never)\n\t\t\t\t\t},\n\t\t\t\t\trun: (context) => execution.runUnparsed(context),\n\t\t\t\t\tparseResult: execution.parseResult,\n\t\t\t\t\tdecodeResult: execution.decodeResult,\n\t\t\t\t\taudit: async (result) => {\n\t\t\t\t\t\t// SAFETY: audit receives this selected parsed command/result and original context.\n\t\t\t\t\t\treturn definition.audit(\n\t\t\t\t\t\t\t{ command: execution.command, result } as never,\n\t\t\t\t\t\t\texecution.context as never,\n\t\t\t\t\t\t)\n\t\t\t\t\t},\n\t\t\t\t\taggregates: definition.aggregates,\n\t\t\t\t\twriteAudit: async (entry) => {\n\t\t\t\t\t\t// SAFETY: host supplied writer for this invocation's original context.\n\t\t\t\t\t\treturn this.#writeAudit(execution.context as never, entry)\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t)\n\t}\n}\n\n/** @deprecated Use the registry returned by createEffectFoundation(...).Command from cvx-kit/effect. */\nexport type ApplicationCommand<Context, Operations extends AuditedRegistry> = BoundCommand<\n\tContext,\n\tOperations\n>\n\n/**\n * The constructor shape a Foundation instance exposes as `Command`.\n * Exported as a TYPE ONLY so factories (e.g. cvx-kit/crud) can accept the\n * destructured facade class as input without importing any runtime kernel.\n * @deprecated Use createEffectFoundation from cvx-kit/effect and declare handlers inside command({...}).\n */\nexport type CommandConstructor = {\n\t/** @deprecated Use createEffectFoundation(...).Command({ context, operations }) from cvx-kit/effect. */\n\tnew <Context, const Operations extends AuditedRegistry>(\n\t\toperations: Operations & {\n\t\t\treadonly [Key in keyof Operations]: OperationHostContext<Context>\n\t\t},\n\t\tdefaults?: CommandDefaults,\n\t): BoundCommand<Context, Operations>\n\toperation: (typeof BoundCommand)['operation']\n\twithContext: (typeof BoundCommand)['withContext']\n\tmiddleware: (typeof BoundCommand)['middleware']\n}\n\n/**\n * Host facade for a component that owns no application execution capability.\n * Declared once; the sole source of the command protocol, query kernel, and\n * observability: `const { Command, Query, observability } = new Foundation(...)`.\n */\nexport class Foundation<Component extends FoundationComponentApi = FoundationComponentApi> {\n\treadonly status: Component['functions']['status']\n\t/** @deprecated Use createEffectFoundation(...).Command from cvx-kit/effect. */\n\treadonly Command: CommandConstructor\n\treadonly Query = Query\n\treadonly observability: Observability\n\t/** Typed-failure boundary — see result.ts. Facade-bound like the kernels. */\n\treadonly executeResultBoundary = executeResultBoundary\n\treadonly projectResult = projectResult\n\treadonly emitSemanticEvent = emitSemanticEvent\n\n\tconstructor(component: Component, options: FoundationOptions) {\n\t\tthis.status = component.functions.status\n\t\tconst observability = new Observability(options.observability)\n\t\tthis.observability = observability\n\t\tconst writeAudit = options.observability.writeAudit ?? (() => undefined)\n\t\tconst checkPermission = options.checkPermission\n\t\tclass HostCommand<Context, const Operations extends AuditedRegistry> extends BoundCommand<\n\t\t\tContext,\n\t\t\tOperations\n\t\t> {\n\t\t\tconstructor(operations: Operations, defaults?: CommandDefaults) {\n\t\t\t\tsuper(operations, {\n\t\t\t\t\tobservability,\n\t\t\t\t\twriteAudit,\n\t\t\t\t\tcheckPermission,\n\t\t\t\t\tdefaults,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tthis.Command = HostCommand\n\t}\n}\n\n// Kernel CLASSES are deliberately NOT exported: Command, Query, and\n// Observability exist only as capabilities of a Foundation instance —\n// `const { Command, Query, observability } = new Foundation(...)`. A loose\n// import would construct kernels without the injected observability, audit\n// writer, and permission checker. Types stay exported for signatures.\nexport type { CommandPreparation, TypedOperation } from './operation'\nexport type {\n\tCommandArgument,\n\tCommandExecution,\n\tCommandHandlerResult,\n\tCommandInput,\n\tCommandRegistry,\n\tCommandResult,\n\tSchemaOutput,\n\tParseable,\n} from './modules/command/command'\nexport type {\n\tCommandObservation,\n\tObservabilityOptions,\n} from './modules/observability/observability'\nexport type { AnyQueryMiddleware, QueryExecution, QueryMiddleware } from './modules/query/query'\nexport type { Result, ResultBoundary, TransactionMetricsContext } from './result'\n\n// The component definition is deliberately NOT re-exported here: Convex's\n// CLI only discovers a component whose resolved file is convex.config.js,\n// so hosts must mount via the dedicated subpath:\n// import foundation from 'cvx-kit/components/foundation/convex.config'\n"],"mappings":"ghBA2JA,IAAM,EAAN,KAAsE,CACrE,OAAO,YAAc,EACrB,GACA,GACA,GACA,GACA,GAGA,WAIA,OAAO,UAAqD,EAAoC,CAC/F,OAAO,CACR,CAMA,OAAO,WAMN,EACuD,CACvD,OAAO,CACR,CAEA,YACC,EACA,EAMC,CACD,KAAKC,GAAiB,EAAK,cAC3B,KAAKC,GAAc,EAAK,WACxB,KAAKC,GAAmB,EAAK,gBAC7B,KAAKC,GAAY,EAAK,UAAY,CAAC,EAEnC,KAAK,WAAa,OAAO,OACxB,OAAO,YACN,OAAO,QAAQ,CAAU,CAAC,CAAC,KAAK,CAAC,EAAW,KAAgB,CAC3D,EACA,EAAW,UACZ,CAAC,CACF,CACD,EACA,KAAKJ,GAAU,IAAIK,EAAwC,CAC1D,aACA,QAAU,GAAc,KAAKC,GAAS,CAAS,CAChD,CAAC,CACF,CAMA,KAAiD,EAM9C,CACF,OAAO,KAAKN,GAAQ,KAAK,CACxB,UAAW,EAAS,UACpB,SAAU,EAAS,IAClB,EAAS,QAER,EACA,CACD,CACF,CAAC,CACF,CAEA,KAAMM,GACL,EAC0C,CAC1C,IAAM,EAAa,EAAU,WAC7B,OAAO,KAAKL,GAAe,QAC1B,CAAE,UAAW,EAAU,UAAW,eAAgB,EAAW,cAAe,MAE3E,EAME,EAAkB,CACnB,UAAW,EAAU,UACrB,eAAgB,EAAW,eAC3B,QAAS,EAAU,QACnB,QAAS,EAAU,QACnB,WACC,EAAW,aAAe,IAAA,GACvB,IAAA,GACA,SAAY,CACZ,GAAI,CAAC,KAAKE,GAAkB,MAAM,IAAI,EAAuB,EAAU,SAAS,EAEhF,MAAM,KAAKA,GAAiB,EAAU,QAAkB,CACvD,WAAY,EAAW,WACvB,UAAW,EAAU,SACtB,CAAC,CACF,EACH,QAAS,SAAY,CAEpB,IAAM,EAAc,MAAM,EAAW,UACpC,EAAU,QACV,EAAU,OACX,EAEA,OADI,GAAa,OAAS,UACnB,CACN,KAAM,UACN,SAAU,EAAY,SACnB,KAAO,IAA2C,CAElD,MAAM,EAAY,SAAU,CAAe,CAC5C,EACC,IAAA,EACJ,EAT4C,CAU7C,EACA,YAAc,GACR,EAAW,aAET,EAAmB,EAAW,aAAc,CAAK,EAFnB,EAAU,YAAY,CAAK,EAOjE,aAAc,KAAO,IAAU,CAC9B,GAAI,CAAC,EAAW,aACf,OAAO,EAAU,aACd,EAAU,aAAa,CAAK,EAC5B,EAAU,YAAY,CAAK,EAE/B,IAAM,EAAS,EAAW,aAE1B,OAAQ,MAAM,EAAoB,EAAQ,CAAK,CAChD,EACA,WAAY,CAAC,GAAI,KAAKC,GAAU,YAAc,CAAC,EAAI,GAAI,EAAW,YAAc,CAAC,CAAE,CAAC,CAAC,IACnF,GAAU,KAAO,IAEV,EAAM,CACZ,GAAG,EACH,aAEA,QAAS,EAAM,QAEf,QAAS,EAAM,QAEf,KAAM,EAAM,IACb,CAAC,CAEH,EACA,aAAc,KAAO,IAAY,CAEhC,MAAM,KAAKA,GAAU,QAAQ,CAAgB,CAC9C,EACA,MAAO,KAAO,IAAY,CAEzB,MAAM,EAAW,QAAQ,EAAkB,EAAU,OAAgB,CACtE,EACA,IAAM,GAAY,EAAU,YAAY,CAAO,EAC/C,YAAa,EAAU,YACvB,aAAc,EAAU,aACxB,MAAO,KAAO,IAEN,EAAW,MACjB,CAAE,QAAS,EAAU,QAAS,QAAO,EACrC,EAAU,OACX,EAED,WAAY,EAAW,WACvB,WAAY,KAAO,IAEX,KAAKF,GAAY,EAAU,QAAkB,CAAK,CAE3D,CAAC,CACH,CACD,CACD,EAgCa,EAAb,KAA2F,CAC1F,OAEA,QACA,MAAiB,EACjB,cAEA,sBAAiC,EACjC,cAAyB,EACzB,kBAA6B,EAE7B,YAAY,EAAsB,EAA4B,CAC7D,KAAK,OAAS,EAAU,UAAU,OAClC,IAAM,EAAgB,IAAI,EAAc,EAAQ,aAAa,EAC7D,KAAK,cAAgB,EACrB,IAAM,EAAa,EAAQ,cAAc,iBAAqB,IAAA,IACxD,EAAkB,EAAQ,gBAChC,MAAM,UAAuE,CAG3E,CACD,YAAY,EAAwB,EAA4B,CAC/D,MAAM,EAAY,CACjB,gBACA,aACA,kBACA,UACD,CAAC,CACF,CACD,CACA,KAAK,QAAU,CAChB,CACD"}
|
|
1
|
+
{"version":3,"file":"client.mjs","names":["CommandKernelClass","BoundCommand","operationFactory","definition","middleware","#observability","deps","#writeAudit","#checkPermission","#defaults","operations","operation","#kernel","Command","#execute","execution","executor","context","command","executeCommandLifecycle","promiseLifecycle","CommandPermissionError","preparation","result","parseCommandSchema","value","replay","decodeCommandSchema","layer","input","entry","Foundation","Query","executeResultBoundary","projectResult","emitSemanticEvent","component","observability","Observability","options","writeAudit","checkPermission","HostCommand"],"sources":["../../../src/components/foundation/client.ts"],"sourcesContent":["import type { Value } from 'convex/values'\nimport {\n\tCommand as CommandKernelClass,\n\ttype CommandExecution,\n\ttype CommandHandlerResult,\n\ttype CommandInput,\n\ttype CommandRegistry,\n\ttype CommandResult,\n\ttype CommandSchema,\n\tdecodeCommandSchema,\n\tparseCommandSchema,\n} from './modules/command/command'\nimport { Observability, type ObservabilityOptions } from './modules/observability/observability'\nimport { Query } from './modules/query/query'\nimport {\n\texecuteCommandLifecycle,\n\tpromiseLifecycle,\n\tCommandPermissionError,\n\ttype PromiseExecution,\n} from './modules/command/lifecycle'\nimport { executeResultBoundary, projectResult } from './result'\nimport { emitSemanticEvent } from './telemetry'\nimport {\n\toperationFactory,\n\ttype CommandPreparation,\n\ttype OperationExtension,\n\ttype OperationHostContext,\n} from './operation'\n\n/** Shape handed to the injected audit writer; classification comes from the operation. */\nexport type AuditEntryInput = {\n\toperation: string\n\tactorId: string\n\taggregate: { type: string; id: string }\n\tmetadata?: Record<string, Value>\n\tclassification: string\n}\n\nexport type AuditWriter<Result = unknown> = (\n\tcontext: never,\n\tentry: AuditEntryInput,\n) => MaybePromise<Result>\n\ntype MaybePromise<Value> = Value | Promise<Value>\ntype OperationKey<Operations extends CommandRegistry> = Extract<keyof Operations, string>\n\nexport type AuditedOperation = Readonly<{\n\tcommand: CommandSchema\n\tresult: CommandSchema\n\tclassification: string\n\t/**\n\t * Permission slug required to execute this operation. Checked through the\n\t * Foundation's injected checkPermission BEFORE guards and the handler;\n\t * declaring a permission without injecting a checker fails closed.\n\t */\n\tpermission?: string\n\tprepare?: (context: never, command: never) => MaybePromise<CommandPreparation<never>>\n\treplayResult?: CommandSchema\n\t/**\n\t * Per-operation precondition, after the permission check and the registry\n\t * default guard, before the handler. Throw to deny — nothing has run yet.\n\t */\n\tguard?: (context: never, command: never) => MaybePromise<void>\n\t/**\n\t * Allowlist of aggregate types this operation's audit may reference. When\n\t * declared, an audit entry whose aggregate.type is not listed throws —\n\t * the audit vocabulary is enforced, not advisory.\n\t */\n\taggregates?: readonly string[]\n\t/** Per-operation middleware, inside the registry-wide chain. */\n\tmiddleware?: readonly AnyCommandMiddleware[]\n\taudit: (\n\t\tresolution: Readonly<{ command: never; result: never }>,\n\t\tcontext: never,\n\t) => MaybePromise<Omit<AuditEntryInput, 'classification'> | null>\n}>\n\n/**\n * Composable, next()-based middleware wrapping [guards → handler]. Runs\n * INSIDE the pipeline's invariants: after the permission check, before the\n * result-schema parse, aggregate allowlist, and audit — so middleware can\n * time, trace, enrich context (`next({ context })`), short-circuit, or\n * transform results, but can never skip authorization, return an invalid\n * result, or desynchronize audit from effects.\n */\nexport type CommandMiddleware<\n\tContext = never,\n\tExtension extends object = object,\n\tInput = unknown,\n\tResult = unknown,\n> = (input: {\n\toperation: string\n\tcommand: Input\n\tcontext: Context\n\tnext: (options?: {\n\t\t/** Merged into the context handed to inner middleware, guards, handler. */\n\t\tcontext?: Extension\n\t}) => Promise<Result>\n}) => Promise<Result>\n\n/** Any-context middleware — what registries and operations accept. */\n// Contravariant seam: the supertype every typed CommandMiddleware<C, E>\n// assigns to. Context, command, and next are contravariant storage slots;\n// dispatch restores the selected operation's types before invocation.\nexport type AnyCommandMiddleware<Input = never, Result = unknown, NextResult = never> = (input: {\n\toperation: string\n\tdefinition?: AuditedOperation\n\tcommand: Input\n\tcontext: never\n\tnext: (options?: { context?: object }) => Promise<NextResult>\n}) => Promise<Result>\n\n/** Registry-wide defaults applied to every operation of one Command. */\nexport type CommandDefaults = Readonly<{\n\t/** Runs before every operation's own guard. Throw to deny. */\n\tguard?: (context: never) => MaybePromise<void>\n\t/** Outermost middleware, in array order, around every operation. */\n\tmiddleware?: readonly AnyCommandMiddleware[]\n}>\n\n/** Injected permission policy: throw to deny. Host semantics, kit ordering. */\nexport type PermissionChecker = (\n\tcontext: never,\n\tinput: Readonly<{ permission: string; operation: string }>,\n) => MaybePromise<void>\n\nexport type AuditedRegistry = Readonly<Record<string, AuditedOperation>>\n\nexport type FoundationOptions = Readonly<{\n\tobservability: ObservabilityOptions &\n\t\tReadonly<{\n\t\t\t/**\n\t\t\t * In-transaction audit writer used by Command. Operations that\n\t\t\t * return an audit record get it written here automatically.\n\t\t\t */\n\t\t\twriteAudit?: AuditWriter\n\t\t}>\n\t/**\n\t * Permission policy for operations that declare a `permission`. Runs\n\t * before guards and the handler; throw to deny. An operation with a\n\t * permission but no injected checker fails closed.\n\t */\n\tcheckPermission?: PermissionChecker\n}>\n\ntype FoundationComponentApi = Readonly<{\n\tfunctions: Readonly<{ status: unknown }>\n}>\n\n/**\n * Application command protocol bound to a Foundation instance:\n * validate, observe, execute, and audit. `classification` and `audit()`\n * are mandatory per operation — auditing is type-enforced, not opt-in.\n * Obtain it by destructuring the Foundation: `const { Command } = new Foundation(...)`.\n */\nclass BoundCommand<Context, const Operations extends AuditedRegistry> {\n\tstatic withContext = operationFactory\n\treadonly #kernel: CommandKernelClass<Context, Operations>\n\treadonly #observability: Observability\n\treadonly #writeAudit: AuditWriter\n\treadonly #checkPermission: PermissionChecker | undefined\n\treadonly #defaults: CommandDefaults\n\n\t/** Declared aggregate types per operation — introspectable for tests. */\n\treadonly aggregates: Readonly<{\n\t\t[Key in OperationKey<Operations>]: Operations[Key]['aggregates']\n\t}>\n\n\tstatic operation<const Definition extends AuditedOperation>(definition: Definition): Definition {\n\t\treturn definition\n\t}\n\n\t/**\n\t * Identity helper that types a middleware against its context and the\n\t * context extension it passes downstream via next({ context }).\n\t */\n\tstatic middleware<\n\t\tContext = never,\n\t\tconst Extension extends object = object,\n\t\tInput = unknown,\n\t\tResult = unknown,\n\t>(\n\t\tmiddleware: CommandMiddleware<Context, Extension, Input, Result>,\n\t): CommandMiddleware<Context, Extension, Input, Result> {\n\t\treturn middleware\n\t}\n\n\tconstructor(\n\t\toperations: Operations,\n\t\tdeps: {\n\t\t\tobservability: Observability\n\t\t\twriteAudit: AuditWriter\n\t\t\tcheckPermission?: PermissionChecker\n\t\t\tdefaults?: CommandDefaults\n\t\t},\n\t) {\n\t\tthis.#observability = deps.observability\n\t\tthis.#writeAudit = deps.writeAudit\n\t\tthis.#checkPermission = deps.checkPermission\n\t\tthis.#defaults = deps.defaults ?? {}\n\t\t// SAFETY: this map preserves every operations key and selects its aggregates property.\n\t\tthis.aggregates = Object.freeze(\n\t\t\tObject.fromEntries(\n\t\t\t\tObject.entries(operations).map(([operation, definition]) => [\n\t\t\t\t\toperation,\n\t\t\t\t\tdefinition.aggregates,\n\t\t\t\t]),\n\t\t\t),\n\t\t) as this['aggregates']\n\t\tthis.#kernel = new CommandKernelClass<Context, Operations>({\n\t\t\toperations,\n\t\t\texecute: (execution) => this.#execute(execution),\n\t\t})\n\t}\n\n\t/**\n\t * @deprecated Declare handlers inside command({...}) using createEffectFoundation\n\t * from cvx-kit/effect, then call exec(operation, input, host).\n\t */\n\texec<const Key extends OperationKey<Operations>>(executor: {\n\t\toperation: Key\n\t\thandler: (\n\t\t\tcontext: Context & OperationExtension<Operations[Key]>,\n\t\t\tcommand: CommandInput<Operations, Key>,\n\t\t) => MaybePromise<CommandHandlerResult<Operations, Key>>\n\t}) {\n\t\treturn this.#kernel.exec({\n\t\t\toperation: executor.operation,\n\t\t\thandler: (context, command) =>\n\t\t\t\texecutor.handler(\n\t\t\t\t\t// SAFETY: operationFactory requires enrichment middleware before this handler.\n\t\t\t\t\tcontext as Context & OperationExtension<Operations[Key]>,\n\t\t\t\t\tcommand,\n\t\t\t\t),\n\t\t})\n\t}\n\n\tasync #execute<Key extends OperationKey<Operations>>(\n\t\texecution: CommandExecution<Context, Operations, Key>,\n\t): Promise<CommandResult<Operations, Key>> {\n\t\tconst definition = execution.definition\n\t\treturn this.#observability.observe(\n\t\t\t{ operation: execution.operation, classification: definition.classification },\n\t\t\t() =>\n\t\t\t\texecuteCommandLifecycle<\n\t\t\t\t\tPromiseExecution,\n\t\t\t\t\tContext,\n\t\t\t\t\tCommandInput<Operations, Key>,\n\t\t\t\t\tCommandHandlerResult<Operations, Key>,\n\t\t\t\t\tCommandResult<Operations, Key>\n\t\t\t\t>(promiseLifecycle, {\n\t\t\t\t\toperation: execution.operation,\n\t\t\t\t\tclassification: definition.classification,\n\t\t\t\t\tcontext: execution.context,\n\t\t\t\t\tcommand: execution.command,\n\t\t\t\t\tpermission:\n\t\t\t\t\t\tdefinition.permission === undefined\n\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t: async () => {\n\t\t\t\t\t\t\t\t\tif (!this.#checkPermission) throw new CommandPermissionError(execution.operation)\n\t\t\t\t\t\t\t\t\t// SAFETY: injected policy consumes this invocation's original host context.\n\t\t\t\t\t\t\t\t\tawait this.#checkPermission(execution.context as never, {\n\t\t\t\t\t\t\t\t\t\tpermission: definition.permission!,\n\t\t\t\t\t\t\t\t\t\toperation: execution.operation,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\tprepare: async () => {\n\t\t\t\t\t\t// SAFETY: selected definition and parsed input are paired by the kernel.\n\t\t\t\t\t\tconst preparation = await definition.prepare?.(\n\t\t\t\t\t\t\texecution.context as never,\n\t\t\t\t\t\t\texecution.command as never,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (preparation?.kind !== 'execute') return preparation\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tkind: 'execute' as const,\n\t\t\t\t\t\t\tcomplete: preparation.complete\n\t\t\t\t\t\t\t\t? async (result: CommandResult<Operations, Key>) => {\n\t\t\t\t\t\t\t\t\t\t// SAFETY: completion belongs to this operation's validated final result.\n\t\t\t\t\t\t\t\t\t\tawait preparation.complete!(result as never)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tparseReplay: (value) => {\n\t\t\t\t\t\tif (!definition.replayResult) return execution.parseResult(value)\n\t\t\t\t\t\t// SAFETY: selected replay schema validates this operation's stored output.\n\t\t\t\t\t\treturn parseCommandSchema(definition.replayResult, value) as CommandResult<\n\t\t\t\t\t\t\tOperations,\n\t\t\t\t\t\t\tKey\n\t\t\t\t\t\t>\n\t\t\t\t\t},\n\t\t\t\t\tdecodeReplay: async (value) => {\n\t\t\t\t\t\tif (!definition.replayResult) {\n\t\t\t\t\t\t\treturn execution.decodeResult\n\t\t\t\t\t\t\t\t? execution.decodeResult(value)\n\t\t\t\t\t\t\t\t: execution.parseResult(value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst replay = definition.replayResult\n\t\t\t\t\t\t// SAFETY: selected replay decoder owns the final output representation.\n\t\t\t\t\t\treturn (await decodeCommandSchema(replay, value)) as CommandResult<Operations, Key>\n\t\t\t\t\t},\n\t\t\t\t\tmiddleware: [...(this.#defaults.middleware ?? []), ...(definition.middleware ?? [])].map(\n\t\t\t\t\t\t(layer) => async (input) => {\n\t\t\t\t\t\t\t// SAFETY: selected definition owns this heterogeneous middleware's pre-validation output.\n\t\t\t\t\t\t\treturn layer({\n\t\t\t\t\t\t\t\t...input,\n\t\t\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\t\t\t// SAFETY: selected command schema owns this heterogeneous storage value.\n\t\t\t\t\t\t\t\tcommand: input.command as never,\n\t\t\t\t\t\t\t\t// SAFETY: only heterogeneous storage erases the selected middleware context.\n\t\t\t\t\t\t\t\tcontext: input.context as never,\n\t\t\t\t\t\t\t\t// SAFETY: selected operation pairs downstream output with its final schema.\n\t\t\t\t\t\t\t\tnext: input.next as (options?: { context?: object }) => Promise<never>,\n\t\t\t\t\t\t\t}) as Promise<CommandHandlerResult<Operations, Key>>\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tdefaultGuard: async (context) => {\n\t\t\t\t\t\t// SAFETY: default guards consume the downstream middleware context.\n\t\t\t\t\t\tawait this.#defaults.guard?.(context as never)\n\t\t\t\t\t},\n\t\t\t\t\tguard: async (context) => {\n\t\t\t\t\t\t// SAFETY: selected guard consumes its parsed input and enriched context.\n\t\t\t\t\t\tawait definition.guard?.(context as never, execution.command as never)\n\t\t\t\t\t},\n\t\t\t\t\trun: (context) => execution.runUnparsed(context),\n\t\t\t\t\tparseResult: execution.parseResult,\n\t\t\t\t\tdecodeResult: execution.decodeResult,\n\t\t\t\t\taudit: async (result) => {\n\t\t\t\t\t\t// SAFETY: audit receives this selected parsed command/result and original context.\n\t\t\t\t\t\treturn definition.audit(\n\t\t\t\t\t\t\t{ command: execution.command, result } as never,\n\t\t\t\t\t\t\texecution.context as never,\n\t\t\t\t\t\t)\n\t\t\t\t\t},\n\t\t\t\t\taggregates: definition.aggregates,\n\t\t\t\t\twriteAudit: async (entry) => {\n\t\t\t\t\t\t// SAFETY: host supplied writer for this invocation's original context.\n\t\t\t\t\t\treturn this.#writeAudit(execution.context as never, entry)\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t)\n\t}\n}\n\n/** @deprecated Use the registry returned by createEffectFoundation(...).Command from cvx-kit/effect. */\nexport type ApplicationCommand<Context, Operations extends AuditedRegistry> = BoundCommand<\n\tContext,\n\tOperations\n>\n\n/**\n * The constructor shape a Foundation instance exposes as `Command`.\n * Exported as a TYPE ONLY so factories (e.g. cvx-kit/crud) can accept the\n * destructured facade class as input without importing any runtime kernel.\n * @deprecated Use createEffectFoundation from cvx-kit/effect and declare handlers inside command({...}).\n */\nexport type CommandConstructor = {\n\t/** @deprecated Use createEffectFoundation(...).Command({ context, operations }) from cvx-kit/effect. */\n\tnew <Context, const Operations extends AuditedRegistry>(\n\t\toperations: Operations & {\n\t\t\treadonly [Key in keyof Operations]: OperationHostContext<Context>\n\t\t},\n\t\tdefaults?: CommandDefaults,\n\t): BoundCommand<Context, Operations>\n\toperation: (typeof BoundCommand)['operation']\n\twithContext: (typeof BoundCommand)['withContext']\n\tmiddleware: (typeof BoundCommand)['middleware']\n}\n\n/**\n * Host facade for a component that owns no application execution capability.\n * Declared once; the sole source of the command protocol, query kernel, and\n * observability: `const { Command, Query, observability } = new Foundation(...)`.\n */\nexport class Foundation<Component extends FoundationComponentApi = FoundationComponentApi> {\n\treadonly status: Component['functions']['status']\n\t/** @deprecated Use createEffectFoundation(...).Command from cvx-kit/effect. */\n\treadonly Command: CommandConstructor\n\treadonly Query = Query\n\treadonly observability: Observability\n\t/** Typed-failure boundary — see result.ts. Facade-bound like the kernels. */\n\treadonly executeResultBoundary = executeResultBoundary\n\treadonly projectResult = projectResult\n\treadonly emitSemanticEvent = emitSemanticEvent\n\n\tconstructor(component: Component, options: FoundationOptions) {\n\t\tthis.status = component.functions.status\n\t\tconst observability = new Observability(options.observability)\n\t\tthis.observability = observability\n\t\tconst writeAudit = options.observability.writeAudit ?? (() => undefined)\n\t\tconst checkPermission = options.checkPermission\n\t\tclass HostCommand<Context, const Operations extends AuditedRegistry> extends BoundCommand<\n\t\t\tContext,\n\t\t\tOperations\n\t\t> {\n\t\t\tconstructor(operations: Operations, defaults?: CommandDefaults) {\n\t\t\t\tsuper(operations, {\n\t\t\t\t\tobservability,\n\t\t\t\t\twriteAudit,\n\t\t\t\t\tcheckPermission,\n\t\t\t\t\tdefaults,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tthis.Command = HostCommand\n\t}\n}\n\n// Kernel CLASSES are deliberately NOT exported: Command, Query, and\n// Observability exist only as capabilities of a Foundation instance —\n// `const { Command, Query, observability } = new Foundation(...)`. A loose\n// import would construct kernels without the injected observability, audit\n// writer, and permission checker. Types stay exported for signatures.\nexport type { CommandPreparation, TypedOperation } from './operation'\nexport type {\n\tCommandArgument,\n\tCommandExecution,\n\tCommandHandlerResult,\n\tCommandInput,\n\tCommandRegistry,\n\tCommandResult,\n\tSchemaOutput,\n\tParseable,\n} from './modules/command/command'\nexport type {\n\tCommandObservation,\n\tObservabilityOptions,\n} from './modules/observability/observability'\nexport type { AnyQueryMiddleware, QueryExecution, QueryMiddleware } from './modules/query/query'\nexport type { Result, ResultBoundary, TransactionMetricsContext } from './result'\n\n// The component definition is deliberately NOT re-exported here: Convex's\n// CLI only discovers a component whose resolved file is convex.config.js,\n// so hosts must mount via the dedicated subpath:\n// import foundation from 'cvx-kit/components/foundation/convex.config'\n"],"mappings":"ghBA2JA,IAAMC,EAAN,KAAsE,CACrE,OAAO,YAAcC,EACrB,GACA,GACA,GACA,GACA,GAGA,WAIA,OAAO,UAAqD,EAAoC,CAC/F,OAAOC,CACR,CAMA,OAAO,WAMN,EACuD,CACvD,OAAOC,CACR,CAEA,YACC,EACA,EAMC,CACD,KAAKC,GAAiBC,EAAK,cAC3B,KAAKC,GAAcD,EAAK,WACxB,KAAKE,GAAmBF,EAAK,gBAC7B,KAAKG,GAAYH,EAAK,UAAY,CAAC,EAEnC,KAAK,WAAa,OAAO,OACxB,OAAO,YACN,OAAO,QAAQI,CAAU,CAAC,CAAC,KAAK,CAACC,EAAWR,KAAgB,CAC3DQ,EACAR,EAAW,UACZ,CAAC,CACF,CACD,EACA,KAAKS,GAAU,IAAIZ,EAAwC,CAC1D,aACA,QAAU,GAAc,KAAKc,GAASC,CAAS,CAChD,CAAC,CACF,CAMA,KAAiD,EAM9C,CACF,OAAO,KAAKH,GAAQ,KAAK,CACxB,UAAWI,EAAS,UACpB,SAAU,EAAS,IAClBA,EAAS,QAERC,EACAC,CACD,CACF,CAAC,CACF,CAEA,KAAMJ,GACL,EAC0C,CAC1C,IAAMX,EAAaY,EAAU,WAC7B,OAAO,KAAKV,GAAe,QAC1B,CAAE,UAAWU,EAAU,UAAW,eAAgBZ,EAAW,cAAe,MAE3EgB,EAMEC,EAAkB,CACnB,UAAWL,EAAU,UACrB,eAAgBZ,EAAW,eAC3B,QAASY,EAAU,QACnB,QAASA,EAAU,QACnB,WACCZ,EAAW,aAAe,IAAA,GACvB,IAAA,GACA,SAAY,CACZ,GAAI,CAAC,KAAKK,GAAkB,MAAM,IAAIa,EAAuBN,EAAU,SAAS,EAEhF,MAAM,KAAKP,GAAiBO,EAAU,QAAkB,CACvD,WAAYZ,EAAW,WACvB,UAAWY,EAAU,SACtB,CAAC,CACF,EACH,QAAS,SAAY,CAEpB,IAAMO,EAAc,MAAMnB,EAAW,UACpCY,EAAU,QACVA,EAAU,OACX,EAEA,OADIO,GAAa,OAAS,UACnB,CACN,KAAM,UACN,SAAUA,EAAY,SACnB,KAAO,IAA2C,CAElD,MAAMA,EAAY,SAAUC,CAAe,CAC5C,EACC,IAAA,EACJ,EAT4CD,CAU7C,EACA,YAAc,GACRnB,EAAW,aAETqB,EAAmBrB,EAAW,aAAcsB,CAAK,EAFnBV,EAAU,YAAYU,CAAK,EAOjE,aAAc,KAAO,IAAU,CAC9B,GAAI,CAACtB,EAAW,aACf,OAAOY,EAAU,aACdA,EAAU,aAAaU,CAAK,EAC5BV,EAAU,YAAYU,CAAK,EAE/B,IAAMC,EAASvB,EAAW,aAE1B,OAAQ,MAAMwB,EAAoBD,EAAQD,CAAK,CAChD,EACA,WAAY,CAAC,GAAI,KAAKhB,GAAU,YAAc,CAAC,EAAI,GAAIN,EAAW,YAAc,CAAC,CAAE,CAAC,CAAC,IACnF,GAAU,KAAO,IAEVyB,EAAM,CACZ,GAAGC,EACH,aAEA,QAASA,EAAM,QAEf,QAASA,EAAM,QAEf,KAAMA,EAAM,IACb,CAAC,CAEH,EACA,aAAc,KAAO,IAAY,CAEhC,MAAM,KAAKpB,GAAU,QAAQQ,CAAgB,CAC9C,EACA,MAAO,KAAO,IAAY,CAEzB,MAAMd,EAAW,QAAQc,EAAkBF,EAAU,OAAgB,CACtE,EACA,IAAM,GAAYA,EAAU,YAAYE,CAAO,EAC/C,YAAaF,EAAU,YACvB,aAAcA,EAAU,aACxB,MAAO,KAAO,IAENZ,EAAW,MACjB,CAAE,QAASY,EAAU,QAAS,QAAO,EACrCA,EAAU,OACX,EAED,WAAYZ,EAAW,WACvB,WAAY,KAAO,IAEX,KAAKI,GAAYQ,EAAU,QAAkBe,CAAK,CAE3D,CAAC,CACH,CACD,CACD,EAgCaC,EAAb,KAA2F,CAC1F,OAEA,QACA,MAAiBC,EACjB,cAEA,sBAAiCC,EACjC,cAAyBC,EACzB,kBAA6BC,EAE7B,YAAY,EAAsB,EAA4B,CAC7D,KAAK,OAASC,EAAU,UAAU,OAClC,IAAMC,EAAgB,IAAIC,EAAcC,EAAQ,aAAa,EAC7D,KAAK,cAAgBF,EACrB,IAAMG,EAAaD,EAAQ,cAAc,iBAAqB,IAAA,IACxDE,EAAkBF,EAAQ,gBAChC,MAAMG,UAAuEzC,CAG3E,CACD,YAAY,EAAwB,EAA4B,CAC/D,MAAMS,EAAY,CACjB,gBACA,aACA,kBACA,UACD,CAAC,CACF,CACD,CACA,KAAK,QAAUgC,CAChB,CACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convex.config.mjs","names":[],"sources":["../../../src/components/foundation/convex.config.ts"],"sourcesContent":["import { defineComponent } from 'convex/server'\n\nexport default defineComponent('foundation')\n"],"mappings":"gDAEA,
|
|
1
|
+
{"version":3,"file":"convex.config.mjs","names":["convex_config_default","defineComponent"],"sources":["../../../src/components/foundation/convex.config.ts"],"sourcesContent":["import { defineComponent } from 'convex/server'\n\nexport default defineComponent('foundation')\n"],"mappings":"gDAEA,IAAAA,EAAeC,EAAgB,YAAY"}
|
|
@@ -2,7 +2,7 @@ declare namespace functions_d_exports {
|
|
|
2
2
|
export { status };
|
|
3
3
|
}
|
|
4
4
|
/** Minimal health signal exposed only through the configured host facade. */
|
|
5
|
-
declare const status: import("convex/server").RegisteredQuery<"public", {}, Promise<"ready">>;
|
|
5
|
+
export declare const status: import("convex/server").RegisteredQuery<"public", {}, Promise<"ready">>;
|
|
6
6
|
//#endregion
|
|
7
|
-
export { functions_d_exports
|
|
7
|
+
export { functions_d_exports };
|
|
8
8
|
//# sourceMappingURL=functions.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.mjs","names":[],"sources":["../../../src/components/foundation/functions.ts"],"sourcesContent":["import { v } from 'convex/values'\n\nimport { query } from './_generated/server'\n\n/** Minimal health signal exposed only through the configured host facade. */\nexport const status = query({\n\targs: {},\n\treturns: v.literal('ready'),\n\thandler: async () => 'ready' as const,\n})\n"],"mappings":"kFAKA,
|
|
1
|
+
{"version":3,"file":"functions.mjs","names":["status","query","v"],"sources":["../../../src/components/foundation/functions.ts"],"sourcesContent":["import { v } from 'convex/values'\n\nimport { query } from './_generated/server'\n\n/** Minimal health signal exposed only through the configured host facade. */\nexport const status = query({\n\targs: {},\n\treturns: v.literal('ready'),\n\thandler: async () => 'ready' as const,\n})\n"],"mappings":"kFAKA,MAAaA,EAASC,EAAM,CAC3B,KAAM,CAAC,EACP,QAASC,EAAE,QAAQ,OAAO,EAC1B,QAAS,SAAY,OACtB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare namespace command_d_exports {
|
|
2
2
|
export { Command, CommandArgument, CommandExecution, CommandHandlerResult, CommandInput, CommandRegistry, CommandResult, CommandSchema, Parseable, SchemaInput, SchemaOutput, decodeCommandSchema, parseCommandSchema };
|
|
3
3
|
}
|
|
4
|
-
type Parseable<Output> = Readonly<{
|
|
4
|
+
export type Parseable<Output> = Readonly<{
|
|
5
5
|
parse: <Input>(value: Input) => Output;
|
|
6
6
|
parseAsync?: <Input>(value: Input) => Promise<Output>;
|
|
7
7
|
}>;
|
|
@@ -37,19 +37,19 @@ interface NeutralDecoder<Input = unknown, Output = unknown, Execution = unknown>
|
|
|
37
37
|
};
|
|
38
38
|
readonly decode: (value: unknown) => Execution;
|
|
39
39
|
}
|
|
40
|
-
type CommandSchema<Output = unknown> = Parseable<Output> | StandardSchema<unknown, Output> | NeutralDecoder<unknown, Output, ValidationResult<Output> | Promise<ValidationResult<Output>>>;
|
|
40
|
+
export type CommandSchema<Output = unknown> = Parseable<Output> | StandardSchema<unknown, Output> | NeutralDecoder<unknown, Output, ValidationResult<Output> | Promise<ValidationResult<Output>>>;
|
|
41
41
|
/** Raw values accepted before decoding, including transform inputs. */
|
|
42
|
-
type SchemaInput<Schema extends CommandSchema> = Schema extends NeutralDecoder<infer Input, unknown, unknown> ? Input : Schema extends {
|
|
42
|
+
export type SchemaInput<Schema extends CommandSchema> = Schema extends NeutralDecoder<infer Input, unknown, unknown> ? Input : Schema extends {
|
|
43
43
|
_input: infer Input;
|
|
44
44
|
} ? Input : Schema extends StandardSchema<infer Input, unknown> ? Input : SchemaOutput<Schema>;
|
|
45
|
-
type SchemaOutput<Schema extends CommandSchema> = Schema extends Parseable<unknown> ? ReturnType<Schema['parse']> : Schema extends NeutralDecoder<unknown, infer Output, unknown> ? Output : Schema extends StandardSchema<unknown, infer Output> ? Output : never;
|
|
46
|
-
type CommandHandlerResult<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaInput<Registry[Key]['result']>;
|
|
47
|
-
type CommandRegistry = Readonly<Record<string, CommandDefinition>>;
|
|
45
|
+
export type SchemaOutput<Schema extends CommandSchema> = Schema extends Parseable<unknown> ? ReturnType<Schema['parse']> : Schema extends NeutralDecoder<unknown, infer Output, unknown> ? Output : Schema extends StandardSchema<unknown, infer Output> ? Output : never;
|
|
46
|
+
export type CommandHandlerResult<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaInput<Registry[Key]['result']>;
|
|
47
|
+
export type CommandRegistry = Readonly<Record<string, CommandDefinition>>;
|
|
48
48
|
/** Values accepted from callers before the command schema parses them. */
|
|
49
|
-
type CommandArgument<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaInput<Registry[Key]['command']>;
|
|
50
|
-
type CommandInput<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaOutput<Registry[Key]['command']>;
|
|
51
|
-
type CommandResult<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaOutput<Registry[Key]['result']>;
|
|
52
|
-
type CommandExecution<Context, Registry extends CommandRegistry, Key extends Operation<Registry>> = Readonly<{
|
|
49
|
+
export type CommandArgument<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaInput<Registry[Key]['command']>;
|
|
50
|
+
export type CommandInput<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaOutput<Registry[Key]['command']>;
|
|
51
|
+
export type CommandResult<Registry extends CommandRegistry, Key extends Operation<Registry>> = SchemaOutput<Registry[Key]['result']>;
|
|
52
|
+
export type CommandExecution<Context, Registry extends CommandRegistry, Key extends Operation<Registry>> = Readonly<{
|
|
53
53
|
context: Context;
|
|
54
54
|
operation: Key;
|
|
55
55
|
definition: Registry[Key];
|
|
@@ -79,7 +79,7 @@ type DynamicExecutor<Context, Registry extends CommandRegistry, Dispatcher, Key
|
|
|
79
79
|
handler: (context: Context, command: CommandInput<Registry, Key>) => MaybePromise<CommandHandlerResult<Registry, Key>>;
|
|
80
80
|
}>;
|
|
81
81
|
/** Generic command kernel. Host policy is injected by the owning domain. */
|
|
82
|
-
declare class Command<Context, const Registry extends CommandRegistry> {
|
|
82
|
+
export declare class Command<Context, const Registry extends CommandRegistry> {
|
|
83
83
|
#private;
|
|
84
84
|
constructor(configuration: {
|
|
85
85
|
readonly operations: Registry;
|
|
@@ -89,9 +89,9 @@ declare class Command<Context, const Registry extends CommandRegistry> {
|
|
|
89
89
|
exec<Dispatcher, const Key extends Operation<Registry>>(executor: DynamicExecutor<Context, Registry, Dispatcher, Key>): (context: Context, command: Dispatcher) => Promise<CommandResult<Registry, Key>>;
|
|
90
90
|
}
|
|
91
91
|
/** Legacy synchronous parsing remains available to existing kernel interpreters. */
|
|
92
|
-
declare function parseCommandSchema<S extends CommandSchema>(schema: S, value: unknown): SchemaOutput<S>;
|
|
92
|
+
export declare function parseCommandSchema<S extends CommandSchema>(schema: S, value: unknown): SchemaOutput<S>;
|
|
93
93
|
/** Interpreter-owned decoding awaits validation and leaves thrown/rejected defects intact. */
|
|
94
|
-
declare function decodeCommandSchema<S extends CommandSchema>(schema: S, value: unknown): Promise<SchemaOutput<S>>;
|
|
94
|
+
export declare function decodeCommandSchema<S extends CommandSchema>(schema: S, value: unknown): Promise<SchemaOutput<S>>;
|
|
95
95
|
//#endregion
|
|
96
|
-
export {
|
|
96
|
+
export { command_d_exports };
|
|
97
97
|
//# sourceMappingURL=command.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.mjs","names":["#operations","#execute"],"sources":["../../../../../src/components/foundation/modules/command/command.ts"],"sourcesContent":["/* oxlint-disable anti-slop/no-unknown-parameters -- Schema validators and interpreter decoders own these untrusted input boundaries and validate before domain callbacks. */\nexport type Parseable<Output> = Readonly<{\n\tparse: <Input>(value: Input) => Output\n\tparseAsync?: <Input>(value: Input) => Promise<Output>\n}>\n\n/** Structural mirror of portable neutral contracts: components cannot import host modules. */\ninterface ValidationIssue {\n\treadonly message: string\n\treadonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[]\n}\ntype ValidationResult<Output> =\n\t| { readonly value: Output; readonly issues?: undefined }\n\t| { readonly issues: readonly ValidationIssue[] }\ninterface StandardSchema<Input = unknown, Output = unknown> {\n\treadonly '~standard': {\n\t\treadonly version: 1\n\t\treadonly vendor: string\n\t\treadonly types?: { readonly input: Input; readonly output: Output }\n\t\treadonly validate: (\n\t\t\tvalue: unknown,\n\t\t) => ValidationResult<Output> | Promise<ValidationResult<Output>>\n\t}\n}\ninterface NeutralDecoder<Input = unknown, Output = unknown, Execution = unknown> {\n\treadonly kind: 'contract'\n\treadonly types?: { readonly input: Input; readonly output: Output }\n\treadonly decode: (value: unknown) => Execution\n}\nexport type CommandSchema<Output = unknown> =\n\t| Parseable<Output>\n\t| StandardSchema<unknown, Output>\n\t| NeutralDecoder<unknown, Output, ValidationResult<Output> | Promise<ValidationResult<Output>>>\n\n/** Raw values accepted before decoding, including transform inputs. */\nexport type SchemaInput<Schema extends CommandSchema> =\n\tSchema extends NeutralDecoder<infer Input, unknown, unknown>\n\t\t? Input\n\t\t: Schema extends { _input: infer Input }\n\t\t\t? Input\n\t\t\t: Schema extends StandardSchema<infer Input, unknown>\n\t\t\t\t? Input\n\t\t\t\t: SchemaOutput<Schema>\nexport type SchemaOutput<Schema extends CommandSchema> =\n\tSchema extends Parseable<unknown>\n\t\t? ReturnType<Schema['parse']>\n\t\t: Schema extends NeutralDecoder<unknown, infer Output, unknown>\n\t\t\t? Output\n\t\t\t: Schema extends StandardSchema<unknown, infer Output>\n\t\t\t\t? Output\n\t\t\t\t: never\nexport type CommandHandlerResult<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaInput<Registry[Key]['result']>\n\nexport type CommandRegistry = Readonly<Record<string, CommandDefinition>>\n\n/** Values accepted from callers before the command schema parses them. */\nexport type CommandArgument<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaInput<Registry[Key]['command']>\n\nexport type CommandInput<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaOutput<Registry[Key]['command']>\n\nexport type CommandResult<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaOutput<Registry[Key]['result']>\n\nexport type CommandExecution<\n\tContext,\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = Readonly<{\n\tcontext: Context\n\toperation: Key\n\tdefinition: Registry[Key]\n\tcommand: CommandInput<Registry, Key>\n\tparseResult: <Input>(value: Input) => CommandResult<Registry, Key>\n\t/** Interpreter-owned asynchronous result decoding, preserving the legacy parser. */\n\tdecodeResult?: <Input>(value: Input) => Promise<CommandResult<Registry, Key>>\n\t/** Runs the handler (result-parsed). Accepts a middleware-enriched context. */\n\trun: (context?: Context) => Promise<CommandResult<Registry, Key>>\n\t/** Runs without parsing for owners that validate after their middleware chain. */\n\trunUnparsed: (context?: Context) => Promise<CommandHandlerResult<Registry, Key>>\n}>\n\ntype CommandDefinition = Readonly<{\n\tcommand: CommandSchema\n\tresult: CommandSchema\n}>\n\ntype Operation<Registry extends CommandRegistry> = Extract<keyof Registry, string>\ntype MaybePromise<Value> = Value | Promise<Value>\ntype Execute<Context, Registry extends CommandRegistry> = <Key extends Operation<Registry>>(\n\texecution: CommandExecution<Context, Registry, Key>,\n) => Promise<CommandResult<Registry, Key>>\n\ntype FixedExecutor<\n\tContext,\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = Readonly<{\n\toperation: Key\n\thandler: (\n\t\tcontext: Context,\n\t\tcommand: CommandInput<Registry, Key>,\n\t) => MaybePromise<CommandHandlerResult<Registry, Key>>\n}>\n\ntype DynamicExecutor<\n\tContext,\n\tRegistry extends CommandRegistry,\n\tDispatcher,\n\tKey extends Operation<Registry>,\n> = Readonly<{\n\tdispatcher: Parseable<Dispatcher>\n\tselect: (dispatcher: Dispatcher) => Key\n\thandler: (\n\t\tcontext: Context,\n\t\tcommand: CommandInput<Registry, Key>,\n\t) => MaybePromise<CommandHandlerResult<Registry, Key>>\n}>\n\nclass CommandConfigurationError extends Error {\n\treadonly code = 'COMMAND_OPERATION_NOT_CONFIGURED'\n\treadonly name = 'CommandConfigurationError'\n\n\tconstructor() {\n\t\tsuper('The selected command operation is not configured')\n\t}\n}\n\n/** Generic command kernel. Host policy is injected by the owning domain. */\nexport class Command<Context, const Registry extends CommandRegistry> {\n\treadonly #operations: Registry\n\treadonly #execute: Execute<Context, Registry>\n\n\tconstructor(configuration: {\n\t\treadonly operations: Registry\n\t\treadonly execute: Execute<Context, Registry>\n\t}) {\n\t\tthis.#operations = configuration.operations\n\t\tthis.#execute = configuration.execute\n\t}\n\n\texec<const Key extends Operation<Registry>>(\n\t\texecutor: FixedExecutor<Context, Registry, Key>,\n\t): (\n\t\tcontext: Context,\n\t\tcommand: CommandArgument<Registry, Key>,\n\t) => Promise<CommandResult<Registry, Key>>\n\texec<Dispatcher, const Key extends Operation<Registry>>(\n\t\texecutor: DynamicExecutor<Context, Registry, Dispatcher, Key>,\n\t): (context: Context, command: Dispatcher) => Promise<CommandResult<Registry, Key>>\n\texec<Dispatcher>(\n\t\texecutor:\n\t\t\t| FixedExecutor<Context, Registry, Operation<Registry>>\n\t\t\t| DynamicExecutor<Context, Registry, Dispatcher, Operation<Registry>>,\n\t) {\n\t\treturn async (\n\t\t\tcontext: Context,\n\t\t\tvalue: Dispatcher | CommandArgument<Registry, Operation<Registry>>,\n\t\t) => {\n\t\t\tconst selected =\n\t\t\t\t'operation' in executor\n\t\t\t\t\t? { operation: executor.operation, value }\n\t\t\t\t\t: await (async () => {\n\t\t\t\t\t\t\tconst dispatcher = await decodeCommandSchema(executor.dispatcher, value)\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\toperation: executor.select(dispatcher),\n\t\t\t\t\t\t\t\tvalue: dispatcher,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})()\n\t\t\tif (!Object.prototype.hasOwnProperty.call(this.#operations, selected.operation)) {\n\t\t\t\tthrow new CommandConfigurationError()\n\t\t\t}\n\t\t\tconst operation = selected.operation\n\t\t\tconst definition = this.#operations[operation]\n\t\t\t// SAFETY: the selected registry entry owns this command schema and its output.\n\t\t\tconst command = (await decodeCommandSchema(\n\t\t\t\tdefinition.command,\n\t\t\t\tselected.value,\n\t\t\t)) as CommandInput<Registry, Operation<Registry>>\n\t\t\t// SAFETY: the selected entry also owns the result schema, including transforms.\n\t\t\tconst parseResult = <Input>(result: Input) =>\n\t\t\t\tparseCommandSchema(definition.result, result) as CommandResult<\n\t\t\t\t\tRegistry,\n\t\t\t\t\tOperation<Registry>\n\t\t\t\t>\n\t\t\t// SAFETY: selected result schema owns the decoded output, including async transforms.\n\t\t\tconst decodeResult = async <Input>(result: Input) =>\n\t\t\t\t(await decodeCommandSchema(definition.result, result)) as CommandResult<\n\t\t\t\t\tRegistry,\n\t\t\t\t\tOperation<Registry>\n\t\t\t\t>\n\t\t\tconst handler = executor.handler\n\t\t\treturn this.#execute({\n\t\t\t\tcontext,\n\t\t\t\toperation,\n\t\t\t\tdefinition,\n\t\t\t\tcommand,\n\t\t\t\tparseResult,\n\t\t\t\tdecodeResult,\n\t\t\t\trunUnparsed: async (contextOverride?: Context) =>\n\t\t\t\t\thandler(contextOverride ?? context, command),\n\t\t\t\trun: async (contextOverride?: Context) =>\n\t\t\t\t\tdecodeResult(await handler(contextOverride ?? context, command)),\n\t\t\t})\n\t\t}\n\t}\n}\n\n/** Legacy synchronous parsing remains available to existing kernel interpreters. */\nexport function parseCommandSchema<S extends CommandSchema>(\n\tschema: S,\n\tvalue: unknown,\n): SchemaOutput<S> {\n\tif (!('parse' in schema))\n\t\tthrow new TypeError('This command schema requires asynchronous decoding')\n\t// SAFETY: this legacy parser belongs to the selected schema.\n\treturn schema.parse(value) as SchemaOutput<S>\n}\n\n/** Interpreter-owned decoding awaits validation and leaves thrown/rejected defects intact. */\nexport async function decodeCommandSchema<S extends CommandSchema>(\n\tschema: S,\n\tvalue: unknown,\n): Promise<SchemaOutput<S>> {\n\tif ('parse' in schema) {\n\t\t// SAFETY: parseAsync and parse share the selected legacy schema's output.\n\t\treturn (await (schema.parseAsync\n\t\t\t? schema.parseAsync(value)\n\t\t\t: schema.parse(value))) as SchemaOutput<S>\n\t}\n\tconst result = await ('kind' in schema\n\t\t? schema.decode(value)\n\t\t: schema['~standard'].validate(value))\n\tif (result.issues !== undefined) throw new CommandValidationError(result.issues)\n\t// SAFETY: this decoder owns the selected schema's output.\n\treturn result.value as SchemaOutput<S>\n}\n\nclass CommandValidationError extends Error {\n\treadonly name = 'CommandValidationError'\n\tconstructor(readonly issues: readonly ValidationIssue[]) {\n\t\tsuper('Command contract validation failed')\n\t}\n}\n"],"mappings":"AAiIA,IAAM,EAAN,cAAwC,KAAM,CAC7C,KAAgB,mCAChB,KAAgB,4BAEhB,aAAc,CACb,MAAM,kDAAkD,CACzD,CACD,EAGa,EAAb,KAAsE,CACrE,GACA,GAEA,YAAY,EAGT,CACF,KAAKA,GAAc,EAAc,WACjC,KAAKC,GAAW,EAAc,OAC/B,CAWA,KACC,EAGC,CACD,OAAO,MACN,EACA,IACI,CACJ,IAAM,EACL,cAAe,EACZ,CAAE,UAAW,EAAS,UAAW,OAAM,EACvC,MAAO,SAAY,CACnB,IAAM,EAAa,MAAM,EAAoB,EAAS,WAAY,CAAK,EACvE,MAAO,CACN,UAAW,EAAS,OAAO,CAAU,EACrC,MAAO,CACR,CACD,EAAA,CAAG,EACN,GAAI,CAAC,OAAO,UAAU,eAAe,KAAK,KAAKD,GAAa,EAAS,SAAS,EAC7E,MAAM,IAAI,EAEX,IAAM,EAAY,EAAS,UACrB,EAAa,KAAKA,GAAY,GAE9B,EAAW,MAAM,EACtB,EAAW,QACX,EAAS,KACV,EAEM,EAAsB,GAC3B,EAAmB,EAAW,OAAQ,CAAM,EAKvC,EAAe,KAAc,IACjC,MAAM,EAAoB,EAAW,OAAQ,CAAM,EAI/C,EAAU,EAAS,QACzB,OAAO,KAAKC,GAAS,CACpB,UACA,YACA,aACA,UACA,cACA,eACA,YAAa,KAAO,IACnB,EAAQ,GAAmB,EAAS,CAAO,EAC5C,IAAK,KAAO,IACX,EAAa,MAAM,EAAQ,GAAmB,EAAS,CAAO,CAAC,CACjE,CAAC,CACF,CACD,CACD,EAGA,SAAgB,EACf,EACA,EACkB,CAClB,GAAI,EAAE,UAAW,GAChB,MAAU,UAAU,oDAAoD,EAEzE,OAAO,EAAO,MAAM,CAAK,CAC1B,CAGA,eAAsB,EACrB,EACA,EAC2B,CAC3B,GAAI,UAAW,EAEd,OAAQ,MAAO,EAAO,WACnB,EAAO,WAAW,CAAK,EACvB,EAAO,MAAM,CAAK,GAEtB,IAAM,EAAS,MAAO,SAAU,EAC7B,EAAO,OAAO,CAAK,EACnB,EAAO,YAAY,CAAC,SAAS,CAAK,GACrC,GAAI,EAAO,SAAW,IAAA,GAAW,MAAM,IAAI,EAAuB,EAAO,MAAM,EAE/E,OAAO,EAAO,KACf,CAEA,IAAM,EAAN,cAAqC,KAAM,CAErB,OADrB,KAAgB,yBAChB,YAAY,EAA6C,CACxD,MAAM,oCAAoC,EADtB,KAAA,OAAA,CAErB,CACD"}
|
|
1
|
+
{"version":3,"file":"command.mjs","names":["CommandConfigurationError","Command","#operations","configuration","#execute","selected","executor","dispatcher","decodeCommandSchema","value","operation","definition","command","parseResult","parseCommandSchema","result","decodeResult","handler","contextOverride","context","schema","CommandValidationError","issues"],"sources":["../../../../../src/components/foundation/modules/command/command.ts"],"sourcesContent":["/* oxlint-disable anti-slop/no-unknown-parameters -- Schema validators and interpreter decoders own these untrusted input boundaries and validate before domain callbacks. */\nexport type Parseable<Output> = Readonly<{\n\tparse: <Input>(value: Input) => Output\n\tparseAsync?: <Input>(value: Input) => Promise<Output>\n}>\n\n/** Structural mirror of portable neutral contracts: components cannot import host modules. */\ninterface ValidationIssue {\n\treadonly message: string\n\treadonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[]\n}\ntype ValidationResult<Output> =\n\t| { readonly value: Output; readonly issues?: undefined }\n\t| { readonly issues: readonly ValidationIssue[] }\ninterface StandardSchema<Input = unknown, Output = unknown> {\n\treadonly '~standard': {\n\t\treadonly version: 1\n\t\treadonly vendor: string\n\t\treadonly types?: { readonly input: Input; readonly output: Output }\n\t\treadonly validate: (\n\t\t\tvalue: unknown,\n\t\t) => ValidationResult<Output> | Promise<ValidationResult<Output>>\n\t}\n}\ninterface NeutralDecoder<Input = unknown, Output = unknown, Execution = unknown> {\n\treadonly kind: 'contract'\n\treadonly types?: { readonly input: Input; readonly output: Output }\n\treadonly decode: (value: unknown) => Execution\n}\nexport type CommandSchema<Output = unknown> =\n\t| Parseable<Output>\n\t| StandardSchema<unknown, Output>\n\t| NeutralDecoder<unknown, Output, ValidationResult<Output> | Promise<ValidationResult<Output>>>\n\n/** Raw values accepted before decoding, including transform inputs. */\nexport type SchemaInput<Schema extends CommandSchema> =\n\tSchema extends NeutralDecoder<infer Input, unknown, unknown>\n\t\t? Input\n\t\t: Schema extends { _input: infer Input }\n\t\t\t? Input\n\t\t\t: Schema extends StandardSchema<infer Input, unknown>\n\t\t\t\t? Input\n\t\t\t\t: SchemaOutput<Schema>\nexport type SchemaOutput<Schema extends CommandSchema> =\n\tSchema extends Parseable<unknown>\n\t\t? ReturnType<Schema['parse']>\n\t\t: Schema extends NeutralDecoder<unknown, infer Output, unknown>\n\t\t\t? Output\n\t\t\t: Schema extends StandardSchema<unknown, infer Output>\n\t\t\t\t? Output\n\t\t\t\t: never\nexport type CommandHandlerResult<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaInput<Registry[Key]['result']>\n\nexport type CommandRegistry = Readonly<Record<string, CommandDefinition>>\n\n/** Values accepted from callers before the command schema parses them. */\nexport type CommandArgument<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaInput<Registry[Key]['command']>\n\nexport type CommandInput<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaOutput<Registry[Key]['command']>\n\nexport type CommandResult<\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = SchemaOutput<Registry[Key]['result']>\n\nexport type CommandExecution<\n\tContext,\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = Readonly<{\n\tcontext: Context\n\toperation: Key\n\tdefinition: Registry[Key]\n\tcommand: CommandInput<Registry, Key>\n\tparseResult: <Input>(value: Input) => CommandResult<Registry, Key>\n\t/** Interpreter-owned asynchronous result decoding, preserving the legacy parser. */\n\tdecodeResult?: <Input>(value: Input) => Promise<CommandResult<Registry, Key>>\n\t/** Runs the handler (result-parsed). Accepts a middleware-enriched context. */\n\trun: (context?: Context) => Promise<CommandResult<Registry, Key>>\n\t/** Runs without parsing for owners that validate after their middleware chain. */\n\trunUnparsed: (context?: Context) => Promise<CommandHandlerResult<Registry, Key>>\n}>\n\ntype CommandDefinition = Readonly<{\n\tcommand: CommandSchema\n\tresult: CommandSchema\n}>\n\ntype Operation<Registry extends CommandRegistry> = Extract<keyof Registry, string>\ntype MaybePromise<Value> = Value | Promise<Value>\ntype Execute<Context, Registry extends CommandRegistry> = <Key extends Operation<Registry>>(\n\texecution: CommandExecution<Context, Registry, Key>,\n) => Promise<CommandResult<Registry, Key>>\n\ntype FixedExecutor<\n\tContext,\n\tRegistry extends CommandRegistry,\n\tKey extends Operation<Registry>,\n> = Readonly<{\n\toperation: Key\n\thandler: (\n\t\tcontext: Context,\n\t\tcommand: CommandInput<Registry, Key>,\n\t) => MaybePromise<CommandHandlerResult<Registry, Key>>\n}>\n\ntype DynamicExecutor<\n\tContext,\n\tRegistry extends CommandRegistry,\n\tDispatcher,\n\tKey extends Operation<Registry>,\n> = Readonly<{\n\tdispatcher: Parseable<Dispatcher>\n\tselect: (dispatcher: Dispatcher) => Key\n\thandler: (\n\t\tcontext: Context,\n\t\tcommand: CommandInput<Registry, Key>,\n\t) => MaybePromise<CommandHandlerResult<Registry, Key>>\n}>\n\nclass CommandConfigurationError extends Error {\n\treadonly code = 'COMMAND_OPERATION_NOT_CONFIGURED'\n\treadonly name = 'CommandConfigurationError'\n\n\tconstructor() {\n\t\tsuper('The selected command operation is not configured')\n\t}\n}\n\n/** Generic command kernel. Host policy is injected by the owning domain. */\nexport class Command<Context, const Registry extends CommandRegistry> {\n\treadonly #operations: Registry\n\treadonly #execute: Execute<Context, Registry>\n\n\tconstructor(configuration: {\n\t\treadonly operations: Registry\n\t\treadonly execute: Execute<Context, Registry>\n\t}) {\n\t\tthis.#operations = configuration.operations\n\t\tthis.#execute = configuration.execute\n\t}\n\n\texec<const Key extends Operation<Registry>>(\n\t\texecutor: FixedExecutor<Context, Registry, Key>,\n\t): (\n\t\tcontext: Context,\n\t\tcommand: CommandArgument<Registry, Key>,\n\t) => Promise<CommandResult<Registry, Key>>\n\texec<Dispatcher, const Key extends Operation<Registry>>(\n\t\texecutor: DynamicExecutor<Context, Registry, Dispatcher, Key>,\n\t): (context: Context, command: Dispatcher) => Promise<CommandResult<Registry, Key>>\n\texec<Dispatcher>(\n\t\texecutor:\n\t\t\t| FixedExecutor<Context, Registry, Operation<Registry>>\n\t\t\t| DynamicExecutor<Context, Registry, Dispatcher, Operation<Registry>>,\n\t) {\n\t\treturn async (\n\t\t\tcontext: Context,\n\t\t\tvalue: Dispatcher | CommandArgument<Registry, Operation<Registry>>,\n\t\t) => {\n\t\t\tconst selected =\n\t\t\t\t'operation' in executor\n\t\t\t\t\t? { operation: executor.operation, value }\n\t\t\t\t\t: await (async () => {\n\t\t\t\t\t\t\tconst dispatcher = await decodeCommandSchema(executor.dispatcher, value)\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\toperation: executor.select(dispatcher),\n\t\t\t\t\t\t\t\tvalue: dispatcher,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})()\n\t\t\tif (!Object.prototype.hasOwnProperty.call(this.#operations, selected.operation)) {\n\t\t\t\tthrow new CommandConfigurationError()\n\t\t\t}\n\t\t\tconst operation = selected.operation\n\t\t\tconst definition = this.#operations[operation]\n\t\t\t// SAFETY: the selected registry entry owns this command schema and its output.\n\t\t\tconst command = (await decodeCommandSchema(\n\t\t\t\tdefinition.command,\n\t\t\t\tselected.value,\n\t\t\t)) as CommandInput<Registry, Operation<Registry>>\n\t\t\t// SAFETY: the selected entry also owns the result schema, including transforms.\n\t\t\tconst parseResult = <Input>(result: Input) =>\n\t\t\t\tparseCommandSchema(definition.result, result) as CommandResult<\n\t\t\t\t\tRegistry,\n\t\t\t\t\tOperation<Registry>\n\t\t\t\t>\n\t\t\t// SAFETY: selected result schema owns the decoded output, including async transforms.\n\t\t\tconst decodeResult = async <Input>(result: Input) =>\n\t\t\t\t(await decodeCommandSchema(definition.result, result)) as CommandResult<\n\t\t\t\t\tRegistry,\n\t\t\t\t\tOperation<Registry>\n\t\t\t\t>\n\t\t\tconst handler = executor.handler\n\t\t\treturn this.#execute({\n\t\t\t\tcontext,\n\t\t\t\toperation,\n\t\t\t\tdefinition,\n\t\t\t\tcommand,\n\t\t\t\tparseResult,\n\t\t\t\tdecodeResult,\n\t\t\t\trunUnparsed: async (contextOverride?: Context) =>\n\t\t\t\t\thandler(contextOverride ?? context, command),\n\t\t\t\trun: async (contextOverride?: Context) =>\n\t\t\t\t\tdecodeResult(await handler(contextOverride ?? context, command)),\n\t\t\t})\n\t\t}\n\t}\n}\n\n/** Legacy synchronous parsing remains available to existing kernel interpreters. */\nexport function parseCommandSchema<S extends CommandSchema>(\n\tschema: S,\n\tvalue: unknown,\n): SchemaOutput<S> {\n\tif (!('parse' in schema))\n\t\tthrow new TypeError('This command schema requires asynchronous decoding')\n\t// SAFETY: this legacy parser belongs to the selected schema.\n\treturn schema.parse(value) as SchemaOutput<S>\n}\n\n/** Interpreter-owned decoding awaits validation and leaves thrown/rejected defects intact. */\nexport async function decodeCommandSchema<S extends CommandSchema>(\n\tschema: S,\n\tvalue: unknown,\n): Promise<SchemaOutput<S>> {\n\tif ('parse' in schema) {\n\t\t// SAFETY: parseAsync and parse share the selected legacy schema's output.\n\t\treturn (await (schema.parseAsync\n\t\t\t? schema.parseAsync(value)\n\t\t\t: schema.parse(value))) as SchemaOutput<S>\n\t}\n\tconst result = await ('kind' in schema\n\t\t? schema.decode(value)\n\t\t: schema['~standard'].validate(value))\n\tif (result.issues !== undefined) throw new CommandValidationError(result.issues)\n\t// SAFETY: this decoder owns the selected schema's output.\n\treturn result.value as SchemaOutput<S>\n}\n\nclass CommandValidationError extends Error {\n\treadonly name = 'CommandValidationError'\n\tconstructor(readonly issues: readonly ValidationIssue[]) {\n\t\tsuper('Command contract validation failed')\n\t}\n}\n"],"mappings":"AAiIA,IAAMA,EAAN,cAAwC,KAAM,CAC7C,KAAgB,mCAChB,KAAgB,4BAEhB,aAAc,CACb,MAAM,kDAAkD,CACzD,CACD,EAGaC,EAAb,KAAsE,CACrE,GACA,GAEA,YAAY,EAGT,CACF,KAAKC,GAAcC,EAAc,WACjC,KAAKC,GAAWD,EAAc,OAC/B,CAWA,KACC,EAGC,CACD,OAAO,MACN,EACA,IACI,CACJ,IAAME,EACL,cAAeC,EACZ,CAAE,UAAWA,EAAS,UAAW,OAAM,EACvC,MAAO,SAAY,CACnB,IAAMC,EAAa,MAAMC,EAAoBF,EAAS,WAAYG,CAAK,EACvE,MAAO,CACN,UAAWH,EAAS,OAAOC,CAAU,EACrC,MAAOA,CACR,CACD,EAAA,CAAG,EACN,GAAI,CAAC,OAAO,UAAU,eAAe,KAAK,KAAKL,GAAaG,EAAS,SAAS,EAC7E,MAAM,IAAIL,EAEX,IAAMU,EAAYL,EAAS,UACrBM,EAAa,KAAKT,GAAYQ,GAE9BE,EAAW,MAAMJ,EACtBG,EAAW,QACXN,EAAS,KACV,EAEMQ,EAAsB,GAC3BC,EAAmBH,EAAW,OAAQI,CAAM,EAKvCC,EAAe,KAAc,IACjC,MAAMR,EAAoBG,EAAW,OAAQI,CAAM,EAI/CE,EAAUX,EAAS,QACzB,OAAO,KAAKF,GAAS,CACpB,UACA,YACA,aACA,UACA,cACA,eACA,YAAa,KAAO,IACnBa,EAAQC,GAAmBC,EAASP,CAAO,EAC5C,IAAK,KAAO,IACXI,EAAa,MAAMC,EAAQC,GAAmBC,EAASP,CAAO,CAAC,CACjE,CAAC,CACF,CACD,CACD,EAGA,SAAgBE,EACf,EACA,EACkB,CAClB,GAAI,EAAE,UAAWM,GAChB,MAAU,UAAU,oDAAoD,EAEzE,OAAOA,EAAO,MAAMX,CAAK,CAC1B,CAGA,eAAsBD,EACrB,EACA,EAC2B,CAC3B,GAAI,UAAWY,EAEd,OAAQ,MAAOA,EAAO,WACnBA,EAAO,WAAWX,CAAK,EACvBW,EAAO,MAAMX,CAAK,GAEtB,IAAMM,EAAS,MAAO,SAAUK,EAC7BA,EAAO,OAAOX,CAAK,EACnBW,EAAO,YAAY,CAAC,SAASX,CAAK,GACrC,GAAIM,EAAO,SAAW,IAAA,GAAW,MAAM,IAAIM,EAAuBN,EAAO,MAAM,EAE/E,OAAOA,EAAO,KACf,CAEA,IAAMM,EAAN,cAAqC,KAAM,CAErB,OADrB,KAAgB,yBAChB,YAAY,EAA6C,CACxD,MAAM,oCAAoC,EADtB,KAAA,OAAAC,CAErB,CACD"}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { AuditEntryInput } from "../../client.mjs";
|
|
2
2
|
//#region src/components/foundation/modules/command/lifecycle.d.ts
|
|
3
3
|
/** Internal sequencing only: interpreters own callback normalization and observation. */
|
|
4
|
-
interface ExecutionKind {
|
|
4
|
+
export interface ExecutionKind {
|
|
5
5
|
readonly value: unknown;
|
|
6
6
|
readonly type: unknown;
|
|
7
7
|
}
|
|
8
|
-
type ExecutionValue<Kind extends ExecutionKind, Value> = (Kind & {
|
|
8
|
+
export type ExecutionValue<Kind extends ExecutionKind, Value> = (Kind & {
|
|
9
9
|
readonly value: Value;
|
|
10
10
|
})['type'];
|
|
11
|
-
interface LifecycleAlgebra<Kind extends ExecutionKind> {
|
|
11
|
+
export interface LifecycleAlgebra<Kind extends ExecutionKind> {
|
|
12
12
|
succeed<Value>(value: Value): ExecutionValue<Kind, Value>;
|
|
13
13
|
suspend<Value>(execute: () => ExecutionValue<Kind, Value>): ExecutionValue<Kind, Value>;
|
|
14
14
|
flatMap<Input, Output>(execution: ExecutionValue<Kind, Input>, next: (input: Input) => ExecutionValue<Kind, Output>): ExecutionValue<Kind, Output>;
|
|
15
15
|
}
|
|
16
|
-
interface PromiseExecution extends ExecutionKind {
|
|
16
|
+
export interface PromiseExecution extends ExecutionKind {
|
|
17
17
|
readonly type: Promise<this['value']>;
|
|
18
18
|
}
|
|
19
|
-
declare const promiseLifecycle: LifecycleAlgebra<PromiseExecution>;
|
|
20
|
-
type LifecyclePreparation<Kind extends ExecutionKind, Result> = {
|
|
19
|
+
export declare const promiseLifecycle: LifecycleAlgebra<PromiseExecution>;
|
|
20
|
+
export type LifecyclePreparation<Kind extends ExecutionKind, Result> = {
|
|
21
21
|
kind: 'replay';
|
|
22
22
|
result: unknown;
|
|
23
23
|
} | {
|
|
24
24
|
kind: 'execute';
|
|
25
25
|
complete?: (result: Result) => ExecutionValue<Kind, void>;
|
|
26
26
|
};
|
|
27
|
-
type LifecycleMiddleware<Kind extends ExecutionKind, Context, Input, Raw> = (input: {
|
|
27
|
+
export type LifecycleMiddleware<Kind extends ExecutionKind, Context, Input, Raw> = (input: {
|
|
28
28
|
operation: string;
|
|
29
29
|
context: Context;
|
|
30
30
|
command: Input;
|
|
@@ -32,7 +32,7 @@ type LifecycleMiddleware<Kind extends ExecutionKind, Context, Input, Raw> = (inp
|
|
|
32
32
|
context?: object;
|
|
33
33
|
}) => ExecutionValue<Kind, Raw>;
|
|
34
34
|
}) => ExecutionValue<Kind, Raw>;
|
|
35
|
-
type LifecycleExecution<Kind extends ExecutionKind, Context, Input, Raw, Result> = {
|
|
35
|
+
export type LifecycleExecution<Kind extends ExecutionKind, Context, Input, Raw, Result> = {
|
|
36
36
|
operation: string;
|
|
37
37
|
classification: string;
|
|
38
38
|
context: Context;
|
|
@@ -60,22 +60,21 @@ type LifecycleExecution<Kind extends ExecutionKind, Context, Input, Raw, Result>
|
|
|
60
60
|
decodeResult: (value: Raw) => ExecutionValue<Kind, Result>;
|
|
61
61
|
});
|
|
62
62
|
/** One owner for the command protocol; every interpretation allocates fresh dispatch state. */
|
|
63
|
-
declare function executeCommandLifecycle<Kind extends ExecutionKind, Context, Input, Raw, Result>(algebra: LifecycleAlgebra<Kind>, execution: LifecycleExecution<Kind, Context, Input, Raw, Result>): ExecutionValue<Kind, Result>;
|
|
64
|
-
declare class CommandMiddlewareError extends Error {
|
|
63
|
+
export declare function executeCommandLifecycle<Kind extends ExecutionKind, Context, Input, Raw, Result>(algebra: LifecycleAlgebra<Kind>, execution: LifecycleExecution<Kind, Context, Input, Raw, Result>): ExecutionValue<Kind, Result>;
|
|
64
|
+
export declare class CommandMiddlewareError extends Error {
|
|
65
65
|
readonly code = "COMMAND_MIDDLEWARE_NEXT_REUSED";
|
|
66
66
|
readonly name = "CommandMiddlewareError";
|
|
67
67
|
constructor(operation: string);
|
|
68
68
|
}
|
|
69
|
-
declare class CommandAggregateError extends Error {
|
|
69
|
+
export declare class CommandAggregateError extends Error {
|
|
70
70
|
readonly code = "COMMAND_AGGREGATE_NOT_DECLARED";
|
|
71
71
|
readonly name = "CommandAggregateError";
|
|
72
72
|
constructor(operation: string, aggregateType: string);
|
|
73
73
|
}
|
|
74
|
-
declare class CommandPermissionError extends Error {
|
|
74
|
+
export declare class CommandPermissionError extends Error {
|
|
75
75
|
readonly code = "COMMAND_PERMISSION_NOT_CONFIGURED";
|
|
76
76
|
readonly name = "CommandPermissionError";
|
|
77
77
|
constructor(operation: string);
|
|
78
78
|
}
|
|
79
79
|
//#endregion
|
|
80
|
-
export { CommandAggregateError, CommandMiddlewareError, CommandPermissionError, ExecutionKind, ExecutionValue, LifecycleAlgebra, LifecycleExecution, LifecycleMiddleware, LifecyclePreparation, PromiseExecution, executeCommandLifecycle, promiseLifecycle };
|
|
81
80
|
//# sourceMappingURL=lifecycle.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.mjs","names":[],"sources":["../../../../../src/components/foundation/modules/command/lifecycle.ts"],"sourcesContent":["import type { AuditEntryInput } from '../../client'\n\n/** Internal sequencing only: interpreters own callback normalization and observation. */\nexport interface ExecutionKind {\n\treadonly value: unknown\n\treadonly type: unknown\n}\nexport type ExecutionValue<Kind extends ExecutionKind, Value> = (Kind & {\n\treadonly value: Value\n})['type']\nexport interface LifecycleAlgebra<Kind extends ExecutionKind> {\n\tsucceed<Value>(value: Value): ExecutionValue<Kind, Value>\n\tsuspend<Value>(execute: () => ExecutionValue<Kind, Value>): ExecutionValue<Kind, Value>\n\tflatMap<Input, Output>(\n\t\texecution: ExecutionValue<Kind, Input>,\n\t\tnext: (input: Input) => ExecutionValue<Kind, Output>,\n\t): ExecutionValue<Kind, Output>\n}\nexport interface PromiseExecution extends ExecutionKind {\n\treadonly type: Promise<this['value']>\n}\nexport const promiseLifecycle: LifecycleAlgebra<PromiseExecution> = {\n\tsucceed: (value) => Promise.resolve(value),\n\tsuspend: (execute) => Promise.resolve().then(execute),\n\tflatMap: (execution, next) => execution.then(next),\n}\nexport type LifecyclePreparation<Kind extends ExecutionKind, Result> =\n\t| { kind: 'replay'; result: unknown }\n\t| { kind: 'execute'; complete?: (result: Result) => ExecutionValue<Kind, void> }\nexport type LifecycleMiddleware<Kind extends ExecutionKind, Context, Input, Raw> = (input: {\n\toperation: string\n\tcontext: Context\n\tcommand: Input\n\tnext: (options?: { context?: object }) => ExecutionValue<Kind, Raw>\n}) => ExecutionValue<Kind, Raw>\nexport type LifecycleExecution<Kind extends ExecutionKind, Context, Input, Raw, Result> = {\n\toperation: string\n\tclassification: string\n\tcontext: Context\n\tcommand: Input\n\tpermission?: () => ExecutionValue<Kind, void>\n\tprepare: () => ExecutionValue<Kind, LifecyclePreparation<Kind, Result> | undefined>\n\tmiddleware: readonly LifecycleMiddleware<Kind, Context, Input, Raw>[]\n\tdefaultGuard: (context: Context) => ExecutionValue<Kind, void>\n\tguard: (context: Context) => ExecutionValue<Kind, void>\n\trun: (context: Context) => ExecutionValue<Kind, Raw>\n\taudit: (result: Result) => ExecutionValue<Kind, Omit<AuditEntryInput, 'classification'> | null>\n\taggregates?: readonly string[]\n\twriteAudit: (entry: AuditEntryInput) => ExecutionValue<Kind, unknown>\n} & (\n\t| {\n\t\t\tparseReplay: <Value>(value: Value) => Result\n\t\t\t// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Replay decoding validates untrusted stored output at the interpreter boundary.\n\t\t\tdecodeReplay?: (value: unknown) => ExecutionValue<Kind, Result>\n\t }\n\t// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Replay decoding validates untrusted stored output at the interpreter boundary.\n\t| { parseReplay?: never; decodeReplay: (value: unknown) => ExecutionValue<Kind, Result> }\n) &\n\t(\n\t\t| {\n\t\t\t\tparseResult: (value: Raw) => Result\n\t\t\t\tdecodeResult?: (value: Raw) => ExecutionValue<Kind, Result>\n\t\t }\n\t\t| { parseResult?: never; decodeResult: (value: Raw) => ExecutionValue<Kind, Result> }\n\t)\n\n/** One owner for the command protocol; every interpretation allocates fresh dispatch state. */\nexport function executeCommandLifecycle<Kind extends ExecutionKind, Context, Input, Raw, Result>(\n\talgebra: LifecycleAlgebra<Kind>,\n\texecution: LifecycleExecution<Kind, Context, Input, Raw, Result>,\n): ExecutionValue<Kind, Result> {\n\treturn algebra.suspend(() => {\n\t\tlet deepest = -1\n\t\tconst terminal = (context: Context): ExecutionValue<Kind, Raw> =>\n\t\t\talgebra.flatMap(execution.defaultGuard(context), () =>\n\t\t\t\talgebra.flatMap(execution.guard(context), () => execution.run(context)),\n\t\t\t)\n\t\tconst dispatch = (index: number, context: Context): ExecutionValue<Kind, Raw> =>\n\t\t\talgebra.suspend(() => {\n\t\t\t\tif (index <= deepest) throw new CommandMiddlewareError(execution.operation)\n\t\t\t\tdeepest = index\n\t\t\t\tconst layer = execution.middleware[index]\n\t\t\t\tif (!layer) return terminal(context)\n\t\t\t\treturn layer({\n\t\t\t\t\toperation: execution.operation,\n\t\t\t\t\tcommand: execution.command,\n\t\t\t\t\tcontext,\n\t\t\t\t\tnext: (options) =>\n\t\t\t\t\t\tdispatch(index + 1, options?.context ? { ...context, ...options.context } : context),\n\t\t\t\t})\n\t\t\t})\n\t\treturn algebra.flatMap(execution.permission?.() ?? algebra.succeed(undefined), () =>\n\t\t\talgebra.flatMap(execution.prepare(), (preparation) => {\n\t\t\t\tif (preparation?.kind === 'replay') {\n\t\t\t\t\treturn algebra.suspend(() =>\n\t\t\t\t\t\texecution.decodeReplay\n\t\t\t\t\t\t\t? execution.decodeReplay(preparation.result)\n\t\t\t\t\t\t\t: algebra.succeed(execution.parseReplay!(preparation.result)),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn algebra.flatMap(dispatch(0, execution.context), (raw) => {\n\t\t\t\t\treturn algebra.flatMap(\n\t\t\t\t\t\texecution.decodeResult\n\t\t\t\t\t\t\t? execution.decodeResult(raw)\n\t\t\t\t\t\t\t: algebra.succeed(execution.parseResult!(raw)),\n\t\t\t\t\t\t(result) =>\n\t\t\t\t\t\t\talgebra.flatMap(execution.audit(result), (audit) => {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\taudit &&\n\t\t\t\t\t\t\t\t\texecution.aggregates &&\n\t\t\t\t\t\t\t\t\t!execution.aggregates.includes(audit.aggregate.type)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tthrow new CommandAggregateError(execution.operation, audit.aggregate.type)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn algebra.flatMap(\n\t\t\t\t\t\t\t\t\taudit\n\t\t\t\t\t\t\t\t\t\t? execution.writeAudit({ ...audit, classification: execution.classification })\n\t\t\t\t\t\t\t\t\t\t: algebra.succeed(undefined),\n\t\t\t\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\t\t\t\talgebra.flatMap(\n\t\t\t\t\t\t\t\t\t\t\tpreparation?.complete?.(result) ?? algebra.succeed(undefined),\n\t\t\t\t\t\t\t\t\t\t\t() => algebra.succeed(result),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t})\n\t\t\t}),\n\t\t)\n\t})\n}\n\nexport class CommandMiddlewareError extends Error {\n\treadonly code = 'COMMAND_MIDDLEWARE_NEXT_REUSED'\n\treadonly name = 'CommandMiddlewareError'\n\tconstructor(operation: string) {\n\t\tsuper(`A middleware for operation \"${operation}\" called next() more than once`)\n\t}\n}\nexport class CommandAggregateError extends Error {\n\treadonly code = 'COMMAND_AGGREGATE_NOT_DECLARED'\n\treadonly name = 'CommandAggregateError'\n\tconstructor(operation: string, aggregateType: string) {\n\t\tsuper(\n\t\t\t`Operation \"${operation}\" audited aggregate type \"${aggregateType}\" outside its declared aggregates`,\n\t\t)\n\t}\n}\nexport class CommandPermissionError extends Error {\n\treadonly code = 'COMMAND_PERMISSION_NOT_CONFIGURED'\n\treadonly name = 'CommandPermissionError'\n\tconstructor(operation: string) {\n\t\tsuper(\n\t\t\t`Operation \"${operation}\" declares a permission but the Foundation has no checkPermission`,\n\t\t)\n\t}\n}\n"],"mappings":"AAqBA,
|
|
1
|
+
{"version":3,"file":"lifecycle.mjs","names":["promiseLifecycle","value","execute","execution","next","executeCommandLifecycle","algebra","deepest","terminal","context","dispatch","index","CommandMiddlewareError","layer","options","preparation","raw","result","audit","CommandAggregateError","operation","aggregateType","CommandPermissionError"],"sources":["../../../../../src/components/foundation/modules/command/lifecycle.ts"],"sourcesContent":["import type { AuditEntryInput } from '../../client'\n\n/** Internal sequencing only: interpreters own callback normalization and observation. */\nexport interface ExecutionKind {\n\treadonly value: unknown\n\treadonly type: unknown\n}\nexport type ExecutionValue<Kind extends ExecutionKind, Value> = (Kind & {\n\treadonly value: Value\n})['type']\nexport interface LifecycleAlgebra<Kind extends ExecutionKind> {\n\tsucceed<Value>(value: Value): ExecutionValue<Kind, Value>\n\tsuspend<Value>(execute: () => ExecutionValue<Kind, Value>): ExecutionValue<Kind, Value>\n\tflatMap<Input, Output>(\n\t\texecution: ExecutionValue<Kind, Input>,\n\t\tnext: (input: Input) => ExecutionValue<Kind, Output>,\n\t): ExecutionValue<Kind, Output>\n}\nexport interface PromiseExecution extends ExecutionKind {\n\treadonly type: Promise<this['value']>\n}\nexport const promiseLifecycle: LifecycleAlgebra<PromiseExecution> = {\n\tsucceed: (value) => Promise.resolve(value),\n\tsuspend: (execute) => Promise.resolve().then(execute),\n\tflatMap: (execution, next) => execution.then(next),\n}\nexport type LifecyclePreparation<Kind extends ExecutionKind, Result> =\n\t| { kind: 'replay'; result: unknown }\n\t| { kind: 'execute'; complete?: (result: Result) => ExecutionValue<Kind, void> }\nexport type LifecycleMiddleware<Kind extends ExecutionKind, Context, Input, Raw> = (input: {\n\toperation: string\n\tcontext: Context\n\tcommand: Input\n\tnext: (options?: { context?: object }) => ExecutionValue<Kind, Raw>\n}) => ExecutionValue<Kind, Raw>\nexport type LifecycleExecution<Kind extends ExecutionKind, Context, Input, Raw, Result> = {\n\toperation: string\n\tclassification: string\n\tcontext: Context\n\tcommand: Input\n\tpermission?: () => ExecutionValue<Kind, void>\n\tprepare: () => ExecutionValue<Kind, LifecyclePreparation<Kind, Result> | undefined>\n\tmiddleware: readonly LifecycleMiddleware<Kind, Context, Input, Raw>[]\n\tdefaultGuard: (context: Context) => ExecutionValue<Kind, void>\n\tguard: (context: Context) => ExecutionValue<Kind, void>\n\trun: (context: Context) => ExecutionValue<Kind, Raw>\n\taudit: (result: Result) => ExecutionValue<Kind, Omit<AuditEntryInput, 'classification'> | null>\n\taggregates?: readonly string[]\n\twriteAudit: (entry: AuditEntryInput) => ExecutionValue<Kind, unknown>\n} & (\n\t| {\n\t\t\tparseReplay: <Value>(value: Value) => Result\n\t\t\t// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Replay decoding validates untrusted stored output at the interpreter boundary.\n\t\t\tdecodeReplay?: (value: unknown) => ExecutionValue<Kind, Result>\n\t }\n\t// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Replay decoding validates untrusted stored output at the interpreter boundary.\n\t| { parseReplay?: never; decodeReplay: (value: unknown) => ExecutionValue<Kind, Result> }\n) &\n\t(\n\t\t| {\n\t\t\t\tparseResult: (value: Raw) => Result\n\t\t\t\tdecodeResult?: (value: Raw) => ExecutionValue<Kind, Result>\n\t\t }\n\t\t| { parseResult?: never; decodeResult: (value: Raw) => ExecutionValue<Kind, Result> }\n\t)\n\n/** One owner for the command protocol; every interpretation allocates fresh dispatch state. */\nexport function executeCommandLifecycle<Kind extends ExecutionKind, Context, Input, Raw, Result>(\n\talgebra: LifecycleAlgebra<Kind>,\n\texecution: LifecycleExecution<Kind, Context, Input, Raw, Result>,\n): ExecutionValue<Kind, Result> {\n\treturn algebra.suspend(() => {\n\t\tlet deepest = -1\n\t\tconst terminal = (context: Context): ExecutionValue<Kind, Raw> =>\n\t\t\talgebra.flatMap(execution.defaultGuard(context), () =>\n\t\t\t\talgebra.flatMap(execution.guard(context), () => execution.run(context)),\n\t\t\t)\n\t\tconst dispatch = (index: number, context: Context): ExecutionValue<Kind, Raw> =>\n\t\t\talgebra.suspend(() => {\n\t\t\t\tif (index <= deepest) throw new CommandMiddlewareError(execution.operation)\n\t\t\t\tdeepest = index\n\t\t\t\tconst layer = execution.middleware[index]\n\t\t\t\tif (!layer) return terminal(context)\n\t\t\t\treturn layer({\n\t\t\t\t\toperation: execution.operation,\n\t\t\t\t\tcommand: execution.command,\n\t\t\t\t\tcontext,\n\t\t\t\t\tnext: (options) =>\n\t\t\t\t\t\tdispatch(index + 1, options?.context ? { ...context, ...options.context } : context),\n\t\t\t\t})\n\t\t\t})\n\t\treturn algebra.flatMap(execution.permission?.() ?? algebra.succeed(undefined), () =>\n\t\t\talgebra.flatMap(execution.prepare(), (preparation) => {\n\t\t\t\tif (preparation?.kind === 'replay') {\n\t\t\t\t\treturn algebra.suspend(() =>\n\t\t\t\t\t\texecution.decodeReplay\n\t\t\t\t\t\t\t? execution.decodeReplay(preparation.result)\n\t\t\t\t\t\t\t: algebra.succeed(execution.parseReplay!(preparation.result)),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn algebra.flatMap(dispatch(0, execution.context), (raw) => {\n\t\t\t\t\treturn algebra.flatMap(\n\t\t\t\t\t\texecution.decodeResult\n\t\t\t\t\t\t\t? execution.decodeResult(raw)\n\t\t\t\t\t\t\t: algebra.succeed(execution.parseResult!(raw)),\n\t\t\t\t\t\t(result) =>\n\t\t\t\t\t\t\talgebra.flatMap(execution.audit(result), (audit) => {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\taudit &&\n\t\t\t\t\t\t\t\t\texecution.aggregates &&\n\t\t\t\t\t\t\t\t\t!execution.aggregates.includes(audit.aggregate.type)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tthrow new CommandAggregateError(execution.operation, audit.aggregate.type)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn algebra.flatMap(\n\t\t\t\t\t\t\t\t\taudit\n\t\t\t\t\t\t\t\t\t\t? execution.writeAudit({ ...audit, classification: execution.classification })\n\t\t\t\t\t\t\t\t\t\t: algebra.succeed(undefined),\n\t\t\t\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\t\t\t\talgebra.flatMap(\n\t\t\t\t\t\t\t\t\t\t\tpreparation?.complete?.(result) ?? algebra.succeed(undefined),\n\t\t\t\t\t\t\t\t\t\t\t() => algebra.succeed(result),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t})\n\t\t\t}),\n\t\t)\n\t})\n}\n\nexport class CommandMiddlewareError extends Error {\n\treadonly code = 'COMMAND_MIDDLEWARE_NEXT_REUSED'\n\treadonly name = 'CommandMiddlewareError'\n\tconstructor(operation: string) {\n\t\tsuper(`A middleware for operation \"${operation}\" called next() more than once`)\n\t}\n}\nexport class CommandAggregateError extends Error {\n\treadonly code = 'COMMAND_AGGREGATE_NOT_DECLARED'\n\treadonly name = 'CommandAggregateError'\n\tconstructor(operation: string, aggregateType: string) {\n\t\tsuper(\n\t\t\t`Operation \"${operation}\" audited aggregate type \"${aggregateType}\" outside its declared aggregates`,\n\t\t)\n\t}\n}\nexport class CommandPermissionError extends Error {\n\treadonly code = 'COMMAND_PERMISSION_NOT_CONFIGURED'\n\treadonly name = 'CommandPermissionError'\n\tconstructor(operation: string) {\n\t\tsuper(\n\t\t\t`Operation \"${operation}\" declares a permission but the Foundation has no checkPermission`,\n\t\t)\n\t}\n}\n"],"mappings":"AAqBA,MAAaA,EAAuD,CACnE,QAAU,GAAU,QAAQ,QAAQC,CAAK,EACzC,QAAU,GAAY,QAAQ,QAAQ,CAAC,CAAC,KAAKC,CAAO,EACpD,SAAU,EAAW,IAASC,EAAU,KAAKC,CAAI,CAClD,EA0CA,SAAgBC,EACf,EACA,EAC+B,CAC/B,OAAOC,EAAQ,YAAc,CAC5B,IAAIC,EAAU,GACRC,EAAY,GACjBF,EAAQ,QAAQH,EAAU,aAAaM,CAAO,MAC7CH,EAAQ,QAAQH,EAAU,MAAMM,CAAO,MAASN,EAAU,IAAIM,CAAO,CAAC,CACvE,EACKC,GAAY,EAAe,IAChCJ,EAAQ,YAAc,CACrB,GAAIK,GAASJ,EAAS,MAAM,IAAIK,EAAuBT,EAAU,SAAS,EAC1E,EAAUQ,EACV,IAAME,EAAQV,EAAU,WAAWQ,GAEnC,OADKE,EACEA,EAAM,CACZ,UAAWV,EAAU,UACrB,QAASA,EAAU,QACnB,UACA,KAAO,GACNO,EAASC,EAAQ,EAAGG,GAAS,QAAU,CAAE,GAAGL,EAAS,GAAGK,EAAQ,OAAQ,EAAIL,CAAO,CACrF,CAAC,EAPkBD,EAASC,CAAO,CAQpC,CAAC,EACF,OAAOH,EAAQ,QAAQH,EAAU,aAAa,GAAKG,EAAQ,QAAQ,IAAA,EAAS,MAC3EA,EAAQ,QAAQH,EAAU,QAAQ,EAAI,GACjCY,GAAa,OAAS,SAClBT,EAAQ,YACdH,EAAU,aACPA,EAAU,aAAaY,EAAY,MAAM,EACzCT,EAAQ,QAAQH,EAAU,YAAaY,EAAY,MAAM,CAAC,CAC9D,EAEMT,EAAQ,QAAQI,EAAS,EAAGP,EAAU,OAAO,EAAI,GAChDG,EAAQ,QACdH,EAAU,aACPA,EAAU,aAAaa,CAAG,EAC1BV,EAAQ,QAAQH,EAAU,YAAaa,CAAG,CAAC,EAC7C,GACAV,EAAQ,QAAQH,EAAU,MAAMc,CAAM,EAAI,GAAU,CACnD,GACCC,GACAf,EAAU,YACV,CAACA,EAAU,WAAW,SAASe,EAAM,UAAU,IAAI,EAEnD,MAAM,IAAIC,EAAsBhB,EAAU,UAAWe,EAAM,UAAU,IAAI,EAE1E,OAAOZ,EAAQ,QACdY,EACGf,EAAU,WAAW,CAAE,GAAGe,EAAO,eAAgBf,EAAU,cAAe,CAAC,EAC3EG,EAAQ,QAAQ,IAAA,EAAS,MAE3BA,EAAQ,QACPS,GAAa,WAAWE,CAAM,GAAKX,EAAQ,QAAQ,IAAA,EAAS,MACtDA,EAAQ,QAAQW,CAAM,CAC7B,CACF,CACD,CAAC,CACH,CACA,CACD,CACF,CACD,CAAC,CACF,CAEA,IAAaL,EAAb,cAA4C,KAAM,CACjD,KAAgB,iCAChB,KAAgB,yBAChB,YAAY,EAAmB,CAC9B,MAAM,+BAA+BQ,EAAU,+BAA+B,CAC/E,CACD,EACaD,EAAb,cAA2C,KAAM,CAChD,KAAgB,iCAChB,KAAgB,wBAChB,YAAY,EAAmB,EAAuB,CACrD,MACC,cAAcC,EAAU,4BAA4BC,EAAc,kCACnE,CACD,CACD,EACaC,EAAb,cAA4C,KAAM,CACjD,KAAgB,oCAChB,KAAgB,yBAChB,YAAY,EAAmB,CAC9B,MACC,cAAcF,EAAU,kEACzB,CACD,CACD"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
declare namespace observability_d_exports {
|
|
2
2
|
export { CommandObservation, Observability, ObservabilityOptions };
|
|
3
3
|
}
|
|
4
|
-
type CommandObservation = Readonly<{
|
|
4
|
+
export type CommandObservation = Readonly<{
|
|
5
5
|
operation: string;
|
|
6
6
|
classification: string;
|
|
7
7
|
outcome: 'completed' | 'denied' | 'failed';
|
|
8
8
|
errorCode?: string;
|
|
9
9
|
durationMs: number;
|
|
10
10
|
}>;
|
|
11
|
-
type ObservabilityOptions = Readonly<{
|
|
11
|
+
export type ObservabilityOptions = Readonly<{
|
|
12
12
|
enabled?: boolean | (() => boolean);
|
|
13
13
|
classifyError: (cause: unknown) => Readonly<{
|
|
14
14
|
outcome: 'denied' | 'failed';
|
|
@@ -18,7 +18,7 @@ type ObservabilityOptions = Readonly<{
|
|
|
18
18
|
clock?: () => number;
|
|
19
19
|
}>;
|
|
20
20
|
/** Payload-free command telemetry that cannot change command behavior. */
|
|
21
|
-
declare class Observability {
|
|
21
|
+
export declare class Observability {
|
|
22
22
|
#private;
|
|
23
23
|
constructor(options: ObservabilityOptions);
|
|
24
24
|
observe<Result>(activation: Readonly<{
|
|
@@ -35,5 +35,5 @@ declare class Observability {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
//#endregion
|
|
38
|
-
export {
|
|
38
|
+
export { observability_d_exports };
|
|
39
39
|
//# sourceMappingURL=observability.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observability.mjs","names":["#options","#now","#emit","#duration"],"sources":["../../../../../src/components/foundation/modules/observability/observability.ts"],"sourcesContent":["export type CommandObservation = Readonly<{\n\toperation: string\n\tclassification: string\n\toutcome: 'completed' | 'denied' | 'failed'\n\terrorCode?: string\n\tdurationMs: number\n}>\n\nexport type ObservabilityOptions = Readonly<{\n\tenabled?: boolean | (() => boolean)\n\tclassifyError: (cause: unknown) => Readonly<{\n\t\toutcome: 'denied' | 'failed'\n\t\terrorCode: string\n\t}>\n\temit?: (observation: CommandObservation) => void\n\tclock?: () => number\n}>\n\nconst identifier = /^[A-Za-z][A-Za-z0-9_.-]{0,159}$/\nconst errorCode = /^[A-Z][A-Z0-9_]{0,95}$/\n\n/** Payload-free command telemetry that cannot change command behavior. */\nexport class Observability {\n\treadonly #options: ObservabilityOptions\n\n\tconstructor(options: ObservabilityOptions) {\n\t\tthis.#options = options\n\t}\n\n\tasync observe<Result>(\n\t\tactivation: Readonly<{ operation: string; classification: string }>,\n\t\texecute: () => Result | Promise<Result>,\n\t): Promise<Result> {\n\t\tconst observation = this.start(activation)\n\t\ttry {\n\t\t\tconst result = await execute()\n\t\t\tobservation.completed()\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tobservation.failed(error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/** Inert synchronous exit hooks for execution interpreters that own their runtime. */\n\tstart(activation: Readonly<{ operation: string; classification: string }>) {\n\t\tconst started = this.#now()\n\t\treturn {\n\t\t\tcompleted: () =>\n\t\t\t\tthis.#emit({\n\t\t\t\t\t...activation,\n\t\t\t\t\toutcome: 'completed',\n\t\t\t\t\tdurationMs: this.#duration(started),\n\t\t\t\t}),\n\t\t\tfailed: (cause: unknown) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\t...activation,\n\t\t\t\t\t\t...this.#options.classifyError(cause),\n\t\t\t\t\t\tdurationMs: this.#duration(started),\n\t\t\t\t\t})\n\t\t\t\t} catch {\n\t\t\t\t\t// Preserve the original command failure when telemetry fails.\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t}\n\n\t#emit(observation: CommandObservation): void {\n\t\ttry {\n\t\t\tconst option = this.#options.enabled\n\t\t\tconst enabled =\n\t\t\t\toption === undefined || option === true || option === false ? option : option()\n\t\t\tif (\n\t\t\t\tenabled !== true ||\n\t\t\t\t!identifier.test(observation.operation) ||\n\t\t\t\t!identifier.test(observation.classification) ||\n\t\t\t\t(observation.errorCode !== undefined && !errorCode.test(observation.errorCode))\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.#options.emit) {\n\t\t\t\tthis.#options.emit(Object.freeze(observation))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconsole.info(JSON.stringify({ event: 'command.execution', ...observation }))\n\t\t} catch {\n\t\t\t// Observability is intentionally behaviorally inert.\n\t\t}\n\t}\n\n\t#now(): number {\n\t\ttry {\n\t\t\treturn this.#options.clock?.() ?? Date.now()\n\t\t} catch {\n\t\t\treturn Date.now()\n\t\t}\n\t}\n\n\t#duration(started: number): number {\n\t\treturn Math.max(0, Math.min(600_000, this.#now() - started))\n\t}\n}\n"],"mappings":"AAkBA,
|
|
1
|
+
{"version":3,"file":"observability.mjs","names":["identifier","errorCode","Observability","#options","options","observation","activation","result","execute","error","started","#now","#emit","#duration","cause","option"],"sources":["../../../../../src/components/foundation/modules/observability/observability.ts"],"sourcesContent":["export type CommandObservation = Readonly<{\n\toperation: string\n\tclassification: string\n\toutcome: 'completed' | 'denied' | 'failed'\n\terrorCode?: string\n\tdurationMs: number\n}>\n\nexport type ObservabilityOptions = Readonly<{\n\tenabled?: boolean | (() => boolean)\n\tclassifyError: (cause: unknown) => Readonly<{\n\t\toutcome: 'denied' | 'failed'\n\t\terrorCode: string\n\t}>\n\temit?: (observation: CommandObservation) => void\n\tclock?: () => number\n}>\n\nconst identifier = /^[A-Za-z][A-Za-z0-9_.-]{0,159}$/\nconst errorCode = /^[A-Z][A-Z0-9_]{0,95}$/\n\n/** Payload-free command telemetry that cannot change command behavior. */\nexport class Observability {\n\treadonly #options: ObservabilityOptions\n\n\tconstructor(options: ObservabilityOptions) {\n\t\tthis.#options = options\n\t}\n\n\tasync observe<Result>(\n\t\tactivation: Readonly<{ operation: string; classification: string }>,\n\t\texecute: () => Result | Promise<Result>,\n\t): Promise<Result> {\n\t\tconst observation = this.start(activation)\n\t\ttry {\n\t\t\tconst result = await execute()\n\t\t\tobservation.completed()\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tobservation.failed(error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/** Inert synchronous exit hooks for execution interpreters that own their runtime. */\n\tstart(activation: Readonly<{ operation: string; classification: string }>) {\n\t\tconst started = this.#now()\n\t\treturn {\n\t\t\tcompleted: () =>\n\t\t\t\tthis.#emit({\n\t\t\t\t\t...activation,\n\t\t\t\t\toutcome: 'completed',\n\t\t\t\t\tdurationMs: this.#duration(started),\n\t\t\t\t}),\n\t\t\tfailed: (cause: unknown) => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\t...activation,\n\t\t\t\t\t\t...this.#options.classifyError(cause),\n\t\t\t\t\t\tdurationMs: this.#duration(started),\n\t\t\t\t\t})\n\t\t\t\t} catch {\n\t\t\t\t\t// Preserve the original command failure when telemetry fails.\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t}\n\n\t#emit(observation: CommandObservation): void {\n\t\ttry {\n\t\t\tconst option = this.#options.enabled\n\t\t\tconst enabled =\n\t\t\t\toption === undefined || option === true || option === false ? option : option()\n\t\t\tif (\n\t\t\t\tenabled !== true ||\n\t\t\t\t!identifier.test(observation.operation) ||\n\t\t\t\t!identifier.test(observation.classification) ||\n\t\t\t\t(observation.errorCode !== undefined && !errorCode.test(observation.errorCode))\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.#options.emit) {\n\t\t\t\tthis.#options.emit(Object.freeze(observation))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconsole.info(JSON.stringify({ event: 'command.execution', ...observation }))\n\t\t} catch {\n\t\t\t// Observability is intentionally behaviorally inert.\n\t\t}\n\t}\n\n\t#now(): number {\n\t\ttry {\n\t\t\treturn this.#options.clock?.() ?? Date.now()\n\t\t} catch {\n\t\t\treturn Date.now()\n\t\t}\n\t}\n\n\t#duration(started: number): number {\n\t\treturn Math.max(0, Math.min(600_000, this.#now() - started))\n\t}\n}\n"],"mappings":"AAkBA,MAAMA,EAAa,kCACbC,EAAY,yBAGlB,IAAaC,EAAb,KAA2B,CAC1B,GAEA,YAAY,EAA+B,CAC1C,KAAKC,GAAWC,CACjB,CAEA,MAAM,QACL,EACA,EACkB,CAClB,IAAMC,EAAc,KAAK,MAAMC,CAAU,EACzC,GAAI,CACH,IAAMC,EAAS,MAAMC,EAAQ,EAE7B,OADAH,EAAY,UAAU,EACfE,CACR,OAASE,EAAO,CAEf,MADAJ,EAAY,OAAOI,CAAK,EAClBA,CACP,CACD,CAGA,MAAM,EAAqE,CAC1E,IAAMC,EAAU,KAAKC,GAAK,EAC1B,MAAO,CACN,cACC,KAAKC,GAAM,CACV,GAAGN,EACH,QAAS,YACT,WAAY,KAAKO,GAAUH,CAAO,CACnC,CAAC,EACF,OAAS,GAAmB,CAC3B,GAAI,CACH,KAAKE,GAAM,CACV,GAAGN,EACH,GAAG,KAAKH,GAAS,cAAcW,CAAK,EACpC,WAAY,KAAKD,GAAUH,CAAO,CACnC,CAAC,CACF,MAAQ,CAER,CACD,CACD,CACD,CAEA,GAAM,EAAuC,CAC5C,GAAI,CACH,IAAMK,EAAS,KAAKZ,GAAS,QAG7B,IADCY,IAAW,IAAA,IAAaA,IAAW,IAAQA,IAAW,GAAQA,EAASA,EAAO,KAElE,IACZ,CAACf,EAAW,KAAKK,EAAY,SAAS,GACtC,CAACL,EAAW,KAAKK,EAAY,cAAc,GAC1CA,EAAY,YAAc,IAAA,IAAa,CAACJ,EAAU,KAAKI,EAAY,SAAS,EAE7E,OAED,GAAI,KAAKF,GAAS,KAAM,CACvB,KAAKA,GAAS,KAAK,OAAO,OAAOE,CAAW,CAAC,EAC7C,MACD,CACA,QAAQ,KAAK,KAAK,UAAU,CAAE,MAAO,oBAAqB,GAAGA,CAAY,CAAC,CAAC,CAC5E,MAAQ,CAER,CACD,CAEA,IAAe,CACd,GAAI,CACH,OAAO,KAAKF,GAAS,QAAQ,GAAK,KAAK,IAAI,CAC5C,MAAQ,CACP,OAAO,KAAK,IAAI,CACjB,CACD,CAEA,GAAU,EAAyB,CAClC,OAAO,KAAK,IAAI,EAAG,KAAK,IAAI,IAAS,KAAKQ,GAAK,EAAID,CAAO,CAAC,CAC5D,CACD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare namespace query_d_exports {
|
|
2
2
|
export { AnyQueryMiddleware, Query, QueryExecution, QueryMiddleware };
|
|
3
3
|
}
|
|
4
|
-
type QueryExecution<Context, Metadata, Result> = Readonly<{
|
|
4
|
+
export type QueryExecution<Context, Metadata, Result> = Readonly<{
|
|
5
5
|
context: Context;
|
|
6
6
|
metadata: Metadata;
|
|
7
7
|
run: () => Promise<Result>;
|
|
@@ -12,7 +12,7 @@ type MaybePromise<Value> = Value | Promise<Value>;
|
|
|
12
12
|
* inside the host's injected execute policy: `next({ context })` merges
|
|
13
13
|
* enrichment into the context handed to inner middleware and the handler.
|
|
14
14
|
*/
|
|
15
|
-
type QueryMiddleware<Context = never, Extension extends object = object> = <Result>(input: {
|
|
15
|
+
export type QueryMiddleware<Context = never, Extension extends object = object> = <Result>(input: {
|
|
16
16
|
metadata: object;
|
|
17
17
|
context: Context;
|
|
18
18
|
next: (options?: {
|
|
@@ -20,7 +20,7 @@ type QueryMiddleware<Context = never, Extension extends object = object> = <Resu
|
|
|
20
20
|
}) => Promise<Result>;
|
|
21
21
|
}) => Promise<Result>;
|
|
22
22
|
/** Any-context middleware — what kernels and executors accept. */
|
|
23
|
-
type AnyQueryMiddleware = <Result>(input: {
|
|
23
|
+
export type AnyQueryMiddleware = <Result>(input: {
|
|
24
24
|
metadata: object;
|
|
25
25
|
context: never;
|
|
26
26
|
next: (options?: {
|
|
@@ -28,7 +28,7 @@ type AnyQueryMiddleware = <Result>(input: {
|
|
|
28
28
|
}) => Promise<Result>;
|
|
29
29
|
}) => Promise<Result>;
|
|
30
30
|
/** Generic query kernel. Authorization remains an injected host policy. */
|
|
31
|
-
declare class Query<Context, Defaults extends object> {
|
|
31
|
+
export declare class Query<Context, Defaults extends object> {
|
|
32
32
|
#private;
|
|
33
33
|
/**
|
|
34
34
|
* Identity helper that types a middleware against its context and the
|
|
@@ -47,5 +47,5 @@ declare class Query<Context, Defaults extends object> {
|
|
|
47
47
|
}): (context: Context, ...args: Arguments) => Promise<Result>;
|
|
48
48
|
}
|
|
49
49
|
//#endregion
|
|
50
|
-
export {
|
|
50
|
+
export { query_d_exports };
|
|
51
51
|
//# sourceMappingURL=query.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.mjs","names":["#defaults","#middleware","#execute"],"sources":["../../../../../src/components/foundation/modules/query/query.ts"],"sourcesContent":["export type QueryExecution<Context, Metadata, Result> = Readonly<{\n\tcontext: Context\n\tmetadata: Metadata\n\trun: () => Promise<Result>\n}>\n\ntype MaybePromise<Value> = Value | Promise<Value>\n\n/**\n * Composable, next()-based middleware around every query handler. Runs\n * inside the host's injected execute policy: `next({ context })` merges\n * enrichment into the context handed to inner middleware and the handler.\n */\nexport type QueryMiddleware<Context = never, Extension extends object = object> = <Result>(input: {\n\tmetadata: object\n\tcontext: Context\n\tnext: (options?: { context?: Extension }) => Promise<Result>\n}) => Promise<Result>\n\n/** Any-context middleware — what kernels and executors accept. */\n// Contravariant seam: the supertype every typed QueryMiddleware<C, E>\n// assigns to. The result stays generic across the chain; context is erased\n// only in storage. Definition sites stay typed via Query.middleware.\nexport type AnyQueryMiddleware = <Result>(input: {\n\tmetadata: object\n\tcontext: never\n\tnext: (options?: { context?: object }) => Promise<Result>\n}) => Promise<Result>\n\nclass QueryMiddlewareError extends Error {\n\treadonly code = 'QUERY_MIDDLEWARE_NEXT_REUSED'\n\treadonly name = 'QueryMiddlewareError'\n\n\tconstructor() {\n\t\tsuper('A query middleware called next() more than once')\n\t}\n}\n\n/** Generic query kernel. Authorization remains an injected host policy. */\nexport class Query<Context, Defaults extends object> {\n\treadonly #defaults: Defaults\n\treadonly #middleware: readonly AnyQueryMiddleware[]\n\treadonly #execute: <Metadata extends object, Result>(\n\t\texecution: QueryExecution<Context, Defaults & Metadata, Result>,\n\t) => Promise<Result>\n\n\t/**\n\t * Identity helper that types a middleware against its context and the\n\t * extension it passes downstream via next({ context }).\n\t */\n\tstatic middleware<Context = never, const Extension extends object = object>(\n\t\tmiddleware: QueryMiddleware<Context, Extension>,\n\t): QueryMiddleware<Context, Extension> {\n\t\treturn middleware\n\t}\n\n\tconstructor(configuration: {\n\t\treadonly defaults: Defaults\n\t\treadonly middleware?: readonly AnyQueryMiddleware[]\n\t\treadonly execute: <Metadata extends object, Result>(\n\t\t\texecution: QueryExecution<Context, Defaults & Metadata, Result>,\n\t\t) => Promise<Result>\n\t}) {\n\t\tthis.#defaults = configuration.defaults\n\t\tthis.#middleware = configuration.middleware ?? []\n\t\tthis.#execute = configuration.execute\n\t}\n\n\texec<Arguments extends readonly unknown[], Result, Metadata extends object = object>(executor: {\n\t\treadonly metadata?: Metadata\n\t\treadonly middleware?: readonly AnyQueryMiddleware[]\n\t\treadonly handler: (context: Context, ...args: Arguments) => MaybePromise<Result>\n\t}): (context: Context, ...args: Arguments) => Promise<Result> {\n\t\treturn (context, ...args) => {\n\t\t\tconst metadata = {\n\t\t\t\t...this.#defaults,\n\t\t\t\t...executor.metadata,\n\t\t\t}\n\t\t\tconst middleware = [...this.#middleware, ...(executor.middleware ?? [])]\n\t\t\tconst run = async (): Promise<Result> => {\n\t\t\t\tif (middleware.length === 0) {\n\t\t\t\t\treturn executor.handler(context, ...args)\n\t\t\t\t}\n\t\t\t\tlet deepest = -1\n\t\t\t\tconst dispatch = async (index: number, current: Context): Promise<Result> => {\n\t\t\t\t\tif (index <= deepest) throw new QueryMiddlewareError()\n\t\t\t\t\tdeepest = index\n\t\t\t\t\tconst layer = middleware[index]\n\t\t\t\t\tif (!layer) return executor.handler(current, ...args)\n\t\t\t\t\treturn layer({\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t// SAFETY: middleware context is erased only in storage; the kernel supplies its Context.\n\t\t\t\t\t\tcontext: current as never,\n\t\t\t\t\t\tnext: (options) =>\n\t\t\t\t\t\t\tdispatch(index + 1, options?.context ? { ...current, ...options.context } : current),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn dispatch(0, context)\n\t\t\t}\n\t\t\treturn this.#execute({ context, metadata, run })\n\t\t}\n\t}\n}\n"],"mappings":"AA6BA,
|
|
1
|
+
{"version":3,"file":"query.mjs","names":["QueryMiddlewareError","Query","middleware","#defaults","configuration","#middleware","#execute","args","metadata","executor","context","deepest","dispatch","index","layer","current","options"],"sources":["../../../../../src/components/foundation/modules/query/query.ts"],"sourcesContent":["export type QueryExecution<Context, Metadata, Result> = Readonly<{\n\tcontext: Context\n\tmetadata: Metadata\n\trun: () => Promise<Result>\n}>\n\ntype MaybePromise<Value> = Value | Promise<Value>\n\n/**\n * Composable, next()-based middleware around every query handler. Runs\n * inside the host's injected execute policy: `next({ context })` merges\n * enrichment into the context handed to inner middleware and the handler.\n */\nexport type QueryMiddleware<Context = never, Extension extends object = object> = <Result>(input: {\n\tmetadata: object\n\tcontext: Context\n\tnext: (options?: { context?: Extension }) => Promise<Result>\n}) => Promise<Result>\n\n/** Any-context middleware — what kernels and executors accept. */\n// Contravariant seam: the supertype every typed QueryMiddleware<C, E>\n// assigns to. The result stays generic across the chain; context is erased\n// only in storage. Definition sites stay typed via Query.middleware.\nexport type AnyQueryMiddleware = <Result>(input: {\n\tmetadata: object\n\tcontext: never\n\tnext: (options?: { context?: object }) => Promise<Result>\n}) => Promise<Result>\n\nclass QueryMiddlewareError extends Error {\n\treadonly code = 'QUERY_MIDDLEWARE_NEXT_REUSED'\n\treadonly name = 'QueryMiddlewareError'\n\n\tconstructor() {\n\t\tsuper('A query middleware called next() more than once')\n\t}\n}\n\n/** Generic query kernel. Authorization remains an injected host policy. */\nexport class Query<Context, Defaults extends object> {\n\treadonly #defaults: Defaults\n\treadonly #middleware: readonly AnyQueryMiddleware[]\n\treadonly #execute: <Metadata extends object, Result>(\n\t\texecution: QueryExecution<Context, Defaults & Metadata, Result>,\n\t) => Promise<Result>\n\n\t/**\n\t * Identity helper that types a middleware against its context and the\n\t * extension it passes downstream via next({ context }).\n\t */\n\tstatic middleware<Context = never, const Extension extends object = object>(\n\t\tmiddleware: QueryMiddleware<Context, Extension>,\n\t): QueryMiddleware<Context, Extension> {\n\t\treturn middleware\n\t}\n\n\tconstructor(configuration: {\n\t\treadonly defaults: Defaults\n\t\treadonly middleware?: readonly AnyQueryMiddleware[]\n\t\treadonly execute: <Metadata extends object, Result>(\n\t\t\texecution: QueryExecution<Context, Defaults & Metadata, Result>,\n\t\t) => Promise<Result>\n\t}) {\n\t\tthis.#defaults = configuration.defaults\n\t\tthis.#middleware = configuration.middleware ?? []\n\t\tthis.#execute = configuration.execute\n\t}\n\n\texec<Arguments extends readonly unknown[], Result, Metadata extends object = object>(executor: {\n\t\treadonly metadata?: Metadata\n\t\treadonly middleware?: readonly AnyQueryMiddleware[]\n\t\treadonly handler: (context: Context, ...args: Arguments) => MaybePromise<Result>\n\t}): (context: Context, ...args: Arguments) => Promise<Result> {\n\t\treturn (context, ...args) => {\n\t\t\tconst metadata = {\n\t\t\t\t...this.#defaults,\n\t\t\t\t...executor.metadata,\n\t\t\t}\n\t\t\tconst middleware = [...this.#middleware, ...(executor.middleware ?? [])]\n\t\t\tconst run = async (): Promise<Result> => {\n\t\t\t\tif (middleware.length === 0) {\n\t\t\t\t\treturn executor.handler(context, ...args)\n\t\t\t\t}\n\t\t\t\tlet deepest = -1\n\t\t\t\tconst dispatch = async (index: number, current: Context): Promise<Result> => {\n\t\t\t\t\tif (index <= deepest) throw new QueryMiddlewareError()\n\t\t\t\t\tdeepest = index\n\t\t\t\t\tconst layer = middleware[index]\n\t\t\t\t\tif (!layer) return executor.handler(current, ...args)\n\t\t\t\t\treturn layer({\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t// SAFETY: middleware context is erased only in storage; the kernel supplies its Context.\n\t\t\t\t\t\tcontext: current as never,\n\t\t\t\t\t\tnext: (options) =>\n\t\t\t\t\t\t\tdispatch(index + 1, options?.context ? { ...current, ...options.context } : current),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn dispatch(0, context)\n\t\t\t}\n\t\t\treturn this.#execute({ context, metadata, run })\n\t\t}\n\t}\n}\n"],"mappings":"AA6BA,IAAMA,EAAN,cAAmC,KAAM,CACxC,KAAgB,+BAChB,KAAgB,uBAEhB,aAAc,CACb,MAAM,iDAAiD,CACxD,CACD,EAGaC,EAAb,KAAqD,CACpD,GACA,GACA,GAQA,OAAO,WACN,EACsC,CACtC,OAAOC,CACR,CAEA,YAAY,EAMT,CACF,KAAKC,GAAYC,EAAc,SAC/B,KAAKC,GAAcD,EAAc,YAAc,CAAC,EAChD,KAAKE,GAAWF,EAAc,OAC/B,CAEA,KAAqF,EAIvB,CAC7D,OAAQ,EAAS,GAAGG,IAAS,CAC5B,IAAMC,EAAW,CAChB,GAAG,KAAKL,GACR,GAAGM,EAAS,QACb,EACMP,EAAa,CAAC,GAAG,KAAKG,GAAa,GAAII,EAAS,YAAc,CAAC,CAAE,EAqBvE,OAAO,KAAKH,GAAS,CAAE,UAAS,WAAU,aApBD,CACxC,GAAIJ,EAAW,SAAW,EACzB,OAAOO,EAAS,QAAQC,EAAS,GAAGH,CAAI,EAEzC,IAAII,EAAU,GACRC,EAAW,MAAO,EAAe,IAAsC,CAC5E,GAAIC,GAASF,EAAS,MAAM,IAAIX,EAChC,EAAUa,EACV,IAAMC,EAAQZ,EAAWW,GAEzB,OADKC,EACEA,EAAM,CACZ,WAEA,QAASC,EACT,KAAO,GACNH,EAASC,EAAQ,EAAGG,GAAS,QAAU,CAAE,GAAGD,EAAS,GAAGC,EAAQ,OAAQ,EAAID,CAAO,CACrF,CAAC,EAPkBN,EAAS,QAAQM,EAAS,GAAGR,CAAI,CAQrD,EACA,OAAOK,EAAS,EAAGF,CAAO,CAC3B,CAC8C,CAAC,CAChD,CACD,CACD"}
|
|
@@ -2,7 +2,7 @@ import { CommandHandlerResult, CommandInput, CommandSchema, SchemaInput, SchemaO
|
|
|
2
2
|
import { AnyCommandMiddleware, AuditEntryInput, AuditedOperation, AuditedRegistry } from "./client.mjs";
|
|
3
3
|
//#region src/components/foundation/operation.d.ts
|
|
4
4
|
type MaybePromise<T> = T | Promise<T>;
|
|
5
|
-
type CommandPreparation<Result> = {
|
|
5
|
+
export type CommandPreparation<Result> = {
|
|
6
6
|
kind: 'replay';
|
|
7
7
|
result: unknown;
|
|
8
8
|
} | {
|
|
@@ -12,10 +12,10 @@ type CommandPreparation<Result> = {
|
|
|
12
12
|
type Parsed<S extends CommandSchema> = SchemaOutput<S>;
|
|
13
13
|
declare const extension: unique symbol;
|
|
14
14
|
declare const hostContext: unique symbol;
|
|
15
|
-
type OperationHostContext<Context> = {
|
|
15
|
+
export type OperationHostContext<Context> = {
|
|
16
16
|
readonly [hostContext]?: (context: Context) => void;
|
|
17
17
|
};
|
|
18
|
-
type OperationExtension<Definition> = Definition extends {
|
|
18
|
+
export type OperationExtension<Definition> = Definition extends {
|
|
19
19
|
readonly [extension]?: infer Extension;
|
|
20
20
|
} ? Extension : unknown;
|
|
21
21
|
type MiddlewareInput<Context, Input, Output, Extension> = {
|
|
@@ -35,7 +35,7 @@ type AuditFor<Aggregate extends string> = Omit<AuditEntryInput, 'classification'
|
|
|
35
35
|
id: string;
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
|
-
type TypedOperation<Context, Input extends CommandSchema, Output extends CommandSchema, Aggregates extends readonly string[], Extension> = OperationHostContext<Context> & {
|
|
38
|
+
export type TypedOperation<Context, Input extends CommandSchema, Output extends CommandSchema, Aggregates extends readonly string[], Extension> = OperationHostContext<Context> & {
|
|
39
39
|
readonly command: Input;
|
|
40
40
|
readonly result: Output;
|
|
41
41
|
readonly classification: string;
|
|
@@ -65,10 +65,9 @@ type RegistryInput<Context, Operations extends AuditedRegistry> = { [Key in Extr
|
|
|
65
65
|
}; }[Extract<keyof Operations, string>];
|
|
66
66
|
type StoredOperation<Context, Input extends CommandSchema, Output extends CommandSchema, Aggregates extends readonly string[], Extension> = Omit<TypedOperation<Context, Input, Output, Aggregates, Extension>, 'middleware'> & Pick<AuditedOperation, 'middleware'>;
|
|
67
67
|
/** Binds host context once; each operation infers its own parsed schemas. */
|
|
68
|
-
declare function operationFactory<Context, Extension extends Record<string, unknown> = Record<never, never>>(): {
|
|
68
|
+
export declare function operationFactory<Context, Extension extends Record<string, unknown> = Record<never, never>>(): {
|
|
69
69
|
operation<const Input extends CommandSchema, const Output extends CommandSchema, const Aggregates extends readonly string[] = readonly string[]>(definition: TypedOperation<Context, Input, Output, Aggregates, Extension>): StoredOperation<Context, Input, Output, Aggregates, Extension>;
|
|
70
70
|
registryMiddleware<const Operations extends AuditedRegistry>(operations: Operations & { readonly [Key in keyof Operations]: OperationHostContext<Context>; }, middleware: (input: RegistryInput<Context, Operations>) => Promise<CommandHandlerResult<Operations, Extract<keyof Operations, string>>>): AnyCommandMiddleware;
|
|
71
71
|
};
|
|
72
72
|
//#endregion
|
|
73
|
-
export { CommandPreparation, OperationExtension, OperationHostContext, TypedOperation, operationFactory };
|
|
74
73
|
//# sourceMappingURL=operation.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operation.mjs","names":[],"sources":["../../../src/components/foundation/operation.ts"],"sourcesContent":["import type {\n\tAuditEntryInput,\n\tAuditedRegistry,\n\tAuditedOperation,\n\tAnyCommandMiddleware,\n} from './client'\nimport type {\n\tCommandInput,\n\tCommandHandlerResult,\n\tCommandSchema,\n\tSchemaOutput,\n\tSchemaInput,\n} from './modules/command/command'\n\ntype MaybePromise<T> = T | Promise<T>\nexport type CommandPreparation<Result> =\n\t| { kind: 'replay'; result: unknown }\n\t| { kind: 'execute'; complete?: (result: Result) => MaybePromise<void> }\ntype Parsed<S extends CommandSchema> = SchemaOutput<S>\ndeclare const extension: unique symbol\ndeclare const hostContext: unique symbol\nexport type OperationHostContext<Context> = {\n\treadonly [hostContext]?: (context: Context) => void\n}\nexport type OperationExtension<Definition> = Definition extends {\n\treadonly [extension]?: infer Extension\n}\n\t? Extension\n\t: unknown\n\ntype MiddlewareInput<Context, Input, Output, Extension> = {\n\toperation: string\n\tcontext: Context\n\tcommand: Input\n\tnext: keyof Extension extends never\n\t\t? (options?: { context?: Extension }) => Promise<Output>\n\t\t: (options: { context: Extension }) => Promise<Output>\n}\ntype LocalMiddleware<C, I, O, E> = (input: MiddlewareInput<C, I, O, E>) => Promise<O>\ntype AuditFor<Aggregate extends string> = Omit<AuditEntryInput, 'classification' | 'aggregate'> & {\n\taggregate: { type: Aggregate; id: string }\n}\nexport type TypedOperation<\n\tContext,\n\tInput extends CommandSchema,\n\tOutput extends CommandSchema,\n\tAggregates extends readonly string[],\n\tExtension,\n> = OperationHostContext<Context> & {\n\treadonly command: Input\n\treadonly result: Output\n\treadonly classification: string\n\treadonly permission?: string\n\t/** Called after permission, inside observation; returns invocation-local hooks. */\n\treadonly prepare?: (\n\t\tcontext: Context,\n\t\tcommand: Parsed<Input>,\n\t) => MaybePromise<CommandPreparation<Parsed<Output>>>\n\t/** Validates stored outputs when result transforms accept a different input shape. */\n\treadonly replayResult?: CommandSchema<Parsed<Output>>\n\treadonly aggregates?: Aggregates\n\treadonly guard?: (context: Context & Extension, command: Parsed<Input>) => MaybePromise<void>\n\treadonly audit: (\n\t\tresolution: { command: Parsed<Input>; result: Parsed<Output> },\n\t\tcontext: Context,\n\t) => MaybePromise<AuditFor<Aggregates[number]> | null>\n\treadonly [extension]?: Extension\n} & (keyof Extension extends never\n\t\t? {\n\t\t\t\treadonly middleware?: readonly LocalMiddleware<\n\t\t\t\t\tContext,\n\t\t\t\t\tParsed<Input>,\n\t\t\t\t\tSchemaInput<Output>,\n\t\t\t\t\tExtension\n\t\t\t\t>[]\n\t\t\t}\n\t\t: {\n\t\t\t\treadonly middleware: readonly [\n\t\t\t\t\tLocalMiddleware<Context, Parsed<Input>, SchemaInput<Output>, Extension>,\n\t\t\t\t\t...LocalMiddleware<\n\t\t\t\t\t\tContext & Extension,\n\t\t\t\t\t\tParsed<Input>,\n\t\t\t\t\t\tSchemaInput<Output>,\n\t\t\t\t\t\tRecord<never, never>\n\t\t\t\t\t>[],\n\t\t\t\t]\n\t\t\t})\n\ntype RegistryInput<Context, Operations extends AuditedRegistry> = {\n\t[Key in Extract<keyof Operations, string>]: {\n\t\toperation: Key\n\t\tdefinition: Operations[Key]\n\t\tcontext: Context\n\t\tcommand: CommandInput<Operations, Key>\n\t\tnext: () => Promise<CommandHandlerResult<Operations, Key>>\n\t}\n}[Extract<keyof Operations, string>]\n\ntype StoredOperation<\n\tContext,\n\tInput extends CommandSchema,\n\tOutput extends CommandSchema,\n\tAggregates extends readonly string[],\n\tExtension,\n> = Omit<TypedOperation<Context, Input, Output, Aggregates, Extension>, 'middleware'> &\n\tPick<AuditedOperation, 'middleware'>\n\n/** Binds host context once; each operation infers its own parsed schemas. */\nexport function operationFactory<\n\tContext,\n\tExtension extends Record<string, unknown> = Record<never, never>,\n>() {\n\treturn {\n\t\toperation<\n\t\t\tconst Input extends CommandSchema,\n\t\t\tconst Output extends CommandSchema,\n\t\t\tconst Aggregates extends readonly string[] = readonly string[],\n\t\t>(\n\t\t\tdefinition: TypedOperation<Context, Input, Output, Aggregates, Extension>,\n\t\t): StoredOperation<Context, Input, Output, Aggregates, Extension> {\n\t\t\t// SAFETY: the kernel selects this definition and parses its input before\n\t\t\t// invoking the heterogeneous middleware registry. Erase only that\n\t\t\t// storage seam; callbacks were checked against these schemas above.\n\t\t\treturn definition as StoredOperation<Context, Input, Output, Aggregates, Extension>\n\t\t},\n\t\tregistryMiddleware<const Operations extends AuditedRegistry>(\n\t\t\toperations: Operations & {\n\t\t\t\treadonly [Key in keyof Operations]: OperationHostContext<Context>\n\t\t\t},\n\t\t\tmiddleware: (\n\t\t\t\tinput: RegistryInput<Context, Operations>,\n\t\t\t) => Promise<CommandHandlerResult<Operations, Extract<keyof Operations, string>>>,\n\t\t): AnyCommandMiddleware {\n\t\t\tfunction ownsDefinition(\n\t\t\t\tinput: Parameters<AnyCommandMiddleware>[0],\n\t\t\t): input is Parameters<AnyCommandMiddleware>[0] & RegistryInput<Context, Operations> {\n\t\t\t\treturn (\n\t\t\t\t\tObject.prototype.hasOwnProperty.call(operations, input.operation) &&\n\t\t\t\t\toperations[input.operation] === input.definition\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn (input) => {\n\t\t\t\tif (!ownsDefinition(input)) {\n\t\t\t\t\tthrow new CommandMiddlewareRegistryError(input.operation)\n\t\t\t\t}\n\t\t\t\treturn middleware(input)\n\t\t\t}\n\t\t},\n\t}\n}\n\nclass CommandMiddlewareRegistryError extends Error {\n\treadonly code = 'COMMAND_MIDDLEWARE_REGISTRY_MISMATCH'\n\tconstructor(operation: string) {\n\t\tsuper(`Typed middleware does not own the definition of operation \"${operation}\"`)\n\t\tthis.name = 'CommandMiddlewareRegistryError'\n\t}\n}\n"],"mappings":"AA4GA,
|
|
1
|
+
{"version":3,"file":"operation.mjs","names":["operationFactory","definition","ownsDefinition","operations","input","CommandMiddlewareRegistryError","middleware","operation"],"sources":["../../../src/components/foundation/operation.ts"],"sourcesContent":["import type {\n\tAuditEntryInput,\n\tAuditedRegistry,\n\tAuditedOperation,\n\tAnyCommandMiddleware,\n} from './client'\nimport type {\n\tCommandInput,\n\tCommandHandlerResult,\n\tCommandSchema,\n\tSchemaOutput,\n\tSchemaInput,\n} from './modules/command/command'\n\ntype MaybePromise<T> = T | Promise<T>\nexport type CommandPreparation<Result> =\n\t| { kind: 'replay'; result: unknown }\n\t| { kind: 'execute'; complete?: (result: Result) => MaybePromise<void> }\ntype Parsed<S extends CommandSchema> = SchemaOutput<S>\ndeclare const extension: unique symbol\ndeclare const hostContext: unique symbol\nexport type OperationHostContext<Context> = {\n\treadonly [hostContext]?: (context: Context) => void\n}\nexport type OperationExtension<Definition> = Definition extends {\n\treadonly [extension]?: infer Extension\n}\n\t? Extension\n\t: unknown\n\ntype MiddlewareInput<Context, Input, Output, Extension> = {\n\toperation: string\n\tcontext: Context\n\tcommand: Input\n\tnext: keyof Extension extends never\n\t\t? (options?: { context?: Extension }) => Promise<Output>\n\t\t: (options: { context: Extension }) => Promise<Output>\n}\ntype LocalMiddleware<C, I, O, E> = (input: MiddlewareInput<C, I, O, E>) => Promise<O>\ntype AuditFor<Aggregate extends string> = Omit<AuditEntryInput, 'classification' | 'aggregate'> & {\n\taggregate: { type: Aggregate; id: string }\n}\nexport type TypedOperation<\n\tContext,\n\tInput extends CommandSchema,\n\tOutput extends CommandSchema,\n\tAggregates extends readonly string[],\n\tExtension,\n> = OperationHostContext<Context> & {\n\treadonly command: Input\n\treadonly result: Output\n\treadonly classification: string\n\treadonly permission?: string\n\t/** Called after permission, inside observation; returns invocation-local hooks. */\n\treadonly prepare?: (\n\t\tcontext: Context,\n\t\tcommand: Parsed<Input>,\n\t) => MaybePromise<CommandPreparation<Parsed<Output>>>\n\t/** Validates stored outputs when result transforms accept a different input shape. */\n\treadonly replayResult?: CommandSchema<Parsed<Output>>\n\treadonly aggregates?: Aggregates\n\treadonly guard?: (context: Context & Extension, command: Parsed<Input>) => MaybePromise<void>\n\treadonly audit: (\n\t\tresolution: { command: Parsed<Input>; result: Parsed<Output> },\n\t\tcontext: Context,\n\t) => MaybePromise<AuditFor<Aggregates[number]> | null>\n\treadonly [extension]?: Extension\n} & (keyof Extension extends never\n\t\t? {\n\t\t\t\treadonly middleware?: readonly LocalMiddleware<\n\t\t\t\t\tContext,\n\t\t\t\t\tParsed<Input>,\n\t\t\t\t\tSchemaInput<Output>,\n\t\t\t\t\tExtension\n\t\t\t\t>[]\n\t\t\t}\n\t\t: {\n\t\t\t\treadonly middleware: readonly [\n\t\t\t\t\tLocalMiddleware<Context, Parsed<Input>, SchemaInput<Output>, Extension>,\n\t\t\t\t\t...LocalMiddleware<\n\t\t\t\t\t\tContext & Extension,\n\t\t\t\t\t\tParsed<Input>,\n\t\t\t\t\t\tSchemaInput<Output>,\n\t\t\t\t\t\tRecord<never, never>\n\t\t\t\t\t>[],\n\t\t\t\t]\n\t\t\t})\n\ntype RegistryInput<Context, Operations extends AuditedRegistry> = {\n\t[Key in Extract<keyof Operations, string>]: {\n\t\toperation: Key\n\t\tdefinition: Operations[Key]\n\t\tcontext: Context\n\t\tcommand: CommandInput<Operations, Key>\n\t\tnext: () => Promise<CommandHandlerResult<Operations, Key>>\n\t}\n}[Extract<keyof Operations, string>]\n\ntype StoredOperation<\n\tContext,\n\tInput extends CommandSchema,\n\tOutput extends CommandSchema,\n\tAggregates extends readonly string[],\n\tExtension,\n> = Omit<TypedOperation<Context, Input, Output, Aggregates, Extension>, 'middleware'> &\n\tPick<AuditedOperation, 'middleware'>\n\n/** Binds host context once; each operation infers its own parsed schemas. */\nexport function operationFactory<\n\tContext,\n\tExtension extends Record<string, unknown> = Record<never, never>,\n>() {\n\treturn {\n\t\toperation<\n\t\t\tconst Input extends CommandSchema,\n\t\t\tconst Output extends CommandSchema,\n\t\t\tconst Aggregates extends readonly string[] = readonly string[],\n\t\t>(\n\t\t\tdefinition: TypedOperation<Context, Input, Output, Aggregates, Extension>,\n\t\t): StoredOperation<Context, Input, Output, Aggregates, Extension> {\n\t\t\t// SAFETY: the kernel selects this definition and parses its input before\n\t\t\t// invoking the heterogeneous middleware registry. Erase only that\n\t\t\t// storage seam; callbacks were checked against these schemas above.\n\t\t\treturn definition as StoredOperation<Context, Input, Output, Aggregates, Extension>\n\t\t},\n\t\tregistryMiddleware<const Operations extends AuditedRegistry>(\n\t\t\toperations: Operations & {\n\t\t\t\treadonly [Key in keyof Operations]: OperationHostContext<Context>\n\t\t\t},\n\t\t\tmiddleware: (\n\t\t\t\tinput: RegistryInput<Context, Operations>,\n\t\t\t) => Promise<CommandHandlerResult<Operations, Extract<keyof Operations, string>>>,\n\t\t): AnyCommandMiddleware {\n\t\t\tfunction ownsDefinition(\n\t\t\t\tinput: Parameters<AnyCommandMiddleware>[0],\n\t\t\t): input is Parameters<AnyCommandMiddleware>[0] & RegistryInput<Context, Operations> {\n\t\t\t\treturn (\n\t\t\t\t\tObject.prototype.hasOwnProperty.call(operations, input.operation) &&\n\t\t\t\t\toperations[input.operation] === input.definition\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn (input) => {\n\t\t\t\tif (!ownsDefinition(input)) {\n\t\t\t\t\tthrow new CommandMiddlewareRegistryError(input.operation)\n\t\t\t\t}\n\t\t\t\treturn middleware(input)\n\t\t\t}\n\t\t},\n\t}\n}\n\nclass CommandMiddlewareRegistryError extends Error {\n\treadonly code = 'COMMAND_MIDDLEWARE_REGISTRY_MISMATCH'\n\tconstructor(operation: string) {\n\t\tsuper(`Typed middleware does not own the definition of operation \"${operation}\"`)\n\t\tthis.name = 'CommandMiddlewareRegistryError'\n\t}\n}\n"],"mappings":"AA4GA,SAAgBA,GAGZ,CACH,MAAO,CACN,UAKC,EACiE,CAIjE,OAAOC,CACR,EACA,mBACC,EAGA,EAGuB,CACvB,SAASC,EACR,EACoF,CACpF,OACC,OAAO,UAAU,eAAe,KAAKC,EAAYC,EAAM,SAAS,GAChED,EAAWC,EAAM,aAAeA,EAAM,UAExC,CACA,MAAQ,IAAU,CACjB,GAAI,CAACF,EAAeE,CAAK,EACxB,MAAM,IAAIC,EAA+BD,EAAM,SAAS,EAEzD,OAAOE,EAAWF,CAAK,CACxB,CACD,CACD,CACD,CAEA,IAAMC,EAAN,cAA6C,KAAM,CAClD,KAAgB,uCAChB,YAAY,EAAmB,CAC9B,MAAM,8DAA8DE,EAAU,EAAE,EAChF,KAAK,KAAO,gCACb,CACD"}
|