mizzkey/packages/backend/src/server/api/endpoints/clips/add-note.ts

116 lines
2.9 KiB
TypeScript
Raw Normal View History

2022-09-17 20:27:08 +02:00
import { Inject, Injectable } from '@nestjs/common';
import ms from 'ms';
2022-09-17 20:27:08 +02:00
import { Endpoint } from '@/server/api/endpoint-base.js';
import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js';
2022-09-20 22:33:11 +02:00
import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js';
2022-09-24 00:15:16 +02:00
import { GetterService } from '@/server/api/GetterService.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';
2020-11-15 04:04:54 +01:00
export const meta = {
tags: ['account', 'notes', 'clips'],
refactor: APIエンドポイントファイルの定義を良い感じにする (#8154) * Fix API Schema Error * Delete SimpleSchema/SimpleObj and Move schemas to dedicated files * Userのスキーマを分割してみる * define packMany type * add , * Ensure enum schema and Make "as const" put once * test? * Revert "test?" This reverts commit 97dc9bfa70851bfb7d1cf38e883f8df20fb78b79. * Revert "Fix API Schema Error" This reverts commit 21b6176d974ed8e3eb73723ad21a105c5d297323. * :v: * clean up * test? * wip * wip * better schema def * :v: * fix * add minLength property * wip * wip * wip * anyOf/oneOf/allOfに対応? ~ relation.ts * refactor! * Define MinimumSchema * wip * wip * anyOf/oneOf/allOfが動作するようにUnionSchemaTypeを修正 * anyOf/oneOf/allOfが動作するようにUnionSchemaTypeを修正 * Update packages/backend/src/misc/schema.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * fix * array oneOfをより正確な型に * array oneOfをより正確な型に * wip * :v: * なんかもういろいろ * remove * very good schema * api schema * wip * refactor: awaitAllの型定義を変えてみる * fix * specify types in awaitAll * specify types in awaitAll * :v: * wip * ... * :v: * AllowDateはやめておく * 不必要なoptional: false, nullable: falseを廃止 * Packedが展開されないように * 続packed * wip * define note type * wip * UserDetailedをMeDetailedかUserDetailedNotMeかを区別できるように * wip * wip * wip specify user type of other schemas * ok * convertSchemaToOpenApiSchemaを改修 * convertSchemaToOpenApiSchemaを改修 * Fix * fix * :v: * wip * 分割代入ではなくallOfで定義するように Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2022-01-18 14:27:10 +01:00
requireCredential: true,
2020-11-15 04:04:54 +01:00
kind: 'write:account',
limit: {
duration: ms('1hour'),
max: 20,
},
2020-11-15 04:04:54 +01:00
errors: {
noSuchClip: {
message: 'No such clip.',
code: 'NO_SUCH_CLIP',
2021-12-09 15:58:30 +01:00
id: 'd6e76cc0-a1b5-4c7c-a287-73fa9c716dcf',
2020-11-15 04:04:54 +01:00
},
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
2021-12-09 15:58:30 +01:00
id: 'fc8c0b49-c7a3-4664-a0a6-b418d386bb8b',
2020-11-15 04:04:54 +01:00
},
alreadyClipped: {
message: 'The note has already been clipped.',
code: 'ALREADY_CLIPPED',
2021-12-09 15:58:30 +01:00
id: '734806c4-542c-463a-9311-15c512803965',
2020-11-15 04:04:54 +01:00
},
tooManyClipNotes: {
message: 'You cannot add notes to the clip any more.',
code: 'TOO_MANY_CLIP_NOTES',
id: 'f0dba960-ff73-4615-8df4-d6ac5d9dc118',
},
2021-12-09 15:58:30 +01:00
},
refactor: APIエンドポイントファイルの定義を良い感じにする (#8154) * Fix API Schema Error * Delete SimpleSchema/SimpleObj and Move schemas to dedicated files * Userのスキーマを分割してみる * define packMany type * add , * Ensure enum schema and Make "as const" put once * test? * Revert "test?" This reverts commit 97dc9bfa70851bfb7d1cf38e883f8df20fb78b79. * Revert "Fix API Schema Error" This reverts commit 21b6176d974ed8e3eb73723ad21a105c5d297323. * :v: * clean up * test? * wip * wip * better schema def * :v: * fix * add minLength property * wip * wip * wip * anyOf/oneOf/allOfに対応? ~ relation.ts * refactor! * Define MinimumSchema * wip * wip * anyOf/oneOf/allOfが動作するようにUnionSchemaTypeを修正 * anyOf/oneOf/allOfが動作するようにUnionSchemaTypeを修正 * Update packages/backend/src/misc/schema.ts Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * fix * array oneOfをより正確な型に * array oneOfをより正確な型に * wip * :v: * なんかもういろいろ * remove * very good schema * api schema * wip * refactor: awaitAllの型定義を変えてみる * fix * specify types in awaitAll * specify types in awaitAll * :v: * wip * ... * :v: * AllowDateはやめておく * 不必要なoptional: false, nullable: falseを廃止 * Packedが展開されないように * 続packed * wip * define note type * wip * UserDetailedをMeDetailedかUserDetailedNotMeかを区別できるように * wip * wip * wip specify user type of other schemas * ok * convertSchemaToOpenApiSchemaを改修 * convertSchemaToOpenApiSchemaを改修 * Fix * fix * :v: * wip * 分割代入ではなくallOfで定義するように Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2022-01-18 14:27:10 +01:00
} as const;
2020-11-15 04:04:54 +01:00
export const paramDef = {
type: 'object',
properties: {
clipId: { type: 'string', format: 'misskey:id' },
noteId: { type: 'string', format: 'misskey:id' },
},
required: ['clipId', 'noteId'],
} as const;
2022-01-02 18:12:50 +01:00
// eslint-disable-next-line import/no-default-export
2022-09-17 20:27:08 +02:00
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.clipsRepository)
private clipsRepository: ClipsRepository,
2020-11-15 04:04:54 +01:00
2022-09-17 20:27:08 +02:00
@Inject(DI.clipNotesRepository)
private clipNotesRepository: ClipNotesRepository,
2020-11-15 04:04:54 +01:00
2022-09-17 20:27:08 +02:00
private idService: IdService,
private roleService: RoleService,
2022-09-17 20:27:08 +02:00
private getterService: GetterService,
) {
super(meta, paramDef, async (ps, me) => {
const clip = await this.clipsRepository.findOneBy({
id: ps.clipId,
userId: me.id,
});
2020-11-15 04:04:54 +01:00
2022-09-17 20:27:08 +02:00
if (clip == null) {
throw new ApiError(meta.errors.noSuchClip);
}
2020-11-15 04:04:54 +01:00
2022-09-17 20:27:08 +02:00
const note = await this.getterService.getNote(ps.noteId).catch(e => {
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
throw e;
});
const exist = await this.clipNotesRepository.findOneBy({
noteId: note.id,
clipId: clip.id,
});
2020-11-15 04:04:54 +01:00
2022-09-17 20:27:08 +02:00
if (exist != null) {
throw new ApiError(meta.errors.alreadyClipped);
}
const currentCount = await this.clipNotesRepository.countBy({
clipId: clip.id,
});
if (currentCount > (await this.roleService.getUserPolicies(me.id)).noteEachClipsLimit) {
throw new ApiError(meta.errors.tooManyClipNotes);
}
2022-09-17 20:27:08 +02:00
await this.clipNotesRepository.insert({
id: this.idService.genId(),
noteId: note.id,
clipId: clip.id,
});
2023-03-16 09:24:49 +01:00
await this.clipsRepository.update(clip.id, {
lastClippedAt: new Date(),
});
2022-09-17 20:27:08 +02:00
});
}
}