UNPKG

gatsby-source-prismic

Version:

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

121 lines (120 loc) 5.35 kB
import { createClient, WebhookType } from "@prismicio/client"; import { cachedFetch } from "../lib/cachedFetch.js"; import { createDocumentNodes } from "../lib/createDocumentNodes.js"; import { fmtLog } from "../lib/fmtLog.js"; import { getModelsCacheKey } from "../lib/getModelsCacheKey.js"; import { hasOwnProperty } from "../lib/hasOwnProperty.js"; const isPrismicWebhookBody = (webhookBody) => { return typeof webhookBody === "object" && webhookBody !== null && hasOwnProperty(webhookBody, "apiUrl") && typeof webhookBody.apiUrl === "string" && /^https?:\/\/([^.]+)\.(wroom\.(?:test|io)|prismic\.io)\/api\/?/.test(webhookBody.apiUrl); }; const sourceNodes = async (args, options) => { const client = createClient(options.apiEndpoint || options.repositoryName, { accessToken: options.accessToken, routes: options.routes, fetch: async (input, init) => { const resolvedFetch = options.fetch || (await import("node-fetch")).default; const url = new URL(input); if (/\/documents\/search\/?/.test(url.pathname)) { return await cachedFetch(input, init, { fetch: resolvedFetch, cache: args.cache, name: "sourceNodes" }); } else { return await resolvedFetch(input, init); } }, defaultParams: { lang: options.lang || "*", fetchLinks: options.fetchLinks, graphQuery: options.graphQuery, predicates: options.predicates } }); let release; if (options.releaseID) { client.queryContentFromReleaseByID(options.releaseID); release = await client.getReleaseByID(options.releaseID); } else if (options.releaseLabel) { client.queryContentFromReleaseByLabel(options.releaseLabel); release = await client.getReleaseByLabel(options.releaseLabel); } if (release && !args.webhookBody) { args.reporter.info(fmtLog(options.repositoryName, `Querying documents from the "${release.label}" Release (ID: "${release.id}")`)); } const { customTypeModels, sharedSliceModels } = await args.cache.get(getModelsCacheKey({ repositoryName: options.repositoryName })); let documentsToCreate = []; const documentIDsToDelete = []; const hasWebhookBody = args.webhookBody && JSON.stringify(args.webhookBody) !== "{}"; if (!hasWebhookBody) { documentsToCreate = await client.dangerouslyGetAll(); } else { if (isPrismicWebhookBody(args.webhookBody) && args.webhookBody.domain === options.repositoryName) { if (!args.webhookBody.secret || args.webhookBody.secret === options.webhookSecret) { switch (args.webhookBody.type) { case WebhookType.TestTrigger: { args.reporter.info(fmtLog(options.repositoryName, "Success! Received a test trigger webhook. When changes to your content are saved, Gatsby will automatically fetch the changes.")); break; } case WebhookType.APIUpdate: { args.reporter.info(fmtLog(options.repositoryName, "Received an API update webhook. Documents will be added, updated, or deleted accordingly.")); const webhookDocumentIDs = args.webhookBody.documents; if (release) { const webhookReleaseDocumentIDs = []; for (const releaseUpdate of [ ...args.webhookBody.releases.update || [], ...args.webhookBody.releases.addition || [], ...args.webhookBody.releases.deletion || [] ]) { if (releaseUpdate.id === release.id) { webhookReleaseDocumentIDs.push(...releaseUpdate.documents); } } webhookDocumentIDs.push(...webhookReleaseDocumentIDs); } documentsToCreate = await client.getAllByIDs([ ...new Set(webhookDocumentIDs) ]); for (const webhookDocumentID of webhookDocumentIDs) { if (!documentsToCreate.some((doc) => doc.id === webhookDocumentID)) { documentIDsToDelete.push(webhookDocumentID); } } break; } } } } } if (documentsToCreate.length > 0) { if (hasWebhookBody) { args.reporter.info(fmtLog(options.repositoryName, `Adding or updating the following Prismic documents: [${documentsToCreate.map((doc) => `"${doc.id}"`).join(", ")}]`)); } await createDocumentNodes({ documents: documentsToCreate, customTypeModels, sharedSliceModels, gatsbyNodeArgs: args, pluginOptions: options }); } if (documentIDsToDelete.length > 0) { args.reporter.info(fmtLog(options.repositoryName, `Deleting the following Prismic documents: [${documentIDsToDelete.map((id) => `"${id}"`).join(", ")}]`)); for (const documentIDToDelete of documentIDsToDelete) { const node = args.getNode(args.createNodeId(documentIDToDelete)); if (node) { args.actions.deleteNode(node); } } } const nodesToTouch = args.getNodes().filter((node) => { return node.internal.owner === "gatsby-source-prismic" && hasOwnProperty(node, "prismicId") && typeof node.prismicId === "string" && !documentIDsToDelete.includes(node.prismicId); }); for (const nodeToTouch of nodesToTouch) { args.actions.touchNode(nodeToTouch); } }; export { sourceNodes }; //# sourceMappingURL=sourceNodes.js.map