Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cname, private cdn support #252

Merged
merged 5 commits into from
Jun 7, 2024
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# [4.6.0-cname-private-cdn-support.1](https://github.com/cloudinary-community/gatsby-transformer-cloudinary/compare/v4.5.0...v4.6.0-cname-private-cdn-support.1) (2024-06-06)


### Features

* cname, private cdn support ([3a82b2f](https://github.com/cloudinary-community/gatsby-transformer-cloudinary/commit/3a82b2f2cd364d06e81bda54478549362d4a7e42))
* configurable transform types [#245](https://github.com/cloudinary-community/gatsby-transformer-cloudinary/issues/245) ([#250](https://github.com/cloudinary-community/gatsby-transformer-cloudinary/issues/250)) ([202ed12](https://github.com/cloudinary-community/gatsby-transformer-cloudinary/commit/202ed12b859957d2008f048373e54a728ee07f63))

# [4.6.0-beta.1](https://github.com/cloudinary-community/gatsby-transformer-cloudinary/compare/v4.5.0...v4.6.0-beta.1) (2024-02-13)


Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,38 @@ Read the [Gatsby Plugin Image Docs](https://www.gatsbyjs.com/docs/reference/buil

Read the [Gatsby Plugin Image Docs](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image/#all-options) on `sizes`.

### `secure`

When set to `false` use non-secure URLs (`http`) instead of secure URLs(`https`) for the image URLs.

**Type:** `Boolean`\
**Default:** `true`

### `secureDistribution`

The custom domain name (CNAME) to use for building secure URLs (`https`).

Relevant only for users on the Advanced plan or higher that have a custom CNAME. For details, see [Private CDNs and CNAMEs](https://cloudinary.com/documentation/advanced_url_delivery_options#private_cdns_and_cnames).

**Type:** `String`\
**Default:** n/a

### `cname`

The custom domain name (CNAME) to use for building non-secure URLs (`http`), remember to set `secure` to `false` when using `cname`.

Relevant only for users on the Advanced plan or higher that have a custom CNAME. For details, see [Private CDNs and CNAMEs](https://cloudinary.com/documentation/advanced_url_delivery_options#private_cdns_and_cnames).

**Type:** `String`\
**Default:** n/a

### `privateCdn`

Relevant only for users on the Advanced plan or higher that have private CDN distribution. For details, see [Private CDNs and CNAMEs](https://cloudinary.com/documentation/advanced_url_delivery_options#private_cdns_and_cnames).

**Type:** `Boolean`\
**Default:** `false`

 

## 📚 Other Resources
Expand Down
140 changes: 140 additions & 0 deletions demo/src/pages/manual-tests/cname-private-cdn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import React from 'react';
import { graphql, useStaticQuery } from 'gatsby';
import { getImage } from 'gatsby-plugin-image';

const CnamePage = () => {
const data = useStaticQuery(graphql`
query {
cname: allProject {
nodes {
name
coverImage {
gatsbyImageData(
height: 300
aspectRatio: 2
placeholder: TRACED_SVG
transformations: ["c_fill", "g_auto:subject", "q_auto"]
cname: "example.com"
secure: false
)
}
}
}
secureDistribution: allProject {
nodes {
name
coverImage {
gatsbyImageData(
height: 300
aspectRatio: 2
placeholder: TRACED_SVG
transformations: ["c_fill", "g_auto:subject", "q_auto"]
secureDistribution: "example.com"
secure: true
)
}
}
}
privateCDNSecure: allProject {
nodes {
name
coverImage {
gatsbyImageData(
height: 300
aspectRatio: 2
placeholder: TRACED_SVG
transformations: ["c_fill", "g_auto:subject", "q_auto"]
privateCdn: true
secure: true
)
}
}
}
privateCDNUnSecure: allProject {
nodes {
name
coverImage {
gatsbyImageData(
height: 300
aspectRatio: 2
placeholder: TRACED_SVG
transformations: ["c_fill", "g_auto:subject", "q_auto"]
privateCdn: true
secure: false
)
}
}
}
}
`);

return (
<>
<h2>Secure distribution</h2>
<p>
Expect url to start with <code>https://example.com</code>
</p>
{data.secureDistribution.nodes.map((node) => {
const gatsbyImage = getImage(node.coverImage?.gatsbyImageData);

return (
<>
<h2>{node.name}</h2>
<pre>{gatsbyImage.images.fallback.src}</pre>
</>
);
})}

<h2>CNAME</h2>
<p>
Expect urls to start with <code>http://example.com</code>
</p>
{data.cname.nodes.map((node) => {
const gatsbyImage = getImage(node.coverImage?.gatsbyImageData);

return (
<>
<h2>{node.name}</h2>
<pre>{gatsbyImage.images.fallback.src}</pre>
</>
);
})}

<h2>Private CDN (Secure)</h2>
<p>
Expect urls to start with the cloudinary subdomain (https version), not{' '}
<code>https://res.cloudinary.com</code>
</p>

{data.privateCDNSecure.nodes.map((node) => {
const gatsbyImage = getImage(node.coverImage?.gatsbyImageData);

return (
<>
<h2>{node.name}</h2>
<pre>{gatsbyImage.images.fallback.src}</pre>
</>
);
})}

<h2>Private CDN (UnSecure)</h2>
<p>
Expect urls to start with the cloudinary subdomain (http version), not{' '}
<code>http://res.cloudinary.com</code>
</p>

{data.privateCDNUnSecure.nodes.map((node) => {
const gatsbyImage = getImage(node.coverImage?.gatsbyImageData);

return (
<>
<h2>{node.name}</h2>
<pre>{gatsbyImage.images.fallback.src}</pre>
</>
);
})}
</>
);
};

export default CnamePage;
3 changes: 3 additions & 0 deletions plugin/gatsby-plugin-image/generate-asset-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ exports.generateCloudinaryAssetUrl = ({
const url = cloudinary.url(publicId, {
cloud_name: cloudName,
secure: options.secure,
cname: options.cname,
secure_distribution: options.secureDistribution,
private_cdn: options.privateCdn,
transformation: transformation,
flags: flags,
urlAnalytics: true,
Expand Down
150 changes: 102 additions & 48 deletions plugin/gatsby-plugin-image/generate-asset-url.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,63 +18,117 @@ describe('generateCloudinaryAssetUrl', () => {
format: 'jpg',
};

it('generates correct Cloudinary url when no options', () => {
const url = generateCloudinaryAssetUrl(asset);
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});
describe('generates correct Cloudinary url', () => {
it('when no options', () => {
const url = generateCloudinaryAssetUrl(asset);
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});

it('generates correct Cloudinary url with transformations option', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
transformations: ['e_grayscale', 'e_pixelate'],
},
it('with transformations option', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
transformations: ['e_grayscale', 'e_pixelate'],
},
});
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400,e_grayscale,e_pixelate/public-id?_a=${ANALYTICS_CODE}`
);
});
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400,e_grayscale,e_pixelate/public-id?_a=${ANALYTICS_CODE}`
);
});

it('generates correct Cloudinary url with chained option', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
chained: ['t_lwj', 'e_pixelate'],
},
it('with chained option', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
chained: ['t_lwj', 'e_pixelate'],
},
});
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/t_lwj/e_pixelate/public-id?_a=${ANALYTICS_CODE}`
);
});
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/t_lwj/e_pixelate/public-id?_a=${ANALYTICS_CODE}`
);
});

it('generates correct Cloudinary url with scure option set to true', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
secure: true,
},
it('with scure option set to true', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
secure: true,
},
});
expect(url).toBe(
`https://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});

it('with custom secure_distribution (cname) and secure is true', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
secure: true,
secureDistribution: 'example.com',
},
});
expect(url).toBe(
`https://example.com/cloud-name/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});
expect(url).toBe(
`https://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});

it('generates correct Cloudinary url in traced SVG mode', () => {
const url = generateCloudinaryAssetUrl({
...asset,
tracedSvg: {
it('with cname and secure is false', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
colors: 2,
detail: 0.3,
despeckle: 0.1,
secure: false,
cname: 'example.com',
},
});
expect(url).toBe(
`http://example.com/cloud-name/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});

it('for private_cdn and secure is true', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
secure: true,
privateCdn: true,
},
});
expect(url).toBe(
`https://cloud-name-res.cloudinary.com/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});

it('for private_cdn and secure is false', () => {
const url = generateCloudinaryAssetUrl({
...asset,
options: {
secure: false,
privateCdn: true,
},
});
expect(url).toBe(
`http://cloud-name-res.cloudinary.com/image/upload/f_jpg,h_600,w_400/public-id?_a=${ANALYTICS_CODE}`
);
});

it('generates correct Cloudinary url in traced SVG mode', () => {
const url = generateCloudinaryAssetUrl({
...asset,
tracedSvg: {
options: {
colors: 2,
detail: 0.3,
despeckle: 0.1,
},
width: 300,
},
width: 300,
},
});
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/e_vectorize:colors:2:detail:0.3:despeckle:0.1,w_300/public-id?_a=${ANALYTICS_CODE}`
);
});
expect(url).toBe(
`http://res.cloudinary.com/cloud-name/image/upload/f_jpg,h_600,w_400/e_vectorize:colors:2:detail:0.3:despeckle:0.1,w_300/public-id?_a=${ANALYTICS_CODE}`
);
});
});
Loading
Loading