twikoo-func 1.7.16 → 1.7.18

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/index.js +96 -2
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -249,11 +249,30 @@ function getAdminTicket (credentials) {
249
249
  return ticket
250
250
  }
251
251
 
252
+ function getSearchKeyword (event) {
253
+ if (event.keyword === undefined || event.keyword === null) return ''
254
+ if (typeof event.keyword !== 'string') throw new Error('搜索关键词必须是字符串')
255
+ const keyword = event.keyword.trim()
256
+ if (keyword.length > 100) throw new Error('搜索关键词不能超过 100 个字符')
257
+ return keyword
258
+ }
259
+
260
+ function commentMatchesKeyword (comment, keyword) {
261
+ return [comment.nick, comment.comment].some(value =>
262
+ typeof value === 'string' && value.toLowerCase().includes(keyword)
263
+ )
264
+ }
265
+
266
+ function escapeRegExp (value) {
267
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
268
+ }
269
+
252
270
  // 读取评论
253
271
  async function commentGet (event) {
254
272
  const res = {}
255
273
  try {
256
274
  validate(event, ['url'])
275
+ if (getSearchKeyword(event)) return commentSearch(event)
257
276
  const uid = await auth.getEndUserInfo().userInfo.uid
258
277
  const isAdminUser = await isAdmin()
259
278
  const limit = parseInt(config.COMMENT_PAGE_SIZE) || 8
@@ -340,6 +359,80 @@ async function commentGet (event) {
340
359
  return res
341
360
  }
342
361
 
362
+ async function commentSearch (event) {
363
+ const res = {}
364
+ try {
365
+ validate(event, ['url'])
366
+ const keyword = getSearchKeyword(event).toLowerCase()
367
+ const page = Math.max(parseInt(event.page) || 1, 1)
368
+ const uid = await auth.getEndUserInfo().userInfo.uid
369
+ const isAdminUser = await isAdmin()
370
+ const limit = parseInt(config.COMMENT_PAGE_SIZE) || 8
371
+ const sort = event.sort || 'newest'
372
+ let more = false
373
+
374
+ const condition = { url: _.in(getUrlQuery(event.url)) }
375
+ const query = getCommentQuery({ condition, uid, isAdminUser })
376
+ const searchComments = []
377
+ let cursor
378
+ while (true) {
379
+ const batchQuery = cursor
380
+ ? _.and(query, _.or(
381
+ { created: _.gt(cursor.created) },
382
+ { created: cursor.created, _id: _.gt(cursor._id) }
383
+ ))
384
+ : query
385
+ const batch = await db.collection('comment')
386
+ .where(batchQuery)
387
+ .orderBy('created', 'asc')
388
+ .orderBy('_id', 'asc')
389
+ .limit(100)
390
+ .get()
391
+ searchComments.push(...batch.data)
392
+ if (batch.data.length < 100) break
393
+ cursor = batch.data[batch.data.length - 1]
394
+ }
395
+ const matchedRoots = new Set(searchComments
396
+ .filter(comment => commentMatchesKeyword(comment, keyword))
397
+ .map(comment => String(comment.rid || comment._id)))
398
+ let main = searchComments.filter(comment =>
399
+ (!comment.rid || comment.rid === '') && matchedRoots.has(String(comment._id))
400
+ )
401
+ const count = main.length
402
+
403
+ main.sort((a, b) => {
404
+ if (sort === 'oldest') return a.created - b.created
405
+ if (sort === 'popular') {
406
+ const ups = (b.ups || []).length - (a.ups || []).length
407
+ if (ups) return ups
408
+ }
409
+ return b.created - a.created
410
+ })
411
+ let top = []
412
+ if (!config.TOP_DISABLED) {
413
+ if (page === 1) top = main.filter(comment => comment.top === true)
414
+ main = main.filter(comment => comment.top !== true)
415
+ }
416
+ main = main.slice((page - 1) * limit, page * limit + 1)
417
+
418
+ if (main.length > limit) {
419
+ more = true
420
+ main = main.slice(0, limit)
421
+ }
422
+ main = [...top, ...main]
423
+
424
+ const mainIds = new Set(main.map(comment => String(comment._id)))
425
+ const reply = searchComments.filter(comment => mainIds.has(String(comment.rid)))
426
+ res.data = parseComment([...main, ...reply], uid, config)
427
+ res.more = more
428
+ res.count = count
429
+ } catch (e) {
430
+ res.data = []
431
+ res.message = e.message
432
+ }
433
+ return res
434
+ }
435
+
343
436
  function getCommentQuery ({ condition, uid, isAdminUser }) {
344
437
  return _.or(
345
438
  { ...condition, isSpam: _.neq(isAdminUser ? 'imaegoo' : true) },
@@ -387,9 +480,10 @@ function getCommentSearchCondition (event) {
387
480
  break
388
481
  }
389
482
  }
390
- if (event.keyword) {
483
+ const keyword = getSearchKeyword(event)
484
+ if (keyword) {
391
485
  const regExp = new db.RegExp({
392
- regexp: event.keyword,
486
+ regexp: escapeRegExp(keyword),
393
487
  options: 'i'
394
488
  })
395
489
  condition = _.or(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twikoo-func",
3
- "version": "1.7.16",
3
+ "version": "1.7.18",
4
4
  "description": "A simple comment system.",
5
5
  "author": "imaegoo <hello@imaegoo.com> (https://github.com/imaegoo)",
6
6
  "license": "MIT",