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:
tamaina 2021-09-12 01:12:23 +09:00 committed by GitHub
parent f59f424795
commit 53f3b779bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 148 additions and 129 deletions

View file

@ -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
View 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; }

View file

@ -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,
}, },
} }
}; };

View file

@ -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: {

View file

@ -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,
} }
}, },
}; };

View file

@ -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,
}, },
}, },
}; };

View file

@ -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,
}, },
} }
}; };

View file

@ -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: {

View file

@ -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,

View file

@ -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,
}, },
} }
}; };

View file

@ -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,

View file

@ -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,

View file

@ -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: {

View file

@ -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: {

View file

@ -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,
}, },
} }

View file

@ -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: {

View file

@ -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;
/** /**
* *

View file

@ -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),
}; };

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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

View file

@ -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 = {