next-cloudinary 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,905 @@
1
+ import Image from 'next/image';
2
+ import { Cloudinary } from '@cloudinary/url-gen';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import Head from 'next/head';
5
+ import { useRef } from 'react';
6
+ import Script from 'next/script';
7
+
8
+ function _extends() {
9
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
10
+ for (var i = 1; i < arguments.length; i++) {
11
+ var source = arguments[i];
12
+ for (var key in source) {
13
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
14
+ target[key] = source[key];
15
+ }
16
+ }
17
+ }
18
+ return target;
19
+ };
20
+ return _extends.apply(this, arguments);
21
+ }
22
+ function _objectWithoutPropertiesLoose(source, excluded) {
23
+ if (source == null) return {};
24
+ var target = {};
25
+ var sourceKeys = Object.keys(source);
26
+ var key, i;
27
+ for (i = 0; i < sourceKeys.length; i++) {
28
+ key = sourceKeys[i];
29
+ if (excluded.indexOf(key) >= 0) continue;
30
+ target[key] = source[key];
31
+ }
32
+ return target;
33
+ }
34
+
35
+ const cropsGravityAuto = ['crop', 'fill', 'lfill', 'fill_pad', 'thumb'];
36
+ const props$6 = ['crop', 'gravity'];
37
+ function plugin$6({
38
+ cldImage,
39
+ options
40
+ } = {}) {
41
+ const {
42
+ width,
43
+ height,
44
+ crop = 'limit'
45
+ } = options;
46
+ let transformationString = `c_${crop},w_${width}`;
47
+ if (!options.gravity && cropsGravityAuto.includes(crop)) {
48
+ options.gravity = 'auto';
49
+ }
50
+ if (!['limit'].includes(crop)) {
51
+ transformationString = `${transformationString},h_${height}`;
52
+ }
53
+ if (options.gravity) {
54
+ if (options.gravity === 'auto' && !cropsGravityAuto.includes(crop)) {
55
+ console.warn('Auto gravity can only be used with crop, fill, lfill, fill_pad or thumb. Not applying gravity.');
56
+ } else {
57
+ transformationString = `${transformationString},g_${options.gravity}`;
58
+ }
59
+ }
60
+ cldImage.resize(transformationString);
61
+ }
62
+
63
+ var croppingPlugin = {
64
+ __proto__: null,
65
+ props: props$6,
66
+ plugin: plugin$6
67
+ };
68
+
69
+ const params = ['art', {
70
+ prop: 'autoBrightness',
71
+ effect: 'auto_brightness'
72
+ }, {
73
+ prop: 'autoColor',
74
+ effect: 'auto_color'
75
+ }, {
76
+ prop: 'autoContrast',
77
+ effect: 'auto_contrast'
78
+ }, {
79
+ prop: 'assistColorblind',
80
+ effect: 'assist_colorblind'
81
+ }, 'blackwhite', 'blur', {
82
+ prop: 'blurFaces',
83
+ effect: 'blur_faces'
84
+ }, {
85
+ prop: 'blurRegion',
86
+ effect: 'blur_region'
87
+ }, 'brightness', {
88
+ prop: 'brightnessHSB',
89
+ effect: 'brightness_hsb'
90
+ }, 'cartoonify', 'colorize', 'contrast', 'distort', {
91
+ prop: 'fillLight',
92
+ effect: 'fill_light'
93
+ }, 'gamma', {
94
+ prop: 'gradientFade',
95
+ effect: 'gradient_fade'
96
+ }, 'grayscale', 'improve', 'negate', {
97
+ prop: 'oilPaint',
98
+ effect: 'oil_paint'
99
+ }, 'outline', 'pixelate', {
100
+ prop: 'pixelateFaces',
101
+ effect: 'pixelate_faces'
102
+ }, {
103
+ prop: 'pixelateRegion',
104
+ effect: 'pixelate_region'
105
+ }, 'redeye', {
106
+ prop: 'replaceColor',
107
+ effect: 'replace_color'
108
+ }, 'saturation', 'sepia', 'shadow', 'sharpen', 'shear', {
109
+ prop: 'simulateColorblind',
110
+ effect: 'simulate_colorblind'
111
+ }, 'tint', {
112
+ prop: 'unsharpMask',
113
+ effect: 'unsharp_mask'
114
+ }, 'vectorize', 'vibrance', 'vignette'];
115
+ const props$5 = params.map(param => param.prop || param);
116
+ function plugin$5({
117
+ cldImage,
118
+ options
119
+ } = {}) {
120
+ params.forEach(key => {
121
+ const prop = key.prop || key;
122
+ const effect = key.effect || key;
123
+ if (options[prop] === true) {
124
+ cldImage.effect(`e_${effect}`);
125
+ } else if (typeof options[prop] === 'string') {
126
+ cldImage.effect(`e_${effect}:${options[prop]}`);
127
+ }
128
+ });
129
+ }
130
+
131
+ var effectsPlugin = {
132
+ __proto__: null,
133
+ props: props$5,
134
+ plugin: plugin$5
135
+ };
136
+
137
+ // aspectRatio
138
+
139
+ const primary = {
140
+ aspectRatio: {
141
+ qualifier: 'ar'
142
+ },
143
+ crop: {
144
+ qualifier: 'c'
145
+ },
146
+ gravity: {
147
+ qualifier: 'g'
148
+ },
149
+ height: {
150
+ qualifier: 'h'
151
+ },
152
+ width: {
153
+ qualifier: 'w'
154
+ }
155
+ };
156
+ const position = {
157
+ angle: {
158
+ qualifier: 'a'
159
+ },
160
+ gravity: {
161
+ qualifier: 'g'
162
+ },
163
+ x: {
164
+ qualifier: 'x'
165
+ },
166
+ y: {
167
+ qualifier: 'y'
168
+ }
169
+ };
170
+ const text = {
171
+ alignment: {
172
+ qualifier: 'alignment'
173
+ },
174
+ border: {
175
+ qualifier: 'bo',
176
+ location: 'primary'
177
+ },
178
+ color: {
179
+ qualifier: 'co',
180
+ location: 'primary'
181
+ },
182
+ fontFamily: {
183
+ qualifier: false
184
+ },
185
+ fontSize: {
186
+ qualifier: false
187
+ },
188
+ fontWeight: {
189
+ qualifier: false
190
+ },
191
+ letterSpacing: {
192
+ qualifier: 'letter_spacing'
193
+ },
194
+ lineSpacing: {
195
+ qualifier: 'line_spacing'
196
+ },
197
+ stroke: {
198
+ qualifier: 'self'
199
+ },
200
+ textDecoration: {
201
+ qualifier: false
202
+ }
203
+ };
204
+
205
+ const _excluded$3 = ["publicId", "position", "text", "effects"];
206
+ const props$4 = ['text', 'overlays'];
207
+ const DEFAULT_TEXT_OPTIONS = {
208
+ color: 'black',
209
+ fontFamily: 'Arial',
210
+ fontSize: 200,
211
+ fontWeight: 'bold'
212
+ };
213
+ function plugin$4({
214
+ cldImage,
215
+ options
216
+ } = {}) {
217
+ const {
218
+ text: text$1,
219
+ overlays = []
220
+ } = options;
221
+ const type = 'overlay';
222
+ const typeQualifier = 'l';
223
+ if (Array.isArray(overlays)) {
224
+ overlays.forEach(applyOverlay);
225
+ }
226
+ if (typeof text$1 === 'string') {
227
+ applyOverlay({
228
+ text: _extends({}, DEFAULT_TEXT_OPTIONS, {
229
+ text: text$1
230
+ })
231
+ });
232
+ } else if (typeof text$1 === 'object') {
233
+ applyOverlay({
234
+ text: _extends({}, DEFAULT_TEXT_OPTIONS, text$1)
235
+ });
236
+ }
237
+
238
+ /**
239
+ * applyOverlay
240
+ */
241
+
242
+ function applyOverlay(_ref) {
243
+ let {
244
+ publicId,
245
+ position: position$1,
246
+ text: text$1,
247
+ effects: layerEffects = []
248
+ } = _ref,
249
+ options = _objectWithoutPropertiesLoose(_ref, _excluded$3);
250
+ const hasPublicId = typeof publicId === 'string';
251
+ const hasText = typeof text$1 === 'object' || typeof text$1 === 'string';
252
+ const hasPosition = typeof position$1 === 'object';
253
+ if (!hasPublicId && !hasText) {
254
+ console.warn(`An ${type} is missing Public ID or Text`);
255
+ return;
256
+ }
257
+
258
+ // Start to construct the transformation string using text or the public ID
259
+ // if it's image-based
260
+
261
+ let layerTransformation;
262
+ if (hasText) {
263
+ layerTransformation = `${typeQualifier}_text`;
264
+ } else {
265
+ layerTransformation = `${typeQualifier}_${publicId.replace(/\//g, ':')}`;
266
+ }
267
+
268
+ // Begin organizing transformations based on what it is and the location
269
+ // it needs to be placed in the URL
270
+
271
+ const primary$1 = [];
272
+ const applied = [];
273
+
274
+ // Gemeral options
275
+
276
+ Object.keys(options).forEach(key => {
277
+ if (!primary[key]) return;
278
+ const {
279
+ qualifier
280
+ } = primary[key];
281
+ primary$1.push(`${qualifier}_${options[key]}`);
282
+ });
283
+
284
+ // Layer effects
285
+
286
+ layerEffects.forEach(effect => {
287
+ Object.keys(effect).forEach(key => {
288
+ if (!primary[key]) return;
289
+ const {
290
+ qualifier
291
+ } = primary[key];
292
+ primary$1.push(`${qualifier}_${effect[key]}`);
293
+ });
294
+ });
295
+
296
+ // Text styling
297
+
298
+ if (hasText) {
299
+ if (typeof text$1 === 'string') {
300
+ text$1 = _extends({}, DEFAULT_TEXT_OPTIONS, {
301
+ text: text$1
302
+ });
303
+ }
304
+ const textTransformations = [];
305
+ Object.keys(text$1).forEach(key => {
306
+ if (!text[key]) return;
307
+ const {
308
+ qualifier,
309
+ location
310
+ } = text[key];
311
+ if (location === 'primary') {
312
+ primary$1.push(`${qualifier}_${text$1[key]}`);
313
+ } else if (qualifier === 'self') {
314
+ textTransformations.push(key);
315
+ } else if (qualifier) {
316
+ textTransformations.push(`${qualifier}_${text$1[key]}`);
317
+ } else {
318
+ textTransformations.push(text$1[key]);
319
+ }
320
+ });
321
+ layerTransformation = `${layerTransformation}:${textTransformations.join('_')}:${text$1.text}`;
322
+ }
323
+
324
+ // Positioning
325
+
326
+ if (hasPosition) {
327
+ Object.keys(position$1).forEach(key => {
328
+ if (!position[key]) return;
329
+ const {
330
+ qualifier
331
+ } = position[key];
332
+ applied.push(`${qualifier}_${position$1[key]}`);
333
+ });
334
+ }
335
+
336
+ // Add all primary transformations
337
+
338
+ layerTransformation = `${layerTransformation},${primary$1.join(',')}`;
339
+
340
+ // Add all applied transformations
341
+
342
+ layerTransformation = `${layerTransformation}/fl_layer_apply,fl_no_overflow`;
343
+ if (applied.length > 0) {
344
+ layerTransformation = `${layerTransformation},${applied.join(',')}`;
345
+ }
346
+
347
+ // Finally add it to the image
348
+
349
+ cldImage.addTransformation(layerTransformation);
350
+ }
351
+ }
352
+
353
+ var overlaysPlugin = {
354
+ __proto__: null,
355
+ props: props$4,
356
+ DEFAULT_TEXT_OPTIONS: DEFAULT_TEXT_OPTIONS,
357
+ plugin: plugin$4
358
+ };
359
+
360
+ const props$3 = ['rawTransformations'];
361
+ function plugin$3({
362
+ cldImage,
363
+ options
364
+ } = {}) {
365
+ const {
366
+ rawTransformations = []
367
+ } = options;
368
+ rawTransformations.forEach(transformation => {
369
+ cldImage.addTransformation(transformation);
370
+ });
371
+ }
372
+
373
+ var rawTransformationsPlugin = {
374
+ __proto__: null,
375
+ props: props$3,
376
+ plugin: plugin$3
377
+ };
378
+
379
+ const props$2 = ['removeBackground'];
380
+ function plugin$2({
381
+ cldImage,
382
+ options
383
+ } = {}) {
384
+ const {
385
+ removeBackground = false
386
+ } = options;
387
+ if (removeBackground) {
388
+ cldImage.effect('e_background_removal');
389
+ }
390
+ }
391
+
392
+ var removeBackgroundPlugin = {
393
+ __proto__: null,
394
+ props: props$2,
395
+ plugin: plugin$2
396
+ };
397
+
398
+ const _excluded$2 = ["publicId", "type", "position", "text", "effects"];
399
+ const props$1 = ['underlay', 'underlays'];
400
+ function plugin$1({
401
+ cldImage,
402
+ options
403
+ } = {}) {
404
+ const {
405
+ underlay,
406
+ underlays = []
407
+ } = options;
408
+ const typeQualifier = 'u';
409
+ if (Array.isArray(underlays)) {
410
+ underlays.forEach(applyUnderlay);
411
+ }
412
+ if (typeof underlay === 'string') {
413
+ const underlayOptions = {
414
+ publicId: underlay,
415
+ crop: 'fill'
416
+ };
417
+ if (options.width) {
418
+ underlayOptions.width = options.width;
419
+ }
420
+ if (options.height) {
421
+ underlayOptions.height = options.height;
422
+ }
423
+ applyUnderlay(underlayOptions);
424
+ }
425
+
426
+ /**
427
+ * applyUnderlay
428
+ */
429
+
430
+ function applyUnderlay(_ref) {
431
+ let {
432
+ publicId,
433
+ type,
434
+ position: position$1,
435
+ effects: layerEffects = []
436
+ } = _ref,
437
+ options = _objectWithoutPropertiesLoose(_ref, _excluded$2);
438
+ const hasPublicId = typeof publicId === 'string';
439
+ const hasPosition = typeof position$1 === 'object';
440
+ if (!hasPublicId) {
441
+ console.warn(`An ${type} is missing a Public ID`);
442
+ return;
443
+ }
444
+
445
+ // Start to construct the transformation string using text or the public ID
446
+ // if it's image-based
447
+
448
+ let layerTransformation = `${typeQualifier}_${publicId.replace(/\//g, ':')}`;
449
+
450
+ // Begin organizing transformations based on what it is and the location
451
+ // it needs to be placed in the URL
452
+
453
+ const primary$1 = [];
454
+ const applied = [];
455
+
456
+ // Gemeral options
457
+
458
+ Object.keys(options).forEach(key => {
459
+ if (!primary[key]) return;
460
+ const {
461
+ qualifier
462
+ } = primary[key];
463
+ primary$1.push(`${qualifier}_${options[key]}`);
464
+ });
465
+
466
+ // Layer effects
467
+
468
+ layerEffects.forEach(effect => {
469
+ Object.keys(effect).forEach(key => {
470
+ if (!primary[key]) return;
471
+ const {
472
+ qualifier
473
+ } = primary[key];
474
+ primary$1.push(`${qualifier}_${effect[key]}`);
475
+ });
476
+ });
477
+
478
+ // Positioning
479
+
480
+ if (hasPosition) {
481
+ Object.keys(position$1).forEach(key => {
482
+ if (!position[key]) return;
483
+ const {
484
+ qualifier
485
+ } = position[key];
486
+ applied.push(`${qualifier}_${position$1[key]}`);
487
+ });
488
+ }
489
+
490
+ // Add all primary transformations
491
+
492
+ layerTransformation = `${layerTransformation},${primary$1.join(',')}`;
493
+
494
+ // Add all applied transformations
495
+
496
+ layerTransformation = `${layerTransformation}/fl_layer_apply,fl_no_overflow`;
497
+ if (applied.length > 0) {
498
+ layerTransformation = `${layerTransformation},${applied.join(',')}`;
499
+ }
500
+
501
+ // Finally add it to the image
502
+
503
+ cldImage.addTransformation(layerTransformation);
504
+ }
505
+ }
506
+
507
+ var underlaysPlugin = {
508
+ __proto__: null,
509
+ props: props$1,
510
+ plugin: plugin$1
511
+ };
512
+
513
+ const props = ['zoompan'];
514
+ function plugin({
515
+ cldImage,
516
+ options
517
+ } = {}) {
518
+ const {
519
+ zoompan = false
520
+ } = options;
521
+ const overrides = {};
522
+ if (zoompan === true) {
523
+ cldImage.effect('e_zoompan');
524
+ } else if (typeof zoompan === 'string') {
525
+ if (zoompan === 'loop') {
526
+ cldImage.effect('e_zoompan');
527
+ cldImage.effect('e_loop');
528
+ } else {
529
+ cldImage.effect(`e_zoompan:${zoompan}`);
530
+ }
531
+ } else if (typeof zoompan === 'object') {
532
+ let zoompanEffect = 'e_zoompan';
533
+ if (typeof zoompan.options === 'string') {
534
+ zoompanEffect = `${zoompanEffect}${zoompan.options}`;
535
+ }
536
+ cldImage.effect(zoompanEffect);
537
+ let loopEffect;
538
+ if (zoompan.loop === true) {
539
+ loopEffect = 'e_loop';
540
+ } else if (typeof zoompan.loop === 'string') {
541
+ loopEffect = `e_loop${zoompan.loop}`;
542
+ }
543
+ if (loopEffect) {
544
+ cldImage.effect(loopEffect);
545
+ }
546
+ }
547
+ if (zoompan !== false) {
548
+ overrides.format = 'gif';
549
+ }
550
+ return {
551
+ options: overrides
552
+ };
553
+ }
554
+
555
+ var zoompanPlugin = {
556
+ __proto__: null,
557
+ props: props,
558
+ plugin: plugin
559
+ };
560
+
561
+ const transformationPlugins = [
562
+ // Background Removal must always come first
563
+ removeBackgroundPlugin, croppingPlugin, effectsPlugin, overlaysPlugin, underlaysPlugin, zoompanPlugin,
564
+ // Raw transformations needs to be last simply to make sure
565
+ // it's always expected to applied the same way
566
+
567
+ rawTransformationsPlugin];
568
+ let cld;
569
+
570
+ /**
571
+ * constructCloudinaryUrl
572
+ */
573
+
574
+ function constructCloudinaryUrl({
575
+ options,
576
+ config
577
+ }) {
578
+ if (!cld) {
579
+ cld = new Cloudinary(_extends({
580
+ cloud: {
581
+ cloudName: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME
582
+ },
583
+ url: {
584
+ // Used to avoid issues with SSR particularly for the blurred placeholder
585
+ analytics: false
586
+ }
587
+ }, config));
588
+ }
589
+ const publicId = getPublicId(options.src);
590
+ const cldImage = cld.image(publicId);
591
+ transformationPlugins.forEach(({
592
+ plugin
593
+ }) => {
594
+ const {
595
+ options: pluginOptions
596
+ } = plugin({
597
+ cldImage,
598
+ options
599
+ }) || {};
600
+ if (pluginOptions != null && pluginOptions.format) {
601
+ options.format = pluginOptions.format;
602
+ }
603
+ });
604
+ return cldImage.setDeliveryType(options.deliveryType || 'upload').format(options.format || 'auto').delivery(`q_${options.quality || 'auto'}`).toURL();
605
+ }
606
+
607
+ /**
608
+ * Retrieves the public id of a cloudiary image url. If no url is recognized it returns the parameter it self.
609
+ * If it's recognized that is a url and it's not possible to get the public id, it warns the user.
610
+ *
611
+ * @param {string} src The cloudiary url or public id.
612
+ *
613
+ * @return {string} The images public id
614
+ */
615
+
616
+ function getPublicId(src) {
617
+ if (typeof src !== 'string') {
618
+ throw new Error(`Invalid src of type ${typeof src}`);
619
+ }
620
+ if (src.includes('res.cloudinary.com')) {
621
+ const regexWithTransformations = /(https?)\:\/\/(res.cloudinary.com)\/([^\/]+)\/(image|video|raw)\/(upload|authenticated)\/(.*)\/(v[0-9]+)\/(.+)(?:\.[a-z]{3})?/;
622
+ const regexWithoutTransformations = /(https?)\:\/\/(res.cloudinary.com)\/([^\/]+)\/(image|video|raw)\/(upload|authenticated)\/(v[0-9]+)\/(.+)(?:\.[a-z]{3})?/;
623
+ const withTransformations = src.match(regexWithTransformations);
624
+ const withoutTransformations = src.match(regexWithoutTransformations);
625
+ if (withTransformations) {
626
+ return withTransformations[withTransformations.length - 1];
627
+ } else if (withoutTransformations) {
628
+ return withoutTransformations[withoutTransformations.length - 1];
629
+ } else {
630
+ console.warn(`Not possible to retrieve the publicUrl from ${src}, make sure it's a valid cloudinary image url.`);
631
+ }
632
+ }
633
+ return src;
634
+ }
635
+
636
+ /**
637
+ * createPlaceholderUrl
638
+ */
639
+
640
+ function createPlaceholderUrl({
641
+ src,
642
+ placeholder = true,
643
+ config
644
+ }) {
645
+ const rawTransformations = [];
646
+ if (placeholder === 'grayscale') {
647
+ rawTransformations.push('e_grayscale');
648
+ }
649
+ if (typeof placeholder === 'string' && placeholder.includes('color:')) {
650
+ const color = placeholder.split(':').splice(1).join(':');
651
+ rawTransformations.push('e_grayscale');
652
+ rawTransformations.push(`e_colorize:60,co_${color}`);
653
+ }
654
+ return constructCloudinaryUrl({
655
+ options: {
656
+ src,
657
+ width: 100,
658
+ quality: 1,
659
+ rawTransformations
660
+ },
661
+ config
662
+ });
663
+ }
664
+
665
+ function cloudinaryLoader(defaultOptions, cldOptions, cldConfig = {}) {
666
+ return constructCloudinaryUrl({
667
+ options: _extends({}, defaultOptions, cldOptions),
668
+ config: cldConfig
669
+ });
670
+ }
671
+
672
+ const CldImage = props => {
673
+ const CLD_OPTIONS = [];
674
+ transformationPlugins.forEach(({
675
+ props: _props = []
676
+ }) => {
677
+ _props.forEach(prop => {
678
+ if (CLD_OPTIONS.includes(prop)) {
679
+ throw new Error(`Option ${prop} already exists!`);
680
+ }
681
+ CLD_OPTIONS.push(prop);
682
+ });
683
+ });
684
+
685
+ // Construct the base Image component props by filtering out Cloudinary-specific props
686
+
687
+ const imageProps = {};
688
+ Object.keys(props).filter(key => !CLD_OPTIONS.includes(key)).forEach(key => imageProps[key] = props[key]);
689
+
690
+ // Construct Cloudinary-specific props by looking for values for any of the supported prop keys
691
+
692
+ const cldOptions = {};
693
+ CLD_OPTIONS.forEach(key => {
694
+ if (props[key]) {
695
+ cldOptions[key] = props[key];
696
+ }
697
+ });
698
+
699
+ // If we see a placeholder option, configure a Cloudinary-based URL.
700
+ // The resulting image will always be blurred per Next.js, so we're
701
+ // limited on options for placeholders.
702
+ //
703
+ // We need to do this logic here as we potentially need to mutate
704
+ // an Image component prop as opposed to simply the URL
705
+ //
706
+ // https://nextjs.org/docs/api-reference/next/image#blurdataurl
707
+
708
+ if (imageProps.placeholder) {
709
+ const publicId = getPublicId(props.src);
710
+ imageProps.blurDataURL = createPlaceholderUrl({
711
+ src: publicId,
712
+ placeholder: props.placeholder
713
+ });
714
+ if (imageProps.placeholder !== 'blur') {
715
+ imageProps.placeholder = 'blur';
716
+ }
717
+ }
718
+ return /*#__PURE__*/jsx(Image, _extends({}, imageProps, {
719
+ loader: options => cloudinaryLoader(_extends({}, imageProps, {
720
+ options
721
+ }), cldOptions)
722
+ }));
723
+ };
724
+
725
+ const _excluded$1 = ["excludeTags", "twitterTitle"];
726
+ const IMAGE_WIDTH = 2400;
727
+ const IMAGE_HEIGHT = 1200;
728
+ const TWITTER_CARD = 'summary_large_image';
729
+ const CldOgImage = _ref => {
730
+ let {
731
+ excludeTags = [],
732
+ twitterTitle
733
+ } = _ref,
734
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
735
+ const options = _extends({}, props, {
736
+ width: props.width || IMAGE_WIDTH,
737
+ height: props.height || IMAGE_HEIGHT,
738
+ crop: props.crop || 'fill',
739
+ gravity: props.gravity || 'center'
740
+ });
741
+ const ogImageUrl = constructCloudinaryUrl({
742
+ options
743
+ });
744
+
745
+ // We need to include the tags within the Next.js Head component rather than
746
+ // direcly adding them inside of the Head otherwise we get unexpected results
747
+
748
+ return /*#__PURE__*/jsxs(Head, {
749
+ children: [/*#__PURE__*/jsx("meta", {
750
+ property: "og:image",
751
+ content: ogImageUrl
752
+ }), /*#__PURE__*/jsx("meta", {
753
+ property: "og:image:secure_url",
754
+ content: ogImageUrl
755
+ }), /*#__PURE__*/jsx("meta", {
756
+ property: "og:image:width",
757
+ content: options.width
758
+ }), /*#__PURE__*/jsx("meta", {
759
+ property: "og:image:height",
760
+ content: options.height
761
+ }), options.alt && /*#__PURE__*/jsx("meta", {
762
+ property: "og:image:alt",
763
+ content: options.alt
764
+ }), !excludeTags.includes('twitter:title') && /*#__PURE__*/jsx("meta", {
765
+ property: "twitter:title",
766
+ content: twitterTitle || ' '
767
+ }), /*#__PURE__*/jsx("meta", {
768
+ property: "twitter:card",
769
+ content: TWITTER_CARD
770
+ }), /*#__PURE__*/jsx("meta", {
771
+ property: "twitter:image",
772
+ content: ogImageUrl
773
+ })]
774
+ });
775
+ };
776
+
777
+ const CldUploadWidget = ({
778
+ children,
779
+ onUpload,
780
+ options,
781
+ signed,
782
+ signatureEndpoint
783
+ }) => {
784
+ const cloudinary = useRef();
785
+ const widget = useRef();
786
+
787
+ /**
788
+ * generateSignature
789
+ * @description Makes a request to an endpoint to sign Cloudinary parameters as part of widget creation
790
+ */
791
+
792
+ function generateSignature(callback, paramsToSign) {
793
+ fetch(signatureEndpoint, {
794
+ method: "POST",
795
+ body: JSON.stringify({
796
+ paramsToSign
797
+ })
798
+ }).then(r => r.json()).then(({
799
+ signature
800
+ }) => {
801
+ callback(signature);
802
+ });
803
+ }
804
+
805
+ /**
806
+ * createWidget
807
+ * @description Creates a new instance of the Cloudinary widget and stores in a ref
808
+ */
809
+
810
+ function createWidget() {
811
+ var _cloudinary$current;
812
+ // When creating a signed upload, you need to provide both your Cloudinary API Key
813
+ // as well as a signature generator function that will sign any paramters
814
+ // either on page load or during the upload process. Read more about signed uploads at:
815
+ // https://cloudinary.com/documentation/upload_widget#signed_uploads
816
+
817
+ const totalOptions = _extends({}, options, !!signed && {
818
+ uploadSignature: generateSignature
819
+ });
820
+
821
+ // no need for apiSecret because of api/sign-cloudinary-params
822
+ if (signed && !totalOptions.apiKey) {
823
+ return new Error("Signed Upload needs apiKey!");
824
+ }
825
+ return (_cloudinary$current = cloudinary.current) == null ? void 0 : _cloudinary$current.createUploadWidget(totalOptions, function (error, result) {
826
+ // The callback is a bit more chatty than failed or success so
827
+ // only trigger when one of those are the case. You can additionally
828
+ // create a separate handler such as onEvent and trigger it on
829
+ // ever occurance
830
+ if (error || result.event === "success") {
831
+ onUpload(error, result, widget == null ? void 0 : widget.current);
832
+ }
833
+ });
834
+ }
835
+
836
+ /**
837
+ * open
838
+ * @description When triggered, uses the current widget instance to open the upload modal
839
+ */
840
+
841
+ function open() {
842
+ if (!(widget != null && widget.current)) {
843
+ widget.current = createWidget();
844
+ }
845
+ (widget == null ? void 0 : widget.current) && widget.current.open();
846
+ }
847
+
848
+ /**
849
+ * handleOnLoad
850
+ * @description Stores the Cloudinary window instance to a ref when the widget script loads
851
+ */
852
+
853
+ function handleOnLoad() {
854
+ cloudinary.current = window.cloudinary;
855
+ }
856
+ return /*#__PURE__*/jsxs(Fragment, {
857
+ children: [children({
858
+ cloudinary: cloudinary.current,
859
+ widget: widget.current,
860
+ open
861
+ }), /*#__PURE__*/jsx(Script, {
862
+ id: `cloudinary-${Math.floor(Math.random() * 100)}`,
863
+ src: "https://widget.cloudinary.com/v2.0/global/all.js",
864
+ onLoad: handleOnLoad,
865
+ onError: e => {
866
+ console.error("Script failed to load", e);
867
+ }
868
+ })]
869
+ });
870
+ };
871
+
872
+ const _excluded = ["onUpload", "options", "signed", "label", "children"];
873
+ const CldUploadButton = _ref => {
874
+ let {
875
+ onUpload,
876
+ options,
877
+ signed,
878
+ children
879
+ } = _ref,
880
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
881
+ return /*#__PURE__*/jsx(Fragment, {
882
+ children: /*#__PURE__*/jsx(CldUploadWidget, {
883
+ signed: signed,
884
+ options: options,
885
+ onUpload: onUpload,
886
+ signatureEndpoint: signed != null ? signed : props.signatureEndpoint,
887
+ children: ({
888
+ open
889
+ }) => {
890
+ function handleOnClick(e) {
891
+ e.preventDefault();
892
+ open();
893
+ }
894
+ return /*#__PURE__*/jsx("button", _extends({
895
+ onClick: handleOnClick
896
+ }, props, {
897
+ children: children
898
+ }));
899
+ }
900
+ })
901
+ });
902
+ };
903
+
904
+ export { CldImage, CldOgImage, CldUploadButton, CldUploadWidget, cloudinaryLoader, position, primary, text };
905
+ //# sourceMappingURL=next-cloudinary.modern.mjs.map