sanity-plugin-mux-input 3.0.5 → 4.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 (123) hide show
  1. package/dist/index.js +28 -28
  2. package/dist/index.js.map +1 -1
  3. package/package.json +5 -15
  4. package/dist/index.cjs +0 -5746
  5. package/dist/index.cjs.map +0 -1
  6. package/dist/index.d.cts +0 -288
  7. package/dist/index.d.cts.map +0 -1
  8. package/sanity.json +0 -8
  9. package/src/_exports/index.ts +0 -73
  10. package/src/actions/assets.ts +0 -152
  11. package/src/actions/secrets.ts +0 -110
  12. package/src/actions/upload.ts +0 -308
  13. package/src/clients/upChunkObservable.ts +0 -54
  14. package/src/components/AddCaptionDialog.tsx +0 -440
  15. package/src/components/CaptionsDialog.tsx +0 -23
  16. package/src/components/ConfigureApi.styled.tsx +0 -19
  17. package/src/components/ConfigureApi.tsx +0 -296
  18. package/src/components/DraggableWatermark.tsx +0 -885
  19. package/src/components/EditCaptionDialog.tsx +0 -511
  20. package/src/components/EditThumbnailDialog.tsx +0 -121
  21. package/src/components/ErrorBoundaryCard.tsx +0 -97
  22. package/src/components/FileInputButton.tsx +0 -54
  23. package/src/components/FileInputMenuItem.styled.tsx +0 -36
  24. package/src/components/FileInputMenuItem.tsx +0 -85
  25. package/src/components/FormField.tsx +0 -38
  26. package/src/components/IconInfo.tsx +0 -22
  27. package/src/components/ImportVideosFromMux.tsx +0 -339
  28. package/src/components/Input.styled.tsx +0 -22
  29. package/src/components/Input.tsx +0 -78
  30. package/src/components/InputBrowser.tsx +0 -41
  31. package/src/components/MuxLogo.tsx +0 -42
  32. package/src/components/Onboard.tsx +0 -65
  33. package/src/components/PageSelector.tsx +0 -54
  34. package/src/components/Player.styled.tsx +0 -11
  35. package/src/components/Player.tsx +0 -117
  36. package/src/components/PlayerActionsMenu.tsx +0 -191
  37. package/src/components/ResyncMetadata.tsx +0 -278
  38. package/src/components/SelectAsset.tsx +0 -39
  39. package/src/components/SelectSortOptions.tsx +0 -45
  40. package/src/components/SpinnerBox.tsx +0 -16
  41. package/src/components/StudioTool.tsx +0 -24
  42. package/src/components/TextTracksEditor.tsx +0 -117
  43. package/src/components/TextTracksManager.tsx +0 -738
  44. package/src/components/UploadConfiguration.tsx +0 -696
  45. package/src/components/UploadPlaceholder.tsx +0 -88
  46. package/src/components/UploadProgress.tsx +0 -80
  47. package/src/components/Uploader.styled.tsx +0 -65
  48. package/src/components/Uploader.tsx +0 -499
  49. package/src/components/VideoDetails/DeleteDialog.tsx +0 -148
  50. package/src/components/VideoDetails/VideoDetails.tsx +0 -358
  51. package/src/components/VideoDetails/VideoReferences.tsx +0 -63
  52. package/src/components/VideoDetails/useVideoDetails.ts +0 -103
  53. package/src/components/VideoInBrowser.tsx +0 -245
  54. package/src/components/VideoMetadata.tsx +0 -45
  55. package/src/components/VideoPlayer.tsx +0 -241
  56. package/src/components/VideoThumbnail.tsx +0 -139
  57. package/src/components/VideosBrowser.tsx +0 -100
  58. package/src/components/documentPreview/DocumentPreview.tsx +0 -84
  59. package/src/components/documentPreview/DraftStatus.tsx +0 -34
  60. package/src/components/documentPreview/MissingSchemaType.tsx +0 -32
  61. package/src/components/documentPreview/PaneItemPreview.tsx +0 -67
  62. package/src/components/documentPreview/PublishedStatus.tsx +0 -35
  63. package/src/components/documentPreview/TimeAgo.tsx +0 -12
  64. package/src/components/icons/Audio.tsx +0 -13
  65. package/src/components/icons/Resolution.tsx +0 -12
  66. package/src/components/icons/StopWatch.tsx +0 -20
  67. package/src/components/icons/ToolIcon.tsx +0 -19
  68. package/src/components/uploadConfiguration/PlaybackPolicy.tsx +0 -133
  69. package/src/components/uploadConfiguration/PlaybackPolicyOption.tsx +0 -76
  70. package/src/components/uploadConfiguration/PlaybackPolicyWarning.tsx +0 -29
  71. package/src/components/uploadConfiguration/ResolutionTierSelector.tsx +0 -72
  72. package/src/components/uploadConfiguration/StaticRenditionSelector.tsx +0 -180
  73. package/src/components/withFocusRing/helpers.ts +0 -24
  74. package/src/components/withFocusRing/index.ts +0 -1
  75. package/src/components/withFocusRing/withFocusRing.ts +0 -30
  76. package/src/context/DialogStateContext.tsx +0 -33
  77. package/src/context/DrmPlaybackWarningContext.tsx +0 -97
  78. package/src/hooks/useAccessControl.ts +0 -13
  79. package/src/hooks/useAssetDocumentValues.ts +0 -11
  80. package/src/hooks/useAssets.ts +0 -73
  81. package/src/hooks/useCancelUpload.ts +0 -22
  82. package/src/hooks/useClient.ts +0 -8
  83. package/src/hooks/useDialogState.ts +0 -11
  84. package/src/hooks/useDocReferences.ts +0 -21
  85. package/src/hooks/useFetchFileSize.ts +0 -55
  86. package/src/hooks/useImportMuxAssets.ts +0 -132
  87. package/src/hooks/useInView.ts +0 -41
  88. package/src/hooks/useMediaMetadata.ts +0 -104
  89. package/src/hooks/useMuxAssets.ts +0 -179
  90. package/src/hooks/useMuxPolling.ts +0 -52
  91. package/src/hooks/useResyncAsset.ts +0 -110
  92. package/src/hooks/useResyncMuxMetadata.ts +0 -169
  93. package/src/hooks/useSaveSecrets.ts +0 -78
  94. package/src/hooks/useSecretsDocumentValues.ts +0 -38
  95. package/src/hooks/useSecretsFormState.ts +0 -47
  96. package/src/plugin.tsx +0 -31
  97. package/src/sanity-ui.d.ts +0 -5
  98. package/src/schema.ts +0 -196
  99. package/src/util/addKeysToMuxData.ts +0 -30
  100. package/src/util/asserters.ts +0 -23
  101. package/src/util/assetTitlePlaceholder.ts +0 -31
  102. package/src/util/constants.ts +0 -15
  103. package/src/util/convertWatermarkToMux.ts +0 -160
  104. package/src/util/createSearchFilter.ts +0 -76
  105. package/src/util/createUrlParamsObject.ts +0 -29
  106. package/src/util/extractFiles.ts +0 -67
  107. package/src/util/formatBytes.ts +0 -31
  108. package/src/util/formatDriveShareLink.ts +0 -64
  109. package/src/util/formatSeconds.ts +0 -48
  110. package/src/util/generateJwt.ts +0 -57
  111. package/src/util/getAnimatedPosterSrc.ts +0 -26
  112. package/src/util/getPlaybackPolicy.ts +0 -69
  113. package/src/util/getPosterSrc.ts +0 -28
  114. package/src/util/getVideoMetadata.ts +0 -23
  115. package/src/util/getVideoSrc.ts +0 -23
  116. package/src/util/parsers.ts +0 -5
  117. package/src/util/pluginVersion.ts +0 -5
  118. package/src/util/readSecrets.ts +0 -38
  119. package/src/util/roundPxString.ts +0 -16
  120. package/src/util/textTracks.ts +0 -222
  121. package/src/util/tryWithSuspend.ts +0 -22
  122. package/src/util/types.ts +0 -566
  123. package/v2-incompatible.js +0 -11
@@ -1,169 +0,0 @@
1
- import {useMemo, useState} from 'react'
2
- import {
3
- createHookFromObservableFactory,
4
- type DocumentStore,
5
- useClient,
6
- useDocumentStore,
7
- } from 'sanity'
8
-
9
- import {addKeysToMuxData} from '../util/addKeysToMuxData'
10
- import {isEmptyOrPlaceholderTitle} from '../util/assetTitlePlaceholder'
11
- import type {VideoAssetDocument} from '../util/types'
12
- import {SANITY_API_VERSION} from './useClient'
13
- import useMuxAssets from './useMuxAssets'
14
- import {useSecretsDocumentValues} from './useSecretsDocumentValues'
15
-
16
- type ResyncState = 'closed' | 'idle' | 'syncing' | 'done' | 'error'
17
-
18
- export default function useResyncMuxMetadata() {
19
- const documentStore = useDocumentStore()
20
- const client = useClient({
21
- apiVersion: SANITY_API_VERSION,
22
- })
23
-
24
- const [sanityAssets, sanityAssetsLoading] = useSanityAssets(documentStore)
25
-
26
- const secretDocumentValues = useSecretsDocumentValues()
27
- const hasSecrets = !!secretDocumentValues.value.secrets?.secretKey
28
-
29
- const [resyncError, setResyncError] = useState<unknown>()
30
- const [resyncState, setResyncState] = useState<ResyncState>('closed')
31
- const dialogOpen = resyncState !== 'closed'
32
-
33
- const muxAssets = useMuxAssets({
34
- client,
35
- enabled: hasSecrets && dialogOpen,
36
- })
37
-
38
- const matchedAssets = useMemo(() => {
39
- return sanityAssets && muxAssets.data
40
- ? sanityAssets.map((sanityDoc) => {
41
- const muxAsset = muxAssets.data?.find(
42
- (m) => m.id === sanityDoc.assetId || m.id === sanityDoc.data?.id,
43
- )
44
- return {
45
- sanityDoc,
46
- muxAsset,
47
- muxTitle: muxAsset?.meta?.title,
48
- currentTitle: sanityDoc.filename,
49
- }
50
- })
51
- : undefined
52
- }, [sanityAssets, muxAssets.data])
53
-
54
- const closeDialog = () => {
55
- if (resyncState !== 'syncing') setResyncState('closed')
56
- }
57
-
58
- const openDialog = () => {
59
- if (resyncState === 'closed') setResyncState('idle')
60
- }
61
-
62
- async function syncAllVideos() {
63
- if (!matchedAssets) return
64
-
65
- setResyncState('syncing')
66
-
67
- try {
68
- const tx = client.transaction()
69
-
70
- matchedAssets.forEach((matched) => {
71
- // Update all videos with the Mux title, even if it's undefined/empty
72
- const newTitle = matched.muxTitle || ''
73
- tx.patch(matched.sanityDoc._id, {set: {filename: newTitle}})
74
- })
75
-
76
- await tx.commit({returnDocuments: false})
77
- setResyncState('done')
78
- } catch (error) {
79
- setResyncState('error')
80
- setResyncError(error)
81
- }
82
- }
83
-
84
- async function syncOnlyEmpty() {
85
- if (!matchedAssets) return
86
-
87
- setResyncState('syncing')
88
-
89
- try {
90
- const tx = client.transaction()
91
-
92
- matchedAssets.forEach((matched) => {
93
- // Only update if the current title is empty or has the placeholder format
94
- // AND there's a new title available from Mux
95
- if (
96
- matched.muxAsset &&
97
- matched.muxTitle &&
98
- isEmptyOrPlaceholderTitle(matched.currentTitle, matched.muxAsset.id)
99
- ) {
100
- tx.patch(matched.sanityDoc._id, {set: {filename: matched.muxTitle}})
101
- }
102
- })
103
-
104
- await tx.commit({returnDocuments: false})
105
- setResyncState('done')
106
- } catch (error) {
107
- setResyncState('error')
108
- setResyncError(error)
109
- }
110
- }
111
-
112
- async function syncFullData() {
113
- if (!matchedAssets) return
114
-
115
- setResyncState('syncing')
116
-
117
- try {
118
- const tx = client.transaction()
119
-
120
- matchedAssets.forEach((matched) => {
121
- if (!matched.muxAsset) return
122
-
123
- const dataWithKeys = addKeysToMuxData(matched.muxAsset)
124
-
125
- // Update all fields: filename, status, and full data from Mux
126
- tx.patch(matched.sanityDoc._id, {
127
- set: {
128
- filename: matched.muxTitle || matched.currentTitle || '',
129
- status: matched.muxAsset.status,
130
- data: dataWithKeys,
131
- },
132
- })
133
- })
134
-
135
- await tx.commit({returnDocuments: false})
136
- setResyncState('done')
137
- } catch (error) {
138
- setResyncState('error')
139
- setResyncError(error)
140
- }
141
- }
142
-
143
- return {
144
- sanityAssetsLoading,
145
- closeDialog,
146
- dialogOpen,
147
- resyncState,
148
- resyncError,
149
- hasSecrets,
150
- syncAllVideos,
151
- syncOnlyEmpty,
152
- syncFullData,
153
- matchedAssets,
154
- muxAssets,
155
- openDialog,
156
- }
157
- }
158
-
159
- const useSanityAssets = createHookFromObservableFactory<VideoAssetDocument[], DocumentStore>(
160
- (documentStore) => {
161
- return documentStore.listenQuery(
162
- /* groq */ `*[_type == "mux.videoAsset"]`,
163
- {},
164
- {
165
- apiVersion: SANITY_API_VERSION,
166
- },
167
- )
168
- },
169
- )
@@ -1,78 +0,0 @@
1
- import {useCallback} from 'react'
2
- import type {SanityClient} from 'sanity'
3
-
4
- import {createSigningKeys, haveValidSigningKeys, saveSecrets, testSecrets} from '../actions/secrets'
5
- import type {Secrets} from '../util/types'
6
-
7
- export const useSaveSecrets = (client: SanityClient, secrets: Secrets) => {
8
- return useCallback(
9
- async ({
10
- token,
11
- secretKey,
12
- enableSignedUrls,
13
- drmConfigId,
14
- }: Pick<
15
- Secrets,
16
- 'token' | 'secretKey' | 'enableSignedUrls' | 'drmConfigId'
17
- >): Promise<Secrets> => {
18
- let {signingKeyId, signingKeyPrivate} = secrets
19
-
20
- try {
21
- await saveSecrets(
22
- client,
23
- token!,
24
- secretKey!,
25
- enableSignedUrls,
26
- signingKeyId!,
27
- signingKeyPrivate!,
28
- drmConfigId!,
29
- )
30
- const valid = await testSecrets(client)
31
- if (!valid?.status && token && secretKey) {
32
- throw new Error('Invalid secrets')
33
- }
34
- } catch (err) {
35
- console.error('Error while trying to save secrets:', err)
36
- throw err
37
- }
38
-
39
- if (enableSignedUrls) {
40
- const hasValidSigningKeys = await haveValidSigningKeys(
41
- client,
42
- signingKeyId!,
43
- signingKeyPrivate!,
44
- )
45
-
46
- if (!hasValidSigningKeys) {
47
- try {
48
- const {data} = await createSigningKeys(client)
49
- signingKeyId = data.id
50
- signingKeyPrivate = data.private_key
51
- await saveSecrets(
52
- client,
53
- token!,
54
- secretKey!,
55
- enableSignedUrls,
56
- signingKeyId,
57
- signingKeyPrivate,
58
- drmConfigId ?? '',
59
- )
60
- } catch (err: any) {
61
- // eslint-disable-next-line no-console
62
- console.log('Error while creating and saving signing key:', err?.message)
63
- throw err
64
- }
65
- }
66
- }
67
- return {
68
- token,
69
- secretKey,
70
- enableSignedUrls,
71
- signingKeyId,
72
- signingKeyPrivate,
73
- drmConfigId,
74
- }
75
- },
76
- [client, secrets],
77
- )
78
- }
@@ -1,38 +0,0 @@
1
- import {useMemo} from 'react'
2
- import {useDocumentValues} from 'sanity'
3
-
4
- import {muxSecretsDocumentId} from '../util/constants'
5
- import type {Secrets} from '../util/types'
6
-
7
- const path = [
8
- 'token',
9
- 'secretKey',
10
- 'enableSignedUrls',
11
- 'signingKeyId',
12
- 'signingKeyPrivate',
13
- 'drmConfigId',
14
- ]
15
- export const useSecretsDocumentValues = () => {
16
- const {error, isLoading, value} = useDocumentValues<Partial<Secrets> | null | undefined>(
17
- muxSecretsDocumentId,
18
- path,
19
- )
20
- const cache = useMemo(() => {
21
- const exists = Boolean(value)
22
- const secrets: Secrets = {
23
- token: value?.token || null,
24
- secretKey: value?.secretKey || null,
25
- enableSignedUrls: value?.enableSignedUrls || false,
26
- signingKeyId: value?.signingKeyId || null,
27
- signingKeyPrivate: value?.signingKeyPrivate || null,
28
- drmConfigId: value?.drmConfigId || null,
29
- }
30
- return {
31
- isInitialSetup: !exists,
32
- needsSetup: !secrets?.token || !secrets?.secretKey,
33
- secrets,
34
- }
35
- }, [value])
36
-
37
- return {error, isLoading, value: cache}
38
- }
@@ -1,47 +0,0 @@
1
- import {useReducer} from 'react'
2
-
3
- import type {Secrets} from '../util/types'
4
-
5
- export interface State extends Pick<
6
- Secrets,
7
- 'token' | 'secretKey' | 'enableSignedUrls' | 'drmConfigId'
8
- > {
9
- submitting: boolean
10
- error: string | null
11
- }
12
- export type Action =
13
- | {type: 'submit'}
14
- | {type: 'error'; payload: string}
15
- | {type: 'reset'; payload: Secrets}
16
- | {type: 'change'; payload: {name: 'token'; value: string}}
17
- | {type: 'change'; payload: {name: 'secretKey'; value: string}}
18
- | {type: 'change'; payload: {name: 'enableSignedUrls'; value: boolean}}
19
- | {type: 'change'; payload: {name: 'drmConfigId'; value: string}}
20
- function init({token, secretKey, enableSignedUrls, drmConfigId}: Secrets): State {
21
- return {
22
- submitting: false,
23
- error: null,
24
- // Form inputs don't set the state back to null when clearing a field, but uses empty strings
25
- // This ensures the `dirty` check works correctly
26
- token: token ?? '',
27
- secretKey: secretKey ?? '',
28
- enableSignedUrls: enableSignedUrls ?? false,
29
- drmConfigId: drmConfigId ?? '',
30
- }
31
- }
32
- function reducer(state: State, action: Action) {
33
- switch (action?.type) {
34
- case 'submit':
35
- return {...state, submitting: true, error: null}
36
- case 'error':
37
- return {...state, submitting: false, error: action.payload}
38
- case 'reset':
39
- return init(action.payload)
40
- case 'change':
41
- return {...state, [action.payload.name]: action.payload.value}
42
- default:
43
- throw new Error(`Unknown action type: ${(action as unknown as Action)?.type}`)
44
- }
45
- }
46
-
47
- export const useSecretsFormState = (secrets: Secrets) => useReducer(reducer, secrets, init)
package/src/plugin.tsx DELETED
@@ -1,31 +0,0 @@
1
- import Input from './components/Input'
2
- import VideoThumbnail from './components/VideoThumbnail'
3
- import type {MuxInputProps, PluginConfig, VideoAssetDocument} from './util/types'
4
-
5
- export function muxVideoCustomRendering(config: PluginConfig) {
6
- return {
7
- components: {
8
- input: (props: MuxInputProps) => (
9
- <Input config={{...config, ...props.schemaType.options}} {...props} />
10
- ),
11
- },
12
- preview: {
13
- select: {
14
- filename: 'asset.filename',
15
- playbackId: 'asset.playbackId',
16
- status: 'asset.status',
17
- assetId: 'asset.assetId',
18
- thumbTime: 'asset.thumbTime',
19
- data: 'asset.data',
20
- },
21
- prepare: (asset: Partial<VideoAssetDocument>) => {
22
- const {filename, playbackId, status} = asset
23
- return {
24
- title: filename || playbackId || '',
25
- subtitle: status ? `status: ${status}` : null,
26
- media: asset.playbackId ? <VideoThumbnail asset={asset} width={64} /> : null,
27
- }
28
- },
29
- },
30
- }
31
- }
@@ -1,5 +0,0 @@
1
- import {type Theme} from '@sanity/ui/theme'
2
-
3
- declare module 'styled-components' {
4
- interface DefaultTheme extends Theme {}
5
- }
package/src/schema.ts DELETED
@@ -1,196 +0,0 @@
1
- export const muxVideoSchema = {
2
- name: 'mux.video',
3
- type: 'object',
4
- title: 'Video asset reference',
5
- fields: [
6
- {
7
- title: 'Video',
8
- name: 'asset',
9
- type: 'reference',
10
- weak: true,
11
- to: [{type: 'mux.videoAsset'}],
12
- },
13
- ],
14
- }
15
-
16
- const muxTrack = {
17
- name: 'mux.track',
18
- type: 'object',
19
- fields: [
20
- {type: 'string', name: 'id'},
21
- {type: 'string', name: 'type'},
22
- {type: 'number', name: 'max_width'},
23
- {type: 'number', name: 'max_frame_rate'},
24
- {type: 'number', name: 'duration'},
25
- {type: 'number', name: 'max_height'},
26
- {type: 'string', name: 'language_code'},
27
- {type: 'string', name: 'name'},
28
- {type: 'string', name: 'status'},
29
- {type: 'string', name: 'text_source'},
30
- {type: 'string', name: 'text_type'},
31
- ],
32
- }
33
-
34
- const muxPlaybackId = {
35
- name: 'mux.playbackId',
36
- type: 'object',
37
- fields: [
38
- {type: 'string', name: 'id'},
39
- {type: 'string', name: 'policy'},
40
- ],
41
- }
42
-
43
- const muxStaticRenditionFile = {
44
- name: 'mux.staticRenditionFile',
45
- type: 'object',
46
- fields: [
47
- {type: 'string', name: 'name'},
48
- {type: 'string', name: 'ext'},
49
- {type: 'number', name: 'height'},
50
- {type: 'number', name: 'width'},
51
- {type: 'number', name: 'bitrate'},
52
- {type: 'string', name: 'filesize'},
53
- {type: 'string', name: 'type'},
54
- {type: 'string', name: 'status'},
55
- {type: 'string', name: 'resolution_tier'},
56
- {type: 'string', name: 'resolution'},
57
- {type: 'string', name: 'id'},
58
- {type: 'string', name: 'passthrough'},
59
- ],
60
- }
61
-
62
- const muxStaticRenditions = {
63
- name: 'mux.staticRenditions',
64
- type: 'object',
65
- fields: [
66
- {type: 'string', name: 'status'},
67
- {
68
- name: 'files',
69
- type: 'array',
70
- of: [{type: 'mux.staticRenditionFile'}],
71
- },
72
- ],
73
- }
74
-
75
- const muxAssetData = {
76
- name: 'mux.assetData',
77
- title: 'Mux asset data',
78
- type: 'object',
79
- fields: [
80
- {
81
- type: 'string',
82
- name: 'resolution_tier',
83
- },
84
- {
85
- type: 'string',
86
- name: 'upload_id',
87
- },
88
- {
89
- type: 'string',
90
- name: 'created_at',
91
- },
92
- {
93
- type: 'string',
94
- name: 'id',
95
- },
96
- {
97
- type: 'string',
98
- name: 'status',
99
- },
100
- {
101
- type: 'string',
102
- name: 'max_stored_resolution',
103
- },
104
- {
105
- type: 'string',
106
- name: 'passthrough',
107
- },
108
- {
109
- type: 'string',
110
- name: 'encoding_tier',
111
- },
112
- {
113
- type: 'string',
114
- name: 'video_quality',
115
- },
116
- {
117
- type: 'string',
118
- name: 'master_access',
119
- },
120
- {
121
- type: 'string',
122
- name: 'aspect_ratio',
123
- },
124
- {
125
- type: 'number',
126
- name: 'duration',
127
- },
128
- {
129
- type: 'number',
130
- name: 'max_stored_frame_rate',
131
- },
132
- {
133
- type: 'string',
134
- name: 'mp4_support',
135
- },
136
- {
137
- type: 'string',
138
- name: 'max_resolution_tier',
139
- },
140
- {
141
- name: 'tracks',
142
- type: 'array',
143
- of: [{type: 'mux.track'}],
144
- },
145
- {
146
- name: 'playback_ids',
147
- type: 'array',
148
- of: [{type: 'mux.playbackId'}],
149
- },
150
- {
151
- name: 'static_renditions',
152
- type: 'mux.staticRenditions',
153
- },
154
- ],
155
- }
156
-
157
- const muxVideoAsset = {
158
- name: 'mux.videoAsset',
159
- type: 'document',
160
- title: 'Video asset',
161
- fields: [
162
- {
163
- type: 'string',
164
- name: 'status',
165
- },
166
- {
167
- type: 'string',
168
- name: 'assetId',
169
- },
170
- {
171
- type: 'string',
172
- name: 'playbackId',
173
- },
174
- {
175
- type: 'string',
176
- name: 'filename',
177
- },
178
- {
179
- type: 'number',
180
- name: 'thumbTime',
181
- },
182
- {
183
- type: 'mux.assetData',
184
- name: 'data',
185
- },
186
- ],
187
- }
188
-
189
- export const schemaTypes = [
190
- muxTrack,
191
- muxPlaybackId,
192
- muxStaticRenditionFile,
193
- muxStaticRenditions,
194
- muxAssetData,
195
- muxVideoAsset,
196
- ]
@@ -1,30 +0,0 @@
1
- import {uuid} from '@sanity/uuid'
2
-
3
- import type {MuxAsset} from './types'
4
-
5
- /**
6
- * Adds _key to array items in MuxAsset data for Sanity compatibility.
7
- * Sanity requires _key on array items for proper editing support.
8
- */
9
- export function addKeysToMuxData(data: MuxAsset): MuxAsset {
10
- return {
11
- ...data,
12
- tracks: data.tracks?.map((track) => ({
13
- ...track,
14
- _key: uuid(),
15
- })),
16
- playback_ids: data.playback_ids?.map((playbackId) => ({
17
- ...playbackId,
18
- _key: uuid(),
19
- })),
20
- static_renditions: data.static_renditions
21
- ? {
22
- ...data.static_renditions,
23
- files: data.static_renditions.files?.map((file) => ({
24
- ...file,
25
- _key: uuid(),
26
- })),
27
- }
28
- : undefined,
29
- }
30
- }
@@ -1,23 +0,0 @@
1
- import {ServerError} from '@sanity/client'
2
-
3
- export function isValidUrl(url: string): boolean {
4
- try {
5
- const parsed = new URL(url)
6
- return parsed && !!parsed.protocol.match(/http:|https:/)
7
- } catch {
8
- return false
9
- }
10
- }
11
-
12
- /**
13
- * We consider a server error one with status code 5XX.
14
- * Used mainly to handle unknown Proxy issues.
15
- */
16
- export function isServerError(error: Error): error is ServerError {
17
- return (
18
- 'statusCode' in error &&
19
- typeof error.statusCode === 'number' &&
20
- 500 <= error.statusCode &&
21
- error.statusCode <= 600
22
- )
23
- }
@@ -1,31 +0,0 @@
1
- import {truncateString} from 'sanity'
2
-
3
- /**
4
- * Generates a placeholder title for a Mux asset when no title is available.
5
- * This format is used when importing assets that don't have a title in Mux.
6
- *
7
- * @param assetId - The Mux asset ID
8
- * @returns A placeholder title in the format "Asset #[truncated-id]"
9
- */
10
- export function generateAssetPlaceholder(assetId: string): string {
11
- return `Asset #${truncateString(assetId, 15)}`
12
- }
13
-
14
- /**
15
- * Checks if a filename is empty or has the placeholder format.
16
- * This is used to determine if a video title should be updated during metadata sync.
17
- *
18
- * @param filename - The current filename/title of the video
19
- * @param assetId - The Mux asset ID to check against
20
- * @returns true if the filename is empty or matches the placeholder format
21
- */
22
- export function isEmptyOrPlaceholderTitle(filename: string | undefined, assetId: string): boolean {
23
- // Check if filename is empty/undefined
24
- if (!filename || filename.trim() === '') {
25
- return true
26
- }
27
-
28
- // Check if filename matches the placeholder format for this asset
29
- const placeholder = generateAssetPlaceholder(assetId)
30
- return filename === placeholder
31
- }
@@ -1,15 +0,0 @@
1
- export const name = 'mux-input' as const
2
-
3
- // Caching namespace, as suspend-react might be in use by other components on the page we must ensure we don't collide
4
- export const cacheNs = 'sanity-plugin-mux-input' as const
5
-
6
- export const muxSecretsDocumentId = 'secrets.mux' as const
7
-
8
- export const DIALOGS_Z_INDEX = 60_000
9
-
10
- export const THUMBNAIL_ASPECT_RATIO = 16 / 9
11
-
12
- /** To prevent excessive height, thumbnails and input should not go beyond to this aspect ratio. */
13
- export const MIN_ASPECT_RATIO = 5 / 4
14
-
15
- export const AUDIO_ASPECT_RATIO = 5 / 1