@chrisburnell/eleventy-cache-webmentions 2.1.11 → 2.1.12
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"cachedAt":
|
|
1
|
+
{"cachedAt":1761155512715,"type":"json","metadata":{}}
|
package/README.md
CHANGED
|
@@ -31,6 +31,8 @@ Check it out: [Webmention Setup for Eleventy](https://chrisburnell.com/article/w
|
|
|
31
31
|
- **With npm:** `npm install @chrisburnell/eleventy-cache-webmentions`
|
|
32
32
|
- **Direct download:** [https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip](https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip)
|
|
33
33
|
|
|
34
|
+
*Important Note: This plugin uses Node.js features only present in versions 18+. If you’re deploying your website somewhere, check to make sure that your Node.js version is set to 18 or greater. ([Cloudflare Pages](https://community.cloudflare.com/t/pages-node-js-version/295548/3), [GitHub Actions](https://github.com/actions/setup-node), [Netlify](https://answers.netlify.com/t/specifying-a-node-version/9701))*
|
|
35
|
+
|
|
34
36
|
Inside your Eleventy config file, use `addPlugin()` to add it to your project:
|
|
35
37
|
|
|
36
38
|
```javascript
|
|
@@ -2,6 +2,9 @@ const sanitizeHTML = require("sanitize-html");
|
|
|
2
2
|
const { AssetCache } = require("@11ty/eleventy-fetch");
|
|
3
3
|
const { styleText } = require("node:util");
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @type {Object}
|
|
7
|
+
*/
|
|
5
8
|
const defaults = {
|
|
6
9
|
refresh: false,
|
|
7
10
|
duration: "1d",
|
|
@@ -19,6 +22,11 @@ const defaults = {
|
|
|
19
22
|
maximumHtmlText: "mentioned this in",
|
|
20
23
|
};
|
|
21
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param {string} url
|
|
27
|
+
* @param {string} domain
|
|
28
|
+
* @returns {string}
|
|
29
|
+
*/
|
|
22
30
|
const absoluteURL = (url, domain) => {
|
|
23
31
|
try {
|
|
24
32
|
return new URL(url, domain).toString();
|
|
@@ -36,12 +44,21 @@ const absoluteURL = (url, domain) => {
|
|
|
36
44
|
}
|
|
37
45
|
};
|
|
38
46
|
|
|
47
|
+
/**
|
|
48
|
+
* @param {string} url
|
|
49
|
+
* @returns {string}
|
|
50
|
+
*/
|
|
39
51
|
const baseUrl = (url) => {
|
|
40
52
|
let hashSplit = url.split("#");
|
|
41
53
|
let queryparamSplit = hashSplit[0].split("?");
|
|
42
54
|
return queryparamSplit[0];
|
|
43
55
|
};
|
|
44
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @param {string} url
|
|
59
|
+
* @param {Object} urlReplacements
|
|
60
|
+
* @returns {string}
|
|
61
|
+
*/
|
|
45
62
|
const fixUrl = (url, urlReplacements) => {
|
|
46
63
|
return Object.entries(urlReplacements).reduce(
|
|
47
64
|
(accumulator, [key, value]) => {
|
|
@@ -52,18 +69,30 @@ const fixUrl = (url, urlReplacements) => {
|
|
|
52
69
|
);
|
|
53
70
|
};
|
|
54
71
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
/**
|
|
73
|
+
* @param {string} url
|
|
74
|
+
* @returns {string}
|
|
75
|
+
*/
|
|
76
|
+
const hostname = (url) => {
|
|
77
|
+
if (typeof url === "string" && url.includes("//")) {
|
|
78
|
+
const urlObject = new URL(url);
|
|
58
79
|
return urlObject.hostname;
|
|
59
80
|
}
|
|
60
|
-
return
|
|
81
|
+
return url;
|
|
61
82
|
};
|
|
62
83
|
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
/**
|
|
85
|
+
* @param {string|number|Date} date
|
|
86
|
+
* @returns {number}
|
|
87
|
+
*/
|
|
88
|
+
const epoch = (date) => {
|
|
89
|
+
return new Date(date).getTime();
|
|
65
90
|
};
|
|
66
91
|
|
|
92
|
+
/**
|
|
93
|
+
* @param {Object} date
|
|
94
|
+
* @returns {string|undefined}
|
|
95
|
+
*/
|
|
67
96
|
const getPublished = (webmention) => {
|
|
68
97
|
return (
|
|
69
98
|
webmention?.["data"]?.["published"] ||
|
|
@@ -73,6 +102,10 @@ const getPublished = (webmention) => {
|
|
|
73
102
|
);
|
|
74
103
|
};
|
|
75
104
|
|
|
105
|
+
/**
|
|
106
|
+
* @param {Object} webmention
|
|
107
|
+
* @returns {string|undefined}
|
|
108
|
+
*/
|
|
76
109
|
const getReceived = (webmention) => {
|
|
77
110
|
return (
|
|
78
111
|
webmention["wm-received"] ||
|
|
@@ -82,6 +115,10 @@ const getReceived = (webmention) => {
|
|
|
82
115
|
);
|
|
83
116
|
};
|
|
84
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @param {Object} webmention
|
|
120
|
+
* @returns {string}
|
|
121
|
+
*/
|
|
85
122
|
const getContent = (webmention) => {
|
|
86
123
|
return (
|
|
87
124
|
webmention?.["contentSanitized"] ||
|
|
@@ -93,6 +130,10 @@ const getContent = (webmention) => {
|
|
|
93
130
|
);
|
|
94
131
|
};
|
|
95
132
|
|
|
133
|
+
/**
|
|
134
|
+
* @param {Object} webmention
|
|
135
|
+
* @returns {string}
|
|
136
|
+
*/
|
|
96
137
|
const getSource = (webmention) => {
|
|
97
138
|
return (
|
|
98
139
|
webmention["wm-source"] ||
|
|
@@ -102,6 +143,10 @@ const getSource = (webmention) => {
|
|
|
102
143
|
);
|
|
103
144
|
};
|
|
104
145
|
|
|
146
|
+
/**
|
|
147
|
+
* @param {Object} webmention
|
|
148
|
+
* @returns {string}
|
|
149
|
+
*/
|
|
105
150
|
const getURL = (webmention) => {
|
|
106
151
|
return (
|
|
107
152
|
webmention?.["data"]?.["url"] ||
|
|
@@ -111,10 +156,18 @@ const getURL = (webmention) => {
|
|
|
111
156
|
);
|
|
112
157
|
};
|
|
113
158
|
|
|
159
|
+
/**
|
|
160
|
+
* @param {Object} webmention
|
|
161
|
+
* @returns {string}
|
|
162
|
+
*/
|
|
114
163
|
const getTarget = (webmention) => {
|
|
115
164
|
return webmention["wm-target"] || webmention["target"];
|
|
116
165
|
};
|
|
117
166
|
|
|
167
|
+
/**
|
|
168
|
+
* @param {Object} webmention
|
|
169
|
+
* @returns {string|undefined}
|
|
170
|
+
*/
|
|
118
171
|
const getType = (webmention) => {
|
|
119
172
|
return (
|
|
120
173
|
webmention["wm-property"] ||
|
|
@@ -123,18 +176,32 @@ const getType = (webmention) => {
|
|
|
123
176
|
);
|
|
124
177
|
};
|
|
125
178
|
|
|
126
|
-
|
|
179
|
+
/**
|
|
180
|
+
* @param {Object[]} webmentions
|
|
181
|
+
* @param {string} type
|
|
182
|
+
* @returns {Object[]}
|
|
183
|
+
*/
|
|
184
|
+
const getByType = (webmentions, type) => {
|
|
127
185
|
return webmentions.filter((webmention) => {
|
|
128
|
-
return
|
|
186
|
+
return type === getType(webmention);
|
|
129
187
|
});
|
|
130
188
|
};
|
|
131
189
|
|
|
132
|
-
|
|
190
|
+
/**
|
|
191
|
+
* @param {Object[]} webmentions
|
|
192
|
+
* @param {string[]} types
|
|
193
|
+
* @returns {Object[]}
|
|
194
|
+
*/
|
|
195
|
+
const getByTypes = (webmentions, types) => {
|
|
133
196
|
return webmentions.filter((webmention) => {
|
|
134
|
-
return
|
|
197
|
+
return types.includes(getType(webmention));
|
|
135
198
|
});
|
|
136
199
|
};
|
|
137
200
|
|
|
201
|
+
/**
|
|
202
|
+
* @param {Object[]} webmentions
|
|
203
|
+
* @returns {Object[]}
|
|
204
|
+
*/
|
|
138
205
|
const removeDuplicates = (webmentions) => {
|
|
139
206
|
return [
|
|
140
207
|
...webmentions
|
|
@@ -152,6 +219,11 @@ const removeDuplicates = (webmentions) => {
|
|
|
152
219
|
];
|
|
153
220
|
};
|
|
154
221
|
|
|
222
|
+
/**
|
|
223
|
+
* @param {Object[]} webmentions
|
|
224
|
+
* @param {string[]} blocklist
|
|
225
|
+
* @returns {Object[]}
|
|
226
|
+
*/
|
|
155
227
|
const processBlocklist = (webmentions, blocklist) => {
|
|
156
228
|
return webmentions.filter((webmention) => {
|
|
157
229
|
let url = getSource(webmention);
|
|
@@ -168,6 +240,11 @@ const processBlocklist = (webmentions, blocklist) => {
|
|
|
168
240
|
});
|
|
169
241
|
};
|
|
170
242
|
|
|
243
|
+
/**
|
|
244
|
+
* @param {Object[]} webmentions
|
|
245
|
+
* @param {string[]} allowlist
|
|
246
|
+
* @returns {Object[]}
|
|
247
|
+
*/
|
|
171
248
|
const processAllowlist = (webmentions, allowlist) => {
|
|
172
249
|
return webmentions.filter((webmention) => {
|
|
173
250
|
let url = getSource(webmention);
|
|
@@ -184,6 +261,12 @@ const processAllowlist = (webmentions, allowlist) => {
|
|
|
184
261
|
});
|
|
185
262
|
};
|
|
186
263
|
|
|
264
|
+
/**
|
|
265
|
+
* @param {Object} options
|
|
266
|
+
* @param {Object[]} webmentions
|
|
267
|
+
* @param {string} url
|
|
268
|
+
* @returns {Promise<{found:number,filtered:Object[]}>}
|
|
269
|
+
*/
|
|
187
270
|
const performFetch = async (options, webmentions, url) => {
|
|
188
271
|
return await fetch(url)
|
|
189
272
|
.then(async (response) => {
|
|
@@ -246,6 +329,10 @@ const performFetch = async (options, webmentions, url) => {
|
|
|
246
329
|
});
|
|
247
330
|
};
|
|
248
331
|
|
|
332
|
+
/**
|
|
333
|
+
* @param {Object} options
|
|
334
|
+
* @returns {Promise<Object[]>}
|
|
335
|
+
*/
|
|
249
336
|
const fetchWebmentions = async (options) => {
|
|
250
337
|
if (!options.domain) {
|
|
251
338
|
throw new Error(
|
|
@@ -377,6 +464,11 @@ const fetchWebmentions = async (options) => {
|
|
|
377
464
|
};
|
|
378
465
|
|
|
379
466
|
let filtered = {};
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* @param {Object} options
|
|
470
|
+
* @returns {Promise<Object<string, Object[]>>}
|
|
471
|
+
*/
|
|
380
472
|
const filteredWebmentions = async (options) => {
|
|
381
473
|
if (Object.entries(filtered).length) {
|
|
382
474
|
return filtered;
|
|
@@ -404,7 +496,13 @@ const filteredWebmentions = async (options) => {
|
|
|
404
496
|
return filtered;
|
|
405
497
|
};
|
|
406
498
|
|
|
407
|
-
|
|
499
|
+
/**
|
|
500
|
+
* @param {Object} options
|
|
501
|
+
* @param {string} url
|
|
502
|
+
* @param {string[]|Object} [types={}]
|
|
503
|
+
* @returns {Promise<Object[]>}
|
|
504
|
+
*/
|
|
505
|
+
const getWebmentions = async (options, url, types = {}) => {
|
|
408
506
|
const webmentions = await filteredWebmentions(options);
|
|
409
507
|
url = absoluteURL(url, options.domain);
|
|
410
508
|
|
|
@@ -416,9 +514,8 @@ const getWebmentions = async (options, url, allowedTypes = {}) => {
|
|
|
416
514
|
webmentions[url]
|
|
417
515
|
// Filter webmentions by allowed response post types
|
|
418
516
|
.filter((entry) => {
|
|
419
|
-
return typeof
|
|
420
|
-
|
|
421
|
-
? allowedTypes.includes(getType(entry))
|
|
517
|
+
return typeof types === "object" && Object.keys(types).length
|
|
518
|
+
? types.includes(getType(entry))
|
|
422
519
|
: true;
|
|
423
520
|
})
|
|
424
521
|
// Sanitize content of webmentions against HTML limit
|
|
@@ -448,6 +545,10 @@ const getWebmentions = async (options, url, allowedTypes = {}) => {
|
|
|
448
545
|
);
|
|
449
546
|
};
|
|
450
547
|
|
|
548
|
+
/**
|
|
549
|
+
* @param {Object} eleventyConfig
|
|
550
|
+
* @param {Object} [options={}]
|
|
551
|
+
*/
|
|
451
552
|
const eleventyCacheWebmentions = (eleventyConfig, options = {}) => {
|
|
452
553
|
options = Object.assign(defaults, options);
|
|
453
554
|
|
package/eslint.config.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrisburnell/eleventy-cache-webmentions",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.12",
|
|
4
4
|
"description": "Cache webmentions using eleventy-fetch and make them available to use in collections, layouts, pages, etc. in Eleventy.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"sanitize-html": "^2.17.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"eslint": "^9.
|
|
62
|
-
"nock": "^14.0.
|
|
61
|
+
"eslint": "^9.38.0",
|
|
62
|
+
"nock": "^14.0.10"
|
|
63
63
|
}
|
|
64
64
|
}
|