cvx-kit 0.1.7 → 0.1.10
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 +15 -0
- package/README.md +63 -47
- 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 +21 -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/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 +20 -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 +5 -6
- package/dist/modules/effect/api-zod.mjs.map +1 -1
- package/dist/modules/effect/api.d.mts +6 -7
- package/dist/modules/effect/api.mjs.map +1 -1
- package/dist/modules/effect/command.d.mts +10 -7
- 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.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 +8 -5
- 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.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/architecture.md +3 -3
- package/docs/auth.md +10 -4
- package/docs/command-context.md +150 -0
- package/docs/commands-legacy.md +511 -0
- package/docs/commands.md +113 -451
- package/docs/conventions.md +15 -5
- package/docs/crud.md +4 -0
- package/docs/domain-operations.md +1 -1
- package/docs/effect.md +14 -3
- package/docs/llms.md +69 -45
- package/docs/migration.md +1 -1
- package/docs/oxlint.md +1 -1
- package/docs/upgrading.md +18 -1
- package/docs/zod-table.md +1 -1
- package/package.json +21 -15
- package/scripts/test-packed-auth.mjs +68 -0
- package/scripts/test-packed-effect.mjs +4 -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":"crud.mjs","names":["secured"],"sources":["../../../src/modules/effect/crud.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport type { GenericId } from 'convex/values'\nimport type { PaginationOptions, PaginationResult } from 'convex/server'\nimport { z } from 'zod'\nimport { paginated, zid } from '../../zod-table'\nimport { defaultErrors } from '../../errors'\nimport type { EffectFoundation, EffectFoundationOptions } from './foundation'\n// oxlint-disable-next-line cvx/component-boundaries -- SAFETY: Match the bound Foundation's concrete observability dependency without changing its lifecycle.\nimport type { Observability } from '../../components/foundation/modules/observability/observability'\nimport { normalizeEffect } from './normalize'\nimport {\n\teffectOperationFactory,\n\ttype CallbackError,\n\ttype CallbackRequirements,\n\ttype EffectValue,\n\ttype EffectOperationArgument,\n\ttype EffectOperationResult,\n\ttype EffectOperationError,\n\ttype EffectOperationRequirements,\n\ttype UnwrappedDefaultError,\n\ttype UnwrappedDefaultRequirements,\n} from './operation'\nimport type { ContractSchema, LegacyParser, StandardSchema } from '../contracts/contract'\n\n/** Table masks and branded IDs come from the same kit-owned table boundary. */\nexport type EffectCrudTable = {\n\ttableName: string\n\tcommandInput: z.ZodObject<Record<string, z.ZodType>>\n\tstorage: z.ZodObject<Record<string, z.ZodType>>\n\tpublicDto: z.ZodObject<Record<string, z.ZodType>>\n\ttools: {\n\t\tid: z.ZodObject<{ id: z.ZodType<GenericId<string>, string> }>\n\t\tupdate: z.ZodObject<{\n\t\t\tid: z.ZodType<GenericId<string>, string>\n\t\t\tdata: z.ZodObject<Record<string, z.ZodType>>\n\t\t}>\n\t}\n}\ntype Input<Table extends EffectCrudTable> = z.output<Table['commandInput']>\ntype Storage<Table extends EffectCrudTable> = z.input<Table['storage']>\ntype Id<Table extends EffectCrudTable> = GenericId<Table['tableName']>\ntype Update<Table extends EffectCrudTable> = z.output<Table['tools']['update']>\ntype IdInput<Table extends EffectCrudTable> = z.output<Table['tools']['id']>\ntype IdContext<Table extends EffectCrudTable> = {\n\tdb: { normalizeId: (table: Table['tableName'], id: string) => Id<Table> | null }\n}\n/** Compare decoded command fields with storage input, allowing server-only fields. */\ntype StorageCompatible<Decoded, Stored> = [Exclude<keyof Decoded, keyof Stored>] extends [never]\n\t? [Decoded] extends [Pick<Partial<Stored>, Extract<keyof Decoded, keyof Stored>>]\n\t\t? true\n\t\t: false\n\t: false\n// Presence only: callback return inference belongs to the existing overrides signature.\ntype StorageOverrides<Table extends EffectCrudTable> = (StorageCompatible<\n\tInput<Table>,\n\tStorage<Table>\n> extends true\n\t? unknown\n\t: { overrides: { create: Function } }) &\n\t(StorageCompatible<Update<Table>['data'], Storage<Table>> extends true\n\t\t? unknown\n\t\t: { overrides: { update: Function } })\ntype Supported<Value> = Value | PromiseLike<Value> | Effect.Effect<Value, unknown, unknown>\nexport type EffectCrudPage<Row> = PaginationResult<Row>\n// Materialize the native interface so the alias also satisfies Convex's function-args constraint.\nexport type EffectCrudPagination = {\n\t[Key in keyof PaginationOptions]: PaginationOptions[Key]\n} & { id?: number }\n/** Trusted repositories receive domain context, never authority from caller arguments. */\nexport type EffectCrudRepository<Context, Table extends EffectCrudTable, Insert, Patch> = {\n\tinsert: (context: Context, values: Storage<Table>) => Insert\n\tpatch: (context: Context, id: Id<Table>, values: Partial<Storage<Table>>) => Patch\n}\nexport type EffectCrudContext<Table extends EffectCrudTable> = {\n\tdb: {\n\t\tinsert: (table: Table['tableName'], values: Storage<Table>) => Promise<Id<Table>>\n\t\tpatch: (id: Id<Table>, values: Partial<Storage<Table>>) => Promise<void>\n\t}\n}\n/* oxlint-disable anti-slop/no-unknown-returns -- Type-only host extraction; the bound Foundation retains the callbacks and their concrete return channels. */\ntype CallbackHost<Callback> = [Exclude<Callback, undefined>] extends [never]\n\t? unknown\n\t: Exclude<Callback, undefined> extends (...args: infer Arguments) => unknown\n\t\t? Arguments extends []\n\t\t\t? unknown\n\t\t\t: Arguments[0]\n\t\t: unknown\ntype PermissionPolicy<Dependencies> = 'checkPermission' extends keyof Dependencies\n\t? Dependencies['checkPermission']\n\t: never\ntype CallbackReturned<Callback> = Callback extends (...args: never[]) => infer Returned\n\t? Returned\n\t: never\ntype QueryCallbackHost<Callback> = Callback extends (host: infer Host, input: never) => unknown\n\t? Host\n\t: never\ntype QueryPolicyHost<Dependencies> = [QueryCallbackHost<PermissionPolicy<Dependencies>>] extends [\n\tnever,\n]\n\t? unknown\n\t: QueryCallbackHost<PermissionPolicy<Dependencies>>\ntype PolicyHost<Options extends EffectFoundationOptions> = CallbackHost<Options['writeAudit']> &\n\tQueryPolicyHost<Options & { observability: EffectFoundation<Options>['observability'] }>\n/* oxlint-enable anti-slop/no-unknown-returns */\n\n/** Keep registry indexing inside a named, constrained declaration boundary. */\ntype CrudExecutor<\n\tHost,\n\tOperations extends Readonly<Record<string, { input: ContractSchema; result: ContractSchema }>>,\n\tCallbacks,\n\tGuard,\n> = {\n\texec<Key extends Extract<keyof Operations, string>>(\n\t\toperation: Key,\n\t\tinput: EffectOperationArgument<Operations[Key]>,\n\t\thost: Host,\n\t): Effect.Effect<\n\t\tEffectOperationResult<Operations[Key]>,\n\t\t| EffectOperationError<Operations[Key]>\n\t\t| CallbackError<Callbacks>\n\t\t| UnwrappedDefaultError<Operations[Key], Guard>,\n\t\t| EffectOperationRequirements<Operations[Key]>\n\t\t| CallbackRequirements<Callbacks>\n\t\t| UnwrappedDefaultRequirements<Operations[Key], Guard>\n\t>\n}\n\nexport type EffectCrudConfig<\n\tOptions extends EffectFoundationOptions,\n\tHost,\n\tContextReturned,\n\tTable extends EffectCrudTable,\n\tActor,\n\tEnrich,\n\tInsert,\n\tPatch,\n\tGet,\n\tList,\n\tProject,\n\tPolicy,\n\tCreateGuard,\n\tUpdateGuard,\n\tArchiveGuard,\n\tGetGuard,\n\tListGuard,\n\tCreateOverride,\n\tUpdateOverride,\n\tArchiveOverride,\n\tCheckId = never,\n> = {\n\tfoundation: EffectFoundation<Options>\n\ttable: Table\n\tcontext: (host: Host) => ContextReturned\n\taggregateType: string\n\tclassification?: string\n\t/** Trusted table-membership check, not an existence lookup or a string-brand parser. */\n\tcheckId?: (context: EffectValue<ContextReturned>, id: string) => CheckId\n\tactor: (context: EffectValue<ContextReturned>) => Actor\n\tenrich?: (context: EffectValue<ContextReturned>, input: Input<Table>) => Enrich\n\trepository?: EffectCrudRepository<EffectValue<ContextReturned>, Table, Insert, Patch>\n\tpolicy?: {\n\t\tguard?: (context: EffectValue<ContextReturned>) => Policy\n\t\tpermissions?: Partial<Record<'create' | 'update' | 'archive' | 'get' | 'list', string>>\n\t}\n\tguards?: {\n\t\tcreate?: (context: EffectValue<ContextReturned>, input: Input<Table>) => CreateGuard\n\t\tupdate?: (context: EffectValue<ContextReturned>, input: Update<Table>) => UpdateGuard\n\t\tarchive?: (context: EffectValue<ContextReturned>, input: IdInput<Table>) => ArchiveGuard\n\t\tget?: (context: EffectValue<ContextReturned>, input: IdInput<Table>) => GetGuard\n\t\tlist?: (context: EffectValue<ContextReturned>, input: EffectCrudPagination) => ListGuard\n\t}\n\toverrides?: {\n\t\tcreate?: (input: Input<Table>, context: EffectValue<ContextReturned>) => CreateOverride\n\t\tupdate?: (input: Update<Table>, context: EffectValue<ContextReturned>) => UpdateOverride\n\t\tarchive?: (input: IdInput<Table>, context: EffectValue<ContextReturned>) => ArchiveOverride\n\t}\n\tread: {\n\t\t/** Maximum initial page target; reactive ranges may return more rows. */\n\t\tmaxPageSize: number\n\t\t/**\n\t\t * Server-owned indexed pagination row budget; defaults to maxPageSize. Search ignores it.\n\t\t * Native reactive ranges may exceed this budget; consumers must honor split metadata.\n\t\t */\n\t\tmaximumRowsRead?: number\n\t\t/** Return raw, undecoded public-schema input; the query result lifecycle decodes it once. */\n\t\tproject: (row: Storage<Table>) => Project\n\t\tget: (context: EffectValue<ContextReturned>, id: Id<Table>) => Get\n\t\t/** Trusted adapters forward the supplied read budget to supported native pagination. */\n\t\tlist: (context: EffectValue<ContextReturned>, input: EffectCrudPagination) => List\n\t}\n} & (EffectValue<ContextReturned> extends EffectCrudContext<Table>\n\t? unknown\n\t: { repository: EffectCrudRepository<EffectValue<ContextReturned>, Table, Insert, Patch> }) &\n\t(EffectValue<ContextReturned> extends IdContext<Table>\n\t\t? unknown\n\t\t: { checkId: (context: EffectValue<ContextReturned>, id: string) => CheckId }) &\n\tStorageOverrides<Table>\n\n/** Generate operations through the Foundation's bound helpers; no runner or policy lives here. */\nexport function createEffectCrud<\n\tconst Options extends EffectFoundationOptions,\n\tHost extends PolicyHost<Options>,\n\tContextReturned,\n\tconst Table extends EffectCrudTable,\n\tActor extends Supported<string>,\n\tEnrich extends Supported<Partial<Storage<Table>>> = never,\n\tInsert extends Supported<Id<Table>> = never,\n\tPatch extends Supported<void> = never,\n\tGet extends Supported<Storage<Table> | null> = never,\n\tList extends Supported<EffectCrudPage<Storage<Table>>> = never,\n\tProject extends Supported<z.input<Table['publicDto']>> = never,\n\tPolicy extends Supported<void> = never,\n\tCreateGuard extends Supported<void> = never,\n\tUpdateGuard extends Supported<void> = never,\n\tArchiveGuard extends Supported<void> = never,\n\tGetGuard extends Supported<void> = never,\n\tListGuard extends Supported<void> = never,\n\tCreateOverride extends Supported<{ id: Id<Table> }> = never,\n\tUpdateOverride extends Supported<{ ok: true }> = never,\n\tArchiveOverride extends Supported<{ ok: true }> = never,\n\tCheckId extends Supported<boolean> = never,\n\tconst Configuration extends object = object,\n>(\n\tconfig: Configuration &\n\t\tProtectedOverrides<Configuration> &\n\t\tEffectCrudConfig<\n\t\t\tOptions,\n\t\t\tHost,\n\t\t\tContextReturned,\n\t\t\tTable,\n\t\t\tActor,\n\t\t\tEnrich,\n\t\t\tInsert,\n\t\t\tPatch,\n\t\t\tGet,\n\t\t\tList,\n\t\t\tProject,\n\t\t\tPolicy,\n\t\t\tCreateGuard,\n\t\t\tUpdateGuard,\n\t\t\tArchiveGuard,\n\t\t\tGetGuard,\n\t\t\tListGuard,\n\t\t\tCreateOverride,\n\t\t\tUpdateOverride,\n\t\t\tArchiveOverride,\n\t\t\tCheckId\n\t\t>,\n) {\n\tconst { table } = config\n\tif ('tenant' in table.storage.shape && !config.enrich) {\n\t\treturn defaultErrors.throw({\n\t\t\tcode: 'CRUD_ENRICH_REQUIRED',\n\t\t\tmessage: `Table \"${table.tableName}\" requires an enrich callback`,\n\t\t})\n\t}\n\tif (!Number.isSafeInteger(config.read.maxPageSize) || config.read.maxPageSize < 1)\n\t\tthrow Error('CRUD maxPageSize must be a positive safe integer')\n\tconst maximumRowsRead = config.read.maximumRowsRead ?? config.read.maxPageSize\n\tif (!Number.isSafeInteger(maximumRowsRead) || maximumRowsRead < 1)\n\t\tthrow Error('CRUD maximumRowsRead must be a positive safe integer')\n\tconst name: Table['tableName'] = table.tableName\n\tconst id = zid(name)\n\tconst commandInput: StandardSchema<z.input<Table['commandInput']>, Input<Table>> &\n\t\tLegacyParser<Input<Table>> = crudSchema<Table['commandInput']>(table.commandInput)\n\tconst updateInput: StandardSchema<z.input<Table['tools']['update']>, Update<Table>> &\n\t\tLegacyParser<Update<Table>> = crudSchema<Table['tools']['update']>(table.tools.update)\n\tconst idInput: StandardSchema<z.input<Table['tools']['id']>, IdInput<Table>> &\n\t\tLegacyParser<IdInput<Table>> = crudSchema<Table['tools']['id']>(table.tools.id)\n\tconst publicDto: Table['publicDto'] = table.publicDto\n\tconst createResult: StandardSchema<{ id: string }, { id: Id<Table> }> &\n\t\tLegacyParser<{ id: Id<Table> }> = crudSchema(z.object({ id }).strict())\n\tconst okResult = z.object({ ok: z.literal(true) }).strict()\n\tconst pagination = z\n\t\t.object({\n\t\t\tnumItems: z.number().int().min(1).max(config.read.maxPageSize),\n\t\t\tcursor: z.string().nullable(),\n\t\t\tendCursor: z.string().nullable().optional(),\n\t\t\tid: z.number().optional(),\n\t\t\tmaximumRowsRead: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),\n\t\t\tmaximumBytesRead: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),\n\t\t})\n\t\t.strict()\n\tconst pageResult = paginated(publicDto).result\n\tconst classification = config.classification ?? 'business'\n\tconst aggregate = (aggregateId: string) => ({ type: config.aggregateType, id: aggregateId })\n\tconst createName = `${name}.create` as const\n\tconst updateName = `${name}.update` as const\n\tconst archiveName = `${name}.archive` as const\n\tconst getName = `${name}.get` as const\n\tconst listName = `${name}.list` as const\n\ttype Domain = EffectValue<ContextReturned>\n\tfunction checkedId(context: Domain, value: string) {\n\t\treturn normalizeAs<boolean, CheckId | boolean>(() => {\n\t\t\tif (config.checkId) return config.checkId(context, value)\n\t\t\t// SAFETY: without an explicit checker, configuration requires this normalizing reader.\n\t\t\tconst secured = context as Domain & IdContext<Table>\n\t\t\treturn secured.db.normalizeId(table.tableName, value) !== null\n\t\t}).pipe(\n\t\t\tEffect.map((valid) => {\n\t\t\t\tif (valid !== true)\n\t\t\t\t\treturn defaultErrors.throw({\n\t\t\t\t\t\tcode: 'CRUD_INVALID_ID',\n\t\t\t\t\t\tmessage: `Invalid ID for table \"${table.tableName}\"`,\n\t\t\t\t\t})\n\t\t\t\t// SAFETY: the trusted runtime table-membership boundary accepted this ID.\n\t\t\t\treturn value as Id<Table>\n\t\t\t}),\n\t\t)\n\t}\n\tfunction insert(context: Domain, values: Storage<Table>) {\n\t\tif (config.repository) return normalizeEffect(() => config.repository!.insert(context, values))\n\t\t// SAFETY: without an explicit repository, EffectCrudConfig requires this secured writer context.\n\t\tconst secured = context as Domain & EffectCrudContext<Table>\n\t\treturn normalizeEffect(() => secured.db.insert(table.tableName, values))\n\t}\n\tfunction patch(context: Domain, documentId: Id<Table>, values: Partial<Storage<Table>>) {\n\t\tif (config.repository)\n\t\t\treturn normalizeEffect(() => config.repository!.patch(context, documentId, values))\n\t\t// SAFETY: without an explicit repository, EffectCrudConfig requires this secured writer context.\n\t\tconst secured = context as Domain & EffectCrudContext<Table>\n\t\treturn normalizeEffect(() => secured.db.patch(documentId, values))\n\t}\n\tconst defaultCreate = (input: Input<Table>, context: Domain) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst enrichment = yield* normalizeAs<\n\t\t\t\tPartial<Storage<Table>> | undefined,\n\t\t\t\tEnrich | undefined\n\t\t\t>(() => config.enrich?.(context, input))\n\t\t\tconst values = Object.fromEntries(\n\t\t\t\tObject.entries({ ...input, ...enrichment }).filter(([, value]) => value !== undefined),\n\t\t\t)\n\t\t\t// SAFETY: StorageOverrides permits this default only for storage-compatible decoded fields; trusted enrichment wins and undefined fields are omitted.\n\t\t\tconst stored = values as Storage<Table>\n\t\t\treturn { id: yield* insert(context, stored) }\n\t\t})\n\tconst create = chooseHandler<\n\t\tInput<Table>,\n\t\tDomain,\n\t\tCreateOverride,\n\t\tReturnType<typeof defaultCreate>,\n\t\tRequiredOverride<Configuration, 'create'>\n\t>(config.overrides?.create, defaultCreate)\n\t// SAFETY: StorageOverrides permits this default only for storage-compatible decoded update fields.\n\tconst defaultUpdate = (input: Update<Table>, context: Domain) =>\n\t\tpatch(context, input.id as Id<Table>, input.data as Partial<Storage<Table>>).pipe(\n\t\t\tEffect.as({ ok: true as const }),\n\t\t)\n\tconst chosenUpdate = chooseHandler<\n\t\tUpdate<Table>,\n\t\tDomain,\n\t\tUpdateOverride,\n\t\tReturnType<typeof defaultUpdate>,\n\t\tRequiredOverride<Configuration, 'update'>\n\t>(config.overrides?.update, defaultUpdate)\n\tconst update = (input: Update<Table>, context: Domain) =>\n\t\tcheckedId(context, input.id).pipe(\n\t\t\tEffect.flatMap(() => normalizeEffect(() => chosenUpdate(input, context))),\n\t\t)\n\t// SAFETY: the checked handler below proves table membership; archive writes only its server timestamp.\n\tconst defaultArchive = (input: IdInput<Table>, context: Domain) =>\n\t\tpatch(context, input.id as Id<Table>, archivePatch<Table>(Date.now())).pipe(\n\t\t\tEffect.as({ ok: true as const }),\n\t\t)\n\tconst chosenArchive = chooseHandler<\n\t\tIdInput<Table>,\n\t\tDomain,\n\t\tArchiveOverride,\n\t\tReturnType<typeof defaultArchive>,\n\t\tRequiredOverride<Configuration, 'archive'>\n\t>(config.overrides?.archive, defaultArchive)\n\tconst archive = (input: IdInput<Table>, context: Domain) =>\n\t\tcheckedId(context, input.id).pipe(\n\t\t\tEffect.flatMap(() => normalizeEffect(() => chosenArchive(input, context))),\n\t\t)\n\tconst define = effectOperationFactory<\n\t\tDomain,\n\t\tRecord<never, never>,\n\t\tCallbackError<Policy>,\n\t\tCallbackRequirements<Policy>\n\t>()\n\tconst createAudit = ({ result }: { result: { id: Id<Table> } }, context: Domain) =>\n\t\tnormalizeAs<string, Actor>(() => config.actor(context)).pipe(\n\t\t\tEffect.map((actorId) => ({\n\t\t\t\toperation: createName,\n\t\t\t\tactorId,\n\t\t\t\taggregate: aggregate(result.id),\n\t\t\t})),\n\t\t)\n\tconst updateAudit = ({ command: input }: { command: Update<Table> }, context: Domain) =>\n\t\tnormalizeAs<string, Actor>(() => config.actor(context)).pipe(\n\t\t\tEffect.map((actorId) => ({ operation: updateName, actorId, aggregate: aggregate(input.id) })),\n\t\t)\n\tconst archiveAudit = ({ command: input }: { command: IdInput<Table> }, context: Domain) =>\n\t\tnormalizeAs<string, Actor>(() => config.actor(context)).pipe(\n\t\t\tEffect.map((actorId) => ({\n\t\t\t\toperation: archiveName,\n\t\t\t\tactorId,\n\t\t\t\taggregate: aggregate(input.id),\n\t\t\t})),\n\t\t)\n\tconst operations = Object.assign(\n\t\t{},\n\t\tnamed(\n\t\t\tcreateName,\n\t\t\tdefine.command<\n\t\t\t\ttypeof commandInput,\n\t\t\t\ttypeof createResult,\n\t\t\t\tReturnType<typeof create>,\n\t\t\t\tCreateGuard,\n\t\t\t\tnever,\n\t\t\t\treadonly string[],\n\t\t\t\tReturnType<typeof createAudit>\n\t\t\t>({\n\t\t\t\tinput: commandInput,\n\t\t\t\tresult: createResult,\n\t\t\t\tclassification,\n\t\t\t\taggregates: [config.aggregateType],\n\t\t\t\tpermission: config.policy?.permissions?.create,\n\t\t\t\tguard: config.guards?.create,\n\t\t\t\thandler: create,\n\t\t\t\taudit: createAudit,\n\t\t\t}),\n\t\t),\n\t\tnamed(\n\t\t\tupdateName,\n\t\t\tdefine.command<\n\t\t\t\ttypeof updateInput,\n\t\t\t\ttypeof okResult,\n\t\t\t\tReturnType<typeof update>,\n\t\t\t\tUpdateGuard,\n\t\t\t\tnever,\n\t\t\t\treadonly string[],\n\t\t\t\tReturnType<typeof updateAudit>\n\t\t\t>({\n\t\t\t\tinput: updateInput,\n\t\t\t\tresult: okResult,\n\t\t\t\tclassification,\n\t\t\t\taggregates: [config.aggregateType],\n\t\t\t\tpermission: config.policy?.permissions?.update,\n\t\t\t\tguard: config.guards?.update,\n\t\t\t\thandler: update,\n\t\t\t\taudit: updateAudit,\n\t\t\t}),\n\t\t),\n\t\tnamed(\n\t\t\tarchiveName,\n\t\t\tdefine.command<\n\t\t\t\ttypeof idInput,\n\t\t\t\ttypeof okResult,\n\t\t\t\tReturnType<typeof archive>,\n\t\t\t\tArchiveGuard,\n\t\t\t\tnever,\n\t\t\t\treadonly string[],\n\t\t\t\tReturnType<typeof archiveAudit>\n\t\t\t>({\n\t\t\t\tinput: idInput,\n\t\t\t\tresult: okResult,\n\t\t\t\tclassification,\n\t\t\t\taggregates: [config.aggregateType],\n\t\t\t\tpermission: config.policy?.permissions?.archive,\n\t\t\t\tguard: config.guards?.archive,\n\t\t\t\thandler: archive,\n\t\t\t\taudit: archiveAudit,\n\t\t\t}),\n\t\t),\n\t)\n\ttype Resolve = (host: Host) => ContextReturned\n\ttype Dependencies = Options & { observability: Observability }\n\tconst commandConfiguration = {\n\t\tcontext: config.context,\n\t\tdefaults: { guard: config.policy?.guard },\n\t\toperations: () => operations,\n\t}\n\t// SAFETY: each operation was checked above; Host is constrained to both bound policy hosts. Generic mapped keys need the paired registry proof restored.\n\tconst commands: CrudExecutor<Host, typeof operations, Resolve | Options[keyof Options], Policy> =\n\t\tconfig.foundation.Command<Resolve, typeof operations, Policy>(\n\t\t\tcommandConfiguration as Parameters<\n\t\t\t\ttypeof config.foundation.Command<Resolve, typeof operations, Policy>\n\t\t\t>[0],\n\t\t)\n\tconst getResult: StandardSchema<\n\t\tz.input<Table['publicDto']> | null,\n\t\tz.output<Table['publicDto']> | null\n\t> &\n\t\tLegacyParser<z.output<Table['publicDto']> | null> = crudSchema(publicDto.nullable())\n\tconst get = (input: IdInput<Table>, context: Domain) =>\n\t\tcheckedId(context, input.id).pipe(\n\t\t\tEffect.flatMap((documentId) =>\n\t\t\t\tnormalizeAs<Storage<Table> | null, Get>(() => config.read.get(context, documentId)),\n\t\t\t),\n\t\t\tEffect.flatMap((row) =>\n\t\t\t\trow === null\n\t\t\t\t\t? Effect.succeed(null)\n\t\t\t\t\t: normalizeAs<z.input<Table['publicDto']>, Project>(() => config.read.project(row)),\n\t\t\t),\n\t\t)\n\tconst list = (input: EffectCrudPagination, context: Domain) =>\n\t\tnormalizeAs<EffectCrudPage<Storage<Table>>, List>(() =>\n\t\t\t// Trusted adapters forward this budget to indexed db.paginate; native search does not enforce it.\n\t\t\tconfig.read.list(context, {\n\t\t\t\t...input,\n\t\t\t\tmaximumRowsRead: Math.min(input.maximumRowsRead ?? maximumRowsRead, maximumRowsRead),\n\t\t\t}),\n\t\t).pipe(\n\t\t\tEffect.flatMap((page) =>\n\t\t\t\tEffect.forEach(page.page, (row) =>\n\t\t\t\t\tnormalizeAs<z.input<Table['publicDto']>, Project>(() => config.read.project(row)),\n\t\t\t\t).pipe(Effect.map((rows) => ({ ...page, page: rows }))),\n\t\t\t),\n\t\t)\n\tconst queryOperations = Object.assign(\n\t\t{},\n\t\tnamed(\n\t\t\tgetName,\n\t\t\tdefine.query<typeof idInput, typeof getResult, ReturnType<typeof get>, GetGuard>({\n\t\t\t\tinput: idInput,\n\t\t\t\tresult: getResult,\n\t\t\t\tpermission: config.policy?.permissions?.get,\n\t\t\t\tguard: config.guards?.get,\n\t\t\t\thandler: get,\n\t\t\t}),\n\t\t),\n\t\tnamed(\n\t\t\tlistName,\n\t\t\tdefine.query<typeof pagination, typeof pageResult, ReturnType<typeof list>, ListGuard>({\n\t\t\t\tinput: pagination,\n\t\t\t\tresult: pageResult,\n\t\t\t\tpermission: config.policy?.permissions?.list,\n\t\t\t\tguard: config.guards?.list,\n\t\t\t\thandler: list,\n\t\t\t}),\n\t\t),\n\t)\n\tconst queryConfiguration = {\n\t\tcontext: config.context,\n\t\tdefaults: { guard: config.policy?.guard },\n\t\t// SAFETY: the two query helpers checked these exact callbacks and schemas before literal-key assembly.\n\t\toperations: () => queryOperations,\n\t}\n\t// SAFETY: checked query helpers produced the registry above; explicit instantiation keeps mapped operation keys paired.\n\tconst queries: CrudExecutor<\n\t\tHost,\n\t\ttypeof queryOperations,\n\t\tContextReturned | CallbackReturned<PermissionPolicy<Dependencies>>,\n\t\tPolicy\n\t> = config.foundation.Query<Host, ContextReturned, typeof queryOperations, Policy>(\n\t\tqueryConfiguration as Parameters<\n\t\t\ttypeof config.foundation.Query<Host, ContextReturned, typeof queryOperations, Policy>\n\t\t>[0],\n\t)\n\treturn { commands, queries, operations, queryOperations }\n}\n\ntype NamedOperation<Name extends string, Definition> = { [Key in Name]: Definition }\nfunction named<const Name extends string, Definition>(name: Name, definition: Definition) {\n\t// SAFETY: the single computed property pairs this literal operation name with its checked definition.\n\treturn { [name]: definition } as NamedOperation<Name, Definition>\n}\ntype ProtectedOverrides<Configuration> = 'overrides' extends keyof Configuration\n\t? {\n\t\t\toverrides?: {\n\t\t\t\t[\n\t\t\t\t\tKey in Exclude<\n\t\t\t\t\t\tkeyof NonNullable<Configuration['overrides']>,\n\t\t\t\t\t\t'create' | 'update' | 'archive'\n\t\t\t\t\t>\n\t\t\t\t]: never\n\t\t\t}\n\t\t}\n\t: unknown\ntype RequiredOverride<Configuration, Key extends string> = Configuration extends {\n\toverrides: { [K in Key]: Function }\n}\n\t? true\n\t: false\ntype Chosen<Override, Default, Required extends boolean> = Required extends true\n\t? Override\n\t: [Override] extends [never]\n\t\t? Default\n\t\t: Override | Default\nfunction chooseHandler<Input, Context, Override, Default, Required extends boolean>(\n\toverride: ((input: Input, context: Context) => Override) | undefined,\n\tfallback: (input: Input, context: Context) => Default,\n): (input: Input, context: Context) => Chosen<Override, Default, Required> {\n\t// SAFETY: never is the absent override default; a declared override replaces only this handler.\n\treturn (override ?? fallback) as (\n\t\tinput: Input,\n\t\tcontext: Context,\n\t) => Chosen<Override, Default, Required>\n}\nfunction normalizeAs<Value, Returned extends Supported<Value>>(invoke: () => Returned) {\n\t// SAFETY: Returned is constrained to this success contract; normalization retains its exact error/service channels.\n\treturn normalizeEffect(invoke) as Effect.Effect<\n\t\tValue,\n\t\tCallbackError<Returned>,\n\t\tCallbackRequirements<Returned>\n\t>\n}\nfunction crudSchema<Schema extends z.ZodType>(\n\tschema: Schema,\n): StandardSchema<z.input<Schema>, z.output<Schema>> & LegacyParser<z.output<Schema>> {\n\treturn {\n\t\t'~standard': schema['~standard'],\n\t\tparse: (value) => schema.parse(value),\n\t\tparseAsync: (value) => schema.parseAsync(value),\n\t}\n}\n\nfunction archivePatch<Table extends EffectCrudTable>(archivedAt: number): Partial<Storage<Table>> {\n\t// SAFETY: all kit table boundaries include the server-owned archivedAt timestamp.\n\treturn Object.fromEntries([['archivedAt', archivedAt]]) as Partial<Storage<Table>>\n}\n"],"mappings":"6QAuMA,SAAgB,EAwBf,EAyBC,CACD,GAAM,CAAE,SAAU,EAClB,GAAI,WAAY,EAAM,QAAQ,OAAS,CAAC,EAAO,OAC9C,OAAO,EAAc,MAAM,CAC1B,KAAM,uBACN,QAAS,UAAU,EAAM,UAAU,8BACpC,CAAC,EAEF,GAAI,CAAC,OAAO,cAAc,EAAO,KAAK,WAAW,GAAK,EAAO,KAAK,YAAc,EAC/E,MAAM,MAAM,kDAAkD,EAC/D,IAAM,EAAkB,EAAO,KAAK,iBAAmB,EAAO,KAAK,YACnE,GAAI,CAAC,OAAO,cAAc,CAAe,GAAK,EAAkB,EAC/D,MAAM,MAAM,sDAAsD,EACnE,IAAM,EAA2B,EAAM,UACjC,EAAK,EAAI,CAAI,EACb,EACwB,EAAkC,EAAM,YAAY,EAC5E,EACyB,EAAqC,EAAM,MAAM,MAAM,EAChF,EAC0B,EAAiC,EAAM,MAAM,EAAE,EACzE,EAAgC,EAAM,UACtC,EAC6B,EAAW,EAAE,OAAO,CAAE,IAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EACjE,EAAW,EAAE,OAAO,CAAE,GAAI,EAAE,QAAQ,EAAI,CAAE,CAAC,CAAC,CAAC,OAAO,EACpD,EAAa,EACjB,OAAO,CACP,SAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAO,KAAK,WAAW,EAC7D,OAAQ,EAAE,OAAO,CAAC,CAAC,SAAS,EAC5B,UAAW,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAC1C,GAAI,EAAE,OAAO,CAAC,CAAC,SAAS,EACxB,gBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,WAA2B,CAAC,CAAC,SAAS,EACnF,iBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,WAA2B,CAAC,CAAC,SAAS,CACrF,CAAC,CAAC,CACD,OAAO,EACH,EAAa,EAAU,CAAS,CAAC,CAAC,OAClC,EAAiB,EAAO,gBAAkB,WAC1C,EAAa,IAAyB,CAAE,KAAM,EAAO,cAAe,GAAI,CAAY,GACpF,EAAa,GAAG,EAAK,SACrB,EAAa,GAAG,EAAK,SACrB,EAAc,GAAG,EAAK,UACtB,EAAU,GAAG,EAAK,MAClB,EAAW,GAAG,EAAK,OAEzB,SAAS,EAAU,EAAiB,EAAe,CAClD,OAAO,MACF,EAAO,QAAgB,EAAO,QAAQ,EAAS,CAAK,EAGjDA,EAAQ,GAAG,YAAY,EAAM,UAAW,CAAK,IAAM,IAC1D,CAAC,CAAC,KACF,EAAO,IAAK,GACP,IAAU,GAMP,EALC,EAAc,MAAM,CAC1B,KAAM,kBACN,QAAS,yBAAyB,EAAM,UAAU,EACnD,CAAC,CAGF,CACF,CACD,CACA,SAAS,EAAO,EAAiB,EAAwB,CACxD,GAAI,EAAO,WAAY,OAAO,MAAsB,EAAO,WAAY,OAAO,EAAS,CAAM,CAAC,EAE9F,IAAM,EAAU,EAChB,OAAO,MAAsB,EAAQ,GAAG,OAAO,EAAM,UAAW,CAAM,CAAC,CACxE,CACA,SAAS,EAAM,EAAiB,EAAuB,EAAiC,CACvF,GAAI,EAAO,WACV,OAAO,MAAsB,EAAO,WAAY,MAAM,EAAS,EAAY,CAAM,CAAC,EAEnF,IAAM,EAAU,EAChB,OAAO,MAAsB,EAAQ,GAAG,MAAM,EAAY,CAAM,CAAC,CAClE,CAcA,IAAM,EAAS,EAMb,EAAO,WAAW,QAnBG,EAAqB,IAC3C,EAAO,IAAI,WAAa,CACvB,IAAM,EAAa,MAAO,MAGlB,EAAO,SAAS,EAAS,CAAK,CAAC,EAMvC,MAAO,CAAE,GAAI,MAAO,EAAO,EALZ,OAAO,YACrB,OAAO,QAAQ,CAAE,GAAG,EAAO,GAAG,CAAW,CAAC,CAAC,CAAC,QAAQ,EAAG,KAAW,IAAU,IAAA,EAAS,CAI7C,CAAC,CAAE,CAC7C,CAAC,CAOuC,EAMnC,EAAe,EAMnB,EAAO,WAAW,QAVG,EAAsB,IAC5C,EAAM,EAAS,EAAM,GAAiB,EAAM,IAA+B,CAAC,CAAC,KAC5E,EAAO,GAAG,CAAE,GAAI,EAAc,CAAC,CAChC,CAOwC,EACnC,GAAU,EAAsB,IACrC,EAAU,EAAS,EAAM,EAAE,CAAC,CAAC,KAC5B,EAAO,YAAc,MAAsB,EAAa,EAAO,CAAO,CAAC,CAAC,CACzE,EAMK,EAAgB,EAMpB,EAAO,WAAW,SAVI,EAAuB,IAC9C,EAAM,EAAS,EAAM,GAAiB,EAAoB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KACtE,EAAO,GAAG,CAAE,GAAI,EAAc,CAAC,CAChC,CAO0C,EACrC,GAAW,EAAuB,IACvC,EAAU,EAAS,EAAM,EAAE,CAAC,CAAC,KAC5B,EAAO,YAAc,MAAsB,EAAc,EAAO,CAAO,CAAC,CAAC,CAC1E,EACK,EAAS,EAKb,EAqBI,EAAa,OAAO,OACzB,CAAC,EACD,EACC,EACA,EAAO,QAQL,CACD,MAAO,EACP,OAAQ,EACR,iBACA,WAAY,CAAC,EAAO,aAAa,EACjC,WAAY,EAAO,QAAQ,aAAa,OACxC,MAAO,EAAO,QAAQ,OACtB,QAAS,EACT,OAxCkB,CAAE,UAAyC,IAC/D,MAAiC,EAAO,MAAM,CAAO,CAAC,CAAC,CAAC,KACvD,EAAO,IAAK,IAAa,CACxB,UAAW,EACX,UACA,UAAW,EAAU,EAAO,EAAE,CAC/B,EAAE,CACH,CAkCC,CAAC,CACF,EACA,EACC,EACA,EAAO,QAQL,CACD,MAAO,EACP,OAAQ,EACR,iBACA,WAAY,CAAC,EAAO,aAAa,EACjC,WAAY,EAAO,QAAQ,aAAa,OACxC,MAAO,EAAO,QAAQ,OACtB,QAAS,EACT,OArDkB,CAAE,QAAS,GAAqC,IACpE,MAAiC,EAAO,MAAM,CAAO,CAAC,CAAC,CAAC,KACvD,EAAO,IAAK,IAAa,CAAE,UAAW,EAAY,UAAS,UAAW,EAAU,EAAM,EAAE,CAAE,EAAE,CAC7F,CAmDC,CAAC,CACF,EACA,EACC,EACA,EAAO,QAQL,CACD,MAAO,EACP,OAAQ,EACR,iBACA,WAAY,CAAC,EAAO,aAAa,EACjC,WAAY,EAAO,QAAQ,aAAa,QACxC,MAAO,EAAO,QAAQ,QACtB,QAAS,EACT,OAtEmB,CAAE,QAAS,GAAsC,IACtE,MAAiC,EAAO,MAAM,CAAO,CAAC,CAAC,CAAC,KACvD,EAAO,IAAK,IAAa,CACxB,UAAW,EACX,UACA,UAAW,EAAU,EAAM,EAAE,CAC9B,EAAE,CACH,CAgEC,CAAC,CACF,CACD,EAGM,EAAuB,CAC5B,QAAS,EAAO,QAChB,SAAU,CAAE,MAAO,EAAO,QAAQ,KAAM,EACxC,eAAkB,CACnB,EAEM,EACL,EAAO,WAAW,QACjB,CAGD,EACK,EAI+C,EAAW,EAAU,SAAS,CAAC,EA0B9E,EAAkB,OAAO,OAC9B,CAAC,EACD,EACC,EACA,EAAO,MAA0E,CAChF,MAAO,EACP,OAAQ,EACR,WAAY,EAAO,QAAQ,aAAa,IACxC,MAAO,EAAO,QAAQ,IACtB,SAlCU,EAAuB,IACnC,EAAU,EAAS,EAAM,EAAE,CAAC,CAAC,KAC5B,EAAO,QAAS,GACf,MAA8C,EAAO,KAAK,IAAI,EAAS,CAAU,CAAC,CACnF,EACA,EAAO,QAAS,GACf,IAAQ,KACL,EAAO,QAAQ,IAAI,EACnB,MAAwD,EAAO,KAAK,QAAQ,CAAG,CAAC,CACpF,CACD,CAyBC,CAAC,CACF,EACA,EACC,EACA,EAAO,MAAgF,CACtF,MAAO,EACP,OAAQ,EACR,WAAY,EAAO,QAAQ,aAAa,KACxC,MAAO,EAAO,QAAQ,KACtB,SAjCW,EAA6B,IAC1C,MAEC,EAAO,KAAK,KAAK,EAAS,CACzB,GAAG,EACH,gBAAiB,KAAK,IAAI,EAAM,iBAAmB,EAAiB,CAAe,CACpF,CAAC,CACF,CAAC,CAAC,KACD,EAAO,QAAS,GACf,EAAO,QAAQ,EAAK,KAAO,GAC1B,MAAwD,EAAO,KAAK,QAAQ,CAAG,CAAC,CACjF,CAAC,CAAC,KAAK,EAAO,IAAK,IAAU,CAAE,GAAG,EAAM,KAAM,CAAK,EAAE,CAAC,CACvD,CACD,CAqBC,CAAC,CACF,CACD,EACM,EAAqB,CAC1B,QAAS,EAAO,QAChB,SAAU,CAAE,MAAO,EAAO,QAAQ,KAAM,EAExC,eAAkB,CACnB,EAYA,MAAO,CAAE,WAAU,QALf,EAAO,WAAW,MACrB,CAIwB,EAAG,aAAY,iBAAgB,CACzD,CAGA,SAAS,EAA6C,EAAY,EAAwB,CAEzF,MAAO,EAAG,GAAO,CAAW,CAC7B,CAuBA,SAAS,EACR,EACA,EAC0E,CAE1E,OAAQ,GAAY,CAIrB,CACA,SAAS,EAAsD,EAAwB,CAEtF,OAAO,EAAgB,CAAM,CAK9B,CACA,SAAS,EACR,EACqF,CACrF,MAAO,CACN,YAAa,EAAO,aACpB,MAAQ,GAAU,EAAO,MAAM,CAAK,EACpC,WAAa,GAAU,EAAO,WAAW,CAAK,CAC/C,CACD,CAEA,SAAS,EAA4C,EAA6C,CAEjG,OAAO,OAAO,YAAY,CAAC,CAAC,aAAc,CAAU,CAAC,CAAC,CACvD"}
|
|
1
|
+
{"version":3,"file":"crud.mjs","names":["secured","createEffectCrud","config","table","defaultErrors","maximumRowsRead","name","id","zid","commandInput","crudSchema","updateInput","idInput","publicDto","createResult","z","okResult","pagination","pageResult","paginated","classification","aggregate","aggregateId","createName","updateName","archiveName","getName","listName","checkedId","normalizeAs","context","value","Effect","valid","insert","normalizeEffect","values","secured","patch","documentId","create","chooseHandler","enrichment","input","chosenUpdate","update","chosenArchive","archivePatch","archive","define","effectOperationFactory","operations","named","result","commandConfiguration","commands","getResult","queryOperations","row","page","rows","queryConfiguration","definition","override","fallback","invoke","schema","archivedAt"],"sources":["../../../src/modules/effect/crud.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport type { GenericId } from 'convex/values'\nimport type { PaginationOptions, PaginationResult } from 'convex/server'\nimport { z } from 'zod'\nimport { paginated, zid } from '../../zod-table'\nimport { defaultErrors } from '../../errors'\nimport type { EffectFoundation, EffectFoundationOptions } from './foundation'\n// oxlint-disable-next-line cvx/component-boundaries -- SAFETY: Match the bound Foundation's concrete observability dependency without changing its lifecycle.\nimport type { Observability } from '../../components/foundation/modules/observability/observability'\nimport { normalizeEffect } from './normalize'\nimport {\n\teffectOperationFactory,\n\ttype CallbackError,\n\ttype CallbackRequirements,\n\ttype EffectValue,\n\ttype EffectOperationArgument,\n\ttype EffectOperationResult,\n\ttype EffectOperationError,\n\ttype EffectOperationRequirements,\n\ttype UnwrappedDefaultError,\n\ttype UnwrappedDefaultRequirements,\n} from './operation'\nimport type { ContractSchema, LegacyParser, StandardSchema } from '../contracts/contract'\n\n/** Table masks and branded IDs come from the same kit-owned table boundary. */\nexport type EffectCrudTable = {\n\ttableName: string\n\tcommandInput: z.ZodObject<Record<string, z.ZodType>>\n\tstorage: z.ZodObject<Record<string, z.ZodType>>\n\tpublicDto: z.ZodObject<Record<string, z.ZodType>>\n\ttools: {\n\t\tid: z.ZodObject<{ id: z.ZodType<GenericId<string>, string> }>\n\t\tupdate: z.ZodObject<{\n\t\t\tid: z.ZodType<GenericId<string>, string>\n\t\t\tdata: z.ZodObject<Record<string, z.ZodType>>\n\t\t}>\n\t}\n}\ntype Input<Table extends EffectCrudTable> = z.output<Table['commandInput']>\ntype Storage<Table extends EffectCrudTable> = z.input<Table['storage']>\ntype Id<Table extends EffectCrudTable> = GenericId<Table['tableName']>\ntype Update<Table extends EffectCrudTable> = z.output<Table['tools']['update']>\ntype IdInput<Table extends EffectCrudTable> = z.output<Table['tools']['id']>\ntype IdContext<Table extends EffectCrudTable> = {\n\tdb: { normalizeId: (table: Table['tableName'], id: string) => Id<Table> | null }\n}\n/** Compare decoded command fields with storage input, allowing server-only fields. */\ntype StorageCompatible<Decoded, Stored> = [Exclude<keyof Decoded, keyof Stored>] extends [never]\n\t? [Decoded] extends [Pick<Partial<Stored>, Extract<keyof Decoded, keyof Stored>>]\n\t\t? true\n\t\t: false\n\t: false\n// Presence only: callback return inference belongs to the existing overrides signature.\ntype StorageOverrides<Table extends EffectCrudTable> = (StorageCompatible<\n\tInput<Table>,\n\tStorage<Table>\n> extends true\n\t? unknown\n\t: { overrides: { create: Function } }) &\n\t(StorageCompatible<Update<Table>['data'], Storage<Table>> extends true\n\t\t? unknown\n\t\t: { overrides: { update: Function } })\ntype Supported<Value> = Value | PromiseLike<Value> | Effect.Effect<Value, unknown, unknown>\nexport type EffectCrudPage<Row> = PaginationResult<Row>\n// Materialize the native interface so the alias also satisfies Convex's function-args constraint.\nexport type EffectCrudPagination = {\n\t[Key in keyof PaginationOptions]: PaginationOptions[Key]\n} & { id?: number }\n/** Trusted repositories receive domain context, never authority from caller arguments. */\nexport type EffectCrudRepository<Context, Table extends EffectCrudTable, Insert, Patch> = {\n\tinsert: (context: Context, values: Storage<Table>) => Insert\n\tpatch: (context: Context, id: Id<Table>, values: Partial<Storage<Table>>) => Patch\n}\nexport type EffectCrudContext<Table extends EffectCrudTable> = {\n\tdb: {\n\t\tinsert: (table: Table['tableName'], values: Storage<Table>) => Promise<Id<Table>>\n\t\tpatch: (id: Id<Table>, values: Partial<Storage<Table>>) => Promise<void>\n\t}\n}\n/* oxlint-disable anti-slop/no-unknown-returns -- Type-only host extraction; the bound Foundation retains the callbacks and their concrete return channels. */\ntype CallbackHost<Callback> = [Exclude<Callback, undefined>] extends [never]\n\t? unknown\n\t: Exclude<Callback, undefined> extends (...args: infer Arguments) => unknown\n\t\t? Arguments extends []\n\t\t\t? unknown\n\t\t\t: Arguments[0]\n\t\t: unknown\ntype PermissionPolicy<Dependencies> = 'checkPermission' extends keyof Dependencies\n\t? Dependencies['checkPermission']\n\t: never\ntype CallbackReturned<Callback> = Callback extends (...args: never[]) => infer Returned\n\t? Returned\n\t: never\ntype QueryCallbackHost<Callback> = Callback extends (host: infer Host, input: never) => unknown\n\t? Host\n\t: never\ntype QueryPolicyHost<Dependencies> = [QueryCallbackHost<PermissionPolicy<Dependencies>>] extends [\n\tnever,\n]\n\t? unknown\n\t: QueryCallbackHost<PermissionPolicy<Dependencies>>\ntype PolicyHost<Options extends EffectFoundationOptions> = CallbackHost<Options['writeAudit']> &\n\tQueryPolicyHost<Options & { observability: EffectFoundation<Options>['observability'] }>\n/* oxlint-enable anti-slop/no-unknown-returns */\n\n/** Keep registry indexing inside a named, constrained declaration boundary. */\ntype CrudExecutor<\n\tHost,\n\tOperations extends Readonly<Record<string, { input: ContractSchema; result: ContractSchema }>>,\n\tCallbacks,\n\tGuard,\n> = {\n\texec<Key extends Extract<keyof Operations, string>>(\n\t\toperation: Key,\n\t\tinput: EffectOperationArgument<Operations[Key]>,\n\t\thost: Host,\n\t): Effect.Effect<\n\t\tEffectOperationResult<Operations[Key]>,\n\t\t| EffectOperationError<Operations[Key]>\n\t\t| CallbackError<Callbacks>\n\t\t| UnwrappedDefaultError<Operations[Key], Guard>,\n\t\t| EffectOperationRequirements<Operations[Key]>\n\t\t| CallbackRequirements<Callbacks>\n\t\t| UnwrappedDefaultRequirements<Operations[Key], Guard>\n\t>\n}\n\nexport type EffectCrudConfig<\n\tOptions extends EffectFoundationOptions,\n\tHost,\n\tContextReturned,\n\tTable extends EffectCrudTable,\n\tActor,\n\tEnrich,\n\tInsert,\n\tPatch,\n\tGet,\n\tList,\n\tProject,\n\tPolicy,\n\tCreateGuard,\n\tUpdateGuard,\n\tArchiveGuard,\n\tGetGuard,\n\tListGuard,\n\tCreateOverride,\n\tUpdateOverride,\n\tArchiveOverride,\n\tCheckId = never,\n> = {\n\tfoundation: EffectFoundation<Options>\n\ttable: Table\n\tcontext: (host: Host) => ContextReturned\n\taggregateType: string\n\tclassification?: string\n\t/** Trusted table-membership check, not an existence lookup or a string-brand parser. */\n\tcheckId?: (context: EffectValue<ContextReturned>, id: string) => CheckId\n\tactor: (context: EffectValue<ContextReturned>) => Actor\n\tenrich?: (context: EffectValue<ContextReturned>, input: Input<Table>) => Enrich\n\trepository?: EffectCrudRepository<EffectValue<ContextReturned>, Table, Insert, Patch>\n\tpolicy?: {\n\t\tguard?: (context: EffectValue<ContextReturned>) => Policy\n\t\tpermissions?: Partial<Record<'create' | 'update' | 'archive' | 'get' | 'list', string>>\n\t}\n\tguards?: {\n\t\tcreate?: (context: EffectValue<ContextReturned>, input: Input<Table>) => CreateGuard\n\t\tupdate?: (context: EffectValue<ContextReturned>, input: Update<Table>) => UpdateGuard\n\t\tarchive?: (context: EffectValue<ContextReturned>, input: IdInput<Table>) => ArchiveGuard\n\t\tget?: (context: EffectValue<ContextReturned>, input: IdInput<Table>) => GetGuard\n\t\tlist?: (context: EffectValue<ContextReturned>, input: EffectCrudPagination) => ListGuard\n\t}\n\toverrides?: {\n\t\tcreate?: (input: Input<Table>, context: EffectValue<ContextReturned>) => CreateOverride\n\t\tupdate?: (input: Update<Table>, context: EffectValue<ContextReturned>) => UpdateOverride\n\t\tarchive?: (input: IdInput<Table>, context: EffectValue<ContextReturned>) => ArchiveOverride\n\t}\n\tread: {\n\t\t/** Maximum initial page target; reactive ranges may return more rows. */\n\t\tmaxPageSize: number\n\t\t/**\n\t\t * Server-owned indexed pagination row budget; defaults to maxPageSize. Search ignores it.\n\t\t * Native reactive ranges may exceed this budget; consumers must honor split metadata.\n\t\t */\n\t\tmaximumRowsRead?: number\n\t\t/** Return raw, undecoded public-schema input; the query result lifecycle decodes it once. */\n\t\tproject: (row: Storage<Table>) => Project\n\t\tget: (context: EffectValue<ContextReturned>, id: Id<Table>) => Get\n\t\t/** Trusted adapters forward the supplied read budget to supported native pagination. */\n\t\tlist: (context: EffectValue<ContextReturned>, input: EffectCrudPagination) => List\n\t}\n} & (EffectValue<ContextReturned> extends EffectCrudContext<Table>\n\t? unknown\n\t: { repository: EffectCrudRepository<EffectValue<ContextReturned>, Table, Insert, Patch> }) &\n\t(EffectValue<ContextReturned> extends IdContext<Table>\n\t\t? unknown\n\t\t: { checkId: (context: EffectValue<ContextReturned>, id: string) => CheckId }) &\n\tStorageOverrides<Table>\n\n/** Generate operations through the Foundation's bound helpers; no runner or policy lives here. */\nexport function createEffectCrud<\n\tconst Options extends EffectFoundationOptions,\n\tHost extends PolicyHost<Options>,\n\tContextReturned,\n\tconst Table extends EffectCrudTable,\n\tActor extends Supported<string>,\n\tEnrich extends Supported<Partial<Storage<Table>>> = never,\n\tInsert extends Supported<Id<Table>> = never,\n\tPatch extends Supported<void> = never,\n\tGet extends Supported<Storage<Table> | null> = never,\n\tList extends Supported<EffectCrudPage<Storage<Table>>> = never,\n\tProject extends Supported<z.input<Table['publicDto']>> = never,\n\tPolicy extends Supported<void> = never,\n\tCreateGuard extends Supported<void> = never,\n\tUpdateGuard extends Supported<void> = never,\n\tArchiveGuard extends Supported<void> = never,\n\tGetGuard extends Supported<void> = never,\n\tListGuard extends Supported<void> = never,\n\tCreateOverride extends Supported<{ id: Id<Table> }> = never,\n\tUpdateOverride extends Supported<{ ok: true }> = never,\n\tArchiveOverride extends Supported<{ ok: true }> = never,\n\tCheckId extends Supported<boolean> = never,\n\tconst Configuration extends object = object,\n>(\n\tconfig: Configuration &\n\t\tProtectedOverrides<Configuration> &\n\t\tEffectCrudConfig<\n\t\t\tOptions,\n\t\t\tHost,\n\t\t\tContextReturned,\n\t\t\tTable,\n\t\t\tActor,\n\t\t\tEnrich,\n\t\t\tInsert,\n\t\t\tPatch,\n\t\t\tGet,\n\t\t\tList,\n\t\t\tProject,\n\t\t\tPolicy,\n\t\t\tCreateGuard,\n\t\t\tUpdateGuard,\n\t\t\tArchiveGuard,\n\t\t\tGetGuard,\n\t\t\tListGuard,\n\t\t\tCreateOverride,\n\t\t\tUpdateOverride,\n\t\t\tArchiveOverride,\n\t\t\tCheckId\n\t\t>,\n) {\n\tconst { table } = config\n\tif ('tenant' in table.storage.shape && !config.enrich) {\n\t\treturn defaultErrors.throw({\n\t\t\tcode: 'CRUD_ENRICH_REQUIRED',\n\t\t\tmessage: `Table \"${table.tableName}\" requires an enrich callback`,\n\t\t})\n\t}\n\tif (!Number.isSafeInteger(config.read.maxPageSize) || config.read.maxPageSize < 1)\n\t\tthrow Error('CRUD maxPageSize must be a positive safe integer')\n\tconst maximumRowsRead = config.read.maximumRowsRead ?? config.read.maxPageSize\n\tif (!Number.isSafeInteger(maximumRowsRead) || maximumRowsRead < 1)\n\t\tthrow Error('CRUD maximumRowsRead must be a positive safe integer')\n\tconst name: Table['tableName'] = table.tableName\n\tconst id = zid(name)\n\tconst commandInput: StandardSchema<z.input<Table['commandInput']>, Input<Table>> &\n\t\tLegacyParser<Input<Table>> = crudSchema<Table['commandInput']>(table.commandInput)\n\tconst updateInput: StandardSchema<z.input<Table['tools']['update']>, Update<Table>> &\n\t\tLegacyParser<Update<Table>> = crudSchema<Table['tools']['update']>(table.tools.update)\n\tconst idInput: StandardSchema<z.input<Table['tools']['id']>, IdInput<Table>> &\n\t\tLegacyParser<IdInput<Table>> = crudSchema<Table['tools']['id']>(table.tools.id)\n\tconst publicDto: Table['publicDto'] = table.publicDto\n\tconst createResult: StandardSchema<{ id: string }, { id: Id<Table> }> &\n\t\tLegacyParser<{ id: Id<Table> }> = crudSchema(z.object({ id }).strict())\n\tconst okResult = z.object({ ok: z.literal(true) }).strict()\n\tconst pagination = z\n\t\t.object({\n\t\t\tnumItems: z.number().int().min(1).max(config.read.maxPageSize),\n\t\t\tcursor: z.string().nullable(),\n\t\t\tendCursor: z.string().nullable().optional(),\n\t\t\tid: z.number().optional(),\n\t\t\tmaximumRowsRead: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),\n\t\t\tmaximumBytesRead: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),\n\t\t})\n\t\t.strict()\n\tconst pageResult = paginated(publicDto).result\n\tconst classification = config.classification ?? 'business'\n\tconst aggregate = (aggregateId: string) => ({ type: config.aggregateType, id: aggregateId })\n\tconst createName = `${name}.create` as const\n\tconst updateName = `${name}.update` as const\n\tconst archiveName = `${name}.archive` as const\n\tconst getName = `${name}.get` as const\n\tconst listName = `${name}.list` as const\n\ttype Domain = EffectValue<ContextReturned>\n\tfunction checkedId(context: Domain, value: string) {\n\t\treturn normalizeAs<boolean, CheckId | boolean>(() => {\n\t\t\tif (config.checkId) return config.checkId(context, value)\n\t\t\t// SAFETY: without an explicit checker, configuration requires this normalizing reader.\n\t\t\tconst secured = context as Domain & IdContext<Table>\n\t\t\treturn secured.db.normalizeId(table.tableName, value) !== null\n\t\t}).pipe(\n\t\t\tEffect.map((valid) => {\n\t\t\t\tif (valid !== true)\n\t\t\t\t\treturn defaultErrors.throw({\n\t\t\t\t\t\tcode: 'CRUD_INVALID_ID',\n\t\t\t\t\t\tmessage: `Invalid ID for table \"${table.tableName}\"`,\n\t\t\t\t\t})\n\t\t\t\t// SAFETY: the trusted runtime table-membership boundary accepted this ID.\n\t\t\t\treturn value as Id<Table>\n\t\t\t}),\n\t\t)\n\t}\n\tfunction insert(context: Domain, values: Storage<Table>) {\n\t\tif (config.repository) return normalizeEffect(() => config.repository!.insert(context, values))\n\t\t// SAFETY: without an explicit repository, EffectCrudConfig requires this secured writer context.\n\t\tconst secured = context as Domain & EffectCrudContext<Table>\n\t\treturn normalizeEffect(() => secured.db.insert(table.tableName, values))\n\t}\n\tfunction patch(context: Domain, documentId: Id<Table>, values: Partial<Storage<Table>>) {\n\t\tif (config.repository)\n\t\t\treturn normalizeEffect(() => config.repository!.patch(context, documentId, values))\n\t\t// SAFETY: without an explicit repository, EffectCrudConfig requires this secured writer context.\n\t\tconst secured = context as Domain & EffectCrudContext<Table>\n\t\treturn normalizeEffect(() => secured.db.patch(documentId, values))\n\t}\n\tconst defaultCreate = (input: Input<Table>, context: Domain) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst enrichment = yield* normalizeAs<\n\t\t\t\tPartial<Storage<Table>> | undefined,\n\t\t\t\tEnrich | undefined\n\t\t\t>(() => config.enrich?.(context, input))\n\t\t\tconst values = Object.fromEntries(\n\t\t\t\tObject.entries({ ...input, ...enrichment }).filter(([, value]) => value !== undefined),\n\t\t\t)\n\t\t\t// SAFETY: StorageOverrides permits this default only for storage-compatible decoded fields; trusted enrichment wins and undefined fields are omitted.\n\t\t\tconst stored = values as Storage<Table>\n\t\t\treturn { id: yield* insert(context, stored) }\n\t\t})\n\tconst create = chooseHandler<\n\t\tInput<Table>,\n\t\tDomain,\n\t\tCreateOverride,\n\t\tReturnType<typeof defaultCreate>,\n\t\tRequiredOverride<Configuration, 'create'>\n\t>(config.overrides?.create, defaultCreate)\n\t// SAFETY: StorageOverrides permits this default only for storage-compatible decoded update fields.\n\tconst defaultUpdate = (input: Update<Table>, context: Domain) =>\n\t\tpatch(context, input.id as Id<Table>, input.data as Partial<Storage<Table>>).pipe(\n\t\t\tEffect.as({ ok: true as const }),\n\t\t)\n\tconst chosenUpdate = chooseHandler<\n\t\tUpdate<Table>,\n\t\tDomain,\n\t\tUpdateOverride,\n\t\tReturnType<typeof defaultUpdate>,\n\t\tRequiredOverride<Configuration, 'update'>\n\t>(config.overrides?.update, defaultUpdate)\n\tconst update = (input: Update<Table>, context: Domain) =>\n\t\tcheckedId(context, input.id).pipe(\n\t\t\tEffect.flatMap(() => normalizeEffect(() => chosenUpdate(input, context))),\n\t\t)\n\t// SAFETY: the checked handler below proves table membership; archive writes only its server timestamp.\n\tconst defaultArchive = (input: IdInput<Table>, context: Domain) =>\n\t\tpatch(context, input.id as Id<Table>, archivePatch<Table>(Date.now())).pipe(\n\t\t\tEffect.as({ ok: true as const }),\n\t\t)\n\tconst chosenArchive = chooseHandler<\n\t\tIdInput<Table>,\n\t\tDomain,\n\t\tArchiveOverride,\n\t\tReturnType<typeof defaultArchive>,\n\t\tRequiredOverride<Configuration, 'archive'>\n\t>(config.overrides?.archive, defaultArchive)\n\tconst archive = (input: IdInput<Table>, context: Domain) =>\n\t\tcheckedId(context, input.id).pipe(\n\t\t\tEffect.flatMap(() => normalizeEffect(() => chosenArchive(input, context))),\n\t\t)\n\tconst define = effectOperationFactory<\n\t\tDomain,\n\t\tRecord<never, never>,\n\t\tCallbackError<Policy>,\n\t\tCallbackRequirements<Policy>\n\t>()\n\tconst createAudit = ({ result }: { result: { id: Id<Table> } }, context: Domain) =>\n\t\tnormalizeAs<string, Actor>(() => config.actor(context)).pipe(\n\t\t\tEffect.map((actorId) => ({\n\t\t\t\toperation: createName,\n\t\t\t\tactorId,\n\t\t\t\taggregate: aggregate(result.id),\n\t\t\t})),\n\t\t)\n\tconst updateAudit = ({ command: input }: { command: Update<Table> }, context: Domain) =>\n\t\tnormalizeAs<string, Actor>(() => config.actor(context)).pipe(\n\t\t\tEffect.map((actorId) => ({ operation: updateName, actorId, aggregate: aggregate(input.id) })),\n\t\t)\n\tconst archiveAudit = ({ command: input }: { command: IdInput<Table> }, context: Domain) =>\n\t\tnormalizeAs<string, Actor>(() => config.actor(context)).pipe(\n\t\t\tEffect.map((actorId) => ({\n\t\t\t\toperation: archiveName,\n\t\t\t\tactorId,\n\t\t\t\taggregate: aggregate(input.id),\n\t\t\t})),\n\t\t)\n\tconst operations = Object.assign(\n\t\t{},\n\t\tnamed(\n\t\t\tcreateName,\n\t\t\tdefine.command<\n\t\t\t\ttypeof commandInput,\n\t\t\t\ttypeof createResult,\n\t\t\t\tReturnType<typeof create>,\n\t\t\t\tCreateGuard,\n\t\t\t\tnever,\n\t\t\t\treadonly string[],\n\t\t\t\tReturnType<typeof createAudit>\n\t\t\t>({\n\t\t\t\tinput: commandInput,\n\t\t\t\tresult: createResult,\n\t\t\t\tclassification,\n\t\t\t\taggregates: [config.aggregateType],\n\t\t\t\tpermission: config.policy?.permissions?.create,\n\t\t\t\tguard: config.guards?.create,\n\t\t\t\thandler: create,\n\t\t\t\taudit: createAudit,\n\t\t\t}),\n\t\t),\n\t\tnamed(\n\t\t\tupdateName,\n\t\t\tdefine.command<\n\t\t\t\ttypeof updateInput,\n\t\t\t\ttypeof okResult,\n\t\t\t\tReturnType<typeof update>,\n\t\t\t\tUpdateGuard,\n\t\t\t\tnever,\n\t\t\t\treadonly string[],\n\t\t\t\tReturnType<typeof updateAudit>\n\t\t\t>({\n\t\t\t\tinput: updateInput,\n\t\t\t\tresult: okResult,\n\t\t\t\tclassification,\n\t\t\t\taggregates: [config.aggregateType],\n\t\t\t\tpermission: config.policy?.permissions?.update,\n\t\t\t\tguard: config.guards?.update,\n\t\t\t\thandler: update,\n\t\t\t\taudit: updateAudit,\n\t\t\t}),\n\t\t),\n\t\tnamed(\n\t\t\tarchiveName,\n\t\t\tdefine.command<\n\t\t\t\ttypeof idInput,\n\t\t\t\ttypeof okResult,\n\t\t\t\tReturnType<typeof archive>,\n\t\t\t\tArchiveGuard,\n\t\t\t\tnever,\n\t\t\t\treadonly string[],\n\t\t\t\tReturnType<typeof archiveAudit>\n\t\t\t>({\n\t\t\t\tinput: idInput,\n\t\t\t\tresult: okResult,\n\t\t\t\tclassification,\n\t\t\t\taggregates: [config.aggregateType],\n\t\t\t\tpermission: config.policy?.permissions?.archive,\n\t\t\t\tguard: config.guards?.archive,\n\t\t\t\thandler: archive,\n\t\t\t\taudit: archiveAudit,\n\t\t\t}),\n\t\t),\n\t)\n\ttype Resolve = (host: Host) => ContextReturned\n\ttype Dependencies = Options & { observability: Observability }\n\tconst commandConfiguration = {\n\t\tcontext: config.context,\n\t\tdefaults: { guard: config.policy?.guard },\n\t\toperations: () => operations,\n\t}\n\t// SAFETY: each operation was checked above; Host is constrained to both bound policy hosts. Generic mapped keys need the paired registry proof restored.\n\tconst commands: CrudExecutor<Host, typeof operations, Resolve | Options[keyof Options], Policy> =\n\t\tconfig.foundation.Command<Resolve, typeof operations, Policy>(\n\t\t\tcommandConfiguration as Parameters<\n\t\t\t\ttypeof config.foundation.Command<Resolve, typeof operations, Policy>\n\t\t\t>[0],\n\t\t)\n\tconst getResult: StandardSchema<\n\t\tz.input<Table['publicDto']> | null,\n\t\tz.output<Table['publicDto']> | null\n\t> &\n\t\tLegacyParser<z.output<Table['publicDto']> | null> = crudSchema(publicDto.nullable())\n\tconst get = (input: IdInput<Table>, context: Domain) =>\n\t\tcheckedId(context, input.id).pipe(\n\t\t\tEffect.flatMap((documentId) =>\n\t\t\t\tnormalizeAs<Storage<Table> | null, Get>(() => config.read.get(context, documentId)),\n\t\t\t),\n\t\t\tEffect.flatMap((row) =>\n\t\t\t\trow === null\n\t\t\t\t\t? Effect.succeed(null)\n\t\t\t\t\t: normalizeAs<z.input<Table['publicDto']>, Project>(() => config.read.project(row)),\n\t\t\t),\n\t\t)\n\tconst list = (input: EffectCrudPagination, context: Domain) =>\n\t\tnormalizeAs<EffectCrudPage<Storage<Table>>, List>(() =>\n\t\t\t// Trusted adapters forward this budget to indexed db.paginate; native search does not enforce it.\n\t\t\tconfig.read.list(context, {\n\t\t\t\t...input,\n\t\t\t\tmaximumRowsRead: Math.min(input.maximumRowsRead ?? maximumRowsRead, maximumRowsRead),\n\t\t\t}),\n\t\t).pipe(\n\t\t\tEffect.flatMap((page) =>\n\t\t\t\tEffect.forEach(page.page, (row) =>\n\t\t\t\t\tnormalizeAs<z.input<Table['publicDto']>, Project>(() => config.read.project(row)),\n\t\t\t\t).pipe(Effect.map((rows) => ({ ...page, page: rows }))),\n\t\t\t),\n\t\t)\n\tconst queryOperations = Object.assign(\n\t\t{},\n\t\tnamed(\n\t\t\tgetName,\n\t\t\tdefine.query<typeof idInput, typeof getResult, ReturnType<typeof get>, GetGuard>({\n\t\t\t\tinput: idInput,\n\t\t\t\tresult: getResult,\n\t\t\t\tpermission: config.policy?.permissions?.get,\n\t\t\t\tguard: config.guards?.get,\n\t\t\t\thandler: get,\n\t\t\t}),\n\t\t),\n\t\tnamed(\n\t\t\tlistName,\n\t\t\tdefine.query<typeof pagination, typeof pageResult, ReturnType<typeof list>, ListGuard>({\n\t\t\t\tinput: pagination,\n\t\t\t\tresult: pageResult,\n\t\t\t\tpermission: config.policy?.permissions?.list,\n\t\t\t\tguard: config.guards?.list,\n\t\t\t\thandler: list,\n\t\t\t}),\n\t\t),\n\t)\n\tconst queryConfiguration = {\n\t\tcontext: config.context,\n\t\tdefaults: { guard: config.policy?.guard },\n\t\t// SAFETY: the two query helpers checked these exact callbacks and schemas before literal-key assembly.\n\t\toperations: () => queryOperations,\n\t}\n\t// SAFETY: checked query helpers produced the registry above; explicit instantiation keeps mapped operation keys paired.\n\tconst queries: CrudExecutor<\n\t\tHost,\n\t\ttypeof queryOperations,\n\t\tContextReturned | CallbackReturned<PermissionPolicy<Dependencies>>,\n\t\tPolicy\n\t> = config.foundation.Query<Host, ContextReturned, typeof queryOperations, Policy>(\n\t\tqueryConfiguration as Parameters<\n\t\t\ttypeof config.foundation.Query<Host, ContextReturned, typeof queryOperations, Policy>\n\t\t>[0],\n\t)\n\treturn { commands, queries, operations, queryOperations }\n}\n\ntype NamedOperation<Name extends string, Definition> = { [Key in Name]: Definition }\nfunction named<const Name extends string, Definition>(name: Name, definition: Definition) {\n\t// SAFETY: the single computed property pairs this literal operation name with its checked definition.\n\treturn { [name]: definition } as NamedOperation<Name, Definition>\n}\ntype ProtectedOverrides<Configuration> = 'overrides' extends keyof Configuration\n\t? {\n\t\t\toverrides?: {\n\t\t\t\t[\n\t\t\t\t\tKey in Exclude<\n\t\t\t\t\t\tkeyof NonNullable<Configuration['overrides']>,\n\t\t\t\t\t\t'create' | 'update' | 'archive'\n\t\t\t\t\t>\n\t\t\t\t]: never\n\t\t\t}\n\t\t}\n\t: unknown\ntype RequiredOverride<Configuration, Key extends string> = Configuration extends {\n\toverrides: { [K in Key]: Function }\n}\n\t? true\n\t: false\ntype Chosen<Override, Default, Required extends boolean> = Required extends true\n\t? Override\n\t: [Override] extends [never]\n\t\t? Default\n\t\t: Override | Default\nfunction chooseHandler<Input, Context, Override, Default, Required extends boolean>(\n\toverride: ((input: Input, context: Context) => Override) | undefined,\n\tfallback: (input: Input, context: Context) => Default,\n): (input: Input, context: Context) => Chosen<Override, Default, Required> {\n\t// SAFETY: never is the absent override default; a declared override replaces only this handler.\n\treturn (override ?? fallback) as (\n\t\tinput: Input,\n\t\tcontext: Context,\n\t) => Chosen<Override, Default, Required>\n}\nfunction normalizeAs<Value, Returned extends Supported<Value>>(invoke: () => Returned) {\n\t// SAFETY: Returned is constrained to this success contract; normalization retains its exact error/service channels.\n\treturn normalizeEffect(invoke) as Effect.Effect<\n\t\tValue,\n\t\tCallbackError<Returned>,\n\t\tCallbackRequirements<Returned>\n\t>\n}\nfunction crudSchema<Schema extends z.ZodType>(\n\tschema: Schema,\n): StandardSchema<z.input<Schema>, z.output<Schema>> & LegacyParser<z.output<Schema>> {\n\treturn {\n\t\t'~standard': schema['~standard'],\n\t\tparse: (value) => schema.parse(value),\n\t\tparseAsync: (value) => schema.parseAsync(value),\n\t}\n}\n\nfunction archivePatch<Table extends EffectCrudTable>(archivedAt: number): Partial<Storage<Table>> {\n\t// SAFETY: all kit table boundaries include the server-owned archivedAt timestamp.\n\treturn Object.fromEntries([['archivedAt', archivedAt]]) as Partial<Storage<Table>>\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { DecodedFailure, ErrorContract, ErrorDefinitions } from "../contracts/er
|
|
|
2
2
|
import { Cause } from "effect";
|
|
3
3
|
//#region src/modules/effect/errors.d.ts
|
|
4
4
|
/** Inspect the whole Cause; cleanup defects and other composite reasons cannot become expected data. */
|
|
5
|
-
declare function projectErrorCause<Definitions extends ErrorDefinitions>(contract: Pick<ErrorContract<Definitions>, 'project'>, cause: Cause.Cause<unknown>): DecodedFailure<Definitions>;
|
|
5
|
+
export declare function projectErrorCause<Definitions extends ErrorDefinitions>(contract: Pick<ErrorContract<Definitions>, 'project'>, cause: Cause.Cause<unknown>): DecodedFailure<Definitions>;
|
|
6
6
|
//#endregion
|
|
7
|
-
export { projectErrorCause };
|
|
8
7
|
//# sourceMappingURL=errors.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/modules/effect/errors.ts"],"sourcesContent":["import { Cause } from 'effect'\nimport type { DecodedFailure, ErrorContract, ErrorDefinitions } from '../contracts/errors'\n\n/** Inspect the whole Cause; cleanup defects and other composite reasons cannot become expected data. */\nexport function projectErrorCause<Definitions extends ErrorDefinitions>(\n\tcontract: Pick<ErrorContract<Definitions>, 'project'>,\n\tcause: Cause.Cause<unknown>,\n): DecodedFailure<Definitions> {\n\tif (cause.reasons.length !== 1) return { _tag: 'UnknownFailure', version: 1 }\n\tconst reason = cause.reasons[0]\n\treturn Cause.isFailReason(reason)\n\t\t? contract.project(reason.error)\n\t\t: { _tag: 'UnknownFailure', version: 1 }\n}\n"],"mappings":"+BAIA,
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":["projectErrorCause","cause","reason","Cause","contract"],"sources":["../../../src/modules/effect/errors.ts"],"sourcesContent":["import { Cause } from 'effect'\nimport type { DecodedFailure, ErrorContract, ErrorDefinitions } from '../contracts/errors'\n\n/** Inspect the whole Cause; cleanup defects and other composite reasons cannot become expected data. */\nexport function projectErrorCause<Definitions extends ErrorDefinitions>(\n\tcontract: Pick<ErrorContract<Definitions>, 'project'>,\n\tcause: Cause.Cause<unknown>,\n): DecodedFailure<Definitions> {\n\tif (cause.reasons.length !== 1) return { _tag: 'UnknownFailure', version: 1 }\n\tconst reason = cause.reasons[0]\n\treturn Cause.isFailReason(reason)\n\t\t? contract.project(reason.error)\n\t\t: { _tag: 'UnknownFailure', version: 1 }\n}\n"],"mappings":"+BAIA,SAAgBA,EACf,EACA,EAC8B,CAC9B,GAAIC,EAAM,QAAQ,SAAW,EAAG,MAAO,CAAE,KAAM,iBAAkB,QAAS,CAAE,EAC5E,IAAMC,EAASD,EAAM,QAAQ,GAC7B,OAAOE,EAAM,aAAaD,CAAM,EAC7BE,EAAS,QAAQF,EAAO,KAAK,EAC7B,CAAE,KAAM,iBAAkB,QAAS,CAAE,CACzC"}
|
|
@@ -3,10 +3,10 @@ import { EffectCommandDependencies, bindEffectCommand } from "./command.mjs";
|
|
|
3
3
|
import { bindEffectQuery } from "./query.mjs";
|
|
4
4
|
//#region src/modules/effect/foundation.d.ts
|
|
5
5
|
/** Shared host capabilities are bound once; registry resolvers stay invocation-local. */
|
|
6
|
-
type EffectFoundationOptions = Omit<EffectCommandDependencies, 'observability'> & {
|
|
6
|
+
export type EffectFoundationOptions = Omit<EffectCommandDependencies, 'observability'> & {
|
|
7
7
|
observability: ObservabilityOptions;
|
|
8
8
|
};
|
|
9
|
-
type EffectFoundation<Options extends EffectFoundationOptions> = {
|
|
9
|
+
export type EffectFoundation<Options extends EffectFoundationOptions> = {
|
|
10
10
|
Command: ReturnType<typeof bindEffectCommand<Options & {
|
|
11
11
|
observability: Observability;
|
|
12
12
|
}>>;
|
|
@@ -15,7 +15,6 @@ type EffectFoundation<Options extends EffectFoundationOptions> = {
|
|
|
15
15
|
}>>;
|
|
16
16
|
observability: Observability;
|
|
17
17
|
};
|
|
18
|
-
declare function createEffectFoundation<const Options extends EffectFoundationOptions>(options: Options): EffectFoundation<Options>;
|
|
18
|
+
export declare function createEffectFoundation<const Options extends EffectFoundationOptions>(options: Options): EffectFoundation<Options>;
|
|
19
19
|
//#endregion
|
|
20
|
-
export { EffectFoundation, EffectFoundationOptions, createEffectFoundation };
|
|
21
20
|
//# sourceMappingURL=foundation.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundation.mjs","names":[],"sources":["../../../src/modules/effect/foundation.ts"],"sourcesContent":["// oxlint-disable-next-line cvx/component-boundaries -- SAFETY: Internal optional adapter shares the Effect-free Foundation lifecycle and types without entering the Convex component deployment graph.\nimport {\n\tObservability,\n\ttype ObservabilityOptions,\n} from '../../components/foundation/modules/observability/observability'\nimport { bindEffectCommand, type EffectCommandDependencies } from './command'\nimport { bindEffectQuery } from './query'\n\n/** Shared host capabilities are bound once; registry resolvers stay invocation-local. */\nexport type EffectFoundationOptions = Omit<EffectCommandDependencies, 'observability'> & {\n\tobservability: ObservabilityOptions\n}\nexport type EffectFoundation<Options extends EffectFoundationOptions> = {\n\tCommand: ReturnType<typeof bindEffectCommand<Options & { observability: Observability }>>\n\tQuery: ReturnType<typeof bindEffectQuery<Options & { observability: Observability }>>\n\tobservability: Observability\n}\n\nexport function createEffectFoundation<const Options extends EffectFoundationOptions>(\n\toptions: Options,\n): EffectFoundation<Options> {\n\tconst observability = new Observability(options.observability)\n\tconst dependencies = { ...options, observability }\n\treturn {\n\t\tCommand: bindEffectCommand(dependencies),\n\t\tQuery: bindEffectQuery(dependencies),\n\t\tobservability,\n\t}\n}\n"],"mappings":"oMAkBA,
|
|
1
|
+
{"version":3,"file":"foundation.mjs","names":["createEffectFoundation","observability","Observability","options","dependencies","bindEffectCommand","bindEffectQuery"],"sources":["../../../src/modules/effect/foundation.ts"],"sourcesContent":["// oxlint-disable-next-line cvx/component-boundaries -- SAFETY: Internal optional adapter shares the Effect-free Foundation lifecycle and types without entering the Convex component deployment graph.\nimport {\n\tObservability,\n\ttype ObservabilityOptions,\n} from '../../components/foundation/modules/observability/observability'\nimport { bindEffectCommand, type EffectCommandDependencies } from './command'\nimport { bindEffectQuery } from './query'\n\n/** Shared host capabilities are bound once; registry resolvers stay invocation-local. */\nexport type EffectFoundationOptions = Omit<EffectCommandDependencies, 'observability'> & {\n\tobservability: ObservabilityOptions\n}\nexport type EffectFoundation<Options extends EffectFoundationOptions> = {\n\tCommand: ReturnType<typeof bindEffectCommand<Options & { observability: Observability }>>\n\tQuery: ReturnType<typeof bindEffectQuery<Options & { observability: Observability }>>\n\tobservability: Observability\n}\n\nexport function createEffectFoundation<const Options extends EffectFoundationOptions>(\n\toptions: Options,\n): EffectFoundation<Options> {\n\tconst observability = new Observability(options.observability)\n\tconst dependencies = { ...options, observability }\n\treturn {\n\t\tCommand: bindEffectCommand(dependencies),\n\t\tQuery: bindEffectQuery(dependencies),\n\t\tobservability,\n\t}\n}\n"],"mappings":"oMAkBA,SAAgBA,EACf,EAC4B,CAC5B,IAAMC,EAAgB,IAAIC,EAAcC,EAAQ,aAAa,EACvDC,EAAe,CAAE,GAAGD,EAAS,eAAc,EACjD,MAAO,CACN,QAASE,EAAkBD,CAAY,EACvC,MAAOE,EAAgBF,CAAY,EACnC,eACD,CACD"}
|
|
@@ -4,7 +4,7 @@ import { IdempotencyError, IdempotencyIdentity, IdempotencyInvocation, Idempoten
|
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
//#region src/modules/effect/idempotency.d.ts
|
|
6
6
|
type Supported<A> = A | PromiseLike<A> | Effect.Effect<A, unknown, unknown>;
|
|
7
|
-
type EffectIdempotencyPreparation<Result, Error = never, Requirements = never> = {
|
|
7
|
+
export type EffectIdempotencyPreparation<Result, Error = never, Requirements = never> = {
|
|
8
8
|
readonly kind: 'replay';
|
|
9
9
|
readonly result: unknown;
|
|
10
10
|
} | {
|
|
@@ -12,7 +12,7 @@ type EffectIdempotencyPreparation<Result, Error = never, Requirements = never> =
|
|
|
12
12
|
readonly complete: (result: Result) => Effect.Effect<void, Error, Requirements>;
|
|
13
13
|
};
|
|
14
14
|
/** Callback throws/rejections remain defects; only explicit Effect failures contribute typed channels. */
|
|
15
|
-
declare function effectTransactionalIdempotency<const Replay extends ContractSchema, Authorize extends Supported<void>, Lookup extends Supported<readonly unknown[]>, Fingerprint extends Supported<string>, Claim, Encode extends Supported<ContractInput<Replay>>, Complete extends Supported<void>>(configuration: {
|
|
15
|
+
export declare function effectTransactionalIdempotency<const Replay extends ContractSchema, Authorize extends Supported<void>, Lookup extends Supported<readonly unknown[]>, Fingerprint extends Supported<string>, Claim, Encode extends Supported<ContractInput<Replay>>, Complete extends Supported<void>>(configuration: {
|
|
16
16
|
readonly final: {
|
|
17
17
|
readonly replayResult: Replay;
|
|
18
18
|
readonly encode: (result: ContractOutput<Replay>) => Encode;
|
|
@@ -27,5 +27,4 @@ declare function effectTransactionalIdempotency<const Replay extends ContractSch
|
|
|
27
27
|
prepare(invocation: IdempotencyInvocation): Effect.Effect<EffectIdempotencyPreparation<ContractOutput<Replay>, CallbackError<Complete | Encode>, CallbackRequirements<Complete | Encode>>, IdempotencyError | CallbackError<Authorize | Claim | Fingerprint | Lookup>, CallbackRequirements<Authorize | Claim | Fingerprint | Lookup>>;
|
|
28
28
|
};
|
|
29
29
|
//#endregion
|
|
30
|
-
export { EffectIdempotencyPreparation, effectTransactionalIdempotency };
|
|
31
30
|
//# sourceMappingURL=idempotency.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idempotency.mjs","names":[],"sources":["../../../src/modules/effect/idempotency.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport type { ContractInput, ContractOutput, ContractSchema } from '../contracts/contract'\nimport {\n\tIdempotencyError,\n\tidempotencyCanonicalInput,\n\tidempotencyFingerprint,\n\tretainedIdempotencyReceipt,\n\ttype IdempotencyIdentity,\n\ttype IdempotencyInvocation,\n\ttype IdempotencyReceipt,\n} from '../contracts/idempotency'\nimport type { CallbackError, CallbackRequirements, EffectValue } from './operation'\nimport { normalizeEffect } from './normalize'\n\ntype Supported<A> = A | PromiseLike<A> | Effect.Effect<A, unknown, unknown>\nexport type EffectIdempotencyPreparation<Result, Error = never, Requirements = never> =\n\t| { readonly kind: 'replay'; readonly result: unknown }\n\t| {\n\t\t\treadonly kind: 'execute'\n\t\t\treadonly complete: (result: Result) => Effect.Effect<void, Error, Requirements>\n\t }\n\n/** Callback throws/rejections remain defects; only explicit Effect failures contribute typed channels. */\nexport function effectTransactionalIdempotency<\n\tconst Replay extends ContractSchema,\n\tAuthorize extends Supported<void>,\n\tLookup extends Supported<readonly unknown[]>,\n\tFingerprint extends Supported<string>,\n\tClaim,\n\tEncode extends Supported<ContractInput<Replay>>,\n\tComplete extends Supported<void>,\n>(configuration: {\n\treadonly final: {\n\t\treadonly replayResult: Replay\n\t\treadonly encode: (result: ContractOutput<Replay>) => Encode\n\t}\n\treadonly authorize: (invocation: IdempotencyInvocation) => Authorize\n\treadonly lookup: (identity: IdempotencyIdentity) => Lookup\n\treadonly fingerprint: (canonicalBytes: string) => Fingerprint\n\treadonly claim: (identity: IdempotencyIdentity, receipt: IdempotencyReceipt) => Claim\n\treadonly complete: (claim: EffectValue<Claim>, receipt: IdempotencyReceipt) => Complete\n}) {\n\ttype PrepareError = IdempotencyError | CallbackError<Authorize | Lookup | Fingerprint | Claim>\n\ttype PrepareRequirements = CallbackRequirements<Authorize | Lookup | Fingerprint | Claim>\n\ttype CompleteError = CallbackError<Encode | Complete>\n\ttype CompleteRequirements = CallbackRequirements<Encode | Complete>\n\ttype Preparation = EffectIdempotencyPreparation<\n\t\tContractOutput<Replay>,\n\t\tCompleteError,\n\t\tCompleteRequirements\n\t>\n\treturn {\n\t\treplayResult: configuration.final.replayResult,\n\t\tprepare(\n\t\t\tinvocation: IdempotencyInvocation,\n\t\t): Effect.Effect<Preparation, PrepareError, PrepareRequirements> {\n\t\t\treturn Effect.gen(function* () {\n\t\t\t\tconst canonical = yield* protocol(() => idempotencyCanonicalInput(invocation))\n\t\t\t\tyield* normalizeEffect(() => configuration.authorize(invocation))\n\t\t\t\tconst rows = yield* normalizeEffect(() => configuration.lookup(invocation.identity))\n\t\t\t\t// SAFETY: Lookup's supported success constraint is the retained-row boundary.\n\t\t\t\tconst retained = yield* protocol(() =>\n\t\t\t\t\tretainedIdempotencyReceipt(rows as readonly unknown[], invocation),\n\t\t\t\t)\n\t\t\t\tconst proposed = yield* normalizeEffect(() => configuration.fingerprint(canonical))\n\t\t\t\t// SAFETY: Fingerprint's supported success constraint is string.\n\t\t\t\tconst fingerprint = yield* protocol(() =>\n\t\t\t\t\tidempotencyFingerprint(proposed as string, retained),\n\t\t\t\t)\n\t\t\t\tif (retained) return { kind: 'replay' as const, result: retained.result }\n\t\t\t\tconst claim = yield* normalizeEffect(() =>\n\t\t\t\t\tconfiguration.claim(invocation.identity, {\n\t\t\t\t\t\tstate: 'pending',\n\t\t\t\t\t\tversions: invocation.versions,\n\t\t\t\t\t\tfingerprint,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\treturn {\n\t\t\t\t\tkind: 'execute' as const,\n\t\t\t\t\tcomplete(\n\t\t\t\t\t\tresult: ContractOutput<Replay>,\n\t\t\t\t\t): Effect.Effect<void, CompleteError, CompleteRequirements> {\n\t\t\t\t\t\treturn normalizeEffect(() => configuration.final.encode(result)).pipe(\n\t\t\t\t\t\t\tEffect.flatMap((wire) =>\n\t\t\t\t\t\t\t\tnormalizeEffect(() =>\n\t\t\t\t\t\t\t\t\tconfiguration.complete(claim, {\n\t\t\t\t\t\t\t\t\t\tstate: 'completed',\n\t\t\t\t\t\t\t\t\t\tversions: invocation.versions,\n\t\t\t\t\t\t\t\t\t\tfingerprint,\n\t\t\t\t\t\t\t\t\t\tresult: wire,\n\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\t\tEffect.asVoid,\n\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}\nfunction protocol<A>(evaluate: () => A): Effect.Effect<A, IdempotencyError> {\n\treturn Effect.try({\n\t\ttry: evaluate,\n\t\tcatch: (error) => {\n\t\t\t// These pure protocol checks throw only IdempotencyError; unexpected failures remain defects.\n\t\t\tif (error instanceof IdempotencyError) return error\n\t\t\tthrow error\n\t\t},\n\t})\n}\n"],"mappings":"6OAuBA,
|
|
1
|
+
{"version":3,"file":"idempotency.mjs","names":["effectTransactionalIdempotency","configuration","Effect","canonical","protocol","idempotencyCanonicalInput","invocation","normalizeEffect","rows","retained","retainedIdempotencyReceipt","proposed","fingerprint","idempotencyFingerprint","claim","result","wire","evaluate","error","IdempotencyError"],"sources":["../../../src/modules/effect/idempotency.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport type { ContractInput, ContractOutput, ContractSchema } from '../contracts/contract'\nimport {\n\tIdempotencyError,\n\tidempotencyCanonicalInput,\n\tidempotencyFingerprint,\n\tretainedIdempotencyReceipt,\n\ttype IdempotencyIdentity,\n\ttype IdempotencyInvocation,\n\ttype IdempotencyReceipt,\n} from '../contracts/idempotency'\nimport type { CallbackError, CallbackRequirements, EffectValue } from './operation'\nimport { normalizeEffect } from './normalize'\n\ntype Supported<A> = A | PromiseLike<A> | Effect.Effect<A, unknown, unknown>\nexport type EffectIdempotencyPreparation<Result, Error = never, Requirements = never> =\n\t| { readonly kind: 'replay'; readonly result: unknown }\n\t| {\n\t\t\treadonly kind: 'execute'\n\t\t\treadonly complete: (result: Result) => Effect.Effect<void, Error, Requirements>\n\t }\n\n/** Callback throws/rejections remain defects; only explicit Effect failures contribute typed channels. */\nexport function effectTransactionalIdempotency<\n\tconst Replay extends ContractSchema,\n\tAuthorize extends Supported<void>,\n\tLookup extends Supported<readonly unknown[]>,\n\tFingerprint extends Supported<string>,\n\tClaim,\n\tEncode extends Supported<ContractInput<Replay>>,\n\tComplete extends Supported<void>,\n>(configuration: {\n\treadonly final: {\n\t\treadonly replayResult: Replay\n\t\treadonly encode: (result: ContractOutput<Replay>) => Encode\n\t}\n\treadonly authorize: (invocation: IdempotencyInvocation) => Authorize\n\treadonly lookup: (identity: IdempotencyIdentity) => Lookup\n\treadonly fingerprint: (canonicalBytes: string) => Fingerprint\n\treadonly claim: (identity: IdempotencyIdentity, receipt: IdempotencyReceipt) => Claim\n\treadonly complete: (claim: EffectValue<Claim>, receipt: IdempotencyReceipt) => Complete\n}) {\n\ttype PrepareError = IdempotencyError | CallbackError<Authorize | Lookup | Fingerprint | Claim>\n\ttype PrepareRequirements = CallbackRequirements<Authorize | Lookup | Fingerprint | Claim>\n\ttype CompleteError = CallbackError<Encode | Complete>\n\ttype CompleteRequirements = CallbackRequirements<Encode | Complete>\n\ttype Preparation = EffectIdempotencyPreparation<\n\t\tContractOutput<Replay>,\n\t\tCompleteError,\n\t\tCompleteRequirements\n\t>\n\treturn {\n\t\treplayResult: configuration.final.replayResult,\n\t\tprepare(\n\t\t\tinvocation: IdempotencyInvocation,\n\t\t): Effect.Effect<Preparation, PrepareError, PrepareRequirements> {\n\t\t\treturn Effect.gen(function* () {\n\t\t\t\tconst canonical = yield* protocol(() => idempotencyCanonicalInput(invocation))\n\t\t\t\tyield* normalizeEffect(() => configuration.authorize(invocation))\n\t\t\t\tconst rows = yield* normalizeEffect(() => configuration.lookup(invocation.identity))\n\t\t\t\t// SAFETY: Lookup's supported success constraint is the retained-row boundary.\n\t\t\t\tconst retained = yield* protocol(() =>\n\t\t\t\t\tretainedIdempotencyReceipt(rows as readonly unknown[], invocation),\n\t\t\t\t)\n\t\t\t\tconst proposed = yield* normalizeEffect(() => configuration.fingerprint(canonical))\n\t\t\t\t// SAFETY: Fingerprint's supported success constraint is string.\n\t\t\t\tconst fingerprint = yield* protocol(() =>\n\t\t\t\t\tidempotencyFingerprint(proposed as string, retained),\n\t\t\t\t)\n\t\t\t\tif (retained) return { kind: 'replay' as const, result: retained.result }\n\t\t\t\tconst claim = yield* normalizeEffect(() =>\n\t\t\t\t\tconfiguration.claim(invocation.identity, {\n\t\t\t\t\t\tstate: 'pending',\n\t\t\t\t\t\tversions: invocation.versions,\n\t\t\t\t\t\tfingerprint,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\treturn {\n\t\t\t\t\tkind: 'execute' as const,\n\t\t\t\t\tcomplete(\n\t\t\t\t\t\tresult: ContractOutput<Replay>,\n\t\t\t\t\t): Effect.Effect<void, CompleteError, CompleteRequirements> {\n\t\t\t\t\t\treturn normalizeEffect(() => configuration.final.encode(result)).pipe(\n\t\t\t\t\t\t\tEffect.flatMap((wire) =>\n\t\t\t\t\t\t\t\tnormalizeEffect(() =>\n\t\t\t\t\t\t\t\t\tconfiguration.complete(claim, {\n\t\t\t\t\t\t\t\t\t\tstate: 'completed',\n\t\t\t\t\t\t\t\t\t\tversions: invocation.versions,\n\t\t\t\t\t\t\t\t\t\tfingerprint,\n\t\t\t\t\t\t\t\t\t\tresult: wire,\n\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\t\tEffect.asVoid,\n\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}\nfunction protocol<A>(evaluate: () => A): Effect.Effect<A, IdempotencyError> {\n\treturn Effect.try({\n\t\ttry: evaluate,\n\t\tcatch: (error) => {\n\t\t\t// These pure protocol checks throw only IdempotencyError; unexpected failures remain defects.\n\t\t\tif (error instanceof IdempotencyError) return error\n\t\t\tthrow error\n\t\t},\n\t})\n}\n"],"mappings":"6OAuBA,SAAgBA,EAQd,EAUC,CAUF,MAAO,CACN,aAAcC,EAAc,MAAM,aAClC,QACC,EACgE,CAChE,OAAOC,EAAO,IAAI,WAAa,CAC9B,IAAMC,EAAY,MAAOC,MAAeC,EAA0BC,CAAU,CAAC,EAC7E,MAAOC,MAAsBN,EAAc,UAAUK,CAAU,CAAC,EAChE,IAAME,EAAO,MAAOD,MAAsBN,EAAc,OAAOK,EAAW,QAAQ,CAAC,EAE7EG,EAAW,MAAOL,MACvBM,EAA2BF,EAA4BF,CAAU,CAClE,EACMK,EAAW,MAAOJ,MAAsBN,EAAc,YAAYE,CAAS,CAAC,EAE5ES,EAAc,MAAOR,MAC1BS,EAAuBF,EAAoBF,CAAQ,CACpD,EACA,GAAIA,EAAU,MAAO,CAAE,KAAM,SAAmB,OAAQA,EAAS,MAAO,EACxE,IAAMK,EAAQ,MAAOP,MACpBN,EAAc,MAAMK,EAAW,SAAU,CACxC,MAAO,UACP,SAAUA,EAAW,SACrB,aACD,CAAC,CACF,EACA,MAAO,CACN,KAAM,UACN,SACC,EAC2D,CAC3D,OAAOC,MAAsBN,EAAc,MAAM,OAAOc,CAAM,CAAC,CAAC,CAAC,KAChEb,EAAO,QAAS,GACfK,MACCN,EAAc,SAASa,EAAO,CAC7B,MAAO,YACP,SAAUR,EAAW,SACrB,cACA,OAAQU,CACT,CAAC,CACF,CACD,EACAd,EAAO,MACR,CACD,CACD,CACD,CAAC,CACF,CACD,CACD,CACA,SAASE,EAAY,EAAuD,CAC3E,OAAOF,EAAO,IAAI,CACjB,IAAKe,EACL,MAAQ,GAAU,CAEjB,GAAIC,aAAiBC,EAAkB,OAAOD,EAC9C,MAAMA,CACP,CACD,CAAC,CACF"}
|
|
@@ -2,9 +2,8 @@ import { CallbackError, CallbackRequirements, EffectValue } from "./operation.mj
|
|
|
2
2
|
import { Cause, Effect } from "effect";
|
|
3
3
|
//#region src/modules/effect/normalize.d.ts
|
|
4
4
|
/** Invoke ordinary and Effect callbacks lazily, preserving ordinary failures as defects. */
|
|
5
|
-
declare function normalizeEffect<Returned>(invoke: () => Returned): Effect.Effect<EffectValue<Returned>, CallbackError<Returned>, CallbackRequirements<Returned>>;
|
|
5
|
+
export declare function normalizeEffect<Returned>(invoke: () => Returned): Effect.Effect<EffectValue<Returned>, CallbackError<Returned>, CallbackRequirements<Returned>>;
|
|
6
6
|
/** Classify singular failures by their value; retain structured interruption/composite causes. */
|
|
7
|
-
declare function observationFailure<Error>(cause: Cause.Cause<Error>): unknown;
|
|
7
|
+
export declare function observationFailure<Error>(cause: Cause.Cause<Error>): unknown;
|
|
8
8
|
//#endregion
|
|
9
|
-
export { normalizeEffect, observationFailure };
|
|
10
9
|
//# sourceMappingURL=normalize.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.mjs","names":[],"sources":["../../../src/modules/effect/normalize.ts"],"sourcesContent":["import { Cause, Effect } from 'effect'\nimport type { CallbackError, CallbackRequirements, EffectValue } from './operation'\n\n/** Invoke ordinary and Effect callbacks lazily, preserving ordinary failures as defects. */\nexport function normalizeEffect<Returned>(\n\tinvoke: () => Returned,\n): Effect.Effect<EffectValue<Returned>, CallbackError<Returned>, CallbackRequirements<Returned>> {\n\t// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Internal callback normalization boundary; the selected schema validates the eventual value.\n\tfunction resolve(value: unknown): Effect.Effect<unknown, unknown, unknown> {\n\t\tif (Effect.isEffect(value)) return Effect.flatMap(value, resolve)\n\t\treturn Effect.promise(() => Promise.resolve(value)).pipe(\n\t\t\tEffect.flatMap((resolved) =>\n\t\t\t\tEffect.isEffect(resolved) ? resolve(resolved) : Effect.succeed(resolved),\n\t\t\t),\n\t\t)\n\t}\n\tconst normalized = Effect.suspend(() => resolve(invoke()))\n\t// SAFETY: the predicate retains Effect channels; ordinary values and rejections\n\t// contribute no typed errors/services. The invocation's concrete return owns A/E/R.\n\treturn normalized as Effect.Effect<\n\t\tEffectValue<Returned>,\n\t\tCallbackError<Returned>,\n\t\tCallbackRequirements<Returned>\n\t>\n}\n\n/** Classify singular failures by their value; retain structured interruption/composite causes. */\nexport function observationFailure<Error>(cause: Cause.Cause<Error>) {\n\tconst reason = cause.reasons.length === 1 ? cause.reasons[0] : undefined\n\tif (reason && Cause.isFailReason(reason)) return reason.error\n\tif (reason && Cause.isDieReason(reason)) return reason.defect\n\treturn cause\n}\n"],"mappings":"2CAIA,
|
|
1
|
+
{"version":3,"file":"normalize.mjs","names":["normalizeEffect","resolve","Effect","value","resolved","invoke","observationFailure","reason","cause","Cause"],"sources":["../../../src/modules/effect/normalize.ts"],"sourcesContent":["import { Cause, Effect } from 'effect'\nimport type { CallbackError, CallbackRequirements, EffectValue } from './operation'\n\n/** Invoke ordinary and Effect callbacks lazily, preserving ordinary failures as defects. */\nexport function normalizeEffect<Returned>(\n\tinvoke: () => Returned,\n): Effect.Effect<EffectValue<Returned>, CallbackError<Returned>, CallbackRequirements<Returned>> {\n\t// oxlint-disable-next-line anti-slop/no-unknown-parameters -- Internal callback normalization boundary; the selected schema validates the eventual value.\n\tfunction resolve(value: unknown): Effect.Effect<unknown, unknown, unknown> {\n\t\tif (Effect.isEffect(value)) return Effect.flatMap(value, resolve)\n\t\treturn Effect.promise(() => Promise.resolve(value)).pipe(\n\t\t\tEffect.flatMap((resolved) =>\n\t\t\t\tEffect.isEffect(resolved) ? resolve(resolved) : Effect.succeed(resolved),\n\t\t\t),\n\t\t)\n\t}\n\tconst normalized = Effect.suspend(() => resolve(invoke()))\n\t// SAFETY: the predicate retains Effect channels; ordinary values and rejections\n\t// contribute no typed errors/services. The invocation's concrete return owns A/E/R.\n\treturn normalized as Effect.Effect<\n\t\tEffectValue<Returned>,\n\t\tCallbackError<Returned>,\n\t\tCallbackRequirements<Returned>\n\t>\n}\n\n/** Classify singular failures by their value; retain structured interruption/composite causes. */\nexport function observationFailure<Error>(cause: Cause.Cause<Error>) {\n\tconst reason = cause.reasons.length === 1 ? cause.reasons[0] : undefined\n\tif (reason && Cause.isFailReason(reason)) return reason.error\n\tif (reason && Cause.isDieReason(reason)) return reason.defect\n\treturn cause\n}\n"],"mappings":"2CAIA,SAAgBA,EACf,EACgG,CAEhG,SAASC,EAAQ,EAA0D,CAE1E,OADIC,EAAO,SAASC,CAAK,EAAUD,EAAO,QAAQC,EAAOF,CAAO,EACzDC,EAAO,YAAc,QAAQ,QAAQC,CAAK,CAAC,CAAC,CAAC,KACnDD,EAAO,QAAS,GACfA,EAAO,SAASE,CAAQ,EAAIH,EAAQG,CAAQ,EAAIF,EAAO,QAAQE,CAAQ,CACxE,CACD,CACD,CAIA,OAHmBF,EAAO,YAAcD,EAAQI,EAAO,CAAC,CAGxC,CAKjB,CAGA,SAAgBC,EAA0B,EAA2B,CACpE,IAAMC,EAASC,EAAM,QAAQ,SAAW,EAAIA,EAAM,QAAQ,GAAK,IAAA,GAG/D,OAFID,GAAUE,EAAM,aAAaF,CAAM,EAAUA,EAAO,MACpDA,GAAUE,EAAM,YAAYF,CAAM,EAAUA,EAAO,OAChDC,CACR"}
|
|
@@ -4,18 +4,18 @@ import { ContractDecoderError, ContractDecoderRequirements } from "./schema.mjs"
|
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
//#region src/modules/effect/operation.d.ts
|
|
6
6
|
/** Ordinary failures are defects; only an explicit Effect supplies a typed error. */
|
|
7
|
-
type CallbackError<Value> = Value extends ((...arguments_: never[]) => infer Returned) ? CallbackError<Returned> : Value extends Effect.Effect<infer Success, infer Error, unknown> ? Error | CallbackError<Success> : Value extends PromiseLike<infer Awaited> ? CallbackError<Awaited> : Value extends readonly (infer Item)[] ? CallbackError<Item> : Value extends {
|
|
7
|
+
export type CallbackError<Value> = Value extends ((...arguments_: never[]) => infer Returned) ? CallbackError<Returned> : Value extends Effect.Effect<infer Success, infer Error, unknown> ? Error | CallbackError<Success> : Value extends PromiseLike<infer Awaited> ? CallbackError<Awaited> : Value extends readonly (infer Item)[] ? CallbackError<Item> : Value extends {
|
|
8
8
|
kind: 'execute';
|
|
9
9
|
complete?: infer Complete;
|
|
10
10
|
} ? CallbackError<Complete> : never;
|
|
11
|
-
type CallbackRequirements<Value> = Value extends ((...arguments_: never[]) => infer Returned) ? CallbackRequirements<Returned> : Value extends Effect.Effect<infer Success, unknown, infer Requirements> ? Requirements | CallbackRequirements<Success> : Value extends PromiseLike<infer Awaited> ? CallbackRequirements<Awaited> : Value extends readonly (infer Item)[] ? CallbackRequirements<Item> : Value extends {
|
|
11
|
+
export type CallbackRequirements<Value> = Value extends ((...arguments_: never[]) => infer Returned) ? CallbackRequirements<Returned> : Value extends Effect.Effect<infer Success, unknown, infer Requirements> ? Requirements | CallbackRequirements<Success> : Value extends PromiseLike<infer Awaited> ? CallbackRequirements<Awaited> : Value extends readonly (infer Item)[] ? CallbackRequirements<Item> : Value extends {
|
|
12
12
|
kind: 'execute';
|
|
13
13
|
complete?: infer Complete;
|
|
14
14
|
} ? CallbackRequirements<Complete> : never;
|
|
15
|
-
type EffectValue<Value> = Value extends Effect.Effect<infer Success, unknown, unknown> ? EffectValue<Success> : Value extends PromiseLike<infer Awaited> ? EffectValue<Awaited> : Value;
|
|
15
|
+
export type EffectValue<Value> = Value extends Effect.Effect<infer Success, unknown, unknown> ? EffectValue<Success> : Value extends PromiseLike<infer Awaited> ? EffectValue<Awaited> : Value;
|
|
16
16
|
declare const checkedOperation: unique symbol;
|
|
17
17
|
/** Type-only evidence that the helper checked callbacks against the base context and schemas. */
|
|
18
|
-
type CheckedEffectOperation<Context> = {
|
|
18
|
+
export type CheckedEffectOperation<Context> = {
|
|
19
19
|
readonly [checkedOperation]: {
|
|
20
20
|
context: (context: Context) => void;
|
|
21
21
|
error: unknown;
|
|
@@ -32,30 +32,30 @@ type CheckedChannels<Context, Error, Requirements, Definition> = {
|
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
34
|
/** Named checked-definition boundary keeps the private evidence marker inside this module's declarations. */
|
|
35
|
-
type CheckedEffectDefinition<Context, Definition, Error = never, Requirements = never> = NoInfer<Omit<Definition, typeof checkedOperation>> & CheckedChannels<Context, Error, Requirements, Omit<Definition, typeof checkedOperation>>;
|
|
35
|
+
export type CheckedEffectDefinition<Context, Definition, Error = never, Requirements = never> = NoInfer<Omit<Definition, typeof checkedOperation>> & CheckedChannels<Context, Error, Requirements, Omit<Definition, typeof checkedOperation>>;
|
|
36
36
|
/** Reject stale helper evidence after callbacks or schemas are replaced. */
|
|
37
|
-
type ValidatedEffectOperations<Operations> = { [Key in keyof Operations]: Operations[Key] extends {
|
|
37
|
+
export type ValidatedEffectOperations<Operations> = { [Key in keyof Operations]: Operations[Key] extends {
|
|
38
38
|
readonly [checkedOperation]: {
|
|
39
39
|
definition: infer Definition;
|
|
40
40
|
};
|
|
41
41
|
} ? Operations[Key] extends Definition ? Operations[Key] : never : never; };
|
|
42
42
|
/** Only middleware whose next contract captured a default policy can discharge its channels. */
|
|
43
|
-
type UnwrappedDefaultError<Definition, Guard> = Definition extends {
|
|
43
|
+
export type UnwrappedDefaultError<Definition, Guard> = Definition extends {
|
|
44
44
|
middleware: Function;
|
|
45
45
|
} ? Definition extends CheckedChannels<never, infer Error, unknown, unknown> ? Exclude<CallbackError<Guard>, Error> : CallbackError<Guard> : CallbackError<Guard>;
|
|
46
|
-
type UnwrappedDefaultRequirements<Definition, Guard> = Definition extends {
|
|
46
|
+
export type UnwrappedDefaultRequirements<Definition, Guard> = Definition extends {
|
|
47
47
|
middleware: Function;
|
|
48
48
|
} ? Definition extends CheckedChannels<never, unknown, infer Requirements, unknown> ? Exclude<CallbackRequirements<Guard>, Requirements> : CallbackRequirements<Guard> : CallbackRequirements<Guard>;
|
|
49
|
-
type EffectOperationArgument<Definition extends {
|
|
49
|
+
export type EffectOperationArgument<Definition extends {
|
|
50
50
|
input: ContractSchema;
|
|
51
51
|
}> = ContractInput<Definition['input']>;
|
|
52
|
-
type EffectOperationInput<Definition extends {
|
|
52
|
+
export type EffectOperationInput<Definition extends {
|
|
53
53
|
input: ContractSchema;
|
|
54
54
|
}> = ContractOutput<Definition['input']>;
|
|
55
|
-
type EffectOperationHandlerResult<Definition extends {
|
|
55
|
+
export type EffectOperationHandlerResult<Definition extends {
|
|
56
56
|
result: ContractSchema;
|
|
57
57
|
}> = ContractInput<Definition['result']>;
|
|
58
|
-
type EffectOperationResult<Definition extends {
|
|
58
|
+
export type EffectOperationResult<Definition extends {
|
|
59
59
|
result: ContractSchema;
|
|
60
60
|
}> = ContractOutput<Definition['result']>;
|
|
61
61
|
type Hook<Definition, Key extends PropertyKey> = Key extends keyof Definition ? Definition[Key] : never;
|
|
@@ -63,17 +63,17 @@ type Returned<Callback> = Callback extends ((...arguments_: never[]) => infer Va
|
|
|
63
63
|
/** A conditional wrapper must retain the unwrapped channels for its absent branch. */
|
|
64
64
|
type CoreValue<Definition> = [Returned<Hook<Definition, 'middleware'>>] extends [never] ? Returned<Hook<Definition, 'handler'>> | Returned<Hook<Definition, 'guard'>> : undefined extends Hook<Definition, 'middleware'> ? Returned<Hook<Definition, 'handler'>> | Returned<Hook<Definition, 'guard'>> | Returned<Hook<Definition, 'middleware'>> : Returned<Hook<Definition, 'middleware'>>;
|
|
65
65
|
type OutsideHooks = 'prepare' | 'audit' | 'checkPermission' | 'writeAudit';
|
|
66
|
-
type EffectOperationError<Definition> = ContractDecoderError<Hook<Definition, 'input'>> | ContractDecoderError<Hook<Definition, 'result'>> | ContractDecoderError<Hook<Definition, 'replayResult'>> | CallbackError<CoreValue<Definition>> | CallbackError<Definition[Extract<keyof Definition, OutsideHooks>]>;
|
|
67
|
-
type EffectOperationRequirements<Definition> = ContractDecoderRequirements<Hook<Definition, 'input'>> | ContractDecoderRequirements<Hook<Definition, 'result'>> | ContractDecoderRequirements<Hook<Definition, 'replayResult'>> | CallbackRequirements<CoreValue<Definition>> | CallbackRequirements<Definition[Extract<keyof Definition, OutsideHooks>]>;
|
|
66
|
+
export type EffectOperationError<Definition> = ContractDecoderError<Hook<Definition, 'input'>> | ContractDecoderError<Hook<Definition, 'result'>> | ContractDecoderError<Hook<Definition, 'replayResult'>> | CallbackError<CoreValue<Definition>> | CallbackError<Definition[Extract<keyof Definition, OutsideHooks>]>;
|
|
67
|
+
export type EffectOperationRequirements<Definition> = ContractDecoderRequirements<Hook<Definition, 'input'>> | ContractDecoderRequirements<Hook<Definition, 'result'>> | ContractDecoderRequirements<Hook<Definition, 'replayResult'>> | CallbackRequirements<CoreValue<Definition>> | CallbackRequirements<Definition[Extract<keyof Definition, OutsideHooks>]>;
|
|
68
68
|
type Supported<Value, Error = unknown, Requirements = unknown> = Value | PromiseLike<Value> | Effect.Effect<Value, Error, Requirements>;
|
|
69
|
-
type EffectPreparation<Result, Error = never, Requirements = never> = {
|
|
69
|
+
export type EffectPreparation<Result, Error = never, Requirements = never> = {
|
|
70
70
|
kind: 'replay';
|
|
71
71
|
result: unknown;
|
|
72
72
|
} | {
|
|
73
73
|
kind: 'execute';
|
|
74
74
|
complete?: (result: Result) => Supported<void, Error, Requirements>;
|
|
75
75
|
};
|
|
76
|
-
type EffectMiddlewareInput<Context, Input, Result, Extension, Error = never, Requirements = never> = {
|
|
76
|
+
export type EffectMiddlewareInput<Context, Input, Result, Extension, Error = never, Requirements = never> = {
|
|
77
77
|
operation: string;
|
|
78
78
|
context: Context;
|
|
79
79
|
command: Input;
|
|
@@ -120,7 +120,7 @@ type OperationDefinition<Context, Input extends ContractSchema, Output extends C
|
|
|
120
120
|
* and returned Effect channels when middleware comes first. TypeScript processes
|
|
121
121
|
* context-sensitive object callbacks in declaration order.
|
|
122
122
|
*/
|
|
123
|
-
declare function effectOperationFactory<Context, Extension extends Record<string, unknown> = Record<never, never>, BaseError = never, BaseRequirements = never>(): {
|
|
123
|
+
export declare function effectOperationFactory<Context, Extension extends Record<string, unknown> = Record<never, never>, BaseError = never, BaseRequirements = never>(): {
|
|
124
124
|
operation: <const Input extends ContractSchema, const Output extends ContractSchema, Handler extends Supported<ContractInput<Output>>, Guard extends Supported<void> = never, Preparation extends Supported<EffectPreparation<ContractOutput<Output>, unknown, unknown>> = never, const Aggregates extends readonly string[] = readonly string[], AuditResult extends Supported<Audit<Aggregates> | null> = never, Middleware extends Supported<ContractInput<Output>> = never, const Metadata extends object = Record<never, never>, const Wire extends ContractSchema = ContractSchema, const Replay extends ContractSchema = never, const Definition extends object = object>(definition: Definition & OperationDefinition<Context, Input, Output, Extension, Aggregates, Handler, Guard, Preparation, AuditResult, Middleware, Metadata, BaseError, BaseRequirements, Wire, Replay>) => CheckedEffectDefinition<Context, typeof definition, BaseError, BaseRequirements>;
|
|
125
125
|
command: <const Input extends ContractSchema, const Output extends ContractSchema, Handler extends Supported<ContractInput<Output>>, Guard extends Supported<void> = never, Preparation extends Supported<EffectPreparation<ContractOutput<Output>, unknown, unknown>> = never, const Aggregates extends readonly string[] = readonly string[], AuditResult extends Supported<Audit<Aggregates> | null> = never, Middleware extends Supported<ContractInput<Output>> = never, const Metadata extends object = Record<never, never>, const Wire extends ContractSchema = ContractSchema, const Replay extends ContractSchema = never, const Definition extends object = object>(definition: Definition & OperationDefinition<Context, Input, Output, Extension, Aggregates, Handler, Guard, Preparation, AuditResult, Middleware, Metadata, BaseError, BaseRequirements, Wire, Replay> & {
|
|
126
126
|
classification: string;
|
|
@@ -137,5 +137,4 @@ declare function effectOperationFactory<Context, Extension extends Record<string
|
|
|
137
137
|
}) => CheckedEffectDefinition<Context, typeof definition, BaseError, BaseRequirements>;
|
|
138
138
|
};
|
|
139
139
|
//#endregion
|
|
140
|
-
export { CallbackError, CallbackRequirements, CheckedEffectDefinition, CheckedEffectOperation, EffectMiddlewareInput, EffectOperationArgument, EffectOperationError, EffectOperationHandlerResult, EffectOperationInput, EffectOperationRequirements, EffectOperationResult, EffectPreparation, EffectValue, UnwrappedDefaultError, UnwrappedDefaultRequirements, ValidatedEffectOperations, effectOperationFactory };
|
|
141
140
|
//# sourceMappingURL=operation.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operation.mjs","names":[],"sources":["../../../src/modules/effect/operation.ts"],"sourcesContent":["import type { Effect } from 'effect'\nimport type { ContractSchema, ContractInput, ContractOutput } from '../contracts/contract'\nimport type { ContractDecoderError, ContractDecoderRequirements } from './schema'\nimport type { AuditEntryInput } from '../../components/foundation/client'\n\n/** Ordinary failures are defects; only an explicit Effect supplies a typed error. */\nexport type CallbackError<Value> = Value extends (...arguments_: never[]) => infer Returned\n\t? CallbackError<Returned>\n\t: Value extends Effect.Effect<infer Success, infer Error, unknown>\n\t\t? Error | CallbackError<Success>\n\t\t: Value extends PromiseLike<infer Awaited>\n\t\t\t? CallbackError<Awaited>\n\t\t\t: Value extends readonly (infer Item)[]\n\t\t\t\t? CallbackError<Item>\n\t\t\t\t: Value extends { kind: 'execute'; complete?: infer Complete }\n\t\t\t\t\t? CallbackError<Complete>\n\t\t\t\t\t: never\n\nexport type CallbackRequirements<Value> = Value extends (...arguments_: never[]) => infer Returned\n\t? CallbackRequirements<Returned>\n\t: Value extends Effect.Effect<infer Success, unknown, infer Requirements>\n\t\t? Requirements | CallbackRequirements<Success>\n\t\t: Value extends PromiseLike<infer Awaited>\n\t\t\t? CallbackRequirements<Awaited>\n\t\t\t: Value extends readonly (infer Item)[]\n\t\t\t\t? CallbackRequirements<Item>\n\t\t\t\t: Value extends { kind: 'execute'; complete?: infer Complete }\n\t\t\t\t\t? CallbackRequirements<Complete>\n\t\t\t\t\t: never\n\nexport type EffectValue<Value> =\n\tValue extends Effect.Effect<infer Success, unknown, unknown>\n\t\t? EffectValue<Success>\n\t\t: Value extends PromiseLike<infer Awaited>\n\t\t\t? EffectValue<Awaited>\n\t\t\t: Value\n\ndeclare const checkedOperation: unique symbol\n/** Type-only evidence that the helper checked callbacks against the base context and schemas. */\nexport type CheckedEffectOperation<Context> = {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\terror: unknown\n\t\trequirements: unknown\n\t\tdefinition: unknown\n\t}\n}\ntype CheckedChannels<Context, Error, Requirements, Definition> = {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\terror: Error\n\t\trequirements: Requirements\n\t\tdefinition: Definition\n\t}\n}\n/** Named checked-definition boundary keeps the private evidence marker inside this module's declarations. */\nexport type CheckedEffectDefinition<\n\tContext,\n\tDefinition,\n\tError = never,\n\tRequirements = never,\n> = NoInfer<Omit<Definition, typeof checkedOperation>> &\n\tCheckedChannels<Context, Error, Requirements, Omit<Definition, typeof checkedOperation>>\n/** Reject stale helper evidence after callbacks or schemas are replaced. */\nexport type ValidatedEffectOperations<Operations> = {\n\t[Key in keyof Operations]: Operations[Key] extends {\n\t\treadonly [checkedOperation]: { definition: infer Definition }\n\t}\n\t\t? Operations[Key] extends Definition\n\t\t\t? Operations[Key]\n\t\t\t: never\n\t\t: never\n}\n/** Only middleware whose next contract captured a default policy can discharge its channels. */\nexport type UnwrappedDefaultError<Definition, Guard> = Definition extends { middleware: Function }\n\t? Definition extends CheckedChannels<never, infer Error, unknown, unknown>\n\t\t? Exclude<CallbackError<Guard>, Error>\n\t\t: CallbackError<Guard>\n\t: CallbackError<Guard>\nexport type UnwrappedDefaultRequirements<Definition, Guard> = Definition extends {\n\tmiddleware: Function\n}\n\t? Definition extends CheckedChannels<never, unknown, infer Requirements, unknown>\n\t\t? Exclude<CallbackRequirements<Guard>, Requirements>\n\t\t: CallbackRequirements<Guard>\n\t: CallbackRequirements<Guard>\nexport type EffectOperationArgument<Definition extends { input: ContractSchema }> = ContractInput<\n\tDefinition['input']\n>\nexport type EffectOperationInput<Definition extends { input: ContractSchema }> = ContractOutput<\n\tDefinition['input']\n>\nexport type EffectOperationHandlerResult<Definition extends { result: ContractSchema }> =\n\tContractInput<Definition['result']>\nexport type EffectOperationResult<Definition extends { result: ContractSchema }> = ContractOutput<\n\tDefinition['result']\n>\n\ntype Hook<Definition, Key extends PropertyKey> = Key extends keyof Definition\n\t? Definition[Key]\n\t: never\ntype Returned<Callback> = Callback extends (...arguments_: never[]) => infer Value ? Value : never\n/** A conditional wrapper must retain the unwrapped channels for its absent branch. */\ntype CoreValue<Definition> = [Returned<Hook<Definition, 'middleware'>>] extends [never]\n\t? Returned<Hook<Definition, 'handler'>> | Returned<Hook<Definition, 'guard'>>\n\t: undefined extends Hook<Definition, 'middleware'>\n\t\t?\n\t\t\t\t| Returned<Hook<Definition, 'handler'>>\n\t\t\t\t| Returned<Hook<Definition, 'guard'>>\n\t\t\t\t| Returned<Hook<Definition, 'middleware'>>\n\t\t: Returned<Hook<Definition, 'middleware'>>\ntype OutsideHooks = 'prepare' | 'audit' | 'checkPermission' | 'writeAudit'\nexport type EffectOperationError<Definition> =\n\t| ContractDecoderError<Hook<Definition, 'input'>>\n\t| ContractDecoderError<Hook<Definition, 'result'>>\n\t| ContractDecoderError<Hook<Definition, 'replayResult'>>\n\t| CallbackError<CoreValue<Definition>>\n\t| CallbackError<Definition[Extract<keyof Definition, OutsideHooks>]>\nexport type EffectOperationRequirements<Definition> =\n\t| ContractDecoderRequirements<Hook<Definition, 'input'>>\n\t| ContractDecoderRequirements<Hook<Definition, 'result'>>\n\t| ContractDecoderRequirements<Hook<Definition, 'replayResult'>>\n\t| CallbackRequirements<CoreValue<Definition>>\n\t| CallbackRequirements<Definition[Extract<keyof Definition, OutsideHooks>]>\n\ntype Supported<Value, Error = unknown, Requirements = unknown> =\n\t| Value\n\t| PromiseLike<Value>\n\t| Effect.Effect<Value, Error, Requirements>\nexport type EffectPreparation<Result, Error = never, Requirements = never> =\n\t| { kind: 'replay'; result: unknown }\n\t| { kind: 'execute'; complete?: (result: Result) => Supported<void, Error, Requirements> }\nexport type EffectMiddlewareInput<\n\tContext,\n\tInput,\n\tResult,\n\tExtension,\n\tError = never,\n\tRequirements = never,\n> = {\n\toperation: string\n\tcontext: Context\n\tcommand: Input\n\tinput: Input\n\tnext: keyof Extension extends never\n\t\t? (options?: { context?: Extension }) => Effect.Effect<Result, Error, Requirements>\n\t\t: (options: { context: Extension }) => Effect.Effect<Result, Error, Requirements>\n}\ntype Audit<Aggregates extends readonly string[]> = Omit<\n\tAuditEntryInput,\n\t'classification' | 'aggregate'\n> & {\n\taggregate: { type: Aggregates[number]; id: string }\n}\ntype OperationDefinition<\n\tContext,\n\tInput extends ContractSchema,\n\tOutput extends ContractSchema,\n\tExtension,\n\tAggregates extends readonly string[],\n\tHandler,\n\tGuard,\n\tPreparation,\n\tAuditResult,\n\tMiddleware,\n\tMetadata,\n\tBaseError,\n\tBaseRequirements,\n\tWire extends ContractSchema,\n\tReplay extends ContractSchema,\n> = {\n\tinput: Input\n\tresult: Output\n\thandler: (input: ContractOutput<Input>, context: Context & Extension) => Handler\n\tclassification?: string\n\tpermission?: string\n\tmetadata?: Metadata\n\taggregates?: Aggregates\n\treplayResult?: Replay & (ContractOutput<Replay> extends ContractOutput<Output> ? unknown : never)\n\twire?: { schema: Wire; project: (value: ContractOutput<Output>) => ContractInput<Wire> }\n\tguard?: (context: Context & Extension, input: ContractOutput<Input>) => Guard\n\tprepare?: (context: Context, input: ContractOutput<Input>) => Preparation\n\taudit?: (\n\t\tresolution: { command: ContractOutput<Input>; result: ContractOutput<Output> },\n\t\tcontext: Context,\n\t) => AuditResult\n} & (keyof Extension extends never\n\t? {\n\t\t\tmiddleware?: (\n\t\t\t\tinput: EffectMiddlewareInput<\n\t\t\t\t\tContext,\n\t\t\t\t\tContractOutput<Input>,\n\t\t\t\t\tContractInput<Output>,\n\t\t\t\t\tExtension,\n\t\t\t\t\tBaseError | CallbackError<Handler | Guard>,\n\t\t\t\t\tBaseRequirements | CallbackRequirements<Handler | Guard>\n\t\t\t\t>,\n\t\t\t) => Middleware\n\t\t}\n\t: {\n\t\t\tmiddleware: (\n\t\t\t\tinput: EffectMiddlewareInput<\n\t\t\t\t\tContext,\n\t\t\t\t\tContractOutput<Input>,\n\t\t\t\t\tContractInput<Output>,\n\t\t\t\t\tExtension,\n\t\t\t\t\tBaseError | CallbackError<Handler | Guard>,\n\t\t\t\t\tBaseRequirements | CallbackRequirements<Handler | Guard>\n\t\t\t\t>,\n\t\t\t) => Middleware\n\t\t})\n\n/**\n * Bind context once; middleware wraps the handler/guard channels and may discharge them.\n * Declare contextual guards/handlers before middleware, or annotate their parameters\n * and returned Effect channels when middleware comes first. TypeScript processes\n * context-sensitive object callbacks in declaration order.\n */\nexport function effectOperationFactory<\n\tContext,\n\tExtension extends Record<string, unknown> = Record<never, never>,\n\tBaseError = never,\n\tBaseRequirements = never,\n>() {\n\tfunction operation<\n\t\tconst Input extends ContractSchema,\n\t\tconst Output extends ContractSchema,\n\t\tHandler extends Supported<ContractInput<Output>>,\n\t\tGuard extends Supported<void> = never,\n\t\tPreparation extends Supported<EffectPreparation<ContractOutput<Output>, unknown, unknown>> =\n\t\t\tnever,\n\t\tconst Aggregates extends readonly string[] = readonly string[],\n\t\tAuditResult extends Supported<Audit<Aggregates> | null> = never,\n\t\tMiddleware extends Supported<ContractInput<Output>> = never,\n\t\tconst Metadata extends object = Record<never, never>,\n\t\t// Retain whether middleware is guaranteed, conditional, or omitted.\n\t\tconst Wire extends ContractSchema = ContractSchema,\n\t\tconst Replay extends ContractSchema = never,\n\t\tconst Definition extends object = object,\n\t>(\n\t\tdefinition: Definition &\n\t\t\tOperationDefinition<\n\t\t\t\tContext,\n\t\t\t\tInput,\n\t\t\t\tOutput,\n\t\t\t\tExtension,\n\t\t\t\tAggregates,\n\t\t\t\tHandler,\n\t\t\t\tGuard,\n\t\t\t\tPreparation,\n\t\t\t\tAuditResult,\n\t\t\t\tMiddleware,\n\t\t\t\tMetadata,\n\t\t\t\tBaseError,\n\t\t\t\tBaseRequirements,\n\t\t\t\tWire,\n\t\t\t\tReplay\n\t\t\t>,\n\t) {\n\t\t// SAFETY: the marker is type-only proof of the helper's checked callback contract.\n\t\treturn definition as CheckedEffectDefinition<\n\t\t\tContext,\n\t\t\ttypeof definition,\n\t\t\tBaseError,\n\t\t\tBaseRequirements\n\t\t>\n\t}\n\tfunction command<\n\t\tconst Input extends ContractSchema,\n\t\tconst Output extends ContractSchema,\n\t\tHandler extends Supported<ContractInput<Output>>,\n\t\tGuard extends Supported<void> = never,\n\t\tPreparation extends Supported<EffectPreparation<ContractOutput<Output>, unknown, unknown>> =\n\t\t\tnever,\n\t\tconst Aggregates extends readonly string[] = readonly string[],\n\t\tAuditResult extends Supported<Audit<Aggregates> | null> = never,\n\t\tMiddleware extends Supported<ContractInput<Output>> = never,\n\t\tconst Metadata extends object = Record<never, never>,\n\t\t// Retain whether middleware is guaranteed, conditional, or omitted.\n\t\tconst Wire extends ContractSchema = ContractSchema,\n\t\tconst Replay extends ContractSchema = never,\n\t\tconst Definition extends object = object,\n\t>(\n\t\tdefinition: Definition &\n\t\t\tOperationDefinition<\n\t\t\t\tContext,\n\t\t\t\tInput,\n\t\t\t\tOutput,\n\t\t\t\tExtension,\n\t\t\t\tAggregates,\n\t\t\t\tHandler,\n\t\t\t\tGuard,\n\t\t\t\tPreparation,\n\t\t\t\tAuditResult,\n\t\t\t\tMiddleware,\n\t\t\t\tMetadata,\n\t\t\t\tBaseError,\n\t\t\t\tBaseRequirements,\n\t\t\t\tWire,\n\t\t\t\tReplay\n\t\t\t> & {\n\t\t\t\tclassification: string\n\t\t\t\taudit: (\n\t\t\t\t\tresolution: { command: ContractOutput<Input>; result: ContractOutput<Output> },\n\t\t\t\t\tcontext: Context,\n\t\t\t\t) => AuditResult\n\t\t\t},\n\t) {\n\t\t// SAFETY: the marker is type-only proof of the helper's checked callback contract.\n\t\treturn definition as CheckedEffectDefinition<\n\t\t\tContext,\n\t\t\ttypeof definition,\n\t\t\tBaseError,\n\t\t\tBaseRequirements\n\t\t>\n\t}\n\tfunction query<\n\t\tconst Input extends ContractSchema,\n\t\tconst Output extends ContractSchema,\n\t\tHandler extends Supported<ContractInput<Output>>,\n\t\tGuard extends Supported<void> = never,\n\t\tMiddleware extends Supported<ContractInput<Output>> = never,\n\t\tconst Metadata extends object = Record<never, never>,\n\t\tconst Wire extends ContractSchema = ContractSchema,\n\t\tconst Replay extends ContractSchema = never,\n\t\tconst Definition extends object = object,\n\t>(\n\t\tdefinition: Definition &\n\t\t\tOperationDefinition<\n\t\t\t\tContext,\n\t\t\t\tInput,\n\t\t\t\tOutput,\n\t\t\t\tExtension,\n\t\t\t\treadonly string[],\n\t\t\t\tHandler,\n\t\t\t\tGuard,\n\t\t\t\tnever,\n\t\t\t\tnever,\n\t\t\t\tMiddleware,\n\t\t\t\tMetadata,\n\t\t\t\tBaseError,\n\t\t\t\tBaseRequirements,\n\t\t\t\tWire,\n\t\t\t\tReplay\n\t\t\t> & {\n\t\t\t\tprepare?: never\n\t\t\t\taudit?: never\n\t\t\t\taggregates?: never\n\t\t\t\treplayResult?: never\n\t\t\t},\n\t) {\n\t\t// SAFETY: the marker is type-only proof of the helper's checked callback contract.\n\t\treturn definition as CheckedEffectDefinition<\n\t\t\tContext,\n\t\t\ttypeof definition,\n\t\t\tBaseError,\n\t\t\tBaseRequirements\n\t\t>\n\t}\n\treturn { operation, command, query }\n}\n"],"mappings":"AA0NA,SAAgB,GAKZ,CACH,SAAS,EAgBR,EAkBC,CAED,OAAO,CAMR,CACA,SAAS,EAgBR,EAwBC,CAED,OAAO,CAMR,CACA,SAAS,EAWR,EAuBC,CAED,OAAO,CAMR,CACA,MAAO,CAAE,YAAW,UAAS,OAAM,CACpC"}
|
|
1
|
+
{"version":3,"file":"operation.mjs","names":["effectOperationFactory","operation","definition","command","query"],"sources":["../../../src/modules/effect/operation.ts"],"sourcesContent":["import type { Effect } from 'effect'\nimport type { ContractSchema, ContractInput, ContractOutput } from '../contracts/contract'\nimport type { ContractDecoderError, ContractDecoderRequirements } from './schema'\nimport type { AuditEntryInput } from '../../components/foundation/client'\n\n/** Ordinary failures are defects; only an explicit Effect supplies a typed error. */\nexport type CallbackError<Value> = Value extends (...arguments_: never[]) => infer Returned\n\t? CallbackError<Returned>\n\t: Value extends Effect.Effect<infer Success, infer Error, unknown>\n\t\t? Error | CallbackError<Success>\n\t\t: Value extends PromiseLike<infer Awaited>\n\t\t\t? CallbackError<Awaited>\n\t\t\t: Value extends readonly (infer Item)[]\n\t\t\t\t? CallbackError<Item>\n\t\t\t\t: Value extends { kind: 'execute'; complete?: infer Complete }\n\t\t\t\t\t? CallbackError<Complete>\n\t\t\t\t\t: never\n\nexport type CallbackRequirements<Value> = Value extends (...arguments_: never[]) => infer Returned\n\t? CallbackRequirements<Returned>\n\t: Value extends Effect.Effect<infer Success, unknown, infer Requirements>\n\t\t? Requirements | CallbackRequirements<Success>\n\t\t: Value extends PromiseLike<infer Awaited>\n\t\t\t? CallbackRequirements<Awaited>\n\t\t\t: Value extends readonly (infer Item)[]\n\t\t\t\t? CallbackRequirements<Item>\n\t\t\t\t: Value extends { kind: 'execute'; complete?: infer Complete }\n\t\t\t\t\t? CallbackRequirements<Complete>\n\t\t\t\t\t: never\n\nexport type EffectValue<Value> =\n\tValue extends Effect.Effect<infer Success, unknown, unknown>\n\t\t? EffectValue<Success>\n\t\t: Value extends PromiseLike<infer Awaited>\n\t\t\t? EffectValue<Awaited>\n\t\t\t: Value\n\ndeclare const checkedOperation: unique symbol\n/** Type-only evidence that the helper checked callbacks against the base context and schemas. */\nexport type CheckedEffectOperation<Context> = {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\terror: unknown\n\t\trequirements: unknown\n\t\tdefinition: unknown\n\t}\n}\ntype CheckedChannels<Context, Error, Requirements, Definition> = {\n\treadonly [checkedOperation]: {\n\t\tcontext: (context: Context) => void\n\t\terror: Error\n\t\trequirements: Requirements\n\t\tdefinition: Definition\n\t}\n}\n/** Named checked-definition boundary keeps the private evidence marker inside this module's declarations. */\nexport type CheckedEffectDefinition<\n\tContext,\n\tDefinition,\n\tError = never,\n\tRequirements = never,\n> = NoInfer<Omit<Definition, typeof checkedOperation>> &\n\tCheckedChannels<Context, Error, Requirements, Omit<Definition, typeof checkedOperation>>\n/** Reject stale helper evidence after callbacks or schemas are replaced. */\nexport type ValidatedEffectOperations<Operations> = {\n\t[Key in keyof Operations]: Operations[Key] extends {\n\t\treadonly [checkedOperation]: { definition: infer Definition }\n\t}\n\t\t? Operations[Key] extends Definition\n\t\t\t? Operations[Key]\n\t\t\t: never\n\t\t: never\n}\n/** Only middleware whose next contract captured a default policy can discharge its channels. */\nexport type UnwrappedDefaultError<Definition, Guard> = Definition extends { middleware: Function }\n\t? Definition extends CheckedChannels<never, infer Error, unknown, unknown>\n\t\t? Exclude<CallbackError<Guard>, Error>\n\t\t: CallbackError<Guard>\n\t: CallbackError<Guard>\nexport type UnwrappedDefaultRequirements<Definition, Guard> = Definition extends {\n\tmiddleware: Function\n}\n\t? Definition extends CheckedChannels<never, unknown, infer Requirements, unknown>\n\t\t? Exclude<CallbackRequirements<Guard>, Requirements>\n\t\t: CallbackRequirements<Guard>\n\t: CallbackRequirements<Guard>\nexport type EffectOperationArgument<Definition extends { input: ContractSchema }> = ContractInput<\n\tDefinition['input']\n>\nexport type EffectOperationInput<Definition extends { input: ContractSchema }> = ContractOutput<\n\tDefinition['input']\n>\nexport type EffectOperationHandlerResult<Definition extends { result: ContractSchema }> =\n\tContractInput<Definition['result']>\nexport type EffectOperationResult<Definition extends { result: ContractSchema }> = ContractOutput<\n\tDefinition['result']\n>\n\ntype Hook<Definition, Key extends PropertyKey> = Key extends keyof Definition\n\t? Definition[Key]\n\t: never\ntype Returned<Callback> = Callback extends (...arguments_: never[]) => infer Value ? Value : never\n/** A conditional wrapper must retain the unwrapped channels for its absent branch. */\ntype CoreValue<Definition> = [Returned<Hook<Definition, 'middleware'>>] extends [never]\n\t? Returned<Hook<Definition, 'handler'>> | Returned<Hook<Definition, 'guard'>>\n\t: undefined extends Hook<Definition, 'middleware'>\n\t\t?\n\t\t\t\t| Returned<Hook<Definition, 'handler'>>\n\t\t\t\t| Returned<Hook<Definition, 'guard'>>\n\t\t\t\t| Returned<Hook<Definition, 'middleware'>>\n\t\t: Returned<Hook<Definition, 'middleware'>>\ntype OutsideHooks = 'prepare' | 'audit' | 'checkPermission' | 'writeAudit'\nexport type EffectOperationError<Definition> =\n\t| ContractDecoderError<Hook<Definition, 'input'>>\n\t| ContractDecoderError<Hook<Definition, 'result'>>\n\t| ContractDecoderError<Hook<Definition, 'replayResult'>>\n\t| CallbackError<CoreValue<Definition>>\n\t| CallbackError<Definition[Extract<keyof Definition, OutsideHooks>]>\nexport type EffectOperationRequirements<Definition> =\n\t| ContractDecoderRequirements<Hook<Definition, 'input'>>\n\t| ContractDecoderRequirements<Hook<Definition, 'result'>>\n\t| ContractDecoderRequirements<Hook<Definition, 'replayResult'>>\n\t| CallbackRequirements<CoreValue<Definition>>\n\t| CallbackRequirements<Definition[Extract<keyof Definition, OutsideHooks>]>\n\ntype Supported<Value, Error = unknown, Requirements = unknown> =\n\t| Value\n\t| PromiseLike<Value>\n\t| Effect.Effect<Value, Error, Requirements>\nexport type EffectPreparation<Result, Error = never, Requirements = never> =\n\t| { kind: 'replay'; result: unknown }\n\t| { kind: 'execute'; complete?: (result: Result) => Supported<void, Error, Requirements> }\nexport type EffectMiddlewareInput<\n\tContext,\n\tInput,\n\tResult,\n\tExtension,\n\tError = never,\n\tRequirements = never,\n> = {\n\toperation: string\n\tcontext: Context\n\tcommand: Input\n\tinput: Input\n\tnext: keyof Extension extends never\n\t\t? (options?: { context?: Extension }) => Effect.Effect<Result, Error, Requirements>\n\t\t: (options: { context: Extension }) => Effect.Effect<Result, Error, Requirements>\n}\ntype Audit<Aggregates extends readonly string[]> = Omit<\n\tAuditEntryInput,\n\t'classification' | 'aggregate'\n> & {\n\taggregate: { type: Aggregates[number]; id: string }\n}\ntype OperationDefinition<\n\tContext,\n\tInput extends ContractSchema,\n\tOutput extends ContractSchema,\n\tExtension,\n\tAggregates extends readonly string[],\n\tHandler,\n\tGuard,\n\tPreparation,\n\tAuditResult,\n\tMiddleware,\n\tMetadata,\n\tBaseError,\n\tBaseRequirements,\n\tWire extends ContractSchema,\n\tReplay extends ContractSchema,\n> = {\n\tinput: Input\n\tresult: Output\n\thandler: (input: ContractOutput<Input>, context: Context & Extension) => Handler\n\tclassification?: string\n\tpermission?: string\n\tmetadata?: Metadata\n\taggregates?: Aggregates\n\treplayResult?: Replay & (ContractOutput<Replay> extends ContractOutput<Output> ? unknown : never)\n\twire?: { schema: Wire; project: (value: ContractOutput<Output>) => ContractInput<Wire> }\n\tguard?: (context: Context & Extension, input: ContractOutput<Input>) => Guard\n\tprepare?: (context: Context, input: ContractOutput<Input>) => Preparation\n\taudit?: (\n\t\tresolution: { command: ContractOutput<Input>; result: ContractOutput<Output> },\n\t\tcontext: Context,\n\t) => AuditResult\n} & (keyof Extension extends never\n\t? {\n\t\t\tmiddleware?: (\n\t\t\t\tinput: EffectMiddlewareInput<\n\t\t\t\t\tContext,\n\t\t\t\t\tContractOutput<Input>,\n\t\t\t\t\tContractInput<Output>,\n\t\t\t\t\tExtension,\n\t\t\t\t\tBaseError | CallbackError<Handler | Guard>,\n\t\t\t\t\tBaseRequirements | CallbackRequirements<Handler | Guard>\n\t\t\t\t>,\n\t\t\t) => Middleware\n\t\t}\n\t: {\n\t\t\tmiddleware: (\n\t\t\t\tinput: EffectMiddlewareInput<\n\t\t\t\t\tContext,\n\t\t\t\t\tContractOutput<Input>,\n\t\t\t\t\tContractInput<Output>,\n\t\t\t\t\tExtension,\n\t\t\t\t\tBaseError | CallbackError<Handler | Guard>,\n\t\t\t\t\tBaseRequirements | CallbackRequirements<Handler | Guard>\n\t\t\t\t>,\n\t\t\t) => Middleware\n\t\t})\n\n/**\n * Bind context once; middleware wraps the handler/guard channels and may discharge them.\n * Declare contextual guards/handlers before middleware, or annotate their parameters\n * and returned Effect channels when middleware comes first. TypeScript processes\n * context-sensitive object callbacks in declaration order.\n */\nexport function effectOperationFactory<\n\tContext,\n\tExtension extends Record<string, unknown> = Record<never, never>,\n\tBaseError = never,\n\tBaseRequirements = never,\n>() {\n\tfunction operation<\n\t\tconst Input extends ContractSchema,\n\t\tconst Output extends ContractSchema,\n\t\tHandler extends Supported<ContractInput<Output>>,\n\t\tGuard extends Supported<void> = never,\n\t\tPreparation extends Supported<EffectPreparation<ContractOutput<Output>, unknown, unknown>> =\n\t\t\tnever,\n\t\tconst Aggregates extends readonly string[] = readonly string[],\n\t\tAuditResult extends Supported<Audit<Aggregates> | null> = never,\n\t\tMiddleware extends Supported<ContractInput<Output>> = never,\n\t\tconst Metadata extends object = Record<never, never>,\n\t\t// Retain whether middleware is guaranteed, conditional, or omitted.\n\t\tconst Wire extends ContractSchema = ContractSchema,\n\t\tconst Replay extends ContractSchema = never,\n\t\tconst Definition extends object = object,\n\t>(\n\t\tdefinition: Definition &\n\t\t\tOperationDefinition<\n\t\t\t\tContext,\n\t\t\t\tInput,\n\t\t\t\tOutput,\n\t\t\t\tExtension,\n\t\t\t\tAggregates,\n\t\t\t\tHandler,\n\t\t\t\tGuard,\n\t\t\t\tPreparation,\n\t\t\t\tAuditResult,\n\t\t\t\tMiddleware,\n\t\t\t\tMetadata,\n\t\t\t\tBaseError,\n\t\t\t\tBaseRequirements,\n\t\t\t\tWire,\n\t\t\t\tReplay\n\t\t\t>,\n\t) {\n\t\t// SAFETY: the marker is type-only proof of the helper's checked callback contract.\n\t\treturn definition as CheckedEffectDefinition<\n\t\t\tContext,\n\t\t\ttypeof definition,\n\t\t\tBaseError,\n\t\t\tBaseRequirements\n\t\t>\n\t}\n\tfunction command<\n\t\tconst Input extends ContractSchema,\n\t\tconst Output extends ContractSchema,\n\t\tHandler extends Supported<ContractInput<Output>>,\n\t\tGuard extends Supported<void> = never,\n\t\tPreparation extends Supported<EffectPreparation<ContractOutput<Output>, unknown, unknown>> =\n\t\t\tnever,\n\t\tconst Aggregates extends readonly string[] = readonly string[],\n\t\tAuditResult extends Supported<Audit<Aggregates> | null> = never,\n\t\tMiddleware extends Supported<ContractInput<Output>> = never,\n\t\tconst Metadata extends object = Record<never, never>,\n\t\t// Retain whether middleware is guaranteed, conditional, or omitted.\n\t\tconst Wire extends ContractSchema = ContractSchema,\n\t\tconst Replay extends ContractSchema = never,\n\t\tconst Definition extends object = object,\n\t>(\n\t\tdefinition: Definition &\n\t\t\tOperationDefinition<\n\t\t\t\tContext,\n\t\t\t\tInput,\n\t\t\t\tOutput,\n\t\t\t\tExtension,\n\t\t\t\tAggregates,\n\t\t\t\tHandler,\n\t\t\t\tGuard,\n\t\t\t\tPreparation,\n\t\t\t\tAuditResult,\n\t\t\t\tMiddleware,\n\t\t\t\tMetadata,\n\t\t\t\tBaseError,\n\t\t\t\tBaseRequirements,\n\t\t\t\tWire,\n\t\t\t\tReplay\n\t\t\t> & {\n\t\t\t\tclassification: string\n\t\t\t\taudit: (\n\t\t\t\t\tresolution: { command: ContractOutput<Input>; result: ContractOutput<Output> },\n\t\t\t\t\tcontext: Context,\n\t\t\t\t) => AuditResult\n\t\t\t},\n\t) {\n\t\t// SAFETY: the marker is type-only proof of the helper's checked callback contract.\n\t\treturn definition as CheckedEffectDefinition<\n\t\t\tContext,\n\t\t\ttypeof definition,\n\t\t\tBaseError,\n\t\t\tBaseRequirements\n\t\t>\n\t}\n\tfunction query<\n\t\tconst Input extends ContractSchema,\n\t\tconst Output extends ContractSchema,\n\t\tHandler extends Supported<ContractInput<Output>>,\n\t\tGuard extends Supported<void> = never,\n\t\tMiddleware extends Supported<ContractInput<Output>> = never,\n\t\tconst Metadata extends object = Record<never, never>,\n\t\tconst Wire extends ContractSchema = ContractSchema,\n\t\tconst Replay extends ContractSchema = never,\n\t\tconst Definition extends object = object,\n\t>(\n\t\tdefinition: Definition &\n\t\t\tOperationDefinition<\n\t\t\t\tContext,\n\t\t\t\tInput,\n\t\t\t\tOutput,\n\t\t\t\tExtension,\n\t\t\t\treadonly string[],\n\t\t\t\tHandler,\n\t\t\t\tGuard,\n\t\t\t\tnever,\n\t\t\t\tnever,\n\t\t\t\tMiddleware,\n\t\t\t\tMetadata,\n\t\t\t\tBaseError,\n\t\t\t\tBaseRequirements,\n\t\t\t\tWire,\n\t\t\t\tReplay\n\t\t\t> & {\n\t\t\t\tprepare?: never\n\t\t\t\taudit?: never\n\t\t\t\taggregates?: never\n\t\t\t\treplayResult?: never\n\t\t\t},\n\t) {\n\t\t// SAFETY: the marker is type-only proof of the helper's checked callback contract.\n\t\treturn definition as CheckedEffectDefinition<\n\t\t\tContext,\n\t\t\ttypeof definition,\n\t\t\tBaseError,\n\t\t\tBaseRequirements\n\t\t>\n\t}\n\treturn { operation, command, query }\n}\n"],"mappings":"AA0NA,SAAgBA,GAKZ,CACH,SAASC,EAgBR,EAkBC,CAED,OAAOC,CAMR,CACA,SAASC,EAgBR,EAwBC,CAED,OAAOD,CAMR,CACA,SAASE,EAWR,EAuBC,CAED,OAAOF,CAMR,CACA,MAAO,CAAE,YAAW,UAAS,OAAM,CACpC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContractSchema } from "../contracts/contract.mjs";
|
|
1
|
+
import { ContractOutput, ContractSchema } from "../contracts/contract.mjs";
|
|
2
2
|
import { OperationPublicResult, SelectedOperation } from "../contracts/exposure.mjs";
|
|
3
3
|
import { Observability, ObservabilityOptions } from "../../components/foundation/modules/observability/observability.mjs";
|
|
4
4
|
import { CallbackError, CallbackRequirements, CheckedEffectOperation, EffectOperationArgument, EffectOperationError, EffectOperationRequirements, EffectOperationResult, EffectValue, UnwrappedDefaultError, UnwrappedDefaultRequirements, ValidatedEffectOperations, effectOperationFactory } from "./operation.mjs";
|
|
@@ -23,7 +23,7 @@ type QueryRegistry<Context> = Readonly<Record<string, Pick<QueryDefinition, 'inp
|
|
|
23
23
|
}>>;
|
|
24
24
|
type OperationKey<Operations> = Extract<keyof Operations, string>;
|
|
25
25
|
/** Injectable domain queries compose lazily; the API chooses native function kind. */
|
|
26
|
-
declare function createEffectQuery<Host, ContextReturned, const Operations extends QueryRegistry<EffectValue<ContextReturned>>, PermissionReturned = never, GuardReturned extends Supported<void> = never>(configuration: {
|
|
26
|
+
export declare function createEffectQuery<Host, ContextReturned, const Operations extends QueryRegistry<EffectValue<ContextReturned>>, PermissionReturned = never, GuardReturned extends Supported<void> = never>(configuration: {
|
|
27
27
|
context: (host: Host) => ContextReturned;
|
|
28
28
|
operations: (definitions: ReturnType<typeof effectOperationFactory<EffectValue<ContextReturned>, Record<never, never>, NoInfer<CallbackError<GuardReturned>>, NoInfer<CallbackRequirements<GuardReturned>>>>) => Operations & NoInfer<ValidatedEffectOperations<Operations>>;
|
|
29
29
|
checkPermission?: (host: Host, input: {
|
|
@@ -38,13 +38,17 @@ declare function createEffectQuery<Host, ContextReturned, const Operations exten
|
|
|
38
38
|
}): {
|
|
39
39
|
exec: <const Key extends OperationKey<Operations>>(operation: Key, input: EffectOperationArgument<Operations[Key]>, host: Host) => Effect.Effect<EffectOperationResult<Operations[Key]>, EffectOperationError<Operations[Key]> | CallbackError<ContextReturned | PermissionReturned> | UnwrappedDefaultError<Operations[Key], GuardReturned>, EffectOperationRequirements<Operations[Key]> | CallbackRequirements<ContextReturned | PermissionReturned> | UnwrappedDefaultRequirements<Operations[Key], GuardReturned>>;
|
|
40
40
|
expose: <const Owner extends symbol, const Key extends OperationKey<Operations>>(owner: Owner, operation: Key) => SelectedOperation<Owner, Key, Operations[Key]['input'], OperationPublicResult<Operations[Key]>>;
|
|
41
|
+
/** Bind invocation context without resolving it or running an operation. */
|
|
42
|
+
withContext(context: Host): {
|
|
43
|
+
exec: <const Key extends OperationKey<Operations>>(operation: Key, input: EffectOperationArgument<Operations[Key]>) => Effect.Effect<ContractOutput<Operations[Key]["result"]>, UnwrappedDefaultError<Operations[Key], GuardReturned> | CallbackError<ContextReturned | PermissionReturned> | EffectOperationError<Operations[Key]>, UnwrappedDefaultRequirements<Operations[Key], GuardReturned> | CallbackRequirements<ContextReturned | PermissionReturned> | EffectOperationRequirements<Operations[Key]>>;
|
|
44
|
+
};
|
|
41
45
|
};
|
|
42
46
|
type Policy<Dependencies> = 'checkPermission' extends keyof Dependencies ? Dependencies['checkPermission'] : never;
|
|
43
47
|
type CallbackHost<Callback> = Callback extends ((host: infer Host, input: never) => unknown) ? Host : never;
|
|
44
48
|
type CallbackReturned<Callback> = Callback extends ((...arguments_: never[]) => infer Returned) ? Returned : never;
|
|
45
49
|
type PolicyHost<Dependencies> = [CallbackHost<Policy<Dependencies>>] extends [never] ? unknown : CallbackHost<Policy<Dependencies>>;
|
|
46
50
|
type PolicyReturned<Dependencies> = CallbackReturned<Policy<Dependencies>>;
|
|
47
|
-
type EffectQueryDependencies = {
|
|
51
|
+
export type EffectQueryDependencies = {
|
|
48
52
|
observability: Observability;
|
|
49
53
|
checkPermission?: (host: never, input: {
|
|
50
54
|
permission: string;
|
|
@@ -52,7 +56,7 @@ type EffectQueryDependencies = {
|
|
|
52
56
|
}) => unknown;
|
|
53
57
|
};
|
|
54
58
|
/** The public Foundation binds trusted application policies once. */
|
|
55
|
-
declare function bindEffectQuery<const Dependencies extends EffectQueryDependencies>(dependencies: Dependencies): <Host extends PolicyHost<Dependencies>, ContextReturned, const Operations extends QueryRegistry<EffectValue<ContextReturned>>, GuardReturned extends Supported<void> = never>(configuration: {
|
|
59
|
+
export declare function bindEffectQuery<const Dependencies extends EffectQueryDependencies>(dependencies: Dependencies): <Host extends PolicyHost<Dependencies>, ContextReturned, const Operations extends QueryRegistry<EffectValue<ContextReturned>>, GuardReturned extends Supported<void> = never>(configuration: {
|
|
56
60
|
context: (host: Host) => ContextReturned;
|
|
57
61
|
operations: (definitions: ReturnType<typeof effectOperationFactory<EffectValue<ContextReturned>, Record<never, never>, NoInfer<CallbackError<GuardReturned>>, NoInfer<CallbackRequirements<GuardReturned>>>>) => Operations & NoInfer<ValidatedEffectOperations<Operations>>;
|
|
58
62
|
defaults?: {
|
|
@@ -61,5 +65,4 @@ declare function bindEffectQuery<const Dependencies extends EffectQueryDependenc
|
|
|
61
65
|
};
|
|
62
66
|
}) => ReturnType<typeof createEffectQuery<Host, ContextReturned, Operations, PolicyReturned<Dependencies>, GuardReturned>>;
|
|
63
67
|
//#endregion
|
|
64
|
-
export { EffectQueryDependencies, bindEffectQuery, createEffectQuery };
|
|
65
68
|
//# sourceMappingURL=query.d.mts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{selectOperation as e}from"../contracts/exposure.mjs";import{effectOperationFactory as t}from"./operation.mjs";import{Observability as n}from"../../components/foundation/modules/observability/observability.mjs";import{decodeEffectContract as r}from"./schema.mjs";import{normalizeEffect as i,observationFailure as a}from"./normalize.mjs";import{Effect as o,Exit as s}from"effect";var c=class extends Error{code=`QUERY_MIDDLEWARE_NEXT_REUSED`;name=`QueryMiddlewareError`;constructor(){super(`A query middleware called next() more than once`)}},l=class extends Error{code=`QUERY_OPERATION_NOT_CONFIGURED`;name=`QueryConfigurationError`;constructor(){super(`The selected query operation is not configured`)}},u=class extends Error{code=`QUERY_PERMISSION_CHECKER_MISSING`;name=`QueryPermissionError`;constructor(){super(`Query permission requires an injected permission checker`)}};function d(d){let f=t(),p=d.operations(f),m=d.observability instanceof n?d.observability:new n(d.observability??{enabled:!1,classifyError:()=>({outcome:`failed`,errorCode:`UNEXPECTED`})});function h(e,t,n){return o.suspend(()=>{if(!Object.prototype.hasOwnProperty.call(p,e))return o.die(new l);let f=p[e];return o.flatMap(r(f.input,t),t=>{let l=m.start({operation:e,classification:f.classification??`query`});return o.gen(function*(){if(f.permission!==void 0){let t=d.checkPermission;if(!t)return yield*o.die(new u);yield*i(()=>t(n,{permission:f.permission,operation:e}))}let a=yield*i(()=>d.context(n)),s={...d.defaults?.metadata,...f.metadata},l=e=>o.gen(function*(){let n=d.defaults?.guard;return n&&(yield*i(()=>n(e))),f.guard&&(yield*i(()=>f.guard(e,t))),yield*i(()=>f.handler(t,e))}),p=!1,m=f.middleware,h=m?yield*i(()=>m({operation:e,input:t,command:t,context:a,metadata:s,next:e=>o.suspend(()=>p?o.die(new c):(p=!0,l(e?.context?Object.assign({},a,e.context):a)))})):yield*l(a);return yield*r(f.result,h)}).pipe(o.onExit(e=>o.sync(()=>{s.isSuccess(e)?l.completed():l.failed(a(e.cause))})))})})}function g(t,n){if(!Object.hasOwn(p,n))throw new l;return e(t,`query`,n,p[n])}return{exec:h,expose:g}}function f(e){return function(t){let n=e.checkPermission;return d({...t,observability:e.observability,checkPermission:e.checkPermission?n:void 0})}}export{f as bindEffectQuery,d as createEffectQuery};
|
|
1
|
+
import{selectOperation as e}from"../contracts/exposure.mjs";import{effectOperationFactory as t}from"./operation.mjs";import{Observability as n}from"../../components/foundation/modules/observability/observability.mjs";import{decodeEffectContract as r}from"./schema.mjs";import{normalizeEffect as i,observationFailure as a}from"./normalize.mjs";import{Effect as o,Exit as s}from"effect";var c=class extends Error{code=`QUERY_MIDDLEWARE_NEXT_REUSED`;name=`QueryMiddlewareError`;constructor(){super(`A query middleware called next() more than once`)}},l=class extends Error{code=`QUERY_OPERATION_NOT_CONFIGURED`;name=`QueryConfigurationError`;constructor(){super(`The selected query operation is not configured`)}},u=class extends Error{code=`QUERY_PERMISSION_CHECKER_MISSING`;name=`QueryPermissionError`;constructor(){super(`Query permission requires an injected permission checker`)}};function d(d){let f=t(),p=d.operations(f),m=d.observability instanceof n?d.observability:new n(d.observability??{enabled:!1,classifyError:()=>({outcome:`failed`,errorCode:`UNEXPECTED`})});function h(e,t,n){return o.suspend(()=>{if(!Object.prototype.hasOwnProperty.call(p,e))return o.die(new l);let f=p[e];return o.flatMap(r(f.input,t),t=>{let l=m.start({operation:e,classification:f.classification??`query`});return o.gen(function*(){if(f.permission!==void 0){let t=d.checkPermission;if(!t)return yield*o.die(new u);yield*i(()=>t(n,{permission:f.permission,operation:e}))}let a=yield*i(()=>d.context(n)),s={...d.defaults?.metadata,...f.metadata},l=e=>o.gen(function*(){let n=d.defaults?.guard;return n&&(yield*i(()=>n(e))),f.guard&&(yield*i(()=>f.guard(e,t))),yield*i(()=>f.handler(t,e))}),p=!1,m=f.middleware,h=m?yield*i(()=>m({operation:e,input:t,command:t,context:a,metadata:s,next:e=>o.suspend(()=>p?o.die(new c):(p=!0,l(e?.context?Object.assign({},a,e.context):a)))})):yield*l(a);return yield*r(f.result,h)}).pipe(o.onExit(e=>o.sync(()=>{s.isSuccess(e)?l.completed():l.failed(a(e.cause))})))})})}function g(t,n){if(!Object.hasOwn(p,n))throw new l;return e(t,`query`,n,p[n])}return{exec:h,expose:g,withContext(e){return{exec:(t,n)=>h(t,n,e)}}}}function f(e){return function(t){let n=e.checkPermission;return d({...t,observability:e.observability,checkPermission:e.checkPermission?n:void 0})}}export{f as bindEffectQuery,d as createEffectQuery};
|
|
2
2
|
//# sourceMappingURL=query.mjs.map
|