@chrisburnell/eleventy-cache-webmentions 2.1.11 → 2.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/.cache/eleventy-fetch-68a403136c61abd104ade94e69ba62 +1 -1
- package/README.md +2 -0
- package/eleventy-cache-webmentions.cjs +677 -0
- package/eleventy-cache-webmentions.js +265 -118
- package/eleventy-cache-webmentions.min.cjs +1 -0
- package/eleventy-cache-webmentions.min.js +1 -0
- package/eslint.config.js +36 -0
- package/package.json +13 -4
|
@@ -1,13 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { AssetCache } from "@11ty/eleventy-fetch";
|
|
2
|
+
import { styleText } from "node:util";
|
|
3
|
+
import sanitizeHTML from "sanitize-html";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {sanitizeHTML.IOptions} AllowedHTML
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} OptionsDefaults
|
|
11
|
+
* @prop {boolean} refresh
|
|
12
|
+
* @prop {string} duration
|
|
13
|
+
* @prop {string} uniqueKey
|
|
14
|
+
* @prop {string} [cacheDirectory]
|
|
15
|
+
* @prop {AllowedHTML} allowedHTML
|
|
16
|
+
* @prop {string[]} allowlist
|
|
17
|
+
* @prop {string[]} blocklist
|
|
18
|
+
* @prop {Object<string, string>} urlReplacements
|
|
19
|
+
* @prop {number} maximumHtmlLength
|
|
20
|
+
* @prop {string} maximumHtmlText
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} OptionsUserInput
|
|
25
|
+
* @prop {string} domain
|
|
26
|
+
* @prop {string} feed
|
|
27
|
+
* @prop {string} key
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {OptionsDefaults & OptionsUserInput} Options
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {Object} Webmention
|
|
36
|
+
* @prop {string} [source]
|
|
37
|
+
* @prop {string} [url]
|
|
38
|
+
* @prop {string} [target]
|
|
39
|
+
* @prop {string} [published]
|
|
40
|
+
* @prop {string} [contentSanitized]
|
|
41
|
+
* @prop {Object} [content]
|
|
42
|
+
* @prop {string} [content.html]
|
|
43
|
+
* @prop {string} [content.value]
|
|
44
|
+
* @prop {Object} [data]
|
|
45
|
+
* @prop {string} [data.title]
|
|
46
|
+
* @prop {string} [data.url]
|
|
47
|
+
* @prop {string} [data.published]
|
|
48
|
+
* @prop {string} [data.content]
|
|
49
|
+
* @prop {string} [type]
|
|
50
|
+
* @prop {Object} [activity]
|
|
51
|
+
* @prop {string} [activity.type]
|
|
52
|
+
* @prop {boolean} [verified]
|
|
53
|
+
* @prop {string} ["wm-property"]
|
|
54
|
+
* @prop {string} ["wm-received"]
|
|
55
|
+
* @prop {string} ["wm-source"]
|
|
56
|
+
* @prop {string} ["wm-target"]
|
|
57
|
+
* @prop {string} ["verified_date"]
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @typedef {"bookmark-of"|"like-of"|"repost-of"|"mention-of"|"in-reply-to"} WebmentionType
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @type {OptionsDefaults}
|
|
66
|
+
*/
|
|
67
|
+
export const defaults = {
|
|
6
68
|
refresh: false,
|
|
7
69
|
duration: "1d",
|
|
8
70
|
uniqueKey: "webmentions",
|
|
71
|
+
cacheDirectory: undefined,
|
|
9
72
|
allowedHTML: {
|
|
10
|
-
allowedTags: ["
|
|
73
|
+
allowedTags: ["a", "b", "em", "i", "strong"],
|
|
11
74
|
allowedAttributes: {
|
|
12
75
|
a: ["href"],
|
|
13
76
|
},
|
|
@@ -19,6 +82,11 @@ const defaults = {
|
|
|
19
82
|
maximumHtmlText: "mentioned this in",
|
|
20
83
|
};
|
|
21
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @param {string} url
|
|
87
|
+
* @param {string} domain
|
|
88
|
+
* @returns {string}
|
|
89
|
+
*/
|
|
22
90
|
const absoluteURL = (url, domain) => {
|
|
23
91
|
try {
|
|
24
92
|
return new URL(url, domain).toString();
|
|
@@ -36,13 +104,22 @@ const absoluteURL = (url, domain) => {
|
|
|
36
104
|
}
|
|
37
105
|
};
|
|
38
106
|
|
|
39
|
-
|
|
107
|
+
/**
|
|
108
|
+
* @param {string} url
|
|
109
|
+
* @returns {string}
|
|
110
|
+
*/
|
|
111
|
+
const baseURL = (url) => {
|
|
40
112
|
let hashSplit = url.split("#");
|
|
41
113
|
let queryparamSplit = hashSplit[0].split("?");
|
|
42
114
|
return queryparamSplit[0];
|
|
43
115
|
};
|
|
44
116
|
|
|
45
|
-
|
|
117
|
+
/**
|
|
118
|
+
* @param {string} url
|
|
119
|
+
* @param {Object<string, string>} [urlReplacements]
|
|
120
|
+
* @returns {string}
|
|
121
|
+
*/
|
|
122
|
+
const fixURL = (url, urlReplacements) => {
|
|
46
123
|
return Object.entries(urlReplacements).reduce(
|
|
47
124
|
(accumulator, [key, value]) => {
|
|
48
125
|
const regex = new RegExp(key, "g");
|
|
@@ -52,19 +129,52 @@ const fixUrl = (url, urlReplacements) => {
|
|
|
52
129
|
);
|
|
53
130
|
};
|
|
54
131
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
132
|
+
/**
|
|
133
|
+
* @param {string} url
|
|
134
|
+
* @returns {string}
|
|
135
|
+
*/
|
|
136
|
+
const hostname = (url) => {
|
|
137
|
+
if (typeof url === "string" && url.includes("//")) {
|
|
138
|
+
const urlObject = new URL(url);
|
|
58
139
|
return urlObject.hostname;
|
|
59
140
|
}
|
|
60
|
-
return
|
|
141
|
+
return url;
|
|
61
142
|
};
|
|
62
143
|
|
|
63
|
-
|
|
64
|
-
|
|
144
|
+
/**
|
|
145
|
+
* @param {string|number|Date} date
|
|
146
|
+
* @returns {number}
|
|
147
|
+
*/
|
|
148
|
+
const epoch = (date) => {
|
|
149
|
+
return new Date(date).getTime();
|
|
65
150
|
};
|
|
66
151
|
|
|
67
|
-
|
|
152
|
+
/**
|
|
153
|
+
* @param {Webmention[]} webmentions
|
|
154
|
+
* @returns {Webmention[]}
|
|
155
|
+
*/
|
|
156
|
+
const removeDuplicates = (webmentions) => {
|
|
157
|
+
return [
|
|
158
|
+
...webmentions
|
|
159
|
+
.reduce((map, webmention) => {
|
|
160
|
+
const key =
|
|
161
|
+
webmention === null || webmention === undefined
|
|
162
|
+
? webmention
|
|
163
|
+
: getSource(webmention);
|
|
164
|
+
if (!map.has(key)) {
|
|
165
|
+
map.set(key, webmention);
|
|
166
|
+
}
|
|
167
|
+
return map;
|
|
168
|
+
}, new Map())
|
|
169
|
+
.values(),
|
|
170
|
+
];
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @param {Webmention} webmention
|
|
175
|
+
* @returns {string|undefined}
|
|
176
|
+
*/
|
|
177
|
+
export const getPublished = (webmention) => {
|
|
68
178
|
return (
|
|
69
179
|
webmention?.["data"]?.["published"] ||
|
|
70
180
|
webmention["published"] ||
|
|
@@ -72,8 +182,13 @@ const getPublished = (webmention) => {
|
|
|
72
182
|
webmention["verified_date"]
|
|
73
183
|
);
|
|
74
184
|
};
|
|
185
|
+
export const getWebmentionPublished = getPublished;
|
|
75
186
|
|
|
76
|
-
|
|
187
|
+
/**
|
|
188
|
+
* @param {Webmention} webmention
|
|
189
|
+
* @returns {string|undefined}
|
|
190
|
+
*/
|
|
191
|
+
export const getReceived = (webmention) => {
|
|
77
192
|
return (
|
|
78
193
|
webmention["wm-received"] ||
|
|
79
194
|
webmention["verified_date"] ||
|
|
@@ -81,8 +196,13 @@ const getReceived = (webmention) => {
|
|
|
81
196
|
webmention?.["data"]?.["published"]
|
|
82
197
|
);
|
|
83
198
|
};
|
|
199
|
+
export const getWebmentionReceived = getReceived;
|
|
84
200
|
|
|
85
|
-
|
|
201
|
+
/**
|
|
202
|
+
* @param {Webmention} webmention
|
|
203
|
+
* @returns {string}
|
|
204
|
+
*/
|
|
205
|
+
export const getContent = (webmention) => {
|
|
86
206
|
return (
|
|
87
207
|
webmention?.["contentSanitized"] ||
|
|
88
208
|
webmention?.["content"]?.["html"] ||
|
|
@@ -92,8 +212,13 @@ const getContent = (webmention) => {
|
|
|
92
212
|
""
|
|
93
213
|
);
|
|
94
214
|
};
|
|
215
|
+
export const getWebmentionContent = getContent;
|
|
95
216
|
|
|
96
|
-
|
|
217
|
+
/**
|
|
218
|
+
* @param {Webmention} webmention
|
|
219
|
+
* @returns {string|undefined}
|
|
220
|
+
*/
|
|
221
|
+
export const getSource = (webmention) => {
|
|
97
222
|
return (
|
|
98
223
|
webmention["wm-source"] ||
|
|
99
224
|
webmention["source"] ||
|
|
@@ -101,8 +226,13 @@ const getSource = (webmention) => {
|
|
|
101
226
|
webmention["url"]
|
|
102
227
|
);
|
|
103
228
|
};
|
|
229
|
+
export const getWebmentionSource = getSource;
|
|
104
230
|
|
|
105
|
-
|
|
231
|
+
/**
|
|
232
|
+
* @param {Webmention} webmention
|
|
233
|
+
* @returns {string|undefined}
|
|
234
|
+
*/
|
|
235
|
+
export const getURL = (webmention) => {
|
|
106
236
|
return (
|
|
107
237
|
webmention?.["data"]?.["url"] ||
|
|
108
238
|
webmention["url"] ||
|
|
@@ -110,49 +240,53 @@ const getURL = (webmention) => {
|
|
|
110
240
|
webmention["source"]
|
|
111
241
|
);
|
|
112
242
|
};
|
|
243
|
+
export const getWebmentionURL = getURL;
|
|
113
244
|
|
|
114
|
-
|
|
245
|
+
/**
|
|
246
|
+
* @param {Webmention} webmention
|
|
247
|
+
* @returns {string|undefined}
|
|
248
|
+
*/
|
|
249
|
+
export const getTarget = (webmention) => {
|
|
115
250
|
return webmention["wm-target"] || webmention["target"];
|
|
116
251
|
};
|
|
252
|
+
export const getWebmentionTarget = getTarget;
|
|
117
253
|
|
|
118
|
-
|
|
254
|
+
/**
|
|
255
|
+
* @param {Webmention} webmention
|
|
256
|
+
* @returns {string|undefined}
|
|
257
|
+
*/
|
|
258
|
+
export const getType = (webmention) => {
|
|
119
259
|
return (
|
|
120
260
|
webmention["wm-property"] ||
|
|
121
261
|
webmention?.["activity"]?.["type"] ||
|
|
122
262
|
webmention["type"]
|
|
123
263
|
);
|
|
124
264
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const getByTypes = (webmentions,
|
|
265
|
+
export const getWebmentionType = getType;
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @param {Webmention[]} webmentions
|
|
269
|
+
* @param {WebmentionType|WebmentionType[]} types
|
|
270
|
+
* @returns {Webmention[]}
|
|
271
|
+
*/
|
|
272
|
+
export const getByTypes = (webmentions, types) => {
|
|
133
273
|
return webmentions.filter((webmention) => {
|
|
134
|
-
|
|
274
|
+
if (typeof types === "string") {
|
|
275
|
+
return types === getType(webmention);
|
|
276
|
+
}
|
|
277
|
+
return types.includes(getType(webmention));
|
|
135
278
|
});
|
|
136
279
|
};
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
map.set(key, webmention);
|
|
148
|
-
}
|
|
149
|
-
return map;
|
|
150
|
-
}, new Map())
|
|
151
|
-
.values(),
|
|
152
|
-
];
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const processBlocklist = (webmentions, blocklist) => {
|
|
280
|
+
export const getByType = getByTypes;
|
|
281
|
+
export const getWebmentionsByTypes = getByTypes;
|
|
282
|
+
export const getWebmentionsByType = getByTypes;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @param {Webmention[]} webmentions
|
|
286
|
+
* @param {string[]} blocklist
|
|
287
|
+
* @returns {Webmention[]}
|
|
288
|
+
*/
|
|
289
|
+
export const processBlocklist = (webmentions, blocklist) => {
|
|
156
290
|
return webmentions.filter((webmention) => {
|
|
157
291
|
let url = getSource(webmention);
|
|
158
292
|
let source = getSource(webmention);
|
|
@@ -167,8 +301,15 @@ const processBlocklist = (webmentions, blocklist) => {
|
|
|
167
301
|
return true;
|
|
168
302
|
});
|
|
169
303
|
};
|
|
170
|
-
|
|
171
|
-
const
|
|
304
|
+
export const processWebmentionBlocklist = processBlocklist;
|
|
305
|
+
export const processWebmentionsBlocklist = processBlocklist;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @param {Webmention[]} webmentions
|
|
309
|
+
* @param {string[]} allowlist
|
|
310
|
+
* @returns {Webmention[]}
|
|
311
|
+
*/
|
|
312
|
+
export const processAllowlist = (webmentions, allowlist) => {
|
|
172
313
|
return webmentions.filter((webmention) => {
|
|
173
314
|
let url = getSource(webmention);
|
|
174
315
|
let source = getSource(webmention);
|
|
@@ -183,8 +324,16 @@ const processAllowlist = (webmentions, allowlist) => {
|
|
|
183
324
|
return false;
|
|
184
325
|
});
|
|
185
326
|
};
|
|
186
|
-
|
|
187
|
-
const
|
|
327
|
+
export const processWebmentionAllowlist = processAllowlist;
|
|
328
|
+
export const processWebmentionsAllowlist = processAllowlist;
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @param {Options} options
|
|
332
|
+
* @param {Webmention[]} webmentions
|
|
333
|
+
* @param {string} url
|
|
334
|
+
* @returns {Promise<{found: number, webmentions: Webmention[]}>}
|
|
335
|
+
*/
|
|
336
|
+
export const fetchWebmentions = async (options, webmentions, url) => {
|
|
188
337
|
return await fetch(url)
|
|
189
338
|
.then(async (response) => {
|
|
190
339
|
if (!response.ok) {
|
|
@@ -193,7 +342,7 @@ const performFetch = async (options, webmentions, url) => {
|
|
|
193
342
|
|
|
194
343
|
const feed = await response.json();
|
|
195
344
|
|
|
196
|
-
if (!options.key in feed) {
|
|
345
|
+
if (!(options.key in feed)) {
|
|
197
346
|
console.log(
|
|
198
347
|
`${styleText("grey", `[${hostname(options.domain)}]`)} ${
|
|
199
348
|
options.key
|
|
@@ -224,7 +373,7 @@ const performFetch = async (options, webmentions, url) => {
|
|
|
224
373
|
|
|
225
374
|
return {
|
|
226
375
|
found: feed[options.key].length,
|
|
227
|
-
|
|
376
|
+
webmentions: webmentions,
|
|
228
377
|
};
|
|
229
378
|
})
|
|
230
379
|
.catch((error) => {
|
|
@@ -241,12 +390,16 @@ const performFetch = async (options, webmentions, url) => {
|
|
|
241
390
|
|
|
242
391
|
return {
|
|
243
392
|
found: 0,
|
|
244
|
-
|
|
393
|
+
webmentions: webmentions,
|
|
245
394
|
};
|
|
246
395
|
});
|
|
247
396
|
};
|
|
248
397
|
|
|
249
|
-
|
|
398
|
+
/**
|
|
399
|
+
* @param {Options} options
|
|
400
|
+
* @returns {Promise<Webmention[]>}
|
|
401
|
+
*/
|
|
402
|
+
export const retrieveWebmentions = async (options) => {
|
|
250
403
|
if (!options.domain) {
|
|
251
404
|
throw new Error(
|
|
252
405
|
"`domain` is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.",
|
|
@@ -267,7 +420,7 @@ const fetchWebmentions = async (options) => {
|
|
|
267
420
|
|
|
268
421
|
let asset = new AssetCache(
|
|
269
422
|
options.uniqueKey || `webmentions-${hostname(options.domain)}`,
|
|
270
|
-
options.
|
|
423
|
+
options.cacheDirectory,
|
|
271
424
|
);
|
|
272
425
|
|
|
273
426
|
let webmentions = [];
|
|
@@ -307,14 +460,14 @@ const fetchWebmentions = async (options) => {
|
|
|
307
460
|
while (true) {
|
|
308
461
|
const urlPaginated =
|
|
309
462
|
urlObject.href + `&per-page=${perPage}&page=${page}`;
|
|
310
|
-
const fetched = await
|
|
463
|
+
const fetched = await fetchWebmentions(
|
|
311
464
|
options,
|
|
312
465
|
webmentions,
|
|
313
466
|
urlPaginated,
|
|
314
467
|
);
|
|
315
468
|
|
|
316
469
|
// An error occurred during fetching paged results → break
|
|
317
|
-
if (!fetched && !fetched.found && !fetched.
|
|
470
|
+
if (!fetched && !fetched.found && !fetched.webmentions) {
|
|
318
471
|
break;
|
|
319
472
|
}
|
|
320
473
|
|
|
@@ -323,7 +476,7 @@ const fetchWebmentions = async (options) => {
|
|
|
323
476
|
break;
|
|
324
477
|
}
|
|
325
478
|
|
|
326
|
-
webmentions = fetched.
|
|
479
|
+
webmentions = fetched.webmentions;
|
|
327
480
|
|
|
328
481
|
// If there are less Webmentions found than should be in each
|
|
329
482
|
// page → break
|
|
@@ -337,8 +490,8 @@ const fetchWebmentions = async (options) => {
|
|
|
337
490
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
338
491
|
}
|
|
339
492
|
} else {
|
|
340
|
-
const fetched = await
|
|
341
|
-
webmentions = fetched.
|
|
493
|
+
const fetched = await fetchWebmentions(options, webmentions, url);
|
|
494
|
+
webmentions = fetched.webmentions;
|
|
342
495
|
}
|
|
343
496
|
|
|
344
497
|
// Process the blocklist, if it has any entries
|
|
@@ -376,36 +529,50 @@ const fetchWebmentions = async (options) => {
|
|
|
376
529
|
return webmentions;
|
|
377
530
|
};
|
|
378
531
|
|
|
379
|
-
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
532
|
+
/** @type {Webmention[]} */
|
|
533
|
+
const WEBMENTIONS = {};
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* @param {Options} options
|
|
537
|
+
* @returns {Promise<Object<string, Webmention[]>>}
|
|
538
|
+
*/
|
|
539
|
+
export const webmentionsByURL = async (options) => {
|
|
540
|
+
if (Object.keys(WEBMENTIONS).length) {
|
|
541
|
+
return WEBMENTIONS;
|
|
383
542
|
}
|
|
384
543
|
|
|
385
|
-
let rawWebmentions = await
|
|
544
|
+
let rawWebmentions = await retrieveWebmentions(options);
|
|
386
545
|
|
|
387
546
|
// Fix local URLs based on urlReplacements and sort Webmentions into groups
|
|
388
547
|
// by target base URL
|
|
389
548
|
rawWebmentions.forEach((webmention) => {
|
|
390
|
-
let url =
|
|
391
|
-
|
|
549
|
+
let url = baseURL(
|
|
550
|
+
fixURL(
|
|
392
551
|
getTarget(webmention).replace(/\/?$/, "/"),
|
|
393
552
|
options.urlReplacements,
|
|
394
553
|
),
|
|
395
554
|
);
|
|
396
555
|
|
|
397
|
-
if (!
|
|
398
|
-
|
|
556
|
+
if (!WEBMENTIONS[url]) {
|
|
557
|
+
WEBMENTIONS[url] = [];
|
|
399
558
|
}
|
|
400
559
|
|
|
401
|
-
|
|
560
|
+
WEBMENTIONS[url].push(webmention);
|
|
402
561
|
});
|
|
403
562
|
|
|
404
|
-
return
|
|
563
|
+
return WEBMENTIONS;
|
|
405
564
|
};
|
|
406
|
-
|
|
407
|
-
const
|
|
408
|
-
|
|
565
|
+
export const webmentionsByUrl = webmentionsByURL;
|
|
566
|
+
export const filteredWebmentions = webmentionsByURL;
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* @param {Options} options
|
|
570
|
+
* @param {string} url
|
|
571
|
+
* @param {WebmentionType[]|WebmentionType} [types=[]]
|
|
572
|
+
* @returns {Promise<Webmention[]>}
|
|
573
|
+
*/
|
|
574
|
+
export const getWebmentions = async (options, url, types = []) => {
|
|
575
|
+
const webmentions = await webmentionsByURL(options);
|
|
409
576
|
url = absoluteURL(url, options.domain);
|
|
410
577
|
|
|
411
578
|
if (!url || !webmentions || !webmentions[url]) {
|
|
@@ -416,9 +583,10 @@ const getWebmentions = async (options, url, allowedTypes = {}) => {
|
|
|
416
583
|
webmentions[url]
|
|
417
584
|
// Filter webmentions by allowed response post types
|
|
418
585
|
.filter((entry) => {
|
|
419
|
-
return typeof
|
|
420
|
-
|
|
421
|
-
|
|
586
|
+
return typeof types === "object" && Object.keys(types).length
|
|
587
|
+
? types.includes(getType(entry))
|
|
588
|
+
: typeof types === "string"
|
|
589
|
+
? types === getType(entry)
|
|
422
590
|
: true;
|
|
423
591
|
})
|
|
424
592
|
// Sanitize content of webmentions against HTML limit
|
|
@@ -448,25 +616,28 @@ const getWebmentions = async (options, url, allowedTypes = {}) => {
|
|
|
448
616
|
);
|
|
449
617
|
};
|
|
450
618
|
|
|
451
|
-
|
|
619
|
+
/**
|
|
620
|
+
* @param {Object} eleventyConfig
|
|
621
|
+
* @param {Options} [options={}]
|
|
622
|
+
*/
|
|
623
|
+
export const eleventyCacheWebmentions = (eleventyConfig, options = {}) => {
|
|
452
624
|
options = Object.assign(defaults, options);
|
|
453
625
|
|
|
626
|
+
const byURL = webmentionsByURL(options);
|
|
627
|
+
const all = Object.values(byURL).reduce(
|
|
628
|
+
(array, webmentions) => [...array, ...webmentions],
|
|
629
|
+
[],
|
|
630
|
+
);
|
|
631
|
+
|
|
454
632
|
// Global Data
|
|
455
633
|
eleventyConfig.addGlobalData("webmentionsDefaults", defaults);
|
|
456
634
|
eleventyConfig.addGlobalData("webmentionsOptions", options);
|
|
457
|
-
|
|
458
|
-
eleventyConfig.addGlobalData("webmentionsByUrl",
|
|
459
|
-
|
|
460
|
-
await filteredWebmentions(options).then((filtered) =>
|
|
461
|
-
Object.values(filtered).reduce(
|
|
462
|
-
(array, webmentions) => [...array, ...webmentions],
|
|
463
|
-
[],
|
|
464
|
-
),
|
|
465
|
-
);
|
|
466
|
-
eleventyConfig.addGlobalData("webmentionsAll", unfiltered);
|
|
635
|
+
eleventyConfig.addGlobalData("webmentionsByURL", byURL);
|
|
636
|
+
eleventyConfig.addGlobalData("webmentionsByUrl", byURL);
|
|
637
|
+
eleventyConfig.addGlobalData("webmentionsAll", all);
|
|
467
638
|
|
|
468
639
|
// Liquid Filters
|
|
469
|
-
eleventyConfig.addLiquidFilter("getWebmentionsByType",
|
|
640
|
+
eleventyConfig.addLiquidFilter("getWebmentionsByType", getByTypes);
|
|
470
641
|
eleventyConfig.addLiquidFilter("getWebmentionsByTypes", getByTypes);
|
|
471
642
|
eleventyConfig.addLiquidFilter("getWebmentionPublished", getPublished);
|
|
472
643
|
eleventyConfig.addLiquidFilter("getWebmentionReceived", getReceived);
|
|
@@ -477,7 +648,7 @@ const eleventyCacheWebmentions = (eleventyConfig, options = {}) => {
|
|
|
477
648
|
eleventyConfig.addLiquidFilter("getWebmentionType", getType);
|
|
478
649
|
|
|
479
650
|
// Nunjucks Filters
|
|
480
|
-
eleventyConfig.addNunjucksFilter("getWebmentionsByType",
|
|
651
|
+
eleventyConfig.addNunjucksFilter("getWebmentionsByType", getByTypes);
|
|
481
652
|
eleventyConfig.addNunjucksFilter("getWebmentionsByTypes", getByTypes);
|
|
482
653
|
eleventyConfig.addNunjucksFilter("getWebmentionPublished", getPublished);
|
|
483
654
|
eleventyConfig.addNunjucksFilter("getWebmentionReceived", getReceived);
|
|
@@ -488,28 +659,4 @@ const eleventyCacheWebmentions = (eleventyConfig, options = {}) => {
|
|
|
488
659
|
eleventyConfig.addNunjucksFilter("getWebmentionType", getType);
|
|
489
660
|
};
|
|
490
661
|
|
|
491
|
-
|
|
492
|
-
module.exports.defaults = defaults;
|
|
493
|
-
module.exports.filteredWebmentions = filteredWebmentions;
|
|
494
|
-
module.exports.webmentionsByUrl = filteredWebmentions;
|
|
495
|
-
module.exports.fetchWebmentions = fetchWebmentions;
|
|
496
|
-
module.exports.performFetch = performFetch;
|
|
497
|
-
module.exports.getWebmentions = getWebmentions;
|
|
498
|
-
module.exports.getByType = getByType;
|
|
499
|
-
module.exports.getWebmentionsByType = getByType;
|
|
500
|
-
module.exports.getByTypes = getByTypes;
|
|
501
|
-
module.exports.getWebmentionsByTypes = getByTypes;
|
|
502
|
-
module.exports.getPublished = getPublished;
|
|
503
|
-
module.exports.getWebmentionPublished = getPublished;
|
|
504
|
-
module.exports.getReceived = getReceived;
|
|
505
|
-
module.exports.getWebmentionReceived = getReceived;
|
|
506
|
-
module.exports.getContent = getContent;
|
|
507
|
-
module.exports.getWebmentionContent = getContent;
|
|
508
|
-
module.exports.getSource = getSource;
|
|
509
|
-
module.exports.getWebmentionSource = getSource;
|
|
510
|
-
module.exports.getURL = getURL;
|
|
511
|
-
module.exports.getWebmentionURL = getURL;
|
|
512
|
-
module.exports.getTarget = getTarget;
|
|
513
|
-
module.exports.getWebmentionTarget = getTarget;
|
|
514
|
-
module.exports.getType = getType;
|
|
515
|
-
module.exports.getWebmentionType = getType;
|
|
662
|
+
export default eleventyCacheWebmentions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const{AssetCache}=require("@11ty/eleventy-fetch"),{styleText}=require("node:util"),sanitizeHTML=require("sanitize-html"),defaults={refresh:!1,duration:"1d",uniqueKey:"webmentions",cacheDirectory:void 0,allowedHTML:{allowedTags:["a","b","em","i","strong"],allowedAttributes:{a:["href"]}},allowlist:[],blocklist:[],urlReplacements:{},maximumHtmlLength:1e3,maximumHtmlText:"mentioned this in"},absoluteURL=(url,domain)=>{try{return new URL(url,domain).toString()}catch{return console.error(`Trying to convert ${styleText("bold",url)} to be an absolute url with base ${styleText("bold",domain)} and failed.`),url}},baseURL=url=>url.split("#")[0].split("?")[0],fixURL=(url,urlReplacements)=>Object.entries(urlReplacements).reduce((accumulator,[key,value])=>{const regex=new RegExp(key,"g");return accumulator.replace(regex,value)},url),hostname=url=>typeof url=="string"&&url.includes("//")?new URL(url).hostname:url,epoch=date=>new Date(date).getTime(),removeDuplicates=webmentions=>[...webmentions.reduce((map,webmention)=>{const key=webmention==null?webmention:getSource(webmention);return map.has(key)||map.set(key,webmention),map},new Map).values()],getPublished=webmention=>webmention?.data?.published||webmention.published||webmention["wm-received"]||webmention.verified_date,getReceived=webmention=>webmention["wm-received"]||webmention.verified_date||webmention.published||webmention?.data?.published,getContent=webmention=>webmention?.contentSanitized||webmention?.content?.html||webmention?.content?.value||webmention?.content||webmention?.data?.content||"",getSource=webmention=>webmention["wm-source"]||webmention.source||webmention?.data?.url||webmention.url,getURL=webmention=>webmention?.data?.url||webmention.url||webmention["wm-source"]||webmention.source,getTarget=webmention=>webmention["wm-target"]||webmention.target,getType=webmention=>webmention["wm-property"]||webmention?.activity?.type||webmention.type,getByTypes=(webmentions,types)=>webmentions.filter(webmention=>typeof types=="string"?types===getType(webmention):types.includes(getType(webmention))),processBlocklist=(webmentions,blocklist)=>webmentions.filter(webmention=>{let url=getSource(webmention),source=getSource(webmention);for(let blocklistURL of blocklist)if(url.includes(blocklistURL.replace(/\/?$/,"/"))||source.includes(blocklistURL.replace(/\/?$/,"/")))return!1;return!0}),processAllowlist=(webmentions,allowlist)=>webmentions.filter(webmention=>{let url=getSource(webmention),source=getSource(webmention);for(let allowlistURL of allowlist)if(url.includes(allowlistURL.replace(/\/?$/,"/"))||source.includes(allowlistURL.replace(/\/?$/,"/")))return!0;return!1}),fetchWebmentions=async(options,webmentions,url)=>await fetch(url).then(async response=>{if(!response.ok)return Promise.reject(response);const feed=await response.json();return options.key in feed?(webmentions=feed[options.key].concat(webmentions),webmentions=removeDuplicates(webmentions),options.blocklist.length&&(webmentions=processBlocklist(webmentions,options.blocklist)),options.allowlist.length&&(webmentions=processAllowlist(webmentions,options.allowlist)),webmentions=webmentions.sort((a,b)=>epoch(getReceived(b))-epoch(getReceived(a))),{found:feed[options.key].length,webmentions}):(console.log(`${styleText("grey",`[${hostname(options.domain)}]`)} ${options.key} was not found as a key in the response from ${styleText("bold",hostname(options.feed))}!`),Promise.reject(response))}).catch(error=>(console.warn(`${styleText("grey",`[${hostname(options.domain)}]`)} Something went wrong with your Webmention request to ${styleText("bold",hostname(options.feed))}!`),console.warn(error instanceof Error?error.message:error),{found:0,webmentions})),retrieveWebmentions=async options=>{if(!options.domain)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.");if(!options.feed)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.");if(!options.key)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.");let asset=new AssetCache(options.uniqueKey||`webmentions-${hostname(options.domain)}`,options.cacheDirectory),webmentions=[];asset.isCacheValid("9001y")&&!options.refresh&&(webmentions=await asset.getCachedValue());const webmentionsCachedLength=webmentions.length;if(!asset.isCacheValid(options.refresh?"0s":options.duration)){const performanceStart=process.hrtime(),since=webmentions.length?getReceived(webmentions[0]):!1,url=`${options.feed}${since?`${options.feed.includes("?")?"&":"?"}since=${since}`:""}`;if(url.includes("https://webmention.io")){const urlObject=new URL(url),perPage=Number(urlObject.searchParams.get("per-page"))||1e3;urlObject.searchParams.delete("per-page");let page=0;for(;;){const urlPaginated=urlObject.href+`&per-page=${perPage}&page=${page}`,fetched=await fetchWebmentions(options,webmentions,urlPaginated);if(!fetched&&!fetched.found&&!fetched.webmentions||fetched.found===0||(webmentions=fetched.webmentions,fetched.found<perPage))break;page+=1,await new Promise(resolve=>setTimeout(resolve,1e3))}}else webmentions=(await fetchWebmentions(options,webmentions,url)).webmentions;options.blocklist.length&&(webmentions=processBlocklist(webmentions,options.blocklist)),options.allowlist.length&&(webmentions=processAllowlist(webmentions,options.allowlist)),await asset.save(webmentions,"json");const performance=process.hrtime(performanceStart);webmentionsCachedLength<webmentions.length&&console.log(`${styleText("grey",`[${hostname(options.domain)}]`)} ${styleText("bold",String(webmentions.length-webmentionsCachedLength))} new Webmentions fetched into cache in ${styleText("bold",(performance[0]+performance[1]/1e9).toFixed(3)+" seconds")}.`)}return webmentions},WEBMENTIONS={},webmentionsByURL=async options=>(Object.keys(WEBMENTIONS).length||(await retrieveWebmentions(options)).forEach(webmention=>{let url=baseURL(fixURL(getTarget(webmention).replace(/\/?$/,"/"),options.urlReplacements));WEBMENTIONS[url]||(WEBMENTIONS[url]=[]),WEBMENTIONS[url].push(webmention)}),WEBMENTIONS),getWebmentions=async(options,url,types=[])=>{const webmentions=await webmentionsByURL(options);return url=absoluteURL(url,options.domain),!url||!webmentions||!webmentions[url]?[]:webmentions[url].filter(entry=>typeof types=="object"&&Object.keys(types).length?types.includes(getType(entry)):typeof types=="string"?types===getType(entry):!0).map(entry=>{const html=getContent(entry);return html.length&&(entry.contentSanitized=sanitizeHTML(html,options.allowedHTML),html.length>options.maximumHtmlLength&&(entry.contentSanitized=`${options.maximumHtmlText} <a href="${getSource(entry)}">${getSource(entry)}</a>`)),entry}).sort((a,b)=>epoch(getPublished(a))-epoch(getPublished(b)))},eleventyCacheWebmentions=(eleventyConfig,options={})=>{options=Object.assign(defaults,options);const byURL=webmentionsByURL(options),all=Object.values(byURL).reduce((array,webmentions)=>[...array,...webmentions],[]);eleventyConfig.addGlobalData("webmentionsDefaults",defaults),eleventyConfig.addGlobalData("webmentionsOptions",options),eleventyConfig.addGlobalData("webmentionsByURL",byURL),eleventyConfig.addGlobalData("webmentionsByUrl",byURL),eleventyConfig.addGlobalData("webmentionsAll",all),eleventyConfig.addLiquidFilter("getWebmentionsByType",getByTypes),eleventyConfig.addLiquidFilter("getWebmentionsByTypes",getByTypes),eleventyConfig.addLiquidFilter("getWebmentionPublished",getPublished),eleventyConfig.addLiquidFilter("getWebmentionReceived",getReceived),eleventyConfig.addLiquidFilter("getWebmentionContent",getContent),eleventyConfig.addLiquidFilter("getWebmentionSource",getSource),eleventyConfig.addLiquidFilter("getWebmentionURL",getURL),eleventyConfig.addLiquidFilter("getWebmentionTarget",getTarget),eleventyConfig.addLiquidFilter("getWebmentionType",getType),eleventyConfig.addNunjucksFilter("getWebmentionsByType",getByTypes),eleventyConfig.addNunjucksFilter("getWebmentionsByTypes",getByTypes),eleventyConfig.addNunjucksFilter("getWebmentionPublished",getPublished),eleventyConfig.addNunjucksFilter("getWebmentionReceived",getReceived),eleventyConfig.addNunjucksFilter("getWebmentionContent",getContent),eleventyConfig.addNunjucksFilter("getWebmentionSource",getSource),eleventyConfig.addNunjucksFilter("getWebmentionURL",getURL),eleventyConfig.addNunjucksFilter("getWebmentionTarget",getTarget),eleventyConfig.addNunjucksFilter("getWebmentionType",getType)};module.exports=eleventyCacheWebmentions,module.exports.defaults=defaults,module.exports.getPublished=getPublished,module.exports.getWebmentionPublished=getPublished,module.exports.getReceived=getReceived,module.exports.getWebmentionReceived=getReceived,module.exports.getContent=getContent,module.exports.getWebmentionContent=getContent,module.exports.getSource=getSource,module.exports.getWebmentionSource=getSource,module.exports.getURL=getURL,module.exports.getWebmentionURL=getURL,module.exports.getTarget=getTarget,module.exports.getWebmentionTarget=getTarget,module.exports.getType=getType,module.exports.getWebmentionType=getType,module.exports.getByTypes=getByTypes,module.exports.getByType=getByTypes,module.exports.getWebmentionsByTypes=getByTypes,module.exports.getWebmentionsByType=getByTypes,module.exports.processBlocklist=processBlocklist,module.exports.processWebmentionBlocklist=processBlocklist,module.exports.processWebmentionsBlocklist=processBlocklist,module.exports.processAllowlist=processAllowlist,module.exports.processWebmentionAllowlist=processAllowlist,module.exports.processWebmentionsAllowlist=processAllowlist,module.exports.fetchWebmentions=fetchWebmentions,module.exports.retrieveWebmentions=retrieveWebmentions,module.exports.webmentionsByURL=webmentionsByURL,module.exports.webmentionsByUrl=webmentionsByURL,module.exports.filteredWebmentions=webmentionsByURL,module.exports.getWebmentions=getWebmentions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AssetCache}from"@11ty/eleventy-fetch";import{styleText}from"node:util";import sanitizeHTML from"sanitize-html";export const defaults={refresh:!1,duration:"1d",uniqueKey:"webmentions",cacheDirectory:void 0,allowedHTML:{allowedTags:["a","b","em","i","strong"],allowedAttributes:{a:["href"]}},allowlist:[],blocklist:[],urlReplacements:{},maximumHtmlLength:1e3,maximumHtmlText:"mentioned this in"};const absoluteURL=(url,domain)=>{try{return new URL(url,domain).toString()}catch{return console.error(`Trying to convert ${styleText("bold",url)} to be an absolute url with base ${styleText("bold",domain)} and failed.`),url}},baseURL=url=>url.split("#")[0].split("?")[0],fixURL=(url,urlReplacements)=>Object.entries(urlReplacements).reduce((accumulator,[key,value])=>{const regex=new RegExp(key,"g");return accumulator.replace(regex,value)},url),hostname=url=>typeof url=="string"&&url.includes("//")?new URL(url).hostname:url,epoch=date=>new Date(date).getTime(),removeDuplicates=webmentions=>[...webmentions.reduce((map,webmention)=>{const key=webmention==null?webmention:getSource(webmention);return map.has(key)||map.set(key,webmention),map},new Map).values()];export const getPublished=webmention=>webmention?.data?.published||webmention.published||webmention["wm-received"]||webmention.verified_date,getWebmentionPublished=getPublished,getReceived=webmention=>webmention["wm-received"]||webmention.verified_date||webmention.published||webmention?.data?.published,getWebmentionReceived=getReceived,getContent=webmention=>webmention?.contentSanitized||webmention?.content?.html||webmention?.content?.value||webmention?.content||webmention?.data?.content||"",getWebmentionContent=getContent,getSource=webmention=>webmention["wm-source"]||webmention.source||webmention?.data?.url||webmention.url,getWebmentionSource=getSource,getURL=webmention=>webmention?.data?.url||webmention.url||webmention["wm-source"]||webmention.source,getWebmentionURL=getURL,getTarget=webmention=>webmention["wm-target"]||webmention.target,getWebmentionTarget=getTarget,getType=webmention=>webmention["wm-property"]||webmention?.activity?.type||webmention.type,getWebmentionType=getType,getByTypes=(webmentions,types)=>webmentions.filter(webmention=>typeof types=="string"?types===getType(webmention):types.includes(getType(webmention))),getByType=getByTypes,getWebmentionsByTypes=getByTypes,getWebmentionsByType=getByTypes,processBlocklist=(webmentions,blocklist)=>webmentions.filter(webmention=>{let url=getSource(webmention),source=getSource(webmention);for(let blocklistURL of blocklist)if(url.includes(blocklistURL.replace(/\/?$/,"/"))||source.includes(blocklistURL.replace(/\/?$/,"/")))return!1;return!0}),processWebmentionBlocklist=processBlocklist,processWebmentionsBlocklist=processBlocklist,processAllowlist=(webmentions,allowlist)=>webmentions.filter(webmention=>{let url=getSource(webmention),source=getSource(webmention);for(let allowlistURL of allowlist)if(url.includes(allowlistURL.replace(/\/?$/,"/"))||source.includes(allowlistURL.replace(/\/?$/,"/")))return!0;return!1}),processWebmentionAllowlist=processAllowlist,processWebmentionsAllowlist=processAllowlist,fetchWebmentions=async(options,webmentions,url)=>await fetch(url).then(async response=>{if(!response.ok)return Promise.reject(response);const feed=await response.json();return options.key in feed?(webmentions=feed[options.key].concat(webmentions),webmentions=removeDuplicates(webmentions),options.blocklist.length&&(webmentions=processBlocklist(webmentions,options.blocklist)),options.allowlist.length&&(webmentions=processAllowlist(webmentions,options.allowlist)),webmentions=webmentions.sort((a,b)=>epoch(getReceived(b))-epoch(getReceived(a))),{found:feed[options.key].length,webmentions}):(console.log(`${styleText("grey",`[${hostname(options.domain)}]`)} ${options.key} was not found as a key in the response from ${styleText("bold",hostname(options.feed))}!`),Promise.reject(response))}).catch(error=>(console.warn(`${styleText("grey",`[${hostname(options.domain)}]`)} Something went wrong with your Webmention request to ${styleText("bold",hostname(options.feed))}!`),console.warn(error instanceof Error?error.message:error),{found:0,webmentions})),retrieveWebmentions=async options=>{if(!options.domain)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.");if(!options.feed)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.");if(!options.key)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.");let asset=new AssetCache(options.uniqueKey||`webmentions-${hostname(options.domain)}`,options.cacheDirectory),webmentions=[];asset.isCacheValid("9001y")&&!options.refresh&&(webmentions=await asset.getCachedValue());const webmentionsCachedLength=webmentions.length;if(!asset.isCacheValid(options.refresh?"0s":options.duration)){const performanceStart=process.hrtime(),since=webmentions.length?getReceived(webmentions[0]):!1,url=`${options.feed}${since?`${options.feed.includes("?")?"&":"?"}since=${since}`:""}`;if(url.includes("https://webmention.io")){const urlObject=new URL(url),perPage=Number(urlObject.searchParams.get("per-page"))||1e3;urlObject.searchParams.delete("per-page");let page=0;for(;;){const urlPaginated=urlObject.href+`&per-page=${perPage}&page=${page}`,fetched=await fetchWebmentions(options,webmentions,urlPaginated);if(!fetched&&!fetched.found&&!fetched.webmentions||fetched.found===0||(webmentions=fetched.webmentions,fetched.found<perPage))break;page+=1,await new Promise(resolve=>setTimeout(resolve,1e3))}}else webmentions=(await fetchWebmentions(options,webmentions,url)).webmentions;options.blocklist.length&&(webmentions=processBlocklist(webmentions,options.blocklist)),options.allowlist.length&&(webmentions=processAllowlist(webmentions,options.allowlist)),await asset.save(webmentions,"json");const performance=process.hrtime(performanceStart);webmentionsCachedLength<webmentions.length&&console.log(`${styleText("grey",`[${hostname(options.domain)}]`)} ${styleText("bold",String(webmentions.length-webmentionsCachedLength))} new Webmentions fetched into cache in ${styleText("bold",(performance[0]+performance[1]/1e9).toFixed(3)+" seconds")}.`)}return webmentions};const WEBMENTIONS={};export const webmentionsByURL=async options=>(Object.keys(WEBMENTIONS).length||(await retrieveWebmentions(options)).forEach(webmention=>{let url=baseURL(fixURL(getTarget(webmention).replace(/\/?$/,"/"),options.urlReplacements));WEBMENTIONS[url]||(WEBMENTIONS[url]=[]),WEBMENTIONS[url].push(webmention)}),WEBMENTIONS),webmentionsByUrl=webmentionsByURL,filteredWebmentions=webmentionsByURL,getWebmentions=async(options,url,types=[])=>{const webmentions=await webmentionsByURL(options);return url=absoluteURL(url,options.domain),!url||!webmentions||!webmentions[url]?[]:webmentions[url].filter(entry=>typeof types=="object"&&Object.keys(types).length?types.includes(getType(entry)):typeof types=="string"?types===getType(entry):!0).map(entry=>{const html=getContent(entry);return html.length&&(entry.contentSanitized=sanitizeHTML(html,options.allowedHTML),html.length>options.maximumHtmlLength&&(entry.contentSanitized=`${options.maximumHtmlText} <a href="${getSource(entry)}">${getSource(entry)}</a>`)),entry}).sort((a,b)=>epoch(getPublished(a))-epoch(getPublished(b)))},eleventyCacheWebmentions=(eleventyConfig,options={})=>{options=Object.assign(defaults,options);const byURL=webmentionsByURL(options),all=Object.values(byURL).reduce((array,webmentions)=>[...array,...webmentions],[]);eleventyConfig.addGlobalData("webmentionsDefaults",defaults),eleventyConfig.addGlobalData("webmentionsOptions",options),eleventyConfig.addGlobalData("webmentionsByURL",byURL),eleventyConfig.addGlobalData("webmentionsByUrl",byURL),eleventyConfig.addGlobalData("webmentionsAll",all),eleventyConfig.addLiquidFilter("getWebmentionsByType",getByTypes),eleventyConfig.addLiquidFilter("getWebmentionsByTypes",getByTypes),eleventyConfig.addLiquidFilter("getWebmentionPublished",getPublished),eleventyConfig.addLiquidFilter("getWebmentionReceived",getReceived),eleventyConfig.addLiquidFilter("getWebmentionContent",getContent),eleventyConfig.addLiquidFilter("getWebmentionSource",getSource),eleventyConfig.addLiquidFilter("getWebmentionURL",getURL),eleventyConfig.addLiquidFilter("getWebmentionTarget",getTarget),eleventyConfig.addLiquidFilter("getWebmentionType",getType),eleventyConfig.addNunjucksFilter("getWebmentionsByType",getByTypes),eleventyConfig.addNunjucksFilter("getWebmentionsByTypes",getByTypes),eleventyConfig.addNunjucksFilter("getWebmentionPublished",getPublished),eleventyConfig.addNunjucksFilter("getWebmentionReceived",getReceived),eleventyConfig.addNunjucksFilter("getWebmentionContent",getContent),eleventyConfig.addNunjucksFilter("getWebmentionSource",getSource),eleventyConfig.addNunjucksFilter("getWebmentionURL",getURL),eleventyConfig.addNunjucksFilter("getWebmentionTarget",getTarget),eleventyConfig.addNunjucksFilter("getWebmentionType",getType)};export default eleventyCacheWebmentions;
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
js.configs.recommended,
|
|
5
|
+
{
|
|
6
|
+
files: ["src/**/*.js"],
|
|
7
|
+
languageOptions: {
|
|
8
|
+
ecmaVersion: "latest",
|
|
9
|
+
},
|
|
10
|
+
rules: {
|
|
11
|
+
"no-process-env": 0,
|
|
12
|
+
"jsdoc/check-access": "warn",
|
|
13
|
+
"jsdoc/check-alignment": "warn",
|
|
14
|
+
"jsdoc/check-indentation": "warn",
|
|
15
|
+
"jsdoc/check-param-names": "warn",
|
|
16
|
+
"jsdoc/check-tag-names": "warn",
|
|
17
|
+
"jsdoc/check-types": "warn",
|
|
18
|
+
"jsdoc/implements-on-classes": "warn",
|
|
19
|
+
"jsdoc/no-undefined-types": "warn",
|
|
20
|
+
"jsdoc/require-jsdoc": [
|
|
21
|
+
"warn",
|
|
22
|
+
{
|
|
23
|
+
require: {
|
|
24
|
+
FunctionDeclaration: true,
|
|
25
|
+
MethodDefinition: true,
|
|
26
|
+
ClassDeclaration: true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
"jsdoc/require-param": "warn",
|
|
31
|
+
"jsdoc/require-param-type": "warn",
|
|
32
|
+
"jsdoc/require-returns": "warn",
|
|
33
|
+
"jsdoc/require-returns-type": "warn",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
];
|