cvx-kit 0.0.8 → 0.1.1
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 +132 -0
- package/README.md +14 -10
- package/ROADMAP.md +126 -0
- package/dist/agent-tools.d.mts +45 -0
- package/dist/agent-tools.mjs +2 -0
- package/dist/agent-tools.mjs.map +1 -0
- package/dist/auth.d.mts +9 -1
- package/dist/auth.mjs +1 -1
- package/dist/auth.mjs.map +1 -1
- package/dist/components/approvals/_generated/api.d.mts +2 -0
- package/dist/components/approvals/_generated/api.mjs.map +1 -1
- package/dist/components/approvals/_generated/component.d.mts +7 -0
- package/dist/components/approvals/_generated/dataModel.d.mts +1 -1
- package/dist/components/approvals/client.d.mts +4 -4
- package/dist/components/approvals/client.mjs +1 -1
- package/dist/components/approvals/client.mjs.map +1 -1
- package/dist/components/approvals/constants.d.mts +8 -2
- package/dist/components/approvals/constants.mjs +1 -1
- package/dist/components/approvals/constants.mjs.map +1 -1
- package/dist/components/approvals/decisions.mjs +1 -1
- package/dist/components/approvals/decisions.mjs.map +1 -1
- package/dist/components/approvals/health.d.mts +15 -0
- package/dist/components/approvals/health.mjs +2 -0
- package/dist/components/approvals/health.mjs.map +1 -0
- package/dist/components/approvals/requests.mjs +1 -1
- package/dist/components/approvals/requests.mjs.map +1 -1
- package/dist/components/approvals/schema.js +1 -0
- package/dist/components/approvals/validators.d.mts +119 -2
- package/dist/components/approvals/validators.mjs +1 -1
- package/dist/components/approvals/validators.mjs.map +1 -1
- package/dist/components/approvals/workflow_steps.d.mts +2 -25
- package/dist/components/approvals/workflow_steps.mjs.map +1 -1
- package/dist/components/foundation/_generated/dataModel.d.mts +1 -1
- package/dist/components/foundation/client.d.mts +26 -9
- package/dist/components/foundation/client.mjs.map +1 -1
- package/dist/components/foundation/modules/query/query.d.mts +19 -8
- package/dist/components/foundation/modules/query/query.mjs.map +1 -1
- package/dist/components/foundation/{schema.mjs → schema.js} +0 -1
- package/dist/crud.d.mts +79 -0
- package/dist/crud.mjs +2 -0
- package/dist/crud.mjs.map +1 -0
- package/dist/index.d.mts +9 -4
- package/dist/index.mjs +1 -1
- package/dist/middleware.d.mts +46 -0
- package/dist/middleware.mjs +2 -0
- package/dist/middleware.mjs.map +1 -0
- package/dist/state-machine.d.mts +18 -0
- package/dist/state-machine.mjs +2 -0
- package/dist/state-machine.mjs.map +1 -0
- package/dist/tenancy.d.mts +1 -1
- package/dist/webhooks.d.mts +164 -0
- package/dist/webhooks.mjs +2 -0
- package/dist/webhooks.mjs.map +1 -0
- package/dist/zod-table.d.mts +34 -3
- package/dist/zod-table.mjs +1 -1
- package/dist/zod-table.mjs.map +1 -1
- package/docs/agent-tools.md +41 -0
- package/docs/approvals.md +50 -2
- package/docs/crud.md +62 -0
- package/docs/llms.md +8 -1
- package/docs/plans/2026-08-14-001-feat-v0.1.0-feature-set-plan.md +461 -0
- package/docs/upgrading.md +175 -0
- package/docs/webhooks.md +58 -0
- package/package.json +25 -2
- package/scripts/convex-config-bridge.mjs +41 -3
- package/scripts/extract-changelog.mjs +29 -0
- package/scripts/smoke-packed-components.mjs +374 -0
- package/src/test.ts +2 -2
- package/dist/components/approvals/schema.mjs +0 -2
- package/dist/components/approvals/schema.mjs.map +0 -1
- package/dist/components/foundation/schema.mjs.map +0 -1
- /package/dist/components/approvals/{schema.d.mts → schema.d.ts} +0 -0
- /package/dist/components/foundation/{schema.d.mts → schema.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../../../src/components/approvals/client.ts"],"sourcesContent":["import type {\n\tFunctionArgs,\n\tFunctionReference,\n\tFunctionReturnType,\n\tGenericDataModel,\n\tGenericMutationCtx,\n\tGenericQueryCtx,\n} from 'convex/server'\n\nimport type { ComponentApi } from './_generated/component'\nimport type { ApprovalDecision } from './constants'\nimport type {\n\tApprovalActor,\n\tApprovalMetadata,\n\tApprovalWorkflowDescriptor,\n} from './validators'\nimport {\n\tcompileApprovalDescriptor,\n\ttype ApprovalActionStep,\n\ttype ApprovalBranchStep,\n\ttype ApprovalDecisionStep,\n\ttype ApprovalDefinition,\n\ttype ApprovalMutationStep,\n\ttype ApprovalNotifyStep,\n\ttype ApprovalWorkflowStep,\n\ttype ApprovalCallbackInput,\n\ttype CreateApprovalHandle,\n} from './workflow_steps'\n\nexport type ApprovalsOptions = Readonly<{\n\tcreateHandle?: CreateApprovalHandle\n}>\n\nexport type ApprovalStartInput = Readonly<{\n\tscopeRef: string\n\tresourceType: string\n\tresourceRef: string\n\trequester: ApprovalActor\n\tmetadata?: ApprovalMetadata\n}>\n\nexport type ApprovalDecisionInput = Readonly<{\n\trunId: string\n\tdecision: ApprovalDecision\n\treason?: string\n}>\n\nexport type ApprovalEvidenceItem = Readonly<{\n\tstepKey: string\n\tactorRef: string\n\tdecision: ApprovalDecision\n\treason?: string\n\tdecidedAt: number\n}>\n\nexport type ApprovalAuditHistoryInput = Readonly<{\n\tresourceType: string\n\tresourceRef: string\n\tlimit?: number\n}>\n\nexport type ApprovalAuditCleanupInput = Readonly<{\n\tolderThanDays: number\n\tbatchSize: number\n}>\n\nexport type ApprovalStatus = FunctionReturnType<\n\tComponentApi['requests']['status']\n>\n\nexport class Approvals<Component extends ComponentApi = ComponentApi> {\n\tprivate readonly component: Component\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(component: Component, options: ApprovalsOptions = {}) {\n\t\tthis.component = component\n\t\tthis.createHandle = options.createHandle\n\t}\n\n\tcleanupAudit<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalAuditCleanupInput,\n\t): Promise<FunctionReturnType<Component['audit']['cleanup']>> {\n\t\treturn ctx.runMutation(this.component.audit.cleanup, input)\n\t}\n\n\tmutation(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<\n\t\t\t\t'mutation',\n\t\t\t\t'internal',\n\t\t\t\tApprovalCallbackInput,\n\t\t\t\tunknown\n\t\t\t>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalMutationStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'mutation',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\taction(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<\n\t\t\t\t'action',\n\t\t\t\t'internal',\n\t\t\t\tApprovalCallbackInput,\n\t\t\t\tunknown\n\t\t\t>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalActionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'action',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tnotify(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<\n\t\t\t\t'action',\n\t\t\t\t'internal',\n\t\t\t\tApprovalCallbackInput,\n\t\t\t\tunknown\n\t\t\t>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalNotifyStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'notify',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tdecision(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tdecisions: readonly ApprovalDecision[]\n\t\t\tquorum: Readonly<{ kind: 'count'; approvals: number }>\n\t\t\tmakerChecker?: boolean\n\t\t\texpiresAfterMs?: number\n\t\t}>,\n\t): ApprovalDecisionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'decision',\n\t\t\tkey,\n\t\t\tdecisions: Object.freeze([...options.decisions]),\n\t\t\tquorum: Object.freeze({ ...options.quorum }),\n\t\t\tmakerChecker: options.makerChecker ?? false,\n\t\t\t...(options.expiresAfterMs === undefined\n\t\t\t\t? {}\n\t\t\t\t: { expiresAfterMs: options.expiresAfterMs }),\n\t\t})\n\t}\n\n\tbranch(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tapprovedStepKey: string\n\t\t\trejectedStepKey: string\n\t\t}>,\n\t): ApprovalBranchStep {\n\t\treturn Object.freeze({ kind: 'branch', key, ...options })\n\t}\n\n\tdefine(\n\t\tinput: Readonly<{\n\t\t\tname: string\n\t\t\tcompatibilityKey?: string\n\t\t\tsteps: readonly ApprovalWorkflowStep[]\n\t\t}>,\n\t): ConfiguredApprovalWorkflow<Component> {\n\t\tconst definition = freezeDefinition({\n\t\t\tname: input.name,\n\t\t\tcompatibilityKey: input.compatibilityKey ?? input.name,\n\t\t\tsteps: input.steps,\n\t\t})\n\t\treturn new ConfiguredApprovalWorkflow(\n\t\t\tthis.component,\n\t\t\tdefinition,\n\t\t\tthis.createHandle,\n\t\t)\n\t}\n}\n\nexport class ConfiguredApprovalWorkflow<\n\tComponent extends ComponentApi = ComponentApi,\n> {\n\treadonly name: string\n\treadonly compatibilityKey: string\n\treadonly steps: readonly ApprovalWorkflowStep[]\n\n\tprivate readonly component: Component\n\tprivate readonly definition: ApprovalDefinition\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(\n\t\tcomponent: Component,\n\t\tdefinition: ApprovalDefinition,\n\t\tcreateHandle?: CreateApprovalHandle,\n\t) {\n\t\tthis.component = component\n\t\tthis.definition = definition\n\t\tthis.name = definition.name\n\t\tthis.compatibilityKey = definition.compatibilityKey\n\t\tthis.steps = definition.steps\n\t\tthis.createHandle = createHandle\n\t\tObject.freeze(this)\n\t}\n\n\tdescriptor(): Promise<Readonly<ApprovalWorkflowDescriptor>> {\n\t\treturn compileApprovalDescriptor(this.definition, this.createHandle)\n\t}\n\n\tasync start<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalStartInput,\n\t): Promise<FunctionReturnType<Component['requests']['start']>> {\n\t\treturn ctx.runMutation(this.component.requests.start, {\n\t\t\t...input,\n\t\t\tworkflow: await this.descriptor(),\n\t\t})\n\t}\n\n\tdecide<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalDecisionInput,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['decisions']['decide']>> {\n\t\treturn ctx.runMutation(this.component.decisions.decide, {\n\t\t\t...input,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tevidence<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['decisions']['list']>> {\n\t\treturn ctx.runQuery(this.component.decisions.list, { runId })\n\t}\n\n\tauditHistory<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: ApprovalAuditHistoryInput,\n\t): Promise<FunctionReturnType<Component['audit']['history']>> {\n\t\treturn ctx.runQuery(this.component.audit.history, input)\n\t}\n\n\tcancel<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['requests']['cancel']>> {\n\t\treturn ctx.runMutation(this.component.requests.cancel, {\n\t\t\trunId,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tstatus<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<ApprovalStatus | null> {\n\t\treturn ctx.runQuery(this.component.requests.status, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tlist<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: FunctionArgs<Component['requests']['list']>,\n\t): Promise<FunctionReturnType<Component['requests']['list']>> {\n\t\treturn ctx.runQuery(this.component.requests.list, input)\n\t}\n\n\trestart<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['requests']['restart']>> {\n\t\treturn ctx.runMutation(this.component.requests.restart, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n}\n\nfunction freezeDefinition(definition: ApprovalDefinition): ApprovalDefinition {\n\treturn Object.freeze({\n\t\t...definition,\n\t\tsteps: Object.freeze(\n\t\t\tdefinition.steps.map((step) => {\n\t\t\t\tif (step.kind === 'decision')\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\t...step,\n\t\t\t\t\t\tdecisions: Object.freeze([...step.decisions]),\n\t\t\t\t\t\tquorum: Object.freeze({ ...step.quorum }),\n\t\t\t\t\t})\n\t\t\t\treturn Object.freeze({ ...step })\n\t\t\t}),\n\t\t),\n\t})\n}\n\n// The component definition is deliberately NOT re-exported here: Convex's\n// CLI only discovers a component whose resolved file is convex.config.js,\n// so hosts must mount via the dedicated subpath:\n// import approvals from 'cvx-kit/components/approvals/convex.config'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../../src/components/approvals/client.ts"],"sourcesContent":["import type {\n\tFunctionArgs,\n\tFunctionReference,\n\tFunctionReturnType,\n\tGenericDataModel,\n\tGenericMutationCtx,\n\tGenericQueryCtx,\n} from 'convex/server'\n\nimport type { ComponentApi } from './_generated/component'\nimport type { ApprovalDecision } from './constants'\nimport type {\n\tApprovalActor,\n\tApprovalMetadata,\n\tApprovalWorkflowDescriptor,\n} from './validators'\nimport {\n\tcompileApprovalDescriptor,\n\ttype ApprovalActionStep,\n\ttype ApprovalBranchStep,\n\ttype ApprovalDecisionStep,\n\ttype ApprovalDefinition,\n\ttype ApprovalMutationStep,\n\ttype ApprovalNotifyStep,\n\ttype ApprovalWorkflowStep,\n\ttype ApprovalCallbackInput,\n\ttype CreateApprovalHandle,\n} from './workflow_steps'\n\nexport { approvalCallbackArgs, approvalCallbackInput } from './validators'\nexport type { ApprovalCallbackInput } from './validators'\n\nexport type ApprovalsOptions = Readonly<{\n\tcreateHandle?: CreateApprovalHandle\n}>\n\nexport type ApprovalStartInput = Readonly<{\n\tscopeRef: string\n\tresourceType: string\n\tresourceRef: string\n\trequester: ApprovalActor\n\tmetadata?: ApprovalMetadata\n}>\n\nexport type ApprovalDecisionInput = Readonly<{\n\trunId: string\n\tdecision: ApprovalDecision\n\treason?: string\n}>\n\nexport type ApprovalEvidenceItem = Readonly<{\n\tstepKey: string\n\tactorRef: string\n\tdecision: ApprovalDecision\n\treason?: string\n\tdecidedAt: number\n}>\n\nexport type ApprovalAuditHistoryInput = Readonly<{\n\tresourceType: string\n\tresourceRef: string\n\tlimit?: number\n}>\n\nexport type ApprovalAuditCleanupInput = Readonly<{\n\tolderThanDays: number\n\tbatchSize: number\n}>\n\nexport type ApprovalStatus = FunctionReturnType<\n\tComponentApi['requests']['status']\n>\n\nexport class Approvals<Component extends ComponentApi = ComponentApi> {\n\tprivate readonly component: Component\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(component: Component, options: ApprovalsOptions = {}) {\n\t\tthis.component = component\n\t\tthis.createHandle = options.createHandle\n\t}\n\n\tcleanupAudit<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalAuditCleanupInput,\n\t): Promise<FunctionReturnType<Component['audit']['cleanup']>> {\n\t\treturn ctx.runMutation(this.component.audit.cleanup, input)\n\t}\n\n\tmutation(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<\n\t\t\t\t'mutation',\n\t\t\t\t'internal',\n\t\t\t\tApprovalCallbackInput,\n\t\t\t\tunknown\n\t\t\t>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalMutationStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'mutation',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\taction(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<\n\t\t\t\t'action',\n\t\t\t\t'internal',\n\t\t\t\tApprovalCallbackInput,\n\t\t\t\tunknown\n\t\t\t>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalActionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'action',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tnotify(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\thandler: FunctionReference<\n\t\t\t\t'action',\n\t\t\t\t'internal',\n\t\t\t\tApprovalCallbackInput,\n\t\t\t\tunknown\n\t\t\t>\n\t\t\tretry?: boolean\n\t\t}>,\n\t): ApprovalNotifyStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'notify',\n\t\t\tkey,\n\t\t\thandler: options.handler,\n\t\t\tretry: options.retry ?? false,\n\t\t})\n\t}\n\n\tdecision(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tdecisions: readonly ApprovalDecision[]\n\t\t\tquorum: Readonly<{ kind: 'count'; approvals: number }>\n\t\t\tmakerChecker?: boolean\n\t\t\texpiresAfterMs?: number\n\t\t}>,\n\t): ApprovalDecisionStep {\n\t\treturn Object.freeze({\n\t\t\tkind: 'decision',\n\t\t\tkey,\n\t\t\tdecisions: Object.freeze([...options.decisions]),\n\t\t\tquorum: Object.freeze({ ...options.quorum }),\n\t\t\tmakerChecker: options.makerChecker ?? false,\n\t\t\t...(options.expiresAfterMs === undefined\n\t\t\t\t? {}\n\t\t\t\t: { expiresAfterMs: options.expiresAfterMs }),\n\t\t})\n\t}\n\n\tbranch(\n\t\tkey: string,\n\t\toptions: Readonly<{\n\t\t\tapprovedStepKey: string\n\t\t\trejectedStepKey: string\n\t\t}>,\n\t): ApprovalBranchStep {\n\t\treturn Object.freeze({ kind: 'branch', key, ...options })\n\t}\n\n\tdefine(\n\t\tinput: Readonly<{\n\t\t\tname: string\n\t\t\tcompatibilityKey?: string\n\t\t\tsteps: readonly ApprovalWorkflowStep[]\n\t\t}>,\n\t): ConfiguredApprovalWorkflow<Component> {\n\t\tconst definition = freezeDefinition({\n\t\t\tname: input.name,\n\t\t\tcompatibilityKey: input.compatibilityKey ?? input.name,\n\t\t\tsteps: input.steps,\n\t\t})\n\t\treturn new ConfiguredApprovalWorkflow(\n\t\t\tthis.component,\n\t\t\tdefinition,\n\t\t\tthis.createHandle,\n\t\t)\n\t}\n}\n\nexport class ConfiguredApprovalWorkflow<\n\tComponent extends ComponentApi = ComponentApi,\n> {\n\treadonly name: string\n\treadonly compatibilityKey: string\n\treadonly steps: readonly ApprovalWorkflowStep[]\n\n\tprivate readonly component: Component\n\tprivate readonly definition: ApprovalDefinition\n\tprivate readonly createHandle: CreateApprovalHandle | undefined\n\n\tconstructor(\n\t\tcomponent: Component,\n\t\tdefinition: ApprovalDefinition,\n\t\tcreateHandle?: CreateApprovalHandle,\n\t) {\n\t\tthis.component = component\n\t\tthis.definition = definition\n\t\tthis.name = definition.name\n\t\tthis.compatibilityKey = definition.compatibilityKey\n\t\tthis.steps = definition.steps\n\t\tthis.createHandle = createHandle\n\t\tObject.freeze(this)\n\t}\n\n\tdescriptor(): Promise<Readonly<ApprovalWorkflowDescriptor>> {\n\t\treturn compileApprovalDescriptor(this.definition, this.createHandle)\n\t}\n\n\tasync start<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalStartInput,\n\t): Promise<FunctionReturnType<Component['requests']['start']>> {\n\t\treturn ctx.runMutation(this.component.requests.start, {\n\t\t\t...input,\n\t\t\tworkflow: await this.descriptor(),\n\t\t})\n\t}\n\n\tdecide<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\tinput: ApprovalDecisionInput,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['decisions']['decide']>> {\n\t\treturn ctx.runMutation(this.component.decisions.decide, {\n\t\t\t...input,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tevidence<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['decisions']['list']>> {\n\t\treturn ctx.runQuery(this.component.decisions.list, { runId })\n\t}\n\n\tauditHistory<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: ApprovalAuditHistoryInput,\n\t): Promise<FunctionReturnType<Component['audit']['history']>> {\n\t\treturn ctx.runQuery(this.component.audit.history, input)\n\t}\n\n\tcancel<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t\tactor: ApprovalActor,\n\t): Promise<FunctionReturnType<Component['requests']['cancel']>> {\n\t\treturn ctx.runMutation(this.component.requests.cancel, {\n\t\t\trunId,\n\t\t\tactor,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tstatus<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<ApprovalStatus | null> {\n\t\treturn ctx.runQuery(this.component.requests.status, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n\n\tlist<DataModel extends GenericDataModel>(\n\t\tctx: GenericQueryCtx<DataModel>,\n\t\tinput: FunctionArgs<Component['requests']['list']>,\n\t): Promise<FunctionReturnType<Component['requests']['list']>> {\n\t\treturn ctx.runQuery(this.component.requests.list, input)\n\t}\n\n\trestart<DataModel extends GenericDataModel>(\n\t\tctx: GenericMutationCtx<DataModel>,\n\t\trunId: string,\n\t): Promise<FunctionReturnType<Component['requests']['restart']>> {\n\t\treturn ctx.runMutation(this.component.requests.restart, {\n\t\t\trunId,\n\t\t\tcompatibilityKey: this.compatibilityKey,\n\t\t})\n\t}\n}\n\nfunction freezeDefinition(definition: ApprovalDefinition): ApprovalDefinition {\n\treturn Object.freeze({\n\t\t...definition,\n\t\tsteps: Object.freeze(\n\t\t\tdefinition.steps.map((step) => {\n\t\t\t\tif (step.kind === 'decision')\n\t\t\t\t\treturn Object.freeze({\n\t\t\t\t\t\t...step,\n\t\t\t\t\t\tdecisions: Object.freeze([...step.decisions]),\n\t\t\t\t\t\tquorum: Object.freeze({ ...step.quorum }),\n\t\t\t\t\t})\n\t\t\t\treturn Object.freeze({ ...step })\n\t\t\t}),\n\t\t),\n\t})\n}\n\n// The component definition is deliberately NOT re-exported here: Convex's\n// CLI only discovers a component whose resolved file is convex.config.js,\n// so hosts must mount via the dedicated subpath:\n// import approvals from 'cvx-kit/components/approvals/convex.config'\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
declare namespace constants_d_exports {
|
|
2
|
-
export { APPROVAL_AUDIT_RETENTION_CATEGORY, APPROVAL_CALLBACK_KINDS, APPROVAL_DECISIONS, APPROVAL_DESCRIPTOR_SCHEMA_VERSION, APPROVAL_EXECUTION_STATES, APPROVAL_QUORUM_KINDS, APPROVAL_RUN_STATES, APPROVAL_STEP_KINDS, ApprovalCallbackKind, ApprovalDecision, ApprovalExecutionState, ApprovalRunState, ApprovalStepKind, MAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE, MAX_APPROVAL_AUDIT_RETENTION_DAYS, MAX_APPROVAL_CAPABILITIES, MAX_APPROVAL_DECISIONS_PER_STEP, MAX_APPROVAL_METADATA_ENTRIES, MAX_APPROVAL_METADATA_KEY_LENGTH, MAX_APPROVAL_METADATA_VALUE_LENGTH, MAX_APPROVAL_NAME_LENGTH, MAX_APPROVAL_REASON_LENGTH, MAX_APPROVAL_REFERENCE_LENGTH, MAX_APPROVAL_WORKFLOW_STEPS, MIN_APPROVAL_AUDIT_RETENTION_DAYS };
|
|
2
|
+
export { APPROVAL_ACTOR_DECISION_INDEX, APPROVAL_AUDIT_RETENTION_CATEGORY, APPROVAL_CALLBACK_KINDS, APPROVAL_COMPONENT_SCHEMA_VERSION, APPROVAL_DECISIONS, APPROVAL_DECISION_HISTORY_INDEX, APPROVAL_DESCRIPTOR_SCHEMA_VERSION, APPROVAL_EXECUTION_STATES, APPROVAL_QUORUM_KINDS, APPROVAL_REQUIRED_DECISION_INDEXES, APPROVAL_RUN_STATES, APPROVAL_STEP_KINDS, ApprovalCallbackKind, ApprovalDecision, ApprovalExecutionState, ApprovalRunState, ApprovalStepKind, MAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE, MAX_APPROVAL_AUDIT_RETENTION_DAYS, MAX_APPROVAL_CAPABILITIES, MAX_APPROVAL_DECISIONS_PER_STEP, MAX_APPROVAL_METADATA_ENTRIES, MAX_APPROVAL_METADATA_KEY_LENGTH, MAX_APPROVAL_METADATA_VALUE_LENGTH, MAX_APPROVAL_NAME_LENGTH, MAX_APPROVAL_REASON_LENGTH, MAX_APPROVAL_REFERENCE_LENGTH, MAX_APPROVAL_WORKFLOW_STEPS, MIN_APPROVAL_AUDIT_RETENTION_DAYS };
|
|
3
3
|
}
|
|
4
4
|
declare const APPROVAL_RUN_STATES: readonly ['pending', 'approved', 'rejected', 'expired', 'canceled'];
|
|
5
5
|
declare const APPROVAL_DECISIONS: readonly ['approved', 'rejected'];
|
|
@@ -8,6 +8,12 @@ declare const APPROVAL_STEP_KINDS: readonly ['mutation', 'action', 'notify', 'de
|
|
|
8
8
|
declare const APPROVAL_QUORUM_KINDS: readonly ['count'];
|
|
9
9
|
declare const APPROVAL_CALLBACK_KINDS: readonly ['mutation', 'action'];
|
|
10
10
|
declare const APPROVAL_DESCRIPTOR_SCHEMA_VERSION: 1;
|
|
11
|
+
/** Version of the component-owned tables and indexes deployed by cvx-kit. */
|
|
12
|
+
declare const APPROVAL_COMPONENT_SCHEMA_VERSION: 1;
|
|
13
|
+
/** Indexes required by approval evidence reads and decision writes. */
|
|
14
|
+
declare const APPROVAL_DECISION_HISTORY_INDEX: 'by_runId_and_decidedAt';
|
|
15
|
+
declare const APPROVAL_ACTOR_DECISION_INDEX: 'by_runId_and_stepKey_and_actor_actorRef';
|
|
16
|
+
declare const APPROVAL_REQUIRED_DECISION_INDEXES: readonly ["by_runId_and_decidedAt", "by_runId_and_stepKey_and_actor_actorRef"];
|
|
11
17
|
declare const APPROVAL_AUDIT_RETENTION_CATEGORY = "approval-protocol";
|
|
12
18
|
declare const MIN_APPROVAL_AUDIT_RETENTION_DAYS = 1;
|
|
13
19
|
declare const MAX_APPROVAL_AUDIT_RETENTION_DAYS = 3650;
|
|
@@ -27,5 +33,5 @@ type ApprovalExecutionState = (typeof APPROVAL_EXECUTION_STATES)[number];
|
|
|
27
33
|
type ApprovalStepKind = (typeof APPROVAL_STEP_KINDS)[number];
|
|
28
34
|
type ApprovalCallbackKind = (typeof APPROVAL_CALLBACK_KINDS)[number];
|
|
29
35
|
//#endregion
|
|
30
|
-
export { APPROVAL_AUDIT_RETENTION_CATEGORY, APPROVAL_CALLBACK_KINDS, APPROVAL_DECISIONS, APPROVAL_DESCRIPTOR_SCHEMA_VERSION, APPROVAL_EXECUTION_STATES, APPROVAL_QUORUM_KINDS, APPROVAL_RUN_STATES, APPROVAL_STEP_KINDS, ApprovalCallbackKind, ApprovalDecision, ApprovalExecutionState, ApprovalRunState, ApprovalStepKind, MAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE, MAX_APPROVAL_AUDIT_RETENTION_DAYS, MAX_APPROVAL_CAPABILITIES, MAX_APPROVAL_DECISIONS_PER_STEP, MAX_APPROVAL_METADATA_ENTRIES, MAX_APPROVAL_METADATA_KEY_LENGTH, MAX_APPROVAL_METADATA_VALUE_LENGTH, MAX_APPROVAL_NAME_LENGTH, MAX_APPROVAL_REASON_LENGTH, MAX_APPROVAL_REFERENCE_LENGTH, MAX_APPROVAL_WORKFLOW_STEPS, MIN_APPROVAL_AUDIT_RETENTION_DAYS, constants_d_exports };
|
|
36
|
+
export { APPROVAL_ACTOR_DECISION_INDEX, APPROVAL_AUDIT_RETENTION_CATEGORY, APPROVAL_CALLBACK_KINDS, APPROVAL_COMPONENT_SCHEMA_VERSION, APPROVAL_DECISIONS, APPROVAL_DECISION_HISTORY_INDEX, APPROVAL_DESCRIPTOR_SCHEMA_VERSION, APPROVAL_EXECUTION_STATES, APPROVAL_QUORUM_KINDS, APPROVAL_REQUIRED_DECISION_INDEXES, APPROVAL_RUN_STATES, APPROVAL_STEP_KINDS, ApprovalCallbackKind, ApprovalDecision, ApprovalExecutionState, ApprovalRunState, ApprovalStepKind, MAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE, MAX_APPROVAL_AUDIT_RETENTION_DAYS, MAX_APPROVAL_CAPABILITIES, MAX_APPROVAL_DECISIONS_PER_STEP, MAX_APPROVAL_METADATA_ENTRIES, MAX_APPROVAL_METADATA_KEY_LENGTH, MAX_APPROVAL_METADATA_VALUE_LENGTH, MAX_APPROVAL_NAME_LENGTH, MAX_APPROVAL_REASON_LENGTH, MAX_APPROVAL_REFERENCE_LENGTH, MAX_APPROVAL_WORKFLOW_STEPS, MIN_APPROVAL_AUDIT_RETENTION_DAYS, constants_d_exports };
|
|
31
37
|
//# sourceMappingURL=constants.d.mts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=[`pending`,`approved`,`rejected`,`expired`,`canceled`],t=[`approved`,`rejected`],n=[`inProgress`,`completed`,`canceled`,`failed`],r=[`mutation`,`action`,`notify`,`decision`,`branch`],i=[`count`],a=[`mutation`,`action`],o=1,s=`approval-protocol`,
|
|
1
|
+
const e=[`pending`,`approved`,`rejected`,`expired`,`canceled`],t=[`approved`,`rejected`],n=[`inProgress`,`completed`,`canceled`,`failed`],r=[`mutation`,`action`,`notify`,`decision`,`branch`],i=[`count`],a=[`mutation`,`action`],o=1,s=1,c=`by_runId_and_decidedAt`,l=`by_runId_and_stepKey_and_actor_actorRef`,u=[c,l],d=`approval-protocol`,f=1,p=3650,m=100,h=256,g=96,_=500,v=32,y=32,b=64,x=512,S=32,C=8;export{l as APPROVAL_ACTOR_DECISION_INDEX,d as APPROVAL_AUDIT_RETENTION_CATEGORY,a as APPROVAL_CALLBACK_KINDS,s as APPROVAL_COMPONENT_SCHEMA_VERSION,t as APPROVAL_DECISIONS,c as APPROVAL_DECISION_HISTORY_INDEX,o as APPROVAL_DESCRIPTOR_SCHEMA_VERSION,n as APPROVAL_EXECUTION_STATES,i as APPROVAL_QUORUM_KINDS,u as APPROVAL_REQUIRED_DECISION_INDEXES,e as APPROVAL_RUN_STATES,r as APPROVAL_STEP_KINDS,m as MAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE,p as MAX_APPROVAL_AUDIT_RETENTION_DAYS,v as MAX_APPROVAL_CAPABILITIES,C as MAX_APPROVAL_DECISIONS_PER_STEP,y as MAX_APPROVAL_METADATA_ENTRIES,b as MAX_APPROVAL_METADATA_KEY_LENGTH,x as MAX_APPROVAL_METADATA_VALUE_LENGTH,g as MAX_APPROVAL_NAME_LENGTH,_ as MAX_APPROVAL_REASON_LENGTH,h as MAX_APPROVAL_REFERENCE_LENGTH,S as MAX_APPROVAL_WORKFLOW_STEPS,f as MIN_APPROVAL_AUDIT_RETENTION_DAYS};
|
|
2
2
|
//# sourceMappingURL=constants.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","names":[],"sources":["../../../src/components/approvals/constants.ts"],"sourcesContent":["export const APPROVAL_RUN_STATES = [\n\t'pending',\n\t'approved',\n\t'rejected',\n\t'expired',\n\t'canceled',\n] as const\n\nexport const APPROVAL_DECISIONS = ['approved', 'rejected'] as const\n\nexport const APPROVAL_EXECUTION_STATES = [\n\t'inProgress',\n\t'completed',\n\t'canceled',\n\t'failed',\n] as const\n\nexport const APPROVAL_STEP_KINDS = [\n\t'mutation',\n\t'action',\n\t'notify',\n\t'decision',\n\t'branch',\n] as const\n\nexport const APPROVAL_QUORUM_KINDS = ['count'] as const\n\nexport const APPROVAL_CALLBACK_KINDS = ['mutation', 'action'] as const\n\nexport const APPROVAL_DESCRIPTOR_SCHEMA_VERSION = 1 as const\n\nexport const APPROVAL_AUDIT_RETENTION_CATEGORY = 'approval-protocol'\nexport const MIN_APPROVAL_AUDIT_RETENTION_DAYS = 1\nexport const MAX_APPROVAL_AUDIT_RETENTION_DAYS = 3_650\nexport const MAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE = 100\n\nexport const MAX_APPROVAL_REFERENCE_LENGTH = 256\nexport const MAX_APPROVAL_NAME_LENGTH = 96\nexport const MAX_APPROVAL_REASON_LENGTH = 500\nexport const MAX_APPROVAL_CAPABILITIES = 32\nexport const MAX_APPROVAL_METADATA_ENTRIES = 32\nexport const MAX_APPROVAL_METADATA_KEY_LENGTH = 64\nexport const MAX_APPROVAL_METADATA_VALUE_LENGTH = 512\nexport const MAX_APPROVAL_WORKFLOW_STEPS = 32\nexport const MAX_APPROVAL_DECISIONS_PER_STEP = 8\n\nexport type ApprovalRunState = (typeof APPROVAL_RUN_STATES)[number]\nexport type ApprovalDecision = (typeof APPROVAL_DECISIONS)[number]\nexport type ApprovalExecutionState = (typeof APPROVAL_EXECUTION_STATES)[number]\nexport type ApprovalStepKind = (typeof APPROVAL_STEP_KINDS)[number]\nexport type ApprovalCallbackKind = (typeof APPROVAL_CALLBACK_KINDS)[number]\n"],"mappings":"AAAA,MAAa,EAAsB,CAClC,UACA,WACA,WACA,UACA,UACD,EAEa,EAAqB,CAAC,WAAY,UAAU,EAE5C,EAA4B,CACxC,aACA,YACA,WACA,QACD,EAEa,EAAsB,CAClC,WACA,SACA,SACA,WACA,QACD,EAEa,EAAwB,CAAC,OAAO,EAEhC,EAA0B,CAAC,WAAY,QAAQ,EAE/C,EAAqC,
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":[],"sources":["../../../src/components/approvals/constants.ts"],"sourcesContent":["export const APPROVAL_RUN_STATES = [\n\t'pending',\n\t'approved',\n\t'rejected',\n\t'expired',\n\t'canceled',\n] as const\n\nexport const APPROVAL_DECISIONS = ['approved', 'rejected'] as const\n\nexport const APPROVAL_EXECUTION_STATES = [\n\t'inProgress',\n\t'completed',\n\t'canceled',\n\t'failed',\n] as const\n\nexport const APPROVAL_STEP_KINDS = [\n\t'mutation',\n\t'action',\n\t'notify',\n\t'decision',\n\t'branch',\n] as const\n\nexport const APPROVAL_QUORUM_KINDS = ['count'] as const\n\nexport const APPROVAL_CALLBACK_KINDS = ['mutation', 'action'] as const\n\nexport const APPROVAL_DESCRIPTOR_SCHEMA_VERSION = 1 as const\n\n/** Version of the component-owned tables and indexes deployed by cvx-kit. */\nexport const APPROVAL_COMPONENT_SCHEMA_VERSION = 1 as const\n\n/** Indexes required by approval evidence reads and decision writes. */\nexport const APPROVAL_DECISION_HISTORY_INDEX =\n\t'by_runId_and_decidedAt' as const\nexport const APPROVAL_ACTOR_DECISION_INDEX =\n\t'by_runId_and_stepKey_and_actor_actorRef' as const\nexport const APPROVAL_REQUIRED_DECISION_INDEXES = [\n\tAPPROVAL_DECISION_HISTORY_INDEX,\n\tAPPROVAL_ACTOR_DECISION_INDEX,\n] as const\n\nexport const APPROVAL_AUDIT_RETENTION_CATEGORY = 'approval-protocol'\nexport const MIN_APPROVAL_AUDIT_RETENTION_DAYS = 1\nexport const MAX_APPROVAL_AUDIT_RETENTION_DAYS = 3_650\nexport const MAX_APPROVAL_AUDIT_CLEANUP_BATCH_SIZE = 100\n\nexport const MAX_APPROVAL_REFERENCE_LENGTH = 256\nexport const MAX_APPROVAL_NAME_LENGTH = 96\nexport const MAX_APPROVAL_REASON_LENGTH = 500\nexport const MAX_APPROVAL_CAPABILITIES = 32\nexport const MAX_APPROVAL_METADATA_ENTRIES = 32\nexport const MAX_APPROVAL_METADATA_KEY_LENGTH = 64\nexport const MAX_APPROVAL_METADATA_VALUE_LENGTH = 512\nexport const MAX_APPROVAL_WORKFLOW_STEPS = 32\nexport const MAX_APPROVAL_DECISIONS_PER_STEP = 8\n\nexport type ApprovalRunState = (typeof APPROVAL_RUN_STATES)[number]\nexport type ApprovalDecision = (typeof APPROVAL_DECISIONS)[number]\nexport type ApprovalExecutionState = (typeof APPROVAL_EXECUTION_STATES)[number]\nexport type ApprovalStepKind = (typeof APPROVAL_STEP_KINDS)[number]\nexport type ApprovalCallbackKind = (typeof APPROVAL_CALLBACK_KINDS)[number]\n"],"mappings":"AAAA,MAAa,EAAsB,CAClC,UACA,WACA,WACA,UACA,UACD,EAEa,EAAqB,CAAC,WAAY,UAAU,EAE5C,EAA4B,CACxC,aACA,YACA,WACA,QACD,EAEa,EAAsB,CAClC,WACA,SACA,SACA,WACA,QACD,EAEa,EAAwB,CAAC,OAAO,EAEhC,EAA0B,CAAC,WAAY,QAAQ,EAE/C,EAAqC,EAGrC,EAAoC,EAGpC,EACZ,yBACY,EACZ,0CACY,EAAqC,CACjD,EACA,CACD,EAEa,EAAoC,oBACpC,EAAoC,EACpC,EAAoC,KACpC,EAAwC,IAExC,EAAgC,IAChC,EAA2B,GAC3B,EAA6B,IAC7B,EAA4B,GAC5B,EAAgC,GAChC,EAAmC,GACnC,EAAqC,IACrC,EAA8B,GAC9B,EAAkC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{components as e,internal as t}from"./_generated/api.mjs";import{internalMutation as n,internalQuery as r,mutation as i,query as a}from"./_generated/server.mjs";import{
|
|
1
|
+
import{components as e,internal as t}from"./_generated/api.mjs";import{internalMutation as n,internalQuery as r,mutation as i,query as a}from"./_generated/server.mjs";import{APPROVAL_ACTOR_DECISION_INDEX as o,APPROVAL_DECISIONS as s,APPROVAL_DECISION_HISTORY_INDEX as c,APPROVAL_RUN_STATES as l}from"./constants.mjs";import{logApprovalTransition as u}from"./audit.mjs";import{approvalActor as d,approvalDecision as f,approvalReason as p}from"./validators.mjs";import{approvalDecisionEventName as m,evaluateDecisionOutcome as h}from"./workflow_steps.mjs";import{canTransitionApprovalRun as g,classifyPendingRunAt as _}from"./functions.mjs";import{zodToConvex as v}from"convex-helpers/server/zod4";import{v as y}from"convex/values";import{WorkflowManager as b}from"@convex-dev/workflow";const x=i({args:{runId:y.id(`approvalRuns`),decision:v(f),reason:y.optional(v(p)),actor:v(d),compatibilityKey:y.string()},returns:y.object({state:y.union(y.literal(l[0]),y.literal(l[1]),y.literal(l[2]),y.literal(l[3]),y.literal(l[4]))}),handler:async(e,t)=>{let n=await e.db.get(t.runId);if(!n)throw Error(`Approval request not found`);k(n.workflow.compatibilityKey,t.compatibilityKey);let r=n.workflow.steps.find(e=>e.kind===`decision`&&e.key===n.currentStepKey);if(!r||r.kind!==`decision`)throw Error(`Approval request is not waiting for a decision`);let i=await e.db.query(`approvalDecisions`).withIndex(o,e=>e.eq(`runId`,n._id).eq(`stepKey`,r.key).eq(`actor.actorRef`,t.actor.actorRef)).unique();if(i){if(i.decision!==t.decision)throw Error(`Actor already submitted a contradictory decision`);return{state:n.state}}if(n.state!==`pending`)throw Error(`Approval request is already ${n.state}`);if(n.expiresAt!==void 0&&_(Date.now(),n.expiresAt)===`expired`)return D(e,n,r.key);if(!r.decisions.includes(t.decision))throw Error(`Decision is not allowed by this workflow step`);if(r.makerChecker&&t.actor.actorRef===n.requester.actorRef)throw Error(`Requester cannot decide this approval step`);let a=Date.now();await e.db.insert(`approvalDecisions`,{runId:n._id,stepKey:r.key,actor:t.actor,decision:t.decision,...t.reason===void 0?{}:{reason:t.reason},decidedAt:a});let s=await e.db.query(`approvalDecisions`).withIndex(`by_runId_and_stepKey_and_decidedAt`,e=>e.eq(`runId`,n._id).eq(`stepKey`,r.key)).collect(),c=h(s.map(e=>({actorRef:e.actor.actorRef,decision:e.decision})),r.quorum.approvals);if(await u(e,{action:`approval.decision.${t.decision}`,actorRef:t.actor.actorRef,runId:n._id,resourceType:n.resourceType,resourceRef:n.resourceRef,transition:`${r.key}:${t.actor.actorRef}:${t.decision}`}),!c)return{state:`pending`};let l=M(n,r.key,c);return await O(e,n,r.key,c,l,{actorRef:t.actor.actorRef,decision:t.decision,...t.reason===void 0?{}:{reason:t.reason},decidedAt:a}),l?{state:c}:{state:`pending`}}}),S=a({args:{runId:y.id(`approvalRuns`)},returns:y.array(y.object({stepKey:y.string(),actorRef:y.string(),decision:v(f),reason:y.optional(v(p)),decidedAt:y.number()})),handler:(e,t)=>A(e,t.runId)}),C=r({args:{runId:y.id(`approvalRuns`),stepKey:y.string()},returns:y.array(y.object({stepKey:y.string(),actorRef:y.string(),decision:v(f),reason:y.optional(v(p)),decidedAt:y.number()})),handler:(e,t)=>j(e,t.runId,t.stepKey)}),w=n({args:{runId:y.id(`approvalRuns`),stepKey:y.string(),workflowId:y.string(),expiresAfterMs:y.optional(y.number())},returns:y.object({state:y.union(y.literal(l[0]),y.literal(l[1]),y.literal(l[2]),y.literal(l[3]),y.literal(l[4])),expiresAt:y.optional(y.number())}),handler:async(e,n)=>{let r=await e.db.get(n.runId);if(!r)throw Error(`Approval request not found`);if(r.workflowId!==n.workflowId)throw Error(`Approval workflow linkage is incomplete`);if(r.state!==`pending`)return{state:r.state,expiresAt:r.expiresAt};let i=Number(r.metadata?.approvalExpiresAt),a=Number.isFinite(i)?i:n.expiresAfterMs===void 0?void 0:Date.now()+n.expiresAfterMs;return await e.db.patch(r._id,{currentStepKey:n.stepKey,expiresAt:a,updatedAt:Date.now()}),await u(e,{action:`approval.waiting`,runId:r._id,resourceType:r.resourceType,resourceRef:r.resourceRef,transition:`${n.stepKey}:waiting`}),a!==void 0&&await e.scheduler.runAt(a,t.decisions.expire,{runId:r._id,stepKey:n.stepKey}),{state:`pending`,...a===void 0?{}:{expiresAt:a}}}}),T=n({args:{runId:y.id(`approvalRuns`),stepKey:y.string()},returns:y.object({state:y.union(y.literal(`missing`),y.literal(l[0]),y.literal(l[1]),y.literal(l[2]),y.literal(l[3]),y.literal(l[4]))}),handler:async(e,t)=>{let n=await e.db.get(t.runId);return n?n.state!==`pending`||n.currentStepKey!==t.stepKey||n.expiresAt===void 0||_(Date.now(),n.expiresAt)===`pending`?{state:n.state}:D(e,n,t.stepKey):{state:`missing`}}}),E=new b(e.workflow);async function D(e,t,n){if(!g(t.state,`expired`))throw Error(`Approval request cannot transition from ${t.state}`);let r=Date.now();if(await e.db.patch(t._id,{state:`expired`,expiresAt:void 0,updatedAt:r,terminalAt:r}),await u(e,{action:`approval.expired`,runId:t._id,resourceType:t.resourceType,resourceRef:t.resourceRef,transition:`${n}:expired`}),!t.workflowId)throw Error(`Approval workflow is not linked`);return await E.sendEvent(e,{workflowId:t.workflowId,name:m(t._id,n),validator:y.object({outcome:y.literal(l[3])}),value:{outcome:`expired`}}),{state:`expired`}}async function O(e,t,n,r,i,a){if(i){if(!g(t.state,r))throw Error(`Approval request cannot transition from ${t.state}`);let i=Date.now();await e.db.patch(t._id,{state:r,expiresAt:void 0,updatedAt:i,terminalAt:i}),await u(e,{action:`approval.${r}`,runId:t._id,resourceType:t.resourceType,resourceRef:t.resourceRef,transition:`${n}:terminal:${r}`})}if(!t.workflowId)throw Error(`Approval workflow is not linked`);await E.sendEvent(e,{workflowId:t.workflowId,name:m(t._id,n),validator:y.object({outcome:y.union(y.literal(s[0]),y.literal(s[1])),terminalEvidence:y.object({actorRef:y.string(),decision:v(f),reason:y.optional(v(p)),decidedAt:y.number()})}),value:{outcome:r,terminalEvidence:a}})}function k(e,t){if(e!==t)throw Error(`Approval workflow compatibility mismatch: expected ${t}, received ${e}`)}async function A(e,t){return(await e.db.query(`approvalDecisions`).withIndex(c,e=>e.eq(`runId`,t)).collect()).map(e=>({stepKey:e.stepKey,actorRef:e.actor.actorRef,decision:e.decision,...e.reason===void 0?{}:{reason:e.reason},decidedAt:e.decidedAt}))}async function j(e,t,n){return(await e.db.query(`approvalDecisions`).withIndex(`by_runId_and_stepKey_and_decidedAt`,e=>e.eq(`runId`,t).eq(`stepKey`,n)).collect()).map(e=>({stepKey:e.stepKey,actorRef:e.actor.actorRef,decision:e.decision,...e.reason===void 0?{}:{reason:e.reason},decidedAt:e.decidedAt}))}function M(e,t,n){if(n===`rejected`)return!0;let r=e.workflow.steps.findIndex(e=>e.kind===`decision`&&e.key===t);return!e.workflow.steps.slice(r+1).some(e=>e.kind===`decision`)}export{x as decide,w as enter,T as expire,S as list,C as listForWorkflow};
|
|
2
2
|
//# sourceMappingURL=decisions.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decisions.mjs","names":[],"sources":["../../../src/components/approvals/decisions.ts"],"sourcesContent":["import { WorkflowManager, type WorkflowId } from '@convex-dev/workflow'\nimport { zodToConvex } from 'convex-helpers/server/zod4'\nimport { v } from 'convex/values'\n\nimport { components, internal } from './_generated/api'\nimport {\n\tinternalMutation,\n\tinternalQuery,\n\tmutation,\n\tquery,\n\ttype QueryCtx,\n} from './_generated/server'\nimport { logApprovalTransition } from './audit'\nimport {\n\tAPPROVAL_DECISIONS,\n\tAPPROVAL_RUN_STATES,\n\ttype ApprovalRunState,\n} from './constants'\nimport { canTransitionApprovalRun, classifyPendingRunAt } from './functions'\nimport { approvalActor, approvalDecision, approvalReason } from './validators'\nimport {\n\tapprovalDecisionEventName,\n\tevaluateDecisionOutcome,\n} from './workflow_steps'\n\nexport const decide = mutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\tdecision: zodToConvex(approvalDecision),\n\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\tactor: zodToConvex(approvalActor),\n\t\tcompatibilityKey: v.string(),\n\t},\n\treturns: v.object({\n\t\tstate: v.union(\n\t\t\tv.literal(APPROVAL_RUN_STATES[0]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[1]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[2]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[3]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[4]),\n\t\t),\n\t}),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tconst step = run.workflow.steps.find(\n\t\t\t(candidate) =>\n\t\t\t\tcandidate.kind === 'decision' && candidate.key === run.currentStepKey,\n\t\t)\n\t\tif (!step || step.kind !== 'decision')\n\t\t\tthrow new Error('Approval request is not waiting for a decision')\n\n\t\tconst prior = await ctx.db\n\t\t\t.query('approvalDecisions')\n\t\t\t.withIndex('by_runId_and_stepKey_and_actor_actorRef', (query) =>\n\t\t\t\tquery\n\t\t\t\t\t.eq('runId', run._id)\n\t\t\t\t\t.eq('stepKey', step.key)\n\t\t\t\t\t.eq('actor.actorRef', input.actor.actorRef),\n\t\t\t)\n\t\t\t.unique()\n\t\tif (prior) {\n\t\t\tif (prior.decision !== input.decision)\n\t\t\t\tthrow new Error('Actor already submitted a contradictory decision')\n\t\t\treturn {\n\t\t\t\tstate: run.state as 'pending' | 'approved' | 'rejected' | 'expired',\n\t\t\t}\n\t\t}\n\t\tif (run.state !== 'pending')\n\t\t\tthrow new Error(`Approval request is already ${run.state}`)\n\t\tif (\n\t\t\trun.expiresAt !== undefined &&\n\t\t\tclassifyPendingRunAt(Date.now(), run.expiresAt) === 'expired'\n\t\t)\n\t\t\treturn claimExpiry(ctx, run, step.key)\n\t\tif (!step.decisions.includes(input.decision))\n\t\t\tthrow new Error('Decision is not allowed by this workflow step')\n\t\tif (step.makerChecker && input.actor.actorRef === run.requester.actorRef)\n\t\t\tthrow new Error('Requester cannot decide this approval step')\n\n\t\tconst decidedAt = Date.now()\n\t\tawait ctx.db.insert('approvalDecisions', {\n\t\t\trunId: run._id,\n\t\t\tstepKey: step.key,\n\t\t\tactor: input.actor,\n\t\t\tdecision: input.decision,\n\t\t\t...(input.reason === undefined ? {} : { reason: input.reason }),\n\t\t\tdecidedAt,\n\t\t})\n\t\tconst evidence = await ctx.db\n\t\t\t.query('approvalDecisions')\n\t\t\t.withIndex('by_runId_and_stepKey_and_decidedAt', (query) =>\n\t\t\t\tquery.eq('runId', run._id).eq('stepKey', step.key),\n\t\t\t)\n\t\t\t.collect()\n\t\tconst outcome = evaluateDecisionOutcome(\n\t\t\tevidence.map((item) => ({\n\t\t\t\tactorRef: item.actor.actorRef,\n\t\t\t\tdecision: item.decision,\n\t\t\t})),\n\t\t\tstep.quorum.approvals,\n\t\t)\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: `approval.decision.${input.decision}`,\n\t\t\tactorRef: input.actor.actorRef,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `${step.key}:${input.actor.actorRef}:${input.decision}`,\n\t\t})\n\t\tif (!outcome) return { state: 'pending' as const }\n\t\tconst terminal = isTerminalDecision(run, step.key, outcome)\n\t\tawait finishDecision(ctx, run, step.key, outcome, terminal, {\n\t\t\tactorRef: input.actor.actorRef,\n\t\t\tdecision: input.decision,\n\t\t\t...(input.reason === undefined ? {} : { reason: input.reason }),\n\t\t\tdecidedAt,\n\t\t})\n\t\treturn terminal ? { state: outcome } : { state: 'pending' as const }\n\t},\n})\n\nexport const list = query({\n\targs: { runId: v.id('approvalRuns') },\n\treturns: v.array(\n\t\tv.object({\n\t\t\tstepKey: v.string(),\n\t\t\tactorRef: v.string(),\n\t\t\tdecision: zodToConvex(approvalDecision),\n\t\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\t\tdecidedAt: v.number(),\n\t\t}),\n\t),\n\thandler: (ctx, input) => listDecisionEvidence(ctx, input.runId),\n})\n\nexport const listForWorkflow = internalQuery({\n\targs: { runId: v.id('approvalRuns'), stepKey: v.string() },\n\treturns: v.array(\n\t\tv.object({\n\t\t\tstepKey: v.string(),\n\t\t\tactorRef: v.string(),\n\t\t\tdecision: zodToConvex(approvalDecision),\n\t\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\t\tdecidedAt: v.number(),\n\t\t}),\n\t),\n\thandler: (ctx, input) =>\n\t\tlistDecisionEvidenceForStep(ctx, input.runId, input.stepKey),\n})\n\nexport const enter = internalMutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\tstepKey: v.string(),\n\t\tworkflowId: v.string(),\n\t\texpiresAfterMs: v.optional(v.number()),\n\t},\n\treturns: v.object({\n\t\tstate: v.union(\n\t\t\tv.literal(APPROVAL_RUN_STATES[0]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[1]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[2]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[3]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[4]),\n\t\t),\n\t\texpiresAt: v.optional(v.number()),\n\t}),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tif (run.workflowId !== input.workflowId)\n\t\t\tthrow new Error('Approval workflow linkage is incomplete')\n\t\tif (run.state !== 'pending')\n\t\t\treturn {\n\t\t\t\tstate: run.state as ApprovalRunState,\n\t\t\t\texpiresAt: run.expiresAt,\n\t\t\t}\n\t\tconst configuredExpiresAt = Number(run.metadata?.approvalExpiresAt)\n\t\tconst expiresAt = Number.isFinite(configuredExpiresAt)\n\t\t\t? configuredExpiresAt\n\t\t\t: input.expiresAfterMs === undefined\n\t\t\t\t? undefined\n\t\t\t\t: Date.now() + input.expiresAfterMs\n\t\tawait ctx.db.patch(run._id, {\n\t\t\tcurrentStepKey: input.stepKey,\n\t\t\texpiresAt,\n\t\t\tupdatedAt: Date.now(),\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: 'approval.waiting',\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `${input.stepKey}:waiting`,\n\t\t})\n\t\tif (expiresAt !== undefined)\n\t\t\tawait ctx.scheduler.runAt(expiresAt, internal.decisions.expire, {\n\t\t\t\trunId: run._id,\n\t\t\t\tstepKey: input.stepKey,\n\t\t\t})\n\t\treturn {\n\t\t\tstate: 'pending' as const,\n\t\t\t...(expiresAt === undefined ? {} : { expiresAt }),\n\t\t}\n\t},\n})\n\nexport const expire = internalMutation({\n\targs: { runId: v.id('approvalRuns'), stepKey: v.string() },\n\treturns: v.object({\n\t\tstate: v.union(\n\t\t\tv.literal('missing'),\n\t\t\tv.literal(APPROVAL_RUN_STATES[0]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[1]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[2]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[3]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[4]),\n\t\t),\n\t}),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) return { state: 'missing' as const }\n\t\tif (\n\t\t\trun.state !== 'pending' ||\n\t\t\trun.currentStepKey !== input.stepKey ||\n\t\t\trun.expiresAt === undefined ||\n\t\t\tclassifyPendingRunAt(Date.now(), run.expiresAt) === 'pending'\n\t\t)\n\t\t\treturn { state: run.state as ApprovalRunState }\n\t\treturn claimExpiry(ctx, run, input.stepKey)\n\t},\n})\n\nconst approvalWorkflow = new WorkflowManager(components.workflow)\n\nasync function claimExpiry(\n\tctx: import('./_generated/server').MutationCtx,\n\trun: import('./_generated/dataModel').Doc<'approvalRuns'>,\n\tstepKey: string,\n): Promise<{ state: 'expired' }> {\n\tif (!canTransitionApprovalRun(run.state, 'expired'))\n\t\tthrow new Error(`Approval request cannot transition from ${run.state}`)\n\tconst now = Date.now()\n\tawait ctx.db.patch(run._id, {\n\t\tstate: 'expired',\n\t\texpiresAt: undefined,\n\t\tupdatedAt: now,\n\t\tterminalAt: now,\n\t})\n\tawait logApprovalTransition(ctx, {\n\t\taction: 'approval.expired',\n\t\trunId: run._id,\n\t\tresourceType: run.resourceType,\n\t\tresourceRef: run.resourceRef,\n\t\ttransition: `${stepKey}:expired`,\n\t})\n\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\tawait approvalWorkflow.sendEvent(ctx, {\n\t\tworkflowId: run.workflowId as WorkflowId,\n\t\tname: approvalDecisionEventName(run._id, stepKey),\n\t\tvalidator: v.object({ outcome: v.literal(APPROVAL_RUN_STATES[3]) }),\n\t\tvalue: { outcome: 'expired' },\n\t})\n\treturn { state: 'expired' }\n}\n\nasync function finishDecision(\n\tctx: import('./_generated/server').MutationCtx,\n\trun: import('./_generated/dataModel').Doc<'approvalRuns'>,\n\tstepKey: string,\n\toutcome: 'approved' | 'rejected',\n\tterminal: boolean,\n\tterminalEvidence: {\n\t\tactorRef: string\n\t\tdecision: 'approved' | 'rejected'\n\t\treason?: string\n\t\tdecidedAt: number\n\t},\n): Promise<void> {\n\tif (terminal) {\n\t\tif (!canTransitionApprovalRun(run.state, outcome))\n\t\t\tthrow new Error(`Approval request cannot transition from ${run.state}`)\n\t\tconst now = Date.now()\n\t\tawait ctx.db.patch(run._id, {\n\t\t\tstate: outcome,\n\t\t\texpiresAt: undefined,\n\t\t\tupdatedAt: now,\n\t\t\tterminalAt: now,\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: `approval.${outcome}`,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `${stepKey}:terminal:${outcome}`,\n\t\t})\n\t}\n\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\tawait approvalWorkflow.sendEvent(ctx, {\n\t\tworkflowId: run.workflowId as WorkflowId,\n\t\tname: approvalDecisionEventName(run._id, stepKey),\n\t\tvalidator: v.object({\n\t\t\toutcome: v.union(\n\t\t\t\tv.literal(APPROVAL_DECISIONS[0]),\n\t\t\t\tv.literal(APPROVAL_DECISIONS[1]),\n\t\t\t),\n\t\t\tterminalEvidence: v.object({\n\t\t\t\tactorRef: v.string(),\n\t\t\t\tdecision: zodToConvex(approvalDecision),\n\t\t\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\t\t\tdecidedAt: v.number(),\n\t\t\t}),\n\t\t}),\n\t\tvalue: { outcome, terminalEvidence },\n\t})\n}\n\nfunction assertCompatible(actual: string, expected: string): void {\n\tif (actual !== expected)\n\t\tthrow new Error(\n\t\t\t`Approval workflow compatibility mismatch: expected ${expected}, received ${actual}`,\n\t\t)\n}\n\nasync function listDecisionEvidence(\n\tctx: QueryCtx,\n\trunId: import('./_generated/dataModel').Id<'approvalRuns'>,\n) {\n\tconst decisions = await ctx.db\n\t\t.query('approvalDecisions')\n\t\t.withIndex('by_runId_and_decidedAt', (query) => query.eq('runId', runId))\n\t\t.collect()\n\treturn decisions.map((decision) => ({\n\t\tstepKey: decision.stepKey,\n\t\tactorRef: decision.actor.actorRef,\n\t\tdecision: decision.decision,\n\t\t...(decision.reason === undefined ? {} : { reason: decision.reason }),\n\t\tdecidedAt: decision.decidedAt,\n\t}))\n}\n\nasync function listDecisionEvidenceForStep(\n\tctx: QueryCtx,\n\trunId: import('./_generated/dataModel').Id<'approvalRuns'>,\n\tstepKey: string,\n) {\n\tconst decisions = await ctx.db\n\t\t.query('approvalDecisions')\n\t\t.withIndex('by_runId_and_stepKey_and_decidedAt', (query) =>\n\t\t\tquery.eq('runId', runId).eq('stepKey', stepKey),\n\t\t)\n\t\t.collect()\n\treturn decisions.map((decision) => ({\n\t\tstepKey: decision.stepKey,\n\t\tactorRef: decision.actor.actorRef,\n\t\tdecision: decision.decision,\n\t\t...(decision.reason === undefined ? {} : { reason: decision.reason }),\n\t\tdecidedAt: decision.decidedAt,\n\t}))\n}\n\nfunction isTerminalDecision(\n\trun: import('./_generated/dataModel').Doc<'approvalRuns'>,\n\tstepKey: string,\n\toutcome: 'approved' | 'rejected',\n): boolean {\n\tif (outcome === 'rejected') return true\n\tconst currentIndex = run.workflow.steps.findIndex(\n\t\t(step) => step.kind === 'decision' && step.key === stepKey,\n\t)\n\treturn !run.workflow.steps\n\t\t.slice(currentIndex + 1)\n\t\t.some((step) => step.kind === 'decision')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"decisions.mjs","names":[],"sources":["../../../src/components/approvals/decisions.ts"],"sourcesContent":["import { WorkflowManager, type WorkflowId } from '@convex-dev/workflow'\nimport { zodToConvex } from 'convex-helpers/server/zod4'\nimport { v } from 'convex/values'\n\nimport { components, internal } from './_generated/api'\nimport {\n\tinternalMutation,\n\tinternalQuery,\n\tmutation,\n\tquery,\n\ttype QueryCtx,\n} from './_generated/server'\nimport { logApprovalTransition } from './audit'\nimport {\n\tAPPROVAL_ACTOR_DECISION_INDEX,\n\tAPPROVAL_DECISION_HISTORY_INDEX,\n\tAPPROVAL_DECISIONS,\n\tAPPROVAL_RUN_STATES,\n\ttype ApprovalRunState,\n} from './constants'\nimport { canTransitionApprovalRun, classifyPendingRunAt } from './functions'\nimport { approvalActor, approvalDecision, approvalReason } from './validators'\nimport {\n\tapprovalDecisionEventName,\n\tevaluateDecisionOutcome,\n} from './workflow_steps'\n\nexport const decide = mutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\tdecision: zodToConvex(approvalDecision),\n\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\tactor: zodToConvex(approvalActor),\n\t\tcompatibilityKey: v.string(),\n\t},\n\treturns: v.object({\n\t\tstate: v.union(\n\t\t\tv.literal(APPROVAL_RUN_STATES[0]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[1]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[2]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[3]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[4]),\n\t\t),\n\t}),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tconst step = run.workflow.steps.find(\n\t\t\t(candidate) =>\n\t\t\t\tcandidate.kind === 'decision' && candidate.key === run.currentStepKey,\n\t\t)\n\t\tif (!step || step.kind !== 'decision')\n\t\t\tthrow new Error('Approval request is not waiting for a decision')\n\n\t\tconst prior = await ctx.db\n\t\t\t.query('approvalDecisions')\n\t\t\t.withIndex(APPROVAL_ACTOR_DECISION_INDEX, (query) =>\n\t\t\t\tquery\n\t\t\t\t\t.eq('runId', run._id)\n\t\t\t\t\t.eq('stepKey', step.key)\n\t\t\t\t\t.eq('actor.actorRef', input.actor.actorRef),\n\t\t\t)\n\t\t\t.unique()\n\t\tif (prior) {\n\t\t\tif (prior.decision !== input.decision)\n\t\t\t\tthrow new Error('Actor already submitted a contradictory decision')\n\t\t\treturn {\n\t\t\t\tstate: run.state as 'pending' | 'approved' | 'rejected' | 'expired',\n\t\t\t}\n\t\t}\n\t\tif (run.state !== 'pending')\n\t\t\tthrow new Error(`Approval request is already ${run.state}`)\n\t\tif (\n\t\t\trun.expiresAt !== undefined &&\n\t\t\tclassifyPendingRunAt(Date.now(), run.expiresAt) === 'expired'\n\t\t)\n\t\t\treturn claimExpiry(ctx, run, step.key)\n\t\tif (!step.decisions.includes(input.decision))\n\t\t\tthrow new Error('Decision is not allowed by this workflow step')\n\t\tif (step.makerChecker && input.actor.actorRef === run.requester.actorRef)\n\t\t\tthrow new Error('Requester cannot decide this approval step')\n\n\t\tconst decidedAt = Date.now()\n\t\tawait ctx.db.insert('approvalDecisions', {\n\t\t\trunId: run._id,\n\t\t\tstepKey: step.key,\n\t\t\tactor: input.actor,\n\t\t\tdecision: input.decision,\n\t\t\t...(input.reason === undefined ? {} : { reason: input.reason }),\n\t\t\tdecidedAt,\n\t\t})\n\t\tconst evidence = await ctx.db\n\t\t\t.query('approvalDecisions')\n\t\t\t.withIndex('by_runId_and_stepKey_and_decidedAt', (query) =>\n\t\t\t\tquery.eq('runId', run._id).eq('stepKey', step.key),\n\t\t\t)\n\t\t\t.collect()\n\t\tconst outcome = evaluateDecisionOutcome(\n\t\t\tevidence.map((item) => ({\n\t\t\t\tactorRef: item.actor.actorRef,\n\t\t\t\tdecision: item.decision,\n\t\t\t})),\n\t\t\tstep.quorum.approvals,\n\t\t)\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: `approval.decision.${input.decision}`,\n\t\t\tactorRef: input.actor.actorRef,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `${step.key}:${input.actor.actorRef}:${input.decision}`,\n\t\t})\n\t\tif (!outcome) return { state: 'pending' as const }\n\t\tconst terminal = isTerminalDecision(run, step.key, outcome)\n\t\tawait finishDecision(ctx, run, step.key, outcome, terminal, {\n\t\t\tactorRef: input.actor.actorRef,\n\t\t\tdecision: input.decision,\n\t\t\t...(input.reason === undefined ? {} : { reason: input.reason }),\n\t\t\tdecidedAt,\n\t\t})\n\t\treturn terminal ? { state: outcome } : { state: 'pending' as const }\n\t},\n})\n\nexport const list = query({\n\targs: { runId: v.id('approvalRuns') },\n\treturns: v.array(\n\t\tv.object({\n\t\t\tstepKey: v.string(),\n\t\t\tactorRef: v.string(),\n\t\t\tdecision: zodToConvex(approvalDecision),\n\t\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\t\tdecidedAt: v.number(),\n\t\t}),\n\t),\n\thandler: (ctx, input) => listDecisionEvidence(ctx, input.runId),\n})\n\nexport const listForWorkflow = internalQuery({\n\targs: { runId: v.id('approvalRuns'), stepKey: v.string() },\n\treturns: v.array(\n\t\tv.object({\n\t\t\tstepKey: v.string(),\n\t\t\tactorRef: v.string(),\n\t\t\tdecision: zodToConvex(approvalDecision),\n\t\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\t\tdecidedAt: v.number(),\n\t\t}),\n\t),\n\thandler: (ctx, input) =>\n\t\tlistDecisionEvidenceForStep(ctx, input.runId, input.stepKey),\n})\n\nexport const enter = internalMutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\tstepKey: v.string(),\n\t\tworkflowId: v.string(),\n\t\texpiresAfterMs: v.optional(v.number()),\n\t},\n\treturns: v.object({\n\t\tstate: v.union(\n\t\t\tv.literal(APPROVAL_RUN_STATES[0]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[1]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[2]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[3]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[4]),\n\t\t),\n\t\texpiresAt: v.optional(v.number()),\n\t}),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tif (run.workflowId !== input.workflowId)\n\t\t\tthrow new Error('Approval workflow linkage is incomplete')\n\t\tif (run.state !== 'pending')\n\t\t\treturn {\n\t\t\t\tstate: run.state as ApprovalRunState,\n\t\t\t\texpiresAt: run.expiresAt,\n\t\t\t}\n\t\tconst configuredExpiresAt = Number(run.metadata?.approvalExpiresAt)\n\t\tconst expiresAt = Number.isFinite(configuredExpiresAt)\n\t\t\t? configuredExpiresAt\n\t\t\t: input.expiresAfterMs === undefined\n\t\t\t\t? undefined\n\t\t\t\t: Date.now() + input.expiresAfterMs\n\t\tawait ctx.db.patch(run._id, {\n\t\t\tcurrentStepKey: input.stepKey,\n\t\t\texpiresAt,\n\t\t\tupdatedAt: Date.now(),\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: 'approval.waiting',\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `${input.stepKey}:waiting`,\n\t\t})\n\t\tif (expiresAt !== undefined)\n\t\t\tawait ctx.scheduler.runAt(expiresAt, internal.decisions.expire, {\n\t\t\t\trunId: run._id,\n\t\t\t\tstepKey: input.stepKey,\n\t\t\t})\n\t\treturn {\n\t\t\tstate: 'pending' as const,\n\t\t\t...(expiresAt === undefined ? {} : { expiresAt }),\n\t\t}\n\t},\n})\n\nexport const expire = internalMutation({\n\targs: { runId: v.id('approvalRuns'), stepKey: v.string() },\n\treturns: v.object({\n\t\tstate: v.union(\n\t\t\tv.literal('missing'),\n\t\t\tv.literal(APPROVAL_RUN_STATES[0]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[1]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[2]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[3]),\n\t\t\tv.literal(APPROVAL_RUN_STATES[4]),\n\t\t),\n\t}),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) return { state: 'missing' as const }\n\t\tif (\n\t\t\trun.state !== 'pending' ||\n\t\t\trun.currentStepKey !== input.stepKey ||\n\t\t\trun.expiresAt === undefined ||\n\t\t\tclassifyPendingRunAt(Date.now(), run.expiresAt) === 'pending'\n\t\t)\n\t\t\treturn { state: run.state as ApprovalRunState }\n\t\treturn claimExpiry(ctx, run, input.stepKey)\n\t},\n})\n\nconst approvalWorkflow = new WorkflowManager(components.workflow)\n\nasync function claimExpiry(\n\tctx: import('./_generated/server').MutationCtx,\n\trun: import('./_generated/dataModel').Doc<'approvalRuns'>,\n\tstepKey: string,\n): Promise<{ state: 'expired' }> {\n\tif (!canTransitionApprovalRun(run.state, 'expired'))\n\t\tthrow new Error(`Approval request cannot transition from ${run.state}`)\n\tconst now = Date.now()\n\tawait ctx.db.patch(run._id, {\n\t\tstate: 'expired',\n\t\texpiresAt: undefined,\n\t\tupdatedAt: now,\n\t\tterminalAt: now,\n\t})\n\tawait logApprovalTransition(ctx, {\n\t\taction: 'approval.expired',\n\t\trunId: run._id,\n\t\tresourceType: run.resourceType,\n\t\tresourceRef: run.resourceRef,\n\t\ttransition: `${stepKey}:expired`,\n\t})\n\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\tawait approvalWorkflow.sendEvent(ctx, {\n\t\tworkflowId: run.workflowId as WorkflowId,\n\t\tname: approvalDecisionEventName(run._id, stepKey),\n\t\tvalidator: v.object({ outcome: v.literal(APPROVAL_RUN_STATES[3]) }),\n\t\tvalue: { outcome: 'expired' },\n\t})\n\treturn { state: 'expired' }\n}\n\nasync function finishDecision(\n\tctx: import('./_generated/server').MutationCtx,\n\trun: import('./_generated/dataModel').Doc<'approvalRuns'>,\n\tstepKey: string,\n\toutcome: 'approved' | 'rejected',\n\tterminal: boolean,\n\tterminalEvidence: {\n\t\tactorRef: string\n\t\tdecision: 'approved' | 'rejected'\n\t\treason?: string\n\t\tdecidedAt: number\n\t},\n): Promise<void> {\n\tif (terminal) {\n\t\tif (!canTransitionApprovalRun(run.state, outcome))\n\t\t\tthrow new Error(`Approval request cannot transition from ${run.state}`)\n\t\tconst now = Date.now()\n\t\tawait ctx.db.patch(run._id, {\n\t\t\tstate: outcome,\n\t\t\texpiresAt: undefined,\n\t\t\tupdatedAt: now,\n\t\t\tterminalAt: now,\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: `approval.${outcome}`,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `${stepKey}:terminal:${outcome}`,\n\t\t})\n\t}\n\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\tawait approvalWorkflow.sendEvent(ctx, {\n\t\tworkflowId: run.workflowId as WorkflowId,\n\t\tname: approvalDecisionEventName(run._id, stepKey),\n\t\tvalidator: v.object({\n\t\t\toutcome: v.union(\n\t\t\t\tv.literal(APPROVAL_DECISIONS[0]),\n\t\t\t\tv.literal(APPROVAL_DECISIONS[1]),\n\t\t\t),\n\t\t\tterminalEvidence: v.object({\n\t\t\t\tactorRef: v.string(),\n\t\t\t\tdecision: zodToConvex(approvalDecision),\n\t\t\t\treason: v.optional(zodToConvex(approvalReason)),\n\t\t\t\tdecidedAt: v.number(),\n\t\t\t}),\n\t\t}),\n\t\tvalue: { outcome, terminalEvidence },\n\t})\n}\n\nfunction assertCompatible(actual: string, expected: string): void {\n\tif (actual !== expected)\n\t\tthrow new Error(\n\t\t\t`Approval workflow compatibility mismatch: expected ${expected}, received ${actual}`,\n\t\t)\n}\n\nasync function listDecisionEvidence(\n\tctx: QueryCtx,\n\trunId: import('./_generated/dataModel').Id<'approvalRuns'>,\n) {\n\tconst decisions = await ctx.db\n\t\t.query('approvalDecisions')\n\t\t.withIndex(APPROVAL_DECISION_HISTORY_INDEX, (query) =>\n\t\t\tquery.eq('runId', runId),\n\t\t)\n\t\t.collect()\n\treturn decisions.map((decision) => ({\n\t\tstepKey: decision.stepKey,\n\t\tactorRef: decision.actor.actorRef,\n\t\tdecision: decision.decision,\n\t\t...(decision.reason === undefined ? {} : { reason: decision.reason }),\n\t\tdecidedAt: decision.decidedAt,\n\t}))\n}\n\nasync function listDecisionEvidenceForStep(\n\tctx: QueryCtx,\n\trunId: import('./_generated/dataModel').Id<'approvalRuns'>,\n\tstepKey: string,\n) {\n\tconst decisions = await ctx.db\n\t\t.query('approvalDecisions')\n\t\t.withIndex('by_runId_and_stepKey_and_decidedAt', (query) =>\n\t\t\tquery.eq('runId', runId).eq('stepKey', stepKey),\n\t\t)\n\t\t.collect()\n\treturn decisions.map((decision) => ({\n\t\tstepKey: decision.stepKey,\n\t\tactorRef: decision.actor.actorRef,\n\t\tdecision: decision.decision,\n\t\t...(decision.reason === undefined ? {} : { reason: decision.reason }),\n\t\tdecidedAt: decision.decidedAt,\n\t}))\n}\n\nfunction isTerminalDecision(\n\trun: import('./_generated/dataModel').Doc<'approvalRuns'>,\n\tstepKey: string,\n\toutcome: 'approved' | 'rejected',\n): boolean {\n\tif (outcome === 'rejected') return true\n\tconst currentIndex = run.workflow.steps.findIndex(\n\t\t(step) => step.kind === 'decision' && step.key === stepKey,\n\t)\n\treturn !run.workflow.steps\n\t\t.slice(currentIndex + 1)\n\t\t.some((step) => step.kind === 'decision')\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare namespace health_d_exports {
|
|
2
|
+
export { check };
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Verifies that the package's component schema and required decision indexes
|
|
6
|
+
* were deployed. A missing schema fails with a cvx-kit-specific diagnostic.
|
|
7
|
+
*/
|
|
8
|
+
declare const check: import("convex/server").RegisteredQuery<"public", {}, Promise<{
|
|
9
|
+
status: 'ready';
|
|
10
|
+
schemaVersion: 1;
|
|
11
|
+
requiredIndexes: ("by_runId_and_decidedAt" | "by_runId_and_stepKey_and_actor_actorRef")[];
|
|
12
|
+
}>>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { check, health_d_exports };
|
|
15
|
+
//# sourceMappingURL=health.d.mts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{query as e}from"./_generated/server.mjs";import{APPROVAL_REQUIRED_DECISION_INDEXES as t}from"./constants.mjs";import{v as n}from"convex/values";const r=e({args:{},returns:n.object({status:n.literal(`ready`),schemaVersion:n.literal(1),requiredIndexes:n.array(n.string())}),handler:async e=>{try{for(let n of t)await e.db.query(`approvalDecisions`).withIndex(n).take(1)}catch(e){throw Error(`cvx-kit approvals schema v1 is not installed with its required indexes. Remove consumer patches, reinstall cvx-kit, and deploy again. Cause: ${e instanceof Error?e.message:String(e)}`)}return{status:`ready`,schemaVersion:1,requiredIndexes:[...t]}}});export{r as check};
|
|
2
|
+
//# sourceMappingURL=health.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.mjs","names":[],"sources":["../../../src/components/approvals/health.ts"],"sourcesContent":["import { v } from 'convex/values'\n\nimport { query } from './_generated/server'\nimport {\n\tAPPROVAL_COMPONENT_SCHEMA_VERSION,\n\tAPPROVAL_REQUIRED_DECISION_INDEXES,\n} from './constants'\n\n/**\n * Verifies that the package's component schema and required decision indexes\n * were deployed. A missing schema fails with a cvx-kit-specific diagnostic.\n */\nexport const check = query({\n\targs: {},\n\treturns: v.object({\n\t\tstatus: v.literal('ready'),\n\t\tschemaVersion: v.literal(APPROVAL_COMPONENT_SCHEMA_VERSION),\n\t\trequiredIndexes: v.array(v.string()),\n\t}),\n\thandler: async (ctx) => {\n\t\ttry {\n\t\t\tfor (const index of APPROVAL_REQUIRED_DECISION_INDEXES) {\n\t\t\t\tawait ctx.db.query('approvalDecisions').withIndex(index).take(1)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`cvx-kit approvals schema v${APPROVAL_COMPONENT_SCHEMA_VERSION} is not installed with its required indexes. Remove consumer patches, reinstall cvx-kit, and deploy again. Cause: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t)\n\t\t}\n\n\t\treturn {\n\t\t\tstatus: 'ready' as const,\n\t\t\tschemaVersion: APPROVAL_COMPONENT_SCHEMA_VERSION,\n\t\t\trequiredIndexes: [...APPROVAL_REQUIRED_DECISION_INDEXES],\n\t\t}\n\t},\n})\n"],"mappings":"uJAYA,MAAa,EAAQ,EAAM,CAC1B,KAAM,CAAC,EACP,QAAS,EAAE,OAAO,CACjB,OAAQ,EAAE,QAAQ,OAAO,EACzB,cAAe,EAAE,QAAA,CAAyC,EAC1D,gBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,CACpC,CAAC,EACD,QAAS,KAAO,IAAQ,CACvB,GAAI,CACH,IAAK,IAAM,KAAS,EACnB,MAAM,EAAI,GAAG,MAAM,mBAAmB,CAAC,CAAC,UAAU,CAAK,CAAC,CAAC,KAAK,CAAC,CAEjE,OAAS,EAAO,CACf,MAAU,MACT,gJAAmL,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GACzO,CACD,CAEA,MAAO,CACN,OAAQ,QACR,cAAA,EACA,gBAAiB,CAAC,GAAG,CAAkC,CACxD,CACD,CACD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{components as e,internal as t}from"./_generated/api.mjs";import{internalMutation as n,internalQuery as r,mutation as i,query as a}from"./_generated/server.mjs";import{APPROVAL_EXECUTION_STATES as o,APPROVAL_RUN_STATES as s}from"./constants.mjs";import{logApprovalTransition as c}from"./audit.mjs";import{approvalActor as l,approvalMetadata as u,approvalName as d,approvalReference as f,approvalRunDocument as p,approvalRunState as m,approvalWorkflowDescriptor as h}from"./validators.mjs";import{canTransitionApprovalRun as g}from"./functions.mjs";import{zodToConvex as
|
|
1
|
+
import{components as e,internal as t}from"./_generated/api.mjs";import{internalMutation as n,internalQuery as r,mutation as i,query as a}from"./_generated/server.mjs";import{APPROVAL_EXECUTION_STATES as o,APPROVAL_RUN_STATES as s}from"./constants.mjs";import{logApprovalTransition as c}from"./audit.mjs";import{approvalActor as l,approvalMetadata as u,approvalName as d,approvalReference as f,approvalRunDocument as p,approvalRunState as m,approvalWorkflowDescriptor as h}from"./validators.mjs";import{canTransitionApprovalRun as g}from"./functions.mjs";import _ from"./schema.js";import{zodToConvex as v}from"convex-helpers/server/zod4";import{paginationOptsValidator as y,paginationResultValidator as b}from"convex/server";import{v as x}from"convex/values";import{WorkflowManager as S}from"@convex-dev/workflow";import{paginator as C}from"convex-helpers/server/pagination";const w=i({args:{scopeRef:v(f),resourceType:v(f),resourceRef:v(f),requester:v(l),metadata:x.optional(v(u)),workflow:v(h)},returns:x.object({runId:x.id(`approvalRuns`)}),handler:async(e,n)=>{let r=Date.now(),i=await e.db.insert(`approvalRuns`,{...n,state:`pending`,createdAt:r,updatedAt:r}),a=await j.start(e,t.workflow.run,{runId:i},{startAsync:!0});return await e.db.patch(i,{workflowId:a,updatedAt:Date.now()}),await c(e,{action:`approval.requested`,actorRef:n.requester.actorRef,runId:i,resourceType:n.resourceType,resourceRef:n.resourceRef,transition:`requested`}),{runId:i}}}),T=i({args:{runId:x.id(`approvalRuns`),actor:v(l),compatibilityKey:x.string()},returns:x.object({state:x.literal(s[4])}),handler:async(e,t)=>{let n=await e.db.get(t.runId);if(!n)throw Error(`Approval request not found`);if(I(n.workflow.compatibilityKey,t.compatibilityKey),n.state!==`pending`){if(n.state===`canceled`)return{state:`canceled`};throw Error(`Approval request is already ${n.state}`)}if(!n.workflowId)throw Error(`Approval workflow is not linked`);if(await j.cancel(e,n.workflowId),!g(n.state,`canceled`))throw Error(`Approval request cannot transition from ${n.state}`);let r=Date.now();return await e.db.patch(n._id,{state:`canceled`,expiresAt:void 0,updatedAt:r,terminalAt:r}),await c(e,{action:`approval.canceled`,actorRef:t.actor.actorRef,runId:n._id,resourceType:n.resourceType,resourceRef:n.resourceRef,transition:`canceled`}),{state:`canceled`}}}),E=i({args:{runId:x.id(`approvalRuns`),compatibilityKey:x.string()},returns:x.null(),handler:async(e,t)=>{let n=await e.db.get(t.runId);if(!n)throw Error(`Approval request not found`);if(I(n.workflow.compatibilityKey,t.compatibilityKey),!n.workflowId)throw Error(`Approval workflow is not linked`);if(!n.executionFailedStepKey)throw Error(`Approval workflow has no failed step to restart`);return await j.restart(e,n.workflowId,{from:n.executionFailedStepKey,startAsync:!0}),null}}),D=a({args:{runId:x.id(`approvalRuns`),compatibilityKey:x.string()},returns:x.union(x.null(),F()),handler:async(e,t)=>{let n=await e.db.get(t.runId);return n?(I(n.workflow.compatibilityKey,t.compatibilityKey),{run:n,execution:M(n.workflowId?await j.status(e,n.workflowId):null)}):null}}),O=a({args:{scopeRef:v(f),state:x.optional(v(m)),paginationOpts:y},returns:b(N()),handler:(e,t)=>C(e.db,_).query(`approvalRuns`).withIndex(`by_scopeRef_and_state`,e=>t.state===void 0?e.eq(`scopeRef`,t.scopeRef):e.eq(`scopeRef`,t.scopeRef).eq(`state`,t.state)).order(`desc`).paginate(t.paginationOpts)}),k=r({args:{runId:x.id(`approvalRuns`)},returns:x.union(x.null(),N()),handler:(e,t)=>e.db.get(t.runId)}),A=n({args:{runId:x.id(`approvalRuns`),outcome:x.union(x.literal(o[1]),x.literal(o[3])),failedStepKey:x.optional(v(d))},returns:x.null(),handler:async(e,t)=>{let n=await e.db.get(t.runId);if(!n)throw Error(`Approval request not found`);return await e.db.patch(n._id,{executionFailedStepKey:t.outcome===`failed`?t.failedStepKey:void 0,updatedAt:Date.now()}),await c(e,{action:`approval.execution.${t.outcome}`,runId:n._id,resourceType:n.resourceType,resourceRef:n.resourceRef,transition:`execution:${t.outcome}`,severity:t.outcome===`failed`?`error`:`info`}),null}}),j=new S(e.workflow);function M(e){if(!e)return null;switch(e.type){case`failed`:return{type:`failed`,error:e.error};case`inProgress`:case`completed`:case`canceled`:return{type:e.type}}}function N(){return x.object({_id:x.id(`approvalRuns`),_creationTime:x.number(),...v(p).fields})}function P(){return x.union(x.object({type:x.literal(o[0])}),x.object({type:x.literal(o[1])}),x.object({type:x.literal(o[2])}),x.object({type:x.literal(o[3]),error:x.string()}))}function F(){return x.object({run:N(),execution:x.union(x.null(),P())})}function I(e,t){if(e!==t)throw Error(`Approval workflow compatibility mismatch: expected ${t}, received ${e}`)}export{T as cancel,k as getForWorkflow,O as list,A as recordExecutionTerminal,E as restart,w as start,D as status};
|
|
2
2
|
//# sourceMappingURL=requests.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requests.mjs","names":[],"sources":["../../../src/components/approvals/requests.ts"],"sourcesContent":["import { WorkflowManager, type WorkflowId } from '@convex-dev/workflow'\nimport { zodToConvex } from 'convex-helpers/server/zod4'\nimport {\n\tpaginationOptsValidator,\n\tpaginationResultValidator,\n} from 'convex/server'\nimport { v } from 'convex/values'\n\nimport { components, internal } from './_generated/api'\nimport {\n\tinternalMutation,\n\tinternalQuery,\n\tmutation,\n\tquery,\n} from './_generated/server'\nimport { logApprovalTransition } from './audit'\nimport { APPROVAL_EXECUTION_STATES, APPROVAL_RUN_STATES } from './constants'\nimport { canTransitionApprovalRun } from './functions'\nimport {\n\tapprovalActor,\n\tapprovalMetadata,\n\tapprovalName,\n\tapprovalReference,\n\tapprovalRunDocument,\n\tapprovalRunState,\n\tapprovalWorkflowDescriptor,\n} from './validators'\n\nexport const start = mutation({\n\targs: {\n\t\tscopeRef: zodToConvex(approvalReference),\n\t\tresourceType: zodToConvex(approvalReference),\n\t\tresourceRef: zodToConvex(approvalReference),\n\t\trequester: zodToConvex(approvalActor),\n\t\tmetadata: v.optional(zodToConvex(approvalMetadata)),\n\t\tworkflow: zodToConvex(approvalWorkflowDescriptor),\n\t},\n\treturns: v.object({ runId: v.id('approvalRuns') }),\n\thandler: async (ctx, input) => {\n\t\tconst now = Date.now()\n\t\tconst runId = await ctx.db.insert('approvalRuns', {\n\t\t\t...input,\n\t\t\tstate: 'pending',\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t})\n\t\tconst workflowId: WorkflowId = await approvalWorkflow.start(\n\t\t\tctx,\n\t\t\tinternal.workflow.run,\n\t\t\t{ runId },\n\t\t\t{ startAsync: true },\n\t\t)\n\t\tawait ctx.db.patch(runId, { workflowId, updatedAt: Date.now() })\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: 'approval.requested',\n\t\t\tactorRef: input.requester.actorRef,\n\t\t\trunId,\n\t\t\tresourceType: input.resourceType,\n\t\t\tresourceRef: input.resourceRef,\n\t\t\ttransition: 'requested',\n\t\t})\n\t\treturn { runId }\n\t},\n})\n\nexport const cancel = mutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\tactor: zodToConvex(approvalActor),\n\t\tcompatibilityKey: v.string(),\n\t},\n\treturns: v.object({ state: v.literal(APPROVAL_RUN_STATES[4]) }),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tif (run.state !== 'pending') {\n\t\t\tif (run.state === 'canceled') return { state: 'canceled' as const }\n\t\t\tthrow new Error(`Approval request is already ${run.state}`)\n\t\t}\n\t\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\t\tawait approvalWorkflow.cancel(ctx, run.workflowId as WorkflowId)\n\t\tif (!canTransitionApprovalRun(run.state, 'canceled'))\n\t\t\tthrow new Error(`Approval request cannot transition from ${run.state}`)\n\t\tconst now = Date.now()\n\t\tawait ctx.db.patch(run._id, {\n\t\t\tstate: 'canceled',\n\t\t\texpiresAt: undefined,\n\t\t\tupdatedAt: now,\n\t\t\tterminalAt: now,\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: 'approval.canceled',\n\t\t\tactorRef: input.actor.actorRef,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: 'canceled',\n\t\t})\n\t\treturn { state: 'canceled' as const }\n\t},\n})\n\nexport const restart = mutation({\n\targs: { runId: v.id('approvalRuns'), compatibilityKey: v.string() },\n\treturns: v.null(),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\t\tif (!run.executionFailedStepKey)\n\t\t\tthrow new Error('Approval workflow has no failed step to restart')\n\t\tawait approvalWorkflow.restart(ctx, run.workflowId as WorkflowId, {\n\t\t\tfrom: run.executionFailedStepKey,\n\t\t\tstartAsync: true,\n\t\t})\n\t\treturn null\n\t},\n})\n\nexport const status = query({\n\targs: { runId: v.id('approvalRuns'), compatibilityKey: v.string() },\n\treturns: v.union(v.null(), approvalStatusValidator()),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) return null\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tconst workflowStatus = run.workflowId\n\t\t\t? await approvalWorkflow.status(ctx, run.workflowId as WorkflowId)\n\t\t\t: null\n\t\tconst execution = normalizeWorkflowStatus(workflowStatus)\n\t\treturn { run, execution }\n\t},\n})\n\nexport const list = query({\n\targs: {\n\t\tscopeRef: zodToConvex(approvalReference),\n\t\tstate: v.optional(zodToConvex(approvalRunState)),\n\t\tpaginationOpts: paginationOptsValidator,\n\t},\n\treturns: paginationResultValidator(approvalRunValidator()),\n\thandler: (ctx, input) =>\n\t\tctx.db\n\t\t\t.query('approvalRuns')\n\t\t\t.withIndex('by_scopeRef_and_state', (query) =>\n\t\t\t\tinput.state === undefined\n\t\t\t\t\t? query.eq('scopeRef', input.scopeRef)\n\t\t\t\t\t: query.eq('scopeRef', input.scopeRef).eq('state', input.state),\n\t\t\t)\n\t\t\t.order('desc')\n\t\t\t.paginate(input.paginationOpts),\n})\n\nexport const getForWorkflow = internalQuery({\n\targs: { runId: v.id('approvalRuns') },\n\treturns: v.union(v.null(), approvalRunValidator()),\n\thandler: (ctx, input) => ctx.db.get(input.runId),\n})\n\nexport const recordExecutionTerminal = internalMutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\toutcome: v.union(\n\t\t\tv.literal(APPROVAL_EXECUTION_STATES[1]),\n\t\t\tv.literal(APPROVAL_EXECUTION_STATES[3]),\n\t\t),\n\t\tfailedStepKey: v.optional(zodToConvex(approvalName)),\n\t},\n\treturns: v.null(),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tawait ctx.db.patch(run._id, {\n\t\t\texecutionFailedStepKey:\n\t\t\t\tinput.outcome === 'failed' ? input.failedStepKey : undefined,\n\t\t\tupdatedAt: Date.now(),\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: `approval.execution.${input.outcome}`,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `execution:${input.outcome}`,\n\t\t\tseverity: input.outcome === 'failed' ? 'error' : 'info',\n\t\t})\n\t\treturn null\n\t},\n})\n\nconst approvalWorkflow = new WorkflowManager(components.workflow)\n\nfunction normalizeWorkflowStatus(\n\tstatus: Awaited<ReturnType<typeof approvalWorkflow.status>> | null,\n) {\n\tif (!status) return null\n\tswitch (status.type) {\n\t\tcase 'failed':\n\t\t\treturn { type: 'failed' as const, error: status.error }\n\t\tcase 'inProgress':\n\t\tcase 'completed':\n\t\tcase 'canceled':\n\t\t\treturn { type: status.type }\n\t}\n}\n\nfunction approvalRunValidator() {\n\treturn v.object({\n\t\t_id: v.id('approvalRuns'),\n\t\t_creationTime: v.number(),\n\t\t...zodToConvex(approvalRunDocument).fields,\n\t})\n}\n\nfunction workflowStatusValidator() {\n\treturn v.union(\n\t\tv.object({ type: v.literal(APPROVAL_EXECUTION_STATES[0]) }),\n\t\tv.object({ type: v.literal(APPROVAL_EXECUTION_STATES[1]) }),\n\t\tv.object({ type: v.literal(APPROVAL_EXECUTION_STATES[2]) }),\n\t\tv.object({\n\t\t\ttype: v.literal(APPROVAL_EXECUTION_STATES[3]),\n\t\t\terror: v.string(),\n\t\t}),\n\t)\n}\n\nfunction approvalStatusValidator() {\n\treturn v.object({\n\t\trun: approvalRunValidator(),\n\t\texecution: v.union(v.null(), workflowStatusValidator()),\n\t})\n}\n\nfunction assertCompatible(actual: string, expected: string): void {\n\tif (actual !== expected)\n\t\tthrow new Error(\n\t\t\t`Approval workflow compatibility mismatch: expected ${expected}, received ${actual}`,\n\t\t)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"requests.mjs","names":["schema"],"sources":["../../../src/components/approvals/requests.ts"],"sourcesContent":["import { WorkflowManager, type WorkflowId } from '@convex-dev/workflow'\nimport { zodToConvex } from 'convex-helpers/server/zod4'\nimport { paginator } from 'convex-helpers/server/pagination'\nimport {\n\tpaginationOptsValidator,\n\tpaginationResultValidator,\n} from 'convex/server'\nimport { v } from 'convex/values'\n\nimport { components, internal } from './_generated/api'\nimport {\n\tinternalMutation,\n\tinternalQuery,\n\tmutation,\n\tquery,\n} from './_generated/server'\nimport { logApprovalTransition } from './audit'\nimport schema from './schema'\nimport { APPROVAL_EXECUTION_STATES, APPROVAL_RUN_STATES } from './constants'\nimport { canTransitionApprovalRun } from './functions'\nimport {\n\tapprovalActor,\n\tapprovalMetadata,\n\tapprovalName,\n\tapprovalReference,\n\tapprovalRunDocument,\n\tapprovalRunState,\n\tapprovalWorkflowDescriptor,\n} from './validators'\n\nexport const start = mutation({\n\targs: {\n\t\tscopeRef: zodToConvex(approvalReference),\n\t\tresourceType: zodToConvex(approvalReference),\n\t\tresourceRef: zodToConvex(approvalReference),\n\t\trequester: zodToConvex(approvalActor),\n\t\tmetadata: v.optional(zodToConvex(approvalMetadata)),\n\t\tworkflow: zodToConvex(approvalWorkflowDescriptor),\n\t},\n\treturns: v.object({ runId: v.id('approvalRuns') }),\n\thandler: async (ctx, input) => {\n\t\tconst now = Date.now()\n\t\tconst runId = await ctx.db.insert('approvalRuns', {\n\t\t\t...input,\n\t\t\tstate: 'pending',\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t})\n\t\tconst workflowId: WorkflowId = await approvalWorkflow.start(\n\t\t\tctx,\n\t\t\tinternal.workflow.run,\n\t\t\t{ runId },\n\t\t\t{ startAsync: true },\n\t\t)\n\t\tawait ctx.db.patch(runId, { workflowId, updatedAt: Date.now() })\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: 'approval.requested',\n\t\t\tactorRef: input.requester.actorRef,\n\t\t\trunId,\n\t\t\tresourceType: input.resourceType,\n\t\t\tresourceRef: input.resourceRef,\n\t\t\ttransition: 'requested',\n\t\t})\n\t\treturn { runId }\n\t},\n})\n\nexport const cancel = mutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\tactor: zodToConvex(approvalActor),\n\t\tcompatibilityKey: v.string(),\n\t},\n\treturns: v.object({ state: v.literal(APPROVAL_RUN_STATES[4]) }),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tif (run.state !== 'pending') {\n\t\t\tif (run.state === 'canceled') return { state: 'canceled' as const }\n\t\t\tthrow new Error(`Approval request is already ${run.state}`)\n\t\t}\n\t\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\t\tawait approvalWorkflow.cancel(ctx, run.workflowId as WorkflowId)\n\t\tif (!canTransitionApprovalRun(run.state, 'canceled'))\n\t\t\tthrow new Error(`Approval request cannot transition from ${run.state}`)\n\t\tconst now = Date.now()\n\t\tawait ctx.db.patch(run._id, {\n\t\t\tstate: 'canceled',\n\t\t\texpiresAt: undefined,\n\t\t\tupdatedAt: now,\n\t\t\tterminalAt: now,\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: 'approval.canceled',\n\t\t\tactorRef: input.actor.actorRef,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: 'canceled',\n\t\t})\n\t\treturn { state: 'canceled' as const }\n\t},\n})\n\nexport const restart = mutation({\n\targs: { runId: v.id('approvalRuns'), compatibilityKey: v.string() },\n\treturns: v.null(),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tif (!run.workflowId) throw new Error('Approval workflow is not linked')\n\t\tif (!run.executionFailedStepKey)\n\t\t\tthrow new Error('Approval workflow has no failed step to restart')\n\t\tawait approvalWorkflow.restart(ctx, run.workflowId as WorkflowId, {\n\t\t\tfrom: run.executionFailedStepKey,\n\t\t\tstartAsync: true,\n\t\t})\n\t\treturn null\n\t},\n})\n\nexport const status = query({\n\targs: { runId: v.id('approvalRuns'), compatibilityKey: v.string() },\n\treturns: v.union(v.null(), approvalStatusValidator()),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) return null\n\t\tassertCompatible(run.workflow.compatibilityKey, input.compatibilityKey)\n\t\tconst workflowStatus = run.workflowId\n\t\t\t? await approvalWorkflow.status(ctx, run.workflowId as WorkflowId)\n\t\t\t: null\n\t\tconst execution = normalizeWorkflowStatus(workflowStatus)\n\t\treturn { run, execution }\n\t},\n})\n\nexport const list = query({\n\targs: {\n\t\tscopeRef: zodToConvex(approvalReference),\n\t\tstate: v.optional(zodToConvex(approvalRunState)),\n\t\tpaginationOpts: paginationOptsValidator,\n\t},\n\treturns: paginationResultValidator(approvalRunValidator()),\n\thandler: (ctx, input) =>\n\t\tpaginator(ctx.db, schema)\n\t\t\t.query('approvalRuns')\n\t\t\t.withIndex('by_scopeRef_and_state', (query) =>\n\t\t\t\tinput.state === undefined\n\t\t\t\t\t? query.eq('scopeRef', input.scopeRef)\n\t\t\t\t\t: query.eq('scopeRef', input.scopeRef).eq('state', input.state),\n\t\t\t)\n\t\t\t.order('desc')\n\t\t\t.paginate(input.paginationOpts),\n})\n\nexport const getForWorkflow = internalQuery({\n\targs: { runId: v.id('approvalRuns') },\n\treturns: v.union(v.null(), approvalRunValidator()),\n\thandler: (ctx, input) => ctx.db.get(input.runId),\n})\n\nexport const recordExecutionTerminal = internalMutation({\n\targs: {\n\t\trunId: v.id('approvalRuns'),\n\t\toutcome: v.union(\n\t\t\tv.literal(APPROVAL_EXECUTION_STATES[1]),\n\t\t\tv.literal(APPROVAL_EXECUTION_STATES[3]),\n\t\t),\n\t\tfailedStepKey: v.optional(zodToConvex(approvalName)),\n\t},\n\treturns: v.null(),\n\thandler: async (ctx, input) => {\n\t\tconst run = await ctx.db.get(input.runId)\n\t\tif (!run) throw new Error('Approval request not found')\n\t\tawait ctx.db.patch(run._id, {\n\t\t\texecutionFailedStepKey:\n\t\t\t\tinput.outcome === 'failed' ? input.failedStepKey : undefined,\n\t\t\tupdatedAt: Date.now(),\n\t\t})\n\t\tawait logApprovalTransition(ctx, {\n\t\t\taction: `approval.execution.${input.outcome}`,\n\t\t\trunId: run._id,\n\t\t\tresourceType: run.resourceType,\n\t\t\tresourceRef: run.resourceRef,\n\t\t\ttransition: `execution:${input.outcome}`,\n\t\t\tseverity: input.outcome === 'failed' ? 'error' : 'info',\n\t\t})\n\t\treturn null\n\t},\n})\n\nconst approvalWorkflow = new WorkflowManager(components.workflow)\n\nfunction normalizeWorkflowStatus(\n\tstatus: Awaited<ReturnType<typeof approvalWorkflow.status>> | null,\n) {\n\tif (!status) return null\n\tswitch (status.type) {\n\t\tcase 'failed':\n\t\t\treturn { type: 'failed' as const, error: status.error }\n\t\tcase 'inProgress':\n\t\tcase 'completed':\n\t\tcase 'canceled':\n\t\t\treturn { type: status.type }\n\t}\n}\n\nfunction approvalRunValidator() {\n\treturn v.object({\n\t\t_id: v.id('approvalRuns'),\n\t\t_creationTime: v.number(),\n\t\t...zodToConvex(approvalRunDocument).fields,\n\t})\n}\n\nfunction workflowStatusValidator() {\n\treturn v.union(\n\t\tv.object({ type: v.literal(APPROVAL_EXECUTION_STATES[0]) }),\n\t\tv.object({ type: v.literal(APPROVAL_EXECUTION_STATES[1]) }),\n\t\tv.object({ type: v.literal(APPROVAL_EXECUTION_STATES[2]) }),\n\t\tv.object({\n\t\t\ttype: v.literal(APPROVAL_EXECUTION_STATES[3]),\n\t\t\terror: v.string(),\n\t\t}),\n\t)\n}\n\nfunction approvalStatusValidator() {\n\treturn v.object({\n\t\trun: approvalRunValidator(),\n\t\texecution: v.union(v.null(), workflowStatusValidator()),\n\t})\n}\n\nfunction assertCompatible(actual: string, expected: string): void {\n\tif (actual !== expected)\n\t\tthrow new Error(\n\t\t\t`Approval workflow compatibility mismatch: expected ${expected}, received ${actual}`,\n\t\t)\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{APPROVAL_ACTOR_DECISION_INDEX as e,APPROVAL_DECISION_HISTORY_INDEX as t}from"./constants.mjs";import{approvalDecisionDocument as n,approvalRunDocument as r}from"./validators.mjs";import{zodToConvex as i}from"convex-helpers/server/zod4";import{defineSchema as a,defineTable as o}from"convex/server";var s=a({approvalRuns:o(i(r)).index(`by_resourceType_and_resourceRef`,[`resourceType`,`resourceRef`]).index(`by_scopeRef_and_state`,[`scopeRef`,`state`]).index(`by_state_and_expiresAt`,[`state`,`expiresAt`]),approvalDecisions:o(i(n)).index(e,[`runId`,`stepKey`,`actor.actorRef`]).index(`by_runId_and_stepKey_and_decidedAt`,[`runId`,`stepKey`,`decidedAt`]).index(t,[`runId`,`decidedAt`])});export{s as default};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
declare namespace validators_d_exports {
|
|
3
|
-
export { ApprovalActor, ApprovalMetadata, ApprovalWorkflowDescriptor, approvalActionCallback, approvalActor, approvalBranchStep, approvalCallback, approvalCallbackKind, approvalCallbackStep, approvalDecision, approvalDecisionDocument, approvalDecisionStep, approvalMetadata, approvalMutationCallback, approvalName, approvalNotifyStep, approvalQuorum, approvalQuorumKind, approvalReason, approvalReference, approvalRunDocument, approvalRunState, approvalStepKind, approvalWorkflowDescriptor, approvalWorkflowStep };
|
|
3
|
+
export { ApprovalActor, ApprovalCallbackInput, ApprovalMetadata, ApprovalWorkflowDescriptor, approvalActionCallback, approvalActor, approvalBranchStep, approvalCallback, approvalCallbackArgs, approvalCallbackInput, approvalCallbackKind, approvalCallbackStep, approvalDecision, approvalDecisionDocument, approvalDecisionStep, approvalMetadata, approvalMutationCallback, approvalName, approvalNotifyStep, approvalQuorum, approvalQuorumKind, approvalReason, approvalReference, approvalRunDocument, approvalRunState, approvalStepKind, approvalWorkflowDescriptor, approvalWorkflowStep };
|
|
4
4
|
}
|
|
5
5
|
declare const approvalRunState: z.ZodEnum<{
|
|
6
6
|
approved: "approved";
|
|
@@ -31,6 +31,122 @@ declare const approvalReference: z.ZodString;
|
|
|
31
31
|
declare const approvalName: z.ZodString;
|
|
32
32
|
declare const approvalReason: z.ZodString;
|
|
33
33
|
declare const approvalMetadata: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
34
|
+
declare const approvalCallbackInput: z.ZodObject<{
|
|
35
|
+
runId: z.ZodString;
|
|
36
|
+
scopeRef: z.ZodString;
|
|
37
|
+
resourceType: z.ZodString;
|
|
38
|
+
resourceRef: z.ZodString;
|
|
39
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
40
|
+
decision: z.ZodOptional<z.ZodObject<{
|
|
41
|
+
stepKey: z.ZodString;
|
|
42
|
+
outcome: z.ZodUnion<readonly [z.ZodEnum<{
|
|
43
|
+
approved: "approved";
|
|
44
|
+
rejected: "rejected";
|
|
45
|
+
}>, z.ZodLiteral<"expired">]>;
|
|
46
|
+
evidence: z.ZodArray<z.ZodObject<{
|
|
47
|
+
stepKey: z.ZodString;
|
|
48
|
+
actorRef: z.ZodString;
|
|
49
|
+
decision: z.ZodEnum<{
|
|
50
|
+
approved: "approved";
|
|
51
|
+
rejected: "rejected";
|
|
52
|
+
}>;
|
|
53
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
54
|
+
decidedAt: z.ZodNumber;
|
|
55
|
+
}, z.core.$strict>>;
|
|
56
|
+
terminalEvidence: z.ZodOptional<z.ZodObject<{
|
|
57
|
+
actorRef: z.ZodString;
|
|
58
|
+
decision: z.ZodEnum<{
|
|
59
|
+
approved: "approved";
|
|
60
|
+
rejected: "rejected";
|
|
61
|
+
}>;
|
|
62
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
63
|
+
decidedAt: z.ZodNumber;
|
|
64
|
+
}, z.core.$strict>>;
|
|
65
|
+
}, z.core.$strict>>;
|
|
66
|
+
}, z.core.$strict>;
|
|
67
|
+
/** Convex argument validator for approval mutation, action, and notify callbacks. */
|
|
68
|
+
declare const approvalCallbackArgs: import("convex/values").VObject<{
|
|
69
|
+
runId: string;
|
|
70
|
+
scopeRef: string;
|
|
71
|
+
resourceType: string;
|
|
72
|
+
resourceRef: string;
|
|
73
|
+
metadata?: {
|
|
74
|
+
[x: string]: string;
|
|
75
|
+
} | undefined;
|
|
76
|
+
decision?: {
|
|
77
|
+
stepKey: string;
|
|
78
|
+
outcome: "approved" | "expired" | "rejected";
|
|
79
|
+
evidence: {
|
|
80
|
+
stepKey: string;
|
|
81
|
+
actorRef: string;
|
|
82
|
+
decision: "approved" | "rejected";
|
|
83
|
+
reason?: string | undefined;
|
|
84
|
+
decidedAt: number;
|
|
85
|
+
}[];
|
|
86
|
+
terminalEvidence?: {
|
|
87
|
+
actorRef: string;
|
|
88
|
+
decision: "approved" | "rejected";
|
|
89
|
+
reason?: string | undefined;
|
|
90
|
+
decidedAt: number;
|
|
91
|
+
} | undefined;
|
|
92
|
+
} | undefined;
|
|
93
|
+
}, {
|
|
94
|
+
runId: import("convex/values").VString<string, "required">;
|
|
95
|
+
scopeRef: import("convex/values").VString<string, "required">;
|
|
96
|
+
resourceType: import("convex/values").VString<string, "required">;
|
|
97
|
+
resourceRef: import("convex/values").VString<string, "required">;
|
|
98
|
+
metadata: import("convex/values").VRecord<Record<string, string> | undefined, import("convex/values").VString<string, "required">, import("convex/values").VString<string, "required">, "optional", string>;
|
|
99
|
+
decision: import("convex/values").VObject<{
|
|
100
|
+
stepKey: string;
|
|
101
|
+
outcome: "approved" | "expired" | "rejected";
|
|
102
|
+
evidence: {
|
|
103
|
+
stepKey: string;
|
|
104
|
+
actorRef: string;
|
|
105
|
+
decision: "approved" | "rejected";
|
|
106
|
+
reason?: string | undefined;
|
|
107
|
+
decidedAt: number;
|
|
108
|
+
}[];
|
|
109
|
+
terminalEvidence?: {
|
|
110
|
+
actorRef: string;
|
|
111
|
+
decision: "approved" | "rejected";
|
|
112
|
+
reason?: string | undefined;
|
|
113
|
+
decidedAt: number;
|
|
114
|
+
} | undefined;
|
|
115
|
+
} | undefined, {
|
|
116
|
+
stepKey: import("convex/values").VString<string, "required">;
|
|
117
|
+
outcome: import("convex/values").VUnion<"approved" | "expired" | "rejected", [import("convex/values").VUnion<"approved" | "rejected", (import("convex/values").VLiteral<"approved", "required"> | import("convex/values").VLiteral<"rejected", "required">)[], "required", never>, import("convex/values").VLiteral<"expired", "required">], "required", never>;
|
|
118
|
+
evidence: import("convex/values").VArray<{
|
|
119
|
+
stepKey: string;
|
|
120
|
+
actorRef: string;
|
|
121
|
+
decision: "approved" | "rejected";
|
|
122
|
+
reason?: string | undefined;
|
|
123
|
+
decidedAt: number;
|
|
124
|
+
}[], import("convex/values").VObject<{
|
|
125
|
+
stepKey: string;
|
|
126
|
+
actorRef: string;
|
|
127
|
+
decision: "approved" | "rejected";
|
|
128
|
+
reason?: string | undefined;
|
|
129
|
+
decidedAt: number;
|
|
130
|
+
}, {
|
|
131
|
+
stepKey: import("convex/values").VString<string, "required">;
|
|
132
|
+
actorRef: import("convex/values").VString<string, "required">;
|
|
133
|
+
decision: import("convex/values").VUnion<"approved" | "rejected", (import("convex/values").VLiteral<"approved", "required"> | import("convex/values").VLiteral<"rejected", "required">)[], "required", never>;
|
|
134
|
+
reason: import("convex/values").VString<string | undefined, "optional">;
|
|
135
|
+
decidedAt: import("convex/values").VFloat64<number, "required">;
|
|
136
|
+
}, "required", "actorRef" | "decidedAt" | "decision" | "reason" | "stepKey">, "required">;
|
|
137
|
+
terminalEvidence: import("convex/values").VObject<{
|
|
138
|
+
actorRef: string;
|
|
139
|
+
decision: "approved" | "rejected";
|
|
140
|
+
reason?: string | undefined;
|
|
141
|
+
decidedAt: number;
|
|
142
|
+
} | undefined, {
|
|
143
|
+
actorRef: import("convex/values").VString<string, "required">;
|
|
144
|
+
decision: import("convex/values").VUnion<"approved" | "rejected", (import("convex/values").VLiteral<"approved", "required"> | import("convex/values").VLiteral<"rejected", "required">)[], "required", never>;
|
|
145
|
+
reason: import("convex/values").VString<string | undefined, "optional">;
|
|
146
|
+
decidedAt: import("convex/values").VFloat64<number, "required">;
|
|
147
|
+
}, "optional", "actorRef" | "decidedAt" | "decision" | "reason">;
|
|
148
|
+
}, "optional", "evidence" | "outcome" | "stepKey" | "terminalEvidence" | "terminalEvidence.actorRef" | "terminalEvidence.decidedAt" | "terminalEvidence.decision" | "terminalEvidence.reason">;
|
|
149
|
+
}, "required", "decision" | "decision.evidence" | "decision.outcome" | "decision.stepKey" | "decision.terminalEvidence" | "decision.terminalEvidence.actorRef" | "decision.terminalEvidence.decidedAt" | "decision.terminalEvidence.decision" | "decision.terminalEvidence.reason" | "metadata" | "resourceRef" | "resourceType" | "runId" | "scopeRef" | `metadata.${string}`>;
|
|
34
150
|
declare const approvalActor: z.ZodObject<{
|
|
35
151
|
actorRef: z.ZodString;
|
|
36
152
|
capabilities: z.ZodArray<z.ZodString>;
|
|
@@ -297,6 +413,7 @@ declare const approvalDecisionDocument: z.ZodObject<{
|
|
|
297
413
|
type ApprovalWorkflowDescriptor = z.infer<typeof approvalWorkflowDescriptor>;
|
|
298
414
|
type ApprovalActor = z.infer<typeof approvalActor>;
|
|
299
415
|
type ApprovalMetadata = z.infer<typeof approvalMetadata>;
|
|
416
|
+
type ApprovalCallbackInput = Readonly<z.infer<typeof approvalCallbackInput>>;
|
|
300
417
|
//#endregion
|
|
301
|
-
export { ApprovalActor, ApprovalMetadata, ApprovalWorkflowDescriptor, approvalActionCallback, approvalActor, approvalBranchStep, approvalCallback, approvalCallbackKind, approvalCallbackStep, approvalDecision, approvalDecisionDocument, approvalDecisionStep, approvalMetadata, approvalMutationCallback, approvalName, approvalNotifyStep, approvalQuorum, approvalQuorumKind, approvalReason, approvalReference, approvalRunDocument, approvalRunState, approvalStepKind, approvalWorkflowDescriptor, approvalWorkflowStep, validators_d_exports };
|
|
418
|
+
export { ApprovalActor, ApprovalCallbackInput, ApprovalMetadata, ApprovalWorkflowDescriptor, approvalActionCallback, approvalActor, approvalBranchStep, approvalCallback, approvalCallbackArgs, approvalCallbackInput, approvalCallbackKind, approvalCallbackStep, approvalDecision, approvalDecisionDocument, approvalDecisionStep, approvalMetadata, approvalMutationCallback, approvalName, approvalNotifyStep, approvalQuorum, approvalQuorumKind, approvalReason, approvalReference, approvalRunDocument, approvalRunState, approvalStepKind, approvalWorkflowDescriptor, approvalWorkflowStep, validators_d_exports };
|
|
302
419
|
//# sourceMappingURL=validators.d.mts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{APPROVAL_CALLBACK_KINDS as e,APPROVAL_DECISIONS as t,APPROVAL_QUORUM_KINDS as n,APPROVAL_RUN_STATES as r,APPROVAL_STEP_KINDS as i}from"./constants.mjs";import{zid as a}from"convex-helpers/server/zod4";import{z as
|
|
1
|
+
import{APPROVAL_CALLBACK_KINDS as e,APPROVAL_DECISIONS as t,APPROVAL_QUORUM_KINDS as n,APPROVAL_RUN_STATES as r,APPROVAL_STEP_KINDS as i}from"./constants.mjs";import{zid as a,zodToConvex as o}from"convex-helpers/server/zod4";import{z as s}from"zod";const c=s.enum(r),l=s.enum(t),u=s.enum(i),d=s.enum(e),f=s.enum(n),p=s.string().trim().min(1).max(256),m=s.string().trim().min(1).max(96).regex(/^[A-Za-z][A-Za-z0-9._-]*$/),h=s.string().trim().min(1).max(500),g=s.record(s.string().min(1).max(64).regex(/^(?![$_])[\x20-\x7E]+$/),s.string().max(512)).refine(e=>Object.keys(e).length<=32,`Metadata may contain at most 32 entries`),_=s.object({stepKey:m,actorRef:p,decision:l,reason:h.optional(),decidedAt:s.number()}).strict(),v=_.omit({stepKey:!0}),y=s.object({runId:p,scopeRef:p,resourceType:m,resourceRef:p,metadata:g.optional(),decision:s.object({stepKey:m,outcome:s.union([l,s.literal(`expired`)]),evidence:s.array(_),terminalEvidence:v.optional()}).strict().optional()}).strict(),b=o(y),x=s.object({actorRef:p,capabilities:s.array(m).max(32),metadata:g.optional()}).strict(),S=s.object({kind:s.literal(`mutation`),handle:p,retry:s.boolean()}).strict(),C=s.object({kind:s.literal(`action`),handle:p,retry:s.boolean()}).strict(),w=s.discriminatedUnion(`kind`,[S,C]),T=s.object({kind:f,approvals:s.number().int().positive().max(8)}).strict(),E=s.discriminatedUnion(`kind`,[s.object({kind:s.literal(`mutation`),key:m,callback:S}).strict(),s.object({kind:s.literal(`action`),key:m,callback:C}).strict()]),D=s.object({kind:s.literal(`notify`),key:m,callback:C}).strict(),O=s.object({kind:s.literal(`decision`),key:m,decisions:s.array(l).min(1).max(8),quorum:T,makerChecker:s.boolean(),expiresAfterMs:s.number().int().positive().optional()}).strict(),k=s.object({kind:s.literal(`branch`),key:m,approvedStepKey:m,rejectedStepKey:m}).strict(),A=s.discriminatedUnion(`kind`,[E,D,O,k]),j=s.object({schemaVersion:s.literal(1),compatibilityKey:m,name:m,steps:s.array(A).min(1).max(32)}).strict().superRefine((e,t)=>{let n=new Set,r=new Map(e.steps.map(e=>[e.key,e])),i=new Map;for(let[r,i]of e.steps.entries())n.has(i.key)&&t.addIssue({code:`custom`,message:`Duplicate workflow step key: ${i.key}`,path:[`steps`,r,`key`]}),n.add(i.key),i.kind===`decision`&&new Set(i.decisions).size!==i.decisions.length&&t.addIssue({code:`custom`,message:`Duplicate decision value in step: ${i.key}`,path:[`steps`,r,`decisions`]});for(let[n,a]of e.steps.entries())if(a.kind===`branch`){e.steps[n-1]?.kind!==`decision`&&t.addIssue({code:`custom`,message:`Branch must immediately follow a decision: ${a.key}`,path:[`steps`,n]});for(let o of[a.approvedStepKey,a.rejectedStepKey]){let a=r.get(o),s=e.steps.findIndex(e=>e.key===o);a?a.kind!==`mutation`&&a.kind!==`action`&&a.kind!==`notify`?t.addIssue({code:`custom`,message:`Branch target must be a callback step: ${o}`,path:[`steps`,n]}):s<=n&&t.addIssue({code:`custom`,message:`Branch target must be declared after its branch: ${o}`,path:[`steps`,n]}):t.addIssue({code:`custom`,message:`Unknown branch target: ${o}`,path:[`steps`,n]}),i.set(o,(i.get(o)??0)+1)}}for(let[e,n]of i)n!==1&&t.addIssue({code:`custom`,message:`Branch callback must belong to exactly one branch: ${e}`,path:[`steps`]})}),M=s.object({scopeRef:p,resourceType:m,resourceRef:p,requester:x,metadata:g.optional(),workflow:j,state:c,currentStepKey:m.optional(),executionFailedStepKey:m.optional(),expiresAt:s.number().optional(),workflowId:p.optional(),createdAt:s.number(),updatedAt:s.number(),terminalAt:s.number().optional()}).strict(),N=s.object({runId:a(`approvalRuns`),stepKey:m,actor:x,decision:l,reason:h.optional(),decidedAt:s.number()}).strict();export{C as approvalActionCallback,x as approvalActor,k as approvalBranchStep,w as approvalCallback,b as approvalCallbackArgs,y as approvalCallbackInput,d as approvalCallbackKind,E as approvalCallbackStep,l as approvalDecision,N as approvalDecisionDocument,O as approvalDecisionStep,g as approvalMetadata,S as approvalMutationCallback,m as approvalName,D as approvalNotifyStep,T as approvalQuorum,f as approvalQuorumKind,h as approvalReason,p as approvalReference,M as approvalRunDocument,c as approvalRunState,u as approvalStepKind,j as approvalWorkflowDescriptor,A as approvalWorkflowStep};
|
|
2
2
|
//# sourceMappingURL=validators.mjs.map
|