Merge branch 'develop' into feat-1714

This commit is contained in:
かっこかり 2024-06-22 15:03:23 +09:00 committed by GitHub
commit f9e29e5f5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 71 additions and 85 deletions

View file

@ -88,7 +88,7 @@ jobs:
if [ "$BRANCH" = "misskey-dev:$HEAD_REF" ]; then if [ "$BRANCH" = "misskey-dev:$HEAD_REF" ]; then
BRANCH="$HEAD_REF" BRANCH="$HEAD_REF"
fi fi
pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name $BRANCH $(echo "$CHROMATIC_PARAMETER") pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name "$BRANCH" $(echo "$CHROMATIC_PARAMETER")
env: env:
HEAD_REF: ${{ github.event.pull_request.head.ref }} HEAD_REF: ${{ github.event.pull_request.head.ref }}
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

View file

@ -16,6 +16,12 @@
- Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949)
- Fix: ユーザーのフィードページのMFMをHTMLに展開するように (#14006) - Fix: ユーザーのフィードページのMFMをHTMLに展開するように (#14006)
- Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036) - Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036)
- Enhance: エンドポイント`clips/update`の必須項目を`clipId`のみに
- Enhance: エンドポイント`admin/roles/update`の必須項目を`roleId`のみに
- Enhance: エンドポイント`pages/update`の必須項目を`pageId`のみに
- Enhance: エンドポイント`gallery/posts/update`の必須項目を`postId`のみに
- Enhance: エンドポイント`i/webhook/update`の必須項目を`webhookId`のみに
- Enhance: エンドポイント`admin/ad/update`の必須項目を`id`のみに
- Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059) - Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059)
- Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 - Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正

View file

@ -40,7 +40,7 @@ export const paramDef = {
startsAt: { type: 'integer' }, startsAt: { type: 'integer' },
dayOfWeek: { type: 'integer' }, dayOfWeek: { type: 'integer' },
}, },
required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'dayOfWeek'], required: ['id'],
} as const; } as const;
@Injectable() @Injectable()
@ -63,8 +63,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
ratio: ps.ratio, ratio: ps.ratio,
memo: ps.memo, memo: ps.memo,
imageUrl: ps.imageUrl, imageUrl: ps.imageUrl,
expiresAt: new Date(ps.expiresAt), expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : undefined,
startsAt: new Date(ps.startsAt), startsAt: ps.startsAt ? new Date(ps.startsAt) : undefined,
dayOfWeek: ps.dayOfWeek, dayOfWeek: ps.dayOfWeek,
}); });

View file

@ -6,7 +6,6 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { RolesRepository } from '@/models/_.js'; import type { RolesRepository } from '@/models/_.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ApiError } from '@/server/api/error.js'; import { ApiError } from '@/server/api/error.js';
import { RoleService } from '@/core/RoleService.js'; import { RoleService } from '@/core/RoleService.js';
@ -50,19 +49,6 @@ export const paramDef = {
}, },
required: [ required: [
'roleId', 'roleId',
'name',
'description',
'color',
'iconUrl',
'target',
'condFormula',
'isPublic',
'isModerator',
'isAdministrator',
'asBadge',
'canEditMembersByModerator',
'displayOrder',
'policies',
], ],
} as const; } as const;

View file

@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only * 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 { Endpoint } from '@/server/api/endpoint-base.js';
import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; import { ClipEntityService } from '@/core/entities/ClipEntityService.js';
import { ClipService } from '@/core/ClipService.js'; import { ClipService } from '@/core/ClipService.js';
@ -41,7 +41,7 @@ export const paramDef = {
isPublic: { type: 'boolean' }, isPublic: { type: 'boolean' },
description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 },
}, },
required: ['clipId', 'name'], required: ['clipId'],
} as const; } as const;
@Injectable() @Injectable()

View file

@ -47,7 +47,7 @@ export const paramDef = {
} }, } },
isSensitive: { type: 'boolean', default: false }, isSensitive: { type: 'boolean', default: false },
}, },
required: ['postId', 'title', 'fileIds'], required: ['postId'],
} as const; } as const;
@Injectable() @Injectable()
@ -62,15 +62,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private galleryPostEntityService: GalleryPostEntityService, private galleryPostEntityService: GalleryPostEntityService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const files = (await Promise.all(ps.fileIds.map(fileId => let files: Array<MiDriveFile> | undefined;
this.driveFilesRepository.findOneBy({
id: fileId,
userId: me.id,
}),
))).filter(x => x != null);
if (files.length === 0) { if (ps.fileIds) {
throw new Error(); 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({ await this.galleryPostsRepository.update({
@ -81,7 +85,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
title: ps.title, title: ps.title,
description: ps.description, description: ps.description,
isSensitive: ps.isSensitive, 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 }); const post = await this.galleryPostsRepository.findOneByOrFail({ id: ps.postId });

View file

@ -34,13 +34,13 @@ export const paramDef = {
webhookId: { type: 'string', format: 'misskey:id' }, webhookId: { type: 'string', format: 'misskey:id' },
name: { type: 'string', minLength: 1, maxLength: 100 }, name: { type: 'string', minLength: 1, maxLength: 100 },
url: { type: 'string', minLength: 1, maxLength: 1024 }, url: { type: 'string', minLength: 1, maxLength: 1024 },
secret: { type: 'string', maxLength: 1024, default: '' }, secret: { type: 'string', nullable: true, maxLength: 1024 },
on: { type: 'array', items: { on: { type: 'array', items: {
type: 'string', enum: webhookEventTypes, type: 'string', enum: webhookEventTypes,
} }, } },
active: { type: 'boolean' }, active: { type: 'boolean' },
}, },
required: ['webhookId', 'name', 'url', 'on', 'active'], required: ['webhookId'],
} as const; } as const;
// TODO: ロジックをサービスに切り出す // TODO: ロジックをサービスに切り出す
@ -66,7 +66,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
await this.webhooksRepository.update(webhook.id, { await this.webhooksRepository.update(webhook.id, {
name: ps.name, name: ps.name,
url: ps.url, url: ps.url,
secret: ps.secret, secret: ps.secret === null ? '' : ps.secret,
on: ps.on, on: ps.on,
active: ps.active, active: ps.active,
}); });

View file

@ -70,7 +70,7 @@ export const paramDef = {
alignCenter: { type: 'boolean' }, alignCenter: { type: 'boolean' },
hideTitleWhenPinned: { type: 'boolean' }, hideTitleWhenPinned: { type: 'boolean' },
}, },
required: ['pageId', 'title', 'name', 'content', 'variables', 'script'], required: ['pageId'],
} as const; } as const;
@Injectable() @Injectable()
@ -91,9 +91,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.accessDenied); throw new ApiError(meta.errors.accessDenied);
} }
let eyeCatchingImage = null;
if (ps.eyeCatchingImageId != null) { if (ps.eyeCatchingImageId != null) {
eyeCatchingImage = await this.driveFilesRepository.findOneBy({ const eyeCatchingImage = await this.driveFilesRepository.findOneBy({
id: ps.eyeCatchingImageId, id: ps.eyeCatchingImageId,
userId: me.id, userId: me.id,
}); });
@ -116,23 +115,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
await this.pagesRepository.update(page.id, { await this.pagesRepository.update(page.id, {
updatedAt: new Date(), updatedAt: new Date(),
title: ps.title, title: ps.title,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing name: ps.name,
name: ps.name === undefined ? page.name : ps.name,
summary: ps.summary === undefined ? page.summary : ps.summary, summary: ps.summary === undefined ? page.summary : ps.summary,
content: ps.content, content: ps.content,
variables: ps.variables, variables: ps.variables,
script: ps.script, script: ps.script,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing alignCenter: ps.alignCenter,
alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, hideTitleWhenPinned: ps.hideTitleWhenPinned,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing font: ps.font,
hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, eyeCatchingImageId: ps.eyeCatchingImageId,
// 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,
}); });
}); });
} }

View file

@ -5881,15 +5881,15 @@ export type operations = {
'application/json': { 'application/json': {
/** Format: misskey:id */ /** Format: misskey:id */
id: string; id: string;
memo: string; memo?: string;
url: string; url?: string;
imageUrl: string; imageUrl?: string;
place: string; place?: string;
priority: string; priority?: string;
ratio: number; ratio?: number;
expiresAt: number; expiresAt?: number;
startsAt: number; startsAt?: number;
dayOfWeek: number; dayOfWeek?: number;
}; };
}; };
}; };
@ -9744,21 +9744,21 @@ export type operations = {
'application/json': { 'application/json': {
/** Format: misskey:id */ /** Format: misskey:id */
roleId: string; roleId: string;
name: string; name?: string;
description: string; description?: string;
color: string | null; color?: string | null;
iconUrl: string | null; iconUrl?: string | null;
/** @enum {string} */ /** @enum {string} */
target: 'manual' | 'conditional'; target?: 'manual' | 'conditional';
condFormula: Record<string, never>; condFormula?: Record<string, never>;
isPublic: boolean; isPublic?: boolean;
isModerator: boolean; isModerator?: boolean;
isAdministrator: boolean; isAdministrator?: boolean;
isExplorable?: boolean; isExplorable?: boolean;
asBadge: boolean; asBadge?: boolean;
canEditMembersByModerator: boolean; canEditMembersByModerator?: boolean;
displayOrder: number; displayOrder?: number;
policies: Record<string, never>; policies?: Record<string, never>;
}; };
}; };
}; };
@ -13400,7 +13400,7 @@ export type operations = {
'application/json': { 'application/json': {
/** Format: misskey:id */ /** Format: misskey:id */
clipId: string; clipId: string;
name: string; name?: string;
isPublic?: boolean; isPublic?: boolean;
description?: string | null; description?: string | null;
}; };
@ -16247,9 +16247,9 @@ export type operations = {
'application/json': { 'application/json': {
/** Format: misskey:id */ /** Format: misskey:id */
postId: string; postId: string;
title: string; title?: string;
description?: string | null; description?: string | null;
fileIds: string[]; fileIds?: string[];
/** @default false */ /** @default false */
isSensitive?: boolean; isSensitive?: boolean;
}; };
@ -20030,12 +20030,11 @@ export type operations = {
'application/json': { 'application/json': {
/** Format: misskey:id */ /** Format: misskey:id */
webhookId: string; webhookId: string;
name: string; name?: string;
url: string; url?: string;
/** @default */ secret?: string | null;
secret?: string; on?: ('mention' | 'unfollow' | 'follow' | 'followed' | 'note' | 'reply' | 'renote' | 'reaction')[];
on: ('mention' | 'unfollow' | 'follow' | 'followed' | 'note' | 'reply' | 'renote' | 'reaction')[]; active?: boolean;
active: boolean;
}; };
}; };
}; };
@ -23404,16 +23403,16 @@ export type operations = {
'application/json': { 'application/json': {
/** Format: misskey:id */ /** Format: misskey:id */
pageId: string; pageId: string;
title: string; title?: string;
name: string; name?: string;
summary?: string | null; summary?: string | null;
content: { content?: {
[key: string]: unknown; [key: string]: unknown;
}[]; }[];
variables: { variables?: {
[key: string]: unknown; [key: string]: unknown;
}[]; }[];
script: string; script?: string;
/** Format: misskey:id */ /** Format: misskey:id */
eyeCatchingImageId?: string | null; eyeCatchingImageId?: string | null;
/** @enum {string} */ /** @enum {string} */