diff --git a/package.json b/package.json index 61ace88c1cfa31f1591fb1ccd77fad6a7c0a4375..b71b41336931460072819bfaa371908cfadf1d4c 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "@fortawesome/free-solid-svg-icons": "5.7.2", "@fortawesome/vue-fontawesome": "0.1.5", "@koa/cors": "2.2.3", - "@prezzemolo/rap": "0.1.2", "@prezzemolo/zip": "0.0.3", "@types/bcryptjs": "2.4.2", "@types/bull": "3.5.11", diff --git a/src/client/app/common/views/components/user-list-editor.vue b/src/client/app/common/views/components/user-list-editor.vue index 8d2e04d045b30522f52c909f316d6983b61c2e04..86024c4da3e6bf10d546fe72137d43000f4fe0df 100644 --- a/src/client/app/common/views/components/user-list-editor.vue +++ b/src/client/app/common/views/components/user-list-editor.vue @@ -77,11 +77,11 @@ export default Vue.extend({ input: { default: this.list.name } - }).then(({ canceled, result: title }) => { + }).then(({ canceled, result: name }) => { if (canceled) return; this.$root.api('users/lists/update', { listId: this.list.id, - title: title + name: name }); }); }, diff --git a/src/client/app/common/views/components/user-lists.vue b/src/client/app/common/views/components/user-lists.vue index 786a6766d3eb32fe20529e58692061082633843f..699251b3131e80d78dd1656974b3dc80ac0a5ce7 100644 --- a/src/client/app/common/views/components/user-lists.vue +++ b/src/client/app/common/views/components/user-lists.vue @@ -28,10 +28,10 @@ export default Vue.extend({ this.$root.dialog({ title: this.$t('list-name'), input: true - }).then(async ({ canceled, result: title }) => { + }).then(async ({ canceled, result: name }) => { if (canceled) return; const list = await this.$root.api('users/lists/create', { - title + name }); this.lists.push(list) diff --git a/src/client/app/desktop/views/home/timeline.vue b/src/client/app/desktop/views/home/timeline.vue index 1e6abac823e801386d4dc2c3f50466d60f89f207..3f9681a047504d59ddd76f19003a060e1c30863e 100644 --- a/src/client/app/desktop/views/home/timeline.vue +++ b/src/client/app/desktop/views/home/timeline.vue @@ -123,10 +123,10 @@ export default Vue.extend({ this.$root.dialog({ title: this.$t('list-name'), input: true - }).then(async ({ canceled, result: title }) => { + }).then(async ({ canceled, result: name }) => { if (canceled) return; const list = await this.$root.api('users/lists/create', { - title + name }); this.list = list; diff --git a/src/misc/schema.ts b/src/misc/schema.ts index 7c17953d97cff8a2685bf42b71689bf20da28453..442c95ad988102685feacb084eca88cdefe10b79 100644 --- a/src/misc/schema.ts +++ b/src/misc/schema.ts @@ -1,14 +1,46 @@ +export const types = { + boolean: 'boolean' as 'boolean', + string: 'string' as 'string', + number: 'number' as 'number', + array: 'array' as 'array', + object: 'object' as 'object', + any: 'any' as 'any', +}; + +export const bool = { + true: true as true, + false: false as false, +}; + export type Schema = { - type: 'number' | 'string' | 'array' | 'object' | any; - optional?: boolean; + type: 'boolean' | 'number' | 'string' | 'array' | 'object' | 'any'; + nullable: boolean; + optional: boolean; items?: Schema; properties?: Obj; description?: string; + example?: any; + format?: string; + ref?: string; + enum?: string[]; }; +type NonUndefinedPropertyNames<T extends Obj> = { + [K in keyof T]: T[K]['optional'] extends true ? never : K +}[keyof T]; + +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 type Obj = { [key: string]: Schema }; -export type ObjType<s extends Obj> = { [P in keyof s]: SchemaType<s[P]> }; +export type ObjType<s extends Obj> = + { [P in keyof OnlyOptional<s>]?: SchemaType<s[P]> } & + { [P in keyof OnlyRequired<s>]: SchemaType<s[P]> }; // https://qiita.com/hrsh7th@github/items/84e8968c3601009cdcf2 type MyType<T extends Schema> = { @@ -16,26 +48,20 @@ type MyType<T extends Schema> = { 1: SchemaType<T>; }[T extends Schema ? 1 : 0]; +type NullOrUndefined<p extends Schema, T> = + p['nullable'] extends true + ? p['optional'] extends true + ? (T | null | undefined) + : (T | null) + : p['optional'] extends true + ? (T | undefined) + : T; + export type SchemaType<p extends Schema> = - p['type'] extends 'number' ? number : - p['type'] extends 'string' ? string : - p['type'] extends 'array' ? MyType<NonNullable<p['items']>>[] : - p['type'] extends 'object' ? ObjType<NonNullable<p['properties']>> : + 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' ? NullOrUndefined<p, ObjType<NonNullable<p['properties']>>> : + p['type'] extends 'any' ? NullOrUndefined<p, any> : any; - -export function convertOpenApiSchema(schema: Schema) { - const x = JSON.parse(JSON.stringify(schema)); // copy - if (!['string', 'number', 'boolean', 'array', 'object'].includes(x.type)) { - x['$ref'] = `#/components/schemas/${x.type}`; - } - if (x.type === 'array' && x.items) { - x.items = convertOpenApiSchema(x.items); - } - if (x.type === 'object' && x.properties) { - x.required = Object.entries(x.properties).filter(([k, v]: any) => !v.isOptional).map(([k, v]: any) => k); - for (const k of Object.keys(x.properties)) { - x.properties[k] = convertOpenApiSchema(x.properties[k]); - } - } - return x; -} diff --git a/src/models/repositories/abuse-user-report.ts b/src/models/repositories/abuse-user-report.ts index f619d6e37f3b02cd219ba9fed0f5020debc0a3ec..c708b265a6e8984454cf534292a62fdea07097bd 100644 --- a/src/models/repositories/abuse-user-report.ts +++ b/src/models/repositories/abuse-user-report.ts @@ -1,8 +1,8 @@ import { EntityRepository, Repository } from 'typeorm'; import { Users } from '..'; -import rap from '@prezzemolo/rap'; import { AbuseUserReport } from '../entities/abuse-user-report'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; @EntityRepository(AbuseUserReport) export class AbuseUserReportRepository extends Repository<AbuseUserReport> { @@ -17,7 +17,7 @@ export class AbuseUserReportRepository extends Repository<AbuseUserReport> { ) { const report = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: report.id, createdAt: report.createdAt, reporterId: report.reporterId, diff --git a/src/models/repositories/app.ts b/src/models/repositories/app.ts index fa5ebf2ac76356ce4fc489b7b9937b70dbc04b2d..6562a470be698f71ca38317672b9feda345da597 100644 --- a/src/models/repositories/app.ts +++ b/src/models/repositories/app.ts @@ -2,6 +2,9 @@ import { EntityRepository, Repository } from 'typeorm'; import { App } from '../entities/app'; import { AccessTokens } from '..'; import { ensure } from '../../prelude/ensure'; +import { types, bool, SchemaType } from '../../misc/schema'; + +export type PackedApp = SchemaType<typeof packedAppSchema>; @EntityRepository(App) export class AppRepository extends Repository<App> { @@ -13,7 +16,7 @@ export class AppRepository extends Repository<App> { includeSecret?: boolean, includeProfileImageIds?: boolean } - ) { + ): Promise<PackedApp> { const opts = Object.assign({ detail: false, includeSecret: false, @@ -37,3 +40,40 @@ export class AppRepository extends Repository<App> { }; } } + +export const packedAppSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this Note.', + example: 'xxxxxxxxxx', + }, + name: { + type: types.string, + optional: bool.false, nullable: bool.false, + description: 'アプリケーションã®åå‰' + }, + callbackUrl: { + type: types.string, + optional: bool.false, nullable: bool.true, + description: 'コールãƒãƒƒã‚¯ã™ã‚‹URL' + }, + permission: { + type: types.array, + optional: bool.true, nullable: bool.false, + items: { + type: types.string, + optional: bool.false, nullable: bool.false, + } + }, + secret: { + type: types.string, + optional: bool.true, nullable: bool.false, + description: 'アプリケーションã®ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆã‚ー' + } + }, +}; diff --git a/src/models/repositories/auth-session.ts b/src/models/repositories/auth-session.ts index 32f7968233359b7f585c56fca889bd250415e7c4..a6a4d46de641f9b89fb2ffffefa9d516aa2e7363 100644 --- a/src/models/repositories/auth-session.ts +++ b/src/models/repositories/auth-session.ts @@ -1,8 +1,8 @@ import { EntityRepository, Repository } from 'typeorm'; import { Apps } from '..'; -import rap from '@prezzemolo/rap'; import { AuthSession } from '../entities/auth-session'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; @EntityRepository(AuthSession) export class AuthSessionRepository extends Repository<AuthSession> { @@ -12,7 +12,7 @@ export class AuthSessionRepository extends Repository<AuthSession> { ) { const session = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: session.id, app: Apps.pack(session.appId, me), token: session.token diff --git a/src/models/repositories/blocking.ts b/src/models/repositories/blocking.ts index e18aa591f371292a5b7399dfc34376c5198d87d6..fd209bce1c632f79b7f607688f481ef3f34c3540 100644 --- a/src/models/repositories/blocking.ts +++ b/src/models/repositories/blocking.ts @@ -1,8 +1,11 @@ import { EntityRepository, Repository } from 'typeorm'; import { Users } from '..'; -import rap from '@prezzemolo/rap'; import { Blocking } from '../entities/blocking'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; +import { SchemaType, types, bool } from '../../misc/schema'; + +export type PackedBlocking = SchemaType<typeof packedBlockingSchema>; @EntityRepository(Blocking) export class BlockingRepository extends Repository<Blocking> { @@ -16,14 +19,47 @@ export class BlockingRepository extends Repository<Blocking> { public async pack( src: Blocking['id'] | Blocking, me?: any - ) { + ): Promise<PackedBlocking> { const blocking = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: blocking.id, + createdAt: blocking.createdAt.toISOString(), + blockeeId: blocking.blockeeId, blockee: Users.pack(blocking.blockeeId, me, { detail: true }) }); } } + +export const packedBlockingSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this blocking.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the blocking was created.' + }, + blockeeId: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + }, + blockee: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', + description: 'The blockee.' + }, + } +}; diff --git a/src/models/repositories/drive-file.ts b/src/models/repositories/drive-file.ts index f117b38b24a2df60b13a43130e071839e4868eae..245db4b797db5ce7f66c7334b8ff905600e3c07e 100644 --- a/src/models/repositories/drive-file.ts +++ b/src/models/repositories/drive-file.ts @@ -1,10 +1,13 @@ import { EntityRepository, Repository } from 'typeorm'; import { DriveFile } from '../entities/drive-file'; import { Users, DriveFolders } from '..'; -import rap from '@prezzemolo/rap'; import { User } from '../entities/user'; import { toPuny } from '../../misc/convert-host'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; +import { types, bool, SchemaType } from '../../misc/schema'; + +export type PackedDriveFile = SchemaType<typeof packedDriveFileSchema>; @EntityRepository(DriveFile) export class DriveFileRepository extends Repository<DriveFile> { @@ -82,7 +85,7 @@ export class DriveFileRepository extends Repository<DriveFile> { self?: boolean, withUser?: boolean, } - ) { + ): Promise<PackedDriveFile> { const opts = Object.assign({ detail: false, self: false @@ -90,9 +93,9 @@ export class DriveFileRepository extends Repository<DriveFile> { const file = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: file.id, - createdAt: file.createdAt, + createdAt: file.createdAt.toISOString(), name: file.name, type: file.type, md5: file.md5, @@ -109,3 +112,66 @@ export class DriveFileRepository extends Repository<DriveFile> { }); } } + +export const packedDriveFileSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this Drive file.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the Drive file was created on Misskey.' + }, + name: { + type: types.string, + optional: bool.false, nullable: bool.false, + description: 'The file name with extension.', + example: 'lenna.jpg' + }, + type: { + type: types.string, + optional: bool.false, nullable: bool.false, + description: 'The MIME type of this Drive file.', + example: 'image/jpeg' + }, + md5: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'md5', + description: 'The MD5 hash of this Drive file.', + example: '15eca7fba0480996e2245f5185bf39f2' + }, + size: { + type: types.number, + optional: bool.false, nullable: bool.false, + description: 'The size of this Drive file. (bytes)', + example: 51469 + }, + url: { + type: types.string, + optional: bool.false, nullable: bool.true, + format: 'url', + description: 'The URL of this Drive file.', + }, + folderId: { + type: types.string, + optional: bool.false, nullable: bool.true, + format: 'id', + description: 'The parent folder ID of this Drive file.', + example: 'xxxxxxxxxx', + }, + isSensitive: { + type: types.boolean, + optional: bool.false, nullable: bool.false, + description: 'Whether this Drive file is sensitive.', + }, + }, +}; diff --git a/src/models/repositories/drive-folder.ts b/src/models/repositories/drive-folder.ts index ce88adefa4146e6c7191a79f14cd2ffe06277a0e..ef920c432683d809c22f409ae49a2660ad02a0ed 100644 --- a/src/models/repositories/drive-folder.ts +++ b/src/models/repositories/drive-folder.ts @@ -1,8 +1,11 @@ import { EntityRepository, Repository } from 'typeorm'; import { DriveFolders, DriveFiles } from '..'; -import rap from '@prezzemolo/rap'; import { DriveFolder } from '../entities/drive-folder'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; +import { SchemaType, types, bool } from '../../misc/schema'; + +export type PackedDriveFolder = SchemaType<typeof packedDriveFolderSchema>; @EntityRepository(DriveFolder) export class DriveFolderRepository extends Repository<DriveFolder> { @@ -18,16 +21,16 @@ export class DriveFolderRepository extends Repository<DriveFolder> { options?: { detail: boolean } - ): Promise<Record<string, any>> { + ): Promise<PackedDriveFolder> { const opts = Object.assign({ detail: false }, options); const folder = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: folder.id, - createdAt: folder.createdAt, + createdAt: folder.createdAt.toISOString(), name: folder.name, parentId: folder.parentId, @@ -48,3 +51,50 @@ export class DriveFolderRepository extends Repository<DriveFolder> { }); } } + +export const packedDriveFolderSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this Drive folder.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the Drive folder was created.' + }, + name: { + type: types.string, + optional: bool.false, nullable: bool.false, + description: 'The folder name.', + }, + foldersCount: { + type: types.number, + optional: bool.true, nullable: bool.false, + description: 'The count of child folders.', + }, + filesCount: { + type: types.number, + optional: bool.true, nullable: bool.false, + description: 'The count of child files.', + }, + parentId: { + type: types.string, + optional: bool.false, nullable: bool.true, + format: 'id', + description: 'The parent folder ID of this folder.', + example: 'xxxxxxxxxx', + }, + parent: { + type: types.object, + optional: bool.true, nullable: bool.true, + ref: 'DriveFolder' + }, + }, +}; diff --git a/src/models/repositories/following.ts b/src/models/repositories/following.ts index 3fff57866f3c720e5d5cffe8d57a7f138f49376e..aba6527face5dd09c5da9e7700c3d935eb4d0cea 100644 --- a/src/models/repositories/following.ts +++ b/src/models/repositories/following.ts @@ -1,8 +1,9 @@ import { EntityRepository, Repository } from 'typeorm'; import { Users } from '..'; -import rap from '@prezzemolo/rap'; import { Following } from '../entities/following'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; +import { SchemaType, types, bool } from '../../misc/schema'; type LocalFollowerFollowing = Following & { followerHost: null; @@ -28,6 +29,8 @@ type RemoteFolloweeFollowing = Following & { followeeSharedInbox: string; }; +export type PackedFollowing = SchemaType<typeof packedFollowingSchema>; + @EntityRepository(Following) export class FollowingRepository extends Repository<Following> { public isLocalFollower(following: Following): following is LocalFollowerFollowing { @@ -64,22 +67,64 @@ export class FollowingRepository extends Repository<Following> { populateFollowee?: boolean; populateFollower?: boolean; } - ) { + ): Promise<PackedFollowing> { const following = typeof src === 'object' ? src : await this.findOne(src).then(ensure); if (opts == null) opts = {}; - return await rap({ + return await awaitAll({ id: following.id, - createdAt: following.createdAt, + createdAt: following.createdAt.toISOString(), followeeId: following.followeeId, followerId: following.followerId, followee: opts.populateFollowee ? Users.pack(following.followee || following.followeeId, me, { detail: true - }) : null, + }) : undefined, follower: opts.populateFollower ? Users.pack(following.follower || following.followerId, me, { detail: true - }) : null, + }) : undefined, }); } } + +export const packedFollowingSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this following.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the following was created.' + }, + followeeId: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + }, + followee: { + type: types.object, + optional: bool.true, nullable: bool.false, + ref: 'User', + description: 'The followee.' + }, + followerId: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + }, + follower: { + type: types.object, + optional: bool.true, nullable: bool.false, + ref: 'User', + description: 'The follower.' + }, + } +}; diff --git a/src/models/repositories/games/reversi/matching.ts b/src/models/repositories/games/reversi/matching.ts index 4d99c6ef76d50e91ea5696aca3924463f3d2de5c..86c9204456593f24d5d7b3a1d24637ec410c3fec 100644 --- a/src/models/repositories/games/reversi/matching.ts +++ b/src/models/repositories/games/reversi/matching.ts @@ -1,8 +1,8 @@ import { EntityRepository, Repository } from 'typeorm'; -import rap from '@prezzemolo/rap'; import { ReversiMatching } from '../../../entities/games/reversi/matching'; import { Users } from '../../..'; import { ensure } from '../../../../prelude/ensure'; +import { awaitAll } from '../../../../prelude/await-all'; @EntityRepository(ReversiMatching) export class ReversiMatchingRepository extends Repository<ReversiMatching> { @@ -12,7 +12,7 @@ export class ReversiMatchingRepository extends Repository<ReversiMatching> { ) { const matching = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: matching.id, createdAt: matching.createdAt, parentId: matching.parentId, diff --git a/src/models/repositories/messaging-message.ts b/src/models/repositories/messaging-message.ts index 665927353976dabaaf582694b475660961ff2be8..33f95bbd5f1da7929ad043be8eb12e9134072295 100644 --- a/src/models/repositories/messaging-message.ts +++ b/src/models/repositories/messaging-message.ts @@ -2,6 +2,9 @@ import { EntityRepository, Repository } from 'typeorm'; import { MessagingMessage } from '../entities/messaging-message'; import { Users, DriveFiles } from '..'; import { ensure } from '../../prelude/ensure'; +import { types, bool, SchemaType } from '../../misc/schema'; + +export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSchema>; @EntityRepository(MessagingMessage) export class MessagingMessageRepository extends Repository<MessagingMessage> { @@ -15,7 +18,7 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> { options?: { populateRecipient: boolean } - ) { + ): Promise<PackedMessagingMessage> { const opts = options || { populateRecipient: true }; @@ -24,15 +27,73 @@ export class MessagingMessageRepository extends Repository<MessagingMessage> { return { id: message.id, - createdAt: message.createdAt, + createdAt: message.createdAt.toISOString(), text: message.text, userId: message.userId, user: await Users.pack(message.user || message.userId, me), recipientId: message.recipientId, - recipient: opts.populateRecipient ? await Users.pack(message.recipient || message.recipientId, me) : null, + recipient: opts.populateRecipient ? await Users.pack(message.recipient || message.recipientId, me) : undefined, fileId: message.fileId, file: message.fileId ? await DriveFiles.pack(message.fileId) : null, isRead: message.isRead }; } } + +export const packedMessagingMessageSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this MessagingMessage.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the MessagingMessage was created.' + }, + userId: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + }, + user: { + type: types.object, + ref: 'User', + optional: bool.true, nullable: bool.false, + }, + text: { + type: types.string, + optional: bool.false, nullable: bool.true, + }, + fileId: { + type: types.string, + optional: bool.true, nullable: bool.true, + format: 'id', + }, + file: { + type: types.object, + optional: bool.true, nullable: bool.true, + ref: 'DriveFile', + }, + recipientId: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + }, + recipient: { + type: types.object, + optional: bool.true, nullable: bool.false, + ref: 'User' + }, + isRead: { + type: types.boolean, + optional: bool.true, nullable: bool.false, + }, + }, +}; diff --git a/src/models/repositories/muting.ts b/src/models/repositories/muting.ts index 1812e2e71341f570b02b56562c9bb8c175be1515..1e8135a5c91e019ac50a43db716cf9bcc218cdd4 100644 --- a/src/models/repositories/muting.ts +++ b/src/models/repositories/muting.ts @@ -1,8 +1,11 @@ import { EntityRepository, Repository } from 'typeorm'; import { Users } from '..'; -import rap from '@prezzemolo/rap'; import { Muting } from '../entities/muting'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; +import { types, bool, SchemaType } from '../../misc/schema'; + +export type PackedMuting = SchemaType<typeof packedMutingSchema>; @EntityRepository(Muting) export class MutingRepository extends Repository<Muting> { @@ -16,14 +19,47 @@ export class MutingRepository extends Repository<Muting> { public async pack( src: Muting['id'] | Muting, me?: any - ) { + ): Promise<PackedMuting> { const muting = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: muting.id, + createdAt: muting.createdAt.toISOString(), + muteeId: muting.muteeId, mutee: Users.pack(muting.muteeId, me, { detail: true }) }); } } + +export const packedMutingSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this muting.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the muting was created.' + }, + muteeId: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + }, + mutee: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', + description: 'The mutee.' + }, + } +}; diff --git a/src/models/repositories/note-reaction.ts b/src/models/repositories/note-reaction.ts index 28191d4ab0d1e81278194fbd4d3abe3dcb6e8c4c..85e5b6b0a1f15900a2f848c7fd01f4a780658331 100644 --- a/src/models/repositories/note-reaction.ts +++ b/src/models/repositories/note-reaction.ts @@ -2,18 +2,54 @@ import { EntityRepository, Repository } from 'typeorm'; import { NoteReaction } from '../entities/note-reaction'; import { Users } from '..'; import { ensure } from '../../prelude/ensure'; +import { types, bool, SchemaType } from '../../misc/schema'; + +export type PackedNoteReaction = SchemaType<typeof packedNoteReactionSchema>; @EntityRepository(NoteReaction) export class NoteReactionRepository extends Repository<NoteReaction> { public async pack( src: NoteReaction['id'] | NoteReaction, me?: any - ) { + ): Promise<PackedNoteReaction> { const reaction = typeof src === 'object' ? src : await this.findOne(src).then(ensure); return { id: reaction.id, + createdAt: reaction.createdAt.toISOString(), user: await Users.pack(reaction.userId, me), + type: reaction.reaction, }; } } + +export const packedNoteReactionSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this reaction.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the reaction was created.' + }, + user: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'User', + description: 'User who performed this reaction.' + }, + type: { + type: types.string, + optional: bool.false, nullable: bool.false, + description: 'The reaction type.' + }, + }, +}; diff --git a/src/models/repositories/note.ts b/src/models/repositories/note.ts index 1d2ce7a9c91f255a43bc37789e37c86a39e496b9..1dbfabe88d7d007d8783f0f46fecf417e1a3ac08 100644 --- a/src/models/repositories/note.ts +++ b/src/models/repositories/note.ts @@ -4,8 +4,11 @@ import { User } from '../entities/user'; import { unique, concat } from '../../prelude/array'; import { nyaize } from '../../misc/nyaize'; import { Emojis, Users, Apps, PollVotes, DriveFiles, NoteReactions, Followings, Polls } from '..'; -import rap from '@prezzemolo/rap'; import { ensure } from '../../prelude/ensure'; +import { SchemaType, types, bool } from '../../misc/schema'; +import { awaitAll } from '../../prelude/await-all'; + +export type PackedNote = SchemaType<typeof packedNoteSchema>; @EntityRepository(Note) export class NoteRepository extends Repository<Note> { @@ -13,18 +16,18 @@ export class NoteRepository extends Repository<Note> { return x.trim().length <= 100; } - private async hideNote(packedNote: any, meId: User['id'] | null) { + private async hideNote(packedNote: PackedNote, meId: User['id'] | null) { let hide = false; // visibility ㌠specified ã‹ã¤è‡ªåˆ†ãŒæŒ‡å®šã•ã‚Œã¦ã„ãªã‹ã£ãŸã‚‰éžè¡¨ç¤º - if (packedNote.visibility == 'specified') { + if (packedNote.visibility === 'specified') { if (meId == null) { hide = true; } else if (meId === packedNote.userId) { hide = false; } else { // 指定ã•ã‚Œã¦ã„ã‚‹ã‹ã©ã†ã‹ - const specified = packedNote.visibleUserIds.some((id: any) => meId === id); + const specified = packedNote.visibleUserIds!.some((id: any) => meId === id); if (specified) { hide = false; @@ -40,10 +43,10 @@ export class NoteRepository extends Repository<Note> { hide = true; } else if (meId === packedNote.userId) { hide = false; - } else if (packedNote.reply && (meId === packedNote.reply.userId)) { + } else if (packedNote.reply && (meId === (packedNote.reply as PackedNote).userId)) { // 自分ã®æŠ•ç¨¿ã«å¯¾ã™ã‚‹ãƒªãƒ—ライ hide = false; - } else if (packedNote.mentions && packedNote.mentions.some((id: any) => meId === id)) { + } else if (packedNote.mentions && packedNote.mentions.some(id => meId === id)) { // 自分ã¸ã®ãƒ¡ãƒ³ã‚·ãƒ§ãƒ³ hide = false; } else { @@ -62,14 +65,13 @@ export class NoteRepository extends Repository<Note> { } if (hide) { - packedNote.visibleUserIds = null; + packedNote.visibleUserIds = undefined; packedNote.fileIds = []; packedNote.files = []; packedNote.text = null; - packedNote.poll = null; + packedNote.poll = undefined; packedNote.cw = null; - packedNote.tags = []; - packedNote.geo = null; + packedNote.geo = undefined; packedNote.isHidden = true; } } @@ -92,7 +94,7 @@ export class NoteRepository extends Repository<Note> { detail?: boolean; skipHide?: boolean; } - ): Promise<Record<string, any>> { + ): Promise<PackedNote> { const opts = Object.assign({ detail: true, skipHide: false @@ -159,9 +161,9 @@ export class NoteRepository extends Repository<Note> { const reactionEmojis = unique(concat([note.emojis, Object.keys(note.reactions)])); - const packed = await rap({ + const packed = await awaitAll({ id: note.id, - createdAt: note.createdAt, + createdAt: note.createdAt.toISOString(), app: note.appId ? Apps.pack(note.appId) : undefined, userId: note.userId, user: Users.pack(note.user || note.userId, meId), @@ -213,3 +215,127 @@ export class NoteRepository extends Repository<Note> { return packed; } } + +export const packedNoteSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this Note.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the Note was created on Misskey.' + }, + text: { + type: types.string, + optional: bool.false, nullable: bool.true, + }, + cw: { + type: types.string, + optional: bool.true, nullable: bool.true, + }, + userId: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + }, + user: { + type: types.object, + ref: 'User', + optional: bool.false, nullable: bool.false, + }, + replyId: { + type: types.string, + optional: bool.true, nullable: bool.true, + format: 'id', + example: 'xxxxxxxxxx', + }, + renoteId: { + type: types.string, + optional: bool.true, nullable: bool.true, + format: 'id', + example: 'xxxxxxxxxx', + }, + reply: { + type: types.object, + optional: bool.true, nullable: bool.true, + ref: 'Note' + }, + renote: { + type: types.object, + optional: bool.true, nullable: bool.true, + ref: 'Note' + }, + viaMobile: { + type: types.boolean, + optional: bool.true, nullable: bool.false, + }, + isHidden: { + type: types.boolean, + optional: bool.true, nullable: bool.false, + }, + visibility: { + type: types.string, + optional: bool.false, nullable: bool.false, + }, + mentions: { + type: types.array, + optional: bool.true, nullable: bool.false, + items: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id' + } + }, + visibleUserIds: { + type: types.array, + optional: bool.true, nullable: bool.false, + items: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id' + } + }, + fileIds: { + type: types.array, + optional: bool.true, nullable: bool.false, + items: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id' + } + }, + files: { + type: types.array, + optional: bool.true, nullable: bool.false, + items: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile' + } + }, + tags: { + type: types.array, + optional: bool.true, nullable: bool.false, + items: { + type: types.string, + optional: bool.false, nullable: bool.false, + } + }, + poll: { + type: types.object, + optional: bool.true, nullable: bool.true, + }, + geo: { + type: types.object, + optional: bool.true, nullable: bool.true, + }, + }, +}; diff --git a/src/models/repositories/notification.ts b/src/models/repositories/notification.ts index 4781d4c065068536805b94040dbacc6d3d731ffb..cf77b35a087543361de6fa25c78d6e4a72d04740 100644 --- a/src/models/repositories/notification.ts +++ b/src/models/repositories/notification.ts @@ -1,8 +1,11 @@ import { EntityRepository, Repository } from 'typeorm'; import { Users, Notes } from '..'; -import rap from '@prezzemolo/rap'; import { Notification } from '../entities/notification'; import { ensure } from '../../prelude/ensure'; +import { awaitAll } from '../../prelude/await-all'; +import { types, bool, SchemaType } from '../../misc/schema'; + +export type PackedNotification = SchemaType<typeof packedNotificationSchema>; @EntityRepository(Notification) export class NotificationRepository extends Repository<Notification> { @@ -14,12 +17,12 @@ export class NotificationRepository extends Repository<Notification> { public async pack( src: Notification['id'] | Notification, - ) { + ): Promise<PackedNotification> { const notification = typeof src === 'object' ? src : await this.findOne(src).then(ensure); - return await rap({ + return await awaitAll({ id: notification.id, - createdAt: notification.createdAt, + createdAt: notification.createdAt.toISOString(), type: notification.type, userId: notification.notifierId, user: Users.pack(notification.notifier || notification.notifierId), @@ -46,3 +49,39 @@ export class NotificationRepository extends Repository<Notification> { }); } } + +export const packedNotificationSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this notification.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the notification was created.' + }, + type: { + type: types.string, + optional: bool.false, nullable: bool.false, + enum: ['follow', 'receiveFollowRequest', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote'], + description: 'The type of the notification.' + }, + userId: { + type: types.string, + optional: bool.true, nullable: bool.true, + format: 'id', + }, + user: { + type: types.object, + ref: 'User', + optional: bool.true, nullable: bool.true, + }, + } +}; diff --git a/src/models/repositories/user-list.ts b/src/models/repositories/user-list.ts index e591794b8b96756d7485aca030df324790b9cf9b..54231c7f851e803044b675b24c3a29ee5d8cfd17 100644 --- a/src/models/repositories/user-list.ts +++ b/src/models/repositories/user-list.ts @@ -2,12 +2,15 @@ import { EntityRepository, Repository } from 'typeorm'; import { UserList } from '../entities/user-list'; import { ensure } from '../../prelude/ensure'; import { UserListJoinings } from '..'; +import { bool, types, SchemaType } from '../../misc/schema'; + +export type PackedUserList = SchemaType<typeof packedUserListSchema>; @EntityRepository(UserList) export class UserListRepository extends Repository<UserList> { public async pack( src: UserList['id'] | UserList, - ) { + ): Promise<PackedUserList> { const userList = typeof src === 'object' ? src : await this.findOne(src).then(ensure); const users = await UserListJoinings.find({ @@ -16,8 +19,43 @@ export class UserListRepository extends Repository<UserList> { return { id: userList.id, + createdAt: userList.createdAt.toISOString(), name: userList.name, userIds: users.map(x => x.userId) }; } } + +export const packedUserListSchema = { + type: types.object, + optional: bool.false, nullable: bool.false, + properties: { + id: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'id', + description: 'The unique identifier for this UserList.', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: types.string, + optional: bool.false, nullable: bool.false, + format: 'date-time', + description: 'The date that the UserList was created.' + }, + name: { + type: types.string, + optional: bool.false, nullable: bool.false, + description: 'The name of the UserList.' + }, + userIds: { + type: types.array, + nullable: bool.false, optional: bool.true, + items: { + type: types.string, + nullable: bool.false, optional: bool.false, + format: 'id', + } + }, + }, +}; diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts index afba15eb53e728a994d5f00dfcd6bc82138f2161..6b212203f991d7e16cc9f0cdd9165c858707d512 100644 --- a/src/models/repositories/user.ts +++ b/src/models/repositories/user.ts @@ -1,9 +1,12 @@ import { EntityRepository, Repository, In } from 'typeorm'; import { User, ILocalUser, IRemoteUser } from '../entities/user'; import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles } from '..'; -import rap from '@prezzemolo/rap'; import { ensure } from '../../prelude/ensure'; import config from '../../config'; +import { SchemaType, bool, types } from '../../misc/schema'; +import { awaitAll } from '../../prelude/await-all'; + +export type PackedUser = SchemaType<typeof packedUserSchema>; @EntityRepository(User) export class UserRepository extends Repository<User> { @@ -71,7 +74,7 @@ export class UserRepository extends Repository<User> { includeSecrets?: boolean, includeHasUnreadNotes?: boolean } - ): Promise<Record<string, any>> { + ): Promise<PackedUser> { const opts = Object.assign({ detail: false, includeSecrets: false @@ -86,7 +89,7 @@ export class UserRepository extends Repository<User> { const falsy = opts.detail ? false : undefined; - return await rap({ + const packed = { id: user.id, name: user.name, username: user.username, @@ -120,8 +123,8 @@ export class UserRepository extends Repository<User> { ...(opts.detail ? { url: profile!.url, - createdAt: user.createdAt, - updatedAt: user.updatedAt, + createdAt: user.createdAt.toISOString(), + updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, bannerUrl: user.bannerUrl, bannerColor: user.bannerColor, isLocked: user.isLocked, @@ -179,7 +182,9 @@ export class UserRepository extends Repository<User> { isBlocked: relation.isBlocked, isMuted: relation.isMuted, } : {}) - }); + }; + + return await awaitAll(packed); } public isLocalUser(user: User): user is ILocalUser { @@ -216,3 +221,156 @@ export class UserRepository extends Repository<User> { } //#endregion } + +export const packedUserSchema = { + type: types.object, + nullable: bool.false, optional: bool.false, + properties: { + id: { + type: types.string, + nullable: bool.false, optional: bool.false, + format: 'id', + description: 'The unique identifier for this User.', + example: 'xxxxxxxxxx', + }, + username: { + type: types.string, + nullable: bool.false, optional: bool.false, + description: 'The screen name, handle, or alias that this user identifies themselves with.', + example: 'ai' + }, + name: { + type: types.string, + nullable: bool.true, optional: bool.false, + description: 'The name of the user, as they’ve defined it.', + example: 'è—' + }, + url: { + type: types.string, + format: 'url', + nullable: bool.true, optional: bool.true, + }, + avatarUrl: { + type: types.string, + format: 'url', + nullable: bool.true, optional: bool.false, + }, + avatarColor: { + type: types.any, + nullable: bool.true, optional: bool.false, + }, + bannerUrl: { + type: types.string, + format: 'url', + nullable: bool.true, optional: bool.true, + }, + bannerColor: { + type: types.any, + nullable: bool.true, optional: bool.true, + }, + emojis: { + type: types.any, + nullable: bool.true, optional: bool.false, + }, + host: { + type: types.string, + nullable: bool.true, optional: bool.false, + example: 'misskey.example.com' + }, + description: { + type: types.string, + nullable: bool.true, optional: bool.true, + description: 'The user-defined UTF-8 string describing their account.', + example: 'Hi masters, I am Ai!' + }, + birthday: { + type: types.string, + nullable: bool.true, optional: bool.true, + example: '2018-03-12' + }, + createdAt: { + type: types.string, + nullable: bool.false, optional: bool.true, + format: 'date-time', + description: 'The date that the user account was created on Misskey.' + }, + updatedAt: { + type: types.string, + nullable: bool.true, optional: bool.true, + format: 'date-time', + }, + location: { + type: types.string, + nullable: bool.true, optional: bool.true, + }, + followersCount: { + type: types.number, + nullable: bool.false, optional: bool.true, + description: 'The number of followers this account currently has.' + }, + followingCount: { + type: types.number, + nullable: bool.false, optional: bool.true, + description: 'The number of users this account is following.' + }, + notesCount: { + type: types.number, + nullable: bool.false, optional: bool.true, + description: 'The number of Notes (including renotes) issued by the user.' + }, + isBot: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + description: 'Whether this account is a bot.' + }, + pinnedNoteIds: { + type: types.array, + nullable: bool.false, optional: bool.true, + items: { + type: types.string, + nullable: bool.false, optional: bool.false, + format: 'id', + } + }, + pinnedNotes: { + type: types.array, + nullable: bool.false, optional: bool.true, + items: { + type: types.object, + nullable: bool.false, optional: bool.false, + ref: 'Note' + } + }, + isCat: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + description: 'Whether this account is a cat.' + }, + isAdmin: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + description: 'Whether this account is the admin.' + }, + isModerator: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + description: 'Whether this account is a moderator.' + }, + isVerified: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + }, + isLocked: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + }, + hasUnreadSpecifiedNotes: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + }, + hasUnreadMentions: { + type: types.boolean, + nullable: bool.false, optional: bool.true, + }, + }, +}; diff --git a/src/prelude/await-all.ts b/src/prelude/await-all.ts new file mode 100644 index 0000000000000000000000000000000000000000..66303fe3baa55c4e56411fa412615cbf8c21bbd7 --- /dev/null +++ b/src/prelude/await-all.ts @@ -0,0 +1,22 @@ +type Await<T> = T extends Promise<infer U> ? U : T; + +type AwaitAll<T> = { + [P in keyof T]: Await<T[P]>; +}; + +export async function awaitAll<T>(obj: T): Promise<AwaitAll<T>> { + const target = {} as any; + const keys = Object.keys(obj); + const rawValues = Object.values(obj); + const retValues = ((values: any[]): any[] => + values.map(value => { + if (!value || !value.constructor || value.constructor.name !== 'Object') return value; + return awaitAll(value); + }) + )(rawValues); + const values = await Promise.all(retValues); + for (let i = 0; i < values.length; i++) { + target[keys[i]] = values[i]; + } + return target; +} diff --git a/src/server/api/define.ts b/src/server/api/define.ts index 990cbf2a86a9a8a01eff63c6672fe2fec67f68f5..1e2600add0f23b5c3b9043b3af2ad64062081b08 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/app/create.ts b/src/server/api/endpoints/app/create.ts index 9db60d2661ab04c5bf4633fc0be26846c0f5fa0f..833d5060c50293547648ab118c75cb5e57902779 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 ce9baed2aebc33a5dda8cc5ab0b5a9fcbb0037fe..e7d3e84388a6c313162ae6d8c086a85411291959 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 bca8d33483686927a3f29664a0c2f19686abe569..9bf27c8e77c6c1a77045cfde000c4411ce18b193 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 7126ac52c112c928b497b5afab3a7a0a1a0b5e9b..b7a58c475039c1241c42694fae99b24cf67368a2 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 97f353579ddbb0b7bcd2890b823c1b072092a0e8..5ff1dc0c49ec18f52a09d15e2525ed6e3d8ca9f8 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 adf780301bc89e82a5e6b170f2c162bb4c5b19ae..0c820468b76725dca72fbfe9e21d7ac17e5138a6 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 { DriveFiles } from '../../../models'; +import { types, bool } from '../../../misc/schema'; export const meta = { desc: { @@ -15,13 +16,16 @@ 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, } } } diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts index 4e4db6c780bc0c7601bd35d7508c41c61f0a1b97..493e14464caf1f8dac358fae46d8980803cd2105 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 7214463dde1bbd85682d3b3b2bb04c30e5fb4053..6bfc95ce8451af6c5e5a6cfd487898b48ba808e7 100644 --- a/src/server/api/endpoints/drive/files/attached-notes.ts +++ b/src/server/api/endpoints/drive/files/attached-notes.ts @@ -3,6 +3,7 @@ import { ID } from '../../../../../misc/cafy-id'; import define from '../../../define'; import { ApiError } from '../../../error'; import { DriveFiles } 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: { diff --git a/src/server/api/endpoints/drive/files/check-existence.ts b/src/server/api/endpoints/drive/files/check-existence.ts index 3a87a9497fa1d723ef71df06801d6480113c06f7..5c5cf295472e4b74ddd4d344ead0dd228203e2dd 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,13 @@ export const meta = { }, res: { - type: 'DriveFile', + type: types.array, + optional: bool.false, nullable: bool.false, + items: { + type: types.object, + optional: bool.false, nullable: bool.false, + ref: 'DriveFile', + } }, }; diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts index 340a39a41cabc082fa65ba467c6a468f9d4cf4f7..0f81a1da9922dc6c4384bd73cc1f06e4d654f5e2 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.ts b/src/server/api/endpoints/drive/files/find.ts index 265850f84c82f912552c200ee7654d8c80dffd08..82b9a97b6d555a6c0a1725552225c1050fafc372 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 e8c0e683c9daf61e98dfd4572bcba6a6ccbc666c..8e74361f9ce1084659e1a67f4194c5aa649b0372 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 08ae2ff709db826cb0959f4ed43f3e097ba68329..dc3174cd2a09b21a49db77c4f2240b611e99a2d1 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 f0989ec5ae474574233b79f61d643bc6292ad2e3..0368d026c3b5b5c813246c8c1412ac05c6348b48 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 60507e7d7f15aacb9e7806dbae9d11ed2595f70d..a020b46aa93c13990d42f0f2988a8d85f9b31989 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 96d9f82421b9e25c5a5002a73a65cf0da58a9c82..db17979a4ba5400819684322d1434eda1ec33fc6 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/hashtags/list.ts b/src/server/api/endpoints/hashtags/list.ts index 2998bc1a1389810436d735a7d681c3ef83c2ccb6..89cc92642276d1514297104bf342903d91859558 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 802f1779933c4f8d392df1ba45cf3fc2b306e6cc..0d2704d01c04568f35a9fc3a79c785aef1339400 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/users.ts b/src/server/api/endpoints/hashtags/users.ts index fa58f2f2c099c0a9a1b80f304ce441259b7dd187..b842f9de64386a7b268a38359345f7956ab933d0 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 afad38c4694e3d0560ae8a764961002dac026d4a..4ecd507e165f1c74548810e3fc69beb18e5734f9 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 56074c9d00cfc0be8e8ba71a4eeb97ef9b24391f..41513e5daa0f98d4f9d4651cebdda0129958aa24 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/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts index c2d746e481309241e8917763d8fc5da339a2e998..27e38bbdec62a5778efcd0164e3d820c36b5fe6a 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 add21e5f1911ca8ad82571bc58407961bcd75f63..0d5295bff338de695d464e40911a89621a3bf0e2 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 30ac0849a3f9a7f3efb0a7757ebcb79ce49a2d3b..388852b9cd46c4f18e6e72f96f65c8e24ba8a9bd 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 785f21f22bac726f68228cf42fd7032da2af1508..71b950f4ce171abd9470eff9123fe3683ab76515 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -5,6 +5,7 @@ import define from '../define'; 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.', }, } diff --git a/src/server/api/endpoints/mute/list.ts b/src/server/api/endpoints/mute/list.ts index 0fd8a4860d20fdd0751bbacec74364658f5ce9b1..f9ea380c762719d86fa6e5b73b7d84b90d0eb3b5 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 17ba96935088ea217fa69564a970265ef53504c4..7aa19c9a2b024fbe06a5fc70673110807e3af21d 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 2b4ae2a3129c60bb864c5835912dfaa956777384..e8861eafa136c0cd0707615619582bbdbcd75fe5 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 6b26e31c07cf28fcb14fd4ecb41acc6af65fa051..acd3ac75ef1d371dd07848233f3932c0a10ac6e7 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 994dfb4dca3c1cde2891c96f4f37492dda3a459b..9822f56a537eebd85db4d3f6ab8ec8b676647f42 100644 --- a/src/server/api/endpoints/notes/create.ts +++ b/src/server/api/endpoints/notes/create.ts @@ -10,6 +10,7 @@ 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 fa9ae39e3a376ac472e6acb12797998ff9f89874..64750815b0b725a3c591adc1541b84f3acb90d0f 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 ceffb1cf4ac9efaf52b4373f543fe8fa2c95b6c0..e26b9e7da3b9c952043f87e4c204c507a11b5dce 100644 --- a/src/server/api/endpoints/notes/global-timeline.ts +++ b/src/server/api/endpoints/notes/global-timeline.ts @@ -7,6 +7,7 @@ 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: { diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts index effee2b1349ee6fab11535f2a9ad7f3a8a72e5ae..5c27d0c14d1ea7166f56f8ea70921e21d420b0fe 100644 --- a/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -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: { diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts index c10c0d7482c58a8a0aabc44c586f0dc0e6d555c5..ed2a5220e1c79e626235a739aa84b2b45d15d991 100644 --- a/src/server/api/endpoints/notes/local-timeline.ts +++ b/src/server/api/endpoints/notes/local-timeline.ts @@ -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: { diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts index b7f614915b855713373e27c7d534bc7d01e89b3d..02e44492ba3e4cb4d54337828c761cd4fb3e785f 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 bcb0b6d1ec79776937b2b7d1859a1a97bd5b5fd1..0773b4faa27abb034d4941e1cda8801082843976 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 74a8ea918e8bcc6c86edfc89c633d100268ab620..00dfac377095e542ed31e4af5d07021dfbb46e90 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 980ff2446ecb882b2bcaee439667a932a139dd03..5fb0fd989fd0bd48ab27e0a19c5085d0f194254d 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 cba3724b6fc14aa8a10a777bf2c011a12ea85d88..f89539a9b78db281b3bedc63e03b0fb946ce7c7f 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', + } }, }; diff --git a/src/server/api/endpoints/notes/search.ts b/src/server/api/endpoints/notes/search.ts index 4d5ac6fbe03f5db5a4646faf4751cfa885b8a384..daf992b6397d6875858517126983add25431403a 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 d41dc20c5498fe3e0194bf72f311f948bf05a685..54b420813d3fd6c8a7eab1050a346c8b9a53bf9d 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 c27f3df1b7ee4c27da7bf5ed04703394879d4e13..5e692db3893eac9534242864c2b3a2d45436026d 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 05f171af8b17d6d552d24724dc3d9f93c5d8bee1..c16018d434e2717d20a807fa41013496edc2ea7b 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 f3ebaa16ad88cf8874c8cf65ed8727708f3be96e..f85109b4b4c0f5c5efc92ada1e4a17c40c9d3fd1 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/users.ts b/src/server/api/endpoints/users.ts index 18af0a26859c00bfc1d7e6a47156d6689d5e8398..c710706f0c89274c126b2104680c5a22caf3fb1e 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 0cb68353ca349c915d8e05e666d3873adae2b315..465b71e2e6e369517bf235bfe3ac2921a3983fcd 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 2e273dc0c2a84fe9ec548559e892c41f3533af35..2a7748ac64b6177ea6cd3d918dcb093dbda79569 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 a1d140c6c9d6250bb0b60491920eb4d61baa1544..420936c0899881c5cbd09f635b1405d480ba12e1 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 21dc6d331df11fe63a79e12265e5e1571ff899c0..79efffbf9ec31507d57318f7a72c5ebf1d93ad9c 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 b05fc45527f9bcc6fd6183e522c2b0179b2f8830..684086b5c6c7a8e9230652fc0068fc6c68dd74aa 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 1a997ec7c5a52d8c9c27ba40c3c0b9319eb260c2..395f9352d42ebc9f0a7f75142f9917d7683ea3b3 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 4691a9939417baaf3a7e93079136b4f6108cbb4e..fdc50e4dae55b5255fc856b687e23bfd1d8f6fe4 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 9e16e34e3920f71576cebca3a0f5e0d2a2faff47..67b646a35f7a10e8e58d7edeab3f4d6613eed9f7 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 96da221d97384a9521a6d2228e2bc5d4c6b9293f..2809465fd78f62f30c2de24818c873116d992522 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 a401166c5564ca1fd1907dddb503371d93262666..820c44e81ba8179bb3e4532a4868cf5ba471e6c4 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 0a4c8699d18b94c14f75dbde7b5ad6ea1aed393d..9006dfbfa475dce20d645c56e7f9642e90a865c5 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 d194c6c8a8efd8c7830ade501e6e4e8234eb5cd0..de26b970ea7a9e039f304102c0c07fbc5a8a330c 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 65826d9321729187af3b42b857efbddae388d865..e54f989e7484316a1dc0b9cae4d6f174321f4db9 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 f8dba2eb292f19f1a074269946919f8df81466be..57158975356a875c6d359c99ae2ee29edee79767 100644 --- a/src/server/api/private/signup.ts +++ b/src/server/api/private/signup.ts @@ -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/stream/channels/global-timeline.ts b/src/server/api/stream/channels/global-timeline.ts index 3aaadc1a4a81e1aa97e64bcd597ba13aaf19e571..7af6719d29ccc70e83f446539030be162dfee3ea 100644 --- a/src/server/api/stream/channels/global-timeline.ts +++ b/src/server/api/stream/channels/global-timeline.ts @@ -3,6 +3,7 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; 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,7 @@ export default class extends Channel { } @autobind - private async onNote(note: any) { + private async onNote(note: PackedNote) { if (note.visibility !== 'public') return; // リプライãªã‚‰å†pack diff --git a/src/server/api/stream/channels/hashtag.ts b/src/server/api/stream/channels/hashtag.ts index 36c56c7ab6bee77071d270dbd48774a8abb7aecc..e55a5083282e3002c4a280f280594f1b7ec22ca1 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 61960657b42fc3b3900629228031504be19b68b2..9aa4dc1c0f72881d12e814dbd8ef484c238ad714 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 a8020bfcfa10ef09d9883414125ed7a8d6af4065..a1e5bf238eddef7428fcb2873afad327cf37c084 100644 --- a/src/server/api/stream/channels/hybrid-timeline.ts +++ b/src/server/api/stream/channels/hybrid-timeline.ts @@ -3,6 +3,8 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; 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 4aec2d66b4028cab2234e127a792ef967ec54578..82b957afa4a2a63943d1d93007ea5241b73ae0b2 100644 --- a/src/server/api/stream/channels/local-timeline.ts +++ b/src/server/api/stream/channels/local-timeline.ts @@ -3,6 +3,8 @@ import shouldMuteThisNote from '../../../../misc/should-mute-this-note'; import Channel from '../channel'; 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 f5434b8f0862485f239c7d2f72e4b9c56df04334..119bacf6ece61f22a954977bf820090547c48b12 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)) { diff --git a/src/services/chart/charts/schemas/active-users.ts b/src/services/chart/charts/schemas/active-users.ts index da8c63389c80c6d3ea602197a9bfc567ee062724..f10393bc36db5ce3cc42a2de36f958b7c46adce7 100644 --- a/src/services/chart/charts/schemas/active-users.ts +++ b/src/services/chart/charts/schemas/active-users.ts @@ -1,9 +1,12 @@ +import { types, bool } from '../../../../misc/schema'; + export const logSchema = { /** * アクティブユーザー数 */ count: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'アクティブユーザー数', }, }; @@ -12,14 +15,17 @@ export const logSchema = { * アクティブユーザーã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { local: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, remote: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, } diff --git a/src/services/chart/charts/schemas/drive.ts b/src/services/chart/charts/schemas/drive.ts index 47530e841761037967a62fd00c904fd8852b7215..3327950635ded57fb641daac85fd1d8bde6f2918 100644 --- a/src/services/chart/charts/schemas/drive.ts +++ b/src/services/chart/charts/schemas/drive.ts @@ -1,9 +1,12 @@ +import { types, bool } from '../../../../misc/schema'; + const logSchema = { /** * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 */ totalCount: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, @@ -11,7 +14,8 @@ const logSchema = { * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイルã®åˆè¨ˆã‚µã‚¤ã‚º */ totalSize: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイルã®åˆè¨ˆã‚µã‚¤ã‚º' }, @@ -19,7 +23,8 @@ const logSchema = { * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 */ incCount: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, @@ -27,7 +32,8 @@ const logSchema = { * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ */ incSize: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–使用é‡' }, @@ -35,7 +41,8 @@ const logSchema = { * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 */ decCount: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, @@ -43,20 +50,24 @@ const logSchema = { * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ */ decSize: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–使用é‡' }, }; export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { local: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, remote: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, } diff --git a/src/services/chart/charts/schemas/federation.ts b/src/services/chart/charts/schemas/federation.ts index d1d275fc95f5f56450d847260007c6e8c6bd610b..41ae977cbd200a0408981541a3fa7999bacea0a4 100644 --- a/src/services/chart/charts/schemas/federation.ts +++ b/src/services/chart/charts/schemas/federation.ts @@ -1,22 +1,29 @@ +import { types, bool } from '../../../../misc/schema'; + /** * フェデレーションã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { instance: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'インスタンス数ã®åˆè¨ˆ' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹æ•°' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少インスタンス数' }, } diff --git a/src/services/chart/charts/schemas/hashtag.ts b/src/services/chart/charts/schemas/hashtag.ts index c1904b67012367dddd73d59ebef158c268b9a21b..918242f66e3cb670345265e8fbc65f318e6514d6 100644 --- a/src/services/chart/charts/schemas/hashtag.ts +++ b/src/services/chart/charts/schemas/hashtag.ts @@ -1,9 +1,12 @@ +import { types, bool } from '../../../../misc/schema'; + export const logSchema = { /** * 投稿ã•ã‚ŒãŸæ•° */ count: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '投稿ã•ã‚ŒãŸæ•°', }, }; @@ -12,14 +15,17 @@ export const logSchema = { * ãƒãƒƒã‚·ãƒ¥ã‚¿ã‚°ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { local: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, remote: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, } diff --git a/src/services/chart/charts/schemas/instance.ts b/src/services/chart/charts/schemas/instance.ts index 001f2428b58a4398312795418e156bcbb19dae53..d97f49ea7226a5ef5f36c2dd6db6dea3fd8f371e 100644 --- a/src/services/chart/charts/schemas/instance.ts +++ b/src/services/chart/charts/schemas/instance.ts @@ -1,58 +1,73 @@ +import { types, bool } from '../../../../misc/schema'; + /** * インスタンスã”ã¨ã®ãƒãƒ£ãƒ¼ãƒˆ */ export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { requests: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { failed: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '失敗ã—ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆæ•°' }, succeeded: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'æˆåŠŸã—ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆæ•°' }, received: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å—ä¿¡ã—ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆæ•°' }, } }, notes: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨æŠ•ç¨¿æ•°' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸæŠ•ç¨¿æ•°' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸæŠ•ç¨¿æ•°' }, diffs: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { normal: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '通常ã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, reply: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'リプライã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, renote: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'Renoteã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, } @@ -61,84 +76,103 @@ export const schema = { }, users: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ¦ãƒ¼ã‚¶ãƒ¼æ•°' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•°' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•°' }, } }, following: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ•ã‚©ãƒãƒ¼æ•°' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ•ã‚©ãƒãƒ¼æ•°' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ•ã‚©ãƒãƒ¼æ•°' }, } }, followers: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ•ã‚©ãƒãƒ¯ãƒ¼æ•°' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ•ã‚©ãƒãƒ¯ãƒ¼æ•°' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ•ã‚©ãƒãƒ¯ãƒ¼æ•°' }, } }, drive: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { totalFiles: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, totalUsage: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイルã®åˆè¨ˆã‚µã‚¤ã‚º' }, incFiles: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, incUsage: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–使用é‡' }, decFiles: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, decUsage: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–使用é‡' }, } diff --git a/src/services/chart/charts/schemas/network.ts b/src/services/chart/charts/schemas/network.ts index 4ef530c07cc0ca2f2b0ca426af59f4751afae902..819e2a145e783d0701c6ca5163eb9f64643a5ba3 100644 --- a/src/services/chart/charts/schemas/network.ts +++ b/src/services/chart/charts/schemas/network.ts @@ -1,27 +1,35 @@ +import { types, bool } from '../../../../misc/schema'; + /** * ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { incomingRequests: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å—ä¿¡ã—ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆæ•°' }, outgoingRequests: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'é€ä¿¡ã—ãŸãƒªã‚¯ã‚¨ã‚¹ãƒˆæ•°' }, totalTime: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¿œç”時間ã®åˆè¨ˆ' // TIP: (totalTime / incomingRequests) ã§ã²ã¨ã¤ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¹³å‡ã§ã©ã‚Œãらã„ã®æ™‚é–“ãŒã‹ã‹ã£ãŸã‹çŸ¥ã‚Œã‚‹ }, incomingBytes: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'åˆè¨ˆå—信データé‡' }, outgoingBytes: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'åˆè¨ˆé€ä¿¡ãƒ‡ãƒ¼ã‚¿é‡' }, } diff --git a/src/services/chart/charts/schemas/notes.ts b/src/services/chart/charts/schemas/notes.ts index 133d1e3730a22c5ab086b8a309b024a595e0b527..aabe49edd91f660b122433ef457f17a4efc528f4 100644 --- a/src/services/chart/charts/schemas/notes.ts +++ b/src/services/chart/charts/schemas/notes.ts @@ -1,34 +1,43 @@ +import { types, bool } from '../../../../misc/schema'; + const logSchema = { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨æŠ•ç¨¿æ•°' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸæŠ•ç¨¿æ•°' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸæŠ•ç¨¿æ•°' }, diffs: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { normal: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '通常ã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, reply: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'リプライã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, renote: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'Renoteã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, } @@ -36,14 +45,17 @@ const logSchema = { }; export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { local: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, remote: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, } diff --git a/src/services/chart/charts/schemas/per-user-drive.ts b/src/services/chart/charts/schemas/per-user-drive.ts index 713bd7ed845e68ee2d5226c7193f6577d98006e4..62e77951677bae7fe246b2088fdf2ef5d9fb4fce 100644 --- a/src/services/chart/charts/schemas/per-user-drive.ts +++ b/src/services/chart/charts/schemas/per-user-drive.ts @@ -1,11 +1,15 @@ +import { types, bool } from '../../../../misc/schema'; + export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { /** * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 */ totalCount: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, @@ -13,7 +17,8 @@ export const schema = { * 集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイルã®åˆè¨ˆã‚µã‚¤ã‚º */ totalSize: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ‰ãƒ©ã‚¤ãƒ–ファイルã®åˆè¨ˆã‚µã‚¤ã‚º' }, @@ -21,7 +26,8 @@ export const schema = { * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 */ incCount: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, @@ -29,7 +35,8 @@ export const schema = { * å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ */ incSize: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–使用é‡' }, @@ -37,7 +44,8 @@ export const schema = { * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数 */ decCount: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ファイル数' }, @@ -45,7 +53,8 @@ export const schema = { * 減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–ä½¿ç”¨é‡ */ decSize: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ‰ãƒ©ã‚¤ãƒ–使用é‡' }, } diff --git a/src/services/chart/charts/schemas/per-user-following.ts b/src/services/chart/charts/schemas/per-user-following.ts index d6ca1130e0f1f2a8d1239d995c72d06c18bfa74e..e57869e79a99346ec0c9badaf846b2c5efe7ee1f 100644 --- a/src/services/chart/charts/schemas/per-user-following.ts +++ b/src/services/chart/charts/schemas/per-user-following.ts @@ -1,15 +1,19 @@ +import { types, bool } from '../../../../misc/schema'; + export const logSchema = { /** * フォãƒãƒ¼ã—ã¦ã„ã‚‹ */ followings: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { /** * フォãƒãƒ¼ã—ã¦ã„ã‚‹åˆè¨ˆ */ total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'フォãƒãƒ¼ã—ã¦ã„ã‚‹åˆè¨ˆ', }, @@ -17,7 +21,8 @@ export const logSchema = { * フォãƒãƒ¼ã—ãŸæ•° */ inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'フォãƒãƒ¼ã—ãŸæ•°', }, @@ -25,7 +30,8 @@ export const logSchema = { * フォãƒãƒ¼è§£é™¤ã—ãŸæ•° */ dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'フォãƒãƒ¼è§£é™¤ã—ãŸæ•°', }, } @@ -35,13 +41,15 @@ export const logSchema = { * フォãƒãƒ¼ã•ã‚Œã¦ã„ã‚‹ */ followers: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { /** * フォãƒãƒ¼ã•ã‚Œã¦ã„ã‚‹åˆè¨ˆ */ total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'フォãƒãƒ¼ã•ã‚Œã¦ã„ã‚‹åˆè¨ˆ', }, @@ -49,7 +57,8 @@ export const logSchema = { * フォãƒãƒ¼ã•ã‚ŒãŸæ•° */ inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'フォãƒãƒ¼ã•ã‚ŒãŸæ•°', }, @@ -57,7 +66,8 @@ export const logSchema = { * フォãƒãƒ¼è§£é™¤ã•ã‚ŒãŸæ•° */ dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'フォãƒãƒ¼è§£é™¤ã•ã‚ŒãŸæ•°', }, } @@ -65,14 +75,17 @@ export const logSchema = { }; export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { local: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, remote: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, } diff --git a/src/services/chart/charts/schemas/per-user-notes.ts b/src/services/chart/charts/schemas/per-user-notes.ts index 3c448c4cee2464c83706320dcdc7e533b62e8736..76324500739fde3b631b79bdb549cea9df081f34 100644 --- a/src/services/chart/charts/schemas/per-user-notes.ts +++ b/src/services/chart/charts/schemas/per-user-notes.ts @@ -1,36 +1,46 @@ +import { types, bool } from '../../../../misc/schema'; + export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨æŠ•ç¨¿æ•°' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸæŠ•ç¨¿æ•°' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸæŠ•ç¨¿æ•°' }, diffs: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { normal: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '通常ã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, reply: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'リプライã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, renote: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'Renoteã®æŠ•ç¨¿æ•°ã®å·®åˆ†' }, } diff --git a/src/services/chart/charts/schemas/per-user-reactions.ts b/src/services/chart/charts/schemas/per-user-reactions.ts index 1278184da65837f810ceb9a0cf122690d1d5d355..df7d5a6dbb11cc8ad701c270831aa666b90c3702 100644 --- a/src/services/chart/charts/schemas/per-user-reactions.ts +++ b/src/services/chart/charts/schemas/per-user-reactions.ts @@ -1,9 +1,12 @@ +import { types, bool } from '../../../../misc/schema'; + export const logSchema = { /** * フォãƒãƒ¼ã—ã¦ã„ã‚‹åˆè¨ˆ */ count: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'リアクションã•ã‚ŒãŸæ•°', }, }; @@ -12,14 +15,17 @@ export const logSchema = { * ユーザーã”ã¨ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã«é–¢ã™ã‚‹ãƒãƒ£ãƒ¼ãƒˆ */ export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { local: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, remote: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, } diff --git a/src/services/chart/charts/schemas/test-grouped.ts b/src/services/chart/charts/schemas/test-grouped.ts index acf3fddb3157dbe34cece0a149bf3e92ad736e97..893458e90a17be3bebaca451381c9a4132b67762 100644 --- a/src/services/chart/charts/schemas/test-grouped.ts +++ b/src/services/chart/charts/schemas/test-grouped.ts @@ -1,21 +1,28 @@ +import { types, bool } from '../../../../misc/schema'; + export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { foo: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '' }, } diff --git a/src/services/chart/charts/schemas/test-unique.ts b/src/services/chart/charts/schemas/test-unique.ts index 8fcfbf3c72342013e599c06ecf33a3098c898684..2b3f445ff02edcb8c4093285f0717ba48e787bf8 100644 --- a/src/services/chart/charts/schemas/test-unique.ts +++ b/src/services/chart/charts/schemas/test-unique.ts @@ -1,8 +1,12 @@ +import { types, bool } from '../../../../misc/schema'; + export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { foo: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '' }, } diff --git a/src/services/chart/charts/schemas/test.ts b/src/services/chart/charts/schemas/test.ts index b1344500bfb3140c6bb4362c589161ee6af3ff59..9bdc05990b6a29097278d3fdad1878afe262f52a 100644 --- a/src/services/chart/charts/schemas/test.ts +++ b/src/services/chart/charts/schemas/test.ts @@ -1,21 +1,28 @@ +import { types, bool } from '../../../../misc/schema'; + export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { foo: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '' }, inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '' }, dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '' }, } diff --git a/src/services/chart/charts/schemas/users.ts b/src/services/chart/charts/schemas/users.ts index db7e2dd057b1e02aa432f6881e2c7db83b53620d..6ae61333503db198e99b9121d4715a7f453f43d4 100644 --- a/src/services/chart/charts/schemas/users.ts +++ b/src/services/chart/charts/schemas/users.ts @@ -1,9 +1,12 @@ +import { types, bool } from '../../../../misc/schema'; + const logSchema = { /** * 集計期間時点ã§ã®ã€å…¨ãƒ¦ãƒ¼ã‚¶ãƒ¼æ•° */ total: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '集計期間時点ã§ã®ã€å…¨ãƒ¦ãƒ¼ã‚¶ãƒ¼æ•°' }, @@ -11,7 +14,8 @@ const logSchema = { * å¢—åŠ ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•° */ inc: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: 'å¢—åŠ ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•°' }, @@ -19,20 +23,24 @@ const logSchema = { * 減少ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•° */ dec: { - type: 'number' as 'number', + type: types.number, + optional: bool.false, nullable: bool.false, description: '減少ã—ãŸãƒ¦ãƒ¼ã‚¶ãƒ¼æ•°' }, }; export const schema = { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: { local: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, remote: { - type: 'object' as 'object', + type: types.object, + optional: bool.false, nullable: bool.false, properties: logSchema }, } diff --git a/src/services/chart/core.ts b/src/services/chart/core.ts index fe762f2b2452afc6b88a235f78a2d9639a50628f..6a69a21b7ed1f9fd6c0b0343afa3e609dac9a0e4 100644 --- a/src/services/chart/core.ts +++ b/src/services/chart/core.ts @@ -8,7 +8,7 @@ import * as moment from 'moment'; import * as nestedProperty from 'nested-property'; import autobind from 'autobind-decorator'; import Logger from '../logger'; -import { Schema } from '../../misc/schema'; +import { Schema, bool, types } from '../../misc/schema'; import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual } from 'typeorm'; import { isDuplicateKeyValueError } from '../../misc/is-duplicate-key-value-error'; @@ -449,7 +449,8 @@ export function convertLog(logSchema: Schema): Schema { if (v.type === 'number') { v.type = 'array'; v.items = { - type: 'number' + type: types.number, + optional: bool.false, nullable: bool.false, }; } else if (v.type === 'object') { for (const k of Object.keys(v.properties!)) { diff --git a/src/services/note/create.ts b/src/services/note/create.ts index 02e33d6789f999570824f7f27f643c3a5186a3d4..ce229d639379e820ec7398a98fcf33091f0bdcea 100644 --- a/src/services/note/create.ts +++ b/src/services/note/create.ts @@ -237,7 +237,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N const noteObj = await Notes.pack(note); if (isFirstNote) { - noteObj.isFirstNote = true; + (noteObj as any).isFirstNote = true; } publishNotesStream(noteObj); diff --git a/test/streaming.ts b/test/streaming.ts index 6b9ef9cea5bac18f47ecd7e0694b9b16c7661677..11c63cd0f59a99537f048644af1a43d0c82111cd 100644 --- a/test/streaming.ts +++ b/test/streaming.ts @@ -628,7 +628,7 @@ describe('Streaming', () => { // ãƒªã‚¹ãƒˆä½œæˆ const list = await request('/users/lists/create', { - title: 'my list' + name: 'my list' }, alice).then(x => x.body); // Alice ㌠Bob をリスイン @@ -658,7 +658,7 @@ describe('Streaming', () => { // ãƒªã‚¹ãƒˆä½œæˆ const list = await request('/users/lists/create', { - title: 'my list' + name: 'my list' }, alice).then(x => x.body); let fired = false; @@ -689,7 +689,7 @@ describe('Streaming', () => { // ãƒªã‚¹ãƒˆä½œæˆ const list = await request('/users/lists/create', { - title: 'my list' + name: 'my list' }, alice).then(x => x.body); // Alice ㌠Bob をリスイン @@ -724,7 +724,7 @@ describe('Streaming', () => { // ãƒªã‚¹ãƒˆä½œæˆ const list = await request('/users/lists/create', { - title: 'my list' + name: 'my list' }, alice).then(x => x.body); // Alice ㌠Bob をリスイン