sanity-plugin-mux-input 2.11.1 → 2.12.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.
package/dist/index.mjs CHANGED
@@ -1526,7 +1526,7 @@ function VideoPlayer({
1526
1526
  crossOrigin: "anonymous",
1527
1527
  metadata: {
1528
1528
  player_name: "Sanity Admin Dashboard",
1529
- player_version: "2.11.1",
1529
+ player_version: "2.12.0",
1530
1530
  page_type: "Preview Player"
1531
1531
  },
1532
1532
  audio: isAudio,
@@ -1617,21 +1617,21 @@ function PublishedStatus(props) {
1617
1617
  }
1618
1618
  function PaneItemPreview(props) {
1619
1619
  const { icon, layout, presence, schemaType, value } = props, title = isRecord(value.title) && isValidElement(value.title) || isString(value.title) || isNumber(value.title) ? value.title : null, observable = useMemo(
1620
- () => getPreviewStateObservable(props.documentPreviewStore, schemaType, value._id, title),
1621
- [props.documentPreviewStore, schemaType, title, value._id]
1622
- ), { draft, published, isLoading } = useObservable(observable, {
1623
- draft: null,
1624
- published: null,
1625
- isLoading: !0
1620
+ () => getPreviewStateObservable(props.documentPreviewStore, schemaType, value._id),
1621
+ [props.documentPreviewStore, schemaType, value._id]
1622
+ ), { snapshot, original, isLoading } = useObservable(observable, {
1623
+ isLoading: !0,
1624
+ snapshot: null,
1625
+ original: null
1626
1626
  }), status = isLoading ? null : /* @__PURE__ */ jsxs(Inline, { space: 4, children: [
1627
1627
  presence && presence.length > 0 && /* @__PURE__ */ jsx(DocumentPreviewPresence, { presence }),
1628
- /* @__PURE__ */ jsx(PublishedStatus, { document: published }),
1629
- /* @__PURE__ */ jsx(DraftStatus, { document: draft })
1628
+ /* @__PURE__ */ jsx(PublishedStatus, { document: original }),
1629
+ /* @__PURE__ */ jsx(DraftStatus, { document: snapshot })
1630
1630
  ] });
1631
1631
  return /* @__PURE__ */ jsx(
1632
1632
  SanityDefaultPreview,
1633
1633
  {
1634
- ...getPreviewValueWithFallback({ value, draft, published }),
1634
+ ...getPreviewValueWithFallback({ snapshot, original, fallback: { title } }),
1635
1635
  isPlaceholder: isLoading,
1636
1636
  icon,
1637
1637
  layout,
@@ -2436,9 +2436,14 @@ const useAccessControl = (config) => {
2436
2436
  isReference(asset) ? asset._ref : "",
2437
2437
  path
2438
2438
  ), useMuxPolling = (asset) => {
2439
- const client = useClient(), projectId = useProjectId(), dataset = useDataset(), shouldFetch = useMemo(
2440
- () => !!asset?.assetId && (asset?.status === "preparing" || asset?.data?.static_renditions?.status === "preparing"),
2441
- [asset?.assetId, asset?.data?.static_renditions?.status, asset?.status]
2439
+ const client = useClient(), projectId = useProjectId(), dataset = useDataset(), isPreparingStaticRenditions = useMemo(() => {
2440
+ if (asset?.data?.static_renditions?.status && asset?.data?.static_renditions?.status !== "disabled")
2441
+ return !1;
2442
+ const files = asset?.data?.static_renditions?.files;
2443
+ return !files || files.length === 0 ? !1 : files.some((file) => file.status === "preparing");
2444
+ }, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files]), shouldFetch = useMemo(
2445
+ () => !!asset?.assetId && (asset?.status === "preparing" || isPreparingStaticRenditions),
2446
+ [asset?.assetId, asset?.status, isPreparingStaticRenditions]
2442
2447
  );
2443
2448
  return useSWR(
2444
2449
  shouldFetch ? `/${projectId}/addons/mux/assets/${dataset}/data/${asset?.assetId}` : null,
@@ -2453,7 +2458,7 @@ const useAccessControl = (config) => {
2453
2458
  { refreshInterval: 2e3, refreshWhenHidden: !0, dedupingInterval: 1e3 }
2454
2459
  );
2455
2460
  };
2456
- var c = function(r) {
2461
+ var c = (function(r) {
2457
2462
  var t, e;
2458
2463
  function n(t2) {
2459
2464
  var e2;
@@ -2469,7 +2474,7 @@ var c = function(r) {
2469
2474
  var r2 = this.state, t2 = this.props, e2 = t2.render, n2 = t2.children, o2 = t2.renderError;
2470
2475
  return r2.hasError ? o2 ? o2({ error: r2.error }) : null : e2 ? e2() : n2 || null;
2471
2476
  }, n;
2472
- }(PureComponent), u = function(r, t) {
2477
+ })(PureComponent), u = function(r, t) {
2473
2478
  switch (t.type) {
2474
2479
  case "catch":
2475
2480
  return { didCatch: !0, error: t.error };
@@ -2745,13 +2750,14 @@ function testUrl(url) {
2745
2750
  const error = new Error("Invalid URL");
2746
2751
  if (typeof url != "string")
2747
2752
  return throwError(error);
2753
+ const trimmedUrl = url.trim();
2748
2754
  let parsed;
2749
2755
  try {
2750
- parsed = new URL(url);
2756
+ parsed = new URL(trimmedUrl);
2751
2757
  } catch {
2752
2758
  return throwError(error);
2753
2759
  }
2754
- return parsed && !parsed.protocol.match(/http:|https:/) ? throwError(error) : of(url);
2760
+ return parsed && !parsed.protocol.match(/http:|https:/) ? throwError(error) : of(trimmedUrl);
2755
2761
  }
2756
2762
  function optionsFromFile(opts, file) {
2757
2763
  if (!(typeof window > "u" || !(file instanceof window.File)))
@@ -2926,7 +2932,12 @@ const TopControls = styled.div`
2926
2932
  ) : null
2927
2933
  ] }) });
2928
2934
  }, Player = ({ asset, buttons, readOnly, onChange }) => {
2929
- const isLoading = useMemo(() => asset?.status === "preparing" ? "Preparing the video" : asset?.status === "waiting_for_upload" ? "Waiting for upload to start" : asset?.status === "waiting" ? "Processing upload" : !(asset?.status === "ready" || typeof asset?.status > "u"), [asset]), isPreparingStaticRenditions = useMemo(() => asset?.data?.static_renditions?.status === "preparing", [asset?.data?.static_renditions?.status]), playRef = useRef(null), muteRef = useRef(null), handleCancelUpload = useCancelUpload(asset, onChange);
2935
+ const isLoading = useMemo(() => asset?.status === "preparing" ? "Preparing the video" : asset?.status === "waiting_for_upload" ? "Waiting for upload to start" : asset?.status === "waiting" ? "Processing upload" : !(asset?.status === "ready" || typeof asset?.status > "u"), [asset]), isPreparingStaticRenditions = useMemo(() => {
2936
+ if (asset?.data?.static_renditions?.status && asset?.data?.static_renditions?.status !== "disabled")
2937
+ return !1;
2938
+ const files = asset?.data?.static_renditions?.files;
2939
+ return !files || files.length === 0 ? !1 : files.some((file) => file.status === "preparing");
2940
+ }, [asset?.data?.static_renditions?.status, asset?.data?.static_renditions?.files]), playRef = useRef(null), muteRef = useRef(null), handleCancelUpload = useCancelUpload(asset, onChange);
2930
2941
  return useEffect(() => {
2931
2942
  const style = document.createElement("style");
2932
2943
  style.innerHTML = "button svg { vertical-align: middle; }", playRef.current?.shadowRoot && playRef.current.shadowRoot.appendChild(style), muteRef?.current?.shadowRoot && muteRef.current.shadowRoot.appendChild(style.cloneNode(!0));
@@ -3347,7 +3358,20 @@ const VIDEO_QUALITY_LEVELS = [
3347
3358
  { value: "1080p", label: "1080p" },
3348
3359
  { value: "1440p", label: "1440p (2k)" },
3349
3360
  { value: "2160p", label: "2160p (4k)" }
3361
+ ], ADVANCED_RESOLUTIONS = [
3362
+ { value: "270p", label: "270p" },
3363
+ { value: "360p", label: "360p" },
3364
+ { value: "480p", label: "480p" },
3365
+ { value: "540p", label: "540p" },
3366
+ { value: "720p", label: "720p" },
3367
+ { value: "1080p", label: "1080p" },
3368
+ { value: "1440p", label: "1440p" },
3369
+ { value: "2160p", label: "2160p" }
3350
3370
  ];
3371
+ function sanitizeStaticRenditions(renditions) {
3372
+ const hasHighest = renditions.includes("highest"), hasSpecificResolutions = renditions.some((r) => r !== "highest" && r !== "audio-only");
3373
+ return hasHighest && hasSpecificResolutions ? renditions.filter((r) => r === "highest" || r === "audio-only") : renditions;
3374
+ }
3351
3375
  function UploadConfiguration({
3352
3376
  stagedUpload,
3353
3377
  secrets,
@@ -3370,18 +3394,18 @@ function UploadConfiguration({
3370
3394
  case "video_quality":
3371
3395
  return action.value === "basic" ? Object.assign({}, prev, {
3372
3396
  video_quality: action.value,
3373
- mp4_support: "none",
3397
+ static_renditions: [],
3374
3398
  max_resolution_tier: "1080p",
3375
3399
  text_tracks: prev.text_tracks?.filter(({ type }) => type !== "autogenerated"),
3376
3400
  public_policy: !0,
3377
3401
  signed_policy: !1
3378
3402
  }) : Object.assign({}, prev, {
3379
3403
  video_quality: action.value,
3380
- mp4_support: pluginConfig.mp4_support,
3404
+ static_renditions: sanitizeStaticRenditions(pluginConfig.static_renditions || []),
3381
3405
  max_resolution_tier: pluginConfig.max_resolution_tier,
3382
3406
  text_tracks: [...autoTextTracks, ...prev.text_tracks || []]
3383
3407
  });
3384
- case "mp4_support":
3408
+ case "static_renditions":
3385
3409
  case "max_resolution_tier":
3386
3410
  case "normalize_audio":
3387
3411
  case "signed_policy":
@@ -3420,13 +3444,34 @@ function UploadConfiguration({
3420
3444
  {
3421
3445
  video_quality: pluginConfig.video_quality,
3422
3446
  max_resolution_tier: pluginConfig.max_resolution_tier,
3423
- mp4_support: pluginConfig.mp4_support,
3447
+ static_renditions: sanitizeStaticRenditions(pluginConfig.static_renditions || []),
3424
3448
  signed_policy: secrets.enableSignedUrls && pluginConfig.defaultSigned,
3425
3449
  public_policy: pluginConfig.defaultPublic,
3426
3450
  normalize_audio: pluginConfig.normalize_audio,
3427
3451
  text_tracks: autoTextTracks
3428
3452
  }
3429
- ), { disableTextTrackConfig, disableUploadConfig } = pluginConfig, skipConfig = disableTextTrackConfig && disableUploadConfig;
3453
+ ), isAdvancedMode = useMemo(() => config.static_renditions.filter(
3454
+ (r) => r !== "highest" && r !== "audio-only"
3455
+ ).length > 0, [config.static_renditions]), [renditionMode, setRenditionMode] = useState(
3456
+ isAdvancedMode ? "advanced" : "standard"
3457
+ ), toggleRendition = (rendition) => {
3458
+ const current = config.static_renditions, hasRendition = current.includes(rendition);
3459
+ dispatch(hasRendition ? {
3460
+ action: "static_renditions",
3461
+ value: current.filter((r) => r !== rendition)
3462
+ } : {
3463
+ action: "static_renditions",
3464
+ value: [...current, rendition]
3465
+ });
3466
+ }, handleModeChange = (mode) => {
3467
+ setRenditionMode(mode), dispatch(mode === "standard" ? {
3468
+ action: "static_renditions",
3469
+ value: config.static_renditions.filter((r) => r === "highest" || r === "audio-only")
3470
+ } : {
3471
+ action: "static_renditions",
3472
+ value: config.static_renditions.filter((r) => r !== "highest")
3473
+ });
3474
+ }, { disableTextTrackConfig, disableUploadConfig } = pluginConfig, skipConfig = disableTextTrackConfig && disableUploadConfig;
3430
3475
  if (useEffect(() => {
3431
3476
  skipConfig && startUpload(formatUploadConfig(config));
3432
3477
  }, []), skipConfig) return null;
@@ -3541,25 +3586,101 @@ function UploadConfiguration({
3541
3586
  }) })
3542
3587
  }
3543
3588
  ),
3544
- !basicConfig && /* @__PURE__ */ jsx(FormField$2, { title: "Additional Configuration", children: /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
3589
+ !basicConfig && /* @__PURE__ */ jsx(FormField$2, { title: "Additional Configuration", children: /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
3545
3590
  /* @__PURE__ */ jsx(PlaybackPolicy, { id, config, secrets, dispatch }),
3546
- !basicConfig && /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, padding: [0, 2], children: [
3547
- /* @__PURE__ */ jsx(
3548
- Checkbox,
3549
- {
3550
- id: `${id}--mp4_support`,
3551
- style: { display: "block" },
3552
- name: "mp4_support",
3553
- required: !0,
3554
- checked: config.mp4_support === "standard",
3555
- onChange: (e) => dispatch({
3556
- action: "mp4_support",
3557
- value: e.currentTarget.checked ? "standard" : "none"
3558
- })
3559
- }
3560
- ),
3561
- /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsx("label", { htmlFor: `${id}--mp4_support`, children: "MP4 support (allow downloading)" }) })
3562
- ] })
3591
+ /* @__PURE__ */ jsx(Stack, { space: 3, children: /* @__PURE__ */ jsx(
3592
+ FormField$2,
3593
+ {
3594
+ title: "Static Renditions",
3595
+ description: "Generate downloadable MP4 or M4A files. Note: Mux will not upscale to produce MP4 renditions - renditions that would cause upscaling are skipped.",
3596
+ children: /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
3597
+ /* @__PURE__ */ jsxs(Flex, { gap: 3, children: [
3598
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
3599
+ /* @__PURE__ */ jsx(
3600
+ Radio,
3601
+ {
3602
+ checked: renditionMode === "standard",
3603
+ name: "rendition-mode",
3604
+ onChange: () => handleModeChange("standard"),
3605
+ value: "standard",
3606
+ id: `${id}--mode-standard`
3607
+ }
3608
+ ),
3609
+ /* @__PURE__ */ jsx(Text, { as: "label", htmlFor: `${id}--mode-standard`, children: "Standard" })
3610
+ ] }),
3611
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
3612
+ /* @__PURE__ */ jsx(
3613
+ Radio,
3614
+ {
3615
+ checked: renditionMode === "advanced",
3616
+ name: "rendition-mode",
3617
+ onChange: () => handleModeChange("advanced"),
3618
+ value: "advanced",
3619
+ id: `${id}--mode-advanced`
3620
+ }
3621
+ ),
3622
+ /* @__PURE__ */ jsx(Text, { as: "label", htmlFor: `${id}--mode-advanced`, children: "Advanced" })
3623
+ ] })
3624
+ ] }),
3625
+ renditionMode === "standard" && /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
3626
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, padding: [0, 2], children: [
3627
+ /* @__PURE__ */ jsx(
3628
+ Checkbox,
3629
+ {
3630
+ id: `${id}--highest`,
3631
+ style: { display: "block" },
3632
+ checked: config.static_renditions.includes("highest"),
3633
+ onChange: () => toggleRendition("highest")
3634
+ }
3635
+ ),
3636
+ /* @__PURE__ */ jsx(Text, { as: "label", htmlFor: `${id}--highest`, children: "Highest Resolution (up to 4K)" })
3637
+ ] }),
3638
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, padding: [0, 2], children: [
3639
+ /* @__PURE__ */ jsx(
3640
+ Checkbox,
3641
+ {
3642
+ id: `${id}--audio-only-standard`,
3643
+ style: { display: "block" },
3644
+ checked: config.static_renditions.includes("audio-only"),
3645
+ onChange: () => toggleRendition("audio-only")
3646
+ }
3647
+ ),
3648
+ /* @__PURE__ */ jsx(Text, { as: "label", htmlFor: `${id}--audio-only-standard`, children: "Audio Only (M4A)" })
3649
+ ] })
3650
+ ] }),
3651
+ renditionMode === "advanced" && /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
3652
+ /* @__PURE__ */ jsx(Label$1, { size: 1, muted: !0, children: "Select specific resolutions:" }),
3653
+ /* @__PURE__ */ jsx(Flex, { gap: 2, wrap: "wrap", children: ADVANCED_RESOLUTIONS.map(({ value, label }) => {
3654
+ const inputId = `${id}--resolution-${value}`;
3655
+ return /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
3656
+ /* @__PURE__ */ jsx(
3657
+ Checkbox,
3658
+ {
3659
+ id: inputId,
3660
+ style: { display: "block" },
3661
+ checked: config.static_renditions.includes(value),
3662
+ onChange: () => toggleRendition(value)
3663
+ }
3664
+ ),
3665
+ /* @__PURE__ */ jsx(Text, { as: "label", htmlFor: inputId, size: 1, children: label })
3666
+ ] }, value);
3667
+ }) }),
3668
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, padding: [2, 2, 0, 2], children: [
3669
+ /* @__PURE__ */ jsx(
3670
+ Checkbox,
3671
+ {
3672
+ id: `${id}--audio-only-advanced`,
3673
+ style: { display: "block" },
3674
+ checked: config.static_renditions.includes("audio-only"),
3675
+ onChange: () => toggleRendition("audio-only")
3676
+ }
3677
+ ),
3678
+ /* @__PURE__ */ jsx(Text, { as: "label", htmlFor: `${id}--audio-only-advanced`, children: "Audio Only (M4A)" })
3679
+ ] })
3680
+ ] })
3681
+ ] })
3682
+ }
3683
+ ) })
3563
3684
  ] }) })
3564
3685
  ] }),
3565
3686
  !disableTextTrackConfig && !basicConfig && /* @__PURE__ */ jsx(
@@ -3611,7 +3732,7 @@ function formatUploadConfig(config) {
3611
3732
  []
3612
3733
  )
3613
3734
  ],
3614
- mp4_support: config.mp4_support,
3735
+ static_renditions: config.static_renditions.length > 0 ? config.static_renditions.map((resolution) => ({ resolution })) : void 0,
3615
3736
  playback_policy: setPlaybackPolicy(config),
3616
3737
  max_resolution_tier: config.max_resolution_tier,
3617
3738
  video_quality: config.video_quality,
@@ -3789,7 +3910,7 @@ function Uploader(props) {
3789
3910
  const events$ = new Subject();
3790
3911
  return {
3791
3912
  observable: events$.asObservable(),
3792
- handleClick: (event) => events$.next(event)
3913
+ handleClick: ((event) => events$.next(event))
3793
3914
  };
3794
3915
  })()
3795
3916
  ).current, uploadRef = useRef(null), uploadingDocumentId = useRef(null), [state, dispatch] = useReducer(
@@ -3800,7 +3921,7 @@ function Uploader(props) {
3800
3921
  case "commitUpload":
3801
3922
  return Object.assign({}, prev, { uploadStatus: { progress: 0 } });
3802
3923
  case "progressInfo": {
3803
- const { ...payload } = action;
3924
+ const { type, action: _, ...payload } = action;
3804
3925
  return Object.assign({}, prev, {
3805
3926
  uploadStatus: {
3806
3927
  ...prev.uploadStatus,
@@ -3908,7 +4029,7 @@ function Uploader(props) {
3908
4029
  });
3909
4030
  }, handlePaste = (event) => {
3910
4031
  event.preventDefault(), event.stopPropagation();
3911
- const url = (event.clipboardData || window.clipboardData).getData("text");
4032
+ const url = (event.clipboardData || window.clipboardData).getData("text")?.trim();
3912
4033
  if (!isValidUrl(url)) {
3913
4034
  toast.push({ status: "error", title: "Invalid URL for Mux video input." });
3914
4035
  return;
@@ -4114,12 +4235,18 @@ const muxVideoSchema = {
4114
4235
  name: "mux.staticRenditionFile",
4115
4236
  type: "object",
4116
4237
  fields: [
4117
- { type: "string", name: "ext" },
4118
4238
  { type: "string", name: "name" },
4239
+ { type: "string", name: "ext" },
4240
+ { type: "number", name: "height" },
4119
4241
  { type: "number", name: "width" },
4120
4242
  { type: "number", name: "bitrate" },
4121
- { type: "number", name: "filesize" },
4122
- { type: "number", name: "height" }
4243
+ { type: "string", name: "filesize" },
4244
+ { type: "string", name: "type" },
4245
+ { type: "string", name: "status" },
4246
+ { type: "string", name: "resolution_tier" },
4247
+ { type: "string", name: "resolution" },
4248
+ { type: "string", name: "id" },
4249
+ { type: "string", name: "passthrough" }
4123
4250
  ]
4124
4251
  }, muxStaticRenditions = {
4125
4252
  name: "mux.staticRenditions",
@@ -4250,6 +4377,7 @@ const muxVideoSchema = {
4250
4377
  muxAssetData,
4251
4378
  muxVideoAsset
4252
4379
  ], defaultConfig = {
4380
+ static_renditions: [],
4253
4381
  mp4_support: "none",
4254
4382
  video_quality: "plus",
4255
4383
  max_resolution_tier: "1080p",
@@ -4258,12 +4386,20 @@ const muxVideoSchema = {
4258
4386
  defaultSigned: !1,
4259
4387
  tool: DEFAULT_TOOL_CONFIG,
4260
4388
  allowedRolesForConfiguration: []
4261
- }, muxInput = definePlugin((userConfig) => {
4389
+ };
4390
+ function convertLegacyConfig(config) {
4391
+ return config.static_renditions && config.static_renditions.length > 0 ? { static_renditions: config.static_renditions } : config.mp4_support === "standard" ? { static_renditions: ["highest"] } : { static_renditions: [] };
4392
+ }
4393
+ const muxInput = definePlugin((userConfig) => {
4262
4394
  if (typeof userConfig == "object" && "encoding_tier" in userConfig) {
4263
4395
  const deprecated_encoding_tier = userConfig.encoding_tier;
4264
4396
  userConfig.video_quality || (deprecated_encoding_tier === "baseline" && (userConfig.video_quality = "basic"), deprecated_encoding_tier === "smart" && (userConfig.video_quality = "plus"));
4265
4397
  }
4266
- const config = { ...defaultConfig, ...userConfig || {} };
4398
+ const config = {
4399
+ ...defaultConfig,
4400
+ ...userConfig || {},
4401
+ ...convertLegacyConfig(userConfig || {})
4402
+ };
4267
4403
  return {
4268
4404
  name: "mux-input",
4269
4405
  schema: {