From 220e112c833ec9b382658caee99eabdb6ec330ef Mon Sep 17 00:00:00 2001 From: anatawa12 <anatawa12@icloud.com> Date: Sat, 15 Jun 2024 08:42:13 +0900 Subject: [PATCH 01/26] fix rate limit check never ends (#13994) --- packages/backend/src/server/api/RateLimiterService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/RateLimiterService.ts b/packages/backend/src/server/api/RateLimiterService.ts index cae106c273..52d73baa0a 100644 --- a/packages/backend/src/server/api/RateLimiterService.ts +++ b/packages/backend/src/server/api/RateLimiterService.ts @@ -57,7 +57,7 @@ export class RateLimiterService { return reject({ code: 'BRIEF_REQUEST_INTERVAL', info }); } else { if (hasLongTermLimit) { - return max; + return max.then(ok, reject); } else { return ok(); } From 9bddb81efca3b2c5821383709cf30cd63ad21371 Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Sat, 15 Jun 2024 08:43:11 +0900 Subject: [PATCH 02/26] =?UTF-8?q?chore:=20issue=E3=82=92=E8=B5=B7=E7=A5=A8?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=89=8D=E3=81=ABGitHub=20Discussions?= =?UTF-8?q?=E3=81=AB=E3=82=82=E8=AA=98=E5=B0=8E=E3=81=99=E3=82=8B=20(#1399?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e8b65dc3b9..5acad83336 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,3 +2,7 @@ contact_links: - name: 💬 Misskey official Discord url: https://discord.gg/Wp8gVStHW3 about: Chat freely about Misskey + # 仮 + - name: 💬 Start discussion + url: https://github.com/misskey-dev/misskey/discussions + about: The official forum to join conversation and ask question From 1a82a41f9274b3a56edeccf755bd7fc91a3fdf4b Mon Sep 17 00:00:00 2001 From: Acid Chicken <root@acid-chicken.com> Date: Sat, 15 Jun 2024 10:28:57 +0900 Subject: [PATCH 03/26] refactor(backend): get column names from metadata (#13943) * ci: enable * chore: stop when generated column found * chore: get column names from metadata * ci: disable --- packages/backend/src/models/_.ts | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/packages/backend/src/models/_.ts b/packages/backend/src/models/_.ts index d366ce48d0..c72bdaa727 100644 --- a/packages/backend/src/models/_.ts +++ b/packages/backend/src/models/_.ts @@ -82,34 +82,14 @@ import { MiReversiGame } from '@/models/ReversiGame.js'; import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js'; export interface MiRepository<T extends ObjectLiteral> { - createTableColumnNames(this: Repository<T> & MiRepository<T>, queryBuilder: InsertQueryBuilder<T>): string[]; - createTableColumnNamesWithPrimaryKey(this: Repository<T> & MiRepository<T>, queryBuilder: InsertQueryBuilder<T>): string[]; + createTableColumnNames(this: Repository<T> & MiRepository<T>): string[]; insertOne(this: Repository<T> & MiRepository<T>, entity: QueryDeepPartialEntity<T>, findOptions?: Pick<FindOneOptions<T>, 'relations'>): Promise<T>; selectAliasColumnNames(this: Repository<T> & MiRepository<T>, queryBuilder: InsertQueryBuilder<T>, builder: SelectQueryBuilder<T>): void; } export const miRepository = { - createTableColumnNames(queryBuilder) { - // @ts-expect-error -- protected - const insertedColumns = queryBuilder.getInsertedColumns(); - if (insertedColumns.length) { - return insertedColumns.map(column => column.databaseName); - } - if (!queryBuilder.expressionMap.mainAlias?.hasMetadata && !queryBuilder.expressionMap.insertColumns.length) { - // @ts-expect-error -- protected - const valueSets = queryBuilder.getValueSets(); - if (valueSets.length === 1) { - return Object.keys(valueSets[0]); - } - } - return queryBuilder.expressionMap.insertColumns; - }, - createTableColumnNamesWithPrimaryKey(queryBuilder) { - const columnNames = this.createTableColumnNames(queryBuilder); - if (!columnNames.includes('id')) { - columnNames.unshift('id'); - } - return columnNames; + createTableColumnNames() { + return this.metadata.columns.filter(column => column.isSelect && !column.isVirtual).map(column => column.databaseName); }, async insertOne(entity, findOptions?) { const queryBuilder = this.createQueryBuilder().insert().values(entity); @@ -117,7 +97,7 @@ export const miRepository = { const mainAlias = queryBuilder.expressionMap.mainAlias!; const name = mainAlias.name; mainAlias.name = 't'; - const columnNames = this.createTableColumnNamesWithPrimaryKey(queryBuilder); + const columnNames = this.createTableColumnNames(); queryBuilder.returning(columnNames.reduce((a, c) => `${a}, ${queryBuilder.escape(c)}`, '').slice(2)); const builder = this.createQueryBuilder().addCommonTableExpression(queryBuilder, 'cte', { columnNames }); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -138,7 +118,7 @@ export const miRepository = { selectOrAddSelect = (selection, selectionAliasName) => builder.addSelect(selection, selectionAliasName); return builder.select(selection, selectionAliasName); }; - for (const columnName of this.createTableColumnNamesWithPrimaryKey(queryBuilder)) { + for (const columnName of this.createTableColumnNames()) { selectOrAddSelect(`${builder.alias}.${columnName}`, `${builder.alias}_${columnName}`); } }, From d4e2be68eeae69b758f1c9154ee7c1c68ae16b43 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 15 Jun 2024 10:32:51 +0900 Subject: [PATCH 04/26] fix(frontend): chart in `MkInstanceCardMini` is no longer displayed (#13932) * fix(frontend): chart in `MkInstanceCardMini` is no longer displayed * Update CHANGELOG.md * test: add `MkInstanceCardMini` story --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 1 + packages/frontend/.storybook/fakes.ts | 29 +++++++++ packages/frontend/.storybook/generate.tsx | 1 + .../src/components/MkChart.stories.impl.ts | 2 +- .../MkInstanceCardMini.stories.impl.ts | 64 +++++++++++++++++++ .../src/components/MkInstanceCardMini.vue | 4 +- 6 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d482d50d0..097a69b687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正 ### Client +- `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正 - Fix: ユーザーページの追加情報のラベルを投稿者のサーバーの絵文字で表示する (#13968) ### Server diff --git a/packages/frontend/.storybook/fakes.ts b/packages/frontend/.storybook/fakes.ts index fdb155261b..9d789a34ff 100644 --- a/packages/frontend/.storybook/fakes.ts +++ b/packages/frontend/.storybook/fakes.ts @@ -125,6 +125,35 @@ export function file(isSensitive = false) { }; } +export function federationInstance(): entities.FederationInstance { + return { + id: 'someinstanceid', + firstRetrievedAt: '2021-01-01T00:00:00.000Z', + host: 'misskey-hub.net', + usersCount: 10, + notesCount: 20, + followingCount: 5, + followersCount: 15, + isNotResponding: false, + isSuspended: false, + suspensionState: 'none', + isBlocked: false, + softwareName: 'misskey', + softwareVersion: '2024.5.0', + openRegistrations: false, + name: 'Misskey Hub', + description: '', + maintainerName: '', + maintainerEmail: '', + isSilenced: false, + iconUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/about-icon.png?raw=true', + faviconUrl: '', + themeColor: '', + infoUpdatedAt: '', + latestRequestReceivedAt: '', + }; +} + export function userDetailed(id = 'someuserid', username = 'miskist', host = 'misskey-hub.net', name = 'Misskey User'): entities.UserDetailed { return { id, diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index d21eea9d17..7b6c86447e 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -403,6 +403,7 @@ function toStories(component: string): Promise<string> { glob('src/components/MkSignupServerRules.vue'), glob('src/components/MkUserSetupDialog.vue'), glob('src/components/MkUserSetupDialog.*.vue'), + glob('src/components/MkInstanceCardMini.vue'), glob('src/components/MkInviteCode.vue'), glob('src/pages/user/home.vue'), ]); diff --git a/packages/frontend/src/components/MkChart.stories.impl.ts b/packages/frontend/src/components/MkChart.stories.impl.ts index 6b0cc3b858..d1d17f6dc0 100644 --- a/packages/frontend/src/components/MkChart.stories.impl.ts +++ b/packages/frontend/src/components/MkChart.stories.impl.ts @@ -29,7 +29,7 @@ function getChartArray(seed: string, limit: number, option?: { accumulate?: bool return array; } -function getChartResolver(fields: string[], option?: { accumulate?: boolean, mulMap?: Record<string, number> }): HttpResponseResolver<PathParams, DefaultBodyType, JsonBodyType> { +export function getChartResolver(fields: string[], option?: { accumulate?: boolean, mulMap?: Record<string, number> }): HttpResponseResolver<PathParams, DefaultBodyType, JsonBodyType> { return ({ request }) => { action(`GET ${request.url}`)(); const limitParam = new URL(request.url).searchParams.get('limit'); diff --git a/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts b/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts new file mode 100644 index 0000000000..a069a0eb8e --- /dev/null +++ b/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { StoryObj } from '@storybook/vue3'; +import { HttpResponse, http } from 'msw'; +import { federationInstance } from '../../.storybook/fakes.js'; +import { commonHandlers } from '../../.storybook/mocks.js'; +import MkInstanceCardMini from './MkInstanceCardMini.vue'; +import { getChartResolver } from './MkChart.stories.impl.js'; +export const Default = { + render(args) { + return { + components: { + MkInstanceCardMini, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '<MkInstanceCardMini v-bind="props" />', + }; + }, + args: { + instance: federationInstance(), + }, + parameters: { + layout: 'centered', + msw: { + handlers: [ + ...commonHandlers, + http.get('/undefined/preview.webp', async ({ request }) => { + const urlStr = new URL(request.url).searchParams.get('url'); + if (urlStr == null) { + return new HttpResponse(null, { status: 404 }); + } + const url = new URL(urlStr); + + if (url.href.startsWith('https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/')) { + const image = await (await fetch(`client-assets/${url.pathname.split('/').pop()}`)).blob(); + return new HttpResponse(image, { + headers: { + 'Content-Type': 'image/jpeg', + }, + }); + } else { + return new HttpResponse(null, { status: 404 }); + } + }), + http.get('/api/charts/instance', getChartResolver(['requests.received'])), + ], + }, + }, +} satisfies StoryObj<typeof MkInstanceCardMini>; diff --git a/packages/frontend/src/components/MkInstanceCardMini.vue b/packages/frontend/src/components/MkInstanceCardMini.vue index e26aef0f69..17c974dd04 100644 --- a/packages/frontend/src/components/MkInstanceCardMini.vue +++ b/packages/frontend/src/components/MkInstanceCardMini.vue @@ -29,8 +29,8 @@ const chartValues = ref<number[] | null>(null); misskeyApiGet('charts/instance', { host: props.instance.host, limit: 16 + 1, span: 'day' }).then(res => { // 今日のぶんの値はまだ途中の値であり、それも含めると大抵の場合前日よりも下降しているようなグラフになってしまうため今日は弾く - res['requests.received'].splice(0, 1); - chartValues.value = res['requests.received']; + res.requests.received.splice(0, 1); + chartValues.value = res.requests.received; }); function getInstanceIcon(instance): string { From 96fcb9f54c9576c8daa78064cbba630895ec8877 Mon Sep 17 00:00:00 2001 From: anatawa12 <anatawa12@icloud.com> Date: Sat, 15 Jun 2024 14:10:37 +0900 Subject: [PATCH 05/26] ci: upgrade dockle (#14002) --- .github/workflows/dockle.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dockle.yml b/.github/workflows/dockle.yml index eee7a78fed..968971dd8d 100644 --- a/.github/workflows/dockle.yml +++ b/.github/workflows/dockle.yml @@ -13,10 +13,12 @@ jobs: runs-on: ubuntu-latest env: DOCKER_CONTENT_TRUST: 1 + DOCKLE_VERSION: 0.4.14 steps: - uses: actions/checkout@v4.1.1 - - run: | - curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v0.4.10/dockle_0.4.10_Linux-64bit.deb" + - name: Download and install dockle v${{ env.DOCKLE_VERSION }} + run: | + curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb" sudo dpkg -i dockle.deb - run: | cp .config/docker_example.env .config/docker.env From 34458d767bd4430c8ed5f080409390aba6f62f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 15 Jun 2024 15:46:36 +0900 Subject: [PATCH 06/26] fix changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 097a69b687..76fed76b56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正 ### Client -- `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正 +- Fix: `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正 - Fix: ユーザーページの追加情報のラベルを投稿者のサーバーの絵文字で表示する (#13968) ### Server From 379ce0145b9d0b74334b35fa57f2ef87366388f2 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 15 Jun 2024 16:35:41 +0900 Subject: [PATCH 07/26] fix(frontend): fix time on `MkChart`'s story (#13958) --- .../frontend/src/components/MkChart.stories.impl.ts | 4 ++++ packages/frontend/src/components/MkChart.vue | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkChart.stories.impl.ts b/packages/frontend/src/components/MkChart.stories.impl.ts index d1d17f6dc0..3bae703245 100644 --- a/packages/frontend/src/components/MkChart.stories.impl.ts +++ b/packages/frontend/src/components/MkChart.stories.impl.ts @@ -76,6 +76,7 @@ const Base = { args: { src: 'federation', span: 'hour', + nowForChromatic: 1716263640000, }, parameters: { layout: 'centered', @@ -100,18 +101,21 @@ const Base = { export const FederationChart = { ...Base, args: { + ...Base.args, src: 'federation', }, } satisfies StoryObj<typeof MkChart>; export const NotesTotalChart = { ...Base, args: { + ...Base.args, src: 'notes-total', }, } satisfies StoryObj<typeof MkChart>; export const DriveChart = { ...Base, args: { + ...Base.args, src: 'drive', }, } satisfies StoryObj<typeof MkChart>; diff --git a/packages/frontend/src/components/MkChart.vue b/packages/frontend/src/components/MkChart.vue index a823a0ec4b..3816bca348 100644 --- a/packages/frontend/src/components/MkChart.vue +++ b/packages/frontend/src/components/MkChart.vue @@ -77,6 +77,7 @@ const props = withDefaults(defineProps<{ stacked?: boolean; bar?: boolean; aspectRatio?: number | null; + nowForChromatic?: number; }>(), { args: undefined, limit: 90, @@ -84,6 +85,13 @@ const props = withDefaults(defineProps<{ stacked: false, bar: false, aspectRatio: null, + + /** + * @desc Overwrites current date to fix background lines of chart. + * @ignore Only used for Chromatic. Don't use this for production. + * @see https://github.com/misskey-dev/misskey/pull/13830#issuecomment-2155886151 + */ + nowForChromatic: undefined, }); const legendEl = shallowRef<InstanceType<typeof MkChartLegend>>(); @@ -106,7 +114,8 @@ const getColor = (i) => { return colorSets[i % colorSets.length]; }; -const now = new Date(); +// eslint-disable-next-line vue/no-setup-props-destructure +const now = props.nowForChromatic != null ? new Date(props.nowForChromatic) : new Date(); let chartInstance: Chart | null = null; let chartData: { series: { From d0ee0203e12d41515b05d7d99ae09f70eeae5874 Mon Sep 17 00:00:00 2001 From: Ryu jongheon <lapy@lapy.link> Date: Tue, 18 Jun 2024 12:18:04 +0900 Subject: [PATCH 08/26] Fix(backend): Limit antenna/webhook/list to exact amount (#14036) ... not +1 * Update antennas/clips e2e test --- packages/backend/src/core/ClipService.ts | 4 ++-- packages/backend/src/core/UserListService.ts | 2 +- .../backend/src/server/api/endpoints/antennas/create.ts | 2 +- .../backend/src/server/api/endpoints/i/import-antennas.ts | 2 +- .../backend/src/server/api/endpoints/i/webhooks/create.ts | 2 +- .../server/api/endpoints/users/lists/create-from-public.ts | 2 +- .../backend/src/server/api/endpoints/users/lists/create.ts | 2 +- packages/backend/test/e2e/antennas.ts | 3 +-- packages/backend/test/e2e/clips.ts | 7 +++---- 9 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/backend/src/core/ClipService.ts b/packages/backend/src/core/ClipService.ts index 9fd1ebad87..929a9db064 100644 --- a/packages/backend/src/core/ClipService.ts +++ b/packages/backend/src/core/ClipService.ts @@ -41,7 +41,7 @@ export class ClipService { const currentCount = await this.clipsRepository.countBy({ userId: me.id, }); - if (currentCount > (await this.roleService.getUserPolicies(me.id)).clipLimit) { + if (currentCount >= (await this.roleService.getUserPolicies(me.id)).clipLimit) { throw new ClipService.TooManyClipsError(); } @@ -102,7 +102,7 @@ export class ClipService { const currentCount = await this.clipNotesRepository.countBy({ clipId: clip.id, }); - if (currentCount > (await this.roleService.getUserPolicies(me.id)).noteEachClipsLimit) { + if (currentCount >= (await this.roleService.getUserPolicies(me.id)).noteEachClipsLimit) { throw new ClipService.TooManyClipNotesError(); } diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index bbdcfed738..6333356fe9 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -95,7 +95,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { const currentCount = await this.userListMembershipsRepository.countBy({ userListId: list.id, }); - if (currentCount > (await this.roleService.getUserPolicies(me.id)).userEachUserListsLimit) { + if (currentCount >= (await this.roleService.getUserPolicies(me.id)).userEachUserListsLimit) { throw new UserListService.TooManyUsersError(); } diff --git a/packages/backend/src/server/api/endpoints/antennas/create.ts b/packages/backend/src/server/api/endpoints/antennas/create.ts index ec08198514..577b9e1b1f 100644 --- a/packages/backend/src/server/api/endpoints/antennas/create.ts +++ b/packages/backend/src/server/api/endpoints/antennas/create.ts @@ -93,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const currentAntennasCount = await this.antennasRepository.countBy({ userId: me.id, }); - if (currentAntennasCount > (await this.roleService.getUserPolicies(me.id)).antennaLimit) { + if (currentAntennasCount >= (await this.roleService.getUserPolicies(me.id)).antennaLimit) { throw new ApiError(meta.errors.tooManyAntennas); } diff --git a/packages/backend/src/server/api/endpoints/i/import-antennas.ts b/packages/backend/src/server/api/endpoints/i/import-antennas.ts index b4661a93e2..bc46163e3d 100644 --- a/packages/backend/src/server/api/endpoints/i/import-antennas.ts +++ b/packages/backend/src/server/api/endpoints/i/import-antennas.ts @@ -78,7 +78,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { if (file.size === 0) throw new ApiError(meta.errors.emptyFile); const antennas: (_Antenna & { userListAccts: string[] | null })[] = JSON.parse(await this.downloadService.downloadTextFile(file.url)); const currentAntennasCount = await this.antennasRepository.countBy({ userId: me.id }); - if (currentAntennasCount + antennas.length > (await this.roleService.getUserPolicies(me.id)).antennaLimit) { + if (currentAntennasCount + antennas.length >= (await this.roleService.getUserPolicies(me.id)).antennaLimit) { throw new ApiError(meta.errors.tooManyAntennas); } this.queueService.createImportAntennasJob(me, antennas); diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts index c692380288..9eb7f5b3a0 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts @@ -85,7 +85,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const currentWebhooksCount = await this.webhooksRepository.countBy({ userId: me.id, }); - if (currentWebhooksCount > (await this.roleService.getUserPolicies(me.id)).webhookLimit) { + if (currentWebhooksCount >= (await this.roleService.getUserPolicies(me.id)).webhookLimit) { throw new ApiError(meta.errors.tooManyWebhooks); } diff --git a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts index 8504da0209..7e44d501ab 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts @@ -100,7 +100,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const currentCount = await this.userListsRepository.countBy({ userId: me.id, }); - if (currentCount > (await this.roleService.getUserPolicies(me.id)).userListLimit) { + if (currentCount >= (await this.roleService.getUserPolicies(me.id)).userListLimit) { throw new ApiError(meta.errors.tooManyUserLists); } diff --git a/packages/backend/src/server/api/endpoints/users/lists/create.ts b/packages/backend/src/server/api/endpoints/users/lists/create.ts index 9378bde5cb..7daf05ba4e 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create.ts @@ -61,7 +61,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const currentCount = await this.userListsRepository.countBy({ userId: me.id, }); - if (currentCount > (await this.roleService.getUserPolicies(me.id)).userListLimit) { + if (currentCount >= (await this.roleService.getUserPolicies(me.id)).userListLimit) { throw new ApiError(meta.errors.tooManyUserLists); } diff --git a/packages/backend/test/e2e/antennas.ts b/packages/backend/test/e2e/antennas.ts index 101238b601..6ac14cd8dc 100644 --- a/packages/backend/test/e2e/antennas.ts +++ b/packages/backend/test/e2e/antennas.ts @@ -163,8 +163,7 @@ describe('アンテナ', () => { }); test('が上限いっぱいまで作成できること', async () => { - // antennaLimit + 1まで作れるのがキモ - const response = await Promise.all([...Array(DEFAULT_POLICIES.antennaLimit + 1)].map(() => successfulApiCall({ + const response = await Promise.all([...Array(DEFAULT_POLICIES.antennaLimit)].map(() => successfulApiCall({ endpoint: 'antennas/create', parameters: { ...defaultParam }, user: alice, diff --git a/packages/backend/test/e2e/clips.ts b/packages/backend/test/e2e/clips.ts index ba6f9d6a65..a229ec06f9 100644 --- a/packages/backend/test/e2e/clips.ts +++ b/packages/backend/test/e2e/clips.ts @@ -153,8 +153,7 @@ describe('クリップ', () => { }); test('の作成はポリシーで定められた数以上はできない。', async () => { - // ポリシー + 1まで作れるという所がミソ - const clipLimit = DEFAULT_POLICIES.clipLimit + 1; + const clipLimit = DEFAULT_POLICIES.clipLimit; for (let i = 0; i < clipLimit; i++) { await create(); } @@ -327,7 +326,7 @@ describe('クリップ', () => { }); test('の一覧(clips/list)が取得できる(上限いっぱい)', async () => { - const clipLimit = DEFAULT_POLICIES.clipLimit + 1; + const clipLimit = DEFAULT_POLICIES.clipLimit; const clips = await createMany({}, clipLimit); const res = await list({ parameters: { limit: 1 }, // FIXME: 無視されて11全部返ってくる @@ -705,7 +704,7 @@ describe('クリップ', () => { // TODO: 17000msくらいかかる... test('をポリシーで定められた上限いっぱい(200)を超えて追加はできない。', async () => { - const noteLimit = DEFAULT_POLICIES.noteEachClipsLimit + 1; + const noteLimit = DEFAULT_POLICIES.noteEachClipsLimit; const noteList = await Promise.all([...Array(noteLimit)].map((_, i) => post(alice, { text: `test ${i}`, }) as unknown)) as Misskey.entities.Note[]; From a88579ca98a70115d6a61c74f26c36215f1f3daa Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:44:30 +0900 Subject: [PATCH 09/26] docs: add changelog entry (follow-up of #14036) (#14037) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76fed76b56..3341d4afff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Server - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) +- Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036) ## 2024.5.0 From f37d684fab115591f2565c9ca11964f802d1c36c Mon Sep 17 00:00:00 2001 From: woxtu <woxtup@gmail.com> Date: Tue, 18 Jun 2024 19:46:20 +0900 Subject: [PATCH 10/26] Add missing styles (#14031) --- packages/frontend/src/pages/announcement.vue | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/frontend/src/pages/announcement.vue b/packages/frontend/src/pages/announcement.vue index 85ae9062d4..802a6bf399 100644 --- a/packages/frontend/src/pages/announcement.vue +++ b/packages/frontend/src/pages/announcement.vue @@ -109,6 +109,15 @@ definePageMetadata(() => ({ </script> <style lang="scss" module> +.fadeEnterActive, +.fadeLeaveActive { + transition: opacity 0.125s ease; +} +.fadeEnterFrom, +.fadeLeaveTo { + opacity: 0; +} + .announcement { padding: 16px; } From 77ae69355c706a5024fae3d645e2f8ef5f436fbf Mon Sep 17 00:00:00 2001 From: woxtu <woxtup@gmail.com> Date: Wed, 19 Jun 2024 12:19:38 +0900 Subject: [PATCH 11/26] Enable to iterate over DOM collections (#14040) --- packages/frontend/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/frontend/tsconfig.json b/packages/frontend/tsconfig.json index 819629a9cf..187a2473ba 100644 --- a/packages/frontend/tsconfig.json +++ b/packages/frontend/tsconfig.json @@ -37,7 +37,8 @@ ], "lib": [ "esnext", - "dom" + "dom", + "dom.iterable" ], "jsx": "preserve" }, From b683d79f8b3efffa4498380a47f136d79e0ddbe7 Mon Sep 17 00:00:00 2001 From: woxtu <woxtup@gmail.com> Date: Thu, 20 Jun 2024 16:24:10 +0900 Subject: [PATCH 12/26] Fix type checking (#14047) --- packages/frontend/src/account.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/account.ts b/packages/frontend/src/account.ts index 7f20e0b1a2..f99b550a83 100644 --- a/packages/frontend/src/account.ts +++ b/packages/frontend/src/account.ts @@ -120,7 +120,7 @@ function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Pr res.json().then(done2, fail2); })) .then(async res => { - if (res.error) { + if ('error' in res) { if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') { // SUSPENDED if (forceShowDialog || $i && (token === $i.token || id === $i.id)) { From 1df90cef4c5ca8fc71b8dd491e0b90ad47263a35 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:03:00 +0900 Subject: [PATCH 13/26] update typescript --- package.json | 2 +- packages/backend/package.json | 2 +- packages/frontend/package.json | 2 +- packages/misskey-js/package.json | 2 +- packages/sw/package.json | 2 +- pnpm-lock.yaml | 264 +++++++++++++++---------------- 6 files changed, 137 insertions(+), 137 deletions(-) diff --git a/package.json b/package.json index b1786e16f1..5adce65415 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "postcss": "8.4.38", "tar": "6.2.1", "terser": "5.30.3", - "typescript": "5.4.5", + "typescript": "5.5.2", "esbuild": "0.20.2", "glob": "10.3.12" }, diff --git a/packages/backend/package.json b/packages/backend/package.json index 772dc8f8b5..15134b1ca8 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -177,7 +177,7 @@ "tsc-alias": "1.8.8", "tsconfig-paths": "4.2.0", "typeorm": "0.3.20", - "typescript": "5.4.5", + "typescript": "5.5.2", "ulid": "2.3.0", "vary": "1.1.2", "web-push": "3.6.7", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 66940a1601..a63d97658b 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -68,7 +68,7 @@ "tinycolor2": "1.6.0", "tsc-alias": "1.8.8", "tsconfig-paths": "4.2.0", - "typescript": "5.4.5", + "typescript": "5.5.2", "uuid": "9.0.1", "v-code-diff": "1.11.0", "vite": "5.2.11", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 4ff1a57309..b99d0dd260 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -51,7 +51,7 @@ "nodemon": "3.1.0", "execa": "8.0.1", "tsd": "0.30.7", - "typescript": "5.4.5", + "typescript": "5.5.2", "esbuild": "0.19.11", "glob": "10.3.12" }, diff --git a/packages/sw/package.json b/packages/sw/package.json index cb59a70238..2deda47369 100644 --- a/packages/sw/package.json +++ b/packages/sw/package.json @@ -20,7 +20,7 @@ "eslint": "8.57.0", "eslint-plugin-import": "2.29.1", "nodemon": "3.1.0", - "typescript": "5.4.5" + "typescript": "5.5.2" }, "type": "module" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5400828781..1281f7eefe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,8 +43,8 @@ importers: specifier: 5.30.3 version: 5.30.3 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.5.2 + version: 5.5.2 optionalDependencies: '@tensorflow/tfjs-core': specifier: 4.4.0 @@ -55,10 +55,10 @@ importers: version: 20.12.7 '@typescript-eslint/eslint-plugin': specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/parser': specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) cross-env: specifier: 7.0.3 version: 7.0.3 @@ -414,8 +414,8 @@ importers: specifier: 0.3.20 version: 0.3.20(ioredis@5.4.1)(pg@8.11.5) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.5.2 + version: 5.5.2 ulid: specifier: 2.3.0 version: 2.3.0 @@ -525,7 +525,7 @@ importers: version: 29.7.0 '@misskey-dev/eslint-plugin': specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) '@nestjs/platform-express': specifier: 10.3.8 version: 10.3.8(@nestjs/common@10.3.8(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.8) @@ -651,10 +651,10 @@ importers: version: 8.5.10 '@typescript-eslint/eslint-plugin': specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/parser': specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) aws-sdk-client-mock: specifier: 3.0.1 version: 3.0.1 @@ -666,7 +666,7 @@ importers: version: 8.57.0 eslint-plugin-import: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) execa: specifier: 8.0.1 version: 8.0.1 @@ -723,7 +723,7 @@ importers: version: 15.1.1 '@vitejs/plugin-vue': specifier: 5.0.4 - version: 5.0.4(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.4.5)) + version: 5.0.4(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2)) '@vue/compiler-sfc': specifier: 3.4.26 version: 3.4.26 @@ -845,27 +845,27 @@ importers: specifier: 4.2.0 version: 4.2.0 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.5.2 + version: 5.5.2 uuid: specifier: 9.0.1 version: 9.0.1 v-code-diff: specifier: 1.11.0 - version: 1.11.0(vue@3.4.26(typescript@5.4.5)) + version: 1.11.0(vue@3.4.26(typescript@5.5.2)) vite: specifier: 5.2.11 version: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) vue: specifier: 3.4.26 - version: 3.4.26(typescript@5.4.5) + version: 3.4.26(typescript@5.5.2) vuedraggable: specifier: next - version: 4.1.0(vue@3.4.26(typescript@5.4.5)) + version: 4.1.0(vue@3.4.26(typescript@5.5.2)) devDependencies: '@misskey-dev/eslint-plugin': specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) '@misskey-dev/summaly': specifier: 5.1.0 version: 5.1.0 @@ -904,10 +904,10 @@ importers: version: 8.0.9 '@storybook/react': specifier: 8.0.9 - version: 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + version: 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.2) '@storybook/react-vite': specifier: 8.0.9 - version: 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.17.2)(typescript@5.4.5)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) + version: 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.17.2)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) '@storybook/test': specifier: 8.0.9 version: 8.0.9(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.12.7))(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) @@ -919,13 +919,13 @@ importers: version: 8.0.9 '@storybook/vue3': specifier: 8.0.9 - version: 8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.4.5)) + version: 8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.5.2)) '@storybook/vue3-vite': specifier: 8.0.9 - version: 8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.4.5)) + version: 8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2)) '@testing-library/vue': specifier: 8.0.3 - version: 8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5)) + version: 8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2)) '@types/escape-regexp': specifier: 0.0.3 version: 0.0.3 @@ -964,10 +964,10 @@ importers: version: 8.5.10 '@typescript-eslint/eslint-plugin': specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/parser': specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) '@vitest/coverage-v8': specifier: 0.34.6 version: 0.34.6(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3)) @@ -988,7 +988,7 @@ importers: version: 8.57.0 eslint-plugin-import: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) eslint-plugin-vue: specifier: 9.25.0 version: 9.25.0(eslint@8.57.0) @@ -1006,10 +1006,10 @@ importers: version: 4.0.5 msw: specifier: 2.2.14 - version: 2.2.14(typescript@5.4.5) + version: 2.2.14(typescript@5.5.2) msw-storybook-addon: specifier: 2.0.1 - version: 2.0.1(msw@2.2.14(typescript@5.4.5)) + version: 2.0.1(msw@2.2.14(typescript@5.5.2)) nodemon: specifier: 3.1.0 version: 3.1.0 @@ -1051,7 +1051,7 @@ importers: version: 9.4.2(eslint@8.57.0) vue-tsc: specifier: 2.0.16 - version: 2.0.16(typescript@5.4.5) + version: 2.0.16(typescript@5.5.2) packages/misskey-bubble-game: dependencies: @@ -1116,7 +1116,7 @@ importers: version: 7.43.1(@types/node@20.12.7) '@misskey-dev/eslint-plugin': specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) '@swc/jest': specifier: 0.2.36 version: 0.2.36(@swc/core@1.4.17) @@ -1128,10 +1128,10 @@ importers: version: 20.12.7 '@typescript-eslint/eslint-plugin': specifier: 7.7.1 - version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/parser': specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) esbuild: specifier: 0.19.11 version: 0.19.11 @@ -1166,8 +1166,8 @@ importers: specifier: 0.30.7 version: 0.30.7 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.5.2 + version: 5.5.2 packages/misskey-js/generator: devDependencies: @@ -1256,10 +1256,10 @@ importers: devDependencies: '@misskey-dev/eslint-plugin': specifier: 1.0.0 - version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + version: 1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0) '@typescript-eslint/parser': specifier: 7.7.1 - version: 7.7.1(eslint@8.57.0)(typescript@5.4.5) + version: 7.7.1(eslint@8.57.0)(typescript@5.5.2) '@typescript/lib-webworker': specifier: npm:@types/serviceworker@0.0.67 version: '@types/serviceworker@0.0.67' @@ -1268,13 +1268,13 @@ importers: version: 8.57.0 eslint-plugin-import: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) nodemon: specifier: 3.1.0 version: 3.1.0 typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 5.5.2 + version: 5.5.2 packages: @@ -10836,8 +10836,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + typescript@5.5.2: + resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==} engines: {node: '>=14.17'} hasBin: true @@ -13662,15 +13662,15 @@ snapshots: '@types/yargs': 17.0.19 chalk: 4.1.2 - '@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.4.5)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': dependencies: glob: 7.2.3 glob-promise: 4.2.2(glob@7.2.3) magic-string: 0.27.0 - react-docgen-typescript: 2.2.2(typescript@5.4.5) + react-docgen-typescript: 2.2.2(typescript@5.5.2) vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 '@jridgewell/gen-mapping@0.3.2': dependencies: @@ -13785,12 +13785,12 @@ snapshots: eslint: 8.57.0 eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0) - '@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0)': + '@misskey-dev/eslint-plugin@1.0.0(@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0))(eslint@8.57.0)': dependencies: - '@typescript-eslint/eslint-plugin': 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2) + '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0) '@misskey-dev/sharp-read-bmp@1.2.0': dependencies: @@ -15020,7 +15020,7 @@ snapshots: - encoding - supports-color - '@storybook/builder-vite@8.0.9(encoding@0.1.13)(typescript@5.4.5)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': + '@storybook/builder-vite@8.0.9(encoding@0.1.13)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': dependencies: '@storybook/channels': 8.0.9 '@storybook/client-logger': 8.0.9 @@ -15041,7 +15041,7 @@ snapshots: ts-dedent: 2.2.0 vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 transitivePeerDependencies: - encoding - supports-color @@ -15339,13 +15339,13 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/react-vite@8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.17.2)(typescript@5.4.5)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': + '@storybook/react-vite@8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.17.2)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.4.5)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) '@rollup/pluginutils': 5.1.0(rollup@4.17.2) - '@storybook/builder-vite': 8.0.9(encoding@0.1.13)(typescript@5.4.5)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) + '@storybook/builder-vite': 8.0.9(encoding@0.1.13)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) '@storybook/node-logger': 8.0.9 - '@storybook/react': 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + '@storybook/react': 8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.2) find-up: 5.0.0 magic-string: 0.30.7 react: 18.3.1 @@ -15362,7 +15362,7 @@ snapshots: - typescript - vite-plugin-glimmerx - '@storybook/react@8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)': + '@storybook/react@8.0.9(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.5.2)': dependencies: '@storybook/client-logger': 8.0.9 '@storybook/docs-tools': 8.0.9(encoding@0.1.13) @@ -15388,7 +15388,7 @@ snapshots: type-fest: 2.19.0 util-deprecate: 1.0.2 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 transitivePeerDependencies: - encoding - supports-color @@ -15456,17 +15456,17 @@ snapshots: '@types/express': 4.17.17 file-system-cache: 2.3.0 - '@storybook/vue3-vite@8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.4.5))': + '@storybook/vue3-vite@8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2))': dependencies: - '@storybook/builder-vite': 8.0.9(encoding@0.1.13)(typescript@5.4.5)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) + '@storybook/builder-vite': 8.0.9(encoding@0.1.13)(typescript@5.5.2)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3)) '@storybook/core-server': 8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3) - '@storybook/vue3': 8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.4.5)) + '@storybook/vue3': 8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.5.2)) find-package-json: 1.2.0 magic-string: 0.30.7 - typescript: 5.4.5 + typescript: 5.5.2 vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) - vue-component-meta: 2.0.16(typescript@5.4.5) - vue-docgen-api: 4.75.1(vue@3.4.26(typescript@5.4.5)) + vue-component-meta: 2.0.16(typescript@5.5.2) + vue-docgen-api: 4.75.1(vue@3.4.26(typescript@5.5.2)) transitivePeerDependencies: - '@preact/preset-vite' - bufferutil @@ -15478,7 +15478,7 @@ snapshots: - vite-plugin-glimmerx - vue - '@storybook/vue3@8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.4.5))': + '@storybook/vue3@8.0.9(encoding@0.1.13)(vue@3.4.26(typescript@5.5.2))': dependencies: '@storybook/docs-tools': 8.0.9(encoding@0.1.13) '@storybook/global': 5.0.0 @@ -15488,7 +15488,7 @@ snapshots: lodash: 4.17.21 ts-dedent: 2.2.0 type-fest: 2.19.0 - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) vue-component-type-helpers: 2.0.21 transitivePeerDependencies: - encoding @@ -15750,12 +15750,12 @@ snapshots: dependencies: '@testing-library/dom': 9.3.4 - '@testing-library/vue@8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))': + '@testing-library/vue@8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2))': dependencies: '@babel/runtime': 7.23.4 '@testing-library/dom': 9.3.3 - '@vue/test-utils': 2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5)) - vue: 3.4.26(typescript@5.4.5) + '@vue/test-utils': 2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2)) + vue: 3.4.26(typescript@5.5.2) optionalDependencies: '@vue/compiler-sfc': 3.4.26 transitivePeerDependencies: @@ -16236,13 +16236,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/scope-manager': 7.7.1 - '@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.5.2) + '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/visitor-keys': 7.7.1 debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 @@ -16250,9 +16250,9 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.2) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 transitivePeerDependencies: - supports-color @@ -16282,16 +16282,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2)': dependencies: '@typescript-eslint/scope-manager': 7.7.1 '@typescript-eslint/types': 7.7.1 - '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.2) '@typescript-eslint/visitor-keys': 7.7.1 debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 transitivePeerDependencies: - supports-color @@ -16334,15 +16334,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.7.1(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@7.7.1(eslint@8.57.0)(typescript@5.5.2)': dependencies: - '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5) - '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.2) + '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.5.2) debug: 4.3.4(supports-color@8.1.1) eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.2) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 transitivePeerDependencies: - supports-color @@ -16381,7 +16381,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.7.1(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@7.7.1(typescript@5.5.2)': dependencies: '@typescript-eslint/types': 7.7.1 '@typescript-eslint/visitor-keys': 7.7.1 @@ -16390,9 +16390,9 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.4 semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.3.0(typescript@5.5.2) optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 transitivePeerDependencies: - supports-color @@ -16424,14 +16424,14 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@7.7.1(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/utils@7.7.1(eslint@8.57.0)(typescript@5.5.2)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 7.7.1 '@typescript-eslint/types': 7.7.1 - '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.5.2) eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: @@ -16455,10 +16455,10 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.4.5))': + '@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.5.2))': dependencies: vite: 5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3) - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) '@vitest/coverage-v8@0.34.6(vitest@0.34.6(happy-dom@10.0.3)(jsdom@24.0.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(sass@1.76.0)(terser@5.30.3))': dependencies: @@ -16604,7 +16604,7 @@ snapshots: '@vue/devtools-api@6.6.1': {} - '@vue/language-core@2.0.16(typescript@5.4.5)': + '@vue/language-core@2.0.16(typescript@5.5.2)': dependencies: '@volar/language-core': 2.2.0 '@vue/compiler-dom': 3.4.25 @@ -16614,7 +16614,7 @@ snapshots: path-browserify: 1.0.1 vue-template-compiler: 2.7.14 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 '@vue/reactivity@3.4.26': dependencies: @@ -16631,11 +16631,11 @@ snapshots: '@vue/shared': 3.4.26 csstype: 3.1.3 - '@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5))': + '@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2))': dependencies: '@vue/compiler-ssr': 3.4.26 '@vue/shared': 3.4.26 - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) '@vue/shared@3.4.21': {} @@ -16643,13 +16643,13 @@ snapshots: '@vue/shared@3.4.26': {} - '@vue/test-utils@2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))': + '@vue/test-utils@2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.5.2)))(vue@3.4.26(typescript@5.5.2))': dependencies: js-beautify: 1.14.9 - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) vue-component-type-helpers: 1.8.4 optionalDependencies: - '@vue/server-renderer': 3.4.26(vue@3.4.26(typescript@5.4.5)) + '@vue/server-renderer': 3.4.26(vue@3.4.26(typescript@5.5.2)) '@webgpu/types@0.1.30': {} @@ -18423,11 +18423,11 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): dependencies: debug: 3.2.7(supports-color@8.1.1) optionalDependencies: - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: @@ -18487,7 +18487,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0): dependencies: array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 @@ -18497,7 +18497,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -18508,7 +18508,7 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.5.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -21148,12 +21148,12 @@ snapshots: optionalDependencies: msgpackr-extract: 3.0.2 - msw-storybook-addon@2.0.1(msw@2.2.14(typescript@5.4.5)): + msw-storybook-addon@2.0.1(msw@2.2.14(typescript@5.5.2)): dependencies: is-node-process: 1.2.0 - msw: 2.2.14(typescript@5.4.5) + msw: 2.2.14(typescript@5.5.2) - msw@2.2.14(typescript@5.4.5): + msw@2.2.14(typescript@5.5.2): dependencies: '@bundled-es-modules/cookie': 2.0.0 '@bundled-es-modules/statuses': 1.0.1 @@ -21173,7 +21173,7 @@ snapshots: type-fest: 4.9.0 yargs: 17.7.2 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 muggle-string@0.4.1: {} @@ -22284,9 +22284,9 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-docgen-typescript@2.2.2(typescript@5.4.5): + react-docgen-typescript@2.2.2(typescript@5.5.2): dependencies: - typescript: 5.4.5 + typescript: 5.5.2 react-docgen@7.0.1: dependencies: @@ -23405,9 +23405,9 @@ snapshots: dependencies: typescript: 5.3.3 - ts-api-utils@1.3.0(typescript@5.4.5): + ts-api-utils@1.3.0(typescript@5.5.2): dependencies: - typescript: 5.4.5 + typescript: 5.5.2 ts-case-convert@2.0.2: {} @@ -23547,7 +23547,7 @@ snapshots: typescript@5.4.2: {} - typescript@5.4.5: {} + typescript@5.5.2: {} ufo@1.3.2: {} @@ -23694,14 +23694,14 @@ snapshots: uuid@9.0.1: {} - v-code-diff@1.11.0(vue@3.4.26(typescript@5.4.5)): + v-code-diff@1.11.0(vue@3.4.26(typescript@5.5.2)): dependencies: diff: 5.1.0 diff-match-patch: 1.0.5 highlight.js: 11.9.0 - vue: 3.4.26(typescript@5.4.5) - vue-demi: 0.14.7(vue@3.4.26(typescript@5.4.5)) - vue-i18n: 9.13.1(vue@3.4.26(typescript@5.4.5)) + vue: 3.4.26(typescript@5.5.2) + vue-demi: 0.14.7(vue@3.4.26(typescript@5.5.2)) + vue-i18n: 9.13.1(vue@3.4.26(typescript@5.5.2)) v8-to-istanbul@9.2.0: dependencies: @@ -23834,14 +23834,14 @@ snapshots: dependencies: vscode-languageserver-protocol: 3.17.5 - vue-component-meta@2.0.16(typescript@5.4.5): + vue-component-meta@2.0.16(typescript@5.5.2): dependencies: '@volar/typescript': 2.2.0 - '@vue/language-core': 2.0.16(typescript@5.4.5) + '@vue/language-core': 2.0.16(typescript@5.5.2) path-browserify: 1.0.1 vue-component-type-helpers: 2.0.16 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 vue-component-type-helpers@1.8.4: {} @@ -23849,11 +23849,11 @@ snapshots: vue-component-type-helpers@2.0.21: {} - vue-demi@0.14.7(vue@3.4.26(typescript@5.4.5)): + vue-demi@0.14.7(vue@3.4.26(typescript@5.5.2)): dependencies: - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) - vue-docgen-api@4.75.1(vue@3.4.26(typescript@5.4.5)): + vue-docgen-api@4.75.1(vue@3.4.26(typescript@5.5.2)): dependencies: '@babel/parser': 7.24.0 '@babel/types': 7.24.0 @@ -23865,8 +23865,8 @@ snapshots: pug: 3.0.2 recast: 0.23.4 ts-map: 1.0.3 - vue: 3.4.26(typescript@5.4.5) - vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.4.26(typescript@5.4.5)) + vue: 3.4.26(typescript@5.5.2) + vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.4.26(typescript@5.5.2)) vue-eslint-parser@9.4.2(eslint@8.57.0): dependencies: @@ -23881,43 +23881,43 @@ snapshots: transitivePeerDependencies: - supports-color - vue-i18n@9.13.1(vue@3.4.26(typescript@5.4.5)): + vue-i18n@9.13.1(vue@3.4.26(typescript@5.5.2)): dependencies: '@intlify/core-base': 9.13.1 '@intlify/shared': 9.13.1 '@vue/devtools-api': 6.6.1 - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) - vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.4.26(typescript@5.4.5)): + vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.4.26(typescript@5.5.2)): dependencies: - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) vue-template-compiler@2.7.14: dependencies: de-indent: 1.0.2 he: 1.2.0 - vue-tsc@2.0.16(typescript@5.4.5): + vue-tsc@2.0.16(typescript@5.5.2): dependencies: '@volar/typescript': 2.2.0 - '@vue/language-core': 2.0.16(typescript@5.4.5) + '@vue/language-core': 2.0.16(typescript@5.5.2) semver: 7.6.0 - typescript: 5.4.5 + typescript: 5.5.2 - vue@3.4.26(typescript@5.4.5): + vue@3.4.26(typescript@5.5.2): dependencies: '@vue/compiler-dom': 3.4.26 '@vue/compiler-sfc': 3.4.26 '@vue/runtime-dom': 3.4.26 - '@vue/server-renderer': 3.4.26(vue@3.4.26(typescript@5.4.5)) + '@vue/server-renderer': 3.4.26(vue@3.4.26(typescript@5.5.2)) '@vue/shared': 3.4.26 optionalDependencies: - typescript: 5.4.5 + typescript: 5.5.2 - vuedraggable@4.1.0(vue@3.4.26(typescript@5.4.5)): + vuedraggable@4.1.0(vue@3.4.26(typescript@5.5.2)): dependencies: sortablejs: 1.14.0 - vue: 3.4.26(typescript@5.4.5) + vue: 3.4.26(typescript@5.5.2) w3c-xmlserializer@5.0.0: dependencies: From bf33382082c41199b631c06ac20ea369b0747470 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:03:51 +0900 Subject: [PATCH 14/26] refactor(backend): remove unnecessary isNotNull sugar --- .../src/core/AbuseReportNotificationService.ts | 7 +++---- packages/backend/src/core/NoteCreateService.ts | 3 +-- .../src/core/activitypub/ApAudienceService.ts | 3 +-- .../backend/src/core/activitypub/ApInboxService.ts | 3 +-- .../src/core/activitypub/ApRendererService.ts | 5 ++--- .../src/core/activitypub/models/ApMentionService.ts | 3 +-- .../src/core/activitypub/models/ApNoteService.ts | 3 +-- .../src/core/activitypub/models/ApPersonService.ts | 3 +-- .../core/activitypub/models/ApQuestionService.ts | 3 +-- packages/backend/src/core/activitypub/models/tag.ts | 3 +-- ...AbuseReportNotificationRecipientEntityService.ts | 5 ++--- .../core/entities/AbuseUserReportEntityService.ts | 3 +-- .../src/core/entities/DriveFileEntityService.ts | 7 +++---- .../src/core/entities/InviteCodeEntityService.ts | 5 ++--- .../backend/src/core/entities/NoteEntityService.ts | 9 ++++----- .../src/core/entities/NotificationEntityService.ts | 13 ++++++------- .../backend/src/core/entities/PageEntityService.ts | 3 +-- .../backend/src/core/entities/UserEntityService.ts | 3 +-- packages/backend/src/misc/is-not-null.ts | 8 -------- .../server/api/endpoints/gallery/posts/create.ts | 3 +-- .../server/api/endpoints/gallery/posts/update.ts | 3 +-- .../src/server/api/endpoints/pinned-users.ts | 3 +-- 22 files changed, 36 insertions(+), 65 deletions(-) delete mode 100644 packages/backend/src/misc/is-not-null.ts diff --git a/packages/backend/src/core/AbuseReportNotificationService.ts b/packages/backend/src/core/AbuseReportNotificationService.ts index df752afcd8..42e5931212 100644 --- a/packages/backend/src/core/AbuseReportNotificationService.ts +++ b/packages/backend/src/core/AbuseReportNotificationService.ts @@ -10,7 +10,6 @@ import sanitizeHtml from 'sanitize-html'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { GlobalEvents, GlobalEventService } from '@/core/GlobalEventService.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import type { AbuseReportNotificationRecipientRepository, MiAbuseReportNotificationRecipient, @@ -91,7 +90,7 @@ export class AbuseReportNotificationService implements OnApplicationShutdown { const recipientEMailAddresses = await this.fetchEMailRecipients().then(it => it .filter(it => it.isActive && it.userProfile?.emailVerified) .map(it => it.userProfile?.email) - .filter(isNotNull), + .filter(x => x != null), ); // 送信先の鮮度を保つため、毎回取得する @@ -138,7 +137,7 @@ export class AbuseReportNotificationService implements OnApplicationShutdown { .then(it => it .filter(it => it.isActive && it.systemWebhookId && it.method === 'webhook') .map(it => it.systemWebhookId) - .filter(isNotNull)); + .filter(x => x != null)); for (const webhookId of recipientWebhookIds) { await Promise.all( abuseReports.map(it => { @@ -340,7 +339,7 @@ export class AbuseReportNotificationService implements OnApplicationShutdown { @bindThis private async removeUnauthorizedRecipientUsers(recipients: MiAbuseReportNotificationRecipient[]): Promise<MiAbuseReportNotificationRecipient[]> { const userRecipients = recipients.filter(it => it.userId !== null); - const recipientUserIds = new Set(userRecipients.map(it => it.userId).filter(isNotNull)); + const recipientUserIds = new Set(userRecipients.map(it => it.userId).filter(x => x != null)); if (recipientUserIds.size <= 0) { // ユーザが通知先として設定されていない場合、この関数での処理を行うべきレコードが無い return recipients; diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 0c9de117d2..a2c3aaa701 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -59,7 +59,6 @@ import { UtilityService } from '@/core/UtilityService.js'; import { UserBlockingService } from '@/core/UserBlockingService.js'; import { isReply } from '@/misc/is-reply.js'; import { trackPromise } from '@/misc/promise-tracker.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; @@ -839,7 +838,7 @@ export class NoteCreateService implements OnApplicationShutdown { const mentions = extractMentions(tokens); let mentionedUsers = (await Promise.all(mentions.map(m => this.remoteUserResolveService.resolveUser(m.username, m.host ?? user.host).catch(() => null), - ))).filter(isNotNull); + ))).filter(x => x != null); // Drop duplicate users mentionedUsers = mentionedUsers.filter((u, i, self) => diff --git a/packages/backend/src/core/activitypub/ApAudienceService.ts b/packages/backend/src/core/activitypub/ApAudienceService.ts index 0fccc7b950..5a5a76f7d6 100644 --- a/packages/backend/src/core/activitypub/ApAudienceService.ts +++ b/packages/backend/src/core/activitypub/ApAudienceService.ts @@ -8,7 +8,6 @@ import promiseLimit from 'promise-limit'; import type { MiRemoteUser, MiUser } from '@/models/User.js'; import { concat, unique } from '@/misc/prelude/array.js'; import { bindThis } from '@/decorators.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { getApIds } from './type.js'; import { ApPersonService } from './models/ApPersonService.js'; import type { ApObject } from './type.js'; @@ -41,7 +40,7 @@ export class ApAudienceService { const limit = promiseLimit<MiUser | null>(2); const mentionedUsers = (await Promise.all( others.map(id => limit(() => this.apPersonService.resolvePerson(id, resolver).catch(() => null))), - )).filter(isNotNull); + )).filter(x => x != null); if (toGroups.public.length > 0) { return { diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index de3178b482..e2164fec1d 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -27,7 +27,6 @@ import { QueueService } from '@/core/QueueService.js'; import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import type { MiRemoteUser } from '@/models/User.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { AbuseReportService } from '@/core/AbuseReportService.js'; import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; @@ -538,7 +537,7 @@ export class ApInboxService { const userIds = uris .filter(uri => uri.startsWith(this.config.url + '/users/')) .map(uri => uri.split('/').at(-1)) - .filter(isNotNull); + .filter(x => x != null); const users = await this.usersRepository.findBy({ id: In(userIds), }); diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 4fc724b548..98e944f347 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -26,7 +26,6 @@ import type { MiUserKeypair } from '@/models/UserKeypair.js'; import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, PollsRepository } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { IdService } from '@/core/IdService.js'; import { JsonLdService } from './JsonLdService.js'; import { ApMfmService } from './ApMfmService.js'; @@ -317,7 +316,7 @@ export class ApRendererService { const getPromisedFiles = async (ids: string[]): Promise<MiDriveFile[]> => { if (ids.length === 0) return []; const items = await this.driveFilesRepository.findBy({ id: In(ids) }); - return ids.map(id => items.find(item => item.id === id)).filter(isNotNull); + return ids.map(id => items.find(item => item.id === id)).filter(x => x != null); }; let inReplyTo; @@ -686,7 +685,7 @@ export class ApRendererService { if (names.length === 0) return []; const allEmojis = await this.customEmojiService.localEmojisCache.fetch(); - const emojis = names.map(name => allEmojis.get(name)).filter(isNotNull); + const emojis = names.map(name => allEmojis.get(name)).filter(x => x != null); return emojis; } diff --git a/packages/backend/src/core/activitypub/models/ApMentionService.ts b/packages/backend/src/core/activitypub/models/ApMentionService.ts index 0ced7e88af..2cd151fa04 100644 --- a/packages/backend/src/core/activitypub/models/ApMentionService.ts +++ b/packages/backend/src/core/activitypub/models/ApMentionService.ts @@ -8,7 +8,6 @@ import promiseLimit from 'promise-limit'; import type { MiUser } from '@/models/_.js'; import { toArray, unique } from '@/misc/prelude/array.js'; import { bindThis } from '@/decorators.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { isMention } from '../type.js'; import { Resolver } from '../ApResolverService.js'; import { ApPersonService } from './ApPersonService.js'; @@ -28,7 +27,7 @@ export class ApMentionService { const limit = promiseLimit<MiUser | null>(2); const mentionedUsers = (await Promise.all( hrefs.map(x => limit(() => this.apPersonService.resolvePerson(x, resolver).catch(() => null))), - )).filter(isNotNull); + )).filter(x => x != null); return mentionedUsers; } diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts index c6e6b3a1e8..fc7aa1e0b9 100644 --- a/packages/backend/src/core/activitypub/models/ApNoteService.ts +++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts @@ -24,7 +24,6 @@ import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; import { checkHttps } from '@/misc/check-https.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js'; import { ApLoggerService } from '../ApLoggerService.js'; import { ApMfmService } from '../ApMfmService.js'; @@ -253,7 +252,7 @@ export class ApNoteService { } }; - const uris = unique([note._misskey_quote, note.quoteUrl].filter(isNotNull)); + const uris = unique([note._misskey_quote, note.quoteUrl].filter(x => x != null)); const results = await Promise.all(uris.map(tryResolveNote)); quote = results.filter((x): x is { status: 'ok', res: MiNote } => x.status === 'ok').map(x => x.res).at(0); diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index 744b1ea683..398c8695d2 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -38,7 +38,6 @@ import { MetaService } from '@/core/MetaService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import type { AccountMoveService } from '@/core/AccountMoveService.js'; import { checkHttps } from '@/misc/check-https.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { getApId, getApType, getOneApHrefNullable, isActor, isCollection, isCollectionOrOrderedCollection, isPropertyValue } from '../type.js'; import { extractApHashtags } from './tag.js'; import type { OnModuleInit } from '@nestjs/common'; @@ -637,7 +636,7 @@ export class ApPersonService implements OnModuleInit { // とりあえずidを別の時間で生成して順番を維持 let td = 0; - for (const note of featuredNotes.filter(isNotNull)) { + for (const note of featuredNotes.filter(x => x != null)) { td -= 1000; transactionalEntityManager.insert(MiUserNotePining, { id: this.idService.gen(Date.now() + td), diff --git a/packages/backend/src/core/activitypub/models/ApQuestionService.ts b/packages/backend/src/core/activitypub/models/ApQuestionService.ts index d1936cfe1d..4fae1e897b 100644 --- a/packages/backend/src/core/activitypub/models/ApQuestionService.ts +++ b/packages/backend/src/core/activitypub/models/ApQuestionService.ts @@ -10,7 +10,6 @@ import type { Config } from '@/config.js'; import type { IPoll } from '@/models/Poll.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { isQuestion } from '../type.js'; import { ApLoggerService } from '../ApLoggerService.js'; import { ApResolverService } from '../ApResolverService.js'; @@ -52,7 +51,7 @@ export class ApQuestionService { const choices = question[multiple ? 'anyOf' : 'oneOf'] ?.map((x) => x.name) - .filter(isNotNull) + .filter(x => x != null) ?? []; const votes = question[multiple ? 'anyOf' : 'oneOf']?.map((x) => x.replies?.totalItems ?? x._misskey_votes ?? 0); diff --git a/packages/backend/src/core/activitypub/models/tag.ts b/packages/backend/src/core/activitypub/models/tag.ts index e7ceec3262..f75cc45f7e 100644 --- a/packages/backend/src/core/activitypub/models/tag.ts +++ b/packages/backend/src/core/activitypub/models/tag.ts @@ -4,7 +4,6 @@ */ import { toArray } from '@/misc/prelude/array.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { isHashtag } from '../type.js'; import type { IObject, IApHashtag } from '../type.js'; @@ -16,7 +15,7 @@ export function extractApHashtags(tags: IObject | IObject[] | null | undefined): return hashtags.map(tag => { const m = tag.name.match(/^#(.+)/); return m ? m[1] : null; - }).filter(isNotNull); + }).filter(x => x != null); } export function extractApHashtagObjects(tags: IObject | IObject[] | null | undefined): IApHashtag[] { diff --git a/packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts b/packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts index 6819afafd9..1e23c194c5 100644 --- a/packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts +++ b/packages/backend/src/core/entities/AbuseReportNotificationRecipientEntityService.ts @@ -11,7 +11,6 @@ import { bindThis } from '@/decorators.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { Packed } from '@/misc/json-schema.js'; import { SystemWebhookEntityService } from '@/core/entities/SystemWebhookEntityService.js'; -import { isNotNull } from '@/misc/is-not-null.js'; @Injectable() export class AbuseReportNotificationRecipientEntityService { @@ -66,13 +65,13 @@ export class AbuseReportNotificationRecipientEntityService { ); } - const userIds = objs.map(it => it.userId).filter(isNotNull); + const userIds = objs.map(it => it.userId).filter(x => x != null); const users: Map<string, Packed<'UserLite'>> = (userIds.length > 0) ? await this.userEntityService.packMany(userIds) .then(it => new Map(it.map(it => [it.id, it]))) : new Map(); - const systemWebhookIds = objs.map(it => it.systemWebhookId).filter(isNotNull); + const systemWebhookIds = objs.map(it => it.systemWebhookId).filter(x => x != null); const systemWebhooks: Map<string, Packed<'SystemWebhook'>> = (systemWebhookIds.length > 0) ? await this.systemWebhookEntityService.packMany(systemWebhookIds) .then(it => new Map(it.map(it => [it.id, it]))) diff --git a/packages/backend/src/core/entities/AbuseUserReportEntityService.ts b/packages/backend/src/core/entities/AbuseUserReportEntityService.ts index b0e1d1ab36..a13c244c19 100644 --- a/packages/backend/src/core/entities/AbuseUserReportEntityService.ts +++ b/packages/backend/src/core/entities/AbuseUserReportEntityService.ts @@ -10,7 +10,6 @@ import { awaitAll } from '@/misc/prelude/await-all.js'; import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import type { Packed } from '@/misc/json-schema.js'; import { UserEntityService } from './UserEntityService.js'; @@ -63,7 +62,7 @@ export class AbuseUserReportEntityService { ) { const _reporters = reports.map(({ reporter, reporterId }) => reporter ?? reporterId); const _targetUsers = reports.map(({ targetUser, targetUserId }) => targetUser ?? targetUserId); - const _assignees = reports.map(({ assignee, assigneeId }) => assignee ?? assigneeId).filter(isNotNull); + const _assignees = reports.map(({ assignee, assigneeId }) => assignee ?? assigneeId).filter(x => x != null); const _userMap = await this.userEntityService.packMany( [..._reporters, ..._targetUsers, ..._assignees], null, diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts index 02ff2e7754..c485555f90 100644 --- a/packages/backend/src/core/entities/DriveFileEntityService.ts +++ b/packages/backend/src/core/entities/DriveFileEntityService.ts @@ -16,7 +16,6 @@ import { appendQuery, query } from '@/misc/prelude/url.js'; import { deepClone } from '@/misc/clone.js'; import { bindThis } from '@/decorators.js'; import { isMimeImage } from '@/misc/is-mime-image.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { IdService } from '@/core/IdService.js'; import { UtilityService } from '../UtilityService.js'; import { VideoProcessingService } from '../VideoProcessingService.js'; @@ -261,11 +260,11 @@ export class DriveFileEntityService { files: MiDriveFile[], options?: PackOptions, ): Promise<Packed<'DriveFile'>[]> { - const _user = files.map(({ user, userId }) => user ?? userId).filter(isNotNull); + const _user = files.map(({ user, userId }) => user ?? userId).filter(x => x != null); const _userMap = await this.userEntityService.packMany(_user) .then(users => new Map(users.map(user => [user.id, user]))); const items = await Promise.all(files.map(f => this.packNullable(f, options, f.userId ? { packedUser: _userMap.get(f.userId) } : {}))); - return items.filter(isNotNull); + return items.filter(x => x != null); } @bindThis @@ -290,6 +289,6 @@ export class DriveFileEntityService { ): Promise<Packed<'DriveFile'>[]> { if (fileIds.length === 0) return []; const filesMap = await this.packManyByIdsMap(fileIds, options); - return fileIds.map(id => filesMap.get(id)).filter(isNotNull); + return fileIds.map(id => filesMap.get(id)).filter(x => x != null); } } diff --git a/packages/backend/src/core/entities/InviteCodeEntityService.ts b/packages/backend/src/core/entities/InviteCodeEntityService.ts index 26f57e1299..5d3e823a2a 100644 --- a/packages/backend/src/core/entities/InviteCodeEntityService.ts +++ b/packages/backend/src/core/entities/InviteCodeEntityService.ts @@ -12,7 +12,6 @@ import type { MiUser } from '@/models/User.js'; import type { MiRegistrationTicket } from '@/models/RegistrationTicket.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { UserEntityService } from './UserEntityService.js'; @Injectable() @@ -59,8 +58,8 @@ export class InviteCodeEntityService { tickets: MiRegistrationTicket[], me: { id: MiUser['id'] }, ) { - const _createdBys = tickets.map(({ createdBy, createdById }) => createdBy ?? createdById).filter(isNotNull); - const _usedBys = tickets.map(({ usedBy, usedById }) => usedBy ?? usedById).filter(isNotNull); + const _createdBys = tickets.map(({ createdBy, createdById }) => createdBy ?? createdById).filter(x => x != null); + const _usedBys = tickets.map(({ usedBy, usedById }) => usedBy ?? usedById).filter(x => x != null); const _userMap = await this.userEntityService.packMany([..._createdBys, ..._usedBys], me) .then(users => new Map(users.map(u => [u.id, u]))); return Promise.all( diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index 2ce72c50b8..2cd092231c 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -14,7 +14,6 @@ import type { MiNote } from '@/models/Note.js'; import type { MiNoteReaction } from '@/models/NoteReaction.js'; import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepository, PollVotesRepository, NoteReactionsRepository, ChannelsRepository } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { DebounceLoader } from '@/misc/loader.js'; import { IdService } from '@/core/IdService.js'; import type { OnModuleInit } from '@nestjs/common'; @@ -276,7 +275,7 @@ export class NoteEntityService implements OnModuleInit { packedFiles.set(k, v); } } - return fileIds.map(id => packedFiles.get(id)).filter(isNotNull); + return fileIds.map(id => packedFiles.get(id)).filter(x => x != null); } @bindThis @@ -449,12 +448,12 @@ export class NoteEntityService implements OnModuleInit { await this.customEmojiService.prefetchEmojis(this.aggregateNoteEmojis(notes)); // TODO: 本当は renote とか reply がないのに renoteId とか replyId があったらここで解決しておく - const fileIds = notes.map(n => [n.fileIds, n.renote?.fileIds, n.reply?.fileIds]).flat(2).filter(isNotNull); + const fileIds = notes.map(n => [n.fileIds, n.renote?.fileIds, n.reply?.fileIds]).flat(2).filter(x => x != null); const packedFiles = fileIds.length > 0 ? await this.driveFileEntityService.packManyByIdsMap(fileIds) : new Map(); const users = [ ...notes.map(({ user, userId }) => user ?? userId), - ...notes.map(({ replyUserId }) => replyUserId).filter(isNotNull), - ...notes.map(({ renoteUserId }) => renoteUserId).filter(isNotNull), + ...notes.map(({ replyUserId }) => replyUserId).filter(x => x != null), + ...notes.map(({ renoteUserId }) => renoteUserId).filter(x => x != null), ]; const packedUsers = await this.userEntityService.packMany(users, me) .then(users => new Map(users.map(u => [u.id, u]))); diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts index 94d56c883b..f393513510 100644 --- a/packages/backend/src/core/entities/NotificationEntityService.ts +++ b/packages/backend/src/core/entities/NotificationEntityService.ts @@ -13,7 +13,6 @@ import type { MiGroupedNotification, MiNotification } from '@/models/Notificatio import type { MiNote } from '@/models/Note.js'; import type { Packed } from '@/misc/json-schema.js'; import { bindThis } from '@/decorators.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { FilterUnionByProperty, groupedNotificationTypes } from '@/types.js'; import { CacheService } from '@/core/CacheService.js'; import { RoleEntityService } from './RoleEntityService.js'; @@ -103,7 +102,7 @@ export class NotificationEntityService implements OnModuleInit { user, reaction: reaction.reaction, }; - }))).filter(r => isNotNull(r.user)); + }))).filter(r => r.user != null); // if all users have been deleted, don't show this notification if (reactions.length === 0) { return null; @@ -124,7 +123,7 @@ export class NotificationEntityService implements OnModuleInit { } return this.userEntityService.pack(userId, { id: meId }); - }))).filter(isNotNull); + }))).filter(x => x != null); // if all users have been deleted, don't show this notification if (users.length === 0) { return null; @@ -181,7 +180,7 @@ export class NotificationEntityService implements OnModuleInit { validNotifications = await this.#filterValidNotifier(validNotifications, meId); - const noteIds = validNotifications.map(x => 'noteId' in x ? x.noteId : null).filter(isNotNull); + const noteIds = validNotifications.map(x => 'noteId' in x ? x.noteId : null).filter(x => x != null); const notes = noteIds.length > 0 ? await this.notesRepository.find({ where: { id: In(noteIds) }, relations: ['user', 'reply', 'reply.user', 'renote', 'renote.user'], @@ -223,7 +222,7 @@ export class NotificationEntityService implements OnModuleInit { ); }); - return (await Promise.all(packPromises)).filter(isNotNull); + return (await Promise.all(packPromises)).filter(x => x != null); } @bindThis @@ -305,7 +304,7 @@ export class NotificationEntityService implements OnModuleInit { this.cacheService.userProfileCache.fetch(meId).then(p => new Set(p.mutedInstances)), ]); - const notifierIds = notifications.map(notification => 'notifierId' in notification ? notification.notifierId : null).filter(isNotNull); + const notifierIds = notifications.map(notification => 'notifierId' in notification ? notification.notifierId : null).filter(x => x != null); const notifiers = notifierIds.length > 0 ? await this.usersRepository.find({ where: { id: In(notifierIds) }, }) : []; @@ -313,7 +312,7 @@ export class NotificationEntityService implements OnModuleInit { const filteredNotifications = ((await Promise.all(notifications.map(async (notification) => { const isValid = this.#validateNotifier(notification, userIdsWhoMeMuting, userMutedInstances, notifiers); return isValid ? notification : null; - }))) as [T | null] ).filter(isNotNull); + }))) as [T | null] ).filter(x => x != null); return filteredNotifications; } diff --git a/packages/backend/src/core/entities/PageEntityService.ts b/packages/backend/src/core/entities/PageEntityService.ts index 142d9e81db..46bf51bb6d 100644 --- a/packages/backend/src/core/entities/PageEntityService.ts +++ b/packages/backend/src/core/entities/PageEntityService.ts @@ -14,7 +14,6 @@ import type { MiPage } from '@/models/Page.js'; import type { MiDriveFile } from '@/models/DriveFile.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import { UserEntityService } from './UserEntityService.js'; import { DriveFileEntityService } from './DriveFileEntityService.js'; @@ -106,7 +105,7 @@ export class PageEntityService { script: page.script, eyeCatchingImageId: page.eyeCatchingImageId, eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId) : null, - attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter(isNotNull)), + attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter(x => x != null)), likedCount: page.likedCount, isLiked: meId ? await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: meId } }) : undefined, }); diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index b80a1ec206..da96878713 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -47,7 +47,6 @@ import { IdService } from '@/core/IdService.js'; import type { AnnouncementService } from '@/core/AnnouncementService.js'; import type { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { AvatarDecorationService } from '@/core/AvatarDecorationService.js'; -import { isNotNull } from '@/misc/is-not-null.js'; import type { OnModuleInit } from '@nestjs/common'; import type { NoteEntityService } from './NoteEntityService.js'; import type { DriveFileEntityService } from './DriveFileEntityService.js'; @@ -514,7 +513,7 @@ export class UserEntityService implements OnModuleInit { movedTo: user.movedToUri ? this.apPersonService.resolvePerson(user.movedToUri).then(user => user.id).catch(() => null) : null, alsoKnownAs: user.alsoKnownAs ? Promise.all(user.alsoKnownAs.map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null))) - .then(xs => xs.length === 0 ? null : xs.filter(isNotNull)) + .then(xs => xs.length === 0 ? null : xs.filter(x => x != null)) : null, createdAt: this.idService.parse(user.id).date.toISOString(), updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, diff --git a/packages/backend/src/misc/is-not-null.ts b/packages/backend/src/misc/is-not-null.ts deleted file mode 100644 index 8d9dc8bb39..0000000000 --- a/packages/backend/src/misc/is-not-null.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export function isNotNull<T extends NonNullable<unknown>>(input: T | undefined | null): input is T { - return input != null; -} diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts index 46f8998810..504a9c789e 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts @@ -12,7 +12,6 @@ import type { MiDriveFile } from '@/models/DriveFile.js'; import { IdService } from '@/core/IdService.js'; import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js'; import { DI } from '@/di-symbols.js'; -import { isNotNull } from '@/misc/is-not-null.js'; export const meta = { tags: ['gallery'], @@ -70,7 +69,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- id: fileId, userId: me.id, }), - ))).filter(isNotNull); + ))).filter(x => x != null); if (files.length === 0) { throw new Error(); diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts index 8bd83ff5ba..2f977784ec 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts @@ -10,7 +10,6 @@ import type { DriveFilesRepository, GalleryPostsRepository } from '@/models/_.js import type { MiDriveFile } from '@/models/DriveFile.js'; import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js'; import { DI } from '@/di-symbols.js'; -import { isNotNull } from '@/misc/is-not-null.js'; export const meta = { tags: ['gallery'], @@ -68,7 +67,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- id: fileId, userId: me.id, }), - ))).filter(isNotNull); + ))).filter(x => x != null); if (files.length === 0) { throw new Error(); diff --git a/packages/backend/src/server/api/endpoints/pinned-users.ts b/packages/backend/src/server/api/endpoints/pinned-users.ts index 784766bcb5..15832ef7f8 100644 --- a/packages/backend/src/server/api/endpoints/pinned-users.ts +++ b/packages/backend/src/server/api/endpoints/pinned-users.ts @@ -12,7 +12,6 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { MetaService } from '@/core/MetaService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; -import { isNotNull } from '@/misc/is-not-null.js'; export const meta = { tags: ['users'], @@ -53,7 +52,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- host: acct.host ?? IsNull(), }))); - return await this.userEntityService.packMany(users.filter(isNotNull), me, { schema: 'UserDetailed' }); + return await this.userEntityService.packMany(users.filter(x => x != null), me, { schema: 'UserDetailed' }); }); } } From 811ffbf3a46656a3cb9e41bec89a61cd33341871 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:18:19 +0900 Subject: [PATCH 15/26] remove unused file --- packages/backend/src/misc/prelude/maybe.ts | 25 ---------------------- packages/backend/test/prelude/maybe.ts | 23 -------------------- 2 files changed, 48 deletions(-) delete mode 100644 packages/backend/src/misc/prelude/maybe.ts delete mode 100644 packages/backend/test/prelude/maybe.ts diff --git a/packages/backend/src/misc/prelude/maybe.ts b/packages/backend/src/misc/prelude/maybe.ts deleted file mode 100644 index 1c58ccb9c7..0000000000 --- a/packages/backend/src/misc/prelude/maybe.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export interface IMaybe<T> { - isJust(): this is IJust<T>; -} - -export interface IJust<T> extends IMaybe<T> { - get(): T; -} - -export function just<T>(value: T): IJust<T> { - return { - isJust: () => true, - get: () => value, - }; -} - -export function nothing<T>(): IMaybe<T> { - return { - isJust: () => false, - }; -} diff --git a/packages/backend/test/prelude/maybe.ts b/packages/backend/test/prelude/maybe.ts deleted file mode 100644 index 16e92216d4..0000000000 --- a/packages/backend/test/prelude/maybe.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import * as assert from 'assert'; -import { just, nothing } from '../../src/misc/prelude/maybe.js'; - -describe('just', () => { - test('has a value', () => { - assert.deepStrictEqual(just(3).isJust(), true); - }); - - test('has the inverse called get', () => { - assert.deepStrictEqual(just(3).get(), 3); - }); -}); - -describe('nothing', () => { - test('has no value', () => { - assert.deepStrictEqual(nothing().isJust(), false); - }); -}); From 1d6ccd97812900444a665fadf689a818d777245c Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:21:27 +0900 Subject: [PATCH 16/26] remove unused files --- packages/backend/src/misc/prelude/math.ts | 8 -------- packages/backend/src/misc/prelude/string.ts | 20 -------------------- packages/backend/src/misc/prelude/symbol.ts | 6 ------ 3 files changed, 34 deletions(-) delete mode 100644 packages/backend/src/misc/prelude/math.ts delete mode 100644 packages/backend/src/misc/prelude/string.ts delete mode 100644 packages/backend/src/misc/prelude/symbol.ts diff --git a/packages/backend/src/misc/prelude/math.ts b/packages/backend/src/misc/prelude/math.ts deleted file mode 100644 index 38556def2d..0000000000 --- a/packages/backend/src/misc/prelude/math.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export function gcd(a: number, b: number): number { - return b === 0 ? a : gcd(b, a % b); -} diff --git a/packages/backend/src/misc/prelude/string.ts b/packages/backend/src/misc/prelude/string.ts deleted file mode 100644 index 67ea529961..0000000000 --- a/packages/backend/src/misc/prelude/string.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export function concat(xs: string[]): string { - return xs.join(''); -} - -export function capitalize(s: string): string { - return toUpperCase(s.charAt(0)) + toLowerCase(s.slice(1)); -} - -export function toUpperCase(s: string): string { - return s.toUpperCase(); -} - -export function toLowerCase(s: string): string { - return s.toLowerCase(); -} diff --git a/packages/backend/src/misc/prelude/symbol.ts b/packages/backend/src/misc/prelude/symbol.ts deleted file mode 100644 index 7e8d39bdb6..0000000000 --- a/packages/backend/src/misc/prelude/symbol.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export const fallback = Symbol('fallback'); From e88f08ad7deeba74f5a196fe3afd52da6982f251 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:31:02 +0900 Subject: [PATCH 17/26] refactor --- .../src/server/api/endpoints/drive/folders/update.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/drive/folders/update.ts b/packages/backend/src/server/api/endpoints/drive/folders/update.ts index 52b8b335b5..62b04e1df3 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/update.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/update.ts @@ -95,15 +95,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check if the circular reference will occur const checkCircle = async (folderId: string): Promise<boolean> => { - // Fetch folder - const folder2 = await this.driveFoldersRepository.findOneBy({ + const folder2 = await this.driveFoldersRepository.findOneByOrFail({ id: folderId, }); - if (folder2!.id === folder!.id) { + if (folder2.id === folder.id) { return true; - } else if (folder2!.parentId) { - return await checkCircle(folder2!.parentId); + } else if (folder2.parentId) { + return await checkCircle(folder2.parentId); } else { return false; } From 2c84d06a66c00991f51de664571c1ade203fcd56 Mon Sep 17 00:00:00 2001 From: woxtu <woxtup@gmail.com> Date: Fri, 21 Jun 2024 13:48:04 +0900 Subject: [PATCH 18/26] Fix type checking (#14052) --- packages/frontend/src/components/MkNotification.vue | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue index 73cd7cd5b3..3fa2eb254e 100644 --- a/packages/frontend/src/components/MkNotification.vue +++ b/packages/frontend/src/components/MkNotification.vue @@ -6,14 +6,14 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div :class="$style.root"> <div :class="$style.head"> - <MkAvatar v-if="['pollEnded', 'note'].includes(notification.type) && notification.note" :class="$style.icon" :user="notification.note.user" link preview/> + <MkAvatar v-if="['pollEnded', 'note'].includes(notification.type) && 'note' in notification" :class="$style.icon" :user="notification.note.user" link preview/> <MkAvatar v-else-if="['roleAssigned', 'achievementEarned'].includes(notification.type)" :class="$style.icon" :user="$i" link preview/> <div v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'" :class="[$style.icon, $style.icon_reactionGroupHeart]"><i class="ti ti-heart" style="line-height: 1;"></i></div> <div v-else-if="notification.type === 'reaction:grouped'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ti ti-plus" style="line-height: 1;"></i></div> <div v-else-if="notification.type === 'renote:grouped'" :class="[$style.icon, $style.icon_renoteGroup]"><i class="ti ti-repeat" style="line-height: 1;"></i></div> <img v-else-if="notification.type === 'test'" :class="$style.icon" :src="infoImageUrl"/> - <MkAvatar v-else-if="notification.user" :class="$style.icon" :user="notification.user" link preview/> - <img v-else-if="notification.icon" :class="[$style.icon, $style.icon_app]" :src="notification.icon" alt=""/> + <MkAvatar v-else-if="'user' in notification" :class="$style.icon" :user="notification.user" link preview/> + <img v-else-if="'icon' in notification" :class="[$style.icon, $style.icon_app]" :src="notification.icon" alt=""/> <div :class="[$style.subIcon, { [$style.t_follow]: notification.type === 'follow', @@ -164,13 +164,13 @@ const props = withDefaults(defineProps<{ const followRequestDone = ref(false); const acceptFollowRequest = () => { - if (props.notification.user == null) return; + if (!('user' in props.notification)) return; followRequestDone.value = true; misskeyApi('following/requests/accept', { userId: props.notification.user.id }); }; const rejectFollowRequest = () => { - if (props.notification.user == null) return; + if (!('user' in props.notification)) return; followRequestDone.value = true; misskeyApi('following/requests/reject', { userId: props.notification.user.id }); }; From a9012d3d0c2036b06d7b313fef7a3867f4559517 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:29:37 +0900 Subject: [PATCH 19/26] test(frontend): fix component error in `MkChart` story (#14056) --- packages/frontend/.storybook/charts.ts | 48 +++++++++++++++++++ .../src/components/MkChart.stories.impl.ts | 45 +---------------- .../MkInstanceCardMini.stories.impl.ts | 3 +- 3 files changed, 52 insertions(+), 44 deletions(-) create mode 100644 packages/frontend/.storybook/charts.ts diff --git a/packages/frontend/.storybook/charts.ts b/packages/frontend/.storybook/charts.ts new file mode 100644 index 0000000000..5015012a82 --- /dev/null +++ b/packages/frontend/.storybook/charts.ts @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { DefaultBodyType, HttpResponse, HttpResponseResolver, JsonBodyType, PathParams, http } from 'msw'; +import seedrandom from 'seedrandom'; +import { action } from '@storybook/addon-actions'; + +function getChartArray(seed: string, limit: number, option?: { accumulate?: boolean, mul?: number }): number[] { + const rng = seedrandom(seed); + const max = Math.floor(option?.mul ?? 250 * rng()); + let accumulation = 0; + const array: number[] = []; + for (let i = 0; i < limit; i++) { + const num = Math.floor((max + 1) * rng()); + if (option?.accumulate) { + accumulation += num; + array.unshift(accumulation); + } else { + array.push(num); + } + } + return array; +} + +export function getChartResolver(fields: string[], option?: { accumulate?: boolean, mulMap?: Record<string, number> }): HttpResponseResolver<PathParams, DefaultBodyType, JsonBodyType> { + return ({ request }) => { + action(`GET ${request.url}`)(); + const limitParam = new URL(request.url).searchParams.get('limit'); + const limit = limitParam ? parseInt(limitParam) : 30; + const res = {}; + for (const field of fields) { + const layers = field.split('.'); + let current = res; + while (layers.length > 1) { + const currentKey = layers.shift()!; + if (current[currentKey] == null) current[currentKey] = {}; + current = current[currentKey]; + } + current[layers[0]] = getChartArray(field, limit, { + accumulate: option?.accumulate, + mul: option?.mulMap != null && field in option.mulMap ? option.mulMap[field] : undefined, + }); + } + return HttpResponse.json(res); + }; +} diff --git a/packages/frontend/src/components/MkChart.stories.impl.ts b/packages/frontend/src/components/MkChart.stories.impl.ts index 3bae703245..1bcb9c30d8 100644 --- a/packages/frontend/src/components/MkChart.stories.impl.ts +++ b/packages/frontend/src/components/MkChart.stories.impl.ts @@ -6,52 +6,11 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable import/no-default-export */ import { StoryObj } from '@storybook/vue3'; -import { DefaultBodyType, HttpResponse, HttpResponseResolver, JsonBodyType, PathParams, http } from 'msw'; -import seedrandom from 'seedrandom'; -import { action } from '@storybook/addon-actions'; +import { http } from 'msw'; import { commonHandlers } from '../../.storybook/mocks.js'; +import { getChartResolver } from '../../.storybook/charts.js'; import MkChart from './MkChart.vue'; -function getChartArray(seed: string, limit: number, option?: { accumulate?: boolean, mul?: number }): number[] { - const rng = seedrandom(seed); - const max = Math.floor(option?.mul ?? 250 * rng()); - let accumulation = 0; - const array: number[] = []; - for (let i = 0; i < limit; i++) { - const num = Math.floor((max + 1) * rng()); - if (option?.accumulate) { - accumulation += num; - array.unshift(accumulation); - } else { - array.push(num); - } - } - return array; -} - -export function getChartResolver(fields: string[], option?: { accumulate?: boolean, mulMap?: Record<string, number> }): HttpResponseResolver<PathParams, DefaultBodyType, JsonBodyType> { - return ({ request }) => { - action(`GET ${request.url}`)(); - const limitParam = new URL(request.url).searchParams.get('limit'); - const limit = limitParam ? parseInt(limitParam) : 30; - const res = {}; - for (const field of fields) { - const layers = field.split('.'); - let current = res; - while (layers.length > 1) { - const currentKey = layers.shift()!; - if (current[currentKey] == null) current[currentKey] = {}; - current = current[currentKey]; - } - current[layers[0]] = getChartArray(field, limit, { - accumulate: option?.accumulate, - mul: option?.mulMap != null && field in option.mulMap ? option.mulMap[field] : undefined, - }); - } - return HttpResponse.json(res); - }; -} - const Base = { render(args) { return { diff --git a/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts b/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts index a069a0eb8e..9e8de9d878 100644 --- a/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts +++ b/packages/frontend/src/components/MkInstanceCardMini.stories.impl.ts @@ -8,8 +8,9 @@ import { StoryObj } from '@storybook/vue3'; import { HttpResponse, http } from 'msw'; import { federationInstance } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; +import { getChartResolver } from '../../.storybook/charts.js'; import MkInstanceCardMini from './MkInstanceCardMini.vue'; -import { getChartResolver } from './MkChart.stories.impl.js'; + export const Default = { render(args) { return { From 4d2eddec2e95587f7e4ec4ed79b6392a203d8789 Mon Sep 17 00:00:00 2001 From: woxtu <woxtup@gmail.com> Date: Sat, 22 Jun 2024 12:40:00 +0900 Subject: [PATCH 20/26] Replace with `vue/no-setup-props-reactivity-loss` rule (#14062) --- packages/frontend/.eslintrc.cjs | 2 +- packages/frontend/src/components/MkChart.vue | 2 +- packages/frontend/src/components/MkDateSeparatedList.vue | 2 +- packages/frontend/src/components/MkMediaAudio.vue | 2 +- packages/frontend/src/components/MkMediaVideo.vue | 2 +- packages/frontend/src/components/MkTutorialDialog.vue | 2 +- packages/frontend/src/components/MkUserSetupDialog.vue | 2 +- packages/frontend/src/components/global/MkTime.vue | 4 ++-- packages/frontend/src/pages/reversi/game.board.vue | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/frontend/.eslintrc.cjs b/packages/frontend/.eslintrc.cjs index 20f88dc078..fd562e1c40 100644 --- a/packages/frontend/.eslintrc.cjs +++ b/packages/frontend/.eslintrc.cjs @@ -56,7 +56,7 @@ module.exports = { 'vue/no-dupe-keys': 'warn', 'vue/valid-v-for': 'warn', 'vue/return-in-computed-property': 'warn', - 'vue/no-setup-props-destructure': 'warn', + 'vue/no-setup-props-reactivity-loss': 'warn', 'vue/max-attributes-per-line': 'off', 'vue/html-self-closing': 'off', 'vue/singleline-html-element-content-newline': 'off', diff --git a/packages/frontend/src/components/MkChart.vue b/packages/frontend/src/components/MkChart.vue index 3816bca348..4b24562249 100644 --- a/packages/frontend/src/components/MkChart.vue +++ b/packages/frontend/src/components/MkChart.vue @@ -114,7 +114,7 @@ const getColor = (i) => { return colorSets[i % colorSets.length]; }; -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const now = props.nowForChromatic != null ? new Date(props.nowForChromatic) : new Date(); let chartInstance: Chart | null = null; let chartData: { diff --git a/packages/frontend/src/components/MkDateSeparatedList.vue b/packages/frontend/src/components/MkDateSeparatedList.vue index 85e131cf9b..f16981716c 100644 --- a/packages/frontend/src/components/MkDateSeparatedList.vue +++ b/packages/frontend/src/components/MkDateSeparatedList.vue @@ -130,7 +130,7 @@ export default defineComponent({ el.style.left = ''; } - // eslint-disable-next-line vue/no-setup-props-destructure + // eslint-disable-next-line vue/no-setup-props-reactivity-loss const classes = { [$style['date-separated-list']]: true, [$style['date-separated-list-nogap']]: props.noGap, diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index 5d2edf467e..ebd4fc9ca4 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -126,7 +126,7 @@ function hasFocus() { const playerEl = shallowRef<HTMLDivElement>(); const audioEl = shallowRef<HTMLAudioElement>(); -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const hide = ref((defaultStore.state.nsfw === 'force' || defaultStore.state.dataSaver.media) ? true : (props.audio.isSensitive && defaultStore.state.nsfw !== 'ignore')); // Menu diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue index 1e3868bc36..707d7c1501 100644 --- a/packages/frontend/src/components/MkMediaVideo.vue +++ b/packages/frontend/src/components/MkMediaVideo.vue @@ -160,7 +160,7 @@ function hasFocus() { return playerEl.value === document.activeElement || playerEl.value.contains(document.activeElement); } -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const hide = ref((defaultStore.state.nsfw === 'force' || defaultStore.state.dataSaver.media) ? true : (props.video.isSensitive && defaultStore.state.nsfw !== 'ignore')); // Menu diff --git a/packages/frontend/src/components/MkTutorialDialog.vue b/packages/frontend/src/components/MkTutorialDialog.vue index d2711e4ec5..9adc8d466c 100644 --- a/packages/frontend/src/components/MkTutorialDialog.vue +++ b/packages/frontend/src/components/MkTutorialDialog.vue @@ -172,7 +172,7 @@ const emit = defineEmits<{ const dialog = shallowRef<InstanceType<typeof MkModalWindow>>(); -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const page = ref(props.initialPage ?? 0); watch(page, (to) => { diff --git a/packages/frontend/src/components/MkUserSetupDialog.vue b/packages/frontend/src/components/MkUserSetupDialog.vue index 1d376382ca..cab0067813 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.vue +++ b/packages/frontend/src/components/MkUserSetupDialog.vue @@ -148,7 +148,7 @@ const emit = defineEmits<{ const dialog = shallowRef<InstanceType<typeof MkModalWindow>>(); -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const page = ref(defaultStore.state.accountSetupWizard); watch(page, () => { diff --git a/packages/frontend/src/components/global/MkTime.vue b/packages/frontend/src/components/global/MkTime.vue index 23fe99bd9c..027b226f3f 100644 --- a/packages/frontend/src/components/global/MkTime.vue +++ b/packages/frontend/src/components/global/MkTime.vue @@ -41,12 +41,12 @@ function getDateSafe(n: Date | string | number) { } } -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const _time = props.time == null ? NaN : getDateSafe(props.time).getTime(); const invalid = Number.isNaN(_time); const absolute = !invalid ? dateTimeFormat.format(_time) : i18n.ts._ago.invalid; -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const now = ref(props.origin?.getTime() ?? Date.now()); const ago = computed(() => (now.value - _time) / 1000/*ms*/); diff --git a/packages/frontend/src/pages/reversi/game.board.vue b/packages/frontend/src/pages/reversi/game.board.vue index 175ea62411..7d9cefa5c9 100644 --- a/packages/frontend/src/pages/reversi/game.board.vue +++ b/packages/frontend/src/pages/reversi/game.board.vue @@ -169,7 +169,7 @@ const props = defineProps<{ const showBoardLabels = ref<boolean>(false); const useAvatarAsStone = ref<boolean>(true); const autoplaying = ref<boolean>(false); -// eslint-disable-next-line vue/no-setup-props-destructure +// eslint-disable-next-line vue/no-setup-props-reactivity-loss const game = ref<Misskey.entities.ReversiGameDetailed & { logs: Reversi.Serializer.SerializedLog[] }>(deepClone(props.game)); const logPos = ref<number>(game.value.logs.length); const engine = shallowRef<Reversi.Game>(Reversi.Serializer.restoreGame({ From 8a9de081f1efd78117c30bdc721785ca323b202c Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:43:03 +0900 Subject: [PATCH 21/26] fix(backend): fallback if `sinceId` is older than the oldest in cache when using FTT (#14061) * fix(backend): fallback if `sinceId` is older than the oldest in cache when using FTT * Update CHANGELOG.md * chore: fix description of test --- CHANGELOG.md | 1 + .../src/core/FanoutTimelineEndpointService.ts | 12 +++---- packages/backend/test/e2e/timelines.ts | 35 +++++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3341d4afff..8ce566370b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) - Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036) +- Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 ## 2024.5.0 diff --git a/packages/backend/src/core/FanoutTimelineEndpointService.ts b/packages/backend/src/core/FanoutTimelineEndpointService.ts index d5058f37c2..b05af99c5e 100644 --- a/packages/backend/src/core/FanoutTimelineEndpointService.ts +++ b/packages/backend/src/core/FanoutTimelineEndpointService.ts @@ -55,9 +55,6 @@ export class FanoutTimelineEndpointService { @bindThis private async getMiNotes(ps: TimelineOptions): Promise<MiNote[]> { - let noteIds: string[]; - let shouldFallbackToDb = false; - // 呼び出し元と以下の処理をシンプルにするためにdbFallbackを置き換える if (!ps.useDbFallback) ps.dbFallback = () => Promise.resolve([]); @@ -67,12 +64,11 @@ export class FanoutTimelineEndpointService { const redisResult = await this.fanoutTimelineService.getMulti(ps.redisTimelines, ps.untilId, ps.sinceId); // TODO: いい感じにgetMulti内でソート済だからuniqするときにredisResultが全てソート済なのを利用して再ソートを避けたい - const redisResultIds = Array.from(new Set(redisResult.flat(1))); + const redisResultIds = Array.from(new Set(redisResult.flat(1))).sort(idCompare); - redisResultIds.sort(idCompare); - noteIds = redisResultIds.slice(0, ps.limit); - - shouldFallbackToDb = shouldFallbackToDb || (noteIds.length === 0); + let noteIds = redisResultIds.slice(0, ps.limit); + const oldestNoteId = ascending ? redisResultIds[0] : redisResultIds[redisResultIds.length - 1]; + const shouldFallbackToDb = noteIds.length === 0 || ps.sinceId != null && ps.sinceId < oldestNoteId; if (!shouldFallbackToDb) { let filter = ps.noteFilter ?? (_note => true); diff --git a/packages/backend/test/e2e/timelines.ts b/packages/backend/test/e2e/timelines.ts index 5487292afc..f6cc2bac28 100644 --- a/packages/backend/test/e2e/timelines.ts +++ b/packages/backend/test/e2e/timelines.ts @@ -7,6 +7,8 @@ // pnpm jest -- e2e/timelines.ts import * as assert from 'assert'; +import { Redis } from 'ioredis'; +import { loadConfig } from '@/config.js'; import { api, post, randomString, sendEnvUpdateRequest, signup, sleep, uploadUrl } from '../utils.js'; function genHost() { @@ -17,7 +19,13 @@ function waitForPushToTl() { return sleep(500); } +let redisForTimelines: Redis; + describe('Timelines', () => { + beforeAll(() => { + redisForTimelines = new Redis(loadConfig().redisForTimelines); + }); + describe('Home TL', () => { test.concurrent('自分の visibility: followers なノートが含まれる', async () => { const [alice] = await Promise.all([signup()]); @@ -1272,6 +1280,33 @@ describe('Timelines', () => { assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false); }); + + /** @see https://github.com/misskey-dev/misskey/issues/14000 */ + test.concurrent('FTT: sinceId にキャッシュより古いノートを指定しても、sinceId による絞り込みが正しく動作する', async () => { + const alice = await signup(); + const noteSince = await post(alice, { text: 'Note where id will be `sinceId`.' }); + const note1 = await post(alice, { text: '1' }); + const note2 = await post(alice, { text: '2' }); + await redisForTimelines.del('list:userTimeline:' + alice.id); + const note3 = await post(alice, { text: '3' }); + + const res = await api('users/notes', { userId: alice.id, sinceId: noteSince.id }); + assert.deepStrictEqual(res.body, [note1, note2, note3]); + }); + + test.concurrent('FTT: sinceId にキャッシュより古いノートを指定しても、sinceId と untilId による絞り込みが正しく動作する', async () => { + const alice = await signup(); + const noteSince = await post(alice, { text: 'Note where id will be `sinceId`.' }); + const note1 = await post(alice, { text: '1' }); + const note2 = await post(alice, { text: '2' }); + await redisForTimelines.del('list:userTimeline:' + alice.id); + const note3 = await post(alice, { text: '3' }); + const noteUntil = await post(alice, { text: 'Note where id will be `untilId`.' }); + await post(alice, { text: '4' }); + + const res = await api('users/notes', { userId: alice.id, sinceId: noteSince.id, untilId: noteUntil.id }); + assert.deepStrictEqual(res.body, [note3, note2, note1]); + }); }); // TODO: リノートミュート済みユーザーのテスト From 1e78ef1cb847da719be23d55c87aaac0294665db Mon Sep 17 00:00:00 2001 From: anatawa12 <anatawa12@icloud.com> Date: Sat, 22 Jun 2024 12:44:01 +0900 Subject: [PATCH 22/26] =?UTF-8?q?fix:=20notRespondingSince=E3=81=8C?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=E3=81=95=E3=82=8C=E3=82=8B=E5=89=8D=E3=81=AB?= =?UTF-8?q?=E4=B8=8D=E9=80=9A=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=9F=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=82=B9=E3=82=BF=E3=83=B3=E3=82=B9=E3=81=8C=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E7=9A=84=E3=81=AB=E9=85=8D=E4=BF=A1=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E3=81=AB=E3=81=AA=E3=82=89=E3=81=AA=E3=81=84=20(#14059)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 1 + .../backend/src/queue/processors/DeliverProcessorService.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ce566370b..facc613b73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) - Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036) +- Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059) - Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 ## 2024.5.0 diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index b73195afc3..d665945861 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -109,6 +109,12 @@ export class DeliverProcessorService { suspensionState: 'autoSuspendedForNotResponding', }); } + } else { + // isNotRespondingがtrueでnotRespondingSinceがnullの場合はnotRespondingSinceをセット + // notRespondingSinceは新たな機能なので、それ以前のデータにはnotRespondingSinceがない場合がある + this.federatedInstanceService.update(i.id, { + notRespondingSince: new Date(), + }); } this.apRequestChart.deliverFail(); From 7e21497edc97b401026193b033b4a85675431907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:45:37 +0900 Subject: [PATCH 23/26] =?UTF-8?q?fix(frontend):=20=E3=83=AA=E3=83=90?= =?UTF-8?q?=E3=83=BC=E3=82=B7=E9=96=8B=E5=A7=8B=E6=99=82=E3=81=AE=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E6=8A=95=E7=A8=BF=E3=81=AEURL=E3=81=8C=E6=AD=A3?= =?UTF-8?q?=E3=81=97=E3=81=8F=E3=81=AA=E3=81=84=E5=A0=B4=E5=90=88=E3=81=8C?= =?UTF-8?q?=E3=81=82=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3=20(#1404?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(frontend): リバーシ開始時の自動投稿のURLが正しくない場合があるのを修正 * :v: --- CHANGELOG.md | 1 + packages/frontend/src/pages/reversi/game.vue | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index facc613b73..c5eb698385 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Client - Fix: `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正 - Fix: ユーザーページの追加情報のラベルを投稿者のサーバーの絵文字で表示する (#13968) +- Fix: リバーシの対局を正しく共有できないことがある問題を修正 ### Server - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 diff --git a/packages/frontend/src/pages/reversi/game.vue b/packages/frontend/src/pages/reversi/game.vue index eadc51881c..97a793753d 100644 --- a/packages/frontend/src/pages/reversi/game.vue +++ b/packages/frontend/src/pages/reversi/game.vue @@ -20,6 +20,7 @@ import { useStream } from '@/stream.js'; import { signinRequired } from '@/account.js'; import { useRouter } from '@/router/supplier.js'; import * as os from '@/os.js'; +import { url } from '@/config.js'; import { i18n } from '@/i18n.js'; import { useInterval } from '@/scripts/use-interval.js'; @@ -44,7 +45,7 @@ function start(_game: Misskey.entities.ReversiGameDetailed) { if (shareWhenStart.value) { misskeyApi('notes/create', { - text: i18n.ts._reversi.iStartedAGame + '\n' + location.href, + text: `${i18n.ts._reversi.iStartedAGame}\n${url}/reversi/g/${props.gameId}`, visibility: 'home', }); } From 3254f7c5cd13c56d023f9fc1ed50f1b602c8359d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:45:52 +0900 Subject: [PATCH 24/26] chore(deps): bump docker/build-push-action from 5 to 6 (#14039) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-develop.yml | 2 +- .github/workflows/docker.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-develop.yml b/.github/workflows/docker-develop.yml index cb84849580..ac2b1b4d35 100644 --- a/.github/workflows/docker-develop.yml +++ b/.github/workflows/docker-develop.yml @@ -37,7 +37,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push by digest id: build - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . push: true diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 23c1bdbc16..db899ba386 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -48,7 +48,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and Push to Docker Hub id: build - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . push: true From ef205fb60ece6a4e7bd985b62692afc299ce39ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AC=E3=82=8B=E3=81=8D=E3=82=83=E3=81=A3=E3=81=A8?= <nullnyat@nca10.moe> Date: Sat, 22 Jun 2024 12:46:30 +0900 Subject: [PATCH 25/26] =?UTF-8?q?enhance(frontend):=20WidgetInstanceInfo.v?= =?UTF-8?q?ue=20=E3=81=A8=20WidgetProfile.vue=20=E3=81=AE=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=AB=E8=AA=BF=E6=95=B4=20(#14028)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🎨 WidgetInstanceInfo.vue and WidgetProfile.vue * 🎨 WidgetInstanceInfo.vue and WidgetProfile.vue * 🎨 WidgetInstanceInfo.vue and WidgetProfile.vue * 🎨 WidgetInstanceInfo.vue and WidgetProfile.vue * 🎨 home.vue --- packages/frontend/src/pages/user/home.vue | 5 +++-- packages/frontend/src/widgets/WidgetInstanceInfo.vue | 7 +++++-- packages/frontend/src/widgets/WidgetProfile.vue | 7 +++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index d0be973552..834d799072 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -392,11 +392,12 @@ onUnmounted(() => { > .name { display: block; - margin: 0; + margin: -10px; + padding: 10px; line-height: 32px; font-weight: bold; font-size: 1.8em; - text-shadow: 0 0 8px #000; + filter: drop-shadow(0 0 4px #000); } > .bottom { diff --git a/packages/frontend/src/widgets/WidgetInstanceInfo.vue b/packages/frontend/src/widgets/WidgetInstanceInfo.vue index 25d824c8ae..5d8beaf9a9 100644 --- a/packages/frontend/src/widgets/WidgetInstanceInfo.vue +++ b/packages/frontend/src/widgets/WidgetInstanceInfo.vue @@ -81,16 +81,19 @@ defineExpose<WidgetComponentExpose>({ .body { text-overflow: ellipsis; overflow: clip; + margin-left: -10px; + padding: 10px; } .name { color: #fff; - filter: drop-shadow(0 0 4px #000); + filter: drop-shadow(0 0 4px #000) drop-shadow(0 0 0.1px rgba(0, 0, 0, 0.5)); font-weight: bold; } .host { color: #fff; - filter: drop-shadow(0 0 4px #000); + filter: drop-shadow(0 0 4px #000) drop-shadow(0 0 0.1px rgba(0, 0, 0, 0.5)); + } </style> diff --git a/packages/frontend/src/widgets/WidgetProfile.vue b/packages/frontend/src/widgets/WidgetProfile.vue index a5578d4de6..ae39098305 100644 --- a/packages/frontend/src/widgets/WidgetProfile.vue +++ b/packages/frontend/src/widgets/WidgetProfile.vue @@ -82,16 +82,19 @@ defineExpose<WidgetComponentExpose>({ .body { text-overflow: ellipsis; overflow: clip; + margin-left: -10px; + padding: 10px; } .name { color: #fff; - filter: drop-shadow(0 0 4px #000); + filter: drop-shadow(0 0 4px #000) drop-shadow(0 0 0.1px rgba(0, 0, 0, 0.5)); font-weight: bold; } .username { color: #fff; - filter: drop-shadow(0 0 4px #000); + filter: drop-shadow(0 0 4px #000) drop-shadow(0 0 0.1px rgba(0, 0, 0, 0.5)); + font-weight: normal; } </style> From ac12ab8629f0a0172250f949a98ee1efb1d0890d Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:51:02 +0900 Subject: [PATCH 26/26] =?UTF-8?q?fix(backend):=20=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AE=E3=83=8E=E3=83=BC=E3=83=88=E3=81=AE?= =?UTF-8?q?MFM=E3=81=AFHTML=E3=81=AB=E3=83=AC=E3=83=B3=E3=83=80=E3=83=BC?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=81=8B=E3=82=89=E8=BF=94=E3=81=99=20(#1400?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): フィードのノートのMFMはHTMLにレンダーしてから返す (test wip) * chore: beforeEachを使う? * fix: プレーンテキストにフォールバックしてMFMが含まれていないか調べる方針を実装 * fix: application/jsonだとパースされるのでその作用をキャンセル * build: fix lint error * docs: update CHANGELOG.md --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 1 + packages/backend/src/server/web/FeedService.ts | 6 +++++- packages/backend/test/e2e/fetch-resource.ts | 17 +++++++++++++++++ packages/backend/test/utils.ts | 5 +++-- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5eb698385..ab9f5f8000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Server - チャート生成時にinstance.suspentionStateに置き換えられたinstance.isSuspendedが参照されてしまう問題を修正 - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) +- Fix: ユーザーのフィードページのMFMをHTMLに展開するように (#14006) - Fix: アンテナ・クリップ・リスト・ウェブフックがロールポリシーの上限より一つ多く作れてしまうのを修正 (#14036) - Fix: notRespondingSinceが実装される前に不通になったインスタンスが自動的に配信停止にならない (#14059) - Fix: FTT有効時、タイムライン用エンドポイントで`sinceId`にキャッシュ内最古のものより古いものを指定した場合に正しく結果が返ってこない問題を修正 diff --git a/packages/backend/src/server/web/FeedService.ts b/packages/backend/src/server/web/FeedService.ts index 10e3ed2682..9d810ddc84 100644 --- a/packages/backend/src/server/web/FeedService.ts +++ b/packages/backend/src/server/web/FeedService.ts @@ -14,6 +14,8 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; +import { MfmService } from "@/core/MfmService.js"; +import { parse as mfmParse } from 'mfm-js'; @Injectable() export class FeedService { @@ -33,6 +35,7 @@ export class FeedService { private userEntityService: UserEntityService, private driveFileEntityService: DriveFileEntityService, private idService: IdService, + private mfmService: MfmService, ) { } @@ -76,13 +79,14 @@ export class FeedService { id: In(note.fileIds), }) : []; const file = files.find(file => file.type.startsWith('image/')); + const text = note.text; feed.addItem({ title: `New note by ${author.name}`, link: `${this.config.url}/notes/${note.id}`, date: this.idService.parse(note.id).date, description: note.cw ?? undefined, - content: note.text ?? undefined, + content: text ? this.mfmService.toHtml(mfmParse(text), JSON.parse(note.mentionedRemoteUsers)) ?? undefined : undefined, image: file ? this.driveFileEntityService.getPublicUrl(file) : undefined, }); } diff --git a/packages/backend/test/e2e/fetch-resource.ts b/packages/backend/test/e2e/fetch-resource.ts index 4851ed14be..7efd688ec2 100644 --- a/packages/backend/test/e2e/fetch-resource.ts +++ b/packages/backend/test/e2e/fetch-resource.ts @@ -153,6 +153,23 @@ describe('Webリソース', () => { path: path('nonexisting'), status: 404, })); + + describe(' has entry such ', () => { + beforeEach(() => { + post(alice, { text: "**a**" }) + }); + + test('MFMを含まない。', async () => { + const content = await simpleGet(path(alice.username), "*/*", undefined, res => res.text()); + const _body: unknown = content.body; + // JSONフィードのときは改めて文字列化する + const body: string = typeof (_body) === "object" ? JSON.stringify(_body) : _body as string; + + if (body.includes("**a**")) { + throw new Error("MFM shouldn't be included"); + } + }); + }) }); describe.each([{ path: '/api/foo' }])('$path', ({ path }) => { diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index 86814fffe0..aad4ab37c9 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -17,6 +17,7 @@ import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/val import { entities } from '../src/postgres.js'; import { loadConfig } from '../src/config.js'; import type * as misskey from 'misskey-js'; +import { type Response } from 'node-fetch'; export { server as startServer, jobQueue as startJobQueue } from '@/boot/common.js'; @@ -454,7 +455,7 @@ export type SimpleGetResponse = { type: string | null, location: string | null }; -export const simpleGet = async (path: string, accept = '*/*', cookie: any = undefined): Promise<SimpleGetResponse> => { +export const simpleGet = async (path: string, accept = '*/*', cookie: any = undefined, bodyExtractor: (res: Response) => Promise<string | null> = _ => Promise.resolve(null)): Promise<SimpleGetResponse> => { const res = await relativeFetch(path, { headers: { Accept: accept, @@ -482,7 +483,7 @@ export const simpleGet = async (path: string, accept = '*/*', cookie: any = unde const body = jsonTypes.includes(res.headers.get('content-type') ?? '') ? await res.json() : htmlTypes.includes(res.headers.get('content-type') ?? '') ? new JSDOM(await res.text()) : - null; + await bodyExtractor(res); return { status: res.status,