@waline/vercel 1.36.4 → 1.37.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.
Files changed (39) hide show
  1. package/__tests__/xss.spec.js +8 -19
  2. package/development.js +1 -0
  3. package/index.js +4 -3
  4. package/package.json +17 -18
  5. package/src/config/adapter.js +9 -11
  6. package/src/config/config.js +4 -12
  7. package/src/config/extend.js +0 -6
  8. package/src/config/middleware.js +2 -5
  9. package/src/controller/article.js +5 -12
  10. package/src/controller/comment.js +33 -53
  11. package/src/controller/db.js +3 -9
  12. package/src/controller/oauth.js +8 -8
  13. package/src/controller/rest.js +1 -1
  14. package/src/controller/user/password.js +3 -12
  15. package/src/controller/user.js +18 -45
  16. package/src/controller/verification.js +3 -2
  17. package/src/extend/think.js +33 -23
  18. package/src/logic/base.js +31 -47
  19. package/src/logic/comment.js +7 -4
  20. package/src/logic/db.js +1 -1
  21. package/src/logic/token.js +2 -2
  22. package/src/middleware/dashboard.js +1 -0
  23. package/src/middleware/plugin.js +1 -1
  24. package/src/service/akismet.js +10 -3
  25. package/src/service/avatar.js +2 -4
  26. package/src/service/markdown/highlight.js +1 -1
  27. package/src/service/markdown/mathCommon.js +2 -8
  28. package/src/service/markdown/mathjax.js +1 -2
  29. package/src/service/markdown/utils.js +5 -5
  30. package/src/service/markdown/xss.js +5 -10
  31. package/src/service/notify.js +111 -135
  32. package/src/service/storage/base.js +2 -7
  33. package/src/service/storage/cloudbase.js +9 -7
  34. package/src/service/storage/github.js +39 -42
  35. package/src/service/storage/leancloud.js +41 -54
  36. package/src/service/storage/mongodb.js +11 -8
  37. package/src/service/storage/mysql.js +7 -13
  38. package/src/service/storage/postgresql.js +7 -11
  39. package/src/service/storage/deta.js +0 -310
@@ -60,8 +60,7 @@ const mathjaxPlugin = (md) => {
60
60
 
61
61
  md.renderer.rules.inlineTeX = (tokens, idx) => inline(tokens[idx].content);
62
62
 
63
- md.renderer.rules.blockTeX = (tokens, idx) =>
64
- `${block(tokens[idx].content)}\n`;
63
+ md.renderer.rules.blockTeX = (tokens, idx) => `${block(tokens[idx].content)}\n`;
65
64
  };
66
65
 
67
66
  module.exports = {
@@ -1,10 +1,10 @@
1
1
  const escapeHtml = (unsafeHTML) =>
2
2
  unsafeHTML
3
- .replace(/&/gu, '&')
4
- .replace(/</gu, '&lt;')
5
- .replace(/>/gu, '&gt;')
6
- .replace(/"/gu, '&quot;')
7
- .replace(/'/gu, '&#039;');
3
+ .replaceAll('&', '&amp;')
4
+ .replaceAll('<', '&lt;')
5
+ .replaceAll('>', '&gt;')
6
+ .replaceAll('"', '&quot;')
7
+ .replaceAll("'", '&#039;');
8
8
 
9
9
  module.exports = {
10
10
  escapeHtml,
@@ -28,16 +28,11 @@ DOMPurify.addHook('afterSanitizeAttributes', (node) => {
28
28
  });
29
29
 
30
30
  const sanitize = (content) =>
31
- DOMPurify.sanitize(
32
- content,
33
- Object.assign(
34
- {
35
- FORBID_TAGS: ['form', 'input', 'style'],
36
- FORBID_ATTR: ['autoplay', 'style'],
37
- },
38
- think.config('domPurify') || {},
39
- ),
40
- );
31
+ DOMPurify.sanitize(content, {
32
+ FORBID_TAGS: ['form', 'input', 'style'],
33
+ FORBID_ATTR: ['autoplay', 'style'],
34
+ ...think.config('domPurify'),
35
+ });
41
36
 
42
37
  module.exports = {
43
38
  sanitize,
@@ -4,19 +4,12 @@ const FormData = require('form-data');
4
4
  const nodemailer = require('nodemailer');
5
5
  const nunjucks = require('nunjucks');
6
6
 
7
- module.exports = class extends think.Service {
7
+ module.exports = class NotifyService extends think.Service {
8
8
  constructor(controller) {
9
9
  super(controller);
10
10
 
11
11
  this.controller = controller;
12
- const {
13
- SMTP_USER,
14
- SMTP_PASS,
15
- SMTP_HOST,
16
- SMTP_PORT,
17
- SMTP_SECURE,
18
- SMTP_SERVICE,
19
- } = process.env;
12
+ const { SMTP_USER, SMTP_PASS, SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_SERVICE } = process.env;
20
13
 
21
14
  if (SMTP_HOST || SMTP_SERVICE) {
22
15
  const config = {
@@ -27,7 +20,7 @@ module.exports = class extends think.Service {
27
20
  config.service = SMTP_SERVICE;
28
21
  } else {
29
22
  config.host = SMTP_HOST;
30
- config.port = parseInt(SMTP_PORT);
23
+ config.port = Number.parseInt(SMTP_PORT, 10);
31
24
  config.secure = SMTP_SECURE && SMTP_SECURE !== 'false';
32
25
  }
33
26
  this.transporter = nodemailer.createTransport(config);
@@ -35,7 +28,9 @@ module.exports = class extends think.Service {
35
28
  }
36
29
 
37
30
  async sleep(second) {
38
- return new Promise((resolve) => setTimeout(resolve, second * 1000));
31
+ return new Promise((resolve) => {
32
+ setTimeout(resolve, second * 1000);
33
+ });
39
34
  }
40
35
 
41
36
  async mail({ to, title, content }, self, parent) {
@@ -43,15 +38,14 @@ module.exports = class extends think.Service {
43
38
  return;
44
39
  }
45
40
 
46
- const { SITE_NAME, SITE_URL, SMTP_USER, SENDER_EMAIL, SENDER_NAME } =
47
- process.env;
41
+ const { SITE_NAME, SITE_URL, SMTP_USER, SENDER_EMAIL, SENDER_NAME } = process.env;
48
42
  const data = {
49
43
  self,
50
44
  parent,
51
45
  site: {
52
46
  name: SITE_NAME,
53
47
  url: SITE_URL,
54
- postUrl: SITE_URL + self.url + '#' + self.objectId,
48
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
55
49
  },
56
50
  };
57
51
 
@@ -59,10 +53,7 @@ module.exports = class extends think.Service {
59
53
  content = this.controller.locale(content, data);
60
54
 
61
55
  return this.transporter.sendMail({
62
- from:
63
- SENDER_EMAIL && SENDER_NAME
64
- ? `"${SENDER_NAME}" <${SENDER_EMAIL}>`
65
- : SMTP_USER,
56
+ from: SENDER_EMAIL && SENDER_NAME ? `"${SENDER_NAME}" <${SENDER_EMAIL}>` : SMTP_USER,
66
57
  to,
67
58
  subject: title,
68
59
  html: content,
@@ -82,7 +73,7 @@ module.exports = class extends think.Service {
82
73
  site: {
83
74
  name: SITE_NAME,
84
75
  url: SITE_URL,
85
- postUrl: SITE_URL + self.url + '#' + self.objectId,
76
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
86
77
  },
87
78
  };
88
79
 
@@ -110,8 +101,7 @@ module.exports = class extends think.Service {
110
101
  }
111
102
 
112
103
  async qywxAmWechat({ title, content }, self, parent) {
113
- const { QYWX_AM, QYWX_PROXY, QYWX_PROXY_PORT, SITE_NAME, SITE_URL } =
114
- process.env;
104
+ const { QYWX_AM, QYWX_PROXY, QYWX_PROXY_PORT, SITE_NAME, SITE_URL } = process.env;
115
105
 
116
106
  if (!QYWX_AM) {
117
107
  return false;
@@ -119,8 +109,8 @@ module.exports = class extends think.Service {
119
109
 
120
110
  const QYWX_AM_AY = QYWX_AM.split(',');
121
111
  const comment = self.comment
122
- .replace(/<a href="(.*?)">(.*?)<\/a>/g, '\n[$2] $1\n')
123
- .replace(/<[^>]+>/g, '');
112
+ .replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '\n[$2] $1\n')
113
+ .replaceAll(/<[^>]+>/g, '');
124
114
  const postName = self.url;
125
115
 
126
116
  const data = {
@@ -133,7 +123,7 @@ module.exports = class extends think.Service {
133
123
  site: {
134
124
  name: SITE_NAME,
135
125
  url: SITE_URL,
136
- postUrl: SITE_URL + self.url + '#' + self.objectId,
126
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
137
127
  },
138
128
  };
139
129
 
@@ -148,7 +138,7 @@ module.exports = class extends think.Service {
148
138
  title = this.controller.locale(title, data);
149
139
  const desp = this.controller.locale(contentWechat, data);
150
140
 
151
- content = desp.replace(/\n/g, '<br/>');
141
+ content = desp.replaceAll('\n', '<br/>');
152
142
 
153
143
  const querystring = new URLSearchParams();
154
144
 
@@ -158,48 +148,38 @@ module.exports = class extends think.Service {
158
148
  let baseUrl = 'https://qyapi.weixin.qq.com';
159
149
 
160
150
  if (QYWX_PROXY) {
161
- if (!QYWX_PROXY_PORT) {
162
- baseUrl = `http://${QYWX_PROXY}`;
163
- } else {
164
- baseUrl = `http://${QYWX_PROXY}:${QYWX_PROXY_PORT}`;
165
- }
151
+ baseUrl = `http://${QYWX_PROXY}${QYWX_PROXY_PORT ? `:${QYWX_PROXY_PORT}` : ''}`;
166
152
  }
167
153
 
168
- const { access_token } = await fetch(
169
- `${baseUrl}/cgi-bin/gettoken?${querystring.toString()}`,
170
- {
171
- headers: {
172
- 'content-type': 'application/json',
173
- },
154
+ const { access_token } = await fetch(`${baseUrl}/cgi-bin/gettoken?${querystring.toString()}`, {
155
+ headers: {
156
+ 'content-type': 'application/json',
174
157
  },
175
- ).then((resp) => resp.json());
176
-
177
- return fetch(
178
- `${baseUrl}/cgi-bin/message/send?access_token=${access_token}`,
179
- {
180
- method: 'POST',
181
- headers: {
182
- 'content-type': 'application/json',
183
- },
184
- body: JSON.stringify({
185
- touser: `${QYWX_AM_AY[2]}`,
186
- agentid: `${QYWX_AM_AY[3]}`,
187
- msgtype: 'mpnews',
188
- mpnews: {
189
- articles: [
190
- {
191
- title,
192
- thumb_media_id: `${QYWX_AM_AY[4]}`,
193
- author: `Waline Comment`,
194
- content_source_url: `${data.site.postUrl}`,
195
- content: `${content}`,
196
- digest: `${desp}`,
197
- },
198
- ],
199
- },
200
- }),
158
+ }).then((resp) => resp.json());
159
+
160
+ return fetch(`${baseUrl}/cgi-bin/message/send?access_token=${access_token}`, {
161
+ method: 'POST',
162
+ headers: {
163
+ 'content-type': 'application/json',
201
164
  },
202
- ).then((resp) => resp.json());
165
+ body: JSON.stringify({
166
+ touser: `${QYWX_AM_AY[2]}`,
167
+ agentid: `${QYWX_AM_AY[3]}`,
168
+ msgtype: 'mpnews',
169
+ mpnews: {
170
+ articles: [
171
+ {
172
+ title,
173
+ thumb_media_id: `${QYWX_AM_AY[4]}`,
174
+ author: `Waline Comment`,
175
+ content_source_url: `${data.site.postUrl}`,
176
+ content: `${content}`,
177
+ digest: `${desp}`,
178
+ },
179
+ ],
180
+ },
181
+ }),
182
+ }).then((resp) => resp.json());
203
183
  }
204
184
 
205
185
  async qq(self, parent) {
@@ -210,8 +190,8 @@ module.exports = class extends think.Service {
210
190
  }
211
191
 
212
192
  const comment = self.comment
213
- .replace(/<a href="(.*?)">(.*?)<\/a>/g, '')
214
- .replace(/<[^>]+>/g, '');
193
+ .replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '')
194
+ .replaceAll(/<[^>]+>/g, '');
215
195
 
216
196
  const data = {
217
197
  self: {
@@ -222,7 +202,7 @@ module.exports = class extends think.Service {
222
202
  site: {
223
203
  name: SITE_NAME,
224
204
  url: SITE_URL,
225
- postUrl: SITE_URL + self.url + '#' + self.objectId,
205
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
226
206
  },
227
207
  };
228
208
 
@@ -233,20 +213,29 @@ module.exports = class extends think.Service {
233
213
  {{self.comment}}
234
214
  仅供预览评论,请前往上述页面查看完整內容。`;
235
215
 
236
- const form = new FormData();
237
-
238
- form.append('msg', this.controller.locale(contentQQ, data));
239
- form.append('qq', QQ_ID);
216
+ const qmsgHost = QMSG_HOST ? QMSG_HOST.replace(/\/$/, '') : 'https://qmsg.zendee.cn';
240
217
 
241
- const qmsgHost = QMSG_HOST
242
- ? QMSG_HOST.replace(/\/$/, '')
243
- : 'https://qmsg.zendee.cn';
218
+ const postBodyData = {
219
+ qq: QQ_ID,
220
+ msg: this.controller.locale(contentQQ, data),
221
+ };
222
+ const postBody = Object.keys(postBodyData)
223
+ .map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(postBodyData[key]))
224
+ .join('&');
244
225
 
245
226
  return fetch(`${qmsgHost}/send/${QMSG_KEY}`, {
246
227
  method: 'POST',
247
- headers: form.getHeaders(),
248
- body: form,
249
- }).then((resp) => resp.json());
228
+ headers: {
229
+ 'Content-Type': 'application/x-www-form-urlencoded',
230
+ },
231
+ body: postBody,
232
+ }).then((resp) =>
233
+ resp.json().then((json) => {
234
+ think.logger.debug(`qq notify response: ${JSON.stringify(json)}`);
235
+
236
+ return json;
237
+ }),
238
+ );
250
239
  }
251
240
 
252
241
  async telegram(self, parent) {
@@ -259,23 +248,19 @@ module.exports = class extends think.Service {
259
248
  let commentLink = '';
260
249
  const href = self.comment.match(/<a href="(.*?)">(.*?)<\/a>/g);
261
250
 
262
- if (href !== null) {
251
+ if (href != null) {
263
252
  for (let i = 0; i < href.length; i++) {
264
253
  href[i] =
265
- '[Link: ' +
266
- href[i].replace(/<a href="(.*?)">(.*?)<\/a>/g, '$2') +
267
- '](' +
268
- href[i].replace(/<a href="(.*?)">(.*?)<\/a>/g, '$1') +
269
- ') ';
270
- commentLink = commentLink + href[i];
254
+ `[Link: ${href[i].replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '$2')}](${href[i].replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '$1')}) `;
255
+ commentLink += href[i];
271
256
  }
272
257
  }
273
258
  if (commentLink !== '') {
274
- commentLink = `\n` + commentLink + `\n`;
259
+ commentLink = `\n${commentLink}\n`;
275
260
  }
276
261
  const comment = self.comment
277
- .replace(/<a href="(.*?)">(.*?)<\/a>/g, '[Link:$2]')
278
- .replace(/<[^>]+>/g, '');
262
+ .replaceAll(/<a href="(.*?)">(.*?)<\/a>/g, '[Link:$2]')
263
+ .replaceAll(/<[^>]+>/g, '');
279
264
 
280
265
  const contentTG =
281
266
  think.config('TGTemplate') ||
@@ -302,27 +287,24 @@ module.exports = class extends think.Service {
302
287
  site: {
303
288
  name: SITE_NAME,
304
289
  url: SITE_URL,
305
- postUrl: SITE_URL + self.url + '#' + self.objectId,
290
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
306
291
  },
307
292
  };
308
293
 
309
- const resp = await fetch(
310
- `https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage`,
311
- {
312
- method: 'POST',
313
- headers: {
314
- 'Content-Type': 'application/json',
315
- },
316
- body: JSON.stringify({
317
- chat_id: TG_CHAT_ID,
318
- text: this.controller.locale(contentTG, data),
319
- parse_mode: 'MarkdownV2',
320
- }),
294
+ const resp = await fetch(`https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage`, {
295
+ method: 'POST',
296
+ headers: {
297
+ 'Content-Type': 'application/json',
321
298
  },
322
- ).then((resp) => resp.json());
299
+ body: JSON.stringify({
300
+ chat_id: TG_CHAT_ID,
301
+ text: this.controller.locale(contentTG, data),
302
+ parse_mode: 'MarkdownV2',
303
+ }),
304
+ }).then((resp) => resp.json());
323
305
 
324
306
  if (!resp.ok) {
325
- console.log('Telegram Notification Failed:' + JSON.stringify(resp));
307
+ console.log(`Telegram Notification Failed:${JSON.stringify(resp)}`);
326
308
  }
327
309
  }
328
310
 
@@ -348,27 +330,29 @@ module.exports = class extends think.Service {
348
330
  site: {
349
331
  name: SITE_NAME,
350
332
  url: SITE_URL,
351
- postUrl: SITE_URL + self.url + '#' + self.objectId,
333
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
352
334
  },
353
335
  };
354
336
 
355
337
  title = this.controller.locale(title, data);
356
338
  content = this.controller.locale(content, data);
357
339
 
358
- const form = new FormData();
340
+ const form = new URLSearchParams();
359
341
 
360
- if (topic) form.append('topic', topic);
361
- if (template) form.append('template', template);
362
- if (channel) form.append('channel', channel);
363
- if (webhook) form.append('webhook', webhook);
364
- if (callbackUrl) form.append('callbackUrl', callbackUrl);
365
- if (title) form.append('title', title);
366
- if (content) form.append('content', content);
342
+ if (topic) form.set('topic', topic);
343
+ if (template) form.set('template', template);
344
+ if (channel) form.set('channel', channel);
345
+ if (webhook) form.set('webhook', webhook);
346
+ if (callbackUrl) form.set('callbackUrl', callbackUrl);
347
+ if (title) form.set('title', title);
348
+ if (content) form.set('content', content);
367
349
 
368
350
  return fetch(`http://www.pushplus.plus/send/${PUSH_PLUS_KEY}`, {
369
351
  method: 'POST',
370
- headers: form.getHeaders(),
371
- body: form,
352
+ headers: {
353
+ 'Content-Type': 'application/x-www-form-urlencoded',
354
+ },
355
+ body: form.toString(),
372
356
  }).then((resp) => resp.json());
373
357
  }
374
358
 
@@ -385,7 +369,7 @@ module.exports = class extends think.Service {
385
369
  site: {
386
370
  name: SITE_NAME,
387
371
  url: SITE_URL,
388
- postUrl: SITE_URL + self.url + '#' + self.objectId,
372
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
389
373
  },
390
374
  };
391
375
 
@@ -420,7 +404,7 @@ module.exports = class extends think.Service {
420
404
  return false;
421
405
  }
422
406
 
423
- self.comment = self.comment.replace(/(<([^>]+)>)/gi, '');
407
+ self.comment = self.comment.replaceAll(/(<([^>]+)>)/gi, '');
424
408
 
425
409
  const data = {
426
410
  self,
@@ -428,7 +412,7 @@ module.exports = class extends think.Service {
428
412
  site: {
429
413
  name: SITE_NAME,
430
414
  url: SITE_URL,
431
- postUrl: SITE_URL + self.url + '#' + self.objectId,
415
+ postUrl: `${SITE_URL}${self.url}#${self.objectId}`,
432
416
  },
433
417
  };
434
418
 
@@ -461,13 +445,13 @@ module.exports = class extends think.Service {
461
445
  };
462
446
 
463
447
  const sign = (timestamp, secret) => {
464
- const signStr = timestamp + '\n' + secret;
448
+ const signStr = `${timestamp}\n${secret}`;
465
449
 
466
450
  return crypto.createHmac('sha256', signStr).update('').digest('base64');
467
451
  };
468
452
 
469
453
  if (LARK_SECRET) {
470
- const timestamp = parseInt(+new Date() / 1000);
454
+ const timestamp = Number.parseInt(Date.now() / 1000, 10);
471
455
 
472
456
  signData = { timestamp: timestamp, sign: sign(timestamp, LARK_SECRET) };
473
457
  }
@@ -484,16 +468,15 @@ module.exports = class extends think.Service {
484
468
  }).then((resp) => resp.json());
485
469
 
486
470
  if (resp.status !== 200) {
487
- console.log('Lark Notification Failed:' + JSON.stringify(resp));
471
+ console.log(`Lark Notification Failed:${JSON.stringify(resp)}`);
488
472
  }
489
473
 
490
- console.log('FeiShu Notification Success:' + JSON.stringify(resp));
474
+ console.log(`FeiShu Notification Success:${JSON.stringify(resp)}`);
491
475
  }
492
476
 
493
477
  async run(comment, parent, disableAuthorNotify = false) {
494
478
  const { AUTHOR_EMAIL, DISABLE_AUTHOR_NOTIFY } = process.env;
495
- const { mailSubject, mailTemplate, mailSubjectAdmin, mailTemplateAdmin } =
496
- think.config();
479
+ const { mailSubject, mailTemplate, mailSubjectAdmin, mailTemplateAdmin } = think.config();
497
480
  const AUTHOR = AUTHOR_EMAIL;
498
481
 
499
482
  const mailList = [];
@@ -504,19 +487,14 @@ module.exports = class extends think.Service {
504
487
  ? parent && (parent.mail || '').toLowerCase() === AUTHOR.toLowerCase()
505
488
  : false;
506
489
  const isCommentSelf =
507
- parent &&
508
- (parent.mail || '').toLowerCase() === (comment.mail || '').toLowerCase();
490
+ parent && (parent.mail || '').toLowerCase() === (comment.mail || '').toLowerCase();
509
491
 
510
492
  const title = mailSubjectAdmin || 'MAIL_SUBJECT_ADMIN';
511
493
  const content = mailTemplateAdmin || 'MAIL_TEMPLATE_ADMIN';
512
494
 
513
495
  if (!DISABLE_AUTHOR_NOTIFY && !isAuthorComment && !disableAuthorNotify) {
514
496
  const wechat = await this.wechat({ title, content }, comment, parent);
515
- const qywxAmWechat = await this.qywxAmWechat(
516
- { title, content },
517
- comment,
518
- parent,
519
- );
497
+ const qywxAmWechat = await this.qywxAmWechat({ title, content }, comment, parent);
520
498
  const qq = await this.qq(comment, parent);
521
499
  const telegram = await this.telegram(comment, parent);
522
500
  const pushplus = await this.pushplus({ title, content }, comment, parent);
@@ -524,17 +502,15 @@ module.exports = class extends think.Service {
524
502
  const lark = await this.lark({ title, content }, comment, parent);
525
503
 
526
504
  if (
527
- [wechat, qq, telegram, qywxAmWechat, pushplus, discord, lark].every(
528
- think.isEmpty,
505
+ [wechat, qq, telegram, qywxAmWechat, pushplus, discord, lark].every((item) =>
506
+ think.isEmpty(item),
529
507
  )
530
508
  ) {
531
509
  mailList.push({ to: AUTHOR, title, content });
532
510
  }
533
511
  }
534
512
 
535
- const disallowList = this.controller.ctx.state.oauthServices.map(
536
- ({ name }) => 'mail.' + name,
537
- );
513
+ const disallowList = this.controller.ctx.state.oauthServices.map(({ name }) => `mail.${name}`);
538
514
  const fakeMail = new RegExp(`@(${disallowList.join('|')})$`, 'i');
539
515
 
540
516
  if (
@@ -556,8 +532,8 @@ module.exports = class extends think.Service {
556
532
  const response = await this.mail(mail, comment, parent);
557
533
 
558
534
  console.log('Notification mail send success: %s', response);
559
- } catch (e) {
560
- console.log('Mail send fail:', e);
535
+ } catch (err) {
536
+ console.log('Mail send fail:', err);
561
537
  }
562
538
  }
563
539
  }
@@ -1,4 +1,4 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
1
+ /* eslint-disable typescript/no-unused-vars */
2
2
 
3
3
  module.exports = class extends think.Service {
4
4
  constructor(tableName) {
@@ -14,12 +14,7 @@ module.exports = class extends think.Service {
14
14
  //to be implemented
15
15
  }
16
16
 
17
- async add(
18
- data,
19
- {
20
- access: { read = true, write = true } = { read: true, write: true },
21
- } = {},
22
- ) {
17
+ async add(data, { access: { read = true, write = true } = { read: true, write: true } } = {}) {
23
18
  //to be implemented
24
19
  }
25
20
 
@@ -27,14 +27,14 @@ module.exports = class extends Base {
27
27
  collections[tableName] = true;
28
28
 
29
29
  return db.collection(tableName);
30
- } catch (e) {
31
- if (e.code === 'DATABASE_COLLECTION_NOT_EXIST') {
30
+ } catch (err) {
31
+ if (err.code === 'DATABASE_COLLECTION_NOT_EXIST') {
32
32
  await db.createCollection(tableName);
33
33
  collections[tableName] = true;
34
34
 
35
35
  return db.collection(tableName);
36
36
  }
37
- throw e;
37
+ throw err;
38
38
  }
39
39
  }
40
40
 
@@ -46,7 +46,7 @@ module.exports = class extends Base {
46
46
  const filter = {};
47
47
  const parseKey = (k) => (k === 'objectId' ? '_id' : k);
48
48
 
49
- for (let k in where) {
49
+ for (const k in where) {
50
50
  if (k === '_complex') {
51
51
  continue;
52
52
  }
@@ -62,12 +62,14 @@ module.exports = class extends Base {
62
62
  const handler = where[k][0].toUpperCase();
63
63
 
64
64
  switch (handler) {
65
- case 'IN':
65
+ case 'IN': {
66
66
  filter[parseKey(k)] = _.in(where[k][1]);
67
67
  break;
68
- case 'NOT IN':
68
+ }
69
+ case 'NOT IN': {
69
70
  filter[parseKey(k)] = _.nin(where[k][1]);
70
71
  break;
72
+ }
71
73
  case 'LIKE': {
72
74
  const first = where[k][1][0];
73
75
  const last = where[k][1].slice(-1);
@@ -152,7 +154,7 @@ module.exports = class extends Base {
152
154
  async select(where, options = {}) {
153
155
  let data = [];
154
156
  let ret = [];
155
- let offset = options.offset || 0;
157
+ const offset = options.offset ?? 0;
156
158
 
157
159
  do {
158
160
  options.offset = offset + data.length;