diff --git a/packages/backend/src/server/api/endpoints/channels/create.ts b/packages/backend/src/server/api/endpoints/channels/create.ts index 69e2f2504c..593ab208de 100644 --- a/packages/backend/src/server/api/endpoints/channels/create.ts +++ b/packages/backend/src/server/api/endpoints/channels/create.ts @@ -8,49 +8,10 @@ import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['channels'], - - requireCredential: true, - - prohibitMoved: true, - - kind: 'write:channels', - - limit: { - duration: ms('1hour'), - max: 10, - }, - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'Channel', - }, - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - name: { type: 'string', minLength: 1, maxLength: 128 }, - description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, - bannerId: { type: 'string', format: 'misskey:id', nullable: true }, - color: { type: 'string', minLength: 1, maxLength: 16 }, - }, - required: ['name'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'channels/create'> { + name = 'channels/create' as const; constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -61,7 +22,7 @@ export default class extends Endpoint { private idService: IdService, private channelEntityService: ChannelEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { let banner = null; if (ps.bannerId != null) { banner = await this.driveFilesRepository.findOneBy({ @@ -70,7 +31,7 @@ export default class extends Endpoint { }); if (banner == null) { - throw new ApiError(meta.errors.noSuchFile); + throw new ApiError(this.meta.errors.noSuchFile); } } diff --git a/packages/backend/src/server/api/endpoints/channels/favorite.ts b/packages/backend/src/server/api/endpoints/channels/favorite.ts index c8544273a1..77405da9eb 100644 --- a/packages/backend/src/server/api/endpoints/channels/favorite.ts +++ b/packages/backend/src/server/api/endpoints/channels/favorite.ts @@ -5,35 +5,10 @@ import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['channels'], - - requireCredential: true, - - prohibitMoved: true, - - kind: 'write:channels', - - errors: { - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: '4938f5f3-6167-4c04-9149-6607b7542861', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - channelId: { type: 'string', format: 'misskey:id' }, - }, - required: ['channelId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'channels/favorite'> { + name = 'channels/favorite' as const; constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, @@ -43,13 +18,13 @@ export default class extends Endpoint { private idService: IdService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const channel = await this.channelsRepository.findOneBy({ id: ps.channelId, }); if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); + throw new ApiError(this.meta.errors.noSuchChannel); } await this.channelFavoritesRepository.insert({ diff --git a/packages/backend/src/server/api/endpoints/channels/featured.ts b/packages/backend/src/server/api/endpoints/channels/featured.ts index 1a8d1164c7..095b8c6444 100644 --- a/packages/backend/src/server/api/endpoints/channels/featured.ts +++ b/packages/backend/src/server/api/endpoints/channels/featured.ts @@ -4,38 +4,17 @@ import type { ChannelsRepository } from '@/models/index.js'; import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['channels'], - - requireCredential: false, - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'Channel', - }, - }, -} 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<'channels/featured'> { + name = 'channels/featured' as const; constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, private channelEntityService: ChannelEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const query = this.channelsRepository.createQueryBuilder('channel') .where('channel.lastNotedAt IS NOT NULL') .andWhere('channel.isArchived = FALSE') diff --git a/packages/backend/src/server/api/endpoints/channels/follow.ts b/packages/backend/src/server/api/endpoints/channels/follow.ts index f3ca66cfd2..70a7e2ee16 100644 --- a/packages/backend/src/server/api/endpoints/channels/follow.ts +++ b/packages/backend/src/server/api/endpoints/channels/follow.ts @@ -6,35 +6,10 @@ import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['channels'], - - requireCredential: true, - - prohibitMoved: true, - - kind: 'write:channels', - - errors: { - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: 'c0031718-d573-4e85-928e-10039f1fbb68', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - channelId: { type: 'string', format: 'misskey:id' }, - }, - required: ['channelId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'channels/follow'> { + name = 'channels/follow' as const; constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, @@ -44,13 +19,13 @@ export default class extends Endpoint { private idService: IdService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const channel = await this.channelsRepository.findOneBy({ id: ps.channelId, }); if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); + throw new ApiError(this.meta.errors.noSuchChannel); } await this.channelFollowingsRepository.insert({ diff --git a/packages/backend/src/server/api/endpoints/channels/followed.ts b/packages/backend/src/server/api/endpoints/channels/followed.ts index f49f3105d5..0868c482ee 100644 --- a/packages/backend/src/server/api/endpoints/channels/followed.ts +++ b/packages/backend/src/server/api/endpoints/channels/followed.ts @@ -5,37 +5,10 @@ import { QueryService } from '@/core/QueryService.js'; import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['channels', 'account'], - - requireCredential: true, - - kind: 'read:channels', - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'Channel', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 }, - }, - required: [], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'channels/followed'> { + name = 'channels/followed' as const; constructor( @Inject(DI.channelFollowingsRepository) private channelFollowingsRepository: ChannelFollowingsRepository, @@ -43,7 +16,7 @@ export default class extends Endpoint { private channelEntityService: ChannelEntityService, private queryService: QueryService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const query = this.queryService.makePaginationQuery(this.channelFollowingsRepository.createQueryBuilder(), ps.sinceId, ps.untilId) .andWhere({ followerId: me.id }); diff --git a/packages/misskey-js/src/endpoints.ts b/packages/misskey-js/src/endpoints.ts index fb291a9a37..c34ecf1b1d 100644 --- a/packages/misskey-js/src/endpoints.ts +++ b/packages/misskey-js/src/endpoints.ts @@ -2593,6 +2593,153 @@ export const endpoints = { }], }, //#endregion + + //#region channels + 'channels/create': { + tags: ['channels'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:channels', + + limit: { + duration: ms('1hour'), + max: 10, + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + name: { type: 'string', minLength: 1, maxLength: 128 }, + description: { + oneOf: [ + { type: 'string', minLength: 1, maxLength: 2048 }, + { type: 'null' }, + ], + }, + bannerId: { + oneOf: [ + { type: 'string', format: 'misskey:id' }, + { type: 'null' }, + ], + }, + color: { type: 'string', minLength: 1, maxLength: 16 }, + }, + required: ['name'], + }, + res: { + $ref: 'https://misskey-hub.net/api/schemas/Channel', + } + }], + }, + 'channels/favorite': { + tags: ['channels'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:channels', + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: '4938f5f3-6167-4c04-9149-6607b7542861', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + channelId: { type: 'string', format: 'misskey:id' }, + }, + required: ['channelId'], + }, + res: undefined, + }] + }, + 'channels/featured': { + tags: ['channels'], + + requireCredential: false, + + defines: [{ + req: undefined, + res: { + type: 'array', + items: { + $ref: 'https://misskey-hub.net/api/schemas/Channel', + }, + }, + }], + }, + 'channels/follow': { + tags: ['channels'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:channels', + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: 'c0031718-d573-4e85-928e-10039f1fbb68', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + channelId: { type: 'string', format: 'misskey:id' }, + }, + required: ['channelId'], + }, + res: undefined, + }], + }, + 'channels/followed': { + tags: ['channels', 'account'], + + requireCredential: true, + + kind: 'read:channels', + + defines: [{ + req: { + type: 'object', + properties: { + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 }, + }, + required: [], + }, + res: { + type: 'array', + items: { + $ref: 'https://misskey-hub.net/api/schemas/Channel', + }, + }, + }], + }, + //#endregion } as const satisfies { [x: string]: IEndpointMeta; }; /**