nodebb-plugin-onekite-discord 1.0.13 → 1.0.14
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/library.js +34 -55
- package/package.json +1 -1
- package/plugin.json +1 -1
package/library.js
CHANGED
|
@@ -2,36 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* - NodeBB rendered: text(url) or text (url)
|
|
13
|
-
* - Bare URLs: https://... or http://... or www.example.com
|
|
14
|
-
*
|
|
15
|
-
* Note: We'll output masked links in embed fields, where Discord supports them.
|
|
8
|
+
* Flatten any link-like markup to plain URLs so Discord auto-linkifies them.
|
|
9
|
+
* Supported:
|
|
10
|
+
* - [text](url)
|
|
11
|
+
* - <a href="url">text</a>
|
|
12
|
+
* - text(url) / text (url)
|
|
13
|
+
* - bare URLs and www.*
|
|
16
14
|
*/
|
|
17
|
-
function
|
|
18
|
-
if (!str || typeof str !== 'string') return
|
|
19
|
-
|
|
20
|
-
const links = [];
|
|
21
|
-
const seen = new Set();
|
|
15
|
+
function flattenLinksToUrls(str) {
|
|
16
|
+
if (!str || typeof str !== 'string') return str;
|
|
22
17
|
|
|
23
18
|
const normalizeUrl = (u) => {
|
|
24
|
-
if (!u) return
|
|
19
|
+
if (!u) return u;
|
|
25
20
|
let url = String(u).trim();
|
|
26
21
|
url = url.replace(/^<(.+)>$/, '$1');
|
|
27
22
|
url = url.replace(/^https:\//i, 'https://');
|
|
28
23
|
url = url.replace(/^http:\//i, 'http://');
|
|
29
24
|
if (/^www\./i.test(url)) url = 'https://' + url;
|
|
30
|
-
// Very small sanity check
|
|
31
|
-
if (!/^https?:\/\//i.test(url)) return null;
|
|
32
25
|
return url;
|
|
33
26
|
};
|
|
34
27
|
|
|
28
|
+
// HTML links -> URL
|
|
29
|
+
str = str.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>.*?<\/a>/gi, (_m, href) => {
|
|
30
|
+
return normalizeUrl(href);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Markdown [text](url) -> URL
|
|
34
|
+
str = str.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, _text, url) => {
|
|
35
|
+
return normalizeUrl(url);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// text(url) or text (url) -> URL
|
|
39
|
+
str = str.replace(/([^\n\r()]{1,200}?)\s*\((https?:\/\/[^)\s]+|www\.[^)\\s]+)\)/g, (_m, _text, url) => {
|
|
40
|
+
return normalizeUrl(url);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return str;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
;
|
|
47
|
+
|
|
35
48
|
const push = (text, url) => {
|
|
36
49
|
const u = normalizeUrl(url);
|
|
37
50
|
if (!u) return;
|
|
@@ -72,46 +85,12 @@ function extractDiscordLinks(str) {
|
|
|
72
85
|
return links;
|
|
73
86
|
}
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
* Remove/flatten link markup from text for embed.description readability.
|
|
77
|
-
* - [text](url) -> text
|
|
78
|
-
* - <a href="url">text</a> -> text
|
|
79
|
-
* - text(url) -> text
|
|
80
|
-
* - leaves bare URLs as-is (optional), but we can also remove them if desired.
|
|
81
|
-
*/
|
|
82
|
-
function stripLinkMarkup(str) {
|
|
83
|
-
if (!str || typeof str !== 'string') return str;
|
|
84
|
-
|
|
85
|
-
// HTML links -> text
|
|
86
|
-
str = str.replace(/<a\s+[^>]*href=["'][^"']+["'][^>]*>(.*?)<\/a>/gi, (_m, text) => text);
|
|
87
|
-
|
|
88
|
-
// Markdown masked -> text
|
|
89
|
-
str = str.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, text) => text);
|
|
90
|
-
|
|
91
|
-
// NodeBB rendered -> text
|
|
92
|
-
str = str.replace(/([^\n\r()]{1,200}?)\s*\((https?:\/\/[^)\s]+|www\.[^)\s]+)\)/g, (_m, text) => String(text).trim());
|
|
88
|
+
?)\s*\((https?:\/\/[^)\s]+|www\.[^)\s]+)\)/g, (_m, text) => String(text).trim());
|
|
93
89
|
|
|
94
90
|
return str;
|
|
95
91
|
}
|
|
96
92
|
|
|
97
|
-
|
|
98
|
-
* Normalize links for Discord embeds.
|
|
99
|
-
* Discord does NOT support masked links in embed descriptions.
|
|
100
|
-
* NodeBB may already render links as: texte(url)
|
|
101
|
-
* We always output a plain URL so Discord auto-linkifies it.
|
|
102
|
-
*/
|
|
103
|
-
function formatDiscordLinks(str) {
|
|
104
|
-
if (!str || typeof str !== 'string') return str;
|
|
105
|
-
|
|
106
|
-
const normalizeUrl = (u) => {
|
|
107
|
-
if (!u) return u;
|
|
108
|
-
let url = String(u).trim();
|
|
109
|
-
url = url.replace(/^<(.+)>$/, '$1');
|
|
110
|
-
url = url.replace(/^https:\//i, 'https://');
|
|
111
|
-
url = url.replace(/^http:\//i, 'http://');
|
|
112
|
-
if (/^www\./i.test(url)) url = 'https://' + url;
|
|
113
|
-
return url;
|
|
114
|
-
};
|
|
93
|
+
;
|
|
115
94
|
|
|
116
95
|
// HTML <a href="...">...</a> -> URL
|
|
117
96
|
str = str.replace(/<a\s+[^>]*href=["']([^"']+)["'][^>]*>.*?<\/a>/gi, (_m, href) => {
|
|
@@ -352,7 +331,7 @@ for (let i = 0; i < extractedLinks.length && linkFields.length < maxFields; i +=
|
|
|
352
331
|
const embedTitle = `${replyIcon}${safeTitle} – ${username}`.slice(0, 256);
|
|
353
332
|
|
|
354
333
|
// Embed title becomes clickable via embed.url
|
|
355
|
-
return { topicData, content: '', embed: { title: embedTitle, url: targetUrl, description:
|
|
334
|
+
return { topicData, content: '', embed: { title: embedTitle, url: targetUrl, description: flattenLinksToUrls(excerpt || ''), fields: linkFields } };
|
|
356
335
|
}
|
|
357
336
|
|
|
358
337
|
function extractTidPid(data) {
|
package/package.json
CHANGED
package/plugin.json
CHANGED