gatsby-source-prismic
Version:
Gatsby source plugin for building websites using Prismic as a data source
121 lines (120 loc) • 5.35 kB
JavaScript
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