@chrisburnell/eleventy-cache-webmentions 0.1.11 → 0.2.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/.prettierrc ADDED
@@ -0,0 +1,4 @@
1
+ # .prettierrc
2
+ semi: false
3
+ printWidth: 9999
4
+ tabWidth: 4
@@ -3,11 +3,6 @@ const sanitizeHTML = require("sanitize-html")
3
3
  const uniqBy = require("lodash/uniqBy")
4
4
  const { AssetCache } = require("@11ty/eleventy-fetch")
5
5
 
6
- // Load .env variables with dotenv
7
- require("dotenv").config()
8
-
9
- const TOKEN = process.env.WEBMENTION_IO_TOKEN
10
-
11
6
  const absoluteURL = (url, domain) => {
12
7
  try {
13
8
  return new URL(url, domain).toString()
@@ -42,10 +37,30 @@ const epoch = (value) => {
42
37
  return new Date(value).getTime()
43
38
  }
44
39
 
40
+ const getPublished = (webmention) => {
41
+ return webmention["wm-received"] || webmention?.["data"]["published"] || webmention["verified_date"] || webmention["published"]
42
+ }
43
+
44
+ const getContent = (webmention) => {
45
+ return webmention?.["content"]["html"] || webmention["content"] || webmention?.["data"]["content"]
46
+ }
47
+
48
+ const getSource = (webmention) => {
49
+ return webmention["url"] || webmention?.["data"]["url"] || webmention["wm-source"] || webmention["source"]
50
+ }
51
+
52
+ const getTarget = (webmention) => {
53
+ return webmention["wm-target"] || webmention["target"]
54
+ }
55
+
56
+ const getType = (webmention) => {
57
+ return webmention["wm-property"] || webmention?.["activity"]["type"] || webmention["type"]
58
+ }
59
+
45
60
  module.exports = (eleventyConfig, options = {}) => {
46
61
  options = Object.assign(
47
62
  {
48
- key: "webmentions",
63
+ uniqueKey: "webmentions",
49
64
  allowedHTML: {
50
65
  allowedTags: ["b", "i", "em", "strong", "a"],
51
66
  allowedAttributes: {
@@ -60,14 +75,10 @@ module.exports = (eleventyConfig, options = {}) => {
60
75
  )
61
76
 
62
77
  const fetchWebmentions = async () => {
63
- let asset = new AssetCache(options.uniqueKey || options.key)
78
+ let asset = new AssetCache(options.uniqueKey)
64
79
  asset.ensureDir()
65
80
 
66
- let webmentions = {
67
- type: "feed",
68
- name: "Webmentions",
69
- children: [],
70
- }
81
+ let webmentions = []
71
82
 
72
83
  // If there is a cached file at all, grab its contents now
73
84
  if (asset.isCacheValid("9001y")) {
@@ -75,25 +86,27 @@ module.exports = (eleventyConfig, options = {}) => {
75
86
  }
76
87
 
77
88
  // If there is a cached file but it is outside of expiry, fetch fresh
78
- // results since the most recent
89
+ // results since the most recent webmention
79
90
  if (!asset.isCacheValid(options.duration)) {
80
- const since = webmentions.children.length ? webmentions.children[0]["wm-received"] : false
81
- const url = `https://webmention.io/api/mentions.jf2?domain=${hostname(options.domain)}&token=${TOKEN}&per-page=9001${since ? `&since=${since}` : ``}`
91
+ const since = webmentions.length ? getPublished(webmentions[0]) : false
92
+ const url = `${options.feed}${since ? `${options.feed.includes("?") ? "&" : "?"}since=${since}` : ""}`
82
93
  await fetch(url)
83
94
  .then(async (response) => {
84
95
  if (response.ok) {
85
96
  const feed = await response.json()
86
- if (feed.children.length) {
87
- console.log(`[${hostname(options.domain)}] ${feed.children.length} new Webmentions fetched into cache.`)
97
+ if (feed[options.key].length) {
98
+ webmentions = uniqBy([...feed[options.key], ...webmentions], (entry) => {
99
+ return getSource(entry)
100
+ })
101
+ console.log(`[${hostname(options.domain)}] ${feed[options.key].length} new Webmentions fetched into cache.`)
88
102
  }
89
- webmentions.children = [...feed.children, ...webmentions.children]
90
103
  await asset.save(webmentions, "json")
91
104
  return webmentions
92
105
  }
93
106
  return Promise.reject(response)
94
107
  })
95
108
  .catch((error) => {
96
- console.log(`[${hostname(options.domain)}] Something went wrong with your request to webmention.io!`, error)
109
+ console.log(`[${hostname(options.domain)}] Something went wrong with your request to ${hostname(options.feed)}!`, error)
97
110
  })
98
111
  }
99
112
 
@@ -105,9 +118,9 @@ module.exports = (eleventyConfig, options = {}) => {
105
118
  let webmentions = {}
106
119
 
107
120
  // Sort Webmentions into groups by target
108
- rawWebmentions.children.forEach((webmention) => {
121
+ rawWebmentions.forEach((webmention) => {
109
122
  // Get the target of the Webmention and fix it up
110
- let url = baseUrl(fixUrl(webmention["wm-target"].replace(/\/?$/, "/"), options.urlReplacements))
123
+ let url = baseUrl(fixUrl(getTarget(webmention).replace(/\/?$/, "/"), options.urlReplacements))
111
124
 
112
125
  if (!webmentions[url]) {
113
126
  webmentions[url] = []
@@ -116,10 +129,10 @@ module.exports = (eleventyConfig, options = {}) => {
116
129
  webmentions[url].push(webmention)
117
130
  })
118
131
 
119
- // Sort Webmentions in groups by url and remove duplicates by wm-id
132
+ // Sort Webmentions in groups by url and remove duplicates by `url`
120
133
  for (let url in webmentions) {
121
- webmentions[url] = uniqBy(webmentions[url], (item) => {
122
- return item["wm-id"]
134
+ webmentions[url] = uniqBy(webmentions[url], (entry) => {
135
+ return getSource(entry)
123
136
  })
124
137
  }
125
138
 
@@ -137,31 +150,26 @@ module.exports = (eleventyConfig, options = {}) => {
137
150
  const results = webmentions[url]
138
151
  // filter webmentions by allowed response post types
139
152
  .filter((entry) => {
140
- return typeof allowedTypes === "object" && Object.keys(allowedTypes).length ? allowedTypes.includes(entry["wm-property"]) : true
141
- })
142
- // remove webmentions without an author name
143
- .filter((entry) => {
144
- const { author } = entry
145
- return !!author && !!author.name
153
+ return typeof allowedTypes === "object" && Object.keys(allowedTypes).length ? allowedTypes.includes(getType(entry)) : true
146
154
  })
147
- // sanitize content of webmentions and check against HTML limit
155
+ // sanitize content of webmentions against HTML limit
148
156
  .map((entry) => {
149
- if (!("content" in entry)) {
157
+ if (!("content" in entry) || !("data" in entry)) {
150
158
  return entry
151
159
  }
152
- const { html, text } = entry.content
160
+ const html = getContent(entry)
153
161
  if (html && html.length > options.maximumHtmlLength) {
154
- entry.content.value = `${options.maximumHtmlText} <a href="${entry["wm-source"]}">${entry["wm-source"]}</a>`
162
+ entry.content = `${options.maximumHtmlText} <a href="${getSource(entry)}">${getSource(entry)}</a>`
155
163
  } else if (Object.keys(options.allowedHTML).length) {
156
- entry.content.value = sanitizeHTML(html || text, options.allowedHTML)
164
+ entry.content = sanitizeHTML(html, options.allowedHTML)
157
165
  } else {
158
- entry.content.value = html || text
166
+ entry.content = html
159
167
  }
160
168
  return entry
161
169
  })
162
- // sort by published/wm-received
170
+ // sort by published
163
171
  .sort((a, b) => {
164
- return epoch(a.published || a["wm-received"]) - epoch(b.published || b["wm-received"])
172
+ return epoch(getPublished(a)) - epoch(getPublished(b))
165
173
  })
166
174
 
167
175
  return results
@@ -178,14 +186,24 @@ module.exports = (eleventyConfig, options = {}) => {
178
186
 
179
187
  if (eleventyConfig && options) {
180
188
  if (!options.domain) {
181
- throw new Error("domain is a required option to be passed when adding the plugin to your eleventyConfig using addPlugin.")
189
+ throw new Error("domain is a required field when adding the plugin to your eleventyConfig using addPlugin. See https://chrisburnell.com/eleventy-cache-webmentions/#installation for more information.")
182
190
  }
183
191
 
184
- // Liquid/Nunjucks Filters
192
+ if (!options.feed) {
193
+ throw new Error("feed is a required field when adding the plugin to your eleventyConfig using addPlugin. See https://chrisburnell.com/eleventy-cache-webmentions/#installation for more information.")
194
+ }
195
+
196
+ if (!options.key) {
197
+ throw new Error("key is a required field when adding the plugin to your eleventyConfig using addPlugin. See https://chrisburnell.com/eleventy-cache-webmentions/#installation for more information.")
198
+ }
199
+
200
+ // Liquid Filter
185
201
  eleventyConfig.addLiquidFilter("getWebmentions", getWebmentionsFilter)
202
+
203
+ // Nunjucks Filter
186
204
  eleventyConfig.addNunjucksAsyncFilter("getWebmentions", getWebmentionsFilter)
187
205
 
188
- // Eleventy Data
206
+ // Global Data
189
207
  eleventyConfig.addGlobalData("webmentions", filteredWebmentions)
190
208
  } else {
191
209
  // JavaScript
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chrisburnell/eleventy-cache-webmentions",
3
- "version": "0.1.11",
4
- "description": "Cache webmentions from webmention.io using eleventy-fetch.",
3
+ "version": "0.2.1",
4
+ "description": "Fetch and cache webmentions using eleventy-fetch.",
5
5
  "main": "eleventy-cache-webmentions.js",
6
6
  "author": "Chris Burnell <me@chrisburnell.com>",
7
7
  "license": "MIT",
@@ -17,7 +17,6 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@11ty/eleventy-fetch": "^3.0.0",
20
- "dotenv": "^10.0.0",
21
20
  "lodash": "^4.17.21",
22
21
  "node-fetch": "2.6.5",
23
22
  "sanitize-html": "^2.5.2"