@chrisburnell/eleventy-cache-webmentions 1.1.5 → 1.2.0

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
@@ -8,8 +8,8 @@ I wrote a quicker and simpler guide to getting this Eleventy plugin working that
8
8
 
9
9
  ## Installation
10
10
 
11
- - **With npm:** `npm install @chrisburnell/eleventy-cache-webmentions`
12
- - **Direct download:** [https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip](https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip)
11
+ - **With npm:** `npm install @chrisburnell/eleventy-cache-webmentions`
12
+ - **Direct download:** [https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip](https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip)
13
13
 
14
14
  Once installed there are **two** more **required** set-up steps:
15
15
 
@@ -21,12 +21,12 @@ Inside your Eleventy config file (typically `.eleventy.js`), use `addPlugin`:
21
21
  const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
22
22
 
23
23
  module.exports = function (eleventyConfig) {
24
- eleventyConfig.addPlugin(pluginWebmentions, {
25
- // these 3 fields are all required!
26
- domain: "https://example.com",
27
- feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
28
- key: "children",
29
- })
24
+ eleventyConfig.addPlugin(pluginWebmentions, {
25
+ // these 3 fields are all required!
26
+ domain: "https://example.com",
27
+ feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
28
+ key: "children",
29
+ })
30
30
  }
31
31
  ```
32
32
 
@@ -38,51 +38,51 @@ Advanced control over how the Webmentions are cached and processed is done by pa
38
38
  const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
39
39
 
40
40
  module.exports = function (eleventyConfig) {
41
- eleventyConfig.addPlugin(pluginWebmentions, {
42
- // domain: required or the plugin will not function
43
- // this is the website that you want to pull in Webmentions for
44
- domain: "https://example.com",
45
- // feed: required or the plugin will not function
46
- // defines the URL of your Webmention server where a feed of Webmentions for your domain can be found
47
- feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
48
- // key: required or the plugin will not function
49
- // dictates the key inside the feed where the array of Webmentions is located
50
- key: "children",
51
- // directory: ".cache" by default
52
- // see https://www.11ty.dev/docs/plugins/cache/#cache-directory for more info
53
- directory: ".cache",
54
- // duration: "1d" by default
55
- // see https://www.11ty.dev/docs/plugins/cache/#change-the-cache-duration for more info
56
- duration: "1d",
57
- // uniquekey: "webmentions" by default
58
- // dictates the name sent to eleventy-fetch to name the file
59
- uniqueKey: "webmentions",
60
- // allowedHTML: Object by default
61
- // see https://www.npmjs.com/package/sanitize-html for more info
62
- allowedHTML: {
63
- allowedTags: ["b", "i", "em", "strong", "a"],
64
- allowedAttributes: {
65
- a: ["href"],
66
- },
67
- },
68
- // allowlist: [] by default
69
- // array of root URLs from which webmentions are wanted exclusively
70
- allowlist: [],
71
- // blocklist: [] by default
72
- // array of root URLs from which webmentions are not wanted
73
- // exclusively
74
- blocklist: [],
75
- // urlReplacements: {} by default
76
- // object of key:value pairs containing from:to URL replacements
77
- urlReplacements: {},
78
- // maximumHtmlLength: 2000 by default
79
- // number of characters in the HTML content at which a different
80
- // message is shown instead of the content
81
- maximumHtmlLength: 2000,
82
- // maximumHtmlText: "mentioned this in" by default
83
- // message shown when maximumHtmlLength is reached
84
- maximumHtmlText: "mentioned this in",
85
- })
41
+ eleventyConfig.addPlugin(pluginWebmentions, {
42
+ // domain: required or the plugin will not function
43
+ // this is the website that you want to pull in Webmentions for
44
+ domain: "https://example.com",
45
+ // feed: required or the plugin will not function
46
+ // defines the URL of your Webmention server where a feed of Webmentions for your domain can be found
47
+ feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
48
+ // key: required or the plugin will not function
49
+ // dictates the key inside the feed where the array of Webmentions is located
50
+ key: "children",
51
+ // directory: ".cache" by default
52
+ // see https://www.11ty.dev/docs/plugins/cache/#cache-directory for more info
53
+ directory: ".cache",
54
+ // duration: "1d" by default
55
+ // see https://www.11ty.dev/docs/plugins/cache/#change-the-cache-duration for more info
56
+ duration: "1d",
57
+ // uniquekey: "webmentions" by default
58
+ // dictates the name sent to eleventy-fetch to name the file
59
+ uniqueKey: "webmentions",
60
+ // allowedHTML: Object by default
61
+ // see https://www.npmjs.com/package/sanitize-html for more info
62
+ allowedHTML: {
63
+ allowedTags: ["b", "i", "em", "strong", "a"],
64
+ allowedAttributes: {
65
+ a: ["href"],
66
+ },
67
+ },
68
+ // allowlist: [] by default
69
+ // array of root URLs from which webmentions are wanted exclusively
70
+ allowlist: [],
71
+ // blocklist: [] by default
72
+ // array of root URLs from which webmentions are not wanted
73
+ // exclusively
74
+ blocklist: [],
75
+ // urlReplacements: {} by default
76
+ // object of key:value pairs containing from:to URL replacements
77
+ urlReplacements: {},
78
+ // maximumHtmlLength: 2000 by default
79
+ // number of characters in the HTML content at which a different
80
+ // message is shown instead of the content
81
+ maximumHtmlLength: 2000,
82
+ // maximumHtmlText: "mentioned this in" by default
83
+ // message shown when maximumHtmlLength is reached
84
+ maximumHtmlText: "mentioned this in",
85
+ })
86
86
  }
87
87
  ```
88
88
 
@@ -92,9 +92,9 @@ Accessing the plugin in JavaScript in the way shown below will give you an Objec
92
92
 
93
93
  ```javascript
94
94
  const Webmentions = require("@chrisburnell/eleventy-cache-webmentions")(null, {
95
- domain: "https://example.com",
96
- feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
97
- key: "children",
95
+ domain: "https://example.com",
96
+ feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
97
+ key: "children",
98
98
  })
99
99
 
100
100
  const webmentionsByUrl = await Webmentions()
@@ -104,28 +104,28 @@ This can prove to be very useful when building out your pages. Using [Eleventy
104
104
 
105
105
  ```javascript
106
106
  const Webmentions = require("@chrisburnell/eleventy-cache-webmentions")(null, {
107
- domain: "https://example.com",
108
- feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
109
- key: "children",
107
+ domain: "https://example.com",
108
+ feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
109
+ key: "children",
110
110
  })
111
111
 
112
112
  module.exports = async () => {
113
- const webmentionsByUrl = await Webmentions()
114
-
115
- return {
116
- eleventyComputed: {
117
- webmentions: (data) => {
118
- const webmentionsForUrl = webmentionsByUrl["https://example.com" + data.page.url] || []
119
-
120
- if (webmentionsForUrl.length) {
121
- return webmentionsForUrl.sort((a, b) => {
122
- return (b.data.published || b.verified_date) - (a.data.published || a.verified_date)
123
- })
124
- }
125
- return []
126
- },
127
- },
128
- }
113
+ const webmentionsByUrl = await Webmentions()
114
+
115
+ return {
116
+ eleventyComputed: {
117
+ webmentions: (data) => {
118
+ const webmentionsForUrl = webmentionsByUrl["https://example.com" + data.page.url] || []
119
+
120
+ if (webmentionsForUrl.length) {
121
+ return webmentionsForUrl.sort((a, b) => {
122
+ return (b.data.published || b.verified_date) - (a.data.published || a.verified_date)
123
+ })
124
+ }
125
+ return []
126
+ },
127
+ },
128
+ }
129
129
  }
130
130
  ```
131
131
 
@@ -133,11 +133,11 @@ You can now use this data in a number of useful ways, not limited to things like
133
133
 
134
134
  ```javascript
135
135
  module.exports = (eleventyConfig) => {
136
- eleventyConfig.addCollection("popular", (collection) => {
137
- return collection.sort((a, b) => {
138
- return b.data.webmentions.length - a.data.webmentions.length
136
+ eleventyConfig.addCollection("popular", (collection) => {
137
+ return collection.sort((a, b) => {
138
+ return b.data.webmentions.length - a.data.webmentions.length
139
+ })
139
140
  })
140
- })
141
141
  }
142
142
  ```
143
143
 
@@ -166,7 +166,7 @@ And, if you need it, the entire Object of sorted Webmentions is available too:
166
166
 
167
167
  ```twig
168
168
  {% raw %}{% set count = 0 %}
169
- {% for url, array in webmentions %}
169
+ {% for url, array in webmentionsAll %}
170
170
  {% set count = array.length + count %}
171
171
  {% endfor %}
172
172
  <p>This site has received {{ count }} Webmentions!</p>{% endraw %}
@@ -190,11 +190,11 @@ WEBMENTION_IO_TOKEN=njJql0lKXnotreal4x3Wmd
190
190
  const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
191
191
 
192
192
  module.exports = function (eleventyConfig) {
193
- eleventyConfig.addPlugin(pluginWebmentions, {
194
- domain: "https://example.com",
195
- feed: `https://webmention.io/api/mentions.jf2?domain=example.com&per-page=9001&token=${process.env.WEBMENTION_IO_TOKEN}`,
196
- key: "children",
197
- })
193
+ eleventyConfig.addPlugin(pluginWebmentions, {
194
+ domain: "https://example.com",
195
+ feed: `https://webmention.io/api/mentions.jf2?domain=example.com&per-page=9001&token=${process.env.WEBMENTION_IO_TOKEN}`,
196
+ key: "children",
197
+ })
198
198
  }
199
199
  ```
200
200
 
@@ -216,11 +216,11 @@ GO_JAMMING_TOKEN=njJql0lKXnotreal4x3Wmd
216
216
  const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
217
217
 
218
218
  module.exports = function (eleventyConfig) {
219
- eleventyConfig.addPlugin(pluginWebmentions, {
220
- domain: "https://example.com",
221
- feed: `https://jam.example.com/webmention/example.com/${process.env.GO_JAMMING_TOKEN}`,
222
- key: "json",
223
- })
219
+ eleventyConfig.addPlugin(pluginWebmentions, {
220
+ domain: "https://example.com",
221
+ feed: `https://jam.example.com/webmention/example.com/${process.env.GO_JAMMING_TOKEN}`,
222
+ key: "json",
223
+ })
224
224
  }
225
225
  ```
226
226
 
@@ -7,7 +7,9 @@ const absoluteURL = (url, domain) => {
7
7
  try {
8
8
  return new URL(url, domain).toString()
9
9
  } catch (e) {
10
- console.log(`Trying to convert ${url} to be an absolute url with base ${domain} and failed.`)
10
+ console.log(
11
+ `Trying to convert ${url} to be an absolute url with base ${domain} and failed.`
12
+ )
11
13
  return url
12
14
  }
13
15
  }
@@ -19,10 +21,13 @@ const baseUrl = (url) => {
19
21
  }
20
22
 
21
23
  const fixUrl = (url, urlReplacements) => {
22
- return Object.entries(urlReplacements).reduce((accumulator, [key, value]) => {
23
- const regex = new RegExp(key, "g")
24
- return accumulator.replace(regex, value)
25
- }, url)
24
+ return Object.entries(urlReplacements).reduce(
25
+ (accumulator, [key, value]) => {
26
+ const regex = new RegExp(key, "g")
27
+ return accumulator.replace(regex, value)
28
+ },
29
+ url
30
+ )
26
31
  }
27
32
 
28
33
  const hostname = (value) => {
@@ -38,15 +43,30 @@ const epoch = (value) => {
38
43
  }
39
44
 
40
45
  const getPublished = (webmention) => {
41
- return webmention["wm-received"] || webmention?.["data"]["published"] || webmention["verified_date"] || webmention["published"]
46
+ return (
47
+ webmention["wm-received"] ||
48
+ webmention?.["data"]["published"] ||
49
+ webmention["verified_date"] ||
50
+ webmention["published"]
51
+ )
42
52
  }
43
53
 
44
54
  const getContent = (webmention) => {
45
- return webmention?.["content"]?.["html"] || webmention?.["content"] || webmention?.["data"]?.["content"] || ""
55
+ return (
56
+ webmention?.["content"]?.["html"] ||
57
+ webmention?.["content"] ||
58
+ webmention?.["data"]?.["content"] ||
59
+ ""
60
+ )
46
61
  }
47
62
 
48
63
  const getSource = (webmention) => {
49
- return webmention["url"] || webmention?.["data"]["url"] || webmention["wm-source"] || webmention["source"]
64
+ return (
65
+ webmention["url"] ||
66
+ webmention?.["data"]["url"] ||
67
+ webmention["wm-source"] ||
68
+ webmention["source"]
69
+ )
50
70
  }
51
71
 
52
72
  const getTarget = (webmention) => {
@@ -54,7 +74,11 @@ const getTarget = (webmention) => {
54
74
  }
55
75
 
56
76
  const getType = (webmention) => {
57
- return webmention["wm-property"] || webmention?.["activity"]["type"] || webmention["type"]
77
+ return (
78
+ webmention["wm-property"] ||
79
+ webmention?.["activity"]["type"] ||
80
+ webmention["type"]
81
+ )
58
82
  }
59
83
 
60
84
  const defaults = {
@@ -74,19 +98,27 @@ const defaults = {
74
98
 
75
99
  const fetchWebmentions = async (options) => {
76
100
  if (!options.domain) {
77
- throw new Error("domain is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
101
+ throw new Error(
102
+ "domain is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information."
103
+ )
78
104
  }
79
105
 
80
106
  if (!options.feed) {
81
- throw new Error("feed is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
107
+ throw new Error(
108
+ "feed is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information."
109
+ )
82
110
  }
83
111
 
84
112
  if (!options.key) {
85
- throw new Error("key is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
113
+ throw new Error(
114
+ "key is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information."
115
+ )
86
116
  }
87
117
 
88
118
  if (!options.uniqueKey) {
89
- throw new Error("uniqueKey is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
119
+ throw new Error(
120
+ "uniqueKey is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information."
121
+ )
90
122
  }
91
123
 
92
124
  let asset = new AssetCache(options.uniqueKey, options.directory)
@@ -103,16 +135,27 @@ const fetchWebmentions = async (options) => {
103
135
  // results since the most recent webmention
104
136
  if (!asset.isCacheValid(options.duration)) {
105
137
  const since = webmentions.length ? getPublished(webmentions[0]) : false
106
- const url = `${options.feed}${since ? `${options.feed.includes("?") ? "&" : "?"}since=${since}` : ""}`
138
+ const url = `${options.feed}${
139
+ since
140
+ ? `${options.feed.includes("?") ? "&" : "?"}since=${since}`
141
+ : ""
142
+ }`
107
143
  await fetch(url)
108
144
  .then(async (response) => {
109
145
  if (response.ok) {
110
146
  const feed = await response.json()
111
147
  if (feed[options.key].length) {
112
- webmentions = uniqBy([...feed[options.key], ...webmentions], (entry) => {
113
- return getSource(entry)
114
- })
115
- console.log(`[${hostname(options.domain)}] ${feed[options.key].length} new Webmentions fetched into cache.`)
148
+ webmentions = uniqBy(
149
+ [...feed[options.key], ...webmentions],
150
+ (entry) => {
151
+ return getSource(entry)
152
+ }
153
+ )
154
+ console.log(
155
+ `[${hostname(options.domain)}] ${
156
+ feed[options.key].length
157
+ } new Webmentions fetched into cache.`
158
+ )
116
159
  }
117
160
  await asset.save(webmentions, "json")
118
161
  return webmentions
@@ -120,7 +163,14 @@ const fetchWebmentions = async (options) => {
120
163
  return Promise.reject(response)
121
164
  })
122
165
  .catch((error) => {
123
- console.log(`[${hostname(options.domain)}] Something went wrong with your request to ${hostname(options.feed)}!`, error)
166
+ console.log(
167
+ `[${hostname(
168
+ options.domain
169
+ )}] Something went wrong with your request to ${hostname(
170
+ options.feed
171
+ )}!`,
172
+ error
173
+ )
124
174
  })
125
175
  }
126
176
 
@@ -168,8 +218,12 @@ const filteredWebmentions = async (options) => {
168
218
  // Fix local URLs based on urlReplacements and sort Webmentions into groups
169
219
  // by target base URL
170
220
  rawWebmentions.forEach((webmention) => {
171
- let url = baseUrl(fixUrl(getTarget(webmention).replace(/\/?$/, "/"), options.urlReplacements))
172
-
221
+ let url = baseUrl(
222
+ fixUrl(
223
+ getTarget(webmention).replace(/\/?$/, "/"),
224
+ options.urlReplacements
225
+ )
226
+ )
173
227
 
174
228
  if (!filtered[url]) {
175
229
  filtered[url] = []
@@ -200,7 +254,10 @@ const getWebmentions = async (options, url, allowedTypes = {}) => {
200
254
  webmentions[url]
201
255
  // filter webmentions by allowed response post types
202
256
  .filter((entry) => {
203
- return typeof allowedTypes === "object" && Object.keys(allowedTypes).length ? allowedTypes.includes(getType(entry)) : true
257
+ return typeof allowedTypes === "object" &&
258
+ Object.keys(allowedTypes).length
259
+ ? allowedTypes.includes(getType(entry))
260
+ : true
204
261
  })
205
262
  // sanitize content of webmentions against HTML limit
206
263
  .map((entry) => {
@@ -209,7 +266,9 @@ const getWebmentions = async (options, url, allowedTypes = {}) => {
209
266
  if (html.length) {
210
267
  entry.content = sanitizeHTML(html, options.allowedHTML)
211
268
  if (html.length > options.maximumHtmlLength) {
212
- entry.content = `${options.maximumHtmlText} <a href="${getSource(entry)}">${getSource(entry)}</a>`
269
+ entry.content = `${
270
+ options.maximumHtmlText
271
+ } <a href="${getSource(entry)}">${getSource(entry)}</a>`
213
272
  }
214
273
  }
215
274
 
@@ -236,13 +295,26 @@ module.exports = (eleventyConfig, options = {}) => {
236
295
 
237
296
  if (eleventyConfig) {
238
297
  // Global Data
239
- eleventyConfig.addGlobalData("webmentions", filteredWebmentions(options))
298
+ const filtered = async () => await filteredWebmentions(options)
299
+ eleventyConfig.addGlobalData("webmentionsByUrl", filtered)
300
+ const unfiltered = async () =>
301
+ await filteredWebmentions(options).then((filtered) =>
302
+ Object.values(filtered).reduce(
303
+ (array, webmentions) => [...array, ...webmentions],
304
+ []
305
+ )
306
+ )
307
+ eleventyConfig.addGlobalData("webmentionsAll", unfiltered)
308
+ eleventyConfig.addGlobalData("webmentions", unfiltered)
240
309
 
241
310
  // Liquid Filter
242
311
  eleventyConfig.addLiquidFilter("getWebmentions", getWebmentionsFilter)
243
312
 
244
313
  // Nunjucks Filter
245
- eleventyConfig.addNunjucksAsyncFilter("getWebmentions", getWebmentionsFilter)
314
+ eleventyConfig.addNunjucksAsyncFilter(
315
+ "getWebmentions",
316
+ getWebmentionsFilter
317
+ )
246
318
  }
247
319
 
248
320
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrisburnell/eleventy-cache-webmentions",
3
- "version": "1.1.5",
3
+ "version": "1.2.0",
4
4
  "description": "Fetch and cache webmentions using eleventy-fetch.",
5
5
  "author": "Chris Burnell <me@chrisburnell.com>",
6
6
  "license": "MIT",
@@ -20,13 +20,13 @@
20
20
  "webmention"
21
21
  ],
22
22
  "devDependencies": {
23
- "eslint": "^8.7.0"
23
+ "eslint": "^8.41.0"
24
24
  },
25
25
  "dependencies": {
26
- "@11ty/eleventy-fetch": "^3.0.0",
26
+ "@11ty/eleventy-fetch": "^4.0.0",
27
27
  "lodash": "^4.17.21",
28
- "node-fetch": "^2.6.5",
29
- "sanitize-html": "^2.7.1"
28
+ "node-fetch": "^3.3.1",
29
+ "sanitize-html": "^2.10.0"
30
30
  },
31
31
  "main": "eleventy-cache-webmentions.js",
32
32
  "scripts": {