diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-08-06 18:28:27 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-08-06 18:28:27 +0900 |
| commit | 5f208a7d99cf985e9c613e2d65656ae4d46aa68a (patch) | |
| tree | 0c74b4e4c8214454eae9b8da9303d3909def3676 /src/server/api/endpoints/users/search.ts | |
| parent | 非公開の投稿に自分以外が返信したりRenoteしたりできな... (diff) | |
| download | sharkey-5f208a7d99cf985e9c613e2d65656ae4d46aa68a.tar.gz sharkey-5f208a7d99cf985e9c613e2d65656ae4d46aa68a.tar.bz2 sharkey-5f208a7d99cf985e9c613e2d65656ae4d46aa68a.zip | |
ユーザー検索APIを統合
Diffstat (limited to 'src/server/api/endpoints/users/search.ts')
| -rw-r--r-- | src/server/api/endpoints/users/search.ts | 161 |
1 files changed, 142 insertions, 19 deletions
diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts index d443d35b47..eda3f95728 100644 --- a/src/server/api/endpoints/users/search.ts +++ b/src/server/api/endpoints/users/search.ts @@ -1,33 +1,156 @@ import $ from 'cafy'; -import User, { pack, ILocalUser } from '../../../../models/user'; const escapeRegexp = require('escape-regexp'); +import User, { pack, ILocalUser, validateUsername, IUser } from '../../../../models/user'; +import getParams from '../../get-params'; + +export const meta = { + desc: { + ja: 'ユーザーを検索します。' + }, + + requireCredential: false, + + params: { + query: $.str.note({ + desc: { + ja: 'クエリ' + } + }), + + offset: $.num.optional.min(0).note({ + default: 0, + desc: { + ja: 'オフセット' + } + }), + + limit: $.num.optional.range(1, 100).note({ + default: 10, + desc: { + ja: '取得する数' + } + }), + + localOnly: $.bool.optional.note({ + default: false, + desc: { + ja: 'ローカルユーザーのみ検索対象にするか否か' + } + }), + }, +}; /** * Search a user */ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { - // Get 'query' parameter - const [query, queryError] = $.str.pipe(x => x != '').get(params.query); - if (queryError) return rej('invalid query param'); + const [ps, psErr] = getParams(meta, params); + if (psErr) return rej(psErr); + + const isUsername = validateUsername(ps.query.replace('@', '')); + + let users: IUser[] = []; + + if (isUsername) { + users = await User + .find({ + host: null, + usernameLower: new RegExp('^' + escapeRegexp(ps.query.replace('@', '').toLowerCase())) + }, { + limit: ps.limit, + skip: ps.offset + }); + + if (users.length < ps.limit && !ps.localOnly) { + const otherUsers = await User + .find({ + host: { $ne: null }, + usernameLower: new RegExp('^' + escapeRegexp(ps.query.replace('@', '').toLowerCase())) + }, { + limit: ps.limit - users.length + }); + + users = users.concat(otherUsers); + } - // Get 'max' parameter - const [max = 10, maxErr] = $.num.optional.range(1, 30).get(params.max); - if (maxErr) return rej('invalid max param'); + if (users.length < ps.limit) { + const otherUsers = await User + .find({ + _id: { $nin: users.map(u => u._id) }, + host: null, + usernameLower: new RegExp(escapeRegexp(ps.query.replace('@', '').toLowerCase())) + }, { + limit: ps.limit - users.length + }); - const escapedQuery = escapeRegexp(query); + users = users.concat(otherUsers); + } - // Search users - const users = await User - .find({ - host: null, - $or: [{ - usernameLower: new RegExp(escapedQuery.replace('@', '').toLowerCase()) + if (users.length < ps.limit && !ps.localOnly) { + const otherUsers = await User + .find({ + _id: { $nin: users.map(u => u._id) }, + host: { $ne: null }, + usernameLower: new RegExp(escapeRegexp(ps.query.replace('@', '').toLowerCase())) + }, { + limit: ps.limit - users.length + }); + + users = users.concat(otherUsers); + } + } + + if (users.length < ps.limit) { + const otherUsers = await User + .find({ + _id: { $nin: users.map(u => u._id) }, + host: null, + name: new RegExp('^' + escapeRegexp(ps.query.toLowerCase())) + }, { + limit: ps.limit - users.length + }); + + users = users.concat(otherUsers); + } + + if (users.length < ps.limit && !ps.localOnly) { + const otherUsers = await User + .find({ + _id: { $nin: users.map(u => u._id) }, + host: { $ne: null }, + name: new RegExp('^' + escapeRegexp(ps.query.toLowerCase())) + }, { + limit: ps.limit - users.length + }); + + users = users.concat(otherUsers); + } + + if (users.length < ps.limit) { + const otherUsers = await User + .find({ + _id: { $nin: users.map(u => u._id) }, + host: null, + name: new RegExp(escapeRegexp(ps.query.toLowerCase())) + }, { + limit: ps.limit - users.length + }); + + users = users.concat(otherUsers); + } + + if (users.length < ps.limit && !ps.localOnly) { + const otherUsers = await User + .find({ + _id: { $nin: users.map(u => u._id) }, + host: { $ne: null }, + name: new RegExp(escapeRegexp(ps.query.toLowerCase())) }, { - name: new RegExp(escapedQuery) - }] - }, { - limit: max - }); + limit: ps.limit - users.length + }); + + users = users.concat(otherUsers); + } // Serialize res(await Promise.all(users.map(user => pack(user, me, { detail: true })))); |