refactor: api/*/update系の必須キーを最低限に (#13824)
* refactor: clips/updateの必須キーをclipIdのみに * refactor: admin/roles/update の必須キーをroleIdのみに * feat: pages/update の必須キーをpageIdのみに * refactor: gallery/posts/update の必須キーをpostidのみに * feat: misskey-jsの型を更新 * feat: i/webhooks/updateの必須キーをwebhookIdのみに * feat: admin/ad/updateの必須キーをidのみに * feat: misskey-jsの型を更新 * chore: update CHANGELOG.md * docs: update CHANGELOG.md * fix: secretが更新できなくなる場合がある Co-authored-by: zyoshoka <107108195+zyoshoka@users.noreply.github.com> * Update packages/backend/src/server/api/endpoints/gallery/posts/update.ts --------- Co-authored-by: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
		@@ -40,7 +40,7 @@ export const paramDef = {
 | 
			
		||||
		startsAt: { type: 'integer' },
 | 
			
		||||
		dayOfWeek: { type: 'integer' },
 | 
			
		||||
	},
 | 
			
		||||
	required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'dayOfWeek'],
 | 
			
		||||
	required: ['id'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
@@ -63,8 +63,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
			
		||||
				ratio: ps.ratio,
 | 
			
		||||
				memo: ps.memo,
 | 
			
		||||
				imageUrl: ps.imageUrl,
 | 
			
		||||
				expiresAt: new Date(ps.expiresAt),
 | 
			
		||||
				startsAt: new Date(ps.startsAt),
 | 
			
		||||
				expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : undefined,
 | 
			
		||||
				startsAt: ps.startsAt ? new Date(ps.startsAt) : undefined,
 | 
			
		||||
				dayOfWeek: ps.dayOfWeek,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import type { RolesRepository } from '@/models/_.js';
 | 
			
		||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { ApiError } from '@/server/api/error.js';
 | 
			
		||||
import { RoleService } from '@/core/RoleService.js';
 | 
			
		||||
@@ -50,19 +49,6 @@ export const paramDef = {
 | 
			
		||||
	},
 | 
			
		||||
	required: [
 | 
			
		||||
		'roleId',
 | 
			
		||||
		'name',
 | 
			
		||||
		'description',
 | 
			
		||||
		'color',
 | 
			
		||||
		'iconUrl',
 | 
			
		||||
		'target',
 | 
			
		||||
		'condFormula',
 | 
			
		||||
		'isPublic',
 | 
			
		||||
		'isModerator',
 | 
			
		||||
		'isAdministrator',
 | 
			
		||||
		'asBadge',
 | 
			
		||||
		'canEditMembersByModerator',
 | 
			
		||||
		'displayOrder',
 | 
			
		||||
		'policies',
 | 
			
		||||
	],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { Injectable } from '@nestjs/common';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import { ClipEntityService } from '@/core/entities/ClipEntityService.js';
 | 
			
		||||
import { ClipService } from '@/core/ClipService.js';
 | 
			
		||||
@@ -41,7 +41,7 @@ export const paramDef = {
 | 
			
		||||
		isPublic: { type: 'boolean' },
 | 
			
		||||
		description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
 | 
			
		||||
	},
 | 
			
		||||
	required: ['clipId', 'name'],
 | 
			
		||||
	required: ['clipId'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ export const paramDef = {
 | 
			
		||||
		} },
 | 
			
		||||
		isSensitive: { type: 'boolean', default: false },
 | 
			
		||||
	},
 | 
			
		||||
	required: ['postId', 'title', 'fileIds'],
 | 
			
		||||
	required: ['postId'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
@@ -62,15 +62,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
			
		||||
		private galleryPostEntityService: GalleryPostEntityService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			const files = (await Promise.all(ps.fileIds.map(fileId =>
 | 
			
		||||
				this.driveFilesRepository.findOneBy({
 | 
			
		||||
					id: fileId,
 | 
			
		||||
					userId: me.id,
 | 
			
		||||
				}),
 | 
			
		||||
			))).filter(x => x != null);
 | 
			
		||||
			let files: Array<MiDriveFile> | undefined;
 | 
			
		||||
 | 
			
		||||
			if (files.length === 0) {
 | 
			
		||||
				throw new Error();
 | 
			
		||||
			if (ps.fileIds) {
 | 
			
		||||
				files = (await Promise.all(ps.fileIds.map(fileId =>
 | 
			
		||||
					this.driveFilesRepository.findOneBy({
 | 
			
		||||
						id: fileId,
 | 
			
		||||
						userId: me.id,
 | 
			
		||||
					}),
 | 
			
		||||
				))).filter(x => x != null);
 | 
			
		||||
 | 
			
		||||
				if (files.length === 0) {
 | 
			
		||||
					throw new Error();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			await this.galleryPostsRepository.update({
 | 
			
		||||
@@ -81,7 +85,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
			
		||||
				title: ps.title,
 | 
			
		||||
				description: ps.description,
 | 
			
		||||
				isSensitive: ps.isSensitive,
 | 
			
		||||
				fileIds: files.map(file => file.id),
 | 
			
		||||
				fileIds: files ? files.map(file => file.id) : undefined,
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			const post = await this.galleryPostsRepository.findOneByOrFail({ id: ps.postId });
 | 
			
		||||
 
 | 
			
		||||
@@ -34,13 +34,13 @@ export const paramDef = {
 | 
			
		||||
		webhookId: { type: 'string', format: 'misskey:id' },
 | 
			
		||||
		name: { type: 'string', minLength: 1, maxLength: 100 },
 | 
			
		||||
		url: { type: 'string', minLength: 1, maxLength: 1024 },
 | 
			
		||||
		secret: { type: 'string', maxLength: 1024, default: '' },
 | 
			
		||||
		secret: { type: 'string', nullable: true, maxLength: 1024 },
 | 
			
		||||
		on: { type: 'array', items: {
 | 
			
		||||
			type: 'string', enum: webhookEventTypes,
 | 
			
		||||
		} },
 | 
			
		||||
		active: { type: 'boolean' },
 | 
			
		||||
	},
 | 
			
		||||
	required: ['webhookId', 'name', 'url', 'on', 'active'],
 | 
			
		||||
	required: ['webhookId'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
@@ -66,7 +66,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
			
		||||
			await this.webhooksRepository.update(webhook.id, {
 | 
			
		||||
				name: ps.name,
 | 
			
		||||
				url: ps.url,
 | 
			
		||||
				secret: ps.secret,
 | 
			
		||||
				secret: ps.secret === null ? '' : ps.secret,
 | 
			
		||||
				on: ps.on,
 | 
			
		||||
				active: ps.active,
 | 
			
		||||
			});
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ export const paramDef = {
 | 
			
		||||
		alignCenter: { type: 'boolean' },
 | 
			
		||||
		hideTitleWhenPinned: { type: 'boolean' },
 | 
			
		||||
	},
 | 
			
		||||
	required: ['pageId', 'title', 'name', 'content', 'variables', 'script'],
 | 
			
		||||
	required: ['pageId'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
@@ -91,9 +91,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
			
		||||
				throw new ApiError(meta.errors.accessDenied);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			let eyeCatchingImage = null;
 | 
			
		||||
			if (ps.eyeCatchingImageId != null) {
 | 
			
		||||
				eyeCatchingImage = await this.driveFilesRepository.findOneBy({
 | 
			
		||||
				const eyeCatchingImage = await this.driveFilesRepository.findOneBy({
 | 
			
		||||
					id: ps.eyeCatchingImageId,
 | 
			
		||||
					userId: me.id,
 | 
			
		||||
				});
 | 
			
		||||
@@ -116,23 +115,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
			
		||||
			await this.pagesRepository.update(page.id, {
 | 
			
		||||
				updatedAt: new Date(),
 | 
			
		||||
				title: ps.title,
 | 
			
		||||
				// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
 | 
			
		||||
				name: ps.name === undefined ? page.name : ps.name,
 | 
			
		||||
				name: ps.name,
 | 
			
		||||
				summary: ps.summary === undefined ? page.summary : ps.summary,
 | 
			
		||||
				content: ps.content,
 | 
			
		||||
				variables: ps.variables,
 | 
			
		||||
				script: ps.script,
 | 
			
		||||
				// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
 | 
			
		||||
				alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter,
 | 
			
		||||
				// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
 | 
			
		||||
				hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned,
 | 
			
		||||
				// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
 | 
			
		||||
				font: ps.font === undefined ? page.font : ps.font,
 | 
			
		||||
				eyeCatchingImageId: ps.eyeCatchingImageId === null
 | 
			
		||||
					? null
 | 
			
		||||
					: ps.eyeCatchingImageId === undefined
 | 
			
		||||
						? page.eyeCatchingImageId
 | 
			
		||||
						: eyeCatchingImage!.id,
 | 
			
		||||
				alignCenter: ps.alignCenter,
 | 
			
		||||
				hideTitleWhenPinned: ps.hideTitleWhenPinned,
 | 
			
		||||
				font: ps.font,
 | 
			
		||||
				eyeCatchingImageId: ps.eyeCatchingImageId,
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user