next-cloudinary 0.2.0 → 0.3.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.
@@ -1,6 +1,7 @@
1
1
  import Image from 'next/image';
2
2
  import { Cloudinary } from '@cloudinary/url-gen';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import Head from 'next/head';
4
5
  import { useRef } from 'react';
5
6
  import Script from 'next/script';
6
7
 
@@ -36,95 +37,32 @@ function _objectWithoutPropertiesLoose(source, excluded) {
36
37
  return target;
37
38
  }
38
39
 
39
- const cld$1 = new Cloudinary({
40
- cloud: {
41
- cloudName: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME
42
- },
43
- url: {
44
- // Used to avoid issues with SSR particularly for the blurred placeholder
45
- analytics: false
46
- }
47
- });
48
- /**
49
- * Retrieves the public id of a cloudiary image url. If no url is recognized it returns the parameter it self.
50
- * If it's recognized that is a url and it's not possible to get the public id, it warns the user.
51
- *
52
- * @param {string} src The cloudiary url or public id.
53
- *
54
- * @return {string} The images public id
55
- */
56
-
57
- function getPublicId(src) {
58
- if (src.includes('res.cloudinary.com')) {
59
- const regexWithTransformations = /(https?)\:\/\/(res.cloudinary.com)\/([^\/]+)\/(image|video|raw)\/(upload|authenticated)\/(.*)\/(v[0-9]+)\/(.+)(?:\.[a-z]{3})?/;
60
- const regexWithoutTransformations = /(https?)\:\/\/(res.cloudinary.com)\/([^\/]+)\/(image|video|raw)\/(upload|authenticated)\/(v[0-9]+)\/(.+)(?:\.[a-z]{3})?/;
61
- const withTransformations = src.match(regexWithTransformations);
62
- const withoutTransformations = src.match(regexWithoutTransformations);
63
-
64
- if (withTransformations) {
65
- return withTransformations[withTransformations.length - 1];
66
- } else if (withoutTransformations) {
67
- return withoutTransformations[withoutTransformations.length - 1];
68
- } else {
69
- console.warn(`Not possible to retrieve the publicUrl from ${src}, make sure it's a valid cloudinary image url.`);
70
- }
71
- }
72
-
73
- return src;
74
- }
75
- /**
76
- * createPlaceholderUrl
77
- */
78
-
79
- function createPlaceholderUrl({
80
- src,
81
- placeholder
82
- }) {
83
- const cldImage = cld$1.image(src).resize('c_limit,w_100').delivery('q_1').format('auto');
84
-
85
- if (placeholder === 'grayscale') {
86
- cldImage.effect('e_grayscale');
87
- }
88
-
89
- if (placeholder.includes('color:')) {
90
- const color = placeholder.split(':').splice(1).join(':');
91
- cldImage.effect('e_grayscale');
92
- cldImage.effect(`e_colorize:60,co_${color}`);
93
- }
94
-
95
- return cldImage.toURL();
96
- }
97
-
98
40
  const cropsGravityAuto = ['crop', 'fill', 'lfill', 'fill_pad', 'thumb'];
99
41
  const props$6 = ['crop', 'gravity'];
100
42
  function plugin$6({
101
43
  cldImage,
102
- options,
103
- cldOptions
44
+ options
104
45
  } = {}) {
105
46
  const {
106
47
  width,
107
- height
48
+ height,
49
+ crop = 'limit'
108
50
  } = options;
109
- const {
110
- crop = 'limit',
111
- gravity
112
- } = cldOptions;
113
51
  let transformationString = `c_${crop},w_${width}`;
114
52
 
115
- if (!gravity && cropsGravityAuto.includes(crop)) {
116
- gravity = 'auto';
53
+ if (!options.gravity && cropsGravityAuto.includes(crop)) {
54
+ options.gravity = 'auto';
117
55
  }
118
56
 
119
57
  if (!['limit'].includes(crop)) {
120
58
  transformationString = `${transformationString},h_${height}`;
121
59
  }
122
60
 
123
- if (gravity) {
124
- if (gravity === 'auto' && !cropsGravityAuto.includes(crop)) {
61
+ if (options.gravity) {
62
+ if (options.gravity === 'auto' && !cropsGravityAuto.includes(crop)) {
125
63
  console.warn('Auto gravity can only be used with crop, fill, lfill, fill_pad or thumb. Not applying gravity.');
126
64
  } else {
127
- transformationString = `${transformationString},g_${gravity}`;
65
+ transformationString = `${transformationString},g_${options.gravity}`;
128
66
  }
129
67
  }
130
68
 
@@ -186,20 +124,16 @@ const params = ['art', {
186
124
  const props$5 = params.map(param => param.prop || param);
187
125
  function plugin$5({
188
126
  cldImage,
189
- cldOptions
127
+ options
190
128
  } = {}) {
191
129
  params.forEach(key => {
192
130
  const prop = key.prop || key;
193
131
  const effect = key.effect || key;
194
132
 
195
- if (prop === 'oilPaint' && cldOptions[prop]) {
196
- console.log('cldOptions[prop]', cldOptions[prop]);
197
- }
198
-
199
- if (cldOptions[prop] === true) {
133
+ if (options[prop] === true) {
200
134
  cldImage.effect(`e_${effect}`);
201
- } else if (typeof cldOptions[prop] === 'string') {
202
- cldImage.effect(`e_${effect}:${cldOptions[prop]}`);
135
+ } else if (typeof options[prop] === 'string') {
136
+ cldImage.effect(`e_${effect}:${options[prop]}`);
203
137
  }
204
138
  });
205
139
  }
@@ -264,29 +198,56 @@ const text = {
264
198
  }
265
199
  };
266
200
 
267
- const _excluded$2 = ["publicId", "position", "text", "effects"];
268
- const props$4 = ['overlays'];
201
+ const _excluded$3 = ["publicId", "position", "text", "effects"];
202
+ const props$4 = ['text', 'overlays'];
203
+ const DEFAULT_TEXT_OPTIONS = {
204
+ color: 'black',
205
+ fontFamily: 'Arial',
206
+ fontSize: 200,
207
+ fontWeight: 'bold'
208
+ };
269
209
  function plugin$4({
270
210
  cldImage,
271
- options,
272
- cldOptions
211
+ options
273
212
  } = {}) {
274
213
  const {
214
+ text: text$1,
275
215
  overlays = []
276
- } = cldOptions;
216
+ } = options;
277
217
  const type = 'overlay';
278
218
  const typeQualifier = 'l';
279
- overlays.forEach(_ref => {
219
+
220
+ if (Array.isArray(overlays)) {
221
+ overlays.forEach(applyOverlay);
222
+ }
223
+
224
+ if (typeof text$1 === 'string') {
225
+ applyOverlay({
226
+ text: _extends({}, DEFAULT_TEXT_OPTIONS, {
227
+ text: text$1
228
+ })
229
+ });
230
+ } else if (typeof text$1 === 'object') {
231
+ applyOverlay({
232
+ text: _extends({}, DEFAULT_TEXT_OPTIONS, text$1)
233
+ });
234
+ }
235
+ /**
236
+ * applyOverlay
237
+ */
238
+
239
+
240
+ function applyOverlay(_ref) {
280
241
  let {
281
242
  publicId,
282
243
  position: position$1,
283
244
  text: text$1,
284
245
  effects: layerEffects = []
285
246
  } = _ref,
286
- options = _objectWithoutPropertiesLoose(_ref, _excluded$2);
247
+ options = _objectWithoutPropertiesLoose(_ref, _excluded$3);
287
248
 
288
249
  const hasPublicId = typeof publicId === 'string';
289
- const hasText = typeof text$1 === 'object';
250
+ const hasText = typeof text$1 === 'object' || typeof text$1 === 'string';
290
251
  const hasPosition = typeof position$1 === 'object';
291
252
 
292
253
  if (!hasPublicId && !hasText) {
@@ -328,6 +289,12 @@ function plugin$4({
328
289
  }); // Text styling
329
290
 
330
291
  if (hasText) {
292
+ if (typeof text$1 === 'string') {
293
+ text$1 = _extends({}, DEFAULT_TEXT_OPTIONS, {
294
+ text: text$1
295
+ });
296
+ }
297
+
331
298
  const textTransformations = [];
332
299
  Object.keys(text$1).forEach(key => {
333
300
  if (!text[key]) return;
@@ -359,7 +326,7 @@ function plugin$4({
359
326
 
360
327
  layerTransformation = `${layerTransformation},${primary$1.join(',')}`; // Add all applied transformations
361
328
 
362
- layerTransformation = `${layerTransformation}/fl_layer_apply`;
329
+ layerTransformation = `${layerTransformation}/fl_layer_apply,fl_no_overflow`;
363
330
 
364
331
  if (applied.length > 0) {
365
332
  layerTransformation = `${layerTransformation},${applied.join(',')}`;
@@ -367,23 +334,24 @@ function plugin$4({
367
334
 
368
335
 
369
336
  cldImage.addTransformation(layerTransformation);
370
- });
337
+ }
371
338
  }
372
339
 
373
340
  var overlaysPlugin = {
374
341
  __proto__: null,
375
342
  props: props$4,
343
+ DEFAULT_TEXT_OPTIONS: DEFAULT_TEXT_OPTIONS,
376
344
  plugin: plugin$4
377
345
  };
378
346
 
379
347
  const props$3 = ['rawTransformations'];
380
348
  function plugin$3({
381
349
  cldImage,
382
- cldOptions
350
+ options
383
351
  } = {}) {
384
352
  const {
385
353
  rawTransformations = []
386
- } = cldOptions;
354
+ } = options;
387
355
  rawTransformations.forEach(transformation => {
388
356
  cldImage.addTransformation(transformation);
389
357
  });
@@ -398,12 +366,11 @@ var rawTransformationsPlugin = {
398
366
  const props$2 = ['removeBackground'];
399
367
  function plugin$2({
400
368
  cldImage,
401
- options,
402
- cldOptions
369
+ options
403
370
  } = {}) {
404
371
  const {
405
372
  removeBackground = false
406
- } = cldOptions;
373
+ } = options;
407
374
 
408
375
  if (removeBackground) {
409
376
  cldImage.effect('e_background_removal');
@@ -416,25 +383,51 @@ var removeBackgroundPlugin = {
416
383
  plugin: plugin$2
417
384
  };
418
385
 
419
- const _excluded$1 = ["publicId", "type", "position", "text", "effects"];
420
- const props$1 = ['underlays'];
386
+ const _excluded$2 = ["publicId", "type", "position", "text", "effects"];
387
+ const props$1 = ['underlay', 'underlays'];
421
388
  function plugin$1({
422
389
  cldImage,
423
- options,
424
- cldOptions
390
+ options
425
391
  } = {}) {
426
392
  const {
393
+ underlay,
427
394
  underlays = []
428
- } = cldOptions;
395
+ } = options;
429
396
  const typeQualifier = 'u';
430
- underlays.forEach(_ref => {
397
+
398
+ if (Array.isArray(underlays)) {
399
+ underlays.forEach(applyUnderlay);
400
+ }
401
+
402
+ if (typeof underlay === 'string') {
403
+ const underlayOptions = {
404
+ publicId: underlay,
405
+ crop: 'fill'
406
+ };
407
+
408
+ if (options.width) {
409
+ underlayOptions.width = options.width;
410
+ }
411
+
412
+ if (options.height) {
413
+ underlayOptions.height = options.height;
414
+ }
415
+
416
+ applyUnderlay(underlayOptions);
417
+ }
418
+ /**
419
+ * applyUnderlay
420
+ */
421
+
422
+
423
+ function applyUnderlay(_ref) {
431
424
  let {
432
425
  publicId,
433
426
  type,
434
427
  position: position$1,
435
428
  effects: layerEffects = []
436
429
  } = _ref,
437
- options = _objectWithoutPropertiesLoose(_ref, _excluded$1);
430
+ options = _objectWithoutPropertiesLoose(_ref, _excluded$2);
438
431
 
439
432
  const hasPublicId = typeof publicId === 'string';
440
433
  const hasPosition = typeof position$1 === 'object';
@@ -483,7 +476,7 @@ function plugin$1({
483
476
 
484
477
  layerTransformation = `${layerTransformation},${primary$1.join(',')}`; // Add all applied transformations
485
478
 
486
- layerTransformation = `${layerTransformation}/fl_layer_apply`;
479
+ layerTransformation = `${layerTransformation}/fl_layer_apply,fl_no_overflow`;
487
480
 
488
481
  if (applied.length > 0) {
489
482
  layerTransformation = `${layerTransformation},${applied.join(',')}`;
@@ -491,7 +484,7 @@ function plugin$1({
491
484
 
492
485
 
493
486
  cldImage.addTransformation(layerTransformation);
494
- });
487
+ }
495
488
  }
496
489
 
497
490
  var underlaysPlugin = {
@@ -503,12 +496,12 @@ var underlaysPlugin = {
503
496
  const props = ['zoompan'];
504
497
  function plugin({
505
498
  cldImage,
506
- cldOptions
499
+ options
507
500
  } = {}) {
508
501
  const {
509
502
  zoompan = false
510
- } = cldOptions;
511
- const options = {};
503
+ } = options;
504
+ const overrides = {};
512
505
 
513
506
  if (zoompan === true) {
514
507
  cldImage.effect('e_zoompan');
@@ -541,11 +534,11 @@ function plugin({
541
534
  }
542
535
 
543
536
  if (zoompan !== false) {
544
- options.format = 'gif';
537
+ overrides.format = 'gif';
545
538
  }
546
539
 
547
540
  return {
548
- options
541
+ options: overrides
549
542
  };
550
543
  }
551
544
 
@@ -555,12 +548,19 @@ var zoompanPlugin = {
555
548
  plugin: plugin
556
549
  };
557
550
 
558
- let cld;
559
551
  const transformationPlugins = [// Background Removal must always come first
560
552
  removeBackgroundPlugin, croppingPlugin, effectsPlugin, overlaysPlugin, underlaysPlugin, zoompanPlugin, // Raw transformations needs to be last simply to make sure
561
553
  // it's always expected to applied the same way
562
554
  rawTransformationsPlugin];
563
- function cloudinaryLoader(defaultOptions, cldOptions, cldConfig = {}) {
555
+ let cld;
556
+ /**
557
+ * constructCloudinaryUrl
558
+ */
559
+
560
+ function constructCloudinaryUrl({
561
+ options,
562
+ config
563
+ }) {
564
564
  if (!cld) {
565
565
  cld = new Cloudinary(_extends({
566
566
  cloud: {
@@ -570,14 +570,9 @@ function cloudinaryLoader(defaultOptions, cldOptions, cldConfig = {}) {
570
570
  // Used to avoid issues with SSR particularly for the blurred placeholder
571
571
  analytics: false
572
572
  }
573
- }, cldConfig));
573
+ }, config));
574
574
  }
575
575
 
576
- const options = _extends({
577
- format: 'auto',
578
- quality: 'auto'
579
- }, defaultOptions);
580
-
581
576
  const publicId = getPublicId(options.src);
582
577
  const cldImage = cld.image(publicId);
583
578
  transformationPlugins.forEach(({
@@ -587,15 +582,83 @@ function cloudinaryLoader(defaultOptions, cldOptions, cldConfig = {}) {
587
582
  options: pluginOptions
588
583
  } = plugin({
589
584
  cldImage,
590
- options,
591
- cldOptions
585
+ options
592
586
  }) || {};
593
587
 
594
588
  if (pluginOptions != null && pluginOptions.format) {
595
589
  options.format = pluginOptions.format;
596
590
  }
597
591
  });
598
- return cldImage.format(options.format).delivery(`q_${options.quality}`).toURL();
592
+ return cldImage.setDeliveryType(options.deliveryType || 'upload').format(options.format || 'auto').delivery(`q_${options.quality || 'auto'}`).toURL();
593
+ }
594
+ /**
595
+ * Retrieves the public id of a cloudiary image url. If no url is recognized it returns the parameter it self.
596
+ * If it's recognized that is a url and it's not possible to get the public id, it warns the user.
597
+ *
598
+ * @param {string} src The cloudiary url or public id.
599
+ *
600
+ * @return {string} The images public id
601
+ */
602
+
603
+ function getPublicId(src) {
604
+ if (typeof src !== 'string') {
605
+ throw new Error(`Invalid src of type ${typeof src}`);
606
+ }
607
+
608
+ if (src.includes('res.cloudinary.com')) {
609
+ const regexWithTransformations = /(https?)\:\/\/(res.cloudinary.com)\/([^\/]+)\/(image|video|raw)\/(upload|authenticated)\/(.*)\/(v[0-9]+)\/(.+)(?:\.[a-z]{3})?/;
610
+ const regexWithoutTransformations = /(https?)\:\/\/(res.cloudinary.com)\/([^\/]+)\/(image|video|raw)\/(upload|authenticated)\/(v[0-9]+)\/(.+)(?:\.[a-z]{3})?/;
611
+ const withTransformations = src.match(regexWithTransformations);
612
+ const withoutTransformations = src.match(regexWithoutTransformations);
613
+
614
+ if (withTransformations) {
615
+ return withTransformations[withTransformations.length - 1];
616
+ } else if (withoutTransformations) {
617
+ return withoutTransformations[withoutTransformations.length - 1];
618
+ } else {
619
+ console.warn(`Not possible to retrieve the publicUrl from ${src}, make sure it's a valid cloudinary image url.`);
620
+ }
621
+ }
622
+
623
+ return src;
624
+ }
625
+ /**
626
+ * createPlaceholderUrl
627
+ */
628
+
629
+ function createPlaceholderUrl({
630
+ src,
631
+ placeholder = true,
632
+ config
633
+ }) {
634
+ const rawTransformations = [];
635
+
636
+ if (placeholder === 'grayscale') {
637
+ rawTransformations.push('e_grayscale');
638
+ }
639
+
640
+ if (typeof placeholder === 'string' && placeholder.includes('color:')) {
641
+ const color = placeholder.split(':').splice(1).join(':');
642
+ rawTransformations.push('e_grayscale');
643
+ rawTransformations.push(`e_colorize:60,co_${color}`);
644
+ }
645
+
646
+ return constructCloudinaryUrl({
647
+ options: {
648
+ src,
649
+ width: 100,
650
+ quality: 1,
651
+ rawTransformations
652
+ },
653
+ config
654
+ });
655
+ }
656
+
657
+ function cloudinaryLoader(defaultOptions, cldOptions, cldConfig = {}) {
658
+ return constructCloudinaryUrl({
659
+ options: _extends({}, defaultOptions, cldOptions),
660
+ config: cldConfig
661
+ });
599
662
  }
600
663
 
601
664
  const CldImage = props => {
@@ -648,6 +711,59 @@ const CldImage = props => {
648
711
  }));
649
712
  };
650
713
 
714
+ const _excluded$1 = ["excludeTags", "twitterTitle"];
715
+ const IMAGE_WIDTH = 2400;
716
+ const IMAGE_HEIGHT = 1200;
717
+ const TWITTER_CARD = 'summary_large_image';
718
+
719
+ const CldOgImage = _ref => {
720
+ let {
721
+ excludeTags = [],
722
+ twitterTitle
723
+ } = _ref,
724
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
725
+
726
+ const options = _extends({}, props, {
727
+ width: props.width || IMAGE_WIDTH,
728
+ height: props.height || IMAGE_HEIGHT,
729
+ crop: props.crop || 'fill',
730
+ gravity: props.gravity || 'center'
731
+ });
732
+
733
+ const ogImageUrl = constructCloudinaryUrl({
734
+ options
735
+ }); // We need to include the tags within the Next.js Head component rather than
736
+ // direcly adding them inside of the Head otherwise we get unexpected results
737
+
738
+ return /*#__PURE__*/jsxs(Head, {
739
+ children: [/*#__PURE__*/jsx("meta", {
740
+ property: "og:image",
741
+ content: ogImageUrl
742
+ }), /*#__PURE__*/jsx("meta", {
743
+ property: "og:image:secure_url",
744
+ content: ogImageUrl
745
+ }), /*#__PURE__*/jsx("meta", {
746
+ property: "og:image:width",
747
+ content: options.width
748
+ }), /*#__PURE__*/jsx("meta", {
749
+ property: "og:image:height",
750
+ content: options.height
751
+ }), options.alt && /*#__PURE__*/jsx("meta", {
752
+ property: "og:image:alt",
753
+ content: options.alt
754
+ }), !excludeTags.includes('twitter:title') && /*#__PURE__*/jsx("meta", {
755
+ property: "twitter:title",
756
+ content: twitterTitle || ' '
757
+ }), /*#__PURE__*/jsx("meta", {
758
+ property: "twitter:card",
759
+ content: TWITTER_CARD
760
+ }), /*#__PURE__*/jsx("meta", {
761
+ property: "twitter:image",
762
+ content: ogImageUrl
763
+ })]
764
+ });
765
+ };
766
+
651
767
  const CldUploadWidget = ({
652
768
  children,
653
769
  onUpload,
@@ -780,5 +896,5 @@ const CldUploadButton = _ref => {
780
896
  });
781
897
  };
782
898
 
783
- export { CldImage, CldUploadButton, CldUploadWidget, cloudinaryLoader, position, primary, text };
899
+ export { CldImage, CldOgImage, CldUploadButton, CldUploadWidget, cloudinaryLoader, position, primary, text };
784
900
  //# sourceMappingURL=next-cloudinary.modern.mjs.map