2022-01-18 15:27:10 +02:00
|
|
|
|
import {
|
|
|
|
|
packedUserLiteSchema,
|
|
|
|
|
packedUserDetailedNotMeOnlySchema,
|
|
|
|
|
packedMeDetailedOnlySchema,
|
|
|
|
|
packedUserDetailedNotMeSchema,
|
|
|
|
|
packedMeDetailedSchema,
|
|
|
|
|
packedUserDetailedSchema,
|
|
|
|
|
packedUserSchema,
|
|
|
|
|
} from '@/models/schema/user';
|
|
|
|
|
import { packedNoteSchema } from '@/models/schema/note';
|
|
|
|
|
import { packedUserListSchema } from '@/models/schema/user-list';
|
|
|
|
|
import { packedAppSchema } from '@/models/schema/app';
|
|
|
|
|
import { packedMessagingMessageSchema } from '@/models/schema/messaging-message';
|
|
|
|
|
import { packedNotificationSchema } from '@/models/schema/notification';
|
|
|
|
|
import { packedDriveFileSchema } from '@/models/schema/drive-file';
|
|
|
|
|
import { packedDriveFolderSchema } from '@/models/schema/drive-folder';
|
|
|
|
|
import { packedFollowingSchema } from '@/models/schema/following';
|
|
|
|
|
import { packedMutingSchema } from '@/models/schema/muting';
|
|
|
|
|
import { packedBlockingSchema } from '@/models/schema/blocking';
|
|
|
|
|
import { packedNoteReactionSchema } from '@/models/schema/note-reaction';
|
|
|
|
|
import { packedHashtagSchema } from '@/models/schema/hashtag';
|
|
|
|
|
import { packedPageSchema } from '@/models/schema/page';
|
|
|
|
|
import { packedUserGroupSchema } from '@/models/schema/user-group';
|
|
|
|
|
import { packedNoteFavoriteSchema } from '@/models/schema/note-favorite';
|
|
|
|
|
import { packedChannelSchema } from '@/models/schema/channel';
|
|
|
|
|
import { packedAntennaSchema } from '@/models/schema/antenna';
|
|
|
|
|
import { packedClipSchema } from '@/models/schema/clip';
|
|
|
|
|
import { packedFederationInstanceSchema } from '@/models/schema/federation-instance';
|
|
|
|
|
import { packedQueueCountSchema } from '@/models/schema/queue';
|
|
|
|
|
import { packedGalleryPostSchema } from '@/models/schema/gallery-post';
|
|
|
|
|
import { packedEmojiSchema } from '@/models/schema/emoji';
|
2021-09-11 19:12:23 +03:00
|
|
|
|
|
|
|
|
|
export const refs = {
|
2022-01-18 15:27:10 +02:00
|
|
|
|
UserLite: packedUserLiteSchema,
|
|
|
|
|
UserDetailedNotMeOnly: packedUserDetailedNotMeOnlySchema,
|
|
|
|
|
MeDetailedOnly: packedMeDetailedOnlySchema,
|
|
|
|
|
UserDetailedNotMe: packedUserDetailedNotMeSchema,
|
|
|
|
|
MeDetailed: packedMeDetailedSchema,
|
|
|
|
|
UserDetailed: packedUserDetailedSchema,
|
2021-09-11 19:12:23 +03:00
|
|
|
|
User: packedUserSchema,
|
2022-01-18 15:27:10 +02:00
|
|
|
|
|
2021-09-11 19:12:23 +03:00
|
|
|
|
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,
|
2021-09-22 16:35:55 +03:00
|
|
|
|
Emoji: packedEmojiSchema,
|
2021-09-11 19:12:23 +03:00
|
|
|
|
};
|
|
|
|
|
|
2022-01-18 15:27:10 +02:00
|
|
|
|
// Packed = SchemaTypeDef<typeof refs[x]>; とすると展開されてマウスホバー時に型表示が使い物にならなくなる
|
|
|
|
|
// ObjType<r['properties']>を指定すると(なぜか)展開されずにPacked<'Hoge'>と表示される
|
2022-02-19 07:05:32 +02:00
|
|
|
|
type PackedDef<r extends { properties?: Obj; oneOf?: ReadonlyArray<Schema>; allOf?: ReadonlyArray<Schema> }> =
|
|
|
|
|
r['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<r['allOf']>> :
|
|
|
|
|
r['oneOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<r['oneOf']> :
|
|
|
|
|
r['properties'] extends Obj ? ObjType<r['properties'], any> :
|
2022-01-18 15:27:10 +02:00
|
|
|
|
never;
|
|
|
|
|
export type Packed<x extends keyof typeof refs> = PackedDef<typeof refs[x]>;
|
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
type TypeStringef = 'null' | 'boolean' | 'integer' | 'number' | 'string' | 'array' | 'object' | 'any';
|
2022-01-18 15:27:10 +02:00
|
|
|
|
type StringDefToType<T extends TypeStringef> =
|
2022-02-19 07:05:32 +02:00
|
|
|
|
T extends 'null' ? null :
|
2022-01-18 15:27:10 +02:00
|
|
|
|
T extends 'boolean' ? boolean :
|
2022-02-19 07:05:32 +02:00
|
|
|
|
T extends 'integer' ? number :
|
2022-01-18 15:27:10 +02:00
|
|
|
|
T extends 'number' ? number :
|
|
|
|
|
T extends 'string' ? string | Date :
|
|
|
|
|
T extends 'array' ? ReadonlyArray<any> :
|
|
|
|
|
T extends 'object' ? Record<string, any> :
|
|
|
|
|
any;
|
|
|
|
|
|
|
|
|
|
// https://swagger.io/specification/?sbsearch=optional#schema-object
|
|
|
|
|
type OfSchema = {
|
2022-02-19 07:05:32 +02:00
|
|
|
|
readonly anyOf?: ReadonlyArray<Schema>;
|
|
|
|
|
readonly oneOf?: ReadonlyArray<Schema>;
|
|
|
|
|
readonly allOf?: ReadonlyArray<Schema>;
|
2022-01-18 15:27:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
export interface Schema extends OfSchema {
|
2022-01-18 15:27:10 +02:00
|
|
|
|
readonly type?: TypeStringef;
|
|
|
|
|
readonly nullable?: boolean;
|
|
|
|
|
readonly optional?: boolean;
|
2022-02-19 07:05:32 +02:00
|
|
|
|
readonly items?: Schema;
|
2022-01-18 15:27:10 +02:00
|
|
|
|
readonly properties?: Obj;
|
2022-02-19 07:05:32 +02:00
|
|
|
|
readonly required?: ReadonlyArray<keyof NonNullable<this['properties']>>;
|
2022-01-18 15:27:10 +02:00
|
|
|
|
readonly description?: string;
|
|
|
|
|
readonly example?: any;
|
|
|
|
|
readonly format?: string;
|
|
|
|
|
readonly ref?: keyof typeof refs;
|
|
|
|
|
readonly enum?: ReadonlyArray<string>;
|
|
|
|
|
readonly default?: (this['type'] extends TypeStringef ? StringDefToType<this['type']> : any) | null;
|
|
|
|
|
readonly maxLength?: number;
|
|
|
|
|
readonly minLength?: number;
|
|
|
|
|
}
|
2021-09-22 16:35:55 +03:00
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
type OptionalPropertyNames<T extends Obj> = {
|
|
|
|
|
[K in keyof T]: T[K]['optional'] extends true ? K : never
|
|
|
|
|
}[keyof T];
|
2019-02-24 02:45:27 +02:00
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
type NonOptionalPropertyNames<T extends Obj> = {
|
|
|
|
|
[K in keyof T]: T[K]['optional'] extends false ? K : never
|
2019-04-23 16:35:26 +03:00
|
|
|
|
}[keyof T];
|
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
type DefaultPropertyNames<T extends Obj> = {
|
|
|
|
|
[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<string, unknown> ? K :
|
|
|
|
|
never
|
2019-04-23 16:35:26 +03:00
|
|
|
|
}[keyof T];
|
|
|
|
|
|
2022-01-18 15:27:10 +02:00
|
|
|
|
export interface Obj { [key: string]: Schema; }
|
2019-02-24 02:45:27 +02:00
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
export type ObjType<s extends Obj, RequiredProps extends ReadonlyArray<keyof s>> =
|
|
|
|
|
{ -readonly [P in keyof s]?: SchemaType<s[P]> } &
|
|
|
|
|
{ -readonly [P in RequiredProps[number]]: SchemaType<s[P]> } &
|
|
|
|
|
{ -readonly [P in OptionalPropertyNames<s>]?: SchemaType<s[P]> } &
|
|
|
|
|
{ -readonly [P in NonOptionalPropertyNames<s>]: SchemaType<s[P]> } &
|
|
|
|
|
{ -readonly [P in DefaultPropertyNames<s>]: SchemaType<s[P]> };
|
2019-02-24 02:45:27 +02:00
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
type NullOrUndefined<p extends Schema, T> =
|
2019-04-23 16:35:26 +03:00
|
|
|
|
p['nullable'] extends true
|
|
|
|
|
? p['optional'] extends true
|
|
|
|
|
? (T | null | undefined)
|
|
|
|
|
: (T | null)
|
|
|
|
|
: p['optional'] extends true
|
|
|
|
|
? (T | undefined)
|
|
|
|
|
: T;
|
|
|
|
|
|
2022-01-18 15:27:10 +02:00
|
|
|
|
// 共用体型を交差型にする型 https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
|
|
|
|
|
type UnionToIntersection<U> = (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<X>で判定するだけではダメ
|
2022-02-19 07:05:32 +02:00
|
|
|
|
type UnionSchemaType<a extends readonly any[], X extends Schema = a[number]> = X extends any ? SchemaType<X> : never;
|
2022-01-18 15:27:10 +02:00
|
|
|
|
type ArrayUnion<T> = T extends any ? Array<T> : never;
|
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
export type SchemaTypeDef<p extends Schema> =
|
|
|
|
|
p['type'] extends 'null' ? null :
|
|
|
|
|
p['type'] extends 'integer' ? number :
|
2022-01-18 15:27:10 +02:00
|
|
|
|
p['type'] extends 'number' ? number :
|
|
|
|
|
p['type'] extends 'string' ? (
|
|
|
|
|
p['enum'] extends readonly string[] ?
|
|
|
|
|
p['enum'][number] :
|
|
|
|
|
p['format'] extends 'date-time' ? string : // Dateにする??
|
|
|
|
|
string
|
|
|
|
|
) :
|
|
|
|
|
p['type'] extends 'boolean' ? boolean :
|
2021-09-11 19:12:23 +03:00
|
|
|
|
p['type'] extends 'object' ? (
|
2022-01-18 15:27:10 +02:00
|
|
|
|
p['ref'] extends keyof typeof refs ? Packed<p['ref']> :
|
2022-02-19 07:05:32 +02:00
|
|
|
|
p['properties'] extends NonNullable<Obj> ? ObjType<p['properties'], NonNullable<p['required']>> :
|
|
|
|
|
p['anyOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<p['anyOf']> & Partial<UnionToIntersection<UnionSchemaType<p['anyOf']>>> :
|
|
|
|
|
p['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<p['allOf']>> :
|
2022-01-18 15:27:10 +02:00
|
|
|
|
any
|
|
|
|
|
) :
|
|
|
|
|
p['type'] extends 'array' ? (
|
|
|
|
|
p['items'] extends OfSchema ? (
|
2022-02-19 07:05:32 +02:00
|
|
|
|
p['items']['anyOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<NonNullable<p['items']['anyOf']>>[] :
|
|
|
|
|
p['items']['oneOf'] extends ReadonlyArray<Schema> ? ArrayUnion<UnionSchemaType<NonNullable<p['items']['oneOf']>>> :
|
|
|
|
|
p['items']['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<NonNullable<p['items']['allOf']>>>[] :
|
2022-01-18 15:27:10 +02:00
|
|
|
|
never
|
|
|
|
|
) :
|
2022-02-19 07:05:32 +02:00
|
|
|
|
p['items'] extends NonNullable<Schema> ? SchemaTypeDef<p['items']>[] :
|
2022-01-18 15:27:10 +02:00
|
|
|
|
any[]
|
2021-09-11 19:12:23 +03:00
|
|
|
|
) :
|
2022-02-19 07:05:32 +02:00
|
|
|
|
p['oneOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<p['oneOf']> :
|
2019-02-24 02:45:27 +02:00
|
|
|
|
any;
|
2022-01-18 15:27:10 +02:00
|
|
|
|
|
2022-02-19 07:05:32 +02:00
|
|
|
|
export type SchemaType<p extends Schema> = NullOrUndefined<p, SchemaTypeDef<p>>;
|