@sanity/workflow-engine-test 0.10.0 → 0.11.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 +37 -0
- package/README.md +15 -7
- package/dist/index.cjs +82 -5702
- package/dist/index.d.cts +70 -796
- package/dist/index.d.ts +70 -796
- package/dist/index.js +81 -5695
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import type { AbortInstanceArgs } from "@sanity/workflow-engine";
|
|
2
2
|
import { ActivityStatus } from "@sanity/workflow-engine";
|
|
3
3
|
import { Actor } from "@sanity/workflow-engine";
|
|
4
|
-
import {
|
|
4
|
+
import { ChildrenArgs } from "@sanity/workflow-engine";
|
|
5
5
|
import { Clock } from "@sanity/workflow-engine";
|
|
6
6
|
import type { CompleteEffectArgs } from "@sanity/workflow-engine";
|
|
7
7
|
import { CreateEngineArgs } from "@sanity/workflow-engine";
|
|
8
8
|
import type { DeclaredExecutionContext } from "@sanity/workflow-engine";
|
|
9
|
+
import { DefinitionsForDocumentArgs } from "@sanity/workflow-engine";
|
|
10
|
+
import type { DeleteDefinitionArgs } from "@sanity/workflow-engine";
|
|
11
|
+
import { DeleteDefinitionResult } from "@sanity/workflow-engine";
|
|
9
12
|
import { DeployDefinitionsArgs } from "@sanity/workflow-engine";
|
|
10
13
|
import { DeployDefinitionsResult } from "@sanity/workflow-engine";
|
|
11
14
|
import { DeployedDefinition } from "@sanity/workflow-engine";
|
|
12
15
|
import type { EditFieldArgs } from "@sanity/workflow-engine";
|
|
13
16
|
import { Engine } from "@sanity/workflow-engine";
|
|
14
17
|
import type { EvaluateArgs } from "@sanity/workflow-engine";
|
|
18
|
+
import { FindPendingEffectsArgs } from "@sanity/workflow-engine";
|
|
15
19
|
import type { FireActionArgs } from "@sanity/workflow-engine";
|
|
16
|
-
import { GdrUri } from "@sanity/workflow-engine";
|
|
17
20
|
import type { Grant } from "@sanity/workflow-engine";
|
|
18
21
|
import { InitialFieldValue } from "@sanity/workflow-engine";
|
|
22
|
+
import { InstanceRefArgs } from "@sanity/workflow-engine";
|
|
23
|
+
import { InstancesForDocumentArgs } from "@sanity/workflow-engine";
|
|
24
|
+
import { InstancesQueryFilter } from "@sanity/workflow-engine";
|
|
19
25
|
import { MutationGuardAction } from "@sanity/workflow-engine";
|
|
20
26
|
import { MutationGuardDoc } from "@sanity/workflow-engine";
|
|
21
27
|
import type { OperationArgs } from "@sanity/workflow-engine";
|
|
@@ -23,24 +29,13 @@ import { OperationResult } from "@sanity/workflow-engine";
|
|
|
23
29
|
import { PendingEffect } from "@sanity/workflow-engine";
|
|
24
30
|
import type { SetStageArgs } from "@sanity/workflow-engine";
|
|
25
31
|
import type { StartInstanceArgs } from "@sanity/workflow-engine";
|
|
32
|
+
import type { TestClient } from "@sanity-labs/client-fake-for-test";
|
|
26
33
|
import type { WorkflowAccess } from "@sanity/workflow-engine";
|
|
27
34
|
import { WorkflowDefinitionInput } from "@sanity/workflow-engine";
|
|
28
35
|
import { WorkflowEvaluation } from "@sanity/workflow-engine";
|
|
29
36
|
import { WorkflowInstance } from "@sanity/workflow-engine";
|
|
30
37
|
import type { WorkflowResource } from "@sanity/workflow-engine";
|
|
31
38
|
|
|
32
|
-
declare type Action = ReleaseAction | VersionAction;
|
|
33
|
-
|
|
34
|
-
/** Options for `action()`. Only `tag` is meaningful to the fake. */
|
|
35
|
-
declare interface ActionOptions {
|
|
36
|
-
/** Request tag, recorded on the {@link CallRecord} (`null` = explicit suppression). */
|
|
37
|
-
tag?: string | null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
declare interface ActionResult {
|
|
41
|
-
transactionId: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
39
|
/**
|
|
45
40
|
* The bench's default identity — wildcard user + wildcard grants,
|
|
46
41
|
* registered as the default token on the bench's fake client so the
|
|
@@ -94,6 +89,9 @@ declare type BenchArgsWithGrants<T> = BenchArgs<T> & {
|
|
|
94
89
|
|
|
95
90
|
declare type BenchCompleteEffectArgs = BenchArgs<CompleteEffectArgs>;
|
|
96
91
|
|
|
92
|
+
declare type BenchDeleteDefinitionArgs =
|
|
93
|
+
BenchArgsWithGrants<DeleteDefinitionArgs>;
|
|
94
|
+
|
|
97
95
|
declare type BenchEditFieldArgs = BenchArgsWithGrants<EditFieldArgs>;
|
|
98
96
|
|
|
99
97
|
declare type BenchEvaluateArgs = BenchArgsWithGrants<EvaluateArgs>;
|
|
@@ -146,8 +144,7 @@ declare interface BenchState {
|
|
|
146
144
|
* Freeze the bench clock at an explicit ISO instant. Every subsequent
|
|
147
145
|
* engine call (`startInstance` / `fireAction` / `tick` / `completeEffect`
|
|
148
146
|
* / `evaluate`) sees this as `$now` and stamps it on history, so
|
|
149
|
-
* time-based `
|
|
150
|
-
* deterministic.
|
|
147
|
+
* time-based `when` triggers and SLA predicates are deterministic.
|
|
151
148
|
*/
|
|
152
149
|
setNow: (iso: string) => void;
|
|
153
150
|
/**
|
|
@@ -160,28 +157,6 @@ declare interface BenchState {
|
|
|
160
157
|
|
|
161
158
|
declare type BenchTickArgs = BenchArgs<OperationArgs>;
|
|
162
159
|
|
|
163
|
-
/**
|
|
164
|
-
* One recorded invocation of a client method — the spy layer behind
|
|
165
|
-
* `client.calls()` / `client.callCount()`. `result` holds the resolved
|
|
166
|
-
* value (awaited, for async methods); `error` holds the thrown/rejected
|
|
167
|
-
* value. Builder-returning methods (`patch`, `transaction`) record the
|
|
168
|
-
* builder as `result`; their eventual writes show up in the mutation log.
|
|
169
|
-
*/
|
|
170
|
-
declare interface CallRecord {
|
|
171
|
-
/** Method name; namespace methods are dotted, e.g. `releases.create`. */
|
|
172
|
-
method: string;
|
|
173
|
-
/** Arguments as passed (stored by reference, like `vi.fn`). */
|
|
174
|
-
args: unknown[];
|
|
175
|
-
/** Resolved/returned value, set once the call settles successfully. */
|
|
176
|
-
result?: unknown;
|
|
177
|
-
/** Thrown or rejected value, set if the call failed. */
|
|
178
|
-
error?: unknown;
|
|
179
|
-
/** Request tag from the call's options, when one was passed (`null` = explicit suppression). */
|
|
180
|
-
tag?: string | null;
|
|
181
|
-
projectId: string;
|
|
182
|
-
dataset: string;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
160
|
/** Helpers composed across the wrapper + read groups at bench assembly. */
|
|
186
161
|
declare interface ComposedHelpers {
|
|
187
162
|
/**
|
|
@@ -274,35 +249,17 @@ export declare interface CreateBenchOptions {
|
|
|
274
249
|
executionContext?: DeclaredExecutionContext;
|
|
275
250
|
}
|
|
276
251
|
|
|
277
|
-
declare interface CurrentUser {
|
|
278
|
-
id: string;
|
|
279
|
-
name?: string;
|
|
280
|
-
email?: string;
|
|
281
|
-
/** @deprecated singular `role` on legacy responses */
|
|
282
|
-
role?: string;
|
|
283
|
-
roles?: {
|
|
284
|
-
name: string;
|
|
285
|
-
title?: string;
|
|
286
|
-
description?: string;
|
|
287
|
-
}[];
|
|
288
|
-
}
|
|
289
|
-
|
|
290
252
|
/** Default workflow resource for benches that don't pass one. */
|
|
291
253
|
export declare const DEFAULT_WORKFLOW_RESOURCE: WorkflowResource;
|
|
292
254
|
|
|
293
255
|
/**
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
256
|
+
* The write {@link GuardHelpers.editDocument} performs. Every arm is a real
|
|
257
|
+
* distinct client write the guard seam vets under that action — `create` is
|
|
258
|
+
* deliberately absent because editing addresses an existing document; create
|
|
259
|
+
* through the client (`bench.client.create` / `clientFor(...).create`), which
|
|
260
|
+
* the same seam gates as a create.
|
|
298
261
|
*/
|
|
299
|
-
declare
|
|
300
|
-
_id?: string;
|
|
301
|
-
_type: string;
|
|
302
|
-
[field: string]: unknown;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
declare type DocumentValuePermission = "create" | "read" | "update";
|
|
262
|
+
export declare type EditDocumentAction = Exclude<MutationGuardAction, "create">;
|
|
306
263
|
|
|
307
264
|
/**
|
|
308
265
|
* How {@link GuardHelpers.editDocument} mutates the document. Each present
|
|
@@ -332,6 +289,9 @@ declare type EngineWrappers = {
|
|
|
332
289
|
deployDefinitions: <T extends WorkflowDefinitionInput<T>>(
|
|
333
290
|
args: DeployDefinitionsArgs<T>,
|
|
334
291
|
) => Promise<DeployDefinitionsResult>;
|
|
292
|
+
deleteDefinition: (
|
|
293
|
+
args: BenchDeleteDefinitionArgs,
|
|
294
|
+
) => Promise<DeleteDefinitionResult>;
|
|
335
295
|
startInstance: (args: BenchStartInstanceArgs) => Promise<OperationResult>;
|
|
336
296
|
fireAction: (args: BenchFireActionArgs) => Promise<OperationResult>;
|
|
337
297
|
editField: (args: BenchEditFieldArgs) => Promise<OperationResult>;
|
|
@@ -346,97 +306,6 @@ declare type EngineWrappers = {
|
|
|
346
306
|
guardsForDefinition: (definition: string) => Promise<MutationGuardDoc[]>;
|
|
347
307
|
};
|
|
348
308
|
|
|
349
|
-
/**
|
|
350
|
-
* A single mutation in the raw array form accepted by `mutate()` — the
|
|
351
|
-
* same shape `@sanity/client` accepts. The inline `patch` form mirrors
|
|
352
|
-
* the real client's keyed patch object.
|
|
353
|
-
*/
|
|
354
|
-
declare type FakeMutation =
|
|
355
|
-
| {
|
|
356
|
-
create: SanityDocumentLike;
|
|
357
|
-
}
|
|
358
|
-
| {
|
|
359
|
-
createOrReplace: SanityDocumentLike;
|
|
360
|
-
}
|
|
361
|
-
| {
|
|
362
|
-
createIfNotExists: SanityDocumentLike;
|
|
363
|
-
}
|
|
364
|
-
| {
|
|
365
|
-
delete: {
|
|
366
|
-
id: string;
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
| {
|
|
370
|
-
patch: {
|
|
371
|
-
id: string;
|
|
372
|
-
ifRevisionID?: string;
|
|
373
|
-
set?: Record<string, unknown>;
|
|
374
|
-
setIfMissing?: Record<string, unknown>;
|
|
375
|
-
unset?: string[];
|
|
376
|
-
inc?: Record<string, number>;
|
|
377
|
-
dec?: Record<string, number>;
|
|
378
|
-
insert?: {
|
|
379
|
-
before?: string;
|
|
380
|
-
after?: string;
|
|
381
|
-
replace?: string;
|
|
382
|
-
items: unknown[];
|
|
383
|
-
};
|
|
384
|
-
};
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* Data-plane subset of `@sanity/client`'s surface, with multi-dataset support.
|
|
389
|
-
*
|
|
390
|
-
* One `createTestClient()` call creates a registry of stores keyed by
|
|
391
|
-
* `(projectId, dataset)`. The returned client points at one of them.
|
|
392
|
-
* `withConfig({ projectId, dataset })` returns a new handle into the same
|
|
393
|
-
* registry but pointing at a different store — useful for workflows where
|
|
394
|
-
* definitions live in one dataset and instances live in another.
|
|
395
|
-
*
|
|
396
|
-
* Two separate `createTestClient()` calls have separate registries, so
|
|
397
|
-
* tests stay isolated from each other.
|
|
398
|
-
*
|
|
399
|
-
* Methods not on the real client:
|
|
400
|
-
*
|
|
401
|
-
* - `seed`, `add`, `reset`, `snapshot`, `store` — bulk-load helpers,
|
|
402
|
-
* scoped to the current dataset.
|
|
403
|
-
* - `simulateConcurrentEdit()` — force the next N revision-guarded writes
|
|
404
|
-
* to a document to 409, for optimistic-locking retry tests.
|
|
405
|
-
* - `datasets()` — lists known dataset keys in this registry.
|
|
406
|
-
*
|
|
407
|
-
* Methods deliberately omitted:
|
|
408
|
-
*
|
|
409
|
-
* - Project / agent / asset / live / listen APIs.
|
|
410
|
-
*/
|
|
411
|
-
declare interface FetchOptions {
|
|
412
|
-
/** Override the client's configured perspective for this read. */
|
|
413
|
-
perspective?: Perspective;
|
|
414
|
-
/**
|
|
415
|
-
* When `false`, resolve to a {@link RawQueryResponse} (`{ query, ms,
|
|
416
|
-
* result }`) instead of the bare result — mirrors `@sanity/client`.
|
|
417
|
-
* Defaults to `true`.
|
|
418
|
-
*/
|
|
419
|
-
filterResponse?: boolean;
|
|
420
|
-
/**
|
|
421
|
-
* With `filterResponse: false`, set to `false` to omit `query` from the
|
|
422
|
-
* raw response. Ignored when `filterResponse` is not `false`.
|
|
423
|
-
*/
|
|
424
|
-
returnQuery?: boolean;
|
|
425
|
-
/**
|
|
426
|
-
* Request tag, recorded on the {@link CallRecord} for assertions.
|
|
427
|
-
* `null` mirrors `@sanity/client`'s explicit-suppression form and is
|
|
428
|
-
* recorded as-is. No other behavior is simulated.
|
|
429
|
-
*/
|
|
430
|
-
tag?: string | null;
|
|
431
|
-
/** Accepted for signature parity; not simulated. */
|
|
432
|
-
signal?: AbortSignal;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
declare interface Grant_2 {
|
|
436
|
-
filter: string;
|
|
437
|
-
permissions: DocumentValuePermission[];
|
|
438
|
-
}
|
|
439
|
-
|
|
440
309
|
declare type GuardHelpers = {
|
|
441
310
|
/** All deployed guard docs ({@link MutationGuardDoc}) in the store. */
|
|
442
311
|
listGuards: () => Promise<MutationGuardDoc[]>;
|
|
@@ -454,137 +323,28 @@ declare type GuardHelpers = {
|
|
|
454
323
|
* client gates the write against deployed guards (incl. `identity()`) and
|
|
455
324
|
* throws `MutationGuardDeniedError` on denial — the lake's intended
|
|
456
325
|
* rejection, simulated by the bench. `as` routes the write through a
|
|
457
|
-
* token-scoped sibling so `identity()` resolves to that actor.
|
|
458
|
-
*
|
|
459
|
-
*
|
|
326
|
+
* token-scoped sibling so `identity()` resolves to that actor.
|
|
327
|
+
*
|
|
328
|
+
* Each {@link EditDocumentAction} performs that real write, so a guard
|
|
329
|
+
* scoped to it is genuinely consulted: `update` (default) applies `patch`;
|
|
330
|
+
* `delete` deletes; `publish` promotes the existing draft
|
|
331
|
+
* (`drafts.<documentId>`) onto `documentId`; `unpublish` retracts
|
|
332
|
+
* `documentId` into its draft. `documentId` is always the published id.
|
|
333
|
+
* A `patch` ({@link EditDocumentPatch}) is required for `update` and
|
|
334
|
+
* rejected for every other action — the combination is contradictory input.
|
|
335
|
+
*
|
|
336
|
+
* Resolves to the post-write document as the DEFAULT identity reads it —
|
|
337
|
+
* `undefined` after `delete`/`unpublish` (the doc is gone), or when the
|
|
338
|
+
* default identity cannot read the written doc.
|
|
460
339
|
*/
|
|
461
340
|
editDocument: (opts: {
|
|
462
341
|
documentId: string;
|
|
463
342
|
patch?: EditDocumentPatch;
|
|
464
|
-
action?:
|
|
343
|
+
action?: EditDocumentAction;
|
|
465
344
|
as?: Actor;
|
|
466
|
-
}) => Promise<StoreDocument>;
|
|
345
|
+
}) => Promise<StoreDocument | undefined>;
|
|
467
346
|
};
|
|
468
347
|
|
|
469
|
-
/** Result of a mutation when ids are requested for all affected documents. */
|
|
470
|
-
declare interface MultipleMutationResult {
|
|
471
|
-
transactionId: string;
|
|
472
|
-
documentIds: string[];
|
|
473
|
-
results: {
|
|
474
|
-
id: string;
|
|
475
|
-
operation: MutationOperation;
|
|
476
|
-
}[];
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
/** Append-only record of one committed transaction (a single mutation is a 1-entry transaction). */
|
|
480
|
-
declare interface MutationLogEntry {
|
|
481
|
-
transactionId: string;
|
|
482
|
-
projectId: string;
|
|
483
|
-
dataset: string;
|
|
484
|
-
mutations: TxnMutation[];
|
|
485
|
-
/** Request tag the commit carried, when one was passed (`null` = explicit suppression). */
|
|
486
|
-
tag?: string | null;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
/** The operation recorded per affected document, matching `@sanity/client`. */
|
|
490
|
-
declare type MutationOperation = "create" | "update" | "delete" | "none";
|
|
491
|
-
|
|
492
|
-
declare interface MutationOptions {
|
|
493
|
-
ifRevisionId?: string;
|
|
494
|
-
/**
|
|
495
|
-
* Shape the resolved value, mirroring `@sanity/client`:
|
|
496
|
-
* - default → the mutated document
|
|
497
|
-
* - `returnDocuments: false` → an id-shaped mutation result
|
|
498
|
-
* ({@link SingleMutationResult} / {@link MultipleMutationResult})
|
|
499
|
-
* - `returnFirst: false` with documents → an array
|
|
500
|
-
*
|
|
501
|
-
* The static return type reflects the default (the document); pass a
|
|
502
|
-
* type argument or cast when requesting an id-shaped result.
|
|
503
|
-
*/
|
|
504
|
-
returnDocuments?: boolean;
|
|
505
|
-
returnFirst?: boolean;
|
|
506
|
-
/** Override the synthetic transaction id used in the result and log. */
|
|
507
|
-
transactionId?: string;
|
|
508
|
-
/** When `true`, validate + shape the result but don't persist. */
|
|
509
|
-
dryRun?: boolean;
|
|
510
|
-
/** Accepted for signature parity; not simulated. */
|
|
511
|
-
visibility?: "sync" | "async" | "deferred";
|
|
512
|
-
/** Accepted for signature parity; not simulated. */
|
|
513
|
-
autoGenerateArrayKeys?: boolean;
|
|
514
|
-
/**
|
|
515
|
-
* Request tag, recorded on the {@link CallRecord} and the
|
|
516
|
-
* {@link MutationLogEntry} for assertions. `null` mirrors
|
|
517
|
-
* `@sanity/client`'s explicit-suppression form and is recorded as-is.
|
|
518
|
-
* No other behavior is simulated.
|
|
519
|
-
*/
|
|
520
|
-
tag?: string | null;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
/** Options for `PatchHandle.commit()`. Only `tag` is meaningful to the fake. */
|
|
524
|
-
declare interface PatchCommitOptions {
|
|
525
|
-
/** Request tag, recorded on the mutation log entry (`null` = explicit suppression). */
|
|
526
|
-
tag?: string | null;
|
|
527
|
-
/** Accepted for signature parity; not simulated. */
|
|
528
|
-
visibility?: "sync" | "async" | "deferred";
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
declare interface PatchHandle {
|
|
532
|
-
set: (props: Record<string, unknown>) => PatchHandle;
|
|
533
|
-
setIfMissing: (props: Record<string, unknown>) => PatchHandle;
|
|
534
|
-
unset: (paths: string[]) => PatchHandle;
|
|
535
|
-
inc: (props: Record<string, number>) => PatchHandle;
|
|
536
|
-
dec: (props: Record<string, number>) => PatchHandle;
|
|
537
|
-
insert: (
|
|
538
|
-
position: "before" | "after" | "replace",
|
|
539
|
-
anchor: string,
|
|
540
|
-
items: unknown[],
|
|
541
|
-
) => PatchHandle;
|
|
542
|
-
ifRevisionId: (rev: string) => PatchHandle;
|
|
543
|
-
commit: (options?: PatchCommitOptions) => Promise<SanityDocument>;
|
|
544
|
-
/** Test-only introspection — not on real Patch */
|
|
545
|
-
toJSON: () => {
|
|
546
|
-
id: string;
|
|
547
|
-
ops: PatchOp[];
|
|
548
|
-
ifRev?: string;
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* Patch operations the test client supports.
|
|
554
|
-
*
|
|
555
|
-
* Subset of `@sanity/client`'s PatchOperations. Each entry is one
|
|
556
|
-
* mutation step applied in order at commit time.
|
|
557
|
-
*/
|
|
558
|
-
declare type PatchOp =
|
|
559
|
-
| {
|
|
560
|
-
kind: "set";
|
|
561
|
-
props: Record<string, unknown>;
|
|
562
|
-
}
|
|
563
|
-
| {
|
|
564
|
-
kind: "setIfMissing";
|
|
565
|
-
props: Record<string, unknown>;
|
|
566
|
-
}
|
|
567
|
-
| {
|
|
568
|
-
kind: "unset";
|
|
569
|
-
paths: string[];
|
|
570
|
-
}
|
|
571
|
-
| {
|
|
572
|
-
kind: "inc";
|
|
573
|
-
props: Record<string, number>;
|
|
574
|
-
}
|
|
575
|
-
| {
|
|
576
|
-
kind: "dec";
|
|
577
|
-
props: Record<string, number>;
|
|
578
|
-
}
|
|
579
|
-
| {
|
|
580
|
-
kind: "insert";
|
|
581
|
-
position: "before" | "after" | "replace";
|
|
582
|
-
anchor: string;
|
|
583
|
-
items: unknown[];
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
declare type Perspective = "raw" | "published" | "drafts" | string[];
|
|
587
|
-
|
|
588
348
|
declare type QueryHelpers = {
|
|
589
349
|
/**
|
|
590
350
|
* Run an arbitrary GROQ query through `workflow.query`. The query MUST
|
|
@@ -616,34 +376,35 @@ declare type QueryHelpers = {
|
|
|
616
376
|
};
|
|
617
377
|
|
|
618
378
|
declare type ReadHelpers = {
|
|
619
|
-
/**
|
|
620
|
-
|
|
379
|
+
/**
|
|
380
|
+
* The engine's instance point-read: throws typed `InstanceNotFoundError`
|
|
381
|
+
* when the doc is missing or belongs to another engine's tag partition.
|
|
382
|
+
*/
|
|
383
|
+
getInstance: (args: InstanceRefArgs) => Promise<WorkflowInstance>;
|
|
621
384
|
/** Current stage name of an instance. */
|
|
622
385
|
currentStage: (instanceId: string) => Promise<string>;
|
|
623
|
-
/**
|
|
624
|
-
|
|
386
|
+
/** Every pending effect on an instance — claimed and unclaimed alike. */
|
|
387
|
+
listPendingEffects: (args: InstanceRefArgs) => Promise<PendingEffect[]>;
|
|
388
|
+
/** Pending effects filtered by claim presence and/or effect names. */
|
|
389
|
+
findPendingEffects: (
|
|
390
|
+
args: FindPendingEffectsArgs,
|
|
391
|
+
) => Promise<PendingEffect[]>;
|
|
625
392
|
/** Status of a single activity on an instance, or undefined if missing. */
|
|
626
393
|
activityStatus: (
|
|
627
394
|
instanceId: string,
|
|
628
395
|
activity: string,
|
|
629
396
|
) => Promise<ActivityStatus | undefined>;
|
|
630
|
-
/** The rendered `$
|
|
631
|
-
*
|
|
632
|
-
|
|
397
|
+
/** The rendered `$context` map — the start-time seed + a parent's spawn
|
|
398
|
+
* handoff, keyed by entry `name`. */
|
|
399
|
+
contextMap: (instanceId: string) => Promise<Record<string, unknown>>;
|
|
400
|
+
/** The rendered `$effects` map — completed effects' outputs, namespaced
|
|
401
|
+
* by effect name. */
|
|
402
|
+
effectOutputsMap: (instanceId: string) => Promise<Record<string, unknown>>;
|
|
633
403
|
/**
|
|
634
|
-
* Spawned children of
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
* Walks `history.spawned` entries on the parent — the durable record
|
|
638
|
-
* (the workflow-scope registry tracks the same children, keyed for
|
|
639
|
-
* adoption rather than enumeration).
|
|
640
|
-
*
|
|
641
|
-
* Returns children ordered by `startedAt` ascending.
|
|
404
|
+
* Spawned children of the instance, optionally restricted to those
|
|
405
|
+
* spawned by `activity`. Ordered by `startedAt` ascending.
|
|
642
406
|
*/
|
|
643
|
-
children: (
|
|
644
|
-
parentInstanceId: string,
|
|
645
|
-
activity?: string,
|
|
646
|
-
) => Promise<WorkflowInstance[]>;
|
|
407
|
+
children: (args: ChildrenArgs) => Promise<WorkflowInstance[]>;
|
|
647
408
|
/**
|
|
648
409
|
* All workflow instances whose `doc.ref` field entry named
|
|
649
410
|
* `entryName` (default `"subject"`) matches the given doc id. Useful
|
|
@@ -655,83 +416,37 @@ declare type ReadHelpers = {
|
|
|
655
416
|
entryName?: string,
|
|
656
417
|
) => Promise<WorkflowInstance[]>;
|
|
657
418
|
/**
|
|
658
|
-
* All instances of `
|
|
659
|
-
*
|
|
660
|
-
*
|
|
419
|
+
* All instances of `definition` currently at `stage`. In-flight only by
|
|
420
|
+
* default; `includeCompleted: true` widens to completed/aborted instances.
|
|
421
|
+
* The options derive from the engine's {@link InstancesQueryFilter}, so a
|
|
422
|
+
* vocabulary drift is a compile error here, not a silently-dropped filter.
|
|
661
423
|
*/
|
|
662
|
-
instancesByStage: (
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
}) => Promise<WorkflowInstance[]>;
|
|
424
|
+
instancesByStage: (
|
|
425
|
+
options: Required<Pick<InstancesQueryFilter, "definition" | "stage">> &
|
|
426
|
+
Pick<InstancesQueryFilter, "includeCompleted">,
|
|
427
|
+
) => Promise<WorkflowInstance[]>;
|
|
667
428
|
/**
|
|
668
429
|
* Every in-flight instance whose reactive watch-set includes `document`
|
|
669
430
|
* (a resource-qualified GDR URI) — the reverse of the forward watch-set.
|
|
670
431
|
* Answers "which instances should this changed doc `tick`?" the way a
|
|
671
432
|
* non-reactive content forwarder needs. Sorted by `startedAt` ascending.
|
|
672
433
|
*/
|
|
673
|
-
instancesForDocument: (
|
|
434
|
+
instancesForDocument: (
|
|
435
|
+
args: InstancesForDocumentArgs,
|
|
436
|
+
) => Promise<WorkflowInstance[]>;
|
|
674
437
|
/**
|
|
675
438
|
* The startable half of {@link ReadHelpers.instancesForDocument}: the
|
|
676
439
|
* latest deployed version of every definition applicable to the LOADED
|
|
677
440
|
* candidate document — startable, a required subject entry accepts its
|
|
678
|
-
* `_type`, `
|
|
441
|
+
* `_type`, `start.filter` passes. All matches, name ascending.
|
|
679
442
|
*/
|
|
680
443
|
definitionsForDocument: (
|
|
681
|
-
|
|
444
|
+
args: DefinitionsForDocumentArgs,
|
|
682
445
|
) => Promise<DeployedDefinition[]>;
|
|
683
446
|
/** Snapshot of all documents in the store — for inspecting the world. */
|
|
684
447
|
snapshot: () => readonly StoreDocument[];
|
|
685
448
|
};
|
|
686
449
|
|
|
687
|
-
declare type ReleaseAction =
|
|
688
|
-
| {
|
|
689
|
-
actionType: "sanity.action.release.create";
|
|
690
|
-
releaseId: string;
|
|
691
|
-
metadata?: Partial<ReleaseMetadata>;
|
|
692
|
-
}
|
|
693
|
-
| {
|
|
694
|
-
actionType: "sanity.action.release.edit";
|
|
695
|
-
releaseId: string;
|
|
696
|
-
patch: {
|
|
697
|
-
set?: Record<string, unknown>;
|
|
698
|
-
unset?: string[];
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
| {
|
|
702
|
-
actionType: "sanity.action.release.schedule";
|
|
703
|
-
releaseId: string;
|
|
704
|
-
publishAt: string;
|
|
705
|
-
}
|
|
706
|
-
| {
|
|
707
|
-
actionType: "sanity.action.release.unschedule";
|
|
708
|
-
releaseId: string;
|
|
709
|
-
}
|
|
710
|
-
| {
|
|
711
|
-
actionType: "sanity.action.release.publish";
|
|
712
|
-
releaseId: string;
|
|
713
|
-
}
|
|
714
|
-
| {
|
|
715
|
-
actionType: "sanity.action.release.archive";
|
|
716
|
-
releaseId: string;
|
|
717
|
-
}
|
|
718
|
-
| {
|
|
719
|
-
actionType: "sanity.action.release.unarchive";
|
|
720
|
-
releaseId: string;
|
|
721
|
-
}
|
|
722
|
-
| {
|
|
723
|
-
actionType: "sanity.action.release.delete";
|
|
724
|
-
releaseId: string;
|
|
725
|
-
};
|
|
726
|
-
|
|
727
|
-
declare interface ReleaseDocument extends SanityDocument {
|
|
728
|
-
_type: "system.release";
|
|
729
|
-
name: string;
|
|
730
|
-
state: ReleaseState;
|
|
731
|
-
metadata: ReleaseMetadata;
|
|
732
|
-
publishAt?: string;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
450
|
/**
|
|
736
451
|
* A `release.ref` entry pointing at `_.releases.<releaseName>` in the bench's
|
|
737
452
|
* default resource — what a release-targeting workflow's `release` field
|
|
@@ -744,86 +459,6 @@ export declare function releaseField(
|
|
|
744
459
|
},
|
|
745
460
|
): InitialFieldValue;
|
|
746
461
|
|
|
747
|
-
declare interface ReleaseMetadata {
|
|
748
|
-
title?: string;
|
|
749
|
-
description?: string;
|
|
750
|
-
releaseType?: ReleaseType;
|
|
751
|
-
intendedPublishAt?: string;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
declare interface ReleasesHandle {
|
|
755
|
-
create: (params: {
|
|
756
|
-
releaseId: string;
|
|
757
|
-
metadata?: Partial<ReleaseMetadata>;
|
|
758
|
-
}) => Promise<
|
|
759
|
-
ActionResult & {
|
|
760
|
-
releaseId: string;
|
|
761
|
-
metadata: ReleaseMetadata;
|
|
762
|
-
}
|
|
763
|
-
>;
|
|
764
|
-
edit: (params: {
|
|
765
|
-
releaseId: string;
|
|
766
|
-
patch: {
|
|
767
|
-
set?: Record<string, unknown>;
|
|
768
|
-
unset?: string[];
|
|
769
|
-
};
|
|
770
|
-
}) => Promise<ActionResult>;
|
|
771
|
-
get: (params: { releaseId: string }) => Promise<ReleaseDocument | undefined>;
|
|
772
|
-
fetchDocuments: (params: { releaseId: string }) => Promise<SanityDocument[]>;
|
|
773
|
-
schedule: (params: {
|
|
774
|
-
releaseId: string;
|
|
775
|
-
publishAt: string;
|
|
776
|
-
}) => Promise<ActionResult>;
|
|
777
|
-
unschedule: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
778
|
-
publish: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
779
|
-
archive: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
780
|
-
unarchive: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
781
|
-
delete: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
declare type ReleaseState = "active" | "scheduled" | "published" | "archived";
|
|
785
|
-
|
|
786
|
-
declare type ReleaseType = "asap" | "scheduled" | "undecided";
|
|
787
|
-
|
|
788
|
-
/** @public */
|
|
789
|
-
declare interface SanityDocument {
|
|
790
|
-
_id: string;
|
|
791
|
-
_type: string;
|
|
792
|
-
_createdAt: string;
|
|
793
|
-
_updatedAt: string;
|
|
794
|
-
_rev: string;
|
|
795
|
-
[key: string]: unknown;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
/**
|
|
799
|
-
* Similar to `SanityDocument` but only requires the `_id` and `_type`
|
|
800
|
-
*
|
|
801
|
-
* @see SanityDocument
|
|
802
|
-
*
|
|
803
|
-
* @public
|
|
804
|
-
*/
|
|
805
|
-
declare interface SanityDocumentLike {
|
|
806
|
-
_id: string;
|
|
807
|
-
_type: string;
|
|
808
|
-
_createdAt?: string;
|
|
809
|
-
_updatedAt?: string;
|
|
810
|
-
_rev?: string;
|
|
811
|
-
_system?: {
|
|
812
|
-
delete?: boolean;
|
|
813
|
-
};
|
|
814
|
-
[key: string]: unknown;
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
/** Result of a mutation when `returnFirst` resolves true and ids are requested. */
|
|
818
|
-
declare interface SingleMutationResult {
|
|
819
|
-
transactionId: string;
|
|
820
|
-
documentId: string;
|
|
821
|
-
results: {
|
|
822
|
-
id: string;
|
|
823
|
-
operation: MutationOperation;
|
|
824
|
-
}[];
|
|
825
|
-
}
|
|
826
|
-
|
|
827
462
|
/** A document as stored in the bench's fake lake. */
|
|
828
463
|
declare type StoreDocument = {
|
|
829
464
|
_id: string;
|
|
@@ -844,367 +479,6 @@ export declare function subjectField(
|
|
|
844
479
|
},
|
|
845
480
|
): InitialFieldValue;
|
|
846
481
|
|
|
847
|
-
declare interface SystemFields {
|
|
848
|
-
_rev: string;
|
|
849
|
-
_createdAt: string;
|
|
850
|
-
_updatedAt: string;
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
declare interface TestClient {
|
|
854
|
-
fetch: <T = unknown>(
|
|
855
|
-
query: string,
|
|
856
|
-
params?: Record<string, unknown>,
|
|
857
|
-
options?: FetchOptions,
|
|
858
|
-
) => Promise<T>;
|
|
859
|
-
getDocument: <T = SanityDocument>(
|
|
860
|
-
id: string,
|
|
861
|
-
options?: FetchOptions,
|
|
862
|
-
) => Promise<T | undefined>;
|
|
863
|
-
getDocuments: <T = SanityDocument>(
|
|
864
|
-
ids: string[],
|
|
865
|
-
options?: FetchOptions,
|
|
866
|
-
) => Promise<(T | null)[]>;
|
|
867
|
-
/**
|
|
868
|
-
* Sanity-style HTTP request hook. Present iff the handle has an
|
|
869
|
-
* acting identity — created with `accessControl`, or bound to a
|
|
870
|
-
* registered token (`identities` + `token`). The engine's access
|
|
871
|
-
* resolver pokes `/users/me` and the configured ACL path through
|
|
872
|
-
* this — without it the engine throws on any verb that needs an
|
|
873
|
-
* actor.
|
|
874
|
-
*/
|
|
875
|
-
request?: <T>(opts: {
|
|
876
|
-
url?: string;
|
|
877
|
-
uri?: string;
|
|
878
|
-
signal?: AbortSignal;
|
|
879
|
-
tag?: string | null;
|
|
880
|
-
}) => Promise<T>;
|
|
881
|
-
create: <T extends SanityDocumentLike>(
|
|
882
|
-
doc: T,
|
|
883
|
-
options?: MutationOptions,
|
|
884
|
-
) => Promise<T & SystemFields>;
|
|
885
|
-
createOrReplace: <T extends SanityDocumentLike>(
|
|
886
|
-
doc: T,
|
|
887
|
-
options?: MutationOptions,
|
|
888
|
-
) => Promise<T & SystemFields>;
|
|
889
|
-
createIfNotExists: <T extends SanityDocumentLike>(
|
|
890
|
-
doc: T,
|
|
891
|
-
options?: MutationOptions,
|
|
892
|
-
) => Promise<T & SystemFields>;
|
|
893
|
-
delete: (
|
|
894
|
-
id: string,
|
|
895
|
-
options?: MutationOptions,
|
|
896
|
-
) => Promise<{
|
|
897
|
-
_id: string;
|
|
898
|
-
} | null>;
|
|
899
|
-
patch: (documentId: string) => PatchHandle;
|
|
900
|
-
transaction: () => TransactionHandle;
|
|
901
|
-
/**
|
|
902
|
-
* Apply a batch of mutations in the raw array form (or a `patch()` /
|
|
903
|
-
* `transaction()` builder) — mirrors `@sanity/client`'s `mutate()`.
|
|
904
|
-
* Atomic: any failure rolls the whole batch back. The resolved shape
|
|
905
|
-
* follows `options.returnDocuments` / `returnFirst` exactly like the
|
|
906
|
-
* real client (default → {@link MultipleMutationResult}).
|
|
907
|
-
*/
|
|
908
|
-
mutate: (
|
|
909
|
-
operations: FakeMutation[] | PatchHandle | TransactionHandle,
|
|
910
|
-
options?: TxnCommitOptions,
|
|
911
|
-
) => Promise<TxnCommitResult>;
|
|
912
|
-
/**
|
|
913
|
-
* Dispatch one or more release / version actions against the store.
|
|
914
|
-
* Returns a synthetic `transactionId`. Multi-action arrays are applied
|
|
915
|
-
* atomically — any failure rolls back the batch.
|
|
916
|
-
*/
|
|
917
|
-
action: (
|
|
918
|
-
action: Action | Action[],
|
|
919
|
-
options?: ActionOptions,
|
|
920
|
-
) => Promise<ActionResult>;
|
|
921
|
-
/** Helpers mirroring `@sanity/client`'s `client.releases.*` surface. */
|
|
922
|
-
releases: ReleasesHandle;
|
|
923
|
-
/** Helper for `sanity.action.document.version.create`. */
|
|
924
|
-
createVersion: (params: {
|
|
925
|
-
releaseId: string;
|
|
926
|
-
publishedId: string;
|
|
927
|
-
document: DocumentBody;
|
|
928
|
-
}) => Promise<ActionResult>;
|
|
929
|
-
/** Helper for `sanity.action.document.version.unpublish`. */
|
|
930
|
-
unpublishVersion: (params: {
|
|
931
|
-
releaseId: string;
|
|
932
|
-
publishedId: string;
|
|
933
|
-
}) => Promise<ActionResult>;
|
|
934
|
-
/**
|
|
935
|
-
* Current `(projectId, dataset)` and active perspective. `token` is
|
|
936
|
-
* present iff the handle is bound to a registered identity.
|
|
937
|
-
*/
|
|
938
|
-
config: () => {
|
|
939
|
-
projectId: string;
|
|
940
|
-
dataset: string;
|
|
941
|
-
perspective: Perspective;
|
|
942
|
-
token?: string;
|
|
943
|
-
};
|
|
944
|
-
/**
|
|
945
|
-
* Return a new client handle pointing at a different `(projectId, dataset)`
|
|
946
|
-
* within the SAME backing registry. Either field can be omitted to keep
|
|
947
|
-
* the current value. Two clients produced by `withConfig` see each
|
|
948
|
-
* other's writes if they point at the same `(projectId, dataset)`.
|
|
949
|
-
*/
|
|
950
|
-
withConfig: (
|
|
951
|
-
config: Partial<{
|
|
952
|
-
projectId: string;
|
|
953
|
-
dataset: string;
|
|
954
|
-
perspective: Perspective;
|
|
955
|
-
/**
|
|
956
|
-
* Rebind the acting identity (and its grants) on a sibling that shares
|
|
957
|
-
* the same store — the test analogue of a token-scoped client. Lets two
|
|
958
|
-
* actors write the same dataset, e.g. for `identity()`-based guards.
|
|
959
|
-
* Mutually exclusive with `token`.
|
|
960
|
-
*/
|
|
961
|
-
accessControl: TestClientAccessControl;
|
|
962
|
-
/**
|
|
963
|
-
* Bind the sibling to a token registered in the family's identity
|
|
964
|
-
* registry (`createTestClient({ identities })` / `addIdentity`): its
|
|
965
|
-
* `/users/me` serves that identity's user, its ACL path serves that
|
|
966
|
-
* identity's grants, and reads/writes are gated through them — the
|
|
967
|
-
* token determines identity, exactly like production. Unknown tokens
|
|
968
|
-
* throw. Mutually exclusive with `accessControl`.
|
|
969
|
-
*/
|
|
970
|
-
token: string;
|
|
971
|
-
}>,
|
|
972
|
-
) => TestClient;
|
|
973
|
-
/** Replace the current dataset with the given documents. */
|
|
974
|
-
seed: (documents: SanityDocumentLike[]) => void;
|
|
975
|
-
/** Add documents to the current dataset without dropping existing ones. */
|
|
976
|
-
add: (documents: SanityDocumentLike[]) => void;
|
|
977
|
-
/** Drop all documents in the current dataset. */
|
|
978
|
-
reset: () => void;
|
|
979
|
-
/** Read-only snapshot of all documents in the current dataset. */
|
|
980
|
-
snapshot: () => readonly SanityDocument[];
|
|
981
|
-
/** Direct store access for the current dataset. */
|
|
982
|
-
store: () => TestStore;
|
|
983
|
-
/**
|
|
984
|
-
* Simulate `count` concurrent edits to `id` in the current dataset: the
|
|
985
|
-
* next `count` revision-guarded mutations (those passing `ifRevisionId`)
|
|
986
|
-
* to that document throw a 409-shaped conflict, as if another client
|
|
987
|
-
* committed between the caller's read and write. Mutations that don't
|
|
988
|
-
* pass `ifRevisionId` are unaffected.
|
|
989
|
-
*
|
|
990
|
-
* Reach for this when the code under test reads a document's `_rev` and
|
|
991
|
-
* commits with `ifRevisionId` internally — so you can't stage the race
|
|
992
|
-
* by mutating the document first (the code would just re-read the new
|
|
993
|
-
* revision and its commit would match). The counter is consumed one per
|
|
994
|
-
* guarded commit, so `count` lets a test drive a recover-after-N-losses
|
|
995
|
-
* path or exhaust a retry budget, deterministically and without relying
|
|
996
|
-
* on promise interleaving.
|
|
997
|
-
*
|
|
998
|
-
* Note: this forces the conflict *outcome* — it short-circuits the
|
|
999
|
-
* revision comparison rather than changing the stored `_rev`. The code
|
|
1000
|
-
* under test sees the identical 409 error a real lost race produces; the
|
|
1001
|
-
* stored revision is left untouched.
|
|
1002
|
-
*/
|
|
1003
|
-
simulateConcurrentEdit: (id: string, count?: number) => void;
|
|
1004
|
-
/** List `(projectId, dataset)` pairs known in this registry. */
|
|
1005
|
-
datasets: () => {
|
|
1006
|
-
projectId: string;
|
|
1007
|
-
dataset: string;
|
|
1008
|
-
}[];
|
|
1009
|
-
/**
|
|
1010
|
-
* Register a handler for a `@sanity/client` member the fake doesn't
|
|
1011
|
-
* implement (e.g. `listen`, `assets`). Accessing that member on the
|
|
1012
|
-
* client then returns the handler instead of throwing the
|
|
1013
|
-
* "not implemented" guard error. Shared across sibling `withConfig`
|
|
1014
|
-
* handles. Stubs fill gaps only — they don't shadow implemented methods.
|
|
1015
|
-
*/
|
|
1016
|
-
stub: (name: string, handler: unknown) => void;
|
|
1017
|
-
/** The currently-registered stubs, keyed by member name. */
|
|
1018
|
-
stubs: () => Record<string, unknown>;
|
|
1019
|
-
/**
|
|
1020
|
-
* Register (or upsert) a token→identity entry in the family's shared
|
|
1021
|
-
* registry. Siblings already bound to `token` resolve lazily, so a
|
|
1022
|
-
* re-registration takes effect on them immediately. Registering an
|
|
1023
|
-
* identity does not bind it — pass `token` at `createTestClient` or
|
|
1024
|
-
* `withConfig({ token })` to act as it.
|
|
1025
|
-
*/
|
|
1026
|
-
addIdentity: (token: string, identity: TestClientIdentity) => void;
|
|
1027
|
-
/** Snapshot of the registered token→identity entries. */
|
|
1028
|
-
identities: () => Record<string, TestClientIdentity>;
|
|
1029
|
-
/**
|
|
1030
|
-
* Every mutation committed through this client's registry, flattened
|
|
1031
|
-
* and in order — `create` / `createOrReplace` / `createIfNotExists` /
|
|
1032
|
-
* `delete` / `patch`, whether issued directly, via `transaction()`, or
|
|
1033
|
-
* via `mutate()`. The spy hook for "assert exactly what writes my code
|
|
1034
|
-
* submitted".
|
|
1035
|
-
*/
|
|
1036
|
-
mutations: () => TxnMutation[];
|
|
1037
|
-
/**
|
|
1038
|
-
* Every committed transaction, in order. A direct mutation is recorded
|
|
1039
|
-
* as a one-mutation transaction. Each entry carries its synthetic
|
|
1040
|
-
* `transactionId` and the `(projectId, dataset)` it targeted.
|
|
1041
|
-
*/
|
|
1042
|
-
transactions: () => MutationLogEntry[];
|
|
1043
|
-
/** Clear the recorded mutation / transaction log. */
|
|
1044
|
-
clearLog: () => void;
|
|
1045
|
-
/**
|
|
1046
|
-
* Every recorded method call, in order — the spy layer for "was `fetch`
|
|
1047
|
-
* called, how many times, and with what params". Records the
|
|
1048
|
-
* `@sanity/client`-surface methods (`fetch`, `getDocument`, `create`,
|
|
1049
|
-
* `patch`, `mutate`, `releases.*`, …), not the test-only helpers.
|
|
1050
|
-
* Pass a method name to filter (e.g. `calls("fetch")`); namespace
|
|
1051
|
-
* methods are dotted (`calls("releases.create")`). Shared across
|
|
1052
|
-
* `withConfig` siblings.
|
|
1053
|
-
*/
|
|
1054
|
-
calls: (method?: string) => CallRecord[];
|
|
1055
|
-
/** Number of recorded calls, optionally filtered by method name. */
|
|
1056
|
-
callCount: (method?: string) => number;
|
|
1057
|
-
/** Clear the recorded call log. */
|
|
1058
|
-
clearCalls: () => void;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
declare interface TestClientAccessControl {
|
|
1062
|
-
/** What `client.request({ url: "/users/me" })` returns. */
|
|
1063
|
-
currentUser: CurrentUser;
|
|
1064
|
-
/** What `client.request({ url: aclPath })` returns. */
|
|
1065
|
-
grants: Grant_2[];
|
|
1066
|
-
/**
|
|
1067
|
-
* URL path the engine's access resolver hits to fetch grants.
|
|
1068
|
-
* Defaults to `/projects/<projectId>/datasets/<dataset>/acl`.
|
|
1069
|
-
*/
|
|
1070
|
-
aclPath?: string;
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
/**
|
|
1074
|
-
* One entry in the token→identity registry (`createTestClient({ identities })`).
|
|
1075
|
-
* A handle bound to the entry's token behaves exactly like one configured
|
|
1076
|
-
* with `accessControl: { currentUser: user, grants }` — `/users/me` serves
|
|
1077
|
-
* `user`, the default ACL path serves `grants`, and reads/writes are gated
|
|
1078
|
-
* through them.
|
|
1079
|
-
*/
|
|
1080
|
-
declare interface TestClientIdentity {
|
|
1081
|
-
/** What `/users/me` returns for clients bound to this token. */
|
|
1082
|
-
user: CurrentUser;
|
|
1083
|
-
/** Grants served at the ACL path and enforced on reads/writes. */
|
|
1084
|
-
grants: Grant_2[];
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
/**
|
|
1088
|
-
* In-memory document store backing a TestClient. Closure-scoped — created
|
|
1089
|
-
* fresh per test, no global state.
|
|
1090
|
-
*
|
|
1091
|
-
* The shape mirrors what `groq-js` evaluates against: an array of
|
|
1092
|
-
* documents. Internally we keep a Map by `_id` for O(1) lookup, and
|
|
1093
|
-
* project to an array on each query.
|
|
1094
|
-
*/
|
|
1095
|
-
declare interface TestStore {
|
|
1096
|
-
/** Replace the entire dataset with the given documents. Existing docs are dropped. */
|
|
1097
|
-
seed: (documents: SanityDocumentLike[]) => void;
|
|
1098
|
-
/** Add documents without dropping existing ones. Conflicts (same _id) overwrite. */
|
|
1099
|
-
add: (documents: SanityDocumentLike[]) => void;
|
|
1100
|
-
/** Remove all documents. */
|
|
1101
|
-
reset: () => void;
|
|
1102
|
-
/** All documents as an array, in insertion order. */
|
|
1103
|
-
all: () => SanityDocument[];
|
|
1104
|
-
/** Get one document by _id, or undefined. */
|
|
1105
|
-
get: (id: string) => SanityDocument | undefined;
|
|
1106
|
-
/** Insert a fully-formed document by _id. Replaces if it already exists. */
|
|
1107
|
-
put: (doc: SanityDocument) => void;
|
|
1108
|
-
/** Remove a document by _id. Returns the removed doc or undefined. */
|
|
1109
|
-
remove: (id: string) => SanityDocument | undefined;
|
|
1110
|
-
/** Snapshot of all docs, useful for assertions. */
|
|
1111
|
-
snapshot: () => readonly SanityDocument[];
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
declare interface TransactionHandle {
|
|
1115
|
-
create: (doc: SanityDocumentLike) => TransactionHandle;
|
|
1116
|
-
createOrReplace: (doc: SanityDocumentLike) => TransactionHandle;
|
|
1117
|
-
createIfNotExists: (doc: SanityDocumentLike) => TransactionHandle;
|
|
1118
|
-
delete: (id: string) => TransactionHandle;
|
|
1119
|
-
/** Accept either a Patch builder (drained at commit) or an inline doc id + ops. */
|
|
1120
|
-
patch: (
|
|
1121
|
-
documentIdOrPatch: string | PatchHandle,
|
|
1122
|
-
ops?: PatchOp[],
|
|
1123
|
-
ifRev?: string,
|
|
1124
|
-
) => TransactionHandle;
|
|
1125
|
-
commit: (options?: TxnCommitOptions) => Promise<TxnCommitResult>;
|
|
1126
|
-
/** Test-only introspection — not on real Transaction. */
|
|
1127
|
-
toJSON: () => TxnMutation[];
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
declare interface TxnCommitOptions {
|
|
1131
|
-
/**
|
|
1132
|
-
* Shape the resolved value (mirrors `@sanity/client`):
|
|
1133
|
-
* - default (both unset) → {@link MultipleMutationResult}
|
|
1134
|
-
* - `returnDocuments: true` → the resulting document(s)
|
|
1135
|
-
* - `returnFirst: true` with `returnDocuments` → a single document
|
|
1136
|
-
* - `returnDocuments: false` → an id-shaped mutation result
|
|
1137
|
-
*/
|
|
1138
|
-
returnDocuments?: boolean;
|
|
1139
|
-
returnFirst?: boolean;
|
|
1140
|
-
/** Override the synthetic transaction id (mirrors `client.transaction(undefined, { transactionId })`). */
|
|
1141
|
-
transactionId?: string;
|
|
1142
|
-
/**
|
|
1143
|
-
* Request tag, recorded on the mutation log entry for assertions.
|
|
1144
|
-
* `null` mirrors `@sanity/client`'s explicit-suppression form and is
|
|
1145
|
-
* recorded as-is. No other behavior is simulated.
|
|
1146
|
-
*/
|
|
1147
|
-
tag?: string | null;
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
declare type TxnCommitResult =
|
|
1151
|
-
| MultipleMutationResult
|
|
1152
|
-
| SingleMutationResult
|
|
1153
|
-
| SanityDocument
|
|
1154
|
-
| SanityDocument[];
|
|
1155
|
-
|
|
1156
|
-
/**
|
|
1157
|
-
* A transaction collects mutations and applies them atomically at commit
|
|
1158
|
-
* time. Mutations are applied in declaration order; if any one fails, the
|
|
1159
|
-
* whole transaction throws and no writes land in the store.
|
|
1160
|
-
*
|
|
1161
|
-
* Subset of `@sanity/client`'s Transaction. Same shape, narrower surface.
|
|
1162
|
-
*/
|
|
1163
|
-
declare type TxnMutation =
|
|
1164
|
-
| {
|
|
1165
|
-
kind: "create";
|
|
1166
|
-
doc: SanityDocumentLike;
|
|
1167
|
-
}
|
|
1168
|
-
| {
|
|
1169
|
-
kind: "createOrReplace";
|
|
1170
|
-
doc: SanityDocumentLike;
|
|
1171
|
-
}
|
|
1172
|
-
| {
|
|
1173
|
-
kind: "createIfNotExists";
|
|
1174
|
-
doc: SanityDocumentLike;
|
|
1175
|
-
}
|
|
1176
|
-
| {
|
|
1177
|
-
kind: "delete";
|
|
1178
|
-
id: string;
|
|
1179
|
-
}
|
|
1180
|
-
| {
|
|
1181
|
-
kind: "patch";
|
|
1182
|
-
documentId: string;
|
|
1183
|
-
ops: PatchOp[];
|
|
1184
|
-
ifRev?: string;
|
|
1185
|
-
};
|
|
1186
|
-
|
|
1187
|
-
declare type VersionAction =
|
|
1188
|
-
| {
|
|
1189
|
-
actionType: "sanity.action.document.version.create";
|
|
1190
|
-
publishedId: string;
|
|
1191
|
-
document: DocumentBody;
|
|
1192
|
-
releaseId?: string;
|
|
1193
|
-
}
|
|
1194
|
-
| {
|
|
1195
|
-
actionType: "sanity.action.document.version.replace";
|
|
1196
|
-
document: SanityDocumentLike;
|
|
1197
|
-
}
|
|
1198
|
-
| {
|
|
1199
|
-
actionType: "sanity.action.document.version.discard";
|
|
1200
|
-
versionId: string;
|
|
1201
|
-
}
|
|
1202
|
-
| {
|
|
1203
|
-
actionType: "sanity.action.document.version.unpublish";
|
|
1204
|
-
versionId: string;
|
|
1205
|
-
publishedId: string;
|
|
1206
|
-
};
|
|
1207
|
-
|
|
1208
482
|
/**
|
|
1209
483
|
* The default grants used when tests don't specify any. A single
|
|
1210
484
|
* permissive grant matches every document and confers all permissions.
|