From 810d065d2176837abf7c9e72cc0eff2f1d20a2fa Mon Sep 17 00:00:00 2001 From: tamaina Date: Mon, 22 May 2023 01:43:00 +0000 Subject: [PATCH] wip --- .../backend/src/server/api/endpoint-base.ts | 3 +- .../api/endpoints/admin/accounts/create.ts | 36 +---- .../api/endpoints/admin/accounts/delete.ts | 20 +-- .../server/api/endpoints/admin/ad/create.ts | 27 +--- .../server/api/endpoints/admin/ad/delete.ts | 30 +--- .../src/server/api/endpoints/admin/ad/list.ts | 5 +- .../server/api/endpoints/admin/ad/update.ts | 31 ---- .../endpoints/admin/announcements/create.ts | 57 +------ .../endpoints/admin/announcements/delete.ts | 30 +--- .../api/endpoints/admin/announcements/list.ts | 65 +------- .../endpoints/admin/announcements/update.ts | 33 +--- .../admin/drive/clean-remote-files.ts | 18 +-- .../api/endpoints/admin/drive/cleanup.ts | 18 +-- .../server/api/endpoints/admin/drive/files.ts | 41 +---- .../api/endpoints/admin/drive/show-file.ts | 150 +----------------- packages/misskey-js/src/api.ts | 6 +- packages/misskey-js/src/endpoints.ts | 106 ++++++++++--- packages/misskey-js/src/schemas/ad.ts | 1 - pnpm-lock.yaml | 10 +- 19 files changed, 144 insertions(+), 543 deletions(-) diff --git a/packages/backend/src/server/api/endpoint-base.ts b/packages/backend/src/server/api/endpoint-base.ts index fa4cdbcea..6cd40ad56 100644 --- a/packages/backend/src/server/api/endpoint-base.ts +++ b/packages/backend/src/server/api/endpoint-base.ts @@ -6,6 +6,7 @@ import { ApiError } from './error.js'; import { endpoints } from 'misskey-js/built/endpoints.js'; import type { IEndpointMeta, ResponseOf, SchemaOrUndefined } from 'misskey-js/built/endpoints.types.js'; import type { Endpoints } from 'misskey-js'; +import { WeakSerialized } from 'schema-type'; const ajv = new Ajv({ useDefaults: true, @@ -29,7 +30,7 @@ export type Executor any, ip?: string | null, headers?: Record | null - ) => Promise>; + ) => Promise>>; // ExecutorWrapperの型はあえて緩くしておく export type ExecutorWrapper = diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts index 8a3541dff..59c1b5aca 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts @@ -7,34 +7,10 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { localUsernameSchema, passwordSchema } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['admin'], - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'User', - properties: { - token: { - type: 'string', - optional: false, nullable: false, - }, - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - username: localUsernameSchema, - password: passwordSchema, - }, - required: ['username', 'password'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/accounts/create'> { + name = 'admin/accounts/create' as const; constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -42,7 +18,7 @@ export default class extends Endpoint { private userEntityService: UserEntityService, private signupService: SignupService, ) { - super(meta, paramDef, async (ps, _me) => { + super(async (ps, _me) => { const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null; const noUsers = (await this.usersRepository.countBy({ host: IsNull(), @@ -55,14 +31,12 @@ export default class extends Endpoint { ignorePreservedUsernames: true, }); - const res = await this.userEntityService.pack(account, account, { + const res = await this.userEntityService.pack(account, account, { detail: true, includeSecrets: true, }); - (res as any).token = secret; - - return res; + return { ...res, token: secret }; }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts b/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts index 16232813a..a12dd9476 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts @@ -7,24 +7,10 @@ import { UserSuspendService } from '@/core/UserSuspendService.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireAdmin: true, -} as const; - -export const paramDef = { - type: 'object', - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/accounts/delete'> { + name = 'admin/accounts/delete' as const; constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -34,7 +20,7 @@ export default class extends Endpoint { private globalEventService: GlobalEventService, private userSuspendService: UserSuspendService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const user = await this.usersRepository.findOneBy({ id: ps.userId }); if (user == null) { diff --git a/packages/backend/src/server/api/endpoints/admin/ad/create.ts b/packages/backend/src/server/api/endpoints/admin/ad/create.ts index 917242db3..e36c94ebc 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/create.ts @@ -4,38 +4,17 @@ import type { AdsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, -} as const; - -export const paramDef = { - type: 'object', - properties: { - url: { type: 'string', minLength: 1 }, - memo: { type: 'string' }, - place: { type: 'string' }, - priority: { type: 'string' }, - ratio: { type: 'integer' }, - expiresAt: { type: 'integer' }, - startsAt: { type: 'integer' }, - imageUrl: { type: 'string', minLength: 1 }, - }, - required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'imageUrl'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/ad/create'> { + name = 'admin/ad/create' as const; constructor( @Inject(DI.adsRepository) private adsRepository: AdsRepository, private idService: IdService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { await this.adsRepository.insert({ id: this.idService.genId(), createdAt: new Date(), diff --git a/packages/backend/src/server/api/endpoints/admin/ad/delete.ts b/packages/backend/src/server/api/endpoints/admin/ad/delete.ts index f4c988540..f0f729ab7 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/delete.ts @@ -4,40 +4,18 @@ import type { AdsRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - errors: { - noSuchAd: { - message: 'No such ad.', - code: 'NO_SUCH_AD', - id: 'ccac9863-3a03-416e-b899-8a64041118b1', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - id: { type: 'string', format: 'misskey:id' }, - }, - required: ['id'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/ad/delete'> { + name = 'admin/ad/delete' as const; constructor( @Inject(DI.adsRepository) private adsRepository: AdsRepository, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const ad = await this.adsRepository.findOneBy({ id: ps.id }); - if (ad == null) throw new ApiError(meta.errors.noSuchAd); + if (ad == null) throw new ApiError(this.meta.errors.noSuchAd); await this.adsRepository.delete(ad.id); }); diff --git a/packages/backend/src/server/api/endpoints/admin/ad/list.ts b/packages/backend/src/server/api/endpoints/admin/ad/list.ts index 0b6d00605..0194ca226 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/list.ts @@ -23,14 +23,15 @@ export const paramDef = { // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/ad/list'> { + name = 'admin/ad/list' as const; constructor( @Inject(DI.adsRepository) private adsRepository: AdsRepository, private queryService: QueryService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId); const ads = await query.take(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/admin/ad/update.ts b/packages/backend/src/server/api/endpoints/admin/ad/update.ts index f692a7a84..da23ac625 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/update.ts @@ -4,37 +4,6 @@ import type { AdsRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - errors: { - noSuchAd: { - message: 'No such ad.', - code: 'NO_SUCH_AD', - id: 'b7aa1727-1354-47bc-a182-3a9c3973d300', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - id: { type: 'string', format: 'misskey:id' }, - memo: { type: 'string' }, - url: { type: 'string', minLength: 1 }, - imageUrl: { type: 'string', minLength: 1 }, - place: { type: 'string' }, - priority: { type: 'string' }, - ratio: { type: 'integer' }, - expiresAt: { type: 'integer' }, - startsAt: { type: 'integer' }, - }, - required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() export default class extends Endpoint<'admin/ad/update'> { 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 751b6be7f..3923b42dd 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts @@ -4,68 +4,17 @@ import type { AnnouncementsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - res: { - type: 'object', - optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string', - optional: false, nullable: false, - format: 'date-time', - }, - updatedAt: { - type: 'string', - optional: false, nullable: true, - format: 'date-time', - }, - title: { - type: 'string', - optional: false, nullable: false, - }, - text: { - type: 'string', - optional: false, nullable: false, - }, - imageUrl: { - type: 'string', - optional: false, nullable: true, - }, - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - title: { type: 'string', minLength: 1 }, - text: { type: 'string', minLength: 1 }, - imageUrl: { type: 'string', nullable: true, minLength: 1 }, - }, - required: ['title', 'text', 'imageUrl'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/announcements/create'> { + name = 'admin/announcements/create' as const; constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, private idService: IdService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const announcement = await this.announcementsRepository.insert({ id: this.idService.genId(), createdAt: new Date(), diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts b/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts index 18d50b8b2..6089b89c9 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts @@ -4,40 +4,18 @@ import type { AnnouncementsRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - errors: { - noSuchAnnouncement: { - message: 'No such announcement.', - code: 'NO_SUCH_ANNOUNCEMENT', - id: 'ecad8040-a276-4e85-bda9-015a708d291e', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - id: { type: 'string', format: 'misskey:id' }, - }, - required: ['id'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/announcements/delete'> { + name = 'admin/announcements/delete' as const; constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const announcement = await this.announcementsRepository.findOneBy({ id: ps.id }); - if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement); + if (announcement == null) throw new ApiError(this.meta.errors.noSuchAnnouncement); await this.announcementsRepository.delete(announcement.id); }); diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts index 9b2049412..b097dc149 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts @@ -5,69 +5,10 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string', - optional: false, nullable: false, - format: 'date-time', - }, - updatedAt: { - type: 'string', - optional: false, nullable: true, - format: 'date-time', - }, - text: { - type: 'string', - optional: false, nullable: false, - }, - title: { - type: 'string', - optional: false, nullable: false, - }, - imageUrl: { - type: 'string', - optional: false, nullable: true, - }, - reads: { - type: 'number', - optional: false, nullable: false, - }, - }, - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - }, - required: [], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/announcements/list'> { + name = 'admin/announcements/list' as const; constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, @@ -77,7 +18,7 @@ export default class extends Endpoint { private queryService: QueryService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId); const announcements = await query.take(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts index 2393c2441..c42f9f892 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts @@ -4,43 +4,18 @@ import type { AnnouncementsRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - errors: { - noSuchAnnouncement: { - message: 'No such announcement.', - code: 'NO_SUCH_ANNOUNCEMENT', - id: 'd3aae5a7-6372-4cb4-b61c-f511ffc2d7cc', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - id: { type: 'string', format: 'misskey:id' }, - title: { type: 'string', minLength: 1 }, - text: { type: 'string', minLength: 1 }, - imageUrl: { type: 'string', nullable: true, minLength: 1 }, - }, - required: ['id', 'title', 'text', 'imageUrl'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/announcements/update'> { + name = 'admin/announcements/update' as const; constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const announcement = await this.announcementsRepository.findOneBy({ id: ps.id }); - if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement); + if (announcement == null) throw new ApiError(this.meta.errors.noSuchAnnouncement); await this.announcementsRepository.update(announcement.id, { updatedAt: new Date(), diff --git a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts index a8964af44..650285333 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts @@ -2,26 +2,14 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueueService } from '@/core/QueueService.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, -} as const; - -export const paramDef = { - type: 'object', - properties: {}, - required: [], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/drive/clean-remote-files'> { + name = 'admin/drive/clean-remote-files' as const; constructor( private queueService: QueueService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { this.queueService.createCleanRemoteFilesJob(); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts index 4f7e02fe9..fcf94cdc6 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts @@ -5,29 +5,17 @@ import type { DriveFilesRepository } from '@/models/index.js'; import { DriveService } from '@/core/DriveService.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, -} as const; - -export const paramDef = { - type: 'object', - properties: {}, - required: [], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/drive/cleanup'> { + name = 'admin/drive/cleanup' as const; constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, private driveService: DriveService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const files = await this.driveFilesRepository.findBy({ userId: IsNull(), }); diff --git a/packages/backend/src/server/api/endpoints/admin/drive/files.ts b/packages/backend/src/server/api/endpoints/admin/drive/files.ts index 8a4498d5f..2aedec334 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/files.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/files.ts @@ -5,45 +5,10 @@ import { QueryService } from '@/core/QueryService.js'; import { DI } from '@/di-symbols.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'DriveFile', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - userId: { type: 'string', format: 'misskey:id', nullable: true }, - type: { type: 'string', nullable: true, pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1) }, - origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'local' }, - hostname: { - type: 'string', - nullable: true, - default: null, - description: 'The local host is represented with `null`.', - }, - }, - required: [], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/drive/files'> { + name = 'admin/drive/files' as const; constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -51,7 +16,7 @@ export default class extends Endpoint { private driveFileEntityService: DriveFileEntityService, private queryService: QueryService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId); if (ps.userId) { diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts index 1d27ac213..376cec16c 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts @@ -5,152 +5,10 @@ import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['admin'], - - requireCredential: true, - requireModerator: true, - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240', - }, - }, - - res: { - type: 'object', - optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string', - optional: false, nullable: false, - format: 'date-time', - }, - userId: { - type: 'string', - optional: false, nullable: true, - format: 'id', - example: 'xxxxxxxxxx', - }, - userHost: { - type: 'string', - optional: false, nullable: true, - description: 'The local host is represented with `null`.', - }, - md5: { - type: 'string', - optional: false, nullable: false, - format: 'md5', - example: '15eca7fba0480996e2245f5185bf39f2', - }, - name: { - type: 'string', - optional: false, nullable: false, - example: 'lenna.jpg', - }, - type: { - type: 'string', - optional: false, nullable: false, - example: 'image/jpeg', - }, - size: { - type: 'number', - optional: false, nullable: false, - example: 51469, - }, - comment: { - type: 'string', - optional: false, nullable: true, - }, - blurhash: { - type: 'string', - optional: false, nullable: true, - }, - properties: { - type: 'object', - optional: false, nullable: false, - }, - storedInternal: { - type: 'boolean', - optional: false, nullable: true, - example: true, - }, - url: { - type: 'string', - optional: false, nullable: true, - format: 'url', - }, - thumbnailUrl: { - type: 'string', - optional: false, nullable: true, - format: 'url', - }, - webpublicUrl: { - type: 'string', - optional: false, nullable: true, - format: 'url', - }, - accessKey: { - type: 'string', - optional: false, nullable: true, - }, - thumbnailAccessKey: { - type: 'string', - optional: false, nullable: true, - }, - webpublicAccessKey: { - type: 'string', - optional: false, nullable: true, - }, - uri: { - type: 'string', - optional: false, nullable: true, - }, - src: { - type: 'string', - optional: false, nullable: true, - }, - folderId: { - type: 'string', - optional: false, nullable: true, - format: 'id', - example: 'xxxxxxxxxx', - }, - isSensitive: { - type: 'boolean', - optional: false, nullable: false, - }, - isLink: { - type: 'boolean', - optional: false, nullable: false, - }, - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - fileId: { type: 'string', format: 'misskey:id' }, - url: { type: 'string' }, - }, - anyOf: [ - { required: ['fileId'] }, - { required: ['url'] }, - ], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'admin/drive/show-file'> { + name = 'admin/drive/show-file' as const; constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -160,7 +18,7 @@ export default class extends Endpoint { private roleService: RoleService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const file = ps.fileId ? await this.driveFilesRepository.findOneBy({ id: ps.fileId }) : await this.driveFilesRepository.findOne({ where: [{ url: ps.url, @@ -172,7 +30,7 @@ export default class extends Endpoint { }); if (file == null) { - throw new ApiError(meta.errors.noSuchFile); + throw new ApiError(this.meta.errors.noSuchFile); } const owner = file.userId ? await this.usersRepository.findOneByOrFail({ diff --git a/packages/misskey-js/src/api.ts b/packages/misskey-js/src/api.ts index 9ccd98396..dfce42c36 100644 --- a/packages/misskey-js/src/api.ts +++ b/packages/misskey-js/src/api.ts @@ -1,4 +1,5 @@ import type { Endpoints, SchemaOrUndefined, IEndpointMeta, ResponseOf } from './endpoints.types.js'; +import type { Serialized, WeakSerialized } from 'schema-type'; const MK_API_ERROR = Symbol(); @@ -42,9 +43,10 @@ export class APIClient { this.fetch = opts.fetch ?? ((...args) => fetch(...args)); } + // WeakSerialized

で推論が効くかは知らない public request, M extends IEndpointMeta = Endpoints[E], R = ResponseOf>( - endpoint: E, params: P, credential?: string | null | undefined, - ): Promise + endpoint: E, params: WeakSerialized

, credential?: string | null | undefined, + ): Promise> { const promise = new Promise((resolve, reject) => { this.fetch(`${this.origin}/api/${endpoint}`, { diff --git a/packages/misskey-js/src/endpoints.ts b/packages/misskey-js/src/endpoints.ts index 0836e813a..991ba037f 100644 --- a/packages/misskey-js/src/endpoints.ts +++ b/packages/misskey-js/src/endpoints.ts @@ -269,7 +269,7 @@ export const endpoints = { res: undefined, }], }, - "admin/drive/clenaup": { + "admin/drive/cleanup": { tags: ['admin'], requireCredential: true, @@ -354,24 +354,94 @@ export const endpoints = { ], }, res: { - allOf: [{ - $ref: 'https://misskey-hub.net/api/schemas/DriveFile', - }, { - type: 'object', - properties: { - requestIp: { - type: ['string', 'null'], - }, - requestHeaders: { - oneOf: [{ - type: 'object', - }, { - type: 'null', - }], - } + type: 'object', + properties: { + id: { $ref: 'https://misskey-hub.net/api/schemas/Id' }, + createdAt: { type: 'string', format: 'date-time' }, + userId: { + oneOf: [ + { $ref: 'https://misskey-hub.net/api/schemas/Id' }, + { type: 'null' }, + ] }, - required: ['requestIp', 'requestHeaders'], - }], + userHost: { type: ['string', 'null'] }, + md5: { type: 'string', format: 'md5', examples: '1bc29b36f623ba82aaf6724fd3b16718' }, + name: { type: 'string', examples: 'lenna.jpg' }, + type: { type: 'string', examples: 'image/jpeg' }, + size: { type: 'number', examples: 51469 }, + comment: { type: ['string', 'null'] }, + blurhash: { type: ['string', 'null'] }, + properties: { type: 'object' }, + storedInternal: { type: ['boolean', 'null'], examples: true }, + url: { + oneOf: [ + { type: 'string', format: 'url' }, + { type: 'null' }, + ], + }, + thumbnailUrl: { + oneOf: [ + { type: 'string', format: 'url' }, + { type: 'null' }, + ], + }, + webpublicUrl: { + oneOf: [ + { type: 'string', format: 'url' }, + { type: 'null' }, + ], + }, + accessKey: { type: ['string', 'null'] }, + thumbnailAccessKey: { type: ['string', 'null'] }, + webpublicAccessKey: { type: ['string', 'null'] }, + uri: { type: ['string', 'null'] }, + src: { type: ['string', 'null'] }, + folderId: { + oneOf: [ + { $ref: 'https://misskey-hub.net/api/schemas/Id' }, + { type: 'null' }, + ] + }, + isSensitive: { type: 'boolean' }, + isLink: { type: 'boolean' }, + requestIp: { + type: ['string', 'null'], + }, + requestHeaders: { + oneOf: [{ + type: 'object', + }, { + type: 'null', + }], + } + }, + required: [ + 'id', + 'createdAt', + 'userId', + 'userHost', + 'md5', + 'name', + 'type', + 'size', + 'comment', + 'blurhash', + 'properties', + 'storedInternal', + 'url', + 'thumbnailUrl', + 'webpublicUrl', + 'accessKey', + 'thumbnailAccessKey', + 'webpublicAccessKey', + 'uri', + 'src', + 'folderId', + 'isSensitive', + 'isLink', + 'requestIp', + 'requestHeaders', + ], }, }], }, diff --git a/packages/misskey-js/src/schemas/ad.ts b/packages/misskey-js/src/schemas/ad.ts index f198fc759..83b07087b 100644 --- a/packages/misskey-js/src/schemas/ad.ts +++ b/packages/misskey-js/src/schemas/ad.ts @@ -40,7 +40,6 @@ export const packedAdSchema = { 'expiresAt', 'startsAt', 'place', - 'property', 'ratio', 'imageUrl', 'memo', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b98240e2a..adebac5da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -626,7 +626,7 @@ importers: version: 29.5.0 schema-type: specifier: github:misskey-dev/schema-type - version: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4) + version: github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e(typescript@5.0.4) packages/frontend: dependencies: @@ -1026,7 +1026,7 @@ importers: version: 4.4.0 schema-type: specifier: github:misskey-dev/schema-type - version: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4) + version: github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e(typescript@5.0.4) ts-essentials: specifier: ^9.3.2 version: 9.3.2(typescript@5.0.4) @@ -20455,9 +20455,9 @@ packages: version: 0.0.0 dev: false - github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4): - resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/e24efd7bba40f638b3b687298873fa56de56aab3} - id: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3 + github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e(typescript@5.0.4): + resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/3e1f60a3486ad51a01912bd7bb092d5bcf47473e} + id: github.com/misskey-dev/schema-type/3e1f60a3486ad51a01912bd7bb092d5bcf47473e name: schema-type version: 1.0.0 dependencies: