@metalsmith/default-values
Version:
A metalsmith plugin for setting default values to file metadata.
103 lines (92 loc) • 3.43 kB
JavaScript
var buffer = require('buffer');
var get = require('dlv');
var dset = require('dset');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
/**
* Sets defaults for object values
* @param {Array<Array<*>>} defaults
* @param {'keep'|'overwrite'} strategy
* @return {import('.').DefaultSetter} Takes an object and sets defaults
*/
function set_defaults(defaults, strategy) {
return (item, context) => {
const delta = {};
defaults.forEach(([key, defaultValue]) => {
const value = get__default["default"](item, key);
if (strategy === 'overwrite' || value === void 0 || value === null || buffer.Buffer.isBuffer(value) && value.toString().trim().length === 0) {
if (typeof defaultValue === 'function') defaultValue = defaultValue(item, context);
if (buffer.Buffer.isBuffer(value) && !buffer.Buffer.isBuffer(defaultValue)) defaultValue = buffer.Buffer.from(defaultValue);
dset.dset(item, key, defaultValue);
dset.dset(delta, key, defaultValue);
}
});
return delta;
};
}
/**
* @callback DefaultSetter
* @param {import('metalsmith').File} file
* @param {Object<string, *>} metadata
*/
/**
* @typedef {Object} DefaultsSet
* @property {string|string[]} [pattern="**"] 1 or more glob patterns to match files. Defaults to `'**'` (all).
* @property {Object<string, *>} [defaults={}] an object whose keys will be set as file metadata keys
* @property {'keep'|'overwrite'} [strategy="keep"] Strategy to handle setting defaults to keys that are aleady defined. Defaults to `'keep'`
*/
/** @type {DefaultsSet} */
const defaultDefaultsSet = {
defaults: {},
strategy: 'keep',
pattern: '**'
};
/**
* Set `defaults` to file metadata matching `pattern`'s.
*
* @param {DefaultsSet|DefaultsSet[]} options an array of defaults sets to add to files matched by pattern
* @return {import('metalsmith').Plugin}
*
* @example
* metalsmith.use(defaultValues({
pattern: 'posts/*.md',
defaults: {
layout: 'post.hbs',
draft: false,
date(post) {
return post.stats.ctime
}
}
}))
**/
function defaultValues(options) {
return function defaultValues(files, metalsmith, done) {
const debug = metalsmith.debug('@metalsmith/default-values');
if (!Array.isArray(options) && typeof options === 'object' && options !== null) {
options = [options];
}
debug('Running with options: %O ', options);
const defaultSets = (options || []).map(defaultsSet => Object.assign({}, defaultDefaultsSet, defaultsSet));
// Loop through configurations
defaultSets.forEach(function ({
pattern,
defaults,
strategy
}) {
const matches = metalsmith.match(pattern, Object.keys(files));
const defaultsEntries = Object.entries(defaults);
debug.info('Matched %s files to pattern "%s": %o', matches.length, pattern, matches);
if (matches.length) {
const setDefaults = set_defaults(defaultsEntries, strategy);
matches.forEach(file => {
const changed = setDefaults(files[file], metalsmith.metadata());
debug.info('Values set for file "%s": %O', file, changed);
});
} else {
debug.warn('No matches for pattern "%s"', pattern);
}
});
done();
};
}
module.exports = defaultValues;