@sanity-labs/client-fake-for-test 0.0.0 → 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Sanity.io
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.cjs CHANGED
@@ -70,6 +70,53 @@ function makeRequestImpl(accessControl, projectId, dataset) {
70
70
  );
71
71
  };
72
72
  }
73
+ function createTestStore(initial) {
74
+ const docs = /* @__PURE__ */ new Map(), promote2 = (doc) => {
75
+ if (typeof doc._id != "string" || doc._id.length === 0)
76
+ throw new Error(`document is missing _id: ${JSON.stringify(doc)}`);
77
+ if (typeof doc._type != "string" || doc._type.length === 0)
78
+ throw new Error(`document ${doc._id} is missing _type`);
79
+ const now = (/* @__PURE__ */ new Date()).toISOString();
80
+ return {
81
+ ...doc,
82
+ _id: doc._id,
83
+ _type: doc._type,
84
+ _rev: doc._rev ?? cryptoRandomKey(),
85
+ _createdAt: doc._createdAt ?? now,
86
+ _updatedAt: doc._updatedAt ?? now
87
+ };
88
+ }, seed = (documents) => {
89
+ docs.clear();
90
+ for (const d of documents) {
91
+ const promoted = promote2(d);
92
+ docs.set(promoted._id, promoted);
93
+ }
94
+ };
95
+ return initial && seed(initial), {
96
+ seed,
97
+ add: (documents) => {
98
+ for (const d of documents) {
99
+ const promoted = promote2(d);
100
+ docs.set(promoted._id, promoted);
101
+ }
102
+ },
103
+ reset: () => docs.clear(),
104
+ all: () => [...docs.values()],
105
+ get: (id) => docs.get(id),
106
+ put: (doc) => {
107
+ docs.set(doc._id, doc);
108
+ },
109
+ remove: (id) => {
110
+ const doc = docs.get(id);
111
+ return doc && docs.delete(id), doc;
112
+ },
113
+ snapshot: () => [...docs.values()]
114
+ };
115
+ }
116
+ function cryptoRandomKey(length = 12) {
117
+ const bytes = new Uint8Array(length);
118
+ return globalThis.crypto.getRandomValues(bytes), [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, length);
119
+ }
73
120
  function createPatch(documentId, executor) {
74
121
  const ops = [];
75
122
  let ifRev;
@@ -248,52 +295,301 @@ function insertIntoArray(doc, position, anchor, items) {
248
295
  const idx = resolveSelector(arr, last.selector);
249
296
  position === "replace" ? arr.splice(idx, 1, ...items) : position === "before" ? arr.splice(idx, 0, ...items) : arr.splice(idx + 1, 0, ...items);
250
297
  }
251
- function createTestStore(initial) {
252
- const docs = /* @__PURE__ */ new Map(), promote = (doc) => {
253
- if (typeof doc._id != "string" || doc._id.length === 0)
254
- throw new Error(`document is missing _id: ${JSON.stringify(doc)}`);
255
- if (typeof doc._type != "string" || doc._type.length === 0)
256
- throw new Error(`document ${doc._id} is missing _type`);
257
- const now = (/* @__PURE__ */ new Date()).toISOString();
258
- return {
259
- ...doc,
260
- _id: doc._id,
261
- _type: doc._type,
262
- _rev: doc._rev ?? cryptoRandomKey(),
263
- _createdAt: doc._createdAt ?? now,
264
- _updatedAt: doc._updatedAt ?? now
265
- };
266
- }, seed = (documents) => {
267
- docs.clear();
268
- for (const d of documents) {
269
- const promoted = promote(d);
270
- docs.set(promoted._id, promoted);
271
- }
298
+ const RELEASE_DOC_PREFIX$1 = "_.releases.", VERSIONS_PREFIX$1 = "versions.", releaseDocId = (releaseId) => `${RELEASE_DOC_PREFIX$1}${releaseId}`, versionDocId = (releaseId, publishedId) => `${VERSIONS_PREFIX$1}${releaseId}.${publishedId}`;
299
+ function parseVersionId(versionId) {
300
+ if (!versionId.startsWith(VERSIONS_PREFIX$1))
301
+ throw new Error(`Not a version id: ${versionId}`);
302
+ const rest = versionId.slice(VERSIONS_PREFIX$1.length), dot = rest.indexOf(".");
303
+ if (dot === -1)
304
+ throw new Error(`Not a version id: ${versionId}`);
305
+ return { releaseId: rest.slice(0, dot), publishedId: rest.slice(dot + 1) };
306
+ }
307
+ function getRelease(store, releaseId) {
308
+ const doc = store.get(releaseDocId(releaseId));
309
+ if (doc === void 0)
310
+ throw new Error(`Release not found: ${releaseId}`);
311
+ return doc;
312
+ }
313
+ function maybeRelease(store, releaseId) {
314
+ return store.get(releaseDocId(releaseId));
315
+ }
316
+ function nowIso() {
317
+ return (/* @__PURE__ */ new Date()).toISOString();
318
+ }
319
+ function promote(doc) {
320
+ const now = nowIso();
321
+ return {
322
+ ...doc,
323
+ _id: doc._id,
324
+ _type: doc._type,
325
+ _rev: cryptoRandomKey(),
326
+ _createdAt: doc._createdAt ?? now,
327
+ _updatedAt: now
272
328
  };
273
- return initial && seed(initial), {
274
- seed,
275
- add: (documents) => {
276
- for (const d of documents) {
277
- const promoted = promote(d);
278
- docs.set(promoted._id, promoted);
329
+ }
330
+ function bumpRev(doc, patch) {
331
+ return {
332
+ ...doc,
333
+ ...patch,
334
+ _rev: cryptoRandomKey(),
335
+ _updatedAt: nowIso()
336
+ };
337
+ }
338
+ function requireActive(release) {
339
+ if (release.state !== "active")
340
+ throw new Error(
341
+ `Release ${release.name} is ${release.state}; only active releases accept version writes`
342
+ );
343
+ }
344
+ function applyAction(store, action) {
345
+ switch (action.actionType) {
346
+ case "sanity.action.release.create": {
347
+ if (maybeRelease(store, action.releaseId) !== void 0)
348
+ throw new Error(`Release ${action.releaseId} already exists`);
349
+ const now = nowIso(), metadata = {
350
+ releaseType: "undecided",
351
+ ...action.metadata
352
+ }, doc = {
353
+ _id: releaseDocId(action.releaseId),
354
+ _type: "system.release",
355
+ _rev: cryptoRandomKey(),
356
+ _createdAt: now,
357
+ _updatedAt: now,
358
+ name: action.releaseId,
359
+ state: "active",
360
+ metadata
361
+ };
362
+ return store.put(doc), { transactionId: cryptoRandomKey() };
363
+ }
364
+ case "sanity.action.release.edit": {
365
+ const release = getRelease(store, action.releaseId), patchOps = [];
366
+ action.patch.set !== void 0 && patchOps.push({ kind: "set", props: action.patch.set }), action.patch.unset !== void 0 && patchOps.push({ kind: "unset", paths: action.patch.unset });
367
+ const patched = applyPatchOps(release, patchOps);
368
+ return store.put(bumpRev(patched, {})), { transactionId: cryptoRandomKey() };
369
+ }
370
+ case "sanity.action.release.schedule": {
371
+ const release = getRelease(store, action.releaseId);
372
+ if (release.state !== "active")
373
+ throw new Error(`Cannot schedule release in state ${release.state}`);
374
+ return store.put(
375
+ bumpRev(release, {
376
+ state: "scheduled",
377
+ publishAt: action.publishAt
378
+ })
379
+ ), { transactionId: cryptoRandomKey() };
380
+ }
381
+ case "sanity.action.release.unschedule": {
382
+ const release = getRelease(store, action.releaseId);
383
+ if (release.state !== "scheduled")
384
+ throw new Error(`Cannot unschedule release in state ${release.state}`);
385
+ const next = { ...release, state: "active" };
386
+ return delete next.publishAt, store.put(bumpRev(next, {})), { transactionId: cryptoRandomKey() };
387
+ }
388
+ case "sanity.action.release.publish": {
389
+ const release = getRelease(store, action.releaseId);
390
+ if (release.state === "published")
391
+ return { transactionId: cryptoRandomKey() };
392
+ if (release.state !== "active" && release.state !== "scheduled")
393
+ throw new Error(`Cannot publish release in state ${release.state}`);
394
+ const prefix = `${VERSIONS_PREFIX$1}${action.releaseId}.`, sources = store.all().filter((d) => d._id.startsWith(prefix));
395
+ for (const v of sources) {
396
+ const pubId = v._id.slice(prefix.length);
397
+ if (v._system?.delete === !0)
398
+ store.remove(pubId);
399
+ else {
400
+ const body = {
401
+ ...v,
402
+ _id: pubId
403
+ };
404
+ delete body._originalId, delete body._system;
405
+ const promoted = promote(body), existing = store.get(pubId);
406
+ existing !== void 0 && (promoted._createdAt = existing._createdAt), store.put(promoted);
407
+ }
408
+ store.remove(v._id);
279
409
  }
280
- },
281
- reset: () => docs.clear(),
282
- all: () => [...docs.values()],
283
- get: (id) => docs.get(id),
284
- put: (doc) => {
285
- docs.set(doc._id, doc);
286
- },
287
- remove: (id) => {
288
- const doc = docs.get(id);
289
- return doc && docs.delete(id), doc;
290
- },
291
- snapshot: () => [...docs.values()]
410
+ return store.put(bumpRev(release, { state: "published" })), { transactionId: cryptoRandomKey() };
411
+ }
412
+ case "sanity.action.release.archive": {
413
+ const release = getRelease(store, action.releaseId);
414
+ if (release.state !== "active" && release.state !== "scheduled")
415
+ throw new Error(`Cannot archive release in state ${release.state}`);
416
+ return store.put(bumpRev(release, { state: "archived" })), { transactionId: cryptoRandomKey() };
417
+ }
418
+ case "sanity.action.release.unarchive": {
419
+ const release = getRelease(store, action.releaseId);
420
+ if (release.state !== "archived")
421
+ throw new Error(`Cannot unarchive release in state ${release.state}`);
422
+ return store.put(bumpRev(release, { state: "active" })), { transactionId: cryptoRandomKey() };
423
+ }
424
+ case "sanity.action.release.delete": {
425
+ const release = getRelease(store, action.releaseId);
426
+ if (release.state !== "archived" && release.state !== "published")
427
+ throw new Error(
428
+ `Cannot delete release in state ${release.state}; archive or publish it first`
429
+ );
430
+ const prefix = `${VERSIONS_PREFIX$1}${action.releaseId}.`;
431
+ for (const v of store.all())
432
+ v._id.startsWith(prefix) && store.remove(v._id);
433
+ return store.remove(release._id), { transactionId: cryptoRandomKey() };
434
+ }
435
+ case "sanity.action.document.version.create": {
436
+ const releaseId = action.releaseId ?? (action.document._id !== void 0 ? parseVersionId(action.document._id).releaseId : void 0);
437
+ if (releaseId === void 0)
438
+ throw new Error("version.create needs releaseId or a document._id that encodes it");
439
+ const release = getRelease(store, releaseId);
440
+ requireActive(release);
441
+ const vid = versionDocId(releaseId, action.publishedId), doc = {
442
+ ...action.document,
443
+ _id: vid
444
+ }, existing = store.get(vid), promoted = promote(doc);
445
+ return existing !== void 0 && (promoted._createdAt = existing._createdAt), store.put(promoted), { transactionId: cryptoRandomKey() };
446
+ }
447
+ case "sanity.action.document.version.replace": {
448
+ const id = action.document._id;
449
+ if (typeof id != "string")
450
+ throw new Error("version.replace needs document._id");
451
+ const { releaseId } = parseVersionId(id), release = getRelease(store, releaseId);
452
+ requireActive(release);
453
+ const existing = store.get(id), promoted = promote(action.document);
454
+ return existing !== void 0 && (promoted._createdAt = existing._createdAt), store.put(promoted), { transactionId: cryptoRandomKey() };
455
+ }
456
+ case "sanity.action.document.version.discard": {
457
+ const { releaseId } = parseVersionId(action.versionId), release = getRelease(store, releaseId);
458
+ return requireActive(release), store.remove(action.versionId), { transactionId: cryptoRandomKey() };
459
+ }
460
+ case "sanity.action.document.version.unpublish": {
461
+ const { releaseId } = parseVersionId(action.versionId), release = getRelease(store, releaseId);
462
+ requireActive(release);
463
+ const doc = {
464
+ _id: action.versionId,
465
+ _type: "stub",
466
+ _system: { delete: !0 }
467
+ };
468
+ return store.put(promote(doc)), { transactionId: cryptoRandomKey() };
469
+ }
470
+ }
471
+ }
472
+ function applyActions(store, actions) {
473
+ const list = Array.isArray(actions) ? actions : [actions], snapshot = /* @__PURE__ */ new Map(), remember = (id) => {
474
+ snapshot.has(id) || snapshot.set(id, store.get(id));
292
475
  };
476
+ try {
477
+ let last = { transactionId: cryptoRandomKey() };
478
+ for (const a of list) {
479
+ switch (a.actionType) {
480
+ case "sanity.action.release.create":
481
+ case "sanity.action.release.edit":
482
+ case "sanity.action.release.schedule":
483
+ case "sanity.action.release.unschedule":
484
+ case "sanity.action.release.archive":
485
+ case "sanity.action.release.unarchive":
486
+ case "sanity.action.release.delete":
487
+ remember(`${RELEASE_DOC_PREFIX$1}${a.releaseId}`);
488
+ break;
489
+ case "sanity.action.release.publish": {
490
+ remember(`${RELEASE_DOC_PREFIX$1}${a.releaseId}`);
491
+ const prefix = `${VERSIONS_PREFIX$1}${a.releaseId}.`;
492
+ for (const d of store.all())
493
+ d._id.startsWith(prefix) && (remember(d._id), remember(d._id.slice(prefix.length)));
494
+ break;
495
+ }
496
+ case "sanity.action.document.version.create": {
497
+ const releaseId = a.releaseId ?? (typeof a.document._id == "string" ? parseVersionId(a.document._id).releaseId : void 0);
498
+ releaseId !== void 0 && remember(versionDocId(releaseId, a.publishedId));
499
+ break;
500
+ }
501
+ case "sanity.action.document.version.replace":
502
+ typeof a.document._id == "string" && remember(a.document._id);
503
+ break;
504
+ case "sanity.action.document.version.discard":
505
+ case "sanity.action.document.version.unpublish":
506
+ remember(a.versionId);
507
+ break;
508
+ }
509
+ last = applyAction(store, a);
510
+ }
511
+ return last;
512
+ } catch (err) {
513
+ for (const [id, doc] of snapshot)
514
+ doc === void 0 ? store.remove(id) : store.put(doc);
515
+ throw err;
516
+ }
293
517
  }
294
- function cryptoRandomKey(length = 12) {
295
- const bytes = new Uint8Array(length);
296
- return globalThis.crypto.getRandomValues(bytes), [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, length);
518
+ const DRAFTS_PREFIX = "drafts.", VERSIONS_PREFIX = "versions.", RELEASE_DOC_PREFIX = "_.releases.";
519
+ function publishedIdOf(id) {
520
+ if (id.startsWith(DRAFTS_PREFIX)) return id.slice(DRAFTS_PREFIX.length);
521
+ if (id.startsWith(VERSIONS_PREFIX)) {
522
+ const rest = id.slice(VERSIONS_PREFIX.length), dot = rest.indexOf(".");
523
+ return dot === -1 ? rest : rest.slice(dot + 1);
524
+ }
525
+ return id;
526
+ }
527
+ function releaseNameOf(id) {
528
+ if (!id.startsWith(VERSIONS_PREFIX)) return;
529
+ const rest = id.slice(VERSIONS_PREFIX.length), dot = rest.indexOf(".");
530
+ if (dot !== -1)
531
+ return rest.slice(0, dot);
532
+ }
533
+ const isDraftId = (id) => id.startsWith(DRAFTS_PREFIX), isVersionId = (id) => id.startsWith(VERSIONS_PREFIX), isSystemId = (id) => id.startsWith("_."), isReleaseDocId = (id) => id.startsWith(RELEASE_DOC_PREFIX);
534
+ function applyPerspective(docs, perspective) {
535
+ if (perspective === "raw") return [...docs];
536
+ if (perspective === "published")
537
+ return docs.filter((d) => !isDraftId(d._id) && !isVersionId(d._id) && !isSystemId(d._id));
538
+ if (perspective === "drafts")
539
+ return mergeStack(docs, [], { includeDrafts: !0, includeReleaseDocs: !1 });
540
+ const stack = [];
541
+ let includeDrafts = !1;
542
+ for (const entry of perspective)
543
+ entry === "drafts" ? includeDrafts = !0 : stack.push(entry);
544
+ return mergeStack(docs, stack, { includeDrafts, includeReleaseDocs: !0 });
545
+ }
546
+ function mergeStack(docs, releaseStack, options) {
547
+ const groups = /* @__PURE__ */ new Map(), systemReleases = [];
548
+ for (const doc of docs) {
549
+ if (isReleaseDocId(doc._id)) {
550
+ options.includeReleaseDocs && systemReleases.push(doc);
551
+ continue;
552
+ }
553
+ if (isSystemId(doc._id)) continue;
554
+ const pubId = publishedIdOf(doc._id);
555
+ let group = groups.get(pubId);
556
+ if (group === void 0 && (group = { versions: /* @__PURE__ */ new Map() }, groups.set(pubId, group)), isDraftId(doc._id))
557
+ group.draft = doc;
558
+ else if (isVersionId(doc._id)) {
559
+ const releaseName = releaseNameOf(doc._id);
560
+ releaseName !== void 0 && group.versions.set(releaseName, doc);
561
+ } else
562
+ group.published = doc;
563
+ }
564
+ const out = [];
565
+ for (const [pubId, group] of groups) {
566
+ let chosen;
567
+ for (const releaseName of releaseStack) {
568
+ const v = group.versions.get(releaseName);
569
+ if (v !== void 0) {
570
+ if (isUnpublishStub(v)) {
571
+ chosen = void 0;
572
+ break;
573
+ }
574
+ chosen = v;
575
+ break;
576
+ }
577
+ }
578
+ chosen === void 0 && options.includeDrafts && group.draft !== void 0 && (chosen = group.draft), chosen === void 0 && group.published !== void 0 && (releaseStack.some((name) => {
579
+ const v = group.versions.get(name);
580
+ return v !== void 0 && isUnpublishStub(v);
581
+ }) || (chosen = group.published)), chosen !== void 0 && out.push(projectToPublishedId(chosen, pubId));
582
+ }
583
+ return [...out, ...systemReleases];
584
+ }
585
+ function isUnpublishStub(doc) {
586
+ return doc._system?.delete === !0;
587
+ }
588
+ function projectToPublishedId(doc, pubId) {
589
+ return doc._id === pubId ? doc : { ...doc, _id: pubId, _originalId: doc._id };
590
+ }
591
+ function resolveDocument(docs, id, perspective) {
592
+ return perspective === "raw" ? docs.find((d) => d._id === id) : applyPerspective(docs, perspective).find((d) => d._id === id);
297
593
  }
298
594
  function createTransaction(executor) {
299
595
  const mutations = [], handle = {
@@ -340,14 +636,20 @@ function createTestClient(options = {}) {
340
636
  const { projectId, dataset } = parseRegistryKey(key);
341
637
  ensureStore(projectId, dataset).seed(docs);
342
638
  }
343
- return makeHandle(registry, defaultProjectId, defaultDataset, options.accessControl);
639
+ return makeHandle(
640
+ registry,
641
+ defaultProjectId,
642
+ defaultDataset,
643
+ options.accessControl,
644
+ options.perspective ?? "raw"
645
+ );
344
646
  }
345
- function makeHandle(registry, projectId, dataset, accessControl) {
647
+ function makeHandle(registry, projectId, dataset, accessControl, perspective) {
346
648
  const store = (() => {
347
649
  const key = registryKey(projectId, dataset);
348
650
  let s = registry.get(key);
349
651
  return s === void 0 && (s = createTestStore(), registry.set(key, s)), s;
350
- })(), promote = (doc) => {
652
+ })(), promote2 = (doc) => {
351
653
  const now = (/* @__PURE__ */ new Date()).toISOString();
352
654
  if (typeof doc._id != "string" || doc._id.length === 0)
353
655
  throw new Error("document is missing _id");
@@ -402,7 +704,7 @@ function makeHandle(registry, projectId, dataset, accessControl) {
402
704
  switch (mut.kind) {
403
705
  case "create": {
404
706
  remember(mut.doc._id);
405
- const promoted = promote(mut.doc);
707
+ const promoted = promote2(mut.doc);
406
708
  if (store.get(promoted._id) !== void 0)
407
709
  throw new Error(`create failed: document ${promoted._id} already exists`);
408
710
  await gate(promoted, "create"), store.put(promoted), touchedIds.push(promoted._id), operations.push({ id: promoted._id, operation: "create" });
@@ -410,7 +712,7 @@ function makeHandle(registry, projectId, dataset, accessControl) {
410
712
  }
411
713
  case "createOrReplace": {
412
714
  remember(mut.doc._id);
413
- const promoted = promote(mut.doc), existing = store.get(promoted._id);
715
+ const promoted = promote2(mut.doc), existing = store.get(promoted._id);
414
716
  await gate(existing ?? promoted, existing !== void 0 ? "update" : "create");
415
717
  const wasPresent = existing !== void 0;
416
718
  store.put(promoted), touchedIds.push(promoted._id), operations.push({ id: promoted._id, operation: wasPresent ? "update" : "create" });
@@ -418,7 +720,7 @@ function makeHandle(registry, projectId, dataset, accessControl) {
418
720
  }
419
721
  case "createIfNotExists": {
420
722
  if (remember(mut.doc._id), store.get(mut.doc._id) === void 0) {
421
- const promoted = promote(mut.doc);
723
+ const promoted = promote2(mut.doc);
422
724
  await gate(promoted, "create"), store.put(promoted), touchedIds.push(promoted._id), operations.push({ id: promoted._id, operation: "create" });
423
725
  }
424
726
  break;
@@ -447,50 +749,63 @@ function makeHandle(registry, projectId, dataset, accessControl) {
447
749
  transactionId: cryptoRandomKey(),
448
750
  results: operations
449
751
  };
450
- }, visibleDocs = async () => {
752
+ }, accessVisibleDocs = async () => {
451
753
  const all = store.all();
452
754
  if (accessControl === void 0) return all;
453
755
  const out = [];
454
756
  for (const doc of all)
455
757
  await canRead(doc) && out.push(doc);
456
758
  return out;
759
+ }, visibleDocs = async (override) => {
760
+ const accessible = await accessVisibleDocs();
761
+ return applyPerspective(accessible, override ?? perspective);
457
762
  };
458
763
  return {
459
- fetch: async (query, params) => {
764
+ fetch: async (query, params, opts) => {
460
765
  const tree = groqJs.parse(query, params ? { params } : void 0);
461
766
  return await (await groqJs.evaluate(tree, {
462
- dataset: await visibleDocs(),
767
+ dataset: await visibleDocs(opts?.perspective),
463
768
  ...params !== void 0 ? { params } : {}
464
769
  })).get();
465
770
  },
466
- getDocument: async (id) => {
467
- const doc = store.get(id);
468
- return doc === void 0 || !await canRead(doc) ? null : doc;
469
- },
470
- getDocuments: async (ids) => {
471
- const result = [];
472
- for (const id of ids) {
771
+ getDocument: async (id, opts) => {
772
+ const effective = opts?.perspective ?? perspective;
773
+ if (effective === "raw") {
473
774
  const doc = store.get(id);
474
- doc === void 0 ? result.push(null) : await canRead(doc) ? result.push(doc) : result.push(null);
775
+ return doc === void 0 || !await canRead(doc) ? null : doc;
475
776
  }
476
- return result;
777
+ const view = await visibleDocs(effective);
778
+ return resolveDocument(view, id, effective) ?? null;
779
+ },
780
+ getDocuments: async (ids, opts) => {
781
+ const effective = opts?.perspective ?? perspective;
782
+ if (effective === "raw") {
783
+ const result = [];
784
+ for (const id of ids) {
785
+ const doc = store.get(id);
786
+ doc === void 0 ? result.push(null) : await canRead(doc) ? result.push(doc) : result.push(null);
787
+ }
788
+ return result;
789
+ }
790
+ const view = await visibleDocs(effective);
791
+ return ids.map((id) => resolveDocument(view, id, effective) ?? null);
477
792
  },
478
793
  create: async (doc, opts) => {
479
794
  if (checkRevision(doc._id, opts?.ifRevisionId), store.get(doc._id) !== void 0)
480
795
  throw new Error(`create failed: document ${doc._id} already exists`);
481
- const promoted = promote(doc);
796
+ const promoted = promote2(doc);
482
797
  return await gate(promoted, "create"), store.put(promoted), promoted;
483
798
  },
484
799
  createOrReplace: async (doc, opts) => {
485
800
  checkRevision(doc._id, opts?.ifRevisionId);
486
- const promoted = promote(doc), existing = store.get(doc._id);
801
+ const promoted = promote2(doc), existing = store.get(doc._id);
487
802
  return await gate(existing ?? promoted, existing !== void 0 ? "update" : "create"), store.put(promoted), promoted;
488
803
  },
489
804
  createIfNotExists: async (doc, opts) => {
490
805
  checkRevision(doc._id, opts?.ifRevisionId);
491
806
  const existing = store.get(doc._id);
492
807
  if (existing !== void 0) return existing;
493
- const promoted = promote(doc);
808
+ const promoted = promote2(doc);
494
809
  return await gate(promoted, "create"), store.put(promoted), promoted;
495
810
  },
496
811
  delete: async (id, opts) => {
@@ -500,9 +815,57 @@ function makeHandle(registry, projectId, dataset, accessControl) {
500
815
  },
501
816
  patch: (documentId) => createPatch(documentId, { apply: applyPatch }),
502
817
  transaction: () => createTransaction({ apply: applyTransaction }),
818
+ action: async (action) => applyActions(store, action),
819
+ releases: {
820
+ create: async ({ releaseId, metadata }) => {
821
+ const result = applyActions(store, {
822
+ actionType: "sanity.action.release.create",
823
+ releaseId,
824
+ ...metadata !== void 0 ? { metadata } : {}
825
+ }), doc = store.get(`_.releases.${releaseId}`);
826
+ return {
827
+ ...result,
828
+ releaseId,
829
+ metadata: doc?.metadata ?? { releaseType: "undecided" }
830
+ };
831
+ },
832
+ edit: async ({ releaseId, patch }) => applyActions(store, { actionType: "sanity.action.release.edit", releaseId, patch }),
833
+ get: async ({ releaseId }) => store.get(`_.releases.${releaseId}`),
834
+ fetchDocuments: async ({ releaseId }) => {
835
+ const prefix = `versions.${releaseId}.`;
836
+ return store.all().filter((d) => d._id.startsWith(prefix));
837
+ },
838
+ schedule: async ({ releaseId, publishAt }) => applyActions(store, {
839
+ actionType: "sanity.action.release.schedule",
840
+ releaseId,
841
+ publishAt
842
+ }),
843
+ unschedule: async ({ releaseId }) => applyActions(store, { actionType: "sanity.action.release.unschedule", releaseId }),
844
+ publish: async ({ releaseId }) => applyActions(store, { actionType: "sanity.action.release.publish", releaseId }),
845
+ archive: async ({ releaseId }) => applyActions(store, { actionType: "sanity.action.release.archive", releaseId }),
846
+ unarchive: async ({ releaseId }) => applyActions(store, { actionType: "sanity.action.release.unarchive", releaseId }),
847
+ delete: async ({ releaseId }) => applyActions(store, { actionType: "sanity.action.release.delete", releaseId })
848
+ },
849
+ createVersion: async ({ releaseId, publishedId, document }) => applyActions(store, {
850
+ actionType: "sanity.action.document.version.create",
851
+ releaseId,
852
+ publishedId,
853
+ document
854
+ }),
855
+ unpublishVersion: async ({ releaseId, publishedId }) => applyActions(store, {
856
+ actionType: "sanity.action.document.version.unpublish",
857
+ versionId: `versions.${releaseId}.${publishedId}`,
858
+ publishedId
859
+ }),
503
860
  ...accessControl !== void 0 ? { request: makeRequestImpl(accessControl, projectId, dataset) } : {},
504
- config: () => ({ projectId, dataset }),
505
- withConfig: (config) => makeHandle(registry, config.projectId ?? projectId, config.dataset ?? dataset, accessControl),
861
+ config: () => ({ projectId, dataset, perspective }),
862
+ withConfig: (config) => makeHandle(
863
+ registry,
864
+ config.projectId ?? projectId,
865
+ config.dataset ?? dataset,
866
+ accessControl,
867
+ config.perspective ?? perspective
868
+ ),
506
869
  seed: (documents) => store.seed(documents),
507
870
  add: (documents) => store.add(documents),
508
871
  reset: () => store.reset(),
@@ -513,10 +876,17 @@ function makeHandle(registry, projectId, dataset, accessControl) {
513
876
  }
514
877
  exports.WriteAccessDeniedError = WriteAccessDeniedError;
515
878
  exports.applyPatchOps = applyPatchOps;
879
+ exports.applyPerspective = applyPerspective;
516
880
  exports.createPatch = createPatch;
517
881
  exports.createTestClient = createTestClient;
518
882
  exports.createTestStore = createTestStore;
519
883
  exports.createTransaction = createTransaction;
520
884
  exports.defaultAclPath = defaultAclPath;
521
885
  exports.evaluateWriteAccess = evaluateWriteAccess;
886
+ exports.isDraftId = isDraftId;
887
+ exports.isReleaseDocId = isReleaseDocId;
888
+ exports.isSystemId = isSystemId;
889
+ exports.isVersionId = isVersionId;
890
+ exports.publishedIdOf = publishedIdOf;
891
+ exports.releaseNameOf = releaseNameOf;
522
892
  //# sourceMappingURL=index.cjs.map