next-cloudinary 6.16.0 → 7.0.0-beta.10

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 (62) hide show
  1. package/dist/CldImage-841d87c1.cjs.js +121 -0
  2. package/dist/CldImage-c9af4fd9.esm.js +113 -0
  3. package/dist/CldUploadButton-196b419b.esm.js +101 -0
  4. package/dist/CldUploadButton-db9b095b.cjs.js +109 -0
  5. package/dist/CldUploadWidget-77f44ab3.esm.js +207 -0
  6. package/dist/CldUploadWidget-cdb65b22.cjs.js +215 -0
  7. package/dist/CldVideoPlayer-4db49132.esm.js +140 -0
  8. package/dist/CldVideoPlayer-a6525186.cjs.js +149 -0
  9. package/dist/cloudinary-1f1b51af.cjs.js +141 -0
  10. package/dist/cloudinary-cb3c790a.esm.js +134 -0
  11. package/dist/cloudinary-loader-ad7ad702.esm.js +57 -0
  12. package/dist/cloudinary-loader-c87ac9ae.cjs.js +60 -0
  13. package/dist/declarations/src/components/CldImage/CldImage.d.ts +14 -0
  14. package/dist/declarations/src/components/CldImage/CldImage.d.ts.map +1 -0
  15. package/dist/declarations/src/components/CldImage/index.d.ts +3 -0
  16. package/dist/declarations/src/components/CldImage/index.d.ts.map +1 -0
  17. package/dist/declarations/src/components/CldOgImage/CldOgImage.d.ts +9 -0
  18. package/dist/declarations/src/components/CldOgImage/CldOgImage.d.ts.map +1 -0
  19. package/dist/declarations/src/components/CldOgImage/index.d.ts +3 -0
  20. package/dist/declarations/src/components/CldOgImage/index.d.ts.map +1 -0
  21. package/dist/declarations/src/components/CldUploadButton/CldUploadButton.d.ts +9 -0
  22. package/dist/declarations/src/components/CldUploadButton/CldUploadButton.d.ts.map +1 -0
  23. package/dist/declarations/src/components/CldUploadButton/index.d.ts +3 -0
  24. package/dist/declarations/src/components/CldUploadButton/index.d.ts.map +1 -0
  25. package/dist/declarations/src/components/CldUploadWidget/CldUploadWidget.d.ts +4 -0
  26. package/dist/declarations/src/components/CldUploadWidget/CldUploadWidget.d.ts.map +1 -0
  27. package/dist/declarations/src/components/CldUploadWidget/CldUploadWidget.types.d.ts +59 -0
  28. package/dist/declarations/src/components/CldUploadWidget/CldUploadWidget.types.d.ts.map +1 -0
  29. package/dist/declarations/src/components/CldUploadWidget/index.d.ts +3 -0
  30. package/dist/declarations/src/components/CldUploadWidget/index.d.ts.map +1 -0
  31. package/dist/declarations/src/components/CldVideoPlayer/CldVideoPlayer.d.ts +4 -0
  32. package/dist/declarations/src/components/CldVideoPlayer/CldVideoPlayer.d.ts.map +1 -0
  33. package/dist/declarations/src/components/CldVideoPlayer/CldVideoPlayer.types.d.ts +28 -0
  34. package/dist/declarations/src/components/CldVideoPlayer/CldVideoPlayer.types.d.ts.map +1 -0
  35. package/dist/declarations/src/components/CldVideoPlayer/index.d.ts +3 -0
  36. package/dist/declarations/src/components/CldVideoPlayer/index.d.ts.map +1 -0
  37. package/dist/declarations/src/helpers/getCldImageUrl.d.ts +9 -0
  38. package/dist/declarations/src/helpers/getCldImageUrl.d.ts.map +1 -0
  39. package/dist/declarations/src/helpers/getCldOgImageUrl.d.ts +7 -0
  40. package/dist/declarations/src/helpers/getCldOgImageUrl.d.ts.map +1 -0
  41. package/dist/declarations/src/helpers/getCldVideoUrl.d.ts +9 -0
  42. package/dist/declarations/src/helpers/getCldVideoUrl.d.ts.map +1 -0
  43. package/dist/declarations/src/index.d.ts +21 -0
  44. package/dist/declarations/src/index.d.ts.map +1 -0
  45. package/dist/declarations/src/loaders/cloudinary-loader.d.ts +16 -0
  46. package/dist/declarations/src/loaders/cloudinary-loader.d.ts.map +1 -0
  47. package/dist/fonts/cloudinary_icon_for_white_bg.svg +1 -1
  48. package/dist/next-cloudinary.cjs.d.mts +2 -0
  49. package/dist/next-cloudinary.cjs.d.ts +2 -0
  50. package/dist/next-cloudinary.cjs.js +165 -0
  51. package/dist/next-cloudinary.cjs.mjs +11 -0
  52. package/dist/next-cloudinary.esm.js +134 -0
  53. package/package.json +51 -13
  54. package/dist/index.d.mts +0 -152
  55. package/dist/index.d.ts +0 -152
  56. package/dist/index.js +0 -4
  57. package/dist/index.js.map +0 -1
  58. package/dist/index.mjs +0 -4
  59. package/dist/index.mjs.map +0 -1
  60. package/plugins/copy-assets.ts +0 -80
  61. package/tsconfig.json +0 -23
  62. package/tsup.config.ts +0 -18
@@ -0,0 +1,121 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var react = require('react');
7
+ var Image = require('next/image');
8
+ var util = require('@cloudinary-util/util');
9
+ var urlLoader = require('@cloudinary-util/url-loader');
10
+ var cloudinaryLoader = require('./cloudinary-loader-c87ac9ae.cjs.js');
11
+ var jsxRuntime = require('react/jsx-runtime');
12
+ require('./cloudinary-1f1b51af.cjs.js');
13
+ require('next/package.json');
14
+
15
+ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
16
+
17
+ var Image__default = /*#__PURE__*/_interopDefault(Image);
18
+
19
+ const CldImage = /*#__PURE__*/react.forwardRef(function CldImage(props, ref) {
20
+ let hasThrownError = false;
21
+
22
+ // Add props here that are intended to only be used for
23
+ // Cloudinary URL construction to avoid them being forwarded
24
+ // to the DOM
25
+
26
+ const CLD_OPTIONS = ['assetType', 'config', 'deliveryType', 'strictTransformations', ...urlLoader.cloudinaryPluginKeys];
27
+
28
+ // Construct the base Image component props by filtering out Cloudinary-specific props
29
+
30
+ const imageProps = {
31
+ alt: props.alt,
32
+ height: props.height,
33
+ src: props.src,
34
+ width: props.width
35
+ };
36
+ Object.keys(props).filter(key => typeof key === 'string' && !CLD_OPTIONS.includes(key)).forEach(key => imageProps[key] = props[key]);
37
+ const defaultImgKey = Object.keys(imageProps).map(key => `${key}:${imageProps[key]}`).join(';');
38
+ const [imgKey, setImgKey] = react.useState(defaultImgKey);
39
+
40
+ // The unoptimized flag is intended to remove all optimizations including quality, format, and sizing
41
+ // via responsive sizing. When passing this in, it also prevents the `loader` from running, thus
42
+ // breaking this component. This rewrites the `src` to construct a fully formed Cloudinary URL
43
+ // that also disables format and quality transformations, to deliver it as unoptimized
44
+ // See about unoptimized not working with loader: https://github.com/vercel/next.js/issues/50764
45
+
46
+ const IMAGE_OPTIONS = process.env.__NEXT_IMAGE_OPTS || {};
47
+ if (props.unoptimized === true || IMAGE_OPTIONS?.unoptimized === true) {
48
+ imageProps.src = cloudinaryLoader.getCldImageUrl({
49
+ ...props,
50
+ width: imageProps.width,
51
+ height: imageProps.height,
52
+ src: imageProps.src,
53
+ format: 'default',
54
+ quality: 'default'
55
+ }, props.config);
56
+ }
57
+
58
+ /**
59
+ * handleOnError
60
+ */
61
+
62
+ async function onError(options) {
63
+ let pollForImage = true;
64
+
65
+ // The onError function should never fire more than once. The use case for tracking it
66
+ // at all outside of the standard Next Image flow is for scenarios like when Cloudinary
67
+ // is processing an image where we want to try to update the UI upon completion.
68
+ // If this fires a second time, it is likely because of another issue, which will end
69
+ // up triggering an infinite loop if the resulting image keeps erroring and
70
+ // this function sets a key using the current time to force refresh the UI
71
+
72
+ if (hasThrownError) return;
73
+ hasThrownError = true;
74
+ if (typeof props.onError === 'function') {
75
+ const onErrorResult = props.onError(options);
76
+ if (typeof onErrorResult === 'boolean' && onErrorResult === false) {
77
+ pollForImage = false;
78
+ }
79
+ } else if (typeof props.onError === 'boolean' && props.onError === false) {
80
+ pollForImage = false;
81
+ }
82
+
83
+ // Give an escape hatch in case the user wants to handle the error themselves
84
+ // or if they want to disable polling for the image
85
+
86
+ if (pollForImage === false) return;
87
+ const image = options.target;
88
+ const result = await util.pollForProcessingImage({
89
+ src: image.src
90
+ });
91
+ if (typeof result.error === 'string' && process.env.NODE_ENV === 'development') {
92
+ console.error(`[CldImage] Failed to load image ${props.src}: ${result.error}`);
93
+ }
94
+ if (result.success) {
95
+ setImgKey(`${defaultImgKey};${Date.now()}`);
96
+ }
97
+ }
98
+ const handleOnError = react.useCallback(onError, [util.pollForProcessingImage, defaultImgKey]);
99
+
100
+ // Copypasta from https://github.com/prismicio/prismic-next/pull/79/files
101
+ // Thanks Angelo!
102
+ // TODO: Remove once https://github.com/vercel/next.js/issues/52216 is resolved.
103
+
104
+ let ResolvedImage = Image__default["default"];
105
+ if ("default" in ResolvedImage) {
106
+ ResolvedImage = ResolvedImage.default;
107
+ }
108
+ return /*#__PURE__*/jsxRuntime.jsx(ResolvedImage, {
109
+ ...imageProps,
110
+ loader: loaderOptions => cloudinaryLoader.cloudinaryLoader({
111
+ loaderOptions,
112
+ imageProps,
113
+ cldOptions: props,
114
+ cldConfig: props.config
115
+ }),
116
+ onError: handleOnError,
117
+ ref: ref
118
+ }, imgKey);
119
+ });
120
+
121
+ exports["default"] = CldImage;
@@ -0,0 +1,113 @@
1
+ 'use client';
2
+ import { forwardRef, useState, useCallback } from 'react';
3
+ import Image from 'next/image';
4
+ import { pollForProcessingImage } from '@cloudinary-util/util';
5
+ import { cloudinaryPluginKeys } from '@cloudinary-util/url-loader';
6
+ import { g as getCldImageUrl, c as cloudinaryLoader } from './cloudinary-loader-ad7ad702.esm.js';
7
+ import { jsx } from 'react/jsx-runtime';
8
+ import './cloudinary-cb3c790a.esm.js';
9
+ import 'next/package.json';
10
+
11
+ const CldImage = /*#__PURE__*/forwardRef(function CldImage(props, ref) {
12
+ let hasThrownError = false;
13
+
14
+ // Add props here that are intended to only be used for
15
+ // Cloudinary URL construction to avoid them being forwarded
16
+ // to the DOM
17
+
18
+ const CLD_OPTIONS = ['assetType', 'config', 'deliveryType', 'strictTransformations', ...cloudinaryPluginKeys];
19
+
20
+ // Construct the base Image component props by filtering out Cloudinary-specific props
21
+
22
+ const imageProps = {
23
+ alt: props.alt,
24
+ height: props.height,
25
+ src: props.src,
26
+ width: props.width
27
+ };
28
+ Object.keys(props).filter(key => typeof key === 'string' && !CLD_OPTIONS.includes(key)).forEach(key => imageProps[key] = props[key]);
29
+ const defaultImgKey = Object.keys(imageProps).map(key => `${key}:${imageProps[key]}`).join(';');
30
+ const [imgKey, setImgKey] = useState(defaultImgKey);
31
+
32
+ // The unoptimized flag is intended to remove all optimizations including quality, format, and sizing
33
+ // via responsive sizing. When passing this in, it also prevents the `loader` from running, thus
34
+ // breaking this component. This rewrites the `src` to construct a fully formed Cloudinary URL
35
+ // that also disables format and quality transformations, to deliver it as unoptimized
36
+ // See about unoptimized not working with loader: https://github.com/vercel/next.js/issues/50764
37
+
38
+ const IMAGE_OPTIONS = process.env.__NEXT_IMAGE_OPTS || {};
39
+ if (props.unoptimized === true || IMAGE_OPTIONS?.unoptimized === true) {
40
+ imageProps.src = getCldImageUrl({
41
+ ...props,
42
+ width: imageProps.width,
43
+ height: imageProps.height,
44
+ src: imageProps.src,
45
+ format: 'default',
46
+ quality: 'default'
47
+ }, props.config);
48
+ }
49
+
50
+ /**
51
+ * handleOnError
52
+ */
53
+
54
+ async function onError(options) {
55
+ let pollForImage = true;
56
+
57
+ // The onError function should never fire more than once. The use case for tracking it
58
+ // at all outside of the standard Next Image flow is for scenarios like when Cloudinary
59
+ // is processing an image where we want to try to update the UI upon completion.
60
+ // If this fires a second time, it is likely because of another issue, which will end
61
+ // up triggering an infinite loop if the resulting image keeps erroring and
62
+ // this function sets a key using the current time to force refresh the UI
63
+
64
+ if (hasThrownError) return;
65
+ hasThrownError = true;
66
+ if (typeof props.onError === 'function') {
67
+ const onErrorResult = props.onError(options);
68
+ if (typeof onErrorResult === 'boolean' && onErrorResult === false) {
69
+ pollForImage = false;
70
+ }
71
+ } else if (typeof props.onError === 'boolean' && props.onError === false) {
72
+ pollForImage = false;
73
+ }
74
+
75
+ // Give an escape hatch in case the user wants to handle the error themselves
76
+ // or if they want to disable polling for the image
77
+
78
+ if (pollForImage === false) return;
79
+ const image = options.target;
80
+ const result = await pollForProcessingImage({
81
+ src: image.src
82
+ });
83
+ if (typeof result.error === 'string' && process.env.NODE_ENV === 'development') {
84
+ console.error(`[CldImage] Failed to load image ${props.src}: ${result.error}`);
85
+ }
86
+ if (result.success) {
87
+ setImgKey(`${defaultImgKey};${Date.now()}`);
88
+ }
89
+ }
90
+ const handleOnError = useCallback(onError, [pollForProcessingImage, defaultImgKey]);
91
+
92
+ // Copypasta from https://github.com/prismicio/prismic-next/pull/79/files
93
+ // Thanks Angelo!
94
+ // TODO: Remove once https://github.com/vercel/next.js/issues/52216 is resolved.
95
+
96
+ let ResolvedImage = Image;
97
+ if ("default" in ResolvedImage) {
98
+ ResolvedImage = ResolvedImage.default;
99
+ }
100
+ return /*#__PURE__*/jsx(ResolvedImage, {
101
+ ...imageProps,
102
+ loader: loaderOptions => cloudinaryLoader({
103
+ loaderOptions,
104
+ imageProps,
105
+ cldOptions: props,
106
+ cldConfig: props.config
107
+ }),
108
+ onError: handleOnError,
109
+ ref: ref
110
+ }, imgKey);
111
+ });
112
+
113
+ export { CldImage as default };
@@ -0,0 +1,101 @@
1
+ 'use client';
2
+ import 'react';
3
+ import CldUploadWidget from './CldUploadWidget-77f44ab3.esm.js';
4
+ import { jsx, Fragment } from 'react/jsx-runtime';
5
+
6
+ const CldUploadButton = ({
7
+ className,
8
+ children,
9
+ onClick,
10
+ onError,
11
+ onOpen,
12
+ onUpload,
13
+ onAbort,
14
+ onBatchCancelled,
15
+ onClose,
16
+ onDisplayChanged,
17
+ onPublicId,
18
+ onQueuesEnd,
19
+ onQueuesStart,
20
+ onRetry,
21
+ onShowCompleted,
22
+ onSourceChanged,
23
+ onSuccess,
24
+ onTags,
25
+ onUploadAdded,
26
+ options,
27
+ signatureEndpoint,
28
+ uploadPreset,
29
+ onAbortAction,
30
+ onBatchCancelledAction,
31
+ onCloseAction,
32
+ onDisplayChangedAction,
33
+ onPublicIdAction,
34
+ onQueuesEndAction,
35
+ onQueuesStartAction,
36
+ onRetryAction,
37
+ onShowCompletedAction,
38
+ onSourceChangedAction,
39
+ onSuccessAction,
40
+ onTagsAction,
41
+ onUploadAddedAction,
42
+ ...props
43
+ }) => {
44
+ return /*#__PURE__*/jsx(Fragment, {
45
+ children: /*#__PURE__*/jsx(CldUploadWidget, {
46
+ onError: onError,
47
+ onOpen: onOpen,
48
+ onUpload: onUpload,
49
+ onAbort: onAbort,
50
+ onBatchCancelled: onBatchCancelled,
51
+ onClose: onClose,
52
+ onDisplayChanged: onDisplayChanged,
53
+ onPublicId: onPublicId,
54
+ onQueuesEnd: onQueuesEnd,
55
+ onQueuesStart: onQueuesStart,
56
+ onRetry: onRetry,
57
+ onShowCompleted: onShowCompleted,
58
+ onSourceChanged: onSourceChanged,
59
+ onSuccess: onSuccess,
60
+ onTags: onTags,
61
+ onUploadAdded: onUploadAdded,
62
+ options: options,
63
+ signatureEndpoint: signatureEndpoint,
64
+ uploadPreset: uploadPreset,
65
+ onAbortAction: onAbortAction,
66
+ onBatchCancelledAction: onBatchCancelledAction,
67
+ onCloseAction: onCloseAction,
68
+ onDisplayChangedAction: onDisplayChangedAction,
69
+ onPublicIdAction: onPublicIdAction,
70
+ onQueuesEndAction: onQueuesEndAction,
71
+ onQueuesStartAction: onQueuesStartAction,
72
+ onRetryAction: onRetryAction,
73
+ onShowCompletedAction: onShowCompletedAction,
74
+ onSourceChangedAction: onSourceChangedAction,
75
+ onSuccessAction: onSuccessAction,
76
+ onTagsAction: onTagsAction,
77
+ onUploadAddedAction: onUploadAddedAction,
78
+ children: ({
79
+ open,
80
+ isLoading
81
+ }) => {
82
+ function handleOnClick(e) {
83
+ e.preventDefault();
84
+ open();
85
+ if (typeof onClick === 'function') {
86
+ onClick(e);
87
+ }
88
+ }
89
+ return /*#__PURE__*/jsx("button", {
90
+ ...props,
91
+ className: className || '',
92
+ onClick: handleOnClick,
93
+ disabled: isLoading,
94
+ children: children || 'Upload'
95
+ });
96
+ }
97
+ })
98
+ });
99
+ };
100
+
101
+ export { CldUploadButton as default };
@@ -0,0 +1,109 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ require('react');
7
+ var CldUploadWidget = require('./CldUploadWidget-cdb65b22.cjs.js');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
11
+
12
+ var CldUploadWidget__default = /*#__PURE__*/_interopDefault(CldUploadWidget);
13
+
14
+ const CldUploadButton = ({
15
+ className,
16
+ children,
17
+ onClick,
18
+ onError,
19
+ onOpen,
20
+ onUpload,
21
+ onAbort,
22
+ onBatchCancelled,
23
+ onClose,
24
+ onDisplayChanged,
25
+ onPublicId,
26
+ onQueuesEnd,
27
+ onQueuesStart,
28
+ onRetry,
29
+ onShowCompleted,
30
+ onSourceChanged,
31
+ onSuccess,
32
+ onTags,
33
+ onUploadAdded,
34
+ options,
35
+ signatureEndpoint,
36
+ uploadPreset,
37
+ onAbortAction,
38
+ onBatchCancelledAction,
39
+ onCloseAction,
40
+ onDisplayChangedAction,
41
+ onPublicIdAction,
42
+ onQueuesEndAction,
43
+ onQueuesStartAction,
44
+ onRetryAction,
45
+ onShowCompletedAction,
46
+ onSourceChangedAction,
47
+ onSuccessAction,
48
+ onTagsAction,
49
+ onUploadAddedAction,
50
+ ...props
51
+ }) => {
52
+ return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
53
+ children: /*#__PURE__*/jsxRuntime.jsx(CldUploadWidget__default["default"], {
54
+ onError: onError,
55
+ onOpen: onOpen,
56
+ onUpload: onUpload,
57
+ onAbort: onAbort,
58
+ onBatchCancelled: onBatchCancelled,
59
+ onClose: onClose,
60
+ onDisplayChanged: onDisplayChanged,
61
+ onPublicId: onPublicId,
62
+ onQueuesEnd: onQueuesEnd,
63
+ onQueuesStart: onQueuesStart,
64
+ onRetry: onRetry,
65
+ onShowCompleted: onShowCompleted,
66
+ onSourceChanged: onSourceChanged,
67
+ onSuccess: onSuccess,
68
+ onTags: onTags,
69
+ onUploadAdded: onUploadAdded,
70
+ options: options,
71
+ signatureEndpoint: signatureEndpoint,
72
+ uploadPreset: uploadPreset,
73
+ onAbortAction: onAbortAction,
74
+ onBatchCancelledAction: onBatchCancelledAction,
75
+ onCloseAction: onCloseAction,
76
+ onDisplayChangedAction: onDisplayChangedAction,
77
+ onPublicIdAction: onPublicIdAction,
78
+ onQueuesEndAction: onQueuesEndAction,
79
+ onQueuesStartAction: onQueuesStartAction,
80
+ onRetryAction: onRetryAction,
81
+ onShowCompletedAction: onShowCompletedAction,
82
+ onSourceChangedAction: onSourceChangedAction,
83
+ onSuccessAction: onSuccessAction,
84
+ onTagsAction: onTagsAction,
85
+ onUploadAddedAction: onUploadAddedAction,
86
+ children: ({
87
+ open,
88
+ isLoading
89
+ }) => {
90
+ function handleOnClick(e) {
91
+ e.preventDefault();
92
+ open();
93
+ if (typeof onClick === 'function') {
94
+ onClick(e);
95
+ }
96
+ }
97
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
98
+ ...props,
99
+ className: className || '',
100
+ onClick: handleOnClick,
101
+ disabled: isLoading,
102
+ children: children || 'Upload'
103
+ });
104
+ }
105
+ })
106
+ });
107
+ };
108
+
109
+ exports["default"] = CldUploadButton;
@@ -0,0 +1,207 @@
1
+ 'use client';
2
+ import { useRef, useState, useEffect } from 'react';
3
+ import Script from 'next/script';
4
+ import { generateSignatureCallback, getUploadWidgetOptions, generateUploadWidgetResultCallback, UPLOAD_WIDGET_EVENTS } from '@cloudinary-util/url-loader';
5
+ import { g as getCloudinaryConfig } from './cloudinary-cb3c790a.esm.js';
6
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
7
+ import 'next/package.json';
8
+
9
+ /**
10
+ * triggerOnIdle
11
+ * @see MDN Polyfill https://github.com/behnammodi/polyfill/blob/master/window.polyfill.js#L7-L24
12
+ */
13
+
14
+ function triggerOnIdle(callback) {
15
+ if (typeof window !== undefined && 'requestIdleCallback' in window) {
16
+ return requestIdleCallback(callback);
17
+ }
18
+ return setTimeout(() => callback(), 1);
19
+ }
20
+
21
+ const CldUploadWidget = ({
22
+ children,
23
+ config,
24
+ onError,
25
+ onOpen,
26
+ onUpload,
27
+ options,
28
+ signatureEndpoint,
29
+ uploadPreset,
30
+ ...props
31
+ }) => {
32
+ const cloudinary = useRef();
33
+ const widget = useRef();
34
+ const [error, setError] = useState(undefined);
35
+ const [results, setResults] = useState(undefined);
36
+ const [isScriptLoading, setIsScriptLoading] = useState(true);
37
+
38
+ // When creating a signed upload, you need to provide both your Cloudinary API Key
39
+ // as well as a signature generator function that will sign any paramters
40
+ // either on page load or during the upload process. Read more about signed uploads at:
41
+ // https://cloudinary.com/documentation/upload_widget#signed_uploads
42
+
43
+ const cloudinaryConfig = getCloudinaryConfig(config);
44
+ const uploadSignature = signatureEndpoint && generateSignatureCallback({
45
+ signatureEndpoint: String(signatureEndpoint),
46
+ fetch
47
+ });
48
+ const uploadOptions = getUploadWidgetOptions({
49
+ uploadPreset: uploadPreset || process.env.NEXT_PUBLIC_CLOUDINARY_UPLOAD_PRESET,
50
+ uploadSignature,
51
+ ...options
52
+ }, cloudinaryConfig);
53
+ const resultsCallback = generateUploadWidgetResultCallback({
54
+ onError: uploadError => {
55
+ setError(uploadError);
56
+ if (typeof onError === 'function') {
57
+ onError(uploadError, {
58
+ widget: widget.current,
59
+ ...instanceMethods
60
+ });
61
+ }
62
+ },
63
+ onResult: uploadResult => {
64
+ if (typeof uploadResult?.event !== 'string') return;
65
+ setResults(uploadResult);
66
+ const widgetEvent = UPLOAD_WIDGET_EVENTS[uploadResult.event];
67
+ if (typeof widgetEvent === 'string' && typeof props[widgetEvent] === 'function') {
68
+ const callback = props[widgetEvent];
69
+ callback(uploadResult, {
70
+ widget: widget.current,
71
+ ...instanceMethods
72
+ });
73
+ }
74
+ const widgetEventAction = `${widgetEvent}Action`;
75
+ if (widgetEventAction && typeof props[widgetEventAction] === 'function') {
76
+ const action = props[widgetEventAction];
77
+ action(uploadResult);
78
+ }
79
+ }
80
+ });
81
+
82
+ // Handle result states and callbacks
83
+
84
+ useEffect(() => {
85
+ if (typeof results === 'undefined') return;
86
+ const isSuccess = results.event === 'success';
87
+ if (isSuccess && typeof onUpload === 'function') {
88
+ if (process.env.NODE_ENV === 'development') {
89
+ console.warn('The onUpload callback is deprecated. Please use onSuccess instead.');
90
+ }
91
+ onUpload(results, widget.current);
92
+ }
93
+ }, [results]);
94
+
95
+ /**
96
+ * handleOnLoad
97
+ * @description Stores the Cloudinary window instance to a ref when the widget script loads
98
+ */
99
+
100
+ function handleOnLoad() {
101
+ setIsScriptLoading(false);
102
+ if (!cloudinary.current) {
103
+ cloudinary.current = window.cloudinary;
104
+ }
105
+
106
+ // To help improve load time of the widget on first instance, use requestIdleCallback
107
+ // to trigger widget creation. Optional.
108
+
109
+ triggerOnIdle(() => {
110
+ if (!widget.current) {
111
+ widget.current = createWidget();
112
+ }
113
+ });
114
+ }
115
+ useEffect(() => {
116
+ return () => {
117
+ widget.current?.destroy();
118
+ widget.current = undefined;
119
+ };
120
+ }, []);
121
+
122
+ /**
123
+ * Instance Methods
124
+ * Gives the ability to interface directly with the Upload Widget instance methods like open and close
125
+ * https://cloudinary.com/documentation/upload_widget_reference#instance_methods
126
+ */
127
+
128
+ function invokeInstanceMethod(method, options = []) {
129
+ if (!widget.current) {
130
+ widget.current = createWidget();
131
+ }
132
+ if (typeof widget?.current[method] === "function") {
133
+ return widget.current[method](...options);
134
+ }
135
+ }
136
+ function close(options) {
137
+ invokeInstanceMethod('close', [options]);
138
+ }
139
+ function destroy(options) {
140
+ return invokeInstanceMethod('destroy', [options]);
141
+ }
142
+ function hide() {
143
+ invokeInstanceMethod('hide');
144
+ }
145
+ function isDestroyed() {
146
+ return invokeInstanceMethod('isDestroyed');
147
+ }
148
+ function isMinimized() {
149
+ return invokeInstanceMethod('isMinimized');
150
+ }
151
+ function isShowing() {
152
+ return invokeInstanceMethod('isShowing');
153
+ }
154
+ function minimize() {
155
+ invokeInstanceMethod('minimize');
156
+ }
157
+ function open(widgetSource, options) {
158
+ invokeInstanceMethod('open', [widgetSource, options]);
159
+ if (typeof onOpen === 'function') {
160
+ onOpen(widget.current);
161
+ }
162
+ }
163
+ function show() {
164
+ invokeInstanceMethod('show');
165
+ }
166
+ function update() {
167
+ invokeInstanceMethod('update');
168
+ }
169
+ const instanceMethods = {
170
+ close,
171
+ destroy,
172
+ hide,
173
+ isDestroyed,
174
+ isMinimized,
175
+ isShowing,
176
+ minimize,
177
+ open,
178
+ show,
179
+ update
180
+ };
181
+
182
+ /**
183
+ * createWidget
184
+ * @description Creates a new instance of the Cloudinary widget and stores in a ref
185
+ */
186
+
187
+ function createWidget() {
188
+ return cloudinary.current?.createUploadWidget(uploadOptions, resultsCallback);
189
+ }
190
+ return /*#__PURE__*/jsxs(Fragment, {
191
+ children: [typeof children === 'function' && children({
192
+ cloudinary: cloudinary.current,
193
+ widget: widget.current,
194
+ results,
195
+ error,
196
+ isLoading: isScriptLoading,
197
+ ...instanceMethods
198
+ }), /*#__PURE__*/jsx(Script, {
199
+ id: `cloudinary-uploadwidget-${Math.floor(Math.random() * 100)}`,
200
+ src: "https://upload-widget.cloudinary.com/global/all.js",
201
+ onLoad: handleOnLoad,
202
+ onError: e => console.error(`Failed to load Cloudinary Upload Widget: ${e.message}`)
203
+ })]
204
+ });
205
+ };
206
+
207
+ export { CldUploadWidget as default };