refactor: APIエンドポイントファイルの定義を良い感じにする (#8154)

* Fix API Schema Error

* Delete SimpleSchema/SimpleObj
and Move schemas to dedicated files

* Userのスキーマを分割してみる

* define packMany type

* add ,

* Ensure enum schema and Make "as const" put once

* test?

* Revert "test?"

This reverts commit 97dc9bfa70.

* Revert "Fix API Schema Error"

This reverts commit 21b6176d97.

* ✌️

* clean up

* test?

* wip

* wip

* better schema def

* ✌️

* fix

* add minLength property

* wip

* wip

* wip

* anyOf/oneOf/allOfに対応? ~ relation.ts

* refactor!

* Define MinimumSchema

* wip

* wip

* anyOf/oneOf/allOfが動作するようにUnionSchemaTypeを修正

* anyOf/oneOf/allOfが動作するようにUnionSchemaTypeを修正

* Update packages/backend/src/misc/schema.ts

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

* fix

* array oneOfをより正確な型に

* array oneOfをより正確な型に

* wip

* ✌️

* なんかもういろいろ

* remove

* very good schema

* api schema

* wip

* refactor: awaitAllの型定義を変えてみる

* fix

* specify types in awaitAll

* specify types in awaitAll

* ✌️

* wip

* ...

* ✌️

* AllowDateはやめておく

* 不必要なoptional: false, nullable: falseを廃止

* Packedが展開されないように

* 続packed

* wip

* define note type

* wip

* UserDetailedをMeDetailedかUserDetailedNotMeかを区別できるように

* wip

* wip

* wip specify user type of other schemas

* ok

* convertSchemaToOpenApiSchemaを改修

* convertSchemaToOpenApiSchemaを改修

* Fix

* fix

* ✌️

* wip

* 分割代入ではなくallOfで定義するように

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
This commit is contained in:
tamaina 2022-01-18 22:27:10 +09:00 committed by GitHub
parent a8fad1b61c
commit efb0ffc4ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
358 changed files with 3623 additions and 3417 deletions

View file

@ -1,30 +1,44 @@
import { SimpleObj, SimpleSchema } from './simple-schema';
import { packedUserSchema } from '@/models/repositories/user';
import { packedNoteSchema } from '@/models/repositories/note';
import { packedUserListSchema } from '@/models/repositories/user-list';
import { packedAppSchema } from '@/models/repositories/app';
import { packedMessagingMessageSchema } from '@/models/repositories/messaging-message';
import { packedNotificationSchema } from '@/models/repositories/notification';
import { packedDriveFileSchema } from '@/models/repositories/drive-file';
import { packedDriveFolderSchema } from '@/models/repositories/drive-folder';
import { packedFollowingSchema } from '@/models/repositories/following';
import { packedMutingSchema } from '@/models/repositories/muting';
import { packedBlockingSchema } from '@/models/repositories/blocking';
import { packedNoteReactionSchema } from '@/models/repositories/note-reaction';
import { packedHashtagSchema } from '@/models/repositories/hashtag';
import { packedPageSchema } from '@/models/repositories/page';
import { packedUserGroupSchema } from '@/models/repositories/user-group';
import { packedNoteFavoriteSchema } from '@/models/repositories/note-favorite';
import { packedChannelSchema } from '@/models/repositories/channel';
import { packedAntennaSchema } from '@/models/repositories/antenna';
import { packedClipSchema } from '@/models/repositories/clip';
import { packedFederationInstanceSchema } from '@/models/repositories/federation-instance';
import { packedQueueCountSchema } from '@/models/repositories/queue';
import { packedGalleryPostSchema } from '@/models/repositories/gallery-post';
import { packedEmojiSchema } from '@/models/repositories/emoji';
import {
packedUserLiteSchema,
packedUserDetailedNotMeOnlySchema,
packedMeDetailedOnlySchema,
packedUserDetailedNotMeSchema,
packedMeDetailedSchema,
packedUserDetailedSchema,
packedUserSchema,
} from '@/models/schema/user';
import { packedNoteSchema } from '@/models/schema/note';
import { packedUserListSchema } from '@/models/schema/user-list';
import { packedAppSchema } from '@/models/schema/app';
import { packedMessagingMessageSchema } from '@/models/schema/messaging-message';
import { packedNotificationSchema } from '@/models/schema/notification';
import { packedDriveFileSchema } from '@/models/schema/drive-file';
import { packedDriveFolderSchema } from '@/models/schema/drive-folder';
import { packedFollowingSchema } from '@/models/schema/following';
import { packedMutingSchema } from '@/models/schema/muting';
import { packedBlockingSchema } from '@/models/schema/blocking';
import { packedNoteReactionSchema } from '@/models/schema/note-reaction';
import { packedHashtagSchema } from '@/models/schema/hashtag';
import { packedPageSchema } from '@/models/schema/page';
import { packedUserGroupSchema } from '@/models/schema/user-group';
import { packedNoteFavoriteSchema } from '@/models/schema/note-favorite';
import { packedChannelSchema } from '@/models/schema/channel';
import { packedAntennaSchema } from '@/models/schema/antenna';
import { packedClipSchema } from '@/models/schema/clip';
import { packedFederationInstanceSchema } from '@/models/schema/federation-instance';
import { packedQueueCountSchema } from '@/models/schema/queue';
import { packedGalleryPostSchema } from '@/models/schema/gallery-post';
import { packedEmojiSchema } from '@/models/schema/emoji';
export const refs = {
UserLite: packedUserLiteSchema,
UserDetailedNotMeOnly: packedUserDetailedNotMeOnlySchema,
MeDetailedOnly: packedMeDetailedOnlySchema,
UserDetailedNotMe: packedUserDetailedNotMeSchema,
MeDetailed: packedMeDetailedSchema,
UserDetailed: packedUserDetailedSchema,
User: packedUserSchema,
UserList: packedUserListSchema,
UserGroup: packedUserGroupSchema,
App: packedAppSchema,
@ -49,12 +63,50 @@ export const refs = {
Emoji: packedEmojiSchema,
};
export type Packed<x extends keyof typeof refs> = ObjType<(typeof refs[x])['properties']>;
// Packed = SchemaTypeDef<typeof refs[x]>; とすると展開されてマウスホバー時に型表示が使い物にならなくなる
// ObjType<r['properties']>を指定するとなぜか展開されずにPacked<'Hoge'>と表示される
type PackedDef<r extends { properties?: Obj; oneOf?: ReadonlyArray<MinimumSchema>; allOf?: ReadonlyArray<MinimumSchema> }> =
r['allOf'] extends ReadonlyArray<MinimumSchema> ? UnionToIntersection<UnionSchemaType<r['allOf']>> :
r['oneOf'] extends ReadonlyArray<MinimumSchema> ? UnionSchemaType<r['oneOf']> :
r['properties'] extends Obj ? ObjType<r['properties']> :
never;
export type Packed<x extends keyof typeof refs> = PackedDef<typeof refs[x]>;
export interface Schema extends SimpleSchema {
items?: Schema;
properties?: Obj;
ref?: keyof typeof refs;
type TypeStringef = 'boolean' | 'number' | 'string' | 'array' | 'object' | 'any';
type StringDefToType<T extends TypeStringef> =
T extends 'boolean' ? boolean :
T extends 'number' ? number :
T extends 'string' ? string | Date :
T extends 'array' ? ReadonlyArray<any> :
T extends 'object' ? Record<string, any> :
any;
// https://swagger.io/specification/?sbsearch=optional#schema-object
type OfSchema = {
readonly anyOf?: ReadonlyArray<MinimumSchema>;
readonly oneOf?: ReadonlyArray<MinimumSchema>;
readonly allOf?: ReadonlyArray<MinimumSchema>;
}
export interface MinimumSchema extends OfSchema {
readonly type?: TypeStringef;
readonly nullable?: boolean;
readonly optional?: boolean;
readonly items?: MinimumSchema;
readonly properties?: Obj;
readonly description?: string;
readonly example?: any;
readonly format?: string;
readonly ref?: keyof typeof refs;
readonly enum?: ReadonlyArray<string>;
readonly default?: (this['type'] extends TypeStringef ? StringDefToType<this['type']> : any) | null;
readonly maxLength?: number;
readonly minLength?: number;
}
export interface Schema extends MinimumSchema {
readonly nullable: boolean;
readonly optional: boolean;
}
type NonUndefinedPropertyNames<T extends Obj> = {
@ -65,22 +117,13 @@ type UndefinedPropertyNames<T extends Obj> = {
[K in keyof T]: T[K]['optional'] extends true ? K : never
}[keyof T];
type OnlyRequired<T extends Obj> = Pick<T, NonUndefinedPropertyNames<T>>;
type OnlyOptional<T extends Obj> = Pick<T, UndefinedPropertyNames<T>>;
export interface Obj extends SimpleObj { [key: string]: Schema; }
export interface Obj { [key: string]: Schema; }
export type ObjType<s extends Obj> =
{ [P in keyof OnlyOptional<s>]?: SchemaType<s[P]> } &
{ [P in keyof OnlyRequired<s>]: SchemaType<s[P]> };
{ -readonly [P in UndefinedPropertyNames<s>]?: SchemaType<s[P]> } &
{ -readonly [P in NonUndefinedPropertyNames<s>]: SchemaType<s[P]> };
// https://qiita.com/hrsh7th@github/items/84e8968c3601009cdcf2
type MyType<T extends Schema> = {
0: any;
1: SchemaType<T>;
}[T extends Schema ? 1 : 0];
type NullOrUndefined<p extends Schema, T> =
type NullOrUndefined<p extends MinimumSchema, T> =
p['nullable'] extends true
? p['optional'] extends true
? (T | null | undefined)
@ -89,15 +132,41 @@ type NullOrUndefined<p extends Schema, T> =
? (T | undefined)
: T;
export type SchemaType<p extends Schema> =
p['type'] extends 'number' ? NullOrUndefined<p, number> :
p['type'] extends 'string' ? NullOrUndefined<p, string> :
p['type'] extends 'boolean' ? NullOrUndefined<p, boolean> :
p['type'] extends 'array' ? NullOrUndefined<p, MyType<NonNullable<p['items']>>[]> :
p['type'] extends 'object' ? (
p['ref'] extends keyof typeof refs
? NullOrUndefined<p, Packed<p['ref']>>
: NullOrUndefined<p, ObjType<NonNullable<p['properties']>>>
// 共用体型を交差型にする型 https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
// https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552
// 単純にSchemaTypeDef<X>で判定するだけではダメ
type UnionSchemaType<a extends readonly any[], X extends MinimumSchema = a[number]> = X extends any ? SchemaType<X> : never;
type ArrayUnion<T> = T extends any ? Array<T> : never;
export type SchemaTypeDef<p extends MinimumSchema> =
p['type'] extends 'number' ? number :
p['type'] extends 'string' ? (
p['enum'] extends readonly string[] ?
p['enum'][number] :
p['format'] extends 'date-time' ? string : // Dateにする
string
) :
p['type'] extends 'any' ? NullOrUndefined<p, any> :
p['type'] extends 'boolean' ? boolean :
p['type'] extends 'object' ? (
p['ref'] extends keyof typeof refs ? Packed<p['ref']> :
p['properties'] extends NonNullable<Obj> ? ObjType<p['properties']> :
p['anyOf'] extends ReadonlyArray<MinimumSchema> ? UnionSchemaType<p['anyOf']> & Partial<UnionToIntersection<UnionSchemaType<p['anyOf']>>> :
p['allOf'] extends ReadonlyArray<MinimumSchema> ? UnionToIntersection<UnionSchemaType<p['allOf']>> :
any
) :
p['type'] extends 'array' ? (
p['items'] extends OfSchema ? (
p['items']['anyOf'] extends ReadonlyArray<MinimumSchema> ? UnionSchemaType<NonNullable<p['items']['anyOf']>>[] :
p['items']['oneOf'] extends ReadonlyArray<MinimumSchema> ? ArrayUnion<UnionSchemaType<NonNullable<p['items']['oneOf']>>> :
p['items']['allOf'] extends ReadonlyArray<MinimumSchema> ? UnionToIntersection<UnionSchemaType<NonNullable<p['items']['allOf']>>>[] :
never
) :
p['items'] extends NonNullable<MinimumSchema> ? SchemaTypeDef<p['items']>[] :
any[]
) :
p['oneOf'] extends ReadonlyArray<MinimumSchema> ? UnionSchemaType<p['oneOf']> :
any;
export type SchemaType<p extends MinimumSchema> = NullOrUndefined<p, SchemaTypeDef<p>>;

View file

@ -1,15 +0,0 @@
export interface SimpleSchema {
type: 'boolean' | 'number' | 'string' | 'array' | 'object' | 'any';
nullable: boolean;
optional: boolean;
items?: SimpleSchema;
properties?: SimpleObj;
description?: string;
example?: any;
format?: string;
ref?: string;
enum?: string[];
default?: boolean | null;
}
export interface SimpleObj { [key: string]: SimpleSchema; }

View file

@ -31,94 +31,3 @@ export class AntennaRepository extends Repository<Antenna> {
};
}
}
export const packedAntennaSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
keywords: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
},
excludeKeywords: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
},
src: {
type: 'string' as const,
optional: false as const, nullable: false as const,
enum: ['home', 'all', 'users', 'list', 'group'],
},
userListId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
},
userGroupId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
},
users: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
caseSensitive: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
default: false,
},
notify: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
withReplies: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
default: false,
},
withFile: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
hasUnreadNote: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
default: false,
},
},
};

View file

@ -38,38 +38,3 @@ export class AppRepository extends Repository<App> {
};
}
}
export const packedAppSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
callbackUrl: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
permission: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
secret: {
type: 'string' as const,
optional: true as const, nullable: false as const,
},
isAuthorized: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
},
};

View file

@ -30,31 +30,3 @@ export class BlockingRepository extends Repository<Blocking> {
return Promise.all(blockings.map(x => this.pack(x, me)));
}
}
export const packedBlockingSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
blockeeId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
blockee: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'User' as const,
},
},
};

View file

@ -40,56 +40,3 @@ export class ChannelRepository extends Repository<Channel> {
};
}
}
export const packedChannelSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
lastNotedAt: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'date-time',
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
description: {
type: 'string' as const,
nullable: true as const, optional: false as const,
},
bannerUrl: {
type: 'string' as const,
format: 'url',
nullable: true as const, optional: false as const,
},
notesCount: {
type: 'number' as const,
nullable: false as const, optional: false as const,
},
usersCount: {
type: 'number' as const,
nullable: false as const, optional: false as const,
},
isFollowing: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
userId: {
type: 'string' as const,
nullable: true as const, optional: false as const,
format: 'id',
},
},
};

View file

@ -29,42 +29,3 @@ export class ClipRepository extends Repository<Clip> {
}
}
export const packedClipSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
userId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
user: {
type: 'object' as const,
ref: 'User' as const,
optional: false as const, nullable: false as const,
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
description: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
isPublic: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
},
};

View file

@ -3,7 +3,7 @@ import { DriveFile } from '@/models/entities/drive-file';
import { Users, DriveFolders } from '../index';
import { User } from '@/models/entities/user';
import { toPuny } from '@/misc/convert-host';
import { awaitAll } from '@/prelude/await-all';
import { awaitAll, Promiseable } from '@/prelude/await-all';
import { Packed } from '@/misc/schema';
import config from '@/config/index';
import { query, appendQuery } from '@/prelude/url';
@ -126,7 +126,7 @@ export class DriveFileRepository extends Repository<DriveFile> {
const meta = await fetchMeta();
return await awaitAll({
return await awaitAll<Packed<'DriveFile'>>({
id: file.id,
createdAt: file.createdAt.toISOString(),
name: file.name,
@ -156,112 +156,3 @@ export class DriveFileRepository extends Repository<DriveFile> {
return items.filter(x => x != null);
}
}
export const packedDriveFileSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
example: 'lenna.jpg',
},
type: {
type: 'string' as const,
optional: false as const, nullable: false as const,
example: 'image/jpeg',
},
md5: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'md5',
example: '15eca7fba0480996e2245f5185bf39f2',
},
size: {
type: 'number' as const,
optional: false as const, nullable: false as const,
example: 51469,
},
isSensitive: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
blurhash: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
properties: {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
width: {
type: 'number' as const,
optional: true as const, nullable: false as const,
example: 1280,
},
height: {
type: 'number' as const,
optional: true as const, nullable: false as const,
example: 720,
},
orientation: {
type: 'number' as const,
optional: true as const, nullable: false as const,
example: 8,
},
avgColor: {
type: 'string' as const,
optional: true as const, nullable: false as const,
example: 'rgb(40,65,87)',
},
},
},
url: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'url',
},
thumbnailUrl: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'url',
},
comment: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
folderId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
folder: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'DriveFolder' as const,
},
userId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
user: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'User' as const,
},
},
};

View file

@ -48,44 +48,3 @@ export class DriveFolderRepository extends Repository<DriveFolder> {
});
}
}
export const packedDriveFolderSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
foldersCount: {
type: 'number' as const,
optional: true as const, nullable: false as const,
},
filesCount: {
type: 'number' as const,
optional: true as const, nullable: false as const,
},
parentId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
parent: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'DriveFolder' as const,
},
},
};

View file

@ -25,41 +25,3 @@ export class EmojiRepository extends Repository<Emoji> {
return Promise.all(emojis.map(x => this.pack(x)));
}
}
export const packedEmojiSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
aliases: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
category: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
host: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
url: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
};

View file

@ -1,106 +1,2 @@
import config from '@/config/index';
export const packedFederationInstanceSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
caughtAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
host: {
type: 'string' as const,
optional: false as const, nullable: false as const,
example: 'misskey.example.com',
},
usersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
notesCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
followingCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
followersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
driveUsage: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
driveFiles: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
latestRequestSentAt: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'date-time',
},
lastCommunicatedAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
isNotResponding: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
isSuspended: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
softwareName: {
type: 'string' as const,
optional: false as const, nullable: true as const,
example: 'misskey',
},
softwareVersion: {
type: 'string' as const,
optional: false as const, nullable: true as const,
example: config.version,
},
openRegistrations: {
type: 'boolean' as const,
optional: false as const, nullable: true as const,
example: true,
},
name: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
description: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
maintainerName: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
maintainerEmail: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
iconUrl: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'url',
},
infoUpdatedAt: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'date-time',
},
},
};

View file

@ -84,41 +84,3 @@ export class FollowingRepository extends Repository<Following> {
return Promise.all(followings.map(x => this.pack(x, me, opts)));
}
}
export const packedFollowingSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
followeeId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
followee: {
type: 'object' as const,
optional: true as const, nullable: false as const,
ref: 'User' as const,
},
followerId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
follower: {
type: 'object' as const,
optional: true as const, nullable: false as const,
ref: 'User' as const,
},
},
};

View file

@ -38,74 +38,3 @@ export class GalleryPostRepository extends Repository<GalleryPost> {
return Promise.all(posts.map(x => this.pack(x, me)));
}
}
export const packedGalleryPostSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
updatedAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
title: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
description: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
userId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
user: {
type: 'object' as const,
ref: 'User' as const,
optional: false as const, nullable: false as const,
},
fileIds: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
files: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'DriveFile' as const,
},
},
tags: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
isSensitive: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
},
};

View file

@ -24,39 +24,3 @@ export class HashtagRepository extends Repository<Hashtag> {
return Promise.all(hashtags.map(x => this.pack(x)));
}
}
export const packedHashtagSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
tag: {
type: 'string' as const,
optional: false as const, nullable: false as const,
example: 'misskey',
},
mentionedUsersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
mentionedLocalUsersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
mentionedRemoteUsersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
attachedUsersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
attachedLocalUsersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
attachedRemoteUsersCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
},
};

View file

@ -42,78 +42,3 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> {
};
}
}
export const packedMessagingMessageSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
userId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
user: {
type: 'object' as const,
ref: 'User' as const,
optional: true as const, nullable: false as const,
},
text: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
fileId: {
type: 'string' as const,
optional: true as const, nullable: true as const,
format: 'id',
},
file: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'DriveFile' as const,
},
recipientId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
},
recipient: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'User' as const,
},
groupId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
format: 'id',
},
group: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'UserGroup' as const,
},
isRead: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
reads: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
},
};

View file

@ -30,31 +30,3 @@ export class MutingRepository extends Repository<Muting> {
return Promise.all(mutings.map(x => this.pack(x, me)));
}
}
export const packedMutingSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
muteeId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
mutee: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'User' as const,
},
},
};

View file

@ -26,31 +26,3 @@ export class NoteFavoriteRepository extends Repository<NoteFavorite> {
return Promise.all(favorites.map(x => this.pack(x, me)));
}
}
export const packedNoteFavoriteSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
note: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'Note' as const,
},
noteId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
};

View file

@ -31,30 +31,3 @@ export class NoteReactionRepository extends Repository<NoteReaction> {
};
}
}
export const packedNoteReactionSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
user: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'User' as const,
},
type: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
};

View file

@ -218,7 +218,7 @@ export class NoteRepository extends Repository<Note> {
const reactionEmojiNames = Object.keys(note.reactions).filter(x => x?.startsWith(':')).map(x => decodeReaction(x).reaction).map(x => x.replace(/:/g, ''));
const packed = await awaitAll({
const packed: Packed<'Note'> = await awaitAll({
id: note.id,
createdAt: note.createdAt.toISOString(),
userId: note.userId,
@ -320,188 +320,3 @@ export class NoteRepository extends Repository<Note> {
})));
}
}
export const packedNoteSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
text: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
cw: {
type: 'string' as const,
optional: true as const, nullable: true as const,
},
userId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
user: {
type: 'object' as const,
ref: 'User' as const,
optional: false as const, nullable: false as const,
},
replyId: {
type: 'string' as const,
optional: true as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
renoteId: {
type: 'string' as const,
optional: true as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
reply: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'Note' as const,
},
renote: {
type: 'object' as const,
optional: true as const, nullable: true as const,
ref: 'Note' as const,
},
isHidden: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
visibility: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
mentions: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
visibleUserIds: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
fileIds: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
},
files: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
ref: 'DriveFile' as const,
},
},
tags: {
type: 'array' as const,
optional: true as const, nullable: false as const,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
},
poll: {
type: 'object' as const,
optional: true as const, nullable: true as const,
},
channelId: {
type: 'string' as const,
optional: true as const, nullable: true as const,
format: 'id',
example: 'xxxxxxxxxx',
},
channel: {
type: 'object' as const,
optional: true as const, nullable: true as const,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
name: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
},
},
},
localOnly: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
emojis: {
type: 'array' as const,
optional: false as const, nullable: false as const,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
url: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
},
},
},
reactions: {
type: 'object' as const,
optional: false as const, nullable: false as const,
},
renoteCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
repliesCount: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
uri: {
type: 'string' as const,
optional: true as const, nullable: false as const,
},
url: {
type: 'string' as const,
optional: true as const, nullable: false as const,
},
myReaction: {
type: 'object' as const,
optional: true as const, nullable: true as const,
},
},
};

View file

@ -107,69 +107,3 @@ export class NotificationRepository extends Repository<Notification> {
})));
}
}
export const packedNotificationSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
isRead: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
},
type: {
type: 'string' as const,
optional: false as const, nullable: false as const,
enum: [...notificationTypes],
},
user: {
type: 'object' as const,
ref: 'User' as const,
optional: true as const, nullable: true as const,
},
userId: {
type: 'string' as const,
optional: true as const, nullable: true as const,
format: 'id',
},
note: {
type: 'object' as const,
ref: 'Note' as const,
optional: true as const, nullable: true as const,
},
reaction: {
type: 'string' as const,
optional: true as const, nullable: true as const,
},
choice: {
type: 'number' as const,
optional: true as const, nullable: true as const,
},
invitation: {
type: 'object' as const,
optional: true as const, nullable: true as const,
},
body: {
type: 'string' as const,
optional: true as const, nullable: true as const,
},
header: {
type: 'string' as const,
optional: true as const, nullable: true as const,
},
icon: {
type: 'string' as const,
optional: true as const, nullable: true as const,
},
},
};

View file

@ -87,56 +87,3 @@ export class PageRepository extends Repository<Page> {
return Promise.all(pages.map(x => this.pack(x, me)));
}
}
export const packedPageSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
updatedAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
title: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
summary: {
type: 'string' as const,
optional: false as const, nullable: true as const,
},
content: {
type: 'array' as const,
optional: false as const, nullable: false as const,
},
variables: {
type: 'array' as const,
optional: false as const, nullable: false as const,
},
userId: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
},
user: {
type: 'object' as const,
ref: 'User' as const,
optional: false as const, nullable: false as const,
},
},
};

View file

@ -1,30 +0,0 @@
export const packedQueueCountSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
waiting: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
active: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
completed: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
failed: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
delayed: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
paused: {
type: 'number' as const,
optional: false as const, nullable: false as const,
},
},
};

View file

@ -23,39 +23,3 @@ export class UserGroupRepository extends Repository<UserGroup> {
};
}
}
export const packedUserGroupSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
ownerId: {
type: 'string' as const,
nullable: false as const, optional: false as const,
format: 'id',
},
userIds: {
type: 'array' as const,
nullable: false as const, optional: true as const,
items: {
type: 'string' as const,
nullable: false as const, optional: false as const,
format: 'id',
},
},
},
};

View file

@ -22,34 +22,3 @@ export class UserListRepository extends Repository<UserList> {
};
}
}
export const packedUserListSchema = {
type: 'object' as const,
optional: false as const, nullable: false as const,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
format: 'date-time',
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
},
userIds: {
type: 'array' as const,
nullable: false as const, optional: true as const,
items: {
type: 'string' as const,
nullable: false as const, optional: false as const,
format: 'id',
},
},
},
};

View file

@ -4,11 +4,19 @@ import { User, ILocalUser, IRemoteUser } from '@/models/entities/user';
import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index';
import config from '@/config/index';
import { Packed } from '@/misc/schema';
import { awaitAll } from '@/prelude/await-all';
import { awaitAll, Promiseable } from '@/prelude/await-all';
import { populateEmojis } from '@/misc/populate-emojis';
import { getAntennas } from '@/misc/antenna-cache';
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const';
type IsUserDetailed<Detailed extends boolean> = Detailed extends true ? Packed<'UserDetailed'> : Packed<'UserLite'>;
type IsMeAndIsUserDetailed<ExpectsMe extends boolean | null, Detailed extends boolean> =
Detailed extends true ?
ExpectsMe extends true ? Packed<'MeDetailed'> :
ExpectsMe extends false ? Packed<'UserDetailedNotMe'> :
Packed<'UserDetailed'> :
Packed<'UserLite'>;
@EntityRepository(User)
export class UserRepository extends Repository<User> {
public async getRelation(me: User['id'], target: User['id']) {
@ -144,7 +152,7 @@ export class UserRepository extends Repository<User> {
return count > 0;
}
public getOnlineStatus(user: User): string {
public getOnlineStatus(user: User): 'unknown' | 'online' | 'active' | 'offline' {
if (user.hideOnlineStatus) return 'unknown';
if (user.lastActiveDate == null) return 'unknown';
const elapsed = Date.now() - user.lastActiveDate.getTime();
@ -163,14 +171,14 @@ export class UserRepository extends Repository<User> {
}
}
public async pack(
public async pack<ExpectsMe extends boolean | null = null, D extends boolean = false>(
src: User['id'] | User,
me?: { id: User['id'] } | null | undefined,
options?: {
detail?: boolean,
detail?: D,
includeSecrets?: boolean,
}
): Promise<Packed<'User'>> {
): Promise<IsMeAndIsUserDetailed<ExpectsMe, D>> {
const opts = Object.assign({
detail: false,
includeSecrets: false,
@ -178,8 +186,9 @@ export class UserRepository extends Repository<User> {
const user = typeof src === 'object' ? src : await this.findOneOrFail(src);
const meId = me ? me.id : null;
const isMe = meId === user.id;
const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null;
const relation = meId && !isMe && opts.detail ? await this.getRelation(meId, user.id) : null;
const pins = opts.detail ? await UserNotePinings.createQueryBuilder('pin')
.where('pin.userId = :userId', { userId: user.id })
.innerJoinAndSelect('pin.note', 'note')
@ -188,12 +197,12 @@ export class UserRepository extends Repository<User> {
const profile = opts.detail ? await UserProfiles.findOneOrFail(user.id) : null;
const followingCount = profile == null ? null :
(profile.ffVisibility === 'public') || (meId === user.id) ? user.followingCount :
(profile.ffVisibility === 'public') || isMe ? user.followingCount :
(profile.ffVisibility === 'followers') && (relation && relation.isFollowing) ? user.followingCount :
null;
const followersCount = profile == null ? null :
(profile.ffVisibility === 'public') || (meId === user.id) ? user.followersCount :
(profile.ffVisibility === 'public') || isMe ? user.followersCount :
(profile.ffVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount :
null;
@ -227,12 +236,11 @@ export class UserRepository extends Repository<User> {
uri: user.uri,
createdAt: user.createdAt.toISOString(),
updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
lastFetchedAt: user.lastFetchedAt?.toISOString(),
lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
bannerUrl: user.bannerUrl,
bannerBlurhash: user.bannerBlurhash,
bannerColor: null, // 後方互換性のため
isLocked: user.isLocked,
isModerator: user.isModerator || falsy,
isSilenced: user.isSilenced || falsy,
isSuspended: user.isSuspended || falsy,
description: profile!.description,
@ -260,7 +268,7 @@ export class UserRepository extends Repository<User> {
: false,
} : {}),
...(opts.detail && meId === user.id ? {
...(opts.detail && isMe ? {
avatarId: user.avatarId,
bannerId: user.bannerId,
injectFeaturedNote: profile!.injectFeaturedNote,
@ -315,19 +323,19 @@ export class UserRepository extends Repository<User> {
isBlocked: relation.isBlocked,
isMuted: relation.isMuted,
} : {}),
};
} as Promiseable<Packed<'User'>> as Promiseable<IsMeAndIsUserDetailed<ExpectsMe, D>>;
return await awaitAll(packed);
}
public packMany(
public packMany<D extends boolean = false>(
users: (User['id'] | User)[],
me?: { id: User['id'] } | null | undefined,
options?: {
detail?: boolean,
detail?: D,
includeSecrets?: boolean,
}
) {
): Promise<IsUserDetailed<D>[]> {
return Promise.all(users.map(u => this.pack(u, me, options)));
}
@ -352,313 +360,3 @@ export class UserRepository extends Repository<User> {
public validateBirthday = $.str.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/);
//#endregion
}
export const packedUserSchema = {
type: 'object' as const,
nullable: false as const, optional: false as const,
properties: {
id: {
type: 'string' as const,
nullable: false as const, optional: false as const,
format: 'id',
example: 'xxxxxxxxxx',
},
name: {
type: 'string' as const,
nullable: true as const, optional: false as const,
example: '藍',
},
username: {
type: 'string' as const,
nullable: false as const, optional: false as const,
example: 'ai',
},
host: {
type: 'string' as const,
nullable: true as const, optional: false as const,
example: 'misskey.example.com',
},
avatarUrl: {
type: 'string' as const,
format: 'url',
nullable: true as const, optional: false as const,
},
avatarBlurhash: {
type: 'any' as const,
nullable: true as const, optional: false as const,
},
avatarColor: {
type: 'any' as const,
nullable: true as const, optional: false as const,
default: null,
},
isAdmin: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
default: false,
},
isModerator: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
default: false,
},
isBot: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
isCat: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
emojis: {
type: 'array' as const,
nullable: false as const, optional: false as const,
items: {
type: 'object' as const,
nullable: false as const, optional: false as const,
properties: {
name: {
type: 'string' as const,
nullable: false as const, optional: false as const,
},
url: {
type: 'string' as const,
nullable: false as const, optional: false as const,
format: 'url',
},
},
},
},
url: {
type: 'string' as const,
format: 'url',
nullable: true as const, optional: true as const,
},
createdAt: {
type: 'string' as const,
nullable: false as const, optional: true as const,
format: 'date-time',
},
updatedAt: {
type: 'string' as const,
nullable: true as const, optional: true as const,
format: 'date-time',
},
bannerUrl: {
type: 'string' as const,
format: 'url',
nullable: true as const, optional: true as const,
},
bannerBlurhash: {
type: 'any' as const,
nullable: true as const, optional: true as const,
},
bannerColor: {
type: 'any' as const,
nullable: true as const, optional: true as const,
default: null,
},
isLocked: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
isSuspended: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
example: false,
},
description: {
type: 'string' as const,
nullable: true as const, optional: true as const,
example: 'Hi masters, I am Ai!',
},
location: {
type: 'string' as const,
nullable: true as const, optional: true as const,
},
birthday: {
type: 'string' as const,
nullable: true as const, optional: true as const,
example: '2018-03-12',
},
fields: {
type: 'array' as const,
nullable: false as const, optional: true as const,
items: {
type: 'object' as const,
nullable: false as const, optional: false as const,
properties: {
name: {
type: 'string' as const,
nullable: false as const, optional: false as const,
},
value: {
type: 'string' as const,
nullable: false as const, optional: false as const,
},
},
maxLength: 4,
},
},
followersCount: {
type: 'number' as const,
nullable: false as const, optional: true as const,
},
followingCount: {
type: 'number' as const,
nullable: false as const, optional: true as const,
},
notesCount: {
type: 'number' as const,
nullable: false as const, optional: true as const,
},
pinnedNoteIds: {
type: 'array' as const,
nullable: false as const, optional: true as const,
items: {
type: 'string' as const,
nullable: false as const, optional: false as const,
format: 'id',
},
},
pinnedNotes: {
type: 'array' as const,
nullable: false as const, optional: true as const,
items: {
type: 'object' as const,
nullable: false as const, optional: false as const,
ref: 'Note' as const,
},
},
pinnedPageId: {
type: 'string' as const,
nullable: true as const, optional: true as const,
},
pinnedPage: {
type: 'object' as const,
nullable: true as const, optional: true as const,
ref: 'Page' as const,
},
twoFactorEnabled: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
default: false,
},
usePasswordLessLogin: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
default: false,
},
securityKeys: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
default: false,
},
avatarId: {
type: 'string' as const,
nullable: true as const, optional: true as const,
format: 'id',
},
bannerId: {
type: 'string' as const,
nullable: true as const, optional: true as const,
format: 'id',
},
autoWatch: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
injectFeaturedNote: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
alwaysMarkNsfw: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
carefulBot: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
autoAcceptFollowed: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasUnreadSpecifiedNotes: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasUnreadMentions: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasUnreadAnnouncement: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasUnreadAntenna: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasUnreadChannel: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasUnreadMessagingMessage: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasUnreadNotification: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
hasPendingReceivedFollowRequest: {
type: 'boolean' as const,
nullable: false as const, optional: true as const,
},
integrations: {
type: 'object' as const,
nullable: false as const, optional: true as const,
},
mutedWords: {
type: 'array' as const,
nullable: false as const, optional: true as const,
},
mutedInstances: {
type: 'array' as const,
nullable: false as const, optional: true as const,
},
mutingNotificationTypes: {
type: 'array' as const,
nullable: false as const, optional: true as const,
},
isFollowing: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
hasPendingFollowRequestFromYou: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
hasPendingFollowRequestToYou: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
isFollowed: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
isBlocking: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
isBlocked: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
isMuted: {
type: 'boolean' as const,
optional: true as const, nullable: false as const,
},
},
};

View file

@ -0,0 +1,89 @@
export const packedAntennaSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
name: {
type: 'string',
optional: false, nullable: false,
},
keywords: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
},
excludeKeywords: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
},
src: {
type: 'string',
optional: false, nullable: false,
enum: ['home', 'all', 'users', 'list', 'group'],
},
userListId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
},
userGroupId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
},
users: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
caseSensitive: {
type: 'boolean',
optional: false, nullable: false,
default: false,
},
notify: {
type: 'boolean',
optional: false, nullable: false,
},
withReplies: {
type: 'boolean',
optional: false, nullable: false,
default: false,
},
withFile: {
type: 'boolean',
optional: false, nullable: false,
},
hasUnreadNote: {
type: 'boolean',
optional: false, nullable: false,
default: false,
},
},
} as const;

View file

@ -0,0 +1,33 @@
export const packedAppSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
},
name: {
type: 'string',
optional: false, nullable: false,
},
callbackUrl: {
type: 'string',
optional: false, nullable: true,
},
permission: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
secret: {
type: 'string',
optional: true, nullable: false,
},
isAuthorized: {
type: 'boolean',
optional: true, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,26 @@
export const packedBlockingSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
blockeeId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
blockee: {
type: 'object',
optional: false, nullable: false,
ref: 'UserDetailed',
},
},
} as const;

View file

@ -0,0 +1,51 @@
export const packedChannelSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
lastNotedAt: {
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
name: {
type: 'string',
optional: false, nullable: false,
},
description: {
type: 'string',
nullable: true, optional: false,
},
bannerUrl: {
type: 'string',
format: 'url',
nullable: true, optional: false,
},
notesCount: {
type: 'number',
nullable: false, optional: false,
},
usersCount: {
type: 'number',
nullable: false, optional: false,
},
isFollowing: {
type: 'boolean',
optional: true, nullable: false,
},
userId: {
type: 'string',
nullable: true, optional: false,
format: 'id',
},
},
} as const;

View file

@ -0,0 +1,38 @@
export const packedClipSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: false, nullable: false,
},
name: {
type: 'string',
optional: false, nullable: false,
},
description: {
type: 'string',
optional: false, nullable: true,
},
isPublic: {
type: 'boolean',
optional: false, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,107 @@
export const packedDriveFileSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
name: {
type: 'string',
optional: false, nullable: false,
example: 'lenna.jpg',
},
type: {
type: 'string',
optional: false, nullable: false,
example: 'image/jpeg',
},
md5: {
type: 'string',
optional: false, nullable: false,
format: 'md5',
example: '15eca7fba0480996e2245f5185bf39f2',
},
size: {
type: 'number',
optional: false, nullable: false,
example: 51469,
},
isSensitive: {
type: 'boolean',
optional: false, nullable: false,
},
blurhash: {
type: 'string',
optional: false, nullable: true,
},
properties: {
type: 'object',
optional: false, nullable: false,
properties: {
width: {
type: 'number',
optional: true, nullable: false,
example: 1280,
},
height: {
type: 'number',
optional: true, nullable: false,
example: 720,
},
orientation: {
type: 'number',
optional: true, nullable: false,
example: 8,
},
avgColor: {
type: 'string',
optional: true, nullable: false,
example: 'rgb(40,65,87)',
},
},
},
url: {
type: 'string',
optional: false, nullable: true,
format: 'url',
},
thumbnailUrl: {
type: 'string',
optional: false, nullable: true,
format: 'url',
},
comment: {
type: 'string',
optional: false, nullable: true,
},
folderId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
folder: {
type: 'object',
optional: true, nullable: true,
ref: 'DriveFolder',
},
userId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
user: {
type: 'object',
optional: true, nullable: true,
ref: 'UserLite',
},
},
} as const;

View file

@ -0,0 +1,39 @@
export const packedDriveFolderSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
name: {
type: 'string',
optional: false, nullable: false,
},
foldersCount: {
type: 'number',
optional: true, nullable: false,
},
filesCount: {
type: 'number',
optional: true, nullable: false,
},
parentId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
parent: {
type: 'object',
optional: true, nullable: true,
ref: 'DriveFolder',
},
},
} as const;

View file

@ -0,0 +1,36 @@
export const packedEmojiSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
aliases: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
name: {
type: 'string',
optional: false, nullable: false,
},
category: {
type: 'string',
optional: false, nullable: true,
},
host: {
type: 'string',
optional: false, nullable: true,
},
url: {
type: 'string',
optional: false, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,105 @@
import config from "@/config";
export const packedFederationInstanceSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
caughtAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
host: {
type: 'string',
optional: false, nullable: false,
example: 'misskey.example.com',
},
usersCount: {
type: 'number',
optional: false, nullable: false,
},
notesCount: {
type: 'number',
optional: false, nullable: false,
},
followingCount: {
type: 'number',
optional: false, nullable: false,
},
followersCount: {
type: 'number',
optional: false, nullable: false,
},
driveUsage: {
type: 'number',
optional: false, nullable: false,
},
driveFiles: {
type: 'number',
optional: false, nullable: false,
},
latestRequestSentAt: {
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
lastCommunicatedAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
isNotResponding: {
type: 'boolean',
optional: false, nullable: false,
},
isSuspended: {
type: 'boolean',
optional: false, nullable: false,
},
softwareName: {
type: 'string',
optional: false, nullable: true,
example: 'misskey',
},
softwareVersion: {
type: 'string',
optional: false, nullable: true,
example: config.version,
},
openRegistrations: {
type: 'boolean',
optional: false, nullable: true,
example: true,
},
name: {
type: 'string',
optional: false, nullable: true,
},
description: {
type: 'string',
optional: false, nullable: true,
},
maintainerName: {
type: 'string',
optional: false, nullable: true,
},
maintainerEmail: {
type: 'string',
optional: false, nullable: true,
},
iconUrl: {
type: 'string',
optional: false, nullable: true,
format: 'url',
},
infoUpdatedAt: {
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
},
} as const;

View file

@ -0,0 +1,36 @@
export const packedFollowingSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
followeeId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
followee: {
type: 'object',
optional: true, nullable: false,
ref: 'UserDetailed',
},
followerId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
follower: {
type: 'object',
optional: true, nullable: false,
ref: 'UserDetailed',
},
},
} as const;

View file

@ -0,0 +1,69 @@
export const packedGalleryPostSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
updatedAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
title: {
type: 'string',
optional: false, nullable: false,
},
description: {
type: 'string',
optional: false, nullable: true,
},
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: false, nullable: false,
},
fileIds: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
files: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'DriveFile',
},
},
tags: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
isSensitive: {
type: 'boolean',
optional: false, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,34 @@
export const packedHashtagSchema = {
type: 'object',
properties: {
tag: {
type: 'string',
optional: false, nullable: false,
example: 'misskey',
},
mentionedUsersCount: {
type: 'number',
optional: false, nullable: false,
},
mentionedLocalUsersCount: {
type: 'number',
optional: false, nullable: false,
},
mentionedRemoteUsersCount: {
type: 'number',
optional: false, nullable: false,
},
attachedUsersCount: {
type: 'number',
optional: false, nullable: false,
},
attachedLocalUsersCount: {
type: 'number',
optional: false, nullable: false,
},
attachedRemoteUsersCount: {
type: 'number',
optional: false, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,73 @@
export const packedMessagingMessageSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: true, nullable: false,
},
text: {
type: 'string',
optional: false, nullable: true,
},
fileId: {
type: 'string',
optional: true, nullable: true,
format: 'id',
},
file: {
type: 'object',
optional: true, nullable: true,
ref: 'DriveFile',
},
recipientId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
},
recipient: {
type: 'object',
optional: true, nullable: true,
ref: 'UserLite',
},
groupId: {
type: 'string',
optional: false, nullable: true,
format: 'id',
},
group: {
type: 'object',
optional: true, nullable: true,
ref: 'UserGroup',
},
isRead: {
type: 'boolean',
optional: true, nullable: false,
},
reads: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
},
} as const;

View file

@ -0,0 +1,26 @@
export const packedMutingSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
muteeId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
mutee: {
type: 'object',
optional: false, nullable: false,
ref: 'UserDetailed',
},
},
} as const;

View file

@ -0,0 +1,26 @@
export const packedNoteFavoriteSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
note: {
type: 'object',
optional: false, nullable: false,
ref: 'Note',
},
noteId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
} as const;

View file

@ -0,0 +1,25 @@
export const packedNoteReactionSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
user: {
type: 'object',
optional: false, nullable: false,
ref: 'UserLite',
},
type: {
type: 'string',
optional: false, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,183 @@
export const packedNoteSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
text: {
type: 'string',
optional: false, nullable: true,
},
cw: {
type: 'string',
optional: true, nullable: true,
},
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: false, nullable: false,
},
replyId: {
type: 'string',
optional: true, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
renoteId: {
type: 'string',
optional: true, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
reply: {
type: 'object',
optional: true, nullable: true,
ref: 'Note',
},
renote: {
type: 'object',
optional: true, nullable: true,
ref: 'Note',
},
isHidden: {
type: 'boolean',
optional: true, nullable: false,
},
visibility: {
type: 'string',
optional: false, nullable: false,
},
mentions: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
visibleUserIds: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
fileIds: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
files: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'DriveFile',
},
},
tags: {
type: 'array',
optional: true, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
poll: {
type: 'object',
optional: true, nullable: true,
},
channelId: {
type: 'string',
optional: true, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
channel: {
type: 'object',
optional: true, nullable: true,
items: {
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string',
optional: false, nullable: false,
},
name: {
type: 'string',
optional: false, nullable: true,
},
},
},
},
localOnly: {
type: 'boolean',
optional: true, nullable: false,
},
emojis: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
properties: {
name: {
type: 'string',
optional: false, nullable: false,
},
url: {
type: 'string',
optional: false, nullable: true,
},
},
},
},
reactions: {
type: 'object',
optional: false, nullable: false,
},
renoteCount: {
type: 'number',
optional: false, nullable: false,
},
repliesCount: {
type: 'number',
optional: false, nullable: false,
},
uri: {
type: 'string',
optional: true, nullable: false,
},
url: {
type: 'string',
optional: true, nullable: false,
},
myReaction: {
type: 'object',
optional: true, nullable: true,
},
},
} as const;

View file

@ -0,0 +1,66 @@
import { notificationTypes } from "@/types";
export const packedNotificationSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
isRead: {
type: 'boolean',
optional: false, nullable: false,
},
type: {
type: 'string',
optional: false, nullable: false,
enum: [...notificationTypes],
},
user: {
type: 'object',
ref: 'UserLite',
optional: true, nullable: true,
},
userId: {
type: 'string',
optional: true, nullable: true,
format: 'id',
},
note: {
type: 'object',
ref: 'Note',
optional: true, nullable: true,
},
reaction: {
type: 'string',
optional: true, nullable: true,
},
choice: {
type: 'number',
optional: true, nullable: true,
},
invitation: {
type: 'object',
optional: true, nullable: true,
},
body: {
type: 'string',
optional: true, nullable: true,
},
header: {
type: 'string',
optional: true, nullable: true,
},
icon: {
type: 'string',
optional: true, nullable: true,
},
},
} as const;

View file

@ -0,0 +1,51 @@
export const packedPageSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
updatedAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
title: {
type: 'string',
optional: false, nullable: false,
},
name: {
type: 'string',
optional: false, nullable: false,
},
summary: {
type: 'string',
optional: false, nullable: true,
},
content: {
type: 'array',
optional: false, nullable: false,
},
variables: {
type: 'array',
optional: false, nullable: false,
},
userId: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
user: {
type: 'object',
ref: 'UserLite',
optional: false, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,25 @@
export const packedQueueCountSchema = {
type: 'object',
properties: {
waiting: {
type: 'number',
optional: false, nullable: false,
},
active: {
type: 'number',
optional: false, nullable: false,
},
completed: {
type: 'number',
optional: false, nullable: false,
},
failed: {
type: 'number',
optional: false, nullable: false,
},
delayed: {
type: 'number',
optional: false, nullable: false,
},
},
} as const;

View file

@ -0,0 +1,34 @@
export const packedUserGroupSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
name: {
type: 'string',
optional: false, nullable: false,
},
ownerId: {
type: 'string',
nullable: false, optional: false,
format: 'id',
},
userIds: {
type: 'array',
nullable: false, optional: true,
items: {
type: 'string',
nullable: false, optional: false,
format: 'id',
},
},
},
} as const;

View file

@ -0,0 +1,29 @@
export const packedUserListSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
name: {
type: 'string',
optional: false, nullable: false,
},
userIds: {
type: 'array',
nullable: false, optional: true,
items: {
type: 'string',
nullable: false, optional: false,
format: 'id',
},
},
},
} as const;

View file

@ -0,0 +1,467 @@
export const packedUserLiteSchema = {
type: 'object',
properties: {
id: {
type: 'string',
nullable: false, optional: false,
format: 'id',
example: 'xxxxxxxxxx',
},
name: {
type: 'string',
nullable: true, optional: false,
example: '藍',
},
username: {
type: 'string',
nullable: false, optional: false,
example: 'ai',
},
host: {
type: 'string',
nullable: true, optional: false,
example: 'misskey.example.com',
},
avatarUrl: {
type: 'string',
format: 'url',
nullable: true, optional: false,
},
avatarBlurhash: {
type: 'any',
nullable: true, optional: false,
},
avatarColor: {
type: 'any',
nullable: true, optional: false,
default: null,
},
isAdmin: {
type: 'boolean',
nullable: false, optional: true,
default: false,
},
isModerator: {
type: 'boolean',
nullable: false, optional: true,
default: false,
},
isBot: {
type: 'boolean',
nullable: false, optional: true,
},
isCat: {
type: 'boolean',
nullable: false, optional: true,
},
emojis: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'object',
nullable: false, optional: false,
properties: {
name: {
type: 'string',
nullable: false, optional: false,
},
url: {
type: 'string',
nullable: false, optional: false,
format: 'url',
},
},
},
},
onlineStatus: {
type: 'string',
format: 'url',
nullable: true, optional: false,
enum: ['unknown', 'online', 'active', 'offline'],
},
},
} as const;
export const packedUserDetailedNotMeOnlySchema = {
type: 'object',
properties: {
url: {
type: 'string',
format: 'url',
nullable: true, optional: false,
},
uri: {
type: 'string',
format: 'uri',
nullable: true, optional: false,
},
createdAt: {
type: 'string',
nullable: false, optional: false,
format: 'date-time',
},
updatedAt: {
type: 'string',
nullable: true, optional: false,
format: 'date-time',
},
lastFetchedAt: {
type: 'string',
nullable: true, optional: false,
format: 'date-time',
},
bannerUrl: {
type: 'string',
format: 'url',
nullable: true, optional: false,
},
bannerBlurhash: {
type: 'any',
nullable: true, optional: false,
},
bannerColor: {
type: 'any',
nullable: true, optional: false,
default: null,
},
isLocked: {
type: 'boolean',
nullable: false, optional: false,
},
isSilenced: {
type: 'boolean',
nullable: false, optional: false,
},
isSuspended: {
type: 'boolean',
nullable: false, optional: false,
example: false,
},
description: {
type: 'string',
nullable: true, optional: false,
example: 'Hi masters, I am Ai!',
},
location: {
type: 'string',
nullable: true, optional: false,
},
birthday: {
type: 'string',
nullable: true, optional: false,
example: '2018-03-12',
},
lang: {
type: 'string',
nullable: true, optional: false,
example: 'ja-JP',
},
fields: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'object',
nullable: false, optional: false,
properties: {
name: {
type: 'string',
nullable: false, optional: false,
},
value: {
type: 'string',
nullable: false, optional: false,
},
},
maxLength: 4,
},
},
followersCount: {
type: 'number',
nullable: false, optional: false,
},
followingCount: {
type: 'number',
nullable: false, optional: false,
},
notesCount: {
type: 'number',
nullable: false, optional: false,
},
pinnedNoteIds: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'string',
nullable: false, optional: false,
format: 'id',
},
},
pinnedNotes: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'object',
nullable: false, optional: false,
ref: 'Note',
},
},
pinnedPageId: {
type: 'string',
nullable: true, optional: false,
},
pinnedPage: {
type: 'object',
nullable: true, optional: false,
ref: 'Page',
},
publicReactions: {
type: 'boolean',
nullable: false, optional: false,
},
twoFactorEnabled: {
type: 'boolean',
nullable: false, optional: false,
default: false,
},
usePasswordLessLogin: {
type: 'boolean',
nullable: false, optional: false,
default: false,
},
securityKeys: {
type: 'boolean',
nullable: false, optional: false,
default: false,
},
//#region relations
isFollowing: {
type: 'boolean',
nullable: false, optional: true,
},
isFollowed: {
type: 'boolean',
nullable: false, optional: true,
},
hasPendingFollowRequestFromYou: {
type: 'boolean',
nullable: false, optional: true,
},
hasPendingFollowRequestToYou: {
type: 'boolean',
nullable: false, optional: true,
},
isBlocking: {
type: 'boolean',
nullable: false, optional: true,
},
isBlocked: {
type: 'boolean',
nullable: false, optional: true,
},
isMuted: {
type: 'boolean',
nullable: false, optional: true,
},
//#endregion
},
} as const;
export const packedMeDetailedOnlySchema = {
type: 'object',
properties: {
avatarId: {
type: 'string',
nullable: true, optional: false,
format: 'id',
},
bannerId: {
type: 'string',
nullable: true, optional: false,
format: 'id',
},
injectFeaturedNote: {
type: 'boolean',
nullable: true, optional: false,
},
receiveAnnouncementEmail: {
type: 'boolean',
nullable: true, optional: false,
},
alwaysMarkNsfw: {
type: 'boolean',
nullable: true, optional: false,
},
carefulBot: {
type: 'boolean',
nullable: true, optional: false,
},
autoAcceptFollowed: {
type: 'boolean',
nullable: true, optional: false,
},
noCrawle: {
type: 'boolean',
nullable: true, optional: false,
},
isExplorable: {
type: 'boolean',
nullable: false, optional: false,
},
isDeleted: {
type: 'boolean',
nullable: false, optional: false,
},
hideOnlineStatus: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadSpecifiedNotes: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadMentions: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadAnnouncement: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadAntenna: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadChannel: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadMessagingMessage: {
type: 'boolean',
nullable: false, optional: false,
},
hasUnreadNotification: {
type: 'boolean',
nullable: false, optional: false,
},
hasPendingReceivedFollowRequest: {
type: 'boolean',
nullable: false, optional: false,
},
integrations: {
type: 'object',
nullable: true, optional: false,
},
mutedWords: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'array',
nullable: false, optional: false,
items: {
type: 'string',
nullable: false, optional: false,
},
},
},
mutedInstances: {
type: 'array',
nullable: true, optional: false,
items: {
type: 'string',
nullable: false, optional: false,
},
},
mutingNotificationTypes: {
type: 'array',
nullable: true, optional: false,
items: {
type: 'string',
nullable: false, optional: false,
},
},
emailNotificationTypes: {
type: 'array',
nullable: true, optional: false,
items: {
type: 'string',
nullable: false, optional: false,
},
},
//#region secrets
email: {
type: 'string',
nullable: true, optional: true,
},
emailVerified: {
type: 'boolean',
nullable: true, optional: true,
},
securityKeysList: {
type: 'array',
nullable: false, optional: true,
items: {
type: 'object',
nullable: false, optional: false,
},
},
//#endregion
},
} as const;
export const packedUserDetailedNotMeSchema = {
type: 'object',
allOf: [
{
type: 'object',
ref: 'UserLite',
},
{
type: 'object',
ref: 'UserDetailedNotMeOnly',
},
],
} as const;
export const packedMeDetailedSchema = {
type: 'object',
allOf: [
{
type: 'object',
ref: 'UserLite',
},
{
type: 'object',
ref: 'UserDetailedNotMeOnly',
},
{
type: 'object',
ref: 'MeDetailedOnly',
},
],
} as const;
export const packedUserDetailedSchema = {
oneOf: [
{
type: 'object',
ref: 'UserDetailedNotMe',
},
{
type: 'object',
ref: 'MeDetailed',
},
],
} as const;
export const packedUserSchema = {
oneOf: [
{
type: 'object',
ref: 'UserLite',
},
{
type: 'object',
ref: 'UserDetailed',
},
],
} as const;

View file

@ -1,13 +1,11 @@
type Await<T> = T extends Promise<infer U> ? U : T;
type AwaitAll<T> = {
[P in keyof T]: Await<T[P]>;
export type Promiseable<T> = {
[K in keyof T]: Promise<T[K]> | T[K];
};
export async function awaitAll<T>(obj: T): Promise<AwaitAll<T>> {
const target = {} as any;
const keys = Object.keys(obj);
const values = Object.values(obj);
export async function awaitAll<T>(obj: Promiseable<T>): Promise<T> {
const target = {} as T;
const keys = Object.keys(obj) as unknown as (keyof T)[];
const values = Object.values(obj) as any[];
const resolvedValues = await Promise.all(values.map(value =>
(!value || !value.constructor || value.constructor.name !== 'Object')

View file

@ -3,7 +3,7 @@ import { dirname } from 'path';
import { Context } from 'cafy';
import * as path from 'path';
import * as glob from 'glob';
import { SimpleSchema } from '@/misc/simple-schema';
import { Schema } from '@/misc/schema';
//const _filename = fileURLToPath(import.meta.url);
const _filename = __filename;
@ -18,87 +18,87 @@ export type Param = {
};
export interface IEndpointMeta {
stability?: string; //'deprecated' | 'experimental' | 'stable';
readonly stability?: 'deprecated' | 'experimental' | 'stable';
tags?: string[];
readonly tags?: ReadonlyArray<string>;
params?: {
[key: string]: Param;
readonly params?: {
readonly [key: string]: Param;
};
errors?: {
[key: string]: {
message: string;
code: string;
id: string;
readonly errors?: {
readonly [key: string]: {
readonly message: string;
readonly code: string;
readonly id: string;
};
};
res?: SimpleSchema;
readonly res?: Schema;
/**
*
* false
*/
requireCredential?: boolean;
readonly requireCredential?: boolean;
/**
* 使
*/
requireAdmin?: boolean;
readonly requireAdmin?: boolean;
/**
* 使
*/
requireModerator?: boolean;
readonly requireModerator?: boolean;
/**
*
*
* withCredential false
*/
limit?: {
readonly limit?: {
/**
*
*/
key?: string;
readonly key?: string;
/**
* (ms)
* max
*/
duration?: number;
readonly duration?: number;
/**
* durationで指定した期間内にいくつまでリクエストできるのか
* duration
*/
max?: number;
readonly max?: number;
/**
* (ms)
*/
minInterval?: number;
readonly minInterval?: number;
};
/**
*
* false
*/
requireFile?: boolean;
readonly requireFile?: boolean;
/**
*
* false
*/
secure?: boolean;
readonly secure?: boolean;
/**
*
*
*/
kind?: string;
readonly kind?: string;
}
export interface IEndpoint {

View file

@ -7,7 +7,7 @@ import { makePaginationQuery } from '../../common/make-pagination-query';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -49,66 +49,66 @@ export const meta = {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
nullable: false as const, optional: false as const,
type: 'string',
nullable: false, optional: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
nullable: false as const, optional: false as const,
type: 'string',
nullable: false, optional: false,
format: 'date-time',
},
comment: {
type: 'string' as const,
nullable: false as const, optional: false as const,
type: 'string',
nullable: false, optional: false,
},
resolved: {
type: 'boolean' as const,
nullable: false as const, optional: false as const,
type: 'boolean',
nullable: false, optional: false,
example: false,
},
reporterId: {
type: 'string' as const,
nullable: false as const, optional: false as const,
type: 'string',
nullable: false, optional: false,
format: 'id',
},
targetUserId: {
type: 'string' as const,
nullable: false as const, optional: false as const,
type: 'string',
nullable: false, optional: false,
format: 'id',
},
assigneeId: {
type: 'string' as const,
nullable: true as const, optional: false as const,
type: 'string',
nullable: true, optional: false,
format: 'id',
},
reporter: {
type: 'object' as const,
nullable: false as const, optional: false as const,
type: 'object',
nullable: false, optional: false,
ref: 'User',
},
targetUser: {
type: 'object' as const,
nullable: false as const, optional: false as const,
type: 'object',
nullable: false, optional: false,
ref: 'User',
},
assignee: {
type: 'object' as const,
nullable: true as const, optional: true as const,
type: 'object',
nullable: true, optional: true,
ref: 'User',
},
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -16,17 +16,17 @@ export const meta = {
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
ref: 'User',
properties: {
token: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, _me) => {

View file

@ -9,7 +9,7 @@ import { ID } from '@/misc/cafy-id';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -17,7 +17,7 @@ export const meta = {
validator: $.type(ID),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -6,7 +6,7 @@ import { genId } from '@/misc/gen-id';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -32,7 +32,7 @@ export const meta = {
validator: $.str.min(1),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -7,7 +7,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -23,7 +23,7 @@ export const meta = {
id: 'ccac9863-3a03-416e-b899-8a64041118b1',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -7,7 +7,7 @@ import { makePaginationQuery } from '../../../common/make-pagination-query';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -24,7 +24,7 @@ export const meta = {
validator: $.optional.type(ID),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -7,7 +7,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -44,7 +44,7 @@ export const meta = {
id: 'b7aa1727-1354-47bc-a182-3a9c3973d300',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -6,7 +6,7 @@ import { genId } from '@/misc/gen-id';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -22,40 +22,40 @@ export const meta = {
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
updatedAt: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
title: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
text: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
imageUrl: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -7,7 +7,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -23,7 +23,7 @@ export const meta = {
id: 'ecad8040-a276-4e85-bda9-015a708d291e',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -7,7 +7,7 @@ import { makePaginationQuery } from '../../../common/make-pagination-query';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -26,48 +26,48 @@ export const meta = {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
updatedAt: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
text: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
title: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
imageUrl: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
reads: {
type: 'number' as const,
optional: false as const, nullable: false as const,
type: 'number',
optional: false, nullable: false,
},
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -7,7 +7,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -32,7 +32,7 @@ export const meta = {
id: 'd3aae5a7-6372-4cb4-b61c-f511ffc2d7cc',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -7,7 +7,7 @@ import { ID } from '@/misc/cafy-id';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -15,7 +15,7 @@ export const meta = {
validator: $.type(ID),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -1,14 +0,0 @@
import define from '../../define';
import { Logs } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireModerator: true,
};
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {
await Logs.clear(); // TRUNCATE
});

View file

@ -4,9 +4,9 @@ import { createCleanRemoteFilesJob } from '@/queue/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -6,9 +6,9 @@ import { DriveFiles } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -7,7 +7,7 @@ import { ID } from '@/misc/cafy-id';
export const meta = {
tags: ['admin'],
requireCredential: false as const,
requireCredential: false,
requireModerator: true,
params: {
@ -44,15 +44,15 @@ export const meta = {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
ref: 'DriveFile',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -7,7 +7,7 @@ import { DriveFiles } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -29,137 +29,137 @@ export const meta = {
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
createdAt: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
userId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
userHost: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
md5: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'md5',
example: '15eca7fba0480996e2245f5185bf39f2',
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
example: 'lenna.jpg',
},
type: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
example: 'image/jpeg',
},
size: {
type: 'number' as const,
optional: false as const, nullable: false as const,
type: 'number',
optional: false, nullable: false,
example: 51469,
},
comment: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
blurhash: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
properties: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
width: {
type: 'number' as const,
optional: false as const, nullable: false as const,
type: 'number',
optional: false, nullable: false,
example: 1280,
},
height: {
type: 'number' as const,
optional: false as const, nullable: false as const,
type: 'number',
optional: false, nullable: false,
example: 720,
},
avgColor: {
type: 'string' as const,
optional: true as const, nullable: false as const,
type: 'string',
optional: true, nullable: false,
example: 'rgb(40,65,87)',
},
},
},
storedInternal: {
type: 'boolean' as const,
optional: false as const, nullable: true as const,
type: 'boolean',
optional: false, nullable: true,
example: true,
},
url: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
format: 'url',
},
thumbnailUrl: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
format: 'url',
},
webpublicUrl: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
format: 'url',
},
accessKey: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
thumbnailAccessKey: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
webpublicAccessKey: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
uri: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
src: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
folderId: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
format: 'id',
example: 'xxxxxxxxxx',
},
isSensitive: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
type: 'boolean',
optional: false, nullable: false,
},
isLink: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
type: 'boolean',
optional: false, nullable: false,
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -8,7 +8,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -20,7 +20,7 @@ export const meta = {
validator: $.arr($.str),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -12,7 +12,7 @@ import { publishBroadcastStream } from '@/services/stream';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -28,7 +28,7 @@ export const meta = {
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -12,7 +12,7 @@ import { publishBroadcastStream } from '@/services/stream';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -30,17 +30,17 @@ export const meta = {
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -9,7 +9,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -17,7 +17,7 @@ export const meta = {
validator: $.arr($.type(ID)),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -9,7 +9,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -25,7 +25,7 @@ export const meta = {
id: 'be83669b-773a-44b7-b1f8-e5e5170ac3c2',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -6,14 +6,14 @@ import { ID } from '@/misc/cafy-id';
export const meta = {
secure: true,
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
fileId: {
validator: $.type(ID),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {

View file

@ -8,7 +8,7 @@ import { ID } from '@/misc/cafy-id';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -37,45 +37,45 @@ export const meta = {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
},
aliases: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
category: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
host: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
url: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -8,7 +8,7 @@ import { Emoji } from '@/models/entities/emoji';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -32,45 +32,45 @@ export const meta = {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
},
aliases: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
},
name: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
category: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
host: {
type: 'string' as const,
optional: false as const, nullable: true as const,
type: 'string',
optional: false, nullable: true,
},
url: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
},
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -8,7 +8,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -20,7 +20,7 @@ export const meta = {
validator: $.arr($.str),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -8,7 +8,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -20,7 +20,7 @@ export const meta = {
validator: $.arr($.str),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -8,7 +8,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -20,7 +20,7 @@ export const meta = {
validator: $.optional.nullable.str,
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -8,7 +8,7 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -36,7 +36,7 @@ export const meta = {
id: '684dec9d-a8c2-4364-9aa8-456c49cb1dc8',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -6,7 +6,7 @@ import { DriveFiles } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -14,7 +14,7 @@ export const meta = {
validator: $.str,
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -7,7 +7,7 @@ import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -15,7 +15,7 @@ export const meta = {
validator: $.str,
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -6,7 +6,7 @@ import { Followings, Users } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -14,7 +14,7 @@ export const meta = {
validator: $.str,
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -6,7 +6,7 @@ import { toPuny } from '@/misc/convert-host';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -18,7 +18,7 @@ export const meta = {
validator: $.bool,
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -2,14 +2,14 @@ import define from '../../define';
import { getConnection } from 'typeorm';
export const meta = {
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
tags: ['admin'],
params: {
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async () => {

View file

@ -2,7 +2,7 @@ import define from '../../define';
import { getConnection } from 'typeorm';
export const meta = {
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
tags: ['admin'],
@ -11,8 +11,8 @@ export const meta = {
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
example: {
migrations: {
count: 66,
@ -20,7 +20,7 @@ export const meta = {
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async () => {

View file

@ -6,25 +6,25 @@ import { genId } from '@/misc/gen-id';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
code: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
example: '2ERUA5VR',
maxLength: 8,
minLength: 8,
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async () => {

View file

@ -6,7 +6,7 @@ import { Users } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireAdmin: true,
params: {
@ -14,7 +14,7 @@ export const meta = {
validator: $.type(ID),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -6,7 +6,7 @@ import { Users } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireAdmin: true,
params: {
@ -14,7 +14,7 @@ export const meta = {
validator: $.type(ID),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -8,7 +8,7 @@ import { PromoNotes } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -34,7 +34,7 @@ export const meta = {
id: 'ae427aa2-7a41-484f-a18c-2c1104051604',
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {

View file

@ -5,11 +5,11 @@ import { insertModerationLog } from '@/services/insert-moderation-log';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -5,25 +5,25 @@ import define from '../../../define';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
anyOf: [
{
type: 'string' as const,
type: 'string',
},
{
type: 'number' as const,
type: 'number',
},
],
},
@ -33,7 +33,7 @@ export const meta = {
12,
]],
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -5,25 +5,25 @@ import { inboxQueue } from '@/queue/queues';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
anyOf: [
{
type: 'string' as const,
type: 'string',
},
{
type: 'number' as const,
type: 'number',
},
],
},
@ -33,7 +33,7 @@ export const meta = {
12,
]],
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -5,7 +5,7 @@ import define from '../../../define';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -24,37 +24,37 @@ export const meta = {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
},
data: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
},
attempts: {
type: 'number' as const,
optional: false as const, nullable: false as const,
type: 'number',
optional: false, nullable: false,
},
maxAttempts: {
type: 'number' as const,
optional: false as const, nullable: false as const,
type: 'number',
optional: false, nullable: false,
},
timestamp: {
type: 'number' as const,
optional: false as const, nullable: false as const,
type: 'number',
optional: false, nullable: false,
},
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -4,30 +4,34 @@ import define from '../../../define';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
deliver: {
optional: false, nullable: false,
ref: 'QueueCount',
},
inbox: {
optional: false, nullable: false,
ref: 'QueueCount',
},
db: {
optional: false, nullable: false,
ref: 'QueueCount',
},
objectStorage: {
optional: false, nullable: false,
ref: 'QueueCount',
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -7,8 +7,8 @@ import { ApiError } from '../../../error';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireModerator: true as const,
requireCredential: true,
requireModerator: true,
params: {
inbox: {
@ -25,22 +25,22 @@ export const meta = {
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
},
inbox: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'url',
},
status: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
default: 'requesting',
enum: [
'requesting',
@ -50,7 +50,7 @@ export const meta = {
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {

View file

@ -4,32 +4,32 @@ import { listRelay } from '@/services/relay';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireModerator: true as const,
requireCredential: true,
requireModerator: true,
params: {
},
res: {
type: 'array' as const,
optional: false as const, nullable: false as const,
type: 'array',
optional: false, nullable: false,
items: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'id',
},
inbox: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
format: 'url',
},
status: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
default: 'requesting',
enum: [
'requesting',
@ -40,7 +40,7 @@ export const meta = {
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {

View file

@ -5,15 +5,15 @@ import { removeRelay } from '@/services/relay';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireModerator: true as const,
requireCredential: true,
requireModerator: true,
params: {
inbox: {
validator: $.str,
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, user) => {

View file

@ -8,7 +8,7 @@ import { Users, UserProfiles } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -18,18 +18,18 @@ export const meta = {
},
res: {
type: 'object' as const,
optional: false as const, nullable: false as const,
type: 'object',
optional: false, nullable: false,
properties: {
password: {
type: 'string' as const,
optional: false as const, nullable: false as const,
type: 'string',
optional: false, nullable: false,
minLength: 8,
maxLength: 8,
},
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps) => {

View file

@ -6,7 +6,7 @@ import { AbuseUserReports } from '@/models/index';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
params: {
@ -14,7 +14,7 @@ export const meta = {
validator: $.type(ID),
},
},
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

View file

@ -5,9 +5,9 @@ import { insertModerationLog } from '@/services/insert-moderation-log';
export const meta = {
tags: ['admin'],
requireCredential: true as const,
requireCredential: true,
requireModerator: true,
};
} as const;
// eslint-disable-next-line import/no-default-export
export default define(meta, async (ps, me) => {

Some files were not shown because too many files have changed in this diff Show more