{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import type { ReadStream } from 'node:fs';\nimport { v2 as cloudinary, ConfigOptions, UploadApiOptions } from 'cloudinary';\nimport intoStream from 'into-stream';\nimport * as utils from '@strapi/utils';\n\ninterface File {\n  name: string;\n  alternativeText?: string;\n  caption?: string;\n  width?: number;\n  height?: number;\n  formats?: Record<string, unknown>;\n  hash: string;\n  ext?: string;\n  mime: string;\n  size: number;\n  sizeInBytes: number;\n  url: string;\n  previewUrl?: string;\n  path?: string;\n  provider?: string;\n  provider_metadata?: Record<string, unknown>;\n  stream?: ReadStream;\n  buffer?: Buffer;\n}\n\nexport default {\n  init(options: ConfigOptions) {\n    cloudinary.config(options);\n\n    const upload = (file: File, customConfig = {}): Promise<void> => {\n      return new Promise((resolve, reject) => {\n        const config: Partial<UploadApiOptions> = {\n          resource_type: 'auto',\n          public_id: file.hash,\n        };\n\n        if (file.ext) {\n          config.filename = `${file.hash}${file.ext}`;\n        }\n\n        if (file.path) {\n          config.folder = file.path;\n        }\n\n        // For files smaller than 99 MB use regular upload as it tends to be faster\n        // and fallback to chunked upload for larger files as that's required by Cloudinary.\n        // https://support.cloudinary.com/hc/en-us/community/posts/360009586100-Upload-movie-video-with-large-size?page=1#community_comment_360002140099\n        // The Cloudinary's max limit for regular upload is actually 100 MB but add some headroom\n        // for size counting shenanigans. (Strapi provides the size in kilobytes rounded to two decimal places here).\n        const uploadMethod =\n          file.size && file.size < 1000 * 99\n            ? cloudinary.uploader.upload_stream\n            : cloudinary.uploader.upload_chunked_stream;\n\n        const uploadStream = uploadMethod({ ...config, ...customConfig }, (err, image) => {\n          if (err) {\n            if (err.message.includes('File size too large')) {\n              reject(new utils.errors.PayloadTooLargeError());\n            } else {\n              reject(new Error(`Error uploading to cloudinary: ${err.message}`));\n            }\n            return;\n          }\n\n          if (!image) {\n            return;\n          }\n\n          if (image.resource_type === 'video') {\n            file.previewUrl = cloudinary.url(`${image.public_id}.gif`, {\n              video_sampling: 6,\n              delay: 200,\n              width: 250,\n              crop: 'scale',\n              resource_type: 'video',\n            });\n          }\n\n          file.url = image.secure_url;\n          file.provider_metadata = {\n            public_id: image.public_id,\n            resource_type: image.resource_type,\n          };\n\n          resolve();\n        });\n\n        if (file.stream) {\n          file.stream.pipe(uploadStream);\n        } else if (file.buffer) {\n          intoStream(file.buffer).pipe(uploadStream);\n        } else {\n          throw new Error('Missing file stream or buffer');\n        }\n      });\n    };\n\n    const replace = async (newFile: File, oldFile: File, customConfig = {}): Promise<void> => {\n      const { public_id: oldPublicId, resource_type: oldResourceType } =\n        oldFile.provider_metadata ?? {};\n\n      // If the public_id is preserved, we can overwrite in place and invalidate\n      // the CDN cache in a single call.\n      if (oldPublicId && newFile.hash === oldPublicId) {\n        return upload(newFile, {\n          public_id: oldPublicId as string,\n          overwrite: true,\n          invalidate: true,\n          ...(oldResourceType ? { resource_type: oldResourceType } : {}),\n          ...customConfig,\n        });\n      }\n\n      // The public_id differs — upload the new file first, then destroy the old.\n      await upload(newFile, customConfig);\n\n      if (oldPublicId) {\n        try {\n          await cloudinary.uploader.destroy(`${oldPublicId}`, {\n            resource_type: (oldResourceType || 'image') as string,\n            invalidate: true,\n          });\n        } catch (error) {\n          if (error instanceof Error) {\n            throw new Error(`Error deleting on cloudinary: ${error.message}`);\n          }\n          throw error;\n        }\n      }\n    };\n\n    return {\n      uploadStream(file: File, customConfig = {}) {\n        return upload(file, customConfig);\n      },\n      upload(file: File, customConfig = {}) {\n        return upload(file, customConfig);\n      },\n      replaceStream(newFile: File, oldFile: File, customConfig = {}) {\n        return replace(newFile, oldFile, customConfig);\n      },\n      replace(newFile: File, oldFile: File, customConfig = {}) {\n        return replace(newFile, oldFile, customConfig);\n      },\n      async delete(file: File, customConfig = {}) {\n        try {\n          const { resource_type: resourceType, public_id: publicId } = file.provider_metadata ?? {};\n          const deleteConfig = {\n            resource_type: (resourceType || 'image') as string,\n            invalidate: true,\n            ...customConfig,\n          };\n\n          const response = await cloudinary.uploader.destroy(`${publicId}`, deleteConfig);\n\n          if (response.result !== 'ok' && response.result !== 'not found') {\n            throw new Error(response.result);\n          }\n        } catch (error) {\n          if (error instanceof Error) {\n            throw new Error(`Error deleting on cloudinary: ${error.message}`);\n          }\n\n          throw error;\n        }\n      },\n    };\n  },\n};\n"],"names":["init","options","cloudinary","config","upload","file","customConfig","Promise","resolve","reject","resource_type","public_id","hash","ext","filename","path","folder","uploadMethod","size","uploader","upload_stream","upload_chunked_stream","uploadStream","err","image","message","includes","utils","errors","PayloadTooLargeError","Error","previewUrl","url","video_sampling","delay","width","crop","secure_url","provider_metadata","stream","pipe","buffer","intoStream","replace","newFile","oldFile","oldPublicId","oldResourceType","overwrite","invalidate","destroy","error","replaceStream","delete","resourceType","publicId","deleteConfig","response","result"],"mappings":"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"}