UNPKG

@metalsmith/default-values

Version:

A metalsmith plugin for setting default values to file metadata.

113 lines (102 loc) 3.73 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, ...args) => { 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, ...args); 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} currentFile * @param {string} currentPath * @param {import('metalsmith').Files} files * @param {import('metalsmith')} 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` or _computed values_ 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, * 'some.nested.property': true, * isodate(post, postPath, allFiles, metalsmith) { * return new Date(post.stats.ctime).toISOString() * } * } *})) **/ function defaultValues(options) { return function defaultValues(files, metalsmith, done) { const debug = metalsmith.debug('@metalsmith/default-values'); if (!options) { debug.warn('No defaults specified. Skipping execution.'); done(); return; } if (!Array.isArray(options) && typeof options === 'object') { options = [options]; } debug('Running with options: %O ', options); const defaultSets = options.map(defaultsSet => ({ ...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], file, files, metalsmith); debug.info('Values set for file "%s": %O', file, changed); }); } else { debug.warn('No matches for pattern "%s"', pattern); } }); done(); }; } module.exports = defaultValues;