@maas/payload-plugin-media-cloud 0.0.5 → 0.0.7

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 (35) hide show
  1. package/dist/adapter/handleDelete.js +3 -3
  2. package/dist/adapter/handleDelete.js.map +1 -1
  3. package/dist/collections/mediaCollection.js +5 -0
  4. package/dist/collections/mediaCollection.js.map +1 -1
  5. package/dist/components/upload-handler/upload-handler.js +7 -7
  6. package/dist/components/upload-handler/upload-handler.js.map +1 -1
  7. package/dist/components/upload-manager/upload-manager.js +6 -6
  8. package/dist/components/upload-manager/upload-manager.js.map +1 -1
  9. package/dist/endpoints/muxAssetHandler.js +1 -0
  10. package/dist/endpoints/muxAssetHandler.js.map +1 -1
  11. package/dist/endpoints/muxCreateUploadHandler.js +3 -3
  12. package/dist/endpoints/muxCreateUploadHandler.js.map +1 -1
  13. package/dist/error-handler/dist/index.js +43 -25
  14. package/dist/error-handler/dist/index.js.map +1 -1
  15. package/dist/hooks/useEmitter.d.ts +2 -3
  16. package/dist/hooks/useEmitter.js.map +1 -1
  17. package/dist/hooks/useErrorHandler.d.ts +5 -5
  18. package/dist/hooks/useErrorHandler.js +7 -6
  19. package/dist/hooks/useErrorHandler.js.map +1 -1
  20. package/dist/plugin.js +7 -7
  21. package/dist/plugin.js.map +1 -1
  22. package/dist/tus/stores/s3/file-operations.js +2 -2
  23. package/dist/tus/stores/s3/file-operations.js.map +1 -1
  24. package/dist/tus/stores/s3/metadata-manager.js +5 -5
  25. package/dist/tus/stores/s3/metadata-manager.js.map +1 -1
  26. package/dist/tus/stores/s3/parts-manager.js +8 -8
  27. package/dist/tus/stores/s3/parts-manager.js.map +1 -1
  28. package/dist/tus/stores/s3/s3-store.js +11 -11
  29. package/dist/tus/stores/s3/s3-store.js.map +1 -1
  30. package/dist/types/errors.d.ts +5 -37
  31. package/dist/types/errors.js +99 -38
  32. package/dist/types/errors.js.map +1 -1
  33. package/dist/utils/file.js +3 -3
  34. package/dist/utils/file.js.map +1 -1
  35. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { MediaCloudError } from "../types/errors.js";
1
+ import { MediaCloudErrors } from "../types/errors.js";
2
2
  import { useErrorHandler } from "../hooks/useErrorHandler.js";
3
3
 
4
4
  //#region src/adapter/handleDelete.ts
@@ -42,7 +42,7 @@ async function deleteMuxAsset(args) {
42
42
  await mux.video.assets.delete(asset.id);
43
43
  }
44
44
  } catch (_error) {
45
- logError(MediaCloudError.MUX_ASSET_DELETE_ERROR);
45
+ logError(MediaCloudErrors.MUX_ASSET_DELETE_ERROR);
46
46
  }
47
47
  }
48
48
  /**
@@ -61,7 +61,7 @@ async function deleteS3File(args) {
61
61
  Delete: { Objects: [{ Key: filename }, { Key: `${filename}.info` }] }
62
62
  });
63
63
  } catch (_error) {
64
- logError(MediaCloudError.S3_DELETE_ERROR);
64
+ logError(MediaCloudErrors.S3_DELETE_ERROR);
65
65
  }
66
66
  }
67
67
 
@@ -1 +1 @@
1
- {"version":3,"file":"handleDelete.js","names":["args: HandleDeleteArgs","args: DeleteMuxAssetArgs","args: DeleteS3FileArgs"],"sources":["../../src/adapter/handleDelete.ts"],"sourcesContent":["import { useErrorHandler } from '../hooks/useErrorHandler'\nimport { MediaCloudError } from '../types/errors'\n\nimport type { HandleDelete } from '@payloadcms/plugin-cloud-storage/types'\nimport type { Document } from 'payload'\nimport type { Mux } from '@mux/mux-node'\nimport type { S3Store } from '../tus/stores/s3/s3-store'\n\ninterface HandleDeleteArgs {\n s3Store: S3Store\n getMuxClient: () => Mux\n}\n\ninterface DeleteMuxAssetArgs {\n getMuxClient: () => Mux\n uploadId: string\n}\n\ninterface DeleteS3FileArgs {\n s3Store: S3Store\n filename: string\n}\n\nconst { logError } = useErrorHandler()\n\n/**\n * Creates a handle delete function for processing file deletions from both Mux and S3 storage\n * @param args - The arguments for creating the delete handler\n * @param args.s3Store - The S3Store instance for S3 file operations\n * @param args.getMuxClient - Function that returns a Mux client instance\n * @returns A HandleDelete function that processes deletion requests based on storage type\n */\nexport function getHandleDelete(args: HandleDeleteArgs): HandleDelete {\n const { s3Store, getMuxClient } = args\n return async ({ doc, req }) => {\n if (req?.method !== 'DELETE' || !doc) {\n return\n }\n\n const media = doc as Document\n\n if (media?.storage === 'mux' && media.mux?.uploadId) {\n await deleteMuxAsset({ getMuxClient, uploadId: media.mux.uploadId })\n } else if (media.filename) {\n await deleteS3File({ s3Store, filename: media.filename })\n }\n }\n}\n\n/**\n * Deletes a Mux asset by upload ID\n * @param args - The arguments for deleting the Mux asset\n * @param args.getMuxClient - Function that returns a Mux client instance\n * @param args.uploadId - The upload ID of the Mux asset to delete\n * @returns Promise that resolves when the asset is deleted or rejects on error\n */\nasync function deleteMuxAsset(args: DeleteMuxAssetArgs): Promise<void> {\n const { getMuxClient, uploadId } = args\n\n try {\n const mux = getMuxClient()\n const assets = await mux.video.assets.list({ upload_id: uploadId })\n if (assets.data.length > 0) {\n const asset = assets.data[0]\n await mux.video.assets.delete(asset.id)\n }\n } catch (_error) {\n logError(MediaCloudError.MUX_ASSET_DELETE_ERROR)\n }\n}\n\n/**\n * Deletes a file from S3 storage including its metadata info file\n * @param args - The arguments for deleting the S3 file\n * @param args.s3Store - The S3Store instance for S3 operations\n * @param args.filename - The filename of the file to delete from S3\n * @returns Promise that resolves when the file is deleted or rejects on error\n */\nasync function deleteS3File(args: DeleteS3FileArgs): Promise<void> {\n const { s3Store, filename } = args\n\n try {\n const { client, bucket } = s3Store\n await client.deleteObjects({\n Bucket: bucket,\n Delete: {\n Objects: [{ Key: filename }, { Key: `${filename}.info` }],\n },\n })\n } catch (_error) {\n logError(MediaCloudError.S3_DELETE_ERROR)\n }\n}\n"],"mappings":";;;;AAuBA,MAAM,EAAE,UAAU,GAAG,iBAAiB;;;;;;;;AAStC,SAAgB,gBAAgBA,MAAsC;CACpE,MAAM,EAAE,SAAS,cAAc,GAAG;AAClC,QAAO,OAAO,EAAE,KAAK,KAAK,KAAK;AAC7B,MAAI,KAAK,WAAW,YAAY,CAAC,IAC/B;EAGF,MAAM,QAAQ;AAEd,MAAI,OAAO,YAAY,SAAS,MAAM,KAAK,UACzC,MAAM,eAAe;GAAE;GAAc,UAAU,MAAM,IAAI;EAAU,EAAC;WAC3D,MAAM,UACf,MAAM,aAAa;GAAE;GAAS,UAAU,MAAM;EAAU,EAAC;CAE5D;AACF;;;;;;;;AASD,eAAe,eAAeC,MAAyC;CACrE,MAAM,EAAE,cAAc,UAAU,GAAG;AAEnC,KAAI;EACF,MAAM,MAAM,cAAc;EAC1B,MAAM,SAAS,MAAM,IAAI,MAAM,OAAO,KAAK,EAAE,WAAW,SAAU,EAAC;AACnE,MAAI,OAAO,KAAK,SAAS,GAAG;GAC1B,MAAM,QAAQ,OAAO,KAAK;GAC1B,MAAM,IAAI,MAAM,OAAO,OAAO,MAAM,GAAG;EACxC;CACF,SAAQ,QAAQ;EACf,SAAS,gBAAgB,uBAAuB;CACjD;AACF;;;;;;;;AASD,eAAe,aAAaC,MAAuC;CACjE,MAAM,EAAE,SAAS,UAAU,GAAG;AAE9B,KAAI;EACF,MAAM,EAAE,QAAQ,QAAQ,GAAG;EAC3B,MAAM,OAAO,cAAc;GACzB,QAAQ;GACR,QAAQ,EACN,SAAS,CAAC,EAAE,KAAK,SAAU,GAAE,EAAE,KAAK,GAAG,SAAS,KAAK,CAAC,CAAE,CAAC,EAC1D;EACF,EAAC;CACH,SAAQ,QAAQ;EACf,SAAS,gBAAgB,gBAAgB;CAC1C;AACF"}
1
+ {"version":3,"file":"handleDelete.js","names":["args: HandleDeleteArgs","args: DeleteMuxAssetArgs","args: DeleteS3FileArgs"],"sources":["../../src/adapter/handleDelete.ts"],"sourcesContent":["import { useErrorHandler } from '../hooks/useErrorHandler'\nimport { MediaCloudErrors } from '../types/errors'\n\nimport type { HandleDelete } from '@payloadcms/plugin-cloud-storage/types'\nimport type { Document } from 'payload'\nimport type { Mux } from '@mux/mux-node'\nimport type { S3Store } from '../tus/stores/s3/s3-store'\n\ninterface HandleDeleteArgs {\n s3Store: S3Store\n getMuxClient: () => Mux\n}\n\ninterface DeleteMuxAssetArgs {\n getMuxClient: () => Mux\n uploadId: string\n}\n\ninterface DeleteS3FileArgs {\n s3Store: S3Store\n filename: string\n}\n\nconst { logError } = useErrorHandler()\n\n/**\n * Creates a handle delete function for processing file deletions from both Mux and S3 storage\n * @param args - The arguments for creating the delete handler\n * @param args.s3Store - The S3Store instance for S3 file operations\n * @param args.getMuxClient - Function that returns a Mux client instance\n * @returns A HandleDelete function that processes deletion requests based on storage type\n */\nexport function getHandleDelete(args: HandleDeleteArgs): HandleDelete {\n const { s3Store, getMuxClient } = args\n return async ({ doc, req }) => {\n if (req?.method !== 'DELETE' || !doc) {\n return\n }\n\n const media = doc as Document\n\n if (media?.storage === 'mux' && media.mux?.uploadId) {\n await deleteMuxAsset({ getMuxClient, uploadId: media.mux.uploadId })\n } else if (media.filename) {\n await deleteS3File({ s3Store, filename: media.filename })\n }\n }\n}\n\n/**\n * Deletes a Mux asset by upload ID\n * @param args - The arguments for deleting the Mux asset\n * @param args.getMuxClient - Function that returns a Mux client instance\n * @param args.uploadId - The upload ID of the Mux asset to delete\n * @returns Promise that resolves when the asset is deleted or rejects on error\n */\nasync function deleteMuxAsset(args: DeleteMuxAssetArgs): Promise<void> {\n const { getMuxClient, uploadId } = args\n\n try {\n const mux = getMuxClient()\n const assets = await mux.video.assets.list({ upload_id: uploadId })\n if (assets.data.length > 0) {\n const asset = assets.data[0]\n await mux.video.assets.delete(asset.id)\n }\n } catch (_error) {\n logError(MediaCloudErrors.MUX_ASSET_DELETE_ERROR)\n }\n}\n\n/**\n * Deletes a file from S3 storage including its metadata info file\n * @param args - The arguments for deleting the S3 file\n * @param args.s3Store - The S3Store instance for S3 operations\n * @param args.filename - The filename of the file to delete from S3\n * @returns Promise that resolves when the file is deleted or rejects on error\n */\nasync function deleteS3File(args: DeleteS3FileArgs): Promise<void> {\n const { s3Store, filename } = args\n\n try {\n const { client, bucket } = s3Store\n await client.deleteObjects({\n Bucket: bucket,\n Delete: {\n Objects: [{ Key: filename }, { Key: `${filename}.info` }],\n },\n })\n } catch (_error) {\n logError(MediaCloudErrors.S3_DELETE_ERROR)\n }\n}\n"],"mappings":";;;;AAuBA,MAAM,EAAE,UAAU,GAAG,iBAAiB;;;;;;;;AAStC,SAAgB,gBAAgBA,MAAsC;CACpE,MAAM,EAAE,SAAS,cAAc,GAAG;AAClC,QAAO,OAAO,EAAE,KAAK,KAAK,KAAK;AAC7B,MAAI,KAAK,WAAW,YAAY,CAAC,IAC/B;EAGF,MAAM,QAAQ;AAEd,MAAI,OAAO,YAAY,SAAS,MAAM,KAAK,UACzC,MAAM,eAAe;GAAE;GAAc,UAAU,MAAM,IAAI;EAAU,EAAC;WAC3D,MAAM,UACf,MAAM,aAAa;GAAE;GAAS,UAAU,MAAM;EAAU,EAAC;CAE5D;AACF;;;;;;;;AASD,eAAe,eAAeC,MAAyC;CACrE,MAAM,EAAE,cAAc,UAAU,GAAG;AAEnC,KAAI;EACF,MAAM,MAAM,cAAc;EAC1B,MAAM,SAAS,MAAM,IAAI,MAAM,OAAO,KAAK,EAAE,WAAW,SAAU,EAAC;AACnE,MAAI,OAAO,KAAK,SAAS,GAAG;GAC1B,MAAM,QAAQ,OAAO,KAAK;GAC1B,MAAM,IAAI,MAAM,OAAO,OAAO,MAAM,GAAG;EACxC;CACF,SAAQ,QAAQ;EACf,SAAS,iBAAiB,uBAAuB;CAClD;AACF;;;;;;;;AASD,eAAe,aAAaC,MAAuC;CACjE,MAAM,EAAE,SAAS,UAAU,GAAG;AAE9B,KAAI;EACF,MAAM,EAAE,QAAQ,QAAQ,GAAG;EAC3B,MAAM,OAAO,cAAc;GACzB,QAAQ;GACR,QAAQ,EACN,SAAS,CAAC,EAAE,KAAK,SAAU,GAAE,EAAE,KAAK,GAAG,SAAS,KAAK,CAAC,CAAE,CAAC,EAC1D;EACF,EAAC;CACH,SAAQ,QAAQ;EACf,SAAS,iBAAiB,gBAAgB;CAC3C;AACF"}
@@ -113,6 +113,11 @@ function getMediaCollection(args) {
113
113
  label: "Duration",
114
114
  type: "number"
115
115
  },
116
+ {
117
+ name: "tracks",
118
+ label: "Tracks",
119
+ type: "json"
120
+ },
116
121
  {
117
122
  name: "maxResolutionTier",
118
123
  label: "Max Resolution Tier",
@@ -1 +1 @@
1
- {"version":3,"file":"mediaCollection.js","names":["args: GetMediaCollectionArgs"],"sources":["../../src/collections/mediaCollection.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { Document } from 'payload'\nimport type { S3Store } from './../tus/stores/s3/s3-store'\n\ninterface GetMediaCollectionArgs {\n s3Store: S3Store\n}\n\n/**\n * Creates a media collection configuration for Payload CMS\n * @param args - Arguments including the S3Store instance\n * @returns A configured Payload collection for media files\n */\nexport function getMediaCollection(\n args: GetMediaCollectionArgs\n): CollectionConfig {\n const { s3Store } = args\n\n return {\n slug: 'media',\n access: {\n read: () => true,\n delete: () => true,\n },\n admin: {\n group: 'Media Cloud',\n pagination: {\n defaultLimit: 50,\n },\n },\n upload: {\n crop: false,\n displayPreview: true,\n hideRemoveFile: true,\n adminThumbnail({ doc }: { doc: Document }) {\n if (doc?.storage === 'mux' && doc?.mux?.playbackId) {\n return `https://image.mux.com/${doc.mux.playbackId}/thumbnail.jpg?width=200&height=200&fit_mode=pad`\n } else if (doc?.storage === 's3') {\n // @TODO: Make configurable CDN to resize images on the fly like imgix or wsrv let use wesrv for now since its free for all\n const url = s3Store.getUrl(doc.filename)\n return `https://wsrv.nl/?url=${url}?width=200&height=200&default=1`\n }\n return null\n },\n },\n fields: [\n {\n name: 'alt',\n label: 'Alternative Text',\n type: 'text',\n },\n {\n name: 'caption',\n label: 'Caption',\n type: 'text',\n },\n {\n name: 'copyright',\n label: 'Copyright',\n type: 'text',\n },\n {\n name: 'storage',\n label: 'Storage',\n type: 'select',\n options: [\n {\n label: 'Mux',\n value: 'mux',\n },\n {\n label: 'S3',\n value: 's3',\n },\n ],\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'mux',\n label: 'Mux',\n type: 'group',\n admin: {\n disableListColumn: true,\n disableBulkEdit: true,\n disableListFilter: true,\n readOnly: true,\n condition: (data) => {\n return data.storage === 'mux'\n },\n },\n fields: [\n {\n name: 'preview',\n type: 'ui',\n admin: {\n condition: (data) => {\n return data.storage === 'mux'\n },\n disableListColumn: true,\n components: {\n Field: '@maas/payload-plugin-media-cloud/components#MuxPreview',\n },\n },\n },\n {\n name: 'status',\n label: 'Status',\n type: 'text',\n },\n {\n name: 'uploadId',\n label: 'Upload ID',\n type: 'text',\n },\n {\n name: 'assetId',\n label: 'Asset ID',\n type: 'text',\n },\n {\n name: 'playbackId',\n label: 'Playback ID',\n type: 'text',\n },\n {\n name: 'aspectRatio',\n label: 'Aspect Ratio',\n type: 'text',\n },\n {\n name: 'duration',\n label: 'Duration',\n type: 'number',\n },\n {\n name: 'maxResolutionTier',\n label: 'Max Resolution Tier',\n type: 'text',\n },\n {\n name: 'videoQuality',\n label: 'Video Quality',\n type: 'text',\n },\n {\n name: 'staticRenditions',\n label: 'Static Renditions',\n type: 'json',\n },\n ],\n },\n ],\n }\n}\n"],"mappings":";;;;;;AAaA,SAAgB,mBACdA,MACkB;CAClB,MAAM,EAAE,SAAS,GAAG;AAEpB,QAAO;EACL,MAAM;EACN,QAAQ;GACN,MAAM,MAAM;GACZ,QAAQ,MAAM;EACf;EACD,OAAO;GACL,OAAO;GACP,YAAY,EACV,cAAc,GACf;EACF;EACD,QAAQ;GACN,MAAM;GACN,gBAAgB;GAChB,gBAAgB;GAChB,eAAe,EAAE,KAAwB,EAAE;AACzC,QAAI,KAAK,YAAY,SAAS,KAAK,KAAK,WACtC,QAAO,CAAC,sBAAsB,EAAE,IAAI,IAAI,WAAW,gDAAgD,CAAC;aAC3F,KAAK,YAAY,MAAM;KAEhC,MAAM,MAAM,QAAQ,OAAO,IAAI,SAAS;AACxC,YAAO,CAAC,qBAAqB,EAAE,IAAI,+BAA+B,CAAC;IACpE;AACD,WAAO;GACR;EACF;EACD,QAAQ;GACN;IACE,MAAM;IACN,OAAO;IACP,MAAM;GACP;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;GACP;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;GACP;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;IACN,SAAS,CACP;KACE,OAAO;KACP,OAAO;IACR,GACD;KACE,OAAO;KACP,OAAO;IACR,CACF;IACD,OAAO,EACL,UAAU,KACX;GACF;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;KACL,mBAAmB;KACnB,iBAAiB;KACjB,mBAAmB;KACnB,UAAU;KACV,WAAW,CAAC,SAAS;AACnB,aAAO,KAAK,YAAY;KACzB;IACF;IACD,QAAQ;KACN;MACE,MAAM;MACN,MAAM;MACN,OAAO;OACL,WAAW,CAAC,SAAS;AACnB,eAAO,KAAK,YAAY;OACzB;OACD,mBAAmB;OACnB,YAAY,EACV,OAAO,yDACR;MACF;KACF;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;IACF;GACF;EACF;CACF;AACF"}
1
+ {"version":3,"file":"mediaCollection.js","names":["args: GetMediaCollectionArgs"],"sources":["../../src/collections/mediaCollection.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { Document } from 'payload'\nimport type { S3Store } from './../tus/stores/s3/s3-store'\n\ninterface GetMediaCollectionArgs {\n s3Store: S3Store\n}\n\n/**\n * Creates a media collection configuration for Payload CMS\n * @param args - Arguments including the S3Store instance\n * @returns A configured Payload collection for media files\n */\nexport function getMediaCollection(\n args: GetMediaCollectionArgs\n): CollectionConfig {\n const { s3Store } = args\n\n return {\n slug: 'media',\n access: {\n read: () => true,\n delete: () => true,\n },\n admin: {\n group: 'Media Cloud',\n pagination: {\n defaultLimit: 50,\n },\n },\n upload: {\n crop: false,\n displayPreview: true,\n hideRemoveFile: true,\n adminThumbnail({ doc }: { doc: Document }) {\n if (doc?.storage === 'mux' && doc?.mux?.playbackId) {\n return `https://image.mux.com/${doc.mux.playbackId}/thumbnail.jpg?width=200&height=200&fit_mode=pad`\n } else if (doc?.storage === 's3') {\n // @TODO: Make configurable CDN to resize images on the fly like imgix or wsrv let use wesrv for now since its free for all\n const url = s3Store.getUrl(doc.filename)\n return `https://wsrv.nl/?url=${url}?width=200&height=200&default=1`\n }\n return null\n },\n },\n fields: [\n {\n name: 'alt',\n label: 'Alternative Text',\n type: 'text',\n },\n {\n name: 'caption',\n label: 'Caption',\n type: 'text',\n },\n {\n name: 'copyright',\n label: 'Copyright',\n type: 'text',\n },\n {\n name: 'storage',\n label: 'Storage',\n type: 'select',\n options: [\n {\n label: 'Mux',\n value: 'mux',\n },\n {\n label: 'S3',\n value: 's3',\n },\n ],\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'mux',\n label: 'Mux',\n type: 'group',\n admin: {\n disableListColumn: true,\n disableBulkEdit: true,\n disableListFilter: true,\n readOnly: true,\n condition: (data) => {\n return data.storage === 'mux'\n },\n },\n fields: [\n {\n name: 'preview',\n type: 'ui',\n admin: {\n condition: (data) => {\n return data.storage === 'mux'\n },\n disableListColumn: true,\n components: {\n Field: '@maas/payload-plugin-media-cloud/components#MuxPreview',\n },\n },\n },\n {\n name: 'status',\n label: 'Status',\n type: 'text',\n },\n {\n name: 'uploadId',\n label: 'Upload ID',\n type: 'text',\n },\n {\n name: 'assetId',\n label: 'Asset ID',\n type: 'text',\n },\n {\n name: 'playbackId',\n label: 'Playback ID',\n type: 'text',\n },\n {\n name: 'aspectRatio',\n label: 'Aspect Ratio',\n type: 'text',\n },\n {\n name: 'duration',\n label: 'Duration',\n type: 'number',\n },\n {\n name: 'tracks',\n label: 'Tracks',\n type: 'json',\n },\n {\n name: 'maxResolutionTier',\n label: 'Max Resolution Tier',\n type: 'text',\n },\n {\n name: 'videoQuality',\n label: 'Video Quality',\n type: 'text',\n },\n {\n name: 'staticRenditions',\n label: 'Static Renditions',\n type: 'json',\n },\n ],\n },\n ],\n }\n}\n"],"mappings":";;;;;;AAaA,SAAgB,mBACdA,MACkB;CAClB,MAAM,EAAE,SAAS,GAAG;AAEpB,QAAO;EACL,MAAM;EACN,QAAQ;GACN,MAAM,MAAM;GACZ,QAAQ,MAAM;EACf;EACD,OAAO;GACL,OAAO;GACP,YAAY,EACV,cAAc,GACf;EACF;EACD,QAAQ;GACN,MAAM;GACN,gBAAgB;GAChB,gBAAgB;GAChB,eAAe,EAAE,KAAwB,EAAE;AACzC,QAAI,KAAK,YAAY,SAAS,KAAK,KAAK,WACtC,QAAO,CAAC,sBAAsB,EAAE,IAAI,IAAI,WAAW,gDAAgD,CAAC;aAC3F,KAAK,YAAY,MAAM;KAEhC,MAAM,MAAM,QAAQ,OAAO,IAAI,SAAS;AACxC,YAAO,CAAC,qBAAqB,EAAE,IAAI,+BAA+B,CAAC;IACpE;AACD,WAAO;GACR;EACF;EACD,QAAQ;GACN;IACE,MAAM;IACN,OAAO;IACP,MAAM;GACP;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;GACP;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;GACP;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;IACN,SAAS,CACP;KACE,OAAO;KACP,OAAO;IACR,GACD;KACE,OAAO;KACP,OAAO;IACR,CACF;IACD,OAAO,EACL,UAAU,KACX;GACF;GACD;IACE,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;KACL,mBAAmB;KACnB,iBAAiB;KACjB,mBAAmB;KACnB,UAAU;KACV,WAAW,CAAC,SAAS;AACnB,aAAO,KAAK,YAAY;KACzB;IACF;IACD,QAAQ;KACN;MACE,MAAM;MACN,MAAM;MACN,OAAO;OACL,WAAW,CAAC,SAAS;AACnB,eAAO,KAAK,YAAY;OACzB;OACD,mBAAmB;OACnB,YAAY,EACV,OAAO,yDACR;MACF;KACF;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;KACD;MACE,MAAM;MACN,OAAO;MACP,MAAM;KACP;IACF;GACF;EACF;CACF;AACF"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
 
4
- import { MediaCloudError } from "../../types/errors.js";
4
+ import { MediaCloudErrors } from "../../types/errors.js";
5
5
  import { useErrorHandler } from "../../hooks/useErrorHandler.js";
6
6
  import { getFileType, isVideo, sanitizeFilename } from "../../utils/file.js";
7
7
  import { emitter } from "../../hooks/useEmitter.js";
@@ -27,7 +27,7 @@ const TUS_RETRY_DELAYS = [
27
27
  */
28
28
  function parseUploadId(uploadUrl) {
29
29
  if (!uploadUrl) {
30
- logError(MediaCloudError.UPLOAD_NO_URL);
30
+ logError(MediaCloudErrors.UPLOAD_NO_URL);
31
31
  return "";
32
32
  }
33
33
  const url = new URL(uploadUrl);
@@ -67,7 +67,7 @@ async function muxUpload(args) {
67
67
  pollingUrl: getAssetEndpoint
68
68
  });
69
69
  uploader.on("error", () => {
70
- logError(MediaCloudError.MUX_UPLOAD_ERROR);
70
+ logError(MediaCloudErrors.MUX_UPLOAD_ERROR);
71
71
  toast.error("Video upload failed");
72
72
  emitter.emit("remove-upload", { id: uploadId });
73
73
  });
@@ -86,7 +86,7 @@ async function muxUpload(args) {
86
86
  storage: "mux"
87
87
  };
88
88
  } catch (_error) {
89
- logError(MediaCloudError.MUX_DIRECT_UPLOAD_ERROR);
89
+ logError(MediaCloudErrors.MUX_DIRECT_UPLOAD_ERROR);
90
90
  toast.error("Video upload failed");
91
91
  return null;
92
92
  }
@@ -115,7 +115,7 @@ async function tusUpload(args) {
115
115
  contentLength: filesize
116
116
  },
117
117
  onError: () => {
118
- logError(MediaCloudError.TUS_UPLOAD_ERROR);
118
+ logError(MediaCloudErrors.TUS_UPLOAD_ERROR);
119
119
  toast.error("File upload failed");
120
120
  resolve(null);
121
121
  },
@@ -153,7 +153,7 @@ const UploadHandler = createClientUploadHandler({ handler: async (args) => {
153
153
  try {
154
154
  const mimeType = await getFileType(file);
155
155
  if (!mimeType) {
156
- throwError(MediaCloudError.FILE_TYPE_UNKNOWN);
156
+ throwError(MediaCloudErrors.FILE_TYPE_UNKNOWN);
157
157
  return null;
158
158
  }
159
159
  const isVideoFile = await isVideo(file);
@@ -167,7 +167,7 @@ const UploadHandler = createClientUploadHandler({ handler: async (args) => {
167
167
  if (isVideoFile) return await muxUpload(uploadArgs);
168
168
  else return await tusUpload(uploadArgs);
169
169
  } catch (_error) {
170
- logError(MediaCloudError.UPLOAD_HANDLER_ERROR);
170
+ logError(MediaCloudErrors.UPLOAD_HANDLER_ERROR);
171
171
  toast.error("Upload failed");
172
172
  return null;
173
173
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upload-handler.js","names":["uploadUrl?: string | null","args: UploadArgs","uploadArgs: UploadArgs"],"sources":["../../../src/components/upload-handler/upload-handler.tsx"],"sourcesContent":["'use client'\n\nimport * as upchunk from '@mux/upchunk'\nimport * as tus from 'tus-js-client'\n\nimport { toast } from '@payloadcms/ui'\nimport { createClientUploadHandler } from '@payloadcms/plugin-cloud-storage/client'\n\nimport { MediaCloudError } from '../../types/errors'\nimport { emitter } from '../../hooks/useEmitter'\nimport { useErrorHandler } from '../../hooks/useErrorHandler'\nimport { isVideo, getFileType, sanitizeFilename } from '../../utils/file'\n\ninterface UploadArgs {\n serverURL: string\n apiRoute: string\n file: File\n mimeType: string\n updateFilename: (filename: string) => void\n}\n\ninterface UploadResult {\n uploadId: string\n mimeType: string\n storage: 'mux' | 's3'\n}\n\ninterface MuxCreateUploadResponse {\n url: string\n uploadId: string\n}\n\nconst { logError, throwError } = useErrorHandler()\n\nconst MUX_CHUNK_SIZE = 30720\nconst TUS_CHUNK_SIZE = 1024 * 1024\nconst TUS_RETRY_DELAYS = [0, 1000, 2000, 5000]\n\n/**\n * Utility function to parse upload ID from URL\n * @param uploadUrl - The upload URL to parse\n * @returns The extracted upload ID or empty string if parsing fails\n */\nfunction parseUploadId(uploadUrl?: string | null): string {\n if (!uploadUrl) {\n logError(MediaCloudError.UPLOAD_NO_URL)\n return ''\n }\n const url = new URL(uploadUrl)\n return url.pathname.split('/').pop() || ''\n}\n\n/**\n * Handles Mux video upload with progress tracking\n * @param args - The upload arguments including file, server URL, and callbacks\n * @returns Promise that resolves to upload result or null if upload fails\n */\nasync function muxUpload(args: UploadArgs): Promise<UploadResult | null> {\n const { file, serverURL, apiRoute, mimeType, updateFilename } = args\n\n const filename = sanitizeFilename(file.name)\n const getUploadUrlEndpoint = `${serverURL}${apiRoute}/mux/upload`\n const getAssetEndpoint = `${serverURL}${apiRoute}/mux/asset`\n\n updateFilename(filename)\n\n try {\n // Request upload URL from Mux\n const response = await fetch(getUploadUrlEndpoint, {\n body: JSON.stringify({ filename, mimeType }),\n credentials: 'include',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n const { url, uploadId } = (await response.json()) as MuxCreateUploadResponse\n\n // Create upchunk uploader\n const uploader = await upchunk.createUpload({\n endpoint: url,\n file,\n chunkSize: MUX_CHUNK_SIZE,\n })\n\n // Add upload to tracker\n emitter.emit('add-upload', {\n id: uploadId,\n filename,\n polling: false,\n pollingUrl: getAssetEndpoint,\n })\n\n // Set up event handlers\n uploader.on('error', () => {\n logError(MediaCloudError.MUX_UPLOAD_ERROR)\n toast.error('Video upload failed')\n emitter.emit('remove-upload', { id: uploadId })\n })\n\n uploader.on('progress', (progress) => {\n emitter.emit('update-upload', {\n id: uploadId,\n progress: progress.detail,\n })\n })\n\n uploader.on('success', () => {\n emitter.emit('upload-completed', { id: uploadId })\n })\n\n return {\n uploadId,\n mimeType,\n storage: 'mux',\n }\n } catch (_error) {\n logError(MediaCloudError.MUX_DIRECT_UPLOAD_ERROR)\n toast.error('Video upload failed')\n return null\n }\n}\n\n/**\n * Handles TUS file upload with resumable capabilities\n * @param args - The upload arguments including file, server URL, and callbacks\n * @returns Promise that resolves to upload result or null if upload fails\n */\nasync function tusUpload(args: UploadArgs): Promise<UploadResult | null> {\n const { apiRoute, serverURL, file, mimeType, updateFilename } = args\n\n const filename = file.name\n const filetype = file.type\n const filesize = file.size.toString()\n\n return new Promise((resolve) => {\n const upload = new tus.Upload(file, {\n endpoint: `${serverURL}${apiRoute}/uploads`,\n retryDelays: TUS_RETRY_DELAYS,\n chunkSize: TUS_CHUNK_SIZE,\n metadata: {\n filename,\n filetype,\n filesize,\n contentType: filetype,\n contentDisposition: 'inline',\n contentLength: filesize,\n },\n onError: () => {\n logError(MediaCloudError.TUS_UPLOAD_ERROR)\n toast.error('File upload failed')\n resolve(null)\n },\n onProgress: (bytesUploaded, bytesTotal) => {\n const percentage = Math.round((bytesUploaded / bytesTotal) * 100)\n const uploadId = parseUploadId(upload?.url)\n emitter.emit('update-upload', {\n id: uploadId,\n progress: percentage,\n })\n },\n onSuccess: () => {\n const uploadId = parseUploadId(upload?.url)\n emitter.emit('upload-completed', { id: uploadId })\n },\n onUploadUrlAvailable: () => {\n const uploadId = parseUploadId(upload?.url)\n updateFilename(uploadId)\n emitter.emit('add-upload', { id: uploadId, filename })\n resolve({\n uploadId,\n mimeType,\n storage: 's3',\n })\n },\n })\n\n upload.start()\n })\n}\n\nexport const UploadHandler = createClientUploadHandler({\n handler: async (args) => {\n const { serverURL, apiRoute, file, updateFilename } = args\n\n try {\n const mimeType = await getFileType(file)\n\n if (!mimeType) {\n throwError(MediaCloudError.FILE_TYPE_UNKNOWN)\n return null\n }\n\n const isVideoFile = await isVideo(file)\n const uploadArgs: UploadArgs = {\n file,\n serverURL,\n apiRoute,\n mimeType,\n updateFilename,\n }\n\n if (isVideoFile) {\n return await muxUpload(uploadArgs)\n } else {\n return await tusUpload(uploadArgs)\n }\n } catch (_error) {\n logError(MediaCloudError.UPLOAD_HANDLER_ERROR)\n toast.error('Upload failed')\n return null\n }\n },\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"upload-handler.js","names":["uploadUrl?: string | null","args: UploadArgs","uploadArgs: UploadArgs"],"sources":["../../../src/components/upload-handler/upload-handler.tsx"],"sourcesContent":["'use client'\n\nimport * as upchunk from '@mux/upchunk'\nimport * as tus from 'tus-js-client'\n\nimport { toast } from '@payloadcms/ui'\nimport { createClientUploadHandler } from '@payloadcms/plugin-cloud-storage/client'\n\nimport { MediaCloudErrors } from '../../types/errors'\nimport { emitter } from '../../hooks/useEmitter'\nimport { useErrorHandler } from '../../hooks/useErrorHandler'\nimport { isVideo, getFileType, sanitizeFilename } from '../../utils/file'\n\ninterface UploadArgs {\n serverURL: string\n apiRoute: string\n file: File\n mimeType: string\n updateFilename: (filename: string) => void\n}\n\ninterface UploadResult {\n uploadId: string\n mimeType: string\n storage: 'mux' | 's3'\n}\n\ninterface MuxCreateUploadResponse {\n url: string\n uploadId: string\n}\n\nconst { logError, throwError } = useErrorHandler()\n\nconst MUX_CHUNK_SIZE = 30720\nconst TUS_CHUNK_SIZE = 1024 * 1024\nconst TUS_RETRY_DELAYS = [0, 1000, 2000, 5000]\n\n/**\n * Utility function to parse upload ID from URL\n * @param uploadUrl - The upload URL to parse\n * @returns The extracted upload ID or empty string if parsing fails\n */\nfunction parseUploadId(uploadUrl?: string | null): string {\n if (!uploadUrl) {\n logError(MediaCloudErrors.UPLOAD_NO_URL)\n return ''\n }\n const url = new URL(uploadUrl)\n return url.pathname.split('/').pop() || ''\n}\n\n/**\n * Handles Mux video upload with progress tracking\n * @param args - The upload arguments including file, server URL, and callbacks\n * @returns Promise that resolves to upload result or null if upload fails\n */\nasync function muxUpload(args: UploadArgs): Promise<UploadResult | null> {\n const { file, serverURL, apiRoute, mimeType, updateFilename } = args\n\n const filename = sanitizeFilename(file.name)\n const getUploadUrlEndpoint = `${serverURL}${apiRoute}/mux/upload`\n const getAssetEndpoint = `${serverURL}${apiRoute}/mux/asset`\n\n updateFilename(filename)\n\n try {\n // Request upload URL from Mux\n const response = await fetch(getUploadUrlEndpoint, {\n body: JSON.stringify({ filename, mimeType }),\n credentials: 'include',\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n const { url, uploadId } = (await response.json()) as MuxCreateUploadResponse\n\n // Create upchunk uploader\n const uploader = await upchunk.createUpload({\n endpoint: url,\n file,\n chunkSize: MUX_CHUNK_SIZE,\n })\n\n // Add upload to tracker\n emitter.emit('add-upload', {\n id: uploadId,\n filename,\n polling: false,\n pollingUrl: getAssetEndpoint,\n })\n\n // Set up event handlers\n uploader.on('error', () => {\n logError(MediaCloudErrors.MUX_UPLOAD_ERROR)\n toast.error('Video upload failed')\n emitter.emit('remove-upload', { id: uploadId })\n })\n\n uploader.on('progress', (progress) => {\n emitter.emit('update-upload', {\n id: uploadId,\n progress: progress.detail,\n })\n })\n\n uploader.on('success', () => {\n emitter.emit('upload-completed', { id: uploadId })\n })\n\n return {\n uploadId,\n mimeType,\n storage: 'mux',\n }\n } catch (_error) {\n logError(MediaCloudErrors.MUX_DIRECT_UPLOAD_ERROR)\n toast.error('Video upload failed')\n return null\n }\n}\n\n/**\n * Handles TUS file upload with resumable capabilities\n * @param args - The upload arguments including file, server URL, and callbacks\n * @returns Promise that resolves to upload result or null if upload fails\n */\nasync function tusUpload(args: UploadArgs): Promise<UploadResult | null> {\n const { apiRoute, serverURL, file, mimeType, updateFilename } = args\n\n const filename = file.name\n const filetype = file.type\n const filesize = file.size.toString()\n\n return new Promise((resolve) => {\n const upload = new tus.Upload(file, {\n endpoint: `${serverURL}${apiRoute}/uploads`,\n retryDelays: TUS_RETRY_DELAYS,\n chunkSize: TUS_CHUNK_SIZE,\n metadata: {\n filename,\n filetype,\n filesize,\n contentType: filetype,\n contentDisposition: 'inline',\n contentLength: filesize,\n },\n onError: () => {\n logError(MediaCloudErrors.TUS_UPLOAD_ERROR)\n toast.error('File upload failed')\n resolve(null)\n },\n onProgress: (bytesUploaded, bytesTotal) => {\n const percentage = Math.round((bytesUploaded / bytesTotal) * 100)\n const uploadId = parseUploadId(upload?.url)\n emitter.emit('update-upload', {\n id: uploadId,\n progress: percentage,\n })\n },\n onSuccess: () => {\n const uploadId = parseUploadId(upload?.url)\n emitter.emit('upload-completed', { id: uploadId })\n },\n onUploadUrlAvailable: () => {\n const uploadId = parseUploadId(upload?.url)\n updateFilename(uploadId)\n emitter.emit('add-upload', { id: uploadId, filename })\n resolve({\n uploadId,\n mimeType,\n storage: 's3',\n })\n },\n })\n\n upload.start()\n })\n}\n\nexport const UploadHandler = createClientUploadHandler({\n handler: async (args) => {\n const { serverURL, apiRoute, file, updateFilename } = args\n\n try {\n const mimeType = await getFileType(file)\n\n if (!mimeType) {\n throwError(MediaCloudErrors.FILE_TYPE_UNKNOWN)\n return null\n }\n\n const isVideoFile = await isVideo(file)\n const uploadArgs: UploadArgs = {\n file,\n serverURL,\n apiRoute,\n mimeType,\n updateFilename,\n }\n\n if (isVideoFile) {\n return await muxUpload(uploadArgs)\n } else {\n return await tusUpload(uploadArgs)\n }\n } catch (_error) {\n logError(MediaCloudErrors.UPLOAD_HANDLER_ERROR)\n toast.error('Upload failed')\n return null\n }\n },\n})\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
 
4
- import { MediaCloudError } from "../../types/errors.js";
4
+ import { MediaCloudErrors } from "../../types/errors.js";
5
5
  import { useErrorHandler } from "../../hooks/useErrorHandler.js";
6
6
  import { useEmitter } from "../../hooks/useEmitter.js";
7
7
  import { createContext, use, useEffect, useRef, useState } from "react";
@@ -65,7 +65,7 @@ function UploadManagerProvider(args) {
65
65
  });
66
66
  }
67
67
  } catch (_error) {
68
- logError(MediaCloudError.UPLOAD_POLLING_ERROR);
68
+ logError(MediaCloudErrors.UPLOAD_POLLING_ERROR);
69
69
  }
70
70
  };
71
71
  const intervalId = setInterval(pollAssets, 2e3);
@@ -75,28 +75,28 @@ function UploadManagerProvider(args) {
75
75
  emitter.on("add-upload", onAddUpload);
76
76
  emitter.on("update-upload", onUpdateUpload);
77
77
  emitter.on("remove-upload", onRemoveUpload);
78
- emitter.on("upload-error", onUploadError);
78
+ emitter.on("upload-errored", onUploadError);
79
79
  emitter.on("upload-completed", onUploadCompleted);
80
80
  return () => {
81
81
  emitter.off("add-upload", onAddUpload);
82
82
  emitter.off("update-upload", onUpdateUpload);
83
83
  emitter.off("remove-upload", onRemoveUpload);
84
- emitter.off("upload-error", onUploadError);
84
+ emitter.off("upload-errored", onUploadError);
85
85
  emitter.off("upload-completed", onUploadCompleted);
86
86
  };
87
87
  }, [emitter]);
88
88
  /**
89
- * Handles the 'upload-error' event
89
+ * Handles the 'upload-errored' event
90
90
  * @param event - The upload error event
91
91
  */
92
92
  function onUploadError(event) {
93
93
  const { id, error } = event;
94
+ logError(MediaCloudErrors.UPLOAD_ERROR);
94
95
  setActiveUploads((prev) => prev.map((upload) => upload.id === id ? {
95
96
  ...upload,
96
97
  error,
97
98
  status: "completed"
98
99
  } : upload));
99
- logError(error);
100
100
  }
101
101
  /**
102
102
  * Handles the 'add-upload' event
@@ -1 +1 @@
1
- {"version":3,"file":"upload-manager.js","names":["args: UploadManagerProviderArgs","uploads: Upload[]","event: { id: string; error: MediaCloudError }","event: OnAddUploadEvent","event: OnUpdateUploadEvent","event: { id: string }","args: AddUploadArgs","args","upload: Upload","args: UpdateUploadArgs","args: RenderUploadListArgs","value: UploadManagerContextType"],"sources":["../../../src/components/upload-manager/upload-manager.tsx"],"sourcesContent":["'use client'\n\nimport { createContext, use, useState, useEffect, useRef } from 'react'\nimport { Button } from '@payloadcms/ui'\n\nimport { useEmitter } from '../../hooks/useEmitter'\nimport { useErrorHandler } from '../../hooks/useErrorHandler'\nimport { MediaCloudError } from '../../types/errors'\n\nimport type React from 'react'\n\nimport './upload-manager.css'\n\ninterface Upload {\n id: string\n filename: string\n progress: number\n error?: string\n polling?: boolean\n pollingUrl?: string\n status?: 'uploading' | 'processing' | 'completed'\n}\n\ninterface UploadManagerContextType {\n showUploadManager?: boolean\n activeUploads: Upload[]\n addUpload: (args: AddUploadArgs) => void\n updateUpload: (args: UpdateUploadArgs) => void\n}\n\ninterface UploadManagerProviderArgs {\n children: React.ReactNode\n}\n\ninterface OnAddUploadEvent {\n id: string\n filename: string\n polling?: boolean\n pollingUrl?: string\n}\n\ninterface OnUpdateUploadEvent {\n id: string\n progress: number\n polling?: boolean\n}\n\ninterface AddUploadArgs {\n id: string\n filename: string\n polling?: boolean\n pollingUrl?: string\n}\n\ninterface UpdateUploadArgs {\n id: string\n progress: number\n polling?: boolean\n}\n\ninterface RenderUploadListArgs {\n uploads: Upload[]\n}\n\nconst { logError } = useErrorHandler()\n\nconst UploadManagerContext = createContext<UploadManagerContextType>({\n showUploadManager: false,\n activeUploads: [],\n addUpload: () => {},\n updateUpload: () => {},\n})\n\n/**\n * Provider component for upload management context\n * @param args - Arguments including children to wrap\n * @returns JSX element providing upload management context\n */\nexport function UploadManagerProvider(args: UploadManagerProviderArgs) {\n const { children } = args\n const [showUploadManager, setShowUploadManager] = useState(false)\n const [activeUploads, setActiveUploads] = useState<Upload[]>([])\n const [activeTab, setActiveTab] = useState<\n 'uploading' | 'processing' | 'completed'\n >('uploading')\n\n const activeTabRef = useRef(activeTab)\n const activeUploadsRef = useRef(activeUploads)\n\n // Keep refs in sync with state\n useEffect(() => {\n activeTabRef.current = activeTab\n }, [activeTab])\n\n useEffect(() => {\n activeUploadsRef.current = activeUploads\n }, [activeUploads])\n\n const emitter = useEmitter()\n\n // Helper function to check if we should auto-switch to completed tab\n function checkAutoSwitchToCompleted(uploads: Upload[]) {\n const hasActiveUploads = uploads.some(\n (upload) => upload.status === 'uploading'\n )\n const hasProcessingUploads = uploads.some(\n (upload) => upload.status === 'processing'\n )\n const hasCompletedUploads = uploads.some(\n (upload) => upload.status === 'completed'\n )\n\n // Auto-switch to completed tab if no uploading/processing uploads remain\n if (\n !hasActiveUploads &&\n !hasProcessingUploads &&\n hasCompletedUploads &&\n activeTabRef.current !== 'completed'\n ) {\n setActiveTab('completed')\n }\n }\n\n // Polling logic\n useEffect(() => {\n const pollingUploads = activeUploads.filter(\n (upload) => upload.polling && upload.pollingUrl\n )\n\n if (pollingUploads.length === 0) {\n return\n }\n\n const pollAssets = async () => {\n for (const upload of pollingUploads) {\n try {\n const response = await fetch(\n `${upload.pollingUrl}?upload_id=${upload.id}`,\n {\n method: 'GET',\n credentials: 'include',\n }\n )\n\n if (response.ok) {\n const data = await response.json()\n\n if (data.ready) {\n // Asset is ready, stop polling for this upload\n setActiveUploads((prev) => {\n const updatedUploads = prev.map((u) =>\n u.id === upload.id\n ? {\n ...u,\n polling: false,\n progress: 100,\n status: 'completed' as const,\n }\n : u\n )\n\n // Check if we should auto-switch to completed tab\n setTimeout(() => checkAutoSwitchToCompleted(updatedUploads), 0)\n\n return updatedUploads\n })\n }\n }\n } catch (_error) {\n logError(MediaCloudError.UPLOAD_POLLING_ERROR)\n }\n }\n }\n\n const intervalId = setInterval(pollAssets, 2000) // Poll every 2 seconds\n\n return () => clearInterval(intervalId)\n }, [activeUploads, emitter])\n\n useEffect(() => {\n emitter.on('add-upload', onAddUpload)\n emitter.on('update-upload', onUpdateUpload)\n emitter.on('remove-upload', onRemoveUpload)\n emitter.on('upload-error', onUploadError)\n emitter.on('upload-completed', onUploadCompleted)\n\n return () => {\n emitter.off('add-upload', onAddUpload)\n emitter.off('update-upload', onUpdateUpload)\n emitter.off('remove-upload', onRemoveUpload)\n emitter.off('upload-error', onUploadError)\n emitter.off('upload-completed', onUploadCompleted)\n }\n }, [emitter])\n\n /**\n * Handles the 'upload-error' event\n * @param event - The upload error event\n */\n function onUploadError(event: { id: string; error: MediaCloudError }) {\n const { id, error } = event\n setActiveUploads((prev) =>\n prev.map((upload) =>\n upload.id === id ? { ...upload, error, status: 'completed' } : upload\n )\n )\n logError(error)\n }\n\n /**\n * Handles the 'add-upload' event\n * @param event - The add upload event\n */\n function onAddUpload(event: OnAddUploadEvent) {\n addUpload({\n id: event.id,\n filename: event.filename,\n polling: event.polling,\n pollingUrl: event.pollingUrl,\n })\n\n // Show the upload manager when new upload starts\n setShowUploadManager(true)\n\n // Auto-switch to uploading tab when new upload starts\n if (activeTabRef.current !== 'uploading') {\n setActiveTab('uploading')\n }\n }\n\n /**\n * Handles the 'update-upload' event\n * @param event - The update upload event\n */\n function onUpdateUpload(event: OnUpdateUploadEvent) {\n updateUpload({\n id: event.id,\n progress: event.progress,\n polling: event.polling,\n })\n }\n\n /**\n * Handles the 'remove-upload' event\n * @param event - The remove upload event\n */\n function onRemoveUpload(event: { id: string }) {\n setActiveUploads((prev) => prev.filter((upload) => upload.id !== event.id))\n }\n\n /**\n * Handles the 'upload-completed' event\n * @param event - The upload completed event\n */\n function onUploadCompleted(event: { id: string }) {\n // Check if this upload has a polling URL (Mux upload)\n const upload = activeUploadsRef.current.find((u) => u.id === event.id)\n if (upload?.pollingUrl) {\n setActiveUploads((prev) =>\n prev.map((u) =>\n u.id === event.id\n ? {\n ...u,\n polling: true,\n progress: 100,\n status: 'processing' as const,\n }\n : u\n )\n )\n } else {\n // Regular upload completion\n setActiveUploads((prev) => {\n const updatedUploads = prev.map((u) =>\n u.id === event.id\n ? { ...u, progress: 100, status: 'completed' as const }\n : u\n )\n\n // Check if we should auto-switch to completed tab\n setTimeout(() => checkAutoSwitchToCompleted(updatedUploads), 0)\n\n return updatedUploads\n })\n }\n }\n\n /**\n * Adds a new upload to the manager\n * @param args - The upload arguments\n */\n function addUpload(args: AddUploadArgs) {\n const { id, filename, polling = false, pollingUrl } = args\n const upload: Upload = {\n id,\n filename,\n progress: 0,\n polling,\n pollingUrl,\n status: 'uploading',\n }\n\n setActiveUploads((prev) => [...prev, upload])\n }\n\n /**\n * Updates an existing upload in the manager\n * @param args - The update arguments\n */\n function updateUpload(args: UpdateUploadArgs) {\n const { id, progress, polling } = args\n setActiveUploads((prev) =>\n prev.map((upload) =>\n upload.id === id\n ? {\n ...upload,\n progress,\n ...(polling !== undefined && { polling }),\n status: polling\n ? 'processing'\n : progress >= 100\n ? 'completed'\n : 'uploading',\n }\n : upload\n )\n )\n setActiveUploads((currentUploads) => {\n return currentUploads\n })\n }\n\n // Filter uploads by status\n const uploadingFiles = activeUploads.filter(\n (upload) => upload.status === 'uploading'\n )\n const processingFiles = activeUploads.filter(\n (upload) => upload.status === 'processing'\n )\n const completedFiles = activeUploads.filter(\n (upload) => upload.status === 'completed'\n )\n\n /**\n * Renders the upload list\n * @param args - The render arguments\n * @returns JSX element representing the upload list\n */\n function renderUploadList(args: RenderUploadListArgs) {\n const { uploads } = args\n return (\n <ul>\n {uploads.map((upload) => (\n <li key={upload.id} data-status={upload.status}>\n <div className=\"upload-info\">\n <span className=\"upload-filename\">{upload.filename}</span>\n <span className=\"upload-meta\">\n {upload.status === 'processing'\n ? 'Processing...'\n : upload.progress < 100\n ? `${Math.ceil(upload.progress)}%`\n : 'Completed'}\n </span>\n </div>\n <div\n className=\"upload-progress-bar\"\n style={\n {\n ['--progress']:\n upload.status === 'processing'\n ? '1'\n : `${upload.progress / 100}`,\n } as React.CSSProperties\n }\n >\n <div\n data-active={upload.status === 'processing'}\n className=\"upload-progress\"\n />\n </div>\n </li>\n ))}\n </ul>\n )\n }\n\n /**\n * Closes the upload manager\n */\n function closeUploadManager() {\n // Only allow closing if no uploads are actively polling\n const hasPollingUploads = activeUploads.some((upload) => upload.polling)\n if (!hasPollingUploads) {\n setActiveUploads([])\n setShowUploadManager(false)\n }\n }\n\n const value: UploadManagerContextType = {\n activeUploads,\n addUpload,\n updateUpload,\n }\n\n return (\n <UploadManagerContext.Provider value={value}>\n {showUploadManager && (\n <div className=\"upload-manager\">\n <div className=\"upload-manager__header\">\n <h4>Uploads</h4>\n <Button\n buttonStyle=\"icon-label\"\n icon=\"x\"\n margin={false}\n onClick={closeUploadManager}\n />\n </div>\n\n <div className=\"upload-manager__tabs\">\n <button\n data-active={activeTab === 'uploading'}\n className=\"upload-tab\"\n onClick={() => setActiveTab('uploading')}\n >\n Uploading ({uploadingFiles.length})\n </button>\n <button\n data-active={activeTab === 'processing'}\n className=\"upload-tab\"\n onClick={() => setActiveTab('processing')}\n >\n Processing ({processingFiles.length})\n </button>\n <button\n data-active={activeTab === 'completed'}\n className=\"upload-tab\"\n onClick={() => setActiveTab('completed')}\n >\n Completed ({completedFiles.length})\n </button>\n </div>\n\n <div className=\"upload-manager__content\">\n {activeTab === 'uploading' && uploadingFiles.length > 0 && (\n <div>{renderUploadList({ uploads: uploadingFiles })}</div>\n )}\n {activeTab === 'processing' && processingFiles.length > 0 && (\n <div>{renderUploadList({ uploads: processingFiles })}</div>\n )}\n {activeTab === 'completed' && completedFiles.length > 0 && (\n <div>\n {renderUploadList({ uploads: completedFiles })}\n <div className=\"upload-manager__footer\">\n <Button\n buttonStyle=\"subtle\"\n size=\"small\"\n margin={false}\n onClick={() => window?.location?.reload()}\n >\n Refresh\n </Button>\n </div>\n </div>\n )}\n {((activeTab === 'uploading' && uploadingFiles.length === 0) ||\n (activeTab === 'processing' && processingFiles.length === 0) ||\n (activeTab === 'completed' && completedFiles.length === 0)) && (\n <p className=\"upload-empty-state\">No {activeTab} files</p>\n )}\n </div>\n </div>\n )}\n {children}\n </UploadManagerContext.Provider>\n )\n}\n\nexport const useUploadManagerContext = () => use(UploadManagerContext)\n"],"mappings":"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"}
1
+ {"version":3,"file":"upload-manager.js","names":["args: UploadManagerProviderArgs","uploads: Upload[]","event: { id: string; error: string }","event: OnAddUploadEvent","event: OnUpdateUploadEvent","event: { id: string }","args: AddUploadArgs","args","upload: Upload","args: UpdateUploadArgs","args: RenderUploadListArgs","value: UploadManagerContextType"],"sources":["../../../src/components/upload-manager/upload-manager.tsx"],"sourcesContent":["'use client'\n\nimport { createContext, use, useState, useEffect, useRef } from 'react'\nimport { Button } from '@payloadcms/ui'\n\nimport { useEmitter } from '../../hooks/useEmitter'\nimport { useErrorHandler } from '../../hooks/useErrorHandler'\nimport { MediaCloudErrors } from '../../types/errors'\n\nimport type React from 'react'\n\nimport './upload-manager.css'\n\ninterface Upload {\n id: string\n filename: string\n progress: number\n error?: string\n polling?: boolean\n pollingUrl?: string\n status?: 'uploading' | 'processing' | 'completed'\n}\n\ninterface UploadManagerContextType {\n showUploadManager?: boolean\n activeUploads: Upload[]\n addUpload: (args: AddUploadArgs) => void\n updateUpload: (args: UpdateUploadArgs) => void\n}\n\ninterface UploadManagerProviderArgs {\n children: React.ReactNode\n}\n\ninterface OnAddUploadEvent {\n id: string\n filename: string\n polling?: boolean\n pollingUrl?: string\n}\n\ninterface OnUpdateUploadEvent {\n id: string\n progress: number\n polling?: boolean\n}\n\ninterface AddUploadArgs {\n id: string\n filename: string\n polling?: boolean\n pollingUrl?: string\n}\n\ninterface UpdateUploadArgs {\n id: string\n progress: number\n polling?: boolean\n}\n\ninterface RenderUploadListArgs {\n uploads: Upload[]\n}\n\nconst { logError } = useErrorHandler()\n\nconst UploadManagerContext = createContext<UploadManagerContextType>({\n showUploadManager: false,\n activeUploads: [],\n addUpload: () => {},\n updateUpload: () => {},\n})\n\n/**\n * Provider component for upload management context\n * @param args - Arguments including children to wrap\n * @returns JSX element providing upload management context\n */\nexport function UploadManagerProvider(args: UploadManagerProviderArgs) {\n const { children } = args\n const [showUploadManager, setShowUploadManager] = useState(false)\n const [activeUploads, setActiveUploads] = useState<Upload[]>([])\n const [activeTab, setActiveTab] = useState<\n 'uploading' | 'processing' | 'completed'\n >('uploading')\n\n const activeTabRef = useRef(activeTab)\n const activeUploadsRef = useRef(activeUploads)\n\n // Keep refs in sync with state\n useEffect(() => {\n activeTabRef.current = activeTab\n }, [activeTab])\n\n useEffect(() => {\n activeUploadsRef.current = activeUploads\n }, [activeUploads])\n\n const emitter = useEmitter()\n\n // Helper function to check if we should auto-switch to completed tab\n function checkAutoSwitchToCompleted(uploads: Upload[]) {\n const hasActiveUploads = uploads.some(\n (upload) => upload.status === 'uploading'\n )\n const hasProcessingUploads = uploads.some(\n (upload) => upload.status === 'processing'\n )\n const hasCompletedUploads = uploads.some(\n (upload) => upload.status === 'completed'\n )\n\n // Auto-switch to completed tab if no uploading/processing uploads remain\n if (\n !hasActiveUploads &&\n !hasProcessingUploads &&\n hasCompletedUploads &&\n activeTabRef.current !== 'completed'\n ) {\n setActiveTab('completed')\n }\n }\n\n // Polling logic\n useEffect(() => {\n const pollingUploads = activeUploads.filter(\n (upload) => upload.polling && upload.pollingUrl\n )\n\n if (pollingUploads.length === 0) {\n return\n }\n\n const pollAssets = async () => {\n for (const upload of pollingUploads) {\n try {\n const response = await fetch(\n `${upload.pollingUrl}?upload_id=${upload.id}`,\n {\n method: 'GET',\n credentials: 'include',\n }\n )\n\n if (response.ok) {\n const data = await response.json()\n\n if (data.ready) {\n // Asset is ready, stop polling for this upload\n setActiveUploads((prev) => {\n const updatedUploads = prev.map((u) =>\n u.id === upload.id\n ? {\n ...u,\n polling: false,\n progress: 100,\n status: 'completed' as const,\n }\n : u\n )\n\n // Check if we should auto-switch to completed tab\n setTimeout(() => checkAutoSwitchToCompleted(updatedUploads), 0)\n\n return updatedUploads\n })\n }\n }\n } catch (_error) {\n logError(MediaCloudErrors.UPLOAD_POLLING_ERROR)\n }\n }\n }\n\n const intervalId = setInterval(pollAssets, 2000) // Poll every 2 seconds\n\n return () => clearInterval(intervalId)\n }, [activeUploads, emitter])\n\n useEffect(() => {\n emitter.on('add-upload', onAddUpload)\n emitter.on('update-upload', onUpdateUpload)\n emitter.on('remove-upload', onRemoveUpload)\n emitter.on('upload-errored', onUploadError)\n emitter.on('upload-completed', onUploadCompleted)\n\n return () => {\n emitter.off('add-upload', onAddUpload)\n emitter.off('update-upload', onUpdateUpload)\n emitter.off('remove-upload', onRemoveUpload)\n emitter.off('upload-errored', onUploadError)\n emitter.off('upload-completed', onUploadCompleted)\n }\n }, [emitter])\n\n /**\n * Handles the 'upload-errored' event\n * @param event - The upload error event\n */\n function onUploadError(event: { id: string; error: string }) {\n const { id, error } = event\n\n logError(MediaCloudErrors.UPLOAD_ERROR)\n\n setActiveUploads((prev) =>\n prev.map((upload) =>\n upload.id === id\n ? { ...upload, error: error, status: 'completed' }\n : upload\n )\n )\n }\n\n /**\n * Handles the 'add-upload' event\n * @param event - The add upload event\n */\n function onAddUpload(event: OnAddUploadEvent) {\n addUpload({\n id: event.id,\n filename: event.filename,\n polling: event.polling,\n pollingUrl: event.pollingUrl,\n })\n\n // Show the upload manager when new upload starts\n setShowUploadManager(true)\n\n // Auto-switch to uploading tab when new upload starts\n if (activeTabRef.current !== 'uploading') {\n setActiveTab('uploading')\n }\n }\n\n /**\n * Handles the 'update-upload' event\n * @param event - The update upload event\n */\n function onUpdateUpload(event: OnUpdateUploadEvent) {\n updateUpload({\n id: event.id,\n progress: event.progress,\n polling: event.polling,\n })\n }\n\n /**\n * Handles the 'remove-upload' event\n * @param event - The remove upload event\n */\n function onRemoveUpload(event: { id: string }) {\n setActiveUploads((prev) => prev.filter((upload) => upload.id !== event.id))\n }\n\n /**\n * Handles the 'upload-completed' event\n * @param event - The upload completed event\n */\n function onUploadCompleted(event: { id: string }) {\n // Check if this upload has a polling URL (Mux upload)\n const upload = activeUploadsRef.current.find((u) => u.id === event.id)\n if (upload?.pollingUrl) {\n setActiveUploads((prev) =>\n prev.map((u) =>\n u.id === event.id\n ? {\n ...u,\n polling: true,\n progress: 100,\n status: 'processing' as const,\n }\n : u\n )\n )\n } else {\n // Regular upload completion\n setActiveUploads((prev) => {\n const updatedUploads = prev.map((u) =>\n u.id === event.id\n ? { ...u, progress: 100, status: 'completed' as const }\n : u\n )\n\n // Check if we should auto-switch to completed tab\n setTimeout(() => checkAutoSwitchToCompleted(updatedUploads), 0)\n\n return updatedUploads\n })\n }\n }\n\n /**\n * Adds a new upload to the manager\n * @param args - The upload arguments\n */\n function addUpload(args: AddUploadArgs) {\n const { id, filename, polling = false, pollingUrl } = args\n const upload: Upload = {\n id,\n filename,\n progress: 0,\n polling,\n pollingUrl,\n status: 'uploading',\n }\n\n setActiveUploads((prev) => [...prev, upload])\n }\n\n /**\n * Updates an existing upload in the manager\n * @param args - The update arguments\n */\n function updateUpload(args: UpdateUploadArgs) {\n const { id, progress, polling } = args\n setActiveUploads((prev) =>\n prev.map((upload) =>\n upload.id === id\n ? {\n ...upload,\n progress,\n ...(polling !== undefined && { polling }),\n status: polling\n ? 'processing'\n : progress >= 100\n ? 'completed'\n : 'uploading',\n }\n : upload\n )\n )\n setActiveUploads((currentUploads) => {\n return currentUploads\n })\n }\n\n // Filter uploads by status\n const uploadingFiles = activeUploads.filter(\n (upload) => upload.status === 'uploading'\n )\n const processingFiles = activeUploads.filter(\n (upload) => upload.status === 'processing'\n )\n const completedFiles = activeUploads.filter(\n (upload) => upload.status === 'completed'\n )\n\n /**\n * Renders the upload list\n * @param args - The render arguments\n * @returns JSX element representing the upload list\n */\n function renderUploadList(args: RenderUploadListArgs) {\n const { uploads } = args\n return (\n <ul>\n {uploads.map((upload) => (\n <li key={upload.id} data-status={upload.status}>\n <div className=\"upload-info\">\n <span className=\"upload-filename\">{upload.filename}</span>\n <span className=\"upload-meta\">\n {upload.status === 'processing'\n ? 'Processing...'\n : upload.progress < 100\n ? `${Math.ceil(upload.progress)}%`\n : 'Completed'}\n </span>\n </div>\n <div\n className=\"upload-progress-bar\"\n style={\n {\n ['--progress']:\n upload.status === 'processing'\n ? '1'\n : `${upload.progress / 100}`,\n } as React.CSSProperties\n }\n >\n <div\n data-active={upload.status === 'processing'}\n className=\"upload-progress\"\n />\n </div>\n </li>\n ))}\n </ul>\n )\n }\n\n /**\n * Closes the upload manager\n */\n function closeUploadManager() {\n // Only allow closing if no uploads are actively polling\n const hasPollingUploads = activeUploads.some((upload) => upload.polling)\n if (!hasPollingUploads) {\n setActiveUploads([])\n setShowUploadManager(false)\n }\n }\n\n const value: UploadManagerContextType = {\n activeUploads,\n addUpload,\n updateUpload,\n }\n\n return (\n <UploadManagerContext.Provider value={value}>\n {showUploadManager && (\n <div className=\"upload-manager\">\n <div className=\"upload-manager__header\">\n <h4>Uploads</h4>\n <Button\n buttonStyle=\"icon-label\"\n icon=\"x\"\n margin={false}\n onClick={closeUploadManager}\n />\n </div>\n\n <div className=\"upload-manager__tabs\">\n <button\n data-active={activeTab === 'uploading'}\n className=\"upload-tab\"\n onClick={() => setActiveTab('uploading')}\n >\n Uploading ({uploadingFiles.length})\n </button>\n <button\n data-active={activeTab === 'processing'}\n className=\"upload-tab\"\n onClick={() => setActiveTab('processing')}\n >\n Processing ({processingFiles.length})\n </button>\n <button\n data-active={activeTab === 'completed'}\n className=\"upload-tab\"\n onClick={() => setActiveTab('completed')}\n >\n Completed ({completedFiles.length})\n </button>\n </div>\n\n <div className=\"upload-manager__content\">\n {activeTab === 'uploading' && uploadingFiles.length > 0 && (\n <div>{renderUploadList({ uploads: uploadingFiles })}</div>\n )}\n {activeTab === 'processing' && processingFiles.length > 0 && (\n <div>{renderUploadList({ uploads: processingFiles })}</div>\n )}\n {activeTab === 'completed' && completedFiles.length > 0 && (\n <div>\n {renderUploadList({ uploads: completedFiles })}\n <div className=\"upload-manager__footer\">\n <Button\n buttonStyle=\"subtle\"\n size=\"small\"\n margin={false}\n onClick={() => window?.location?.reload()}\n >\n Refresh\n </Button>\n </div>\n </div>\n )}\n {((activeTab === 'uploading' && uploadingFiles.length === 0) ||\n (activeTab === 'processing' && processingFiles.length === 0) ||\n (activeTab === 'completed' && completedFiles.length === 0)) && (\n <p className=\"upload-empty-state\">No {activeTab} files</p>\n )}\n </div>\n </div>\n )}\n {children}\n </UploadManagerContext.Provider>\n )\n}\n\nexport const useUploadManagerContext = () => use(UploadManagerContext)\n"],"mappings":"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"}
@@ -33,6 +33,7 @@ function getMuxAssetHandler(args) {
33
33
  playbackId: asset.playback_ids?.[0]?.id,
34
34
  aspectRatio: asset.aspect_ratio,
35
35
  duration: asset.duration,
36
+ tracks: asset.tracks,
36
37
  maxResolutionTier: asset.max_resolution_tier,
37
38
  videoQuality: asset.video_quality,
38
39
  staticRenditions: asset.static_renditions
@@ -1 +1 @@
1
- {"version":3,"file":"muxAssetHandler.js","names":["args: GetMuxAssetHandlerArgs"],"sources":["../../src/endpoints/muxAssetHandler.ts"],"sourcesContent":["import type { Mux } from '@mux/mux-node'\n\nimport type { PayloadHandler } from 'payload'\nimport type { StaticRenditions } from '../types'\n\ninterface GetMuxAssetHandlerArgs {\n getMuxClient: () => Mux\n}\n\nexport function getMuxAssetHandler(\n args: GetMuxAssetHandlerArgs\n): PayloadHandler {\n const { getMuxClient } = args\n\n return async (req) => {\n try {\n const mux = getMuxClient()\n const { query } = req\n\n const uploadId = query.upload_id as string\n\n if (!uploadId) {\n return Response.json(\n { message: 'Upload ID is required' },\n { status: 400 }\n )\n }\n\n const assets = await mux.video.assets.list({\n limit: 1,\n upload_id: uploadId,\n })\n\n const asset = assets?.data[0]\n\n if (!asset) {\n return Response.json(\n { message: 'No asset found for the given upload ID' },\n { status: 404 }\n )\n }\n\n if (asset.status === 'ready') {\n const { payload } = req\n\n const { docs } = await payload.find({\n collection: 'media',\n where: {\n 'mux.uploadId': {\n equals: uploadId,\n },\n },\n limit: 1,\n pagination: false,\n })\n\n if (docs.length > 0) {\n if (asset?.status === 'ready') {\n const { id } = docs[0]\n await payload.update({\n collection: 'media',\n id,\n data: {\n mux: {\n status: asset.status,\n assetId: asset.id,\n playbackId: asset.playback_ids?.[0]?.id,\n aspectRatio: asset.aspect_ratio,\n duration: asset.duration,\n maxResolutionTier: asset.max_resolution_tier,\n videoQuality: asset.video_quality,\n staticRenditions: asset.static_renditions as StaticRenditions,\n },\n },\n })\n }\n }\n return Response.json(\n {\n ready: asset.status === 'ready',\n asset,\n },\n { status: 200 }\n )\n } else {\n return Response.json(\n {\n ready: false,\n asset,\n },\n { status: 200 }\n )\n }\n } catch (_error) {\n return Response.json(\n { message: 'Failed to fetch Mux asset' },\n { status: 500 }\n )\n }\n }\n}\n"],"mappings":";AASA,SAAgB,mBACdA,MACgB;CAChB,MAAM,EAAE,cAAc,GAAG;AAEzB,QAAO,OAAO,QAAQ;AACpB,MAAI;GACF,MAAM,MAAM,cAAc;GAC1B,MAAM,EAAE,OAAO,GAAG;GAElB,MAAM,WAAW,MAAM;AAEvB,OAAI,CAAC,SACH,QAAO,SAAS,KACd,EAAE,SAAS,wBAAyB,GACpC,EAAE,QAAQ,IAAK,EAChB;GAGH,MAAM,SAAS,MAAM,IAAI,MAAM,OAAO,KAAK;IACzC,OAAO;IACP,WAAW;GACZ,EAAC;GAEF,MAAM,QAAQ,QAAQ,KAAK;AAE3B,OAAI,CAAC,MACH,QAAO,SAAS,KACd,EAAE,SAAS,yCAA0C,GACrD,EAAE,QAAQ,IAAK,EAChB;AAGH,OAAI,MAAM,WAAW,SAAS;IAC5B,MAAM,EAAE,SAAS,GAAG;IAEpB,MAAM,EAAE,MAAM,GAAG,MAAM,QAAQ,KAAK;KAClC,YAAY;KACZ,OAAO,EACL,gBAAgB,EACd,QAAQ,SACT,EACF;KACD,OAAO;KACP,YAAY;IACb,EAAC;AAEF,QAAI,KAAK,SAAS,GAChB;SAAI,OAAO,WAAW,SAAS;MAC7B,MAAM,EAAE,IAAI,GAAG,KAAK;MACpB,MAAM,QAAQ,OAAO;OACnB,YAAY;OACZ;OACA,MAAM,EACJ,KAAK;QACH,QAAQ,MAAM;QACd,SAAS,MAAM;QACf,YAAY,MAAM,eAAe,IAAI;QACrC,aAAa,MAAM;QACnB,UAAU,MAAM;QAChB,mBAAmB,MAAM;QACzB,cAAc,MAAM;QACpB,kBAAkB,MAAM;OACzB,EACF;MACF,EAAC;KACH;;AAEH,WAAO,SAAS,KACd;KACE,OAAO,MAAM,WAAW;KACxB;IACD,GACD,EAAE,QAAQ,IAAK,EAChB;GACF,MACC,QAAO,SAAS,KACd;IACE,OAAO;IACP;GACD,GACD,EAAE,QAAQ,IAAK,EAChB;EAEJ,SAAQ,QAAQ;AACf,UAAO,SAAS,KACd,EAAE,SAAS,4BAA6B,GACxC,EAAE,QAAQ,IAAK,EAChB;EACF;CACF;AACF"}
1
+ {"version":3,"file":"muxAssetHandler.js","names":["args: GetMuxAssetHandlerArgs"],"sources":["../../src/endpoints/muxAssetHandler.ts"],"sourcesContent":["import type { Mux } from '@mux/mux-node'\n\nimport type { PayloadHandler } from 'payload'\nimport type { StaticRenditions } from '../types'\n\ninterface GetMuxAssetHandlerArgs {\n getMuxClient: () => Mux\n}\n\nexport function getMuxAssetHandler(\n args: GetMuxAssetHandlerArgs\n): PayloadHandler {\n const { getMuxClient } = args\n\n return async (req) => {\n try {\n const mux = getMuxClient()\n const { query } = req\n\n const uploadId = query.upload_id as string\n\n if (!uploadId) {\n return Response.json(\n { message: 'Upload ID is required' },\n { status: 400 }\n )\n }\n\n const assets = await mux.video.assets.list({\n limit: 1,\n upload_id: uploadId,\n })\n\n const asset = assets?.data[0]\n\n if (!asset) {\n return Response.json(\n { message: 'No asset found for the given upload ID' },\n { status: 404 }\n )\n }\n\n if (asset.status === 'ready') {\n const { payload } = req\n\n const { docs } = await payload.find({\n collection: 'media',\n where: {\n 'mux.uploadId': {\n equals: uploadId,\n },\n },\n limit: 1,\n pagination: false,\n })\n\n if (docs.length > 0) {\n if (asset?.status === 'ready') {\n const { id } = docs[0]\n await payload.update({\n collection: 'media',\n id,\n data: {\n mux: {\n status: asset.status,\n assetId: asset.id,\n playbackId: asset.playback_ids?.[0]?.id,\n aspectRatio: asset.aspect_ratio,\n duration: asset.duration,\n tracks: asset.tracks,\n maxResolutionTier: asset.max_resolution_tier,\n videoQuality: asset.video_quality,\n staticRenditions: asset.static_renditions as StaticRenditions,\n },\n },\n })\n }\n }\n return Response.json(\n {\n ready: asset.status === 'ready',\n asset,\n },\n { status: 200 }\n )\n } else {\n return Response.json(\n {\n ready: false,\n asset,\n },\n { status: 200 }\n )\n }\n } catch (_error) {\n return Response.json(\n { message: 'Failed to fetch Mux asset' },\n { status: 500 }\n )\n }\n }\n}\n"],"mappings":";AASA,SAAgB,mBACdA,MACgB;CAChB,MAAM,EAAE,cAAc,GAAG;AAEzB,QAAO,OAAO,QAAQ;AACpB,MAAI;GACF,MAAM,MAAM,cAAc;GAC1B,MAAM,EAAE,OAAO,GAAG;GAElB,MAAM,WAAW,MAAM;AAEvB,OAAI,CAAC,SACH,QAAO,SAAS,KACd,EAAE,SAAS,wBAAyB,GACpC,EAAE,QAAQ,IAAK,EAChB;GAGH,MAAM,SAAS,MAAM,IAAI,MAAM,OAAO,KAAK;IACzC,OAAO;IACP,WAAW;GACZ,EAAC;GAEF,MAAM,QAAQ,QAAQ,KAAK;AAE3B,OAAI,CAAC,MACH,QAAO,SAAS,KACd,EAAE,SAAS,yCAA0C,GACrD,EAAE,QAAQ,IAAK,EAChB;AAGH,OAAI,MAAM,WAAW,SAAS;IAC5B,MAAM,EAAE,SAAS,GAAG;IAEpB,MAAM,EAAE,MAAM,GAAG,MAAM,QAAQ,KAAK;KAClC,YAAY;KACZ,OAAO,EACL,gBAAgB,EACd,QAAQ,SACT,EACF;KACD,OAAO;KACP,YAAY;IACb,EAAC;AAEF,QAAI,KAAK,SAAS,GAChB;SAAI,OAAO,WAAW,SAAS;MAC7B,MAAM,EAAE,IAAI,GAAG,KAAK;MACpB,MAAM,QAAQ,OAAO;OACnB,YAAY;OACZ;OACA,MAAM,EACJ,KAAK;QACH,QAAQ,MAAM;QACd,SAAS,MAAM;QACf,YAAY,MAAM,eAAe,IAAI;QACrC,aAAa,MAAM;QACnB,UAAU,MAAM;QAChB,QAAQ,MAAM;QACd,mBAAmB,MAAM;QACzB,cAAc,MAAM;QACpB,kBAAkB,MAAM;OACzB,EACF;MACF,EAAC;KACH;;AAEH,WAAO,SAAS,KACd;KACE,OAAO,MAAM,WAAW;KACxB;IACD,GACD,EAAE,QAAQ,IAAK,EAChB;GACF,MACC,QAAO,SAAS,KACd;IACE,OAAO;IACP;GACD,GACD,EAAE,QAAQ,IAAK,EAChB;EAEJ,SAAQ,QAAQ;AACf,UAAO,SAAS,KACd,EAAE,SAAS,4BAA6B,GACxC,EAAE,QAAQ,IAAK,EAChB;EACF;CACF;AACF"}
@@ -1,4 +1,4 @@
1
- import { MediaCloudError } from "../types/errors.js";
1
+ import { MediaCloudErrors } from "../types/errors.js";
2
2
  import { useErrorHandler } from "../hooks/useErrorHandler.js";
3
3
 
4
4
  //#region src/endpoints/muxCreateUploadHandler.ts
@@ -8,7 +8,7 @@ function getMuxCreateUploadHandler(args) {
8
8
  const { throwError, logError } = useErrorHandler();
9
9
  try {
10
10
  if (!req.json) {
11
- throwError(MediaCloudError.MUX_REQUEST_NO_JSON);
11
+ throwError(MediaCloudErrors.MUX_REQUEST_NO_JSON);
12
12
  throw new Error();
13
13
  }
14
14
  const body = req.json ? await req.json() : "";
@@ -29,7 +29,7 @@ function getMuxCreateUploadHandler(args) {
29
29
  uploadId: upload.id
30
30
  });
31
31
  } catch (_error) {
32
- logError(MediaCloudError.MUX_CREATE_UPLOAD_ERROR);
32
+ logError(MediaCloudErrors.MUX_CREATE_UPLOAD_ERROR);
33
33
  return Response.json({ message: "Failed to create upload" }, { status: 500 });
34
34
  }
35
35
  };
@@ -1 +1 @@
1
- {"version":3,"file":"muxCreateUploadHandler.js","names":["args: GetMuxCreateUploadHandlerArgs"],"sources":["../../src/endpoints/muxCreateUploadHandler.ts"],"sourcesContent":["import type { Mux } from '@mux/mux-node'\n\nimport type { PayloadHandler } from 'payload'\nimport { MediaCloudPluginOptions } from '../types'\nimport { useErrorHandler } from '../hooks/useErrorHandler'\nimport { MediaCloudError } from '../types/errors'\n\ninterface GetMuxCreateUploadHandlerArgs {\n getMuxClient: () => Mux\n pluginOptions: MediaCloudPluginOptions\n}\n\nexport function getMuxCreateUploadHandler(\n args: GetMuxCreateUploadHandlerArgs\n): PayloadHandler {\n const { getMuxClient, pluginOptions } = args\n\n return async (req) => {\n const { throwError, logError } = useErrorHandler()\n\n try {\n if (!req.json) {\n throwError(MediaCloudError.MUX_REQUEST_NO_JSON)\n throw new Error() // This will never execute but satisfies TypeScript\n }\n const body = req.json ? await req.json() : ''\n const { filename } = body\n const mux = getMuxClient()\n const assetOptions = pluginOptions.mux?.assetOptions || {}\n const upload = await mux.video.uploads.create({\n cors_origin: '*',\n new_asset_settings: {\n playback_policies: ['public'],\n meta: {\n title: filename,\n },\n ...assetOptions,\n },\n test: pluginOptions.mux?.testMode ?? true,\n })\n return Response.json({ url: upload.url, uploadId: upload.id })\n } catch (_error) {\n logError(MediaCloudError.MUX_CREATE_UPLOAD_ERROR)\n return Response.json(\n { message: 'Failed to create upload' },\n { status: 500 }\n )\n }\n }\n}\n"],"mappings":";;;;AAYA,SAAgB,0BACdA,MACgB;CAChB,MAAM,EAAE,cAAc,eAAe,GAAG;AAExC,QAAO,OAAO,QAAQ;EACpB,MAAM,EAAE,YAAY,UAAU,GAAG,iBAAiB;AAElD,MAAI;AACF,OAAI,CAAC,IAAI,MAAM;IACb,WAAW,gBAAgB,oBAAoB;AAC/C,UAAM,IAAI;GACX;GACD,MAAM,OAAO,IAAI,OAAO,MAAM,IAAI,MAAM,GAAG;GAC3C,MAAM,EAAE,UAAU,GAAG;GACrB,MAAM,MAAM,cAAc;GAC1B,MAAM,eAAe,cAAc,KAAK,gBAAgB,CAAE;GAC1D,MAAM,SAAS,MAAM,IAAI,MAAM,QAAQ,OAAO;IAC5C,aAAa;IACb,oBAAoB;KAClB,mBAAmB,CAAC,QAAS;KAC7B,MAAM,EACJ,OAAO,SACR;KACD,GAAG;IACJ;IACD,MAAM,cAAc,KAAK,YAAY;GACtC,EAAC;AACF,UAAO,SAAS,KAAK;IAAE,KAAK,OAAO;IAAK,UAAU,OAAO;GAAI,EAAC;EAC/D,SAAQ,QAAQ;GACf,SAAS,gBAAgB,wBAAwB;AACjD,UAAO,SAAS,KACd,EAAE,SAAS,0BAA2B,GACtC,EAAE,QAAQ,IAAK,EAChB;EACF;CACF;AACF"}
1
+ {"version":3,"file":"muxCreateUploadHandler.js","names":["args: GetMuxCreateUploadHandlerArgs"],"sources":["../../src/endpoints/muxCreateUploadHandler.ts"],"sourcesContent":["import type { Mux } from '@mux/mux-node'\n\nimport type { PayloadHandler } from 'payload'\nimport { MediaCloudPluginOptions } from '../types'\nimport { useErrorHandler } from '../hooks/useErrorHandler'\nimport { MediaCloudErrors } from '../types/errors'\n\ninterface GetMuxCreateUploadHandlerArgs {\n getMuxClient: () => Mux\n pluginOptions: MediaCloudPluginOptions\n}\n\nexport function getMuxCreateUploadHandler(\n args: GetMuxCreateUploadHandlerArgs\n): PayloadHandler {\n const { getMuxClient, pluginOptions } = args\n\n return async (req) => {\n const { throwError, logError } = useErrorHandler()\n\n try {\n if (!req.json) {\n throwError(MediaCloudErrors.MUX_REQUEST_NO_JSON)\n throw new Error() // This will never execute but satisfies TypeScript\n }\n const body = req.json ? await req.json() : ''\n const { filename } = body\n const mux = getMuxClient()\n const assetOptions = pluginOptions.mux?.assetOptions || {}\n const upload = await mux.video.uploads.create({\n cors_origin: '*',\n new_asset_settings: {\n playback_policies: ['public'],\n meta: {\n title: filename,\n },\n ...assetOptions,\n },\n test: pluginOptions.mux?.testMode ?? true,\n })\n return Response.json({ url: upload.url, uploadId: upload.id })\n } catch (_error) {\n logError(MediaCloudErrors.MUX_CREATE_UPLOAD_ERROR)\n return Response.json(\n { message: 'Failed to create upload' },\n { status: 500 }\n )\n }\n }\n}\n"],"mappings":";;;;AAYA,SAAgB,0BACdA,MACgB;CAChB,MAAM,EAAE,cAAc,eAAe,GAAG;AAExC,QAAO,OAAO,QAAQ;EACpB,MAAM,EAAE,YAAY,UAAU,GAAG,iBAAiB;AAElD,MAAI;AACF,OAAI,CAAC,IAAI,MAAM;IACb,WAAW,iBAAiB,oBAAoB;AAChD,UAAM,IAAI;GACX;GACD,MAAM,OAAO,IAAI,OAAO,MAAM,IAAI,MAAM,GAAG;GAC3C,MAAM,EAAE,UAAU,GAAG;GACrB,MAAM,MAAM,cAAc;GAC1B,MAAM,eAAe,cAAc,KAAK,gBAAgB,CAAE;GAC1D,MAAM,SAAS,MAAM,IAAI,MAAM,QAAQ,OAAO;IAC5C,aAAa;IACb,oBAAoB;KAClB,mBAAmB,CAAC,QAAS;KAC7B,MAAM,EACJ,OAAO,SACR;KACD,GAAG;IACJ;IACD,MAAM,cAAc,KAAK,YAAY;GACtC,EAAC;AACF,UAAO,SAAS,KAAK;IAAE,KAAK,OAAO;IAAK,UAAU,OAAO;GAAI,EAAC;EAC/D,SAAQ,QAAQ;GACf,SAAS,iBAAiB,wBAAwB;AAClD,UAAO,SAAS,KACd,EAAE,SAAS,0BAA2B,GACtC,EAAE,QAAQ,IAAK,EAChB;EACF;CACF;AACF"}
@@ -1,29 +1,37 @@
1
1
  //#region ../error-handler/dist/index.js
2
2
  /**
3
- * Creates an error handler with configurable prefix and error sets
4
- * @param config - Configuration object containing prefix, level, and error set
5
- * @returns Object with logError and throwError functions
3
+ * Creates a logger with configurable prefix, levels, and error/log sets
4
+ * @param config - Configuration object containing prefix, level, error set, and log set
5
+ * @returns Object with logError, throwError, and log functions
6
6
  */
7
- function createErrorHandler(config) {
8
- const { prefix, level, errors } = config;
7
+ function createLogger(config) {
8
+ const { prefix, level, errors = {}, logs = {} } = config;
9
+ const logEntriesSet = new Set(Object.values(logs));
10
+ const errorEntryKeyMap = /* @__PURE__ */ new Map();
11
+ Object.entries(errors).forEach(([key, errorEntry]) => {
12
+ errorEntryKeyMap.set(errorEntry, key);
13
+ });
9
14
  class BaseError extends Error {
10
15
  key;
11
- constructor({ message, key }) {
16
+ errorCode;
17
+ constructor({ message, key, errorCode }) {
12
18
  super(`[${prefix}] ${message}`);
13
19
  this.name = "BaseError";
14
20
  this.key = key;
21
+ this.errorCode = errorCode;
15
22
  }
16
23
  }
17
24
  function formatMessage(message) {
18
25
  return `[${prefix}] ${message}`;
19
26
  }
20
- function logError(message, overrideLevel) {
21
- const formattedMessage = formatMessage(message);
27
+ function logError(errorEntry, overrideLevel) {
28
+ if (!errorEntry) {
29
+ console.error(`[${prefix}] Invalid error entry provided`);
30
+ return;
31
+ }
32
+ const formattedMessage = formatMessage(errorEntry.message);
22
33
  const logLevel = overrideLevel ?? level;
23
34
  switch (logLevel) {
24
- case "LOG":
25
- console.log(formattedMessage);
26
- break;
27
35
  case "WARNING":
28
36
  console.warn(formattedMessage);
29
37
  break;
@@ -33,33 +41,43 @@ function createErrorHandler(config) {
33
41
  default: console.error(formattedMessage);
34
42
  }
35
43
  }
36
- function logConsole(message) {
37
- const formattedMessage = formatMessage(message);
44
+ function log(logEntry) {
45
+ if (!logEntry || !logEntriesSet.has(logEntry)) {
46
+ console.error(`[${prefix}] Invalid log entry provided`);
47
+ return;
48
+ }
49
+ const formattedMessage = formatMessage(logEntry.message);
38
50
  console.log(formattedMessage);
39
51
  }
40
- function throwError(message) {
41
- const key = (Object.keys(errors).find((k) => errors[k] === message) ?? "").toString();
52
+ function throwError(errorEntry) {
53
+ if (!errorEntry) throw new BaseError({
54
+ key: "UNKNOWN_ERROR",
55
+ message: "Invalid error entry provided",
56
+ errorCode: 500
57
+ });
58
+ const errorCode = errorEntry.errorCode ?? 500;
59
+ const errorKey = errorEntryKeyMap.get(errorEntry) || "UNKNOWN_ERROR";
42
60
  throw new BaseError({
43
- key,
44
- message
61
+ key: errorKey,
62
+ message: errorEntry.message,
63
+ errorCode
45
64
  });
46
65
  }
47
66
  return {
48
67
  logError,
49
68
  throwError,
50
- logConsole
69
+ log
51
70
  };
52
71
  }
53
72
  /**
54
- * Error level enum for categorizing error severity
73
+ * Log level enum for categorizing log/error severity
55
74
  */
56
- let ErrorLevel = /* @__PURE__ */ function(ErrorLevel$1) {
57
- ErrorLevel$1["LOG"] = "LOG";
58
- ErrorLevel$1["WARNING"] = "WARNING";
59
- ErrorLevel$1["ERROR"] = "ERROR";
60
- return ErrorLevel$1;
75
+ let LogLevel = /* @__PURE__ */ function(LogLevel$1) {
76
+ LogLevel$1["WARNING"] = "WARNING";
77
+ LogLevel$1["ERROR"] = "ERROR";
78
+ return LogLevel$1;
61
79
  }({});
62
80
 
63
81
  //#endregion
64
- export { ErrorLevel, createErrorHandler };
82
+ export { LogLevel, createLogger };
65
83
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../error-handler/dist/index.js"],"sourcesContent":["//#region src/createErrorHandler.ts\n/**\n* Creates an error handler with configurable prefix and error sets\n* @param config - Configuration object containing prefix, level, and error set\n* @returns Object with logError and throwError functions\n*/\nfunction createErrorHandler(config) {\n\tconst { prefix, level, errors } = config;\n\tclass BaseError extends Error {\n\t\tkey;\n\t\tconstructor({ message, key }) {\n\t\t\tsuper(`[${prefix}] ${message}`);\n\t\t\tthis.name = \"BaseError\";\n\t\t\tthis.key = key;\n\t\t}\n\t}\n\tfunction formatMessage(message) {\n\t\treturn `[${prefix}] ${message}`;\n\t}\n\tfunction logError(message, overrideLevel) {\n\t\tconst formattedMessage = formatMessage(message);\n\t\tconst logLevel = overrideLevel ?? level;\n\t\tswitch (logLevel) {\n\t\t\tcase \"LOG\":\n\t\t\t\tconsole.log(formattedMessage);\n\t\t\t\tbreak;\n\t\t\tcase \"WARNING\":\n\t\t\t\tconsole.warn(formattedMessage);\n\t\t\t\tbreak;\n\t\t\tcase \"ERROR\":\n\t\t\t\tconsole.error(formattedMessage);\n\t\t\t\tbreak;\n\t\t\tdefault: console.error(formattedMessage);\n\t\t}\n\t}\n\tfunction logConsole(message) {\n\t\tconst formattedMessage = formatMessage(message);\n\t\tconsole.log(formattedMessage);\n\t}\n\tfunction throwError(message) {\n\t\tconst key = (Object.keys(errors).find((k) => errors[k] === message) ?? \"\").toString();\n\t\tthrow new BaseError({\n\t\t\tkey,\n\t\t\tmessage\n\t\t});\n\t}\n\treturn {\n\t\tlogError,\n\t\tthrowError,\n\t\tlogConsole\n\t};\n}\n\n//#endregion\n//#region src/types.ts\n/**\n* Error level enum for categorizing error severity\n*/\nlet ErrorLevel = /* @__PURE__ */ function(ErrorLevel$1) {\n\tErrorLevel$1[\"LOG\"] = \"LOG\";\n\tErrorLevel$1[\"WARNING\"] = \"WARNING\";\n\tErrorLevel$1[\"ERROR\"] = \"ERROR\";\n\treturn ErrorLevel$1;\n}({});\n\n//#endregion\nexport { ErrorLevel, createErrorHandler };\n//# sourceMappingURL=index.js.map"],"mappings":";;;;;;AAMA,SAAS,mBAAmB,QAAQ;CACnC,MAAM,EAAE,QAAQ,OAAO,QAAQ,GAAG;CAClC,MAAM,kBAAkB,MAAM;EAC7B;EACA,YAAY,EAAE,SAAS,KAAK,EAAE;GAC7B,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC;GAC/B,KAAK,OAAO;GACZ,KAAK,MAAM;EACX;CACD;CACD,SAAS,cAAc,SAAS;AAC/B,SAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS;CAC/B;CACD,SAAS,SAAS,SAAS,eAAe;EACzC,MAAM,mBAAmB,cAAc,QAAQ;EAC/C,MAAM,WAAW,iBAAiB;AAClC,UAAQ,UAAR;GACC,KAAK;IACJ,QAAQ,IAAI,iBAAiB;AAC7B;GACD,KAAK;IACJ,QAAQ,KAAK,iBAAiB;AAC9B;GACD,KAAK;IACJ,QAAQ,MAAM,iBAAiB;AAC/B;GACD,SAAS,QAAQ,MAAM,iBAAiB;EACxC;CACD;CACD,SAAS,WAAW,SAAS;EAC5B,MAAM,mBAAmB,cAAc,QAAQ;EAC/C,QAAQ,IAAI,iBAAiB;CAC7B;CACD,SAAS,WAAW,SAAS;EAC5B,MAAM,OAAO,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,OAAO,OAAO,QAAQ,IAAI,IAAI,UAAU;AACrF,QAAM,IAAI,UAAU;GACnB;GACA;EACA;CACD;AACD,QAAO;EACN;EACA;EACA;CACA;AACD;;;;AAOD,IAAI,6BAA6B,SAAS,cAAc;CACvD,aAAa,SAAS;CACtB,aAAa,aAAa;CAC1B,aAAa,WAAW;AACxB,QAAO;AACP,EAAC,CAAE,EAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../error-handler/dist/index.js"],"sourcesContent":["//#region src/createErrorHandler.ts\n/**\n* Creates a logger with configurable prefix, levels, and error/log sets\n* @param config - Configuration object containing prefix, level, error set, and log set\n* @returns Object with logError, throwError, and log functions\n*/\nfunction createLogger(config) {\n\tconst { prefix, level, errors = {}, logs = {} } = config;\n\tconst logEntriesSet = new Set(Object.values(logs));\n\tconst errorEntryKeyMap = /* @__PURE__ */ new Map();\n\tObject.entries(errors).forEach(([key, errorEntry]) => {\n\t\terrorEntryKeyMap.set(errorEntry, key);\n\t});\n\tclass BaseError extends Error {\n\t\tkey;\n\t\terrorCode;\n\t\tconstructor({ message, key, errorCode }) {\n\t\t\tsuper(`[${prefix}] ${message}`);\n\t\t\tthis.name = \"BaseError\";\n\t\t\tthis.key = key;\n\t\t\tthis.errorCode = errorCode;\n\t\t}\n\t}\n\tfunction formatMessage(message) {\n\t\treturn `[${prefix}] ${message}`;\n\t}\n\tfunction logError(errorEntry, overrideLevel) {\n\t\tif (!errorEntry) {\n\t\t\tconsole.error(`[${prefix}] Invalid error entry provided`);\n\t\t\treturn;\n\t\t}\n\t\tconst formattedMessage = formatMessage(errorEntry.message);\n\t\tconst logLevel = overrideLevel ?? level;\n\t\tswitch (logLevel) {\n\t\t\tcase \"WARNING\":\n\t\t\t\tconsole.warn(formattedMessage);\n\t\t\t\tbreak;\n\t\t\tcase \"ERROR\":\n\t\t\t\tconsole.error(formattedMessage);\n\t\t\t\tbreak;\n\t\t\tdefault: console.error(formattedMessage);\n\t\t}\n\t}\n\tfunction log(logEntry) {\n\t\tif (!logEntry || !logEntriesSet.has(logEntry)) {\n\t\t\tconsole.error(`[${prefix}] Invalid log entry provided`);\n\t\t\treturn;\n\t\t}\n\t\tconst formattedMessage = formatMessage(logEntry.message);\n\t\tconsole.log(formattedMessage);\n\t}\n\tfunction throwError(errorEntry) {\n\t\tif (!errorEntry) throw new BaseError({\n\t\t\tkey: \"UNKNOWN_ERROR\",\n\t\t\tmessage: \"Invalid error entry provided\",\n\t\t\terrorCode: 500\n\t\t});\n\t\tconst errorCode = errorEntry.errorCode ?? 500;\n\t\tconst errorKey = errorEntryKeyMap.get(errorEntry) || \"UNKNOWN_ERROR\";\n\t\tthrow new BaseError({\n\t\t\tkey: errorKey,\n\t\t\tmessage: errorEntry.message,\n\t\t\terrorCode\n\t\t});\n\t}\n\treturn {\n\t\tlogError,\n\t\tthrowError,\n\t\tlog\n\t};\n}\n\n//#endregion\n//#region src/types.ts\n/**\n* Log level enum for categorizing log/error severity\n*/\nlet LogLevel = /* @__PURE__ */ function(LogLevel$1) {\n\tLogLevel$1[\"WARNING\"] = \"WARNING\";\n\tLogLevel$1[\"ERROR\"] = \"ERROR\";\n\treturn LogLevel$1;\n}({});\n\n//#endregion\nexport { LogLevel, createLogger };\n//# sourceMappingURL=index.js.map"],"mappings":";;;;;;AAMA,SAAS,aAAa,QAAQ;CAC7B,MAAM,EAAE,QAAQ,OAAO,SAAS,CAAE,GAAE,OAAO,CAAE,GAAE,GAAG;CAClD,MAAM,gBAAgB,IAAI,IAAI,OAAO,OAAO,KAAK;CACjD,MAAM,mCAAmC,IAAI;CAC7C,OAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,WAAW,KAAK;EACrD,iBAAiB,IAAI,YAAY,IAAI;CACrC,EAAC;CACF,MAAM,kBAAkB,MAAM;EAC7B;EACA;EACA,YAAY,EAAE,SAAS,KAAK,WAAW,EAAE;GACxC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC;GAC/B,KAAK,OAAO;GACZ,KAAK,MAAM;GACX,KAAK,YAAY;EACjB;CACD;CACD,SAAS,cAAc,SAAS;AAC/B,SAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS;CAC/B;CACD,SAAS,SAAS,YAAY,eAAe;AAC5C,MAAI,CAAC,YAAY;GAChB,QAAQ,MAAM,CAAC,CAAC,EAAE,OAAO,8BAA8B,CAAC,CAAC;AACzD;EACA;EACD,MAAM,mBAAmB,cAAc,WAAW,QAAQ;EAC1D,MAAM,WAAW,iBAAiB;AAClC,UAAQ,UAAR;GACC,KAAK;IACJ,QAAQ,KAAK,iBAAiB;AAC9B;GACD,KAAK;IACJ,QAAQ,MAAM,iBAAiB;AAC/B;GACD,SAAS,QAAQ,MAAM,iBAAiB;EACxC;CACD;CACD,SAAS,IAAI,UAAU;AACtB,MAAI,CAAC,YAAY,CAAC,cAAc,IAAI,SAAS,EAAE;GAC9C,QAAQ,MAAM,CAAC,CAAC,EAAE,OAAO,4BAA4B,CAAC,CAAC;AACvD;EACA;EACD,MAAM,mBAAmB,cAAc,SAAS,QAAQ;EACxD,QAAQ,IAAI,iBAAiB;CAC7B;CACD,SAAS,WAAW,YAAY;AAC/B,MAAI,CAAC,WAAY,OAAM,IAAI,UAAU;GACpC,KAAK;GACL,SAAS;GACT,WAAW;EACX;EACD,MAAM,YAAY,WAAW,aAAa;EAC1C,MAAM,WAAW,iBAAiB,IAAI,WAAW,IAAI;AACrD,QAAM,IAAI,UAAU;GACnB,KAAK;GACL,SAAS,WAAW;GACpB;EACA;CACD;AACD,QAAO;EACN;EACA;EACA;CACA;AACD;;;;AAOD,IAAI,2BAA2B,SAAS,YAAY;CACnD,WAAW,aAAa;CACxB,WAAW,WAAW;AACtB,QAAO;AACP,EAAC,CAAE,EAAC"}
@@ -1,4 +1,3 @@
1
- import { MediaCloudError } from "../types/errors.js";
2
1
  import * as mitt0 from "mitt";
3
2
 
4
3
  //#region src/hooks/useEmitter.d.ts
@@ -19,9 +18,9 @@ type EmitterEvents = {
19
18
  'upload-completed': {
20
19
  id: string;
21
20
  };
22
- 'upload-error': {
21
+ 'upload-errored': {
23
22
  id: string;
24
- error: MediaCloudError;
23
+ error: string;
25
24
  };
26
25
  };
27
26
  declare const emitter: mitt0.Emitter<EmitterEvents>;
@@ -1 +1 @@
1
- {"version":3,"file":"useEmitter.js","names":[],"sources":["../../src/hooks/useEmitter.ts"],"sourcesContent":["import mitt from 'mitt'\nimport { MediaCloudError } from '../types/errors'\n\ntype EmitterEvents = {\n 'add-upload': {\n id: string\n filename: string\n polling?: boolean\n pollingUrl?: string\n }\n 'update-upload': { id: string; progress: number }\n 'remove-upload': { id: string }\n 'upload-completed': { id: string }\n 'upload-error': { id: string; error: MediaCloudError }\n}\n\nconst emitter = mitt<EmitterEvents>()\n\n/**\n * Hook to access the global event emitter for upload management\n * @returns An object with emitter methods (on, off, emit)\n */\nfunction useEmitter() {\n return {\n on: emitter.on,\n off: emitter.off,\n emit: emitter.emit,\n }\n}\n\nexport { useEmitter, emitter }\n"],"mappings":";;;AAgBA,MAAM,UAAU,MAAqB;;;;;AAMrC,SAAS,aAAa;AACpB,QAAO;EACL,IAAI,QAAQ;EACZ,KAAK,QAAQ;EACb,MAAM,QAAQ;CACf;AACF"}
1
+ {"version":3,"file":"useEmitter.js","names":[],"sources":["../../src/hooks/useEmitter.ts"],"sourcesContent":["import mitt from 'mitt'\n\ntype EmitterEvents = {\n 'add-upload': {\n id: string\n filename: string\n polling?: boolean\n pollingUrl?: string\n }\n 'update-upload': { id: string; progress: number }\n 'remove-upload': { id: string }\n 'upload-completed': { id: string }\n 'upload-errored': { id: string; error: string }\n}\n\nconst emitter = mitt<EmitterEvents>()\n\n/**\n * Hook to access the global event emitter for upload management\n * @returns An object with emitter methods (on, off, emit)\n */\nfunction useEmitter() {\n return {\n on: emitter.on,\n off: emitter.off,\n emit: emitter.emit,\n }\n}\n\nexport { useEmitter, emitter }\n"],"mappings":";;;AAeA,MAAM,UAAU,MAAqB;;;;;AAMrC,SAAS,aAAa;AACpB,QAAO;EACL,IAAI,QAAQ;EACZ,KAAK,QAAQ;EACb,MAAM,QAAQ;CACf;AACF"}
@@ -1,11 +1,11 @@
1
- import { MediaCloudError } from "../types/errors.js";
2
- import { ErrorLevel } from "@maas/error-handler";
1
+ import * as _maas_error_handler0 from "@maas/error-handler";
2
+ import { LogLevel } from "@maas/error-handler";
3
3
 
4
4
  //#region src/hooks/useErrorHandler.d.ts
5
5
  declare function useErrorHandler(): {
6
- logError: (errorKey: MediaCloudError, level?: ErrorLevel) => void;
7
- throwError: (errorKey: MediaCloudError) => never;
8
- logConsole: (errorKey: MediaCloudError) => void;
6
+ logError: (errorEntry: _maas_error_handler0.ErrorEntry, overrideLevel?: LogLevel) => void;
7
+ throwError: (errorEntry: _maas_error_handler0.ErrorEntry) => never;
8
+ log: (logEntry: _maas_error_handler0.LogEntry) => void;
9
9
  };
10
10
  //#endregion
11
11
  export { useErrorHandler };