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