sanity-plugin-mux-input 3.0.4 → 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 (130) hide show
  1. package/README.md +0 -2
  2. package/dist/index.d.ts +134 -193
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +2893 -4417
  5. package/dist/index.js.map +1 -1
  6. package/package.json +33 -43
  7. package/dist/index.cjs +0 -7270
  8. package/dist/index.cjs.map +0 -1
  9. package/dist/index.d.cts +0 -347
  10. package/sanity.json +0 -8
  11. package/src/_exports/index.ts +0 -73
  12. package/src/actions/assets.ts +0 -152
  13. package/src/actions/secrets.ts +0 -111
  14. package/src/actions/upload.ts +0 -310
  15. package/src/clients/upChunkObservable.ts +0 -54
  16. package/src/components/AddCaptionDialog.tsx +0 -440
  17. package/src/components/CaptionsDialog.tsx +0 -23
  18. package/src/components/ConfigureApi.styled.tsx +0 -19
  19. package/src/components/ConfigureApi.tsx +0 -296
  20. package/src/components/DraggableWatermark.tsx +0 -877
  21. package/src/components/EditCaptionDialog.tsx +0 -510
  22. package/src/components/EditThumbnailDialog.tsx +0 -122
  23. package/src/components/ErrorBoundaryCard.tsx +0 -96
  24. package/src/components/FileInputButton.tsx +0 -54
  25. package/src/components/FileInputMenuItem.styled.tsx +0 -36
  26. package/src/components/FileInputMenuItem.tsx +0 -85
  27. package/src/components/FormField.tsx +0 -38
  28. package/src/components/IconInfo.tsx +0 -22
  29. package/src/components/ImportVideosFromMux.tsx +0 -342
  30. package/src/components/Input.styled.tsx +0 -22
  31. package/src/components/Input.tsx +0 -78
  32. package/src/components/InputBrowser.tsx +0 -41
  33. package/src/components/InputError.tsx +0 -17
  34. package/src/components/MuxLogo.tsx +0 -42
  35. package/src/components/Onboard.tsx +0 -65
  36. package/src/components/PageSelector.tsx +0 -54
  37. package/src/components/Player.styled.tsx +0 -55
  38. package/src/components/Player.tsx +0 -117
  39. package/src/components/PlayerActionsMenu.tsx +0 -190
  40. package/src/components/ResyncMetadata.tsx +0 -280
  41. package/src/components/SelectAsset.tsx +0 -39
  42. package/src/components/SelectSortOptions.tsx +0 -45
  43. package/src/components/SpinnerBox.tsx +0 -16
  44. package/src/components/StudioTool.tsx +0 -24
  45. package/src/components/TextTracksEditor.tsx +0 -117
  46. package/src/components/TextTracksManager.tsx +0 -737
  47. package/src/components/UploadConfiguration.tsx +0 -694
  48. package/src/components/UploadPlaceholder.tsx +0 -88
  49. package/src/components/UploadProgress.tsx +0 -80
  50. package/src/components/Uploader.styled.tsx +0 -66
  51. package/src/components/Uploader.tsx +0 -498
  52. package/src/components/VideoDetails/DeleteDialog.tsx +0 -147
  53. package/src/components/VideoDetails/VideoDetails.tsx +0 -358
  54. package/src/components/VideoDetails/VideoReferences.tsx +0 -63
  55. package/src/components/VideoDetails/useVideoDetails.ts +0 -103
  56. package/src/components/VideoInBrowser.tsx +0 -245
  57. package/src/components/VideoMetadata.tsx +0 -45
  58. package/src/components/VideoPlayer.tsx +0 -235
  59. package/src/components/VideoThumbnail.tsx +0 -138
  60. package/src/components/VideosBrowser.tsx +0 -100
  61. package/src/components/documentPreview/DocumentPreview.tsx +0 -83
  62. package/src/components/documentPreview/DraftStatus.tsx +0 -34
  63. package/src/components/documentPreview/MissingSchemaType.tsx +0 -32
  64. package/src/components/documentPreview/PaneItemPreview.tsx +0 -74
  65. package/src/components/documentPreview/PublishedStatus.tsx +0 -35
  66. package/src/components/documentPreview/TimeAgo.tsx +0 -12
  67. package/src/components/documentPreview/paneItemTypes.ts +0 -7
  68. package/src/components/icons/Audio.tsx +0 -13
  69. package/src/components/icons/Resolution.tsx +0 -12
  70. package/src/components/icons/StopWatch.tsx +0 -20
  71. package/src/components/icons/ToolIcon.tsx +0 -19
  72. package/src/components/uploadConfiguration/PlaybackPolicy.tsx +0 -133
  73. package/src/components/uploadConfiguration/PlaybackPolicyOption.tsx +0 -76
  74. package/src/components/uploadConfiguration/PlaybackPolicyWarning.tsx +0 -29
  75. package/src/components/uploadConfiguration/ResolutionTierSelector.tsx +0 -72
  76. package/src/components/uploadConfiguration/StaticRenditionSelector.tsx +0 -180
  77. package/src/components/withFocusRing/helpers.ts +0 -24
  78. package/src/components/withFocusRing/index.ts +0 -1
  79. package/src/components/withFocusRing/withFocusRing.ts +0 -30
  80. package/src/context/DialogStateContext.tsx +0 -36
  81. package/src/context/DrmPlaybackWarningContext.tsx +0 -93
  82. package/src/hooks/useAccessControl.ts +0 -13
  83. package/src/hooks/useAssetDocumentValues.ts +0 -11
  84. package/src/hooks/useAssets.ts +0 -68
  85. package/src/hooks/useCancelUpload.ts +0 -22
  86. package/src/hooks/useClient.ts +0 -8
  87. package/src/hooks/useDialogState.ts +0 -11
  88. package/src/hooks/useDocReferences.ts +0 -21
  89. package/src/hooks/useFetchFileSize.ts +0 -54
  90. package/src/hooks/useImportMuxAssets.ts +0 -132
  91. package/src/hooks/useInView.ts +0 -42
  92. package/src/hooks/useMediaMetadata.ts +0 -103
  93. package/src/hooks/useMuxAssets.ts +0 -179
  94. package/src/hooks/useMuxPolling.ts +0 -49
  95. package/src/hooks/useResyncAsset.ts +0 -110
  96. package/src/hooks/useResyncMuxMetadata.ts +0 -176
  97. package/src/hooks/useSaveSecrets.ts +0 -78
  98. package/src/hooks/useSecretsDocumentValues.ts +0 -38
  99. package/src/hooks/useSecretsFormState.ts +0 -47
  100. package/src/plugin.tsx +0 -31
  101. package/src/sanity-ui.d.ts +0 -5
  102. package/src/schema.ts +0 -196
  103. package/src/util/addKeysToMuxData.ts +0 -30
  104. package/src/util/areSecretsSignable.ts +0 -5
  105. package/src/util/asserters.ts +0 -36
  106. package/src/util/assetTitlePlaceholder.ts +0 -31
  107. package/src/util/constants.ts +0 -15
  108. package/src/util/convertWatermarkToMux.ts +0 -160
  109. package/src/util/createSearchFilter.ts +0 -76
  110. package/src/util/createUrlParamsObject.ts +0 -29
  111. package/src/util/extractFiles.ts +0 -67
  112. package/src/util/formatBytes.ts +0 -32
  113. package/src/util/formatDriveShareLink.ts +0 -64
  114. package/src/util/formatSeconds.ts +0 -49
  115. package/src/util/generateJwt.ts +0 -57
  116. package/src/util/getAnimatedPosterSrc.ts +0 -26
  117. package/src/util/getPlaybackPolicy.ts +0 -69
  118. package/src/util/getPosterSrc.ts +0 -28
  119. package/src/util/getStoryboardSrc.ts +0 -27
  120. package/src/util/getVideoMetadata.ts +0 -23
  121. package/src/util/getVideoSrc.ts +0 -23
  122. package/src/util/isSigned.ts +0 -20
  123. package/src/util/parsers.ts +0 -5
  124. package/src/util/pluginVersion.ts +0 -1
  125. package/src/util/readSecrets.ts +0 -38
  126. package/src/util/roundPxString.ts +0 -16
  127. package/src/util/textTracks.ts +0 -222
  128. package/src/util/tryWithSuspend.ts +0 -22
  129. package/src/util/types.ts +0 -596
  130. package/v2-incompatible.js +0 -11
@@ -1,176 +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 {MuxAsset, 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 type MatchedAsset = {
19
- sanityDoc: VideoAssetDocument
20
- muxAsset: MuxAsset | undefined
21
- muxTitle: string | undefined
22
- currentTitle: string | undefined
23
- }
24
-
25
- export default function useResyncMuxMetadata() {
26
- const documentStore = useDocumentStore()
27
- const client = useClient({
28
- apiVersion: SANITY_API_VERSION,
29
- })
30
-
31
- const [sanityAssets, sanityAssetsLoading] = useSanityAssets(documentStore)
32
-
33
- const secretDocumentValues = useSecretsDocumentValues()
34
- const hasSecrets = !!secretDocumentValues.value.secrets?.secretKey
35
-
36
- const [resyncError, setResyncError] = useState<unknown>()
37
- const [resyncState, setResyncState] = useState<ResyncState>('closed')
38
- const dialogOpen = resyncState !== 'closed'
39
-
40
- const muxAssets = useMuxAssets({
41
- client,
42
- enabled: hasSecrets && dialogOpen,
43
- })
44
-
45
- const matchedAssets = useMemo(() => {
46
- return sanityAssets && muxAssets.data
47
- ? sanityAssets.map((sanityDoc) => {
48
- const muxAsset = muxAssets.data?.find(
49
- (m) => m.id === sanityDoc.assetId || m.id === sanityDoc.data?.id
50
- )
51
- return {
52
- sanityDoc,
53
- muxAsset,
54
- muxTitle: muxAsset?.meta?.title,
55
- currentTitle: sanityDoc.filename,
56
- }
57
- })
58
- : undefined
59
- }, [sanityAssets, muxAssets.data])
60
-
61
- const closeDialog = () => {
62
- if (resyncState !== 'syncing') setResyncState('closed')
63
- }
64
-
65
- const openDialog = () => {
66
- if (resyncState === 'closed') setResyncState('idle')
67
- }
68
-
69
- async function syncAllVideos() {
70
- if (!matchedAssets) return
71
-
72
- setResyncState('syncing')
73
-
74
- try {
75
- const tx = client.transaction()
76
-
77
- matchedAssets.forEach((matched) => {
78
- // Update all videos with the Mux title, even if it's undefined/empty
79
- const newTitle = matched.muxTitle || ''
80
- tx.patch(matched.sanityDoc._id, {set: {filename: newTitle}})
81
- })
82
-
83
- await tx.commit({returnDocuments: false})
84
- setResyncState('done')
85
- } catch (error) {
86
- setResyncState('error')
87
- setResyncError(error)
88
- }
89
- }
90
-
91
- async function syncOnlyEmpty() {
92
- if (!matchedAssets) return
93
-
94
- setResyncState('syncing')
95
-
96
- try {
97
- const tx = client.transaction()
98
-
99
- matchedAssets.forEach((matched) => {
100
- // Only update if the current title is empty or has the placeholder format
101
- // AND there's a new title available from Mux
102
- if (
103
- matched.muxAsset &&
104
- matched.muxTitle &&
105
- isEmptyOrPlaceholderTitle(matched.currentTitle, matched.muxAsset.id)
106
- ) {
107
- tx.patch(matched.sanityDoc._id, {set: {filename: matched.muxTitle}})
108
- }
109
- })
110
-
111
- await tx.commit({returnDocuments: false})
112
- setResyncState('done')
113
- } catch (error) {
114
- setResyncState('error')
115
- setResyncError(error)
116
- }
117
- }
118
-
119
- async function syncFullData() {
120
- if (!matchedAssets) return
121
-
122
- setResyncState('syncing')
123
-
124
- try {
125
- const tx = client.transaction()
126
-
127
- matchedAssets.forEach((matched) => {
128
- if (!matched.muxAsset) return
129
-
130
- const dataWithKeys = addKeysToMuxData(matched.muxAsset)
131
-
132
- // Update all fields: filename, status, and full data from Mux
133
- tx.patch(matched.sanityDoc._id, {
134
- set: {
135
- filename: matched.muxTitle || matched.currentTitle || '',
136
- status: matched.muxAsset.status,
137
- data: dataWithKeys,
138
- },
139
- })
140
- })
141
-
142
- await tx.commit({returnDocuments: false})
143
- setResyncState('done')
144
- } catch (error) {
145
- setResyncState('error')
146
- setResyncError(error)
147
- }
148
- }
149
-
150
- return {
151
- sanityAssetsLoading,
152
- closeDialog,
153
- dialogOpen,
154
- resyncState,
155
- resyncError,
156
- hasSecrets,
157
- syncAllVideos,
158
- syncOnlyEmpty,
159
- syncFullData,
160
- matchedAssets,
161
- muxAssets,
162
- openDialog,
163
- }
164
- }
165
-
166
- const useSanityAssets = createHookFromObservableFactory<VideoAssetDocument[], DocumentStore>(
167
- (documentStore) => {
168
- return documentStore.listenQuery(
169
- /* groq */ `*[_type == "mux.videoAsset"]`,
170
- {},
171
- {
172
- apiVersion: SANITY_API_VERSION,
173
- }
174
- )
175
- }
176
- )
@@ -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,5 +0,0 @@
1
- import type {Secrets, SignableSecrets} from './types'
2
-
3
- export function areSecretsSignable(secrets: Secrets): secrets is SignableSecrets {
4
- return !!secrets.signingKeyId && !!secrets.signingKeyPrivate
5
- }
@@ -1,36 +0,0 @@
1
- import {ServerError} from '@sanity/client'
2
- import {type InputProps, isObjectInputProps, type PreviewLayoutKey, type PreviewProps} from 'sanity'
3
-
4
- import type {MuxInputPreviewProps, MuxInputProps} from './types'
5
-
6
- export function isMuxInputProps(props: InputProps): props is MuxInputProps {
7
- return isObjectInputProps(props) && props.schemaType.type?.name === 'mux.video'
8
- }
9
-
10
- export function isMuxInputPreviewProps(
11
- props: PreviewProps<PreviewLayoutKey>
12
- ): props is MuxInputPreviewProps {
13
- return props.schemaType?.type?.name === 'mux.video'
14
- }
15
-
16
- export function isValidUrl(url: string): boolean {
17
- try {
18
- const parsed = new URL(url)
19
- return parsed && !!parsed.protocol.match(/http:|https:/)
20
- } catch {
21
- return false
22
- }
23
- }
24
-
25
- /**
26
- * We consider a server error one with status code 5XX.
27
- * Used mainly to handle unknown Proxy issues.
28
- */
29
- export function isServerError(error: Error): error is ServerError {
30
- return (
31
- 'statusCode' in error &&
32
- typeof error.statusCode === 'number' &&
33
- 500 <= error.statusCode &&
34
- error.statusCode <= 600
35
- )
36
- }
@@ -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