summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/users/search.ts
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-08-06 18:28:27 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-08-06 18:28:27 +0900
commit5f208a7d99cf985e9c613e2d65656ae4d46aa68a (patch)
tree0c74b4e4c8214454eae9b8da9303d3909def3676 /src/server/api/endpoints/users/search.ts
parent非公開の投稿に自分以外が返信したりRenoteしたりできな... (diff)
downloadsharkey-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.ts161
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 }))));