@mapbox/batfish
Version:
The React-powered static-site generator you didn't know you wanted
110 lines (99 loc) • 3.54 kB
JavaScript
//
;
const fs = require('fs');
const path = require('path');
const pify = require('pify');
const globby = require('globby');
const grayMatter = require('gray-matter');
const joinUrlParts = require('./join-url-parts');
const constants = require('./constants');
const errorTypes = require('./error-types');
const wrapError = require('./wrap-error');
// Get data about pages. Reads the pagesDirectory, figures out URL paths, parses
// front matter.
//
// Return Promise resolves with an object whose keys are page paths and values
// are page data. See type definition for BatfishPageData.
function getPagesData(
batfishConfig
) {
const base = batfishConfig.siteBasePath;
const notFoundPath = joinUrlParts(base, '404', '');
// Convert a page's file path to its URL path.
const pageFilePathToUrlPath = (filePath ) => {
const relativePath = path.relative(batfishConfig.pagesDirectory, filePath);
if (/^index\.(js|md)$/.test(relativePath)) {
if (base === '/') return base;
return base + '/';
}
if (/\/index\.(js|md)$/.test(relativePath)) {
return joinUrlParts(base, path.dirname(relativePath), '');
}
return joinUrlParts(base, relativePath.replace(/\.(js|md)$/, ''), '');
};
let pagesData = {};
const registerPage = (filePath ) => {
const is404 =
filePath.replace(/\.(js|md)$/, '') ===
path.join(batfishConfig.pagesDirectory, '404');
return pify(fs.readFile)(filePath, 'utf8').then((content ) => {
const isMarkdown = path.extname(filePath) === '.md';
const grayMatterOptions = isMarkdown
? { delims: ['---', '---'] }
: { delims: ['/*---', '---*/'] };
let parsedFrontMatter;
try {
parsedFrontMatter = grayMatter(content, grayMatterOptions);
} catch (parseError) {
throw wrapError(parseError, errorTypes.FrontMatterError, {
filePath
});
}
const published = parsedFrontMatter.data.published !== false;
if (!published && batfishConfig.production) return;
const pagePath = pageFilePathToUrlPath(filePath);
const pageData = {
filePath,
path: pagePath,
frontMatter: parsedFrontMatter.data
};
if (is404) {
pageData.is404 = true;
pageData.path = notFoundPath;
}
pagesData[pagePath] = pageData;
});
};
const pagesGlob = [`**/*.${constants.PAGE_EXT_GLOB}`];
if (batfishConfig.unprocessedPageFiles) {
pagesGlob.push(...batfishConfig.unprocessedPageFiles.map((g) => `!${g}`));
}
return globby(pagesGlob, {
cwd: batfishConfig.pagesDirectory,
absolute: true
})
.then((pageFilePaths) => {
if (batfishConfig.spa && pageFilePaths.length > 1) {
throw new errorTypes.ConfigFatalError(
'In your Batfish config you set `spa: true`, but you have more than one page. SPA mode only allows one Batfish page.'
);
}
return Promise.all(pageFilePaths.map(registerPage));
})
.then(() => {
if (
!pagesData[notFoundPath] &&
!batfishConfig.production &&
!batfishConfig.spa
) {
pagesData[notFoundPath] = {
filePath: path.join(__dirname, '../webpack/default-not-found.js'),
path: notFoundPath,
is404: true,
frontMatter: {}
};
}
return pagesData;
});
}
module.exports = getPagesData;