diff --git a/packages/backend/src/server/api/endpoints/clips/create.ts b/packages/backend/src/server/api/endpoints/clips/create.ts index 5395a5c373..356cef8279 100644 --- a/packages/backend/src/server/api/endpoints/clips/create.ts +++ b/packages/backend/src/server/api/endpoints/clips/create.ts @@ -7,30 +7,6 @@ import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; import { ApiError } from '@/server/api/error.js'; -export const meta = { - tags: ['clips'], - - requireCredential: true, - - prohibitMoved: true, - - kind: 'write:account', - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'Clip', - }, - - errors: { - tooManyClips: { - message: 'You cannot create clip any more.', - code: 'TOO_MANY_CLIPS', - id: '920f7c2d-6208-4b76-8082-e632020f5883', - }, - }, -} as const; - export const paramDef = { type: 'object', properties: { @@ -43,7 +19,8 @@ export const paramDef = { // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'clips/create'> { + name = 'clips/create' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, @@ -52,12 +29,12 @@ export default class extends Endpoint { private roleService: RoleService, private idService: IdService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const currentCount = await this.clipsRepository.countBy({ userId: me.id, }); if (currentCount > (await this.roleService.getUserPolicies(me.id)).clipLimit) { - throw new ApiError(meta.errors.tooManyClips); + throw new ApiError(this.meta.errors.tooManyClips); } const clip = await this.clipsRepository.insert({ diff --git a/packages/backend/src/server/api/endpoints/clips/delete.ts b/packages/backend/src/server/api/endpoints/clips/delete.ts index 077a9ec40f..216c8ed17b 100644 --- a/packages/backend/src/server/api/endpoints/clips/delete.ts +++ b/packages/backend/src/server/api/endpoints/clips/delete.ts @@ -4,45 +4,22 @@ import type { ClipsRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['clips'], - - requireCredential: true, - - kind: 'write:account', - - errors: { - noSuchClip: { - message: 'No such clip.', - code: 'NO_SUCH_CLIP', - id: '70ca08ba-6865-4630-b6fb-8494759aa754', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - clipId: { type: 'string', format: 'misskey:id' }, - }, - required: ['clipId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'clips/delete'> { + name = 'clips/delete' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const clip = await this.clipsRepository.findOneBy({ id: ps.clipId, userId: me.id, }); if (clip == null) { - throw new ApiError(meta.errors.noSuchClip); + throw new ApiError(this.meta.errors.noSuchClip); } await this.clipsRepository.delete(clip.id); diff --git a/packages/backend/src/server/api/endpoints/clips/favorite.ts b/packages/backend/src/server/api/endpoints/clips/favorite.ts index f08caaf8d7..d041f98832 100644 --- a/packages/backend/src/server/api/endpoints/clips/favorite.ts +++ b/packages/backend/src/server/api/endpoints/clips/favorite.ts @@ -5,41 +5,10 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['clip'], - - requireCredential: true, - - prohibitMoved: true, - - kind: 'write:clip-favorite', - - errors: { - noSuchClip: { - message: 'No such clip.', - code: 'NO_SUCH_CLIP', - id: '4c2aaeae-80d8-4250-9606-26cb1fdb77a5', - }, - - alreadyFavorited: { - message: 'The clip has already been favorited.', - code: 'ALREADY_FAVORITED', - id: '92658936-c625-4273-8326-2d790129256e', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - clipId: { type: 'string', format: 'misskey:id' }, - }, - required: ['clipId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'clips/favorite'> { + name = 'clips/favorite' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, @@ -49,13 +18,13 @@ export default class extends Endpoint { private idService: IdService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const clip = await this.clipsRepository.findOneBy({ id: ps.clipId }); if (clip == null) { - throw new ApiError(meta.errors.noSuchClip); + throw new ApiError(this.meta.errors.noSuchClip); } if ((clip.userId !== me.id) && !clip.isPublic) { - throw new ApiError(meta.errors.noSuchClip); + throw new ApiError(this.meta.errors.noSuchClip); } const exist = await this.clipFavoritesRepository.findOneBy({ @@ -64,7 +33,7 @@ export default class extends Endpoint { }); if (exist != null) { - throw new ApiError(meta.errors.alreadyFavorited); + throw new ApiError(this.meta.errors.alreadyFavorited); } await this.clipFavoritesRepository.insert({ diff --git a/packages/backend/src/server/api/endpoints/clips/list.ts b/packages/backend/src/server/api/endpoints/clips/list.ts index 3b8deab709..790488a2d9 100644 --- a/packages/backend/src/server/api/endpoints/clips/list.ts +++ b/packages/backend/src/server/api/endpoints/clips/list.ts @@ -4,40 +4,17 @@ import type { ClipsRepository } from '@/models/index.js'; import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; import { DI } from '@/di-symbols.js'; -export const meta = { - tags: ['clips', 'account'], - - requireCredential: true, - - kind: 'read:account', - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'Clip', - }, - }, -} 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<'clips/list'> { + name = 'clips/list' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, private clipEntityService: ClipEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const clips = await this.clipsRepository.findBy({ userId: me.id, }); diff --git a/packages/misskey-js/src/endpoints.ts b/packages/misskey-js/src/endpoints.ts index a654857ea5..8d6a96b822 100644 --- a/packages/misskey-js/src/endpoints.ts +++ b/packages/misskey-js/src/endpoints.ts @@ -3227,37 +3227,37 @@ export const endpoints = { //#region clips 'clips/add-note': { tags: ['account', 'notes', 'clips'], - + requireCredential: true, - + prohibitMoved: true, - + kind: 'write:account', - + limit: { duration: ms('1hour'), max: 20, }, - + errors: { noSuchClip: { message: 'No such clip.', code: 'NO_SUCH_CLIP', id: 'd6e76cc0-a1b5-4c7c-a287-73fa9c716dcf', }, - + noSuchNote: { message: 'No such note.', code: 'NO_SUCH_NOTE', id: 'fc8c0b49-c7a3-4664-a0a6-b418d386bb8b', }, - + alreadyClipped: { message: 'The note has already been clipped.', code: 'ALREADY_CLIPPED', id: '734806c4-542c-463a-9311-15c512803965', }, - + tooManyClipNotes: { message: 'You cannot add notes to the clip any more.', code: 'TOO_MANY_CLIP_NOTES', @@ -3277,6 +3277,115 @@ export const endpoints = { res: undefined, }] }, + 'clips/create': { + tags: ['clips'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:account', + + errors: { + tooManyClips: { + message: 'You cannot create clip any more.', + code: 'TOO_MANY_CLIPS', + id: '920f7c2d-6208-4b76-8082-e632020f5883', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + name: { type: 'string', minLength: 1, maxLength: 100 }, + isPublic: { type: 'boolean', default: false }, + description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, + }, + required: ['name'], + }, + res: { + $ref: 'https://misskey-hub.net/api/schemas/Clip', + }, + }], + }, + 'clips/delete': { + tags: ['clips'], + + requireCredential: true, + + kind: 'write:account', + + errors: { + noSuchClip: { + message: 'No such clip.', + code: 'NO_SUCH_CLIP', + id: '70ca08ba-6865-4630-b6fb-8494759aa754', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + clipId: { type: 'string', format: 'misskey:id' }, + }, + required: ['clipId'], + }, + res: undefined, + }] + }, + 'clips/favorite': { + tags: ['clip'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:clip-favorite', + + errors: { + noSuchClip: { + message: 'No such clip.', + code: 'NO_SUCH_CLIP', + id: '4c2aaeae-80d8-4250-9606-26cb1fdb77a5', + }, + + alreadyFavorited: { + message: 'The clip has already been favorited.', + code: 'ALREADY_FAVORITED', + id: '92658936-c625-4273-8326-2d790129256e', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + clipId: { type: 'string', format: 'misskey:id' }, + }, + required: ['clipId'], + }, + res: undefined, + }], + }, + 'clips/list': { + tags: ['clips', 'account'], + + requireCredential: true, + + kind: 'read:account', + + defines: [{ + req: undefined, + res: { + type: 'array', + items: { + $ref: 'https://misskey-hub.net/api/schemas/Clip', + }, + } + }], + } //#endregion } as const satisfies { [x: string]: IEndpointMeta; };