@waline/vercel 1.15.1 → 1.16.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waline/vercel",
3
- "version": "1.15.1",
3
+ "version": "1.16.0",
4
4
  "description": "vercel server for waline comment system",
5
5
  "keywords": [
6
6
  "waline",
@@ -20,6 +20,7 @@
20
20
  "akismet": "^2.0.7",
21
21
  "deta": "^1.1.0",
22
22
  "dompurify": "^2.3.6",
23
+ "dy-node-ip2region": "^1.0.1",
23
24
  "fast-csv": "^4.3.6",
24
25
  "jsdom": "^19.0.0",
25
26
  "jsonwebtoken": "^8.5.1",
@@ -14,6 +14,7 @@ const {
14
14
  TCB_KEY,
15
15
  SECURE_DOMAINS,
16
16
  DISABLE_USERAGENT,
17
+ DISABLE_REGION,
17
18
  AVATAR_PROXY,
18
19
  GITHUB_TOKEN,
19
20
  DETA_PROJECT_KEY,
@@ -106,6 +107,7 @@ module.exports = {
106
107
  disallowIPList: [],
107
108
  secureDomains: SECURE_DOMAINS ? SECURE_DOMAINS.split(/\s*,\s*/) : undefined,
108
109
  disableUserAgent: DISABLE_USERAGENT && !isFalse(DISABLE_USERAGENT),
110
+ disableReigon: DISABLE_REGION && !isFalse(DISABLE_REGION),
109
111
  levels:
110
112
  !LEVELS || isFalse(LEVELS)
111
113
  ? false
@@ -5,7 +5,7 @@ const { getMarkdownParser } = require('../service/markdown');
5
5
 
6
6
  const markdownParser = getMarkdownParser();
7
7
  async function formatCmt(
8
- { ua, user_id, ...comment },
8
+ { ua, user_id, ip, ...comment },
9
9
  users = [],
10
10
  { avatarProxy },
11
11
  loginUser
@@ -41,8 +41,13 @@ async function formatCmt(
41
41
  delete comment.mail;
42
42
  } else {
43
43
  comment.orig = comment.comment;
44
+ comment.ip = ip;
44
45
  }
45
46
 
47
+ // administrator can always show region
48
+ if (isAdmin || !think.config('disableRegion')) {
49
+ comment.addr = await think.ip2region(ip, { depth: isAdmin ? 3 : 1 });
50
+ }
46
51
  comment.comment = markdownParser(comment.comment);
47
52
  return comment;
48
53
  }
@@ -88,6 +93,7 @@ module.exports = class extends BaseRest {
88
93
  'pid',
89
94
  'rid',
90
95
  'ua',
96
+ 'ip',
91
97
  'user_id',
92
98
  'sticky',
93
99
  ],
@@ -235,6 +241,7 @@ module.exports = class extends BaseRest {
235
241
  'pid',
236
242
  'rid',
237
243
  'ua',
244
+ 'ip',
238
245
  'user_id',
239
246
  'sticky',
240
247
  ],
@@ -264,6 +271,13 @@ module.exports = class extends BaseRest {
264
271
  ...comments.filter(({ rid, sticky }) => !rid && sticky),
265
272
  ...comments.filter(({ rid, sticky }) => !rid && !sticky),
266
273
  ].slice(pageOffset, pageOffset + pageSize);
274
+ const rootIds = {};
275
+ rootComments.forEach(({ objectId }) => {
276
+ rootIds[objectId] = true;
277
+ });
278
+ comments = comments.filter(
279
+ (cmt) => rootIds[cmt.objectId] || rootIds[cmt.rid]
280
+ );
267
281
  } else {
268
282
  rootComments = await this.modelInstance.select(
269
283
  { ...where, rid: undefined },
@@ -1,5 +1,9 @@
1
+ const ip2region = require('dy-node-ip2region');
2
+ const helper = require('think-helper');
1
3
  const preventMessage = 'PREVENT_NEXT_PROCESS';
2
4
 
5
+ const regionSearch = ip2region.create();
6
+
3
7
  module.exports = {
4
8
  prevent() {
5
9
  throw new Error(preventMessage);
@@ -18,4 +22,46 @@ module.exports = {
18
22
 
19
23
  return -1;
20
24
  },
25
+ promiseAllQueue(promises, taskNum) {
26
+ return new Promise((resolve, reject) => {
27
+ const ret = [];
28
+ let index = 0;
29
+ let count = 0;
30
+
31
+ function runTask() {
32
+ const idx = index;
33
+ index += 1;
34
+ if (index > promises.length) {
35
+ return Promise.resolve();
36
+ }
37
+
38
+ return promises[idx].then((data) => {
39
+ ret[idx] = data;
40
+ count += 1;
41
+ if (count === promises.length) {
42
+ resolve(ret);
43
+ }
44
+ return runTask();
45
+ }, reject);
46
+ }
47
+
48
+ for (let i = 0; i < taskNum; i++) {
49
+ runTask();
50
+ }
51
+ });
52
+ },
53
+ async ip2region(ip, { depth = 1 }) {
54
+ if (!ip) return '';
55
+
56
+ try {
57
+ const search = helper.promisify(regionSearch.btreeSearch, regionSearch);
58
+ const { region } = await search(ip);
59
+ const [,, province, city, isp] = region.split('|');
60
+ const address = Array.from(new Set([province, city, isp]));
61
+ return address.slice(0, depth).join(' ');
62
+ } catch(e) {
63
+ console.log(e);
64
+ return '';
65
+ }
66
+ }
21
67
  };
@@ -139,6 +139,7 @@ module.exports = class extends Base {
139
139
 
140
140
  // todo: query optimize
141
141
  const counts = [];
142
+ const countsPromise = [];
142
143
  for (let i = 0; i < options.group.length; i++) {
143
144
  const groupName = options.group[i];
144
145
  if (!where._complex || !Array.isArray(where._complex[groupName])) {
@@ -157,17 +158,21 @@ module.exports = class extends Base {
157
158
  _complex: undefined,
158
159
  [groupName]: where._complex[groupName][1][j],
159
160
  };
160
- const num = await this.count(groupWhere, {
161
+ const countPromise = this.count(groupWhere, {
161
162
  ...options,
162
163
  group: undefined,
164
+ }).then((num) => {
165
+ counts.push({
166
+ ...groupFlatValue,
167
+ [groupName]: where._complex[groupName][1][j],
168
+ count: num,
169
+ });
163
170
  });
164
- counts.push({
165
- ...groupFlatValue,
166
- [groupName]: where._complex[groupName][1][j],
167
- count: num,
168
- });
171
+ countsPromise.push(countPromise);
169
172
  }
170
173
  }
174
+
175
+ await think.promiseAllQueue(countsPromise, 3);
171
176
  return counts;
172
177
  }
173
178