b4983ef56f
This reverts commit 9e366dc563
.
224 lines
7.3 KiB
TypeScript
224 lines
7.3 KiB
TypeScript
import {
|
||
packedUserLiteSchema,
|
||
packedUserDetailedNotMeOnlySchema,
|
||
packedMeDetailedOnlySchema,
|
||
packedUserDetailedNotMeSchema,
|
||
packedMeDetailedSchema,
|
||
packedUserDetailedSchema,
|
||
packedUserSchema,
|
||
} from "@/models/schema/user.js";
|
||
import { packedNoteSchema } from "@/models/schema/note.js";
|
||
import { packedUserListSchema } from "@/models/schema/user-list.js";
|
||
import { packedAppSchema } from "@/models/schema/app.js";
|
||
import { packedMessagingMessageSchema } from "@/models/schema/messaging-message.js";
|
||
import { packedNotificationSchema } from "@/models/schema/notification.js";
|
||
import { packedDriveFileSchema } from "@/models/schema/drive-file.js";
|
||
import { packedDriveFolderSchema } from "@/models/schema/drive-folder.js";
|
||
import { packedFollowingSchema } from "@/models/schema/following.js";
|
||
import { packedMutingSchema } from "@/models/schema/muting.js";
|
||
import { packedRenoteMutingSchema } from "@/models/schema/renote-muting.js";
|
||
import { packedBlockingSchema } from "@/models/schema/blocking.js";
|
||
import { packedNoteReactionSchema } from "@/models/schema/note-reaction.js";
|
||
import { packedHashtagSchema } from "@/models/schema/hashtag.js";
|
||
import { packedPageSchema } from "@/models/schema/page.js";
|
||
import { packedUserGroupSchema } from "@/models/schema/user-group.js";
|
||
import { packedNoteFavoriteSchema } from "@/models/schema/note-favorite.js";
|
||
import { packedChannelSchema } from "@/models/schema/channel.js";
|
||
import { packedAntennaSchema } from "@/models/schema/antenna.js";
|
||
import { packedClipSchema } from "@/models/schema/clip.js";
|
||
import { packedFederationInstanceSchema } from "@/models/schema/federation-instance.js";
|
||
import { packedQueueCountSchema } from "@/models/schema/queue.js";
|
||
import { packedGalleryPostSchema } from "@/models/schema/gallery-post.js";
|
||
import { packedEmojiSchema } from "@/models/schema/emoji.js";
|
||
import { packedNoteEdit } from "@/models/schema/note-edit.js";
|
||
|
||
export const refs = {
|
||
UserLite: packedUserLiteSchema,
|
||
UserDetailedNotMeOnly: packedUserDetailedNotMeOnlySchema,
|
||
MeDetailedOnly: packedMeDetailedOnlySchema,
|
||
UserDetailedNotMe: packedUserDetailedNotMeSchema,
|
||
MeDetailed: packedMeDetailedSchema,
|
||
UserDetailed: packedUserDetailedSchema,
|
||
User: packedUserSchema,
|
||
|
||
UserList: packedUserListSchema,
|
||
UserGroup: packedUserGroupSchema,
|
||
App: packedAppSchema,
|
||
MessagingMessage: packedMessagingMessageSchema,
|
||
Note: packedNoteSchema,
|
||
NoteEdit: packedNoteEdit,
|
||
NoteReaction: packedNoteReactionSchema,
|
||
NoteFavorite: packedNoteFavoriteSchema,
|
||
Notification: packedNotificationSchema,
|
||
DriveFile: packedDriveFileSchema,
|
||
DriveFolder: packedDriveFolderSchema,
|
||
Following: packedFollowingSchema,
|
||
Muting: packedMutingSchema,
|
||
RenoteMuting: packedRenoteMutingSchema,
|
||
Blocking: packedBlockingSchema,
|
||
Hashtag: packedHashtagSchema,
|
||
Page: packedPageSchema,
|
||
Channel: packedChannelSchema,
|
||
QueueCount: packedQueueCountSchema,
|
||
Antenna: packedAntennaSchema,
|
||
Clip: packedClipSchema,
|
||
FederationInstance: packedFederationInstanceSchema,
|
||
GalleryPost: packedGalleryPostSchema,
|
||
Emoji: packedEmojiSchema,
|
||
};
|
||
|
||
export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>;
|
||
|
||
type TypeStringef =
|
||
| "null"
|
||
| "boolean"
|
||
| "integer"
|
||
| "number"
|
||
| "string"
|
||
| "array"
|
||
| "object"
|
||
| "any";
|
||
type StringDefToType<T extends TypeStringef> = T extends "null"
|
||
? null
|
||
: T extends "boolean"
|
||
? boolean
|
||
: T extends "integer"
|
||
? number
|
||
: 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 = {
|
||
readonly anyOf?: ReadonlyArray<Schema>;
|
||
readonly oneOf?: ReadonlyArray<Schema>;
|
||
readonly allOf?: ReadonlyArray<Schema>;
|
||
};
|
||
|
||
export interface Schema extends OfSchema {
|
||
readonly type?: TypeStringef;
|
||
readonly nullable?: boolean;
|
||
readonly optional?: boolean;
|
||
readonly items?: Schema;
|
||
readonly properties?: Obj;
|
||
readonly required?: ReadonlyArray<
|
||
Extract<keyof NonNullable<this["properties"]>, string>
|
||
>;
|
||
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;
|
||
readonly maximum?: number;
|
||
readonly minimum?: number;
|
||
readonly pattern?: string;
|
||
}
|
||
|
||
type RequiredPropertyNames<s extends Obj> = {
|
||
[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<string, unknown>
|
||
? K
|
||
: never;
|
||
}[keyof s];
|
||
|
||
export type Obj = Record<string, Schema>;
|
||
|
||
// https://github.com/misskey-dev/misskey/issues/8535
|
||
// To avoid excessive stack depth error,
|
||
// deceive TypeScript with UnionToIntersection (or more precisely, `infer` expression within it).
|
||
export type ObjType<
|
||
s extends Obj,
|
||
RequiredProps extends keyof s,
|
||
> = UnionToIntersection<
|
||
{
|
||
-readonly [R in RequiredPropertyNames<s>]-?: SchemaType<s[R]>;
|
||
} & {
|
||
-readonly [R in RequiredProps]-?: SchemaType<s[R]>;
|
||
} & {
|
||
-readonly [P in keyof s]?: SchemaType<s[P]>;
|
||
}
|
||
>;
|
||
|
||
type NullOrUndefined<p extends Schema, T> =
|
||
| (p["nullable"] extends true ? null : never)
|
||
| (p["optional"] extends true ? undefined : never)
|
||
| T;
|
||
|
||
// https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
|
||
// Get intersection from union
|
||
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
|
||
// To get union, we use `Foo extends any ? Hoge<Foo> : never`
|
||
type UnionSchemaType<
|
||
a extends readonly any[],
|
||
X extends Schema = a[number],
|
||
> = X extends any ? SchemaType<X> : never;
|
||
type ArrayUnion<T> = T extends any ? Array<T> : never;
|
||
|
||
export type SchemaTypeDef<p extends Schema> = p["type"] extends "null"
|
||
? null
|
||
: p["type"] extends "integer"
|
||
? number
|
||
: 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
|
||
: p["type"] extends "object"
|
||
? p["ref"] extends keyof typeof refs
|
||
? Packed<p["ref"]>
|
||
: p["properties"] extends NonNullable<Obj>
|
||
? ObjType<p["properties"], NonNullable<p["required"]>[number]>
|
||
: p["anyOf"] extends ReadonlyArray<Schema>
|
||
? UnionSchemaType<p["anyOf"]> &
|
||
Partial<UnionToIntersection<UnionSchemaType<p["anyOf"]>>>
|
||
: p["allOf"] extends ReadonlyArray<Schema>
|
||
? UnionToIntersection<UnionSchemaType<p["allOf"]>>
|
||
: any
|
||
: p["type"] extends "array"
|
||
? p["items"] extends OfSchema
|
||
? 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"]>>>[]
|
||
: never
|
||
: p["items"] extends NonNullable<Schema>
|
||
? SchemaTypeDef<p["items"]>[]
|
||
: any[]
|
||
: p["oneOf"] extends ReadonlyArray<Schema>
|
||
? UnionSchemaType<p["oneOf"]>
|
||
: any;
|
||
|
||
export type SchemaType<p extends Schema> = NullOrUndefined<p, SchemaTypeDef<p>>;
|