@sanity/workflow-engine-test 0.7.0 → 0.9.0

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/dist/index.d.cts CHANGED
@@ -3,15 +3,16 @@ import { Actor } from "@sanity/workflow-engine";
3
3
  import type { CompleteEffectArgs } from "@sanity/workflow-engine";
4
4
  import { DeployDefinitionsArgs } from "@sanity/workflow-engine";
5
5
  import { DeployDefinitionsResult } from "@sanity/workflow-engine";
6
- import { DispatchResult } from "@sanity/workflow-engine";
7
6
  import type { EditFieldArgs } from "@sanity/workflow-engine";
8
7
  import type { EvaluateArgs } from "@sanity/workflow-engine";
9
8
  import type { FireActionArgs } from "@sanity/workflow-engine";
10
9
  import { GdrUri } from "@sanity/workflow-engine";
11
10
  import type { Grant } from "@sanity/workflow-engine";
11
+ import { InitialFieldValue } from "@sanity/workflow-engine";
12
12
  import { MutationGuardAction } from "@sanity/workflow-engine";
13
13
  import { MutationGuardDoc } from "@sanity/workflow-engine";
14
14
  import type { OperationArgs } from "@sanity/workflow-engine";
15
+ import { OperationResult } from "@sanity/workflow-engine";
15
16
  import { PendingEffect } from "@sanity/workflow-engine";
16
17
  import type { StartInstanceArgs } from "@sanity/workflow-engine";
17
18
  import type { WorkflowAccess } from "@sanity/workflow-engine";
@@ -51,21 +52,16 @@ export declare type Bench = BenchState &
51
52
  EngineWrappers &
52
53
  ReadHelpers &
53
54
  GuardHelpers &
54
- QueryHelpers;
55
+ QueryHelpers &
56
+ ComposedHelpers;
55
57
 
56
- declare type BenchCompleteEffectArgs = Omit<
57
- CompleteEffectArgs,
58
- "client" | "tag" | "workflowResource" | "access"
59
- > & {
58
+ declare type BenchCompleteEffectArgs = Omit<CompleteEffectArgs, "access"> & {
60
59
  access?: WorkflowAccess;
61
60
  /** Shortcut for `access.actor`. */
62
61
  actor?: Actor;
63
62
  };
64
63
 
65
- declare type BenchEditFieldArgs = Omit<
66
- EditFieldArgs,
67
- "client" | "tag" | "workflowResource" | "access"
68
- > & {
64
+ declare type BenchEditFieldArgs = Omit<EditFieldArgs, "access"> & {
69
65
  access?: WorkflowAccess;
70
66
  /** Shortcut for `access.actor`. */
71
67
  actor?: Actor;
@@ -73,10 +69,7 @@ declare type BenchEditFieldArgs = Omit<
73
69
  grants?: Grant[];
74
70
  };
75
71
 
76
- declare type BenchEvaluateArgs = Omit<
77
- EvaluateArgs,
78
- "client" | "tag" | "workflowResource" | "access"
79
- > & {
72
+ declare type BenchEvaluateArgs = Omit<EvaluateArgs, "access"> & {
80
73
  access?: WorkflowAccess;
81
74
  /** Shortcut for `access.actor`. */
82
75
  actor?: Actor;
@@ -84,10 +77,7 @@ declare type BenchEvaluateArgs = Omit<
84
77
  grants?: Grant[];
85
78
  };
86
79
 
87
- declare type BenchFireActionArgs = Omit<
88
- FireActionArgs,
89
- "client" | "tag" | "workflowResource" | "access"
90
- > & {
80
+ declare type BenchFireActionArgs = Omit<FireActionArgs, "access"> & {
91
81
  access?: WorkflowAccess;
92
82
  /** Shortcut for `access.actor`. */
93
83
  actor?: Actor;
@@ -95,10 +85,7 @@ declare type BenchFireActionArgs = Omit<
95
85
  grants?: Grant[];
96
86
  };
97
87
 
98
- declare type BenchStartInstanceArgs = Omit<
99
- StartInstanceArgs,
100
- "client" | "tag" | "workflowResource" | "access"
101
- > & {
88
+ declare type BenchStartInstanceArgs = Omit<StartInstanceArgs, "access"> & {
102
89
  access?: WorkflowAccess;
103
90
  /** Shortcut for `access.actor`. */
104
91
  actor?: Actor;
@@ -142,10 +129,7 @@ declare interface BenchState {
142
129
  advance: (ms: number) => void;
143
130
  }
144
131
 
145
- declare type BenchTickArgs = Omit<
146
- OperationArgs,
147
- "client" | "tag" | "workflowResource" | "access"
148
- > & {
132
+ declare type BenchTickArgs = Omit<OperationArgs, "access"> & {
149
133
  access?: WorkflowAccess;
150
134
  /** Shortcut for `access.actor`. */
151
135
  actor?: Actor;
@@ -171,6 +155,21 @@ declare interface CallRecord {
171
155
  dataset: string;
172
156
  }
173
157
 
158
+ /** Helpers composed across the wrapper + read groups at bench assembly. */
159
+ declare interface ComposedHelpers {
160
+ /**
161
+ * Complete the pending effect named `effect` — {@link EngineWrappers.completeEffect}
162
+ * with the `effectKey` looked up by name, throwing loud when no such effect
163
+ * is pending. The idiomatic way to play an external handler reporting its
164
+ * result; pass `ops` to write outcome fields in the same commit.
165
+ */
166
+ completePendingEffect: (
167
+ args: Omit<BenchCompleteEffectArgs, "effectKey"> & {
168
+ effect: string;
169
+ },
170
+ ) => Promise<OperationResult>;
171
+ }
172
+
174
173
  /**
175
174
  * Create a fresh bench. By default the bench is fully isolated — two
176
175
  * `createBench()` calls have no shared state. Pass `client` + `tag`
@@ -282,13 +281,13 @@ declare type DocumentValuePermission = "create" | "read" | "update";
282
281
  /** Engine-call wrappers that inject the bench-owned client + tag + access. */
283
282
  declare type EngineWrappers = {
284
283
  deployDefinitions: (
285
- args: Omit<DeployDefinitionsArgs, "client" | "tag" | "workflowResource">,
284
+ args: DeployDefinitionsArgs,
286
285
  ) => Promise<DeployDefinitionsResult>;
287
- startInstance: (args: BenchStartInstanceArgs) => Promise<WorkflowInstance>;
288
- fireAction: (args: BenchFireActionArgs) => Promise<DispatchResult>;
289
- editField: (args: BenchEditFieldArgs) => Promise<DispatchResult>;
290
- completeEffect: (args: BenchCompleteEffectArgs) => Promise<DispatchResult>;
291
- tick: (args: BenchTickArgs) => Promise<DispatchResult>;
286
+ startInstance: (args: BenchStartInstanceArgs) => Promise<OperationResult>;
287
+ fireAction: (args: BenchFireActionArgs) => Promise<OperationResult>;
288
+ editField: (args: BenchEditFieldArgs) => Promise<OperationResult>;
289
+ completeEffect: (args: BenchCompleteEffectArgs) => Promise<OperationResult>;
290
+ tick: (args: BenchTickArgs) => Promise<OperationResult>;
292
291
  evaluate: (args: BenchEvaluateArgs) => Promise<WorkflowEvaluation>;
293
292
  guardsForInstance: (instanceId: string) => Promise<MutationGuardDoc[]>;
294
293
  guardsForDefinition: (definition: string) => Promise<MutationGuardDoc[]>;
@@ -382,7 +381,7 @@ declare interface Grant_2 {
382
381
  }
383
382
 
384
383
  declare type GuardHelpers = {
385
- /** All deployed `temp.system.guard` docs in the store. */
384
+ /** All deployed guard docs ({@link MutationGuardDoc}) in the store. */
386
385
  listGuards: () => Promise<MutationGuardDoc[]>;
387
386
  /**
388
387
  * Guards that would deny an arbitrary edit to `documentId` right now (i.e.
@@ -394,20 +393,18 @@ declare type GuardHelpers = {
394
393
  as?: Actor,
395
394
  ) => Promise<MutationGuardDoc[]>;
396
395
  /**
397
- * Write to a document through the client's enforced write seam — the bench
396
+ * Write to a document through the client's guarded write seam — the bench
398
397
  * client gates the write against deployed guards (incl. `identity()`) and
399
- * throws `MutationGuardDeniedError` on denial, exactly as the lake would.
400
- * `as` routes the write through a token-scoped sibling so `identity()`
401
- * resolves to that actor.
398
+ * throws `MutationGuardDeniedError` on denial the lake's intended
399
+ * rejection, simulated by the bench. `as` routes the write through a
400
+ * token-scoped sibling so `identity()` resolves to that actor.
402
401
  */
403
- editDocument: (
404
- documentId: string,
405
- patch: Record<string, unknown>,
406
- options?: {
407
- action?: MutationGuardAction;
408
- as?: Actor;
409
- },
410
- ) => Promise<StoreDocument>;
402
+ editDocument: (opts: {
403
+ documentId: string;
404
+ patch: Record<string, unknown>;
405
+ action?: MutationGuardAction;
406
+ as?: Actor;
407
+ }) => Promise<StoreDocument>;
411
408
  };
412
409
 
413
410
  /** Result of a mutation when ids are requested for all affected documents. */
@@ -533,11 +530,15 @@ declare type QueryHelpers = {
533
530
  * workflow?" — useful for filter debugging, UIs that mirror engine
534
531
  * state, etc.
535
532
  */
536
- queryInScope: <T = unknown>(
537
- instanceId: string,
538
- groq: string,
539
- params?: Record<string, unknown>,
540
- ) => Promise<T>;
533
+ queryInScope: <T = unknown>({
534
+ instanceId,
535
+ groq,
536
+ params,
537
+ }: {
538
+ instanceId: string;
539
+ groq: string;
540
+ params?: Record<string, unknown>;
541
+ }) => Promise<T>;
541
542
  };
542
543
 
543
544
  declare type ReadHelpers = {
@@ -584,13 +585,11 @@ declare type ReadHelpers = {
584
585
  * completed instances (`completedAt != null`) by default; set
585
586
  * `{ openOnly: true }` to filter to in-flight only.
586
587
  */
587
- instancesByStage: (
588
- workflowName: string,
589
- stage: string,
590
- options?: {
591
- openOnly?: boolean;
592
- },
593
- ) => Promise<WorkflowInstance[]>;
588
+ instancesByStage: (options: {
589
+ workflowName: string;
590
+ stage: string;
591
+ openOnly?: boolean;
592
+ }) => Promise<WorkflowInstance[]>;
594
593
  /**
595
594
  * Every in-flight instance whose reactive watch-set includes `document`
596
595
  * (a resource-qualified GDR URI) — the reverse of the forward watch-set.
@@ -650,6 +649,18 @@ declare interface ReleaseDocument extends SanityDocument {
650
649
  publishAt?: string;
651
650
  }
652
651
 
652
+ /**
653
+ * A `release.ref` entry pointing at `_.releases.<releaseName>` in the bench's
654
+ * default resource — what a release-targeting workflow's `release` field
655
+ * expects at start.
656
+ */
657
+ export declare function releaseField(
658
+ releaseName: string,
659
+ opts?: {
660
+ name?: string;
661
+ },
662
+ ): InitialFieldValue;
663
+
653
664
  declare interface ReleaseMetadata {
654
665
  title?: string;
655
666
  description?: string;
@@ -737,6 +748,19 @@ declare type StoreDocument = {
737
748
  [key: string]: unknown;
738
749
  };
739
750
 
751
+ /**
752
+ * The conventional workflow-scope `subject` doc.ref entry, keyed by a bare
753
+ * doc id in the bench's default resource. `type` defaults to `'document'`;
754
+ * pass the subject's schema type when a filter or projection reads it.
755
+ */
756
+ export declare function subjectField(
757
+ documentId: string,
758
+ opts?: {
759
+ name?: string;
760
+ type?: string;
761
+ },
762
+ ): InitialFieldValue;
763
+
740
764
  declare interface SystemFields {
741
765
  _rev: string;
742
766
  _createdAt: string;
package/dist/index.d.ts CHANGED
@@ -3,15 +3,16 @@ import { Actor } from "@sanity/workflow-engine";
3
3
  import type { CompleteEffectArgs } from "@sanity/workflow-engine";
4
4
  import { DeployDefinitionsArgs } from "@sanity/workflow-engine";
5
5
  import { DeployDefinitionsResult } from "@sanity/workflow-engine";
6
- import { DispatchResult } from "@sanity/workflow-engine";
7
6
  import type { EditFieldArgs } from "@sanity/workflow-engine";
8
7
  import type { EvaluateArgs } from "@sanity/workflow-engine";
9
8
  import type { FireActionArgs } from "@sanity/workflow-engine";
10
9
  import { GdrUri } from "@sanity/workflow-engine";
11
10
  import type { Grant } from "@sanity/workflow-engine";
11
+ import { InitialFieldValue } from "@sanity/workflow-engine";
12
12
  import { MutationGuardAction } from "@sanity/workflow-engine";
13
13
  import { MutationGuardDoc } from "@sanity/workflow-engine";
14
14
  import type { OperationArgs } from "@sanity/workflow-engine";
15
+ import { OperationResult } from "@sanity/workflow-engine";
15
16
  import { PendingEffect } from "@sanity/workflow-engine";
16
17
  import type { StartInstanceArgs } from "@sanity/workflow-engine";
17
18
  import type { WorkflowAccess } from "@sanity/workflow-engine";
@@ -51,21 +52,16 @@ export declare type Bench = BenchState &
51
52
  EngineWrappers &
52
53
  ReadHelpers &
53
54
  GuardHelpers &
54
- QueryHelpers;
55
+ QueryHelpers &
56
+ ComposedHelpers;
55
57
 
56
- declare type BenchCompleteEffectArgs = Omit<
57
- CompleteEffectArgs,
58
- "client" | "tag" | "workflowResource" | "access"
59
- > & {
58
+ declare type BenchCompleteEffectArgs = Omit<CompleteEffectArgs, "access"> & {
60
59
  access?: WorkflowAccess;
61
60
  /** Shortcut for `access.actor`. */
62
61
  actor?: Actor;
63
62
  };
64
63
 
65
- declare type BenchEditFieldArgs = Omit<
66
- EditFieldArgs,
67
- "client" | "tag" | "workflowResource" | "access"
68
- > & {
64
+ declare type BenchEditFieldArgs = Omit<EditFieldArgs, "access"> & {
69
65
  access?: WorkflowAccess;
70
66
  /** Shortcut for `access.actor`. */
71
67
  actor?: Actor;
@@ -73,10 +69,7 @@ declare type BenchEditFieldArgs = Omit<
73
69
  grants?: Grant[];
74
70
  };
75
71
 
76
- declare type BenchEvaluateArgs = Omit<
77
- EvaluateArgs,
78
- "client" | "tag" | "workflowResource" | "access"
79
- > & {
72
+ declare type BenchEvaluateArgs = Omit<EvaluateArgs, "access"> & {
80
73
  access?: WorkflowAccess;
81
74
  /** Shortcut for `access.actor`. */
82
75
  actor?: Actor;
@@ -84,10 +77,7 @@ declare type BenchEvaluateArgs = Omit<
84
77
  grants?: Grant[];
85
78
  };
86
79
 
87
- declare type BenchFireActionArgs = Omit<
88
- FireActionArgs,
89
- "client" | "tag" | "workflowResource" | "access"
90
- > & {
80
+ declare type BenchFireActionArgs = Omit<FireActionArgs, "access"> & {
91
81
  access?: WorkflowAccess;
92
82
  /** Shortcut for `access.actor`. */
93
83
  actor?: Actor;
@@ -95,10 +85,7 @@ declare type BenchFireActionArgs = Omit<
95
85
  grants?: Grant[];
96
86
  };
97
87
 
98
- declare type BenchStartInstanceArgs = Omit<
99
- StartInstanceArgs,
100
- "client" | "tag" | "workflowResource" | "access"
101
- > & {
88
+ declare type BenchStartInstanceArgs = Omit<StartInstanceArgs, "access"> & {
102
89
  access?: WorkflowAccess;
103
90
  /** Shortcut for `access.actor`. */
104
91
  actor?: Actor;
@@ -142,10 +129,7 @@ declare interface BenchState {
142
129
  advance: (ms: number) => void;
143
130
  }
144
131
 
145
- declare type BenchTickArgs = Omit<
146
- OperationArgs,
147
- "client" | "tag" | "workflowResource" | "access"
148
- > & {
132
+ declare type BenchTickArgs = Omit<OperationArgs, "access"> & {
149
133
  access?: WorkflowAccess;
150
134
  /** Shortcut for `access.actor`. */
151
135
  actor?: Actor;
@@ -171,6 +155,21 @@ declare interface CallRecord {
171
155
  dataset: string;
172
156
  }
173
157
 
158
+ /** Helpers composed across the wrapper + read groups at bench assembly. */
159
+ declare interface ComposedHelpers {
160
+ /**
161
+ * Complete the pending effect named `effect` — {@link EngineWrappers.completeEffect}
162
+ * with the `effectKey` looked up by name, throwing loud when no such effect
163
+ * is pending. The idiomatic way to play an external handler reporting its
164
+ * result; pass `ops` to write outcome fields in the same commit.
165
+ */
166
+ completePendingEffect: (
167
+ args: Omit<BenchCompleteEffectArgs, "effectKey"> & {
168
+ effect: string;
169
+ },
170
+ ) => Promise<OperationResult>;
171
+ }
172
+
174
173
  /**
175
174
  * Create a fresh bench. By default the bench is fully isolated — two
176
175
  * `createBench()` calls have no shared state. Pass `client` + `tag`
@@ -282,13 +281,13 @@ declare type DocumentValuePermission = "create" | "read" | "update";
282
281
  /** Engine-call wrappers that inject the bench-owned client + tag + access. */
283
282
  declare type EngineWrappers = {
284
283
  deployDefinitions: (
285
- args: Omit<DeployDefinitionsArgs, "client" | "tag" | "workflowResource">,
284
+ args: DeployDefinitionsArgs,
286
285
  ) => Promise<DeployDefinitionsResult>;
287
- startInstance: (args: BenchStartInstanceArgs) => Promise<WorkflowInstance>;
288
- fireAction: (args: BenchFireActionArgs) => Promise<DispatchResult>;
289
- editField: (args: BenchEditFieldArgs) => Promise<DispatchResult>;
290
- completeEffect: (args: BenchCompleteEffectArgs) => Promise<DispatchResult>;
291
- tick: (args: BenchTickArgs) => Promise<DispatchResult>;
286
+ startInstance: (args: BenchStartInstanceArgs) => Promise<OperationResult>;
287
+ fireAction: (args: BenchFireActionArgs) => Promise<OperationResult>;
288
+ editField: (args: BenchEditFieldArgs) => Promise<OperationResult>;
289
+ completeEffect: (args: BenchCompleteEffectArgs) => Promise<OperationResult>;
290
+ tick: (args: BenchTickArgs) => Promise<OperationResult>;
292
291
  evaluate: (args: BenchEvaluateArgs) => Promise<WorkflowEvaluation>;
293
292
  guardsForInstance: (instanceId: string) => Promise<MutationGuardDoc[]>;
294
293
  guardsForDefinition: (definition: string) => Promise<MutationGuardDoc[]>;
@@ -382,7 +381,7 @@ declare interface Grant_2 {
382
381
  }
383
382
 
384
383
  declare type GuardHelpers = {
385
- /** All deployed `temp.system.guard` docs in the store. */
384
+ /** All deployed guard docs ({@link MutationGuardDoc}) in the store. */
386
385
  listGuards: () => Promise<MutationGuardDoc[]>;
387
386
  /**
388
387
  * Guards that would deny an arbitrary edit to `documentId` right now (i.e.
@@ -394,20 +393,18 @@ declare type GuardHelpers = {
394
393
  as?: Actor,
395
394
  ) => Promise<MutationGuardDoc[]>;
396
395
  /**
397
- * Write to a document through the client's enforced write seam — the bench
396
+ * Write to a document through the client's guarded write seam — the bench
398
397
  * client gates the write against deployed guards (incl. `identity()`) and
399
- * throws `MutationGuardDeniedError` on denial, exactly as the lake would.
400
- * `as` routes the write through a token-scoped sibling so `identity()`
401
- * resolves to that actor.
398
+ * throws `MutationGuardDeniedError` on denial the lake's intended
399
+ * rejection, simulated by the bench. `as` routes the write through a
400
+ * token-scoped sibling so `identity()` resolves to that actor.
402
401
  */
403
- editDocument: (
404
- documentId: string,
405
- patch: Record<string, unknown>,
406
- options?: {
407
- action?: MutationGuardAction;
408
- as?: Actor;
409
- },
410
- ) => Promise<StoreDocument>;
402
+ editDocument: (opts: {
403
+ documentId: string;
404
+ patch: Record<string, unknown>;
405
+ action?: MutationGuardAction;
406
+ as?: Actor;
407
+ }) => Promise<StoreDocument>;
411
408
  };
412
409
 
413
410
  /** Result of a mutation when ids are requested for all affected documents. */
@@ -533,11 +530,15 @@ declare type QueryHelpers = {
533
530
  * workflow?" — useful for filter debugging, UIs that mirror engine
534
531
  * state, etc.
535
532
  */
536
- queryInScope: <T = unknown>(
537
- instanceId: string,
538
- groq: string,
539
- params?: Record<string, unknown>,
540
- ) => Promise<T>;
533
+ queryInScope: <T = unknown>({
534
+ instanceId,
535
+ groq,
536
+ params,
537
+ }: {
538
+ instanceId: string;
539
+ groq: string;
540
+ params?: Record<string, unknown>;
541
+ }) => Promise<T>;
541
542
  };
542
543
 
543
544
  declare type ReadHelpers = {
@@ -584,13 +585,11 @@ declare type ReadHelpers = {
584
585
  * completed instances (`completedAt != null`) by default; set
585
586
  * `{ openOnly: true }` to filter to in-flight only.
586
587
  */
587
- instancesByStage: (
588
- workflowName: string,
589
- stage: string,
590
- options?: {
591
- openOnly?: boolean;
592
- },
593
- ) => Promise<WorkflowInstance[]>;
588
+ instancesByStage: (options: {
589
+ workflowName: string;
590
+ stage: string;
591
+ openOnly?: boolean;
592
+ }) => Promise<WorkflowInstance[]>;
594
593
  /**
595
594
  * Every in-flight instance whose reactive watch-set includes `document`
596
595
  * (a resource-qualified GDR URI) — the reverse of the forward watch-set.
@@ -650,6 +649,18 @@ declare interface ReleaseDocument extends SanityDocument {
650
649
  publishAt?: string;
651
650
  }
652
651
 
652
+ /**
653
+ * A `release.ref` entry pointing at `_.releases.<releaseName>` in the bench's
654
+ * default resource — what a release-targeting workflow's `release` field
655
+ * expects at start.
656
+ */
657
+ export declare function releaseField(
658
+ releaseName: string,
659
+ opts?: {
660
+ name?: string;
661
+ },
662
+ ): InitialFieldValue;
663
+
653
664
  declare interface ReleaseMetadata {
654
665
  title?: string;
655
666
  description?: string;
@@ -737,6 +748,19 @@ declare type StoreDocument = {
737
748
  [key: string]: unknown;
738
749
  };
739
750
 
751
+ /**
752
+ * The conventional workflow-scope `subject` doc.ref entry, keyed by a bare
753
+ * doc id in the bench's default resource. `type` defaults to `'document'`;
754
+ * pass the subject's schema type when a filter or projection reads it.
755
+ */
756
+ export declare function subjectField(
757
+ documentId: string,
758
+ opts?: {
759
+ name?: string;
760
+ type?: string;
761
+ },
762
+ ): InitialFieldValue;
763
+
740
764
  declare interface SystemFields {
741
765
  _rev: string;
742
766
  _createdAt: string;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { guardsForResource, denyingGuards, MutationGuardDeniedError, workflow, WORKFLOW_INSTANCE_TYPE, tagScopeFilter, effectsContextMap, validateTag } from "@sanity/workflow-engine";
1
+ import { guardsForResource, denyingGuards, MutationGuardDeniedError, workflow, instancesQuery, WORKFLOW_INSTANCE_TYPE, tagScopeFilter, effectsContextMap, gdrFromResource, gdrRef, validateTag } from "@sanity/workflow-engine";
2
2
  import require$$0 from "tty";
3
3
  import require$$1 from "util";
4
4
  function escapeRegExp(string2) {
@@ -5010,7 +5010,7 @@ const DEFAULT_WORKFLOW_RESOURCE = {
5010
5010
  type: "dataset",
5011
5011
  id: "test.test"
5012
5012
  }, ALL_ACCESS_USER = {
5013
- kind: "user",
5013
+ kind: "person",
5014
5014
  id: "bench-user",
5015
5015
  roles: ["*"]
5016
5016
  }, WILDCARD_GRANTS = [
@@ -5069,7 +5069,11 @@ function resolveBenchAccess(options) {
5069
5069
  grants: options.grants ?? WILDCARD_GRANTS
5070
5070
  };
5071
5071
  }
5072
- function accessFor(access, args, canTokenResolve) {
5072
+ function accessFor({
5073
+ access,
5074
+ args,
5075
+ canTokenResolve
5076
+ }) {
5073
5077
  if (args.access !== void 0) return args.access;
5074
5078
  if (args.actor === void 0 && args.grants === void 0) return access;
5075
5079
  const inheritedGrants = canTokenResolve ? void 0 : access.grants, grants = args.grants ?? inheritedGrants;
@@ -5082,10 +5086,14 @@ function stripAccessShortcuts(args) {
5082
5086
  const rest = { ...args };
5083
5087
  return delete rest.access, delete rest.actor, delete rest.grants, rest;
5084
5088
  }
5085
- function createEngineWrappers(scope, access, clock) {
5089
+ function createEngineWrappers({
5090
+ scope,
5091
+ access,
5092
+ clock
5093
+ }) {
5086
5094
  const canTokenResolve = "request" in scope.client, withAccess = (args) => ({
5087
5095
  ...scope,
5088
- access: accessFor(access, args, canTokenResolve),
5096
+ access: accessFor({ access, args, canTokenResolve }),
5089
5097
  clock,
5090
5098
  ...stripAccessShortcuts(args)
5091
5099
  });
@@ -5117,8 +5125,8 @@ function createGuardHelpers(client) {
5117
5125
  ...as ? { identity: as.id } : {}
5118
5126
  });
5119
5127
  },
5120
- editDocument: async (documentId, patch, editOptions) => {
5121
- const action = editOptions?.action ?? "update", as = editOptions?.as, writer = as ? client.withConfig({
5128
+ editDocument: async ({ documentId, patch, action: editAction, as }) => {
5129
+ const action = editAction ?? "update", writer = as ? client.withConfig({
5122
5130
  accessControl: { currentUser: { id: as.id }, grants: WILDCARD_GRANTS }
5123
5131
  }) : client;
5124
5132
  return action === "delete" ? await writer.delete(documentId) : await writer.patch(documentId).set(patch).commit(), await client.getDocument(documentId);
@@ -5129,7 +5137,11 @@ function createQueryHelpers(scope) {
5129
5137
  const withParams = (params) => params !== void 0 ? { params } : {};
5130
5138
  return {
5131
5139
  query: (groq, params) => workflow.query({ ...scope, groq, ...withParams(params) }),
5132
- queryInScope: (instanceId, groq, params) => workflow.queryInScope({ ...scope, instanceId, groq, ...withParams(params) })
5140
+ queryInScope: ({
5141
+ instanceId,
5142
+ groq,
5143
+ params
5144
+ }) => workflow.queryInScope({ ...scope, instanceId, groq, ...withParams(params) })
5133
5145
  };
5134
5146
  }
5135
5147
  function createReadHelpers(scope) {
@@ -5168,24 +5180,49 @@ function createReadHelpers(scope) {
5168
5180
  { ref: subjectRef, entry: entryName, tag }
5169
5181
  )
5170
5182
  ),
5171
- instancesByStage: async (workflowName, stage, queryOptions) => {
5172
- const filter = queryOptions?.openOnly ? " && completedAt == null" : "";
5173
- return client.fetch(
5174
- `*[_type == "${WORKFLOW_INSTANCE_TYPE}" && definition == $wf && currentStage == $stage && ${tagScopeFilter()}${filter}]
5175
- | order(startedAt asc)`,
5176
- { wf: workflowName, stage, tag }
5177
- );
5183
+ instancesByStage: async ({ workflowName, stage, openOnly }) => {
5184
+ const { query, params } = instancesQuery({
5185
+ tag,
5186
+ filter: { definition: workflowName, stage, includeCompleted: !openOnly }
5187
+ });
5188
+ return client.fetch(query, params);
5178
5189
  },
5179
5190
  instancesForDocument: async (document2) => workflow.instancesForDocument({ ...scope, document: document2 }),
5180
5191
  snapshot: () => client.snapshot()
5181
5192
  };
5182
5193
  }
5194
+ function subjectField(documentId, opts) {
5195
+ return {
5196
+ type: "doc.ref",
5197
+ name: opts?.name ?? "subject",
5198
+ value: gdrRef({
5199
+ res: DEFAULT_WORKFLOW_RESOURCE,
5200
+ documentId,
5201
+ type: opts?.type ?? "document"
5202
+ })
5203
+ };
5204
+ }
5205
+ function releaseField(releaseName, opts) {
5206
+ return {
5207
+ type: "release.ref",
5208
+ name: opts?.name ?? "release",
5209
+ value: {
5210
+ id: gdrFromResource(DEFAULT_WORKFLOW_RESOURCE, `_.releases.${releaseName}`),
5211
+ type: "system.release",
5212
+ releaseName
5213
+ }
5214
+ };
5215
+ }
5183
5216
  function createBench(options = {}) {
5184
5217
  const tag = options.tag ?? "bench";
5185
5218
  validateTag(tag);
5186
- const workflowResource = options.workflowResource ?? DEFAULT_WORKFLOW_RESOURCE, client = resolveBenchClient(options), scope = { client, tag, workflowResource }, access = resolveBenchAccess(options);
5219
+ const workflowResource = options.workflowResource ?? DEFAULT_WORKFLOW_RESOURCE, client = resolveBenchClient(options), scope = {
5220
+ client,
5221
+ tag,
5222
+ workflowResource
5223
+ }, access = resolveBenchAccess(options);
5187
5224
  let frozenNow = options.now !== void 0 ? assertIsoInstant(options.now) : void 0;
5188
- const clock = () => frozenNow ?? (/* @__PURE__ */ new Date()).toISOString();
5225
+ const clock = () => frozenNow ?? (/* @__PURE__ */ new Date()).toISOString(), engine = createEngineWrappers({ scope, access, clock }), reads = createReadHelpers(scope);
5189
5226
  return {
5190
5227
  client,
5191
5228
  access,
@@ -5201,10 +5238,16 @@ function createBench(options = {}) {
5201
5238
  throw new Error(`bench.advance: ms must be a finite number, got ${ms2}`);
5202
5239
  frozenNow = new Date(Date.parse(frozenNow ?? (/* @__PURE__ */ new Date()).toISOString()) + ms2).toISOString();
5203
5240
  },
5204
- ...createEngineWrappers(scope, access, clock),
5205
- ...createReadHelpers(scope),
5241
+ ...engine,
5242
+ ...reads,
5206
5243
  ...createGuardHelpers(client),
5207
- ...createQueryHelpers(scope)
5244
+ ...createQueryHelpers(scope),
5245
+ completePendingEffect: async ({ effect, ...rest }) => {
5246
+ const match = (await reads.pendingEffects(rest.instanceId)).find((e) => e.name === effect);
5247
+ if (match === void 0)
5248
+ throw new Error(`completePendingEffect: no pending effect named "${effect}"`);
5249
+ return engine.completeEffect({ ...rest, effectKey: match._key });
5250
+ }
5208
5251
  };
5209
5252
  }
5210
5253
  function assertIsoInstant(iso) {
@@ -5218,6 +5261,8 @@ export {
5218
5261
  ALL_ACCESS_USER,
5219
5262
  DEFAULT_WORKFLOW_RESOURCE,
5220
5263
  WILDCARD_GRANTS,
5221
- createBench
5264
+ createBench,
5265
+ releaseField,
5266
+ subjectField
5222
5267
  };
5223
5268
  //# sourceMappingURL=index.js.map