UNPKG

gatsby-plugin-stork

Version:

A Gatsby plugin for generating Stork search indexes.

117 lines (98 loc) 3.3 kB
const { execSync } = require("child_process"); const fs = require("fs").promises; const tmp = require("tmp"); const pathUtil = require("path"); const TOML = require("@iarna/toml"); const { DEFAULTS, DEFAULT_OUTPUT_FILE_NAME } = require("./defaults"); const { createSchema } = require("./schema"); exports.pluginOptionsSchema = ({ Joi }) => createSchema(Joi); exports.onPostBootstrap = async ({ getNodes }, pluginOptions) => { assertStorkIsInstalled(); const { indexes } = { ...DEFAULTS, ...pluginOptions, }; const nodes = getNodes(); await Promise.all( indexes.map(async ({ filename = DEFAULT_OUTPUT_FILE_NAME, resolvers }) => { const files = []; nodes.forEach(node => { const resolver = resolvers[node.internal.type]; if (!resolver) return; const resolvedValues = {}; Object.entries(resolver).forEach(([key, resolveFunc]) => { resolvedValues[key] = resolveFunc(node); }); files.push(resolvedValues); }); // Serialize and write to TOML const { name: tempFileName, removeCallback } = tmp.fileSync({ postfix: ".toml", }); // Throw if any files are invalid // N.B. either path or contents is valid const testForInvalidFile = ({ path, contents, url, title }) => !(path || contents) || !url || !title; if (files.some(testForInvalidFile)) { const invalidFiles = files.filter(testForInvalidFile); console.error( "The following node inputs were missing one or more of the required fields (path/contents, url, and title):" ); invalidFiles.forEach(console.error); throw new Error("Could not generate index from invalid files"); } console.log(`Writing temporary TOML to ${tempFileName}`); const outputObject = { input: { base_directory: __dirname, files, }, output: { filename: pathUtil.join("public", filename), }, }; const tomlString = TOML.stringify(outputObject); await fs.writeFile(tempFileName, tomlString); buildStorkIndex(tempFileName, tomlString); // Clean up temp file removeCallback(); }) ); }; /** * Checks that stork is installed on the host machine. * @throws if Stork is not present. */ function assertStorkIsInstalled() { if (process.env.GATSBY_STORK_EXECUTABLE_PATH) { // if the user provides an executable path, we trust // that it's properly installed there return; } // Check if Stork is present try { execSync("which -s stork"); // `-s` omits output and just returns a 0 or 1 exit code } catch (e) { console.error( "It looks like the Stork executable is not installed. For some instructions on how to install Stork, see the documentation: https://stork-search.net/docs/install" ); throw e; } } /** * Builds stork index. * @throws if Stork returns a non-zero exit code. */ function buildStorkIndex(tempFileName, tomlString) { try { execSync( `${ process.env.GATSBY_STORK_EXECUTABLE_PATH || "stork" } --build ${tempFileName}` ); } catch (e) { console.error("Could not generate index for generated TOML file:"); console.error(tomlString); throw e; } }