@sanity/sdk 2.6.0 → 2.7.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 (39) hide show
  1. package/dist/index.d.ts +124 -13
  2. package/dist/index.js +468 -243
  3. package/dist/index.js.map +1 -1
  4. package/package.json +5 -4
  5. package/src/_exports/index.ts +3 -0
  6. package/src/auth/authMode.test.ts +56 -0
  7. package/src/auth/authMode.ts +71 -0
  8. package/src/auth/authStore.test.ts +85 -4
  9. package/src/auth/authStore.ts +63 -125
  10. package/src/auth/authStrategy.ts +39 -0
  11. package/src/auth/dashboardAuth.ts +132 -0
  12. package/src/auth/standaloneAuth.ts +109 -0
  13. package/src/auth/studioAuth.ts +217 -0
  14. package/src/auth/studioModeAuth.test.ts +43 -1
  15. package/src/auth/studioModeAuth.ts +10 -1
  16. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +21 -6
  17. package/src/config/sanityConfig.ts +48 -7
  18. package/src/projection/getProjectionState.ts +6 -5
  19. package/src/projection/projectionQuery.test.ts +38 -55
  20. package/src/projection/projectionQuery.ts +27 -31
  21. package/src/projection/projectionStore.test.ts +4 -4
  22. package/src/projection/projectionStore.ts +3 -2
  23. package/src/projection/resolveProjection.ts +2 -2
  24. package/src/projection/statusQuery.test.ts +35 -0
  25. package/src/projection/statusQuery.ts +71 -0
  26. package/src/projection/subscribeToStateAndFetchBatches.test.ts +63 -50
  27. package/src/projection/subscribeToStateAndFetchBatches.ts +106 -27
  28. package/src/projection/types.ts +12 -0
  29. package/src/projection/util.ts +0 -1
  30. package/src/query/queryStore.test.ts +64 -0
  31. package/src/query/queryStore.ts +30 -10
  32. package/src/releases/getPerspectiveState.test.ts +17 -14
  33. package/src/releases/getPerspectiveState.ts +58 -38
  34. package/src/releases/releasesStore.test.ts +59 -61
  35. package/src/releases/releasesStore.ts +21 -35
  36. package/src/releases/utils/isReleasePerspective.ts +7 -0
  37. package/src/store/createActionBinder.test.ts +211 -1
  38. package/src/store/createActionBinder.ts +95 -17
  39. package/src/store/createSanityInstance.ts +3 -1
@@ -1,8 +1,9 @@
1
+ import {DocumentId, getPublishedId} from '@sanity/id-utils'
1
2
  import {type SanityProjectionResult} from 'groq'
2
3
  import {omit} from 'lodash-es'
3
4
 
4
5
  import {type DocumentHandle} from '../config/sanityConfig'
5
- import {bindActionByDataset} from '../store/createActionBinder'
6
+ import {bindActionBySourceAndPerspective} from '../store/createActionBinder'
6
7
  import {type SanityInstance} from '../store/createSanityInstance'
7
8
  import {
8
9
  createStateSourceAction,
@@ -10,7 +11,7 @@ import {
10
11
  type StateSource,
11
12
  } from '../store/createStateSourceAction'
12
13
  import {hashString} from '../utils/hashString'
13
- import {getPublishedId, insecureRandomId} from '../utils/ids'
14
+ import {insecureRandomId} from '../utils/ids'
14
15
  import {projectionStore} from './projectionStore'
15
16
  import {type ProjectionStoreState, type ProjectionValuePending} from './types'
16
17
  import {PROJECTION_STATE_CLEAR_DELAY, STABLE_EMPTY_PROJECTION, validateProjection} from './util'
@@ -70,21 +71,21 @@ export function getProjectionState(
70
71
  /**
71
72
  * @beta
72
73
  */
73
- export const _getProjectionState = bindActionByDataset(
74
+ export const _getProjectionState = bindActionBySourceAndPerspective(
74
75
  projectionStore,
75
76
  createStateSourceAction({
76
77
  selector: (
77
78
  {state}: SelectorContext<ProjectionStoreState>,
78
79
  options: ProjectionOptions<string, string, string, string>,
79
80
  ): ProjectionValuePending<object> | undefined => {
80
- const documentId = getPublishedId(options.documentId)
81
+ const documentId = getPublishedId(DocumentId(options.documentId))
81
82
  const projectionHash = hashString(options.projection)
82
83
  return state.values[documentId]?.[projectionHash] ?? STABLE_EMPTY_PROJECTION
83
84
  },
84
85
  onSubscribe: ({state}, options: ProjectionOptions<string, string, string, string>) => {
85
86
  const {projection, ...docHandle} = options
86
87
  const subscriptionId = insecureRandomId()
87
- const documentId = getPublishedId(docHandle.documentId)
88
+ const documentId = getPublishedId(DocumentId(docHandle.documentId))
88
89
  const validProjection = validateProjection(projection)
89
90
  const projectionHash = hashString(validProjection)
90
91
 
@@ -1,10 +1,11 @@
1
+ import {DocumentId} from '@sanity/id-utils'
1
2
  import {describe, expect, it} from 'vitest'
2
3
 
3
4
  import {createProjectionQuery, processProjectionQuery} from './projectionQuery'
4
5
 
5
6
  describe('createProjectionQuery', () => {
6
7
  it('creates a query and params for given ids and projections', () => {
7
- const ids = new Set(['doc1', 'doc2'])
8
+ const ids = new Set(['doc1', 'doc2'].map(DocumentId))
8
9
  const projectionHash = '{title, description}'
9
10
  const documentProjections = {
10
11
  doc1: {[projectionHash]: projectionHash},
@@ -15,11 +16,11 @@ describe('createProjectionQuery', () => {
15
16
  expect(query).toMatch(/.*_id in \$__ids_.*/)
16
17
  expect(Object.keys(params)).toHaveLength(1)
17
18
  expect(params[`__ids_${projectionHash}`]).toBeDefined()
18
- expect(params[`__ids_${projectionHash}`]).toHaveLength(4)
19
+ expect(params[`__ids_${projectionHash}`]).toHaveLength(2)
19
20
  })
20
21
 
21
22
  it('handles multiple different projections', () => {
22
- const ids = new Set(['doc1', 'doc2'])
23
+ const ids = new Set(['doc1', 'doc2'].map(DocumentId))
23
24
  const projectionHash1 = '{title, description}'
24
25
  const projectionHash2 = '{name, age}'
25
26
  const documentProjections = {
@@ -31,13 +32,13 @@ describe('createProjectionQuery', () => {
31
32
  expect(query).toMatch(/.*_id in \$__ids_.*/)
32
33
  expect(Object.keys(params)).toHaveLength(2)
33
34
  expect(params[`__ids_${projectionHash1}`]).toBeDefined()
34
- expect(params[`__ids_${projectionHash1}`]).toHaveLength(2)
35
+ expect(params[`__ids_${projectionHash1}`]).toHaveLength(1)
35
36
  expect(params[`__ids_${projectionHash2}`]).toBeDefined()
36
- expect(params[`__ids_${projectionHash2}`]).toHaveLength(2)
37
+ expect(params[`__ids_${projectionHash2}`]).toHaveLength(1)
37
38
  })
38
39
 
39
40
  it('filters out ids without projections', () => {
40
- const ids = new Set(['doc1', 'doc2', 'doc3'])
41
+ const ids = new Set(['doc1', 'doc2', 'doc3'].map(DocumentId))
41
42
  const projectionHash1 = '{title}'
42
43
  // projectionHash2 missing intentionally
43
44
  const projectionHash3 = '{name}'
@@ -51,9 +52,9 @@ describe('createProjectionQuery', () => {
51
52
  expect(query).toMatch(/.*_id in \$__ids_.*/)
52
53
  expect(Object.keys(params)).toHaveLength(2)
53
54
  expect(params[`__ids_${projectionHash1}`]).toBeDefined()
54
- expect(params[`__ids_${projectionHash1}`]).toHaveLength(2)
55
+ expect(params[`__ids_${projectionHash1}`]).toHaveLength(1)
55
56
  expect(params[`__ids_${projectionHash3}`]).toBeDefined()
56
- expect(params[`__ids_${projectionHash3}`]).toHaveLength(2)
57
+ expect(params[`__ids_${projectionHash3}`]).toHaveLength(1)
57
58
  })
58
59
  })
59
60
 
@@ -63,10 +64,9 @@ describe('processProjectionQuery', () => {
63
64
  it('returns structure with empty object if no results found', () => {
64
65
  const ids = new Set(['doc1'])
65
66
  const result = processProjectionQuery({
66
- projectId: 'p',
67
- dataset: 'd',
68
67
  ids,
69
68
  results: [], // no results
69
+ perspective: 'published',
70
70
  })
71
71
 
72
72
  expect(result['doc1']).toEqual({})
@@ -85,10 +85,14 @@ describe('processProjectionQuery', () => {
85
85
  ]
86
86
 
87
87
  const processed = processProjectionQuery({
88
- projectId: 'p',
89
- dataset: 'd',
90
88
  ids,
91
89
  results,
90
+ perspective: 'published',
91
+ documentStatuses: {
92
+ doc1: {
93
+ lastEditedPublishedAt: '2021-01-01',
94
+ },
95
+ },
92
96
  })
93
97
 
94
98
  expect(processed['doc1']?.[testProjectionHash]).toEqual({
@@ -116,10 +120,14 @@ describe('processProjectionQuery', () => {
116
120
  ]
117
121
 
118
122
  const processed = processProjectionQuery({
119
- projectId: 'p',
120
- dataset: 'd',
121
123
  ids: new Set(['doc1']),
122
124
  results,
125
+ perspective: 'published',
126
+ documentStatuses: {
127
+ doc1: {
128
+ lastEditedPublishedAt: '2021-01-01',
129
+ },
130
+ },
123
131
  })
124
132
 
125
133
  expect(processed['doc1']?.[testProjectionHash]).toEqual({
@@ -134,66 +142,37 @@ describe('processProjectionQuery', () => {
134
142
  })
135
143
  })
136
144
 
137
- it('handles both draft and published documents', () => {
145
+ it('handles release perspective with all three status fields', () => {
138
146
  const results = [
139
- {
140
- _id: 'drafts.doc1',
141
- _type: 'document',
142
- _updatedAt: '2021-01-02',
143
- result: {title: 'Draft'},
144
- __projectionHash: testProjectionHash,
145
- },
146
147
  {
147
148
  _id: 'doc1',
148
149
  _type: 'document',
149
- _updatedAt: '2021-01-01',
150
- result: {title: 'Published'},
150
+ _updatedAt: '2021-01-03',
151
+ result: {title: 'Version'},
151
152
  __projectionHash: testProjectionHash,
152
153
  },
153
154
  ]
154
155
 
155
156
  const processed = processProjectionQuery({
156
- projectId: 'p',
157
- dataset: 'd',
158
157
  ids: new Set(['doc1']),
159
158
  results,
160
- })
161
-
162
- expect(processed['doc1']?.[testProjectionHash]).toEqual({
163
- data: {
164
- title: 'Draft',
165
- _status: {
159
+ perspective: {releaseName: 'release1'},
160
+ documentStatuses: {
161
+ doc1: {
166
162
  lastEditedDraftAt: '2021-01-02',
167
163
  lastEditedPublishedAt: '2021-01-01',
164
+ lastEditedVersionAt: '2021-01-03',
168
165
  },
169
166
  },
170
- isPending: false,
171
- })
172
- })
173
-
174
- it('uses published result when no draft exists', () => {
175
- const results = [
176
- {
177
- _id: 'doc1',
178
- _type: 'document',
179
- _updatedAt: '2021-01-01',
180
- result: {title: 'Published'},
181
- __projectionHash: testProjectionHash,
182
- },
183
- ]
184
-
185
- const processed = processProjectionQuery({
186
- projectId: 'p',
187
- dataset: 'd',
188
- ids: new Set(['doc1']),
189
- results,
190
167
  })
191
168
 
192
169
  expect(processed['doc1']?.[testProjectionHash]).toEqual({
193
170
  data: {
194
- title: 'Published',
171
+ title: 'Version',
195
172
  _status: {
173
+ lastEditedDraftAt: '2021-01-02',
196
174
  lastEditedPublishedAt: '2021-01-01',
175
+ lastEditedVersionAt: '2021-01-03',
197
176
  },
198
177
  },
199
178
  isPending: false,
@@ -221,10 +200,14 @@ describe('processProjectionQuery', () => {
221
200
  ]
222
201
 
223
202
  const processed = processProjectionQuery({
224
- projectId: 'p',
225
- dataset: 'd',
226
203
  ids: new Set(['doc1']),
227
204
  results,
205
+ perspective: 'published',
206
+ documentStatuses: {
207
+ doc1: {
208
+ lastEditedPublishedAt: '2021-01-01',
209
+ },
210
+ },
228
211
  })
229
212
 
230
213
  expect(processed['doc1']?.[hash1]).toEqual({
@@ -1,5 +1,13 @@
1
- import {getDraftId, getPublishedId} from '../utils/ids'
2
- import {type DocumentProjections, type DocumentProjectionValues} from './types'
1
+ import {type ClientPerspective} from '@sanity/client'
2
+ import {DocumentId} from '@sanity/id-utils'
3
+
4
+ import {type ReleasePerspective} from '../config/sanityConfig'
5
+ import {getPublishedId} from '../utils/ids'
6
+ import {
7
+ type DocumentProjections,
8
+ type DocumentProjectionValues,
9
+ type ProjectionStoreState,
10
+ } from './types'
3
11
  import {validateProjection} from './util'
4
12
 
5
13
  export type ProjectionQueryResult = {
@@ -18,8 +26,8 @@ interface CreateProjectionQueryResult {
18
26
  type ProjectionMap = Record<string, {projection: string; documentIds: Set<string>}>
19
27
 
20
28
  export function createProjectionQuery(
21
- documentIds: Set<string>,
22
- documentProjections: {[TDocumentId in string]?: DocumentProjections},
29
+ documentIds: Set<DocumentId>,
30
+ documentProjections: {[TDocumentId in DocumentId]?: DocumentProjections},
23
31
  ): CreateProjectionQueryResult {
24
32
  const projections = Array.from(documentIds)
25
33
  .flatMap((id) => {
@@ -48,11 +56,7 @@ export function createProjectionQuery(
48
56
 
49
57
  const params = Object.fromEntries(
50
58
  Object.entries(projections).map(([projectionHash, value]) => {
51
- const idsInProjection = Array.from(value.documentIds).flatMap((id) => [
52
- getPublishedId(id),
53
- getDraftId(id),
54
- ])
55
-
59
+ const idsInProjection = Array.from(value.documentIds).flatMap((id) => DocumentId(id))
56
60
  return [`__ids_${projectionHash}`, Array.from(idsInProjection)]
57
61
  }),
58
62
  )
@@ -61,28 +65,28 @@ export function createProjectionQuery(
61
65
  }
62
66
 
63
67
  interface ProcessProjectionQueryOptions {
64
- projectId: string
65
- dataset: string
66
68
  ids: Set<string>
67
69
  results: ProjectionQueryResult[]
70
+ documentStatuses?: ProjectionStoreState['documentStatuses']
71
+ perspective: ClientPerspective | ReleasePerspective
68
72
  }
69
73
 
70
- export function processProjectionQuery({ids, results}: ProcessProjectionQueryOptions): {
74
+ export function processProjectionQuery({
75
+ ids,
76
+ results,
77
+ documentStatuses,
78
+ }: ProcessProjectionQueryOptions): {
71
79
  [TDocumentId in string]?: DocumentProjectionValues<Record<string, unknown>>
72
80
  } {
73
81
  const groupedResults: {
74
82
  [docId: string]: {
75
- [hash: string]: {
76
- draft?: ProjectionQueryResult
77
- published?: ProjectionQueryResult
78
- }
83
+ [hash: string]: ProjectionQueryResult | undefined
79
84
  }
80
85
  } = {}
81
86
 
82
87
  for (const result of results) {
83
88
  const originalId = getPublishedId(result._id)
84
89
  const hash = result.__projectionHash
85
- const isDraft = result._id.startsWith('drafts.')
86
90
 
87
91
  if (!ids.has(originalId)) continue
88
92
 
@@ -90,14 +94,10 @@ export function processProjectionQuery({ids, results}: ProcessProjectionQueryOpt
90
94
  groupedResults[originalId] = {}
91
95
  }
92
96
  if (!groupedResults[originalId][hash]) {
93
- groupedResults[originalId][hash] = {}
97
+ groupedResults[originalId][hash] = undefined
94
98
  }
95
99
 
96
- if (isDraft) {
97
- groupedResults[originalId][hash].draft = result
98
- } else {
99
- groupedResults[originalId][hash].published = result
100
- }
100
+ groupedResults[originalId][hash] = result
101
101
  }
102
102
 
103
103
  const finalValues: {
@@ -111,22 +111,18 @@ export function processProjectionQuery({ids, results}: ProcessProjectionQueryOpt
111
111
  if (!projectionsForDoc) continue
112
112
 
113
113
  for (const hash in projectionsForDoc) {
114
- const {draft, published} = projectionsForDoc[hash]
115
-
116
- const projectionResultData = draft?.result ?? published?.result
114
+ const projectionResult = projectionsForDoc[hash]
115
+ const projectionResultData = projectionResult?.result
117
116
 
118
117
  if (!projectionResultData) {
119
118
  finalValues[originalId][hash] = {data: null, isPending: false}
120
119
  continue
121
120
  }
122
121
 
123
- const _status = {
124
- ...(draft?._updatedAt && {lastEditedDraftAt: draft._updatedAt}),
125
- ...(published?._updatedAt && {lastEditedPublishedAt: published._updatedAt}),
126
- }
122
+ const statusFromStore = documentStatuses?.[originalId]
127
123
 
128
124
  finalValues[originalId][hash] = {
129
- data: {...projectionResultData, _status},
125
+ data: {...projectionResultData, _status: statusFromStore},
130
126
  isPending: false,
131
127
  }
132
128
  }
@@ -30,8 +30,8 @@ describe('projectionStore', () => {
30
30
  instance,
31
31
  {
32
32
  name: 'p.d',
33
- projectId: 'p',
34
- dataset: 'd',
33
+ source: {projectId: 'p', dataset: 'd'},
34
+ perspective: 'drafts',
35
35
  },
36
36
  projectionStore,
37
37
  )
@@ -42,8 +42,8 @@ describe('projectionStore', () => {
42
42
  state,
43
43
  key: {
44
44
  name: 'p.d',
45
- projectId: 'p',
46
- dataset: 'd',
45
+ source: {projectId: 'p', dataset: 'd'},
46
+ perspective: 'drafts',
47
47
  },
48
48
  })
49
49
 
@@ -1,15 +1,16 @@
1
- import {type BoundDatasetKey} from '../store/createActionBinder'
1
+ import {type BoundPerspectiveKey} from '../store/createActionBinder'
2
2
  import {defineStore} from '../store/defineStore'
3
3
  import {subscribeToStateAndFetchBatches} from './subscribeToStateAndFetchBatches'
4
4
  import {type ProjectionStoreState} from './types'
5
5
 
6
- export const projectionStore = defineStore<ProjectionStoreState, BoundDatasetKey>({
6
+ export const projectionStore = defineStore<ProjectionStoreState, BoundPerspectiveKey>({
7
7
  name: 'Projection',
8
8
  getInitialState() {
9
9
  return {
10
10
  values: {},
11
11
  documentProjections: {},
12
12
  subscriptions: {},
13
+ documentStatuses: {},
13
14
  }
14
15
  },
15
16
  initialize(context) {
@@ -1,7 +1,7 @@
1
1
  import {type SanityProjectionResult} from 'groq'
2
2
  import {filter, firstValueFrom} from 'rxjs'
3
3
 
4
- import {bindActionByDataset} from '../store/createActionBinder'
4
+ import {bindActionBySourceAndPerspective} from '../store/createActionBinder'
5
5
  import {type SanityInstance} from '../store/createSanityInstance'
6
6
  import {getProjectionState, type ProjectionOptions} from './getProjectionState'
7
7
  import {projectionStore} from './projectionStore'
@@ -38,7 +38,7 @@ export function resolveProjection(
38
38
  /**
39
39
  * @beta
40
40
  */
41
- const _resolveProjection = bindActionByDataset(
41
+ const _resolveProjection = bindActionBySourceAndPerspective(
42
42
  projectionStore,
43
43
  (
44
44
  {instance}: {instance: SanityInstance},
@@ -0,0 +1,35 @@
1
+ import {DocumentId, getVersionId} from '@sanity/id-utils'
2
+ import {describe, expect, it} from 'vitest'
3
+
4
+ import {buildStatusQueryIds, processStatusQueryResults} from './statusQuery'
5
+
6
+ describe('buildStatusQueryIds', () => {
7
+ it('includes draft and published ids only when perspective is not a release', () => {
8
+ const ids = new Set(['doc1'].map(DocumentId))
9
+ const result = buildStatusQueryIds(ids, 'published')
10
+ expect(result).toContain('drafts.doc1')
11
+ expect(result).toContain('doc1')
12
+ expect(result).toHaveLength(2)
13
+ })
14
+
15
+ it('includes version ids when perspective is a release', () => {
16
+ const ids = new Set(['doc1'].map(DocumentId))
17
+ const perspective = {releaseName: 'myRelease'}
18
+ const result = buildStatusQueryIds(ids, perspective)
19
+ expect(result).toContain('drafts.doc1')
20
+ expect(result).toContain('doc1')
21
+ expect(result).toContain(getVersionId(DocumentId('doc1'), 'myRelease'))
22
+ expect(result).toHaveLength(3)
23
+ })
24
+ })
25
+
26
+ describe('processStatusQueryResults', () => {
27
+ it('sets lastEditedVersionAt when result _id is a version id', () => {
28
+ const versionId = getVersionId(DocumentId('doc1'), 'myRelease')
29
+ const results = [{_id: versionId, _updatedAt: '2025-01-01T12:00:00Z'}]
30
+ const documentStatuses = processStatusQueryResults(results)
31
+ expect(documentStatuses['doc1']).toEqual({
32
+ lastEditedVersionAt: '2025-01-01T12:00:00Z',
33
+ })
34
+ })
35
+ })
@@ -0,0 +1,71 @@
1
+ import {
2
+ DocumentId,
3
+ getDraftId,
4
+ getPublishedId,
5
+ getVersionId,
6
+ isDraftId,
7
+ isPublishedId,
8
+ isVersionId,
9
+ } from '@sanity/id-utils'
10
+
11
+ import {isReleasePerspective} from '../releases/utils/isReleasePerspective'
12
+ import {type BoundPerspectiveKey} from '../store/createActionBinder'
13
+ import {type ProjectionStoreState} from './types'
14
+
15
+ interface StatusQueryResult {
16
+ _id: string
17
+ _updatedAt: string
18
+ }
19
+
20
+ /**
21
+ * Builds an array of document IDs to query for status information using the "raw" perspective.
22
+ * Includes draft, published, and version IDs as needed.
23
+ */
24
+ export function buildStatusQueryIds(
25
+ documentIds: Set<string>,
26
+ perspective: BoundPerspectiveKey['perspective'],
27
+ ): string[] {
28
+ const ids: string[] = []
29
+ const releaseName = isReleasePerspective(perspective) ? perspective.releaseName : null
30
+
31
+ for (const id of documentIds) {
32
+ const publishedId = getPublishedId(DocumentId(id))
33
+ const draftId = getDraftId(publishedId)
34
+
35
+ // Always query for draft and published versions
36
+ ids.push(draftId, publishedId)
37
+
38
+ // If it's a release perspective, also query for the version
39
+ if (releaseName) {
40
+ ids.push(getVersionId(publishedId, releaseName))
41
+ }
42
+ }
43
+
44
+ return ids
45
+ }
46
+
47
+ /**
48
+ * Processes status query results into documentStatuses (same shape as _status returned to users).
49
+ */
50
+ export function processStatusQueryResults(
51
+ results: StatusQueryResult[],
52
+ ): ProjectionStoreState['documentStatuses'] {
53
+ const documentStatuses: ProjectionStoreState['documentStatuses'] = {}
54
+
55
+ for (const result of results) {
56
+ const id = DocumentId(result._id)
57
+ const updatedAt = result._updatedAt
58
+ const publishedId = getPublishedId(id)
59
+ const statusData = documentStatuses[publishedId] ?? {}
60
+ if (isDraftId(id)) {
61
+ statusData.lastEditedDraftAt = updatedAt
62
+ } else if (isVersionId(id)) {
63
+ statusData.lastEditedVersionAt = updatedAt
64
+ } else if (isPublishedId(id)) {
65
+ statusData.lastEditedPublishedAt = updatedAt
66
+ }
67
+ documentStatuses[publishedId] = statusData
68
+ }
69
+
70
+ return documentStatuses
71
+ }