refactor: Expand schema (#7772)
* packedNotificationSchemaを更新 * read:gallery, write:gallery, read:gallery-likes, write:gallery-likesに翻訳を追加 * fix * add header, choice, invitation * test * fix * yatta * remove no longer needed "as PackedUser/PackedNote" * clean up * add simple-schema * fix lint * define items in full Schema * revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736 * user packとnote packの型不整合を修正
This commit is contained in:
		
							parent
							
								
									f59f424795
								
							
						
					
					
						commit
						53f3b779bf
					
				
					 24 changed files with 148 additions and 129 deletions
				
			
		|  | @ -1,15 +1,57 @@ | ||||||
| export type Schema = { | import { SimpleObj, SimpleSchema } from './simple-schema'; | ||||||
| 	type: 'boolean' | 'number' | 'string' | 'array' | 'object' | 'any'; | import { packedUserSchema } from '@/models/repositories/user'; | ||||||
| 	nullable: boolean; | import { packedNoteSchema } from '@/models/repositories/note'; | ||||||
| 	optional: boolean; | import { packedUserListSchema } from '@/models/repositories/user-list'; | ||||||
|  | import { packedAppSchema } from '@/models/repositories/app'; | ||||||
|  | import { packedMessagingMessageSchema } from '@/models/repositories/messaging-message'; | ||||||
|  | import { packedNotificationSchema } from '@/models/repositories/notification'; | ||||||
|  | import { packedDriveFileSchema } from '@/models/repositories/drive-file'; | ||||||
|  | import { packedDriveFolderSchema } from '@/models/repositories/drive-folder'; | ||||||
|  | import { packedFollowingSchema } from '@/models/repositories/following'; | ||||||
|  | import { packedMutingSchema } from '@/models/repositories/muting'; | ||||||
|  | import { packedBlockingSchema } from '@/models/repositories/blocking'; | ||||||
|  | import { packedNoteReactionSchema } from '@/models/repositories/note-reaction'; | ||||||
|  | import { packedHashtagSchema } from '@/models/repositories/hashtag'; | ||||||
|  | import { packedPageSchema } from '@/models/repositories/page'; | ||||||
|  | import { packedUserGroupSchema } from '@/models/repositories/user-group'; | ||||||
|  | import { packedNoteFavoriteSchema } from '@/models/repositories/note-favorite'; | ||||||
|  | import { packedChannelSchema } from '@/models/repositories/channel'; | ||||||
|  | import { packedAntennaSchema } from '@/models/repositories/antenna'; | ||||||
|  | import { packedClipSchema } from '@/models/repositories/clip'; | ||||||
|  | import { packedFederationInstanceSchema } from '@/models/repositories/federation-instance'; | ||||||
|  | import { packedQueueCountSchema } from '@/models/repositories/queue'; | ||||||
|  | import { packedGalleryPostSchema } from '@/models/repositories/gallery-post'; | ||||||
|  | 
 | ||||||
|  | export const refs = { | ||||||
|  | 	User: packedUserSchema, | ||||||
|  | 	UserList: packedUserListSchema, | ||||||
|  | 	UserGroup: packedUserGroupSchema, | ||||||
|  | 	App: packedAppSchema, | ||||||
|  | 	MessagingMessage: packedMessagingMessageSchema, | ||||||
|  | 	Note: packedNoteSchema, | ||||||
|  | 	NoteReaction: packedNoteReactionSchema, | ||||||
|  | 	NoteFavorite: packedNoteFavoriteSchema, | ||||||
|  | 	Notification: packedNotificationSchema, | ||||||
|  | 	DriveFile: packedDriveFileSchema, | ||||||
|  | 	DriveFolder: packedDriveFolderSchema, | ||||||
|  | 	Following: packedFollowingSchema, | ||||||
|  | 	Muting: packedMutingSchema, | ||||||
|  | 	Blocking: packedBlockingSchema, | ||||||
|  | 	Hashtag: packedHashtagSchema, | ||||||
|  | 	Page: packedPageSchema, | ||||||
|  | 	Channel: packedChannelSchema, | ||||||
|  | 	QueueCount: packedQueueCountSchema, | ||||||
|  | 	Antenna: packedAntennaSchema, | ||||||
|  | 	Clip: packedClipSchema, | ||||||
|  | 	FederationInstance: packedFederationInstanceSchema, | ||||||
|  | 	GalleryPost: packedGalleryPostSchema, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export interface Schema extends SimpleSchema { | ||||||
| 	items?: Schema; | 	items?: Schema; | ||||||
| 	properties?: Obj; | 	properties?: Obj; | ||||||
| 	description?: string; | 	ref?: keyof typeof refs; | ||||||
| 	example?: any; | } | ||||||
| 	format?: string; |  | ||||||
| 	ref?: string; |  | ||||||
| 	enum?: string[]; |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| type NonUndefinedPropertyNames<T extends Obj> = { | type NonUndefinedPropertyNames<T extends Obj> = { | ||||||
| 	[K in keyof T]: T[K]['optional'] extends true ? never : K | 	[K in keyof T]: T[K]['optional'] extends true ? never : K | ||||||
|  | @ -22,7 +64,7 @@ type UndefinedPropertyNames<T extends Obj> = { | ||||||
| type OnlyRequired<T extends Obj> = Pick<T, NonUndefinedPropertyNames<T>>; | type OnlyRequired<T extends Obj> = Pick<T, NonUndefinedPropertyNames<T>>; | ||||||
| type OnlyOptional<T extends Obj> = Pick<T, UndefinedPropertyNames<T>>; | type OnlyOptional<T extends Obj> = Pick<T, UndefinedPropertyNames<T>>; | ||||||
| 
 | 
 | ||||||
| export type Obj = { [key: string]: Schema }; | export interface Obj extends SimpleObj { [key: string]: Schema; } | ||||||
| 
 | 
 | ||||||
| export type ObjType<s extends Obj> = | export type ObjType<s extends Obj> = | ||||||
| 	{ [P in keyof OnlyOptional<s>]?: SchemaType<s[P]> } & | 	{ [P in keyof OnlyOptional<s>]?: SchemaType<s[P]> } & | ||||||
|  | @ -48,6 +90,10 @@ export type SchemaType<p extends Schema> = | ||||||
| 	p['type'] extends 'string' ? NullOrUndefined<p, string> : | 	p['type'] extends 'string' ? NullOrUndefined<p, string> : | ||||||
| 	p['type'] extends 'boolean' ? NullOrUndefined<p, boolean> : | 	p['type'] extends 'boolean' ? NullOrUndefined<p, boolean> : | ||||||
| 	p['type'] extends 'array' ? NullOrUndefined<p, MyType<NonNullable<p['items']>>[]> : | 	p['type'] extends 'array' ? NullOrUndefined<p, MyType<NonNullable<p['items']>>[]> : | ||||||
| 	p['type'] extends 'object' ? NullOrUndefined<p, ObjType<NonNullable<p['properties']>>> : | 	p['type'] extends 'object' ? ( | ||||||
|  | 		p['ref'] extends keyof typeof refs | ||||||
|  | 			? NullOrUndefined<p, SchemaType<typeof refs[p['ref']]>> | ||||||
|  | 			: NullOrUndefined<p, ObjType<NonNullable<p['properties']>>> | ||||||
|  | 	) : | ||||||
| 	p['type'] extends 'any' ? NullOrUndefined<p, any> : | 	p['type'] extends 'any' ? NullOrUndefined<p, any> : | ||||||
| 	any; | 	any; | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								src/misc/simple-schema.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/misc/simple-schema.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | export interface SimpleSchema { | ||||||
|  | 	type: 'boolean' | 'number' | 'string' | 'array' | 'object' | 'any'; | ||||||
|  | 	nullable: boolean; | ||||||
|  | 	optional: boolean; | ||||||
|  | 	items?: SimpleSchema; | ||||||
|  | 	properties?: SimpleObj; | ||||||
|  | 	description?: string; | ||||||
|  | 	example?: any; | ||||||
|  | 	format?: string; | ||||||
|  | 	ref?: string; | ||||||
|  | 	enum?: string[]; | ||||||
|  | 	default?: boolean | null; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface SimpleObj { [key: string]: SimpleSchema; } | ||||||
|  | @ -56,7 +56,7 @@ export const packedBlockingSchema = { | ||||||
| 		blockee: { | 		blockee: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -53,7 +53,7 @@ export const packedClipSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 		name: { | 		name: { | ||||||
|  |  | ||||||
|  | @ -234,7 +234,7 @@ export const packedDriveFileSchema = { | ||||||
| 		folder: { | 		folder: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'DriveFolder' | 			ref: 'DriveFolder' as const, | ||||||
| 		}, | 		}, | ||||||
| 		userId: { | 		userId: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
|  | @ -245,7 +245,7 @@ export const packedDriveFileSchema = { | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'User' | 			ref: 'User' as const, | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -87,7 +87,7 @@ export const packedDriveFolderSchema = { | ||||||
| 		parent: { | 		parent: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'DriveFolder' | 			ref: 'DriveFolder' as const, | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -110,7 +110,7 @@ export const packedFollowingSchema = { | ||||||
| 		followee: { | 		followee: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: false as const, | 			optional: true as const, nullable: false as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 		}, | 		}, | ||||||
| 		followerId: { | 		followerId: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
|  | @ -120,7 +120,7 @@ export const packedFollowingSchema = { | ||||||
| 		follower: { | 		follower: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: false as const, | 			optional: true as const, nullable: false as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { EntityRepository, Repository } from 'typeorm'; | import { EntityRepository, Repository } from 'typeorm'; | ||||||
| import { GalleryPost } from '@/models/entities/gallery-post'; | import { GalleryPost } from '@/models/entities/gallery-post'; | ||||||
| import { SchemaType } from '../../misc/schema'; | import { SchemaType } from '@/misc/schema'; | ||||||
| import { Users, DriveFiles, GalleryLikes } from '../index'; | import { Users, DriveFiles, GalleryLikes } from '../index'; | ||||||
| import { awaitAll } from '@/prelude/await-all'; | import { awaitAll } from '@/prelude/await-all'; | ||||||
| import { User } from '@/models/entities/user'; | import { User } from '@/models/entities/user'; | ||||||
|  | @ -76,7 +76,7 @@ export const packedGalleryPostSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 		fileIds: { | 		fileIds: { | ||||||
|  | @ -94,7 +94,7 @@ export const packedGalleryPostSchema = { | ||||||
| 			items: { | 			items: { | ||||||
| 				type: 'object' as const, | 				type: 'object' as const, | ||||||
| 				optional: false as const, nullable: false as const, | 				optional: false as const, nullable: false as const, | ||||||
| 				ref: 'DriveFile' | 				ref: 'DriveFile' as const, | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 		tags: { | 		tags: { | ||||||
|  |  | ||||||
|  | @ -67,7 +67,7 @@ export const packedMessagingMessageSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 			optional: true as const, nullable: false as const, | 			optional: true as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 		text: { | 		text: { | ||||||
|  | @ -82,7 +82,7 @@ export const packedMessagingMessageSchema = { | ||||||
| 		file: { | 		file: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'DriveFile', | 			ref: 'DriveFile' as const, | ||||||
| 		}, | 		}, | ||||||
| 		recipientId: { | 		recipientId: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
|  | @ -92,7 +92,7 @@ export const packedMessagingMessageSchema = { | ||||||
| 		recipient: { | 		recipient: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'User' | 			ref: 'User' as const, | ||||||
| 		}, | 		}, | ||||||
| 		groupId: { | 		groupId: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
|  | @ -102,7 +102,7 @@ export const packedMessagingMessageSchema = { | ||||||
| 		group: { | 		group: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'UserGroup' | 			ref: 'UserGroup' as const, | ||||||
| 		}, | 		}, | ||||||
| 		isRead: { | 		isRead: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
|  |  | ||||||
|  | @ -56,7 +56,7 @@ export const packedMutingSchema = { | ||||||
| 		mutee: { | 		mutee: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -45,7 +45,7 @@ export const packedNoteFavoriteSchema = { | ||||||
| 		note: { | 		note: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 			ref: 'Note', | 			ref: 'Note' as const, | ||||||
| 		}, | 		}, | ||||||
| 		noteId: { | 		noteId: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ export const packedNoteReactionSchema = { | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 		}, | 		}, | ||||||
| 		type: { | 		type: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
|  |  | ||||||
|  | @ -95,7 +95,7 @@ export class NoteRepository extends Repository<Note> { | ||||||
| 				hide = true; | 				hide = true; | ||||||
| 			} else if (meId === packedNote.userId) { | 			} else if (meId === packedNote.userId) { | ||||||
| 				hide = false; | 				hide = false; | ||||||
| 			} else if (packedNote.reply && (meId === (packedNote.reply as PackedNote).userId)) { | 			} else if (packedNote.reply && (meId === packedNote.reply.userId)) { | ||||||
| 				// 自分の投稿に対するリプライ
 | 				// 自分の投稿に対するリプライ
 | ||||||
| 				hide = false; | 				hide = false; | ||||||
| 			} else if (packedNote.mentions && packedNote.mentions.some(id => meId === id)) { | 			} else if (packedNote.mentions && packedNote.mentions.some(id => meId === id)) { | ||||||
|  | @ -353,7 +353,7 @@ export const packedNoteSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 		replyId: { | 		replyId: { | ||||||
|  | @ -371,12 +371,12 @@ export const packedNoteSchema = { | ||||||
| 		reply: { | 		reply: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'Note' | 			ref: 'Note' as const, | ||||||
| 		}, | 		}, | ||||||
| 		renote: { | 		renote: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'Note' | 			ref: 'Note' as const, | ||||||
| 		}, | 		}, | ||||||
| 		viaMobile: { | 		viaMobile: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
|  | @ -423,7 +423,7 @@ export const packedNoteSchema = { | ||||||
| 			items: { | 			items: { | ||||||
| 				type: 'object' as const, | 				type: 'object' as const, | ||||||
| 				optional: false as const, nullable: false as const, | 				optional: false as const, nullable: false as const, | ||||||
| 				ref: 'DriveFile' | 				ref: 'DriveFile' as const, | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 		tags: { | 		tags: { | ||||||
|  | @ -447,11 +447,24 @@ export const packedNoteSchema = { | ||||||
| 		channel: { | 		channel: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 			ref: 'Channel' | 			items: { | ||||||
|  | 				type: 'object' as const, | ||||||
|  | 				optional: false as const, nullable: false as const, | ||||||
|  | 				properties: { | ||||||
|  | 					id: { | ||||||
|  | 						type: 'string' as const, | ||||||
|  | 						optional: false as const, nullable: false as const, | ||||||
|  | 					}, | ||||||
|  | 					name: { | ||||||
|  | 						type: 'string' as const, | ||||||
|  | 						optional: false as const, nullable: true as const, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		localOnly: { | 		localOnly: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
| 			optional: false as const, nullable: true as const, | 			optional: true as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 		emojis: { | 		emojis: { | ||||||
| 			type: 'array' as const, | 			type: 'array' as const, | ||||||
|  | @ -466,7 +479,7 @@ export const packedNoteSchema = { | ||||||
| 					}, | 					}, | ||||||
| 					url: { | 					url: { | ||||||
| 						type: 'string' as const, | 						type: 'string' as const, | ||||||
| 						optional: false as const, nullable: false as const, | 						optional: false as const, nullable: true as const, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  | @ -485,11 +498,11 @@ export const packedNoteSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		uri: { | 		uri: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
| 			optional: false as const, nullable: true as const, | 			optional: true as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 		url: { | 		url: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
| 			optional: false as const, nullable: true as const, | 			optional: true as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		myReaction: { | 		myReaction: { | ||||||
|  |  | ||||||
|  | @ -136,7 +136,7 @@ export const packedNotificationSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 		}, | 		}, | ||||||
| 		userId: { | 		userId: { | ||||||
|  | @ -146,7 +146,7 @@ export const packedNotificationSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		note: { | 		note: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			ref: 'Note', | 			ref: 'Note' as const, | ||||||
| 			optional: true as const, nullable: true as const, | 			optional: true as const, nullable: true as const, | ||||||
| 		}, | 		}, | ||||||
| 		reaction: { | 		reaction: { | ||||||
|  |  | ||||||
|  | @ -137,7 +137,7 @@ export const packedPageSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		user: { | 		user: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			ref: 'User', | 			ref: 'User' as const, | ||||||
| 			optional: false as const, nullable: false as const, | 			optional: false as const, nullable: false as const, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -375,12 +375,12 @@ export const packedUserSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		isAdmin: { | 		isAdmin: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
| 			nullable: false as const, optional: false as const, | 			nullable: false as const, optional: true as const, | ||||||
| 			default: false | 			default: false | ||||||
| 		}, | 		}, | ||||||
| 		isModerator: { | 		isModerator: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
| 			nullable: false as const, optional: false as const, | 			nullable: false as const, optional: true as const, | ||||||
| 			default: false | 			default: false | ||||||
| 		}, | 		}, | ||||||
| 		isBot: { | 		isBot: { | ||||||
|  | @ -402,23 +402,11 @@ export const packedUserSchema = { | ||||||
| 						type: 'string' as const, | 						type: 'string' as const, | ||||||
| 						nullable: false as const, optional: false as const | 						nullable: false as const, optional: false as const | ||||||
| 					}, | 					}, | ||||||
| 					host: { |  | ||||||
| 						type: 'string' as const, |  | ||||||
| 						nullable: true as const, optional: false as const |  | ||||||
| 					}, |  | ||||||
| 					url: { | 					url: { | ||||||
| 						type: 'string' as const, | 						type: 'string' as const, | ||||||
| 						nullable: false as const, optional: false as const, | 						nullable: false as const, optional: false as const, | ||||||
| 						format: 'url' | 						format: 'url' | ||||||
| 					}, | 					}, | ||||||
| 					aliases: { |  | ||||||
| 						type: 'array' as const, |  | ||||||
| 						nullable: false as const, optional: false as const, |  | ||||||
| 						items: { |  | ||||||
| 							type: 'string' as const, |  | ||||||
| 							nullable: false as const, optional: false as const |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
|  | @ -457,7 +445,7 @@ export const packedUserSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		isSuspended: { | 		isSuspended: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
| 			nullable: false as const, optional: false as const, | 			nullable: false as const, optional: true as const, | ||||||
| 			example: false | 			example: false | ||||||
| 		}, | 		}, | ||||||
| 		description: { | 		description: { | ||||||
|  | @ -476,7 +464,7 @@ export const packedUserSchema = { | ||||||
| 		}, | 		}, | ||||||
| 		fields: { | 		fields: { | ||||||
| 			type: 'array' as const, | 			type: 'array' as const, | ||||||
| 			nullable: false as const, optional: false as const, | 			nullable: false as const, optional: true as const, | ||||||
| 			items: { | 			items: { | ||||||
| 				type: 'object' as const, | 				type: 'object' as const, | ||||||
| 				nullable: false as const, optional: false as const, | 				nullable: false as const, optional: false as const, | ||||||
|  | @ -520,31 +508,31 @@ export const packedUserSchema = { | ||||||
| 			items: { | 			items: { | ||||||
| 				type: 'object' as const, | 				type: 'object' as const, | ||||||
| 				nullable: false as const, optional: false as const, | 				nullable: false as const, optional: false as const, | ||||||
| 				ref: 'Note' | 				ref: 'Note' as const, | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 		pinnedPageId: { | 		pinnedPageId: { | ||||||
| 			type: 'string' as const, | 			type: 'string' as const, | ||||||
| 			nullable: true as const, optional: false as const | 			nullable: true as const, optional: true as const | ||||||
| 		}, | 		}, | ||||||
| 		pinnedPage: { | 		pinnedPage: { | ||||||
| 			type: 'object' as const, | 			type: 'object' as const, | ||||||
| 			nullable: true as const, optional: false as const, | 			nullable: true as const, optional: true as const, | ||||||
| 			ref: 'Page' | 			ref: 'Page' as const, | ||||||
| 		}, | 		}, | ||||||
| 		twoFactorEnabled: { | 		twoFactorEnabled: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
| 			nullable: false as const, optional: false as const, | 			nullable: false as const, optional: true as const, | ||||||
| 			default: false | 			default: false | ||||||
| 		}, | 		}, | ||||||
| 		usePasswordLessLogin: { | 		usePasswordLessLogin: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
| 			nullable: false as const, optional: false as const, | 			nullable: false as const, optional: true as const, | ||||||
| 			default: false | 			default: false | ||||||
| 		}, | 		}, | ||||||
| 		securityKeys: { | 		securityKeys: { | ||||||
| 			type: 'boolean' as const, | 			type: 'boolean' as const, | ||||||
| 			nullable: false as const, optional: false as const, | 			nullable: false as const, optional: true as const, | ||||||
| 			default: false | 			default: false | ||||||
| 		}, | 		}, | ||||||
| 		avatarId: { | 		avatarId: { | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import { dirname } from 'path'; | ||||||
| import { Context } from 'cafy'; | import { Context } from 'cafy'; | ||||||
| import * as path from 'path'; | import * as path from 'path'; | ||||||
| import * as glob from 'glob'; | import * as glob from 'glob'; | ||||||
| import { Schema } from '@/misc/schema'; | import { SimpleSchema } from '@/misc/simple-schema'; | ||||||
| 
 | 
 | ||||||
| //const _filename = fileURLToPath(import.meta.url);
 | //const _filename = fileURLToPath(import.meta.url);
 | ||||||
| const _filename = __filename; | const _filename = __filename; | ||||||
|  | @ -34,7 +34,7 @@ export interface IEndpointMeta { | ||||||
| 		}; | 		}; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	res?: Schema; | 	res?: SimpleSchema; | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * このエンドポイントにリクエストするのにユーザー情報が必須か否か | 	 * このエンドポイントにリクエストするのにユーザー情報が必須か否か | ||||||
|  |  | ||||||
|  | @ -1,26 +1,4 @@ | ||||||
| import { packedUserSchema } from '@/models/repositories/user'; | import { refs, Schema } from '@/misc/schema'; | ||||||
| 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'; |  | ||||||
| import { packedHashtagSchema } from '@/models/repositories/hashtag'; |  | ||||||
| import { packedPageSchema } from '@/models/repositories/page'; |  | ||||||
| import { packedUserGroupSchema } from '@/models/repositories/user-group'; |  | ||||||
| import { packedNoteFavoriteSchema } from '@/models/repositories/note-favorite'; |  | ||||||
| import { packedChannelSchema } from '@/models/repositories/channel'; |  | ||||||
| import { packedAntennaSchema } from '@/models/repositories/antenna'; |  | ||||||
| import { packedClipSchema } from '@/models/repositories/clip'; |  | ||||||
| import { packedFederationInstanceSchema } from '@/models/repositories/federation-instance'; |  | ||||||
| import { packedQueueCountSchema } from '@/models/repositories/queue'; |  | ||||||
| import { packedGalleryPostSchema } from '@/models/repositories/gallery-post'; |  | ||||||
| 
 | 
 | ||||||
| export function convertSchemaToOpenApiSchema(schema: Schema) { | export function convertSchemaToOpenApiSchema(schema: Schema) { | ||||||
| 	const res: any = schema; | 	const res: any = schema; | ||||||
|  | @ -72,26 +50,7 @@ export const schemas = { | ||||||
| 		required: ['error'] | 		required: ['error'] | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	User: convertSchemaToOpenApiSchema(packedUserSchema), | 	...Object.fromEntries( | ||||||
| 	UserList: convertSchemaToOpenApiSchema(packedUserListSchema), | 		Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema)]) | ||||||
| 	UserGroup: convertSchemaToOpenApiSchema(packedUserGroupSchema), | 	), | ||||||
| 	App: convertSchemaToOpenApiSchema(packedAppSchema), |  | ||||||
| 	MessagingMessage: convertSchemaToOpenApiSchema(packedMessagingMessageSchema), |  | ||||||
| 	Note: convertSchemaToOpenApiSchema(packedNoteSchema), |  | ||||||
| 	NoteReaction: convertSchemaToOpenApiSchema(packedNoteReactionSchema), |  | ||||||
| 	NoteFavorite: convertSchemaToOpenApiSchema(packedNoteFavoriteSchema), |  | ||||||
| 	Notification: convertSchemaToOpenApiSchema(packedNotificationSchema), |  | ||||||
| 	DriveFile: convertSchemaToOpenApiSchema(packedDriveFileSchema), |  | ||||||
| 	DriveFolder: convertSchemaToOpenApiSchema(packedDriveFolderSchema), |  | ||||||
| 	Following: convertSchemaToOpenApiSchema(packedFollowingSchema), |  | ||||||
| 	Muting: convertSchemaToOpenApiSchema(packedMutingSchema), |  | ||||||
| 	Blocking: convertSchemaToOpenApiSchema(packedBlockingSchema), |  | ||||||
| 	Hashtag: convertSchemaToOpenApiSchema(packedHashtagSchema), |  | ||||||
| 	Page: convertSchemaToOpenApiSchema(packedPageSchema), |  | ||||||
| 	Channel: convertSchemaToOpenApiSchema(packedChannelSchema), |  | ||||||
| 	QueueCount: convertSchemaToOpenApiSchema(packedQueueCountSchema), |  | ||||||
| 	Antenna: convertSchemaToOpenApiSchema(packedAntennaSchema), |  | ||||||
| 	Clip: convertSchemaToOpenApiSchema(packedClipSchema), |  | ||||||
| 	FederationInstance: convertSchemaToOpenApiSchema(packedFederationInstanceSchema), |  | ||||||
| 	GalleryPost: convertSchemaToOpenApiSchema(packedGalleryPostSchema), |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -43,7 +43,7 @@ export default class extends Channel { | ||||||
| 
 | 
 | ||||||
| 		// 関係ない返信は除外
 | 		// 関係ない返信は除外
 | ||||||
| 		if (note.reply) { | 		if (note.reply) { | ||||||
| 			const reply = note.reply as PackedNote; | 			const reply = note.reply; | ||||||
| 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | ||||||
| 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ export default class extends Channel { | ||||||
| 
 | 
 | ||||||
| 		// 関係ない返信は除外
 | 		// 関係ない返信は除外
 | ||||||
| 		if (note.reply) { | 		if (note.reply) { | ||||||
| 			const reply = note.reply as PackedNote; | 			const reply = note.reply; | ||||||
| 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | ||||||
| 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ import Channel from '../channel'; | ||||||
| import { fetchMeta } from '@/misc/fetch-meta'; | import { fetchMeta } from '@/misc/fetch-meta'; | ||||||
| import { Notes } from '@/models/index'; | import { Notes } from '@/models/index'; | ||||||
| import { PackedNote } from '@/models/repositories/note'; | import { PackedNote } from '@/models/repositories/note'; | ||||||
| import { PackedUser } from '@/models/repositories/user'; |  | ||||||
| import { checkWordMute } from '@/misc/check-word-mute'; | import { checkWordMute } from '@/misc/check-word-mute'; | ||||||
| import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; | import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; | ||||||
| 
 | 
 | ||||||
|  | @ -31,7 +30,7 @@ export default class extends Channel { | ||||||
| 		if (!( | 		if (!( | ||||||
| 			(note.channelId == null && this.user!.id === note.userId) || | 			(note.channelId == null && this.user!.id === note.userId) || | ||||||
| 			(note.channelId == null && this.following.has(note.userId)) || | 			(note.channelId == null && this.following.has(note.userId)) || | ||||||
| 			(note.channelId == null && ((note.user as PackedUser).host == null && note.visibility === 'public')) || | 			(note.channelId == null && (note.user.host == null && note.visibility === 'public')) || | ||||||
| 			(note.channelId != null && this.followingChannels.has(note.channelId)) | 			(note.channelId != null && this.followingChannels.has(note.channelId)) | ||||||
| 		)) return; | 		)) return; | ||||||
| 
 | 
 | ||||||
|  | @ -60,7 +59,7 @@ export default class extends Channel { | ||||||
| 
 | 
 | ||||||
| 		// 関係ない返信は除外
 | 		// 関係ない返信は除外
 | ||||||
| 		if (note.reply) { | 		if (note.reply) { | ||||||
| 			const reply = note.reply as PackedNote; | 			const reply = note.reply; | ||||||
| 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | ||||||
| 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ import Channel from '../channel'; | ||||||
| import { fetchMeta } from '@/misc/fetch-meta'; | import { fetchMeta } from '@/misc/fetch-meta'; | ||||||
| import { Notes } from '@/models/index'; | import { Notes } from '@/models/index'; | ||||||
| import { PackedNote } from '@/models/repositories/note'; | import { PackedNote } from '@/models/repositories/note'; | ||||||
| import { PackedUser } from '@/models/repositories/user'; |  | ||||||
| import { checkWordMute } from '@/misc/check-word-mute'; | import { checkWordMute } from '@/misc/check-word-mute'; | ||||||
| import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; | import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; | ||||||
| 
 | 
 | ||||||
|  | @ -26,7 +25,7 @@ export default class extends Channel { | ||||||
| 
 | 
 | ||||||
| 	@autobind | 	@autobind | ||||||
| 	private async onNote(note: PackedNote) { | 	private async onNote(note: PackedNote) { | ||||||
| 		if ((note.user as PackedUser).host !== null) return; | 		if (note.user.host !== null) return; | ||||||
| 		if (note.visibility !== 'public') return; | 		if (note.visibility !== 'public') return; | ||||||
| 		if (note.channelId != null && !this.followingChannels.has(note.channelId)) return; | 		if (note.channelId != null && !this.followingChannels.has(note.channelId)) return; | ||||||
| 
 | 
 | ||||||
|  | @ -45,7 +44,7 @@ export default class extends Channel { | ||||||
| 
 | 
 | ||||||
| 		// 関係ない返信は除外
 | 		// 関係ない返信は除外
 | ||||||
| 		if (note.reply) { | 		if (note.reply) { | ||||||
| 			const reply = note.reply as PackedNote; | 			const reply = note.reply; | ||||||
| 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | 			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
 | ||||||
| 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -165,8 +165,8 @@ export default class Connection { | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		add(note); | 		add(note); | ||||||
| 		if (note.reply) add(note.reply as PackedNote); | 		if (note.reply) add(note.reply); | ||||||
| 		if (note.renote) add(note.renote as PackedNote); | 		if (note.renote) add(note.renote); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@autobind | 	@autobind | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| import * as nestedProperty from 'nested-property'; | import * as nestedProperty from 'nested-property'; | ||||||
| import autobind from 'autobind-decorator'; | import autobind from 'autobind-decorator'; | ||||||
| import Logger from '../logger'; | import Logger from '../logger'; | ||||||
| import { Schema } from '@/misc/schema'; | import { SimpleSchema } from '@/misc/simple-schema'; | ||||||
| import { EntitySchema, getRepository, Repository, LessThan, Between } from 'typeorm'; | import { EntitySchema, getRepository, Repository, LessThan, Between } from 'typeorm'; | ||||||
| import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '@/prelude/time'; | import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '@/prelude/time'; | ||||||
| import { getChartInsertLock } from '@/misc/app-lock'; | import { getChartInsertLock } from '@/misc/app-lock'; | ||||||
|  | @ -56,7 +56,7 @@ export default abstract class Chart<T extends Record<string, any>> { | ||||||
| 		diff: DeepPartial<T>; | 		diff: DeepPartial<T>; | ||||||
| 		group: string | null; | 		group: string | null; | ||||||
| 	}[] = []; | 	}[] = []; | ||||||
| 	public schema: Schema; | 	public schema: SimpleSchema; | ||||||
| 	protected repository: Repository<Log>; | 	protected repository: Repository<Log>; | ||||||
| 
 | 
 | ||||||
| 	protected abstract genNewLog(latest: T): DeepPartial<T>; | 	protected abstract genNewLog(latest: T): DeepPartial<T>; | ||||||
|  | @ -69,7 +69,7 @@ export default abstract class Chart<T extends Record<string, any>> { | ||||||
| 	protected abstract fetchActual(group: string | null): Promise<DeepPartial<T>>; | 	protected abstract fetchActual(group: string | null): Promise<DeepPartial<T>>; | ||||||
| 
 | 
 | ||||||
| 	@autobind | 	@autobind | ||||||
| 	private static convertSchemaToFlatColumnDefinitions(schema: Schema) { | 	private static convertSchemaToFlatColumnDefinitions(schema: SimpleSchema) { | ||||||
| 		const columns = {} as any; | 		const columns = {} as any; | ||||||
| 		const flatColumns = (x: Obj, path?: string) => { | 		const flatColumns = (x: Obj, path?: string) => { | ||||||
| 			for (const [k, v] of Object.entries(x)) { | 			for (const [k, v] of Object.entries(x)) { | ||||||
|  | @ -181,7 +181,7 @@ export default abstract class Chart<T extends Record<string, any>> { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@autobind | 	@autobind | ||||||
| 	public static schemaToEntity(name: string, schema: Schema): EntitySchema { | 	public static schemaToEntity(name: string, schema: SimpleSchema): EntitySchema { | ||||||
| 		return new EntitySchema({ | 		return new EntitySchema({ | ||||||
| 			name: `__chart__${camelToSnake(name)}`, | 			name: `__chart__${camelToSnake(name)}`, | ||||||
| 			columns: { | 			columns: { | ||||||
|  | @ -211,7 +211,7 @@ export default abstract class Chart<T extends Record<string, any>> { | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	constructor(name: string, schema: Schema, grouped = false) { | 	constructor(name: string, schema: SimpleSchema, grouped = false) { | ||||||
| 		this.name = name; | 		this.name = name; | ||||||
| 		this.schema = schema; | 		this.schema = schema; | ||||||
| 		const entity = Chart.schemaToEntity(name, schema); | 		const entity = Chart.schemaToEntity(name, schema); | ||||||
|  | @ -546,8 +546,8 @@ export default abstract class Chart<T extends Record<string, any>> { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function convertLog(logSchema: Schema): Schema { | export function convertLog(logSchema: SimpleSchema): SimpleSchema { | ||||||
| 	const v: Schema = JSON.parse(JSON.stringify(logSchema)); // copy
 | 	const v: SimpleSchema = JSON.parse(JSON.stringify(logSchema)); // copy
 | ||||||
| 	if (v.type === 'number') { | 	if (v.type === 'number') { | ||||||
| 		v.type = 'array'; | 		v.type = 'array'; | ||||||
| 		v.items = { | 		v.items = { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue