@chrisburnell/eleventy-cache-webmentions 0.2.0 → 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/eleventy-cache-webmentions.js +37 -22
- package/package.json +1 -1
|
@@ -37,6 +37,26 @@ const epoch = (value) => {
|
|
|
37
37
|
return new Date(value).getTime()
|
|
38
38
|
}
|
|
39
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
|
+
|
|
40
60
|
module.exports = (eleventyConfig, options = {}) => {
|
|
41
61
|
options = Object.assign(
|
|
42
62
|
{
|
|
@@ -68,15 +88,15 @@ module.exports = (eleventyConfig, options = {}) => {
|
|
|
68
88
|
// If there is a cached file but it is outside of expiry, fetch fresh
|
|
69
89
|
// results since the most recent webmention
|
|
70
90
|
if (!asset.isCacheValid(options.duration)) {
|
|
71
|
-
const since = webmentions.length ? webmentions[0]
|
|
72
|
-
const url = `${options.feed}${since
|
|
91
|
+
const since = webmentions.length ? getPublished(webmentions[0]) : false
|
|
92
|
+
const url = `${options.feed}${since ? `${options.feed.includes("?") ? "&" : "?"}since=${since}` : ""}`
|
|
73
93
|
await fetch(url)
|
|
74
94
|
.then(async (response) => {
|
|
75
95
|
if (response.ok) {
|
|
76
96
|
const feed = await response.json()
|
|
77
97
|
if (feed[options.key].length) {
|
|
78
|
-
webmentions = uniqBy([...feed[options.key], ...webmentions], (
|
|
79
|
-
return
|
|
98
|
+
webmentions = uniqBy([...feed[options.key], ...webmentions], (entry) => {
|
|
99
|
+
return getSource(entry)
|
|
80
100
|
})
|
|
81
101
|
console.log(`[${hostname(options.domain)}] ${feed[options.key].length} new Webmentions fetched into cache.`)
|
|
82
102
|
}
|
|
@@ -97,10 +117,10 @@ module.exports = (eleventyConfig, options = {}) => {
|
|
|
97
117
|
const rawWebmentions = await fetchWebmentions()
|
|
98
118
|
let webmentions = {}
|
|
99
119
|
|
|
100
|
-
// Sort Webmentions into groups by
|
|
120
|
+
// Sort Webmentions into groups by target
|
|
101
121
|
rawWebmentions.forEach((webmention) => {
|
|
102
122
|
// Get the target of the Webmention and fix it up
|
|
103
|
-
let url = baseUrl(fixUrl((webmention
|
|
123
|
+
let url = baseUrl(fixUrl(getTarget(webmention).replace(/\/?$/, "/"), options.urlReplacements))
|
|
104
124
|
|
|
105
125
|
if (!webmentions[url]) {
|
|
106
126
|
webmentions[url] = []
|
|
@@ -111,8 +131,8 @@ module.exports = (eleventyConfig, options = {}) => {
|
|
|
111
131
|
|
|
112
132
|
// Sort Webmentions in groups by url and remove duplicates by `url`
|
|
113
133
|
for (let url in webmentions) {
|
|
114
|
-
webmentions[url] = uniqBy(webmentions[url], (
|
|
115
|
-
return
|
|
134
|
+
webmentions[url] = uniqBy(webmentions[url], (entry) => {
|
|
135
|
+
return getSource(entry)
|
|
116
136
|
})
|
|
117
137
|
}
|
|
118
138
|
|
|
@@ -130,31 +150,26 @@ module.exports = (eleventyConfig, options = {}) => {
|
|
|
130
150
|
const results = webmentions[url]
|
|
131
151
|
// filter webmentions by allowed response post types
|
|
132
152
|
.filter((entry) => {
|
|
133
|
-
return typeof allowedTypes === "object" && Object.keys(allowedTypes).length ? allowedTypes.includes(entry
|
|
134
|
-
})
|
|
135
|
-
// remove webmentions without an author name
|
|
136
|
-
.filter((entry) => {
|
|
137
|
-
const { author } = entry
|
|
138
|
-
return !!author && !!author.name
|
|
153
|
+
return typeof allowedTypes === "object" && Object.keys(allowedTypes).length ? allowedTypes.includes(getType(entry)) : true
|
|
139
154
|
})
|
|
140
|
-
// sanitize content of webmentions
|
|
155
|
+
// sanitize content of webmentions against HTML limit
|
|
141
156
|
.map((entry) => {
|
|
142
|
-
if (!("content" in entry)) {
|
|
157
|
+
if (!("content" in entry) || !("data" in entry)) {
|
|
143
158
|
return entry
|
|
144
159
|
}
|
|
145
|
-
const
|
|
160
|
+
const html = getContent(entry)
|
|
146
161
|
if (html && html.length > options.maximumHtmlLength) {
|
|
147
|
-
entry.content
|
|
162
|
+
entry.content = `${options.maximumHtmlText} <a href="${getSource(entry)}">${getSource(entry)}</a>`
|
|
148
163
|
} else if (Object.keys(options.allowedHTML).length) {
|
|
149
|
-
entry.content
|
|
164
|
+
entry.content = sanitizeHTML(html, options.allowedHTML)
|
|
150
165
|
} else {
|
|
151
|
-
entry.content
|
|
166
|
+
entry.content = html
|
|
152
167
|
}
|
|
153
168
|
return entry
|
|
154
169
|
})
|
|
155
|
-
// sort by
|
|
170
|
+
// sort by published
|
|
156
171
|
.sort((a, b) => {
|
|
157
|
-
return epoch(a
|
|
172
|
+
return epoch(getPublished(a)) - epoch(getPublished(b))
|
|
158
173
|
})
|
|
159
174
|
|
|
160
175
|
return results
|
package/package.json
CHANGED