@metalsmith/collections 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,9 +36,12 @@ yarn add @metalsmith/collections
36
36
  Pass options to `@metalsmith/collections` in the plugin chain:
37
37
 
38
38
  ```js
39
- const Metalsmith = require('metalsmith')
40
- const markdown = require('@metalsmith/markdown')
41
- const collections = require('@metalsmith/collections')
39
+ import Metalsmith from 'metalsmith'
40
+ import markdown from '@metalsmith/markdown'
41
+ import collections from '@metalsmith/collections'
42
+ import { dirname } from 'path'
43
+
44
+ const __dirname = dirname(new URL(import.meta.url).pathname)
42
45
 
43
46
  // defaults, only create collections based on file metadata
44
47
  Metalsmith(__dirname)
package/lib/index.cjs ADDED
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ var get = require('lodash.get');
4
+ var readMetadata = require('read-metadata');
5
+
6
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
+
8
+ var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
9
+
10
+ function sortBy(key) {
11
+ let getKey = x => x[key];
12
+
13
+ if (key.includes('.')) {
14
+ getKey = x => get__default["default"](x, key);
15
+ }
16
+
17
+ return function defaultSort(a, b) {
18
+ a = getKey(a);
19
+ b = getKey(b);
20
+ if (!a && !b) return 0;
21
+ if (!a) return -1;
22
+ if (!b) return 1;
23
+ if (b > a) return -1;
24
+ if (a > b) return 1;
25
+ return 0;
26
+ };
27
+ } // for backwards-compatibility only, date makes as little sense as "pubdate" or any custom key
28
+
29
+
30
+ const defaultSort = sortBy('date');
31
+
32
+ const defaultFilter = () => true;
33
+ /**
34
+ * @typedef {Object} CollectionConfig
35
+ * @property {string|string[]} [pattern] - One or more glob patterns to match files to a collection
36
+ * @property {string|(a,b) => 0|1|-1} [sortBy] - A key to sort by (e.g. `date`,`title`, ..) or a custom sort function
37
+ * @property {number} [limit] - Limit the amount of items in a collection to `limit`
38
+ * @property {boolean} [refer] - Adds `next` and `previous` keys to file metadata of matched files
39
+ * @property {boolean} [reverse] - Whether to invert the sorting function results (asc/descending)
40
+ * @property {Function} [filterBy] - A function that gets a `Metalsmith.File` as first argument and returns `true` for every file to include in the collection
41
+ * @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`)
42
+ */
43
+
44
+ /** @type {CollectionConfig} */
45
+
46
+
47
+ const defaultOptions = {
48
+ pattern: null,
49
+ reverse: false,
50
+ metadata: null,
51
+ limit: Infinity,
52
+ refer: true,
53
+ sortBy: defaultSort,
54
+ filterBy: defaultFilter
55
+ };
56
+ /**
57
+ * Normalize options
58
+ * @param {Object.<string,CollectionConfig>} options
59
+ */
60
+
61
+ function normalizeOptions(options) {
62
+ options = options || {};
63
+
64
+ for (const config in options) {
65
+ let normalized = options[config];
66
+
67
+ if (typeof normalized === 'string' || Array.isArray(normalized)) {
68
+ normalized = {
69
+ pattern: normalized
70
+ };
71
+ }
72
+
73
+ normalized = Object.assign({}, defaultOptions, normalized);
74
+
75
+ if (typeof normalized.metadata === 'string') {
76
+ normalized.metadata = readMetadata.sync(normalized.metadata);
77
+ }
78
+
79
+ if (typeof normalized.sortBy === 'string') {
80
+ normalized.sortBy = sortBy(normalized.sortBy);
81
+ }
82
+
83
+ options[config] = normalized;
84
+ }
85
+
86
+ return options;
87
+ }
88
+ /**
89
+ * Add `collections` of files to the global metadata as a sorted array.
90
+ * @example
91
+ * metalsmith.use(collections({
92
+ * posts: 'posts/*.md',
93
+ * portfolio: {
94
+ * pattern: 'portfolio/*.md',
95
+ * metadata: { title: 'My portfolio' },
96
+ * sortBy: 'order'
97
+ * }
98
+ * }))
99
+ *
100
+ * @param {Object.<string,CollectionConfig|string>} options
101
+ * @return {import('metalsmith').Plugin}
102
+ */
103
+
104
+
105
+ function collections(options) {
106
+ options = normalizeOptions(options);
107
+ const collectionNames = Object.keys(options);
108
+ const mappedCollections = collectionNames.map(name => {
109
+ return Object.assign({
110
+ name: name
111
+ }, options[name]);
112
+ });
113
+ return function collections(files, metalsmith, done) {
114
+ const metadata = metalsmith.metadata();
115
+ const fileNames = Object.keys(files);
116
+ const debug = metalsmith.debug('@metalsmith/collections');
117
+ metadata.collections = {};
118
+ fileNames.forEach(filePath => {
119
+ // add path property to file metadata for convenience
120
+ // this is for backward-compatibility only and is pretty useless
121
+ const file = files[filePath];
122
+ file.path = file.path || filePath; // dynamically add collections with default options when encountered in file metadata,
123
+ // and not explicitly defined in plugin options
124
+
125
+ if (file.collection) {
126
+ (Array.isArray(file.collection) ? file.collection : [file.collection]).forEach(name => {
127
+ if (!collectionNames.includes(name)) {
128
+ collectionNames.push(name);
129
+ const normalized = Object.assign({}, defaultOptions);
130
+ mappedCollections.push(Object.assign({
131
+ name
132
+ }, normalized));
133
+ }
134
+ });
135
+ }
136
+ });
137
+ debug('Identified %s collections: %s', mappedCollections.length, collectionNames.join());
138
+ mappedCollections.forEach(collection => {
139
+ const {
140
+ pattern,
141
+ filterBy,
142
+ sortBy,
143
+ reverse,
144
+ refer,
145
+ limit
146
+ } = collection;
147
+ const name = collection.name;
148
+ const matches = [];
149
+ debug('Processing collection %s with options %s:', name, collection); // first match by pattern if provided
150
+
151
+ if (pattern) {
152
+ matches.push.apply(matches, metalsmith.match(pattern, fileNames).map(filepath => {
153
+ const data = files[filepath]; // pattern-matched files might or might not have a "collection" property defined in front-matter
154
+ // and might also be included in multiple collections
155
+
156
+ if (!data.collection) {
157
+ data.collection = [];
158
+ } else if (typeof data.collection === 'string') {
159
+ data.collection = [data.collection];
160
+ }
161
+
162
+ if (!data.collection.includes(collection.name)) {
163
+ data.collection = [...data.collection, collection.name];
164
+ }
165
+
166
+ return data;
167
+ }));
168
+ } // next match by "collection" key, but only push if the files haven't been added through pattern matching first
169
+
170
+
171
+ matches.push.apply(matches, Object.values(files).filter(file => {
172
+ const patternMatched = matches.includes(file);
173
+ const isInCollection = Array.isArray(file.collection) ? file.collection.includes(collection.name) : file.collection === collection.name;
174
+ return !patternMatched && isInCollection;
175
+ }));
176
+
177
+ if (Object.prototype.hasOwnProperty.call(metadata, name)) {
178
+ debug('Warning: overwriting previously set metadata property %s', name);
179
+ } // apply sort, reverse, filter, limit options in this order
180
+
181
+
182
+ metadata[name] = matches.sort(sortBy);
183
+
184
+ if (reverse) {
185
+ metadata[name].reverse();
186
+ }
187
+
188
+ metadata[name] = metadata[name].filter(filterBy).slice(0, limit);
189
+
190
+ if (collection.metadata) {
191
+ metadata[name].metadata = collection.metadata;
192
+ }
193
+
194
+ if (refer) {
195
+ if (reverse) {
196
+ metadata[name].forEach((file, i) => {
197
+ Object.assign(file, {
198
+ next: i > 0 ? metadata[name][i - 1] : null,
199
+ previous: i < metadata[name].length - 1 ? metadata[name][i + 1] : null
200
+ });
201
+ });
202
+ } else {
203
+ metadata[name].forEach((file, i) => {
204
+ Object.assign(file, {
205
+ previous: i > 0 ? metadata[name][i - 1] : null,
206
+ next: i < metadata[name].length - 1 ? metadata[name][i + 1] : null
207
+ });
208
+ });
209
+ }
210
+ }
211
+
212
+ metadata.collections[name] = metadata[name];
213
+ debug('Added %s files to collection %s', metadata[name].length, name);
214
+ });
215
+ done();
216
+ };
217
+ }
218
+
219
+ collections.defaults = defaultOptions;
220
+
221
+ module.exports = collections;
222
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"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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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ import Metalsmith from "metalsmith";
2
+
3
+ export default collections;
4
+ export type CollectionConfig = {
5
+ /**
6
+ * - One or more glob patterns to match files to a collection
7
+ */
8
+ pattern?: string | string[] | null;
9
+ /**
10
+ * - A key to sort by (e.g. `date`,`title`, ..) or a custom sort function
11
+ */
12
+ sortBy?: string | ((a: any, b: any) => 0 | 1 | -1);
13
+ /**
14
+ * - Limit the amount of items in a collection to `limit`
15
+ */
16
+ limit?: number;
17
+ /**
18
+ * - Adds `next` and `previous` keys to file metadata of matched files
19
+ */
20
+ refer?: boolean;
21
+ /**
22
+ * - Whether to invert the sorting function results (asc/descending)
23
+ */
24
+ reverse?: boolean;
25
+ /**
26
+ * - A function that gets a `Metalsmith.File` as first argument and returns `true` for every file to include in the collection
27
+ */
28
+ filterBy?: Function;
29
+ /**
30
+ * - An object with metadata to attach to the collection, or a `json`/`yaml`filepath string to load data from (relative to `Metalsmith.directory`)
31
+ */
32
+ metadata?: any | string | null;
33
+ };
34
+ /**
35
+ * Add `collections` of files to the global metadata as a sorted array.
36
+ * @example
37
+ * metalsmith.use(collections({
38
+ * posts: 'posts/*.md',
39
+ * portfolio: {
40
+ * pattern: 'portfolio/*.md',
41
+ * metadata: { title: 'My portfolio' },
42
+ * sortBy: 'order'
43
+ * }
44
+ * }))
45
+ *
46
+ * @param {Object.<string,CollectionConfig|string>} options
47
+ */
48
+ declare function collections(options: {
49
+ [x: string]: CollectionConfig | string;
50
+ }): Metalsmith.Plugin;
51
+ declare namespace collections {
52
+ export { defaultOptions as defaults };
53
+ }
54
+
55
+ declare const defaultOptions: CollectionConfig;
package/lib/index.js CHANGED
@@ -1,22 +1,43 @@
1
- const debug = require('debug')('@metalsmith/collections')
2
- const loadMetadata = require('read-metadata').sync
3
- const get = require('lodash.get')
4
- // for backwards-compatibility only, date makes as little sense as "pubdate" or any custom key
5
- const defaultSort = sortBy('date')
6
- const defaultFilter = () => true
1
+ import get from 'lodash.get';
2
+ import { sync } from 'read-metadata';
7
3
 
4
+ function sortBy(key) {
5
+ let getKey = x => x[key];
6
+
7
+ if (key.includes('.')) {
8
+ getKey = x => get(x, key);
9
+ }
10
+
11
+ return function defaultSort(a, b) {
12
+ a = getKey(a);
13
+ b = getKey(b);
14
+ if (!a && !b) return 0;
15
+ if (!a) return -1;
16
+ if (!b) return 1;
17
+ if (b > a) return -1;
18
+ if (a > b) return 1;
19
+ return 0;
20
+ };
21
+ } // for backwards-compatibility only, date makes as little sense as "pubdate" or any custom key
22
+
23
+
24
+ const defaultSort = sortBy('date');
25
+
26
+ const defaultFilter = () => true;
8
27
  /**
9
28
  * @typedef {Object} CollectionConfig
10
- * @property {string|string[]} pattern - One or more glob patterns to match files to a collection
11
- * @property {string|(a,b) => 0|1|-1} sortBy - A key to sort by (e.g. `date`,`title`, ..) or a custom sort function
12
- * @property {number} limit - Limit the amount of items in a collection to `limit`
13
- * @property {boolean} refer - Adds `next` and `previous` keys to file metadata of matched files
14
- * @property {boolean} reverse - Whether to invert the sorting function results (asc/descending)
15
- * @property {Function} filterBy - A function that gets a `Metalsmith.File` as first argument and returns `true` for every file to include in the collection
16
- * @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`)
29
+ * @property {string|string[]} [pattern] - One or more glob patterns to match files to a collection
30
+ * @property {string|(a,b) => 0|1|-1} [sortBy] - A key to sort by (e.g. `date`,`title`, ..) or a custom sort function
31
+ * @property {number} [limit] - Limit the amount of items in a collection to `limit`
32
+ * @property {boolean} [refer] - Adds `next` and `previous` keys to file metadata of matched files
33
+ * @property {boolean} [reverse] - Whether to invert the sorting function results (asc/descending)
34
+ * @property {Function} [filterBy] - A function that gets a `Metalsmith.File` as first argument and returns `true` for every file to include in the collection
35
+ * @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`)
17
36
  */
18
37
 
19
38
  /** @type {CollectionConfig} */
39
+
40
+
20
41
  const defaultOptions = {
21
42
  pattern: null,
22
43
  reverse: false,
@@ -25,170 +46,171 @@ const defaultOptions = {
25
46
  refer: true,
26
47
  sortBy: defaultSort,
27
48
  filterBy: defaultFilter
28
- }
29
-
30
- function sortBy(key) {
31
- let getKey = (x) => x[key]
32
- if (key.includes('.')) {
33
- getKey = (x) => get(x, key)
34
- }
35
- return function defaultSort(a, b) {
36
- a = getKey(a)
37
- b = getKey(b)
38
- if (!a && !b) return 0
39
- if (!a) return -1
40
- if (!b) return 1
41
- if (b > a) return -1
42
- if (a > b) return 1
43
- return 0
44
- }
45
- }
46
-
49
+ };
47
50
  /**
48
51
  * Normalize options
49
52
  * @param {Object.<string,CollectionConfig>} options
50
53
  */
54
+
51
55
  function normalizeOptions(options) {
52
- options = options || {}
56
+ options = options || {};
53
57
 
54
58
  for (const config in options) {
55
- let normalized = options[config]
59
+ let normalized = options[config];
60
+
56
61
  if (typeof normalized === 'string' || Array.isArray(normalized)) {
57
- normalized = { pattern: normalized }
62
+ normalized = {
63
+ pattern: normalized
64
+ };
58
65
  }
59
- normalized = Object.assign({}, defaultOptions, normalized)
66
+
67
+ normalized = Object.assign({}, defaultOptions, normalized);
68
+
60
69
  if (typeof normalized.metadata === 'string') {
61
- normalized.metadata = loadMetadata(normalized.metadata)
70
+ normalized.metadata = sync(normalized.metadata);
62
71
  }
72
+
63
73
  if (typeof normalized.sortBy === 'string') {
64
- normalized.sortBy = sortBy(normalized.sortBy)
74
+ normalized.sortBy = sortBy(normalized.sortBy);
65
75
  }
66
- options[config] = normalized
76
+
77
+ options[config] = normalized;
67
78
  }
68
79
 
69
- return options
80
+ return options;
70
81
  }
71
-
72
82
  /**
73
- * Metalsmith plugin that adds `collections` of files to the global
74
- * metadata as a sorted array.
83
+ * Add `collections` of files to the global metadata as a sorted array.
84
+ * @example
85
+ * metalsmith.use(collections({
86
+ * posts: 'posts/*.md',
87
+ * portfolio: {
88
+ * pattern: 'portfolio/*.md',
89
+ * metadata: { title: 'My portfolio' },
90
+ * sortBy: 'order'
91
+ * }
92
+ * }))
75
93
  *
76
94
  * @param {Object.<string,CollectionConfig|string>} options
77
95
  * @return {import('metalsmith').Plugin}
78
96
  */
79
- function initializeCollections(options) {
80
- options = normalizeOptions(options)
81
- const collectionNames = Object.keys(options)
82
- const mappedCollections = collectionNames.map((name) => {
83
- return Object.assign({ name: name }, options[name])
84
- })
85
97
 
86
- return function collections(files, metalsmith, done) {
87
- const metadata = metalsmith.metadata()
88
- const fileNames = Object.keys(files)
89
98
 
90
- metadata.collections = {}
91
-
92
- fileNames.forEach((filePath) => {
99
+ function collections(options) {
100
+ options = normalizeOptions(options);
101
+ const collectionNames = Object.keys(options);
102
+ const mappedCollections = collectionNames.map(name => {
103
+ return Object.assign({
104
+ name: name
105
+ }, options[name]);
106
+ });
107
+ return function collections(files, metalsmith, done) {
108
+ const metadata = metalsmith.metadata();
109
+ const fileNames = Object.keys(files);
110
+ const debug = metalsmith.debug('@metalsmith/collections');
111
+ metadata.collections = {};
112
+ fileNames.forEach(filePath => {
93
113
  // add path property to file metadata for convenience
94
114
  // this is for backward-compatibility only and is pretty useless
95
- const file = files[filePath]
96
- file.path = file.path || filePath
97
-
98
- // dynamically add collections with default options when encountered in file metadata,
115
+ const file = files[filePath];
116
+ file.path = file.path || filePath; // dynamically add collections with default options when encountered in file metadata,
99
117
  // and not explicitly defined in plugin options
118
+
100
119
  if (file.collection) {
101
- ;(Array.isArray(file.collection) ? file.collection : [file.collection]).forEach((name) => {
120
+ (Array.isArray(file.collection) ? file.collection : [file.collection]).forEach(name => {
102
121
  if (!collectionNames.includes(name)) {
103
- collectionNames.push(name)
104
- const normalized = Object.assign({}, defaultOptions)
105
- mappedCollections.push(Object.assign({ name }, normalized))
122
+ collectionNames.push(name);
123
+ const normalized = Object.assign({}, defaultOptions);
124
+ mappedCollections.push(Object.assign({
125
+ name
126
+ }, normalized));
106
127
  }
107
- })
128
+ });
108
129
  }
109
- })
130
+ });
131
+ debug('Identified %s collections: %s', mappedCollections.length, collectionNames.join());
132
+ mappedCollections.forEach(collection => {
133
+ const {
134
+ pattern,
135
+ filterBy,
136
+ sortBy,
137
+ reverse,
138
+ refer,
139
+ limit
140
+ } = collection;
141
+ const name = collection.name;
142
+ const matches = [];
143
+ debug('Processing collection %s with options %s:', name, collection); // first match by pattern if provided
110
144
 
111
- debug('Identified %s collections: %s', mappedCollections.length, collectionNames.join())
145
+ if (pattern) {
146
+ matches.push.apply(matches, metalsmith.match(pattern, fileNames).map(filepath => {
147
+ const data = files[filepath]; // pattern-matched files might or might not have a "collection" property defined in front-matter
148
+ // and might also be included in multiple collections
149
+
150
+ if (!data.collection) {
151
+ data.collection = [];
152
+ } else if (typeof data.collection === 'string') {
153
+ data.collection = [data.collection];
154
+ }
112
155
 
113
- mappedCollections.forEach((collection) => {
114
- const { pattern, filterBy, sortBy, reverse, refer, limit } = collection
115
- const name = collection.name
116
- const matches = []
117
- debug('Processing collection %s with options %s:', name, collection)
156
+ if (!data.collection.includes(collection.name)) {
157
+ data.collection = [...data.collection, collection.name];
158
+ }
159
+
160
+ return data;
161
+ }));
162
+ } // next match by "collection" key, but only push if the files haven't been added through pattern matching first
118
163
 
119
- // first match by pattern if provided
120
- if (pattern) {
121
- matches.push.apply(
122
- matches,
123
- metalsmith.match(pattern, fileNames).map((filepath) => {
124
- const data = files[filepath]
125
- // pattern-matched files might or might not have a "collection" property defined in front-matter
126
- // and might also be included in multiple collections
127
- if (!data.collection) {
128
- data.collection = []
129
- } else if (typeof data.collection === 'string') {
130
- data.collection = [data.collection]
131
- }
132
- if (!data.collection.includes(collection.name)) {
133
- data.collection = [...data.collection, collection.name]
134
- }
135
- return data
136
- })
137
- )
138
- }
139
164
 
140
- // next match by "collection" key, but only push if the files haven't been added through pattern matching first
141
- matches.push.apply(
142
- matches,
143
- Object.values(files).filter((file) => {
144
- const patternMatched = matches.includes(file)
145
- const isInCollection = Array.isArray(file.collection)
146
- ? file.collection.includes(collection.name)
147
- : file.collection === collection.name
148
- return !patternMatched && isInCollection
149
- })
150
- )
165
+ matches.push.apply(matches, Object.values(files).filter(file => {
166
+ const patternMatched = matches.includes(file);
167
+ const isInCollection = Array.isArray(file.collection) ? file.collection.includes(collection.name) : file.collection === collection.name;
168
+ return !patternMatched && isInCollection;
169
+ }));
151
170
 
152
171
  if (Object.prototype.hasOwnProperty.call(metadata, name)) {
153
- debug('Warning: overwriting previously set metadata property %s', name)
154
- }
155
- // apply sort, reverse, filter, limit options in this order
156
- metadata[name] = matches.sort(sortBy)
172
+ debug('Warning: overwriting previously set metadata property %s', name);
173
+ } // apply sort, reverse, filter, limit options in this order
174
+
175
+
176
+ metadata[name] = matches.sort(sortBy);
157
177
 
158
178
  if (reverse) {
159
- metadata[name].reverse()
179
+ metadata[name].reverse();
160
180
  }
161
181
 
162
- metadata[name] = metadata[name].filter(filterBy).slice(0, limit)
182
+ metadata[name] = metadata[name].filter(filterBy).slice(0, limit);
163
183
 
164
184
  if (collection.metadata) {
165
- metadata[name].metadata = collection.metadata
185
+ metadata[name].metadata = collection.metadata;
166
186
  }
187
+
167
188
  if (refer) {
168
189
  if (reverse) {
169
190
  metadata[name].forEach((file, i) => {
170
191
  Object.assign(file, {
171
192
  next: i > 0 ? metadata[name][i - 1] : null,
172
193
  previous: i < metadata[name].length - 1 ? metadata[name][i + 1] : null
173
- })
174
- })
194
+ });
195
+ });
175
196
  } else {
176
197
  metadata[name].forEach((file, i) => {
177
198
  Object.assign(file, {
178
199
  previous: i > 0 ? metadata[name][i - 1] : null,
179
200
  next: i < metadata[name].length - 1 ? metadata[name][i + 1] : null
180
- })
181
- })
201
+ });
202
+ });
182
203
  }
183
204
  }
184
205
 
185
- metadata.collections[name] = metadata[name]
186
- debug('Added %s files to collection %s', metadata[name].length, name)
187
- })
188
- done()
189
- }
206
+ metadata.collections[name] = metadata[name];
207
+ debug('Added %s files to collection %s', metadata[name].length, name);
208
+ });
209
+ done();
210
+ };
190
211
  }
191
212
 
192
- initializeCollections.defaults = defaultOptions
213
+ collections.defaults = defaultOptions;
193
214
 
194
- module.exports = initializeCollections
215
+ export { collections as default };
216
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","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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"}
package/package.json CHANGED
@@ -15,9 +15,18 @@
15
15
  "type": "git",
16
16
  "url": "https://github.com/metalsmith/collections.git"
17
17
  },
18
- "version": "1.2.2",
18
+ "version": "1.3.1",
19
19
  "license": "MIT",
20
- "main": "lib/index.js",
20
+ "source": "src/index.js",
21
+ "main": "lib/index.cjs",
22
+ "module": "lib/index.js",
23
+ "type": "module",
24
+ "types": "./lib/index.d.ts",
25
+ "exports": {
26
+ "types": "./lib/index.d.ts",
27
+ "import": "./lib/index.js",
28
+ "require": "./lib/index.cjs"
29
+ },
21
30
  "dependencies": {
22
31
  "lodash.get": "^4.4.2",
23
32
  "read-metadata": "^1.0.0"
@@ -25,10 +34,12 @@
25
34
  "devDependencies": {
26
35
  "auto-changelog": "^2.4.0",
27
36
  "coveralls": "^3.1.1",
28
- "debug": "^4.3.4",
29
37
  "eslint": "^8.20.0",
30
38
  "eslint-config-prettier": "^8.5.0",
31
- "metalsmith": "^2.4.1",
39
+ "eslint-plugin-import": "^2.26.0",
40
+ "eslint-plugin-node": "^11.1.0",
41
+ "metalsmith": "^2.5.0",
42
+ "microbundle": "^0.15.0",
32
43
  "mocha": "^9.2.2",
33
44
  "nodemon": "^2.0.19",
34
45
  "nyc": "^15.1.0",
@@ -44,21 +55,22 @@
44
55
  ],
45
56
  "scripts": {
46
57
  "changelog": "auto-changelog -u --starting-date 2021-12-01 --sort-commits date-desc --commit-limit false --ignore-commit-pattern '(dev|Release|Merge)'",
47
- "test": "nyc mocha",
48
58
  "coverage": "nyc report --reporter=text-lcov > ./coverage.info",
49
- "coveralls": "npm run coverage && cat ./coverage.info | coveralls",
50
59
  "format": "prettier --write \"**/*.{yml,md,js,json}\"",
51
60
  "format:check": "prettier --list-different \"**/*.{yml,md,js,json}\"",
52
61
  "lint": "eslint --fix .",
53
62
  "lint:check": "eslint --fix-dry-run .",
54
63
  "dev": "nodemon --exec 'npm test'",
55
- "release": "release-it ."
64
+ "release": "release-it .",
65
+ "build": "microbundle --target node -f cjs,esm --strict --generateTypes=false",
66
+ "pretest": "npm run build",
67
+ "test": "nyc mocha"
56
68
  },
57
69
  "publishConfig": {
58
70
  "access": "public"
59
71
  },
60
72
  "peerDependencies": {
61
- "metalsmith": "^2.4.1"
73
+ "metalsmith": "^2.5.0"
62
74
  },
63
75
  "engines": {
64
76
  "node": ">=12"
package/CHANGELOG.md DELETED
@@ -1,97 +0,0 @@
1
- ### Changelog
2
-
3
- #### [v1.2.2](https://github.com/metalsmith/collections/compare/v1.2.2...v1.2.1) / 2022-07-28
4
-
5
- - Resolves [`#102`](https://github.com/metalsmith/collections/issues/99): removes multimatch dependency, uses metalsmith.match instead
6
- - Drops support for Metalsmith < 2.4.1
7
- - Drops support for Node < 12
8
-
9
- #### [v1.2.1](https://github.com/metalsmith/collections/compare/v1.2.1...v1.2.0) / 2022-02-03
10
-
11
- - Fixes [`#99`](https://github.com/metalsmith/collections/issues/99): collection key on file metadata - no dupes, no nested arrays
12
- - Fixes regression: incorrect previous & next refs when reverse: true
13
- - Fixes typo's in README
14
-
15
- #### [v1.2.0](https://github.com/metalsmith/collections/compare/v1.2.0...v1.1.0) / 2022-01-29
16
-
17
- - Feature: sortBy now also understands nested metadata properties, e.g. `sortBy: 'meta.display.order'`
18
- - Fixed JSDoc typo that made type hints unavailable
19
- - Documented limit & refer options
20
- - Improved README.md with more elaborate examples
21
- - Refactored to cleaner code
22
- - Removed dependencies: `extend`,`uniq`
23
- - Added dependency `lodash.get`
24
- - Added core-plugin tests
25
- - Updated devDependencies release-it, prettier, eslint
26
-
27
- #### [v1.1.0](https://github.com/metalsmith/collections/compare/v1.0.0...v1.1.0) / 2021-15-12
28
-
29
- - Added standardised code formatting and QA [`#86`](https://github.com/metalsmith/collections/pull/86)
30
- - Updated History with v1 PRs [`#85`](https://github.com/metalsmith/collections/pull/85)
31
- - Added better JSDoc types, return named plugin function [`3aa3443`](https://github.com/metalsmith/collections/commit/3aa3443802c2f814c90cf39c7b43de8fc3d3ff13)
32
- - Updated multimatch to 4.0.0, debug to 4.3.3 [`71d6f65`](https://github.com/metalsmith/collections/commit/71d6f65b9ec5572196e17dfebf5cff2361853f9d)
33
-
34
- # [1.0.0][] / 2018-10-17
35
-
36
- - Fixed API and merged many PRs
37
- - Allow metadata-based filtering with `filterBy` option
38
- - removed unused module
39
- - Add documentation: `sortBy` can be a function
40
- - display only matching files when debugging
41
- - assign data.path where undefined
42
- - Clear collections
43
- - Added multiple collections syntax to Readme.md
44
-
45
- #### [0.7.0][] / 2015-02-07
46
-
47
- - Allow front matter and pattern collections.
48
- - Added the ability to limit the size of a collection
49
- - Allow collections through metadata alone
50
- - add ability to disable next/previous references
51
-
52
- #### [0.6.0][] / 2014-08-12
53
-
54
- - Added the ability to set multiple collections
55
-
56
- #### [0.5.1][] / 2014-08-05
57
-
58
- - Fixed bug with require statement
59
-
60
- #### [0.5.0][] / 2014-08-04
61
-
62
- - Added the ability to add metadata to collections
63
-
64
- #### [0.4.1][] - May 4, 2014
65
-
66
- - fix empty collections
67
-
68
- #### [0.4.0][] - March 25, 2014
69
-
70
- - add option for `sortBy` to be a sorting function
71
-
72
- #### [0.3.0][] - March 24, 2014
73
-
74
- - add `collection` property to each file for pattern matches
75
-
76
- #### [0.2.0][] - March 20, 2014
77
-
78
- - add collections dictionary to global metadata
79
-
80
- #### [0.1.0][] - March 6, 2014
81
-
82
- - add matching by pattern
83
- - add shorthand for pattern matching
84
- - add previous and next references
85
-
86
- #### [0.0.3][] - February 6, 2014
87
-
88
- - add debug statements
89
- - swap to `extend` from `defaults` to avoid cloning
90
-
91
- #### [0.0.2][] - February 6, 2014
92
-
93
- - swap to `merge` to not act on clones
94
-
95
- #### [0.0.1][] - February 5, 2014
96
-
97
- :sparkles: