diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2019-04-24 15:23:48 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2019-04-24 15:23:48 +0900 |
| commit | 723d3e6871a6039330e870d94d187367e9c579aa (patch) | |
| tree | 637cbe640d99d6f0fc8890fdc85497a31817596f /src/server/api | |
| parent | Merge branch 'develop' (diff) | |
| parent | 11.3.0 (diff) | |
| download | misskey-723d3e6871a6039330e870d94d187367e9c579aa.tar.gz misskey-723d3e6871a6039330e870d94d187367e9c579aa.tar.bz2 misskey-723d3e6871a6039330e870d94d187367e9c579aa.zip | |
Merge branch 'develop'
Diffstat (limited to 'src/server/api')
76 files changed, 563 insertions, 637 deletions
diff --git a/src/server/api/define.ts b/src/server/api/define.ts index 990cbf2a86..1e2600add0 100644 --- a/src/server/api/define.ts +++ b/src/server/api/define.ts @@ -3,6 +3,7 @@ import { ILocalUser } from '../../models/entities/user'; import { IEndpointMeta } from './endpoints'; import { ApiError } from './error'; import { App } from '../../models/entities/app'; +import { SchemaType } from '../../misc/schema'; type Params<T extends IEndpointMeta> = { [P in keyof T['params']]: NonNullable<T['params']>[P]['transform'] extends Function @@ -12,7 +13,11 @@ type Params<T extends IEndpointMeta> = { export type Response = Record<string, any> | void; -export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T>, user: ILocalUser, app: App, file?: any, cleanup?: Function) => Promise<Response>): (params: any, user: ILocalUser, app: App, file?: any) => Promise<any> { +type executor<T extends IEndpointMeta> = + (params: Params<T>, user: ILocalUser, app: App, file?: any, cleanup?: Function) => Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>; + +export default function <T extends IEndpointMeta>(meta: T, cb: executor<T>) + : (params: any, user: ILocalUser, app: App, file?: any) => Promise<any> { return (params: any, user: ILocalUser, app: App, file?: any) => { function cleanup() { fs.unlink(file.path, () => {}); diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index 3c6380acb4..1f5dd5364f 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -164,7 +164,7 @@ export const meta = { }, maintainerName: { - validator: $.optional.str, + validator: $.optional.nullable.str, desc: { 'ja-JP': 'インスタンスの管理者名' } diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts index 1b992eeaa7..1bb15117dd 100644 --- a/src/server/api/endpoints/ap/show.ts +++ b/src/server/api/endpoints/ap/show.ts @@ -9,7 +9,7 @@ import { extractDbHost } from '../../../../misc/convert-host'; import { Users, Notes } from '../../../../models'; import { Note } from '../../../../models/entities/note'; import { User } from '../../../../models/entities/user'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { validActor } from '../../../../remote/activitypub/type'; export const meta = { diff --git a/src/server/api/endpoints/app/create.ts b/src/server/api/endpoints/app/create.ts index 9db60d2661..833d5060c5 100644 --- a/src/server/api/endpoints/app/create.ts +++ b/src/server/api/endpoints/app/create.ts @@ -4,12 +4,13 @@ import define from '../../define'; import { Apps } from '../../../../models'; import { genId } from '../../../../misc/gen-id'; import { unique } from '../../../../prelude/array'; +import { types, bool } from '../../../../misc/schema'; export const meta = { tags: ['app'], requireCredential: false, - + desc: { 'ja-JP': 'アプリを作成します。', 'en-US': 'Create a application.' @@ -50,29 +51,12 @@ export const meta = { } }, }, - + res: { - type: 'object', - properties: { - id: { - type: 'string', - description: 'アプリケーションのID' - }, - name: { - type: 'string', - description: 'アプリケーションの名前' - }, - callbackUrl: { - type: 'string', - nullable: true, - description: 'コールバックするURL' - }, - secret: { - type: 'string', - description: 'アプリケーションのシークレットキー' - } - } - } + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'App', + }, }; export default define(meta, async (ps, user) => { diff --git a/src/server/api/endpoints/app/show.ts b/src/server/api/endpoints/app/show.ts index ce9baed2ae..e7d3e84388 100644 --- a/src/server/api/endpoints/app/show.ts +++ b/src/server/api/endpoints/app/show.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; import { ApiError } from '../../error'; import { Apps } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { tags: ['app'], @@ -13,6 +14,12 @@ export const meta = { }, }, + res: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'App', + }, + errors: { noSuchApp: { message: 'No such app.', diff --git a/src/server/api/endpoints/auth/session/generate.ts b/src/server/api/endpoints/auth/session/generate.ts index bca8d33483..9bf27c8e77 100644 --- a/src/server/api/endpoints/auth/session/generate.ts +++ b/src/server/api/endpoints/auth/session/generate.ts @@ -5,12 +5,13 @@ import define from '../../../define'; import { ApiError } from '../../../error'; import { Apps, AuthSessions } from '../../../../../models'; import { genId } from '../../../../../misc/gen-id'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { tags: ['auth'], requireCredential: false, - + desc: { 'ja-JP': 'アプリを認証するためのトークンを作成します。', 'en-US': 'Generate a token for authorize application.' @@ -27,14 +28,18 @@ export const meta = { }, res: { - type: 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { token: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, description: 'セッションのトークン' }, url: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'url', description: 'セッションのURL' }, } diff --git a/src/server/api/endpoints/auth/session/userkey.ts b/src/server/api/endpoints/auth/session/userkey.ts index 7126ac52c1..b7a58c4750 100644 --- a/src/server/api/endpoints/auth/session/userkey.ts +++ b/src/server/api/endpoints/auth/session/userkey.ts @@ -3,6 +3,7 @@ import define from '../../../define'; import { ApiError } from '../../../error'; import { Apps, AuthSessions, AccessTokens, Users } from '../../../../../models'; import { ensure } from '../../../../../prelude/ensure'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { tags: ['auth'], @@ -28,15 +29,19 @@ export const meta = { }, res: { - type: 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { accessToken: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, description: 'ユーザーのアクセストークン', }, user: { - type: 'User', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', description: '認証したユーザー' }, } diff --git a/src/server/api/endpoints/blocking/list.ts b/src/server/api/endpoints/blocking/list.ts index 97f353579d..5ff1dc0c49 100644 --- a/src/server/api/endpoints/blocking/list.ts +++ b/src/server/api/endpoints/blocking/list.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; import { Blockings } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -32,9 +33,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Blocking', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Blocking', } }, }; diff --git a/src/server/api/endpoints/drive.ts b/src/server/api/endpoints/drive.ts index adf780301b..4d4516bd80 100644 --- a/src/server/api/endpoints/drive.ts +++ b/src/server/api/endpoints/drive.ts @@ -1,6 +1,7 @@ import define from '../define'; -import fetchMeta from '../../../misc/fetch-meta'; +import { fetchMeta } from '../../../misc/fetch-meta'; import { DriveFiles } from '../../../models'; +import { types, bool } from '../../../misc/schema'; export const meta = { desc: { @@ -15,20 +16,23 @@ export const meta = { kind: 'read:drive', res: { - type: 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { capacity: { - type: 'number' + type: types.number, + optional: bool.false, nullable: bool.false, }, usage: { - type: 'number' + type: types.number, + optional: bool.false, nullable: bool.false, } } } }; export default define(meta, async (ps, user) => { - const instance = await fetchMeta(); + const instance = await fetchMeta(true); // Calculate drive usage const usage = await DriveFiles.clacDriveUsageOf(user); diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts index 4e4db6c780..493e14464c 100644 --- a/src/server/api/endpoints/drive/files.ts +++ b/src/server/api/endpoints/drive/files.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; import { DriveFiles } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -41,10 +42,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'DriveFile', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile', + } }, }; diff --git a/src/server/api/endpoints/drive/files/attached-notes.ts b/src/server/api/endpoints/drive/files/attached-notes.ts index 7214463dde..f770bc7136 100644 --- a/src/server/api/endpoints/drive/files/attached-notes.ts +++ b/src/server/api/endpoints/drive/files/attached-notes.ts @@ -2,7 +2,8 @@ import $ from 'cafy'; import { ID } from '../../../../../misc/cafy-id'; import define from '../../../define'; import { ApiError } from '../../../error'; -import { DriveFiles } from '../../../../../models'; +import { DriveFiles, Notes } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { stability: 'stable', @@ -29,10 +30,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { @@ -55,8 +59,11 @@ export default define(meta, async (ps, user) => { throw new ApiError(meta.errors.noSuchFile); } - /* v11 TODO - return await packMany(file.metadata.attachedNoteIds || [], user, { + const notes = await Notes.createQueryBuilder('note') + .where(':file = ANY(note.fileIds)', { file: file.id }) + .getMany(); + + return await Notes.packMany(notes, user, { detail: true - });*/ + }); }); diff --git a/src/server/api/endpoints/drive/files/check-existence.ts b/src/server/api/endpoints/drive/files/check-existence.ts index 3a87a9497f..ab19566f1c 100644 --- a/src/server/api/endpoints/drive/files/check-existence.ts +++ b/src/server/api/endpoints/drive/files/check-existence.ts @@ -1,6 +1,7 @@ import $ from 'cafy'; import define from '../../../define'; import { DriveFiles } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { desc: { @@ -24,7 +25,8 @@ export const meta = { }, res: { - type: 'DriveFile', + type: types.boolean, + optional: bool.false, nullable: bool.false, }, }; @@ -34,7 +36,5 @@ export default define(meta, async (ps, user) => { userId: user.id, }); - return { - file: file ? await DriveFiles.pack(file, { self: true }) : null - }; + return file != null; }); diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts index 340a39a41c..0f81a1da99 100644 --- a/src/server/api/endpoints/drive/files/create.ts +++ b/src/server/api/endpoints/drive/files/create.ts @@ -6,6 +6,7 @@ import define from '../../../define'; import { apiLogger } from '../../../logger'; import { ApiError } from '../../../error'; import { DriveFiles } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { desc: { @@ -56,7 +57,9 @@ export const meta = { }, res: { - type: 'DriveFile', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile', }, errors: { @@ -87,7 +90,7 @@ export default define(meta, async (ps, user, app, file, cleanup) => { try { // Create file const driveFile = await create(user, file.path, name, null, ps.folderId, ps.force, false, null, null, ps.isSensitive); - return DriveFiles.pack(driveFile, { self: true }); + return await DriveFiles.pack(driveFile, { self: true }); } catch (e) { apiLogger.error(e); throw new ApiError(); diff --git a/src/server/api/endpoints/drive/files/find-by-hash.ts b/src/server/api/endpoints/drive/files/find-by-hash.ts new file mode 100644 index 0000000000..d56e63bc59 --- /dev/null +++ b/src/server/api/endpoints/drive/files/find-by-hash.ts @@ -0,0 +1,44 @@ +import $ from 'cafy'; +import define from '../../../define'; +import { DriveFiles } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; + +export const meta = { + desc: { + 'ja-JP': '与えられたMD5ハッシュ値を持つファイルを取得します。', + }, + + tags: ['drive'], + + requireCredential: true, + + kind: 'read:drive', + + params: { + md5: { + validator: $.str, + desc: { + 'ja-JP': 'ファイルのMD5ハッシュ' + } + } + }, + + res: { + type: types.array, + optional: bool.false, nullable: bool.false, + items: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile', + } + }, +}; + +export default define(meta, async (ps, user) => { + const files = await DriveFiles.find({ + md5: ps.md5, + userId: user.id, + }); + + return await DriveFiles.packMany(files, { self: true }); +}); diff --git a/src/server/api/endpoints/drive/files/find.ts b/src/server/api/endpoints/drive/files/find.ts index 265850f84c..82b9a97b6d 100644 --- a/src/server/api/endpoints/drive/files/find.ts +++ b/src/server/api/endpoints/drive/files/find.ts @@ -2,6 +2,7 @@ import $ from 'cafy'; import { ID } from '../../../../../misc/cafy-id'; import define from '../../../define'; import { DriveFiles } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { requireCredential: true, @@ -22,7 +23,17 @@ export const meta = { 'ja-JP': 'フォルダID' } }, - } + }, + + res: { + type: types.array, + optional: bool.false, nullable: bool.false, + items: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile', + } + }, }; export default define(meta, async (ps, user) => { diff --git a/src/server/api/endpoints/drive/files/show.ts b/src/server/api/endpoints/drive/files/show.ts index e8c0e683c9..8e74361f9c 100644 --- a/src/server/api/endpoints/drive/files/show.ts +++ b/src/server/api/endpoints/drive/files/show.ts @@ -4,6 +4,7 @@ import define from '../../../define'; import { ApiError } from '../../../error'; import { DriveFile } from '../../../../../models/entities/drive-file'; import { DriveFiles } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { stability: 'stable', @@ -38,7 +39,9 @@ export const meta = { }, res: { - type: 'DriveFile', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile', }, errors: { diff --git a/src/server/api/endpoints/drive/folders.ts b/src/server/api/endpoints/drive/folders.ts index 08ae2ff709..dc3174cd2a 100644 --- a/src/server/api/endpoints/drive/folders.ts +++ b/src/server/api/endpoints/drive/folders.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; import { DriveFolders } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -37,10 +38,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'DriveFolder', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFolder', + } }, }; diff --git a/src/server/api/endpoints/drive/folders/find.ts b/src/server/api/endpoints/drive/folders/find.ts index f0989ec5ae..0368d026c3 100644 --- a/src/server/api/endpoints/drive/folders/find.ts +++ b/src/server/api/endpoints/drive/folders/find.ts @@ -2,6 +2,7 @@ import $ from 'cafy'; import { ID } from '../../../../../misc/cafy-id'; import define from '../../../define'; import { DriveFolders } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { tags: ['drive'], @@ -25,10 +26,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'DriveFolder', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFolder', + } }, }; diff --git a/src/server/api/endpoints/drive/folders/show.ts b/src/server/api/endpoints/drive/folders/show.ts index 60507e7d7f..a020b46aa9 100644 --- a/src/server/api/endpoints/drive/folders/show.ts +++ b/src/server/api/endpoints/drive/folders/show.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../../misc/cafy-id'; import define from '../../../define'; import { ApiError } from '../../../error'; import { DriveFolders } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { stability: 'stable', @@ -29,7 +30,9 @@ export const meta = { }, res: { - type: 'DriveFolder', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFolder', }, errors: { diff --git a/src/server/api/endpoints/drive/stream.ts b/src/server/api/endpoints/drive/stream.ts index 96d9f82421..db17979a4b 100644 --- a/src/server/api/endpoints/drive/stream.ts +++ b/src/server/api/endpoints/drive/stream.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; import { DriveFiles } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; +import { types, bool } from '../../../../misc/schema'; export const meta = { tags: ['drive'], @@ -31,10 +32,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'DriveFile', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile', + } }, }; diff --git a/src/server/api/endpoints/federation/instances.ts b/src/server/api/endpoints/federation/instances.ts index 301338ed96..3c4e0037d6 100644 --- a/src/server/api/endpoints/federation/instances.ts +++ b/src/server/api/endpoints/federation/instances.ts @@ -1,7 +1,7 @@ import $ from 'cafy'; import define from '../../define'; import { Instances } from '../../../../models'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; export const meta = { tags: ['federation'], @@ -62,7 +62,7 @@ export default define(meta, async (ps, me) => { } if (typeof ps.blocked === 'boolean') { - const meta = await fetchMeta(); + const meta = await fetchMeta(true); if (ps.blocked) { query.andWhere('instance.host IN (:...blocks)', { blocks: meta.blockedHosts }); } else { diff --git a/src/server/api/endpoints/hashtags/list.ts b/src/server/api/endpoints/hashtags/list.ts index 2998bc1a13..89cc926422 100644 --- a/src/server/api/endpoints/hashtags/list.ts +++ b/src/server/api/endpoints/hashtags/list.ts @@ -1,6 +1,7 @@ import $ from 'cafy'; import define from '../../define'; import { Hashtags } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { tags: ['hashtags'], @@ -47,9 +48,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Hashtag' + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Hashtag', } }, }; diff --git a/src/server/api/endpoints/hashtags/search.ts b/src/server/api/endpoints/hashtags/search.ts index 802f177993..0d2704d01c 100644 --- a/src/server/api/endpoints/hashtags/search.ts +++ b/src/server/api/endpoints/hashtags/search.ts @@ -1,6 +1,7 @@ import $ from 'cafy'; import define from '../../define'; import { Hashtags } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -37,9 +38,11 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'string' + type: types.string, + optional: bool.false, nullable: bool.false, } }, }; diff --git a/src/server/api/endpoints/hashtags/trend.ts b/src/server/api/endpoints/hashtags/trend.ts index e01e9d698f..84b750f2c1 100644 --- a/src/server/api/endpoints/hashtags/trend.ts +++ b/src/server/api/endpoints/hashtags/trend.ts @@ -1,5 +1,5 @@ import define from '../../define'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { Notes } from '../../../../models'; import { Note } from '../../../../models/entities/note'; @@ -24,7 +24,7 @@ export const meta = { }; export default define(meta, async () => { - const instance = await fetchMeta(); + const instance = await fetchMeta(true); const hiddenTags = instance.hiddenTags.map(t => t.toLowerCase()); const tagNotes = await Notes.createQueryBuilder('note') diff --git a/src/server/api/endpoints/hashtags/users.ts b/src/server/api/endpoints/hashtags/users.ts index fa58f2f2c0..b842f9de64 100644 --- a/src/server/api/endpoints/hashtags/users.ts +++ b/src/server/api/endpoints/hashtags/users.ts @@ -1,6 +1,7 @@ import $ from 'cafy'; import define from '../../define'; import { Users } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { requireCredential: false, @@ -47,9 +48,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'User' + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', } }, }; diff --git a/src/server/api/endpoints/i.ts b/src/server/api/endpoints/i.ts index afad38c469..4ecd507e16 100644 --- a/src/server/api/endpoints/i.ts +++ b/src/server/api/endpoints/i.ts @@ -1,5 +1,6 @@ import define from '../define'; import { Users } from '../../../models'; +import { types, bool } from '../../../misc/schema'; export const meta = { stability: 'stable', @@ -15,8 +16,10 @@ export const meta = { params: {}, res: { - type: 'User', - } + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', + }, }; export default define(meta, async (ps, user, app) => { diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts index 56074c9d00..41513e5daa 100644 --- a/src/server/api/endpoints/i/notifications.ts +++ b/src/server/api/endpoints/i/notifications.ts @@ -4,6 +4,7 @@ import { readNotification } from '../../common/read-notification'; import define from '../../define'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Notifications, Followings, Mutings } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -53,10 +54,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Notification', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Notification', + } }, }; diff --git a/src/server/api/endpoints/i/update-email.ts b/src/server/api/endpoints/i/update-email.ts index e02f53a643..d4b9721d82 100644 --- a/src/server/api/endpoints/i/update-email.ts +++ b/src/server/api/endpoints/i/update-email.ts @@ -2,7 +2,7 @@ import $ from 'cafy'; import { publishMainStream } from '../../../../services/stream'; import define from '../../define'; import * as nodemailer from 'nodemailer'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import rndstr from 'rndstr'; import config from '../../../../config'; import * as ms from 'ms'; @@ -63,7 +63,7 @@ export default define(meta, async (ps, user) => { emailVerifyCode: code }); - const meta = await fetchMeta(); + const meta = await fetchMeta(true); const enableAuth = meta.smtpUser != null && meta.smtpUser !== ''; diff --git a/src/server/api/endpoints/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts index c2d746e481..27e38bbdec 100644 --- a/src/server/api/endpoints/messaging/history.ts +++ b/src/server/api/endpoints/messaging/history.ts @@ -3,6 +3,7 @@ import define from '../../define'; import { MessagingMessage } from '../../../../models/entities/messaging-message'; import { MessagingMessages, Mutings } from '../../../../models'; import { Brackets } from 'typeorm'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -24,10 +25,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'MessagingMessage', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'MessagingMessage', + } }, }; diff --git a/src/server/api/endpoints/messaging/messages.ts b/src/server/api/endpoints/messaging/messages.ts index add21e5f19..0d5295bff3 100644 --- a/src/server/api/endpoints/messaging/messages.ts +++ b/src/server/api/endpoints/messaging/messages.ts @@ -6,6 +6,7 @@ import { ApiError } from '../../error'; import { getUser } from '../../common/getters'; import { MessagingMessages } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -48,10 +49,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'MessagingMessage', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'MessagingMessage', + } }, errors: { diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts index 30ac0849a3..388852b9cd 100644 --- a/src/server/api/endpoints/messaging/messages/create.ts +++ b/src/server/api/endpoints/messaging/messages/create.ts @@ -9,6 +9,7 @@ import { getUser } from '../../../common/getters'; import { MessagingMessages, DriveFiles, Mutings } from '../../../../../models'; import { MessagingMessage } from '../../../../../models/entities/messaging-message'; import { genId } from '../../../../../misc/gen-id'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { desc: { @@ -41,7 +42,9 @@ export const meta = { }, res: { - type: 'MessagingMessage', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'MessagingMessage', }, errors: { diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 785f21f22b..793eb5a204 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -2,9 +2,10 @@ import $ from 'cafy'; import * as os from 'os'; import config from '../../../config'; import define from '../define'; -import fetchMeta from '../../../misc/fetch-meta'; +import { fetchMeta } from '../../../misc/fetch-meta'; import * as pkg from '../../../../package.json'; import { Emojis } from '../../../models'; +import { types, bool } from '../../../misc/schema'; export const meta = { stability: 'stable', @@ -26,32 +27,40 @@ export const meta = { }, res: { - type: 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { version: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, description: 'The version of Misskey of this instance.', example: pkg.version }, name: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, description: 'The name of this instance.', }, description: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, description: 'The description of this instance.', }, announcements: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { title: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, description: 'The title of the announcement.', }, text: { - type: 'string', + type: types.string, + optional: bool.false, nullable: bool.false, description: 'The text of the announcement. (can be HTML)', }, } @@ -59,19 +68,23 @@ export const meta = { description: 'The announcements of this instance.', }, disableRegistration: { - type: 'boolean', + type: types.boolean, + optional: bool.false, nullable: bool.false, description: 'Whether disabled open registration.', }, disableLocalTimeline: { - type: 'boolean', + type: types.boolean, + optional: bool.false, nullable: bool.false, description: 'Whether disabled LTL and STL.', }, disableGlobalTimeline: { - type: 'boolean', + type: types.boolean, + optional: bool.false, nullable: bool.false, description: 'Whether disabled GTL.', }, enableEmojiReaction: { - type: 'boolean', + type: types.boolean, + optional: bool.false, nullable: bool.false, description: 'Whether enabled emoji reaction.', }, } @@ -79,7 +92,7 @@ export const meta = { }; export default define(meta, async (ps, me) => { - const instance = await fetchMeta(); + const instance = await fetchMeta(true); const emojis = await Emojis.find({ host: null }); diff --git a/src/server/api/endpoints/mute/list.ts b/src/server/api/endpoints/mute/list.ts index 0fd8a4860d..f9ea380c76 100644 --- a/src/server/api/endpoints/mute/list.ts +++ b/src/server/api/endpoints/mute/list.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Mutings } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -32,9 +33,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Muting', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Muting', } }, }; diff --git a/src/server/api/endpoints/notes.ts b/src/server/api/endpoints/notes.ts index 17ba969350..7aa19c9a2b 100644 --- a/src/server/api/endpoints/notes.ts +++ b/src/server/api/endpoints/notes.ts @@ -3,6 +3,7 @@ import { ID } from '../../../misc/cafy-id'; import define from '../define'; import { makePaginationQuery } from '../common/make-pagination-query'; import { Notes } from '../../../models'; +import { types, bool } from '../../../misc/schema'; export const meta = { desc: { @@ -62,9 +63,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', } }, }; diff --git a/src/server/api/endpoints/notes/children.ts b/src/server/api/endpoints/notes/children.ts index 2b4ae2a312..e8861eafa1 100644 --- a/src/server/api/endpoints/notes/children.ts +++ b/src/server/api/endpoints/notes/children.ts @@ -6,6 +6,7 @@ import { generateVisibilityQuery } from '../../common/generate-visibility-query' import { generateMuteQuery } from '../../common/generate-mute-query'; import { Brackets } from 'typeorm'; import { Notes } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -41,10 +42,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, }; diff --git a/src/server/api/endpoints/notes/conversation.ts b/src/server/api/endpoints/notes/conversation.ts index 6b26e31c07..acd3ac75ef 100644 --- a/src/server/api/endpoints/notes/conversation.ts +++ b/src/server/api/endpoints/notes/conversation.ts @@ -5,6 +5,7 @@ import { ApiError } from '../../error'; import { getNote } from '../../common/getters'; import { Note } from '../../../../models/entities/note'; import { Notes } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -37,10 +38,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts index 994dfb4dca..6cd84b866f 100644 --- a/src/server/api/endpoints/notes/create.ts +++ b/src/server/api/endpoints/notes/create.ts @@ -3,13 +3,14 @@ import * as ms from 'ms'; import { length } from 'stringz'; import create from '../../../../services/note/create'; import define from '../../define'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { ApiError } from '../../error'; import { ID } from '../../../../misc/cafy-id'; import { User } from '../../../../models/entities/user'; import { Users, DriveFiles, Notes } from '../../../../models'; import { DriveFile } from '../../../../models/entities/drive-file'; import { Note } from '../../../../models/entities/note'; +import { types, bool } from '../../../../misc/schema'; let maxNoteTextLength = 1000; @@ -174,10 +175,13 @@ export const meta = { }, res: { - type: 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { createdNote: { - type: 'Note', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', description: '作成した投稿' } } diff --git a/src/server/api/endpoints/notes/featured.ts b/src/server/api/endpoints/notes/featured.ts index fa9ae39e3a..64750815b0 100644 --- a/src/server/api/endpoints/notes/featured.ts +++ b/src/server/api/endpoints/notes/featured.ts @@ -2,6 +2,7 @@ import $ from 'cafy'; import define from '../../define'; import { generateMuteQuery } from '../../common/generate-mute-query'; import { Notes } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -24,10 +25,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, }; diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts index ceffb1cf4a..3631208da7 100644 --- a/src/server/api/endpoints/notes/global-timeline.ts +++ b/src/server/api/endpoints/notes/global-timeline.ts @@ -1,12 +1,13 @@ import $ from 'cafy'; import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { ApiError } from '../../error'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Notes } from '../../../../models'; import { generateMuteQuery } from '../../common/generate-mute-query'; import { activeUsersChart } from '../../../../services/chart'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -46,10 +47,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { @@ -62,7 +66,6 @@ export const meta = { }; export default define(meta, async (ps, user) => { - // TODO どっかにキャッシュ const m = await fetchMeta(); if (m.disableGlobalTimeline) { if (user == null || (!user.isAdmin && !user.isModerator)) { diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts index effee2b134..c05c8dedd6 100644 --- a/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -1,7 +1,7 @@ import $ from 'cafy'; import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { ApiError } from '../../error'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Followings, Notes } from '../../../../models'; @@ -9,6 +9,7 @@ import { Brackets } from 'typeorm'; import { generateVisibilityQuery } from '../../common/generate-visibility-query'; import { generateMuteQuery } from '../../common/generate-mute-query'; import { activeUsersChart } from '../../../../services/chart'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -89,10 +90,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { @@ -105,7 +109,6 @@ export const meta = { }; export default define(meta, async (ps, user) => { - // TODO どっかにキャッシュ const m = await fetchMeta(); if (m.disableLocalTimeline && !user.isAdmin && !user.isModerator) { throw new ApiError(meta.errors.stlDisabled); diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts index c10c0d7482..ca84fc6ef9 100644 --- a/src/server/api/endpoints/notes/local-timeline.ts +++ b/src/server/api/endpoints/notes/local-timeline.ts @@ -1,7 +1,7 @@ import $ from 'cafy'; import { ID } from '../../../../misc/cafy-id'; import define from '../../define'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { ApiError } from '../../error'; import { Notes } from '../../../../models'; import { generateMuteQuery } from '../../common/generate-mute-query'; @@ -9,6 +9,7 @@ import { makePaginationQuery } from '../../common/make-pagination-query'; import { generateVisibilityQuery } from '../../common/generate-visibility-query'; import { activeUsersChart } from '../../../../services/chart'; import { Brackets } from 'typeorm'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -63,10 +64,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { @@ -79,7 +83,6 @@ export const meta = { }; export default define(meta, async (ps, user) => { - // TODO どっかにキャッシュ const m = await fetchMeta(); if (m.disableLocalTimeline) { if (user == null || (!user.isAdmin && !user.isModerator)) { diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts index b7f614915b..02e44492ba 100644 --- a/src/server/api/endpoints/notes/mentions.ts +++ b/src/server/api/endpoints/notes/mentions.ts @@ -7,6 +7,7 @@ import { generateVisibilityQuery } from '../../common/generate-visibility-query' import { generateMuteQuery } from '../../common/generate-mute-query'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Brackets } from 'typeorm'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -43,10 +44,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, }; diff --git a/src/server/api/endpoints/notes/reactions.ts b/src/server/api/endpoints/notes/reactions.ts index bcb0b6d1ec..0773b4faa2 100644 --- a/src/server/api/endpoints/notes/reactions.ts +++ b/src/server/api/endpoints/notes/reactions.ts @@ -4,6 +4,7 @@ import define from '../../define'; import { getNote } from '../../common/getters'; import { ApiError } from '../../error'; import { NoteReactions } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -44,9 +45,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Reaction' + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'NoteReaction', } }, diff --git a/src/server/api/endpoints/notes/renotes.ts b/src/server/api/endpoints/notes/renotes.ts index 74a8ea918e..00dfac3770 100644 --- a/src/server/api/endpoints/notes/renotes.ts +++ b/src/server/api/endpoints/notes/renotes.ts @@ -7,6 +7,7 @@ import { generateVisibilityQuery } from '../../common/generate-visibility-query' import { generateMuteQuery } from '../../common/generate-mute-query'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Notes } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -42,10 +43,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { diff --git a/src/server/api/endpoints/notes/replies.ts b/src/server/api/endpoints/notes/replies.ts index 980ff2446e..5fb0fd989f 100644 --- a/src/server/api/endpoints/notes/replies.ts +++ b/src/server/api/endpoints/notes/replies.ts @@ -5,6 +5,7 @@ import { Notes } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { generateVisibilityQuery } from '../../common/generate-visibility-query'; import { generateMuteQuery } from '../../common/generate-mute-query'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -46,10 +47,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, }; diff --git a/src/server/api/endpoints/notes/search-by-tag.ts b/src/server/api/endpoints/notes/search-by-tag.ts index cba3724b6f..0b49f896ad 100644 --- a/src/server/api/endpoints/notes/search-by-tag.ts +++ b/src/server/api/endpoints/notes/search-by-tag.ts @@ -6,6 +6,7 @@ import { Notes } from '../../../../models'; import { generateMuteQuery } from '../../common/generate-mute-query'; import { generateVisibilityQuery } from '../../common/generate-visibility-query'; import { Brackets } from 'typeorm'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -81,10 +82,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, }; @@ -96,14 +100,14 @@ export default define(meta, async (ps, me) => { if (me) generateMuteQuery(query, me); if (ps.tag) { - query.andWhere(':tag = ANY(note.tags)', { tag: ps.tag }); + query.andWhere(':tag = ANY(note.tags)', { tag: ps.tag.toLowerCase() }); } else { let i = 0; query.andWhere(new Brackets(qb => { for (const tags of ps.query!) { qb.orWhere(new Brackets(qb => { for (const tag of tags) { - qb.andWhere(`:tag${i} = ANY(note.tags)`, { [`tag${i}`]: tag }); + qb.andWhere(`:tag${i} = ANY(note.tags)`, { [`tag${i}`]: tag.toLowerCase() }); i++; } })); diff --git a/src/server/api/endpoints/notes/search.ts b/src/server/api/endpoints/notes/search.ts index 4d5ac6fbe0..daf992b639 100644 --- a/src/server/api/endpoints/notes/search.ts +++ b/src/server/api/endpoints/notes/search.ts @@ -4,6 +4,7 @@ import define from '../../define'; import { ApiError } from '../../error'; import { Notes } from '../../../../models'; import { In } from 'typeorm'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -32,10 +33,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { diff --git a/src/server/api/endpoints/notes/show.ts b/src/server/api/endpoints/notes/show.ts index d41dc20c54..54b420813d 100644 --- a/src/server/api/endpoints/notes/show.ts +++ b/src/server/api/endpoints/notes/show.ts @@ -4,6 +4,7 @@ import define from '../../define'; import { getNote } from '../../common/getters'; import { ApiError } from '../../error'; import { Notes } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { stability: 'stable', @@ -28,7 +29,9 @@ export const meta = { }, res: { - type: 'Note', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', }, errors: { diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts index c27f3df1b7..5e692db389 100644 --- a/src/server/api/endpoints/notes/timeline.ts +++ b/src/server/api/endpoints/notes/timeline.ts @@ -7,6 +7,7 @@ import { generateVisibilityQuery } from '../../common/generate-visibility-query' import { generateMuteQuery } from '../../common/generate-mute-query'; import { activeUsersChart } from '../../../../services/chart'; import { Brackets } from 'typeorm'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -88,10 +89,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, }; diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts index 05f171af8b..c16018d434 100644 --- a/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/src/server/api/endpoints/notes/user-list-timeline.ts @@ -6,6 +6,7 @@ import { UserLists, UserListJoinings, Notes } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { generateVisibilityQuery } from '../../common/generate-visibility-query'; import { activeUsersChart } from '../../../../services/chart'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -94,10 +95,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { diff --git a/src/server/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts index f3ebaa16ad..f85109b4b4 100644 --- a/src/server/api/endpoints/stats.ts +++ b/src/server/api/endpoints/stats.ts @@ -1,6 +1,7 @@ import define from '../define'; import { Notes, Users } from '../../../models'; import { federationChart, driveChart } from '../../../services/chart'; +import { bool, types } from '../../../misc/schema'; export const meta = { requireCredential: false, @@ -15,26 +16,32 @@ export const meta = { }, res: { - type: 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { notesCount: { - type: 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'The count of all (local/remote) notes of this instance.', }, originalNotesCount: { - type: 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'The count of all local notes of this instance.', }, usersCount: { - type: 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'The count of all (local/remote) accounts of this instance.', }, originalUsersCount: { - type: 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'The count of all local accounts of this instance.', }, instances: { - type: 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'The count of federated instances.', }, } @@ -42,7 +49,14 @@ export const meta = { }; export default define(meta, async () => { - const [notesCount, originalNotesCount, usersCount, originalUsersCount, instances, driveUsageLocal, driveUsageRemote] = await Promise.all([ + const [notesCount, + originalNotesCount, + usersCount, + originalUsersCount, + instances, + driveUsageLocal, + driveUsageRemote + ] = await Promise.all([ Notes.count(), Notes.count({ userHost: null }), Users.count(), @@ -53,6 +67,12 @@ export default define(meta, async () => { ]); return { - notesCount, originalNotesCount, usersCount, originalUsersCount, instances, driveUsageLocal, driveUsageRemote + notesCount, + originalNotesCount, + usersCount, + originalUsersCount, + instances, + driveUsageLocal, + driveUsageRemote }; }); diff --git a/src/server/api/endpoints/sw/register.ts b/src/server/api/endpoints/sw/register.ts index 559937ca2f..a4838b4565 100644 --- a/src/server/api/endpoints/sw/register.ts +++ b/src/server/api/endpoints/sw/register.ts @@ -1,6 +1,6 @@ import $ from 'cafy'; import define from '../../define'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { genId } from '../../../../misc/gen-id'; import { SwSubscriptions } from '../../../../models'; @@ -33,7 +33,7 @@ export default define(meta, async (ps, user) => { publickey: ps.publickey, }); - const instance = await fetchMeta(); + const instance = await fetchMeta(true); if (exist != null) { return { diff --git a/src/server/api/endpoints/users.ts b/src/server/api/endpoints/users.ts index 18af0a2685..c710706f0c 100644 --- a/src/server/api/endpoints/users.ts +++ b/src/server/api/endpoints/users.ts @@ -2,6 +2,7 @@ import $ from 'cafy'; import define from '../define'; import { Users } from '../../../models'; import { generateMuteQueryForUsers } from '../common/generate-mute-query'; +import { types, bool } from '../../../misc/schema'; export const meta = { tags: ['users'], @@ -53,9 +54,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'User', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', } }, }; diff --git a/src/server/api/endpoints/users/followers.ts b/src/server/api/endpoints/users/followers.ts index 0cb68353ca..465b71e2e6 100644 --- a/src/server/api/endpoints/users/followers.ts +++ b/src/server/api/endpoints/users/followers.ts @@ -5,6 +5,7 @@ import { ApiError } from '../../error'; import { Users, Followings } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { toPunyNullable } from '../../../../misc/convert-host'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -48,10 +49,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Following', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Following', + } }, errors: { diff --git a/src/server/api/endpoints/users/following.ts b/src/server/api/endpoints/users/following.ts index 2e273dc0c2..2a7748ac64 100644 --- a/src/server/api/endpoints/users/following.ts +++ b/src/server/api/endpoints/users/following.ts @@ -5,6 +5,7 @@ import { ApiError } from '../../error'; import { Users, Followings } from '../../../../models'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { toPunyNullable } from '../../../../misc/convert-host'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -48,10 +49,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Following', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Following', + } }, errors: { diff --git a/src/server/api/endpoints/users/get-frequently-replied-users.ts b/src/server/api/endpoints/users/get-frequently-replied-users.ts index a1d140c6c9..420936c089 100644 --- a/src/server/api/endpoints/users/get-frequently-replied-users.ts +++ b/src/server/api/endpoints/users/get-frequently-replied-users.ts @@ -6,6 +6,7 @@ import { ApiError } from '../../error'; import { getUser } from '../../common/getters'; import { Not, In } from 'typeorm'; import { Notes, Users } from '../../../../models'; +import { types, bool } from '../../../../misc/schema'; export const meta = { tags: ['users'], @@ -28,9 +29,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'User', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', } }, diff --git a/src/server/api/endpoints/users/lists/create.ts b/src/server/api/endpoints/users/lists/create.ts index 21dc6d331d..79efffbf9e 100644 --- a/src/server/api/endpoints/users/lists/create.ts +++ b/src/server/api/endpoints/users/lists/create.ts @@ -3,6 +3,7 @@ import define from '../../../define'; import { UserLists } from '../../../../../models'; import { genId } from '../../../../../misc/gen-id'; import { UserList } from '../../../../../models/entities/user-list'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { desc: { @@ -17,10 +18,16 @@ export const meta = { kind: 'write:account', params: { - title: { + name: { validator: $.str.range(1, 100) } - } + }, + + res: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'UserList', + }, }; export default define(meta, async (ps, user) => { @@ -28,7 +35,7 @@ export default define(meta, async (ps, user) => { id: genId(), createdAt: new Date(), userId: user.id, - name: ps.title, + name: ps.name, } as UserList); return await UserLists.pack(userList); diff --git a/src/server/api/endpoints/users/lists/list.ts b/src/server/api/endpoints/users/lists/list.ts index b05fc45527..684086b5c6 100644 --- a/src/server/api/endpoints/users/lists/list.ts +++ b/src/server/api/endpoints/users/lists/list.ts @@ -1,5 +1,6 @@ import define from '../../../define'; import { UserLists } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { desc: { @@ -13,10 +14,13 @@ export const meta = { kind: 'read:account', res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'UserList', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'UserList', + } }, }; diff --git a/src/server/api/endpoints/users/lists/show.ts b/src/server/api/endpoints/users/lists/show.ts index 1a997ec7c5..395f9352d4 100644 --- a/src/server/api/endpoints/users/lists/show.ts +++ b/src/server/api/endpoints/users/lists/show.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../../misc/cafy-id'; import define from '../../../define'; import { ApiError } from '../../../error'; import { UserLists } from '../../../../../models'; +import { types, bool } from '../../../../../misc/schema'; export const meta = { desc: { @@ -23,7 +24,9 @@ export const meta = { }, res: { - type: 'UserList' + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'UserList', }, errors: { diff --git a/src/server/api/endpoints/users/notes.ts b/src/server/api/endpoints/users/notes.ts index 4691a99394..fdc50e4dae 100644 --- a/src/server/api/endpoints/users/notes.ts +++ b/src/server/api/endpoints/users/notes.ts @@ -8,6 +8,7 @@ import { generateVisibilityQuery } from '../../common/generate-visibility-query' import { Notes } from '../../../../models'; import { generateMuteQuery } from '../../common/generate-mute-query'; import { Brackets } from 'typeorm'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -119,10 +120,13 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'Note', - }, + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'Note', + } }, errors: { diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts index 9e16e34e39..67b646a35f 100644 --- a/src/server/api/endpoints/users/recommendation.ts +++ b/src/server/api/endpoints/users/recommendation.ts @@ -3,6 +3,7 @@ import $ from 'cafy'; import define from '../../define'; import { Users, Followings } from '../../../../models'; import { generateMuteQueryForUsers } from '../../common/generate-mute-query'; +import { types, bool } from '../../../../misc/schema'; export const meta = { desc: { @@ -28,9 +29,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'User', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', } }, }; diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts index 96da221d97..2809465fd7 100644 --- a/src/server/api/endpoints/users/search.ts +++ b/src/server/api/endpoints/users/search.ts @@ -2,6 +2,7 @@ import $ from 'cafy'; import define from '../../define'; import { Users } from '../../../../models'; import { User } from '../../../../models/entities/user'; +import { bool, types } from '../../../../misc/schema'; export const meta = { desc: { @@ -54,9 +55,12 @@ export const meta = { }, res: { - type: 'array', + type: types.array, + optional: bool.false, nullable: bool.false, items: { - type: 'User', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', } }, }; diff --git a/src/server/api/endpoints/users/show.ts b/src/server/api/endpoints/users/show.ts index a401166c55..820c44e81b 100644 --- a/src/server/api/endpoints/users/show.ts +++ b/src/server/api/endpoints/users/show.ts @@ -6,6 +6,7 @@ import { ApiError } from '../../error'; import { ID } from '../../../../misc/cafy-id'; import { Users } from '../../../../models'; import { In } from 'typeorm'; +import { bool, types } from '../../../../misc/schema'; export const meta = { desc: { @@ -42,7 +43,9 @@ export const meta = { }, res: { - type: 'User', + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', }, errors: { diff --git a/src/server/api/openapi/description.ts b/src/server/api/openapi/description.ts index 0a4c8699d1..9006dfbfa4 100644 --- a/src/server/api/openapi/description.ts +++ b/src/server/api/openapi/description.ts @@ -44,20 +44,20 @@ export function getDescription(lang = 'ja-JP'): string { const descriptions = { 'ja-JP': `**Misskey is a decentralized microblogging platform.** -## Usage +# Usage **APIはすべてPOSTでリクエスト/レスポンスともにJSON形式です。** 一部のAPIはリクエストに認証情報(APIキー)が必要です。リクエストの際に\`i\`というパラメータでAPIキーを添付してください。 -### 自分のアカウントのAPIキーを取得する +## 自分のアカウントのAPIキーを取得する 「設定 > API」で、自分のAPIキーを取得できます。 > アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。 -### アプリケーションとしてAPIキーを取得する +## アプリケーションとしてAPIキーを取得する 直接ユーザーのAPIキーをアプリケーションが扱うのはセキュリティ上のリスクがあるので、 アプリケーションからAPIを利用する際には、アプリケーションとアプリケーションを利用するユーザーが結び付けられた専用のAPIキーを発行します。 -#### 1.アプリケーションを登録する +### 1.アプリケーションを登録する まず、あなたのアプリケーションやWebサービス(以後、あなたのアプリと呼びます)をMisskeyに登録します。 [デベロッパーセンター](/dev)にアクセスし、「アプリ > アプリ作成」からアプリを作成してください。 @@ -65,7 +65,7 @@ export function getDescription(lang = 'ja-JP'): string { > アプリに成りすまされる可能性があるため、極力このシークレットキーは公開しないようにしてください。</p> -#### 2.ユーザーに認証させる +### 2.ユーザーに認証させる アプリを使ってもらうには、ユーザーにアカウントへのアクセスの許可をもらう必要があります。 認証セッションを開始するには、[${config.apiUrl}/auth/session/generate](#operation/auth/session/generate) へパラメータに\`appSecret\`としてシークレットキーを含めたリクエストを送信します。 @@ -76,7 +76,7 @@ export function getDescription(lang = 'ja-JP'): string { あなたのアプリがコールバックURLを設定していない場合、ユーザーがあなたのアプリの連携を許可したことを(何らかの方法で(たとえばボタンを押させるなど))確認出来るようにしてください。 -#### 3.アクセストークンを取得する +### 3.アクセストークンを取得する ユーザーが連携を許可したら、[${config.apiUrl}/auth/session/userkey](#operation/auth/session/userkey) へリクエストを送信します。 上手くいけば、認証したユーザーのアクセストークンがレスポンスとして取得できます。おめでとうございます! @@ -88,7 +88,7 @@ APIキーの生成方法を擬似コードで表すと次のようになりま const i = sha256(userToken + secretKey); \`\`\` -## Permissions +# Permissions |Permisson (kind)|Description|Endpoints| |:--|:--|:--| ${permissionTable} diff --git a/src/server/api/openapi/gen-spec.ts b/src/server/api/openapi/gen-spec.ts index d194c6c8a8..de26b970ea 100644 --- a/src/server/api/openapi/gen-spec.ts +++ b/src/server/api/openapi/gen-spec.ts @@ -2,9 +2,8 @@ import endpoints from '../endpoints'; import { Context } from 'cafy'; import config from '../../../config'; import { errors as basicErrors } from './errors'; -import { schemas } from './schemas'; +import { schemas, convertSchemaToOpenApiSchema } from './schemas'; import { getDescription } from './description'; -import { convertOpenApiSchema } from '../../../misc/schema'; export function genOpenapiSpec(lang = 'ja-JP') { const spec = { @@ -59,7 +58,7 @@ export function genOpenapiSpec(lang = 'ja-JP') { deprecated: (param.data || {}).deprecated, ...((param.data || {}).default ? { default: (param.data || {}).default } : {}), type: param.name === 'ID' ? 'string' : param.name.toLowerCase(), - ...(param.name === 'ID' ? { example: 'xxxxxxxxxxxxxxxxxxxxxxxx', format: 'id' } : {}), + ...(param.name === 'ID' ? { example: 'xxxxxxxxxx', format: 'id' } : {}), nullable: param.isNullable, ...(param.name === 'String' ? { ...((param as any).enum ? { enum: (param as any).enum } : {}), @@ -106,7 +105,7 @@ export function genOpenapiSpec(lang = 'ja-JP') { const required = endpoint.meta.params ? Object.entries(endpoint.meta.params).filter(([k, v]) => !v.validator.isOptional).map(([k, v]) => k) : []; - const resSchema = endpoint.meta.res ? convertOpenApiSchema(endpoint.meta.res) : {}; + const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res) : {}; let desc = (endpoint.meta.desc ? endpoint.meta.desc[lang] : 'No description provided.') + '\n\n'; desc += `**Credential required**: *${endpoint.meta.requireCredential ? 'Yes' : 'No'}*`; diff --git a/src/server/api/openapi/schemas.ts b/src/server/api/openapi/schemas.ts index 65826d9321..e54f989e74 100644 --- a/src/server/api/openapi/schemas.ts +++ b/src/server/api/openapi/schemas.ts @@ -1,3 +1,39 @@ +import { packedUserSchema } from '../../../models/repositories/user'; +import { Schema } from '../../../misc/schema'; +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'; + +export function convertSchemaToOpenApiSchema(schema: Schema) { + const res: any = schema; + + if (schema.type === 'object' && schema.properties) { + res.required = Object.entries(schema.properties).filter(([k, v]) => v.optional !== true).map(([k]) => k); + + for (const k of Object.keys(schema.properties)) { + res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]); + } + } + + if (schema.type === 'array' && schema.items) { + res.items = convertSchemaToOpenApiSchema(schema.items); + } + + if (schema.ref) { + res.$ref = `#/components/schemas/${schema.ref}`; + } + + return res; +} + export const schemas = { Error: { type: 'object', @@ -26,413 +62,18 @@ export const schemas = { required: ['error'] }, - User: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this User.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - username: { - type: 'string', - description: 'The screen name, handle, or alias that this user identifies themselves with.', - example: 'ai' - }, - name: { - type: 'string', - nullable: true, - description: 'The name of the user, as they’ve defined it.', - example: '藍' - }, - host: { - type: 'string', - nullable: true, - example: 'misskey.example.com' - }, - description: { - type: 'string', - nullable: true, - description: 'The user-defined UTF-8 string describing their account.', - example: 'Hi masters, I am Ai!' - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the user account was created on Misskey.' - }, - followersCount: { - type: 'number', - description: 'The number of followers this account currently has.' - }, - followingCount: { - type: 'number', - description: 'The number of users this account is following.' - }, - notesCount: { - type: 'number', - description: 'The number of Notes (including renotes) issued by the user.' - }, - isBot: { - type: 'boolean', - description: 'Whether this account is a bot.' - }, - isCat: { - type: 'boolean', - description: 'Whether this account is a cat.' - }, - isAdmin: { - type: 'boolean', - description: 'Whether this account is the admin.' - }, - isVerified: { - type: 'boolean' - }, - isLocked: { - type: 'boolean' - }, - }, - required: ['id', 'name', 'username', 'createdAt'] - }, - - UserList: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this UserList.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the UserList was created.' - }, - title: { - type: 'string', - description: 'The name of the UserList.' - }, - }, - required: ['id', 'createdAt', 'title'] - }, - - MessagingMessage: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this MessagingMessage.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the MessagingMessage was created.' - }, - text: { - type: 'string', - nullable: true - }, - file: { - type: 'DriveFile', - nullable: true - }, - recipientId: { - type: 'string', - format: 'id', - }, - recipient: { - $ref: '#/components/schemas/User' - }, - }, - required: ['id', 'createdAt'] - }, - - Note: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this Note.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the Note was created on Misskey.' - }, - text: { - type: 'string' - }, - cw: { - type: 'string' - }, - userId: { - type: 'string', - format: 'id', - }, - user: { - $ref: '#/components/schemas/User' - }, - replyId: { - type: 'string', - format: 'id', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - renoteId: { - type: 'string', - format: 'id', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - reply: { - $ref: '#/components/schemas/Note' - }, - renote: { - $ref: '#/components/schemas/Note' - }, - viaMobile: { - type: 'boolean' - }, - visibility: { - type: 'string' - }, - }, - required: ['id', 'userId', 'createdAt'] - }, - - Notification: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this notification.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the notification was created.' - }, - type: { - type: 'string', - enum: ['follow', 'receiveFollowRequest', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote'], - description: 'The type of the notification.' - }, - }, - required: ['id', 'createdAt', 'type'] - }, - - DriveFile: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this Drive file.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the Drive file was created on Misskey.' - }, - name: { - type: 'string', - description: 'The file name with extension.', - example: 'lenna.jpg' - }, - type: { - type: 'string', - description: 'The MIME type of this Drive file.', - example: 'image/jpeg' - }, - md5: { - type: 'string', - format: 'md5', - description: 'The MD5 hash of this Drive file.', - example: '15eca7fba0480996e2245f5185bf39f2' - }, - size: { - type: 'number', - description: 'The size of this Drive file. (bytes)', - example: 51469 - }, - folderId: { - type: 'string', - format: 'id', - nullable: true, - description: 'The parent folder ID of this Drive file.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - isSensitive: { - type: 'boolean', - description: 'Whether this Drive file is sensitive.', - }, - }, - required: ['id', 'createdAt', 'name', 'type', 'size', 'md5'] - }, - - DriveFolder: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this Drive folder.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the Drive folder was created.' - }, - name: { - type: 'string', - description: 'The folder name.', - }, - foldersCount: { - type: 'number', - description: 'The count of child folders.', - }, - filesCount: { - type: 'number', - description: 'The count of child files.', - }, - parentId: { - type: 'string', - format: 'id', - nullable: true, - description: 'The parent folder ID of this folder.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - parent: { - $ref: '#/components/schemas/DriveFolder' - }, - }, - required: ['id', 'createdAt', 'name'] - }, - - Following: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this following.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the following was created.' - }, - followeeId: { - type: 'string', - format: 'id', - }, - followee: { - $ref: '#/components/schemas/User', - description: 'The followee.' - }, - followerId: { - type: 'string', - format: 'id', - }, - follower: { - $ref: '#/components/schemas/User', - description: 'The follower.' - }, - }, - required: ['id', 'createdAt', 'followeeId', 'followerId'] - }, - - Muting: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this mute.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the mute was created.' - }, - mutee: { - $ref: '#/components/schemas/User', - description: 'The mutee.' - }, - }, - required: ['id', 'createdAt', 'mutee'] - }, - - Blocking: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this block.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the block was created.' - }, - blockee: { - $ref: '#/components/schemas/User', - description: 'The blockee.' - }, - }, - required: ['id', 'createdAt', 'blockee'] - }, - - Reaction: { - type: 'object', - properties: { - id: { - type: 'string', - format: 'id', - description: 'The unique identifier for this reaction.', - example: 'xxxxxxxxxxxxxxxxxxxxxxxx', - }, - createdAt: { - type: 'string', - format: 'date-time', - description: 'The date that the reaction was created.' - }, - user: { - $ref: '#/components/schemas/User', - description: 'User who performed this reaction.' - }, - type: { - type: 'string', - enum: [ - 'like', - 'love', - 'laugh', - 'hmm', - 'surprise', - 'congrats', - 'angry', - 'confused', - 'rip', - 'pudding', - 'star' - ], - description: 'The reaction type.' - }, - }, - required: ['id', 'createdAt', 'user', 'type'] - }, + User: convertSchemaToOpenApiSchema(packedUserSchema), + UserList: convertSchemaToOpenApiSchema(packedUserListSchema), + App: convertSchemaToOpenApiSchema(packedAppSchema), + MessagingMessage: convertSchemaToOpenApiSchema(packedMessagingMessageSchema), + Note: convertSchemaToOpenApiSchema(packedNoteSchema), + Notification: convertSchemaToOpenApiSchema(packedNotificationSchema), + DriveFile: convertSchemaToOpenApiSchema(packedDriveFileSchema), + DriveFolder: convertSchemaToOpenApiSchema(packedDriveFolderSchema), + Following: convertSchemaToOpenApiSchema(packedFollowingSchema), + Muting: convertSchemaToOpenApiSchema(packedMutingSchema), + Blocking: convertSchemaToOpenApiSchema(packedBlockingSchema), + NoteReaction: convertSchemaToOpenApiSchema(packedNoteReactionSchema), Hashtag: { type: 'object', diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts index f8dba2eb29..c75f8fb296 100644 --- a/src/server/api/private/signup.ts +++ b/src/server/api/private/signup.ts @@ -3,7 +3,7 @@ import * as bcrypt from 'bcryptjs'; import { generateKeyPair } from 'crypto'; import generateUserToken from '../common/generate-native-user-token'; import config from '../../../config'; -import fetchMeta from '../../../misc/fetch-meta'; +import { fetchMeta } from '../../../misc/fetch-meta'; import * as recaptcha from 'recaptcha-promise'; import { Users, RegistrationTickets } from '../../../models'; import { genId } from '../../../misc/gen-id'; @@ -17,7 +17,7 @@ import { getConnection } from 'typeorm'; export default async (ctx: Koa.BaseContext) => { const body = ctx.request.body as any; - const instance = await fetchMeta(); + const instance = await fetchMeta(true); // Verify recaptcha // ただしテスト時はこの機構は障害となるため無効にする @@ -135,7 +135,7 @@ export default async (ctx: Koa.BaseContext) => { includeSecrets: true }); - res.token = secret; + (res as any).token = secret; ctx.body = res; }; diff --git a/src/server/api/service/discord.ts b/src/server/api/service/discord.ts index d8a979b5b2..589579b8e0 100644 --- a/src/server/api/service/discord.ts +++ b/src/server/api/service/discord.ts @@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream'; import redis from '../../../db/redis'; import * as uuid from 'uuid'; import signin from '../common/signin'; -import fetchMeta from '../../../misc/fetch-meta'; +import { fetchMeta } from '../../../misc/fetch-meta'; import { Users, UserProfiles } from '../../../models'; import { ILocalUser } from '../../../models/entities/user'; import { ensure } from '../../../prelude/ensure'; @@ -68,7 +68,7 @@ router.get('/disconnect/discord', async ctx => { }); async function getOAuth2() { - const meta = await fetchMeta(); + const meta = await fetchMeta(true); if (meta.enableDiscordIntegration) { return new OAuth2( diff --git a/src/server/api/service/github.ts b/src/server/api/service/github.ts index a4d274cc62..1b0ce6936c 100644 --- a/src/server/api/service/github.ts +++ b/src/server/api/service/github.ts @@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream'; import redis from '../../../db/redis'; import * as uuid from 'uuid'; import signin from '../common/signin'; -import fetchMeta from '../../../misc/fetch-meta'; +import { fetchMeta } from '../../../misc/fetch-meta'; import { Users, UserProfiles } from '../../../models'; import { ILocalUser } from '../../../models/entities/user'; import { ensure } from '../../../prelude/ensure'; @@ -65,7 +65,7 @@ router.get('/disconnect/github', async ctx => { }); async function getOath2() { - const meta = await fetchMeta(); + const meta = await fetchMeta(true); if (meta.enableGithubIntegration && meta.githubClientId && meta.githubClientSecret) { return new OAuth2( diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts index 39fdfd8654..36299b1f29 100644 --- a/src/server/api/service/twitter.ts +++ b/src/server/api/service/twitter.ts @@ -6,7 +6,7 @@ import redis from '../../../db/redis'; import { publishMainStream } from '../../../services/stream'; import config from '../../../config'; import signin from '../common/signin'; -import fetchMeta from '../../../misc/fetch-meta'; +import { fetchMeta } from '../../../misc/fetch-meta'; import { Users, UserProfiles } from '../../../models'; import { ILocalUser } from '../../../models/entities/user'; import { ensure } from '../../../prelude/ensure'; @@ -65,7 +65,7 @@ router.get('/disconnect/twitter', async ctx => { }); async function getTwAuth() { - const meta = await fetchMeta(); + const meta = await fetchMeta(true); if (meta.enableTwitterIntegration && meta.twitterConsumerKey && meta.twitterConsumerSecret) { return autwh({ diff --git a/src/server/api/stream/channels/global-timeline.ts b/src/server/api/stream/channels/global-timeline.ts index bfb7697ba7..1271aae3a2 100644 --- a/src/server/api/stream/channels/global-timeline.ts +++ b/src/server/api/stream/channels/global-timeline.ts @@ -1,8 +1,9 @@ import autobind from 'autobind-decorator'; import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { Notes } from '../../../../models'; +import { PackedNote } from '../../../../models/repositories/note'; export default class extends Channel { public readonly chName = 'globalTimeline'; @@ -21,7 +22,9 @@ export default class extends Channel { } @autobind - private async onNote(note: any) { + private async onNote(note: PackedNote) { + if (note.visibility !== 'public') return; + // リプライなら再pack if (note.replyId != null) { note.reply = await Notes.pack(note.replyId, this.user, { diff --git a/src/server/api/stream/channels/hashtag.ts b/src/server/api/stream/channels/hashtag.ts index 36c56c7ab6..e55a508328 100644 --- a/src/server/api/stream/channels/hashtag.ts +++ b/src/server/api/stream/channels/hashtag.ts @@ -2,6 +2,7 @@ import autobind from 'autobind-decorator'; import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; import { Notes } from '../../../../models'; +import { PackedNote } from '../../../../models/repositories/note'; export default class extends Channel { public readonly chName = 'hashtag'; @@ -20,8 +21,8 @@ export default class extends Channel { } @autobind - private async onNote(note: any) { - const noteTags = note.tags.map((t: string) => t.toLowerCase()); + private async onNote(note: PackedNote) { + const noteTags = note.tags ? note.tags.map((t: string) => t.toLowerCase()) : []; const matched = this.q.some(tags => tags.every(tag => noteTags.includes(tag.toLowerCase()))); if (!matched) return; diff --git a/src/server/api/stream/channels/home-timeline.ts b/src/server/api/stream/channels/home-timeline.ts index 61960657b4..9aa4dc1c0f 100644 --- a/src/server/api/stream/channels/home-timeline.ts +++ b/src/server/api/stream/channels/home-timeline.ts @@ -2,6 +2,7 @@ import autobind from 'autobind-decorator'; import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; import { Notes } from '../../../../models'; +import { PackedNote } from '../../../../models/repositories/note'; export default class extends Channel { public readonly chName = 'homeTimeline'; @@ -15,7 +16,7 @@ export default class extends Channel { } @autobind - private async onNote(note: any) { + private async onNote(note: PackedNote) { // その投稿のユーザーをフォローしていなかったら弾く if (this.user!.id !== note.userId && !this.following.includes(note.userId)) return; diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts index a8020bfcfa..b9feb70258 100644 --- a/src/server/api/stream/channels/hybrid-timeline.ts +++ b/src/server/api/stream/channels/hybrid-timeline.ts @@ -1,8 +1,10 @@ import autobind from 'autobind-decorator'; import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { Notes } from '../../../../models'; +import { PackedNote } from '../../../../models/repositories/note'; +import { PackedUser } from '../../../../models/repositories/user'; export default class extends Channel { public readonly chName = 'hybridTimeline'; @@ -19,12 +21,12 @@ export default class extends Channel { } @autobind - private async onNote(note: any) { + private async onNote(note: PackedNote) { // 自分自身の投稿 または その投稿のユーザーをフォローしている または 全体公開のローカルの投稿 の場合だけ if (!( this.user!.id === note.userId || this.following.includes(note.userId) || - (note.user.host == null && note.visibility === 'public') + ((note.user as PackedUser).host == null && note.visibility === 'public') )) return; if (['followers', 'specified'].includes(note.visibility)) { diff --git a/src/server/api/stream/channels/local-timeline.ts b/src/server/api/stream/channels/local-timeline.ts index 4aec2d66b4..24cbc0a7bf 100644 --- a/src/server/api/stream/channels/local-timeline.ts +++ b/src/server/api/stream/channels/local-timeline.ts @@ -1,8 +1,10 @@ import autobind from 'autobind-decorator'; import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; -import fetchMeta from '../../../../misc/fetch-meta'; +import { fetchMeta } from '../../../../misc/fetch-meta'; import { Notes } from '../../../../models'; +import { PackedNote } from '../../../../models/repositories/note'; +import { PackedUser } from '../../../../models/repositories/user'; export default class extends Channel { public readonly chName = 'localTimeline'; @@ -21,8 +23,8 @@ export default class extends Channel { } @autobind - private async onNote(note: any) { - if (note.user.host !== null) return; + private async onNote(note: PackedNote) { + if ((note.user as PackedUser).host !== null) return; if (note.visibility === 'home') return; if (['followers', 'specified'].includes(note.visibility)) { diff --git a/src/server/api/stream/channels/user-list.ts b/src/server/api/stream/channels/user-list.ts index f5434b8f08..119bacf6ec 100644 --- a/src/server/api/stream/channels/user-list.ts +++ b/src/server/api/stream/channels/user-list.ts @@ -3,6 +3,7 @@ import Channel from '../channel'; import { Notes, UserListJoinings } from '../../../../models'; import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import { User } from '../../../../models/entities/user'; +import { PackedNote } from '../../../../models/repositories/note'; export default class extends Channel { public readonly chName = 'userList'; @@ -38,7 +39,7 @@ export default class extends Channel { } @autobind - private async onNote(note: any) { + private async onNote(note: PackedNote) { if (!this.listUsers.includes(note.userId)) return; if (['followers', 'specified'].includes(note.visibility)) { |