nodebb-plugin-link-preview 1.0.2 → 1.0.3

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.
Files changed (2) hide show
  1. package/library.js +29 -40
  2. package/package.json +2 -1
package/library.js CHANGED
@@ -4,9 +4,12 @@ const winston = require.main.require('winston');
4
4
  const dns = require('dns');
5
5
 
6
6
  const { getLinkPreview } = require('link-preview-js');
7
+ const { load } = require('cheerio');
7
8
 
8
9
  const meta = require.main.require('./src/meta');
9
10
  const cache = require.main.require('./src/cache');
11
+ const posts = require.main.require('./src/posts');
12
+ const postsCache = require.main.require('./src/posts/cache');
10
13
 
11
14
  const controllers = require('./lib/controllers');
12
15
 
@@ -34,31 +37,30 @@ plugin.applyDefaults = async (data) => {
34
37
  return data;
35
38
  };
36
39
 
37
- async function process(content) {
38
- const anchorRegex = /<a\s+(?:[^>]*?\s+)?href=["']([^"']*)["'][^>]*>(.*?)<\/a>/g;
39
- const matches = [];
40
- let match;
41
-
40
+ async function process(content, opts) {
42
41
  const { embedHtml, embedImage, embedAudio, embedVideo } = await meta.settings.get('link-preview');
43
42
  if (![embedHtml, embedImage, embedAudio, embedVideo].some(prop => prop === 'on')) {
44
43
  return content;
45
44
  }
46
45
 
47
- // eslint-disable-next-line no-cond-assign
48
- while ((match = anchorRegex.exec(content)) !== null) {
49
- matches.push(match);
50
- }
46
+ const $ = load(content, null, false);
47
+ for (const anchor of $('a')) {
48
+ const $anchor = $(anchor);
49
+ const url = $anchor.attr('href');
51
50
 
52
- const previews = await Promise.all(matches.map(async (match) => {
53
- const anchor = match[1];
51
+ if ($anchor.hasClass('plugin-mentions-a')) {
52
+ break;
53
+ }
54
54
 
55
- const cached = cache.get(`link-preview:${anchor}`);
55
+ const cached = cache.get(`link-preview:${url}`);
56
56
  if (cached) {
57
- return await render(cached);
57
+ // eslint-disable-next-line no-await-in-loop
58
+ $anchor.replaceWith($(await render(cached)));
59
+ break;
58
60
  }
59
61
 
60
62
  // Generate the preview, but return false for now so as to not block response
61
- getLinkPreview(anchor, {
63
+ getLinkPreview(url, {
62
64
  resolveDNSHost: async url => new Promise((resolve, reject) => {
63
65
  const { hostname } = new URL(url);
64
66
  dns.lookup(hostname, (err, address) => {
@@ -84,36 +86,23 @@ async function process(content) {
84
86
 
85
87
  return false;
86
88
  },
87
- }).then((preview) => {
88
- const parsedUrl = new URL(anchor);
89
+ }).then(async (preview) => {
90
+ const parsedUrl = new URL(url);
89
91
  preview.hostname = parsedUrl.hostname;
90
92
 
91
93
  winston.verbose(`[link-preview] ${preview.url} (${preview.contentType}, cache: miss)`);
92
- cache.set(`link-preview:${anchor}`, preview);
94
+ cache.set(`link-preview:${url}`, preview);
95
+
96
+ if (opts.hasOwnProperty('pid') && await posts.exists(opts.pid)) {
97
+ postsCache.del(String(opts.pid));
98
+ }
93
99
  }).catch(() => {
94
- winston.verbose(`[link-preview] ${anchor} (invalid, cache: miss)`);
95
- cache.set(`link-preview:${anchor}`, {
96
- url: anchor,
97
- });
100
+ winston.verbose(`[link-preview] ${url} (invalid, cache: miss)`);
101
+ cache.set(`link-preview:${url}`, { url });
98
102
  });
103
+ }
99
104
 
100
- return false;
101
- }));
102
-
103
- // Replace match with embed
104
- previews.reverse();
105
- matches.reverse();
106
- previews.forEach((preview, idx) => {
107
- if (preview) {
108
- const match = matches[idx];
109
- const { index } = match;
110
- const { length } = match[0];
111
-
112
- content = `${content.substring(0, index)}${preview}${content.substring(index + length)}`;
113
- }
114
- });
115
-
116
- return content;
105
+ return $.html();
117
106
  }
118
107
 
119
108
  async function render(preview) {
@@ -147,9 +136,9 @@ async function render(preview) {
147
136
 
148
137
  plugin.onParse = async (payload) => {
149
138
  if (typeof payload === 'string') { // raw
150
- payload = await process(payload);
139
+ payload = await process(payload, {});
151
140
  } else if (payload && payload.postData && payload.postData.content) { // post
152
- payload.postData.content = await process(payload.postData.content);
141
+ payload.postData.content = await process(payload.postData.content, { pid: payload.postData.pid });
153
142
  }
154
143
 
155
144
  return payload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-link-preview",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A starter kit for quickly creating NodeBB plugins",
5
5
  "main": "library.js",
6
6
  "repository": {
@@ -43,6 +43,7 @@
43
43
  "lint-staged": "13.2.2"
44
44
  },
45
45
  "dependencies": {
46
+ "cheerio": "^1.0.0-rc.12",
46
47
  "link-preview-js": "^3.0.4"
47
48
  }
48
49
  }