@maas/payload-plugin-media-cloud 0.0.6 → 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.
|
@@ -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"}
|
|
@@ -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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-operations.js","names":["maxMultipartParts: number","maxUploadSize: number","minPartSize: number","preferredPartSize: number","args: CalculateOptimalPartSizeArgs","optimalPartSize: number","args: CalculateOffsetFromPartsArgs","args: CalculatePartNumberArgs","args: GenerateUniqueTmpFileNameArgs","args: CalculateOffsetFromPartsExportArgs"],"sources":["../../../../src/tus/stores/s3/file-operations.ts"],"sourcesContent":["import crypto from 'node:crypto'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { useErrorHandler } from '../../../hooks/useErrorHandler'\nimport { MediaCloudErrors
|
|
1
|
+
{"version":3,"file":"file-operations.js","names":["maxMultipartParts: number","maxUploadSize: number","minPartSize: number","preferredPartSize: number","args: CalculateOptimalPartSizeArgs","optimalPartSize: number","args: CalculateOffsetFromPartsArgs","args: CalculatePartNumberArgs","args: GenerateUniqueTmpFileNameArgs","args: CalculateOffsetFromPartsExportArgs"],"sources":["../../../../src/tus/stores/s3/file-operations.ts"],"sourcesContent":["import crypto from 'node:crypto'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { useErrorHandler } from '../../../hooks/useErrorHandler'\nimport { MediaCloudErrors } from '../../../types/errors'\n\nimport type { NodeFSError } from '../../../types'\nimport type AWS from '@aws-sdk/client-s3'\n\ntype CalculateOptimalPartSizeArgs = {\n size?: number\n}\n\ntype CalculateOffsetFromPartsArgs = {\n parts?: Array<AWS.Part>\n}\n\ntype CalculatePartNumberArgs = {\n parts: Array<AWS.Part>\n}\n\ntype GenerateUniqueTmpFileNameArgs = {\n template: string\n}\n\ntype CalculateOffsetFromPartsExportArgs = {\n parts?: Array<{ Size?: number }>\n}\n\nconst { throwError } = useErrorHandler()\n\nexport class S3FileOperations {\n constructor(\n private maxMultipartParts: number,\n private maxUploadSize: number,\n private minPartSize: number,\n private preferredPartSize: number\n ) {}\n\n /**\n * Calculates the optimal part size for S3 multipart upload\n * @param args - The function arguments\n * @param args.size - The upload size in bytes (optional)\n * @returns The optimal part size in bytes\n */\n calculateOptimalPartSize(args: CalculateOptimalPartSizeArgs): number {\n const { size } = args\n // When upload size is not known we assume largest possible value (`maxUploadSize`)\n let uploadSize = size\n if (uploadSize === undefined) {\n uploadSize = this.maxUploadSize\n }\n\n let optimalPartSize: number\n\n // When upload is smaller or equal to PreferredPartSize, we upload in just one part.\n if (uploadSize <= this.preferredPartSize) {\n optimalPartSize = uploadSize\n }\n // Does the upload fit in MaxMultipartParts parts or less with PreferredPartSize.\n else if (uploadSize <= this.preferredPartSize * this.maxMultipartParts) {\n optimalPartSize = this.preferredPartSize\n // The upload is too big for the preferred size.\n // We divide the size with the max amount of parts and round it up.\n } else {\n optimalPartSize = Math.ceil(uploadSize / this.maxMultipartParts)\n }\n\n // Always ensure the part size is at least minPartSize\n return Math.max(optimalPartSize, this.minPartSize)\n }\n\n /**\n * Calculates the offset based on uploaded parts\n * @param args - The function arguments\n * @param args.parts - Array of uploaded parts (optional)\n * @returns The total offset in bytes\n */\n calculateOffsetFromParts(args: CalculateOffsetFromPartsArgs): number {\n const { parts } = args\n return parts && parts.length > 0\n ? parts.reduce((a, b) => a + (b.Size ?? 0), 0)\n : 0\n }\n\n /**\n * Calculates the next part number based on existing parts\n * @param args - The function arguments\n * @param args.parts - Array of uploaded parts\n * @returns The next part number to use\n */\n calculatePartNumber(args: CalculatePartNumberArgs): number {\n const { parts } = args\n return parts.length > 0 ? parts[parts.length - 1].PartNumber! + 1 : 1\n }\n\n /**\n * Generates a unique temporary file name\n * @param args - The function arguments\n * @param args.template - The template string for the file name\n * @returns Promise that resolves to the unique file path\n * @throws Error if unable to find unique name after max tries\n */\n async generateUniqueTmpFileName(\n args: GenerateUniqueTmpFileNameArgs\n ): Promise<string> {\n const { template } = args\n const tries = 5\n for (let i = 0; i < tries; i++) {\n const randomId = crypto.randomBytes(16).toString('hex')\n const filePath = path.join(os.tmpdir(), `${template}${randomId}`)\n try {\n await fs.promises.access(filePath, fs.constants.F_OK)\n } catch (error) {\n const nodeError = error as NodeFSError\n if (nodeError.code === 'ENOENT') {\n return filePath\n }\n }\n }\n throwError(MediaCloudErrors.S3_UNIQUE_NAME_ERROR)\n throw new Error() // This will never execute but satisfies TypeScript\n }\n}\n\n/**\n * Calculates the total offset from uploaded parts\n * @param args - The function arguments\n * @param args.parts - Array of parts with size information (optional)\n * @returns The total offset in bytes\n */\nexport function calculateOffsetFromParts(\n args: CalculateOffsetFromPartsExportArgs\n) {\n const { parts } = args\n return parts && parts.length > 0\n ? parts.reduce((a, b) => a + (b.Size ?? 0), 0)\n : 0\n}\n"],"mappings":";;;;;;;;AA+BA,MAAM,EAAE,YAAY,GAAG,iBAAiB;AAExC,IAAa,mBAAb,MAA8B;CAC5B,YACUA,mBACAC,eACAC,aACAC,mBACR;EAJQ;EACA;EACA;EACA;CACN;;;;;;;CAQJ,yBAAyBC,MAA4C;EACnE,MAAM,EAAE,MAAM,GAAG;EAEjB,IAAI,aAAa;AACjB,MAAI,eAAe,QACjB,aAAa,KAAK;EAGpB,IAAIC;AAGJ,MAAI,cAAc,KAAK,mBACrB,kBAAkB;WAGX,cAAc,KAAK,oBAAoB,KAAK,mBACnD,kBAAkB,KAAK;OAIvB,kBAAkB,KAAK,KAAK,aAAa,KAAK,kBAAkB;AAIlE,SAAO,KAAK,IAAI,iBAAiB,KAAK,YAAY;CACnD;;;;;;;CAQD,yBAAyBC,MAA4C;EACnE,MAAM,EAAE,OAAO,GAAG;AAClB,SAAO,SAAS,MAAM,SAAS,IAC3B,MAAM,OAAO,CAAC,GAAG,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAC5C;CACL;;;;;;;CAQD,oBAAoBC,MAAuC;EACzD,MAAM,EAAE,OAAO,GAAG;AAClB,SAAO,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,GAAG,aAAc,IAAI;CACrE;;;;;;;;CASD,MAAM,0BACJC,MACiB;EACjB,MAAM,EAAE,UAAU,GAAG;EACrB,MAAM,QAAQ;AACd,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;GAC9B,MAAM,WAAW,OAAO,YAAY,GAAG,CAAC,SAAS,MAAM;GACvD,MAAM,WAAW,KAAK,KAAK,GAAG,QAAQ,EAAE,GAAG,WAAW,UAAU,CAAC;AACjE,OAAI;IACF,MAAM,GAAG,SAAS,OAAO,UAAU,GAAG,UAAU,KAAK;GACtD,SAAQ,OAAO;IACd,MAAM,YAAY;AAClB,QAAI,UAAU,SAAS,SACrB,QAAO;GAEV;EACF;EACD,WAAW,iBAAiB,qBAAqB;AACjD,QAAM,IAAI;CACX;AACF;;;;;;;AAQD,SAAgB,yBACdC,MACA;CACA,MAAM,EAAE,OAAO,GAAG;AAClB,QAAO,SAAS,MAAM,SAAS,IAC3B,MAAM,OAAO,CAAC,GAAG,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAC5C;AACL"}
|