Fixed 267U.pre2

This commit is contained in:
2026-07-26 18:25:37 +09:00
parent 50bfaeafdf
commit 317d00a284
1286 changed files with 80222 additions and 1 deletions
@@ -0,0 +1,123 @@
import { Brackets } from "typeorm";
import { Followings, Users } from "../../../../models/index.js";
import define from "../../define.js";
import { sqlLikeEscape } from "../../../../misc/sql-like-escape.js";
import { generateMinorBadgeUserVisibilityQuery } from "../../common/generate-minor-badge-visibility-query.js";
export const meta = {
tags: [
"users"
],
requireCredential: false,
requireCredentialPrivateMode: true,
description: "Search for a user by username and/or host.",
res: {
type: "array",
optional: false,
nullable: false,
items: {
type: "object",
optional: false,
nullable: false,
ref: "User"
}
}
};
export const paramDef = {
type: "object",
properties: {
username: {
type: "string",
nullable: true
},
host: {
type: "string",
nullable: true
},
limit: {
type: "integer",
minimum: 1,
maximum: 100,
default: 10
},
maxDaysSinceLastActive: {
type: "integer",
minimum: 1,
maximum: 1000,
nullable: true
},
detail: {
type: "boolean",
default: true
}
},
anyOf: [
{
required: [
"username"
]
},
{
required: [
"host"
]
}
]
};
// TODO: avatar,bannerをJOINしたいけどエラーになる
export default define(meta, paramDef, async (ps, me)=>{
const activeThreshold = ps.maxDaysSinceLastActive ? new Date(Date.now() - 1000 * 60 * 60 * 24 * ps.maxDaysSinceLastActive) : null;
if (ps.host) {
const q = Users.createQueryBuilder("user").where("user.isSuspended = FALSE").andWhere("user.host LIKE :host", {
host: `${sqlLikeEscape(ps.host.toLowerCase())}%`
});
if (ps.username) {
q.andWhere("user.usernameLower LIKE :username", {
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`
});
}
q.andWhere("user.updatedAt IS NOT NULL");
generateMinorBadgeUserVisibilityQuery(q, me);
q.orderBy("user.updatedAt", "DESC");
const users = await q.take(ps.limit).getMany();
return await Users.packMany(users, me, {
detail: ps.detail
});
} else if (ps.username) {
let users = [];
if (me) {
const followingQuery = Followings.createQueryBuilder("following").select("following.followeeId").where("following.followerId = :followerId", {
followerId: me.id
});
const query = Users.createQueryBuilder("user").where(`user.id IN (${followingQuery.getQuery()})`).andWhere("user.isSuspended = FALSE").andWhere("user.usernameLower LIKE :username", {
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`
});
if (activeThreshold) {
query.andWhere(new Brackets((qb)=>{
qb.where("user.updatedAt IS NULL").orWhere("user.updatedAt > :activeThreshold", {
activeThreshold: activeThreshold
});
}));
}
generateMinorBadgeUserVisibilityQuery(query, me);
query.setParameters(followingQuery.getParameters());
users = await query.orderBy("user.usernameLower", "ASC").take(ps.limit).getMany();
if (users.length < ps.limit) {
const otherQuery = await Users.createQueryBuilder("user").where(`user.id NOT IN (${followingQuery.getQuery()})`).andWhere("user.isSuspended = FALSE").andWhere("user.usernameLower LIKE :username", {
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`
}).andWhere("user.updatedAt IS NOT NULL");
generateMinorBadgeUserVisibilityQuery(otherQuery, me);
otherQuery.setParameters(followingQuery.getParameters());
const otherUsers = await otherQuery.orderBy("user.updatedAt", "DESC").take(ps.limit - users.length).getMany();
users = users.concat(otherUsers);
}
} else {
users = await Users.createQueryBuilder("user").where("user.isSuspended = FALSE").andWhere("user.usernameLower LIKE :username", {
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`
}).andWhere("user.updatedAt IS NOT NULL").andWhere("NOT ('E' = ANY(user.\"minorBadges\"))").orderBy("user.updatedAt", "DESC").take(ps.limit - users.length).getMany();
}
return await Users.packMany(users, me, {
detail: !!ps.detail
});
}
return [];
});