UNPKG

@ehp/gatsby-source-drupal

Version:

Gatsby source plugin for building websites using the Drupal CMS as a data source

247 lines (198 loc) 6.84 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); const axios = require(`axios`); const axiosRetry = require(`axios-retry`); const crypto = require(`crypto`); const _ = require(`lodash`); const _require = require(`gatsby-source-filesystem`), createRemoteFileNode = _require.createRemoteFileNode; const _require2 = require(`url`), URL = _require2.URL; const _require3 = require(`./normalize`), nodeFromData = _require3.nodeFromData, normalizeTypeName = _require3.normalizeTypeName; axiosRetry(axios, { retries: 999, retryDelay: retryCount => { return retryCount * 1000; } }); // Get content digest of node. const createContentDigest = obj => crypto.createHash(`md5`).update(JSON.stringify(obj)).digest(`hex`); exports.sourceNodes = /*#__PURE__*/ function () { var _ref = (0, _asyncToGenerator2.default)(function* ({ actions, getNode, hasNodeChanged, store, cache, createNodeId }, { baseUrl, apiBase }) { const createNode = actions.createNode; // Default apiBase to `jsonapi` apiBase = apiBase || `jsonapi`; // Touch existing Drupal nodes so Gatsby doesn't garbage collect them. // _.values(store.getState().nodes) // .filter(n => n.internal.type.slice(0, 8) === `drupal__`) // .forEach(n => touchNode({ nodeId: n.id })) // Fetch articles. // console.time(`fetch Drupal data`) console.log(`Starting to fetch data from Drupal`); // TODO restore this // let lastFetched // if ( // store.getState().status.plugins && // store.getState().status.plugins[`gatsby-source-drupal`] // ) { // lastFetched = store.getState().status.plugins[`gatsby-source-drupal`].status // .lastFetched // } const data = yield axios.get(`${baseUrl}/${apiBase}`); const allData = yield Promise.all(_.map(data.data.links, /*#__PURE__*/ function () { var _ref2 = (0, _asyncToGenerator2.default)(function* (url, type) { if (type === `self`) return; if (!url) return; if (!type) return; const getNext = /*#__PURE__*/ function () { var _ref3 = (0, _asyncToGenerator2.default)(function* (url, data = []) { const d = yield axios.get(url); data = data.concat(d.data.data); if (d.data.links.next) { data = yield getNext(d.data.links.next, data); } return data; }); return function getNext(_x5) { return _ref3.apply(this, arguments); }; }(); const data = yield getNext(url); const result = { type, data // eslint-disable-next-line consistent-return }; return result; }); return function (_x3, _x4) { return _ref2.apply(this, arguments); }; }())); // Make list of all IDs so we can check against that when creating // relationships. const ids = {}; _.each(allData, contentType => { if (!contentType) return; _.each(contentType.data, datum => { ids[datum.id] = true; }); }); // Create back references var backRefs = {}; const addBackRef = function addBackRef(sourceId, linkedId, relationshipName, type) { if (ids[linkedId]) { if (typeof backRefs[linkedId] === `undefined`) { backRefs[linkedId] = []; } backRefs[linkedId].push({ id: sourceId, type: normalizeTypeName(`backref_${relationshipName}`) }); backRefs[linkedId].push({ id: sourceId, type: normalizeTypeName(`backref_${relationshipName}_${type}`) }); } }; _.each(allData, function (contentType) { if (!contentType) return; _.each(contentType.data, function (datum) { if (datum.relationships) { _.each(datum.relationships, function (v, k) { if (!v.data) { return; } if (_.isArray(v.data)) { v.data.forEach(function (data) { addBackRef(datum.id, data.id, k, contentType.type); }); } else { addBackRef(datum.id, v.data.id, k, contentType.type); } }); } }); }); // Process nodes const nodes = []; _.each(allData, contentType => { if (!contentType) return; _.each(contentType.data, datum => { const node = nodeFromData(datum); // Add relationships if (datum.relationships) { var addedRelationships = false; node.relationships = {}; _.each(datum.relationships, (v, k) => { if (!v.data) return; if (_.isArray(v.data) && v.data.length > 0) { node.relationships[`${normalizeTypeName(k)}___NODE`] = v.data.map(function (data) { return data.id; }); addedRelationships = true; } else if (ids[v.data.id]) { node.relationships[`${normalizeTypeName(k)}___NODE`] = v.data.id; addedRelationships = true; } }); if (backRefs[datum.id]) { backRefs[datum.id].forEach(function (ref) { if (!node.relationships[`${ref.type}___NODE`]) { node.relationships[`${ref.type}___NODE`] = []; } node.relationships[`${ref.type}___NODE`].push(ref.id); addedRelationships = true; }); } if (!addedRelationships) { delete node.relationships; } } node.internal.contentDigest = createContentDigest(node); nodes.push(node); }); }); // Download all files. yield Promise.all(nodes.map( /*#__PURE__*/ function () { var _ref4 = (0, _asyncToGenerator2.default)(function* (node) { let fileNode; if (node.internal.type === `files` || node.internal.type === `file__file`) { try { // Resolve w/ baseUrl if node.uri isn't absolute. const url = new URL(node.url, baseUrl); fileNode = yield createRemoteFileNode({ url: url.href, store, cache, createNode, createNodeId }); } catch (e) {// Ignore } if (fileNode) { node.localFile___NODE = fileNode.id; } } }); return function (_x6) { return _ref4.apply(this, arguments); }; }())); nodes.forEach(n => createNode(n)); }); return function (_x, _x2) { return _ref.apply(this, arguments); }; }();