diff --git a/packages/backend/src/server/api/endpoints/clips/my-favorites.ts b/packages/backend/src/server/api/endpoints/clips/my-favorites.ts index fc727e93bd..ddb90cbb7a 100644 --- a/packages/backend/src/server/api/endpoints/clips/my-favorites.ts +++ b/packages/backend/src/server/api/endpoints/clips/my-favorites.ts @@ -4,41 +4,17 @@ import type { ClipFavoritesRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; -export const meta = { - tags: ['account', 'clip'], - - requireCredential: true, - - kind: 'read:clip-favorite', - - 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/my-favorites'> { + name = 'clips/my-favorites' as const; constructor( @Inject(DI.clipFavoritesRepository) private clipFavoritesRepository: ClipFavoritesRepository, private clipEntityService: ClipEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { const query = this.clipFavoritesRepository.createQueryBuilder('favorite') .andWhere('favorite.userId = :meId', { meId: me.id }) .leftJoinAndSelect('favorite.clip', 'clip'); diff --git a/packages/backend/src/server/api/endpoints/clips/notes.ts b/packages/backend/src/server/api/endpoints/clips/notes.ts index dcb415b752..4ab90667d0 100644 --- a/packages/backend/src/server/api/endpoints/clips/notes.ts +++ b/packages/backend/src/server/api/endpoints/clips/notes.ts @@ -6,46 +6,10 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['account', 'notes', 'clips'], - - requireCredential: false, - - kind: 'read:account', - - errors: { - noSuchClip: { - message: 'No such clip.', - code: 'NO_SUCH_CLIP', - id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00', - }, - }, - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'Note', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - clipId: { 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' }, - }, - required: ['clipId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'clips/notes'> { + name = 'clips/notes' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, @@ -59,17 +23,17 @@ export default class extends Endpoint { private noteEntityService: NoteEntityService, private queryService: QueryService, ) { - 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.isPublic && (me == null || (clip.userId !== me.id))) { - throw new ApiError(meta.errors.noSuchClip); + throw new ApiError(this.meta.errors.noSuchClip); } const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) diff --git a/packages/backend/src/server/api/endpoints/clips/remove-note.ts b/packages/backend/src/server/api/endpoints/clips/remove-note.ts index 50c5d758bd..d8d8ba057e 100644 --- a/packages/backend/src/server/api/endpoints/clips/remove-note.ts +++ b/packages/backend/src/server/api/endpoints/clips/remove-note.ts @@ -5,42 +5,10 @@ import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; import { GetterService } from '@/server/api/GetterService.js'; -export const meta = { - tags: ['account', 'notes', 'clips'], - - requireCredential: true, - - prohibitMoved: true, - - kind: 'write:account', - - errors: { - noSuchClip: { - message: 'No such clip.', - code: 'NO_SUCH_CLIP', - id: 'b80525c6-97f7-49d7-a42d-ebccd49cfd52', - }, - - noSuchNote: { - message: 'No such note.', - code: 'NO_SUCH_NOTE', - id: 'aff017de-190e-434b-893e-33a9ff5049d8', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - clipId: { type: 'string', format: 'misskey:id' }, - noteId: { type: 'string', format: 'misskey:id' }, - }, - required: ['clipId', 'noteId'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'clips/remove-note'> { + name = 'clips/remove-note' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, @@ -50,18 +18,18 @@ export default class extends Endpoint { private getterService: GetterService, ) { - 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); } const note = await this.getterService.getNote(ps.noteId).catch(err => { - if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); + if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(this.meta.errors.noSuchNote); throw err; }); diff --git a/packages/backend/src/server/api/endpoints/clips/show.ts b/packages/backend/src/server/api/endpoints/clips/show.ts index 99d630a9b5..e0cfc35d15 100644 --- a/packages/backend/src/server/api/endpoints/clips/show.ts +++ b/packages/backend/src/server/api/endpoints/clips/show.ts @@ -5,57 +5,28 @@ import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['clips', 'account'], - - requireCredential: false, - - kind: 'read:account', - - errors: { - noSuchClip: { - message: 'No such clip.', - code: 'NO_SUCH_CLIP', - id: 'c3c5fe33-d62c-44d2-9ea5-d997703f5c20', - }, - }, - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'Clip', - }, -} 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/show'> { + name = 'clips/show' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, private clipEntityService: ClipEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { // Fetch the clip 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.isPublic && (me == null || (clip.userId !== me.id))) { - throw new ApiError(meta.errors.noSuchClip); + throw new ApiError(this.meta.errors.noSuchClip); } return await this.clipEntityService.pack(clip, me); diff --git a/packages/backend/src/server/api/endpoints/clips/unfavorite.ts b/packages/backend/src/server/api/endpoints/clips/unfavorite.ts index 3da252a226..16a3e318b4 100644 --- a/packages/backend/src/server/api/endpoints/clips/unfavorite.ts +++ b/packages/backend/src/server/api/endpoints/clips/unfavorite.ts @@ -4,41 +4,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: '2603966e-b865-426c-94a7-af4a01241dc1', - }, - - notFavorited: { - message: 'You have not favorited the clip.', - code: 'NOT_FAVORITED', - id: '90c3a9e8-b321-4dae-bf57-2bf79bbcc187', - }, - }, -} 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/unfavorite'> { + name = 'clips/unfavorite' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, @@ -46,10 +15,10 @@ export default class extends Endpoint { @Inject(DI.clipFavoritesRepository) private clipFavoritesRepository: ClipFavoritesRepository, ) { - 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); } const exist = await this.clipFavoritesRepository.findOneBy({ @@ -58,7 +27,7 @@ export default class extends Endpoint { }); if (exist == null) { - throw new ApiError(meta.errors.notFavorited); + throw new ApiError(this.meta.errors.notFavorited); } await this.clipFavoritesRepository.delete(exist.id); diff --git a/packages/backend/src/server/api/endpoints/clips/update.ts b/packages/backend/src/server/api/endpoints/clips/update.ts index 70f1959353..adecd82b29 100644 --- a/packages/backend/src/server/api/endpoints/clips/update.ts +++ b/packages/backend/src/server/api/endpoints/clips/update.ts @@ -5,51 +5,17 @@ import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; -export const meta = { - tags: ['clips'], - - requireCredential: true, - - prohibitMoved: true, - - kind: 'write:account', - - errors: { - noSuchClip: { - message: 'No such clip.', - code: 'NO_SUCH_CLIP', - id: 'b4d92d70-b216-46fa-9a3f-a8c811699257', - }, - }, - - res: { - type: 'object', - optional: false, nullable: false, - ref: 'Clip', - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - clipId: { type: 'string', format: 'misskey:id' }, - name: { type: 'string', minLength: 1, maxLength: 100 }, - isPublic: { type: 'boolean' }, - description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, - }, - required: ['clipId', 'name'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'clips/update'> { + name = 'clips/update' as const; constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, private clipEntityService: ClipEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { // Fetch the clip const clip = await this.clipsRepository.findOneBy({ id: ps.clipId, @@ -57,7 +23,7 @@ export default class extends Endpoint { }); if (clip == null) { - throw new ApiError(meta.errors.noSuchClip); + throw new ApiError(this.meta.errors.noSuchClip); } await this.clipsRepository.update(clip.id, { diff --git a/packages/misskey-js/src/endpoints.ts b/packages/misskey-js/src/endpoints.ts index 8d6a96b822..90c0eccc73 100644 --- a/packages/misskey-js/src/endpoints.ts +++ b/packages/misskey-js/src/endpoints.ts @@ -3385,7 +3385,188 @@ export const endpoints = { }, } }], - } + }, + 'clips/my-favorites': { + tags: ['account', 'clip'], + + requireCredential: true, + + kind: 'read:clip-favorite', + + defines: [{ + req: undefined, + res: { + type: 'array', + items: { + $ref: 'https://misskey-hub.net/api/schemas/Clip', + }, + }, + }], + }, + 'clips/notes': { + tags: ['account', 'notes', 'clips'], + + requireCredential: false, + + kind: 'read:account', + + errors: { + noSuchClip: { + message: 'No such clip.', + code: 'NO_SUCH_CLIP', + id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + clipId: { 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' }, + }, + required: ['clipId'], + }, + res: { + type: 'array', + items: { + $ref: 'https://misskey-hub.net/api/schemas/Note', + }, + }, + }], + }, + 'clips/remove-note': { + tags: ['account', 'notes', 'clips'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:account', + + errors: { + noSuchClip: { + message: 'No such clip.', + code: 'NO_SUCH_CLIP', + id: 'b80525c6-97f7-49d7-a42d-ebccd49cfd52', + }, + + noSuchNote: { + message: 'No such note.', + code: 'NO_SUCH_NOTE', + id: 'aff017de-190e-434b-893e-33a9ff5049d8', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + clipId: { type: 'string', format: 'misskey:id' }, + noteId: { type: 'string', format: 'misskey:id' }, + }, + required: ['clipId', 'noteId'], + }, + res: undefined, + }], + }, + 'clips/show': { + tags: ['clips', 'account'], + + requireCredential: false, + + kind: 'read:account', + + errors: { + noSuchClip: { + message: 'No such clip.', + code: 'NO_SUCH_CLIP', + id: 'c3c5fe33-d62c-44d2-9ea5-d997703f5c20', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + clipId: { type: 'string', format: 'misskey:id' }, + }, + required: ['clipId'], + }, + res: { + $ref: 'https://misskey-hub.net/api/schemas/Clip', + }, + }], + }, + 'clips/unfavorite': { + tags: ['clip'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:clip-favorite', + + errors: { + noSuchClip: { + message: 'No such clip.', + code: 'NO_SUCH_CLIP', + id: '2603966e-b865-426c-94a7-af4a01241dc1', + }, + + notFavorited: { + message: 'You have not favorited the clip.', + code: 'NOT_FAVORITED', + id: '90c3a9e8-b321-4dae-bf57-2bf79bbcc187', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + clipId: { type: 'string', format: 'misskey:id' }, + }, + required: ['clipId'], + }, + res: undefined, + }] + }, + 'clips/update': { + tags: ['clips'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'write:account', + + errors: { + noSuchClip: { + message: 'No such clip.', + code: 'NO_SUCH_CLIP', + id: 'b4d92d70-b216-46fa-9a3f-a8c811699257', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + clipId: { type: 'string', format: 'misskey:id' }, + name: { type: 'string', minLength: 1, maxLength: 100 }, + isPublic: { type: 'boolean' }, + description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, + }, + required: ['clipId', 'name'], + }, + res: { + $ref: 'https://misskey-hub.net/api/schemas/Clip', + }, + }] + }, //#endregion } as const satisfies { [x: string]: IEndpointMeta; };