@sanity-labs/client-fake-for-test 0.1.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/dist/index.cjs +435 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +226 -26
- package/dist/index.d.ts +226 -26
- package/dist/index.js +436 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
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
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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(
|
|
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
|
-
})(),
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
},
|
|
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
|
|
468
|
-
|
|
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
|
|
775
|
+
return doc === void 0 || !await canRead(doc) ? null : doc;
|
|
475
776
|
}
|
|
476
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|