UNPKG

@metalsmith/default-values

Version:

A metalsmith plugin for setting default values to file metadata.

103 lines (92 loc) 3.43 kB
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;