sanity-plugin-media 4.3.6 → 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 (162) hide show
  1. package/package.json +6 -15
  2. package/dist/index.cjs +0 -4721
  3. package/dist/index.cjs.map +0 -1
  4. package/dist/index.d.cts +0 -239
  5. package/dist/index.d.cts.map +0 -1
  6. package/sanity.json +0 -8
  7. package/src/__tests__/fixtures/createEpicTestStore.ts +0 -28
  8. package/src/__tests__/fixtures/listenMock.ts +0 -9
  9. package/src/__tests__/fixtures/mockSanityClient.ts +0 -84
  10. package/src/__tests__/fixtures/renderWithProviders.tsx +0 -55
  11. package/src/__tests__/fixtures/rootState.ts +0 -27
  12. package/src/__tests__/fixtures/withinDialog.ts +0 -28
  13. package/src/components/AssetGridVirtualized/index.tsx +0 -94
  14. package/src/components/AssetMetadata/index.tsx +0 -122
  15. package/src/components/AssetTableVirtualized/index.tsx +0 -73
  16. package/src/components/AutoTagInputWrapper/index.tsx +0 -85
  17. package/src/components/Browser/Browser.test.tsx +0 -45
  18. package/src/components/Browser/index.tsx +0 -90
  19. package/src/components/Browser/useBrowserInit.ts +0 -126
  20. package/src/components/ButtonAssetCopy/index.tsx +0 -65
  21. package/src/components/ButtonViewGroup/index.tsx +0 -39
  22. package/src/components/CardAsset/CardAsset.test.tsx +0 -323
  23. package/src/components/CardAsset/index.tsx +0 -290
  24. package/src/components/CardUpload/index.tsx +0 -161
  25. package/src/components/Controls/index.tsx +0 -136
  26. package/src/components/DebugControls/index.tsx +0 -80
  27. package/src/components/Dialog/index.tsx +0 -11
  28. package/src/components/DialogAssetEdit/Details.tsx +0 -181
  29. package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +0 -216
  30. package/src/components/DialogAssetEdit/index.tsx +0 -493
  31. package/src/components/DialogConfirm/index.tsx +0 -90
  32. package/src/components/DialogSearchFacets/index.tsx +0 -42
  33. package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +0 -121
  34. package/src/components/DialogTagCreate/index.tsx +0 -111
  35. package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +0 -165
  36. package/src/components/DialogTagEdit/index.tsx +0 -201
  37. package/src/components/DialogTags/index.tsx +0 -45
  38. package/src/components/Dialogs/index.tsx +0 -76
  39. package/src/components/DocumentList/index.tsx +0 -62
  40. package/src/components/FileAssetPreview/index.tsx +0 -37
  41. package/src/components/FileIcon/index.tsx +0 -43
  42. package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +0 -63
  43. package/src/components/FormBuilderTool/index.tsx +0 -69
  44. package/src/components/FormFieldInputLabel/index.tsx +0 -66
  45. package/src/components/FormFieldInputTags/index.tsx +0 -98
  46. package/src/components/FormFieldInputText/index.tsx +0 -41
  47. package/src/components/FormFieldInputTextarea/index.tsx +0 -43
  48. package/src/components/FormSubmitButton/index.tsx +0 -59
  49. package/src/components/Header/index.tsx +0 -80
  50. package/src/components/Image/index.tsx +0 -41
  51. package/src/components/Items/index.tsx +0 -68
  52. package/src/components/Notifications/index.tsx +0 -24
  53. package/src/components/OrderSelect/index.tsx +0 -66
  54. package/src/components/PickedBar/index.tsx +0 -77
  55. package/src/components/Progress/index.tsx +0 -38
  56. package/src/components/ReduxProvider/index.tsx +0 -96
  57. package/src/components/SearchFacet/index.tsx +0 -66
  58. package/src/components/SearchFacetNumber/index.tsx +0 -133
  59. package/src/components/SearchFacetSelect/index.tsx +0 -110
  60. package/src/components/SearchFacetString/index.tsx +0 -88
  61. package/src/components/SearchFacetTags/index.tsx +0 -121
  62. package/src/components/SearchFacets/index.tsx +0 -72
  63. package/src/components/SearchFacetsControl/index.tsx +0 -140
  64. package/src/components/TableHeader/index.tsx +0 -110
  65. package/src/components/TableHeaderItem/index.tsx +0 -61
  66. package/src/components/TableRowAsset/index.tsx +0 -419
  67. package/src/components/TableRowUpload/index.tsx +0 -164
  68. package/src/components/Tag/index.tsx +0 -200
  69. package/src/components/TagIcon/index.tsx +0 -22
  70. package/src/components/TagView/index.tsx +0 -39
  71. package/src/components/TagViewHeader/index.tsx +0 -70
  72. package/src/components/TagsPanel/index.tsx +0 -40
  73. package/src/components/TagsVirtualized/index.tsx +0 -160
  74. package/src/components/TextInputNumber/index.tsx +0 -32
  75. package/src/components/TextInputSearch/index.tsx +0 -60
  76. package/src/components/Tool/index.tsx +0 -13
  77. package/src/components/UploadDropzone/UploadDropzone.test.tsx +0 -40
  78. package/src/components/UploadDropzone/index.tsx +0 -173
  79. package/src/config/orders.ts +0 -28
  80. package/src/config/searchFacets.ts +0 -312
  81. package/src/constants.ts +0 -87
  82. package/src/contexts/AssetSourceDispatchContext.tsx +0 -38
  83. package/src/contexts/DropzoneDispatchContext.tsx +0 -32
  84. package/src/contexts/ToolOptionsContext.tsx +0 -66
  85. package/src/formSchema/index.test.ts +0 -56
  86. package/src/formSchema/index.ts +0 -39
  87. package/src/hooks/useBreakpointIndex.ts +0 -50
  88. package/src/hooks/useKeyPress.ts +0 -39
  89. package/src/hooks/usePortalPopoverProps.ts +0 -13
  90. package/src/hooks/useTypedSelector.ts +0 -7
  91. package/src/hooks/useVersionedClient.ts +0 -6
  92. package/src/index.ts +0 -5
  93. package/src/modules/assets/actions.ts +0 -42
  94. package/src/modules/assets/deleteAndUpdateEpics.test.ts +0 -87
  95. package/src/modules/assets/fetchEpic.test.ts +0 -73
  96. package/src/modules/assets/index.ts +0 -782
  97. package/src/modules/assets/reducer.test.ts +0 -91
  98. package/src/modules/assets/tagsAndListenerEpics.test.ts +0 -206
  99. package/src/modules/debug/index.ts +0 -28
  100. package/src/modules/dialog/actions.ts +0 -10
  101. package/src/modules/dialog/epics.test.ts +0 -168
  102. package/src/modules/dialog/index.ts +0 -238
  103. package/src/modules/dialog/reducer.test.ts +0 -185
  104. package/src/modules/index.ts +0 -117
  105. package/src/modules/notifications/epics.test.ts +0 -374
  106. package/src/modules/notifications/index.ts +0 -199
  107. package/src/modules/notifications/reducer.test.ts +0 -54
  108. package/src/modules/search/index.test.ts +0 -36
  109. package/src/modules/search/index.ts +0 -167
  110. package/src/modules/selected/index.ts +0 -22
  111. package/src/modules/selectors.test.ts +0 -21
  112. package/src/modules/selectors.ts +0 -17
  113. package/src/modules/tags/epics.test.ts +0 -96
  114. package/src/modules/tags/index.test.ts +0 -42
  115. package/src/modules/tags/index.ts +0 -540
  116. package/src/modules/types.ts +0 -3
  117. package/src/modules/uploads/actions.ts +0 -13
  118. package/src/modules/uploads/epics.test.ts +0 -109
  119. package/src/modules/uploads/index.test.ts +0 -59
  120. package/src/modules/uploads/index.ts +0 -272
  121. package/src/operators/checkTagName.test.ts +0 -29
  122. package/src/operators/checkTagName.ts +0 -33
  123. package/src/operators/debugThrottle.ts +0 -25
  124. package/src/plugin.tsx +0 -54
  125. package/src/schemas/tag.ts +0 -28
  126. package/src/styled/GlobalStyles/index.tsx +0 -40
  127. package/src/styled/react-select/creatable.tsx +0 -184
  128. package/src/styled/react-select/single.tsx +0 -184
  129. package/src/types/index.ts +0 -346
  130. package/src/types/sanity-ui.d.ts +0 -5
  131. package/src/utils/applyMediaTags.ts +0 -87
  132. package/src/utils/blocksToText.test.ts +0 -43
  133. package/src/utils/blocksToText.ts +0 -27
  134. package/src/utils/constructFilter.test.ts +0 -120
  135. package/src/utils/constructFilter.ts +0 -98
  136. package/src/utils/generatePreviewBlobUrl.test.ts +0 -68
  137. package/src/utils/generatePreviewBlobUrl.ts +0 -53
  138. package/src/utils/getAssetResolution.test.ts +0 -13
  139. package/src/utils/getAssetResolution.ts +0 -7
  140. package/src/utils/getDocumentAssetIds.test.ts +0 -50
  141. package/src/utils/getDocumentAssetIds.ts +0 -35
  142. package/src/utils/getSchemeColor.test.ts +0 -12
  143. package/src/utils/getSchemeColor.ts +0 -43
  144. package/src/utils/getTagSelectOptions.test.ts +0 -44
  145. package/src/utils/getTagSelectOptions.ts +0 -16
  146. package/src/utils/getUniqueDocuments.test.ts +0 -26
  147. package/src/utils/getUniqueDocuments.ts +0 -15
  148. package/src/utils/imageDprUrl.test.ts +0 -46
  149. package/src/utils/imageDprUrl.ts +0 -27
  150. package/src/utils/isSupportedAssetType.test.ts +0 -16
  151. package/src/utils/isSupportedAssetType.ts +0 -15
  152. package/src/utils/mediaField.ts +0 -73
  153. package/src/utils/sanitizeFormData.test.ts +0 -59
  154. package/src/utils/sanitizeFormData.ts +0 -26
  155. package/src/utils/typeGuards.test.ts +0 -18
  156. package/src/utils/typeGuards.ts +0 -9
  157. package/src/utils/uploadSanityAsset.test.ts +0 -29
  158. package/src/utils/uploadSanityAsset.ts +0 -97
  159. package/src/utils/withMaxConcurrency.test.ts +0 -43
  160. package/src/utils/withMaxConcurrency.ts +0 -55
  161. package/src/utils/zodFormResolver.ts +0 -17
  162. package/v2-incompatible.js +0 -11
@@ -1,66 +0,0 @@
1
- import {type PropsWithChildren, createContext, useContext, useMemo} from 'react'
2
- import type {DropzoneOptions} from 'react-dropzone'
3
-
4
- import type {MediaToolOptions, Locale} from '../types'
5
-
6
- type ContextProps = {
7
- dropzone: Pick<DropzoneOptions, 'maxSize'>
8
- components: MediaToolOptions['components']
9
- createTagsOnUpload: boolean
10
- creditLine: MediaToolOptions['creditLine']
11
- directUploads: MediaToolOptions['directUploads']
12
- locales?: Locale[]
13
- }
14
-
15
- const ToolOptionsContext = createContext<ContextProps | null>(null)
16
-
17
- type Props = {
18
- options?: MediaToolOptions | void
19
- }
20
-
21
- export const ToolOptionsProvider = ({options, children}: PropsWithChildren<Props>) => {
22
- // oxlint-disable-next-line react-compiler
23
- const value = useMemo<ContextProps>(() => {
24
- let creditLineExcludeSources
25
-
26
- if (options?.creditLine?.excludeSources) {
27
- creditLineExcludeSources = Array.isArray(options?.creditLine?.excludeSources)
28
- ? options.creditLine.excludeSources
29
- : [options?.creditLine?.excludeSources]
30
- }
31
-
32
- return {
33
- dropzone: {maxSize: options?.maximumUploadSize},
34
- components: {
35
- details: options?.components?.details,
36
- },
37
- createTagsOnUpload: options?.createTagsOnUpload ?? true,
38
- creditLine: {
39
- enabled: options?.creditLine?.enabled || false,
40
- excludeSources: creditLineExcludeSources,
41
- },
42
- directUploads: options?.directUploads ?? true,
43
- locales: options?.locales,
44
- }
45
- }, [
46
- options?.creditLine?.enabled,
47
- options?.components,
48
- options?.createTagsOnUpload,
49
- options?.creditLine?.excludeSources,
50
- options?.maximumUploadSize,
51
- options?.directUploads,
52
- options?.locales,
53
- ])
54
-
55
- return <ToolOptionsContext.Provider value={value}>{children}</ToolOptionsContext.Provider>
56
- }
57
-
58
- export const useToolOptions = () => {
59
- const context = useContext(ToolOptionsContext)
60
-
61
- if (!context) {
62
- throw new Error('useToolOptions must be used within an ToolOptionsProvider')
63
- }
64
-
65
- return context
66
- }
@@ -1,56 +0,0 @@
1
- // @vitest-environment node
2
-
3
- import {describe, expect, it} from 'vitest'
4
-
5
- import {assetFormSchema, tagFormSchema, tagOptionSchema} from './index'
6
-
7
- describe('tagOptionSchema', () => {
8
- it('accepts trimmed non-empty label and value', () => {
9
- expect(tagOptionSchema.safeParse({label: 'A', value: 'b'}).success).toBe(true)
10
- })
11
-
12
- it('rejects empty label or value after trim', () => {
13
- expect(tagOptionSchema.safeParse({label: ' ', value: 'x'}).success).toBe(false)
14
- expect(tagOptionSchema.safeParse({label: 'x', value: ''}).success).toBe(false)
15
- })
16
- })
17
-
18
- describe('tagFormSchema', () => {
19
- it('requires non-empty name', () => {
20
- expect(tagFormSchema.safeParse({name: 'x'}).success).toBe(true)
21
- expect(tagFormSchema.safeParse({name: ''}).success).toBe(false)
22
- })
23
- })
24
-
25
- describe('assetFormSchema', () => {
26
- const base = {
27
- altText: '',
28
- creditLine: '',
29
- description: '',
30
- opt: {media: {tags: null}},
31
- originalFilename: 'file.png',
32
- title: '',
33
- }
34
-
35
- it('accepts valid asset form payload', () => {
36
- expect(assetFormSchema.safeParse(base).success).toBe(true)
37
- })
38
-
39
- it('rejects empty originalFilename', () => {
40
- expect(
41
- assetFormSchema.safeParse({
42
- ...base,
43
- originalFilename: ' ',
44
- }).success,
45
- ).toBe(false)
46
- })
47
-
48
- it('validates nested tag options', () => {
49
- expect(
50
- assetFormSchema.safeParse({
51
- ...base,
52
- opt: {media: {tags: [{label: '', value: 'v'}]}},
53
- }).success,
54
- ).toBe(false)
55
- })
56
- })
@@ -1,39 +0,0 @@
1
- import * as z from 'zod'
2
-
3
- // Helper to generate localized string schema
4
- function localizedStringSchema(locales?: {id: string}[]) {
5
- if (!locales || locales.length === 0) {
6
- return z.string().trim().optional()
7
- }
8
- const shape: Record<string, z.ZodTypeAny> = {}
9
- for (const locale of locales) {
10
- shape[locale.id] = z.string().trim().optional()
11
- }
12
- return z.object(shape).passthrough()
13
- }
14
-
15
- export const tagOptionSchema = z.object({
16
- label: z.string().trim().min(1, {message: 'Label cannot be empty'}),
17
- value: z.string().trim().min(1, {message: 'Value cannot be empty'}),
18
- })
19
-
20
- export function getAssetFormSchema(locales?: {id: string}[]) {
21
- return z.object({
22
- altText: localizedStringSchema(locales),
23
- creditLine: localizedStringSchema(locales),
24
- description: localizedStringSchema(locales),
25
- opt: z.object({
26
- media: z.object({
27
- tags: z.array(tagOptionSchema).nullable(),
28
- }),
29
- }),
30
- originalFilename: z.string().trim().min(1, {message: 'Filename cannot be empty'}),
31
- title: localizedStringSchema(locales),
32
- })
33
- }
34
-
35
- export const assetFormSchema = getAssetFormSchema()
36
-
37
- export const tagFormSchema = z.object({
38
- name: z.string().min(1, {message: 'Name cannot be empty'}),
39
- })
@@ -1,50 +0,0 @@
1
- import {studioTheme} from '@sanity/ui'
2
- import {useEffect, useState} from 'react'
3
-
4
- // Determine the current breakpoint index
5
- // - create MediaQueryLists from every breakpoint defined in our sanity studio theme
6
- // - for each MQL, listen to change events and return the selected breakpoint index
7
- const useBreakpointIndex = (): number => {
8
- const mediaQueryLists = studioTheme?.container?.map((width) =>
9
- window.matchMedia(`(max-width: ${width}px)`),
10
- )
11
-
12
- const getBreakpointIndex = () => mediaQueryLists.findIndex((mql) => mql.matches)
13
-
14
- const [value, setValue] = useState(getBreakpointIndex())
15
-
16
- useEffect(() => {
17
- const handleBreakpoint = () => {
18
- setValue(getBreakpointIndex)
19
- }
20
-
21
- // NOTE: older versions of Safari use the older `addListener` and `removeListener` methods
22
- mediaQueryLists.forEach((mql) => {
23
- try {
24
- mql.addEventListener('change', handleBreakpoint)
25
- } catch {
26
- try {
27
- mql.addListener(handleBreakpoint)
28
- } catch {
29
- // Do nothing
30
- }
31
- }
32
- })
33
- return () => {
34
- try {
35
- mediaQueryLists.forEach((mql) => mql.removeEventListener('change', handleBreakpoint))
36
- } catch {
37
- try {
38
- mediaQueryLists.forEach((mql) => mql.removeListener(handleBreakpoint))
39
- } catch {
40
- // Do nothing
41
- }
42
- }
43
- }
44
- // oxlint-disable-next-line react-hooks/exhaustive-deps - use the hook from `@sanity/ui` instead of this home-rolled one
45
- }, [])
46
-
47
- return value
48
- }
49
-
50
- export default useBreakpointIndex
@@ -1,39 +0,0 @@
1
- import {isHotkey} from 'is-hotkey-esm'
2
- import {type RefObject, useCallback, useEffect, useRef} from 'react'
3
-
4
- const useKeyPress = (hotkey: string, onPress?: () => void): RefObject<boolean> => {
5
- const keyPressed = useRef(false)
6
-
7
- // If pressed key is our target key then set to true
8
- const downHandler = useCallback(
9
- (e: KeyboardEvent) => {
10
- if (isHotkey(hotkey, e)) {
11
- keyPressed.current = true
12
- if (onPress) {
13
- onPress()
14
- }
15
- }
16
- },
17
- [hotkey, onPress],
18
- )
19
-
20
- // If released key is our target key then set to false
21
- const upHandler = useCallback(() => {
22
- keyPressed.current = false
23
- }, [])
24
-
25
- // Add event listeners
26
- useEffect(() => {
27
- window.addEventListener('keydown', downHandler)
28
- window.addEventListener('keyup', upHandler)
29
- // Remove event listeners on cleanup
30
- return () => {
31
- window.removeEventListener('keydown', downHandler)
32
- window.removeEventListener('keyup', upHandler)
33
- }
34
- }, [downHandler, upHandler])
35
-
36
- return keyPressed
37
- }
38
-
39
- export default useKeyPress
@@ -1,13 +0,0 @@
1
- import {type PopoverProps, usePortal} from '@sanity/ui'
2
-
3
- export function usePortalPopoverProps(): PopoverProps {
4
- const portal = usePortal()
5
-
6
- return {
7
- animate: true,
8
- constrainSize: true,
9
- floatingBoundary: portal.element,
10
- portal: true,
11
- referenceBoundary: portal.element,
12
- }
13
- }
@@ -1,7 +0,0 @@
1
- import {type TypedUseSelectorHook, useSelector} from 'react-redux'
2
-
3
- import type {RootReducerState} from '../modules/types'
4
-
5
- const useTypedSelector: TypedUseSelectorHook<RootReducerState> = useSelector
6
-
7
- export default useTypedSelector
@@ -1,6 +0,0 @@
1
- import type {SanityClient} from '@sanity/client'
2
- import {useClient} from 'sanity'
3
-
4
- const useVersionedClient = (): SanityClient => useClient({apiVersion: '2025-10-02'})
5
-
6
- export default useVersionedClient
package/src/index.ts DELETED
@@ -1,5 +0,0 @@
1
- export {media, mediaAssetSource} from './plugin'
2
- export {AutoTagInput} from './components/AutoTagInputWrapper'
3
- export type {AutoTagInputProps} from './components/AutoTagInputWrapper'
4
- export {mediaField} from './utils/mediaField'
5
- export type {MediaTagsOptions, MediaToolOptions} from './types'
@@ -1,42 +0,0 @@
1
- import {createAction} from '@reduxjs/toolkit'
2
-
3
- import type {AssetItem, HttpError, Tag} from '../../types'
4
-
5
- export const ASSETS_ACTIONS = {
6
- tagsAddComplete: createAction(
7
- 'actions/tagsAddComplete',
8
- function prepare({assets, tag}: {assets: AssetItem[]; tag: Tag}) {
9
- return {payload: {assets, tag}}
10
- },
11
- ),
12
- tagsAddError: createAction(
13
- 'actions/tagsAddError',
14
- function prepare({assets, error, tag}: {assets: AssetItem[]; error: HttpError; tag: Tag}) {
15
- return {payload: {assets, error, tag}}
16
- },
17
- ),
18
- tagsAddRequest: createAction(
19
- 'actions/tagsAddRequest',
20
- function prepare({assets, tag}: {assets: AssetItem[]; tag: Tag}) {
21
- return {payload: {assets, tag}}
22
- },
23
- ),
24
- tagsRemoveComplete: createAction(
25
- 'actions/tagsRemoveComplete',
26
- function prepare({assets, tag}: {assets: AssetItem[]; tag: Tag}) {
27
- return {payload: {assets, tag}}
28
- },
29
- ),
30
- tagsRemoveError: createAction(
31
- 'actions/tagsRemoveError',
32
- function prepare({assets, error, tag}: {assets: AssetItem[]; error: HttpError; tag: Tag}) {
33
- return {payload: {assets, error, tag}}
34
- },
35
- ),
36
- tagsRemoveRequest: createAction(
37
- 'actions/tagsRemoveRequest',
38
- function prepare({assets, tag}: {assets: AssetItem[]; tag: Tag}) {
39
- return {payload: {assets, tag}}
40
- },
41
- ),
42
- }
@@ -1,87 +0,0 @@
1
- // @vitest-environment node
2
-
3
- import {of} from 'rxjs'
4
- import {describe, expect, it, vi} from 'vitest'
5
-
6
- import {createEpicTestStore} from '../../__tests__/fixtures/createEpicTestStore'
7
- import {createMockSanityClient, mockPatchChain} from '../../__tests__/fixtures/mockSanityClient'
8
- import type {ImageAsset} from '../../types'
9
- import {
10
- assetsActions,
11
- assetsDeleteEpic,
12
- assetsUpdateEpic,
13
- initialState as assetsInitialState,
14
- } from './index'
15
-
16
- const sampleAsset = {
17
- _id: 'a1',
18
- _type: 'sanity.imageAsset',
19
- _createdAt: '',
20
- _updatedAt: '',
21
- _rev: 'r',
22
- originalFilename: 'x.png',
23
- size: 1,
24
- mimeType: 'image/png',
25
- url: '',
26
- } as ImageAsset
27
-
28
- describe('assetsDeleteEpic', () => {
29
- it('dispatches deleteComplete when observable.delete succeeds', async () => {
30
- const client = createMockSanityClient({
31
- observable: {
32
- delete: vi.fn(() => of({})),
33
- },
34
- })
35
-
36
- const store = createEpicTestStore(assetsDeleteEpic, client, {
37
- assets: {
38
- ...assetsInitialState,
39
- assetTypes: ['image'],
40
- allIds: ['a1'],
41
- byIds: {
42
- a1: {_type: 'asset', asset: sampleAsset, picked: false, updating: false},
43
- },
44
- },
45
- })
46
-
47
- store.dispatch(assetsActions.deleteRequest({assets: [sampleAsset]}))
48
-
49
- await vi.waitFor(() => {
50
- expect(store.getState().assets.byIds['a1']).toBeUndefined()
51
- expect(client.observable.delete).toHaveBeenCalled()
52
- })
53
- })
54
- })
55
-
56
- describe('assetsUpdateEpic', () => {
57
- it('commits patch and dispatches updateComplete', async () => {
58
- const updated = {...sampleAsset, title: 'Updated'}
59
- const chain = mockPatchChain(updated)
60
- const client = createMockSanityClient({
61
- patch: vi.fn(() => chain),
62
- })
63
-
64
- const store = createEpicTestStore(assetsUpdateEpic, client, {
65
- assets: {
66
- ...assetsInitialState,
67
- assetTypes: ['image'],
68
- allIds: ['a1'],
69
- byIds: {
70
- a1: {_type: 'asset', asset: sampleAsset, picked: false, updating: false},
71
- },
72
- },
73
- })
74
-
75
- store.dispatch(
76
- assetsActions.updateRequest({
77
- asset: sampleAsset,
78
- formData: {title: 'Updated'},
79
- }),
80
- )
81
-
82
- await vi.waitFor(() => {
83
- expect(chain.commit).toHaveBeenCalled()
84
- expect(store.getState().assets.byIds['a1']!.asset.title).toBe('Updated')
85
- })
86
- })
87
- })
@@ -1,73 +0,0 @@
1
- // @vitest-environment node
2
-
3
- import {of, throwError} from 'rxjs'
4
- import {describe, expect, it, vi} from 'vitest'
5
-
6
- import {createEpicTestStore} from '../../__tests__/fixtures/createEpicTestStore'
7
- import {createMockSanityClient} from '../../__tests__/fixtures/mockSanityClient'
8
- import type {ImageAsset} from '../../types'
9
- import {assetsActions, assetsFetchEpic} from './index'
10
-
11
- function assertFetchSucceeded(store: ReturnType<typeof createEpicTestStore>, asset: ImageAsset) {
12
- expect(store.getState().assets.byIds['a1']?.asset).toEqual(asset)
13
- expect(store.getState().assets.fetching).toBe(false)
14
- }
15
-
16
- function assertFetchFailed(store: ReturnType<typeof createEpicTestStore>) {
17
- expect(store.getState().assets.fetchingError?.message).toBe('boom')
18
- }
19
-
20
- const sampleAsset = {
21
- _id: 'a1',
22
- _type: 'sanity.imageAsset',
23
- _createdAt: '',
24
- _updatedAt: '',
25
- _rev: 'r',
26
- originalFilename: 'x.png',
27
- size: 1,
28
- mimeType: 'image/png',
29
- url: '',
30
- } as ImageAsset
31
-
32
- describe('assetsFetchEpic', () => {
33
- it('dispatches fetchComplete when observable.fetch succeeds', async () => {
34
- const client = createMockSanityClient({
35
- observable: {
36
- fetch: vi.fn(() => of({items: [sampleAsset]})),
37
- },
38
- })
39
-
40
- const store = createEpicTestStore(assetsFetchEpic, client)
41
- store.dispatch(
42
- assetsActions.fetchRequest({
43
- params: {},
44
- queryFilter: '_type == "sanity.imageAsset"',
45
- selector: '',
46
- sort: '',
47
- }),
48
- )
49
-
50
- await vi.waitFor(() => assertFetchSucceeded(store, sampleAsset))
51
- })
52
-
53
- it('dispatches fetchError when fetch fails', async () => {
54
- const fetchErr = throwError(() => ({message: 'boom', statusCode: 500}))
55
- const client = createMockSanityClient({
56
- observable: {
57
- fetch: vi.fn(() => fetchErr),
58
- },
59
- })
60
-
61
- const store = createEpicTestStore(assetsFetchEpic, client)
62
- store.dispatch(
63
- assetsActions.fetchRequest({
64
- params: {},
65
- queryFilter: '_type == "sanity.imageAsset"',
66
- selector: '',
67
- sort: '',
68
- }),
69
- )
70
-
71
- await vi.waitFor(() => assertFetchFailed(store))
72
- })
73
- })