From dbd9d11d6749245947381c8b4d72a76347406bfb Mon Sep 17 00:00:00 2001 From: Soni L Date: Sat, 25 Feb 2023 23:14:07 -0300 Subject: [PATCH 01/25] Simplify search.vue (remove dead code) (#10088) * Simplify search.vue This is already handled by the code above it, no need to handle it twice * Remove unused imports --- packages/frontend/src/pages/search.vue | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/packages/frontend/src/pages/search.vue b/packages/frontend/src/pages/search.vue index d32bdcd78..7e81cd2c0 100644 --- a/packages/frontend/src/pages/search.vue +++ b/packages/frontend/src/pages/search.vue @@ -37,7 +37,6 @@ import { i18n } from '@/i18n'; import { definePageMetadata } from '@/scripts/page-metadata'; import * as os from '@/os'; import { useRouter, mainRouter } from '@/router'; -import { $i } from '@/account'; const router = useRouter(); @@ -116,24 +115,6 @@ const search = async () => { return; } - if ($i != null) { - if (query.startsWith('https://') || (query.startsWith('@') && !query.includes(' '))) { - const promise = os.api('ap/show', { - uri: query, - }); - - os.promiseDialog(promise, null, null, i18n.ts.fetchingAsApObject); - - const res = await promise; - - if (res.type === 'User') { - router.replace(`/@${res.object.username}@${res.object.host}`); - } else if (res.type === 'Note') { - router.replace(`/notes/${res.object.id}`); - } - } - } - window.history.replaceState('', '', `/search?q=${encodeURIComponent(query)}&type=${searchType}${searchType === 'user' ? `&origin=${searchOrigin}` : ''}`); }; From 991945ea264ec11669bf4ae037dc03dfebcdb4c5 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 11:24:09 +0900 Subject: [PATCH 02/25] Update about-misskey.vue --- packages/frontend/src/pages/about-misskey.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index 782fe9fdb..a49025c92 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -203,6 +203,7 @@ const patrons = [ 'ThatOneCalculator', 'pixeldesu', 'あめ玉', + '氷月氷華里', ]; let thereIsTreasure = $ref($i && !claimedAchievements.includes('foundTreasure')); From 18dbcfa0b09715a234a4eca0288e17d5cbf7622c Mon Sep 17 00:00:00 2001 From: tamaina Date: Sun, 26 Feb 2023 11:28:05 +0900 Subject: [PATCH 03/25] test(server): add validation test of api:notes/create (#10090) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(server): notes/createのバリデーションが効いていない Fix #10079 Co-Authored-By: mei23 * anyOf内にバリデーションを書いても最初の一つしかチェックされない * :v: * wip * wip * :v: * RequiredProp * Revert "RequiredProp" This reverts commit 74693900119a590263106fa3adefd008d69ce80c. * add api:notes/create * fix lint * text * :v: * improve readability --------- Co-authored-by: mei23 Co-authored-by: syuilo --- .vscode/settings.json | 5 +- CONTRIBUTING.md | 21 ++ packages/backend/.eslintrc.cjs | 2 +- packages/backend/jest.config.cjs | 3 +- packages/backend/src/misc/schema.ts | 17 +- .../api/endpoints/admin/drive/show-file.ts | 18 +- .../server/api/endpoints/drive/files/show.ts | 18 +- .../server/api/endpoints/notes/create.test.ts | 248 ++++++++++++++++++ .../src/server/api/endpoints/notes/create.ts | 111 ++++---- .../api/endpoints/notes/search-by-tag.ts | 41 ++- .../src/server/api/endpoints/pages/show.ts | 20 +- .../server/api/endpoints/users/followers.ts | 27 +- .../server/api/endpoints/users/following.ts | 27 +- .../users/search-by-username-and-host.ts | 17 +- .../src/server/api/endpoints/users/show.ts | 40 ++- .../backend/test/prelude/get-api-validator.ts | 11 + packages/backend/test/resources/misskey.svg | 7 + packages/backend/test/tsconfig.json | 3 +- packages/backend/tsconfig.json | 7 +- 19 files changed, 431 insertions(+), 212 deletions(-) create mode 100644 packages/backend/src/server/api/endpoints/notes/create.test.ts create mode 100644 packages/backend/test/prelude/get-api-validator.ts create mode 100644 packages/backend/test/resources/misskey.svg diff --git a/.vscode/settings.json b/.vscode/settings.json index c94a34194..6a0497946 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,8 @@ "search.exclude": { "**/node_modules": true }, - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "files.associations": { + "*.test.ts": "typescript" + } } \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 668989f12..10d93cd9f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -299,6 +299,27 @@ pnpm dlx typeorm migration:generate -d ormconfig.js -o - 生成後、ファイルをmigration下に移してください - 作成されたスクリプトは不必要な変更を含むため除去してください +### JSON SchemaのobjectでanyOfを使うとき +JSON Schemaで、objectに対してanyOfを使う場合、anyOfの中でpropertiesを定義しないこと。 +バリデーションが効かないため。(SchemaTypeもそのように作られており、objectのanyOf内のpropertiesは捨てられます) +https://github.com/misskey-dev/misskey/pull/10082 + +テキストhogeおよびfugaについて、片方を必須としつつ両方の指定もありうる場合: + +``` +export const paramDef = { + type: 'object', + properties: { + hoge: { type: 'string', minLength: 1 }, + fuga: { type: 'string', minLength: 1 }, + }, + anyOf: [ + { required: ['hoge'] }, + { required: ['fuga'] }, + ], +} as const; +``` + ### コネクションには`markRaw`せよ **Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。 diff --git a/packages/backend/.eslintrc.cjs b/packages/backend/.eslintrc.cjs index 5a06889dc..f9fe4814e 100644 --- a/packages/backend/.eslintrc.cjs +++ b/packages/backend/.eslintrc.cjs @@ -1,7 +1,7 @@ module.exports = { parserOptions: { tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], + project: ['./tsconfig.json', './test/tsconfig.json'], }, extends: [ '../shared/.eslintrc.js', diff --git a/packages/backend/jest.config.cjs b/packages/backend/jest.config.cjs index 2f11f6a3e..8a11ad848 100644 --- a/packages/backend/jest.config.cjs +++ b/packages/backend/jest.config.cjs @@ -20,7 +20,7 @@ module.exports = { // collectCoverage: false, // An array of glob patterns indicating a set of files for which coverage information should be collected - collectCoverageFrom: ['src/**/*.ts'], + collectCoverageFrom: ['src/**/*.ts', '!src/**/*.test.ts'], // The directory where Jest should output its coverage files coverageDirectory: "coverage", @@ -159,6 +159,7 @@ module.exports = { // The glob patterns Jest uses to detect test files testMatch: [ "/test/unit/**/*.ts", + "/src/**/*.test.ts", //"/test/e2e/**/*.ts" ], diff --git a/packages/backend/src/misc/schema.ts b/packages/backend/src/misc/schema.ts index 7fc4a3e65..6a0802f8a 100644 --- a/packages/backend/src/misc/schema.ts +++ b/packages/backend/src/misc/schema.ts @@ -116,10 +116,10 @@ export type Obj = Record; // https://github.com/misskey-dev/misskey/issues/8535 // To avoid excessive stack depth error, // deceive TypeScript with UnionToIntersection (or more precisely, `infer` expression within it). -export type ObjType = +export type ObjType> = UnionToIntersection< { -readonly [R in RequiredPropertyNames]-?: SchemaType } & - { -readonly [R in RequiredProps]-?: SchemaType } & + { -readonly [R in RequiredProps[number]]-?: SchemaType } & { -readonly [P in keyof s]?: SchemaType } >; @@ -136,18 +136,19 @@ type PartialIntersection = Partial>; // https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552 // To get union, we use `Foo extends any ? Hoge : never` type UnionSchemaType = X extends any ? SchemaType : never; -type UnionObjectSchemaType = X extends any ? ObjectSchemaType : never; +//type UnionObjectSchemaType = X extends any ? ObjectSchemaType : never; +type UnionObjType = a[number]> = X extends any ? ObjType : never; type ArrayUnion = T extends any ? Array : never; type ObjectSchemaTypeDef

= p['ref'] extends keyof typeof refs ? Packed : p['properties'] extends NonNullable ? - p['anyOf'] extends ReadonlyArray ? - ObjType[number]> & UnionObjectSchemaType & PartialIntersection> - : - ObjType[number]> + p['anyOf'] extends ReadonlyArray ? p['anyOf'][number]['required'] extends ReadonlyArray ? + UnionObjType> & ObjType> + : never + : ObjType> : - p['anyOf'] extends ReadonlyArray ? UnionObjectSchemaType & PartialIntersection> : + p['anyOf'] extends ReadonlyArray ? never : // see CONTRIBUTING.md p['allOf'] extends ReadonlyArray ? UnionToIntersection> : any diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts index 85b566aab..1d27ac213 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts @@ -138,19 +138,13 @@ export const meta = { export const paramDef = { type: 'object', + properties: { + fileId: { type: 'string', format: 'misskey:id' }, + url: { type: 'string' }, + }, anyOf: [ - { - properties: { - fileId: { type: 'string', format: 'misskey:id' }, - }, - required: ['fileId'], - }, - { - properties: { - url: { type: 'string' }, - }, - required: ['url'], - }, + { required: ['fileId'] }, + { required: ['url'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/drive/files/show.ts b/packages/backend/src/server/api/endpoints/drive/files/show.ts index e0a07a364..271b33ef4 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/show.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/show.ts @@ -39,19 +39,13 @@ export const meta = { export const paramDef = { type: 'object', + properties: { + fileId: { type: 'string', format: 'misskey:id' }, + url: { type: 'string' }, + }, anyOf: [ - { - properties: { - fileId: { type: 'string', format: 'misskey:id' }, - }, - required: ['fileId'], - }, - { - properties: { - url: { type: 'string' }, - }, - required: ['url'], - }, + { required: ['fileId'] }, + { required: ['url'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/notes/create.test.ts b/packages/backend/src/server/api/endpoints/notes/create.test.ts new file mode 100644 index 000000000..4e5ec361f --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/create.test.ts @@ -0,0 +1,248 @@ +process.env.NODE_ENV = 'test'; + +import { readFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; +import { dirname } from 'node:path'; +import { describe, test, expect } from '@jest/globals'; +import { getValidator } from '../../../../../test/prelude/get-api-validator.js'; +import { paramDef } from './create.js'; + +const _filename = fileURLToPath(import.meta.url); +const _dirname = dirname(_filename); + +const VALID = true; +const INVALID = false; + +describe('api:notes/create', () => { + describe('validation', () => { + const v = getValidator(paramDef); + const tooLong = readFile(_dirname + '/../../../../../test/resources/misskey.svg', 'utf-8'); + + test('reject empty', () => { + const valid = v({ }); + expect(valid).toBe(INVALID); + }); + + describe('text', () => { + test('simple post', () => { + expect(v({ text: 'Hello, world!' })) + .toBe(VALID); + }); + + test('null post', () => { + expect(v({ text: null })) + .toBe(INVALID); + }); + + test('0 characters post', () => { + expect(v({ text: '' })) + .toBe(INVALID); + }); + + test('over 3000 characters post', async () => { + expect(v({ text: await tooLong })) + .toBe(INVALID); + }); + }); + + describe('cw', () => { + test('simple cw', () => { + expect(v({ text: 'Hello, world!', cw: 'Hello, world!' })) + .toBe(VALID); + }); + + test('null cw', () => { + expect(v({ text: 'Body', cw: null })) + .toBe(VALID); + }); + + test('0 characters cw', () => { + expect(v({ text: 'Body', cw: '' })) + .toBe(VALID); + }); + + test('reject only cw', () => { + expect(v({ cw: 'Hello, world!' })) + .toBe(INVALID); + }); + + test('over 100 characters cw', async () => { + expect(v({ text: 'Body', cw: await tooLong })) + .toBe(INVALID); + }); + }); + + describe('visibility', () => { + test('public', () => { + expect(v({ text: 'Hello, world!', visibility: 'public' })) + .toBe(VALID); + }); + + test('home', () => { + expect(v({ text: 'Hello, world!', visibility: 'home' })) + .toBe(VALID); + }); + + test('followers', () => { + expect(v({ text: 'Hello, world!', visibility: 'followers' })) + .toBe(VALID); + }); + + test('reject only visibility', () => { + expect(v({ visibility: 'public' })) + .toBe(INVALID); + }); + + test('reject invalid visibility', () => { + expect(v({ text: 'Hello, world!', visibility: 'invalid' })) + .toBe(INVALID); + }); + + test('reject null visibility', () => { + expect(v({ text: 'Hello, world!', visibility: null })) + .toBe(INVALID); + }); + + describe('visibility:specified', () => { + test('specified without visibleUserIds', () => { + expect(v({ text: 'Hello, world!', visibility: 'specified' })) + .toBe(VALID); + }); + + test('specified with empty visibleUserIds', () => { + expect(v({ text: 'Hello, world!', visibility: 'specified', visibleUserIds: [] })) + .toBe(VALID); + }); + + test('reject specified with non unique visibleUserIds', () => { + expect(v({ text: 'Hello, world!', visibility: 'specified', visibleUserIds: ['1', '1', '2'] })) + .toBe(INVALID); + }); + + test('reject specified with null visibleUserIds', () => { + expect(v({ text: 'Hello, world!', visibility: 'specified', visibleUserIds: null })) + .toBe(INVALID); + }); + }); + }); + + describe('fileIds', () => { + test('only fileIds', () => { + expect(v({ fileIds: ['1', '2', '3'] })) + .toBe(VALID); + }); + + test('text and fileIds', () => { + expect(v({ text: 'Hello, world!', fileIds: ['1', '2', '3'] })) + .toBe(VALID); + }); + + test('reject null fileIds', () => { + expect(v({ fileIds: null })) + .toBe(INVALID); + }); + + test('reject text and null fileIds (複合的なanyOfのバリデーションが正しく動作する)', () => { + expect(v({ text: 'Hello, world!', fileIds: null })) + .toBe(INVALID); + }); + + test('reject 0 files', () => { + expect(v({ fileIds: [] })) + .toBe(INVALID); + }); + + test('reject non unique', () => { + expect(v({ fileIds: ['1', '1', '2'] })) + .toBe(INVALID); + }); + + test('reject invalid id', () => { + expect(v({ fileIds: ['あ'] })) + .toBe(INVALID); + }); + + test('reject over 17 files', () => { + const valid = v({ text: 'Hello, world!', fileIds: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'] }); + expect(valid).toBe(INVALID); + }); + }); + + describe('poll', () => { + test('note with poll', () => { + expect(v({ text: 'Hello, world!', poll: { choices: ['a', 'b', 'c'] } })) + .toBe(VALID); + }); + + test('null poll', () => { + expect(v({ text: 'Hello, world!', poll: null })) + .toBe(VALID); + }); + + test('allow only poll', () => { + expect(v({ poll: { choices: ['a', 'b', 'c'] } })) + .toBe(VALID); + }); + + test('poll with expiresAt', async () => { + expect(v({ poll: { choices: ['a', 'b', 'c'], expiresAt: 1 } })) + .toBe(VALID); + }); + + test('poll with expiredAfter', async () => { + expect(v({ poll: { choices: ['a', 'b', 'c'], expiredAfter: 1 } })) + .toBe(VALID); + }); + + test('reject poll without choices', () => { + expect(v({ poll: { } })) + .toBe(INVALID); + }); + + test('reject poll with empty choices', () => { + expect(v({ poll: { choices: [] } })) + .toBe(INVALID); + }); + + test('reject poll with null choices', () => { + expect(v({ poll: { choices: null } })) + .toBe(INVALID); + }); + + test('reject poll with 1 choice', () => { + expect(v({ poll: { choices: ['a'] } })) + .toBe(INVALID); + }); + + test('reject poll with too long choice', async () => { + expect(v({ poll: { choices: [await tooLong, '2'] } })) + .toBe(INVALID); + }); + + test('reject poll with too many choices', () => { + expect(v({ poll: { choices: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] } })) + .toBe(INVALID); + }); + + test('reject poll with non unique choices', () => { + expect(v({ poll: { choices: ['a', 'a', 'b', 'c'] } })) + .toBe(INVALID); + }); + + test('reject poll with expiredAfter 0', async () => { + expect(v({ poll: { choices: ['a', 'b', 'c'], expiredAfter: 0 } })) + .toBe(INVALID); + }); + }); + + test('text, fileIds and poll', () => { + expect(v({ text: 'Hello, world!', fileIds: ['1', '2', '3'], poll: { choices: ['a', 'b', 'c'] } })) + .toBe(VALID); + }); + + test('text, invalid fileIds and invalid poll', () => { + expect(v({ text: 'Hello, world!', fileIds: ['あ'], poll: { choices: ['a'] } })) + .toBe(INVALID); + }); + }); +}); diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index f4c5a84a4..2848cd7df 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -101,74 +101,55 @@ export const paramDef = { noExtractHashtags: { type: 'boolean', default: false }, noExtractEmojis: { type: 'boolean', default: false }, replyId: { type: 'string', format: 'misskey:id', nullable: true }, + renoteId: { type: 'string', format: 'misskey:id', nullable: true }, channelId: { type: 'string', format: 'misskey:id', nullable: true }, + + // anyOf内にバリデーションを書いても最初の一つしかチェックされない + // See https://github.com/misskey-dev/misskey/pull/10082 + text: { + type: 'string', + minLength: 1, + maxLength: MAX_NOTE_TEXT_LENGTH, + nullable: false + }, + fileIds: { + type: 'array', + uniqueItems: true, + minItems: 1, + maxItems: 16, + items: { type: 'string', format: 'misskey:id' }, + }, + mediaIds: { + type: 'array', + uniqueItems: true, + minItems: 1, + maxItems: 16, + items: { type: 'string', format: 'misskey:id' }, + }, + poll: { + type: 'object', + nullable: true, + properties: { + choices: { + type: 'array', + uniqueItems: true, + minItems: 2, + maxItems: 10, + items: { type: 'string', minLength: 1, maxLength: 50 }, + }, + multiple: { type: 'boolean' }, + expiresAt: { type: 'integer', nullable: true }, + expiredAfter: { type: 'integer', nullable: true, minimum: 1 }, + }, + required: ['choices'], + }, }, + // (re)note with text, files and poll are optional anyOf: [ - { - // (re)note with text, files and poll are optional - properties: { - text: { type: 'string', minLength: 1, maxLength: MAX_NOTE_TEXT_LENGTH, nullable: false }, - }, - required: ['text'], - }, - { - // (re)note with files, text and poll are optional - properties: { - fileIds: { - type: 'array', - uniqueItems: true, - minItems: 1, - maxItems: 16, - items: { type: 'string', format: 'misskey:id' }, - }, - }, - required: ['fileIds'], - }, - { - // (re)note with files, text and poll are optional - properties: { - mediaIds: { - deprecated: true, - description: 'Use `fileIds` instead. If both are specified, this property is discarded.', - type: 'array', - uniqueItems: true, - minItems: 1, - maxItems: 16, - items: { type: 'string', format: 'misskey:id' }, - }, - }, - required: ['mediaIds'], - }, - { - // (re)note with poll, text and files are optional - properties: { - poll: { - type: 'object', - nullable: true, - properties: { - choices: { - type: 'array', - uniqueItems: true, - minItems: 2, - maxItems: 10, - items: { type: 'string', minLength: 1, maxLength: 50 }, - }, - multiple: { type: 'boolean' }, - expiresAt: { type: 'integer', nullable: true }, - expiredAfter: { type: 'integer', nullable: true, minimum: 1 }, - }, - required: ['choices'], - }, - }, - required: ['poll'], - }, - { - // pure renote - properties: { - renoteId: { type: 'string', format: 'misskey:id', nullable: true }, - }, - required: ['renoteId'], - }, + { required: ['text'] }, + { required: ['fileIds'] }, + { required: ['mediaIds'] }, + { required: ['poll'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts index bcd793ac4..da1a4bcc4 100644 --- a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts +++ b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts @@ -36,32 +36,25 @@ export const paramDef = { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + + tag: { type: 'string', minLength: 1 }, + query: { + type: 'array', + description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.', + items: { + type: 'array', + items: { + type: 'string', + minLength: 1, + }, + minItems: 1, + }, + minItems: 1, + }, }, anyOf: [ - { - properties: { - tag: { type: 'string', minLength: 1 }, - }, - required: ['tag'], - }, - { - properties: { - query: { - type: 'array', - description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.', - items: { - type: 'array', - items: { - type: 'string', - minLength: 1, - }, - minItems: 1, - }, - minItems: 1, - }, - }, - required: ['query'], - }, + { required: ['tag'] }, + { required: ['query'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts index 651252afb..bf2b2a431 100644 --- a/packages/backend/src/server/api/endpoints/pages/show.ts +++ b/packages/backend/src/server/api/endpoints/pages/show.ts @@ -29,20 +29,14 @@ export const meta = { export const paramDef = { type: 'object', + properties: { + pageId: { type: 'string', format: 'misskey:id' }, + name: { type: 'string' }, + username: { type: 'string' }, + }, anyOf: [ - { - properties: { - pageId: { type: 'string', format: 'misskey:id' }, - }, - required: ['pageId'], - }, - { - properties: { - name: { type: 'string' }, - username: { type: 'string' }, - }, - required: ['name', 'username'], - }, + { required: ['pageId'] }, + { required: ['name', 'username'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts index 17ce92001..97f1310c3 100644 --- a/packages/backend/src/server/api/endpoints/users/followers.ts +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -46,25 +46,18 @@ export const paramDef = { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + + userId: { type: 'string', format: 'misskey:id' }, + username: { type: 'string' }, + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, }, anyOf: [ - { - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], - }, - { - properties: { - username: { type: 'string' }, - host: { - type: 'string', - nullable: true, - description: 'The local host is represented with `null`.', - }, - }, - required: ['username', 'host'], - }, + { required: ['userId'] }, + { required: ['username', 'host'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts index 6dbda0d72..d406594a2 100644 --- a/packages/backend/src/server/api/endpoints/users/following.ts +++ b/packages/backend/src/server/api/endpoints/users/following.ts @@ -46,25 +46,18 @@ export const paramDef = { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + + userId: { type: 'string', format: 'misskey:id' }, + username: { type: 'string' }, + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, }, anyOf: [ - { - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], - }, - { - properties: { - username: { type: 'string' }, - host: { - type: 'string', - nullable: true, - description: 'The local host is represented with `null`.', - }, - }, - required: ['username', 'host'], - }, + { required: ['userId'] }, + { required: ['username', 'host'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts index 1cefcf270..6c340d8fb 100644 --- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -31,20 +31,13 @@ export const paramDef = { properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, detail: { type: 'boolean', default: true }, + + username: { type: 'string', nullable: true }, + host: { type: 'string', nullable: true }, }, anyOf: [ - { - properties: { - username: { type: 'string', nullable: true }, - }, - required: ['username'], - }, - { - properties: { - host: { type: 'string', nullable: true }, - }, - required: ['host'], - }, + { required: ['username'] }, + { required: ['host'] }, ], } as const; diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index 70258ef00..29f24b045 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -54,32 +54,22 @@ export const meta = { export const paramDef = { type: 'object', + properties: { + userId: { type: 'string', format: 'misskey:id' }, + userIds: { type: 'array', uniqueItems: true, items: { + type: 'string', format: 'misskey:id', + } }, + username: { type: 'string' }, + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, + }, anyOf: [ - { - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], - }, - { - properties: { - userIds: { type: 'array', uniqueItems: true, items: { - type: 'string', format: 'misskey:id', - } }, - }, - required: ['userIds'], - }, - { - properties: { - username: { type: 'string' }, - host: { - type: 'string', - nullable: true, - description: 'The local host is represented with `null`.', - }, - }, - required: ['username'], - }, + { required: ['userId'] }, + { required: ['userIds'] }, + { required: ['username'] }, ], } as const; diff --git a/packages/backend/test/prelude/get-api-validator.ts b/packages/backend/test/prelude/get-api-validator.ts new file mode 100644 index 000000000..1f4a2dbc9 --- /dev/null +++ b/packages/backend/test/prelude/get-api-validator.ts @@ -0,0 +1,11 @@ +import { Schema } from '@/misc/schema'; +import Ajv from 'ajv'; + +export const getValidator = (paramDef: Schema) => { + const ajv = new Ajv({ + useDefaults: true, + }); + ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/); + + return ajv.compile(paramDef); +} diff --git a/packages/backend/test/resources/misskey.svg b/packages/backend/test/resources/misskey.svg new file mode 100644 index 000000000..3fcb2d3ec --- /dev/null +++ b/packages/backend/test/resources/misskey.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/backend/test/tsconfig.json b/packages/backend/test/tsconfig.json index da82ddc4a..8a024a678 100644 --- a/packages/backend/test/tsconfig.json +++ b/packages/backend/test/tsconfig.json @@ -33,11 +33,12 @@ "lib": [ "esnext" ], - "types": ["jest"] + "types": ["jest", "node"] }, "compileOnSave": false, "include": [ "./**/*.ts", + "../src/**/*.test.ts", "../src/@types/**/*.ts", ] } diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json index 6f335a244..faadbcdfc 100644 --- a/packages/backend/tsconfig.json +++ b/packages/backend/tsconfig.json @@ -26,9 +26,7 @@ "rootDir": "./src", "baseUrl": "./", "paths": { - "@/*": [ - "./src/*" - ] + "@/*": ["./src/*"] }, "outDir": "./built", "types": [ @@ -46,4 +44,7 @@ "include": [ "./src/**/*.ts" ], + "exclude": [ + "./src/**/*.test.ts" + ] } From 16ac03322cb4c5746fd627dd1e29b06e76278a76 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 11:32:10 +0900 Subject: [PATCH 04/25] New Crowdin updates (#10059) * New translations ja-JP.yml (Japanese, Kansai) * New translations ja-JP.yml (Romanian) * New translations ja-JP.yml (French) * New translations ja-JP.yml (Spanish) * New translations ja-JP.yml (Arabic) * New translations ja-JP.yml (Czech) * New translations ja-JP.yml (German) * New translations ja-JP.yml (Italian) * New translations ja-JP.yml (Korean) * New translations ja-JP.yml (Polish) * New translations ja-JP.yml (Russian) * New translations ja-JP.yml (Slovak) * New translations ja-JP.yml (Ukrainian) * New translations ja-JP.yml (Chinese Simplified) * New translations ja-JP.yml (Chinese Traditional) * New translations ja-JP.yml (English) * New translations ja-JP.yml (Vietnamese) * New translations ja-JP.yml (Indonesian) * New translations ja-JP.yml (Bengali) * New translations ja-JP.yml (Thai) * New translations ja-JP.yml (Japanese, Kansai) * New translations ja-JP.yml (Chinese Traditional) * New translations ja-JP.yml (Chinese Traditional) * New translations ja-JP.yml (German) * New translations ja-JP.yml (English) * New translations ja-JP.yml (German) * New translations ja-JP.yml (Ukrainian) * New translations ja-JP.yml (Chinese Simplified) * New translations ja-JP.yml (English) * New translations ja-JP.yml (Ukrainian) * New translations ja-JP.yml (Ukrainian) * New translations ja-JP.yml (Ukrainian) * New translations ja-JP.yml (Chinese Simplified) * New translations ja-JP.yml (Japanese, Kansai) * New translations ja-JP.yml (Thai) * New translations ja-JP.yml (Thai) * New translations ja-JP.yml (Thai) * New translations ja-JP.yml (Spanish) * New translations ja-JP.yml (Spanish) --- locales/ar-SA.yml | 1 + locales/bn-BD.yml | 1 + locales/cs-CZ.yml | 1 + locales/de-DE.yml | 38 ++++++++++++++++++++++++-- locales/en-US.yml | 39 ++++++++++++++++++++++++--- locales/es-ES.yml | 48 +++++++++++++++++++++++++++++++++ locales/fr-FR.yml | 1 + locales/id-ID.yml | 1 + locales/it-IT.yml | 1 + locales/ja-KS.yml | 68 ++++++++++++++++++++++++++++++++++++++++++++--- locales/ko-KR.yml | 1 + locales/pl-PL.yml | 1 + locales/ro-RO.yml | 2 ++ locales/ru-RU.yml | 1 + locales/sk-SK.yml | 1 + locales/th-TH.yml | 34 ++++++++++++++++++++++++ locales/uk-UA.yml | 26 ++++++++++++++++++ locales/vi-VN.yml | 1 + locales/zh-CN.yml | 36 ++++++++++++++++++++++++- locales/zh-TW.yml | 46 +++++++++++++++++++++++++++----- 20 files changed, 333 insertions(+), 15 deletions(-) diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index fb06f77da..3425b9c82 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -971,6 +971,7 @@ _ago: weeksAgo: "منذ {n} أسابيع" monthsAgo: "منذ {n} أشهر" yearsAgo: "منذ {n} سنوات" + invalid: "لا يوجد شيء هنا" _time: second: "ثا" minute: "د" diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index 18898bf4d..da17fc48d 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -1033,6 +1033,7 @@ _ago: weeksAgo: "{n} সপ্তাহ আগে" monthsAgo: "{n} মাস আগে" yearsAgo: "{n} বছর আগে" + invalid: "এখানে কিছুই নাই" _time: second: "সেকেন্ড" minute: "মিনিট" diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index 32891ff9f..7f665895b 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -659,6 +659,7 @@ _sfx: _ago: future: "Budoucí" justNow: "Teď" + invalid: "Nic nebylo nalezeno" _time: second: "Sekund" minute: "Minut" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index e68207f90..e5f8e9327 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -393,13 +393,19 @@ about: "Über" aboutMisskey: "Über Misskey" administrator: "Administrator" token: "Token" +2fa: "Zwei-Faktor-Authentifizierung" +totp: "Authentifizierungs-App" +totpDescription: "Logge dich via Authentifizierungs-App mit Einmalpasswort ein" moderator: "Moderator" moderation: "Moderation" nUsersMentioned: "Von {n} Benutzern erwähnt" +securityKeyAndPasskey: "Security-Tokens und Passkeys" securityKey: "Sicherheitsschlüssel" lastUsed: "Zuletzt benutzt" +lastUsedAt: "Zuletzt verwendet: {t}" unregister: "Deaktivieren" passwordLessLogin: "Passwortloses Anmelden einrichten" +passwordLessLoginDescription: "Ermöglicht passwortfreies Einloggen, nur via Security-Token oder Passkey" resetPassword: "Passwort zurücksetzen" newPasswordIs: "Das neue Passwort ist „{password}“" reduceUiAnimation: "Animationen der Benutzeroberfläche reduzieren" @@ -773,6 +779,7 @@ popularPosts: "Beliebte Beiträge" shareWithNote: "Mit Notiz teilen" ads: "Werbung" expiration: "Frist" +startingperiod: "Start" memo: "Merkzettel" priority: "Priorität" high: "Hoch" @@ -805,6 +812,7 @@ lastCommunication: "Letzte Kommunikation" resolved: "Gelöst" unresolved: "Ungelöst" breakFollow: "Follower entfernen" +breakFollowConfirm: "Diesen Follower wirklich entfernen?" itsOn: "Eingeschaltet" itsOff: "Ausgeschaltet" emailRequiredForSignup: "Angabe einer Email-Adresse als benötigt markieren" @@ -939,6 +947,10 @@ collapseRenotes: "Bereits gesehene Renotes verkürzt anzeigen" internalServerError: "Serverinterner Fehler" internalServerErrorDescription: "Im Server ist ein unerwarteter Fehler aufgetreten." copyErrorInfo: "Fehlerdetails kopieren" +joinThisServer: "Bei dieser Instanz registrieren" +exploreOtherServers: "Eine andere Instanz finden" +letsLookAtTimeline: "Die Chronik durchstöbern" +disableFederationWarn: "Dies deaktiviert Föderation, aber alle Notizen bleiben, sofern nicht umgestellt, öffentlich. In den meisten Fällen wird diese Option nicht benötigt." _achievements: earnedAt: "Freigeschaltet am" _types: @@ -1452,6 +1464,7 @@ _ago: weeksAgo: "vor {n} Woche(n)" monthsAgo: "vor {n} Monat(en)" yearsAgo: "vor {n} Jahr(en)" + invalid: "Ungültig" _time: second: "Sekunde(n)" minute: "Minute(n)" @@ -1485,14 +1498,29 @@ _tutorial: step8_3: "Diese Einstellung kannst du jederzeit ändern." _2fa: alreadyRegistered: "Du hast bereits ein Gerät für Zwei-Faktor-Authentifizierung registriert." + registerTOTP: "Authentifizierungs-App registrieren" + passwordToTOTP: "Bitte Passwort eingeben" step1: "Installiere zuerst eine Authentifizierungsapp (z.B. {a} oder {b}) auf deinem Gerät." step2: "Dann, scanne den angezeigten QR-Code mit deinem Gerät." + step2Click: "Durch Klicken dieses QR-Codes kannst du Verifikation mit deinem Security-Token oder einer App registrieren." step2Url: "Nutzt du ein Desktopprogramm kannst du alternativ diese URL eingeben:" + step3Title: "Authentifizierungsscode eingeben" step3: "Gib zum Abschluss den Token ein, der von deiner App angezeigt wird." step4: "Alle folgenden Anmeldungsversuche werden ab sofort die Eingabe eines solchen Tokens benötigen." + securityKeyNotSupported: "Dein Browser unterstützt keine Security-Tokens." + registerTOTPBeforeKey: "Um einen Security-Token oder einen Passkey zu registrieren, musst du zuerst eine Authentifizierungs-App registrieren." securityKeyInfo: "Du kannst neben Fingerabdruck- oder PIN-Authentifizierung auf deinem Gerät auch Anmeldung mit Hilfe eines FIDO2-kompatiblen Hardware-Sicherheitsschlüssels einrichten." - removeKeyConfirm: "Das Backup {name} löschen?" - renewTOTPCancel: "Nein, danke" + chromePasskeyNotSupported: "Chrome-Passkeys werden zur Zeit nicht unterstützt." + registerSecurityKey: "Security-Token oder Passkey registrieren" + securityKeyName: "Schlüsselname eingeben" + tapSecurityKey: "Bitten folge den Anweisungen deines Browsers zur Registrierung" + removeKey: "Sicherheitsschlüssel entfernen" + removeKeyConfirm: "Den Schlüssel {name} wirklich löschen?" + whyTOTPOnlyRenew: "Solange ein Sicherheitsschlüssel registriert ist, kann die Authentifizierungs-App nicht entfernt werden." + renewTOTP: "Authentifizierungs-App neu einrichten" + renewTOTPConfirm: "Codes der bisherigen App werden hierdurch nutzlos" + renewTOTPOk: "Neu einrichten" + renewTOTPCancel: "Abbrechen" _permissions: "read:account": "Deine Benutzerkontoinformationen lesen" "write:account": "Deine Benutzerkontoinformationen bearbeiten" @@ -1615,6 +1643,8 @@ _visibility: followersDescription: "Nur für Follower sichtbar" specified: "Direkt" specifiedDescription: "Nur für bestimmte Benutzer sichtbar" + disableFederation: "Deförderiert" + disableFederationDescription: "Nicht an andere Instanzen übertragen" _postForm: replyPlaceholder: "Dieser Notiz antworten …" quotePlaceholder: "Diese Notiz zitieren …" @@ -1770,6 +1800,7 @@ _notification: pollEnded: "Ende von Umfragen" receiveFollowRequest: "Erhaltene Follow-Anfragen" followRequestAccepted: "Akzeptierte Follow-Anfragen" + achievementEarned: "Errungenschaft freigeschaltet" app: "Benachrichtigungen von Apps" _actions: followBack: "folgt dir nun auch" @@ -1802,3 +1833,6 @@ _deck: channel: "Kanal" mentions: "Erwähnungen" direct: "Direktnachrichten" +_dialog: + charactersExceeded: "Maximallänge überschritten! Momentan {current} von {max}" + charactersBelow: "Minimallänge unterschritten! Momentan {current} von {min}" diff --git a/locales/en-US.yml b/locales/en-US.yml index 1ee562091..f118ddba7 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -393,13 +393,19 @@ about: "About" aboutMisskey: "About Misskey" administrator: "Administrator" token: "Token" +2fa: "Two-factor authentication" +totp: "Authenticator App" +totpDescription: "Use an authenticator app to enter one-time passwords" moderator: "Moderator" moderation: "Moderation" nUsersMentioned: "Mentioned by {n} users" +securityKeyAndPasskey: "Security- and passkeys" securityKey: "Security key" lastUsed: "Last used" +lastUsedAt: "Last used: {t}" unregister: "Unregister" passwordLessLogin: "Password-less login" +passwordLessLoginDescription: "Allows password-less login using a security- or passkey only" resetPassword: "Reset password" newPasswordIs: "The new password is \"{password}\"" reduceUiAnimation: "Reduce UI animations" @@ -773,6 +779,7 @@ popularPosts: "Popular posts" shareWithNote: "Share with note" ads: "Advertisements" expiration: "Deadline" +startingperiod: "Start" memo: "Memo" priority: "Priority" high: "High" @@ -805,7 +812,7 @@ lastCommunication: "Last communication" resolved: "Resolved" unresolved: "Unresolved" breakFollow: "Remove follower" -breakFollowConfirm: "Are you sure want to remove follower?" +breakFollowConfirm: "Really remove this follower?" itsOn: "Enabled" itsOff: "Disabled" emailRequiredForSignup: "Require email address for sign-up" @@ -940,6 +947,10 @@ collapseRenotes: "Collapse renotes you've already seen" internalServerError: "Internal Server Error" internalServerErrorDescription: "The server has run into an unexpected error." copyErrorInfo: "Copy error details" +joinThisServer: "Sign up at this instance" +exploreOtherServers: "Look for another instance" +letsLookAtTimeline: "Have a look at the timeline" +disableFederationWarn: "This will disable federation, but posts will continue to be public unless set otherwise. You usually do not need to use this setting." _achievements: earnedAt: "Unlocked at" _types: @@ -1453,6 +1464,7 @@ _ago: weeksAgo: "{n}w ago" monthsAgo: "{n}mo ago" yearsAgo: "{n}y ago" + invalid: "None" _time: second: "Second(s)" minute: "Minute(s)" @@ -1486,14 +1498,29 @@ _tutorial: step8_3: "You can always change this setting later." _2fa: alreadyRegistered: "You have already registered a 2-factor authentication device." + registerTOTP: "Register authenticator app" + passwordToTOTP: "Enter your password" step1: "First, install an authentication app (such as {a} or {b}) on your device." step2: "Then, scan the QR code displayed on this screen." + step2Click: "Clicking on this QR code will allow you to register 2FA to your security key or phone authenticator app." step2Url: "You can also enter this URL if you're using a desktop program:" + step3Title: "Enter an authentication code" step3: "Enter the token provided by your app to finish setup." step4: "From now on, any future login attempts will ask for such a login token." + securityKeyNotSupported: "Your browser does not support security keys." + registerTOTPBeforeKey: "Please set up an authenticator app to register a security or pass key." securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup authentication via hardware security keys that support FIDO2 to further secure your account." - removeKeyConfirm: "Delete the {name} backup?" - renewTOTPCancel: "Not now" + chromePasskeyNotSupported: "Chrome passkeys are currently not supported." + registerSecurityKey: "Register a security or pass key" + securityKeyName: "Enter a key name" + tapSecurityKey: "Please follow your browser to register the security or pass key" + removeKey: "Remove security key" + removeKeyConfirm: "Really delete the {name} key?" + whyTOTPOnlyRenew: "The authenticator app cannot be removed as long as a security key is registered." + renewTOTP: "Reconfigure authenticator app" + renewTOTPConfirm: "This will cause verification codes from your previous app to stop working" + renewTOTPOk: "Reconfigure" + renewTOTPCancel: "Cancel" _permissions: "read:account": "View your account information" "write:account": "Edit your account information" @@ -1616,6 +1643,8 @@ _visibility: followersDescription: "Make visible to your followers only" specified: "Direct" specifiedDescription: "Make visible for specified users only" + disableFederation: "Unfederated" + disableFederationDescription: "Don't transmit to other instances" _postForm: replyPlaceholder: "Reply to this note..." quotePlaceholder: "Quote this note..." @@ -1771,6 +1800,7 @@ _notification: pollEnded: "Polls ending" receiveFollowRequest: "Received follow requests" followRequestAccepted: "Accepted follow requests" + achievementEarned: "Achievement unlocked" app: "Notifications from linked apps" _actions: followBack: "followed you back" @@ -1803,3 +1833,6 @@ _deck: channel: "Channel" mentions: "Mentions" direct: "Direct notes" +_dialog: + charactersExceeded: "You've exceeded the maximum character limit! Currently at {current} of {max}." + charactersBelow: "You're below the minimum character limit! Currently at {current} of {min}." diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 6f638b336..2acf47cb4 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -103,6 +103,8 @@ renoted: "Renotado" cantRenote: "No se puede renotar este post" cantReRenote: "No se puede renotar una renota" quote: "Citar" +inChannelRenote: "Renota sólo del canal" +inChannelQuote: "Cita sólo del canal" pinnedNote: "Nota fijada" pinned: "Fijar al perfil" you: "Tú" @@ -391,13 +393,19 @@ about: "Información" aboutMisskey: "Sobre Misskey" administrator: "Administrador" token: "Token" +2fa: "Autenticación de doble factor" +totp: "Aplicación autentícadora" +totpDescription: "Ingresa una contaseña de un sólo uso usando la aplicación autenticadora" moderator: "Moderador" moderation: "Moderación" nUsersMentioned: "{n} usuarios mencionados" +securityKeyAndPasskey: "Clave de seguridad / clave de paso" securityKey: "Clave de seguridad" lastUsed: "Última vez usado" +lastUsedAt: "Último uso: {t}" unregister: "Cancelar registro" passwordLessLogin: "Iniciar sesión sin contraseña" +passwordLessLoginDescription: "Iniciar sesión con sólo una clave se seguridad / de paso sin usar una contraseña" resetPassword: "Resetear contraseña" newPasswordIs: "La nueva contraseña es \"{password}\"" reduceUiAnimation: "Reducir la animación de la UI" @@ -451,6 +459,8 @@ native: "Nativo" disableDrawer: "No mostrar los menús en cajones" noHistory: "No hay datos en el historial" signinHistory: "Historial de ingresos" +enableAdvancedMfm: "Habilitar MFM avanzado" +enableAnimatedMfm: "Habilitar MFM con movimiento" doing: "Voy en camino" category: "Categoría" tags: "Etiqueta" @@ -769,6 +779,7 @@ popularPosts: "Más vistos" shareWithNote: "Compartir con una nota" ads: "Anuncios" expiration: "Termina el" +startingperiod: "periodo de inicio" memo: "Notas" priority: "Prioridad" high: "Alta" @@ -801,6 +812,7 @@ lastCommunication: "Última comunicación" resolved: "Resuelto" unresolved: "Sin resolver" breakFollow: "Dejar de seguir" +breakFollowConfirm: "¿Quieres dejar de seguir?" itsOn: "¡Está encendido!" itsOff: "¡Está apagado!" emailRequiredForSignup: "Se requere una dirección de correo electrónico para el registro de la cuenta" @@ -845,6 +857,8 @@ failedToFetchAccountInformation: "No se pudo obtener información de la cuenta" rateLimitExceeded: "Se excedió el límite de peticiones" cropImage: "Recortar imágen" cropImageAsk: "¿Desea recortar la imagen?" +cropYes: "Recortar" +cropNo: "Usar como está" file: "Archivos" recentNHours: "Últimas {n} horas" recentNDays: "Últimos {n} días" @@ -925,6 +939,18 @@ selectFromPresets: "Escoger desde predefinidos" achievements: "Logros" gotInvalidResponseError: "Respuesta del servidor inválida" gotInvalidResponseErrorDescription: "Puede que el servidor esté caído o en mantenimiento. Favor de intentar más tarde" +thisPostMayBeAnnoying: "Ésta publicación puede resultar molesta." +thisPostMayBeAnnoyingHome: "Publicar en línea de tiempo 'Inicio'" +thisPostMayBeAnnoyingCancel: "detener" +thisPostMayBeAnnoyingIgnore: "Publicar de todos modos" +collapseRenotes: "Colapsar renotas que ya hayas visto" +internalServerError: "Error interno del servidor" +internalServerErrorDescription: "El servidor tuvo un error inesperado." +copyErrorInfo: "Copiar detalles del error" +joinThisServer: "Registrarse en esta instancia" +exploreOtherServers: "Buscar otra instancia" +letsLookAtTimeline: "Mirar la línea de tiempo local" +disableFederationWarn: "Esto desactivará la federación, pero las publicaciones segurán siendo públicas al menos que se configure diferente. Usualmente no necesitas usar esta configuración." _achievements: earnedAt: "Desbloqueado el" _types: @@ -1438,6 +1464,7 @@ _ago: weeksAgo: "Hace {n} semanas" monthsAgo: "Hace {n} meses" yearsAgo: "Hace {n} años" + invalid: "No hay nada que ver aqui" _time: second: "Segundos" minute: "Minutos" @@ -1471,13 +1498,28 @@ _tutorial: step8_3: "La configuración de las notificaciones puede modificarse posteriormente." _2fa: alreadyRegistered: "Ya has completado la configuración." + registerTOTP: "Registrar aplicación autenticadora" + passwordToTOTP: "Ingresa tu contraseña" step1: "Primero, instale en su dispositivo la aplicación de autenticación {a} o {b} u otra." step2: "Luego, escanee con la aplicación el código QR mostrado en pantalla." + step2Click: "Clicking on this QR code will allow you to register 2FA to your security key or phone authenticator app.\nTocar este código QR te permitirá registrar la autenticación 2FA a tu llave de seguridad o aplicación autenticadora." step2Url: "En una aplicación de escritorio se puede ingresar la siguiente URL:" + step3Title: "Ingresa un código de autenticación" step3: "Para terminar, ingrese el token mostrado en la aplicación." step4: "Ahora cuando inicie sesión, ingrese el mismo token" + securityKeyNotSupported: "Tu navegador no soporta claves de autenticación." + registerTOTPBeforeKey: "Please set up an authenticator app to register a security or pass key.\npor favor. configura una aplicación de autenticación para registrar una llave de seguridad." securityKeyInfo: "Se puede configurar el inicio de sesión usando una clave de seguridad de hardware que soporte FIDO2 o con un certificado de huella digital o con un PIN" + chromePasskeyNotSupported: "Las llaves de seguridad de Chrome no son soportadas por el momento." + registerSecurityKey: "Registrar una llave de seguridad" + securityKeyName: "Ingresa un nombre para la clave" + tapSecurityKey: "Por favor, sigue tu navegador para registrar una llave de seguridad" + removeKey: "Quitar la llave de seguridad" removeKeyConfirm: "¿Borrar el respaldo \"{name}\"?" + whyTOTPOnlyRenew: "The authenticator app cannot be removed as long as a security key is registered.\nLa aplicación autenticadora no puede ser eliminada mientras la llave de seguridad se encuentre registrada." + renewTOTP: "Reconfigurar la aplicación autenticadora" + renewTOTPConfirm: "This will cause verification codes from your previous app to stop working\nEsto hará que los códigos de verificación de la aplicación anterior dejen de funcionar" + renewTOTPOk: "Reconfigurar" renewTOTPCancel: "No gracias" _permissions: "read:account": "Ver información de la cuenta" @@ -1601,6 +1643,8 @@ _visibility: followersDescription: "Visible sólo para tus seguidores" specified: "Mensaje directo" specifiedDescription: "Visible sólo para los usuarios elegidos" + disableFederation: "No federado" + disableFederationDescription: "No enviar a otras instancias" _postForm: replyPlaceholder: "Responder a esta nota" quotePlaceholder: "Citar esta nota" @@ -1756,6 +1800,7 @@ _notification: pollEnded: "La encuesta terminó" receiveFollowRequest: "Recibió una solicitud de seguimiento" followRequestAccepted: "El seguimiento fue aceptado" + achievementEarned: "Logro desbloqueado" app: "Notificaciones desde aplicaciones" _actions: followBack: "Te sigue de vuelta" @@ -1788,3 +1833,6 @@ _deck: channel: "Canal" mentions: "Menciones" direct: "Mensaje directo" +_dialog: + charactersExceeded: "¡Has excedido el límite de caracteres! Actualmente {current} de {max}." + charactersBelow: "¡Estás por debajo del límite de caracteres! Actualmente {current} de {min}." diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index de6156e39..1b40f99b4 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -1121,6 +1121,7 @@ _ago: weeksAgo: "Il y a {n} semaines" monthsAgo: "Il y a {n} mois" yearsAgo: "Il y a {n} ans" + invalid: "Il n'y a rien à voir ici" _time: second: "s" minute: "min" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index d3d1a1621..18941c5c3 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -1452,6 +1452,7 @@ _ago: weeksAgo: "{n} minggu lalu" monthsAgo: "{n} bulan lalu" yearsAgo: "{n} tahun lalu" + invalid: "Tidak ada sama sekali disini" _time: second: "detik" minute: "menit" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 0ce65eea8..7b2addc6b 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -1452,6 +1452,7 @@ _ago: weeksAgo: "{n} sett. fa" monthsAgo: "{n} mesi fa" yearsAgo: "{n} anni fa" + invalid: "Niente da visualizzare" _time: second: "s" minute: "min" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 68664067c..73f007e2b 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -393,13 +393,19 @@ about: "情報" aboutMisskey: "Misskeyってなんや?" administrator: "管理者" token: "トークン" +2fa: "二要素認証" +totp: "認証アプリ" +totpDescription: "認証アプリ使てワンタイムパスワードを入れる" moderator: "モデレーター" moderation: "モデレーション" nUsersMentioned: "{n}人が投稿" +securityKeyAndPasskey: "セキュリティキー・パスキー" securityKey: "セキュリティキー" lastUsed: "最後につこうた日" +lastUsedAt: "最後に使たん: {t}" unregister: "登録やめる" passwordLessLogin: "パスワード無くてもログインできるようにする" +passwordLessLoginDescription: "パスワードやなくて、セキュリティキーとかパスキーだけでログインするわ" resetPassword: "パスワードをリセット" newPasswordIs: "今度のパスワードは「{password}」や" reduceUiAnimation: "UIの動きやアニメーションを減らす" @@ -575,7 +581,7 @@ generateAccessToken: "アクセストークンの発行" permission: "権限" enableAll: "全部使えるようにする" disableAll: "全部使えへんようにする" -tokenRequested: "アカウントへのアクセス許可" +tokenRequested: "アカウントへのアクセス許してやったらどうや" pluginTokenRequestedDescription: "このプラグインはここで設定した権限を使えるようになるで。" notificationType: "通知の種類" edit: "編集" @@ -773,6 +779,7 @@ popularPosts: "人気の投稿" shareWithNote: "ノートで共有" ads: "広告" expiration: "期限" +startingperiod: "始めた期間" memo: "メモ" priority: "優先度" high: "高い" @@ -805,6 +812,7 @@ lastCommunication: "直近の通信" resolved: "解決したで" unresolved: "まだ解決してないで" breakFollow: "フォロワーを解除するで" +breakFollowConfirm: "フォロワー解除してもええか?" itsOn: "オンになっとるよ" itsOff: "オフになってるで" emailRequiredForSignup: "アカウント登録にメールアドレスを必須にするで" @@ -939,6 +947,10 @@ collapseRenotes: "見たことあるRenoteは省略やで" internalServerError: "サーバー内部エラー" internalServerErrorDescription: "サーバー内部でよう分からんエラーやわ" copyErrorInfo: "エラー情報をコピー" +joinThisServer: "このサーバーに登録するわ" +exploreOtherServers: "他のサーバー見てみる" +letsLookAtTimeline: "タイムライン見てみーや" +disableFederationWarn: "連合が無効になっとるで。無効にしても投稿は非公開ってわけちゃうねん。大体の場合はこのオプションを有効にする必要は別にないで。" _achievements: earnedAt: "貰った日ぃ" _types: @@ -1051,21 +1063,42 @@ _achievements: _myNoteFavorited1: title: "星ぃ欲しい" description: "ワレのノートが他のひとにお気に入り登録されたで" + _profileFilled: + title: "準備万端や" + description: "プロフィールを設定した" + _markedAsCat: + title: "吾輩は猫やねん" + description: "アカウントがCatになってもうた" + flavor: "名前はまだないねん。" + _following1: + title: "はじめてのフォロー" + description: "初めてフォローした" _following10: + title: "ついてく、ついてく" description: "フォローが10人超えた" _following50: + title: "友達ぎょうさん" description: "フォローが50人超えた" _following100: + title: "友達100人" description: "フォローが100人超えた" _following300: + title: "いや友達多すぎやろ" description: "フォローが300人超えた" + _followers1: + title: "はじめてのフォロワー" + description: "初めてフォローされた" _followers10: + title: "フォローみぃ!" description: "フォロワーが10人超えた" _followers50: + title: "ぞろぞろ" description: "フォロワーが50人超えた" _followers100: + title: "人気もん" description: "フォロワーが100人超えた" _followers300: + title: "ほらそこ一列に並んで!" description: "フォロワーが300人超えた" _followers500: title: "基地局" @@ -1150,6 +1183,10 @@ _achievements: title: "クッキー叩くやつ" description: "クッキー叩いてもうた" flavor: "兄ちゃんソフト間違っとんで" + _brainDiver: + title: "Brain Diver" + description: "Brain Diverへのリンクを投稿したった" + flavor: "Misskey-Misskey La-Tu-Ma" _role: new: "ロールの作成" edit: "ロールの編集" @@ -1170,6 +1207,8 @@ _role: baseRole: "ベースロール" useBaseValue: "ベースロールの値を使用" chooseRoleToAssign: "アサインするロールを選択" + iconUrl: "アイコン画像のURL" + asBadge: "バッジとして見せる" descriptionOfAsBadge: "オンにすると、ユーザー名の横んとこにロールのアイコンが表示されるで。" canEditMembersByModerator: "モデレーターのメンバー編集を許可" descriptionOfCanEditMembersByModerator: "オンにすると、管理者に加えてモデレーターもこのロールへユーザーをアサイン/アサイン解除できるようになるで。オフにすると管理者のみが行えるで。" @@ -1425,6 +1464,7 @@ _ago: weeksAgo: "{n}週間前" monthsAgo: "{n}ヶ月前" yearsAgo: "{n}年前" + invalid: "あらへん" _time: second: "秒" minute: "分" @@ -1458,13 +1498,28 @@ _tutorial: step8_3: "通知の設定はあとから変更できるで" _2fa: alreadyRegistered: "もう設定終わっとるわ。" + registerTOTP: "認証アプリの設定はじめる" + passwordToTOTP: "パスワードを入れてーや" step1: "ほんなら、{a}や{b}とかの認証アプリを使っとるデバイスにインストールしてな。" step2: "次に、ここにあるQRコードをアプリでスキャンしてな~。" + step2Click: "QRコードをクリックすると、今使とる端末に入っとる認証アプリとかキーリングに登録できるで。" step2Url: "デスクトップアプリやったら次のURLを入力してや:" + step3Title: "確認コードを入れてーや" step3: "アプリに表示されているトークンを入力して終わりや。" step4: "これからログインするときも、同じようにトークンを入力するんやで" + securityKeyNotSupported: "今使とるブラウザはセキュリティキーに対応してへんのやってさ。" + registerTOTPBeforeKey: "セキュリティキー・パスキーを登録するんやったら、まず認証アプリを設定してーな。" securityKeyInfo: "FIDO2をサポートするハードウェアセキュリティキーか端末の指紋認証やPINを使ってログインするように設定できるで。" + chromePasskeyNotSupported: "Chromeのパスキーは今んとこ対応してないねん。" + registerSecurityKey: "セキュリティキー・パスキーを登録するわ" + securityKeyName: "キーの名前を入れてーや" + tapSecurityKey: "ブラウザが言うこと聞いて、セキュリティキーとかパスキー登録しといでや" + removeKey: "セキュリティキーをほかす" removeKeyConfirm: "{name}を消すん?" + whyTOTPOnlyRenew: "セキュリティキーが登録されとったら、認証アプリの設定は解除できへんで。" + renewTOTP: "認証アプリをもっかい設定" + renewTOTPConfirm: "今までの人称アプリの確認コードは使えんくなるけどええか?" + renewTOTPOk: "もっかい設定する" renewTOTPCancel: "やめとく" _permissions: "read:account": "アカウントの情報を見るで" @@ -1500,6 +1555,7 @@ _permissions: "read:gallery-likes": "ギャラリーのいいねを見るで" "write:gallery-likes": "ギャラリーのいいねを操作するで" _auth: + shareAccessTitle: "アプリへのアクセス許してやったらどうや" shareAccess: "「{name}」がアカウントにアクセスすることを許可してええか?" shareAccessAsk: "アカウントのアクセスを許可してもええか?" permission: "{name}に次の権限つけたってやって" @@ -1587,14 +1643,16 @@ _visibility: followersDescription: "自分のフォロワーのみに公開するで" specified: "ダイレクト" specifiedDescription: "選んだユーザーのみに公開するで" + disableFederation: "連合なし" + disableFederationDescription: "他インスタンスへは送らんとくわ" _postForm: replyPlaceholder: "このノートに返信..." quotePlaceholder: "このノートを引用..." channelPlaceholder: "チャンネルに投稿..." _placeholders: - a: "いまどうしとるん?" + a: "いまどないしとるん?" b: "何かあったん?" - c: "何を考えとるん?" + c: "何か考えとるん?" d: "何か言いたいことあるん?" e: "ここに書いてーなー" f: "あんたが書くの待っとるで" @@ -1742,6 +1800,7 @@ _notification: pollEnded: "アンケートが終了したで" receiveFollowRequest: "フォロー許可してほしいみたいやで" followRequestAccepted: "フォローが受理されたで" + achievementEarned: "実績の獲得" app: "連携アプリからの通知や" _actions: followBack: "フォローバック" @@ -1774,3 +1833,6 @@ _deck: channel: "チャンネル" mentions: "あんた宛て" direct: "ダイレクト" +_dialog: + charactersExceeded: "最大の文字数を上回っとるで!今は {current} / 最大でも {max}" + charactersBelow: "最小の文字数を下回っとるで!今は {current} / 最低でも {min}" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 1c5cf8517..3e39980db 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1452,6 +1452,7 @@ _ago: weeksAgo: "{n}주 전" monthsAgo: "{n}개월 전" yearsAgo: "{n}년 전" + invalid: "아무것도 없습니다" _time: second: "초" minute: "분" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 3003e9325..1c19c4f3e 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -1061,6 +1061,7 @@ _ago: weeksAgo: "{n} tyg. temu" monthsAgo: "{n} mies. temu" yearsAgo: "{n} lat temu" + invalid: "Nie ma tu niczego" _time: second: "sekunda" minute: "minuta" diff --git a/locales/ro-RO.yml b/locales/ro-RO.yml index c3438172c..10cb085f3 100644 --- a/locales/ro-RO.yml +++ b/locales/ro-RO.yml @@ -648,6 +648,8 @@ _sfx: note: "Note" notification: "Notificări" chat: "Chat" +_ago: + invalid: "Nu e nimic de văzut aici" _widgets: profile: "Profil" instanceInfo: "Informații despre instanță" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 70839694b..86a60ee79 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -1452,6 +1452,7 @@ _ago: weeksAgo: "{n} нед. назад" monthsAgo: "{n} мес. назад" yearsAgo: "{n} г. назад" + invalid: "Ничего нет" _time: second: "с" minute: "мин" diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml index f55fdf979..525eb9ca0 100644 --- a/locales/sk-SK.yml +++ b/locales/sk-SK.yml @@ -1123,6 +1123,7 @@ _ago: weeksAgo: "pred {n} týždňami" monthsAgo: "pred {n} mesiacmi" yearsAgo: "pred {n} rokmi" + invalid: "Nič tu nie je" _time: second: "s" minute: "min" diff --git a/locales/th-TH.yml b/locales/th-TH.yml index 2c721e45e..a56d7451b 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -393,13 +393,19 @@ about: "เกี่ยวกับ" aboutMisskey: "เกี่ยวกับ Misskey" administrator: "ผู้ดูแลระบบ" token: "โทเค็น" +2fa: "การยืนยันตัวตนแบบสองชั้น" +totp: "แอป Authenticator" +totpDescription: "ใช้แอปยืนยันตัวตนเพื่อป้อนรหัสผ่านแบบใช้ครั้งเดียว" moderator: "ผู้ควบคุม" moderation: "การกลั่นกรอง" nUsersMentioned: "กล่าวถึงโดยผู้ใช้ {n} รายนี้" +securityKeyAndPasskey: "ความปลอดภัยและรหัสผ่าน" securityKey: "กุญแจความปลอดภัย" lastUsed: "ใช้ล่าสุด" +lastUsedAt: "ใช้งานครั้งล่าสุด: {t}" unregister: "เลิกติดตาม" passwordLessLogin: "เข้าสู่ระบบแบบไม่ใช้รหัสผ่าน" +passwordLessLoginDescription: "อนุญาตให้เข้าสู่ระบบโดยไม่ต้องใช้รหัสผ่านโดยใช้รหัสรักษาความปลอดภัยหรือรหัสผ่านเท่านั้น" resetPassword: "รีเซ็ตรหัสผ่าน" newPasswordIs: "รหัสผ่านใหม่คือ \"{password}\"" reduceUiAnimation: "ลดภาพเคลื่อนไหว UI" @@ -773,6 +779,7 @@ popularPosts: "โพสต์ติดอันดับ" shareWithNote: "แบ่งปันด้วยโน้ต" ads: "โฆษณา" expiration: "กำหนดเวลา" +startingperiod: "เริ่ม" memo: "ข้อควรจำ" priority: "ลำดับความสำคัญ" high: "สูง" @@ -805,6 +812,7 @@ lastCommunication: "การสื่อสารครั้งสุดท้ resolved: "คลี่คลายแล้ว" unresolved: "รอการเฉลย" breakFollow: "ลบผู้ติดตาม" +breakFollowConfirm: "ลบผู้ติดตามนี้ออกจริงหรอ?" itsOn: "เปิดใช้งาน" itsOff: "ปิดใช้งาน" emailRequiredForSignup: "จำเป็นต้องการใช้ที่อยู่อีเมลสำหรับการสมัคร" @@ -939,6 +947,10 @@ collapseRenotes: "ยุบ renotes ที่คุณได้เห็นแ internalServerError: "เซิร์ฟเวอร์ภายในเกิดข้อผิดพลาด" internalServerErrorDescription: "เซิร์ฟเวอร์รันค้นพบข้อผิดพลาดที่ไม่คาดคิด" copyErrorInfo: "คัดลอกรายละเอียดข้อผิดพลาด" +joinThisServer: "ลงชื่อสมัครใช้ในอินสแตนซ์นี้" +exploreOtherServers: "มองหาอินสแตนซ์อื่น" +letsLookAtTimeline: "ลองดูที่ไทม์ไลน์" +disableFederationWarn: "การดำเนินการนี้ถ้าหากจะปิดใช้งานการรวมศูนย์ แต่โพสต์ดังกล่าวนั้นจะยังคงเป็นสาธารณะต่อไป ยกเว้นแต่ว่าจะตั้งค่าเป็นอย่างอื่น โดยปกติคุณไม่จำเป็นต้องใช้การตั้งค่านี้นะ" _achievements: earnedAt: "ได้รับเมื่อ" _types: @@ -1452,6 +1464,7 @@ _ago: weeksAgo: "{n} สัปดาห์ที่แล้ว" monthsAgo: "{n} เดือนที่แล้ว" yearsAgo: "{n} ปีที่ผ่านมา" + invalid: "ไม่พบผลลัพธ์" _time: second: "วินาที" minute: "นาที" @@ -1485,13 +1498,28 @@ _tutorial: step8_3: "คุณสามารถเปลี่ยนการตั้งค่านี้ในภายหลังได้ตลอดเวลานะ" _2fa: alreadyRegistered: "คุณได้ลงทะเบียนอุปกรณ์ยืนยันตัวตนแบบ 2 ชั้นแล้ว" + registerTOTP: "ลงทะเบียนแอพตัวตรวจสอบสิทธิ์" + passwordToTOTP: "กรอกรหัสผ่าน" step1: "ขั้นตอนแรก ติดตั้งแอปยืนยันตัวตน (เช่น {a} หรือ {b}) บนอุปกรณ์ของคุณ" step2: "จากนั้นสแกนรหัส QR ที่แสดงบนหน้าจอนี้" + step2Click: "การคลิกที่รหัส QR นี้จะช่วยให้คุณนั้นสามารถลงทะเบียน 2FA กับคีย์ความปลอดภัยหรือแอปตรวจสอบความถูกต้องของโทรศัพท์ได้" step2Url: "คุณยังสามารถป้อนบน URL นี้หากคุณใช้โปรแกรมเดสก์ท็อป:" + step3Title: "ป้อนรหัสยืนยัน" step3: "ป้อนโทเค็นที่แอปของคุณให้มาเพื่อเสร็จสิ้นการตั้งค่า" step4: "นับจากนี้เป็นต้นไปการพยายามเข้าสู่ระบบในอนาคตนั้น อาจจะต้องขอโทเค็นในการเข้าสู่ระบบดังกล่าว" + securityKeyNotSupported: "เบราว์เซอร์ของคุณไม่รองรับคีย์ความปลอดภัยนะ" + registerTOTPBeforeKey: "กรุณาตั้งค่าแอปยืนยันตัวตนเพื่อลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน" securityKeyInfo: "นอกจากนี้การตรวจสอบความถูกต้องด้วยลายนิ้วมือหรือ PIN แล้ว คุณยังสามารถตั้งค่าการตรวจสอบสิทธิ์ผ่านคีย์ความปลอดภัยของฮาร์ดแวร์ที่รองรับ FIDO2 เพื่อเพิ่มความปลอดภัยให้กับบัญชีของคุณ" + chromePasskeyNotSupported: "ขณะนี้ยังไม่รองรับรหัสผ่านของ Chrome" + registerSecurityKey: "ลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน" + securityKeyName: "ป้อนชื่อคีย์" + tapSecurityKey: "กรุณาทำตามเบราว์เซอร์ของคุณเพื่อลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน" + removeKey: "ลบคีย์ความปลอดภัยออก" removeKeyConfirm: "ลบข้อมูลสำรอง {name} มั้ย?" + whyTOTPOnlyRenew: "ไม่สามารถลบแอปตัวรับรองความถูกต้องได้ตราบใดที่มีการลงทะเบียนคีย์ความปลอดภัยไว้แล้ว" + renewTOTP: "กำหนดค่าแอพตัวตรวจสอบสิทธิ์ใหม่" + renewTOTPConfirm: "วิธีการแบบนี้จะทําให้รหัสยืนยันจากแอพก่อนหน้าของคุณหยุดทํางานเลยนะ" + renewTOTPOk: "ตั้งค่าคอนฟิกใหม่" renewTOTPCancel: "ไม่เป็นไร" _permissions: "read:account": "ดูข้อมูลบัญชีของคุณ" @@ -1615,6 +1643,8 @@ _visibility: followersDescription: "ทำให้ผู้ติดตามนั้นมองเห็นแค่คุณเท่านั้น" specified: "ไดเร็ค" specifiedDescription: "ทำให้มองเห็นได้เฉพาะผู้ใช้ที่ระบุเท่านั้น" + disableFederation: "ไม่มีสหภาพ" + disableFederationDescription: "อย่าส่งไปยังอินสแตนซ์อื่น" _postForm: replyPlaceholder: "ตอบกลับโน้ตนี้..." quotePlaceholder: "อ้างโน้ตนี้..." @@ -1770,6 +1800,7 @@ _notification: pollEnded: "โพลนี้สิ้นสุดลงแล้ว" receiveFollowRequest: "ได้รับคำขอติดตาม\n" followRequestAccepted: "ยอมรับคำขอติดตาม" + achievementEarned: "ปลดล็อกความสำเร็จแล้ว" app: "การแจ้งเตือนจากแอปที่มีลิงก์" _actions: followBack: "ติดตามกลับด้วย" @@ -1802,3 +1833,6 @@ _deck: channel: "แชนแนล" mentions: "พูดถึง" direct: "ไดเร็ค" +_dialog: + charactersExceeded: "คุณกำลังมีตัวอักขระเกินขีดจำกัดสูงสุดแล้วนะ! ปัจจุบันอยู่ที่ {current} จาก {max}" + charactersBelow: "คุณกำลังใช้อักขระต่ำกว่าขีดจำกัดขั้นต่ำเลยนะ! ปัจจุบันอยู่ที่ {current} จาก {min}" diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 79ec11f42..c47ad4539 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -49,6 +49,7 @@ deleteAndEdit: "Видалити й редагувати" deleteAndEditConfirm: "Ви впевнені, що хочете видалити цю нотатку та відредагувати її? Ви втратите всі реакції, поширення та відповіді на неї." addToList: "Додати до списку" sendMessage: "Надіслати повідомлення" +copyRSS: "Скопіювати RSS" copyUsername: "Скопіювати ім’я користувача" searchUser: "Пошук користувачів" reply: "Відповісти" @@ -128,6 +129,7 @@ unblockConfirm: "Ви впевнені, що хочете розблокуват suspendConfirm: "Ви впевнені, що хочете призупинити цей акаунт?" unsuspendConfirm: "Ви впевнені, що хочете відновити цей акаунт?" selectList: "Виберіть список" +selectChannel: "Виберіть канал" selectAntenna: "Виберіть антену" selectWidget: "Виберіть віджет" editWidgets: "Редагувати віджети" @@ -255,6 +257,7 @@ noMoreHistory: "Подальшої історії немає" startMessaging: "Розпочати діалог" nUsersRead: "Прочитали {n}" agreeTo: "Я погоджуюсь з {0}" +agreeBelow: "Я погоджуюся з наведеним нижче" tos: "Умови використання" start: "Розпочати" home: "Домівка" @@ -387,6 +390,8 @@ about: "Інформація" aboutMisskey: "Про Misskey" administrator: "Адмін" token: "Токен" +2fa: "Двофакторна аутентифікація" +totp: "Програма аутентифікації" moderator: "Модератор" moderation: "Модерація" nUsersMentioned: "Згадали: {n}" @@ -445,6 +450,8 @@ aboutX: "Про {x}" disableDrawer: "Не використовувати висувні меню" noHistory: "Історія порожня" signinHistory: "Історія входів" +enableAdvancedMfm: "Увімкнути розширений MFM" +enableAnimatedMfm: "Увімкнути анімований MFM" doing: "Виконується" category: "Категорія" tags: "Теги" @@ -697,6 +704,7 @@ accentColor: "Акцент" textColor: "Текст" saveAs: "Зберегти як…" advanced: "Розширені" +advancedSettings: "Розширені налаштування" value: "Значення" createdAt: "Створено" updatedAt: "Останнє оновлення" @@ -761,6 +769,7 @@ popularPosts: "Популярні дописи" shareWithNote: "Поділитися нотаткою" ads: "Реклама" expiration: "Опитування закінчується" +startingperiod: "Початковий період" memo: "Примітка" priority: "Пріоритет" high: "Високий" @@ -879,8 +888,17 @@ like: "Вподобати" unlike: "Не вподобати" numberOfLikes: "Вподобання" show: "Відображення" +roles: "Ролі" +role: "Роль" +normalUser: "Звичайний користувач" +undefined: "Не визначено" +assign: "Призначити" +unassign: "Скасувати призначення" color: "Колір" achievements: "Досягнення" +joinThisServer: "Зареєструватися на цьому сервері" +exploreOtherServers: "Знайти інший сервер" +letsLookAtTimeline: "Перегляд історії" _achievements: earnedAt: "Відкрито" _types: @@ -1102,6 +1120,13 @@ _achievements: description: "Відправити посилання на \"Brain Diver\"" flavor: "Misskey-Misskey La-Tu-Ma" _role: + new: "Нова роль" + edit: "Змінити роль" + name: "Назва ролі" + description: "Опис ролі" + permission: "Права ролі" + assignTarget: "Призначити" + manual: "Вручну" priority: "Пріоритет" _priority: low: "Низький" @@ -1299,6 +1324,7 @@ _ago: weeksAgo: "{n} тиж. тому" monthsAgo: "{n} міс. тому" yearsAgo: "{n} р. тому" + invalid: "Тут нічого немає" _time: second: "с" minute: "х" diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index 44aed8bc3..174b1ddf1 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -1102,6 +1102,7 @@ _ago: weeksAgo: "{n} tuần trước" monthsAgo: "{n} tháng trước" yearsAgo: "{n} năm trước" + invalid: "Không có gì ở đây" _time: second: "s" minute: "phút" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 7ba895639..acc69e72e 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -393,13 +393,19 @@ about: "关于" aboutMisskey: "关于 Misskey" administrator: "管理员" token: "Token (令牌)" +2fa: "双因素认证" +totp: "身份验证应用" +totpDescription: "使用认证应用输入一次性密码。" moderator: "监察员" moderation: "管理" nUsersMentioned: "{n} 被提到" +securityKeyAndPasskey: "安全密钥/密码" securityKey: "安全密钥" lastUsed: "最后使用:" +lastUsedAt: "最后使用: {t}" unregister: "删除账户" passwordLessLogin: "无密码登录" +passwordLessLoginDescription: "不使用密码,仅使用安全密钥或Passkey登录" resetPassword: "重置密码" newPasswordIs: "新的密码是「{password}」" reduceUiAnimation: "减少UI动画" @@ -773,6 +779,7 @@ popularPosts: "热门投稿" shareWithNote: "在帖子中分享" ads: "广告" expiration: "截止时间" +startingperiod: "开始时间" memo: "便笺" priority: "优先级" high: "高" @@ -805,6 +812,7 @@ lastCommunication: "最近通信" resolved: "已解决" unresolved: "未解决" breakFollow: "移除关注者" +breakFollowConfirm: "你想取消关注吗?" itsOn: "已开启" itsOff: "已关闭" emailRequiredForSignup: "注册账户需要电子邮件地址" @@ -849,7 +857,7 @@ failedToFetchAccountInformation: "获取账户信息失败" rateLimitExceeded: "已超過速率限制" cropImage: "剪裁图像" cropImageAsk: "是否要裁剪图像?" -cropYes: "已裁剪" +cropYes: "去裁剪" cropNo: "就这样吧!" file: "文件" recentNHours: "最近{n}小时" @@ -939,6 +947,10 @@ collapseRenotes: "省略显示已经看过的转发内容" internalServerError: "内部服务器错误" internalServerErrorDescription: "内部服务器发生了预期外的错误" copyErrorInfo: "复制错误信息" +joinThisServer: "在本实例上注册" +exploreOtherServers: "探索其他实例" +letsLookAtTimeline: "时间线" +disableFederationWarn: "联合被禁用。 禁用它并不能使帖子变成私人的。 在大多数情况下,这个选项不需要被启用。" _achievements: earnedAt: "达成时间" _types: @@ -1452,6 +1464,7 @@ _ago: weeksAgo: "{n}周前" monthsAgo: "{n}月前" yearsAgo: "{n}年前" + invalid: "没有" _time: second: "秒" minute: "分" @@ -1485,13 +1498,28 @@ _tutorial: step8_3: "您也可以稍后再更改通知设置。" _2fa: alreadyRegistered: "此设备已被注册" + registerTOTP: "开始设置认证应用" + passwordToTOTP: "请输入您的密码" step1: "首先,在您的设备上安装验证应用,例如{a}或{b}。" step2: "然后,扫描屏幕上显示的二维码。" + step2Click: "通过点击QR码,您可以使用设备上安装的身份验证器应用程序或密钥环进行注册" step2Url: "在桌面应用程序中输入以下URL:" + step3Title: "输入验证码" step3: "输入您的应用提供的动态口令以完成设置。" step4: "从现在开始,任何登录操作都将要求您提供动态口令。" + securityKeyNotSupported: "您的浏览器不支持安全密钥。" + registerTOTPBeforeKey: "要注册安全密钥或Passkey,请先设置验证器应用程序。" securityKeyInfo: "您可以设置使用支持FIDO2的硬件安全密钥、设备上的指纹或PIN来保护您的登录过程。" + chromePasskeyNotSupported: "目前不支持 Chrome 的Passkey。" + registerSecurityKey: "注册安全密钥或Passkey" + securityKeyName: "输入密钥名称" + tapSecurityKey: "请按照浏览器说明操作来注册安全密钥或Passkey。" + removeKey: "删除安全密钥" removeKeyConfirm: "您确定要删除 {name} 吗?" + whyTOTPOnlyRenew: "如果注册了安全密钥,则无法取消验证器应用程序上的设置。" + renewTOTP: "重置验证器应用程序" + renewTOTPConfirm: "当前验证器应用程序的验证码将不再有效" + renewTOTPOk: "重新配置" renewTOTPCancel: "不用,谢谢" _permissions: "read:account": "查看账户信息" @@ -1615,6 +1643,8 @@ _visibility: followersDescription: "仅发送至关注者" specified: "指定用户" specifiedDescription: "仅发送至指定用户" + disableFederation: "不参与联合" + disableFederationDescription: "不发送到其他实例" _postForm: replyPlaceholder: "回复这个帖子..." quotePlaceholder: "引用这个帖子..." @@ -1770,6 +1800,7 @@ _notification: pollEnded: "问卷调查结束" receiveFollowRequest: "收到关注请求" followRequestAccepted: "关注请求已通过" + achievementEarned: "取得的成就" app: "关联应用的通知" _actions: followBack: "回关" @@ -1802,3 +1833,6 @@ _deck: channel: "频道" mentions: "提及" direct: "指定用户" +_dialog: + charactersExceeded: "已经超过了最大字符数! 当前字符数 {current} / 限制字符数 {max}" + charactersBelow: "低于最小字符数!当前字符数 {current} / 限制字符数 {min}" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 1dd2ae4ce..623e36d6e 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -46,7 +46,7 @@ copyContent: "複製內容" copyLink: "複製連結" delete: "刪除" deleteAndEdit: "刪除並編輯" -deleteAndEditConfirm: "要刪除並再次編輯嗎?此貼文的所有情感、轉發和回覆也將會消失。" +deleteAndEditConfirm: "要刪除並再次編輯嗎?此貼文的所有反應、轉發和回覆也將會消失。" addToList: "加入至清單" sendMessage: "發送訊息" copyRSS: "複製RSS" @@ -112,7 +112,7 @@ clickToShow: "按一下以顯示" sensitive: "敏感內容" add: "新增" reaction: "反應" -reactions: "情感" +reactions: "反應" reactionSetting: "在選擇器中顯示反應" reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。" rememberNoteVisibility: "記住貼文可見性" @@ -213,7 +213,7 @@ default: "預設" defaultValueIs: "預設值:{value}" noCustomEmojis: "沒有自訂的表情符號" noJobs: "沒有任務" -federating: "整合搜索中" +federating: "聯邦運作中" blocked: "已封鎖" suspended: "已凍結" all: "全部" @@ -393,13 +393,19 @@ about: "關於" aboutMisskey: "關於 Misskey" administrator: "管理員" token: "權杖" +2fa: "雙因素驗證" +totp: "驗證應用程式" +totpDescription: "以驗證應用程式輸入一次性密碼" moderator: "審查員" moderation: "審查" nUsersMentioned: "提到了{n}" +securityKeyAndPasskey: "安全金鑰・Passkey" securityKey: "安全金鑰" lastUsed: "上次使用" +lastUsedAt: "最後使用:{t}" unregister: "註銷帳號" passwordLessLogin: "設置無密碼登入" +passwordLessLoginDescription: "不使用密碼,以安全金鑰或 Passkey 登入" resetPassword: "重置密碼" newPasswordIs: "新密碼為「{password}」" reduceUiAnimation: "減少介面的動態視覺" @@ -773,6 +779,7 @@ popularPosts: "熱門的貼文" shareWithNote: "在貼文中分享" ads: "廣告" expiration: "期限" +startingperiod: "開始期間" memo: "備忘錄" priority: "優先級" high: "高" @@ -805,6 +812,7 @@ lastCommunication: "最近的通信" resolved: "已解決" unresolved: "未解決" breakFollow: "移除追蹤者" +breakFollowConfirm: "確定要取消被追隨嗎?" itsOn: "已開啟" itsOff: "已關閉" emailRequiredForSignup: "註冊帳戶需要電子郵件地址" @@ -939,6 +947,10 @@ collapseRenotes: "省略顯示已看過的轉發貼文" internalServerError: "內部伺服器錯誤" internalServerErrorDescription: "內部伺服器發生了非預期的錯誤。" copyErrorInfo: "複製錯誤資訊" +joinThisServer: "在此伺服器上註冊" +exploreOtherServers: "探索其他伺服器" +letsLookAtTimeline: "看看時間軸" +disableFederationWarn: "聯邦被停用了。即使停用也不會讓您的貼文不公開,在大多數情況下,不需要啟用這個選項。" _achievements: earnedAt: "獲得日期" _types: @@ -1083,7 +1095,7 @@ _achievements: title: "成群結隊" description: "跟隨者超過50人了" _followers100: - title: "紅人" + title: "熱門人物" description: "跟隨者超過100人了" _followers300: title: "請排成一排" @@ -1141,7 +1153,7 @@ _achievements: description: "試圖遞迴套入雲端硬碟資料夾" _reactWithoutRead: title: "有好好讀過嗎?" - description: "對包含100字以上內容的貼文做出情感反應" + description: "對包含100字以上內容的貼文在3秒以內做出反應" _clickedClickHere: title: "點擊這裡" description: "已點擊這裡了" @@ -1452,6 +1464,7 @@ _ago: weeksAgo: "{n}周前" monthsAgo: "{n}個月前" yearsAgo: "{n}年前" + invalid: "未發現" _time: second: "秒" minute: "分鐘" @@ -1485,13 +1498,28 @@ _tutorial: step8_3: "通知的設定可以在之後變更。" _2fa: alreadyRegistered: "此設備已經被註冊過了" + registerTOTP: "開始設定驗證應用程式" + passwordToTOTP: "請輸入密碼" step1: "首先,在您的設備上安裝二步驗證程式,例如{a}或{b}。" step2: "然後,掃描螢幕上的QR code。" + step2Click: "點擊QR code,可以使用設備上安裝的驗證應用程式或金鑰環進行註冊。" step2Url: "在桌面版應用中,請輸入以下的URL:" + step3Title: "輸入驗證碼" step3: "輸入您的App提供的權杖以完成設定。" step4: "從現在開始,任何登入操作都將要求您提供權杖。" + securityKeyNotSupported: "您的瀏覽器不支援安全金鑰。" + registerTOTPBeforeKey: "要註冊安全金鑰・Passkey,請先設定驗證應用程式。" securityKeyInfo: "您可以設定使用支援FIDO2的硬體安全鎖、終端設備的指纹認證或者PIN碼來登入。" + chromePasskeyNotSupported: "目前不支援Chrome的Passkey。" + registerSecurityKey: "註冊安全金鑰・Passkey" + securityKeyName: "輸入金鑰名稱" + tapSecurityKey: "按照瀏覽器的說明操作,註冊安全金鑰和Passkey。" + removeKey: "刪除安全金鑰" removeKeyConfirm: "要刪除{name}嗎?" + whyTOTPOnlyRenew: "如果註冊了安全金鑰,則無法解除驗證應用程式的設定。" + renewTOTP: "重設驗證應用程式" + renewTOTPConfirm: "目前驗證應用程式的驗證碼將無法使用。" + renewTOTPOk: "重設" renewTOTPCancel: "現在不要" _permissions: "read:account": "查看我的帳戶資訊" @@ -1564,7 +1592,7 @@ _widgets: photos: "照片" digitalClock: "電子時鐘" unixClock: "UNIX時間" - federation: "聯邦宇宙" + federation: "站台聯邦" instanceCloud: "實例雲" postForm: "發佈窗口" slideshow: "幻燈片" @@ -1615,6 +1643,8 @@ _visibility: followersDescription: "僅發送至關注者" specified: "指定使用者" specifiedDescription: "僅發送至指定使用者" + disableFederation: "停用聯邦" + disableFederationDescription: "不要傳遞給其他實例" _postForm: replyPlaceholder: "回覆此貼文..." quotePlaceholder: "引用此貼文..." @@ -1770,6 +1800,7 @@ _notification: pollEnded: "問卷調查結束" receiveFollowRequest: "已收到追隨請求" followRequestAccepted: "追隨請求已接受" + achievementEarned: "獲得成就" app: "應用程式通知" _actions: followBack: "回關" @@ -1802,3 +1833,6 @@ _deck: channel: "頻道" mentions: "提及" direct: "指定使用者" +_dialog: + charactersExceeded: "已超過最大字數!現在 {current} / 限制 {max}" + charactersBelow: "低於最少字數!現在 {current} / 限制 {max}" From 60342ed3fa40e52015a76c597c29fb4146137a03 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 11:57:37 +0900 Subject: [PATCH 05/25] enhance(client): improve user menu ux --- .../frontend/src/scripts/get-user-menu.ts | 74 ++++++++----------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/packages/frontend/src/scripts/get-user-menu.ts b/packages/frontend/src/scripts/get-user-menu.ts index 69d0ed085..6c6baf826 100644 --- a/packages/frontend/src/scripts/get-user-menu.ts +++ b/packages/frontend/src/scripts/get-user-menu.ts @@ -12,29 +12,6 @@ import { Router } from '@/nirax'; export function getUserMenu(user: misskey.entities.UserDetailed, router: Router = mainRouter) { const meId = $i ? $i.id : null; - async function pushList() { - const t = i18n.ts.selectList; // なぜか後で参照すると null になるので最初にメモリに確保しておく - const lists = await os.api('users/lists/list'); - if (lists.length === 0) { - os.alert({ - type: 'error', - text: i18n.ts.youHaveNoLists, - }); - return; - } - const { canceled, result: listId } = await os.select({ - title: t, - items: lists.map(list => ({ - value: list.id, text: list.name, - })), - }); - if (canceled) return; - os.apiWithDialog('users/lists/push', { - listId: listId, - userId: user.id, - }); - } - async function toggleMute() { if (user.isMuted) { os.apiWithDialog('mute/delete', { @@ -137,12 +114,43 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router os.post({ specified: user }); }, }, null, { + type: 'parent', icon: 'ti ti-list', text: i18n.ts.addToList, - action: pushList, + children: async () => { + const lists = await os.api('users/lists/list'); + + return lists.map(list => ({ + text: list.name, + action: () => { + os.apiWithDialog('users/lists/push', { + listId: list.id, + userId: user.id, + }); + }, + })); + }, }] as any; if ($i && meId !== user.id) { + if (iAmModerator) { + menu = menu.concat([{ + type: 'parent', + icon: 'ti ti-badges', + text: i18n.ts.roles, + children: async () => { + const roles = await os.api('admin/roles/list'); + + return roles.filter(r => r.target === 'manual').map(r => ({ + text: r.name, + action: () => { + os.apiWithDialog('admin/roles/assign', { roleId: r.id, userId: user.id }); + }, + })); + }, + }]); + } + menu = menu.concat([null, { icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off', text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute, @@ -166,24 +174,6 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router text: i18n.ts.reportAbuse, action: reportAbuse, }]); - - if (iAmModerator) { - menu = menu.concat([null, { - icon: 'ti ti-badges', - text: i18n.ts.roles, - action: async () => { - const roles = await os.api('admin/roles/list'); - - const { canceled, result: roleId } = await os.select({ - title: i18n.ts._role.chooseRoleToAssign, - items: roles.map(r => ({ text: r.name, value: r.id })), - }); - if (canceled) return; - - await os.apiWithDialog('admin/roles/assign', { roleId, userId: user.id }); - }, - }]); - } } if ($i && meId === user.id) { From 72888b4814cc97ce9853832b976cefdcc0f7ad99 Mon Sep 17 00:00:00 2001 From: Khsmty Date: Sun, 26 Feb 2023 12:25:27 +0900 Subject: [PATCH 06/25] =?UTF-8?q?enhance(client):=20photoswipe=20=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E6=99=82=E3=81=AB=E6=88=BB=E3=82=8B=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E3=82=92=E3=81=97=E3=81=A6=E3=82=82=E5=89=8D=E3=81=AE=E7=94=BB?= =?UTF-8?q?=E9=9D=A2=E3=81=AB=E6=88=BB=E3=82=89=E3=81=AA=E3=81=84=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=20(#10098)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(client): photoswipe 表示時に戻る操作をしても前の画面に戻らないように * add: changelog --------- Co-authored-by: syuilo --- CHANGELOG.md | 1 + .../frontend/src/components/MkMediaList.vue | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 489fcff2c..5ac696c28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Improvements - feat: 検索画面の統合 (Khsmty) +- photoswipe 表示時に戻る操作をしても前の画面に戻らないように ### Bugfixes - diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index a12bb78e3..fafa0bd23 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -113,6 +113,23 @@ onMounted(() => { }); lightbox.init(); + + window.addEventListener('popstate', () => { + if (lightbox.pswp && lightbox.pswp.isOpen === true) { + lightbox.pswp.close(); + return; + } + }); + + lightbox.on('beforeOpen', () => { + history.pushState(null, '', '#pswp'); + }); + + lightbox.on('close', () => { + if (window.location.hash === '#pswp') { + history.back(); + } + }); }); const previewable = (file: misskey.entities.DriveFile): boolean => { From 2acdd933c099111c9f0787b4d1aedc95ea6b93a1 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 12:50:34 +0900 Subject: [PATCH 07/25] =?UTF-8?q?enhance(client):=20=E3=83=A1=E3=83=8B?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=81=AE=E3=80=8C=E3=82=82=E3=81=A3=E3=81=A8?= =?UTF-8?q?=E3=80=8D=E3=81=8B=E3=82=89=E3=82=A4=E3=83=B3=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=83=B3=E3=82=B9=E6=83=85=E5=A0=B1=E3=82=92=E8=A6=8B=E3=82=8C?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/navbar.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/frontend/src/navbar.ts b/packages/frontend/src/navbar.ts index 48bece05f..efc0e8c92 100644 --- a/packages/frontend/src/navbar.ts +++ b/packages/frontend/src/navbar.ts @@ -1,6 +1,7 @@ import { computed, reactive } from 'vue'; import { $i } from './account'; import { miLocalStorage } from './local-storage'; +import { openInstanceMenu } from './ui/_common_/common'; import * as os from '@/os'; import { i18n } from '@/i18n'; import { ui } from '@/config'; @@ -121,6 +122,13 @@ export const navbarItemDef = reactive({ }], ev.currentTarget ?? ev.target); }, }, + about: { + title: i18n.ts.about, + icon: 'ti ti-info-circle', + action: (ev) => { + openInstanceMenu(ev); + }, + }, reload: { title: i18n.ts.reload, icon: 'ti ti-refresh', From 1bdde6bd5cd4683b7a6ed931a5b2cc5261c3da63 Mon Sep 17 00:00:00 2001 From: daima3629 <52790780+daima3629@users.noreply.github.com> Date: Sun, 26 Feb 2023 14:14:57 +0900 Subject: [PATCH 08/25] [Fix] fixed an typo in error message (#10102) --- packages/backend/src/server/api/endpoints/admin/emoji/add.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts index 8889f3026..04c58050f 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts @@ -16,7 +16,7 @@ export const meta = { errors: { noSuchFile: { message: 'No such file.', - code: 'MO_SUCH_FILE', + code: 'NO_SUCH_FILE', id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf', }, }, From 302af7099cea6f1eaeb513570dcb34d31753eb6f Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 14:17:29 +0900 Subject: [PATCH 09/25] Update codecov.yml --- codecov.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/codecov.yml b/codecov.yml index 5d8d232b5..410f064be 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,6 +1,4 @@ coverage: status: - project: - default: - only_pulls: true - if_ci_failed: success + project: false + patch: false From cedfb85b603cafbd50870cf5e0dcb861dfe20ae9 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 14:21:54 +0900 Subject: [PATCH 10/25] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ac696c28..ebc776243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,7 @@ ## 13.x.x (unreleased) ### Improvements -- feat: 検索画面の統合 (Khsmty) -- photoswipe 表示時に戻る操作をしても前の画面に戻らないように +- ### Bugfixes - @@ -21,6 +20,7 @@ You should also include the user name that made the change. - enhance(client): improve clip menu ux - 検索画面の統合 - enhance(client): ノートメニューからユーザーメニューを開けるように +- photoswipe 表示時に戻る操作をしても前の画面に戻らないように ### Bugfixes - Windows環境でswcを使うと正しくビルドできない問題の修正 From cc149e2f46024b081a2c6b695e64089eb57cfe6f Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 17:12:15 +0900 Subject: [PATCH 11/25] =?UTF-8?q?fix(server):=20=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=81=AE=E3=82=B9=E3=82=BF=E3=83=83=E3=82=AF=E3=83=88?= =?UTF-8?q?=E3=83=AC=E3=83=BC=E3=82=B9=E3=81=AF=E8=BF=94=E3=81=95=E3=81=AA?= =?UTF-8?q?=E3=81=84=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #10064 --- CHANGELOG.md | 1 + packages/backend/src/server/api/ApiCallService.ts | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebc776243..a6a90b39f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ You should also include the user name that made the change. - fix(client): Android ChromeでPWAとしてインストールできない問題を修正 - 未知のユーザーが deleteActor されたら処理をスキップする - fix(server): notes/createで、fileIdsと見つかったファイルの数が異なる場合はエラーにする +- fix(server): エラーのスタックトレースは返さないように ## 13.7.5 (2023/02/24) diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index 347fa59d3..6d8540dd4 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -2,6 +2,7 @@ import { pipeline } from 'node:stream'; import * as fs from 'node:fs'; import { promisify } from 'node:util'; import { Inject, Injectable } from '@nestjs/common'; +import { v4 as uuid } from 'uuid'; import { DI } from '@/di-symbols.js'; import { getIpHash } from '@/misc/get-ip-hash.js'; import type { LocalUser, User } from '@/models/entities/User.js'; @@ -320,6 +321,7 @@ export class ApiCallService implements OnApplicationShutdown { if (err instanceof ApiError) { throw err; } else { + const errId = uuid(); this.logger.error(`Internal error occurred in ${ep.name}: ${err.message}`, { ep: ep.name, ps: data, @@ -327,14 +329,15 @@ export class ApiCallService implements OnApplicationShutdown { message: err.message, code: err.name, stack: err.stack, + id: errId, }, }); - console.error(err); + console.error(err, errId); throw new ApiError(null, { e: { message: err.message, code: err.name, - stack: err.stack, + id: errId, }, }); } From 9234ffc927155ecc4f774dcb5d0e078b704035d3 Mon Sep 17 00:00:00 2001 From: Windymelt <1113940+windymelt@users.noreply.github.com> Date: Sun, 26 Feb 2023 18:18:23 +0900 Subject: [PATCH 12/25] =?UTF-8?q?[chore]Editorconfig:=20yml=E3=81=AB?= =?UTF-8?q?=E5=8A=A0=E3=81=88=E3=81=A6yaml=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AB=E5=AF=BE=E3=81=97=E3=81=A6=E3=82=82=E5=90=8C?= =?UTF-8?q?=E3=81=98=E8=A6=8F=E7=B4=84=E3=82=92=E9=81=A9=E7=94=A8=E3=81=99?= =?UTF-8?q?=E3=82=8B=20(#10081)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added yaml file in addition to yml file, in editorconfig * Applied editorconfig for pnpm-workspace.yaml --------- Co-authored-by: syuilo --- .editorconfig | 2 +- pnpm-workspace.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index 6db136764..a6f988f8d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,5 +7,5 @@ charset = utf-8 insert_final_newline = true end_of_line = lf -[*.yml] +[*.{yml,yaml}] indent_style = space diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 949cfb3d4..334ff382e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,4 +1,4 @@ packages: - 'packages/backend' - 'packages/frontend' - - 'packages/sw' \ No newline at end of file + - 'packages/sw' From 76f3bdcdf95a8706d7572a22f9ca70e22afea5fd Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 18:51:45 +0900 Subject: [PATCH 13/25] update deps --- package.json | 8 +- packages/backend/package.json | 18 +- packages/frontend/package.json | 27 +- pnpm-lock.yaml | 659 ++++++++++++++++++++++++--------- 4 files changed, 503 insertions(+), 209 deletions(-) diff --git a/package.json b/package.json index 8d5334433..f08272ea9 100644 --- a/package.json +++ b/package.json @@ -55,11 +55,11 @@ "devDependencies": { "@types/gulp": "4.0.10", "@types/gulp-rename": "2.0.1", - "@typescript-eslint/eslint-plugin": "5.52.0", - "@typescript-eslint/parser": "5.52.0", + "@typescript-eslint/eslint-plugin": "5.53.0", + "@typescript-eslint/parser": "5.53.0", "cross-env": "7.0.3", - "cypress": "12.6.0", - "eslint": "8.34.0", + "cypress": "12.7.0", + "eslint": "8.35.0", "start-server-and-test": "1.15.4" }, "optionalDependencies": { diff --git a/packages/backend/package.json b/packages/backend/package.json index 4d1d37eff..9fa1e68a4 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -80,7 +80,7 @@ "fluent-ffmpeg": "2.1.2", "form-data": "4.0.0", "got": "12.5.3", - "happy-dom": "^8.7.0", + "happy-dom": "8.9.0", "hpagent": "1.2.0", "ioredis": "4.28.5", "ip-cidr": "3.1.0", @@ -88,7 +88,7 @@ "js-yaml": "4.1.0", "jsdom": "21.1.0", "json5": "2.2.3", - "jsonld": "8.1.0", + "jsonld": "8.1.1", "jsrsasign": "10.6.1", "mfm-js": "0.23.3", "mime-types": "2.1.35", @@ -127,7 +127,7 @@ "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "summaly": "github:misskey-dev/summaly", - "systeminformation": "5.17.9", + "systeminformation": "5.17.10", "tinycolor2": "1.6.0", "tmp": "0.2.1", "tsc-alias": "1.8.2", @@ -156,7 +156,7 @@ "@types/color-convert": "2.0.0", "@types/content-disposition": "0.5.5", "@types/escape-regexp": "0.0.1", - "@types/fluent-ffmpeg": "2.1.20", + "@types/fluent-ffmpeg": "2.1.21", "@types/ioredis": "4.28.10", "@types/jest": "29.4.0", "@types/js-yaml": "4.0.5", @@ -164,7 +164,7 @@ "@types/jsonld": "1.5.8", "@types/jsrsasign": "10.5.5", "@types/mime-types": "2.1.1", - "@types/node": "18.14.0", + "@types/node": "18.14.1", "@types/node-fetch": "3.0.3", "@types/nodemailer": "6.4.7", "@types/oauth": "0.9.1", @@ -183,18 +183,18 @@ "@types/tinycolor2": "1.4.3", "@types/tmp": "0.2.3", "@types/unzipper": "0.10.5", - "@types/uuid": "9.0.0", + "@types/uuid": "9.0.1", "@types/vary": "1.1.0", "@types/web-push": "3.3.2", "@types/websocket": "1.0.5", "@types/ws": "8.5.4", "@typescript-eslint/eslint-plugin": "5.52.0", - "@typescript-eslint/parser": "5.52.0", + "@typescript-eslint/parser": "5.53.0", "cross-env": "7.0.3", - "eslint": "8.34.0", + "eslint": "8.35.0", "eslint-plugin-import": "2.27.5", "execa": "6.1.0", "jest": "29.4.3", "jest-mock": "29.4.3" } -} \ No newline at end of file +} diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 24f8d9b6a..e4c04f593 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -41,12 +41,12 @@ "matter-js": "0.19.0", "mfm-js": "0.23.3", "misskey-js": "0.0.15", - "photoswipe": "5.3.5", + "photoswipe": "5.3.6", "prismjs": "1.29.0", "punycode": "2.3.0", "querystring": "0.2.1", "rndstr": "1.0.0", - "rollup": "3.17.2", + "rollup": "3.17.3", "s-age": "1.1.2", "sanitize-html": "2.10.0", "sass": "1.58.3", @@ -54,7 +54,7 @@ "strict-event-emitter-types": "2.0.0", "syuilo-password-strength": "0.0.1", "textarea-caret": "3.1.0", - "three": "0.149.0", + "three": "0.150.0", "throttle-debounce": "5.0.0", "tinycolor2": "1.6.0", "tsc-alias": "1.8.2", @@ -63,7 +63,7 @@ "typescript": "4.9.5", "uuid": "9.0.0", "vanilla-tilt": "1.8.0", - "vite": "4.1.2", + "vite": "4.1.4", "vue": "3.2.47", "vue-plyr": "7.0.0", "vue-prism-editor": "2.0.0-alpha.2", @@ -71,29 +71,28 @@ }, "devDependencies": { "@types/escape-regexp": "0.0.1", - "@types/glob": "8.0.1", "@types/gulp": "4.0.10", "@types/gulp-rename": "2.0.1", "@types/matter-js": "0.18.2", - "@types/node": "18.14.0", + "@types/node": "18.14.1", "@types/punycode": "2.1.0", "@types/sanitize-html": "2.8.0", - "@types/seedrandom": "3.0.4", + "@types/seedrandom": "3.0.5", "@types/throttle-debounce": "5.0.0", "@types/tinycolor2": "1.4.3", - "@types/uuid": "9.0.0", + "@types/uuid": "9.0.1", "@types/websocket": "1.0.5", "@types/ws": "8.5.4", - "@typescript-eslint/eslint-plugin": "5.52.0", - "@typescript-eslint/parser": "5.52.0", + "@typescript-eslint/eslint-plugin": "5.53.0", + "@typescript-eslint/parser": "5.53.0", "@vue/runtime-core": "3.2.47", "cross-env": "7.0.3", - "cypress": "12.6.0", - "eslint": "8.34.0", + "cypress": "12.7.0", + "eslint": "8.35.0", "eslint-plugin-import": "2.27.5", "eslint-plugin-vue": "9.9.0", "start-server-and-test": "1.15.4", "vue-eslint-parser": "9.1.0", - "vue-tsc": "1.1.4" + "vue-tsc": "1.2.0" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6273952ea..a6d65b296 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,11 +11,11 @@ importers: '@tensorflow/tfjs-core': 4.2.0 '@types/gulp': 4.0.10 '@types/gulp-rename': 2.0.1 - '@typescript-eslint/eslint-plugin': 5.52.0 - '@typescript-eslint/parser': 5.52.0 + '@typescript-eslint/eslint-plugin': 5.53.0 + '@typescript-eslint/parser': 5.53.0 cross-env: 7.0.3 - cypress: 12.6.0 - eslint: 8.34.0 + cypress: 12.7.0 + eslint: 8.35.0 execa: 5.1.1 gulp: 4.0.2 gulp-cssnano: 2.1.3 @@ -39,11 +39,11 @@ importers: devDependencies: '@types/gulp': 4.0.10 '@types/gulp-rename': 2.0.1 - '@typescript-eslint/eslint-plugin': 5.52.0_6cfvjsbua5ptj65675bqcn6oza - '@typescript-eslint/parser': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/eslint-plugin': 5.53.0_cjo54hduev4bqhpjw5znwiokqu + '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu cross-env: 7.0.3 - cypress: 12.6.0 - eslint: 8.34.0 + cypress: 12.7.0 + eslint: 8.35.0 start-server-and-test: 1.15.4 packages/backend: @@ -90,7 +90,7 @@ importers: '@types/color-convert': 2.0.0 '@types/content-disposition': 0.5.5 '@types/escape-regexp': 0.0.1 - '@types/fluent-ffmpeg': 2.1.20 + '@types/fluent-ffmpeg': 2.1.21 '@types/ioredis': 4.28.10 '@types/jest': 29.4.0 '@types/js-yaml': 4.0.5 @@ -98,7 +98,7 @@ importers: '@types/jsonld': 1.5.8 '@types/jsrsasign': 10.5.5 '@types/mime-types': 2.1.1 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/node-fetch': 3.0.3 '@types/nodemailer': 6.4.7 '@types/oauth': 0.9.1 @@ -117,13 +117,13 @@ importers: '@types/tinycolor2': 1.4.3 '@types/tmp': 0.2.3 '@types/unzipper': 0.10.5 - '@types/uuid': 9.0.0 + '@types/uuid': 9.0.1 '@types/vary': 1.1.0 '@types/web-push': 3.3.2 '@types/websocket': 1.0.5 '@types/ws': 8.5.4 '@typescript-eslint/eslint-plugin': 5.52.0 - '@typescript-eslint/parser': 5.52.0 + '@typescript-eslint/parser': 5.53.0 accepts: 1.3.8 ajv: 8.12.0 archiver: 5.3.1 @@ -144,7 +144,7 @@ importers: date-fns: 2.29.3 deep-email-validator: 0.1.21 escape-regexp: 0.0.1 - eslint: 8.34.0 + eslint: 8.35.0 eslint-plugin-import: 2.27.5 execa: 6.1.0 fastify: 4.13.0 @@ -153,7 +153,7 @@ importers: fluent-ffmpeg: 2.1.2 form-data: 4.0.0 got: 12.5.3 - happy-dom: ^8.7.0 + happy-dom: 8.9.0 hpagent: 1.2.0 ioredis: 4.28.5 ip-cidr: 3.1.0 @@ -163,7 +163,7 @@ importers: js-yaml: 4.1.0 jsdom: 21.1.0 json5: 2.2.3 - jsonld: 8.1.0 + jsonld: 8.1.1 jsrsasign: 10.6.1 mfm-js: 0.23.3 mime-types: 2.1.35 @@ -202,7 +202,7 @@ importers: strict-event-emitter-types: 2.0.0 stringz: 2.1.0 summaly: github:misskey-dev/summaly - systeminformation: 5.17.9 + systeminformation: 5.17.10 tinycolor2: 1.6.0 tmp: 0.2.1 tsc-alias: 1.8.2 @@ -262,7 +262,7 @@ importers: fluent-ffmpeg: 2.1.2 form-data: 4.0.0 got: 12.5.3 - happy-dom: 8.7.0 + happy-dom: 8.9.0 hpagent: 1.2.0 ioredis: 4.28.5 ip-cidr: 3.1.0 @@ -270,7 +270,7 @@ importers: js-yaml: 4.1.0 jsdom: 21.1.0 json5: 2.2.3 - jsonld: 8.1.0 + jsonld: 8.1.1 jsrsasign: 10.6.1 mfm-js: 0.23.3 mime-types: 2.1.35 @@ -309,7 +309,7 @@ importers: strict-event-emitter-types: 2.0.0 stringz: 2.1.0 summaly: github.com/misskey-dev/summaly/51f3870e1ff5e0b22102e804112b10cb72f3c494 - systeminformation: 5.17.9 + systeminformation: 5.17.10 tinycolor2: 1.6.0 tmp: 0.2.1 tsc-alias: 1.8.2 @@ -351,7 +351,7 @@ importers: '@types/color-convert': 2.0.0 '@types/content-disposition': 0.5.5 '@types/escape-regexp': 0.0.1 - '@types/fluent-ffmpeg': 2.1.20 + '@types/fluent-ffmpeg': 2.1.21 '@types/ioredis': 4.28.10 '@types/jest': 29.4.0 '@types/js-yaml': 4.0.5 @@ -359,7 +359,7 @@ importers: '@types/jsonld': 1.5.8 '@types/jsrsasign': 10.5.5 '@types/mime-types': 2.1.1 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/node-fetch': 3.0.3 '@types/nodemailer': 6.4.7 '@types/oauth': 0.9.1 @@ -378,18 +378,18 @@ importers: '@types/tinycolor2': 1.4.3 '@types/tmp': 0.2.3 '@types/unzipper': 0.10.5 - '@types/uuid': 9.0.0 + '@types/uuid': 9.0.1 '@types/vary': 1.1.0 '@types/web-push': 3.3.2 '@types/websocket': 1.0.5 '@types/ws': 8.5.4 - '@typescript-eslint/eslint-plugin': 5.52.0_6cfvjsbua5ptj65675bqcn6oza - '@typescript-eslint/parser': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/eslint-plugin': 5.52.0_cjo54hduev4bqhpjw5znwiokqu + '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu cross-env: 7.0.3 - eslint: 8.34.0 - eslint-plugin-import: 2.27.5_mcvs2y73sfmcxqzpjj5lr7a2m4 + eslint: 8.35.0 + eslint-plugin-import: 2.27.5_nhka4er4oejxhxq3ecgtwxvdji execa: 6.1.0 - jest: 29.4.3_@types+node@18.14.0 + jest: 29.4.3_@types+node@18.14.1 jest-mock: 29.4.3 packages/frontend: @@ -401,21 +401,20 @@ importers: '@syuilo/aiscript': 0.12.4 '@tabler/icons-webfont': 2.2.0 '@types/escape-regexp': 0.0.1 - '@types/glob': 8.0.1 '@types/gulp': 4.0.10 '@types/gulp-rename': 2.0.1 '@types/matter-js': 0.18.2 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/punycode': 2.1.0 '@types/sanitize-html': 2.8.0 - '@types/seedrandom': 3.0.4 + '@types/seedrandom': 3.0.5 '@types/throttle-debounce': 5.0.0 '@types/tinycolor2': 1.4.3 - '@types/uuid': 9.0.0 + '@types/uuid': 9.0.1 '@types/websocket': 1.0.5 '@types/ws': 8.5.4 - '@typescript-eslint/eslint-plugin': 5.52.0 - '@typescript-eslint/parser': 5.52.0 + '@typescript-eslint/eslint-plugin': 5.53.0 + '@typescript-eslint/parser': 5.53.0 '@vitejs/plugin-vue': 4.0.0 '@vue/compiler-sfc': 3.2.47 '@vue/runtime-core': 3.2.47 @@ -433,10 +432,10 @@ importers: compare-versions: 5.0.1 cropperjs: 2.0.0-beta.2 cross-env: 7.0.3 - cypress: 12.6.0 + cypress: 12.7.0 date-fns: 2.29.3 escape-regexp: 0.0.1 - eslint: 8.34.0 + eslint: 8.35.0 eslint-plugin-import: 2.27.5 eslint-plugin-vue: 9.9.0 eventemitter3: 5.0.0 @@ -448,12 +447,12 @@ importers: matter-js: 0.19.0 mfm-js: 0.23.3 misskey-js: 0.0.15 - photoswipe: 5.3.5 + photoswipe: 5.3.6 prismjs: 1.29.0 punycode: 2.3.0 querystring: 0.2.1 rndstr: 1.0.0 - rollup: 3.17.2 + rollup: 3.17.3 s-age: 1.1.2 sanitize-html: 2.10.0 sass: 1.58.3 @@ -462,7 +461,7 @@ importers: strict-event-emitter-types: 2.0.0 syuilo-password-strength: 0.0.1 textarea-caret: 3.1.0 - three: 0.149.0 + three: 0.150.0 throttle-debounce: 5.0.0 tinycolor2: 1.6.0 tsc-alias: 1.8.2 @@ -471,21 +470,21 @@ importers: typescript: 4.9.5 uuid: 9.0.0 vanilla-tilt: 1.8.0 - vite: 4.1.2 + vite: 4.1.4 vue: 3.2.47 vue-eslint-parser: 9.1.0 vue-plyr: 7.0.0 vue-prism-editor: 2.0.0-alpha.2 - vue-tsc: 1.1.4 + vue-tsc: 1.2.0 vuedraggable: next dependencies: '@discordapp/twemoji': 14.0.2 - '@rollup/plugin-alias': 4.0.3_rollup@3.17.2 - '@rollup/plugin-json': 6.0.0_rollup@3.17.2 - '@rollup/pluginutils': 5.0.2_rollup@3.17.2 + '@rollup/plugin-alias': 4.0.3_rollup@3.17.3 + '@rollup/plugin-json': 6.0.0_rollup@3.17.3 + '@rollup/pluginutils': 5.0.2_rollup@3.17.3 '@syuilo/aiscript': 0.12.4 '@tabler/icons-webfont': 2.2.0 - '@vitejs/plugin-vue': 4.0.0_vite@4.1.2+vue@3.2.47 + '@vitejs/plugin-vue': 4.0.0_vite@4.1.4+vue@3.2.47 '@vue/compiler-sfc': 3.2.47 autobind-decorator: 2.4.0 autosize: 5.0.2 @@ -511,12 +510,12 @@ importers: matter-js: 0.19.0 mfm-js: 0.23.3 misskey-js: 0.0.15 - photoswipe: 5.3.5 + photoswipe: 5.3.6 prismjs: 1.29.0 punycode: 2.3.0 querystring: 0.2.1 rndstr: 1.0.0 - rollup: 3.17.2 + rollup: 3.17.3 s-age: 1.1.2 sanitize-html: 2.10.0 sass: 1.58.3 @@ -524,7 +523,7 @@ importers: strict-event-emitter-types: 2.0.0 syuilo-password-strength: 0.0.1 textarea-caret: 3.1.0 - three: 0.149.0 + three: 0.150.0 throttle-debounce: 5.0.0 tinycolor2: 1.6.0 tsc-alias: 1.8.2 @@ -533,37 +532,36 @@ importers: typescript: 4.9.5 uuid: 9.0.0 vanilla-tilt: 1.8.0 - vite: 4.1.2_hlkwzk2izwsolfmdrejei4vrty + vite: 4.1.4_435aevtanapkguv7m72cl6trbi vue: 3.2.47 vue-plyr: 7.0.0 vue-prism-editor: 2.0.0-alpha.2_vue@3.2.47 vuedraggable: 4.1.0_vue@3.2.47 devDependencies: '@types/escape-regexp': 0.0.1 - '@types/glob': 8.0.1 '@types/gulp': 4.0.10 '@types/gulp-rename': 2.0.1 '@types/matter-js': 0.18.2 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/punycode': 2.1.0 '@types/sanitize-html': 2.8.0 - '@types/seedrandom': 3.0.4 + '@types/seedrandom': 3.0.5 '@types/throttle-debounce': 5.0.0 '@types/tinycolor2': 1.4.3 - '@types/uuid': 9.0.0 + '@types/uuid': 9.0.1 '@types/websocket': 1.0.5 '@types/ws': 8.5.4 - '@typescript-eslint/eslint-plugin': 5.52.0_6cfvjsbua5ptj65675bqcn6oza - '@typescript-eslint/parser': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/eslint-plugin': 5.53.0_cjo54hduev4bqhpjw5znwiokqu + '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu '@vue/runtime-core': 3.2.47 cross-env: 7.0.3 - cypress: 12.6.0 - eslint: 8.34.0 - eslint-plugin-import: 2.27.5_mcvs2y73sfmcxqzpjj5lr7a2m4 - eslint-plugin-vue: 9.9.0_eslint@8.34.0 + cypress: 12.7.0 + eslint: 8.35.0 + eslint-plugin-import: 2.27.5_nhka4er4oejxhxq3ecgtwxvdji + eslint-plugin-vue: 9.9.0_eslint@8.35.0 start-server-and-test: 1.15.4 - vue-eslint-parser: 9.1.0_eslint@8.34.0 - vue-tsc: 1.1.4_typescript@4.9.5 + vue-eslint-parser: 9.1.0_eslint@8.35.0 + vue-tsc: 1.2.0_typescript@4.9.5 packages/sw: specifiers: @@ -1319,6 +1317,28 @@ packages: - supports-color dev: true + /@eslint/eslintrc/2.0.0: + resolution: {integrity: sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.4.1 + globals: 13.19.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js/8.35.0: + resolution: {integrity: sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@fastify/accept-negotiator/1.0.0: resolution: {integrity: sha512-4R/N2KfYeld7A5LGkai+iUFMahXcxxYbDp+XS2B1yuL3cdmZLJ9TlCnNzT3q5xFTqsYm0GPpinLUwfSwjcVjyA==} engines: {node: '>=14'} @@ -1496,7 +1516,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 chalk: 4.1.2 jest-message-util: 29.4.3 jest-util: 29.4.3 @@ -1517,14 +1537,14 @@ packages: '@jest/test-result': 29.4.3 '@jest/transform': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.1 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.4.3 - jest-config: 29.4.3_@types+node@18.14.0 + jest-config: 29.4.3_@types+node@18.14.1 jest-haste-map: 29.4.3 jest-message-util: 29.4.3 jest-regex-util: 29.4.3 @@ -1558,7 +1578,7 @@ packages: dependencies: '@jest/fake-timers': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 jest-mock: 29.4.3 dev: true @@ -1592,7 +1612,7 @@ packages: dependencies: '@jest/types': 29.4.3 '@sinonjs/fake-timers': 10.0.2 - '@types/node': 18.14.0 + '@types/node': 18.14.1 jest-message-util: 29.4.3 jest-mock: 29.4.3 jest-util: 29.4.3 @@ -1625,7 +1645,7 @@ packages: '@jest/transform': 29.4.3 '@jest/types': 29.4.3 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.14.0 + '@types/node': 18.14.1 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -1719,7 +1739,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/yargs': 16.0.5 chalk: 4.1.2 dev: true @@ -1731,7 +1751,7 @@ packages: '@jest/schemas': 29.4.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/yargs': 17.0.19 chalk: 4.1.2 dev: true @@ -2084,7 +2104,7 @@ packages: - encoding dev: true - /@rollup/plugin-alias/4.0.3_rollup@3.17.2: + /@rollup/plugin-alias/4.0.3_rollup@3.17.3: resolution: {integrity: sha512-ZuDWE1q4PQDhvm/zc5Prun8sBpLJy41DMptYrS6MhAy9s9kL/doN1613BWfEchGVfKxzliJ3BjbOPizXX38DbQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2093,11 +2113,11 @@ packages: rollup: optional: true dependencies: - rollup: 3.17.2 + rollup: 3.17.3 slash: 4.0.0 dev: false - /@rollup/plugin-json/6.0.0_rollup@3.17.2: + /@rollup/plugin-json/6.0.0_rollup@3.17.3: resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2106,11 +2126,11 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.17.2 - rollup: 3.17.2 + '@rollup/pluginutils': 5.0.2_rollup@3.17.3 + rollup: 3.17.3 dev: false - /@rollup/pluginutils/5.0.2_rollup@3.17.2: + /@rollup/pluginutils/5.0.2_rollup@3.17.3: resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2122,7 +2142,7 @@ packages: '@types/estree': 1.0.0 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 3.17.2 + rollup: 3.17.3 dev: false /@sideway/address/4.1.4: @@ -2468,7 +2488,7 @@ packages: /@types/accepts/1.3.5: resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/archiver/5.3.1: @@ -2523,7 +2543,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/responselike': 1.0.0 dev: false @@ -2562,37 +2582,37 @@ packages: /@types/expect/1.20.4: resolution: {integrity: sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==} - /@types/fluent-ffmpeg/2.1.20: - resolution: {integrity: sha512-B+OvhCdJ3LgEq2PhvWNOiB/EfwnXLElfMCgc4Z1K5zXgSfo9I6uGKwR/lqmNPFQuebNnes7re3gqkV77SyypLg==} + /@types/fluent-ffmpeg/2.1.21: + resolution: {integrity: sha512-+n3dy/Tegt6n+YwGZUiGq6i8Jrnt8+MoyPiW1L6J5EWUl7GSt18a/VyReecfCsvTTNBXNMIKOMHDstiQM8nJLA==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/glob-stream/6.1.1: resolution: {integrity: sha512-AGOUTsTdbPkRS0qDeyeS+6KypmfVpbT5j23SN8UPG63qjKXNKjXn6V9wZUr8Fin0m9l8oGYaPK8b2WUMF8xI1A==} dependencies: '@types/glob': 8.0.1 - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/glob/8.0.0: resolution: {integrity: sha512-l6NQsDDyQUVeoTynNpC9uRvCUint/gSUXQA2euwmTuWGvPY5LSDUu6tkCtJB2SvGQlJQzLaKqcGZP4//7EDveA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/glob/8.0.1: resolution: {integrity: sha512-8bVUjXZvJacUFkJXHdyZ9iH1Eaj5V7I8c4NdH5sQJsdXkqT4CA5Dhb4yb4VE/3asyx4L9ayZr1NIhTsWHczmMw==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/graceful-fs/4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/gulp-rename/2.0.1: @@ -2617,7 +2637,7 @@ packages: /@types/ioredis/4.28.10: resolution: {integrity: sha512-69LyhUgrXdgcNDv7ogs1qXZomnfOEnSmrmMFqKgt1XMJxmoOSG/u3wYy13yACIfKuMJ8IhKgHafDO3sx19zVQQ==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/istanbul-lib-coverage/2.0.4: @@ -2650,7 +2670,7 @@ packages: /@types/jsdom/21.1.0: resolution: {integrity: sha512-leWreJOdnuIxq9Y70tBVm/bvTuh31DSlF/r4l7Cfi4uhVQqLHD0Q4v301GMisEMwwbMgF7ZKxuZ+Jbd4NcdmRw==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/tough-cookie': 4.0.2 parse5: 7.1.2 dev: true @@ -2674,7 +2694,7 @@ packages: /@types/keyv/3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: false /@types/long/4.0.2: @@ -2696,7 +2716,7 @@ packages: /@types/node-fetch/2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 form-data: 3.0.1 dev: false @@ -2713,19 +2733,19 @@ packages: /@types/node/18.11.18: resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} - /@types/node/18.14.0: - resolution: {integrity: sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==} + /@types/node/18.14.1: + resolution: {integrity: sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==} /@types/nodemailer/6.4.7: resolution: {integrity: sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/oauth/0.9.1: resolution: {integrity: sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/offscreencanvas/2019.3.0: @@ -2739,7 +2759,7 @@ packages: /@types/pg/8.6.6: resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 pg-protocol: 1.5.0 pg-types: 2.2.0 dev: true @@ -2759,7 +2779,7 @@ packages: /@types/qrcode/1.5.0: resolution: {integrity: sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/random-seed/0.3.3: @@ -2783,7 +2803,7 @@ packages: /@types/responselike/1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: false /@types/sanitize-html/2.8.0: @@ -2796,8 +2816,8 @@ packages: resolution: {integrity: sha512-AnxLHewubLVzoF/A4qdxBGHCKifw8cY32iro3DQX9TPcetE95zBeVt3jnsvtvAUf1vwzMfwzp4t/L2yqPlnjkQ==} dev: false - /@types/seedrandom/3.0.4: - resolution: {integrity: sha512-/rWdxeiuZenlawrHU+XV6ZHMTKOqrC2hMfeDfLTIWJhDZP5aVqXRysduYHBbhD7CeJO6FJr/D2uBVXB7GT6v7w==} + /@types/seedrandom/3.0.5: + resolution: {integrity: sha512-kopEpYpFQvQdYsZkZVwht/0THHmTFFYXDaqV/lM45eweJ8kcGVDgZHs0RVTolSq55UPZNmjhKc9r7UvLu/mQQg==} dev: true /@types/semver/7.3.13: @@ -2811,7 +2831,7 @@ packages: /@types/sharp/0.31.1: resolution: {integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/sinonjs__fake-timers/8.1.1: @@ -2853,7 +2873,7 @@ packages: /@types/undertaker/1.2.8: resolution: {integrity: sha512-gW3PRqCHYpo45XFQHJBhch7L6hytPsIe0QeLujlnFsjHPnXLhJcPdN6a9368d7aIQgH2I/dUTPFBlGeSNA3qOg==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/undertaker-registry': 1.0.1 async-done: 1.3.2 dev: true @@ -2861,24 +2881,24 @@ packages: /@types/unzipper/0.10.5: resolution: {integrity: sha512-NrLJb29AdnBARpg9S/4ktfPEisbJ0AvaaAr3j7Q1tg8AgcEUsq2HqbNzvgLRoWyRtjzeLEv7vuL39u1mrNIyNA==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true - /@types/uuid/9.0.0: - resolution: {integrity: sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==} + /@types/uuid/9.0.1: + resolution: {integrity: sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==} dev: true /@types/vary/1.1.0: resolution: {integrity: sha512-LQWqrIa0dvEOOH37lGksMEXbypRLUFqu6Gx0pmX7zIUisD2I/qaVgEX/vJ/PSVSW0Hk6yz1BNkFpqg6dZm3Wug==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/vinyl-fs/2.4.12: resolution: {integrity: sha512-LgBpYIWuuGsihnlF+OOWWz4ovwCYlT03gd3DuLwex50cYZLmX3yrW+sFF9ndtmh7zcZpS6Ri47PrIu+fV+sbXw==} dependencies: '@types/glob-stream': 6.1.1 - '@types/node': 18.14.0 + '@types/node': 18.14.1 '@types/vinyl': 2.0.7 dev: true @@ -2886,12 +2906,12 @@ packages: resolution: {integrity: sha512-4UqPv+2567NhMQuMLdKAyK4yzrfCqwaTt6bLhHEs8PFcxbHILsrxaY63n4wgE/BRLDWDQeI+WcTmkXKExh9hQg==} dependencies: '@types/expect': 1.20.4 - '@types/node': 18.14.0 + '@types/node': 18.14.1 /@types/web-push/3.3.2: resolution: {integrity: sha512-JxWGVL/m7mWTIg4mRYO+A6s0jPmBkr4iJr39DqJpRJAc+jrPiEe1/asmkwerzRon8ZZDxaZJpsxpv0Z18Wo9gw==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/webgl-ext/0.0.30: @@ -2901,13 +2921,13 @@ packages: /@types/websocket/1.0.5: resolution: {integrity: sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/ws/8.5.4: resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true /@types/yargs-parser/21.0.0: @@ -2930,11 +2950,11 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 dev: true optional: true - /@typescript-eslint/eslint-plugin/5.52.0_6cfvjsbua5ptj65675bqcn6oza: + /@typescript-eslint/eslint-plugin/5.52.0_cjo54hduev4bqhpjw5znwiokqu: resolution: {integrity: sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2945,12 +2965,40 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu '@typescript-eslint/scope-manager': 5.52.0 - '@typescript-eslint/type-utils': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm - '@typescript-eslint/utils': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/type-utils': 5.52.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/utils': 5.52.0_ycpbpc6yetojsgtrx3mwntkhsu debug: 4.3.4 - eslint: 8.34.0 + eslint: 8.35.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + natural-compare-lite: 1.4.0 + regexpp: 3.2.0 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.5 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/eslint-plugin/5.53.0_cjo54hduev4bqhpjw5znwiokqu: + resolution: {integrity: sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/scope-manager': 5.53.0 + '@typescript-eslint/type-utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + debug: 4.3.4 + eslint: 8.35.0 grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 @@ -2982,6 +3030,26 @@ packages: - supports-color dev: true + /@typescript-eslint/parser/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu: + resolution: {integrity: sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.53.0 + '@typescript-eslint/types': 5.53.0 + '@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5 + debug: 4.3.4 + eslint: 8.35.0 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/scope-manager/5.52.0: resolution: {integrity: sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2990,7 +3058,15 @@ packages: '@typescript-eslint/visitor-keys': 5.52.0 dev: true - /@typescript-eslint/type-utils/5.52.0_7kw3g6rralp5ps6mg3uyzz6azm: + /@typescript-eslint/scope-manager/5.53.0: + resolution: {integrity: sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.53.0 + '@typescript-eslint/visitor-keys': 5.53.0 + dev: true + + /@typescript-eslint/type-utils/5.52.0_ycpbpc6yetojsgtrx3mwntkhsu: resolution: {integrity: sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -3001,9 +3077,29 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 5.52.0_typescript@4.9.5 - '@typescript-eslint/utils': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/utils': 5.52.0_ycpbpc6yetojsgtrx3mwntkhsu debug: 4.3.4 - eslint: 8.34.0 + eslint: 8.35.0 + tsutils: 3.21.0_typescript@4.9.5 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/type-utils/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu: + resolution: {integrity: sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5 + '@typescript-eslint/utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + debug: 4.3.4 + eslint: 8.35.0 tsutils: 3.21.0_typescript@4.9.5 typescript: 4.9.5 transitivePeerDependencies: @@ -3015,6 +3111,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/types/5.53.0: + resolution: {integrity: sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@typescript-eslint/typescript-estree/5.52.0_typescript@4.9.5: resolution: {integrity: sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3036,7 +3137,28 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.52.0_7kw3g6rralp5ps6mg3uyzz6azm: + /@typescript-eslint/typescript-estree/5.53.0_typescript@4.9.5: + resolution: {integrity: sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.53.0 + '@typescript-eslint/visitor-keys': 5.53.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.5 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.52.0_ycpbpc6yetojsgtrx3mwntkhsu: resolution: {integrity: sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -3047,9 +3169,29 @@ packages: '@typescript-eslint/scope-manager': 5.52.0 '@typescript-eslint/types': 5.52.0 '@typescript-eslint/typescript-estree': 5.52.0_typescript@4.9.5 - eslint: 8.34.0 + eslint: 8.35.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.34.0 + eslint-utils: 3.0.0_eslint@8.35.0 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/utils/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu: + resolution: {integrity: sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@types/semver': 7.3.13 + '@typescript-eslint/scope-manager': 5.53.0 + '@typescript-eslint/types': 5.53.0 + '@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5 + eslint: 8.35.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.35.0 semver: 7.3.8 transitivePeerDependencies: - supports-color @@ -3064,40 +3206,48 @@ packages: eslint-visitor-keys: 3.3.0 dev: true - /@vitejs/plugin-vue/4.0.0_vite@4.1.2+vue@3.2.47: + /@typescript-eslint/visitor-keys/5.53.0: + resolution: {integrity: sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.53.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /@vitejs/plugin-vue/4.0.0_vite@4.1.4+vue@3.2.47: resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.0.0 vue: ^3.2.25 dependencies: - vite: 4.1.2_hlkwzk2izwsolfmdrejei4vrty + vite: 4.1.4_435aevtanapkguv7m72cl6trbi vue: 3.2.47 dev: false - /@volar/language-core/1.2.0-alpha.16: - resolution: {integrity: sha512-aIktWe9Zg0M+u/RIXHCuL+IoLRHTrpsbTib8olrg4etlurHDXahoVhoEnH9wmlliray0iigIo2z5vwueYInp3g==} + /@volar/language-core/1.3.0-alpha.0: + resolution: {integrity: sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==} dependencies: - '@volar/source-map': 1.2.0-alpha.16 + '@volar/source-map': 1.3.0-alpha.0 dev: true - /@volar/source-map/1.2.0-alpha.16: - resolution: {integrity: sha512-/AK3VqnFqONd221COI2ZnEvfgBulfoQkjA/ZjPOXpsOkWri99TLcfZY/NTQRytp7Hx6EP/1p1DDeyGuMCUYjgA==} + /@volar/source-map/1.3.0-alpha.0: + resolution: {integrity: sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==} dependencies: muggle-string: 0.2.2 dev: true - /@volar/typescript/1.2.0-alpha.16: - resolution: {integrity: sha512-ltlTLHIkLxgmTVBZmOnhmnlNzEj2lpvlBmmaV2GWYTrBUMt0z1OgeCq0Utlj9HjjrGPhwWxZNkv86ZABgrMA3Q==} + /@volar/typescript/1.3.0-alpha.0: + resolution: {integrity: sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==} dependencies: - '@volar/language-core': 1.2.0-alpha.16 + '@volar/language-core': 1.3.0-alpha.0 dev: true - /@volar/vue-language-core/1.1.4: - resolution: {integrity: sha512-2C2CwHvaT5AzNzDbYZQ85lNr4jACZARoZMZBLuU5+JyIwhWeAfxvyAeoE3VbgfgycN5t6X4uBqx/Wzh1QLgD8Q==} + /@volar/vue-language-core/1.2.0: + resolution: {integrity: sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==} dependencies: - '@volar/language-core': 1.2.0-alpha.16 - '@volar/source-map': 1.2.0-alpha.16 + '@volar/language-core': 1.3.0-alpha.0 + '@volar/source-map': 1.3.0-alpha.0 '@vue/compiler-dom': 3.2.47 '@vue/compiler-sfc': 3.2.47 '@vue/reactivity': 3.2.47 @@ -3107,11 +3257,11 @@ packages: vue-template-compiler: 2.7.14 dev: true - /@volar/vue-typescript/1.1.4: - resolution: {integrity: sha512-x5i5TUUXb1PM0rM80Y8XUeMBUcoS3/TjR3WTxvvEUIol9uEOPp6uxxQQ67uSv7ocN6vB0LugJqS6FA7Z93oL0Q==} + /@volar/vue-typescript/1.2.0: + resolution: {integrity: sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==} dependencies: - '@volar/typescript': 1.2.0-alpha.16 - '@volar/vue-language-core': 1.1.4 + '@volar/typescript': 1.3.0-alpha.0 + '@volar/vue-language-core': 1.2.0 dev: true /@vue/compiler-core/3.2.47: @@ -3251,11 +3401,13 @@ packages: /acorn/7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} + hasBin: true dev: false /acorn/8.8.1: resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} engines: {node: '>=0.4.0'} + hasBin: true /adm-zip/0.5.10: resolution: {integrity: sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==} @@ -4920,9 +5072,10 @@ packages: uniq: 1.0.1 dev: false - /cypress/12.6.0: - resolution: {integrity: sha512-WdHSVaS1lumSd5XpVTslZd8ui9GIGphrzvXq9+3DtVhqjRZC5M70gu5SW/Y/SLPq3D1wiXGZoHC6HJ7ESVE2lw==} + /cypress/12.7.0: + resolution: {integrity: sha512-7rq+nmhzz0u6yabCFyPtADU2OOrYt6pvUau9qV7xyifJ/hnsaw/vkr0tnLlcuuQKUAOC1v1M1e4Z0zG7S0IAvA==} engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0} + hasBin: true requiresBuild: true dependencies: '@cypress/request': 2.88.11 @@ -5687,6 +5840,7 @@ packages: /esbuild/0.16.17: resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} engines: {node: '>=12'} + hasBin: true requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.16.17 @@ -5765,6 +5919,35 @@ packages: - supports-color dev: true + /eslint-module-utils/2.7.4_bchzgevzrq32s4jgdbchl2wqu4: + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + debug: 3.2.7 + eslint: 8.35.0 + eslint-import-resolver-node: 0.3.7 + transitivePeerDependencies: + - supports-color + dev: true + /eslint-module-utils/2.7.4_npjqex3ey3rgd34fjcuucz7la4: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} @@ -5827,19 +6010,52 @@ packages: - supports-color dev: true - /eslint-plugin-vue/9.9.0_eslint@8.34.0: + /eslint-plugin-import/2.27.5_nhka4er4oejxhxq3ecgtwxvdji: + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.35.0 + eslint-import-resolver-node: 0.3.7 + eslint-module-utils: 2.7.4_bchzgevzrq32s4jgdbchl2wqu4 + has: 1.0.3 + is-core-module: 2.11.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.1 + semver: 6.3.0 + tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-vue/9.9.0_eslint@8.35.0: resolution: {integrity: sha512-YbubS7eK0J7DCf0U2LxvVP7LMfs6rC6UltihIgval3azO3gyDwEGVgsCMe1TmDiEkl6GdMKfRpaME6QxIYtzDQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 dependencies: - eslint: 8.34.0 - eslint-utils: 3.0.0_eslint@8.34.0 + eslint: 8.35.0 + eslint-utils: 3.0.0_eslint@8.35.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.0.11 semver: 7.3.8 - vue-eslint-parser: 9.1.0_eslint@8.34.0 + vue-eslint-parser: 9.1.0_eslint@8.35.0 xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -5871,6 +6087,16 @@ packages: eslint-visitor-keys: 2.1.0 dev: true + /eslint-utils/3.0.0_eslint@8.35.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.35.0 + eslint-visitor-keys: 2.1.0 + dev: true + /eslint-visitor-keys/2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} @@ -5928,6 +6154,55 @@ packages: - supports-color dev: true + /eslint/8.35.0: + resolution: {integrity: sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint/eslintrc': 2.0.0 + '@eslint/js': 8.35.0 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.35.0 + eslint-visitor-keys: 3.3.0 + espree: 9.4.1 + esquery: 1.4.2 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.19.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.2.0 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + regexpp: 3.2.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + /espree/9.4.1: resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5953,6 +6228,13 @@ packages: estraverse: 5.3.0 dev: true + /esquery/1.4.2: + resolution: {integrity: sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + /esrecurse/4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -6190,6 +6472,7 @@ packages: /extract-zip/2.0.1_supports-color@8.1.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} + hasBin: true dependencies: debug: 4.3.4_supports-color@8.1.1 get-stream: 5.2.0 @@ -7081,11 +7364,12 @@ packages: engines: {node: '>=0.8.0'} dev: false - /happy-dom/8.7.0: - resolution: {integrity: sha512-F/mH5l8aQwlfeByB0nU6Lg7a0FBax/nPCYNYg8tn/abdKCmiIJH+gU/5MVysf5XoM6KjJsvkbIaXAmS/8HxXLA==} + /happy-dom/8.9.0: + resolution: {integrity: sha512-JZwJuGdR7ko8L61136YzmrLv7LgTh5b8XaEM3P709mLjyQuXJ3zHTDXvUtBBahRjGlcYW0zGjIiEWizoTUGKfA==} dependencies: css.escape: 1.5.1 he: 1.2.0 + iconv-lite: 0.6.3 node-fetch: 2.6.7 webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 @@ -7194,6 +7478,7 @@ packages: /he/1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true /hexoid/1.0.0: resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} @@ -7618,6 +7903,7 @@ packages: /is-ci/3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true dependencies: ci-info: 3.7.1 dev: true @@ -8030,7 +8316,7 @@ packages: '@jest/expect': 29.4.3 '@jest/test-result': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -8049,7 +8335,7 @@ packages: - supports-color dev: true - /jest-cli/29.4.3_@types+node@18.14.0: + /jest-cli/29.4.3_@types+node@18.14.1: resolution: {integrity: sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -8066,7 +8352,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 29.4.3_@types+node@18.14.0 + jest-config: 29.4.3_@types+node@18.14.1 jest-util: 29.4.3 jest-validate: 29.4.3 prompts: 2.4.2 @@ -8077,7 +8363,7 @@ packages: - ts-node dev: true - /jest-config/29.4.3_@types+node@18.14.0: + /jest-config/29.4.3_@types+node@18.14.1: resolution: {integrity: sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -8092,7 +8378,7 @@ packages: '@babel/core': 7.20.12 '@jest/test-sequencer': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 babel-jest: 29.4.3_@babel+core@7.20.12 chalk: 4.1.2 ci-info: 3.7.1 @@ -8161,7 +8447,7 @@ packages: '@jest/environment': 29.4.3 '@jest/fake-timers': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 jest-mock: 29.4.3 jest-util: 29.4.3 dev: true @@ -8187,7 +8473,7 @@ packages: dependencies: '@jest/types': 29.4.3 '@types/graceful-fs': 4.1.6 - '@types/node': 18.14.0 + '@types/node': 18.14.1 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -8263,7 +8549,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 jest-util: 29.4.3 dev: true @@ -8318,7 +8604,7 @@ packages: '@jest/test-result': 29.4.3 '@jest/transform': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -8349,7 +8635,7 @@ packages: '@jest/test-result': 29.4.3 '@jest/transform': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -8405,7 +8691,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 chalk: 4.1.2 ci-info: 3.7.1 graceful-fs: 4.2.10 @@ -8417,7 +8703,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 chalk: 4.1.2 ci-info: 3.7.1 graceful-fs: 4.2.10 @@ -8442,7 +8728,7 @@ packages: dependencies: '@jest/test-result': 29.4.3 '@jest/types': 29.4.3 - '@types/node': 18.14.0 + '@types/node': 18.14.1 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -8454,13 +8740,13 @@ packages: resolution: {integrity: sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 jest-util: 29.4.3 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest/29.4.3_@types+node@18.14.0: + /jest/29.4.3_@types+node@18.14.1: resolution: {integrity: sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -8473,7 +8759,7 @@ packages: '@jest/core': 29.4.3 '@jest/types': 29.4.3 import-local: 3.1.0 - jest-cli: 29.4.3_@types+node@18.14.0 + jest-cli: 29.4.3_@types+node@18.14.1 transitivePeerDependencies: - '@types/node' - supports-color @@ -8526,6 +8812,7 @@ packages: /js-yaml/3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true dependencies: argparse: 1.0.10 esprima: 4.0.1 @@ -8533,6 +8820,7 @@ packages: /js-yaml/3.7.0: resolution: {integrity: sha512-eIlkGty7HGmntbV6P/ZlAsoncFLGsNoM27lkTzS+oneY/EiNhj+geqD9ezg/ip+SW6Var0BJU2JtV0vEUZpWVQ==} + hasBin: true dependencies: argparse: 1.0.10 esprima: 2.7.3 @@ -8660,8 +8948,8 @@ packages: graceful-fs: 4.2.10 dev: true - /jsonld/8.1.0: - resolution: {integrity: sha512-6tYhiEVYO3rTcoYCGCArw8SqawuW0hf/cqmaE5WbX44CGb7d8N2UFvmUj9OYkJhChD98bfdPljUj7S39MrzsHg==} + /jsonld/8.1.1: + resolution: {integrity: sha512-TbtV1hlnoDYxbscazbxcS7seDGV+pc0yktxpMySh0OBFvnLw/TIth0jiQtP/9r+ywuCbtj10XjDNBIkRgiyeUg==} engines: {node: '>=14'} dependencies: '@digitalbazaar/http-client': 3.2.0 @@ -9394,6 +9682,7 @@ packages: /nanoid/3.3.4: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true /nanomatch/1.2.13: resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} @@ -10186,8 +10475,8 @@ packages: split2: 4.1.0 dev: false - /photoswipe/5.3.5: - resolution: {integrity: sha512-90JeebKBhjz1co9goGJ4vjDK84YhGKbLO8J/aKcoWS/OGddVZB77ONIs7igUKa0IB1HozTs0BiS184wzZCghMw==} + /photoswipe/5.3.6: + resolution: {integrity: sha512-v7e8iMfaPUujTACYsK5HBCCtFoW9n2dMZmjIlbvFS2oSpTQmPrfc3PrWnGx8OGY3jNOKho8JC8L277+m+9ag9Q==} engines: {node: '>= 0.12.0'} dev: false @@ -11356,9 +11645,10 @@ packages: seedrandom: 2.4.2 dev: false - /rollup/3.17.2: - resolution: {integrity: sha512-qMNZdlQPCkWodrAZ3qnJtvCAl4vpQ8q77uEujVCCbC/6CLB7Lcmvjq7HyiOSnf4fxTT9XgsE36oLHJBH49xjqA==} + /rollup/3.17.3: + resolution: {integrity: sha512-p5LaCXiiOL/wrOkj8djsIDFmyU9ysUxcyW+EKRLHb6TKldJzXpImjcRSR+vgo09DBdofGcOoLOsRyxxG2n5/qQ==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true optionalDependencies: fsevents: 2.3.2 dev: false @@ -11491,6 +11781,7 @@ packages: /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true dev: false /semver/6.3.0: @@ -12110,10 +12401,11 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: false - /systeminformation/5.17.9: - resolution: {integrity: sha512-inxwRLI/4qpx4o85R54/zdhNagdBGBgs0la7Vl3qBorRVKRDk0nNsDTCGzG4lOITsw1gl7LRWeG4Zsp1pC8nfg==} + /systeminformation/5.17.10: + resolution: {integrity: sha512-FUm264baeDpruTw4P50BRRmYHD39D3jkOQ0VpNIkp8CdNejQbsp4Me18jacGBc/mWSVxKdQw4wSHmcL7ERxrNg==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true dev: false /syuilo-password-strength/0.0.1: @@ -12221,8 +12513,8 @@ packages: real-require: 0.2.0 dev: false - /three/0.149.0: - resolution: {integrity: sha512-tohpUxPDht0qExRLDTM8sjRLc5d9STURNrdnK3w9A+V4pxaTBfKWWT/IqtiLfg23Vfc3Z+ImNfvRw1/0CtxrkQ==} + /three/0.150.0: + resolution: {integrity: sha512-12oqqBZom9fb5HtX3rD8qPVnamojuiN5Os7r0x8s3HQ+WHRwnEyzl2XU3aEKocsDkG++rkE9+HWzx77O59NXtw==} dev: false /throttle-debounce/5.0.0: @@ -12796,6 +13088,8 @@ packages: /uuid/3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true dev: false /uuid/8.0.0: @@ -12804,6 +13098,7 @@ packages: /uuid/8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true /uuid/9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} @@ -12912,8 +13207,8 @@ packages: replace-ext: 1.0.1 dev: false - /vite/4.1.2_hlkwzk2izwsolfmdrejei4vrty: - resolution: {integrity: sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==} + /vite/4.1.4_435aevtanapkguv7m72cl6trbi: + resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -12937,11 +13232,11 @@ packages: terser: optional: true dependencies: - '@types/node': 18.14.0 + '@types/node': 18.14.1 esbuild: 0.16.17 postcss: 8.4.21 resolve: 1.22.1 - rollup: 3.17.2 + rollup: 3.17.3 sass: 1.58.3 optionalDependencies: fsevents: 2.3.2 @@ -12952,14 +13247,14 @@ packages: engines: {node: '>=0.10.0'} dev: false - /vue-eslint-parser/9.1.0_eslint@8.34.0: + /vue-eslint-parser/9.1.0_eslint@8.35.0: resolution: {integrity: sha512-NGn/iQy8/Wb7RrRa4aRkokyCZfOUWk19OP5HP6JEozQFX5AoS/t+Z0ZN7FY4LlmWc4FNI922V7cvX28zctN8dQ==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.3.4 - eslint: 8.34.0 + eslint: 8.35.0 eslint-scope: 7.1.1 eslint-visitor-keys: 3.3.0 espree: 9.4.1 @@ -12993,14 +13288,14 @@ packages: he: 1.2.0 dev: true - /vue-tsc/1.1.4_typescript@4.9.5: - resolution: {integrity: sha512-CMG8KZsBBPyulYie05XxJCfq/yAPiB/uMMeHmog09aLm2Kml82C6tUSRgQz8ujM4JoCrpDqVCd9G0NuM9aLt1g==} + /vue-tsc/1.2.0_typescript@4.9.5: + resolution: {integrity: sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==} hasBin: true peerDependencies: typescript: '*' dependencies: - '@volar/vue-language-core': 1.1.4 - '@volar/vue-typescript': 1.1.4 + '@volar/vue-language-core': 1.2.0 + '@volar/vue-typescript': 1.2.0 typescript: 4.9.5 dev: true From 67ca7ee4ec8121ec84fa652104749e394896d35e Mon Sep 17 00:00:00 2001 From: xianon Date: Sun, 26 Feb 2023 18:54:52 +0900 Subject: [PATCH 14/25] =?UTF-8?q?=E3=83=9B=E3=83=BC=E3=83=A0=E3=82=BF?= =?UTF-8?q?=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E3=81=AE=E8=AA=AD?= =?UTF-8?q?=E3=81=BF=E8=BE=BC=E3=81=BF=E3=81=A7=E3=82=AF=E3=82=A8=E3=83=AA?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=82=A2=E3=82=A6=E3=83=88=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=99?= =?UTF-8?q?=E3=82=8B=20(#10106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/api/endpoints/notes/timeline.ts | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index d1c35e36e..942c4cf51 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -66,17 +66,9 @@ export default class extends Endpoint { })) !== 0; //#region Construct query - const followingQuery = this.followingsRepository.createQueryBuilder('following') - .select('following.followeeId') - .where('following.followerId = :followerId', { followerId: me.id }); - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.createdAt > :minDate', { minDate: new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)) }) // 30日前まで - .andWhere(new Brackets(qb => { qb - .where('note.userId = :meId', { meId: me.id }); - if (hasFollowing) qb.orWhere(`note.userId IN (${ followingQuery.getQuery() })`); - })) .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('user.avatar', 'avatar') .leftJoinAndSelect('user.banner', 'banner') @@ -87,8 +79,19 @@ export default class extends Endpoint { .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') .leftJoinAndSelect('renote.user', 'renoteUser') .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') - .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner') - .setParameters(followingQuery.getParameters()); + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); + + if (hasFollowing) { + const followees = await this.followingsRepository.createQueryBuilder('following') + .select('following.followeeId') + .where('following.followerId = :followerId', { followerId: me.id }) + .getMany(); + const meOrFolloweeIds = [me.id, ...followees.map(f => f.followeeId)]; + + query.andWhere('note.userId IN (:...meOrFolloweeIds)', { meOrFolloweeIds: meOrFolloweeIds }); + } else { + query.andWhere('note.userId = :meId', { meId: me.id }); + } this.queryService.generateChannelQuery(query, me); this.queryService.generateRepliesQuery(query, me); From a78a839841a5f668d420abdee358756e130fdb0a Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 18:57:24 +0900 Subject: [PATCH 15/25] refactor --- .../src/server/api/endpoints/notes/timeline.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index 942c4cf51..e6de087c4 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -58,12 +58,10 @@ export default class extends Endpoint { private activeUsersChart: ActiveUsersChart, ) { super(meta, paramDef, async (ps, me) => { - const hasFollowing = (await this.followingsRepository.count({ - where: { - followerId: me.id, - }, - take: 1, - })) !== 0; + const followees = await this.followingsRepository.createQueryBuilder('following') + .select('following.followeeId') + .where('following.followerId = :followerId', { followerId: me.id }) + .getMany(); //#region Construct query const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), @@ -81,11 +79,7 @@ export default class extends Endpoint { .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); - if (hasFollowing) { - const followees = await this.followingsRepository.createQueryBuilder('following') - .select('following.followeeId') - .where('following.followerId = :followerId', { followerId: me.id }) - .getMany(); + if (followees.length > 0) { const meOrFolloweeIds = [me.id, ...followees.map(f => f.followeeId)]; query.andWhere('note.userId IN (:...meOrFolloweeIds)', { meOrFolloweeIds: meOrFolloweeIds }); From dc9ef87c443918c991d3964a6a8ac1d799f84048 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 19:02:06 +0900 Subject: [PATCH 16/25] New translations ja-JP.yml (French) (#10103) --- locales/fr-FR.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index 1b40f99b4..72fc0ff39 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -103,6 +103,8 @@ renoted: "Renoté !" cantRenote: "Ce message ne peut pas être renoté." cantReRenote: "Impossible de renoter une Renote." quote: "Citer" +inChannelRenote: "Renoter dans le canal" +inChannelQuote: "Citer dans le canal" pinnedNote: "Note épinglée" pinned: "Épingler sur le profil" you: "Vous" @@ -129,6 +131,7 @@ unblockConfirm: "Êtes-vous sûr·e de vouloir débloquer ce compte ?" suspendConfirm: "Êtes-vous sûr·e de vouloir suspendre ce compte ?" unsuspendConfirm: "Êtes-vous sûr·e de vouloir annuler la suspension de ce compte ?" selectList: "Sélectionner une liste" +selectChannel: "Sélectionner un canal" selectAntenna: "Sélectionner une antenne" selectWidget: "Sélectionner un widget" editWidgets: "Modifier les widgets" @@ -898,6 +901,17 @@ show: "Affichage" neverShow: "Ne plus afficher" remindMeLater: "Peut-être plus tard" color: "Couleur" +_achievements: + _types: + _notes100000: + title: "ALL YOUR NOTE ARE BELONG TO US" + _login1000: + flavor: "Merci d'utiliser Misskey !" + _markedAsCat: + title: "Je suis un chat" + flavor: "Je n'ai pas encore de nom" + _following50: + title: "Beaucoup d'amis" _role: priority: "Priorité" _priority: From f78c519ae5ab73188a1a471a6a7fa90d1c4ef80e Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 19:02:35 +0900 Subject: [PATCH 17/25] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6a90b39f..53ff078cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ You should also include the user name that made the change. ### Improvements - チャンネル内ハイライト +- ホームタイムラインのパフォーマンスを改善 - renoteした際の表示を改善 - バックグラウンドで一定時間経過したらページネーションのアイテム更新をしない - enhance(client): MkUrlPreviewの閉じるボタンを見やすく From a56898df9471779ca772bffc4b77d7f2ffe7aee2 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 19:03:22 +0900 Subject: [PATCH 18/25] 13.8.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53ff078cf..c259bfbb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ You should also include the user name that made the change. --> -## 13.x.x (unreleased) +## 13.8.0 (2023/02/26) ### Improvements - チャンネル内ハイライト diff --git a/package.json b/package.json index f08272ea9..c91708de5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "13.7.5", + "version": "13.8.0", "codename": "nasubi", "repository": { "type": "git", From d019c1c440e3a155b2820361ca31a9f52c834570 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 20:07:45 +0900 Subject: [PATCH 19/25] Update packages/backend/check_connect.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Acid Chicken (硫酸鶏) --- packages/backend/check_connect.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/check_connect.js b/packages/backend/check_connect.js index 8bf134a10..627789580 100644 --- a/packages/backend/check_connect.js +++ b/packages/backend/check_connect.js @@ -1,5 +1,5 @@ -import {loadConfig} from './built/config.js'; -import {createRedisConnection} from "./built/redis.js"; +import { loadConfig } from './built/config.js'; +import { createRedisConnection } from './built/redis.js'; const config = loadConfig(); const redis = createRedisConnection(config); From 9f8c9dd8819e855e2b49b9963d9fcc79e3f376c6 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 20:07:52 +0900 Subject: [PATCH 20/25] Update packages/backend/check_connect.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Acid Chicken (硫酸鶏) --- packages/backend/check_connect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/check_connect.js b/packages/backend/check_connect.js index 627789580..ed429c025 100644 --- a/packages/backend/check_connect.js +++ b/packages/backend/check_connect.js @@ -6,5 +6,5 @@ const redis = createRedisConnection(config); redis.on('connect', () => redis.disconnect()); redis.on('error', (e) => { - throw e; + throw e; }); From 02d7ffd305013d3189c189ac585ca5d6e50c2db6 Mon Sep 17 00:00:00 2001 From: tamaina Date: Sun, 26 Feb 2023 11:10:24 +0000 Subject: [PATCH 21/25] =?UTF-8?q?fix(server):=20=E5=8D=98=E7=B4=94?= =?UTF-8?q?=E3=81=ABrenote=E3=81=A7=E3=81=8D=E3=81=AA=E3=81=84=E3=81=AE?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/server/api/endpoints/notes/create.test.ts | 15 +++++++++++++++ .../src/server/api/endpoints/notes/create.ts | 1 + 2 files changed, 16 insertions(+) diff --git a/packages/backend/src/server/api/endpoints/notes/create.test.ts b/packages/backend/src/server/api/endpoints/notes/create.test.ts index 4e5ec361f..6bff7fc0c 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.test.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.test.ts @@ -235,6 +235,21 @@ describe('api:notes/create', () => { }); }); + describe('renote', () => { + test('just a renote', () => { + expect(v({ renoteId: '1' })) + .toBe(VALID); + }); + test('just a quote', () => { + expect(v({ text: 'Hello, world!', renoteId: '1' })) + .toBe(VALID); + }); + test('reject invalid renoteId', () => { + expect(v({ renoteId: 'あ' })) + .toBe(INVALID); + }); + }); + test('text, fileIds and poll', () => { expect(v({ text: 'Hello, world!', fileIds: ['1', '2', '3'], poll: { choices: ['a', 'b', 'c'] } })) .toBe(VALID); diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 2848cd7df..786ad103b 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -147,6 +147,7 @@ export const paramDef = { // (re)note with text, files and poll are optional anyOf: [ { required: ['text'] }, + { required: ['renoteId'] }, { required: ['fileIds'] }, { required: ['mediaIds'] }, { required: ['poll'] }, From b7e72cfb7e3273de701034c753e9a8a673cb677f Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 20:29:53 +0900 Subject: [PATCH 22/25] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c259bfbb6..3734bbfd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ You should also include the user name that made the change. - fix(client): Android ChromeでPWAとしてインストールできない問題を修正 - 未知のユーザーが deleteActor されたら処理をスキップする - fix(server): notes/createで、fileIdsと見つかったファイルの数が異なる場合はエラーにする +- fix(server): notes/createのバリデーションが機能していないのを修正 - fix(server): エラーのスタックトレースは返さないように ## 13.7.5 (2023/02/24) From 103dc32dcef30f62c23e68acc679a13c13ae1d93 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 20:30:03 +0900 Subject: [PATCH 23/25] Update 03_release.md --- .github/PULL_REQUEST_TEMPLATE/03_release.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE/03_release.md b/.github/PULL_REQUEST_TEMPLATE/03_release.md index 0c71ea804..46d410138 100644 --- a/.github/PULL_REQUEST_TEMPLATE/03_release.md +++ b/.github/PULL_REQUEST_TEMPLATE/03_release.md @@ -1,10 +1,19 @@ -# Summary +## Summary This is a release PR. For more information on the release instructions, please see: https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md#release -# Checklist +## For reviewers +- CHANGELOGに抜け漏れは無いか +- バージョンの上げ方は適切か +- 他にこのリリースに含めなければならない変更は無いか +- 全体的な変更内容を俯瞰し問題は無いか +- レビューされていないコミットがある場合は、それが問題ないか + +などを確認し、リリースする準備が整っていると思われる場合は approve してください。 + +## Checklist - [ ] package.jsonのバージョンが正しく更新されている - [ ] CHANGELOGが過不足無く更新されている - [ ] CIが全て通っている From d8dcce807b4dc9b996611d7ea9ee93153bc0a0df Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 20:51:06 +0900 Subject: [PATCH 24/25] =?UTF-8?q?fix(client):=20=E3=83=A2=E3=83=90?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E7=92=B0=E5=A2=83=E3=81=A7=E3=83=9D=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=82=A2=E3=83=83=E3=83=97=E3=81=8C=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #10110 --- packages/frontend/src/components/MkModal.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkModal.vue b/packages/frontend/src/components/MkModal.vue index dbad02fb7..4529d61c2 100644 --- a/packages/frontend/src/components/MkModal.vue +++ b/packages/frontend/src/components/MkModal.vue @@ -125,7 +125,7 @@ function onBgClick() { } if (type === 'drawer') { - maxHeight = (window.innerHeight - SCROLLBAR_THICKNESS) / 1.5; + maxHeight = window.innerHeight / 1.5; } const keymap = { From 81e6a21fe06633adf50acd089f2005dfb10b95d4 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 26 Feb 2023 20:52:00 +0900 Subject: [PATCH 25/25] 13.8.1 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3734bbfd4..eb9ad1c10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ You should also include the user name that made the change. --> + +## 13.8.1 (2023/02/26) + +### Bugfixes +- モバイルでドロワーメニューが表示されない問題を修正 + ## 13.8.0 (2023/02/26) ### Improvements diff --git a/package.json b/package.json index c91708de5..2dec3f31f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "13.8.0", + "version": "13.8.1", "codename": "nasubi", "repository": { "type": "git",