UNPKG

gatsby-source-strapi

Version:

Gatsby source plugin for building websites using Strapi as a data source

142 lines (136 loc) 4.31 kB
"use strict"; exports.__esModule = true; exports.sourceNodes = exports.onPreInit = void 0; var _fetch = require("./fetch"); var _downloadMediaFiles = require("./download-media-files"); var _helpers = require("./helpers"); var _normalize = require("./normalize"); var _axiosInstance = require("./axios-instance"); const LAST_FETCHED_KEY = "timestamp"; const onPreInit = () => console.log("Loaded gatsby-source-strapi-plugin"); exports.onPreInit = onPreInit; const sourceNodes = async ({ actions, createContentDigest, createNodeId, reporter, getCache, store, cache, getNodes, getNode }, strapiConfig) => { reporter.info(`gatsby-source-strapi is using Strapi version ${strapiConfig.version || 5}`); // Cast singleTypes and collectionTypes to empty arrays if they're not defined if (!Array.isArray(strapiConfig.singleTypes)) { strapiConfig.singleTypes = []; } if (!Array.isArray(strapiConfig.collectionTypes)) { strapiConfig.collectionTypes = []; } const axiosInstance = (0, _axiosInstance.createAxiosInstance)(strapiConfig); const { schemas } = await (0, _fetch.fetchStrapiContentTypes)(axiosInstance); const { deleteNode, touchNode } = actions; const context = { strapiConfig, axiosInstance, actions, schemas, createContentDigest, createNodeId, reporter, getCache, getNode, getNodes, store, cache }; const { createNode } = actions; const existingNodes = getNodes().filter(n => n.internal.owner === `gatsby-source-strapi` || n.internal.type === "File"); for (const n of existingNodes) { touchNode(n); } const endpoints = (0, _helpers.getEndpoints)(strapiConfig, schemas); const lastFetched = await cache.get(LAST_FETCHED_KEY); const allResults = await Promise.all(endpoints.map(({ kind, ...config }) => { if (kind === "singleType") { return (0, _fetch.fetchEntity)(config, context); } return (0, _fetch.fetchEntities)(config, context); })); let newOrExistingEntries; // Fetch only the updated data between run if (lastFetched) { // Add the updatedAt filter const deltaEndpoints = endpoints.map(endpoint => { return { ...endpoint, queryParams: { ...endpoint.queryParams, filters: { ...endpoint.queryParams.filters, updatedAt: { $gt: lastFetched } } } }; }); newOrExistingEntries = await Promise.all(deltaEndpoints.map(({ kind, ...config }) => { if (kind === "singleType") { return (0, _fetch.fetchEntity)(config, context); } return (0, _fetch.fetchEntities)(config, context); })); } const data = newOrExistingEntries || allResults; // Build a map of all nodes with the gatsby id and the strapi_id const existingNodesMap = (0, _helpers.buildMapFromNodes)(existingNodes); // Build a map of all the parent nodes that should be removed // This should also delete all the created nodes for markdown, relations, dz... // When fetching only one content type and populating its relations it might cause some issues // as the relation nodes will never be deleted // it's best to fetch the content type and its relations separately and to populate // only one level of relation const nodesToRemoveMap = (0, _helpers.buildNodesToRemoveMap)(existingNodesMap, endpoints, allResults); // Delete all nodes that should be deleted for (const [nodeName, nodesToDelete] of Object.entries(nodesToRemoveMap)) { if (nodesToDelete.length > 0) { reporter.info(`Strapi: ${nodeName} deleting ${nodesToDelete.length}`); for (const { id } of nodesToDelete) { const node = getNode(id); touchNode(node); deleteNode(node); } } } await cache.set(LAST_FETCHED_KEY, Date.now()); for (const [index, { uid }] of endpoints.entries()) { if (!strapiConfig.skipFileDownloads) { await (0, _downloadMediaFiles.downloadMediaFiles)(data[index], context, uid); } for (let entity of data[index]) { const nodes = (0, _normalize.createNodes)(entity, context, uid); await Promise.all(nodes.map(n => createNode(n))); } } return; }; exports.sourceNodes = sourceNodes;