sanity-plugin-media 4.3.5 → 5.0.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 (166) hide show
  1. package/dist/index.d.ts +190 -413
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +2532 -3564
  4. package/dist/index.js.map +1 -1
  5. package/package.json +29 -35
  6. package/dist/index.cjs +0 -5753
  7. package/dist/index.cjs.map +0 -1
  8. package/dist/index.d.cts +0 -462
  9. package/sanity.json +0 -8
  10. package/src/__tests__/fixtures/createEpicTestStore.ts +0 -28
  11. package/src/__tests__/fixtures/listenMock.ts +0 -9
  12. package/src/__tests__/fixtures/mockSanityClient.ts +0 -84
  13. package/src/__tests__/fixtures/renderWithProviders.tsx +0 -55
  14. package/src/__tests__/fixtures/rootState.ts +0 -27
  15. package/src/__tests__/fixtures/withinDialog.ts +0 -28
  16. package/src/components/AssetGridVirtualized/index.tsx +0 -94
  17. package/src/components/AssetMetadata/index.tsx +0 -122
  18. package/src/components/AssetTableVirtualized/index.tsx +0 -73
  19. package/src/components/AutoTagInputWrapper/index.tsx +0 -87
  20. package/src/components/Browser/Browser.test.tsx +0 -45
  21. package/src/components/Browser/index.tsx +0 -90
  22. package/src/components/Browser/useBrowserInit.ts +0 -126
  23. package/src/components/ButtonAssetCopy/index.tsx +0 -65
  24. package/src/components/ButtonViewGroup/index.tsx +0 -39
  25. package/src/components/CardAsset/CardAsset.test.tsx +0 -323
  26. package/src/components/CardAsset/index.tsx +0 -290
  27. package/src/components/CardUpload/index.tsx +0 -161
  28. package/src/components/Controls/index.tsx +0 -136
  29. package/src/components/DebugControls/index.tsx +0 -80
  30. package/src/components/Dialog/index.tsx +0 -11
  31. package/src/components/DialogAssetEdit/Details.tsx +0 -181
  32. package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +0 -216
  33. package/src/components/DialogAssetEdit/index.tsx +0 -492
  34. package/src/components/DialogConfirm/index.tsx +0 -88
  35. package/src/components/DialogSearchFacets/index.tsx +0 -42
  36. package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +0 -121
  37. package/src/components/DialogTagCreate/index.tsx +0 -103
  38. package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +0 -165
  39. package/src/components/DialogTagEdit/index.tsx +0 -190
  40. package/src/components/DialogTags/index.tsx +0 -45
  41. package/src/components/Dialogs/index.tsx +0 -76
  42. package/src/components/DocumentList/index.tsx +0 -62
  43. package/src/components/FileAssetPreview/index.tsx +0 -37
  44. package/src/components/FileIcon/index.tsx +0 -43
  45. package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +0 -63
  46. package/src/components/FormBuilderTool/index.tsx +0 -69
  47. package/src/components/FormFieldInputLabel/index.tsx +0 -66
  48. package/src/components/FormFieldInputTags/index.tsx +0 -98
  49. package/src/components/FormFieldInputText/index.tsx +0 -41
  50. package/src/components/FormFieldInputTextarea/index.tsx +0 -43
  51. package/src/components/FormSubmitButton/index.tsx +0 -59
  52. package/src/components/Header/index.tsx +0 -80
  53. package/src/components/Image/index.tsx +0 -41
  54. package/src/components/Items/index.tsx +0 -68
  55. package/src/components/Notifications/index.tsx +0 -24
  56. package/src/components/OrderSelect/index.tsx +0 -66
  57. package/src/components/PickedBar/index.tsx +0 -77
  58. package/src/components/Progress/index.tsx +0 -38
  59. package/src/components/ReduxProvider/index.tsx +0 -96
  60. package/src/components/SearchFacet/index.tsx +0 -66
  61. package/src/components/SearchFacetNumber/index.tsx +0 -133
  62. package/src/components/SearchFacetSelect/index.tsx +0 -110
  63. package/src/components/SearchFacetString/index.tsx +0 -88
  64. package/src/components/SearchFacetTags/index.tsx +0 -121
  65. package/src/components/SearchFacets/index.tsx +0 -72
  66. package/src/components/SearchFacetsControl/index.tsx +0 -140
  67. package/src/components/TableHeader/index.tsx +0 -110
  68. package/src/components/TableHeaderItem/index.tsx +0 -61
  69. package/src/components/TableRowAsset/index.tsx +0 -420
  70. package/src/components/TableRowUpload/index.tsx +0 -164
  71. package/src/components/Tag/index.tsx +0 -200
  72. package/src/components/TagIcon/index.tsx +0 -22
  73. package/src/components/TagView/index.tsx +0 -39
  74. package/src/components/TagViewHeader/index.tsx +0 -70
  75. package/src/components/TagsPanel/index.tsx +0 -40
  76. package/src/components/TagsVirtualized/index.tsx +0 -160
  77. package/src/components/TextInputNumber/index.tsx +0 -32
  78. package/src/components/TextInputSearch/index.tsx +0 -60
  79. package/src/components/Tool/index.tsx +0 -13
  80. package/src/components/UploadDropzone/UploadDropzone.test.tsx +0 -40
  81. package/src/components/UploadDropzone/index.tsx +0 -173
  82. package/src/config/orders.ts +0 -28
  83. package/src/config/searchFacets.ts +0 -312
  84. package/src/constants.ts +0 -87
  85. package/src/contexts/AssetSourceDispatchContext.tsx +0 -37
  86. package/src/contexts/DropzoneDispatchContext.tsx +0 -34
  87. package/src/contexts/ToolOptionsContext.tsx +0 -65
  88. package/src/formSchema/index.test.ts +0 -56
  89. package/src/formSchema/index.ts +0 -39
  90. package/src/hooks/useBreakpointIndex.ts +0 -49
  91. package/src/hooks/useKeyPress.ts +0 -39
  92. package/src/hooks/useOnScreen.ts +0 -34
  93. package/src/hooks/usePortalPopoverProps.ts +0 -13
  94. package/src/hooks/useTypedSelector.ts +0 -7
  95. package/src/hooks/useVersionedClient.ts +0 -6
  96. package/src/index.ts +0 -5
  97. package/src/modules/assets/actions.ts +0 -42
  98. package/src/modules/assets/deleteAndUpdateEpics.test.ts +0 -87
  99. package/src/modules/assets/fetchEpic.test.ts +0 -73
  100. package/src/modules/assets/index.ts +0 -825
  101. package/src/modules/assets/reducer.test.ts +0 -91
  102. package/src/modules/assets/tagsAndListenerEpics.test.ts +0 -206
  103. package/src/modules/debug/index.ts +0 -28
  104. package/src/modules/dialog/actions.ts +0 -10
  105. package/src/modules/dialog/epics.test.ts +0 -168
  106. package/src/modules/dialog/index.ts +0 -238
  107. package/src/modules/dialog/reducer.test.ts +0 -185
  108. package/src/modules/index.ts +0 -124
  109. package/src/modules/notifications/epics.test.ts +0 -374
  110. package/src/modules/notifications/index.ts +0 -199
  111. package/src/modules/notifications/reducer.test.ts +0 -54
  112. package/src/modules/search/index.test.ts +0 -36
  113. package/src/modules/search/index.ts +0 -167
  114. package/src/modules/selected/index.ts +0 -22
  115. package/src/modules/selectors.test.ts +0 -21
  116. package/src/modules/selectors.ts +0 -17
  117. package/src/modules/tags/epics.test.ts +0 -96
  118. package/src/modules/tags/index.test.ts +0 -42
  119. package/src/modules/tags/index.ts +0 -540
  120. package/src/modules/types.ts +0 -3
  121. package/src/modules/uploads/actions.ts +0 -13
  122. package/src/modules/uploads/epics.test.ts +0 -109
  123. package/src/modules/uploads/index.test.ts +0 -59
  124. package/src/modules/uploads/index.ts +0 -282
  125. package/src/operators/checkTagName.test.ts +0 -29
  126. package/src/operators/checkTagName.ts +0 -33
  127. package/src/operators/debugThrottle.ts +0 -25
  128. package/src/plugin.tsx +0 -54
  129. package/src/schemas/tag.ts +0 -28
  130. package/src/styled/GlobalStyles/index.tsx +0 -40
  131. package/src/styled/react-select/creatable.tsx +0 -184
  132. package/src/styled/react-select/single.tsx +0 -184
  133. package/src/types/index.ts +0 -379
  134. package/src/types/sanity-ui.d.ts +0 -6
  135. package/src/utils/applyMediaTags.ts +0 -87
  136. package/src/utils/blocksToText.test.ts +0 -43
  137. package/src/utils/blocksToText.ts +0 -27
  138. package/src/utils/constructFilter.test.ts +0 -120
  139. package/src/utils/constructFilter.ts +0 -98
  140. package/src/utils/generatePreviewBlobUrl.test.ts +0 -70
  141. package/src/utils/generatePreviewBlobUrl.ts +0 -53
  142. package/src/utils/getAssetResolution.test.ts +0 -13
  143. package/src/utils/getAssetResolution.ts +0 -7
  144. package/src/utils/getDocumentAssetIds.test.ts +0 -50
  145. package/src/utils/getDocumentAssetIds.ts +0 -35
  146. package/src/utils/getSchemeColor.test.ts +0 -12
  147. package/src/utils/getSchemeColor.ts +0 -43
  148. package/src/utils/getTagSelectOptions.test.ts +0 -44
  149. package/src/utils/getTagSelectOptions.ts +0 -16
  150. package/src/utils/getUniqueDocuments.test.ts +0 -26
  151. package/src/utils/getUniqueDocuments.ts +0 -15
  152. package/src/utils/imageDprUrl.test.ts +0 -46
  153. package/src/utils/imageDprUrl.ts +0 -27
  154. package/src/utils/isSupportedAssetType.test.ts +0 -16
  155. package/src/utils/isSupportedAssetType.ts +0 -15
  156. package/src/utils/mediaField.ts +0 -73
  157. package/src/utils/sanitizeFormData.test.ts +0 -59
  158. package/src/utils/sanitizeFormData.ts +0 -26
  159. package/src/utils/typeGuards.test.ts +0 -18
  160. package/src/utils/typeGuards.ts +0 -9
  161. package/src/utils/uploadSanityAsset.test.ts +0 -29
  162. package/src/utils/uploadSanityAsset.ts +0 -97
  163. package/src/utils/withMaxConcurrency.test.ts +0 -43
  164. package/src/utils/withMaxConcurrency.ts +0 -55
  165. package/src/utils/zodFormResolver.ts +0 -17
  166. package/v2-incompatible.js +0 -11
@@ -1,59 +0,0 @@
1
- // @vitest-environment node
2
-
3
- import {describe, expect, it} from 'vitest'
4
-
5
- import type {UploadItem} from '../../types'
6
- import uploadsReducer, {uploadsActions} from './index'
7
-
8
- describe('uploads slice', () => {
9
- it('uploadStart adds item to queue', () => {
10
- let state = uploadsReducer(undefined, {type: '@@INIT'} as never)
11
- const uploadItem = {
12
- _type: 'upload',
13
- assetType: 'image',
14
- hash: 'abc',
15
- name: 'x.png',
16
- size: 1,
17
- status: 'queued',
18
- } as UploadItem
19
-
20
- state = uploadsReducer(
21
- state,
22
- uploadsActions.uploadStart({
23
- file: new File([], 'x.png'),
24
- uploadItem,
25
- }),
26
- )
27
-
28
- expect(state.allIds).toEqual(['abc'])
29
- expect(state.byIds.abc).toMatchObject({hash: 'abc', status: 'queued'})
30
- })
31
-
32
- it('uploadProgress updates percent and status', () => {
33
- let state = uploadsReducer(undefined, {type: '@@INIT'} as never)
34
- const uploadItem = {
35
- _type: 'upload',
36
- assetType: 'image',
37
- hash: 'h1',
38
- name: 'x.png',
39
- size: 1,
40
- status: 'queued',
41
- percent: 0,
42
- } as UploadItem
43
-
44
- state = uploadsReducer(
45
- state,
46
- uploadsActions.uploadStart({file: new File([], 'x.png'), uploadItem}),
47
- )
48
- state = uploadsReducer(
49
- state,
50
- uploadsActions.uploadProgress({
51
- uploadHash: 'h1',
52
- event: {percent: 42, stage: 'upload'} as any,
53
- }),
54
- )
55
-
56
- expect(state.byIds.h1.percent).toBe(42)
57
- expect(state.byIds.h1.status).toBe('uploading')
58
- })
59
- })
@@ -1,282 +0,0 @@
1
- import {createSelector, createSlice, type PayloadAction} from '@reduxjs/toolkit'
2
- import type {ClientError, SanityAssetDocument, SanityImageAssetDocument} from '@sanity/client'
3
- import groq from 'groq'
4
- import type {Selector} from 'react-redux'
5
- import {empty, merge, of} from 'rxjs'
6
- import {catchError, delay, filter, mergeMap, takeUntil, withLatestFrom} from 'rxjs/operators'
7
-
8
- import type {HttpError, MyEpic, SanityUploadProgressEvent, UploadItem} from '../../types'
9
- import constructFilter from '../../utils/constructFilter'
10
- import {generatePreviewBlobUrl$} from '../../utils/generatePreviewBlobUrl'
11
- import {hashFile$, uploadAsset$} from '../../utils/uploadSanityAsset'
12
- import {assetsActions} from '../assets'
13
- import type {RootReducerState} from '../types'
14
- import {UPLOADS_ACTIONS} from './actions'
15
-
16
- export type UploadsReducerState = {
17
- allIds: string[]
18
- byIds: Record<string, UploadItem>
19
- }
20
-
21
- const initialState = {
22
- allIds: [],
23
- byIds: {},
24
- } as UploadsReducerState
25
-
26
- const uploadsSlice = createSlice({
27
- name: 'uploads',
28
- initialState,
29
- extraReducers: (builder) => {
30
- builder //
31
- .addCase(UPLOADS_ACTIONS.uploadComplete, (state, action) => {
32
- const {asset} = action.payload
33
- if (state.byIds[asset.sha1hash]) {
34
- state.byIds[asset.sha1hash].status = 'complete'
35
- }
36
- })
37
- },
38
- reducers: {
39
- checkRequest(
40
- _state,
41
- _action: PayloadAction<{assets: (SanityAssetDocument | SanityImageAssetDocument)[]}>,
42
- ) {
43
- //
44
- },
45
- checkComplete(state, action: PayloadAction<{results: Record<string, string | null>}>) {
46
- const {results} = action.payload
47
-
48
- const assetHashes = Object.keys(results)
49
-
50
- assetHashes.forEach((hash) => {
51
- const deleteIndex = state.allIds.indexOf(hash)
52
- if (deleteIndex >= 0) {
53
- state.allIds.splice(deleteIndex, 1)
54
- }
55
-
56
- if (state.byIds[hash]) {
57
- const blobUrl = state.byIds[hash].objectUrl
58
- if (blobUrl) {
59
- window.URL.revokeObjectURL(blobUrl)
60
- }
61
-
62
- delete state.byIds[hash]
63
- }
64
- })
65
- },
66
- previewReady(state, action: PayloadAction<{hash: string; blobUrl: string}>) {
67
- const {blobUrl, hash} = action.payload
68
- if (state.byIds[hash]) {
69
- state.byIds[hash].objectUrl = blobUrl
70
- }
71
- },
72
- uploadCancel(state, action: PayloadAction<{hash: string}>) {
73
- const {hash} = action.payload
74
- const deleteIndex = state.allIds.indexOf(hash)
75
- if (deleteIndex >= 0) {
76
- state.allIds.splice(deleteIndex, 1)
77
- }
78
- if (state.byIds[hash]) {
79
- delete state.byIds[hash]
80
- }
81
- },
82
- uploadError(state, action: PayloadAction<{error: HttpError; hash: string}>) {
83
- const {hash} = action.payload
84
- const deleteIndex = state.allIds.indexOf(hash)
85
- if (deleteIndex >= 0) {
86
- state.allIds.splice(deleteIndex, 1)
87
- }
88
- delete state.byIds[hash]
89
- },
90
- uploadRequest(
91
- _state,
92
- _action: PayloadAction<{file: File; forceAsAssetType?: 'file' | 'image'}>,
93
- ) {
94
- //
95
- },
96
- uploadProgress(
97
- state,
98
- action: PayloadAction<{event: SanityUploadProgressEvent; uploadHash: string}>,
99
- ) {
100
- const {event, uploadHash} = action.payload
101
- state.byIds[uploadHash].percent = event.percent
102
- state.byIds[uploadHash].status = 'uploading'
103
- },
104
- uploadStart(state, action: PayloadAction<{file: File; uploadItem: UploadItem}>) {
105
- const {uploadItem} = action.payload
106
- if (!state.allIds.includes(uploadItem.hash)) {
107
- state.allIds.push(uploadItem.hash)
108
- }
109
- state.byIds[uploadItem.hash] = uploadItem
110
- },
111
- },
112
- })
113
-
114
- // Epics
115
-
116
- export const uploadsAssetStartEpic: MyEpic = (action$, _state$, {client}) =>
117
- action$.pipe(
118
- filter(uploadsActions.uploadStart.match),
119
- mergeMap((action) => {
120
- const {file, uploadItem} = action.payload
121
-
122
- return merge(
123
- // Generate low res preview
124
- of(null).pipe(
125
- mergeMap(() => generatePreviewBlobUrl$(file)),
126
- mergeMap((url) => {
127
- return of(
128
- uploadsActions.previewReady({
129
- blobUrl: url,
130
- hash: uploadItem.hash,
131
- }),
132
- )
133
- }),
134
- ),
135
- // Upload asset and receive progress / complete events
136
- of(null).pipe(
137
- // delay(500000), // debug uploads
138
- mergeMap(() => uploadAsset$(client, uploadItem.assetType, file, uploadItem.hash)),
139
- takeUntil(
140
- action$.pipe(
141
- filter(uploadsActions.uploadCancel.match),
142
- filter((v) => v.payload.hash === uploadItem.hash),
143
- ),
144
- ),
145
- mergeMap((event) => {
146
- if (event?.type === 'complete') {
147
- return of(
148
- UPLOADS_ACTIONS.uploadComplete({
149
- asset: event.asset,
150
- }),
151
- )
152
- }
153
- if (event?.type === 'progress' && event?.stage === 'upload') {
154
- return of(
155
- uploadsActions.uploadProgress({
156
- event,
157
- uploadHash: uploadItem.hash,
158
- }),
159
- )
160
- }
161
- return empty()
162
- }),
163
- catchError((error: ClientError) =>
164
- of(
165
- uploadsActions.uploadError({
166
- error: {
167
- message: error?.message || 'Internal error',
168
- statusCode: error?.statusCode || 500,
169
- },
170
- hash: uploadItem.hash,
171
- }),
172
- ),
173
- ),
174
- ),
175
- )
176
- }),
177
- )
178
-
179
- export const uploadsAssetUploadEpic: MyEpic = (action$, state$) =>
180
- action$.pipe(
181
- filter(uploadsActions.uploadRequest.match),
182
- withLatestFrom(state$),
183
- mergeMap(([action, state]) => {
184
- const {file, forceAsAssetType} = action.payload
185
-
186
- return of(action).pipe(
187
- // Generate SHA1 hash from local file
188
- // This will throw in insecure contexts (non-localhost / https)
189
- mergeMap(() => hashFile$(file)),
190
- // Ignore if the file exists and is currently being uploaded
191
- filter((hash) => {
192
- const exists = !!state.uploads.byIds[hash]
193
- return !exists
194
- }),
195
- // Dispatch start action and begin upload process
196
- mergeMap((hash) => {
197
- const assetType = forceAsAssetType || (file.type.indexOf('image') >= 0 ? 'image' : 'file')
198
- const uploadItem = {
199
- _type: 'upload',
200
- assetType,
201
- hash,
202
- name: file.name,
203
- size: file.size,
204
- status: 'queued',
205
- } as UploadItem
206
- return of(uploadsActions.uploadStart({file, uploadItem}))
207
- }),
208
- )
209
- }),
210
- )
211
-
212
- export const uploadsCompleteQueueEpic: MyEpic = (action$) =>
213
- action$.pipe(
214
- filter(UPLOADS_ACTIONS.uploadComplete.match),
215
- mergeMap((action) => {
216
- return of(
217
- uploadsActions.checkRequest({
218
- assets: [action.payload.asset],
219
- }),
220
- )
221
- }),
222
- )
223
-
224
- export const uploadsCheckRequestEpic: MyEpic = (action$, state$, {client}) =>
225
- action$.pipe(
226
- filter(uploadsActions.checkRequest.match),
227
- withLatestFrom(state$),
228
- mergeMap(([action, state]) => {
229
- const {assets} = action.payload
230
-
231
- const documentIds = assets.map((asset) => asset._id)
232
-
233
- const constructedFilter = constructFilter({
234
- assetTypes: state.assets.assetTypes,
235
- searchFacets: state.search.facets,
236
- searchQuery: state.search.query,
237
- })
238
-
239
- const query = groq`
240
- *[${constructedFilter} && _id in $documentIds].sha1hash
241
- `
242
-
243
- return of(action).pipe(
244
- delay(1000), // give Sanity some time to register the recently uploaded asset
245
- mergeMap(() => client.observable.fetch<string[]>(query, {documentIds})),
246
- mergeMap((resultHashes) => {
247
- const checkedResults = assets.reduce((acc: Record<string, string | null>, asset) => {
248
- acc[asset.sha1hash] = resultHashes.includes(asset.sha1hash) ? asset._id : null
249
- return acc
250
- }, {})
251
-
252
- return of(
253
- uploadsActions.checkComplete({results: checkedResults}), //
254
- assetsActions.insertUploads({results: checkedResults}),
255
- )
256
- }),
257
- )
258
- }),
259
- )
260
-
261
- // Selectors
262
-
263
- const selectUploadsByIds = (state: RootReducerState) => state.uploads.byIds
264
-
265
- const selectUploadsAllIds = (state: RootReducerState) => state.uploads.allIds
266
-
267
- export const selectUploadById = createSelector(
268
- [
269
- (state: RootReducerState) => state.uploads.byIds,
270
- (_state: RootReducerState, uploadId: string) => uploadId,
271
- ],
272
- (byIds, uploadId) => byIds[uploadId],
273
- )
274
-
275
- export const selectUploads: Selector<RootReducerState, UploadItem[]> = createSelector(
276
- [selectUploadsByIds, selectUploadsAllIds],
277
- (byIds, allIds) => allIds.map((id) => byIds[id]),
278
- )
279
-
280
- export const uploadsActions = {...uploadsSlice.actions}
281
-
282
- export default uploadsSlice.reducer
@@ -1,29 +0,0 @@
1
- // @vitest-environment node
2
-
3
- import type {SanityClient} from '@sanity/client'
4
- import {firstValueFrom, of} from 'rxjs'
5
- import {describe, expect, it, vi} from 'vitest'
6
-
7
- import checkTagName from './checkTagName'
8
-
9
- describe('checkTagName', () => {
10
- it('errors with 409 when a tag with the same slug exists', async () => {
11
- const client = {
12
- fetch: vi.fn().mockResolvedValue(1),
13
- } as unknown as SanityClient
14
-
15
- await expect(
16
- firstValueFrom(of(null).pipe(checkTagName(client, 'existing'))),
17
- ).rejects.toMatchObject({statusCode: 409, message: 'Tag already exists'})
18
- })
19
-
20
- it('emits true when name is available', async () => {
21
- const client = {
22
- fetch: vi.fn().mockResolvedValue(0),
23
- } as unknown as SanityClient
24
-
25
- await expect(firstValueFrom(of(null).pipe(checkTagName(client, 'fresh-name')))).resolves.toBe(
26
- true,
27
- )
28
- })
29
- })
@@ -1,33 +0,0 @@
1
- import type {SanityClient} from '@sanity/client'
2
- import groq from 'groq'
3
- import {from, Observable, of, throwError} from 'rxjs'
4
- import {mergeMap} from 'rxjs/operators'
5
-
6
- import {TAG_DOCUMENT_NAME} from '../constants'
7
- import type {HttpError} from '../types'
8
-
9
- const checkTagName = (client: SanityClient, name: string) => {
10
- return function <T>(source: Observable<T>): Observable<boolean> {
11
- return source.pipe(
12
- mergeMap(() => {
13
- return from(
14
- client.fetch(groq`count(*[_type == "${TAG_DOCUMENT_NAME}" && name.current == $name])`, {
15
- name,
16
- }),
17
- ) as Observable<number>
18
- }),
19
- mergeMap((existingTagCount: number) => {
20
- if (existingTagCount > 0) {
21
- return throwError({
22
- message: 'Tag already exists',
23
- statusCode: 409,
24
- } as HttpError)
25
- }
26
-
27
- return of(true)
28
- }),
29
- )
30
- }
31
- }
32
-
33
- export default checkTagName
@@ -1,25 +0,0 @@
1
- import {iif, type Observable, of, throwError} from 'rxjs'
2
- import {delay, mergeMap} from 'rxjs/operators'
3
-
4
- const debugThrottle = (throttled?: boolean) => {
5
- return function <T>(source: Observable<T>): Observable<T> {
6
- return iif(
7
- () => !!throttled,
8
- source.pipe(
9
- delay(3000),
10
- mergeMap((v) => {
11
- if (Math.random() > 0.5) {
12
- return throwError({
13
- message: 'Test error',
14
- statusCode: 500,
15
- })
16
- }
17
- return of(v)
18
- }),
19
- ),
20
- source,
21
- )
22
- }
23
- }
24
-
25
- export default debugThrottle
package/src/plugin.tsx DELETED
@@ -1,54 +0,0 @@
1
- import {ImageIcon} from '@sanity/icons'
2
- import {type AssetSource, type Tool as SanityTool, definePlugin} from 'sanity'
3
-
4
- import FormBuilderTool from './components/FormBuilderTool'
5
- import Tool from './components/Tool'
6
- import {ToolOptionsProvider} from './contexts/ToolOptionsContext'
7
- import mediaTag from './schemas/tag'
8
- import type {MediaToolOptions} from './types'
9
-
10
- const plugin = {
11
- icon: ImageIcon,
12
- name: 'media',
13
- title: 'Media',
14
- }
15
-
16
- export const mediaAssetSource = {
17
- ...plugin,
18
- component: FormBuilderTool,
19
- } satisfies AssetSource
20
-
21
- const tool = {
22
- ...plugin,
23
- component: Tool,
24
- __internalApplicationType: 'sanity/media',
25
- } satisfies SanityTool
26
-
27
- export const media = definePlugin<MediaToolOptions | void>((options) => ({
28
- name: 'media',
29
- studio: {
30
- components: {
31
- layout: (props) => (
32
- <ToolOptionsProvider options={options}>{props.renderDefault(props)}</ToolOptionsProvider>
33
- ),
34
- },
35
- },
36
- form: {
37
- file: {
38
- assetSources: (prev) => {
39
- return [...prev, mediaAssetSource]
40
- },
41
- },
42
- image: {
43
- assetSources: (prev) => {
44
- return [...prev, mediaAssetSource]
45
- },
46
- },
47
- },
48
- schema: {
49
- types: [mediaTag],
50
- },
51
- tools: (prev) => {
52
- return [...prev, tool]
53
- },
54
- }))
@@ -1,28 +0,0 @@
1
- import TagIcon from '../components/TagIcon'
2
- import {TAG_DOCUMENT_NAME} from '../constants'
3
-
4
- export default {
5
- title: 'Media Tag',
6
- icon: TagIcon,
7
- name: TAG_DOCUMENT_NAME,
8
- type: 'document',
9
- fields: [
10
- {
11
- title: 'Name',
12
- name: 'name',
13
- type: 'slug',
14
- },
15
- ],
16
- preview: {
17
- select: {
18
- name: 'name',
19
- },
20
- prepare(selection: any) {
21
- const {name} = selection
22
- return {
23
- media: TagIcon,
24
- title: name?.current,
25
- }
26
- },
27
- },
28
- }
@@ -1,40 +0,0 @@
1
- import {createGlobalStyle, css} from 'styled-components'
2
-
3
- const customScrollbar = css`
4
- ::-webkit-scrollbar {
5
- width: 14px;
6
- }
7
-
8
- ::-webkit-scrollbar-thumb {
9
- border-radius: 10px;
10
- border: 4px solid rgba(0, 0, 0, 0);
11
- background: var(--card-border-color);
12
- background-clip: padding-box;
13
-
14
- &:hover {
15
- background: var(--card-muted-fg-color);
16
- background-clip: padding-box;
17
- }
18
- }
19
- `
20
-
21
- const GlobalStyle = createGlobalStyle`
22
- .media__custom-scrollbar {
23
- ${customScrollbar}
24
- }
25
-
26
- // @sanity/ui overrides
27
-
28
- // Custom scrollbar on Box (used in Dialogs)
29
- div[data-ui="Box"] {
30
- ${customScrollbar}
31
- }
32
-
33
- // Dialog background color
34
- div[data-ui="Dialog"] {
35
- background-color: rgba(15, 17, 18, 0.9);
36
- }
37
-
38
- `
39
-
40
- export default GlobalStyle