@sanity-labs/client-fake-for-test 0.1.0 → 0.3.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/README.md +103 -26
- package/dist/index.cjs +862 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +515 -35
- package/dist/index.d.ts +515 -35
- package/dist/index.js +863 -111
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export declare type Action = ReleaseAction | VersionAction;
|
|
2
|
+
|
|
3
|
+
export declare interface ActionResult {
|
|
4
|
+
transactionId: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
/**
|
|
2
8
|
* Apply an ordered list of patch ops to a document, returning the new doc.
|
|
3
9
|
*
|
|
@@ -16,6 +22,45 @@ export declare function applyPatchOps(
|
|
|
16
22
|
ops: PatchOp[],
|
|
17
23
|
): SanityDocument;
|
|
18
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Apply a perspective to a raw set of documents and return the view
|
|
27
|
+
* groq-js should evaluate against.
|
|
28
|
+
*
|
|
29
|
+
* For non-raw perspectives, each output document for a non-system id
|
|
30
|
+
* gets `_id` projected to its published id and `_originalId` carrying
|
|
31
|
+
* the source id (matching the wire shape of the real Content Lake).
|
|
32
|
+
*/
|
|
33
|
+
export declare function applyPerspective(
|
|
34
|
+
docs: readonly SanityDocument[],
|
|
35
|
+
perspective: Perspective,
|
|
36
|
+
): SanityDocument[];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* One recorded invocation of a client method — the spy layer behind
|
|
40
|
+
* `client.calls()` / `client.callCount()`. `result` holds the resolved
|
|
41
|
+
* value (awaited, for async methods); `error` holds the thrown/rejected
|
|
42
|
+
* value. Builder-returning methods (`patch`, `transaction`) record the
|
|
43
|
+
* builder as `result`; their eventual writes show up in the mutation log.
|
|
44
|
+
*/
|
|
45
|
+
export declare interface CallRecord {
|
|
46
|
+
/** Method name; namespace methods are dotted, e.g. `releases.create`. */
|
|
47
|
+
method: string;
|
|
48
|
+
/** Arguments as passed (stored by reference, like `vi.fn`). */
|
|
49
|
+
args: unknown[];
|
|
50
|
+
/** Resolved/returned value, set once the call settles successfully. */
|
|
51
|
+
result?: unknown;
|
|
52
|
+
/** Thrown or rejected value, set if the call failed. */
|
|
53
|
+
error?: unknown;
|
|
54
|
+
projectId: string;
|
|
55
|
+
dataset: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Outcome of a recorded call, reported once a (possibly async) result is known. */
|
|
59
|
+
export declare type CallSettler = (outcome: {
|
|
60
|
+
result?: unknown;
|
|
61
|
+
error?: unknown;
|
|
62
|
+
}) => void;
|
|
63
|
+
|
|
19
64
|
export declare function createPatch(
|
|
20
65
|
documentId: string,
|
|
21
66
|
executor: PatchExecutor,
|
|
@@ -65,6 +110,13 @@ export declare interface CreateTestClientOptions {
|
|
|
65
110
|
* unconditionally — the legacy behavior.
|
|
66
111
|
*/
|
|
67
112
|
accessControl?: TestClientAccessControl;
|
|
113
|
+
/**
|
|
114
|
+
* Default perspective applied to reads. Per-fetch `options.perspective`
|
|
115
|
+
* overrides this. `withConfig({ perspective })` returns a sibling
|
|
116
|
+
* handle with a different default. Defaults to `"raw"` so existing
|
|
117
|
+
* tests stay green.
|
|
118
|
+
*/
|
|
119
|
+
perspective?: Perspective;
|
|
68
120
|
}
|
|
69
121
|
|
|
70
122
|
/**
|
|
@@ -102,8 +154,33 @@ export declare function defaultAclPath(
|
|
|
102
154
|
dataset: string,
|
|
103
155
|
): string;
|
|
104
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Document body accepted by `version.create` / `createVersion`. The id
|
|
159
|
+
* is derived from `releaseId + publishedId` so callers may omit `_id`
|
|
160
|
+
* here. `version.replace` requires `_id` since it identifies the doc
|
|
161
|
+
* to replace.
|
|
162
|
+
*/
|
|
163
|
+
export declare interface DocumentBody {
|
|
164
|
+
_id?: string;
|
|
165
|
+
_type: string;
|
|
166
|
+
[field: string]: unknown;
|
|
167
|
+
}
|
|
168
|
+
|
|
105
169
|
export declare type DocumentValuePermission = "create" | "read" | "update";
|
|
106
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Error helpers shared across the fake.
|
|
173
|
+
*
|
|
174
|
+
* Every error the fake throws is prefixed with {@link ERR_PREFIX} so it's
|
|
175
|
+
* unmistakably attributable to *this fake* — not to `@sanity/client`,
|
|
176
|
+
* groq-js, or the code under test — and carries enough context to fix
|
|
177
|
+
* the problem without reading the fake's source. Short, bare messages
|
|
178
|
+
* ("not found", "invalid id") are a poor developer experience in a test
|
|
179
|
+
* double: prefer stating what happened, the offending value, and what to
|
|
180
|
+
* do about it.
|
|
181
|
+
*/
|
|
182
|
+
export declare const ERR_PREFIX = "[client-fake-for-test]";
|
|
183
|
+
|
|
107
184
|
/**
|
|
108
185
|
* Resolve whether `grants` allow `permission` on `document` for the
|
|
109
186
|
* given user. Same logic the engine uses in `permissions.grantsPermissionOn`
|
|
@@ -125,13 +202,168 @@ export declare function evaluateWriteAccess(args: {
|
|
|
125
202
|
matchingGrants: number;
|
|
126
203
|
}>;
|
|
127
204
|
|
|
205
|
+
/** Build a prefixed Error. Pass a fully-formed, dev-facing message. */
|
|
206
|
+
export declare function fakeError(message: string): Error;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* A single mutation in the raw array form accepted by `mutate()` — the
|
|
210
|
+
* same shape `@sanity/client` accepts. The inline `patch` form mirrors
|
|
211
|
+
* the real client's keyed patch object.
|
|
212
|
+
*/
|
|
213
|
+
export declare type FakeMutation =
|
|
214
|
+
| {
|
|
215
|
+
create: SanityDocumentLike;
|
|
216
|
+
}
|
|
217
|
+
| {
|
|
218
|
+
createOrReplace: SanityDocumentLike;
|
|
219
|
+
}
|
|
220
|
+
| {
|
|
221
|
+
createIfNotExists: SanityDocumentLike;
|
|
222
|
+
}
|
|
223
|
+
| {
|
|
224
|
+
delete: {
|
|
225
|
+
id: string;
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
| {
|
|
229
|
+
patch: {
|
|
230
|
+
id: string;
|
|
231
|
+
ifRevisionID?: string;
|
|
232
|
+
set?: Record<string, unknown>;
|
|
233
|
+
setIfMissing?: Record<string, unknown>;
|
|
234
|
+
unset?: string[];
|
|
235
|
+
inc?: Record<string, number>;
|
|
236
|
+
dec?: Record<string, number>;
|
|
237
|
+
insert?: {
|
|
238
|
+
before?: string;
|
|
239
|
+
after?: string;
|
|
240
|
+
replace?: string;
|
|
241
|
+
items: unknown[];
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Data-plane subset of `@sanity/client`'s surface, with multi-dataset support.
|
|
248
|
+
*
|
|
249
|
+
* One `createTestClient()` call creates a registry of stores keyed by
|
|
250
|
+
* `(projectId, dataset)`. The returned client points at one of them.
|
|
251
|
+
* `withConfig({ projectId, dataset })` returns a new handle into the same
|
|
252
|
+
* registry but pointing at a different store — useful for workflows where
|
|
253
|
+
* definitions live in one dataset and instances live in another.
|
|
254
|
+
*
|
|
255
|
+
* Two separate `createTestClient()` calls have separate registries, so
|
|
256
|
+
* tests stay isolated from each other.
|
|
257
|
+
*
|
|
258
|
+
* Methods not on the real client:
|
|
259
|
+
*
|
|
260
|
+
* - `seed`, `add`, `reset`, `snapshot`, `store` — bulk-load helpers,
|
|
261
|
+
* scoped to the current dataset.
|
|
262
|
+
* - `datasets()` — lists known dataset keys in this registry.
|
|
263
|
+
*
|
|
264
|
+
* Methods deliberately omitted:
|
|
265
|
+
*
|
|
266
|
+
* - Project / agent / asset / live / listen APIs.
|
|
267
|
+
*/
|
|
268
|
+
export declare interface FetchOptions {
|
|
269
|
+
/** Override the client's configured perspective for this read. */
|
|
270
|
+
perspective?: Perspective;
|
|
271
|
+
/**
|
|
272
|
+
* When `false`, resolve to a {@link RawQueryResponse} (`{ query, ms,
|
|
273
|
+
* result }`) instead of the bare result — mirrors `@sanity/client`.
|
|
274
|
+
* Defaults to `true`.
|
|
275
|
+
*/
|
|
276
|
+
filterResponse?: boolean;
|
|
277
|
+
/**
|
|
278
|
+
* With `filterResponse: false`, set to `false` to omit `query` from the
|
|
279
|
+
* raw response. Ignored when `filterResponse` is not `false`.
|
|
280
|
+
*/
|
|
281
|
+
returnQuery?: boolean;
|
|
282
|
+
/** Accepted for signature parity; not simulated. */
|
|
283
|
+
tag?: string;
|
|
284
|
+
/** Accepted for signature parity; not simulated. */
|
|
285
|
+
signal?: AbortSignal;
|
|
286
|
+
}
|
|
287
|
+
|
|
128
288
|
export declare interface Grant {
|
|
129
289
|
filter: string;
|
|
130
290
|
permissions: DocumentValuePermission[];
|
|
131
291
|
}
|
|
132
292
|
|
|
293
|
+
export declare interface GuardConfig {
|
|
294
|
+
/**
|
|
295
|
+
* Resolve a registered stub for an unimplemented member, or `undefined`.
|
|
296
|
+
* Checked only for members the client doesn't already implement, so
|
|
297
|
+
* stubs fill gaps without shadowing core behaviour.
|
|
298
|
+
*/
|
|
299
|
+
getStub: (name: string) => unknown;
|
|
300
|
+
/**
|
|
301
|
+
* Called synchronously when a recorded method is invoked, with the
|
|
302
|
+
* method name and its arguments. Returns a settler the wrapper invokes
|
|
303
|
+
* once the result (or rejection) is known. Omit to disable recording.
|
|
304
|
+
*/
|
|
305
|
+
onCall?: (method: string, args: unknown[]) => CallSettler;
|
|
306
|
+
/**
|
|
307
|
+
* Top-level member names whose calls are recorded via `onCall`. A
|
|
308
|
+
* recorded member that resolves to a namespace object (e.g. `releases`)
|
|
309
|
+
* has each of its methods recorded as `name.method`.
|
|
310
|
+
*/
|
|
311
|
+
recorded?: Set<string>;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export declare const isDraftId: (id: string) => boolean;
|
|
315
|
+
|
|
316
|
+
export declare const isReleaseDocId: (id: string) => boolean;
|
|
317
|
+
|
|
318
|
+
export declare const isSystemId: (id: string) => boolean;
|
|
319
|
+
|
|
320
|
+
export declare const isVersionId: (id: string) => boolean;
|
|
321
|
+
|
|
322
|
+
/** Result of a mutation when ids are requested for all affected documents. */
|
|
323
|
+
export declare interface MultipleMutationResult {
|
|
324
|
+
transactionId: string;
|
|
325
|
+
documentIds: string[];
|
|
326
|
+
results: {
|
|
327
|
+
id: string;
|
|
328
|
+
operation: MutationOperation;
|
|
329
|
+
}[];
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/** Append-only record of one committed transaction (a single mutation is a 1-entry transaction). */
|
|
333
|
+
export declare interface MutationLogEntry {
|
|
334
|
+
transactionId: string;
|
|
335
|
+
projectId: string;
|
|
336
|
+
dataset: string;
|
|
337
|
+
mutations: TxnMutation[];
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/** The operation recorded per affected document, matching `@sanity/client`. */
|
|
341
|
+
export declare type MutationOperation = "create" | "update" | "delete" | "none";
|
|
342
|
+
|
|
133
343
|
export declare interface MutationOptions {
|
|
134
344
|
ifRevisionId?: string;
|
|
345
|
+
/**
|
|
346
|
+
* Shape the resolved value, mirroring `@sanity/client`:
|
|
347
|
+
* - default → the mutated document
|
|
348
|
+
* - `returnDocuments: false` → an id-shaped mutation result
|
|
349
|
+
* ({@link SingleMutationResult} / {@link MultipleMutationResult})
|
|
350
|
+
* - `returnFirst: false` with documents → an array
|
|
351
|
+
*
|
|
352
|
+
* The static return type reflects the default (the document); pass a
|
|
353
|
+
* type argument or cast when requesting an id-shaped result.
|
|
354
|
+
*/
|
|
355
|
+
returnDocuments?: boolean;
|
|
356
|
+
returnFirst?: boolean;
|
|
357
|
+
/** Override the synthetic transaction id used in the result and log. */
|
|
358
|
+
transactionId?: string;
|
|
359
|
+
/** When `true`, validate + shape the result but don't persist. */
|
|
360
|
+
dryRun?: boolean;
|
|
361
|
+
/** Accepted for signature parity; not simulated. */
|
|
362
|
+
visibility?: "sync" | "async" | "deferred";
|
|
363
|
+
/** Accepted for signature parity; not simulated. */
|
|
364
|
+
autoGenerateArrayKeys?: boolean;
|
|
365
|
+
/** Accepted for signature parity; not simulated. */
|
|
366
|
+
tag?: string;
|
|
135
367
|
}
|
|
136
368
|
|
|
137
369
|
export declare interface PatchExecutor {
|
|
@@ -197,6 +429,118 @@ export declare type PatchOp =
|
|
|
197
429
|
items: unknown[];
|
|
198
430
|
};
|
|
199
431
|
|
|
432
|
+
export declare type Perspective = "raw" | "published" | "drafts" | string[];
|
|
433
|
+
|
|
434
|
+
/** Strip `drafts.` / `versions.<name>.` prefix to recover the published id. */
|
|
435
|
+
export declare function publishedIdOf(id: string): string;
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Shape returned by `fetch` when `filterResponse: false`. Matches
|
|
439
|
+
* `@sanity/client`'s `RawQueryResponse`. `query` is omitted when the
|
|
440
|
+
* caller also passes `returnQuery: false`.
|
|
441
|
+
*/
|
|
442
|
+
export declare interface RawQueryResponse<R> {
|
|
443
|
+
query?: string;
|
|
444
|
+
ms: number;
|
|
445
|
+
result: R;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export declare type ReleaseAction =
|
|
449
|
+
| {
|
|
450
|
+
actionType: "sanity.action.release.create";
|
|
451
|
+
releaseId: string;
|
|
452
|
+
metadata?: Partial<ReleaseMetadata>;
|
|
453
|
+
}
|
|
454
|
+
| {
|
|
455
|
+
actionType: "sanity.action.release.edit";
|
|
456
|
+
releaseId: string;
|
|
457
|
+
patch: {
|
|
458
|
+
set?: Record<string, unknown>;
|
|
459
|
+
unset?: string[];
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
| {
|
|
463
|
+
actionType: "sanity.action.release.schedule";
|
|
464
|
+
releaseId: string;
|
|
465
|
+
publishAt: string;
|
|
466
|
+
}
|
|
467
|
+
| {
|
|
468
|
+
actionType: "sanity.action.release.unschedule";
|
|
469
|
+
releaseId: string;
|
|
470
|
+
}
|
|
471
|
+
| {
|
|
472
|
+
actionType: "sanity.action.release.publish";
|
|
473
|
+
releaseId: string;
|
|
474
|
+
}
|
|
475
|
+
| {
|
|
476
|
+
actionType: "sanity.action.release.archive";
|
|
477
|
+
releaseId: string;
|
|
478
|
+
}
|
|
479
|
+
| {
|
|
480
|
+
actionType: "sanity.action.release.unarchive";
|
|
481
|
+
releaseId: string;
|
|
482
|
+
}
|
|
483
|
+
| {
|
|
484
|
+
actionType: "sanity.action.release.delete";
|
|
485
|
+
releaseId: string;
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
export declare interface ReleaseDocument extends SanityDocument {
|
|
489
|
+
_type: "system.release";
|
|
490
|
+
name: string;
|
|
491
|
+
state: ReleaseState;
|
|
492
|
+
metadata: ReleaseMetadata;
|
|
493
|
+
publishAt?: string;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export declare interface ReleaseMetadata {
|
|
497
|
+
title?: string;
|
|
498
|
+
description?: string;
|
|
499
|
+
releaseType?: ReleaseType;
|
|
500
|
+
intendedPublishAt?: string;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/** Extract the release name from a `versions.<name>.<id>` id, else undefined. */
|
|
504
|
+
export declare function releaseNameOf(id: string): string | undefined;
|
|
505
|
+
|
|
506
|
+
export declare interface ReleasesHandle {
|
|
507
|
+
create: (params: {
|
|
508
|
+
releaseId: string;
|
|
509
|
+
metadata?: Partial<ReleaseMetadata>;
|
|
510
|
+
}) => Promise<
|
|
511
|
+
ActionResult & {
|
|
512
|
+
releaseId: string;
|
|
513
|
+
metadata: ReleaseMetadata;
|
|
514
|
+
}
|
|
515
|
+
>;
|
|
516
|
+
edit: (params: {
|
|
517
|
+
releaseId: string;
|
|
518
|
+
patch: {
|
|
519
|
+
set?: Record<string, unknown>;
|
|
520
|
+
unset?: string[];
|
|
521
|
+
};
|
|
522
|
+
}) => Promise<ActionResult>;
|
|
523
|
+
get: (params: { releaseId: string }) => Promise<ReleaseDocument | undefined>;
|
|
524
|
+
fetchDocuments: (params: { releaseId: string }) => Promise<SanityDocument[]>;
|
|
525
|
+
schedule: (params: {
|
|
526
|
+
releaseId: string;
|
|
527
|
+
publishAt: string;
|
|
528
|
+
}) => Promise<ActionResult>;
|
|
529
|
+
unschedule: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
530
|
+
publish: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
531
|
+
archive: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
532
|
+
unarchive: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
533
|
+
delete: (params: { releaseId: string }) => Promise<ActionResult>;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export declare type ReleaseState =
|
|
537
|
+
| "active"
|
|
538
|
+
| "scheduled"
|
|
539
|
+
| "published"
|
|
540
|
+
| "archived";
|
|
541
|
+
|
|
542
|
+
export declare type ReleaseType = "asap" | "scheduled" | "undecided";
|
|
543
|
+
|
|
200
544
|
/** @public */
|
|
201
545
|
declare interface SanityDocument {
|
|
202
546
|
_id: string;
|
|
@@ -226,42 +570,57 @@ declare interface SanityDocumentLike {
|
|
|
226
570
|
[key: string]: unknown;
|
|
227
571
|
}
|
|
228
572
|
|
|
573
|
+
/** Result of a mutation when `returnFirst` resolves true and ids are requested. */
|
|
574
|
+
export declare interface SingleMutationResult {
|
|
575
|
+
transactionId: string;
|
|
576
|
+
documentId: string;
|
|
577
|
+
results: {
|
|
578
|
+
id: string;
|
|
579
|
+
operation: MutationOperation;
|
|
580
|
+
}[];
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/** Members this fake actually implements — surfaced in error messages. */
|
|
584
|
+
export declare const SUPPORTED_SURFACE: readonly [
|
|
585
|
+
"fetch",
|
|
586
|
+
"getDocument",
|
|
587
|
+
"getDocuments",
|
|
588
|
+
"create",
|
|
589
|
+
"createOrReplace",
|
|
590
|
+
"createIfNotExists",
|
|
591
|
+
"delete",
|
|
592
|
+
"patch",
|
|
593
|
+
"transaction",
|
|
594
|
+
"mutate",
|
|
595
|
+
"action",
|
|
596
|
+
"releases",
|
|
597
|
+
"createVersion",
|
|
598
|
+
"unpublishVersion",
|
|
599
|
+
"request (only with accessControl)",
|
|
600
|
+
"config",
|
|
601
|
+
"withConfig",
|
|
602
|
+
];
|
|
603
|
+
|
|
229
604
|
export declare interface SystemFields {
|
|
230
605
|
_rev: string;
|
|
231
606
|
_createdAt: string;
|
|
232
607
|
_updatedAt: string;
|
|
233
608
|
}
|
|
234
609
|
|
|
235
|
-
/**
|
|
236
|
-
* Data-plane subset of `@sanity/client`'s surface, with multi-dataset support.
|
|
237
|
-
*
|
|
238
|
-
* One `createTestClient()` call creates a registry of stores keyed by
|
|
239
|
-
* `(projectId, dataset)`. The returned client points at one of them.
|
|
240
|
-
* `withConfig({ projectId, dataset })` returns a new handle into the same
|
|
241
|
-
* registry but pointing at a different store — useful for workflows where
|
|
242
|
-
* definitions live in one dataset and instances live in another.
|
|
243
|
-
*
|
|
244
|
-
* Two separate `createTestClient()` calls have separate registries, so
|
|
245
|
-
* tests stay isolated from each other.
|
|
246
|
-
*
|
|
247
|
-
* Methods not on the real client:
|
|
248
|
-
*
|
|
249
|
-
* - `seed`, `add`, `reset`, `snapshot`, `store` — bulk-load helpers,
|
|
250
|
-
* scoped to the current dataset.
|
|
251
|
-
* - `datasets()` — lists known dataset keys in this registry.
|
|
252
|
-
*
|
|
253
|
-
* Methods deliberately omitted:
|
|
254
|
-
*
|
|
255
|
-
* - Project / agent / asset / live / listen APIs.
|
|
256
|
-
* - Perspective handling.
|
|
257
|
-
*/
|
|
258
610
|
export declare interface TestClient {
|
|
259
611
|
fetch: <T = unknown>(
|
|
260
612
|
query: string,
|
|
261
613
|
params?: Record<string, unknown>,
|
|
614
|
+
options?: FetchOptions,
|
|
262
615
|
) => Promise<T>;
|
|
263
|
-
getDocument: <T = SanityDocument>(
|
|
264
|
-
|
|
616
|
+
getDocument: <T = SanityDocument>(
|
|
617
|
+
id: string,
|
|
618
|
+
options?: FetchOptions,
|
|
619
|
+
) => Promise<T | undefined>;
|
|
620
|
+
getDocuments: <T = SanityDocument>(
|
|
621
|
+
ids: string[],
|
|
622
|
+
options?: FetchOptions,
|
|
623
|
+
) => Promise<(T | null)[]>;
|
|
265
624
|
/**
|
|
266
625
|
* Sanity-style HTTP request hook. Present iff the client was
|
|
267
626
|
* created with `accessControl`. The engine's access resolver pokes
|
|
@@ -300,10 +659,41 @@ export declare interface TestClient {
|
|
|
300
659
|
} | null>;
|
|
301
660
|
patch: (documentId: string) => PatchHandle;
|
|
302
661
|
transaction: () => TransactionHandle;
|
|
303
|
-
/**
|
|
662
|
+
/**
|
|
663
|
+
* Apply a batch of mutations in the raw array form (or a `patch()` /
|
|
664
|
+
* `transaction()` builder) — mirrors `@sanity/client`'s `mutate()`.
|
|
665
|
+
* Atomic: any failure rolls the whole batch back. The resolved shape
|
|
666
|
+
* follows `options.returnDocuments` / `returnFirst` exactly like the
|
|
667
|
+
* real client (default → {@link MultipleMutationResult}).
|
|
668
|
+
*/
|
|
669
|
+
mutate: (
|
|
670
|
+
operations: FakeMutation[] | PatchHandle | TransactionHandle,
|
|
671
|
+
options?: TxnCommitOptions,
|
|
672
|
+
) => Promise<TxnCommitResult>;
|
|
673
|
+
/**
|
|
674
|
+
* Dispatch one or more release / version actions against the store.
|
|
675
|
+
* Returns a synthetic `transactionId`. Multi-action arrays are applied
|
|
676
|
+
* atomically — any failure rolls back the batch.
|
|
677
|
+
*/
|
|
678
|
+
action: (action: Action | Action[]) => Promise<ActionResult>;
|
|
679
|
+
/** Helpers mirroring `@sanity/client`'s `client.releases.*` surface. */
|
|
680
|
+
releases: ReleasesHandle;
|
|
681
|
+
/** Helper for `sanity.action.document.version.create`. */
|
|
682
|
+
createVersion: (params: {
|
|
683
|
+
releaseId: string;
|
|
684
|
+
publishedId: string;
|
|
685
|
+
document: DocumentBody;
|
|
686
|
+
}) => Promise<ActionResult>;
|
|
687
|
+
/** Helper for `sanity.action.document.version.unpublish`. */
|
|
688
|
+
unpublishVersion: (params: {
|
|
689
|
+
releaseId: string;
|
|
690
|
+
publishedId: string;
|
|
691
|
+
}) => Promise<ActionResult>;
|
|
692
|
+
/** Current `(projectId, dataset)` and active perspective. */
|
|
304
693
|
config: () => {
|
|
305
694
|
projectId: string;
|
|
306
695
|
dataset: string;
|
|
696
|
+
perspective: Perspective;
|
|
307
697
|
};
|
|
308
698
|
/**
|
|
309
699
|
* Return a new client handle pointing at a different `(projectId, dataset)`
|
|
@@ -315,6 +705,7 @@ export declare interface TestClient {
|
|
|
315
705
|
config: Partial<{
|
|
316
706
|
projectId: string;
|
|
317
707
|
dataset: string;
|
|
708
|
+
perspective: Perspective;
|
|
318
709
|
}>,
|
|
319
710
|
) => TestClient;
|
|
320
711
|
/** Replace the current dataset with the given documents. */
|
|
@@ -332,6 +723,46 @@ export declare interface TestClient {
|
|
|
332
723
|
projectId: string;
|
|
333
724
|
dataset: string;
|
|
334
725
|
}[];
|
|
726
|
+
/**
|
|
727
|
+
* Register a handler for a `@sanity/client` member the fake doesn't
|
|
728
|
+
* implement (e.g. `listen`, `assets`). Accessing that member on the
|
|
729
|
+
* client then returns the handler instead of throwing the
|
|
730
|
+
* "not implemented" guard error. Shared across sibling `withConfig`
|
|
731
|
+
* handles. Stubs fill gaps only — they don't shadow implemented methods.
|
|
732
|
+
*/
|
|
733
|
+
stub: (name: string, handler: unknown) => void;
|
|
734
|
+
/** The currently-registered stubs, keyed by member name. */
|
|
735
|
+
stubs: () => Record<string, unknown>;
|
|
736
|
+
/**
|
|
737
|
+
* Every mutation committed through this client's registry, flattened
|
|
738
|
+
* and in order — `create` / `createOrReplace` / `createIfNotExists` /
|
|
739
|
+
* `delete` / `patch`, whether issued directly, via `transaction()`, or
|
|
740
|
+
* via `mutate()`. The spy hook for "assert exactly what writes my code
|
|
741
|
+
* submitted".
|
|
742
|
+
*/
|
|
743
|
+
mutations: () => TxnMutation[];
|
|
744
|
+
/**
|
|
745
|
+
* Every committed transaction, in order. A direct mutation is recorded
|
|
746
|
+
* as a one-mutation transaction. Each entry carries its synthetic
|
|
747
|
+
* `transactionId` and the `(projectId, dataset)` it targeted.
|
|
748
|
+
*/
|
|
749
|
+
transactions: () => MutationLogEntry[];
|
|
750
|
+
/** Clear the recorded mutation / transaction log. */
|
|
751
|
+
clearLog: () => void;
|
|
752
|
+
/**
|
|
753
|
+
* Every recorded method call, in order — the spy layer for "was `fetch`
|
|
754
|
+
* called, how many times, and with what params". Records the
|
|
755
|
+
* `@sanity/client`-surface methods (`fetch`, `getDocument`, `create`,
|
|
756
|
+
* `patch`, `mutate`, `releases.*`, …), not the test-only helpers.
|
|
757
|
+
* Pass a method name to filter (e.g. `calls("fetch")`); namespace
|
|
758
|
+
* methods are dotted (`calls("releases.create")`). Shared across
|
|
759
|
+
* `withConfig` siblings.
|
|
760
|
+
*/
|
|
761
|
+
calls: (method?: string) => CallRecord[];
|
|
762
|
+
/** Number of recorded calls, optionally filtered by method name. */
|
|
763
|
+
callCount: (method?: string) => number;
|
|
764
|
+
/** Clear the recorded call log. */
|
|
765
|
+
clearCalls: () => void;
|
|
335
766
|
}
|
|
336
767
|
|
|
337
768
|
export declare interface TestClientAccessControl {
|
|
@@ -390,20 +821,22 @@ export declare interface TransactionHandle {
|
|
|
390
821
|
}
|
|
391
822
|
|
|
392
823
|
export declare interface TxnCommitOptions {
|
|
393
|
-
/**
|
|
824
|
+
/**
|
|
825
|
+
* Shape the resolved value (mirrors `@sanity/client`):
|
|
826
|
+
* - default (both unset) → {@link MultipleMutationResult}
|
|
827
|
+
* - `returnDocuments: true` → the resulting document(s)
|
|
828
|
+
* - `returnFirst: true` with `returnDocuments` → a single document
|
|
829
|
+
* - `returnDocuments: false` → an id-shaped mutation result
|
|
830
|
+
*/
|
|
394
831
|
returnDocuments?: boolean;
|
|
395
|
-
/** With `returnDocuments`, return only the first updated doc. */
|
|
396
832
|
returnFirst?: boolean;
|
|
833
|
+
/** Override the synthetic transaction id (mirrors `client.transaction(undefined, { transactionId })`). */
|
|
834
|
+
transactionId?: string;
|
|
397
835
|
}
|
|
398
836
|
|
|
399
837
|
export declare type TxnCommitResult =
|
|
400
|
-
|
|
|
401
|
-
|
|
402
|
-
results: {
|
|
403
|
-
id: string;
|
|
404
|
-
operation: "create" | "update" | "delete";
|
|
405
|
-
}[];
|
|
406
|
-
}
|
|
838
|
+
| MultipleMutationResult
|
|
839
|
+
| SingleMutationResult
|
|
407
840
|
| SanityDocument
|
|
408
841
|
| SanityDocument[];
|
|
409
842
|
|
|
@@ -445,6 +878,53 @@ export declare type TxnMutation =
|
|
|
445
878
|
ifRev?: string;
|
|
446
879
|
};
|
|
447
880
|
|
|
881
|
+
/**
|
|
882
|
+
* Curated map of real `@sanity/client` members the fake deliberately omits.
|
|
883
|
+
* Keyed by the top-level property name; nested access (e.g.
|
|
884
|
+
* `assets.upload`) is reported with the full dotted path.
|
|
885
|
+
*/
|
|
886
|
+
export declare const UNSUPPORTED_MEMBERS: Record<string, UnsupportedEntry>;
|
|
887
|
+
|
|
888
|
+
declare interface UnsupportedEntry {
|
|
889
|
+
/** What the real member is. */
|
|
890
|
+
what: string;
|
|
891
|
+
/** What to do instead. */
|
|
892
|
+
workaround: string;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
export declare type VersionAction =
|
|
896
|
+
| {
|
|
897
|
+
actionType: "sanity.action.document.version.create";
|
|
898
|
+
publishedId: string;
|
|
899
|
+
document: DocumentBody;
|
|
900
|
+
releaseId?: string;
|
|
901
|
+
}
|
|
902
|
+
| {
|
|
903
|
+
actionType: "sanity.action.document.version.replace";
|
|
904
|
+
document: SanityDocumentLike;
|
|
905
|
+
}
|
|
906
|
+
| {
|
|
907
|
+
actionType: "sanity.action.document.version.discard";
|
|
908
|
+
versionId: string;
|
|
909
|
+
}
|
|
910
|
+
| {
|
|
911
|
+
actionType: "sanity.action.document.version.unpublish";
|
|
912
|
+
versionId: string;
|
|
913
|
+
publishedId: string;
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* Wrap a client object so unimplemented members fail informatively,
|
|
918
|
+
* registered stubs are served, and recorded methods report their calls.
|
|
919
|
+
*
|
|
920
|
+
* @param client - the fully-built client object (plain literal).
|
|
921
|
+
* @param config - stub resolver plus optional call-recording hooks.
|
|
922
|
+
*/
|
|
923
|
+
export declare function wrapWithGuards<T extends object>(
|
|
924
|
+
client: T,
|
|
925
|
+
config: GuardConfig,
|
|
926
|
+
): T;
|
|
927
|
+
|
|
448
928
|
/**
|
|
449
929
|
* Sanity-style 403 raised when a configured-grants check rejects a
|
|
450
930
|
* write. The thrown object carries the doc id, the attempted
|