From f3500ffda96913e41708a6ca04ef9bbf07af74e4 Mon Sep 17 00:00:00 2001 From: Nila <43315617+nilathedragon@users.noreply.github.com> Date: Sat, 30 Mar 2024 02:28:47 +0100 Subject: [PATCH 01/60] fix: report progress out of 100% in CleanRemoteFilesProcessorService (#13633) * Report progress out of 100% in CleanRemoteFilesProcessorService * Add changelog entry --- CHANGELOG.md | 1 + .../src/queue/processors/CleanRemoteFilesProcessorService.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f41ff2171f1f..3cfbb5f9c8a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ - Enhance: misskey-dev/summaly@5.1.0の取り込み(プレビュー生成処理の効率化) - Fix: フォローリクエストを作成する際に既存のものは削除するように (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/440) +- Fix: CleanRemoteFilesProcessorService report progress from 100% (#13632) ## 2024.3.1 diff --git a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts index 917de8b72c13..728fc9e72b77 100644 --- a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts +++ b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts @@ -63,7 +63,7 @@ export class CleanRemoteFilesProcessorService { isLink: false, }); - job.updateProgress(deletedCount / total); + job.updateProgress(100 / total * deletedCount); } this.logger.succ('All cached remote files has been deleted.'); From b35ae97ba7b57ae2b04eb0cc25dd3360e321e537 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:51:53 +0900 Subject: [PATCH 02/60] fix(backend): better `notes/translate` error response (#13631) * fix(backend): better `notes/translate` error response * Update CHANGELOG.md * test(backend): perform administrative operations as `root` --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- CHANGELOG.md | 1 + .../server/api/endpoints/notes/translate.ts | 13 ++- packages/backend/test/e2e/note.ts | 107 ++++++++++++++---- packages/misskey-js/src/autogen/types.ts | 4 + 4 files changed, 97 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cfbb5f9c8a3..5963549cc654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ - Enhance: misskey-dev/summaly@5.1.0の取り込み(プレビュー生成処理の効率化) - Fix: フォローリクエストを作成する際に既存のものは削除するように (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/440) +- Fix: エンドポイント`notes/translate`のエラーを改善 - Fix: CleanRemoteFilesProcessorService report progress from 100% (#13632) ## 2024.3.1 diff --git a/packages/backend/src/server/api/endpoints/notes/translate.ts b/packages/backend/src/server/api/endpoints/notes/translate.ts index 78812351f498..38a9660aa239 100644 --- a/packages/backend/src/server/api/endpoints/notes/translate.ts +++ b/packages/backend/src/server/api/endpoints/notes/translate.ts @@ -21,7 +21,7 @@ export const meta = { res: { type: 'object', - optional: false, nullable: false, + optional: true, nullable: false, properties: { sourceLang: { type: 'string' }, text: { type: 'string' }, @@ -39,6 +39,11 @@ export const meta = { code: 'NO_SUCH_NOTE', id: 'bea9b03f-36e0-49c5-a4db-627a029f8971', }, + cannotTranslateInvisibleNote: { + message: 'Cannot translate invisible note.', + code: 'CANNOT_TRANSLATE_INVISIBLE_NOTE', + id: 'ea29f2ca-c368-43b3-aaf1-5ac3e74bbe5d', + }, }, } as const; @@ -72,17 +77,17 @@ export default class extends Endpoint { // eslint- }); if (!(await this.noteEntityService.isVisibleForMe(note, me.id))) { - return 204; // TODO: 良い感じのエラー返す + throw new ApiError(meta.errors.cannotTranslateInvisibleNote); } if (note.text == null) { - return 204; + return; } const instance = await this.metaService.fetch(); if (instance.deeplAuthKey == null) { - return 204; // TODO: 良い感じのエラー返す + throw new ApiError(meta.errors.unavailable); } let targetLang = ps.targetLang; diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index 11016f58aef3..bda31d964074 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -8,12 +8,13 @@ process.env.NODE_ENV = 'test'; import * as assert from 'assert'; import { MiNote } from '@/models/Note.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; -import { api, initTestDb, post, signup, uploadFile, uploadUrl } from '../utils.js'; +import { api, initTestDb, post, role, signup, uploadFile, uploadUrl } from '../utils.js'; import type * as misskey from 'misskey-js'; describe('Note', () => { let Notes: any; + let root: misskey.entities.SignupResponse; let alice: misskey.entities.SignupResponse; let bob: misskey.entities.SignupResponse; let tom: misskey.entities.SignupResponse; @@ -21,6 +22,7 @@ describe('Note', () => { beforeAll(async () => { const connection = await initTestDb(true); Notes = connection.getRepository(MiNote); + root = await signup({ username: 'root' }); alice = await signup({ username: 'alice' }); bob = await signup({ username: 'bob' }); tom = await signup({ username: 'tom', host: 'example.com' }); @@ -473,14 +475,14 @@ describe('Note', () => { value: true, }, } as any, - }, alice); + }, root); assert.strictEqual(res.status, 200); const assign = await api('admin/roles/assign', { userId: alice.id, roleId: res.body.id, - }, alice); + }, root); assert.strictEqual(assign.status, 204); assert.strictEqual(file.body!.isSensitive, false); @@ -508,11 +510,11 @@ describe('Note', () => { await api('admin/roles/unassign', { userId: alice.id, roleId: res.body.id, - }); + }, root); await api('admin/roles/delete', { roleId: res.body.id, - }, alice); + }, root); }); }); @@ -644,7 +646,7 @@ describe('Note', () => { sensitiveWords: [ 'test', ], - }, alice); + }, root); assert.strictEqual(sensitive.status, 204); @@ -663,7 +665,7 @@ describe('Note', () => { sensitiveWords: [ '/Test/i', ], - }, alice); + }, root); assert.strictEqual(sensitive.status, 204); @@ -680,7 +682,7 @@ describe('Note', () => { sensitiveWords: [ 'Test hoge', ], - }, alice); + }, root); assert.strictEqual(sensitive.status, 204); @@ -697,7 +699,7 @@ describe('Note', () => { prohibitedWords: [ 'test', ], - }, alice); + }, root); assert.strictEqual(prohibited.status, 204); @@ -716,7 +718,7 @@ describe('Note', () => { prohibitedWords: [ '/Test/i', ], - }, alice); + }, root); assert.strictEqual(prohibited.status, 204); @@ -733,7 +735,7 @@ describe('Note', () => { prohibitedWords: [ 'Test hoge', ], - }, alice); + }, root); assert.strictEqual(prohibited.status, 204); @@ -750,7 +752,7 @@ describe('Note', () => { prohibitedWords: [ 'test', ], - }, alice); + }, root); assert.strictEqual(prohibited.status, 204); @@ -785,7 +787,7 @@ describe('Note', () => { value: 0, }, } as any, - }, alice); + }, root); assert.strictEqual(res.status, 200); @@ -794,7 +796,7 @@ describe('Note', () => { const assign = await api('admin/roles/assign', { userId: alice.id, roleId: res.body.id, - }, alice); + }, root); assert.strictEqual(assign.status, 204); @@ -810,11 +812,11 @@ describe('Note', () => { await api('admin/roles/unassign', { userId: alice.id, roleId: res.body.id, - }); + }, root); await api('admin/roles/delete', { roleId: res.body.id, - }, alice); + }, root); }); test('ダイレクト投稿もエラーになる', async () => { @@ -839,7 +841,7 @@ describe('Note', () => { value: 0, }, } as any, - }, alice); + }, root); assert.strictEqual(res.status, 200); @@ -848,7 +850,7 @@ describe('Note', () => { const assign = await api('admin/roles/assign', { userId: alice.id, roleId: res.body.id, - }, alice); + }, root); assert.strictEqual(assign.status, 204); @@ -866,11 +868,11 @@ describe('Note', () => { await api('admin/roles/unassign', { userId: alice.id, roleId: res.body.id, - }); + }, root); await api('admin/roles/delete', { roleId: res.body.id, - }, alice); + }, root); }); test('ダイレクトの宛先とメンションが同じ場合は重複してカウントしない', async () => { @@ -895,7 +897,7 @@ describe('Note', () => { value: 1, }, } as any, - }, alice); + }, root); assert.strictEqual(res.status, 200); @@ -904,7 +906,7 @@ describe('Note', () => { const assign = await api('admin/roles/assign', { userId: alice.id, roleId: res.body.id, - }, alice); + }, root); assert.strictEqual(assign.status, 204); @@ -921,11 +923,11 @@ describe('Note', () => { await api('admin/roles/unassign', { userId: alice.id, roleId: res.body.id, - }); + }, root); await api('admin/roles/delete', { roleId: res.body.id, - }, alice); + }, root); }); }); @@ -960,4 +962,61 @@ describe('Note', () => { assert.strictEqual(mainNote.repliesCount, 0); }); }); + + describe('notes/translate', () => { + describe('翻訳機能の利用が許可されていない場合', () => { + let cannotTranslateRole: misskey.entities.Role; + + beforeAll(async () => { + cannotTranslateRole = await role(root, {}, { canUseTranslator: false }); + await api('admin/roles/assign', { roleId: cannotTranslateRole.id, userId: alice.id }, root); + }); + + test('翻訳機能の利用が許可されていない場合翻訳できない', async () => { + const aliceNote = await post(alice, { text: 'Hello' }); + const res = await api('notes/translate', { + noteId: aliceNote.id, + targetLang: 'ja', + }, alice); + + assert.strictEqual(res.status, 400); + assert.strictEqual(res.body.error.code, 'UNAVAILABLE'); + }); + + afterAll(async () => { + await api('admin/roles/unassign', { roleId: cannotTranslateRole.id, userId: alice.id }, root); + }); + }); + + test('存在しないノートは翻訳できない', async () => { + const res = await api('notes/translate', { noteId: 'foo', targetLang: 'ja' }, alice); + + assert.strictEqual(res.status, 400); + assert.strictEqual(res.body.error.code, 'NO_SUCH_NOTE'); + }); + + test('不可視なノートは翻訳できない', async () => { + const aliceNote = await post(alice, { visibility: 'followers', text: 'Hello' }); + const bobTranslateAttempt = await api('notes/translate', { noteId: aliceNote.id, targetLang: 'ja' }, bob); + + assert.strictEqual(bobTranslateAttempt.status, 400); + assert.strictEqual(bobTranslateAttempt.body.error.code, 'CANNOT_TRANSLATE_INVISIBLE_NOTE'); + }); + + test('text: null なノートを翻訳すると空のレスポンスが返ってくる', async () => { + const aliceNote = await post(alice, { text: null, poll: { choices: ['kinoko', 'takenoko'] } }); + const res = await api('notes/translate', { noteId: aliceNote.id, targetLang: 'ja' }, alice); + + assert.strictEqual(res.status, 204); + }); + + test('サーバーに DeepL 認証キーが登録されていない場合翻訳できない', async () => { + const aliceNote = await post(alice, { text: 'Hello' }); + const res = await api('notes/translate', { noteId: aliceNote.id, targetLang: 'ja' }, alice); + + // NOTE: デフォルトでは登録されていないので落ちる + assert.strictEqual(res.status, 400); + assert.strictEqual(res.body.error.code, 'UNAVAILABLE'); + }); + }); }); diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 4b2ad16b0fcb..b6b26c000cdf 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -21864,6 +21864,10 @@ export type operations = { }; }; }; + /** @description OK (without any results) */ + 204: { + content: never; + }; /** @description Client error */ 400: { content: { From 2a851437ffcd8778d157a6841875f03330c994b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Sat, 30 Mar 2024 15:28:19 +0900 Subject: [PATCH 03/60] =?UTF-8?q?fix:=20misskey-js=E3=80=81bubble-game?= =?UTF-8?q?=E3=80=81reversi=E3=81=AE=E3=83=93=E3=83=AB=E3=83=89=E3=82=92es?= =?UTF-8?q?build=E3=81=AB=E7=B5=B1=E5=90=88=E3=81=99=E3=82=8B=20(#13600)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: ビルドが遅いパッケージのビルド速度を改善 * dependenciesの整理 * fix ci * ビルド開始時に古いファイルを消す * fix ci * fix ci --- .github/workflows/lint.yml | 2 +- package.json | 4 +- packages/backend/.swcrc | 3 +- packages/misskey-bubble-game/.eslintignore | 1 + packages/misskey-bubble-game/build.js | 114 ++++++++++--- packages/misskey-bubble-game/package.json | 26 ++- packages/misskey-bubble-game/src/index.ts | 6 +- packages/misskey-bubble-game/tsconfig.json | 2 +- packages/misskey-js/.eslintignore | 1 + packages/misskey-js/api-extractor.json | 2 +- packages/misskey-js/build.js | 105 ++++++++++++ packages/misskey-js/package.json | 29 ++-- packages/misskey-js/src/api.ts | 2 +- packages/misskey-js/src/index.ts | 15 +- packages/misskey-js/tsconfig.json | 2 +- packages/misskey-reversi/.eslintignore | 1 + packages/misskey-reversi/build.js | 114 ++++++++++--- packages/misskey-reversi/package.json | 26 ++- packages/misskey-reversi/tsconfig.json | 2 +- pnpm-lock.yaml | 188 ++++----------------- scripts/dev.mjs | 59 +++---- 21 files changed, 422 insertions(+), 282 deletions(-) create mode 100644 packages/misskey-js/build.js diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 31e974edaa8c..9b3f85fe1db9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -92,6 +92,6 @@ jobs: - run: pnpm i --frozen-lockfile - run: pnpm --filter misskey-js run build if: ${{ matrix.workspace == 'backend' }} - - run: pnpm --filter misskey-reversi run build:tsc + - run: pnpm --filter misskey-reversi run build if: ${{ matrix.workspace == 'backend' }} - run: pnpm --filter ${{ matrix.workspace }} run typecheck diff --git a/package.json b/package.json index 8f5ab0b12425..84d6db5124a3 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,9 @@ "postcss": "8.4.35", "tar": "6.2.0", "terser": "5.28.1", - "typescript": "5.3.3" + "typescript": "5.3.3", + "esbuild": "0.19.11", + "glob": "10.3.10" }, "devDependencies": { "@types/node": "^20.11.28", diff --git a/packages/backend/.swcrc b/packages/backend/.swcrc index 0504a2d38933..845190b5f419 100644 --- a/packages/backend/.swcrc +++ b/packages/backend/.swcrc @@ -19,5 +19,6 @@ }, "target": "es2022" }, - "minify": false + "minify": false, + "sourceMaps": "inline" } diff --git a/packages/misskey-bubble-game/.eslintignore b/packages/misskey-bubble-game/.eslintignore index f22128f047fd..52ea8b3362e9 100644 --- a/packages/misskey-bubble-game/.eslintignore +++ b/packages/misskey-bubble-game/.eslintignore @@ -5,3 +5,4 @@ node_modules /jest.config.ts /test /test-d +build.js diff --git a/packages/misskey-bubble-game/build.js b/packages/misskey-bubble-game/build.js index 4744dfaf7b44..0b79f4b9159b 100644 --- a/packages/misskey-bubble-game/build.js +++ b/packages/misskey-bubble-game/build.js @@ -1,31 +1,105 @@ +import * as esbuild from "esbuild"; import { build } from "esbuild"; import { globSync } from "glob"; +import { execa } from "execa"; +import fs from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname } from "node:path"; + +const _filename = fileURLToPath(import.meta.url); +const _dirname = dirname(_filename); +const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8')); const entryPoints = globSync("./src/**/**.{ts,tsx}"); /** @type {import('esbuild').BuildOptions} */ const options = { - entryPoints, - minify: true, - outdir: "./built/esm", - target: "es2022", - platform: "browser", - format: "esm", + entryPoints, + minify: process.env.NODE_ENV === 'production', + outdir: "./built", + target: "es2022", + platform: "browser", + format: "esm", + sourcemap: 'linked', }; -if (process.env.WATCH === "true") { - options.watch = { - onRebuild(error, result) { - if (error) { - console.error("watch build failed:", error); - } else { - console.log("watch build succeeded:", result); - } - }, - }; +// built配下をすべて削除する +fs.rmSync('./built', { recursive: true, force: true }); + +if (process.argv.map(arg => arg.toLowerCase()).includes("--watch")) { + await watchSrc(); +} else { + await buildSrc(); +} + +async function buildSrc() { + console.log(`[${_package.name}] start building...`); + + await build(options) + .then(it => { + console.log(`[${_package.name}] build succeeded.`); + }) + .catch((err) => { + process.stderr.write(err.stderr); + process.exit(1); + }); + + if (process.env.NODE_ENV === 'production') { + console.log(`[${_package.name}] skip building d.ts because NODE_ENV is production.`); + } else { + await buildDts(); + } + + console.log(`[${_package.name}] finish building.`); } -build(options).catch((err) => { - process.stderr.write(err.stderr); - process.exit(1); -}); +function buildDts() { + return execa( + 'tsc', + [ + '--project', 'tsconfig.json', + '--outDir', 'built', + '--declaration', 'true', + '--emitDeclarationOnly', 'true', + ], + { + stdout: process.stdout, + stderr: process.stderr, + } + ); +} + +async function watchSrc() { + const plugins = [{ + name: 'gen-dts', + setup(build) { + build.onStart(() => { + console.log(`[${_package.name}] detect changed...`); + }); + build.onEnd(async result => { + if (result.errors.length > 0) { + console.error(`[${_package.name}] watch build failed:`, result); + return; + } + await buildDts(); + }); + }, + }]; + + console.log(`[${_package.name}] start watching...`) + + const context = await esbuild.context({ ...options, plugins }); + await context.watch(); + + await new Promise((resolve, reject) => { + process.on('SIGHUP', resolve); + process.on('SIGINT', resolve); + process.on('SIGTERM', resolve); + process.on('SIGKILL', resolve); + process.on('uncaughtException', reject); + process.on('exit', resolve); + }).finally(async () => { + await context.dispose(); + console.log(`[${_package.name}] finish watching.`); + }); +} diff --git a/packages/misskey-bubble-game/package.json b/packages/misskey-bubble-game/package.json index ddc4c2134bcf..a3aad147a984 100644 --- a/packages/misskey-bubble-game/package.json +++ b/packages/misskey-bubble-game/package.json @@ -2,24 +2,21 @@ "type": "module", "name": "misskey-bubble-game", "version": "0.0.1", - "types": "./built/dts/index.d.ts", + "main": "./built/index.js", + "types": "./built/index.d.ts", "exports": { ".": { - "import": "./built/esm/index.js", - "types": "./built/dts/index.d.ts" + "import": "./built/index.js", + "types": "./built/index.d.ts" }, "./*": { - "import": "./built/esm/*", - "types": "./built/dts/*" + "import": "./built/*", + "types": "./built/*" } }, "scripts": { "build": "node ./build.js", - "build:tsc": "npm run tsc", - "tsc": "npm run tsc-esm && npm run tsc-dts", - "tsc-esm": "tsc --outDir built/esm", - "tsc-dts": "tsc --outDir built/dts --declaration true --emitDeclarationOnly true --declarationMap true", - "watch": "nodemon -w src -e ts,js,cjs,mjs,json --exec \"pnpm run build:tsc\"", + "watch": "nodemon -w package.json -e json --exec \"node ./build.js --watch\"", "eslint": "eslint . --ext .js,.jsx,.ts,.tsx", "typecheck": "tsc --noEmit", "lint": "pnpm typecheck && pnpm eslint" @@ -27,21 +24,22 @@ "devDependencies": { "@misskey-dev/eslint-plugin": "1.0.0", "@types/matter-js": "0.19.6", - "@types/node": "20.11.5", "@types/seedrandom": "3.0.8", + "@types/node": "20.11.5", "@typescript-eslint/eslint-plugin": "7.1.0", "@typescript-eslint/parser": "7.1.0", "eslint": "8.57.0", "nodemon": "3.0.2", - "typescript": "5.3.3" + "execa": "8.0.1", + "typescript": "5.3.3", + "esbuild": "0.19.11", + "glob": "10.3.10" }, "files": [ "built" ], "dependencies": { - "esbuild": "0.19.11", "eventemitter3": "5.0.1", - "glob": "^10.3.10", "matter-js": "0.19.0", "seedrandom": "3.0.5" } diff --git a/packages/misskey-bubble-game/src/index.ts b/packages/misskey-bubble-game/src/index.ts index 004a7d008ef4..c5f1f6806257 100644 --- a/packages/misskey-bubble-game/src/index.ts +++ b/packages/misskey-bubble-game/src/index.ts @@ -6,5 +6,9 @@ import { DropAndFusionGame, Mono } from './game.js'; export { - DropAndFusionGame, Mono, + DropAndFusionGame, +}; + +export type { + Mono, }; diff --git a/packages/misskey-bubble-game/tsconfig.json b/packages/misskey-bubble-game/tsconfig.json index f56b65e86802..6e34e332e000 100644 --- a/packages/misskey-bubble-game/tsconfig.json +++ b/packages/misskey-bubble-game/tsconfig.json @@ -6,7 +6,7 @@ "moduleResolution": "nodenext", "declaration": true, "declarationMap": true, - "sourceMap": true, + "sourceMap": false, "outDir": "./built/", "removeComments": true, "strict": true, diff --git a/packages/misskey-js/.eslintignore b/packages/misskey-js/.eslintignore index f22128f047fd..52ea8b3362e9 100644 --- a/packages/misskey-js/.eslintignore +++ b/packages/misskey-js/.eslintignore @@ -5,3 +5,4 @@ node_modules /jest.config.ts /test /test-d +build.js diff --git a/packages/misskey-js/api-extractor.json b/packages/misskey-js/api-extractor.json index f80d0f20a821..a95281a6d559 100644 --- a/packages/misskey-js/api-extractor.json +++ b/packages/misskey-js/api-extractor.json @@ -45,7 +45,7 @@ * * SUPPORTED TOKENS: , , */ - "mainEntryPointFilePath": "/built/dts/index.d.ts", + "mainEntryPointFilePath": "/built/index.d.ts", /** * A list of NPM package names whose exports should be treated as part of this package. diff --git a/packages/misskey-js/build.js b/packages/misskey-js/build.js new file mode 100644 index 000000000000..0b79f4b9159b --- /dev/null +++ b/packages/misskey-js/build.js @@ -0,0 +1,105 @@ +import * as esbuild from "esbuild"; +import { build } from "esbuild"; +import { globSync } from "glob"; +import { execa } from "execa"; +import fs from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname } from "node:path"; + +const _filename = fileURLToPath(import.meta.url); +const _dirname = dirname(_filename); +const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8')); + +const entryPoints = globSync("./src/**/**.{ts,tsx}"); + +/** @type {import('esbuild').BuildOptions} */ +const options = { + entryPoints, + minify: process.env.NODE_ENV === 'production', + outdir: "./built", + target: "es2022", + platform: "browser", + format: "esm", + sourcemap: 'linked', +}; + +// built配下をすべて削除する +fs.rmSync('./built', { recursive: true, force: true }); + +if (process.argv.map(arg => arg.toLowerCase()).includes("--watch")) { + await watchSrc(); +} else { + await buildSrc(); +} + +async function buildSrc() { + console.log(`[${_package.name}] start building...`); + + await build(options) + .then(it => { + console.log(`[${_package.name}] build succeeded.`); + }) + .catch((err) => { + process.stderr.write(err.stderr); + process.exit(1); + }); + + if (process.env.NODE_ENV === 'production') { + console.log(`[${_package.name}] skip building d.ts because NODE_ENV is production.`); + } else { + await buildDts(); + } + + console.log(`[${_package.name}] finish building.`); +} + +function buildDts() { + return execa( + 'tsc', + [ + '--project', 'tsconfig.json', + '--outDir', 'built', + '--declaration', 'true', + '--emitDeclarationOnly', 'true', + ], + { + stdout: process.stdout, + stderr: process.stderr, + } + ); +} + +async function watchSrc() { + const plugins = [{ + name: 'gen-dts', + setup(build) { + build.onStart(() => { + console.log(`[${_package.name}] detect changed...`); + }); + build.onEnd(async result => { + if (result.errors.length > 0) { + console.error(`[${_package.name}] watch build failed:`, result); + return; + } + await buildDts(); + }); + }, + }]; + + console.log(`[${_package.name}] start watching...`) + + const context = await esbuild.context({ ...options, plugins }); + await context.watch(); + + await new Promise((resolve, reject) => { + process.on('SIGHUP', resolve); + process.on('SIGINT', resolve); + process.on('SIGTERM', resolve); + process.on('SIGKILL', resolve); + process.on('uncaughtException', reject); + process.on('exit', resolve); + }).finally(async () => { + await context.dispose(); + console.log(`[${_package.name}] finish watching.`); + }); +} diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 772f001c0734..a9c75c95c28e 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -3,23 +3,21 @@ "name": "misskey-js", "version": "2024.3.1", "description": "Misskey SDK for JavaScript", - "types": "./built/dts/index.d.ts", + "main": "./built/index.js", + "types": "./built/index.d.ts", "exports": { ".": { - "import": "./built/esm/index.js", - "types": "./built/dts/index.d.ts" + "import": "./built/index.js", + "types": "./built/index.d.ts" }, "./*": { - "import": "./built/esm/*", - "types": "./built/dts/*" + "import": "./built/*", + "types": "./built/*" } }, "scripts": { - "build": "npm run ts", - "ts": "npm run ts-esm && npm run ts-dts", - "ts-esm": "tsc --outDir built/esm", - "ts-dts": "tsc --outDir built/dts --declaration true --emitDeclarationOnly true --declarationMap true", - "watch": "nodemon -w src -e ts,js,cjs,mjs,json --exec \"pnpm run ts\"", + "build": "node ./build.js", + "watch": "nodemon -w package.json -e json --exec \"node ./build.js --watch\"", "tsd": "tsd", "api": "pnpm api-extractor run --local --verbose", "api-prod": "pnpm api-extractor run --verbose", @@ -49,17 +47,16 @@ "mock-socket": "9.3.1", "ncp": "2.0.0", "nodemon": "3.1.0", + "execa": "8.0.1", "tsd": "0.30.7", - "typescript": "5.3.3" + "typescript": "5.3.3", + "esbuild": "0.19.11", + "glob": "10.3.10" }, "files": [ - "built", - "built/esm", - "built/dts" + "built" ], "dependencies": { - "@swc/cli": "0.1.63", - "@swc/core": "1.3.105", "eventemitter3": "5.0.1", "reconnecting-websocket": "4.4.0" } diff --git a/packages/misskey-js/src/api.ts b/packages/misskey-js/src/api.ts index 134ead0d7959..959a634a743f 100644 --- a/packages/misskey-js/src/api.ts +++ b/packages/misskey-js/src/api.ts @@ -3,7 +3,7 @@ import './autogen/apiClientJSDoc.js'; import { SwitchCaseResponseType } from './api.types.js'; import type { Endpoints } from './api.types.js'; -export { +export type { SwitchCaseResponseType, } from './api.types.js'; diff --git a/packages/misskey-js/src/index.ts b/packages/misskey-js/src/index.ts index 54cae8ec0332..28007a8ade3c 100644 --- a/packages/misskey-js/src/index.ts +++ b/packages/misskey-js/src/index.ts @@ -1,17 +1,20 @@ -import { Endpoints } from './api.types.js'; +import { type Endpoints } from './api.types.js'; import Stream, { Connection } from './streaming.js'; -import { Channels } from './streaming.types.js'; -import { Acct } from './acct.js'; +import { type Channels } from './streaming.types.js'; +import { type Acct } from './acct.js'; import * as consts from './consts.js'; -export { +export type { Endpoints, - Stream, - Connection as ChannelConnection, Channels, Acct, }; +export { + Stream, + Connection as ChannelConnection, +}; + export const permissions = consts.permissions; export const notificationTypes = consts.notificationTypes; export const noteVisibilities = consts.noteVisibilities; diff --git a/packages/misskey-js/tsconfig.json b/packages/misskey-js/tsconfig.json index f56b65e86802..6e34e332e000 100644 --- a/packages/misskey-js/tsconfig.json +++ b/packages/misskey-js/tsconfig.json @@ -6,7 +6,7 @@ "moduleResolution": "nodenext", "declaration": true, "declarationMap": true, - "sourceMap": true, + "sourceMap": false, "outDir": "./built/", "removeComments": true, "strict": true, diff --git a/packages/misskey-reversi/.eslintignore b/packages/misskey-reversi/.eslintignore index f22128f047fd..52ea8b3362e9 100644 --- a/packages/misskey-reversi/.eslintignore +++ b/packages/misskey-reversi/.eslintignore @@ -5,3 +5,4 @@ node_modules /jest.config.ts /test /test-d +build.js diff --git a/packages/misskey-reversi/build.js b/packages/misskey-reversi/build.js index 4744dfaf7b44..0b79f4b9159b 100644 --- a/packages/misskey-reversi/build.js +++ b/packages/misskey-reversi/build.js @@ -1,31 +1,105 @@ +import * as esbuild from "esbuild"; import { build } from "esbuild"; import { globSync } from "glob"; +import { execa } from "execa"; +import fs from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname } from "node:path"; + +const _filename = fileURLToPath(import.meta.url); +const _dirname = dirname(_filename); +const _package = JSON.parse(fs.readFileSync(_dirname + '/package.json', 'utf-8')); const entryPoints = globSync("./src/**/**.{ts,tsx}"); /** @type {import('esbuild').BuildOptions} */ const options = { - entryPoints, - minify: true, - outdir: "./built/esm", - target: "es2022", - platform: "browser", - format: "esm", + entryPoints, + minify: process.env.NODE_ENV === 'production', + outdir: "./built", + target: "es2022", + platform: "browser", + format: "esm", + sourcemap: 'linked', }; -if (process.env.WATCH === "true") { - options.watch = { - onRebuild(error, result) { - if (error) { - console.error("watch build failed:", error); - } else { - console.log("watch build succeeded:", result); - } - }, - }; +// built配下をすべて削除する +fs.rmSync('./built', { recursive: true, force: true }); + +if (process.argv.map(arg => arg.toLowerCase()).includes("--watch")) { + await watchSrc(); +} else { + await buildSrc(); +} + +async function buildSrc() { + console.log(`[${_package.name}] start building...`); + + await build(options) + .then(it => { + console.log(`[${_package.name}] build succeeded.`); + }) + .catch((err) => { + process.stderr.write(err.stderr); + process.exit(1); + }); + + if (process.env.NODE_ENV === 'production') { + console.log(`[${_package.name}] skip building d.ts because NODE_ENV is production.`); + } else { + await buildDts(); + } + + console.log(`[${_package.name}] finish building.`); } -build(options).catch((err) => { - process.stderr.write(err.stderr); - process.exit(1); -}); +function buildDts() { + return execa( + 'tsc', + [ + '--project', 'tsconfig.json', + '--outDir', 'built', + '--declaration', 'true', + '--emitDeclarationOnly', 'true', + ], + { + stdout: process.stdout, + stderr: process.stderr, + } + ); +} + +async function watchSrc() { + const plugins = [{ + name: 'gen-dts', + setup(build) { + build.onStart(() => { + console.log(`[${_package.name}] detect changed...`); + }); + build.onEnd(async result => { + if (result.errors.length > 0) { + console.error(`[${_package.name}] watch build failed:`, result); + return; + } + await buildDts(); + }); + }, + }]; + + console.log(`[${_package.name}] start watching...`) + + const context = await esbuild.context({ ...options, plugins }); + await context.watch(); + + await new Promise((resolve, reject) => { + process.on('SIGHUP', resolve); + process.on('SIGINT', resolve); + process.on('SIGTERM', resolve); + process.on('SIGKILL', resolve); + process.on('uncaughtException', reject); + process.on('exit', resolve); + }).finally(async () => { + await context.dispose(); + console.log(`[${_package.name}] finish watching.`); + }); +} diff --git a/packages/misskey-reversi/package.json b/packages/misskey-reversi/package.json index 7bfc890fef85..45a61208610d 100644 --- a/packages/misskey-reversi/package.json +++ b/packages/misskey-reversi/package.json @@ -2,24 +2,21 @@ "type": "module", "name": "misskey-reversi", "version": "0.0.1", - "types": "./built/dts/index.d.ts", + "main": "./built/index.js", + "types": "./built/index.d.ts", "exports": { ".": { - "import": "./built/esm/index.js", - "types": "./built/dts/index.d.ts" + "import": "./built/index.js", + "types": "./built/index.d.ts" }, "./*": { - "import": "./built/esm/*", - "types": "./built/dts/*" + "import": "./built/*", + "types": "./built/*" } }, "scripts": { "build": "node ./build.js", - "build:tsc": "npm run tsc", - "tsc": "npm run tsc-esm && npm run tsc-dts", - "tsc-esm": "tsc --outDir built/esm", - "tsc-dts": "tsc --outDir built/dts --declaration true --emitDeclarationOnly true --declarationMap true", - "watch": "nodemon -w src -e ts,js,cjs,mjs,json --exec \"pnpm run build:tsc\"", + "watch": "nodemon -w package.json -e json --exec \"node ./build.js --watch\"", "eslint": "eslint . --ext .js,.jsx,.ts,.tsx", "typecheck": "tsc --noEmit", "lint": "pnpm typecheck && pnpm eslint" @@ -30,15 +27,16 @@ "@typescript-eslint/eslint-plugin": "7.1.0", "@typescript-eslint/parser": "7.1.0", "eslint": "8.57.0", + "execa": "8.0.1", "nodemon": "3.0.2", - "typescript": "5.3.3" + "typescript": "5.3.3", + "esbuild": "0.19.11", + "glob": "10.3.10" }, "files": [ "built" ], "dependencies": { - "crc-32": "1.2.2", - "esbuild": "0.19.11", - "glob": "10.3.10" + "crc-32": "1.2.2" } } diff --git a/packages/misskey-reversi/tsconfig.json b/packages/misskey-reversi/tsconfig.json index f56b65e86802..6e34e332e000 100644 --- a/packages/misskey-reversi/tsconfig.json +++ b/packages/misskey-reversi/tsconfig.json @@ -6,7 +6,7 @@ "moduleResolution": "nodenext", "declaration": true, "declarationMap": true, - "sourceMap": true, + "sourceMap": false, "outDir": "./built/", "removeComments": true, "strict": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 383b31b1f361..46512784c3ab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,12 +15,18 @@ importers: cssnano: specifier: 6.0.5 version: 6.0.5(postcss@8.4.35) + esbuild: + specifier: 0.19.11 + version: 0.19.11 execa: specifier: 8.0.1 version: 8.0.1 fast-glob: specifier: 3.3.2 version: 3.3.2 + glob: + specifier: 10.3.10 + version: 10.3.10 ignore-walk: specifier: 6.0.4 version: 6.0.4 @@ -1037,15 +1043,9 @@ importers: packages/misskey-bubble-game: dependencies: - esbuild: - specifier: 0.19.11 - version: 0.19.11 eventemitter3: specifier: 5.0.1 version: 5.0.1 - glob: - specifier: ^10.3.10 - version: 10.3.10 matter-js: specifier: 0.19.0 version: 0.19.0 @@ -1071,9 +1071,18 @@ importers: '@typescript-eslint/parser': specifier: 7.1.0 version: 7.1.0(eslint@8.57.0)(typescript@5.3.3) + esbuild: + specifier: 0.19.11 + version: 0.19.11 eslint: specifier: 8.57.0 version: 8.57.0 + execa: + specifier: 8.0.1 + version: 8.0.1 + glob: + specifier: 10.3.10 + version: 10.3.10 nodemon: specifier: 3.0.2 version: 3.0.2 @@ -1083,12 +1092,6 @@ importers: packages/misskey-js: dependencies: - '@swc/cli': - specifier: 0.1.63 - version: 0.1.63(@swc/core@1.3.105) - '@swc/core': - specifier: 1.3.105 - version: 1.3.105 eventemitter3: specifier: 5.0.1 version: 5.0.1 @@ -1104,7 +1107,7 @@ importers: version: 1.0.0(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) '@swc/jest': specifier: 0.2.31 - version: 0.2.31(@swc/core@1.3.105) + version: 0.2.31(@swc/core@1.3.107) '@types/jest': specifier: 29.5.12 version: 29.5.12 @@ -1117,9 +1120,18 @@ importers: '@typescript-eslint/parser': specifier: 7.1.0 version: 7.1.0(eslint@8.57.0)(typescript@5.3.3) + esbuild: + specifier: 0.19.11 + version: 0.19.11 eslint: specifier: 8.57.0 version: 8.57.0 + execa: + specifier: 8.0.1 + version: 8.0.1 + glob: + specifier: 10.3.10 + version: 10.3.10 jest: specifier: 29.7.0 version: 29.7.0(@types/node@20.11.22) @@ -1186,12 +1198,6 @@ importers: crc-32: specifier: 1.2.2 version: 1.2.2 - esbuild: - specifier: 0.19.11 - version: 0.19.11 - glob: - specifier: 10.3.10 - version: 10.3.10 devDependencies: '@misskey-dev/eslint-plugin': specifier: 1.0.0 @@ -1205,9 +1211,18 @@ importers: '@typescript-eslint/parser': specifier: 7.1.0 version: 7.1.0(eslint@8.57.0)(typescript@5.3.3) + esbuild: + specifier: 0.19.11 + version: 0.19.11 eslint: specifier: 8.57.0 version: 8.57.0 + execa: + specifier: 8.0.1 + version: 8.0.1 + glob: + specifier: 10.3.10 + version: 10.3.10 nodemon: specifier: 3.0.2 version: 3.0.2 @@ -6669,26 +6684,6 @@ packages: - supports-color dev: true - /@swc/cli@0.1.63(@swc/core@1.3.105): - resolution: {integrity: sha512-EM9oxxHzmmsprYRbGqsS2M4M/Gr5Gkcl0ROYYIdlUyTkhOiX822EQiRCpPCwdutdnzH2GyaTN7wc6i0Y+CKd3A==} - engines: {node: '>= 12.13'} - hasBin: true - peerDependencies: - '@swc/core': ^1.2.66 - chokidar: 3.5.3 - peerDependenciesMeta: - chokidar: - optional: true - dependencies: - '@mole-inc/bin-wrapper': 8.0.1 - '@swc/core': 1.3.105 - commander: 7.2.0 - fast-glob: 3.3.2 - semver: 7.5.4 - slash: 3.0.0 - source-map: 0.7.4 - dev: false - /@swc/cli@0.1.63(@swc/core@1.3.107)(chokidar@3.5.3): resolution: {integrity: sha512-EM9oxxHzmmsprYRbGqsS2M4M/Gr5Gkcl0ROYYIdlUyTkhOiX822EQiRCpPCwdutdnzH2GyaTN7wc6i0Y+CKd3A==} engines: {node: '>= 12.13'} @@ -6721,14 +6716,6 @@ packages: dev: false optional: true - /@swc/core-darwin-arm64@1.3.105: - resolution: {integrity: sha512-buWeweLVDXXmcnfIemH4PGnpjwsDTUGitnPchdftb0u1FU8zSSP/lw/pUCBDG/XvWAp7c/aFxgN4CyG0j7eayA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - /@swc/core-darwin-arm64@1.3.107: resolution: {integrity: sha512-47tD/5vSXWxPd0j/ZllyQUg4bqalbQTsmqSw0J4dDdS82MWqCAwUErUrAZPRjBkjNQ6Kmrf5rpCWaGTtPw+ngw==} engines: {node: '>=10'} @@ -6746,14 +6733,6 @@ packages: dev: false optional: true - /@swc/core-darwin-x64@1.3.105: - resolution: {integrity: sha512-hFmXPApqjA/8sy/9NpljHVaKi1OvL9QkJ2MbbTCCbJERuHMpMUeMBUWipHRfepGHFhU+9B9zkEup/qJaJR4XIg==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - /@swc/core-darwin-x64@1.3.107: resolution: {integrity: sha512-hwiLJ2ulNkBGAh1m1eTfeY1417OAYbRGcb/iGsJ+LuVLvKAhU/itzsl535CvcwAlt2LayeCFfcI8gdeOLeZa9A==} engines: {node: '>=10'} @@ -6782,14 +6761,6 @@ packages: dev: false optional: true - /@swc/core-linux-arm-gnueabihf@1.3.105: - resolution: {integrity: sha512-mwXyMC41oMKkKrPpL8uJpOxw7fyfQoVtIw3Y5p0Blabk+espNYqix0E8VymHdRKuLmM//z5wVmMsuHdGBHvZeg==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - /@swc/core-linux-arm-gnueabihf@1.3.107: resolution: {integrity: sha512-I2wzcC0KXqh0OwymCmYwNRgZ9nxX7DWnOOStJXV3pS0uB83TXAkmqd7wvMBuIl9qu4Hfomi9aDM7IlEEn9tumQ==} engines: {node: '>=10'} @@ -6807,14 +6778,6 @@ packages: dev: false optional: true - /@swc/core-linux-arm64-gnu@1.3.105: - resolution: {integrity: sha512-H7yEIVydnUtqBSUxwmO6vpIQn7j+Rr0DF6ZOORPyd/SFzQJK9cJRtmJQ3ZMzlJ1Bb+1gr3MvjgLEnmyCYEm2Hg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - /@swc/core-linux-arm64-gnu@1.3.107: resolution: {integrity: sha512-HWgnn7JORYlOYnGsdunpSF8A+BCZKPLzLtEUA27/M/ZuANcMZabKL9Zurt7XQXq888uJFAt98Gy+59PU90aHKg==} engines: {node: '>=10'} @@ -6832,14 +6795,6 @@ packages: dev: false optional: true - /@swc/core-linux-arm64-musl@1.3.105: - resolution: {integrity: sha512-Jg7RTFT3pGFdGt5elPV6oDkinRy7q9cXpenjXnJnM2uvx3jOwnsAhexPyCDHom8SHL0j+9kaLLC66T3Gz1E4UA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - /@swc/core-linux-arm64-musl@1.3.107: resolution: {integrity: sha512-vfPF74cWfAm8hyhS8yvYI94ucMHIo8xIYU+oFOW9uvDlGQRgnUf/6DEVbLyt/3yfX5723Ln57U8uiMALbX5Pyw==} engines: {node: '>=10'} @@ -6857,14 +6812,6 @@ packages: dev: false optional: true - /@swc/core-linux-x64-gnu@1.3.105: - resolution: {integrity: sha512-DJghplpyusAmp1X5pW/y93MmS/u83Sx5GrpJxI6KLPa82+NItTgMcl8KBQmW5GYAJpVKZyaIvBanS5TdR8aN2w==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - /@swc/core-linux-x64-gnu@1.3.107: resolution: {integrity: sha512-uBVNhIg0ip8rH9OnOsCARUFZ3Mq3tbPHxtmWk9uAa5u8jQwGWeBx5+nTHpDOVd3YxKb6+5xDEI/edeeLpha/9g==} engines: {node: '>=10'} @@ -6882,14 +6829,6 @@ packages: dev: false optional: true - /@swc/core-linux-x64-musl@1.3.105: - resolution: {integrity: sha512-wD5jL2dZH/5nPNssBo6jhOvkI0lmWnVR4vnOXWjuXgjq1S0AJpO5jdre/6pYLmf26hft3M42bteDnjR4AAZ38w==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - /@swc/core-linux-x64-musl@1.3.107: resolution: {integrity: sha512-mvACkUvzSIB12q1H5JtabWATbk3AG+pQgXEN95AmEX2ZA5gbP9+B+mijsg7Sd/3tboHr7ZHLz/q3SHTvdFJrEw==} engines: {node: '>=10'} @@ -6907,14 +6846,6 @@ packages: dev: false optional: true - /@swc/core-win32-arm64-msvc@1.3.105: - resolution: {integrity: sha512-UqJtwILUHRw2+3UTPnRkZrzM/bGdQtbR4UFdp79mZQYfryeOUVNg7aJj/bWUTkKtLiZ3o+FBNrM/x2X1mJX5bA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - /@swc/core-win32-arm64-msvc@1.3.107: resolution: {integrity: sha512-J3P14Ngy/1qtapzbguEH41kY109t6DFxfbK4Ntz9dOWNuVY3o9/RTB841ctnJk0ZHEG+BjfCJjsD2n8H5HcaOA==} engines: {node: '>=10'} @@ -6932,14 +6863,6 @@ packages: dev: false optional: true - /@swc/core-win32-ia32-msvc@1.3.105: - resolution: {integrity: sha512-Z95C6vZgBEJ1snidYyjVKnVWiy/ZpPiIFIXGWkDr4ZyBgL3eZX12M6LzZ+NApHKffrbO4enbFyFomueBQgS2oA==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - /@swc/core-win32-ia32-msvc@1.3.107: resolution: {integrity: sha512-ZBUtgyjTHlz8TPJh7kfwwwFma+ktr6OccB1oXC8fMSopD0AxVnQasgun3l3099wIsAB9eEsJDQ/3lDkOLs1gBA==} engines: {node: '>=10'} @@ -6957,14 +6880,6 @@ packages: dev: false optional: true - /@swc/core-win32-x64-msvc@1.3.105: - resolution: {integrity: sha512-3J8fkyDPFsS3mszuYUY4Wfk7/B2oio9qXUwF3DzOs2MK+XgdyMLIptIxL7gdfitXJBH8k39uVjrIw1JGJDjyFA==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - /@swc/core-win32-x64-msvc@1.3.107: resolution: {integrity: sha512-Eyzo2XRqWOxqhE1gk9h7LWmUf4Bp4Xn2Ttb0ayAXFp6YSTxQIThXcT9kipXZqcpxcmDwoq8iWbbf2P8XL743EA==} engines: {node: '>=10'} @@ -6982,30 +6897,6 @@ packages: dev: false optional: true - /@swc/core@1.3.105: - resolution: {integrity: sha512-me2VZyr3OjqRpFrYQJJYy7x/zbFSl9nt+MAGnIcBtjDsN00iTVqEaKxBjPBFQV9BDAgPz2SRWes/DhhVm5SmMw==} - engines: {node: '>=10'} - requiresBuild: true - peerDependencies: - '@swc/helpers': ^0.5.0 - peerDependenciesMeta: - '@swc/helpers': - optional: true - dependencies: - '@swc/counter': 0.1.1 - '@swc/types': 0.1.5 - optionalDependencies: - '@swc/core-darwin-arm64': 1.3.105 - '@swc/core-darwin-x64': 1.3.105 - '@swc/core-linux-arm-gnueabihf': 1.3.105 - '@swc/core-linux-arm64-gnu': 1.3.105 - '@swc/core-linux-arm64-musl': 1.3.105 - '@swc/core-linux-x64-gnu': 1.3.105 - '@swc/core-linux-x64-musl': 1.3.105 - '@swc/core-win32-arm64-msvc': 1.3.105 - '@swc/core-win32-ia32-msvc': 1.3.105 - '@swc/core-win32-x64-msvc': 1.3.105 - /@swc/core@1.3.107: resolution: {integrity: sha512-zKhqDyFcTsyLIYK1iEmavljZnf4CCor5pF52UzLAz4B6Nu/4GLU+2LQVAf+oRHjusG39PTPjd2AlRT3f3QWfsQ==} engines: {node: '>=10'} @@ -7033,17 +6924,6 @@ packages: /@swc/counter@0.1.1: resolution: {integrity: sha512-xVRaR4u9hcYjFvcSg71Lz5Bo4//CyjAAfMxa7UsaDSYxAshflUkVJWiyVWrfxC59z2kP1IzI4/1BEpnhI9o3Mw==} - /@swc/jest@0.2.31(@swc/core@1.3.105): - resolution: {integrity: sha512-Gh0Ste380O8KUY1IqsKr+aOvqqs2Loa+WcWWVNwl+lhXqOWK1iTFAP1K0IDfLqAuFP68+D/PxcpBJn21e6Quvw==} - engines: {npm: '>= 7.0.0'} - peerDependencies: - '@swc/core': '*' - dependencies: - '@jest/create-cache-key-function': 29.7.0 - '@swc/core': 1.3.105 - jsonc-parser: 3.2.0 - dev: true - /@swc/jest@0.2.31(@swc/core@1.3.107): resolution: {integrity: sha512-Gh0Ste380O8KUY1IqsKr+aOvqqs2Loa+WcWWVNwl+lhXqOWK1iTFAP1K0IDfLqAuFP68+D/PxcpBJn21e6Quvw==} engines: {npm: '>= 7.0.0'} diff --git a/scripts/dev.mjs b/scripts/dev.mjs index 1ca2c6c2eae6..bbb2547758b1 100644 --- a/scripts/dev.mjs +++ b/scripts/dev.mjs @@ -16,35 +16,36 @@ await execa('pnpm', ['clean'], { stderr: process.stderr, }); -await execa('pnpm', ['build-pre'], { - cwd: _dirname + '/../', - stdout: process.stdout, - stderr: process.stderr, -}); - -await execa('pnpm', ['build-assets'], { - cwd: _dirname + '/../', - stdout: process.stdout, - stderr: process.stderr, -}); - -await execa('pnpm', ['--filter', 'misskey-js', 'ts'], { - cwd: _dirname + '/../', - stdout: process.stdout, - stderr: process.stderr, -}); - -await execa('pnpm', ['--filter', 'misskey-reversi', 'build:tsc'], { - cwd: _dirname + '/../', - stdout: process.stdout, - stderr: process.stderr, -}); - -await execa('pnpm', ['--filter', 'misskey-bubble-game', 'build:tsc'], { - cwd: _dirname + '/../', - stdout: process.stdout, - stderr: process.stderr, -}); +await Promise.all([ + execa('pnpm', ['build-pre'], { + cwd: _dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }), + execa('pnpm', ['build-assets'], { + cwd: _dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }), + execa('pnpm', ['--filter', 'misskey-js', 'build'], { + cwd: _dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }), +]); + +await Promise.all([ + execa('pnpm', ['--filter', 'misskey-reversi', 'build'], { + cwd: _dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }), + execa('pnpm', ['--filter', 'misskey-bubble-game', 'build'], { + cwd: _dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }), +]); execa('pnpm', ['build-pre', '--watch'], { cwd: _dirname + '/../', From 50da7d2a2728745bcf29cf71fb230c85a1845060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 30 Mar 2024 15:34:05 +0900 Subject: [PATCH 04/60] =?UTF-8?q?enhance(frontend):=202=E8=A6=81=E7=B4=A0?= =?UTF-8?q?=E8=AA=8D=E8=A8=BC=E3=82=BB=E3=83=83=E3=83=88=E3=82=A2=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=82=A6=E3=82=A3=E3=82=B6=E3=83=BC=E3=83=89=E3=81=AB?= =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E3=82=92=E8=B5=B7=E5=8B=95=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=83=9C=E3=82=BF=E3=83=B3=E3=82=92=E6=96=B0=E8=A8=AD?= =?UTF-8?q?=20(#13636)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): 2要素認証セットアップウィザードにアプリを起動するボタンを新設 * add comment * use css module --- locales/index.d.ts | 10 +++++----- locales/ja-JP.yml | 4 ++-- packages/frontend/src/components/MkButton.vue | 2 ++ .../frontend/src/pages/settings/2fa.qrdialog.vue | 16 +++++++++++++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/locales/index.d.ts b/locales/index.d.ts index e1250946f35f..428cf9135cff 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4928,6 +4928,10 @@ export interface Locale extends ILocale { * バックアップコードを使う */ "useBackupCode": string; + /** + * アプリを起動 + */ + "launchApp": string; "_bubbleGame": { /** * 遊び方 @@ -7542,13 +7546,9 @@ export interface Locale extends ILocale { */ "step1": ParameterizedString<"a" | "b">; /** - * 次に、表示されているQRコードをアプリでスキャンします。 + * 次に、表示されているQRコードをアプリでスキャンするか、ボタンをクリックして端末上でアプリを開きます。 */ "step2": string; - /** - * QRコードをクリックすると、お使いの端末にインストールされている認証アプリやキーリングに登録できます。 - */ - "step2Click": string; /** * デスクトップアプリを使用する場合は次のURIを入力します */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 1c4df27d92ad..9e76e420c38a 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1228,6 +1228,7 @@ gameRetry: "リトライ" notUsePleaseLeaveBlank: "使用しない場合は空欄にしてください" useTotp: "ワンタイムパスワードを使う" useBackupCode: "バックアップコードを使う" +launchApp: "アプリを起動" _bubbleGame: howToPlay: "遊び方" @@ -1983,8 +1984,7 @@ _2fa: alreadyRegistered: "既に設定は完了しています。" registerTOTP: "認証アプリの設定を開始" step1: "まず、{a}や{b}などの認証アプリをお使いのデバイスにインストールします。" - step2: "次に、表示されているQRコードをアプリでスキャンします。" - step2Click: "QRコードをクリックすると、お使いの端末にインストールされている認証アプリやキーリングに登録できます。" + step2: "次に、表示されているQRコードをアプリでスキャンするか、ボタンをクリックして端末上でアプリを開きます。" step2Uri: "デスクトップアプリを使用する場合は次のURIを入力します" step3Title: "確認コードを入力" step3: "アプリに表示されている確認コード(トークン)を入力します。" diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue index 817f1aadf334..3489255b9152 100644 --- a/packages/frontend/src/components/MkButton.vue +++ b/packages/frontend/src/components/MkButton.vue @@ -23,6 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only v-else class="_button" :class="[$style.root, { [$style.inline]: inline, [$style.primary]: primary, [$style.gradate]: gradate, [$style.danger]: danger, [$style.rounded]: rounded, [$style.full]: full, [$style.small]: small, [$style.large]: large, [$style.transparent]: transparent, [$style.asLike]: asLike }]" :to="to ?? '#'" + :behavior="linkBehavior" @mousedown="onMousedown" >
@@ -43,6 +44,7 @@ const props = defineProps<{ inline?: boolean; link?: boolean; to?: string; + linkBehavior?: null | 'window' | 'browser'; autofocus?: boolean; wait?: boolean; danger?: boolean; diff --git a/packages/frontend/src/pages/settings/2fa.qrdialog.vue b/packages/frontend/src/pages/settings/2fa.qrdialog.vue index 2ef664b9a363..73253b1ef43f 100644 --- a/packages/frontend/src/pages/settings/2fa.qrdialog.vue +++ b/packages/frontend/src/pages/settings/2fa.qrdialog.vue @@ -33,8 +33,12 @@ SPDX-License-Identifier: AGPL-3.0-only Google Authenticator -
{{ i18n.ts._2fa.step2 }}
{{ i18n.ts._2fa.step2Click }}
- +
{{ i18n.ts._2fa.step2 }}
+
+ + +
{{ i18n.ts.launchApp }}
+
@@ -177,8 +181,14 @@ function allDone() { transform: translateX(-50px); } -.qr { +.qrRoot { + display: block; + margin: 0 auto; width: 200px; max-width: 100%; } + +.qr { + width: 100%; +} From b96d9c6973b1c861306fdb9f51256cee5325a2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 30 Mar 2024 16:02:03 +0900 Subject: [PATCH 05/60] =?UTF-8?q?fix/enhance(frontend):=20=E6=98=A0?= =?UTF-8?q?=E5=83=8F=E3=83=BB=E9=9F=B3=E5=A3=B0=E5=91=A8=E3=82=8A=E3=81=AE?= =?UTF-8?q?=E6=94=B9=E4=BF=AE=20(#13206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): 映像・音声周りの改修 * fix * fix design * fix lint * キーボードショートカットを整備 * Update Changelog * fix * feat: ループ再生 * ネイティブの動作と同期されるように * Update Changelog * key指定を消す --- CHANGELOG.md | 3 + locales/index.d.ts | 18 +++ locales/ja-JP.yml | 7 + .../frontend/src/components/MkMediaAudio.vue | 112 ++++++++++++++- .../frontend/src/components/MkMediaVideo.vue | 131 +++++++++++++++++- packages/frontend/src/components/MkMenu.vue | 91 +++++++++++- .../src/components/MkSwitch.button.vue | 13 +- .../frontend/src/pages/settings/general.vue | 2 + packages/frontend/src/scripts/keycode.ts | 1 + packages/frontend/src/store.ts | 4 + packages/frontend/src/types/menu.ts | 10 +- 11 files changed, 373 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5963549cc654..ebf932012959 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ - Enhance: ページのデザインを変更 - Enhance: 2要素認証(ワンタイムパスワード)の入力欄を改善 - Enhance: 「今日誕生日のフォロー中ユーザー」ウィジェットを手動でリロードできるように +- Enhance: 映像・音声の再生にブラウザのネイティブプレイヤーを使用できるように +- Enhance: 映像・音声の再生メニューに「再生速度」「ループ再生」「ピクチャインピクチャ」を追加 +- Enhance: 映像・音声の再生にキーボードショートカットが使えるように - Fix: 一部のページ内リンクが正しく動作しない問題を修正 - Fix: 周年の実績が閏年を考慮しない問題を修正 - Fix: ローカルURLのプレビューポップアップが左上に表示される diff --git a/locales/index.d.ts b/locales/index.d.ts index 428cf9135cff..3dbe46c7b2f6 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4932,6 +4932,10 @@ export interface Locale extends ILocale { * アプリを起動 */ "launchApp": string; + /** + * 動画・音声の再生にブラウザのUIを使用する + */ + "useNativeUIForVideoAudioPlayer": string; "_bubbleGame": { /** * 遊び方 @@ -9834,6 +9838,20 @@ export interface Locale extends ILocale { */ "summaryProxyDescription2": string; }; + "_mediaControls": { + /** + * ピクチャインピクチャ + */ + "pip": string; + /** + * 再生速度 + */ + "playbackRate": string; + /** + * ループ再生 + */ + "loop": string; + }; } declare const locales: { [lang: string]: Locale; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 9e76e420c38a..aa765d13108f 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1229,6 +1229,7 @@ notUsePleaseLeaveBlank: "使用しない場合は空欄にしてください" useTotp: "ワンタイムパスワードを使う" useBackupCode: "バックアップコードを使う" launchApp: "アプリを起動" +useNativeUIForVideoAudioPlayer: "動画・音声の再生にブラウザのUIを使用する" _bubbleGame: howToPlay: "遊び方" @@ -2619,3 +2620,9 @@ _urlPreviewSetting: summaryProxy: "プレビューを生成するプロキシのエンドポイント" summaryProxyDescription: "Misskey本体ではなく、サマリープロキシを使用してプレビューを生成します。" summaryProxyDescription2: "プロキシには下記パラメータがクエリ文字列として連携されます。プロキシ側がこれらをサポートしない場合、設定値は無視されます。" + +_mediaControls: + pip: "ピクチャインピクチャ" + playbackRate: "再生速度" + loop: "ループ再生" + \ No newline at end of file diff --git a/packages/frontend/src/components/MkMediaAudio.vue b/packages/frontend/src/components/MkMediaAudio.vue index 96c9b9fd66c8..5d2edf467e54 100644 --- a/packages/frontend/src/components/MkMediaAudio.vue +++ b/packages/frontend/src/components/MkMediaAudio.vue @@ -5,11 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only