@chrisburnell/eleventy-cache-webmentions 2.0.6 → 2.1.0-beta.2

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.
@@ -83,6 +83,59 @@ const defaults = {
83
83
  maximumHtmlText: "mentioned this in",
84
84
  }
85
85
 
86
+ const performFetch = async (options, webmentions, url) => {
87
+ return await fetch(url)
88
+ .then(async (response) => {
89
+ if (response.ok) {
90
+ const feed = await response.json()
91
+ if (feed[options.key].length) {
92
+ // Combine newly-fetched Webmentions with cached Webmentions
93
+ webmentions = feed[options.key].concat(webmentions)
94
+ // Remove duplicates by source URL
95
+ webmentions = uniqBy([...feed[options.key], ...webmentions], (webmention) => {
96
+ return getSource(webmention)
97
+ })
98
+ // Process the blocklist, if it has any entries
99
+ if (options.blocklist.length) {
100
+ webmentions = webmentions.filter((webmention) => {
101
+ let sourceUrl = getSource(webmention)
102
+ for (let url of options.blocklist) {
103
+ if (sourceUrl.includes(url.replace(/\/?$/, "/"))) {
104
+ return false
105
+ }
106
+ }
107
+ return true
108
+ })
109
+ }
110
+ // Process the allowlist, if it has any entries
111
+ if (options.allowlist.length) {
112
+ webmentions = webmentions.filter((webmention) => {
113
+ let sourceUrl = getSource(webmention)
114
+ for (let url of options.allowlist) {
115
+ if (sourceUrl.includes(url.replace(/\/?$/, "/"))) {
116
+ return true
117
+ }
118
+ }
119
+ return false
120
+ })
121
+ }
122
+ // Sort webmentions by received date for getting most recent Webmention on subsequent requests
123
+ webmentions = webmentions.sort((a, b) => {
124
+ return epoch(getReceived(b)) - epoch(getReceived(a))
125
+ })
126
+ }
127
+ return {
128
+ found: feed[options.key].length,
129
+ filtered: webmentions,
130
+ }
131
+ }
132
+ return Promise.reject(response)
133
+ })
134
+ .catch((error) => {
135
+ console.log(`[${hostname(options.domain)}] Something went wrong with your request to ${hostname(options.feed)}!`, error)
136
+ })
137
+ }
138
+
86
139
  const fetchWebmentions = async (options) => {
87
140
  if (!options.domain) {
88
141
  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.")
@@ -117,58 +170,51 @@ const fetchWebmentions = async (options) => {
117
170
  const since = webmentions.length ? getReceived(webmentions[0]) : false
118
171
  // Build the URL for the fetch request
119
172
  const url = `${options.feed}${since ? `${options.feed.includes("?") ? "&" : "?"}since=${since}` : ""}`
120
- await fetch(url)
121
- .then(async (response) => {
122
- if (response.ok) {
123
- const feed = await response.json()
124
- if (feed[options.key].length) {
125
- // Combine newly-fetched Webmentions with cached Webmentions
126
- webmentions = feed[options.key].concat(webmentions)
127
- // Remove duplicates by source URL
128
- webmentions = uniqBy([...feed[options.key], ...webmentions], (webmention) => {
129
- return getSource(webmention)
130
- })
131
- // Process the blocklist, if it has any entries
132
- if (options.blocklist.length) {
133
- webmentions = webmentions.filter((webmention) => {
134
- let sourceUrl = getSource(webmention)
135
- for (let url of options.blocklist) {
136
- if (sourceUrl.includes(url.replace(/\/?$/, "/"))) {
137
- return false
138
- }
139
- }
140
- return true
141
- })
142
- }
143
- // Process the allowlist, if it has any entries
144
- if (options.allowlist.length) {
145
- webmentions = webmentions.filter((webmention) => {
146
- let sourceUrl = getSource(webmention)
147
- for (let url of options.allowlist) {
148
- if (sourceUrl.includes(url.replace(/\/?$/, "/"))) {
149
- return true
150
- }
151
- }
152
- return false
153
- })
154
- }
155
- // Sort webmentions by received date for getting most recent Webmention on subsequent requests
156
- webmentions = webmentions.sort((a, b) => {
157
- return epoch(getReceived(b)) - epoch(getReceived(a))
158
- })
159
- // Add a console message with the number of fetched and processed Webmentions, if any
160
- if (webmentionsCachedLength < webmentions.length) {
161
- console.log(`[${hostname(options.domain)}] ${webmentions.length - webmentionsCachedLength} new Webmentions fetched into cache.`)
162
- }
163
- }
164
- await asset.save(webmentions, "json")
165
- return webmentions
173
+
174
+ // If using webmention.io, loop through pages until no results found
175
+ if (url.includes("https://webmention.io")) {
176
+ // Start on page 0, to increment per subsequent request
177
+ let page = 0
178
+ // Loop until a break condition is hit
179
+ while (true) {
180
+ const perPage = Number(new URL(url).searchParams.get("per-page")) || 1000
181
+ const urlPaginated = url + `&page=${page}`
182
+ const fetched = await performFetch(options, webmentions, urlPaginated)
183
+
184
+ // An error occurred during fetching paged results → break
185
+ if (!fetched && !fetched.found && !fetched.filtered) {
186
+ break
166
187
  }
167
- return Promise.reject(response)
168
- })
169
- .catch((error) => {
170
- console.log(`[${hostname(options.domain)}] Something went wrong with your request to ${hostname(options.feed)}!`, error)
171
- })
188
+
189
+ // Page has no Webmentions → break
190
+ if (fetched.found === 0) {
191
+ break
192
+ }
193
+
194
+ webmentions = fetched.filtered
195
+
196
+ // If there are less Webmentions found than should be in each
197
+ // page → break
198
+ if (fetched.found < perPage) {
199
+ break
200
+ }
201
+
202
+ // Increment page
203
+ page += 1
204
+ // Throttle next request
205
+ await new Promise(resolve => setTimeout(resolve, 1000))
206
+ }
207
+ } else {
208
+ const fetched = await performFetch(options, webmentions, url)
209
+ webmentions = fetched.filtered
210
+ }
211
+
212
+ await asset.save(webmentions, "json")
213
+
214
+ // Add a console message with the number of fetched and processed Webmentions, if any
215
+ if (webmentionsCachedLength < webmentions.length) {
216
+ console.log(`[${hostname(options.domain)}] ${webmentions.length - webmentionsCachedLength} new Webmentions fetched into cache.`)
217
+ }
172
218
  }
173
219
 
174
220
  return webmentions
package/package.json CHANGED
@@ -1,16 +1,32 @@
1
1
  {
2
2
  "name": "@chrisburnell/eleventy-cache-webmentions",
3
- "version": "2.0.6",
3
+ "version": "2.1.0-beta.2",
4
4
  "description": "Cache webmentions using eleventy-fetch and make them available to use in collections, layouts, pages, etc. in Eleventy.",
5
- "author": "Chris Burnell <me@chrisburnell.com>",
6
5
  "license": "MIT",
7
6
  "repository": {
8
7
  "type": "git",
9
8
  "url": "git@github.com:chrisburnell/eleventy-cache-webmentions.git"
10
9
  },
10
+ "homepage": "https://chrisburnell.com/eleventy-cache-webmentions/",
11
11
  "bugs": {
12
12
  "url": "https://github.com/chrisburnell/eleventy-cache-webmentions/issues"
13
13
  },
14
+ "author": "Chris Burnell <me@chrisburnell.com>",
15
+ "contributors": [
16
+ {
17
+ "name": "Chris Burnell",
18
+ "email": "me@chrisburnell.com",
19
+ "url": "https://chrisburnell.com",
20
+ "mastodon": "@chrisburnell@repc.co"
21
+ }
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "main": "eleventy-cache-webmentions.js",
27
+ "scripts": {
28
+ "lint": "eslint eleventy-cache-webmentions.js"
29
+ },
14
30
  "keywords": [
15
31
  "eleventy",
16
32
  "eleventy-plugin",
@@ -19,17 +35,13 @@
19
35
  "js",
20
36
  "webmention"
21
37
  ],
22
- "devDependencies": {
23
- "eslint": "^9.2.0"
24
- },
25
38
  "dependencies": {
26
39
  "@11ty/eleventy-fetch": "^4.0.1",
27
40
  "lodash": "^4.17.21",
28
41
  "node-fetch": "2.6.7",
29
42
  "sanitize-html": "^2.13.0"
30
43
  },
31
- "main": "eleventy-cache-webmentions.js",
32
- "scripts": {
33
- "lint": "eslint eleventy-cache-webmentions.js"
44
+ "devDependencies": {
45
+ "eslint": "^9.2.0"
34
46
  }
35
47
  }