diff --git a/packages/backend/src/server/api/endpoints/channels/show.ts b/packages/backend/src/server/api/endpoints/channels/show.ts index 070d14631e..37a9b7297a 100644 --- a/packages/backend/src/server/api/endpoints/channels/show.ts +++ b/packages/backend/src/server/api/endpoints/channels/show.ts @@ -5,50 +5,23 @@ import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['channels'], - - requireCredential: false, - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'Channel', - }, - - errors: { - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: '6f6c314b-7486-4897-8966-c04a66a02923', - }, - }, -} 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/show'> { + name = 'channels/show' as const; constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, private channelEntityService: ChannelEntityService, ) { - 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); } return await this.channelEntityService.pack(channel, me, true); diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index c881074bab..3c0aead612 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -9,46 +9,10 @@ import { DI } from '@/di-symbols.js'; import { IdService } from '@/core/IdService.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['notes', 'channels'], - - requireCredential: false, - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'Note', - }, - }, - - errors: { - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: '4d0eeeba-a02c-4c3c-9966-ef60d38d2e7f', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - channelId: { type: 'string', format: 'misskey:id' }, - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - sinceDate: { type: 'integer' }, - untilDate: { type: 'integer' }, - }, - required: ['channelId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'channels/timeline'> { + name = 'channels/timeline' as const; constructor( @Inject(DI.redis) private redisClient: Redis.Redis, @@ -64,13 +28,13 @@ export default class extends Endpoint { private queryService: QueryService, private activeUsersChart: ActiveUsersChart, ) { - 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); } let timeline: Note[] = []; diff --git a/packages/backend/src/server/api/endpoints/channels/unfavorite.ts b/packages/backend/src/server/api/endpoints/channels/unfavorite.ts index 67fb1ea03e..cd79edcb75 100644 --- a/packages/backend/src/server/api/endpoints/channels/unfavorite.ts +++ b/packages/backend/src/server/api/endpoints/channels/unfavorite.ts @@ -4,35 +4,10 @@ import type { ChannelFavoritesRepository, ChannelsRepository } from '@/models/in 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: '353c68dd-131a-476c-aa99-88a345e83668', - }, - }, -} 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/unfavorite'> { + name = 'channels/unfavorite' as const; constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, @@ -40,13 +15,13 @@ export default class extends Endpoint { @Inject(DI.channelFavoritesRepository) private channelFavoritesRepository: ChannelFavoritesRepository, ) { - 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.delete({ diff --git a/packages/backend/src/server/api/endpoints/channels/unfollow.ts b/packages/backend/src/server/api/endpoints/channels/unfollow.ts index f46ff9f286..429ef4c410 100644 --- a/packages/backend/src/server/api/endpoints/channels/unfollow.ts +++ b/packages/backend/src/server/api/endpoints/channels/unfollow.ts @@ -5,35 +5,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: '19959ee9-0153-4c51-bbd9-a98c49dc59d6', - }, - }, -} 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/unfollow'> { + name = 'channels/unfollow' as const; constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, @@ -41,13 +16,13 @@ export default class extends Endpoint { @Inject(DI.channelFollowingsRepository) private channelFollowingsRepository: ChannelFollowingsRepository, ) { - 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.delete({ diff --git a/packages/backend/src/server/api/endpoints/channels/update.ts b/packages/backend/src/server/api/endpoints/channels/update.ts index 30d7f8b244..fdddbd877f 100644 --- a/packages/backend/src/server/api/endpoints/channels/update.ts +++ b/packages/backend/src/server/api/endpoints/channels/update.ts @@ -6,62 +6,10 @@ import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['channels'], - - requireCredential: true, - - kind: 'write:channels', - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'Channel', - }, - - errors: { - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: 'f9c5467f-d492-4c3c-9a8d-a70dacc86512', - }, - - accessDenied: { - message: 'You do not have edit privilege of the channel.', - code: 'ACCESS_DENIED', - id: '1fb7cb09-d46a-4fdf-b8df-057788cce513', - }, - - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'e86c14a4-0da2-4032-8df3-e737a04c7f3b', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - channelId: { type: 'string', format: 'misskey:id' }, - name: { type: 'string', minLength: 1, maxLength: 128 }, - description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, - bannerId: { type: 'string', format: 'misskey:id', nullable: true }, - isArchived: { type: 'boolean', nullable: true }, - pinnedNoteIds: { - type: 'array', - items: { - type: 'string', format: 'misskey:id', - }, - }, - color: { type: 'string', minLength: 1, maxLength: 16 }, - }, - required: ['channelId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'channels/update'> { + name = 'channels/update' as const; constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, @@ -73,18 +21,18 @@ export default class extends Endpoint { private roleService: RoleService, ) { - 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); } const iAmModerator = await this.roleService.isModerator(me); if (channel.userId !== me.id && !iAmModerator) { - throw new ApiError(meta.errors.accessDenied); + throw new ApiError(this.meta.errors.accessDenied); } // eslint:disable-next-line:no-unnecessary-initializer @@ -96,7 +44,7 @@ export default class extends Endpoint { }); if (banner == null) { - throw new ApiError(meta.errors.noSuchFile); + throw new ApiError(this.meta.errors.noSuchFile); } } else if (ps.bannerId === null) { banner = null; diff --git a/packages/misskey-js/src/endpoints.ts b/packages/misskey-js/src/endpoints.ts index ee03883b62..6597d51026 100644 --- a/packages/misskey-js/src/endpoints.ts +++ b/packages/misskey-js/src/endpoints.ts @@ -2806,6 +2806,183 @@ export const endpoints = { }, }], }, + 'channels/show': { + tags: ['channels'], + + requireCredential: false, + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: '6f6c314b-7486-4897-8966-c04a66a02923', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + channelId: { type: 'string', format: 'misskey:id' }, + }, + required: ['channelId'], + }, + res: { + $ref: 'https://misskey-hub.net/api/schemas/Channel', + }, + }], + }, + 'channels/timeline': { + tags: ['notes', 'channels'], + + requireCredential: false, + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: '4d0eeeba-a02c-4c3c-9966-ef60d38d2e7f', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + channelId: { type: 'string', format: 'misskey:id' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + }, + required: ['channelId'], + }, + res: { + type: 'array', + items: { + $ref: 'https://misskey-hub.net/api/schemas/Note', + }, + }, + }], + }, + 'channels/unfavorite': { + tags: ['channels'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:channels', + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: '353c68dd-131a-476c-aa99-88a345e83668', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + channelId: { type: 'string', format: 'misskey:id' }, + }, + required: ['channelId'], + }, + res: undefined, + }], + }, + 'channels/unfollow': { + tags: ['channels'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:channels', + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: '19959ee9-0153-4c51-bbd9-a98c49dc59d6', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + channelId: { type: 'string', format: 'misskey:id' }, + }, + required: ['channelId'], + }, + res: undefined, + }], + }, + 'channels/update': { + tags: ['channels'], + + requireCredential: true, + + kind: 'write:channels', + + errors: { + noSuchChannel: { + message: 'No such channel.', + code: 'NO_SUCH_CHANNEL', + id: 'f9c5467f-d492-4c3c-9a8d-a70dacc86512', + }, + + accessDenied: { + message: 'You do not have edit privilege of the channel.', + code: 'ACCESS_DENIED', + id: '1fb7cb09-d46a-4fdf-b8df-057788cce513', + }, + + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'e86c14a4-0da2-4032-8df3-e737a04c7f3b', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + channelId: { type: 'string', format: 'misskey:id' }, + 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' }, + ], + }, + isArchived: { type: ['boolean', 'true'] }, + pinnedNoteIds: { + type: 'array', + items: { + type: 'string', format: 'misskey:id', + }, + }, + color: { type: 'string', minLength: 1, maxLength: 16 }, + }, + required: ['channelId'], + }, + res: { + $ref: 'https://misskey-hub.net/api/schemas/Channel', + }, + }], + }, //#endregion } as const satisfies { [x: string]: IEndpointMeta; };