@waline/vercel 1.19.2 → 1.20.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 +7 -7
- package/src/config/config.js +1 -1
- package/src/controller/comment.js +37 -11
- package/src/controller/db.js +10 -7
- package/src/logic/comment.js +6 -2
- package/src/service/notify.js +9 -3
- package/src/service/storage/mysql.js +9 -1
- package/src/service/storage/postgresql.js +8 -0
- package/src/service/storage/sqlite.js +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waline/vercel",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"description": "vercel server for waline comment system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"waline",
|
|
@@ -16,17 +16,17 @@
|
|
|
16
16
|
"author": "lizheming <i@imnerd.org>",
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@cloudbase/node-sdk": "2.9.1",
|
|
19
|
-
"@koa/cors": "3.
|
|
19
|
+
"@koa/cors": "3.4.1",
|
|
20
20
|
"akismet": "2.0.7",
|
|
21
21
|
"deta": "1.1.0",
|
|
22
|
-
"dompurify": "2.
|
|
22
|
+
"dompurify": "2.4.0",
|
|
23
23
|
"dy-node-ip2region": "1.0.1",
|
|
24
24
|
"fast-csv": "4.3.6",
|
|
25
25
|
"form-data": "4.0.0",
|
|
26
26
|
"jsdom": "20.0.0",
|
|
27
27
|
"jsonwebtoken": "8.5.1",
|
|
28
|
-
"katex": "0.16.
|
|
29
|
-
"leancloud-storage": "4.13.
|
|
28
|
+
"katex": "0.16.2",
|
|
29
|
+
"leancloud-storage": "4.13.2",
|
|
30
30
|
"markdown-it": "13.0.1",
|
|
31
31
|
"markdown-it-emoji": "2.0.2",
|
|
32
32
|
"markdown-it-sub": "1.0.0",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"nodemailer": "6.7.8",
|
|
37
37
|
"nunjucks": "3.2.3",
|
|
38
38
|
"phpass": "0.1.1",
|
|
39
|
-
"prismjs": "1.
|
|
39
|
+
"prismjs": "1.29.0",
|
|
40
40
|
"speakeasy": "2.0.0",
|
|
41
|
-
"think-helper": "1.1.
|
|
41
|
+
"think-helper": "1.1.4",
|
|
42
42
|
"think-logger3": "1.3.1",
|
|
43
43
|
"think-model": "1.5.4",
|
|
44
44
|
"think-model-mysql": "1.1.7",
|
package/src/config/config.js
CHANGED
|
@@ -145,7 +145,8 @@ module.exports = class extends BaseRest {
|
|
|
145
145
|
|
|
146
146
|
case 'count': {
|
|
147
147
|
const { url } = this.get();
|
|
148
|
-
const where =
|
|
148
|
+
const where =
|
|
149
|
+
Array.isArray(url) && url.length ? { url: ['IN', url] } : {};
|
|
149
150
|
|
|
150
151
|
if (think.isEmpty(userInfo) || this.config('storage') === 'deta') {
|
|
151
152
|
where.status = ['NOT IN', ['waiting', 'spam']];
|
|
@@ -156,12 +157,19 @@ module.exports = class extends BaseRest {
|
|
|
156
157
|
user_id: userInfo.objectId,
|
|
157
158
|
};
|
|
158
159
|
}
|
|
159
|
-
const data = await this.modelInstance.select(where, { field: ['url'] });
|
|
160
|
-
const counts = url.map(
|
|
161
|
-
(u) => data.filter(({ url }) => url === u).length
|
|
162
|
-
);
|
|
163
160
|
|
|
164
|
-
|
|
161
|
+
if (Array.isArray(url) && url.length > 1) {
|
|
162
|
+
const data = await this.modelInstance.select(where, {
|
|
163
|
+
field: ['url'],
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
return this.json(
|
|
167
|
+
url.map((u) => data.filter(({ url }) => url === u).length)
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
const data = await this.modelInstance.count(where);
|
|
171
|
+
|
|
172
|
+
return this.json(data);
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
case 'list': {
|
|
@@ -239,7 +247,7 @@ module.exports = class extends BaseRest {
|
|
|
239
247
|
}
|
|
240
248
|
|
|
241
249
|
default: {
|
|
242
|
-
const { path: url, page, pageSize } = this.get();
|
|
250
|
+
const { path: url, page, pageSize, sortBy } = this.get();
|
|
243
251
|
const where = { url };
|
|
244
252
|
|
|
245
253
|
if (think.isEmpty(userInfo) || this.config('storage') === 'deta') {
|
|
@@ -258,7 +266,6 @@ module.exports = class extends BaseRest {
|
|
|
258
266
|
let rootComments = [];
|
|
259
267
|
let rootCount = 0;
|
|
260
268
|
const selectOptions = {
|
|
261
|
-
desc: 'insertedAt',
|
|
262
269
|
field: [
|
|
263
270
|
'status',
|
|
264
271
|
'comment',
|
|
@@ -276,6 +283,16 @@ module.exports = class extends BaseRest {
|
|
|
276
283
|
],
|
|
277
284
|
};
|
|
278
285
|
|
|
286
|
+
if (sortBy) {
|
|
287
|
+
const [field, order] = sortBy.split('_');
|
|
288
|
+
|
|
289
|
+
if (order === 'desc') {
|
|
290
|
+
selectOptions.desc = field;
|
|
291
|
+
} else if (order === 'asc') {
|
|
292
|
+
// do nothing because of ascending order is default behaviour
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
279
296
|
/**
|
|
280
297
|
* most of case we have just little comments
|
|
281
298
|
* while if we want get rootComments, rootCount, childComments with pagination
|
|
@@ -573,7 +590,10 @@ module.exports = class extends BaseRest {
|
|
|
573
590
|
parentComment = await this.modelInstance.select({ objectId: pid });
|
|
574
591
|
parentComment = parentComment[0];
|
|
575
592
|
if (parentComment.user_id) {
|
|
576
|
-
parentUser = await this.
|
|
593
|
+
parentUser = await this.service(
|
|
594
|
+
`storage/${this.config('storage')}`,
|
|
595
|
+
'User'
|
|
596
|
+
).select({
|
|
577
597
|
objectId: parentComment.user_id,
|
|
578
598
|
});
|
|
579
599
|
parentUser = parentUser[0];
|
|
@@ -665,7 +685,10 @@ module.exports = class extends BaseRest {
|
|
|
665
685
|
let cmtUser;
|
|
666
686
|
|
|
667
687
|
if (newData.user_id) {
|
|
668
|
-
cmtUser = await this.
|
|
688
|
+
cmtUser = await this.service(
|
|
689
|
+
`storage/${this.config('storage')}`,
|
|
690
|
+
'User'
|
|
691
|
+
).select({
|
|
669
692
|
objectId: newData.user_id,
|
|
670
693
|
});
|
|
671
694
|
cmtUser = cmtUser[0];
|
|
@@ -680,7 +703,10 @@ module.exports = class extends BaseRest {
|
|
|
680
703
|
let pUser;
|
|
681
704
|
|
|
682
705
|
if (pComment.user_id) {
|
|
683
|
-
pUser = await this.
|
|
706
|
+
pUser = await this.service(
|
|
707
|
+
`storage/${this.config('storage')}`,
|
|
708
|
+
'User'
|
|
709
|
+
).select({
|
|
684
710
|
objectId: pComment.user_id,
|
|
685
711
|
});
|
|
686
712
|
pUser = pUser[0];
|
package/src/controller/db.js
CHANGED
|
@@ -76,12 +76,15 @@ module.exports = class extends BaseRest {
|
|
|
76
76
|
let i = 0;
|
|
77
77
|
|
|
78
78
|
data = formatID(data, () => (i = i + 1));
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
await model.setSeqId(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (storage === 'leancloud' || storage === 'mysql') {
|
|
83
|
+
data.forEach((item) => {
|
|
84
|
+
item.insertedAt && (item.insertedAt = new Date(item.insertedAt));
|
|
85
|
+
item.createdAt && (item.createdAt = new Date(item.createdAt));
|
|
86
|
+
item.updatedAt && (item.updatedAt = new Date(item.updatedAt));
|
|
87
|
+
});
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
// delete all data at first
|
|
@@ -113,7 +116,7 @@ module.exports = class extends BaseRest {
|
|
|
113
116
|
const oldId = cmt[field];
|
|
114
117
|
const newId = idMaps[tableName].get(cmt[field]);
|
|
115
118
|
|
|
116
|
-
if (oldId !== newId) {
|
|
119
|
+
if (oldId && newId && oldId !== newId) {
|
|
117
120
|
willUpdateItem[field] = newId;
|
|
118
121
|
}
|
|
119
122
|
});
|
package/src/logic/comment.js
CHANGED
|
@@ -32,6 +32,7 @@ module.exports = class extends Base {
|
|
|
32
32
|
* @apiParam {String} path comment url path
|
|
33
33
|
* @apiParam {String} page page
|
|
34
34
|
* @apiParam {String} pagesize page size
|
|
35
|
+
* @apiParam {String} sortBy comment sort type, one of 'insertedAt_desc', 'insertedAt_asc', 'like_desc'
|
|
35
36
|
*
|
|
36
37
|
* @apiSuccess (200) {Number} page return current comments list page
|
|
37
38
|
* @apiSuccess (200) {Number} pageSize to return error message if error
|
|
@@ -89,7 +90,7 @@ module.exports = class extends Base {
|
|
|
89
90
|
* @apiGroup Comment
|
|
90
91
|
* @apiVersion 0.0.1
|
|
91
92
|
*
|
|
92
|
-
* @apiParam {String} url a array string join by comma just like `a` or `a,b
|
|
93
|
+
* @apiParam {String} url a array string join by comma just like `a` or `a,b`, return site comment count if url empty
|
|
93
94
|
*
|
|
94
95
|
* @apiSuccessExample {Number} Single Path Response:
|
|
95
96
|
* 300
|
|
@@ -131,7 +132,6 @@ module.exports = class extends Base {
|
|
|
131
132
|
this.rules = {
|
|
132
133
|
url: {
|
|
133
134
|
array: true,
|
|
134
|
-
required: true,
|
|
135
135
|
},
|
|
136
136
|
};
|
|
137
137
|
break;
|
|
@@ -169,6 +169,10 @@ module.exports = class extends Base {
|
|
|
169
169
|
int: { max: 100 },
|
|
170
170
|
default: 10,
|
|
171
171
|
},
|
|
172
|
+
sortBy: {
|
|
173
|
+
in: ['insertedAt_desc', 'insertedAt_asc', 'like_desc'],
|
|
174
|
+
default: 'insertedAt_desc',
|
|
175
|
+
},
|
|
172
176
|
};
|
|
173
177
|
break;
|
|
174
178
|
}
|
package/src/service/notify.js
CHANGED
|
@@ -144,12 +144,11 @@ module.exports = class extends think.Service {
|
|
|
144
144
|
querystring.set('corpsecret', `${QYWX_AM_AY[1]}`);
|
|
145
145
|
|
|
146
146
|
const { access_token } = await fetch(
|
|
147
|
-
`https://qyapi.weixin.qq.com/cgi-bin/gettoken`,
|
|
147
|
+
`https://qyapi.weixin.qq.com/cgi-bin/gettoken?${querystring.toString()}`,
|
|
148
148
|
{
|
|
149
149
|
headers: {
|
|
150
150
|
'content-type': 'application/json',
|
|
151
151
|
},
|
|
152
|
-
body: querystring,
|
|
153
152
|
}
|
|
154
153
|
).then((resp) => resp.json());
|
|
155
154
|
|
|
@@ -392,6 +391,8 @@ module.exports = class extends think.Service {
|
|
|
392
391
|
const isReplyAuthor = AUTHOR
|
|
393
392
|
? parent && parent.mail.toLowerCase() === AUTHOR.toLowerCase()
|
|
394
393
|
: false;
|
|
394
|
+
const isCommentSelf =
|
|
395
|
+
parent && parent.mail.toLowerCase() === comment.mail.toLowerCase();
|
|
395
396
|
|
|
396
397
|
const title = mailSubjectAdmin || '{{site.name | safe}} 上有新评论了';
|
|
397
398
|
const content =
|
|
@@ -436,7 +437,12 @@ module.exports = class extends think.Service {
|
|
|
436
437
|
);
|
|
437
438
|
const fakeMail = new RegExp(`@(${disallowList.join('|')})$`, 'i');
|
|
438
439
|
|
|
439
|
-
if (
|
|
440
|
+
if (
|
|
441
|
+
parent &&
|
|
442
|
+
!fakeMail.test(parent.mail) &&
|
|
443
|
+
!isCommentSelf &&
|
|
444
|
+
comment.status !== 'waiting'
|
|
445
|
+
) {
|
|
440
446
|
mailList.push({
|
|
441
447
|
to: parent.mail,
|
|
442
448
|
title:
|
|
@@ -44,7 +44,7 @@ module.exports = class extends Base {
|
|
|
44
44
|
|
|
45
45
|
instance.where(this.parseWhere(where));
|
|
46
46
|
if (desc) {
|
|
47
|
-
instance.order(
|
|
47
|
+
instance.order(`\`${desc}\` DESC`);
|
|
48
48
|
}
|
|
49
49
|
if (limit || offset) {
|
|
50
50
|
instance.limit(offset || 0, limit);
|
|
@@ -113,4 +113,12 @@ module.exports = class extends Base {
|
|
|
113
113
|
|
|
114
114
|
return instance.where(this.parseWhere(where)).delete();
|
|
115
115
|
}
|
|
116
|
+
|
|
117
|
+
async setSeqId(id) {
|
|
118
|
+
const instance = this.model(this.tableName);
|
|
119
|
+
|
|
120
|
+
return instance.query(
|
|
121
|
+
`ALTER TABLE ${instance.tableName} AUTO_INCREMENT = ${id};`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
116
124
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const MySQL = require('./mysql');
|
|
2
|
+
|
|
3
|
+
module.exports = class extends MySQL {
|
|
4
|
+
async setSeqId(id) {
|
|
5
|
+
const instance = this.model(this.tableName);
|
|
6
|
+
|
|
7
|
+
return instance.query(
|
|
8
|
+
`UPDATE SQLITE_SEQUENCE SET SEQ=${id} WHERE NAME='${instance.tableName}';`
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
};
|