@sanity/workflow-engine-test 0.12.0 → 0.13.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/CHANGELOG.md +35 -0
- package/README.md +2 -2
- package/dist/index.cjs +17 -2
- package/dist/index.d.cts +27 -10
- package/dist/index.d.ts +27 -10
- package/dist/index.js +17 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @sanity/workflow-engine-test
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 00c089d: **BREAKING:** Require every definition deployment and workflow deployment configuration to state an `expectedMinReaderModel` literal that exactly matches the installed engine's writer capability.
|
|
8
|
+
|
|
9
|
+
Deploy and definition-diff paths now reject missing or stale acknowledgements before client access or telemetry, with a structured error and readers-first rollout guidance.
|
|
10
|
+
|
|
11
|
+
- 55a54b3: Surfaces understand the new `subject` field kind. Studio plugin: the start dialog's default subject seed lands on a definition's `subject`-kind entry whatever it is named (the doc.ref-named-`subject` convention stays the fallback), subject entries get the document picker / read-only face / state-panel preview / document pill, and mapping validation checks the subject entry's `types` facet. MCP: the subject lookup behind title enrichment prefers the `subject`-kind entry and keeps the name convention as fallback; the authoring guide teaches the kind. Test bench — **BREAKING:** `subjectField` now builds a `subject`-KIND entry value (matching its name and the engine's subject rule); a definition declaring the doc.ref convention needs the new `docRefField(documentId, {name})` instead. `instancesForSubject` matches both single-ref kinds.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 71cd58e: Explain that effect-completion field operations require an explicit workflow or stage target scope when validation rejects a missing scope, and document the requirement on `EffectHandler`.
|
|
16
|
+
- 9126299: **BREAKING:** Delete persisted stage guard documents when their stage exits, and remove the lifted-record `GUARD_LIFTED_PREDICATE` and `isGuardLifted` exports.
|
|
17
|
+
|
|
18
|
+
Guard deletion now uses the observed document revision so stale exit reconciliation cannot delete a guard reactivated by a newer stage visit. Reactive guard streams contain only active persisted guards.
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [239d9f6]
|
|
21
|
+
- Updated dependencies [3af2ca0]
|
|
22
|
+
- Updated dependencies [7276702]
|
|
23
|
+
- Updated dependencies [58f8211]
|
|
24
|
+
- Updated dependencies [00c089d]
|
|
25
|
+
- Updated dependencies [71cd58e]
|
|
26
|
+
- Updated dependencies [cd03973]
|
|
27
|
+
- Updated dependencies [d26cc1a]
|
|
28
|
+
- Updated dependencies [9126299]
|
|
29
|
+
- Updated dependencies [72018af]
|
|
30
|
+
- Updated dependencies [5cd8ffd]
|
|
31
|
+
- Updated dependencies [b82bda4]
|
|
32
|
+
- Updated dependencies [55a54b3]
|
|
33
|
+
- Updated dependencies [b82bda4]
|
|
34
|
+
- Updated dependencies [4490442]
|
|
35
|
+
- Updated dependencies [1540dce]
|
|
36
|
+
- @sanity/workflow-engine@0.18.0
|
|
37
|
+
|
|
3
38
|
## 0.12.0
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ test reads as the workflow it exercises:
|
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
const bench = createBench({now: '2026-01-01T00:00:00Z'})
|
|
40
|
-
await bench.deployDefinitions({definitions: [reviewWorkflow]})
|
|
40
|
+
await bench.deployDefinitions({expectedMinReaderModel: 2, definitions: [reviewWorkflow]})
|
|
41
41
|
|
|
42
42
|
const {instance} = await bench.startInstance({
|
|
43
43
|
definition: 'review-workflow',
|
|
@@ -72,7 +72,7 @@ raw `workflow.*` calls, and the default tag ships as the `BENCH_TAG` constant.
|
|
|
72
72
|
## Mutation guards
|
|
73
73
|
|
|
74
74
|
A workflow stage can deploy **mutation guards** — `temp.system.guard` documents
|
|
75
|
-
that lock the documents it governs while the stage is active, and
|
|
75
|
+
that lock the documents it governs while the stage is active, and are deleted when it
|
|
76
76
|
exits. The lake does not enforce this doc type yet: in production, guard
|
|
77
77
|
enforcement is the engine's own **optimistic** evaluation (advisory verdicts
|
|
78
78
|
and engine-side write denials), and the lake ACL is the only hard boundary.
|
package/dist/index.cjs
CHANGED
|
@@ -304,7 +304,7 @@ function createReadHelpers(scope) {
|
|
|
304
304
|
...engineScope,
|
|
305
305
|
...args
|
|
306
306
|
}),
|
|
307
|
-
instancesForSubject: async (subjectRef, entryName = "subject") => client.fetch(`*[_type == "${workflowEngine.WORKFLOW_INSTANCE_TYPE}"\n && fields[_type
|
|
307
|
+
instancesForSubject: async (subjectRef, entryName = "subject") => client.fetch(`*[_type == "${workflowEngine.WORKFLOW_INSTANCE_TYPE}"\n && fields[_type in ["doc.ref", "subject"] && name == $entry][0].value.id == $ref\n && ${workflowEngine.tagScopeFilter()}] | order(startedAt asc)`, {
|
|
308
308
|
ref: subjectRef,
|
|
309
309
|
entry: entryName,
|
|
310
310
|
tag: tag
|
|
@@ -354,7 +354,7 @@ function createBenchEngine(bench, overrides = {}) {
|
|
|
354
354
|
|
|
355
355
|
function subjectField(documentId, opts) {
|
|
356
356
|
return {
|
|
357
|
-
type: "
|
|
357
|
+
type: "subject",
|
|
358
358
|
name: opts?.name ?? "subject",
|
|
359
359
|
value: workflowEngine.gdrRef({
|
|
360
360
|
res: DEFAULT_WORKFLOW_RESOURCE,
|
|
@@ -364,6 +364,18 @@ function subjectField(documentId, opts) {
|
|
|
364
364
|
};
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
+
function docRefField(documentId, opts) {
|
|
368
|
+
return {
|
|
369
|
+
type: "doc.ref",
|
|
370
|
+
name: opts.name,
|
|
371
|
+
value: workflowEngine.gdrRef({
|
|
372
|
+
res: DEFAULT_WORKFLOW_RESOURCE,
|
|
373
|
+
documentId: documentId,
|
|
374
|
+
type: opts.type ?? "document"
|
|
375
|
+
})
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
|
|
367
379
|
function releaseField(releaseName, opts) {
|
|
368
380
|
return {
|
|
369
381
|
type: "release.ref",
|
|
@@ -392,6 +404,7 @@ async function startedInstanceFixture(bench, opts) {
|
|
|
392
404
|
} ]
|
|
393
405
|
});
|
|
394
406
|
await bench.deployDefinitions({
|
|
407
|
+
expectedMinReaderModel: 2,
|
|
395
408
|
definitions: [ flow ]
|
|
396
409
|
});
|
|
397
410
|
const {instance: instance} = await bench.startInstance({
|
|
@@ -505,6 +518,8 @@ exports.createBench = createBench;
|
|
|
505
518
|
|
|
506
519
|
exports.createBenchEngine = createBenchEngine;
|
|
507
520
|
|
|
521
|
+
exports.docRefField = docRefField;
|
|
522
|
+
|
|
508
523
|
exports.releaseField = releaseField;
|
|
509
524
|
|
|
510
525
|
exports.startedInstanceFixture = startedInstanceFixture;
|
package/dist/index.d.cts
CHANGED
|
@@ -276,6 +276,19 @@ export declare interface CreateBenchOptions {
|
|
|
276
276
|
/** Default workflow resource for benches that don't pass one. */
|
|
277
277
|
export declare const DEFAULT_WORKFLOW_RESOURCE: WorkflowResource;
|
|
278
278
|
|
|
279
|
+
/**
|
|
280
|
+
* A plain `doc.ref` entry value in the bench's default resource — for
|
|
281
|
+
* document-reference inputs that are NOT the workflow's subject (the
|
|
282
|
+
* `subject` kind is what marks THE subject; see {@link subjectField}).
|
|
283
|
+
*/
|
|
284
|
+
export declare function docRefField(
|
|
285
|
+
documentId: string,
|
|
286
|
+
opts: {
|
|
287
|
+
name: string;
|
|
288
|
+
type?: string;
|
|
289
|
+
},
|
|
290
|
+
): InitialFieldValue;
|
|
291
|
+
|
|
279
292
|
/**
|
|
280
293
|
* The write {@link GuardHelpers.editDocument} performs. Every arm is a real
|
|
281
294
|
* distinct client write the guard seam vets under that action — `create` is
|
|
@@ -335,6 +348,7 @@ declare type EngineWrappers = {
|
|
|
335
348
|
* so the fixture module needs no import of the bench itself. */
|
|
336
349
|
declare interface FixtureBench {
|
|
337
350
|
deployDefinitions: (args: {
|
|
351
|
+
expectedMinReaderModel: 2;
|
|
338
352
|
definitions: WorkflowDefinition[];
|
|
339
353
|
}) => Promise<unknown>;
|
|
340
354
|
startInstance: (args: {
|
|
@@ -350,8 +364,8 @@ declare type GuardHelpers = {
|
|
|
350
364
|
listGuards: () => Promise<MutationGuardDoc[]>;
|
|
351
365
|
/**
|
|
352
366
|
* Guards that would deny an arbitrary edit to `documentId` right now (i.e.
|
|
353
|
-
* active locks). Probes by changing every non-system field; a
|
|
354
|
-
*
|
|
367
|
+
* active locks). Probes by changing every non-system field; a guard whose
|
|
368
|
+
* predicate is `"true"` returns nothing.
|
|
355
369
|
*/
|
|
356
370
|
activeGuardsForDocument: (
|
|
357
371
|
documentId: string,
|
|
@@ -447,10 +461,10 @@ declare type ReadHelpers = {
|
|
|
447
461
|
*/
|
|
448
462
|
children: (args: ChildrenArgs) => Promise<WorkflowInstance[]>;
|
|
449
463
|
/**
|
|
450
|
-
* All workflow instances whose
|
|
451
|
-
* `entryName` (default `"subject"`) matches the given doc
|
|
452
|
-
* for "what workflow is running on this document?" questions.
|
|
453
|
-
* `entryName` for workflows whose subject entry uses a different name.
|
|
464
|
+
* All workflow instances whose single-ref field entry (`subject` kind or
|
|
465
|
+
* `doc.ref`) named `entryName` (default `"subject"`) matches the given doc
|
|
466
|
+
* id. Useful for "what workflow is running on this document?" questions.
|
|
467
|
+
* Pass `entryName` for workflows whose subject entry uses a different name.
|
|
454
468
|
*/
|
|
455
469
|
instancesForSubject: (
|
|
456
470
|
subjectRef: string,
|
|
@@ -478,7 +492,7 @@ declare type ReadHelpers = {
|
|
|
478
492
|
/**
|
|
479
493
|
* The startable half of {@link ReadHelpers.instancesForDocument}: the
|
|
480
494
|
* latest deployed version of every definition applicable to the LOADED
|
|
481
|
-
* candidate document — startable,
|
|
495
|
+
* candidate document — startable, the `subject`-kind entry accepts its
|
|
482
496
|
* `_type`, `start.filter` (browse-time-pure) passes. All matches, name
|
|
483
497
|
* ascending.
|
|
484
498
|
*/
|
|
@@ -530,9 +544,12 @@ declare type StoreDocument = {
|
|
|
530
544
|
};
|
|
531
545
|
|
|
532
546
|
/**
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
547
|
+
* A workflow-scope `subject`-KIND entry value, keyed by a bare doc id in the
|
|
548
|
+
* bench's default resource — what a definition declaring the first-class
|
|
549
|
+
* `subject` kind expects at start (applicability and document pickers key on
|
|
550
|
+
* that kind). `type` defaults to `'document'`; pass the subject's schema
|
|
551
|
+
* type when a filter or projection reads it. For a plain `doc.ref` input,
|
|
552
|
+
* use {@link docRefField}.
|
|
536
553
|
*/
|
|
537
554
|
export declare function subjectField(
|
|
538
555
|
documentId: string,
|
package/dist/index.d.ts
CHANGED
|
@@ -276,6 +276,19 @@ export declare interface CreateBenchOptions {
|
|
|
276
276
|
/** Default workflow resource for benches that don't pass one. */
|
|
277
277
|
export declare const DEFAULT_WORKFLOW_RESOURCE: WorkflowResource;
|
|
278
278
|
|
|
279
|
+
/**
|
|
280
|
+
* A plain `doc.ref` entry value in the bench's default resource — for
|
|
281
|
+
* document-reference inputs that are NOT the workflow's subject (the
|
|
282
|
+
* `subject` kind is what marks THE subject; see {@link subjectField}).
|
|
283
|
+
*/
|
|
284
|
+
export declare function docRefField(
|
|
285
|
+
documentId: string,
|
|
286
|
+
opts: {
|
|
287
|
+
name: string;
|
|
288
|
+
type?: string;
|
|
289
|
+
},
|
|
290
|
+
): InitialFieldValue;
|
|
291
|
+
|
|
279
292
|
/**
|
|
280
293
|
* The write {@link GuardHelpers.editDocument} performs. Every arm is a real
|
|
281
294
|
* distinct client write the guard seam vets under that action — `create` is
|
|
@@ -335,6 +348,7 @@ declare type EngineWrappers = {
|
|
|
335
348
|
* so the fixture module needs no import of the bench itself. */
|
|
336
349
|
declare interface FixtureBench {
|
|
337
350
|
deployDefinitions: (args: {
|
|
351
|
+
expectedMinReaderModel: 2;
|
|
338
352
|
definitions: WorkflowDefinition[];
|
|
339
353
|
}) => Promise<unknown>;
|
|
340
354
|
startInstance: (args: {
|
|
@@ -350,8 +364,8 @@ declare type GuardHelpers = {
|
|
|
350
364
|
listGuards: () => Promise<MutationGuardDoc[]>;
|
|
351
365
|
/**
|
|
352
366
|
* Guards that would deny an arbitrary edit to `documentId` right now (i.e.
|
|
353
|
-
* active locks). Probes by changing every non-system field; a
|
|
354
|
-
*
|
|
367
|
+
* active locks). Probes by changing every non-system field; a guard whose
|
|
368
|
+
* predicate is `"true"` returns nothing.
|
|
355
369
|
*/
|
|
356
370
|
activeGuardsForDocument: (
|
|
357
371
|
documentId: string,
|
|
@@ -447,10 +461,10 @@ declare type ReadHelpers = {
|
|
|
447
461
|
*/
|
|
448
462
|
children: (args: ChildrenArgs) => Promise<WorkflowInstance[]>;
|
|
449
463
|
/**
|
|
450
|
-
* All workflow instances whose
|
|
451
|
-
* `entryName` (default `"subject"`) matches the given doc
|
|
452
|
-
* for "what workflow is running on this document?" questions.
|
|
453
|
-
* `entryName` for workflows whose subject entry uses a different name.
|
|
464
|
+
* All workflow instances whose single-ref field entry (`subject` kind or
|
|
465
|
+
* `doc.ref`) named `entryName` (default `"subject"`) matches the given doc
|
|
466
|
+
* id. Useful for "what workflow is running on this document?" questions.
|
|
467
|
+
* Pass `entryName` for workflows whose subject entry uses a different name.
|
|
454
468
|
*/
|
|
455
469
|
instancesForSubject: (
|
|
456
470
|
subjectRef: string,
|
|
@@ -478,7 +492,7 @@ declare type ReadHelpers = {
|
|
|
478
492
|
/**
|
|
479
493
|
* The startable half of {@link ReadHelpers.instancesForDocument}: the
|
|
480
494
|
* latest deployed version of every definition applicable to the LOADED
|
|
481
|
-
* candidate document — startable,
|
|
495
|
+
* candidate document — startable, the `subject`-kind entry accepts its
|
|
482
496
|
* `_type`, `start.filter` (browse-time-pure) passes. All matches, name
|
|
483
497
|
* ascending.
|
|
484
498
|
*/
|
|
@@ -530,9 +544,12 @@ declare type StoreDocument = {
|
|
|
530
544
|
};
|
|
531
545
|
|
|
532
546
|
/**
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
547
|
+
* A workflow-scope `subject`-KIND entry value, keyed by a bare doc id in the
|
|
548
|
+
* bench's default resource — what a definition declaring the first-class
|
|
549
|
+
* `subject` kind expects at start (applicability and document pickers key on
|
|
550
|
+
* that kind). `type` defaults to `'document'`; pass the subject's schema
|
|
551
|
+
* type when a filter or projection reads it. For a plain `doc.ref` input,
|
|
552
|
+
* use {@link docRefField}.
|
|
536
553
|
*/
|
|
537
554
|
export declare function subjectField(
|
|
538
555
|
documentId: string,
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { guardsForResource, denyingGuards, MutationGuardDeniedError, workflow, instancesQuery, WORKFLOW_INSTANCE_TYPE, tagScopeFilter, effectOutputsMap, contextMap, createEngine,
|
|
1
|
+
import { guardsForResource, denyingGuards, MutationGuardDeniedError, workflow, instancesQuery, WORKFLOW_INSTANCE_TYPE, tagScopeFilter, effectOutputsMap, contextMap, createEngine, gdrRef, releaseRef, validateTag, EXECUTION_KINDS, resourceFromParsed, sameResource, datasetResourceParts } from "@sanity/workflow-engine";
|
|
2
2
|
|
|
3
3
|
import { createTestClient, defaultAclPath, isDraftId, isVersionId } from "@sanity-labs/client-fake-for-test";
|
|
4
4
|
|
|
@@ -302,7 +302,7 @@ function createReadHelpers(scope) {
|
|
|
302
302
|
...engineScope,
|
|
303
303
|
...args
|
|
304
304
|
}),
|
|
305
|
-
instancesForSubject: async (subjectRef, entryName = "subject") => client.fetch(`*[_type == "${WORKFLOW_INSTANCE_TYPE}"\n && fields[_type
|
|
305
|
+
instancesForSubject: async (subjectRef, entryName = "subject") => client.fetch(`*[_type == "${WORKFLOW_INSTANCE_TYPE}"\n && fields[_type in ["doc.ref", "subject"] && name == $entry][0].value.id == $ref\n && ${tagScopeFilter()}] | order(startedAt asc)`, {
|
|
306
306
|
ref: subjectRef,
|
|
307
307
|
entry: entryName,
|
|
308
308
|
tag: tag
|
|
@@ -352,7 +352,7 @@ function createBenchEngine(bench, overrides = {}) {
|
|
|
352
352
|
|
|
353
353
|
function subjectField(documentId, opts) {
|
|
354
354
|
return {
|
|
355
|
-
type: "
|
|
355
|
+
type: "subject",
|
|
356
356
|
name: opts?.name ?? "subject",
|
|
357
357
|
value: gdrRef({
|
|
358
358
|
res: DEFAULT_WORKFLOW_RESOURCE,
|
|
@@ -362,6 +362,18 @@ function subjectField(documentId, opts) {
|
|
|
362
362
|
};
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
+
function docRefField(documentId, opts) {
|
|
366
|
+
return {
|
|
367
|
+
type: "doc.ref",
|
|
368
|
+
name: opts.name,
|
|
369
|
+
value: gdrRef({
|
|
370
|
+
res: DEFAULT_WORKFLOW_RESOURCE,
|
|
371
|
+
documentId: documentId,
|
|
372
|
+
type: opts.type ?? "document"
|
|
373
|
+
})
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
365
377
|
function releaseField(releaseName, opts) {
|
|
366
378
|
return {
|
|
367
379
|
type: "release.ref",
|
|
@@ -390,6 +402,7 @@ async function startedInstanceFixture(bench, opts) {
|
|
|
390
402
|
} ]
|
|
391
403
|
});
|
|
392
404
|
await bench.deployDefinitions({
|
|
405
|
+
expectedMinReaderModel: 2,
|
|
393
406
|
definitions: [ flow ]
|
|
394
407
|
});
|
|
395
408
|
const {instance: instance} = await bench.startInstance({
|
|
@@ -489,4 +502,4 @@ function assertIsoInstant(iso) {
|
|
|
489
502
|
return new Date(ms).toISOString();
|
|
490
503
|
}
|
|
491
504
|
|
|
492
|
-
export { ALL_ACCESS, ALL_ACCESS_USER, BENCH_TAG, DEFAULT_WORKFLOW_RESOURCE, WILDCARD_GRANTS, createBench, createBenchEngine, releaseField, startedInstanceFixture, subjectField };
|
|
505
|
+
export { ALL_ACCESS, ALL_ACCESS_USER, BENCH_TAG, DEFAULT_WORKFLOW_RESOURCE, WILDCARD_GRANTS, createBench, createBenchEngine, docRefField, releaseField, startedInstanceFixture, subjectField };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workflow-engine-test",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "In-memory test bench (createBench) for @sanity/workflow-engine.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@sanity-labs/client-fake-for-test": "^0.8.0",
|
|
46
|
-
"@sanity/workflow-engine": "0.
|
|
46
|
+
"@sanity/workflow-engine": "0.18.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@sanity/client": "^7.22.1",
|