Refactor API (#4770)
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update description.ts * wip
This commit is contained in:
		
							parent
							
								
									f31f986d66
								
							
						
					
					
						commit
						0463c6bb0f
					
				
					 105 changed files with 1622 additions and 808 deletions
				
			
		|  | @ -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", | ||||
|  |  | |||
|  | @ -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 | ||||
| 				}); | ||||
| 			}); | ||||
| 		}, | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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]; | ||||
| 
 | ||||
| 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']>> : | ||||
| 	any; | ||||
| 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 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; | ||||
| } | ||||
| export type SchemaType<p extends Schema> = | ||||
| 	p['type'] extends 'number' ? NullOrUndefined<p, number> : | ||||
| 	p['type'] extends 'string' ? NullOrUndefined<p, string> : | ||||
| 	p['type'] extends 'boolean' ? NullOrUndefined<p, boolean> : | ||||
| 	p['type'] extends 'array' ? NullOrUndefined<p, MyType<NonNullable<p['items']>>[]> : | ||||
| 	p['type'] extends 'object' ? NullOrUndefined<p, ObjType<NonNullable<p['properties']>>> : | ||||
| 	p['type'] extends 'any' ? NullOrUndefined<p, any> : | ||||
| 	any; | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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: 'アプリケーションのシークレットキー' | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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.' | ||||
| 		}, | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -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.', | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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' | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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.' | ||||
| 		}, | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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.' | ||||
| 		}, | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -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.' | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
| 		}, | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -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', | ||||
| 			} | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										22
									
								
								src/prelude/await-all.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/prelude/await-all.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -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; | ||||
| } | ||||
|  | @ -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, () => {}); | ||||
|  |  | |||
|  | @ -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) => { | ||||
|  |  | |||
|  | @ -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.', | ||||
|  |  | |||
|  | @ -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' | ||||
| 			}, | ||||
| 		} | ||||
|  |  | |||
|  | @ -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: '認証したユーザー' | ||||
| 			}, | ||||
| 		} | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -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) => { | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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) => { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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.', | ||||
| 			}, | ||||
| 		} | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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: '作成した投稿' | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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 | ||||
| 	}; | ||||
| }); | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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', | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
|  |  | |||
|  | @ -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: { | ||||
|  |  | |||
|  | @ -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} | ||||
|  |  | |||
|  | @ -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'}*`; | ||||
|  |  | |||
|  | @ -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', | ||||
|  |  | |||
|  | @ -135,7 +135,7 @@ export default async (ctx: Koa.BaseContext) => { | |||
| 		includeSecrets: true | ||||
| 	}); | ||||
| 
 | ||||
| 	res.token = secret; | ||||
| 	(res as any).token = secret; | ||||
| 
 | ||||
| 	ctx.body = res; | ||||
| }; | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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)) { | ||||
|  |  | |||
|  | @ -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)) { | ||||
|  |  | |||
|  | @ -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)) { | ||||
|  |  | |||
|  | @ -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 | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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 | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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: '減少インスタンス数' | ||||
| 				}, | ||||
| 			} | ||||
|  |  | |||
|  | @ -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 | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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: '減少したドライブ使用量' | ||||
| 				}, | ||||
| 			} | ||||
|  |  | |||
|  | @ -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: '合計送信データ量' | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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 | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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: '減少したドライブ使用量' | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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 | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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の投稿数の差分' | ||||
| 				}, | ||||
| 			} | ||||
|  |  | |||
|  | @ -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 | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
|  | @ -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: '' | ||||
| 				}, | ||||
| 			} | ||||
|  |  | |||
|  | @ -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: '' | ||||
| 		}, | ||||
| 	} | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue