@waline/vercel 1.13.3 → 1.13.6

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,14 +1,23 @@
1
1
  {
2
2
  "name": "@waline/vercel",
3
- "version": "1.13.3",
3
+ "version": "1.13.6",
4
4
  "description": "vercel server for waline comment system",
5
- "repository": "https://github.com/walinejs/waline",
5
+ "keywords": [
6
+ "waline",
7
+ "vercel",
8
+ "comment",
9
+ "blog"
10
+ ],
11
+ "repository": {
12
+ "url": "https://github.com/walinejs/waline",
13
+ "directory": "packages/server"
14
+ },
6
15
  "license": "MIT",
7
16
  "author": "lizheming <i@imnerd.org>",
8
17
  "dependencies": {
9
18
  "@cloudbase/node-sdk": "^2.9.0",
10
- "@koa/cors": "^3.2.0",
11
- "akismet": "^2.0.6",
19
+ "@koa/cors": "^3.3.0",
20
+ "akismet": "^2.0.7",
12
21
  "deta": "^1.1.0",
13
22
  "dompurify": "^2.3.6",
14
23
  "fast-csv": "^4.3.6",
@@ -32,7 +41,7 @@
32
41
  "think-model": "^1.5.4",
33
42
  "think-model-mysql": "^1.1.7",
34
43
  "think-model-postgresql": "1.1.6",
35
- "think-model-sqlite": "^1.2.2",
44
+ "think-model-sqlite": "^1.2.3",
36
45
  "think-mongo": "^2.1.2",
37
46
  "think-router-rest": "^1.0.5",
38
47
  "thinkjs": "^3.2.14",
@@ -7,8 +7,13 @@ module.exports = [
7
7
  {
8
8
  context: {
9
9
  get serverURL() {
10
- const { protocol, host, path, controller } = this;
11
- return `${protocol}://${host}${path.slice(0, -controller.length)}`;
10
+ const { SERVER_URL } = process.env;
11
+ if (SERVER_URL) {
12
+ return SERVER_URL;
13
+ }
14
+
15
+ const { protocol, host } = this;
16
+ return `${protocol}://${host}`;
12
17
  },
13
18
  },
14
19
  controller: {
@@ -218,7 +218,12 @@ module.exports = class extends BaseRest {
218
218
  };
219
219
  }
220
220
 
221
- const comments = await this.modelInstance.select(where, {
221
+ const totalCount = await this.modelInstance.count(where);
222
+ const pageOffset = Math.max((page - 1) * pageSize, 0);
223
+ let comments = [];
224
+ let rootComments = [];
225
+ let rootCount = 0;
226
+ const selectOptions = {
222
227
  desc: 'insertedAt',
223
228
  field: [
224
229
  'status',
@@ -233,7 +238,54 @@ module.exports = class extends BaseRest {
233
238
  'user_id',
234
239
  'sticky',
235
240
  ],
236
- });
241
+ };
242
+
243
+ /**
244
+ * most of case we have just little comments
245
+ * while if we want get rootComments, rootCount, childComments with pagination
246
+ * we have to query three times from storage service
247
+ * That's so expensive for user, especially in the serverless.
248
+ * so we have a comments length check
249
+ * If you have less than 1000 comments, then we'll get all comments one time
250
+ * then we'll compute rootComment, rootCount, childComments in program to reduce http request query
251
+ *
252
+ * Why we have limit and the limit is 1000?
253
+ * Many serverless storages have fetch data limit, for example LeanCloud is 100, and CloudBase is 1000
254
+ * If we have much commments, We should use more request to fetch all comments
255
+ * If we have 3000 comments, We have to use 30 http request to fetch comments, things go athwart.
256
+ * And Serverless Service like vercel have excute time limit
257
+ * if we have more http requests in a serverless function, it may timeout easily.
258
+ * so we use limit to avoid it.
259
+ */
260
+ if (totalCount < 1000) {
261
+ comments = await this.modelInstance.select(where, selectOptions);
262
+ rootCount = comments.filter(({ rid }) => !rid).length;
263
+ rootComments = [
264
+ ...comments.filter(({ rid, sticky }) => !rid && sticky),
265
+ ...comments.filter(({ rid, sticky }) => !rid && !sticky),
266
+ ].slice(pageOffset, pageOffset + pageSize);
267
+ } else {
268
+ rootComments = await this.modelInstance.select(
269
+ { ...where, rid: undefined },
270
+ {
271
+ ...selectOptions,
272
+ offset: pageOffset,
273
+ limit: pageSize,
274
+ }
275
+ );
276
+ const children = await this.modelInstance.select(
277
+ {
278
+ ...where,
279
+ rid: ['IN', rootComments.map(({ objectId }) => objectId)],
280
+ },
281
+ selectOptions
282
+ );
283
+ comments = [...rootComments, ...children];
284
+ rootCount = await this.modelInstance.count({
285
+ ...where,
286
+ rid: undefined,
287
+ });
288
+ }
237
289
 
238
290
  const userModel = this.service(
239
291
  `storage/${this.config('storage')}`,
@@ -253,18 +305,11 @@ module.exports = class extends BaseRest {
253
305
  );
254
306
  }
255
307
 
256
- const rootCount = comments.filter(({ rid }) => !rid).length;
257
- const pageOffset = Math.max((page - 1) * pageSize, 0);
258
- const rootComments = [
259
- ...comments.filter(({ rid, sticky }) => !rid && sticky),
260
- ...comments.filter(({ rid, sticky }) => !rid && !sticky),
261
- ].slice(pageOffset, pageOffset + pageSize);
262
-
263
308
  return this.json({
264
309
  page,
265
310
  totalPages: Math.ceil(rootCount / pageSize),
266
311
  pageSize,
267
- count: comments.length,
312
+ count: totalCount,
268
313
  data: await Promise.all(
269
314
  rootComments.map(async (comment) => {
270
315
  const cmt = await formatCmt(
@@ -19,10 +19,9 @@ module.exports = class extends BaseRest {
19
19
 
20
20
  for (let i = 0; i < exportData.tables.length; i++) {
21
21
  const tableName = exportData.tables[i];
22
- const model = this.service(
23
- `storage/${this.config('storage')}`,
24
- tableName
25
- );
22
+ const storage = this.config('storage');
23
+ const model = this.service(`storage/${storage}`, tableName);
24
+
26
25
  const data = await model.select({});
27
26
  exportData.data[tableName] = data;
28
27
  }
@@ -41,7 +40,8 @@ module.exports = class extends BaseRest {
41
40
 
42
41
  for (let i = 0; i < importData.tables.length; i++) {
43
42
  const tableName = importData.tables[i];
44
- const model = this.model(tableName);
43
+ const storage = this.config('storage');
44
+ const model = this.service(`storage/${storage}`, tableName);
45
45
 
46
46
  // delete all data at first
47
47
  await model.delete({});
@@ -12,7 +12,9 @@ module.exports = class extends think.Controller {
12
12
  <title>Waline Example</title>
13
13
  </head>
14
14
  <body>
15
- <div id="waline" style="max-width: 800px;margin: 0 auto;"></div> <script src="https://cdn.jsdelivr.net/npm/@waline/client/dist/Waline.min.js"></script>
15
+ <div id="waline" style="max-width: 800px;margin: 0 auto;"></div>
16
+ <script src="https://unpkg.com/@waline/client@v2/dist/waline.js"></script>
17
+ <link href='//unpkg.com/@waline/client@v2/dist/waline.css' rel='stylesheet' />
16
18
  <script>
17
19
  console.log(
18
20
  '%c @waline/server %c v${version} ',
@@ -20,7 +22,7 @@ module.exports = class extends think.Controller {
20
22
  'padding:4px;border:1px solid #0078E7;'
21
23
  );
22
24
  const params = new URLSearchParams(location.search.slice(1));
23
- const waline = new Waline({
25
+ const waline = Waline.init({
24
26
  el: '#waline',
25
27
  path: params.get('path') || '/',
26
28
  lang: params.get('lng'),
@@ -14,8 +14,7 @@ module.exports = function () {
14
14
  window.SITE_NAME = ${JSON.stringify(process.env.SITE_NAME)};
15
15
  </script>
16
16
  <script src="${
17
- process.env.WALINE_ADMIN_MODULE_ASSET_URL ||
18
- 'https://cdn.jsdelivr.net/npm/@waline/admin'
17
+ process.env.WALINE_ADMIN_MODULE_ASSET_URL || '//unpkg.com/@waline/admin'
19
18
  }"></script>
20
19
  </body>
21
20
  </html>`;
@@ -354,7 +354,7 @@ module.exports = class extends think.Service {
354
354
  }
355
355
 
356
356
  async run(comment, parent, disableAuthorNotify = false) {
357
- const { AUTHOR_EMAIL, BLOGGER_EMAIL } = process.env;
357
+ const { AUTHOR_EMAIL, BLOGGER_EMAIL, DISABLE_AUTHOR_NOTIFY } = process.env;
358
358
  const { mailSubject, mailTemplate, mailSubjectAdmin, mailTemplateAdmin } =
359
359
  think.config();
360
360
  const AUTHOR = AUTHOR_EMAIL || BLOGGER_EMAIL;
@@ -383,7 +383,7 @@ module.exports = class extends think.Service {
383
383
  <br/>
384
384
  </div>`;
385
385
 
386
- if (!isAuthorComment && !disableAuthorNotify) {
386
+ if (!DISABLE_AUTHOR_NOTIFY && !isAuthorComment && !disableAuthorNotify) {
387
387
  const wechat = await this.wechat({ title, content }, comment, parent);
388
388
  const qywxAmWechat = await this.qywxAmWechat(
389
389
  { title, content },
@@ -154,6 +154,11 @@ module.exports = class extends Base {
154
154
  }
155
155
 
156
156
  async add(data) {
157
+ if (data.objectId) {
158
+ data._id = data.objectId;
159
+ delete data.objectId;
160
+ }
161
+
157
162
  const instance = await this.collection(this.tableName);
158
163
  const { id } = await instance.add(data);
159
164
  return { ...data, objectId: id };
@@ -121,6 +121,11 @@ module.exports = class extends Base {
121
121
  }
122
122
 
123
123
  async add(data) {
124
+ if (data.objectId) {
125
+ data._id = data.objectId;
126
+ delete data.objectId;
127
+ }
128
+
124
129
  const instance = this.mongo(this.tableName);
125
130
  const id = await instance.add(data);
126
131
  return { ...data, objectId: id.toString() };
@@ -57,6 +57,11 @@ module.exports = class extends Base {
57
57
  }
58
58
 
59
59
  async add(data) {
60
+ if (data.objectId) {
61
+ data.id = data.objectId;
62
+ delete data.objectId;
63
+ }
64
+
60
65
  const instance = this.model(this.tableName);
61
66
  const id = await instance.add(data);
62
67
  return { ...data, objectId: id };