@metalsmith/collections
Version:
A Metalsmith plugin that adds collections of files to the global metadata.
1 lines • 14.5 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["import get from 'lodash.get'\nimport { sync as loadMetadata } from 'read-metadata'\n\nfunction sortBy(key) {\n let getKey = (x) => x[key]\n if (key.includes('.')) {\n getKey = (x) => get(x, key)\n }\n return function defaultSort(a, b) {\n a = getKey(a)\n b = getKey(b)\n if (!a && !b) return 0\n if (!a) return -1\n if (!b) return 1\n if (b > a) return -1\n if (a > b) return 1\n return 0\n }\n}\n\n// for backwards-compatibility only, date makes as little sense as \"pubdate\" or any custom key\nconst defaultSort = sortBy('date')\nconst defaultFilter = () => true\n\n/**\n * @typedef {Object} CollectionConfig\n * @property {string|string[]} [pattern] - One or more glob patterns to match files to a collection\n * @property {string|(a,b) => 0|1|-1} [sortBy] - A key to sort by (e.g. `date`,`title`, ..) or a custom sort function\n * @property {number} [limit] - Limit the amount of items in a collection to `limit`\n * @property {boolean} [refer] - Adds `next` and `previous` keys to file metadata of matched files\n * @property {boolean} [reverse] - Whether to invert the sorting function results (asc/descending)\n * @property {Function} [filterBy] - A function that gets a `Metalsmith.File` as first argument and returns `true` for every file to include in the collection\n * @property {Object|string} [metadata] - An object with metadata to attach to the collection, or a `json`/`yaml`filepath string to load data from (relative to `Metalsmith.directory`)\n */\n\n/** @type {CollectionConfig} */\nconst defaultOptions = {\n pattern: null,\n reverse: false,\n metadata: null,\n limit: Infinity,\n refer: true,\n sortBy: defaultSort,\n filterBy: defaultFilter\n}\n\n/**\n * Normalize options\n * @param {Object.<string,CollectionConfig>} options\n */\nfunction normalizeOptions(options) {\n options = options || {}\n\n for (const config in options) {\n let normalized = options[config]\n if (typeof normalized === 'string' || Array.isArray(normalized)) {\n normalized = { pattern: normalized }\n }\n normalized = Object.assign({}, defaultOptions, normalized)\n if (typeof normalized.metadata === 'string') {\n normalized.metadata = loadMetadata(normalized.metadata)\n }\n if (typeof normalized.sortBy === 'string') {\n normalized.sortBy = sortBy(normalized.sortBy)\n }\n options[config] = normalized\n }\n\n return options\n}\n\n/**\n * Add `collections` of files to the global metadata as a sorted array.\n * @example\n * metalsmith.use(collections({\n * posts: 'posts/*.md',\n * portfolio: {\n * pattern: 'portfolio/*.md',\n * metadata: { title: 'My portfolio' },\n * sortBy: 'order'\n * }\n * }))\n *\n * @param {Object.<string,CollectionConfig|string>} options\n * @return {import('metalsmith').Plugin}\n */\nfunction collections(options) {\n options = normalizeOptions(options)\n const collectionNames = Object.keys(options)\n const mappedCollections = collectionNames.map((name) => {\n return Object.assign({ name: name }, options[name])\n })\n\n return function collections(files, metalsmith, done) {\n const metadata = metalsmith.metadata()\n const fileNames = Object.keys(files)\n const debug = metalsmith.debug('@metalsmith/collections')\n\n metadata.collections = {}\n\n fileNames.forEach((filePath) => {\n // add path property to file metadata for convenience\n // this is for backward-compatibility only and is pretty useless\n const file = files[filePath]\n file.path = file.path || filePath\n\n // dynamically add collections with default options when encountered in file metadata,\n // and not explicitly defined in plugin options\n if (file.collection) {\n ;(Array.isArray(file.collection) ? file.collection : [file.collection]).forEach((name) => {\n if (!collectionNames.includes(name)) {\n collectionNames.push(name)\n const normalized = Object.assign({}, defaultOptions)\n mappedCollections.push(Object.assign({ name }, normalized))\n }\n })\n }\n })\n\n debug('Identified %s collections: %s', mappedCollections.length, collectionNames.join())\n\n mappedCollections.forEach((collection) => {\n const { pattern, filterBy, sortBy, reverse, refer, limit } = collection\n const name = collection.name\n const matches = []\n debug('Processing collection %s with options %s:', name, collection)\n\n // first match by pattern if provided\n if (pattern) {\n matches.push.apply(\n matches,\n metalsmith.match(pattern, fileNames).map((filepath) => {\n const data = files[filepath]\n // pattern-matched files might or might not have a \"collection\" property defined in front-matter\n // and might also be included in multiple collections\n if (!data.collection) {\n data.collection = []\n } else if (typeof data.collection === 'string') {\n data.collection = [data.collection]\n }\n if (!data.collection.includes(collection.name)) {\n data.collection = [...data.collection, collection.name]\n }\n return data\n })\n )\n }\n\n // next match by \"collection\" key, but only push if the files haven't been added through pattern matching first\n matches.push.apply(\n matches,\n Object.values(files).filter((file) => {\n const patternMatched = matches.includes(file)\n const isInCollection = Array.isArray(file.collection)\n ? file.collection.includes(collection.name)\n : file.collection === collection.name\n return !patternMatched && isInCollection\n })\n )\n\n if (Object.prototype.hasOwnProperty.call(metadata, name)) {\n debug('Warning: overwriting previously set metadata property %s', name)\n }\n // apply sort, reverse, filter, limit options in this order\n metadata[name] = matches.sort(sortBy)\n\n if (reverse) {\n metadata[name].reverse()\n }\n\n metadata[name] = metadata[name].filter(filterBy).slice(0, limit)\n\n if (collection.metadata) {\n metadata[name].metadata = collection.metadata\n }\n if (refer) {\n if (reverse) {\n metadata[name].forEach((file, i) => {\n Object.assign(file, {\n next: i > 0 ? metadata[name][i - 1] : null,\n previous: i < metadata[name].length - 1 ? metadata[name][i + 1] : null\n })\n })\n } else {\n metadata[name].forEach((file, i) => {\n Object.assign(file, {\n previous: i > 0 ? metadata[name][i - 1] : null,\n next: i < metadata[name].length - 1 ? metadata[name][i + 1] : null\n })\n })\n }\n }\n\n metadata.collections[name] = metadata[name]\n debug('Added %s files to collection %s', metadata[name].length, name)\n })\n done()\n }\n}\n\ncollections.defaults = defaultOptions\n\nexport default collections\n"],"names":["sortBy","key","getKey","x","includes","get","defaultSort","a","b","defaultFilter","defaultOptions","pattern","reverse","metadata","limit","Infinity","refer","filterBy","normalizeOptions","options","config","normalized","Array","isArray","Object","assign","loadMetadata","collections","collectionNames","keys","mappedCollections","map","name","files","metalsmith","done","fileNames","debug","forEach","filePath","file","path","collection","push","length","join","matches","apply","match","filepath","data","values","filter","patternMatched","isInCollection","prototype","hasOwnProperty","call","sort","slice","i","next","previous","defaults"],"mappings":"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"}