From fd8f8162e186981ca2acf9d3b1caef523c748691 Mon Sep 17 00:00:00 2001 From: tamaina Date: Sat, 19 Feb 2022 23:21:28 +0900 Subject: [PATCH] =?UTF-8?q?SchemaType=E3=81=AE=E5=9E=8B=E8=A8=88=E7=AE=97?= =?UTF-8?q?=E9=87=8F=E3=82=92=E5=89=8A=E6=B8=9B=20(#8332)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * schema typeの型計算量を削減 * reduce some type error * wip * fix * clean up * more shrink --- packages/backend/src/misc/schema.ts | 47 ++++++------------- .../backend/src/models/repositories/app.ts | 2 +- .../endpoints/admin/announcements/create.ts | 2 +- .../server/api/endpoints/i/gallery/likes.ts | 28 ++++++----- .../src/server/api/endpoints/i/page-likes.ts | 29 +++++++----- .../src/server/api/endpoints/my/apps.ts | 41 +--------------- .../src/server/api/endpoints/sw/register.ts | 8 ++-- .../backend/src/server/api/stream/types.ts | 1 + .../src/services/create-system-user.ts | 4 +- 9 files changed, 57 insertions(+), 105 deletions(-) diff --git a/packages/backend/src/misc/schema.ts b/packages/backend/src/misc/schema.ts index fbe5a1e421..5909969bbf 100644 --- a/packages/backend/src/misc/schema.ts +++ b/packages/backend/src/misc/schema.ts @@ -63,14 +63,7 @@ export const refs = { Emoji: packedEmojiSchema, }; -// Packed = SchemaTypeDef; とすると展開されてマウスホバー時に型表示が使い物にならなくなる -// ObjTypeを指定すると(なぜか)展開されずにPacked<'Hoge'>と表示される -type PackedDef; allOf?: ReadonlyArray }> = - r['allOf'] extends ReadonlyArray ? UnionToIntersection> : - r['oneOf'] extends ReadonlyArray ? UnionSchemaType : - r['properties'] extends Obj ? ObjType : - never; -export type Packed = PackedDef; +export type Packed = SchemaType; type TypeStringef = 'null' | 'boolean' | 'integer' | 'number' | 'string' | 'array' | 'object' | 'any'; type StringDefToType = @@ -107,31 +100,20 @@ export interface Schema extends OfSchema { readonly minLength?: number; } -type OptionalPropertyNames = { - [K in keyof T]: T[K]['optional'] extends true ? K : never -}[keyof T]; - -type NonOptionalPropertyNames = { - [K in keyof T]: T[K]['optional'] extends false ? K : never -}[keyof T]; - -type DefaultPropertyNames = { - [K in keyof T]: T[K]['default'] extends null ? K : - T[K]['default'] extends string ? K : - T[K]['default'] extends number ? K : - T[K]['default'] extends boolean ? K : - T[K]['default'] extends Record ? K : - never -}[keyof T]; +type RequiredPropertyNames = { + [K in keyof s]: + // K is not optional + s[K]['optional'] extends false ? K : + // K has default value + s[K]['default'] extends null | string | number | boolean | Record ? K : never +}[keyof s]; export interface Obj { [key: string]: Schema; } -export type ObjType> = +export type ObjType = { -readonly [P in keyof s]?: SchemaType } & - { -readonly [P in RequiredProps[number]]: SchemaType } & - { -readonly [P in OptionalPropertyNames]?: SchemaType } & - { -readonly [P in NonOptionalPropertyNames]: SchemaType } & - { -readonly [P in DefaultPropertyNames]: SchemaType }; + { -readonly [P in RequiredProps]: SchemaType } & + { -readonly [P in RequiredPropertyNames]: SchemaType }; type NullOrUndefined

= p['nullable'] extends true @@ -142,11 +124,12 @@ type NullOrUndefined

= ? (T | undefined) : T; -// 共用体型を交差型にする型 https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection +// https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection +// Get intersection from union type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; // https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552 -// 単純にSchemaTypeDefで判定するだけではダメ +// To get union, we use `Foo extends any ? Hoge : never` type UnionSchemaType = X extends any ? SchemaType : never; type ArrayUnion = T extends any ? Array : never; @@ -163,7 +146,7 @@ export type SchemaTypeDef

= p['type'] extends 'boolean' ? boolean : p['type'] extends 'object' ? ( p['ref'] extends keyof typeof refs ? Packed : - p['properties'] extends NonNullable ? ObjType> : + p['properties'] extends NonNullable ? ObjType[number]> : p['anyOf'] extends ReadonlyArray ? UnionSchemaType & Partial>> : p['allOf'] extends ReadonlyArray ? UnionToIntersection> : any diff --git a/packages/backend/src/models/repositories/app.ts b/packages/backend/src/models/repositories/app.ts index 6bac4d9598..5576c67236 100644 --- a/packages/backend/src/models/repositories/app.ts +++ b/packages/backend/src/models/repositories/app.ts @@ -32,7 +32,7 @@ export class AppRepository extends Repository { ...(me ? { isAuthorized: await AccessTokens.count({ appId: app.id, - userId: me, + userId: me.id, }).then(count => count > 0), } : {}), }; diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts index 8d2bda9781..295d99513d 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts @@ -65,5 +65,5 @@ export default define(meta, paramDef, async (ps) => { imageUrl: ps.imageUrl, }).then(x => Announcements.findOneOrFail(x.identifiers[0])); - return announcement; + return Object.assign({}, announcement, { createdAt: announcement.createdAt.toISOString(), updatedAt: null }); }); diff --git a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts index dc862a6b05..7578ed3216 100644 --- a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts +++ b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts @@ -10,20 +10,24 @@ export const meta = { kind: 'read:gallery-likes', res: { - type: 'object', + type: 'array', optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', + items: { + type: 'object', + optional: false, nullable: false, + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + post: { + type: 'object', + optional: false, nullable: false, + ref: 'GalleryPost', + }, }, - page: { - type: 'object', - optional: false, nullable: false, - ref: 'GalleryPost', - }, - }, + } }, } as const; diff --git a/packages/backend/src/server/api/endpoints/i/page-likes.ts b/packages/backend/src/server/api/endpoints/i/page-likes.ts index e66bc616c2..60ac3ccde1 100644 --- a/packages/backend/src/server/api/endpoints/i/page-likes.ts +++ b/packages/backend/src/server/api/endpoints/i/page-likes.ts @@ -10,20 +10,23 @@ export const meta = { kind: 'read:page-likes', res: { - type: 'object', + type: 'array', optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', + items: { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + page: { + type: 'object', + optional: false, nullable: false, + ref: 'Page', + }, }, - page: { - type: 'object', - optional: false, nullable: false, - ref: 'Page', - }, - }, + } }, } as const; @@ -47,5 +50,5 @@ export default define(meta, paramDef, async (ps, user) => { .take(ps.limit) .getMany(); - return await PageLikes.packMany(likes, user); + return PageLikes.packMany(likes, user); }); diff --git a/packages/backend/src/server/api/endpoints/my/apps.ts b/packages/backend/src/server/api/endpoints/my/apps.ts index 60e5014110..8dee11fb93 100644 --- a/packages/backend/src/server/api/endpoints/my/apps.ts +++ b/packages/backend/src/server/api/endpoints/my/apps.ts @@ -12,46 +12,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - }, - name: { - type: 'string', - optional: false, nullable: false, - }, - callbackUrl: { - type: 'string', - optional: false, nullable: false, - }, - permission: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'string', - optional: false, nullable: false, - }, - }, - secret: { - type: 'string', - optional: true, nullable: false, - }, - isAuthorized: { - type: 'object', - optional: true, nullable: false, - properties: { - appId: { - type: 'string', - optional: false, nullable: false, - }, - userId: { - type: 'string', - optional: false, nullable: false, - }, - }, - }, - }, + ref: 'App', }, }, } as const; diff --git a/packages/backend/src/server/api/endpoints/sw/register.ts b/packages/backend/src/server/api/endpoints/sw/register.ts index 9091c9481a..459b0dd969 100644 --- a/packages/backend/src/server/api/endpoints/sw/register.ts +++ b/packages/backend/src/server/api/endpoints/sw/register.ts @@ -14,12 +14,12 @@ export const meta = { properties: { state: { type: 'string', - optional: false, nullable: false, + optional: true, nullable: false, enum: ['already-subscribed', 'subscribed'], }, key: { type: 'string', - optional: false, nullable: false, + optional: false, nullable: true, }, }, }, @@ -49,7 +49,7 @@ export default define(meta, paramDef, async (ps, user) => { if (exist != null) { return { - state: 'already-subscribed', + state: 'already-subscribed' as const, key: instance.swPublicKey, }; } @@ -64,7 +64,7 @@ export default define(meta, paramDef, async (ps, user) => { }); return { - state: 'subscribed', + state: 'subscribed' as const, key: instance.swPublicKey, }; }); diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index e2f1c6fc9c..921856b38d 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -84,6 +84,7 @@ export interface MainStreamTypes { }; driveFileCreated: Packed<'DriveFile'>; readAntenna: Antenna; + receiveFollowRequest: Packed<'User'>; } export interface DriveStreamTypes { diff --git a/packages/backend/src/services/create-system-user.ts b/packages/backend/src/services/create-system-user.ts index 82130dd593..2e9ec178fd 100644 --- a/packages/backend/src/services/create-system-user.ts +++ b/packages/backend/src/services/create-system-user.ts @@ -4,7 +4,7 @@ import generateNativeUserToken from '../server/api/common/generate-native-user-t import { genRsaKeyPair } from '@/misc/gen-key-pair'; import { User } from '@/models/entities/user'; import { UserProfile } from '@/models/entities/user-profile'; -import { getConnection } from 'typeorm'; +import { getConnection, ObjectLiteral } from 'typeorm'; import { genId } from '@/misc/gen-id'; import { UserKeypair } from '@/models/entities/user-keypair'; import { UsedUsername } from '@/models/entities/used-username'; @@ -21,7 +21,7 @@ export async function createSystemUser(username: string) { const keyPair = await genRsaKeyPair(4096); - let account!: User; + let account!: User | ObjectLiteral; // Start transaction await getConnection().transaction(async transactionalEntityManager => {