@sanity-labs/client-fake-for-test 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -5
- package/dist/index.cjs +280 -163
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +122 -24
- package/dist/index.d.ts +122 -24
- package/dist/index.js +280 -163
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare type Action = ReleaseAction | VersionAction;
|
|
1
|
+
export declare type Action = ReleaseAction | VersionAction | DocumentAction;
|
|
2
2
|
|
|
3
3
|
/** Options for `action()`. Only `tag` is meaningful to the fake. */
|
|
4
4
|
export declare interface ActionOptions {
|
|
@@ -107,8 +107,9 @@ export declare interface CreateTestClientOptions {
|
|
|
107
107
|
datasets?: Record<string, SanityDocumentLike[]>;
|
|
108
108
|
/**
|
|
109
109
|
* Opt-in access-control simulation. When set, the client exposes
|
|
110
|
-
* `request({ url })` that serves `/users/me`
|
|
111
|
-
* path,
|
|
110
|
+
* `request({ url })` that serves `/users/me` (host-aware), the
|
|
111
|
+
* configured ACL path, and `/projects/<projectId>/users/<ids>`,
|
|
112
|
+
* AND every mutation is gated through the supplied `grants`
|
|
112
113
|
* — writes that the grants don't permit throw a `WriteAccessDeniedError`
|
|
113
114
|
* shaped like Sanity's 403. Lets tests demonstrate the full
|
|
114
115
|
* "engine soft-gate + lake hard-gate" contract end-to-end without
|
|
@@ -165,6 +166,14 @@ export declare interface CreateTestClientOptions {
|
|
|
165
166
|
* tests stay green.
|
|
166
167
|
*/
|
|
167
168
|
perspective?: Perspective;
|
|
169
|
+
/**
|
|
170
|
+
* Which API host the root handle models: the project host (default
|
|
171
|
+
* `true`) or the global host (`false`) — same flag as the real
|
|
172
|
+
* `createClient` config. A global-hosted handle's `/users/me` serves
|
|
173
|
+
* the identity's account-global record. `withConfig({ useProjectHostname })`
|
|
174
|
+
* mints siblings on the other host.
|
|
175
|
+
*/
|
|
176
|
+
useProjectHostname?: boolean;
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
/**
|
|
@@ -202,6 +211,26 @@ export declare function defaultAclPath(
|
|
|
202
211
|
dataset: string,
|
|
203
212
|
): string;
|
|
204
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Draft↔published document actions — `sanity.action.document.publish`
|
|
216
|
+
* promotes the draft onto the published id (and deletes the draft);
|
|
217
|
+
* `sanity.action.document.unpublish` retracts the published document into a
|
|
218
|
+
* draft (keeping an existing draft untouched) and deletes the published one.
|
|
219
|
+
*/
|
|
220
|
+
export declare type DocumentAction =
|
|
221
|
+
| {
|
|
222
|
+
actionType: "sanity.action.document.publish";
|
|
223
|
+
draftId: string;
|
|
224
|
+
publishedId: string;
|
|
225
|
+
ifDraftRevisionId?: string;
|
|
226
|
+
ifPublishedRevisionId?: string;
|
|
227
|
+
}
|
|
228
|
+
| {
|
|
229
|
+
actionType: "sanity.action.document.unpublish";
|
|
230
|
+
draftId: string;
|
|
231
|
+
publishedId: string;
|
|
232
|
+
};
|
|
233
|
+
|
|
205
234
|
/**
|
|
206
235
|
* Document body accepted by `version.create` / `createVersion`. The id
|
|
207
236
|
* is derived from `releaseId + publishedId` so callers may omit `_id`
|
|
@@ -387,11 +416,13 @@ export declare interface MultipleMutationResult {
|
|
|
387
416
|
* A pluggable write interceptor, configured via
|
|
388
417
|
* `createTestClient({ mutationGuard })`. It runs on each write through the
|
|
389
418
|
* document mutation API — `create` / `createOrReplace` / `createIfNotExists` /
|
|
390
|
-
* `patch` / `delete` and the equivalent `transaction()` operations —
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
419
|
+
* `patch` / `delete` and the equivalent `transaction()` operations — and on the
|
|
420
|
+
* document publish/unpublish actions (`sanity.action.document.publish` /
|
|
421
|
+
* `.unpublish` via `client.action`) — before the store changes; **throw to
|
|
422
|
+
* reject the write** (the throw propagates out of the client call, exactly as
|
|
423
|
+
* a real lake rejection would). The release/version action API
|
|
424
|
+
* (`client.releases.*`, `createVersion`, the `sanity.action.release.*` and
|
|
425
|
+
* `*.version.*` action types) is **not** intercepted.
|
|
395
426
|
*
|
|
396
427
|
* The client itself has no opinion about *what* a guard is — it only provides
|
|
397
428
|
* the seam and the before/after/identity context. Callers (e.g. a workflow test
|
|
@@ -404,13 +435,21 @@ export declare type MutationGuard = (
|
|
|
404
435
|
) => void | Promise<void>;
|
|
405
436
|
|
|
406
437
|
/** The kind of write a {@link MutationGuard} is asked to vet. */
|
|
407
|
-
export declare type MutationGuardAction =
|
|
438
|
+
export declare type MutationGuardAction =
|
|
439
|
+
| "create"
|
|
440
|
+
| "update"
|
|
441
|
+
| "delete"
|
|
442
|
+
| "publish"
|
|
443
|
+
| "unpublish";
|
|
408
444
|
|
|
409
445
|
/**
|
|
410
446
|
* The before/after image of a single document write, handed to a
|
|
411
447
|
* {@link MutationGuard} before it is applied.
|
|
412
448
|
*
|
|
413
|
-
* - `before` is null on create
|
|
449
|
+
* - `before` is null on create and on a publish with no live published
|
|
450
|
+
* document; `after` is null on delete and unpublish.
|
|
451
|
+
* - On publish/unpublish both images are of the *published* document —
|
|
452
|
+
* `after` on publish is the draft's content promoted onto the published id.
|
|
414
453
|
* - `identity` is the acting user — the id bound to the client's token
|
|
415
454
|
* (its `accessControl.currentUser`), or undefined when the client has no
|
|
416
455
|
* identity configured.
|
|
@@ -553,6 +592,19 @@ export declare type PatchOp =
|
|
|
553
592
|
|
|
554
593
|
export declare type Perspective = "raw" | "published" | "drafts" | string[];
|
|
555
594
|
|
|
595
|
+
/**
|
|
596
|
+
* A row served by the project-users directory endpoint
|
|
597
|
+
* (`/projects/<projectId>/users/<id>`), mirroring Sanity's project user
|
|
598
|
+
* retrieval API: the project-scoped `id` alongside its account-global
|
|
599
|
+
* `sanityUserId` — the one sanctioned bridge between the two namespaces.
|
|
600
|
+
*/
|
|
601
|
+
export declare interface ProjectUserRecord {
|
|
602
|
+
id: string;
|
|
603
|
+
sanityUserId: string;
|
|
604
|
+
displayName: string;
|
|
605
|
+
email?: string;
|
|
606
|
+
}
|
|
607
|
+
|
|
556
608
|
/** Strip `drafts.` / `versions.<name>.` prefix to recover the published id. */
|
|
557
609
|
export declare function publishedIdOf(id: string): string;
|
|
558
610
|
|
|
@@ -789,9 +841,11 @@ export declare interface TestClient {
|
|
|
789
841
|
options?: TxnCommitOptions,
|
|
790
842
|
) => Promise<TxnCommitResult>;
|
|
791
843
|
/**
|
|
792
|
-
* Dispatch one or more release / version actions against the
|
|
793
|
-
* Returns a synthetic `transactionId`. Multi-action arrays are
|
|
794
|
-
* atomically — any failure rolls back the batch.
|
|
844
|
+
* Dispatch one or more release / version / document actions against the
|
|
845
|
+
* store. Returns a synthetic `transactionId`. Multi-action arrays are
|
|
846
|
+
* applied atomically — any failure rolls back the batch. The document
|
|
847
|
+
* publish/unpublish actions run through the access gate and the
|
|
848
|
+
* `mutationGuard` seam; release/version actions apply unhooked.
|
|
795
849
|
*/
|
|
796
850
|
action: (
|
|
797
851
|
action: Action | Action[],
|
|
@@ -811,14 +865,16 @@ export declare interface TestClient {
|
|
|
811
865
|
publishedId: string;
|
|
812
866
|
}) => Promise<ActionResult>;
|
|
813
867
|
/**
|
|
814
|
-
* Current `(projectId, dataset)
|
|
815
|
-
*
|
|
868
|
+
* Current `(projectId, dataset)`, active perspective, and which API host
|
|
869
|
+
* the handle models (`useProjectHostname`). `token` is present iff the
|
|
870
|
+
* handle is bound to a registered identity.
|
|
816
871
|
*/
|
|
817
872
|
config: () => {
|
|
818
873
|
projectId: string;
|
|
819
874
|
dataset: string;
|
|
820
875
|
perspective: Perspective;
|
|
821
876
|
token?: string;
|
|
877
|
+
useProjectHostname: boolean;
|
|
822
878
|
};
|
|
823
879
|
/**
|
|
824
880
|
* Return a new client handle pointing at a different `(projectId, dataset)`
|
|
@@ -831,6 +887,14 @@ export declare interface TestClient {
|
|
|
831
887
|
projectId: string;
|
|
832
888
|
dataset: string;
|
|
833
889
|
perspective: Perspective;
|
|
890
|
+
/**
|
|
891
|
+
* Model the global API host (`false`) instead of the project host
|
|
892
|
+
* (default `true`). A global-hosted sibling's `/users/me` serves the
|
|
893
|
+
* identity's account-global record (`globalUser`, falling back to the
|
|
894
|
+
* project record) — mirroring `@sanity/client`, where a non-project
|
|
895
|
+
* config routes requests to `api.sanity.io`.
|
|
896
|
+
*/
|
|
897
|
+
useProjectHostname: boolean;
|
|
834
898
|
/**
|
|
835
899
|
* Rebind the acting identity (and its grants) on a sibling that shares
|
|
836
900
|
* the same store — the test analogue of a token-scoped client. Lets two
|
|
@@ -841,10 +905,11 @@ export declare interface TestClient {
|
|
|
841
905
|
/**
|
|
842
906
|
* Bind the sibling to a token registered in the family's identity
|
|
843
907
|
* registry (`createTestClient({ identities })` / `addIdentity`): its
|
|
844
|
-
* `/users/me` serves that identity's
|
|
845
|
-
*
|
|
846
|
-
*
|
|
847
|
-
*
|
|
908
|
+
* `/users/me` serves that identity's record for the sibling's project
|
|
909
|
+
* and host, its ACL path serves that identity's grants, and
|
|
910
|
+
* reads/writes are gated through them — the token determines
|
|
911
|
+
* identity, exactly like production. Unknown tokens throw. Mutually
|
|
912
|
+
* exclusive with `accessControl`.
|
|
848
913
|
*/
|
|
849
914
|
token: string;
|
|
850
915
|
}>,
|
|
@@ -938,8 +1003,18 @@ export declare interface TestClient {
|
|
|
938
1003
|
}
|
|
939
1004
|
|
|
940
1005
|
export declare interface TestClientAccessControl {
|
|
941
|
-
/** What `client.request({ url: "/users/me" })` returns. */
|
|
1006
|
+
/** What `client.request({ url: "/users/me" })` returns on a project-hosted handle. */
|
|
942
1007
|
currentUser: CurrentUser;
|
|
1008
|
+
/**
|
|
1009
|
+
* What `/users/me` returns on a global-hosted handle
|
|
1010
|
+
* (`useProjectHostname: false`, at creation or via `withConfig`).
|
|
1011
|
+
* Sanity serves the
|
|
1012
|
+
* account-global user there (`g*` id, no roles) while the project host
|
|
1013
|
+
* serves the project-scoped record (`p*` id, project roles). Omit to
|
|
1014
|
+
* serve `currentUser` from both — the single-id collapse that is also
|
|
1015
|
+
* exactly how robot tokens behave in production.
|
|
1016
|
+
*/
|
|
1017
|
+
globalUser?: CurrentUser;
|
|
943
1018
|
/** What `client.request({ url: aclPath })` returns. */
|
|
944
1019
|
grants: Grant[];
|
|
945
1020
|
/**
|
|
@@ -952,13 +1027,36 @@ export declare interface TestClientAccessControl {
|
|
|
952
1027
|
/**
|
|
953
1028
|
* One entry in the token→identity registry (`createTestClient({ identities })`).
|
|
954
1029
|
* A handle bound to the entry's token behaves exactly like one configured
|
|
955
|
-
* with `accessControl: { currentUser:
|
|
956
|
-
*
|
|
957
|
-
*
|
|
1030
|
+
* with `accessControl: { currentUser: projectUserOf(identity, projectId),
|
|
1031
|
+
* globalUser, grants }` — `/users/me` serves the record for the handle's
|
|
1032
|
+
* project and host, the default ACL path serves `grants`, and reads/writes
|
|
1033
|
+
* are gated through them.
|
|
958
1034
|
*/
|
|
959
1035
|
export declare interface TestClientIdentity {
|
|
960
|
-
/**
|
|
1036
|
+
/**
|
|
1037
|
+
* The project-scoped user record: what `/users/me` returns on a
|
|
1038
|
+
* project-hosted handle, and the id `identity()` resolves to in grant
|
|
1039
|
+
* filters and mutation guards. Per-project variants go in
|
|
1040
|
+
* `usersByProject`; this is the record for any project without one.
|
|
1041
|
+
*/
|
|
961
1042
|
user: CurrentUser;
|
|
1043
|
+
/**
|
|
1044
|
+
* The account-global user record, served by `/users/me` on a
|
|
1045
|
+
* global-hosted handle (`useProjectHostname: false`, at creation or
|
|
1046
|
+
* via `withConfig`).
|
|
1047
|
+
* The same person carries a different id per project (`p*`) and one
|
|
1048
|
+
* global id (`g*`); registering both lets tests model that split.
|
|
1049
|
+
* Omit for single-id principals (robot tokens resolve to one `p-*` id
|
|
1050
|
+
* on every host).
|
|
1051
|
+
*/
|
|
1052
|
+
globalUser?: CurrentUser;
|
|
1053
|
+
/**
|
|
1054
|
+
* Per-project user records, keyed by projectId — the same token
|
|
1055
|
+
* resolves to a different project-scoped id in each project, which is
|
|
1056
|
+
* what these model. A handle's project falls back to `user` when its
|
|
1057
|
+
* projectId has no entry.
|
|
1058
|
+
*/
|
|
1059
|
+
usersByProject?: Record<string, CurrentUser>;
|
|
962
1060
|
/** Grants served at the ACL path and enforced on reads/writes. */
|
|
963
1061
|
grants: Grant[];
|
|
964
1062
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare type Action = ReleaseAction | VersionAction;
|
|
1
|
+
export declare type Action = ReleaseAction | VersionAction | DocumentAction;
|
|
2
2
|
|
|
3
3
|
/** Options for `action()`. Only `tag` is meaningful to the fake. */
|
|
4
4
|
export declare interface ActionOptions {
|
|
@@ -107,8 +107,9 @@ export declare interface CreateTestClientOptions {
|
|
|
107
107
|
datasets?: Record<string, SanityDocumentLike[]>;
|
|
108
108
|
/**
|
|
109
109
|
* Opt-in access-control simulation. When set, the client exposes
|
|
110
|
-
* `request({ url })` that serves `/users/me`
|
|
111
|
-
* path,
|
|
110
|
+
* `request({ url })` that serves `/users/me` (host-aware), the
|
|
111
|
+
* configured ACL path, and `/projects/<projectId>/users/<ids>`,
|
|
112
|
+
* AND every mutation is gated through the supplied `grants`
|
|
112
113
|
* — writes that the grants don't permit throw a `WriteAccessDeniedError`
|
|
113
114
|
* shaped like Sanity's 403. Lets tests demonstrate the full
|
|
114
115
|
* "engine soft-gate + lake hard-gate" contract end-to-end without
|
|
@@ -165,6 +166,14 @@ export declare interface CreateTestClientOptions {
|
|
|
165
166
|
* tests stay green.
|
|
166
167
|
*/
|
|
167
168
|
perspective?: Perspective;
|
|
169
|
+
/**
|
|
170
|
+
* Which API host the root handle models: the project host (default
|
|
171
|
+
* `true`) or the global host (`false`) — same flag as the real
|
|
172
|
+
* `createClient` config. A global-hosted handle's `/users/me` serves
|
|
173
|
+
* the identity's account-global record. `withConfig({ useProjectHostname })`
|
|
174
|
+
* mints siblings on the other host.
|
|
175
|
+
*/
|
|
176
|
+
useProjectHostname?: boolean;
|
|
168
177
|
}
|
|
169
178
|
|
|
170
179
|
/**
|
|
@@ -202,6 +211,26 @@ export declare function defaultAclPath(
|
|
|
202
211
|
dataset: string,
|
|
203
212
|
): string;
|
|
204
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Draft↔published document actions — `sanity.action.document.publish`
|
|
216
|
+
* promotes the draft onto the published id (and deletes the draft);
|
|
217
|
+
* `sanity.action.document.unpublish` retracts the published document into a
|
|
218
|
+
* draft (keeping an existing draft untouched) and deletes the published one.
|
|
219
|
+
*/
|
|
220
|
+
export declare type DocumentAction =
|
|
221
|
+
| {
|
|
222
|
+
actionType: "sanity.action.document.publish";
|
|
223
|
+
draftId: string;
|
|
224
|
+
publishedId: string;
|
|
225
|
+
ifDraftRevisionId?: string;
|
|
226
|
+
ifPublishedRevisionId?: string;
|
|
227
|
+
}
|
|
228
|
+
| {
|
|
229
|
+
actionType: "sanity.action.document.unpublish";
|
|
230
|
+
draftId: string;
|
|
231
|
+
publishedId: string;
|
|
232
|
+
};
|
|
233
|
+
|
|
205
234
|
/**
|
|
206
235
|
* Document body accepted by `version.create` / `createVersion`. The id
|
|
207
236
|
* is derived from `releaseId + publishedId` so callers may omit `_id`
|
|
@@ -387,11 +416,13 @@ export declare interface MultipleMutationResult {
|
|
|
387
416
|
* A pluggable write interceptor, configured via
|
|
388
417
|
* `createTestClient({ mutationGuard })`. It runs on each write through the
|
|
389
418
|
* document mutation API — `create` / `createOrReplace` / `createIfNotExists` /
|
|
390
|
-
* `patch` / `delete` and the equivalent `transaction()` operations —
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
419
|
+
* `patch` / `delete` and the equivalent `transaction()` operations — and on the
|
|
420
|
+
* document publish/unpublish actions (`sanity.action.document.publish` /
|
|
421
|
+
* `.unpublish` via `client.action`) — before the store changes; **throw to
|
|
422
|
+
* reject the write** (the throw propagates out of the client call, exactly as
|
|
423
|
+
* a real lake rejection would). The release/version action API
|
|
424
|
+
* (`client.releases.*`, `createVersion`, the `sanity.action.release.*` and
|
|
425
|
+
* `*.version.*` action types) is **not** intercepted.
|
|
395
426
|
*
|
|
396
427
|
* The client itself has no opinion about *what* a guard is — it only provides
|
|
397
428
|
* the seam and the before/after/identity context. Callers (e.g. a workflow test
|
|
@@ -404,13 +435,21 @@ export declare type MutationGuard = (
|
|
|
404
435
|
) => void | Promise<void>;
|
|
405
436
|
|
|
406
437
|
/** The kind of write a {@link MutationGuard} is asked to vet. */
|
|
407
|
-
export declare type MutationGuardAction =
|
|
438
|
+
export declare type MutationGuardAction =
|
|
439
|
+
| "create"
|
|
440
|
+
| "update"
|
|
441
|
+
| "delete"
|
|
442
|
+
| "publish"
|
|
443
|
+
| "unpublish";
|
|
408
444
|
|
|
409
445
|
/**
|
|
410
446
|
* The before/after image of a single document write, handed to a
|
|
411
447
|
* {@link MutationGuard} before it is applied.
|
|
412
448
|
*
|
|
413
|
-
* - `before` is null on create
|
|
449
|
+
* - `before` is null on create and on a publish with no live published
|
|
450
|
+
* document; `after` is null on delete and unpublish.
|
|
451
|
+
* - On publish/unpublish both images are of the *published* document —
|
|
452
|
+
* `after` on publish is the draft's content promoted onto the published id.
|
|
414
453
|
* - `identity` is the acting user — the id bound to the client's token
|
|
415
454
|
* (its `accessControl.currentUser`), or undefined when the client has no
|
|
416
455
|
* identity configured.
|
|
@@ -553,6 +592,19 @@ export declare type PatchOp =
|
|
|
553
592
|
|
|
554
593
|
export declare type Perspective = "raw" | "published" | "drafts" | string[];
|
|
555
594
|
|
|
595
|
+
/**
|
|
596
|
+
* A row served by the project-users directory endpoint
|
|
597
|
+
* (`/projects/<projectId>/users/<id>`), mirroring Sanity's project user
|
|
598
|
+
* retrieval API: the project-scoped `id` alongside its account-global
|
|
599
|
+
* `sanityUserId` — the one sanctioned bridge between the two namespaces.
|
|
600
|
+
*/
|
|
601
|
+
export declare interface ProjectUserRecord {
|
|
602
|
+
id: string;
|
|
603
|
+
sanityUserId: string;
|
|
604
|
+
displayName: string;
|
|
605
|
+
email?: string;
|
|
606
|
+
}
|
|
607
|
+
|
|
556
608
|
/** Strip `drafts.` / `versions.<name>.` prefix to recover the published id. */
|
|
557
609
|
export declare function publishedIdOf(id: string): string;
|
|
558
610
|
|
|
@@ -789,9 +841,11 @@ export declare interface TestClient {
|
|
|
789
841
|
options?: TxnCommitOptions,
|
|
790
842
|
) => Promise<TxnCommitResult>;
|
|
791
843
|
/**
|
|
792
|
-
* Dispatch one or more release / version actions against the
|
|
793
|
-
* Returns a synthetic `transactionId`. Multi-action arrays are
|
|
794
|
-
* atomically — any failure rolls back the batch.
|
|
844
|
+
* Dispatch one or more release / version / document actions against the
|
|
845
|
+
* store. Returns a synthetic `transactionId`. Multi-action arrays are
|
|
846
|
+
* applied atomically — any failure rolls back the batch. The document
|
|
847
|
+
* publish/unpublish actions run through the access gate and the
|
|
848
|
+
* `mutationGuard` seam; release/version actions apply unhooked.
|
|
795
849
|
*/
|
|
796
850
|
action: (
|
|
797
851
|
action: Action | Action[],
|
|
@@ -811,14 +865,16 @@ export declare interface TestClient {
|
|
|
811
865
|
publishedId: string;
|
|
812
866
|
}) => Promise<ActionResult>;
|
|
813
867
|
/**
|
|
814
|
-
* Current `(projectId, dataset)
|
|
815
|
-
*
|
|
868
|
+
* Current `(projectId, dataset)`, active perspective, and which API host
|
|
869
|
+
* the handle models (`useProjectHostname`). `token` is present iff the
|
|
870
|
+
* handle is bound to a registered identity.
|
|
816
871
|
*/
|
|
817
872
|
config: () => {
|
|
818
873
|
projectId: string;
|
|
819
874
|
dataset: string;
|
|
820
875
|
perspective: Perspective;
|
|
821
876
|
token?: string;
|
|
877
|
+
useProjectHostname: boolean;
|
|
822
878
|
};
|
|
823
879
|
/**
|
|
824
880
|
* Return a new client handle pointing at a different `(projectId, dataset)`
|
|
@@ -831,6 +887,14 @@ export declare interface TestClient {
|
|
|
831
887
|
projectId: string;
|
|
832
888
|
dataset: string;
|
|
833
889
|
perspective: Perspective;
|
|
890
|
+
/**
|
|
891
|
+
* Model the global API host (`false`) instead of the project host
|
|
892
|
+
* (default `true`). A global-hosted sibling's `/users/me` serves the
|
|
893
|
+
* identity's account-global record (`globalUser`, falling back to the
|
|
894
|
+
* project record) — mirroring `@sanity/client`, where a non-project
|
|
895
|
+
* config routes requests to `api.sanity.io`.
|
|
896
|
+
*/
|
|
897
|
+
useProjectHostname: boolean;
|
|
834
898
|
/**
|
|
835
899
|
* Rebind the acting identity (and its grants) on a sibling that shares
|
|
836
900
|
* the same store — the test analogue of a token-scoped client. Lets two
|
|
@@ -841,10 +905,11 @@ export declare interface TestClient {
|
|
|
841
905
|
/**
|
|
842
906
|
* Bind the sibling to a token registered in the family's identity
|
|
843
907
|
* registry (`createTestClient({ identities })` / `addIdentity`): its
|
|
844
|
-
* `/users/me` serves that identity's
|
|
845
|
-
*
|
|
846
|
-
*
|
|
847
|
-
*
|
|
908
|
+
* `/users/me` serves that identity's record for the sibling's project
|
|
909
|
+
* and host, its ACL path serves that identity's grants, and
|
|
910
|
+
* reads/writes are gated through them — the token determines
|
|
911
|
+
* identity, exactly like production. Unknown tokens throw. Mutually
|
|
912
|
+
* exclusive with `accessControl`.
|
|
848
913
|
*/
|
|
849
914
|
token: string;
|
|
850
915
|
}>,
|
|
@@ -938,8 +1003,18 @@ export declare interface TestClient {
|
|
|
938
1003
|
}
|
|
939
1004
|
|
|
940
1005
|
export declare interface TestClientAccessControl {
|
|
941
|
-
/** What `client.request({ url: "/users/me" })` returns. */
|
|
1006
|
+
/** What `client.request({ url: "/users/me" })` returns on a project-hosted handle. */
|
|
942
1007
|
currentUser: CurrentUser;
|
|
1008
|
+
/**
|
|
1009
|
+
* What `/users/me` returns on a global-hosted handle
|
|
1010
|
+
* (`useProjectHostname: false`, at creation or via `withConfig`).
|
|
1011
|
+
* Sanity serves the
|
|
1012
|
+
* account-global user there (`g*` id, no roles) while the project host
|
|
1013
|
+
* serves the project-scoped record (`p*` id, project roles). Omit to
|
|
1014
|
+
* serve `currentUser` from both — the single-id collapse that is also
|
|
1015
|
+
* exactly how robot tokens behave in production.
|
|
1016
|
+
*/
|
|
1017
|
+
globalUser?: CurrentUser;
|
|
943
1018
|
/** What `client.request({ url: aclPath })` returns. */
|
|
944
1019
|
grants: Grant[];
|
|
945
1020
|
/**
|
|
@@ -952,13 +1027,36 @@ export declare interface TestClientAccessControl {
|
|
|
952
1027
|
/**
|
|
953
1028
|
* One entry in the token→identity registry (`createTestClient({ identities })`).
|
|
954
1029
|
* A handle bound to the entry's token behaves exactly like one configured
|
|
955
|
-
* with `accessControl: { currentUser:
|
|
956
|
-
*
|
|
957
|
-
*
|
|
1030
|
+
* with `accessControl: { currentUser: projectUserOf(identity, projectId),
|
|
1031
|
+
* globalUser, grants }` — `/users/me` serves the record for the handle's
|
|
1032
|
+
* project and host, the default ACL path serves `grants`, and reads/writes
|
|
1033
|
+
* are gated through them.
|
|
958
1034
|
*/
|
|
959
1035
|
export declare interface TestClientIdentity {
|
|
960
|
-
/**
|
|
1036
|
+
/**
|
|
1037
|
+
* The project-scoped user record: what `/users/me` returns on a
|
|
1038
|
+
* project-hosted handle, and the id `identity()` resolves to in grant
|
|
1039
|
+
* filters and mutation guards. Per-project variants go in
|
|
1040
|
+
* `usersByProject`; this is the record for any project without one.
|
|
1041
|
+
*/
|
|
961
1042
|
user: CurrentUser;
|
|
1043
|
+
/**
|
|
1044
|
+
* The account-global user record, served by `/users/me` on a
|
|
1045
|
+
* global-hosted handle (`useProjectHostname: false`, at creation or
|
|
1046
|
+
* via `withConfig`).
|
|
1047
|
+
* The same person carries a different id per project (`p*`) and one
|
|
1048
|
+
* global id (`g*`); registering both lets tests model that split.
|
|
1049
|
+
* Omit for single-id principals (robot tokens resolve to one `p-*` id
|
|
1050
|
+
* on every host).
|
|
1051
|
+
*/
|
|
1052
|
+
globalUser?: CurrentUser;
|
|
1053
|
+
/**
|
|
1054
|
+
* Per-project user records, keyed by projectId — the same token
|
|
1055
|
+
* resolves to a different project-scoped id in each project, which is
|
|
1056
|
+
* what these model. A handle's project falls back to `user` when its
|
|
1057
|
+
* projectId has no entry.
|
|
1058
|
+
*/
|
|
1059
|
+
usersByProject?: Record<string, CurrentUser>;
|
|
962
1060
|
/** Grants served at the ACL path and enforced on reads/writes. */
|
|
963
1061
|
grants: Grant[];
|
|
964
1062
|
}
|