diff --git a/packages/gatsby-source-drupal/README.md b/packages/gatsby-source-drupal/README.md index 4327018e346a1..046a4a4e91e27 100644 --- a/packages/gatsby-source-drupal/README.md +++ b/packages/gatsby-source-drupal/README.md @@ -250,6 +250,29 @@ module.exports = { } ``` +## CDN + +You can add an optional CDN or API gateway URL `proxyUrl` param. The URL can be a simple proxy of the Drupal +`baseUrl`, or another URL (even containing a path) where the Drupal JSON API resources can be retrieved. + +This option is required as Drupal doesn't know about the CDN so it returns URLs pointing to the `baseUrl`. With `proxyUrl` set, the plugin will rewrite URLs returned from Drupal to keep pointing at the `proxyUrl` + +```javascript +// In your gatsby-config.js +module.exports = { + plugins: [ + { + resolve: `gatsby-source-drupal`, + options: { + baseUrl: `https://live-contentacms.pantheonsite.io/`, + proxyUrl: `https://xyz.cloudfront.net/`, // optional, defaults to the value of baseUrl + apiBase: `api`, // optional, defaults to `jsonapi` + }, + }, + ], +} +``` + ## GET Search Params You can append optional GET request params to the request url using `params` option. diff --git a/packages/gatsby-source-drupal/src/__tests__/index.js b/packages/gatsby-source-drupal/src/__tests__/index.js index 59ff60f390c68..ef8ded945c761 100644 --- a/packages/gatsby-source-drupal/src/__tests__/index.js +++ b/packages/gatsby-source-drupal/src/__tests__/index.js @@ -1,5 +1,14 @@ +import got from "got" + +const baseUrl = `http://fixture` +const proxyUrl = `http://fixture-proxy` + jest.mock(`got`, () => jest.fn(path => { + if (path.includes(proxyUrl)) { + path = path.replace(proxyUrl, baseUrl) + } + let last = `` if (path.includes(`i18n-test`)) { last = `i18n-test-` @@ -59,7 +68,6 @@ const { handleWebhookUpdate } = require(`../utils`) describe(`gatsby-source-drupal`, () => { let nodes = {} const createNodeId = id => `generated-id-${id}` - const baseUrl = `http://fixture` const createContentDigest = jest.fn().mockReturnValue(`contentDigest`) const { objectContaining } = expect const actions = { @@ -450,6 +458,38 @@ describe(`gatsby-source-drupal`, () => { expect(nodes[createNodeId(`und.article-3`)]).toBeDefined() }) + it(`Can use the proxyUrl plugin option to use a different API url for sourcing`, async () => { + got.mockClear() + nodes = {} + await sourceNodes(args, { baseUrl, proxyUrl }) + + let callSkipCount = 0 + for (const [index, call] of got.mock.calls.entries()) { + if (call[0] === `http://fixture/jsonapi`) { + callSkipCount++ + continue + } + + expect(got).toHaveBeenNthCalledWith( + index + 1, + expect.stringContaining(proxyUrl), + expect.anything() + ) + } + + expect(callSkipCount).toBe(1) + expect(got).toBeCalledTimes(8) + + expect(Object.keys(nodes).length).not.toEqual(0) + expect(nodes[createNodeId(`und.file-1`)]).toBeDefined() + expect(nodes[createNodeId(`und.file-2`)]).toBeDefined() + expect(nodes[createNodeId(`und.tag-1`)]).toBeDefined() + expect(nodes[createNodeId(`und.tag-2`)]).toBeDefined() + expect(nodes[createNodeId(`und.article-1`)]).toBeDefined() + expect(nodes[createNodeId(`und.article-2`)]).toBeDefined() + expect(nodes[createNodeId(`und.article-3`)]).toBeDefined() + }) + it(`Verify JSON:API includes relationships`, async () => { // Reset nodes and test includes relationships. Object.keys(nodes).forEach(key => delete nodes[key]) diff --git a/packages/gatsby-source-drupal/src/gatsby-node.js b/packages/gatsby-source-drupal/src/gatsby-node.js index cfe34cb110ba5..ab9d72d1fc4d3 100644 --- a/packages/gatsby-source-drupal/src/gatsby-node.js +++ b/packages/gatsby-source-drupal/src/gatsby-node.js @@ -155,6 +155,7 @@ exports.sourceNodes = async ( globalReporter = reporter const { baseUrl, + proxyUrl = baseUrl, apiBase = `jsonapi`, basicAuth = {}, filters, @@ -534,6 +535,11 @@ ${JSON.stringify(webhookBody, null, 4)}` } } + // If proxyUrl is defined, use it instead of baseUrl to get the content. + if (proxyUrl !== baseUrl) { + url = url.replace(baseUrl, proxyUrl) + } + let d try { d = await requestQueue.push([ @@ -833,6 +839,9 @@ exports.pluginOptionsSchema = ({ Joi }) => baseUrl: Joi.string() .required() .description(`The URL to root of your Drupal instance`), + proxyUrl: Joi.string().description( + `The CDN URL equivalent to your baseUrl` + ), apiBase: Joi.string().description( `The path to the root of the JSONAPI — defaults to "jsonapi"` ),