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
|
@ -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…
Reference in a new issue