@sanity/sdk 2.11.0 → 2.12.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.
Files changed (57) hide show
  1. package/dist/_chunks-dts/utils.d.ts +171 -19
  2. package/dist/_chunks-es/_internal.js +41 -26
  3. package/dist/_chunks-es/_internal.js.map +1 -1
  4. package/dist/_chunks-es/createGroqSearchFilter.js +25 -9
  5. package/dist/_chunks-es/createGroqSearchFilter.js.map +1 -1
  6. package/dist/_chunks-es/telemetryManager.js +25 -19
  7. package/dist/_chunks-es/telemetryManager.js.map +1 -1
  8. package/dist/_chunks-es/version.js +1 -1
  9. package/dist/_exports/_internal.d.ts +27 -11
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.js +723 -418
  12. package/dist/index.js.map +1 -1
  13. package/package.json +16 -16
  14. package/src/_exports/index.ts +23 -2
  15. package/src/auth/refreshStampedToken.test.ts +2 -2
  16. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +116 -0
  17. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +27 -9
  18. package/src/config/sanityConfig.ts +12 -0
  19. package/src/document/actions.test.ts +112 -1
  20. package/src/document/actions.ts +148 -1
  21. package/src/document/applyDocumentActions.ts +4 -3
  22. package/src/document/documentStore.ts +7 -6
  23. package/src/document/events.test.ts +57 -2
  24. package/src/document/events.ts +43 -24
  25. package/src/document/permissions.ts +1 -1
  26. package/src/document/processActions/create.ts +135 -0
  27. package/src/document/processActions/delete.ts +100 -0
  28. package/src/document/processActions/discard.ts +63 -0
  29. package/src/document/processActions/edit.ts +141 -0
  30. package/src/document/processActions/processActions.ts +209 -0
  31. package/src/document/processActions/publish.ts +120 -0
  32. package/src/document/processActions/releaseArchive.ts +77 -0
  33. package/src/document/processActions/releaseCreate.ts +59 -0
  34. package/src/document/processActions/releaseDelete.ts +65 -0
  35. package/src/document/processActions/releaseEdit.ts +36 -0
  36. package/src/document/processActions/releasePublish.ts +45 -0
  37. package/src/document/processActions/releaseSchedule.ts +87 -0
  38. package/src/document/processActions/releaseUtil.ts +31 -0
  39. package/src/document/processActions/shared.ts +139 -0
  40. package/src/document/processActions/unpublish.ts +85 -0
  41. package/src/document/processActions.test.ts +424 -2
  42. package/src/document/reducers.ts +41 -6
  43. package/src/releases/getPerspectiveState.test.ts +1 -1
  44. package/src/releases/releasesStore.test.ts +50 -1
  45. package/src/releases/releasesStore.ts +41 -18
  46. package/src/releases/utils/sortReleases.test.ts +2 -2
  47. package/src/releases/utils/sortReleases.ts +1 -1
  48. package/src/telemetry/environment.test.ts +119 -0
  49. package/src/telemetry/environment.ts +92 -0
  50. package/src/telemetry/{__telemetry__/sdk.telemetry.ts → events.ts} +9 -9
  51. package/src/telemetry/initTelemetry.test.ts +240 -16
  52. package/src/telemetry/initTelemetry.ts +39 -16
  53. package/src/telemetry/telemetryManager.test.ts +129 -65
  54. package/src/telemetry/telemetryManager.ts +41 -29
  55. package/src/document/processActions.ts +0 -735
  56. package/src/telemetry/devMode.test.ts +0 -60
  57. package/src/telemetry/devMode.ts +0 -41
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { switchMap, from, firstValueFrom, EMPTY, asapScheduler, distinctUntilChanged, map as map$1, combineLatest, of, concatMap, withLatestFrom, filter as filter$1, concat, timer, throwError, first as first$1, Subject, takeUntil, share, partition, merge, shareReplay, tap as tap$1, catchError as catchError$1, startWith as startWith$1, pairwise as pairwise$1, groupBy as groupBy$1, mergeMap as mergeMap$1, throttle, race, skip, Observable, NEVER, fromEvent, Subscription, debounceTime, defer } from "rxjs";
2
2
  import { createLogger, pickProperties, insecureRandomId, getClientState, bindActionGlobally, createStateSourceAction, setCleanupTimeout, omitProperty, defineStore, authStore, AuthStateType, getCleanedUrl, getTokenFromLocation, createLoggedInAuthState, getAuthCode, REQUEST_TAG_PREFIX, DEFAULT_API_VERSION, getDefaultLocation, isDeepEqual, configureLogging as configureLogging$1, isReleasePerspective, bindActionByResource, isDatasetResource, isMediaLibraryResource, isCanvasResource, getUsersKey, addSubscription, parseUsersKey, getClient, PROJECT_API_VERSION, setUsersError, setUsersData, API_VERSION as API_VERSION$8, getDashboardOrganizationId as getDashboardOrganizationId$1, USERS_STATE_CLEAR_DELAY, removeSubscription, updateLastLoadMoreRequest, cancelRequest, initializeRequest, getTokenState, getQueryState, resolveQuery, bindActionByResourceAndPerspective, PREVIEW_PROJECTION, transformProjectionToPreview } from "./_chunks-es/createGroqSearchFilter.js";
3
- import { createGroqSearchFilter, getActiveReleasesState, getAuthState, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCurrentUserState, getIsInDashboardState, getLoginUrlState, getPerspectiveState, getQueryKey, isCanvasSource, isDatasetSource, isMediaLibrarySource, isProjectUserNotFoundClientError, isStudioConfig, parseQueryKey, setAuthToken } from "./_chunks-es/createGroqSearchFilter.js";
3
+ import { createGroqSearchFilter, getActiveReleasesState, getAllReleasesState, getAuthState, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCurrentUserState, getIsInDashboardState, getLoginUrlState, getPerspectiveState, getQueryKey, isCanvasSource, isDatasetSource, isMediaLibrarySource, isProjectUserNotFoundClientError, isStudioConfig, parseQueryKey, setAuthToken } from "./_chunks-es/createGroqSearchFilter.js";
4
4
  import { first, switchMap as switchMap$1, groupBy, mergeMap, startWith, pairwise, filter, map, delay, tap, catchError, scan, share as share$1 } from "rxjs/operators";
5
5
  import { createController, createNode } from "@sanity/comlink";
6
6
  import { createSelector } from "reselect";
@@ -9,9 +9,9 @@ import { getVersionId, DocumentId, getPublishedId, getDraftId, isDraftId, isVers
9
9
  import { jsonMatch, stringifyPath, slicePath, getIndexForKey } from "@sanity/json-match";
10
10
  import { getIndexForKey as getIndexForKey2, getPathDepth, joinPaths, jsonMatch as jsonMatch2, slicePath as slicePath2, stringifyPath as stringifyPath2 } from "@sanity/json-match";
11
11
  import { evaluateSync, parse } from "groq-js";
12
- import { diffValue } from "@sanity/diff-patch";
13
12
  import { applyPatches, parsePatch } from "@sanity/diff-match-patch";
14
13
  import { isKeySegment, isKeyedObject } from "@sanity/types";
14
+ import { diffValue } from "@sanity/diff-patch";
15
15
  import { createDocumentLoaderFromClient } from "@sanity/mutate/_unstable_store";
16
16
  import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
17
17
  import { fromUrl } from "@sanity/bifur-client";
@@ -642,7 +642,47 @@ function discardDocument(doc) {
642
642
  documentId: effectiveDocumentId
643
643
  };
644
644
  }
645
- const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$4 = "v2025-05-06";
645
+ function createRelease(handle, metadata = { releaseType: "undecided" }) {
646
+ return { type: "release.create", ...handle, metadata };
647
+ }
648
+ function editRelease(handle, patch) {
649
+ return { type: "release.edit", ...handle, patch };
650
+ }
651
+ function publishRelease(handle) {
652
+ return { type: "release.publish", ...handle };
653
+ }
654
+ function scheduleRelease(handle, publishAt) {
655
+ return { type: "release.schedule", ...handle, publishAt };
656
+ }
657
+ function unscheduleRelease(handle) {
658
+ return { type: "release.unschedule", ...handle };
659
+ }
660
+ function archiveRelease(handle) {
661
+ return { type: "release.archive", ...handle };
662
+ }
663
+ function unarchiveRelease(handle) {
664
+ return { type: "release.unarchive", ...handle };
665
+ }
666
+ function deleteRelease(handle) {
667
+ return { type: "release.delete", ...handle };
668
+ }
669
+ const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$4 = "v2025-05-06", RELEASE_DOCUMENTS_PATH = "_.releases";
670
+ function getReleaseDocumentId(releaseId) {
671
+ return `${RELEASE_DOCUMENTS_PATH}.${releaseId}`;
672
+ }
673
+ const RELEASE_ACTION_TYPES = /* @__PURE__ */ new Set([
674
+ "release.create",
675
+ "release.edit",
676
+ "release.publish",
677
+ "release.schedule",
678
+ "release.unschedule",
679
+ "release.archive",
680
+ "release.unarchive",
681
+ "release.delete"
682
+ ]);
683
+ function isReleaseAction(action) {
684
+ return RELEASE_ACTION_TYPES.has(action.type);
685
+ }
646
686
  function generateArrayKey(length = 12) {
647
687
  const numBytes = Math.ceil(length / 2), bytes = crypto.getRandomValues(new Uint8Array(numBytes));
648
688
  return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, length);
@@ -1290,6 +1330,561 @@ class ActionError extends Error {
1290
1330
  }
1291
1331
  class PermissionActionError extends ActionError {
1292
1332
  }
1333
+ function applySingleDocPatch({
1334
+ base: initialBase,
1335
+ working: initialWorking,
1336
+ documentId,
1337
+ patches,
1338
+ transactionId,
1339
+ timestamp,
1340
+ grants,
1341
+ notFoundMessage = "Cannot edit document because it does not exist.",
1342
+ permissionMessage = `You do not have permission to edit document "${documentId}".`
1343
+ }) {
1344
+ let base = initialBase, working = initialWorking;
1345
+ const userPatches = patches?.map((patch) => ({ patch: { id: documentId, ...patch } }));
1346
+ if (!userPatches?.length)
1347
+ return { base, working, diffedPatches: [], workingMutations: [] };
1348
+ if (!working[documentId] || !base[documentId])
1349
+ throw new ActionError({ documentId, transactionId, message: notFoundMessage });
1350
+ const baseBefore = base[documentId];
1351
+ base = processMutations({ documents: base, transactionId, mutations: userPatches, timestamp });
1352
+ const baseAfter = base[documentId], diffedPatches = diffValue(baseBefore, baseAfter), workingBefore = working[documentId];
1353
+ if (!checkGrant(grants.update, workingBefore))
1354
+ throw new PermissionActionError({ documentId, transactionId, message: permissionMessage });
1355
+ const workingMutations = diffedPatches.map((patch) => ({
1356
+ patch: { id: documentId, ...patch }
1357
+ }));
1358
+ return working = processMutations({
1359
+ documents: working,
1360
+ transactionId,
1361
+ mutations: workingMutations,
1362
+ timestamp
1363
+ }), { base, working, diffedPatches, workingMutations };
1364
+ }
1365
+ function handleCreate(action, ctx) {
1366
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1367
+ let { base, working } = ctx;
1368
+ const documentId = getId(action.documentId);
1369
+ if (action.liveEdit) {
1370
+ if (working[documentId])
1371
+ throw new ActionError({
1372
+ documentId,
1373
+ transactionId,
1374
+ message: "This document already exists."
1375
+ });
1376
+ const newDocBase2 = { _type: action.documentType, _id: documentId, ...action.initialValue }, mutations2 = [{ create: {
1377
+ _type: action.documentType,
1378
+ _id: documentId,
1379
+ ...action.initialValue
1380
+ } }];
1381
+ if (base = processMutations({
1382
+ documents: base,
1383
+ transactionId,
1384
+ mutations: [{ create: newDocBase2 }],
1385
+ timestamp
1386
+ }), working = processMutations({
1387
+ documents: working,
1388
+ transactionId,
1389
+ mutations: mutations2,
1390
+ timestamp
1391
+ }), !checkGrant(grants.create, working[documentId]))
1392
+ throw new PermissionActionError({
1393
+ documentId,
1394
+ transactionId,
1395
+ message: `You do not have permission to create document "${documentId}".`
1396
+ });
1397
+ return outgoingMutations.push(...mutations2), { base, working };
1398
+ }
1399
+ const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : void 0, draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
1400
+ if (versionId ? working[versionId] : working[draftId]) {
1401
+ const errorDocType = versionId ? "release version" : "draft";
1402
+ throw new ActionError({
1403
+ documentId,
1404
+ transactionId,
1405
+ message: `A ${errorDocType} of this document already exists. Please use or discard the existing ${errorDocType} before creating a new one.`
1406
+ });
1407
+ }
1408
+ const newDocBase = {
1409
+ ...base[draftId] ?? base[publishedId],
1410
+ _type: action.documentType,
1411
+ _id: versionId ?? draftId,
1412
+ ...action.initialValue
1413
+ }, newDocWorking = {
1414
+ ...working[draftId] ?? working[publishedId],
1415
+ _type: action.documentType,
1416
+ _id: versionId ?? draftId,
1417
+ ...action.initialValue
1418
+ }, mutations = [{ create: newDocWorking }];
1419
+ if (base = processMutations({
1420
+ documents: base,
1421
+ transactionId,
1422
+ mutations: [{ create: newDocBase }],
1423
+ timestamp
1424
+ }), working = processMutations({
1425
+ documents: working,
1426
+ transactionId,
1427
+ mutations,
1428
+ timestamp
1429
+ }), versionId && !checkGrant(grants.create, working[versionId]))
1430
+ throw new PermissionActionError({
1431
+ documentId,
1432
+ transactionId,
1433
+ message: `You do not have permission to create a release version for document "${documentId}".`
1434
+ });
1435
+ if (!versionId && !checkGrant(grants.create, working[draftId]))
1436
+ throw new PermissionActionError({
1437
+ documentId,
1438
+ transactionId,
1439
+ message: `You do not have permission to create a draft for document "${documentId}".`
1440
+ });
1441
+ return outgoingMutations.push(...mutations), outgoingActions.push({
1442
+ actionType: "sanity.action.document.version.create",
1443
+ publishedId,
1444
+ attributes: newDocWorking
1445
+ }), { base, working };
1446
+ }
1447
+ function handleDelete(action, ctx) {
1448
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1449
+ let { base, working } = ctx;
1450
+ const documentId = action.documentId;
1451
+ if (isReleasePerspective(action.perspective))
1452
+ throw new ActionError({
1453
+ documentId,
1454
+ transactionId,
1455
+ message: 'Cannot delete a version document. You may want to use the "unpublish" or "discard" actions instead.'
1456
+ });
1457
+ if (action.liveEdit) {
1458
+ if (!working[documentId])
1459
+ throw new ActionError({
1460
+ documentId,
1461
+ transactionId,
1462
+ message: "The document you are trying to delete does not exist."
1463
+ });
1464
+ if (!checkGrant(grants.update, working[documentId]))
1465
+ throw new PermissionActionError({
1466
+ documentId,
1467
+ transactionId,
1468
+ message: "You do not have permission to delete this document."
1469
+ });
1470
+ const mutations2 = [{ delete: { id: documentId } }];
1471
+ return base = processMutations({ documents: base, transactionId, mutations: mutations2, timestamp }), working = processMutations({ documents: working, transactionId, mutations: mutations2, timestamp }), outgoingMutations.push(...mutations2), { base, working };
1472
+ }
1473
+ const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
1474
+ if (!working[publishedId])
1475
+ throw new ActionError({
1476
+ documentId,
1477
+ transactionId,
1478
+ message: working[draftId] ? "Cannot delete a document without a published version." : "The document you are trying to delete does not exist."
1479
+ });
1480
+ const cantDeleteDraft = working[draftId] && !checkGrant(grants.update, working[draftId]), cantDeletePublished = working[publishedId] && !checkGrant(grants.update, working[publishedId]);
1481
+ if (cantDeleteDraft || cantDeletePublished)
1482
+ throw new PermissionActionError({
1483
+ documentId,
1484
+ transactionId,
1485
+ message: "You do not have permission to delete this document."
1486
+ });
1487
+ const mutations = [{ delete: { id: publishedId } }, { delete: { id: draftId } }], includeDrafts = working[draftId] ? [draftId] : void 0;
1488
+ return base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1489
+ actionType: "sanity.action.document.delete",
1490
+ publishedId,
1491
+ ...includeDrafts ? { includeDrafts } : {}
1492
+ }), { base, working };
1493
+ }
1494
+ function handleDiscard(action, ctx) {
1495
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1496
+ let { base, working } = ctx;
1497
+ const documentId = getId(action.documentId);
1498
+ if (action.liveEdit)
1499
+ throw new ActionError({
1500
+ documentId,
1501
+ transactionId,
1502
+ message: `Cannot discard changes for liveEdit document "${documentId}". LiveEdit documents do not support drafts.`
1503
+ });
1504
+ const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : getDraftId(DocumentId(documentId)), mutations = [{ delete: { id: versionId } }];
1505
+ if (!working[versionId])
1506
+ throw new ActionError({
1507
+ documentId,
1508
+ transactionId,
1509
+ message: `There is no draft or version available to discard for document "${documentId}".`
1510
+ });
1511
+ if (!checkGrant(grants.update, working[versionId]))
1512
+ throw new PermissionActionError({
1513
+ documentId,
1514
+ transactionId,
1515
+ message: `You do not have permission to discard changes for document "${documentId}".`
1516
+ });
1517
+ return base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1518
+ actionType: "sanity.action.document.version.discard",
1519
+ versionId
1520
+ }), { base, working };
1521
+ }
1522
+ function handleEdit(action, ctx) {
1523
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1524
+ let { base, working } = ctx;
1525
+ const documentId = getId(action.documentId);
1526
+ if (action.liveEdit) {
1527
+ const result = applySingleDocPatch({
1528
+ base,
1529
+ working,
1530
+ documentId,
1531
+ patches: action.patches,
1532
+ transactionId,
1533
+ timestamp,
1534
+ grants
1535
+ });
1536
+ return outgoingMutations.push(...result.workingMutations), { base: result.base, working: result.working };
1537
+ }
1538
+ const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : void 0, draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId)), patchDocumentId = isReleasePerspective(action.perspective) ? versionId : draftId, userPatches = action.patches?.map((patch) => ({
1539
+ patch: { id: patchDocumentId, ...patch }
1540
+ }));
1541
+ if (!userPatches?.length) return { base, working };
1542
+ if (isReleasePerspective(action.perspective)) {
1543
+ if (!working[versionId] && !base[versionId])
1544
+ throw new ActionError({
1545
+ documentId,
1546
+ transactionId,
1547
+ message: "This document does not exist in the release. Please create it or add it to the release first."
1548
+ });
1549
+ } else if (!working[draftId] && !working[publishedId] || !base[draftId] && !base[publishedId])
1550
+ throw new ActionError({
1551
+ documentId,
1552
+ transactionId,
1553
+ message: "Cannot edit document because it does not exist in draft or published form."
1554
+ });
1555
+ const baseMutations = [];
1556
+ !isReleasePerspective(action.perspective) && !base[draftId] && base[publishedId] && baseMutations.push({ create: { ...base[publishedId], _id: draftId } });
1557
+ const baseBefore = base[patchDocumentId] ?? base[publishedId];
1558
+ userPatches && baseMutations.push(...userPatches), base = processMutations({
1559
+ documents: base,
1560
+ transactionId,
1561
+ mutations: baseMutations,
1562
+ timestamp
1563
+ });
1564
+ const baseAfter = base[patchDocumentId], patches = diffValue(baseBefore, baseAfter), workingMutations = [];
1565
+ if (!isReleasePerspective(action.perspective) && !working[draftId] && working[publishedId]) {
1566
+ const newDraftFromPublished = { ...working[publishedId], _id: draftId };
1567
+ if (!checkGrant(grants.create, newDraftFromPublished))
1568
+ throw new PermissionActionError({
1569
+ documentId,
1570
+ transactionId,
1571
+ message: "You do not have permission to create a draft for editing this document."
1572
+ });
1573
+ workingMutations.push({ create: newDraftFromPublished });
1574
+ }
1575
+ const workingBefore = working[patchDocumentId] ?? working[publishedId];
1576
+ if (!checkGrant(grants.update, workingBefore))
1577
+ throw new PermissionActionError({
1578
+ documentId,
1579
+ transactionId,
1580
+ message: `You do not have permission to edit document "${documentId}".`
1581
+ });
1582
+ return workingMutations.push(...patches.map((patch) => ({ patch: { id: patchDocumentId, ...patch } }))), working = processMutations({
1583
+ documents: working,
1584
+ transactionId,
1585
+ mutations: workingMutations,
1586
+ timestamp
1587
+ }), outgoingMutations.push(...workingMutations), outgoingActions.push(
1588
+ ...patches.map((patch) => ({
1589
+ actionType: "sanity.action.document.edit",
1590
+ draftId: patchDocumentId,
1591
+ publishedId,
1592
+ patch
1593
+ }))
1594
+ ), { base, working };
1595
+ }
1596
+ function handlePublish(action, ctx) {
1597
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1598
+ let { base, working } = ctx;
1599
+ const documentId = getId(action.documentId);
1600
+ if (action.liveEdit || isReleasePerspective(action.perspective))
1601
+ throw new ActionError({
1602
+ documentId,
1603
+ transactionId,
1604
+ message: "Cannot publish this document. Publishing is not supported for liveEdit or version (release) documents."
1605
+ });
1606
+ const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId)), workingDraft = working[draftId], baseDraft = base[draftId];
1607
+ if (!workingDraft || !baseDraft)
1608
+ throw new ActionError({
1609
+ documentId,
1610
+ transactionId,
1611
+ message: `Cannot publish because no draft version was found for document "${documentId}".`
1612
+ });
1613
+ if (!isDeepEqual(workingDraft, baseDraft))
1614
+ throw new ActionError({
1615
+ documentId,
1616
+ transactionId,
1617
+ message: "Publish aborted: The document has changed elsewhere. Please try again."
1618
+ });
1619
+ const newPublishedFromDraft = { ...strengthenOnPublish(workingDraft), _id: publishedId }, mutations = [{ delete: { id: draftId } }, { createOrReplace: newPublishedFromDraft }];
1620
+ if (working[draftId] && !checkGrant(grants.update, working[draftId]))
1621
+ throw new PermissionActionError({
1622
+ documentId,
1623
+ transactionId,
1624
+ message: `Publish failed: You do not have permission to update the draft for "${documentId}".`
1625
+ });
1626
+ if (working[publishedId] && !checkGrant(grants.update, newPublishedFromDraft))
1627
+ throw new PermissionActionError({
1628
+ documentId,
1629
+ transactionId,
1630
+ message: `Publish failed: You do not have permission to update the published version of "${documentId}".`
1631
+ });
1632
+ if (!working[publishedId] && !checkGrant(grants.create, newPublishedFromDraft))
1633
+ throw new PermissionActionError({
1634
+ documentId,
1635
+ transactionId,
1636
+ message: `Publish failed: You do not have permission to publish a new version of "${documentId}".`
1637
+ });
1638
+ return base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1639
+ actionType: "sanity.action.document.publish",
1640
+ draftId,
1641
+ publishedId
1642
+ }), { base, working };
1643
+ }
1644
+ function strengthenOnPublish(draft) {
1645
+ const isStrengthenReference = (value) => "_strengthenOnPublish" in value;
1646
+ function strengthen(value) {
1647
+ if (typeof value != "object" || !value) return value;
1648
+ if (isStrengthenReference(value)) {
1649
+ const { _strengthenOnPublish, _weak, ...rest } = value;
1650
+ return {
1651
+ ...rest,
1652
+ ..._strengthenOnPublish.weak && { _weak: !0 }
1653
+ };
1654
+ }
1655
+ return Array.isArray(value) ? value.map(strengthen) : Object.fromEntries(Object.entries(value).map(([k, v]) => [k, strengthen(v)]));
1656
+ }
1657
+ return strengthen(draft);
1658
+ }
1659
+ function handleReleaseArchive(action, ctx) {
1660
+ const { base, working, grants, outgoingActions, transactionId } = ctx, releaseDocumentId = getReleaseDocumentId(action.releaseId), existing = working[releaseDocumentId] ?? base[releaseDocumentId];
1661
+ if (!existing)
1662
+ throw new ActionError({
1663
+ documentId: releaseDocumentId,
1664
+ transactionId,
1665
+ message: `Cannot archive release "${action.releaseId}" because it does not exist.`
1666
+ });
1667
+ if (!checkGrant(grants.update, existing))
1668
+ throw new PermissionActionError({
1669
+ documentId: releaseDocumentId,
1670
+ transactionId,
1671
+ message: `You do not have permission to archive release "${action.releaseId}".`
1672
+ });
1673
+ return outgoingActions.push({
1674
+ actionType: "sanity.action.release.archive",
1675
+ releaseId: action.releaseId
1676
+ }), { base, working };
1677
+ }
1678
+ function handleReleaseUnarchive(action, ctx) {
1679
+ const { base, working, grants, outgoingActions, transactionId } = ctx, releaseDocumentId = getReleaseDocumentId(action.releaseId), existing = working[releaseDocumentId] ?? base[releaseDocumentId];
1680
+ if (!existing)
1681
+ throw new ActionError({
1682
+ documentId: releaseDocumentId,
1683
+ transactionId,
1684
+ message: `Cannot unarchive release "${action.releaseId}" because it does not exist.`
1685
+ });
1686
+ if (!checkGrant(grants.update, existing))
1687
+ throw new PermissionActionError({
1688
+ documentId: releaseDocumentId,
1689
+ transactionId,
1690
+ message: `You do not have permission to unarchive release "${action.releaseId}".`
1691
+ });
1692
+ return outgoingActions.push({
1693
+ actionType: "sanity.action.release.unarchive",
1694
+ releaseId: action.releaseId
1695
+ }), { base, working };
1696
+ }
1697
+ function handleReleaseCreate(action, ctx) {
1698
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1699
+ let { base, working } = ctx;
1700
+ const releaseDocumentId = getReleaseDocumentId(action.releaseId);
1701
+ if (working[releaseDocumentId] || base[releaseDocumentId])
1702
+ throw new ActionError({
1703
+ documentId: releaseDocumentId,
1704
+ transactionId,
1705
+ message: `A release with id "${action.releaseId}" already exists.`
1706
+ });
1707
+ const mutations = [{ create: {
1708
+ _id: releaseDocumentId,
1709
+ _type: "system.release",
1710
+ name: action.releaseId,
1711
+ state: "active",
1712
+ metadata: action.metadata
1713
+ } }];
1714
+ if (base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), !checkGrant(grants.create, working[releaseDocumentId]))
1715
+ throw new PermissionActionError({
1716
+ documentId: releaseDocumentId,
1717
+ transactionId,
1718
+ message: `You do not have permission to create release "${action.releaseId}".`
1719
+ });
1720
+ return outgoingMutations.push(...mutations), outgoingActions.push({
1721
+ actionType: "sanity.action.release.create",
1722
+ releaseId: action.releaseId,
1723
+ metadata: action.metadata
1724
+ }), { base, working };
1725
+ }
1726
+ const DELETABLE_STATES = /* @__PURE__ */ new Set(["archived", "published"]);
1727
+ function handleReleaseDelete(action, ctx) {
1728
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1729
+ let { base, working } = ctx;
1730
+ const releaseDocumentId = getReleaseDocumentId(action.releaseId), existing = working[releaseDocumentId] ?? base[releaseDocumentId];
1731
+ if (!existing)
1732
+ throw new ActionError({
1733
+ documentId: releaseDocumentId,
1734
+ transactionId,
1735
+ message: `Cannot delete release "${action.releaseId}" because it does not exist.`
1736
+ });
1737
+ const state = existing.state;
1738
+ if (state && typeof state == "string" && !DELETABLE_STATES.has(state))
1739
+ throw new ActionError({
1740
+ documentId: releaseDocumentId,
1741
+ transactionId,
1742
+ message: `Cannot delete release "${action.releaseId}" while it is "${state}". Archive it first.`
1743
+ });
1744
+ if (!checkGrant(grants.update, existing))
1745
+ throw new PermissionActionError({
1746
+ documentId: releaseDocumentId,
1747
+ transactionId,
1748
+ message: `You do not have permission to delete release "${action.releaseId}".`
1749
+ });
1750
+ const mutations = [{ delete: { id: releaseDocumentId } }];
1751
+ return base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1752
+ actionType: "sanity.action.release.delete",
1753
+ releaseId: action.releaseId
1754
+ }), { base, working };
1755
+ }
1756
+ function handleReleaseEdit(action, ctx) {
1757
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx, { base, working } = ctx, releaseDocumentId = getReleaseDocumentId(action.releaseId), result = applySingleDocPatch({
1758
+ base,
1759
+ working,
1760
+ documentId: releaseDocumentId,
1761
+ patches: [action.patch],
1762
+ transactionId,
1763
+ timestamp,
1764
+ grants,
1765
+ notFoundMessage: `Cannot edit release "${action.releaseId}" because it does not exist.`,
1766
+ permissionMessage: `You do not have permission to edit release "${action.releaseId}".`
1767
+ });
1768
+ return outgoingMutations.push(...result.workingMutations), outgoingActions.push(
1769
+ ...result.diffedPatches.map((patch) => ({
1770
+ actionType: "sanity.action.release.edit",
1771
+ releaseId: action.releaseId,
1772
+ patch
1773
+ }))
1774
+ ), { base: result.base, working: result.working };
1775
+ }
1776
+ function handleReleasePublish(action, ctx) {
1777
+ const { base, working, grants, outgoingActions, transactionId } = ctx, releaseDocumentId = getReleaseDocumentId(action.releaseId), existing = working[releaseDocumentId] ?? base[releaseDocumentId];
1778
+ if (!existing)
1779
+ throw new ActionError({
1780
+ documentId: releaseDocumentId,
1781
+ transactionId,
1782
+ message: `Cannot publish release "${action.releaseId}" because it does not exist.`
1783
+ });
1784
+ if (!checkGrant(grants.update, existing))
1785
+ throw new PermissionActionError({
1786
+ documentId: releaseDocumentId,
1787
+ transactionId,
1788
+ message: `You do not have permission to publish release "${action.releaseId}".`
1789
+ });
1790
+ return outgoingActions.push({
1791
+ actionType: "sanity.action.release.publish",
1792
+ releaseId: action.releaseId
1793
+ }), { base, working };
1794
+ }
1795
+ function handleReleaseSchedule(action, ctx) {
1796
+ const { base, working, grants, outgoingActions, transactionId } = ctx, releaseDocumentId = getReleaseDocumentId(action.releaseId);
1797
+ if (Number.isNaN(Date.parse(action.publishAt)))
1798
+ throw new ActionError({
1799
+ documentId: releaseDocumentId,
1800
+ transactionId,
1801
+ message: `Cannot schedule release "${action.releaseId}": "publishAt" must be a valid ISO 8601 timestamp (received "${action.publishAt}").`
1802
+ });
1803
+ const existing = working[releaseDocumentId] ?? base[releaseDocumentId];
1804
+ if (!existing)
1805
+ throw new ActionError({
1806
+ documentId: releaseDocumentId,
1807
+ transactionId,
1808
+ message: `Cannot schedule release "${action.releaseId}" because it does not exist.`
1809
+ });
1810
+ if (!checkGrant(grants.update, existing))
1811
+ throw new PermissionActionError({
1812
+ documentId: releaseDocumentId,
1813
+ transactionId,
1814
+ message: `You do not have permission to schedule release "${action.releaseId}".`
1815
+ });
1816
+ return outgoingActions.push({
1817
+ actionType: "sanity.action.release.schedule",
1818
+ releaseId: action.releaseId,
1819
+ publishAt: action.publishAt
1820
+ }), { base, working };
1821
+ }
1822
+ function handleReleaseUnschedule(action, ctx) {
1823
+ const { base, working, grants, outgoingActions, transactionId } = ctx, releaseDocumentId = getReleaseDocumentId(action.releaseId), existing = working[releaseDocumentId] ?? base[releaseDocumentId];
1824
+ if (!existing)
1825
+ throw new ActionError({
1826
+ documentId: releaseDocumentId,
1827
+ transactionId,
1828
+ message: `Cannot unschedule release "${action.releaseId}" because it does not exist.`
1829
+ });
1830
+ if (!checkGrant(grants.update, existing))
1831
+ throw new PermissionActionError({
1832
+ documentId: releaseDocumentId,
1833
+ transactionId,
1834
+ message: `You do not have permission to unschedule release "${action.releaseId}".`
1835
+ });
1836
+ return outgoingActions.push({
1837
+ actionType: "sanity.action.release.unschedule",
1838
+ releaseId: action.releaseId
1839
+ }), { base, working };
1840
+ }
1841
+ function handleUnpublish(action, ctx) {
1842
+ const { transactionId, timestamp, grants, outgoingActions, outgoingMutations } = ctx;
1843
+ let { base, working } = ctx;
1844
+ const documentId = getId(action.documentId);
1845
+ if (action.liveEdit || isReleasePerspective(action.perspective))
1846
+ throw new ActionError({
1847
+ documentId,
1848
+ transactionId,
1849
+ message: "Cannot unpublish this document. Unpublishing is not supported for liveEdit or version (release) documents."
1850
+ });
1851
+ const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
1852
+ if (!working[publishedId] && !base[publishedId])
1853
+ throw new ActionError({
1854
+ documentId,
1855
+ transactionId,
1856
+ message: `Cannot unpublish because the document "${documentId}" is not currently published.`
1857
+ });
1858
+ const sourceDoc = working[publishedId] ?? base[publishedId], newDraftFromPublished = { ...sourceDoc, _id: draftId }, mutations = [
1859
+ { delete: { id: publishedId } },
1860
+ { createIfNotExists: newDraftFromPublished }
1861
+ ];
1862
+ if (!checkGrant(grants.update, sourceDoc))
1863
+ throw new PermissionActionError({
1864
+ documentId,
1865
+ transactionId,
1866
+ message: `You do not have permission to unpublish the document "${documentId}".`
1867
+ });
1868
+ if (!working[draftId] && !checkGrant(grants.create, newDraftFromPublished))
1869
+ throw new PermissionActionError({
1870
+ documentId,
1871
+ transactionId,
1872
+ message: `You do not have permission to create a draft from the published version of "${documentId}".`
1873
+ });
1874
+ return base = processMutations({
1875
+ documents: base,
1876
+ transactionId,
1877
+ mutations: [
1878
+ { delete: { id: publishedId } },
1879
+ { createIfNotExists: { ...base[publishedId] ?? sourceDoc, _id: draftId } }
1880
+ ],
1881
+ timestamp
1882
+ }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1883
+ actionType: "sanity.action.document.unpublish",
1884
+ draftId,
1885
+ publishedId
1886
+ }), { base, working };
1887
+ }
1293
1888
  function processActions({
1294
1889
  actions,
1295
1890
  transactionId,
@@ -1298,361 +1893,26 @@ function processActions({
1298
1893
  timestamp,
1299
1894
  grants
1300
1895
  }) {
1301
- let working = { ...initialWorking }, base = { ...initialBase };
1302
- const outgoingActions = [], outgoingMutations = [];
1303
- for (const action of actions)
1304
- switch (action.type) {
1305
- case "document.create": {
1306
- const documentId = getId(action.documentId);
1307
- if (action.liveEdit) {
1308
- if (working[documentId])
1309
- throw new ActionError({
1310
- documentId,
1311
- transactionId,
1312
- message: "This document already exists."
1313
- });
1314
- const newDocBase2 = { _type: action.documentType, _id: documentId, ...action.initialValue }, mutations2 = [{ create: {
1315
- _type: action.documentType,
1316
- _id: documentId,
1317
- ...action.initialValue
1318
- } }];
1319
- if (base = processMutations({
1320
- documents: base,
1321
- transactionId,
1322
- mutations: [{ create: newDocBase2 }],
1323
- timestamp
1324
- }), working = processMutations({
1325
- documents: working,
1326
- transactionId,
1327
- mutations: mutations2,
1328
- timestamp
1329
- }), !checkGrant(grants.create, working[documentId]))
1330
- throw new PermissionActionError({
1331
- documentId,
1332
- transactionId,
1333
- message: `You do not have permission to create document "${documentId}".`
1334
- });
1335
- outgoingMutations.push(...mutations2);
1336
- continue;
1337
- }
1338
- const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : void 0, draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
1339
- if (versionId ? working[versionId] : working[draftId]) {
1340
- const errorDocType = versionId ? "release version" : "draft";
1341
- throw new ActionError({
1342
- documentId,
1343
- transactionId,
1344
- message: `A ${errorDocType} of this document already exists. Please use or discard the existing ${errorDocType} before creating a new one.`
1345
- });
1346
- }
1347
- const newDocBase = {
1348
- ...base[draftId] ?? base[publishedId],
1349
- _type: action.documentType,
1350
- _id: versionId ?? draftId,
1351
- ...action.initialValue
1352
- }, newDocWorking = {
1353
- ...working[draftId] ?? working[publishedId],
1354
- _type: action.documentType,
1355
- _id: versionId ?? draftId,
1356
- ...action.initialValue
1357
- }, mutations = [{ create: newDocWorking }];
1358
- if (base = processMutations({
1359
- documents: base,
1360
- transactionId,
1361
- mutations: [{ create: newDocBase }],
1362
- timestamp
1363
- }), working = processMutations({
1364
- documents: working,
1365
- transactionId,
1366
- mutations,
1367
- timestamp
1368
- }), versionId && !checkGrant(grants.create, working[versionId]))
1369
- throw new PermissionActionError({
1370
- documentId,
1371
- transactionId,
1372
- message: `You do not have permission to create a release version for document "${documentId}".`
1373
- });
1374
- if (!versionId && !checkGrant(grants.create, working[draftId]))
1375
- throw new PermissionActionError({
1376
- documentId,
1377
- transactionId,
1378
- message: `You do not have permission to create a draft for document "${documentId}".`
1379
- });
1380
- outgoingMutations.push(...mutations), outgoingActions.push({
1381
- actionType: "sanity.action.document.version.create",
1382
- publishedId,
1383
- attributes: newDocWorking
1384
- });
1385
- continue;
1386
- }
1387
- case "document.delete": {
1388
- const documentId = action.documentId;
1389
- if (isReleasePerspective(action.perspective))
1390
- throw new ActionError({
1391
- documentId,
1392
- transactionId,
1393
- message: 'Cannot delete a version document. You may want to use the "unpublish" or "discard" actions instead.'
1394
- });
1395
- if (action.liveEdit) {
1396
- if (!working[documentId])
1397
- throw new ActionError({
1398
- documentId,
1399
- transactionId,
1400
- message: "The document you are trying to delete does not exist."
1401
- });
1402
- if (!checkGrant(grants.update, working[documentId]))
1403
- throw new PermissionActionError({
1404
- documentId,
1405
- transactionId,
1406
- message: "You do not have permission to delete this document."
1407
- });
1408
- const mutations2 = [{ delete: { id: documentId } }];
1409
- base = processMutations({ documents: base, transactionId, mutations: mutations2, timestamp }), working = processMutations({ documents: working, transactionId, mutations: mutations2, timestamp }), outgoingMutations.push(...mutations2);
1410
- continue;
1411
- }
1412
- const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
1413
- if (!working[publishedId])
1414
- throw new ActionError({
1415
- documentId,
1416
- transactionId,
1417
- message: working[draftId] ? "Cannot delete a document without a published version." : "The document you are trying to delete does not exist."
1418
- });
1419
- const cantDeleteDraft = working[draftId] && !checkGrant(grants.update, working[draftId]), cantDeletePublished = working[publishedId] && !checkGrant(grants.update, working[publishedId]);
1420
- if (cantDeleteDraft || cantDeletePublished)
1421
- throw new PermissionActionError({
1422
- documentId,
1423
- transactionId,
1424
- message: "You do not have permission to delete this document."
1425
- });
1426
- const mutations = [{ delete: { id: publishedId } }, { delete: { id: draftId } }], includeDrafts = working[draftId] ? [draftId] : void 0;
1427
- base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1428
- actionType: "sanity.action.document.delete",
1429
- publishedId,
1430
- ...includeDrafts ? { includeDrafts } : {}
1431
- });
1432
- continue;
1433
- }
1434
- case "document.discard": {
1435
- const documentId = getId(action.documentId);
1436
- if (action.liveEdit)
1437
- throw new ActionError({
1438
- documentId,
1439
- transactionId,
1440
- message: `Cannot discard changes for liveEdit document "${documentId}". LiveEdit documents do not support drafts.`
1441
- });
1442
- const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : getDraftId(DocumentId(documentId)), mutations = [{ delete: { id: versionId } }];
1443
- if (!working[versionId])
1444
- throw new ActionError({
1445
- documentId,
1446
- transactionId,
1447
- message: `There is no draft or version available to discard for document "${documentId}".`
1448
- });
1449
- if (!checkGrant(grants.update, working[versionId]))
1450
- throw new PermissionActionError({
1451
- documentId,
1452
- transactionId,
1453
- message: `You do not have permission to discard changes for document "${documentId}".`
1454
- });
1455
- base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1456
- actionType: "sanity.action.document.version.discard",
1457
- versionId
1458
- });
1459
- continue;
1460
- }
1461
- case "document.edit": {
1462
- const documentId = getId(action.documentId);
1463
- if (action.liveEdit) {
1464
- const userPatches2 = action.patches?.map((patch) => ({ patch: { id: documentId, ...patch } }));
1465
- if (!userPatches2?.length) continue;
1466
- if (!working[documentId] || !base[documentId])
1467
- throw new ActionError({
1468
- documentId,
1469
- transactionId,
1470
- message: "Cannot edit document because it does not exist."
1471
- });
1472
- const baseBefore2 = base[documentId];
1473
- userPatches2 && (base = processMutations({
1474
- documents: base,
1475
- transactionId,
1476
- mutations: userPatches2,
1477
- timestamp
1478
- }));
1479
- const baseAfter2 = base[documentId], patches2 = diffValue(baseBefore2, baseAfter2), workingBefore2 = working[documentId];
1480
- if (!checkGrant(grants.update, workingBefore2))
1481
- throw new PermissionActionError({
1482
- documentId,
1483
- transactionId,
1484
- message: `You do not have permission to edit document "${documentId}".`
1485
- });
1486
- const workingMutations2 = patches2.map((patch) => ({ patch: { id: documentId, ...patch } }));
1487
- working = processMutations({
1488
- documents: working,
1489
- transactionId,
1490
- mutations: workingMutations2,
1491
- timestamp
1492
- }), outgoingMutations.push(...workingMutations2);
1493
- continue;
1494
- }
1495
- const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : void 0, draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId)), patchDocumentId = isReleasePerspective(action.perspective) ? versionId : draftId, userPatches = action.patches?.map((patch) => ({
1496
- patch: { id: patchDocumentId, ...patch }
1497
- }));
1498
- if (!userPatches?.length) continue;
1499
- if (isReleasePerspective(action.perspective)) {
1500
- if (!working[versionId] && !base[versionId])
1501
- throw new ActionError({
1502
- documentId,
1503
- transactionId,
1504
- message: "This document does not exist in the release. Please create it or add it to the release first."
1505
- });
1506
- } else if (!working[draftId] && !working[publishedId] || !base[draftId] && !base[publishedId])
1507
- throw new ActionError({
1508
- documentId,
1509
- transactionId,
1510
- message: "Cannot edit document because it does not exist in draft or published form."
1511
- });
1512
- const baseMutations = [];
1513
- !isReleasePerspective(action.perspective) && !base[draftId] && base[publishedId] && baseMutations.push({ create: { ...base[publishedId], _id: draftId } });
1514
- const baseBefore = base[patchDocumentId] ?? base[publishedId];
1515
- userPatches && baseMutations.push(...userPatches), base = processMutations({
1516
- documents: base,
1517
- transactionId,
1518
- mutations: baseMutations,
1519
- timestamp
1520
- });
1521
- const baseAfter = base[patchDocumentId], patches = diffValue(baseBefore, baseAfter), workingMutations = [];
1522
- if (!isReleasePerspective(action.perspective) && !working[draftId] && working[publishedId]) {
1523
- const newDraftFromPublished = { ...working[publishedId], _id: draftId };
1524
- if (!checkGrant(grants.create, newDraftFromPublished))
1525
- throw new PermissionActionError({
1526
- documentId,
1527
- transactionId,
1528
- message: "You do not have permission to create a draft for editing this document."
1529
- });
1530
- workingMutations.push({ create: newDraftFromPublished });
1531
- }
1532
- const workingBefore = working[patchDocumentId] ?? working[publishedId];
1533
- if (!checkGrant(grants.update, workingBefore))
1534
- throw new PermissionActionError({
1535
- documentId,
1536
- transactionId,
1537
- message: `You do not have permission to edit document "${documentId}".`
1538
- });
1539
- workingMutations.push(...patches.map((patch) => ({ patch: { id: patchDocumentId, ...patch } }))), working = processMutations({
1540
- documents: working,
1541
- transactionId,
1542
- mutations: workingMutations,
1543
- timestamp
1544
- }), outgoingMutations.push(...workingMutations), outgoingActions.push(
1545
- ...patches.map((patch) => ({
1546
- actionType: "sanity.action.document.edit",
1547
- draftId: patchDocumentId,
1548
- publishedId,
1549
- patch
1550
- }))
1551
- );
1552
- continue;
1553
- }
1554
- case "document.publish": {
1555
- const documentId = getId(action.documentId);
1556
- if (action.liveEdit || isReleasePerspective(action.perspective))
1557
- throw new ActionError({
1558
- documentId,
1559
- transactionId,
1560
- message: "Cannot publish this document. Publishing is not supported for liveEdit or version (release) documents."
1561
- });
1562
- const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId)), workingDraft = working[draftId], baseDraft = base[draftId];
1563
- if (!workingDraft || !baseDraft)
1564
- throw new ActionError({
1565
- documentId,
1566
- transactionId,
1567
- message: `Cannot publish because no draft version was found for document "${documentId}".`
1568
- });
1569
- if (!isDeepEqual(workingDraft, baseDraft))
1570
- throw new ActionError({
1571
- documentId,
1572
- transactionId,
1573
- message: "Publish aborted: The document has changed elsewhere. Please try again."
1574
- });
1575
- const newPublishedFromDraft = { ...strengthenOnPublish(workingDraft), _id: publishedId }, mutations = [
1576
- { delete: { id: draftId } },
1577
- { createOrReplace: newPublishedFromDraft }
1578
- ];
1579
- if (working[draftId] && !checkGrant(grants.update, working[draftId]))
1580
- throw new PermissionActionError({
1581
- documentId,
1582
- transactionId,
1583
- message: `Publish failed: You do not have permission to update the draft for "${documentId}".`
1584
- });
1585
- if (working[publishedId] && !checkGrant(grants.update, newPublishedFromDraft))
1586
- throw new PermissionActionError({
1587
- documentId,
1588
- transactionId,
1589
- message: `Publish failed: You do not have permission to update the published version of "${documentId}".`
1590
- });
1591
- if (!working[publishedId] && !checkGrant(grants.create, newPublishedFromDraft))
1592
- throw new PermissionActionError({
1593
- documentId,
1594
- transactionId,
1595
- message: `Publish failed: You do not have permission to publish a new version of "${documentId}".`
1596
- });
1597
- base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1598
- actionType: "sanity.action.document.publish",
1599
- draftId,
1600
- publishedId
1601
- });
1602
- continue;
1603
- }
1604
- case "document.unpublish": {
1605
- const documentId = getId(action.documentId);
1606
- if (action.liveEdit || isReleasePerspective(action.perspective))
1607
- throw new ActionError({
1608
- documentId,
1609
- transactionId,
1610
- message: "Cannot unpublish this document. Unpublishing is not supported for liveEdit or version (release) documents."
1611
- });
1612
- const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
1613
- if (!working[publishedId] && !base[publishedId])
1614
- throw new ActionError({
1615
- documentId,
1616
- transactionId,
1617
- message: `Cannot unpublish because the document "${documentId}" is not currently published.`
1618
- });
1619
- const sourceDoc = working[publishedId] ?? base[publishedId], newDraftFromPublished = { ...sourceDoc, _id: draftId }, mutations = [
1620
- { delete: { id: publishedId } },
1621
- { createIfNotExists: newDraftFromPublished }
1622
- ];
1623
- if (!checkGrant(grants.update, sourceDoc))
1624
- throw new PermissionActionError({
1625
- documentId,
1626
- transactionId,
1627
- message: `You do not have permission to unpublish the document "${documentId}".`
1628
- });
1629
- if (!working[draftId] && !checkGrant(grants.create, newDraftFromPublished))
1630
- throw new PermissionActionError({
1631
- documentId,
1632
- transactionId,
1633
- message: `You do not have permission to create a draft from the published version of "${documentId}".`
1634
- });
1635
- base = processMutations({
1636
- documents: base,
1637
- transactionId,
1638
- mutations: [
1639
- { delete: { id: publishedId } },
1640
- { createIfNotExists: { ...base[publishedId] ?? sourceDoc, _id: draftId } }
1641
- ],
1642
- timestamp
1643
- }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
1644
- actionType: "sanity.action.document.unpublish",
1645
- draftId,
1646
- publishedId
1647
- });
1648
- continue;
1649
- }
1650
- default:
1651
- throw new Error(
1652
- `Unknown action type: "${// @ts-expect-error invalid input
1653
- action.type}". Please contact support if this issue persists.`
1654
- );
1655
- }
1896
+ let base = { ...initialBase }, working = { ...initialWorking };
1897
+ const outgoingActions = [], outgoingMutations = [], liveEditAction = actions.find((action) => !isReleaseAction(action) && action.liveEdit), otherAction = actions.find((action) => isReleaseAction(action) || !action.liveEdit);
1898
+ if (liveEditAction && otherAction)
1899
+ throw new ActionError({
1900
+ documentId: liveEditAction.documentId,
1901
+ transactionId,
1902
+ message: "Cannot combine liveEdit document actions with other actions in the same transaction. Submit them as separate transactions."
1903
+ });
1904
+ for (const action of actions) {
1905
+ const result = dispatch(action, {
1906
+ base,
1907
+ working,
1908
+ transactionId,
1909
+ timestamp,
1910
+ grants,
1911
+ outgoingActions,
1912
+ outgoingMutations
1913
+ });
1914
+ base = result.base, working = result.working;
1915
+ }
1656
1916
  const previousRevs = Object.fromEntries(
1657
1917
  Object.entries(initialWorking).map(([id, doc]) => [id, doc?._rev])
1658
1918
  );
@@ -1664,20 +1924,42 @@ function processActions({
1664
1924
  previousRevs
1665
1925
  };
1666
1926
  }
1667
- function strengthenOnPublish(draft) {
1668
- const isStrengthenReference = (value) => "_strengthenOnPublish" in value;
1669
- function strengthen(value) {
1670
- if (typeof value != "object" || !value) return value;
1671
- if (isStrengthenReference(value)) {
1672
- const { _strengthenOnPublish, _weak, ...rest } = value;
1673
- return {
1674
- ...rest,
1675
- ..._strengthenOnPublish.weak && { _weak: !0 }
1676
- };
1677
- }
1678
- return Array.isArray(value) ? value.map(strengthen) : Object.fromEntries(Object.entries(value).map(([k, v]) => [k, strengthen(v)]));
1927
+ function dispatch(action, ctx) {
1928
+ switch (action.type) {
1929
+ case "document.create":
1930
+ return handleCreate(action, ctx);
1931
+ case "document.delete":
1932
+ return handleDelete(action, ctx);
1933
+ case "document.discard":
1934
+ return handleDiscard(action, ctx);
1935
+ case "document.edit":
1936
+ return handleEdit(action, ctx);
1937
+ case "document.publish":
1938
+ return handlePublish(action, ctx);
1939
+ case "document.unpublish":
1940
+ return handleUnpublish(action, ctx);
1941
+ case "release.create":
1942
+ return handleReleaseCreate(action, ctx);
1943
+ case "release.edit":
1944
+ return handleReleaseEdit(action, ctx);
1945
+ case "release.publish":
1946
+ return handleReleasePublish(action, ctx);
1947
+ case "release.schedule":
1948
+ return handleReleaseSchedule(action, ctx);
1949
+ case "release.unschedule":
1950
+ return handleReleaseUnschedule(action, ctx);
1951
+ case "release.archive":
1952
+ return handleReleaseArchive(action, ctx);
1953
+ case "release.unarchive":
1954
+ return handleReleaseUnarchive(action, ctx);
1955
+ case "release.delete":
1956
+ return handleReleaseDelete(action, ctx);
1957
+ default:
1958
+ throw new Error(
1959
+ `Unknown action type: "${// @ts-expect-error invalid input
1960
+ action.type}". Please contact support if this issue persists.`
1961
+ );
1679
1962
  }
1680
- return strengthen(draft);
1681
1963
  }
1682
1964
  const EMPTY_REVISIONS = {};
1683
1965
  function queueTransaction(prev, transaction) {
@@ -1754,29 +2036,31 @@ function batchAppliedTransactions([curr, ...rest]) {
1754
2036
  };
1755
2037
  if (!rest.length) return editAction;
1756
2038
  const next = batchAppliedTransactions(rest);
1757
- if (next)
1758
- return next.disableBatching || !!action.liveEdit != !!next.actions[0]?.liveEdit ? editAction : {
1759
- disableBatching: !1,
1760
- // Use the transactionId from the later (next) transaction.
1761
- transactionId: next.transactionId,
1762
- // Accumulate actions: current action first, then later ones.
1763
- actions: [action, ...next.actions],
1764
- // Merge outgoingActions in order.
1765
- outgoingActions: [...curr.outgoingActions, ...next.outgoingActions],
1766
- // Batched transaction IDs: preserve order by placing curr first.
1767
- batchedTransactionIds: [curr.transactionId, ...next.batchedTransactionIds],
1768
- // Merge outgoingMutations in order.
1769
- outgoingMutations: [...curr.outgoingMutations, ...next.outgoingMutations],
1770
- // Working state reflects the latest optimistic changes: later transactions override earlier.
1771
- working: { ...curr.working, ...next.working },
1772
- // Base state (base, previous, previousRevs) must reflect the original state.
1773
- // Use curr values (the earliest transaction) to override later ones.
1774
- previousRevs: { ...next.previousRevs, ...curr.previousRevs },
1775
- previous: { ...next.previous, ...curr.previous },
1776
- base: { ...next.base, ...curr.base },
1777
- // Use the earliest timestamp from curr.
1778
- timestamp: curr.timestamp ?? next.timestamp
1779
- };
2039
+ if (!next) return;
2040
+ if (next.disableBatching) return editAction;
2041
+ const nextFirst = next.actions[0], nextLiveEdit = nextFirst && "liveEdit" in nextFirst ? nextFirst.liveEdit : !1;
2042
+ return !!action.liveEdit != !!nextLiveEdit ? editAction : {
2043
+ disableBatching: !1,
2044
+ // Use the transactionId from the later (next) transaction.
2045
+ transactionId: next.transactionId,
2046
+ // Accumulate actions: current action first, then later ones.
2047
+ actions: [action, ...next.actions],
2048
+ // Merge outgoingActions in order.
2049
+ outgoingActions: [...curr.outgoingActions, ...next.outgoingActions],
2050
+ // Batched transaction IDs: preserve order by placing curr first.
2051
+ batchedTransactionIds: [curr.transactionId, ...next.batchedTransactionIds],
2052
+ // Merge outgoingMutations in order.
2053
+ outgoingMutations: [...curr.outgoingMutations, ...next.outgoingMutations],
2054
+ // Working state reflects the latest optimistic changes: later transactions override earlier.
2055
+ working: { ...curr.working, ...next.working },
2056
+ // Base state (base, previous, previousRevs) must reflect the original state.
2057
+ // Use curr values (the earliest transaction) to override later ones.
2058
+ previousRevs: { ...next.previousRevs, ...curr.previousRevs },
2059
+ previous: { ...next.previous, ...curr.previous },
2060
+ base: { ...next.base, ...curr.base },
2061
+ // Use the earliest timestamp from curr.
2062
+ timestamp: curr.timestamp ?? next.timestamp
2063
+ };
1780
2064
  }
1781
2065
  function transitionAppliedTransactionsToOutgoing(prev) {
1782
2066
  if (prev.outgoing) return prev;
@@ -1953,32 +2237,43 @@ function manageSubscriberIds({ state }, handles) {
1953
2237
  }
1954
2238
  function getDocumentIdsFromHandleLikes(handles) {
1955
2239
  return handles.flatMap((handle) => {
2240
+ if ("type" in handle && isReleaseAction(handle))
2241
+ return [getReleaseDocumentId(handle.releaseId)];
1956
2242
  const idsForDocument = [];
1957
2243
  return handle.documentId ? handle.liveEdit ? [handle.documentId] : (isReleasePerspective(handle.perspective) && idsForDocument.push(
1958
2244
  getVersionId(DocumentId(handle.documentId), handle.perspective.releaseName)
1959
2245
  ), idsForDocument.push(getPublishedId(DocumentId(handle.documentId))), idsForDocument.push(getDraftId(DocumentId(handle.documentId))), idsForDocument) : [];
1960
2246
  });
1961
2247
  }
2248
+ const actionMap = {
2249
+ "document.create": "created",
2250
+ "document.delete": "deleted",
2251
+ "document.discard": "discarded",
2252
+ "document.edit": "edited",
2253
+ "document.publish": "published",
2254
+ "document.unpublish": "unpublished",
2255
+ "release.create": "created",
2256
+ "release.edit": "edited",
2257
+ "release.delete": "deleted"
2258
+ };
1962
2259
  function getDocumentEvents(outgoing) {
1963
- const documentIdsByAction = Object.entries(
1964
- outgoing.actions.reduce(
1965
- (acc, { type, documentId }) => {
1966
- const ids = acc[type] || /* @__PURE__ */ new Set();
1967
- return documentId && ids.add(documentId), acc[type] = ids, acc;
1968
- },
1969
- {}
1970
- )
1971
- ), actionMap = {
1972
- "document.create": "created",
1973
- "document.delete": "deleted",
1974
- "document.discard": "discarded",
1975
- "document.edit": "edited",
1976
- "document.publish": "published",
1977
- "document.unpublish": "unpublished"
1978
- };
1979
- return documentIdsByAction.flatMap(
1980
- ([actionType, documentIds]) => Array.from(documentIds).map(
1981
- (documentId) => ({ type: actionMap[actionType], documentId, outgoing })
2260
+ const documentIdsByAction = outgoing.actions.reduce(
2261
+ (acc, action) => {
2262
+ if (!(action.type in actionMap)) return acc;
2263
+ const documentId = isReleaseAction(action) ? getReleaseDocumentId(action.releaseId) : action.documentId;
2264
+ if (!documentId) return acc;
2265
+ const type = action.type, ids = acc[type] ?? /* @__PURE__ */ new Set();
2266
+ return ids.add(documentId), acc[type] = ids, acc;
2267
+ },
2268
+ {}
2269
+ );
2270
+ return Object.entries(documentIdsByAction).flatMap(
2271
+ ([actionType, documentIds]) => Array.from(documentIds ?? []).map(
2272
+ (documentId) => ({
2273
+ type: actionMap[actionType],
2274
+ documentId,
2275
+ outgoing
2276
+ })
1982
2277
  )
1983
2278
  );
1984
2279
  }
@@ -2202,7 +2497,7 @@ const _resolveDocument = bindActionByResource(
2202
2497
  result,
2203
2498
  outgoing
2204
2499
  }));
2205
- return outgoing.actions.some((action) => action.liveEdit) ? client.observable.mutate(outgoing.outgoingMutations, {
2500
+ return outgoing.actions.some((action) => !isReleaseAction(action) && action.liveEdit) ? client.observable.mutate(outgoing.outgoingMutations, {
2206
2501
  transactionId: outgoing.transactionId,
2207
2502
  visibility: "async",
2208
2503
  returnDocuments: !1,
@@ -2725,7 +3020,7 @@ const handleIncomingMessage = (event) => {
2725
3020
  }) : getClient(instance, {
2726
3021
  apiVersion: PRESENCE_API_VERSION,
2727
3022
  resource
2728
- }), token$ = getTokenState(instance).observable.pipe(distinctUntilChanged()), [incomingEvents$, dispatch] = createBifurTransport({
3023
+ }), token$ = getTokenState(instance).observable.pipe(distinctUntilChanged()), [incomingEvents$, dispatch2] = createBifurTransport({
2729
3024
  client,
2730
3025
  token$,
2731
3026
  sessionId
@@ -2746,7 +3041,7 @@ const handleIncomingMessage = (event) => {
2746
3041
  return newLocations.delete(event.sessionId), { ...prevState, locations: newLocations };
2747
3042
  }));
2748
3043
  })
2749
- ), dispatch({ type: "rollCall" }).subscribe(), isCanvasResource(resource)) {
3044
+ ), dispatch2({ type: "rollCall" }).subscribe(), isCanvasResource(resource)) {
2750
3045
  const globalClient = getClient(instance, { apiVersion: PRESENCE_API_VERSION });
2751
3046
  subscription.add(
2752
3047
  globalClient.observable.request({
@@ -2758,7 +3053,7 @@ const handleIncomingMessage = (event) => {
2758
3053
  );
2759
3054
  }
2760
3055
  return () => {
2761
- dispatch({ type: "disconnect" }).subscribe(), subscription.unsubscribe();
3056
+ dispatch2({ type: "disconnect" }).subscribe(), subscription.unsubscribe();
2762
3057
  };
2763
3058
  }
2764
3059
  }), selectLocations = (state) => state.locations, selectUsers = (state) => state.users, selectPresence = createSelector(
@@ -3245,6 +3540,7 @@ export {
3245
3540
  agentTransform,
3246
3541
  agentTranslate,
3247
3542
  applyDocumentActions,
3543
+ archiveRelease,
3248
3544
  configureLogging,
3249
3545
  createDatasetHandle,
3250
3546
  createDocument,
@@ -3252,13 +3548,17 @@ export {
3252
3548
  createDocumentTypeHandle,
3253
3549
  createGroqSearchFilter,
3254
3550
  createProjectHandle,
3551
+ createRelease,
3255
3552
  createSanityInstance,
3256
3553
  defineIntent,
3257
3554
  deleteDocument,
3555
+ deleteRelease,
3258
3556
  destroyController,
3259
3557
  discardDocument,
3260
3558
  editDocument,
3559
+ editRelease,
3261
3560
  getActiveReleasesState,
3561
+ getAllReleasesState,
3262
3562
  getAuthState,
3263
3563
  getClient,
3264
3564
  getClientErrorApiBody,
@@ -3291,6 +3591,7 @@ export {
3291
3591
  getProjectsState,
3292
3592
  getQueryKey,
3293
3593
  getQueryState,
3594
+ getReleaseDocumentId,
3294
3595
  getTokenState,
3295
3596
  getUserState,
3296
3597
  getUsersKey,
@@ -3313,6 +3614,7 @@ export {
3313
3614
  parseQueryKey,
3314
3615
  parseUsersKey,
3315
3616
  publishDocument,
3617
+ publishRelease,
3316
3618
  releaseChannel,
3317
3619
  releaseNode,
3318
3620
  resolveDatasets,
@@ -3328,11 +3630,14 @@ export {
3328
3630
  resolveQuery,
3329
3631
  resolveUser,
3330
3632
  resolveUsers,
3633
+ scheduleRelease,
3331
3634
  setAuthToken,
3332
3635
  slicePath2 as slicePath,
3333
3636
  stringifyPath2 as stringifyPath,
3334
3637
  subscribeDocumentEvents,
3335
3638
  transformProjectionToPreview,
3336
- unpublishDocument
3639
+ unarchiveRelease,
3640
+ unpublishDocument,
3641
+ unscheduleRelease
3337
3642
  };
3338
3643
  //# sourceMappingURL=index.js.map