refactor: use ajv instead of cafy (#8324)

* wip

* wip

* Update abuse-user-reports.ts

* Update files.ts

* Update list-remote.ts

* Update list.ts

* Update show-users.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update update.ts

* Update search.ts

* Update reactions.ts

* Update search.ts

* wip

* wip

* wip

* wip

* Update update.ts

* Update relation.ts

* Update available.ts

* wip

* wip

* wip

* Update packages/backend/src/server/api/define.ts

Co-authored-by: Johann150 <johann.galle@protonmail.com>

* Update define.ts

* Update define.ts

* typo

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update update.ts

* wip

* Update signup.ts

* Update call.ts

* minimum for limit

* type

* remove needless annotation

* wip

* Update signup.ts

* wip

* wip

* fix

* Update create.ts

Co-authored-by: Johann150 <johann.galle@protonmail.com>
This commit is contained in:
syuilo 2022-02-19 14:05:32 +09:00 committed by GitHub
parent 59785ea04c
commit 510de87607
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
320 changed files with 4395 additions and 5939 deletions

View file

@ -1,40 +1,30 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { Clips } from '@/models/index';
import { makePaginationQuery } from '../../common/make-pagination-query';
export const meta = {
tags: ['users', 'clips'],
} as const;
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
const query = makePaginationQuery(Clips.createQueryBuilder('clip'), ps.sinceId, ps.untilId)
.andWhere(`clip.userId = :userId`, { userId: ps.userId })
.andWhere('clip.isPublic = true');
const clips = await query
.take(ps.limit!)
.take(ps.limit)
.getMany();
return await Clips.packMany(clips);

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { ApiError } from '../../error';
import { Users, Followings, UserProfiles } from '@/models/index';
@ -11,33 +9,6 @@ export const meta = {
requireCredential: false,
params: {
userId: {
validator: $.optional.type(ID),
},
username: {
validator: $.optional.str,
},
host: {
validator: $.optional.nullable.str,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -63,8 +34,21 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
username: { type: 'string' },
host: { type: 'string', nullable: true },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const user = await Users.findOne(ps.userId != null
? { id: ps.userId }
: { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) });
@ -98,7 +82,7 @@ export default define(meta, async (ps, me) => {
.innerJoinAndSelect('following.follower', 'follower');
const followings = await query
.take(ps.limit!)
.take(ps.limit)
.getMany();
return await Followings.packMany(followings, me, { populateFollower: true });

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { ApiError } from '../../error';
import { Users, Followings, UserProfiles } from '@/models/index';
@ -11,33 +9,6 @@ export const meta = {
requireCredential: false,
params: {
userId: {
validator: $.optional.type(ID),
},
username: {
validator: $.optional.str,
},
host: {
validator: $.optional.nullable.str,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -63,8 +34,21 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
username: { type: 'string' },
host: { type: 'string', nullable: true },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const user = await Users.findOne(ps.userId != null
? { id: ps.userId }
: { usernameLower: ps.username!.toLowerCase(), host: toPunyNullable(ps.host) });
@ -98,7 +82,7 @@ export default define(meta, async (ps, me) => {
.innerJoinAndSelect('following.followee', 'followee');
const followings = await query
.take(ps.limit!)
.take(ps.limit)
.getMany();
return await Followings.packMany(followings, me, { populateFollowee: true });

View file

@ -1,39 +1,29 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { GalleryPosts } from '@/models/index';
import { makePaginationQuery } from '../../../common/make-pagination-query';
export const meta = {
tags: ['users', 'gallery'],
} as const;
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
const query = makePaginationQuery(GalleryPosts.createQueryBuilder('post'), ps.sinceId, ps.untilId)
.andWhere(`post.userId = :userId`, { userId: ps.userId });
const posts = await query
.take(ps.limit!)
.take(ps.limit)
.getMany();
return await GalleryPosts.packMany(posts, user);

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { maximum } from '@/prelude/array';
import { ApiError } from '../../error';
@ -12,17 +10,6 @@ export const meta = {
requireCredential: false,
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -52,8 +39,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Lookup user
const user = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
@ -104,7 +100,7 @@ export default define(meta, async (ps, me) => {
const repliedUsersSorted = Object.keys(repliedUsers).sort((a, b) => repliedUsers[b] - repliedUsers[a]);
// Extract top replied users
const topRepliedUsers = repliedUsersSorted.slice(0, ps.limit!);
const topRepliedUsers = repliedUsersSorted.slice(0, ps.limit);
// Make replies object (includes weights)
const repliesObj = await Promise.all(topRepliedUsers.map(async (user) => ({

View file

@ -1,4 +1,3 @@
import $ from 'cafy';
import define from '../../../define';
import { UserGroups, UserGroupJoinings } from '@/models/index';
import { genId } from '@/misc/gen-id';
@ -12,12 +11,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
name: {
validator: $.str.range(1, 100),
},
},
res: {
type: 'object',
optional: false, nullable: false,
@ -25,8 +18,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
},
required: ['name'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
const userGroup = await UserGroups.insert({
id: genId(),
createdAt: new Date(),

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserGroups } from '@/models/index';
@ -11,12 +9,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
},
errors: {
noSuchGroup: {
message: 'No such group.',
@ -26,8 +18,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
const userGroup = await UserGroups.findOne({
id: ps.groupId,
userId: user.id,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../../define';
import { ApiError } from '../../../../error';
import { UserGroupJoinings, UserGroupInvitations } from '@/models/index';
@ -13,12 +11,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
invitationId: {
validator: $.type(ID),
},
},
errors: {
noSuchInvitation: {
message: 'No such invitation.',
@ -28,8 +20,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
invitationId: { type: 'string', format: 'misskey:id' },
},
required: ['invitationId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
// Fetch the invitation
const invitation = await UserGroupInvitations.findOne({
id: ps.invitationId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../../define';
import { ApiError } from '../../../../error';
import { UserGroupInvitations } from '@/models/index';
@ -11,12 +9,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
invitationId: {
validator: $.type(ID),
},
},
errors: {
noSuchInvitation: {
message: 'No such invitation.',
@ -26,8 +18,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
invitationId: { type: 'string', format: 'misskey:id' },
},
required: ['invitationId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
// Fetch the invitation
const invitation = await UserGroupInvitations.findOne({
id: ps.invitationId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { getUser } from '../../../common/getters';
@ -15,16 +13,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
userId: {
validator: $.type(ID),
},
},
errors: {
noSuchGroup: {
message: 'No such group.',
@ -52,8 +40,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await UserGroups.findOne({
id: ps.groupId,

View file

@ -20,8 +20,14 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const ownedGroups = await UserGroups.find({
userId: me.id,
});

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserGroups, UserGroupJoinings } from '@/models/index';
@ -11,12 +9,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
},
errors: {
noSuchGroup: {
message: 'No such group.',
@ -32,8 +24,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await UserGroups.findOne({
id: ps.groupId,

View file

@ -19,8 +19,14 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const userGroups = await UserGroups.find({
userId: me.id,
});

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { getUser } from '../../../common/getters';
@ -12,16 +10,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
userId: {
validator: $.type(ID),
},
},
errors: {
noSuchGroup: {
message: 'No such group.',
@ -43,8 +31,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await UserGroups.findOne({
id: ps.groupId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserGroups, UserGroupJoinings } from '@/models/index';
@ -11,12 +9,6 @@ export const meta = {
kind: 'read:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
},
res: {
type: 'object',
optional: false, nullable: false,
@ -32,8 +24,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await UserGroups.findOne({
id: ps.groupId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { getUser } from '../../../common/getters';
@ -12,16 +10,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
userId: {
validator: $.type(ID),
},
},
res: {
type: 'object',
optional: false, nullable: false,
@ -49,8 +37,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await UserGroups.findOne({
id: ps.groupId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserGroups } from '@/models/index';
@ -11,16 +9,6 @@ export const meta = {
kind: 'write:user-groups',
params: {
groupId: {
validator: $.type(ID),
},
name: {
validator: $.str.range(1, 100),
},
},
res: {
type: 'object',
optional: false, nullable: false,
@ -36,8 +24,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
name: { type: 'string', minLength: 1, maxLength: 100 },
},
required: ['groupId', 'name'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await UserGroups.findOne({
id: ps.groupId,

View file

@ -1,4 +1,3 @@
import $ from 'cafy';
import define from '../../../define';
import { UserLists } from '@/models/index';
import { genId } from '@/misc/gen-id';
@ -11,12 +10,6 @@ export const meta = {
kind: 'write:account',
params: {
name: {
validator: $.str.range(1, 100),
},
},
res: {
type: 'object',
optional: false, nullable: false,
@ -24,8 +17,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
},
required: ['name'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
const userList = await UserLists.insert({
id: genId(),
createdAt: new Date(),

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserLists } from '@/models/index';
@ -11,12 +9,6 @@ export const meta = {
kind: 'write:account',
params: {
listId: {
validator: $.type(ID),
},
},
errors: {
noSuchList: {
message: 'No such list.',
@ -26,8 +18,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
listId: { type: 'string', format: 'misskey:id' },
},
required: ['listId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
const userList = await UserLists.findOne({
id: ps.listId,
userId: user.id,

View file

@ -19,8 +19,14 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const userLists = await UserLists.find({
userId: me.id,
});

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import { publishUserListStream } from '@/services/stream';
import define from '../../../define';
import { ApiError } from '../../../error';
@ -13,16 +11,6 @@ export const meta = {
kind: 'write:account',
params: {
listId: {
validator: $.type(ID),
},
userId: {
validator: $.type(ID),
},
},
errors: {
noSuchList: {
message: 'No such list.',
@ -38,8 +26,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
listId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['listId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the list
const userList = await UserLists.findOne({
id: ps.listId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { getUser } from '../../../common/getters';
@ -13,16 +11,6 @@ export const meta = {
kind: 'write:account',
params: {
listId: {
validator: $.type(ID),
},
userId: {
validator: $.type(ID),
},
},
errors: {
noSuchList: {
message: 'No such list.',
@ -50,8 +38,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
listId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['listId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the list
const userList = await UserLists.findOne({
id: ps.listId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserLists } from '@/models/index';
@ -11,12 +9,6 @@ export const meta = {
kind: 'read:account',
params: {
listId: {
validator: $.type(ID),
},
},
res: {
type: 'object',
optional: false, nullable: false,
@ -32,8 +24,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
listId: { type: 'string', format: 'misskey:id' },
},
required: ['listId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Fetch the list
const userList = await UserLists.findOne({
id: ps.listId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../../define';
import { ApiError } from '../../../error';
import { UserLists } from '@/models/index';
@ -11,16 +9,6 @@ export const meta = {
kind: 'write:account',
params: {
listId: {
validator: $.type(ID),
},
name: {
validator: $.str.range(1, 100),
},
},
res: {
type: 'object',
optional: false, nullable: false,
@ -36,8 +24,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
listId: { type: 'string', format: 'misskey:id' },
name: { type: 'string', minLength: 1, maxLength: 100 },
},
required: ['listId', 'name'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
// Fetch the list
const userList = await UserLists.findOne({
id: ps.listId,

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { ApiError } from '../../error';
import { getUser } from '../../common/getters';
@ -14,57 +12,6 @@ import { generateMutedInstanceQuery } from '../../common/generate-muted-instance
export const meta = {
tags: ['users', 'notes'],
params: {
userId: {
validator: $.type(ID),
},
includeReplies: {
validator: $.optional.bool,
default: true,
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
sinceDate: {
validator: $.optional.num,
},
untilDate: {
validator: $.optional.num,
},
includeMyRenotes: {
validator: $.optional.bool,
default: true,
},
withFiles: {
validator: $.optional.bool,
default: false,
},
fileType: {
validator: $.optional.arr($.str),
},
excludeNsfw: {
validator: $.optional.bool,
default: false,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -84,8 +31,28 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
includeReplies: { type: 'boolean', default: true },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
sinceDate: { type: 'integer' },
untilDate: { type: 'integer' },
includeMyRenotes: { type: 'boolean', default: true },
withFiles: { type: 'boolean', default: false },
fileType: { type: 'array', items: {
type: 'string',
} },
excludeNsfw: { type: 'boolean', default: false },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Lookup user
const user = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
@ -141,7 +108,7 @@ export default define(meta, async (ps, me) => {
//#endregion
const timeline = await query.take(ps.limit!).getMany();
const timeline = await query.take(ps.limit).getMany();
return await Notes.packMany(timeline, me);
});

View file

@ -1,40 +1,30 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { Pages } from '@/models/index';
import { makePaginationQuery } from '../../common/make-pagination-query';
export const meta = {
tags: ['users', 'pages'],
} as const;
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {
export default define(meta, paramDef, async (ps, user) => {
const query = makePaginationQuery(Pages.createQueryBuilder('page'), ps.sinceId, ps.untilId)
.andWhere(`page.userId = :userId`, { userId: ps.userId })
.andWhere('page.visibility = \'public\'');
const pages = await query
.take(ps.limit!)
.take(ps.limit)
.getMany();
return await Pages.packMany(pages);

View file

@ -1,5 +1,3 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { NoteReactions, UserProfiles } from '@/models/index';
import { makePaginationQuery } from '../../common/make-pagination-query';
@ -11,33 +9,6 @@ export const meta = {
requireCredential: false,
params: {
userId: {
validator: $.type(ID),
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
sinceId: {
validator: $.optional.type(ID),
},
untilId: {
validator: $.optional.type(ID),
},
sinceDate: {
validator: $.optional.num,
},
untilDate: {
validator: $.optional.num,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -57,8 +28,21 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
sinceDate: { type: 'integer' },
untilDate: { type: 'integer' },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const profile = await UserProfiles.findOneOrFail(ps.userId);
if (me == null || (me.id !== ps.userId && !profile.publicReactions)) {
@ -73,7 +57,7 @@ export default define(meta, async (ps, me) => {
generateVisibilityQuery(query, me);
const reactions = await query
.take(ps.limit!)
.take(ps.limit)
.getMany();
return await Promise.all(reactions.map(reaction => NoteReactions.pack(reaction, me, { withNote: true })));

View file

@ -1,5 +1,4 @@
import ms from 'ms';
import $ from 'cafy';
import define from '../../define';
import { Users, Followings } from '@/models/index';
import { generateMutedUserQueryForUsers } from '../../common/generate-muted-user-query';
@ -12,18 +11,6 @@ export const meta = {
kind: 'read:account',
params: {
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
offset: {
validator: $.optional.num.min(0),
default: 0,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -35,8 +22,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
offset: { type: 'integer', default: 0 },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const query = Users.createQueryBuilder('user')
.where('user.isLocked = FALSE')
.andWhere('user.isExplorable = TRUE')
@ -58,7 +54,7 @@ export default define(meta, async (ps, me) => {
query.setParameters(followingQuery.getParameters());
const users = await query.take(ps.limit!).skip(ps.offset).getMany();
const users = await query.take(ps.limit).skip(ps.offset).getMany();
return await Users.packMany(users, me, { detail: true });
});

View file

@ -1,6 +1,4 @@
import $ from 'cafy';
import define from '../../define';
import { ID } from '@/misc/cafy-id';
import { Users } from '@/models/index';
export const meta = {
@ -8,12 +6,6 @@ export const meta = {
requireCredential: true,
params: {
userId: {
validator: $.either($.type(ID), $.arr($.type(ID)).unique()),
},
},
res: {
optional: false, nullable: false,
oneOf: [
@ -101,8 +93,24 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: {
anyOf: [
{ type: 'string', format: 'misskey:id' },
{
type: 'array',
items: { type: 'string', format: 'misskey:id' },
},
],
},
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const ids = Array.isArray(ps.userId) ? ps.userId : [ps.userId];
const relations = await Promise.all(ids.map(id => Users.getRelation(me.id, id)));

View file

@ -1,6 +1,4 @@
import $ from 'cafy';
import * as sanitizeHtml from 'sanitize-html';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
import { publishAdminStream } from '@/services/stream';
import { ApiError } from '../../error';
@ -15,16 +13,6 @@ export const meta = {
requireCredential: true,
params: {
userId: {
validator: $.type(ID),
},
comment: {
validator: $.str.range(1, 2048),
},
},
errors: {
noSuchUser: {
message: 'No such user.',
@ -46,8 +34,17 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
comment: { type: 'string', minLength: 1, maxLength: 2048 },
},
required: ['userId', 'comment'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
// Lookup user
const user = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);

View file

@ -1,4 +1,3 @@
import $ from 'cafy';
import define from '../../define';
import { Followings, Users } from '@/models/index';
import { Brackets } from 'typeorm';
@ -10,26 +9,6 @@ export const meta = {
requireCredential: false,
params: {
username: {
validator: $.optional.nullable.str,
},
host: {
validator: $.optional.nullable.str,
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
detail: {
validator: $.optional.bool,
default: true,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -41,8 +20,19 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
username: { type: 'string', nullable: true },
host: { type: 'string', nullable: true },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
detail: { type: 'boolean', default: true },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日
if (ps.host) {
@ -57,7 +47,7 @@ export default define(meta, async (ps, me) => {
q.andWhere('user.updatedAt IS NOT NULL');
q.orderBy('user.updatedAt', 'DESC');
const users = await q.take(ps.limit!).getMany();
const users = await q.take(ps.limit).getMany();
return await Users.packMany(users, me, { detail: ps.detail });
} else if (ps.username) {
@ -82,10 +72,10 @@ export default define(meta, async (ps, me) => {
users = await query
.orderBy('user.usernameLower', 'ASC')
.take(ps.limit!)
.take(ps.limit)
.getMany();
if (users.length < ps.limit!) {
if (users.length < ps.limit) {
const otherQuery = await Users.createQueryBuilder('user')
.where(`user.id NOT IN (${ followingQuery.getQuery() })`)
.andWhere(`user.id != :meId`, { meId: me.id })
@ -97,7 +87,7 @@ export default define(meta, async (ps, me) => {
const otherUsers = await otherQuery
.orderBy('user.updatedAt', 'DESC')
.take(ps.limit! - users.length)
.take(ps.limit - users.length)
.getMany();
users = users.concat(otherUsers);
@ -108,7 +98,7 @@ export default define(meta, async (ps, me) => {
.andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
.andWhere('user.updatedAt IS NOT NULL')
.orderBy('user.updatedAt', 'DESC')
.take(ps.limit! - users.length)
.take(ps.limit - users.length)
.getMany();
}

View file

@ -1,4 +1,3 @@
import $ from 'cafy';
import define from '../../define';
import { UserProfiles, Users } from '@/models/index';
import { User } from '@/models/entities/user';
@ -9,32 +8,6 @@ export const meta = {
requireCredential: false,
params: {
query: {
validator: $.str,
},
offset: {
validator: $.optional.num.min(0),
default: 0,
},
limit: {
validator: $.optional.num.range(1, 100),
default: 10,
},
origin: {
validator: $.optional.str.or(['local', 'remote', 'combined']),
default: 'combined',
},
detail: {
validator: $.optional.bool,
default: true,
},
},
res: {
type: 'array',
optional: false, nullable: false,
@ -46,8 +19,20 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
query: { type: 'string' },
offset: { type: 'integer', default: 0 },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
origin: { type: 'string', enum: ['local', 'remote', 'combined'], default: "combined" },
detail: { type: 'boolean', default: true },
},
required: ['query'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日
const isUsername = ps.query.startsWith('@');
@ -71,7 +56,7 @@ export default define(meta, async (ps, me) => {
users = await usernameQuery
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
.take(ps.limit!)
.take(ps.limit)
.skip(ps.offset)
.getMany();
} else {
@ -91,11 +76,11 @@ export default define(meta, async (ps, me) => {
users = await nameQuery
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
.take(ps.limit!)
.take(ps.limit)
.skip(ps.offset)
.getMany();
if (users.length < ps.limit!) {
if (users.length < ps.limit) {
const profQuery = UserProfiles.createQueryBuilder('prof')
.select('prof.userId')
.where('prof.description ILIKE :query', { query: '%' + ps.query + '%' });
@ -117,7 +102,7 @@ export default define(meta, async (ps, me) => {
users = users.concat(await query
.orderBy('user.updatedAt', 'DESC', 'NULLS LAST')
.take(ps.limit!)
.take(ps.limit)
.skip(ps.offset)
.getMany()
);

View file

@ -1,9 +1,7 @@
import $ from 'cafy';
import { resolveUser } from '@/remote/resolve-user';
import define from '../../define';
import { apiLogger } from '../../logger';
import { ApiError } from '../../error';
import { ID } from '@/misc/cafy-id';
import { Users } from '@/models/index';
import { In } from 'typeorm';
import { User } from '@/models/entities/user';
@ -13,24 +11,6 @@ export const meta = {
requireCredential: false,
params: {
userId: {
validator: $.optional.type(ID),
},
userIds: {
validator: $.optional.arr($.type(ID)).unique(),
},
username: {
validator: $.optional.str,
},
host: {
validator: $.optional.nullable.str,
},
},
res: {
optional: false, nullable: false,
oneOf: [
@ -64,8 +44,21 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
userIds: { type: 'array', uniqueItems: true, items: {
type: 'string', format: 'misskey:id',
} },
username: { type: 'string' },
host: { type: 'string', nullable: true },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
let user;
const isAdminOrModerator = me && (me.isAdmin || me.isModerator);

View file

@ -1,7 +1,5 @@
import $ from 'cafy';
import define from '../../define';
import { ApiError } from '../../error';
import { ID } from '@/misc/cafy-id';
import { DriveFiles, Followings, NoteFavorites, NoteReactions, Notes, PageLikes, PollVotes, Users } from '@/models/index';
export const meta = {
@ -9,12 +7,6 @@ export const meta = {
requireCredential: false,
params: {
userId: {
validator: $.type(ID),
},
},
errors: {
noSuchUser: {
message: 'No such user.',
@ -24,8 +16,16 @@ export const meta = {
},
} as const;
const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {
export default define(meta, paramDef, async (ps, me) => {
const user = await Users.findOne(ps.userId);
if (user == null) {
throw new ApiError(meta.errors.noSuchUser);