@sanity/sdk 2.8.0 → 2.10.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 (111) hide show
  1. package/dist/_chunks-dts/utils.d.ts +2450 -0
  2. package/dist/_chunks-es/_internal.js +129 -0
  3. package/dist/_chunks-es/_internal.js.map +1 -0
  4. package/dist/_chunks-es/createGroqSearchFilter.js +1537 -0
  5. package/dist/_chunks-es/createGroqSearchFilter.js.map +1 -0
  6. package/dist/_chunks-es/telemetryManager.js +87 -0
  7. package/dist/_chunks-es/telemetryManager.js.map +1 -0
  8. package/dist/_chunks-es/version.js +7 -0
  9. package/dist/_chunks-es/version.js.map +1 -0
  10. package/dist/_exports/_internal.d.ts +64 -0
  11. package/dist/_exports/_internal.js +20 -0
  12. package/dist/_exports/_internal.js.map +1 -0
  13. package/dist/index.d.ts +2 -2343
  14. package/dist/index.js +465 -1813
  15. package/dist/index.js.map +1 -1
  16. package/package.json +17 -12
  17. package/src/_exports/_internal.ts +14 -0
  18. package/src/_exports/index.ts +18 -1
  19. package/src/auth/authStore.test.ts +150 -1
  20. package/src/auth/authStore.ts +11 -11
  21. package/src/auth/dashboardAuth.ts +2 -2
  22. package/src/auth/handleAuthCallback.ts +9 -3
  23. package/src/auth/logout.test.ts +1 -1
  24. package/src/auth/logout.ts +1 -1
  25. package/src/auth/refreshStampedToken.test.ts +118 -1
  26. package/src/auth/refreshStampedToken.ts +3 -2
  27. package/src/auth/standaloneAuth.ts +9 -3
  28. package/src/auth/studioAuth.ts +34 -7
  29. package/src/auth/studioModeAuth.ts +2 -1
  30. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +10 -2
  31. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +5 -1
  32. package/src/auth/subscribeToStorageEventsAndSetToken.ts +2 -2
  33. package/src/auth/utils.ts +33 -0
  34. package/src/client/clientStore.test.ts +44 -30
  35. package/src/client/clientStore.ts +49 -48
  36. package/src/comlink/controller/actions/getOrCreateChannel.ts +2 -2
  37. package/src/comlink/node/actions/getOrCreateNode.ts +2 -2
  38. package/src/comlink/node/getNodeState.ts +2 -1
  39. package/src/config/sanityConfig.ts +78 -12
  40. package/src/document/actions.ts +18 -11
  41. package/src/document/applyDocumentActions.test.ts +7 -6
  42. package/src/document/applyDocumentActions.ts +10 -4
  43. package/src/document/documentStore.test.ts +542 -188
  44. package/src/document/documentStore.ts +142 -76
  45. package/src/document/events.ts +7 -2
  46. package/src/document/permissions.test.ts +18 -16
  47. package/src/document/permissions.ts +35 -11
  48. package/src/document/processActions.test.ts +359 -32
  49. package/src/document/processActions.ts +106 -78
  50. package/src/document/reducers.test.ts +117 -29
  51. package/src/document/reducers.ts +47 -40
  52. package/src/document/sharedListener.ts +16 -6
  53. package/src/document/util.ts +14 -0
  54. package/src/favorites/favorites.test.ts +9 -2
  55. package/src/presence/bifurTransport.test.ts +46 -6
  56. package/src/presence/bifurTransport.ts +19 -2
  57. package/src/presence/presenceStore.test.ts +96 -0
  58. package/src/presence/presenceStore.ts +96 -24
  59. package/src/preview/getPreviewState.test.ts +115 -98
  60. package/src/preview/getPreviewState.ts +38 -60
  61. package/src/preview/previewProjectionUtils.test.ts +179 -0
  62. package/src/preview/previewProjectionUtils.ts +93 -0
  63. package/src/preview/resolvePreview.test.ts +42 -25
  64. package/src/preview/resolvePreview.ts +33 -10
  65. package/src/preview/{previewStore.ts → types.ts} +8 -17
  66. package/src/projection/getProjectionState.test.ts +16 -16
  67. package/src/projection/getProjectionState.ts +6 -5
  68. package/src/projection/projectionQuery.ts +2 -3
  69. package/src/projection/projectionStore.test.ts +2 -2
  70. package/src/projection/resolveProjection.ts +2 -2
  71. package/src/projection/subscribeToStateAndFetchBatches.test.ts +1 -1
  72. package/src/projection/subscribeToStateAndFetchBatches.ts +12 -11
  73. package/src/projection/types.ts +1 -1
  74. package/src/query/queryStore.test.ts +12 -12
  75. package/src/query/queryStore.ts +12 -11
  76. package/src/query/reducers.ts +3 -3
  77. package/src/releases/getPerspectiveState.ts +7 -6
  78. package/src/releases/releasesStore.test.ts +20 -5
  79. package/src/releases/releasesStore.ts +20 -8
  80. package/src/store/createActionBinder.test.ts +31 -31
  81. package/src/store/createActionBinder.ts +43 -38
  82. package/src/store/createSanityInstance.ts +2 -3
  83. package/src/store/createStateSourceAction.test.ts +62 -0
  84. package/src/store/createStateSourceAction.ts +34 -39
  85. package/src/telemetry/__telemetry__/sdk.telemetry.ts +42 -0
  86. package/src/telemetry/devMode.test.ts +52 -0
  87. package/src/telemetry/devMode.ts +40 -0
  88. package/src/telemetry/initTelemetry.test.ts +225 -0
  89. package/src/telemetry/initTelemetry.ts +205 -0
  90. package/src/telemetry/telemetryManager.test.ts +263 -0
  91. package/src/telemetry/telemetryManager.ts +187 -0
  92. package/src/users/reducers.ts +3 -4
  93. package/src/users/usersStore.test.ts +1 -0
  94. package/src/users/usersStore.ts +5 -1
  95. package/src/utils/createFetcherStore.test.ts +6 -4
  96. package/src/utils/createFetcherStore.ts +8 -5
  97. package/src/utils/getStagingApiHost.test.ts +21 -0
  98. package/src/utils/getStagingApiHost.ts +14 -0
  99. package/src/utils/ids.test.ts +1 -29
  100. package/src/utils/ids.ts +0 -10
  101. package/src/utils/isImportError.test.ts +72 -0
  102. package/src/utils/isImportError.ts +34 -0
  103. package/src/utils/object.test.ts +95 -0
  104. package/src/utils/object.ts +142 -0
  105. package/src/utils/setCleanupTimeout.ts +24 -0
  106. package/src/preview/previewQuery.test.ts +0 -236
  107. package/src/preview/previewQuery.ts +0 -153
  108. package/src/preview/previewStore.test.ts +0 -36
  109. package/src/preview/subscribeToStateAndFetchBatches.test.ts +0 -221
  110. package/src/preview/subscribeToStateAndFetchBatches.ts +0 -112
  111. package/src/preview/util.ts +0 -13
@@ -1,4 +1,4 @@
1
- import {type Reference, type SanityDocument} from '@sanity/types'
1
+ import {type CreateMutation, type Reference, type SanityDocument} from '@sanity/types'
2
2
  import {parse} from 'groq-js'
3
3
  import {describe, expect, it} from 'vitest'
4
4
 
@@ -885,17 +885,43 @@ describe('processActions', () => {
885
885
  expect(doc?._type).toBe('liveArticle')
886
886
  expect(doc?._rev).toBe(transactionId)
887
887
 
888
- // Should use document.create action, not version.create
889
- expect(result.outgoingActions).toHaveLength(1)
890
- const action = result.outgoingActions[0]
891
- expect(action.actionType).toBe('sanity.action.document.create')
892
- if ('attributes' in action && 'publishedId' in action) {
893
- expect(action.publishedId).toBe('live1')
894
- expect(action.attributes._id).toBe('live1')
895
- expect(action.attributes._type).toBe('liveArticle')
896
- } else {
897
- throw new Error('Expected action to have attributes and publishedId')
898
- }
888
+ // Should not use actions
889
+ expect(result.outgoingActions).toHaveLength(0)
890
+ expect(result.outgoingMutations).toHaveLength(1)
891
+ const mutation = result.outgoingMutations[0] as CreateMutation
892
+ expect(mutation.create._id).toBe('live1')
893
+ expect(mutation.create._type).toBe('liveArticle')
894
+ })
895
+
896
+ it('should apply initialValue when creating a liveEdit document', () => {
897
+ const base: DocumentSet = {}
898
+ const working: DocumentSet = {}
899
+ const actions: DocumentAction[] = [
900
+ {
901
+ documentId: 'live1',
902
+ type: 'document.create',
903
+ documentType: 'liveArticle',
904
+ liveEdit: true,
905
+ initialValue: {title: 'Initial Title', count: 42},
906
+ },
907
+ ]
908
+
909
+ const result = processActions({
910
+ actions,
911
+ transactionId,
912
+ base,
913
+ working,
914
+ timestamp,
915
+ grants: defaultGrants,
916
+ })
917
+
918
+ const doc = result.working['live1']
919
+ expect(doc?.['title']).toBe('Initial Title')
920
+ expect(doc?.['count']).toBe(42)
921
+
922
+ const mutation = result.outgoingMutations[0] as CreateMutation
923
+ expect(mutation.create['title']).toBe('Initial Title')
924
+ expect(mutation.create['count']).toBe(42)
899
925
  })
900
926
 
901
927
  it('should throw an error if liveEdit document already exists', () => {
@@ -946,12 +972,15 @@ describe('processActions', () => {
946
972
  expect(editedDoc?.['title']).toBe('Updated Title')
947
973
  expect(editedDoc?._id).toBe('live1')
948
974
 
949
- // Should use document.edit action with draftId prefixed (for server validation) but publishedId as the actual doc
950
- expect(result.outgoingActions[0]).toMatchObject({
951
- actionType: 'sanity.action.document.edit',
952
- draftId: 'drafts.live1',
953
- publishedId: 'live1',
975
+ expect(result.outgoingMutations[0]).toEqual({
976
+ patch: {
977
+ id: 'live1',
978
+ diffMatchPatch: {
979
+ title: '@@ -1,12 +1,11 @@\n-Original\n+Updated\n Tit\n',
980
+ },
981
+ },
954
982
  })
983
+ expect(result.outgoingActions).toHaveLength(0)
955
984
  })
956
985
 
957
986
  it('should throw an error if liveEdit document does not exist', () => {
@@ -998,12 +1027,9 @@ describe('processActions', () => {
998
1027
 
999
1028
  expect(result.working['live1']).toBeNull()
1000
1029
 
1001
- expect(result.outgoingActions).toEqual([
1002
- {
1003
- actionType: 'sanity.action.document.delete',
1004
- publishedId: 'live1',
1005
- },
1006
- ])
1030
+ expect(result.outgoingActions).toHaveLength(0)
1031
+ expect(result.outgoingMutations).toHaveLength(1)
1032
+ expect(result.outgoingMutations[0]).toEqual({delete: {id: 'live1'}})
1007
1033
  })
1008
1034
 
1009
1035
  it('should throw an error if liveEdit document does not exist', () => {
@@ -1040,10 +1066,7 @@ describe('processActions', () => {
1040
1066
 
1041
1067
  expect(() =>
1042
1068
  processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1043
- ).toThrow('Cannot publish liveEdit document')
1044
- expect(() =>
1045
- processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1046
- ).toThrow('LiveEdit documents do not support drafts or publishing')
1069
+ ).toThrow(/Publishing is not supported for liveEdit or version/)
1047
1070
  })
1048
1071
  })
1049
1072
 
@@ -1063,10 +1086,7 @@ describe('processActions', () => {
1063
1086
 
1064
1087
  expect(() =>
1065
1088
  processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1066
- ).toThrow('Cannot unpublish liveEdit document')
1067
- expect(() =>
1068
- processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1069
- ).toThrow('LiveEdit documents do not support drafts or publishing')
1089
+ ).toThrow(/Unpublishing is not supported for liveEdit or version/)
1070
1090
  })
1071
1091
  })
1072
1092
 
@@ -1086,11 +1106,318 @@ describe('processActions', () => {
1086
1106
 
1087
1107
  expect(() =>
1088
1108
  processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1089
- ).toThrow('Cannot discard changes for liveEdit document')
1109
+ ).toThrow('Cannot discard changes for liveEdit document "live1"')
1110
+
1090
1111
  expect(() =>
1091
1112
  processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1092
1113
  ).toThrow('LiveEdit documents do not support drafts')
1093
1114
  })
1094
1115
  })
1095
1116
  })
1117
+
1118
+ describe('release perspective (version) documents', () => {
1119
+ const releaseName = 'test-release'
1120
+ const perspective = {releaseName}
1121
+ const versionId = `versions.${releaseName}.doc1`
1122
+
1123
+ describe('document.create', () => {
1124
+ it('should create a version document for a release perspective', () => {
1125
+ const base: DocumentSet = {}
1126
+ const working: DocumentSet = {}
1127
+ const actions: DocumentAction[] = [
1128
+ {
1129
+ documentId: versionId,
1130
+ type: 'document.create',
1131
+ documentType: 'article',
1132
+ perspective,
1133
+ },
1134
+ ]
1135
+ const result = processActions({
1136
+ actions,
1137
+ transactionId,
1138
+ base,
1139
+ working,
1140
+ timestamp,
1141
+ grants: defaultGrants,
1142
+ })
1143
+
1144
+ const versionDoc = result.working[versionId]
1145
+ expect(versionDoc).toBeDefined()
1146
+ expect(versionDoc?._id).toBe(versionId)
1147
+ expect(versionDoc?._type).toBe('article')
1148
+ expect(versionDoc?._rev).toBe(transactionId)
1149
+
1150
+ expect(result.outgoingActions).toEqual([
1151
+ {
1152
+ actionType: 'sanity.action.document.version.create',
1153
+ publishedId: 'doc1',
1154
+ attributes: expect.objectContaining({_id: versionId, _type: 'article'}),
1155
+ },
1156
+ ])
1157
+ })
1158
+
1159
+ it('should create a version document using the published document as a base', () => {
1160
+ const published = createDoc('doc1', 'Published Title')
1161
+ const base: DocumentSet = {doc1: published}
1162
+ const working: DocumentSet = {doc1: published}
1163
+ const actions: DocumentAction[] = [
1164
+ {
1165
+ documentId: versionId,
1166
+ type: 'document.create',
1167
+ documentType: 'article',
1168
+ perspective,
1169
+ },
1170
+ ]
1171
+ const result = processActions({
1172
+ actions,
1173
+ transactionId,
1174
+ base,
1175
+ working,
1176
+ timestamp,
1177
+ grants: defaultGrants,
1178
+ })
1179
+
1180
+ const versionDoc = result.working[versionId]
1181
+ expect(versionDoc).toBeDefined()
1182
+ expect(versionDoc?._id).toBe(versionId)
1183
+ expect(versionDoc?.['title']).toBe('Published Title')
1184
+ })
1185
+
1186
+ it('should throw if a version document already exists', () => {
1187
+ const existingVersion = createDoc(versionId, 'Existing Version')
1188
+ const base: DocumentSet = {[versionId]: existingVersion}
1189
+ const working: DocumentSet = {[versionId]: existingVersion}
1190
+ const actions: DocumentAction[] = [
1191
+ {
1192
+ documentId: versionId,
1193
+ type: 'document.create',
1194
+ documentType: 'article',
1195
+ perspective,
1196
+ },
1197
+ ]
1198
+ expect(() =>
1199
+ processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1200
+ ).toThrow(/release version.*already exists/i)
1201
+ })
1202
+
1203
+ it('should create a version document with initial values', () => {
1204
+ const base: DocumentSet = {}
1205
+ const working: DocumentSet = {}
1206
+ const actions: DocumentAction[] = [
1207
+ {
1208
+ documentId: versionId,
1209
+ type: 'document.create',
1210
+ documentType: 'article',
1211
+ perspective,
1212
+ initialValue: {title: 'Release Version Title', count: 7},
1213
+ },
1214
+ ]
1215
+ const result = processActions({
1216
+ actions,
1217
+ transactionId,
1218
+ base,
1219
+ working,
1220
+ timestamp,
1221
+ grants: defaultGrants,
1222
+ })
1223
+
1224
+ const versionDoc = result.working[versionId]
1225
+ expect(versionDoc?.['title']).toBe('Release Version Title')
1226
+ expect(versionDoc?.['count']).toBe(7)
1227
+ })
1228
+
1229
+ it('should throw PermissionActionError if create permission is denied', () => {
1230
+ const base: DocumentSet = {}
1231
+ const working: DocumentSet = {}
1232
+ const actions: DocumentAction[] = [
1233
+ {
1234
+ documentId: versionId,
1235
+ type: 'document.create',
1236
+ documentType: 'article',
1237
+ perspective,
1238
+ },
1239
+ ]
1240
+ const grants = {...defaultGrants, create: alwaysDeny}
1241
+ expect(() =>
1242
+ processActions({actions, transactionId, base, working, timestamp, grants}),
1243
+ ).toThrow(/You do not have permission to create a release version/)
1244
+ })
1245
+ })
1246
+
1247
+ describe('document.edit', () => {
1248
+ it('should edit a version document directly', () => {
1249
+ const version = createDoc(versionId, 'Original Version Title')
1250
+ const base: DocumentSet = {[versionId]: version}
1251
+ const working: DocumentSet = {[versionId]: version}
1252
+ const actions: DocumentAction[] = [
1253
+ {
1254
+ documentId: versionId,
1255
+ type: 'document.edit',
1256
+ documentType: 'article',
1257
+ perspective,
1258
+ patches: [{set: {title: 'Updated Version Title'}}],
1259
+ },
1260
+ ]
1261
+ const result = processActions({
1262
+ actions,
1263
+ transactionId,
1264
+ base,
1265
+ working,
1266
+ timestamp,
1267
+ grants: defaultGrants,
1268
+ })
1269
+
1270
+ const editedDoc = result.working[versionId]
1271
+ expect(editedDoc?.['title']).toBe('Updated Version Title')
1272
+ expect(editedDoc?._id).toBe(versionId)
1273
+
1274
+ // outgoing action should use versionId as draftId and the base publishedId
1275
+ expect(result.outgoingActions[0]).toMatchObject({
1276
+ actionType: 'sanity.action.document.edit',
1277
+ draftId: versionId,
1278
+ publishedId: 'doc1',
1279
+ })
1280
+ })
1281
+
1282
+ it('should throw if the version document does not exist', () => {
1283
+ const base: DocumentSet = {}
1284
+ const working: DocumentSet = {}
1285
+ const actions: DocumentAction[] = [
1286
+ {
1287
+ documentId: versionId,
1288
+ type: 'document.edit',
1289
+ documentType: 'article',
1290
+ perspective,
1291
+ patches: [{set: {title: 'Should Fail'}}],
1292
+ },
1293
+ ]
1294
+ expect(() =>
1295
+ processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1296
+ ).toThrow(/does not exist in the release/)
1297
+ })
1298
+
1299
+ it('should throw PermissionActionError if update permission is denied', () => {
1300
+ const version = createDoc(versionId, 'Version Title')
1301
+ const base: DocumentSet = {[versionId]: version}
1302
+ const working: DocumentSet = {[versionId]: version}
1303
+ const actions: DocumentAction[] = [
1304
+ {
1305
+ documentId: versionId,
1306
+ type: 'document.edit',
1307
+ documentType: 'article',
1308
+ perspective,
1309
+ patches: [{set: {title: 'No Permission'}}],
1310
+ },
1311
+ ]
1312
+ const grants = {...defaultGrants, update: alwaysDeny}
1313
+ expect(() =>
1314
+ processActions({actions, transactionId, base, working, timestamp, grants}),
1315
+ ).toThrow(/You do not have permission to edit document/)
1316
+ })
1317
+ })
1318
+
1319
+ describe('document.discard', () => {
1320
+ it('should discard a version document', () => {
1321
+ const version = createDoc(versionId, 'Version Title')
1322
+ const base: DocumentSet = {[versionId]: version}
1323
+ const working: DocumentSet = {[versionId]: version}
1324
+ const actions: DocumentAction[] = [
1325
+ {
1326
+ documentId: versionId,
1327
+ type: 'document.discard',
1328
+ documentType: 'article',
1329
+ perspective,
1330
+ },
1331
+ ]
1332
+ const result = processActions({
1333
+ actions,
1334
+ transactionId,
1335
+ base,
1336
+ working,
1337
+ timestamp,
1338
+ grants: defaultGrants,
1339
+ })
1340
+
1341
+ expect(result.working[versionId]).toBeNull()
1342
+ expect(result.outgoingActions).toEqual([
1343
+ {
1344
+ actionType: 'sanity.action.document.version.discard',
1345
+ versionId,
1346
+ },
1347
+ ])
1348
+ })
1349
+
1350
+ it('should throw if there is no version document to discard', () => {
1351
+ const base: DocumentSet = {}
1352
+ const working: DocumentSet = {}
1353
+ const actions: DocumentAction[] = [
1354
+ {
1355
+ documentId: versionId,
1356
+ type: 'document.discard',
1357
+ documentType: 'article',
1358
+ perspective,
1359
+ },
1360
+ ]
1361
+ expect(() =>
1362
+ processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1363
+ ).toThrow(/no draft or version available to discard/)
1364
+ })
1365
+
1366
+ it('should throw PermissionActionError if update permission is denied', () => {
1367
+ const version = createDoc(versionId, 'Version Title')
1368
+ const base: DocumentSet = {[versionId]: version}
1369
+ const working: DocumentSet = {[versionId]: version}
1370
+ const actions: DocumentAction[] = [
1371
+ {
1372
+ documentId: versionId,
1373
+ type: 'document.discard',
1374
+ documentType: 'article',
1375
+ perspective,
1376
+ },
1377
+ ]
1378
+ const grants = {...defaultGrants, update: alwaysDeny}
1379
+ expect(() =>
1380
+ processActions({actions, transactionId, base, working, timestamp, grants}),
1381
+ ).toThrow(/You do not have permission to discard changes/)
1382
+ })
1383
+ })
1384
+
1385
+ describe('document.publish', () => {
1386
+ it('should throw for release perspective documents', () => {
1387
+ const version = createDoc(versionId, 'Version Title')
1388
+ const base: DocumentSet = {[versionId]: version}
1389
+ const working: DocumentSet = {[versionId]: version}
1390
+ const actions: DocumentAction[] = [
1391
+ {
1392
+ documentId: versionId,
1393
+ type: 'document.publish',
1394
+ documentType: 'article',
1395
+ perspective,
1396
+ },
1397
+ ]
1398
+ expect(() =>
1399
+ processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1400
+ ).toThrow(/Publishing is not supported for liveEdit or version/)
1401
+ })
1402
+ })
1403
+
1404
+ describe('document.delete', () => {
1405
+ it('should throw for release perspective documents', () => {
1406
+ const version = createDoc(versionId, 'Version Title')
1407
+ const base: DocumentSet = {[versionId]: version}
1408
+ const working: DocumentSet = {[versionId]: version}
1409
+ const actions: DocumentAction[] = [
1410
+ {
1411
+ documentId: versionId,
1412
+ type: 'document.delete',
1413
+ documentType: 'article',
1414
+ perspective,
1415
+ },
1416
+ ]
1417
+ expect(() =>
1418
+ processActions({actions, transactionId, base, working, timestamp, grants: defaultGrants}),
1419
+ ).toThrow(/Cannot delete a version document/)
1420
+ })
1421
+ })
1422
+ })
1096
1423
  })