feat: note.isDeletable

This commit is contained in:
オスカー、 2025-01-07 18:49:56 +09:00
parent 9927231add
commit d485432661
Signed by: SWREI
GPG Key ID: 8947F3AF5B0B4BFE
19 changed files with 396 additions and 18 deletions

View File

@ -1340,7 +1340,7 @@ endingCreditMembers: "Users to display in the closing credits"
endingCreditMembersDescription: "IDs of users to display on the server information page, one per line."
emailAddressLogin: "Login with email address"
usernameLogin: "Login with username"
unarchive: "Unarchive"
_bubbleGame:
howToPlay: "How to play"
hold: "Hold"

4
locales/index.d.ts vendored
View File

@ -5528,6 +5528,10 @@ export interface Locale extends ILocale {
*
*/
"usernameLogin": string;
/**
*
*/
"unarchive": string;
"_bubbleGame": {
/**
*

View File

@ -1375,6 +1375,7 @@ endingCreditMembers: "スタッフロールに表示するユーザー"
endingCreditMembersDescription: "サーバー情報ページに表示するユーザーのIDを一行に一つずつ書きます。"
emailAddressLogin: "メールアドレスでログイン"
usernameLogin: "ユーザー名でログイン"
unarchive: "アーカイブ解除"
_bubbleGame:
howToPlay: "遊び方"

View File

@ -1296,8 +1296,8 @@ passkeyVerificationSucceededButPasswordlessLoginDisabled: "패스키를 검증
messageToFollower: "팔로워에 보낼 메시지"
target: "대상"
testCaptchaWarning: "CAPTCHA를 테스트하기 위한 기능입니다. <strong>실제 환경에서는 사용하지 마세요.</strong>"
prohibitedWordsForNameOfUser: "금지 단어 (사용자 이름)"
prohibitedWordsForNameOfUserDescription: "이 목록에 포함되는 키워드가 사용자 이름에 있는 경우, 일반 사용자는 이름을 바꿀 수 없습니다. 모더레이터 권한을 가진 사용자는 제한 대상에서 제외됩니다."
prohibitedWordsForNameOfUser: "금지 단어 (닉네임)"
prohibitedWordsForNameOfUserDescription: "이 목록에 포함되는 키워드가 닉네임에 있는 경우, 일반 유저는 이름을 바꿀 수 없습니다. 중재자는 제한 대상에서 제외됩니다."
yourNameContainsProhibitedWords: "바꾸려는 이름에 금지된 키워드가 포함되어 있습니다."
yourNameContainsProhibitedWordsDescription: "이름에 금지된 키워드가 있습니다. 이름을 사용해야 하는 경우, 서버 관리자에 문의하세요."
lockdown: "잠금"
@ -1346,7 +1346,7 @@ normalizeConfirm: "정상화 이후에는 계정을 되돌릴 수 없게 됩니
normalizeDescription: "정상화는 유저의 일괄적인 데이터 말소 및 계정 정지를 위한 기능으로, 계정 삭제와 비슷한 효과를 가지며, 실행 후에는 모든 신고가 닫히게 됩니다. 기능을 실행하고 나면 되돌릴 수 없는 점을 유의하시기 바랍니다."
useNormalization: "정상화 메뉴를 표시하기"
gtagConsentCustomize: "데이터 수집 및 개인정보 설정"
gtagConsentCustomizeDescription: "{host}에서 수집하는 데이터 범위를 사용자 지정할 수 있습니다.\n다만, 인증 기능, 부정 행위 방지, 기타 사용자 보호 등 보안과 관련된 정보 수집은 비활성화할 수 없습니다."
gtagConsentCustomizeDescription: "{host}에서 수집하는 데이터 범위를 설정할 수 있습니다.\n다만, 인증 기능, 부정 행위 방지, 기타 유저 보호 등 보안과 관련된 정보 수집은 비활성화할 수 없습니다."
gtagConsentAnalytics: "통계 정보 수집"
gtagConsentAnalyticsDescription: "사이트 체류 시간 등 분석 관련 정보 저장(쿠키 등)을 활성화합니다."
gtagConsentFunctionality: "기능 및 설정 사용 정보 수집"
@ -1354,7 +1354,7 @@ gtagConsentFunctionalityDescription: "언어 설정 등 웹사이트나 앱의
gtagConsentPersonalization: "개인 맞춤형 정보 수집"
gtagConsentPersonalizationDescription: "추천 게시물 등 개인화 관련 정보 저장을 활성화합니다."
helpUsImproveUserExperience: "Misskey의 미래를 위해,\n데이터 수집에 협조해 주세요!"
pleaseConsentToTracking: "{host}는 [개인정보 처리방침]({privacyPolicyUrl})에 따라 서비스 제공, 운영, 사용자 경험 향상을 위해 사용 중인 IP 주소, 이용 현황, 디바이스 정보 등 개인 정보를 포함할 수 있는 정보를 수집할 수 있습니다.\n\n수집된 데이터는 향후 기능 개발, 운영 방침 결정, 서비스 개선점 파악에 활용됩니다."
pleaseConsentToTracking: "{host}는 [개인정보 처리방침]({privacyPolicyUrl})에 따라 서비스 제공, 운영, 유저 경험 향상을 위해 사용 중인 IP 주소, 이용 현황, 디바이스 정보 등 개인 정보를 포함할 수 있는 정보를 수집할 수 있습니다.\n\n수집된 데이터는 향후 기능 개발, 운영 방침 결정, 서비스 개선점 파악에 활용됩니다."
consentEssential: "필수 항목만 허용"
consentAll: "모두 허용"
consentSelected: "선택한 항목만 허용"
@ -1364,8 +1364,8 @@ unmuteNotification: "알림 뮤트를 해제하기"
endingCreditMembers: "엔딩 크레딧에 표시할 유저"
endingCreditMembersDescription: "서버 정보 페이지에 표시할 유저의 ID를 한 줄에 하나씩 적습니다."
emailAddressLogin: "이메일 주소로 로그인"
usernameLogin: "사용자명으로 로그인"
usernameLogin: "유저명으로 로그인"
unarchive: "아카이브 해제"
_bubbleGame:
howToPlay: "설명"
hold: "홀드"
@ -1412,7 +1412,7 @@ _announcement:
needConfirmationToRead: "읽음으로 표시하기 전에 확인하기"
needConfirmationToReadDescription: "활성화하면 이 공지사항을 읽음으로 표시하기 전에 확인 알림창을 띄웁니다."
needEnrollmentTutorialToRead: "읽음으로 표시하기 전에 튜토리얼 진행하기"
needEnrollmentTutorialToReadDescription: "활성화하면 이 공지사항을 읽음으로 표시하기 전에 사용자에게 튜토리얼을 진행하도록 요구합니다."
needEnrollmentTutorialToReadDescription: "활성화하면 이 공지사항을 읽음으로 표시하기 전에 유저가 튜토리얼을 진행하도록 요구합니다."
end: "공지에서 내리기"
tooManyActiveAnnouncementDescription: "공지사항이 너무 많을 경우, 유저 경험에 영향을 끼칠 가능성이 있습니다. 오래된 공지사항은 아카이브하시는 것을 권장드립니다."
readConfirmTitle: "읽음으로 표시합니까?"
@ -2835,6 +2835,6 @@ _hideSensitiveInformation:
_selfXssPrevention:
warning: "경고"
title: "「이 화면에 무언가를 붙여넣으라는 메시지」는 모두 *사기*입니다."
description1: "여기에 무언가를 붙여넣으면, 악의를 가진 사용자에게 계정을 탈취당하거나 개인정보를 훔쳐갈 수 있습니다."
description1: "여기에 무언가를 붙여넣으면, 악의를 가진 다른 유저에게 계정을 탈취당하거나 개인정보를 훔쳐갈 수 있습니다."
description2: "붙여넣으려는 것이 무엇인지 정확히 이해하지 못하면, %c지금 작업을 중단하고 이 창을 닫으십시오."
description3: "자세한 내용은 여기를 확인하십시오. {link}"

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class NotificationMuting1730885274028 {
name = 'NotificationMuting1730885274028'

View File

@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class NoteIsDeletable1736233575620 {
name = 'NoteIsDeletable1736233575620'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" ADD "isDeletable" boolean NOT NULL DEFAULT true`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "isDeletable"`);
}
}

View File

@ -549,11 +549,15 @@ export class ApInboxService {
const note = await this.apDbResolverService.getNoteFromApId(uri);
if (note == null) {
return 'message not found';
return 'no such note';
}
if (note.userId !== actor.id) {
return '投稿を削除しようとしているユーザーは投稿の作成者ではありません';
return 'actor and note author is not same';
}
if (!note.isDeletable) {
return 'note is not deletable'
}
await this.noteDeleteService.delete(actor, note);

View File

@ -43,11 +43,11 @@ export class AutoNoteRemovalProcessorService {
@bindThis
public async process(job: Bull.Job<Record<string, unknown>>): Promise<void> {
this.logger.info('Checking notes that to remove automatically...');
this.logger.info('Checking users that enabled note auto-removal');
this.logger.info('Checking notes to remove automatically...');
this.logger.info('Checking users that enabled note auto removal');
const users = await this.usersRepository.find({ where: { autoRemoval: true } });
if (users.length < 1) {
this.logger.info('Does not have any user that enabled autoRemoval');
this.logger.info('No user that enabled note auto removal');
return;
}
const now = Date.now();
@ -81,6 +81,7 @@ export class AutoNoteRemovalProcessorService {
const notes = await this.notesRepository.find({
where: {
userId: user.id,
isDeletable: true,
...(cursor ? {
id: And(Not(In(condition)), MoreThan(cursor)),
} : {
@ -110,9 +111,9 @@ export class AutoNoteRemovalProcessorService {
}
await job.updateProgress(100);
this.logger.succ('All of auto-removable notes deleted');
this.logger.succ('All auto removable notes deleted');
}
this.logger.succ('All notes to auto-remove has beed removed.');
this.logger.succ('Note auto removal job completed.');
}
}

View File

@ -288,6 +288,7 @@ import * as ep___renoteMute_delete from './endpoints/renote-mute/delete.js';
import * as ep___renoteMute_list from './endpoints/renote-mute/list.js';
import * as ep___my_apps from './endpoints/my/apps.js';
import * as ep___notes from './endpoints/notes.js';
import * as ep___notes_archive from './endpoints/notes/archive.js';
import * as ep___notes_children from './endpoints/notes/children.js';
import * as ep___notes_clips from './endpoints/notes/clips.js';
import * as ep___notes_conversation from './endpoints/notes/conversation.js';
@ -315,6 +316,7 @@ import * as ep___notes_threadMuting_create from './endpoints/notes/thread-muting
import * as ep___notes_threadMuting_delete from './endpoints/notes/thread-muting/delete.js';
import * as ep___notes_timeline from './endpoints/notes/timeline.js';
import * as ep___notes_translate from './endpoints/notes/translate.js';
import * as ep___notes_unarchive from './endpoints/notes/unarchive.js';
import * as ep___notes_unrenote from './endpoints/notes/unrenote.js';
import * as ep___notes_userListTimeline from './endpoints/notes/user-list-timeline.js';
import * as ep___notifications_create from './endpoints/notifications/create.js';
@ -690,6 +692,7 @@ const $renoteMute_delete: Provider = { provide: 'ep:renote-mute/delete', useClas
const $renoteMute_list: Provider = { provide: 'ep:renote-mute/list', useClass: ep___renoteMute_list.default };
const $my_apps: Provider = { provide: 'ep:my/apps', useClass: ep___my_apps.default };
const $notes: Provider = { provide: 'ep:notes', useClass: ep___notes.default };
const $notes_archive: Provider = { provide: 'ep:notes/archive', useClass: ep___notes_archive.default };
const $notes_children: Provider = { provide: 'ep:notes/children', useClass: ep___notes_children.default };
const $notes_clips: Provider = { provide: 'ep:notes/clips', useClass: ep___notes_clips.default };
const $notes_conversation: Provider = { provide: 'ep:notes/conversation', useClass: ep___notes_conversation.default };
@ -717,6 +720,7 @@ const $notes_threadMuting_create: Provider = { provide: 'ep:notes/thread-muting/
const $notes_threadMuting_delete: Provider = { provide: 'ep:notes/thread-muting/delete', useClass: ep___notes_threadMuting_delete.default };
const $notes_timeline: Provider = { provide: 'ep:notes/timeline', useClass: ep___notes_timeline.default };
const $notes_translate: Provider = { provide: 'ep:notes/translate', useClass: ep___notes_translate.default };
const $notes_unarchive: Provider = { provide: 'ep:notes/unarchive', useClass: ep___notes_unarchive.default };
const $notes_unrenote: Provider = { provide: 'ep:notes/unrenote', useClass: ep___notes_unrenote.default };
const $notes_userListTimeline: Provider = { provide: 'ep:notes/user-list-timeline', useClass: ep___notes_userListTimeline.default };
const $notifications_create: Provider = { provide: 'ep:notifications/create', useClass: ep___notifications_create.default };
@ -1096,6 +1100,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$renoteMute_list,
$my_apps,
$notes,
$notes_archive,
$notes_children,
$notes_clips,
$notes_conversation,
@ -1123,6 +1128,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$notes_threadMuting_delete,
$notes_timeline,
$notes_translate,
$notes_unarchive,
$notes_unrenote,
$notes_userListTimeline,
$notifications_create,
@ -1496,6 +1502,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$renoteMute_list,
$my_apps,
$notes,
$notes_archive,
$notes_children,
$notes_clips,
$notes_conversation,
@ -1523,6 +1530,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$notes_threadMuting_delete,
$notes_timeline,
$notes_translate,
$notes_unarchive,
$notes_unrenote,
$notes_userListTimeline,
$notifications_create,

View File

@ -288,6 +288,7 @@ import * as ep___renoteMute_delete from './endpoints/renote-mute/delete.js';
import * as ep___renoteMute_list from './endpoints/renote-mute/list.js';
import * as ep___my_apps from './endpoints/my/apps.js';
import * as ep___notes from './endpoints/notes.js';
import * as ep___notes_archive from './endpoints/notes/archive.js';
import * as ep___notes_children from './endpoints/notes/children.js';
import * as ep___notes_clips from './endpoints/notes/clips.js';
import * as ep___notes_conversation from './endpoints/notes/conversation.js';
@ -315,6 +316,7 @@ import * as ep___notes_threadMuting_create from './endpoints/notes/thread-muting
import * as ep___notes_threadMuting_delete from './endpoints/notes/thread-muting/delete.js';
import * as ep___notes_timeline from './endpoints/notes/timeline.js';
import * as ep___notes_translate from './endpoints/notes/translate.js';
import * as ep___notes_unarchive from './endpoints/notes/unarchive.js';
import * as ep___notes_unrenote from './endpoints/notes/unrenote.js';
import * as ep___notes_userListTimeline from './endpoints/notes/user-list-timeline.js';
import * as ep___notifications_create from './endpoints/notifications/create.js';
@ -688,6 +690,7 @@ const eps = [
['renote-mute/list', ep___renoteMute_list],
['my/apps', ep___my_apps],
['notes', ep___notes],
['notes/archive', ep___notes_archive],
['notes/children', ep___notes_children],
['notes/clips', ep___notes_clips],
['notes/conversation', ep___notes_conversation],
@ -715,6 +718,7 @@ const eps = [
['notes/thread-muting/delete', ep___notes_threadMuting_delete],
['notes/timeline', ep___notes_timeline],
['notes/translate', ep___notes_translate],
['notes/unarchive', ep___notes_unarchive],
['notes/unrenote', ep___notes_unrenote],
['notes/user-list-timeline', ep___notes_userListTimeline],
['notifications/create', ep___notifications_create],

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import ms from 'ms';
import { Inject, Injectable } from '@nestjs/common';
import type { NotesRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { GetterService } from '@/server/api/GetterService.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';
export const meta = {
tags: ['notes'],
requireCredential: true,
requireModerator: true,
secure: true,
kind: 'write:notes',
limit: {
duration: ms('1hour'),
max: 300,
minInterval: ms('1sec'),
},
errors: {
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '490be23f-8c1f-4796-819f-94cb4f9d1630',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
noteId: { type: 'string', format: 'misskey:id' },
},
required: ['noteId'],
} as const;
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
private getterService: GetterService,
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
const note = await this.getterService.getNote(ps.noteId).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
throw err;
});
await this.notesRepository.update(note.id, { isDeletable: false });
});
}
}

View File

@ -34,6 +34,12 @@ export const meta = {
id: '490be23f-8c1f-4796-819f-94cb4f9d1630',
},
deletionNotAllowed: {
message: 'Note is not allowed to delete.',
code: 'DELETION_NOT_ALLOWED',
id: 'c6e6ad27-3ec2-49a7-bb55-09fb70f6e2fd',
},
accessDenied: {
message: 'Access denied.',
code: 'ACCESS_DENIED',
@ -66,8 +72,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw err;
});
if (note.id === 'a2h9mk6pav') {
throw new ApiError(meta.errors.accessDenied);
if (note.isDeletable === false) {
throw new ApiError(meta.errors.deletionNotAllowed);
}
if (!await this.roleService.isModerator(me) && (note.userId !== me.id)) {

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import ms from 'ms';
import { Inject, Injectable } from '@nestjs/common';
import type { NotesRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { GetterService } from '@/server/api/GetterService.js';
import { RoleService } from '@/core/RoleService.js';
import { ApiError } from '../../error.js';
export const meta = {
tags: ['notes'],
requireCredential: true,
requireModerator: true,
secure: true,
kind: 'write:notes',
limit: {
duration: ms('1hour'),
max: 300,
minInterval: ms('1sec'),
},
errors: {
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '490be23f-8c1f-4796-819f-94cb4f9d1630',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
noteId: { type: 'string', format: 'misskey:id' },
},
required: ['noteId'],
} as const;
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
constructor(
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
private getterService: GetterService,
private roleService: RoleService,
) {
super(meta, paramDef, async (ps, me) => {
const note = await this.getterService.getNote(ps.noteId).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
throw err;
});
await this.notesRepository.update(note.id, { isDeletable: true });
});
}
}

View File

@ -226,6 +226,12 @@ export function getNoteMenu(props: {
});
}
function toggleDeletable(archive: boolean): void {
os.apiWithDialog(archive ? 'notes/archive' : 'notes/unarchive', {
noteId: appearNote.id,
});
}
function copyContent(): void {
copyToClipboard(appearNote.text);
os.success();
@ -355,6 +361,20 @@ export function getNoteMenu(props: {
text: i18n.ts.muteThread,
action: () => toggleThreadMute(true),
}),
...(iAmModerator ? appearNote.isDeletable ? [
{
icon: 'ti ti-archive',
text: i18n.ts.archive,
action: () => toggleDeletable(true),
}]
: [
{
icon: 'ti ti-archive-off',
text: i18n.ts.unarchive,
action: () => toggleDeletable(false),
}]
: []
),
appearNote.userId === $i.id ? ($i.pinnedNoteIds ?? []).includes(appearNote.id) ? {
icon: 'ti ti-pinned-off',
text: i18n.ts.unpin,
@ -432,11 +452,13 @@ export function getNoteMenu(props: {
appearNote.userId === $i.id ? {
icon: 'ti ti-edit',
text: i18n.ts.deleteAndEdit,
disabled: !appearNote.isDeletable,
action: delEdit,
} : undefined,
{
icon: 'ti ti-trash',
text: i18n.ts.delete,
disabled: !appearNote.isDeletable,
danger: true,
action: del,
}]

View File

@ -1642,6 +1642,7 @@ declare namespace entities {
MyAppsResponse,
NotesRequest,
NotesResponse,
NotesArchiveRequest,
NotesChildrenRequest,
NotesChildrenResponse,
NotesClipsRequest,
@ -1688,6 +1689,7 @@ declare namespace entities {
NotesTimelineResponse,
NotesTranslateRequest,
NotesTranslateResponse,
NotesUnarchiveRequest,
NotesUnrenoteRequest,
NotesUserListTimelineRequest,
NotesUserListTimelineResponse,
@ -2604,6 +2606,9 @@ type NoteFavorite = components['schemas']['NoteFavorite'];
// @public (undocumented)
type NoteReaction = components['schemas']['NoteReaction'];
// @public (undocumented)
type NotesArchiveRequest = operations['notes___archive']['requestBody']['content']['application/json'];
// @public (undocumented)
type NotesChildrenRequest = operations['notes___children']['requestBody']['content']['application/json'];
@ -2748,6 +2753,9 @@ type NotesTranslateRequest = operations['notes___translate']['requestBody']['con
// @public (undocumented)
type NotesTranslateResponse = operations['notes___translate']['responses']['200']['content']['application/json'];
// @public (undocumented)
type NotesUnarchiveRequest = operations['notes___unarchive']['requestBody']['content']['application/json'];
// @public (undocumented)
type NotesUnrenoteRequest = operations['notes___unrenote']['requestBody']['content']['application/json'];

View File

@ -3144,6 +3144,18 @@ declare module '../api.js' {
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:notes*
*/
request<E extends 'notes/archive', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
@ -3441,6 +3453,18 @@ declare module '../api.js' {
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:notes*
*/
request<E extends 'notes/unarchive', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*

View File

@ -414,6 +414,7 @@ import type {
MyAppsResponse,
NotesRequest,
NotesResponse,
NotesArchiveRequest,
NotesChildrenRequest,
NotesChildrenResponse,
NotesClipsRequest,
@ -460,6 +461,7 @@ import type {
NotesTimelineResponse,
NotesTranslateRequest,
NotesTranslateResponse,
NotesUnarchiveRequest,
NotesUnrenoteRequest,
NotesUserListTimelineRequest,
NotesUserListTimelineResponse,
@ -879,6 +881,7 @@ export type Endpoints = {
'renote-mute/list': { req: RenoteMuteListRequest; res: RenoteMuteListResponse };
'my/apps': { req: MyAppsRequest; res: MyAppsResponse };
'notes': { req: NotesRequest; res: NotesResponse };
'notes/archive': { req: NotesArchiveRequest; res: EmptyResponse };
'notes/children': { req: NotesChildrenRequest; res: NotesChildrenResponse };
'notes/clips': { req: NotesClipsRequest; res: NotesClipsResponse };
'notes/conversation': { req: NotesConversationRequest; res: NotesConversationResponse };
@ -906,6 +909,7 @@ export type Endpoints = {
'notes/thread-muting/delete': { req: NotesThreadMutingDeleteRequest; res: EmptyResponse };
'notes/timeline': { req: NotesTimelineRequest; res: NotesTimelineResponse };
'notes/translate': { req: NotesTranslateRequest; res: NotesTranslateResponse };
'notes/unarchive': { req: NotesUnarchiveRequest; res: EmptyResponse };
'notes/unrenote': { req: NotesUnrenoteRequest; res: EmptyResponse };
'notes/user-list-timeline': { req: NotesUserListTimelineRequest; res: NotesUserListTimelineResponse };
'notifications/create': { req: NotificationsCreateRequest; res: EmptyResponse };

View File

@ -417,6 +417,7 @@ export type MyAppsRequest = operations['my___apps']['requestBody']['content']['a
export type MyAppsResponse = operations['my___apps']['responses']['200']['content']['application/json'];
export type NotesRequest = operations['notes']['requestBody']['content']['application/json'];
export type NotesResponse = operations['notes']['responses']['200']['content']['application/json'];
export type NotesArchiveRequest = operations['notes___archive']['requestBody']['content']['application/json'];
export type NotesChildrenRequest = operations['notes___children']['requestBody']['content']['application/json'];
export type NotesChildrenResponse = operations['notes___children']['responses']['200']['content']['application/json'];
export type NotesClipsRequest = operations['notes___clips']['requestBody']['content']['application/json'];
@ -463,6 +464,7 @@ export type NotesTimelineRequest = operations['notes___timeline']['requestBody']
export type NotesTimelineResponse = operations['notes___timeline']['responses']['200']['content']['application/json'];
export type NotesTranslateRequest = operations['notes___translate']['requestBody']['content']['application/json'];
export type NotesTranslateResponse = operations['notes___translate']['responses']['200']['content']['application/json'];
export type NotesUnarchiveRequest = operations['notes___unarchive']['requestBody']['content']['application/json'];
export type NotesUnrenoteRequest = operations['notes___unrenote']['requestBody']['content']['application/json'];
export type NotesUserListTimelineRequest = operations['notes___user-list-timeline']['requestBody']['content']['application/json'];
export type NotesUserListTimelineResponse = operations['notes___user-list-timeline']['responses']['200']['content']['application/json'];

View File

@ -2722,6 +2722,16 @@ export type paths = {
*/
post: operations['notes'];
};
'/notes/archive': {
/**
* notes/archive
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:notes*
*/
post: operations['notes___archive'];
};
'/notes/children': {
/**
* notes/children
@ -2979,6 +2989,16 @@ export type paths = {
*/
post: operations['notes___translate'];
};
'/notes/unarchive': {
/**
* notes/unarchive
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:notes*
*/
post: operations['notes___unarchive'];
};
'/notes/unrenote': {
/**
* notes/unrenote
@ -4352,6 +4372,7 @@ export type components = {
url?: string;
reactionAndUserPairCache?: string[];
clippedCount?: number;
isDeletable: boolean;
myReaction?: string | null;
};
NoteReaction: {
@ -23523,6 +23544,65 @@ export type operations = {
};
};
};
/**
* notes/archive
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:notes*
*/
notes___archive: {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
noteId: string;
};
};
};
responses: {
/** @description OK (without any results) */
204: {
content: never;
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description To many requests */
429: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* notes/children
* @description No description provided.
@ -25307,6 +25387,65 @@ export type operations = {
};
};
};
/**
* notes/unarchive
* @description No description provided.
*
* **Internal Endpoint**: This endpoint is an API for the misskey mainframe and is not intended for use by third parties.
* **Credential required**: *Yes* / **Permission**: *write:notes*
*/
notes___unarchive: {
requestBody: {
content: {
'application/json': {
/** Format: misskey:id */
noteId: string;
};
};
};
responses: {
/** @description OK (without any results) */
204: {
content: never;
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description To many requests */
429: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/**
* notes/unrenote
* @description No description provided.