Merge: upstream/develop -> feat/hide-sensitive-from-antenna
This commit is contained in:
		
						commit
						46a13d07a5
					
				|  | @ -9,7 +9,7 @@ updates: | |||
|   directory: "/" | ||||
|   schedule: | ||||
|     interval: daily | ||||
|   open-pull-requests-limit: 100 | ||||
|   open-pull-requests-limit: 0 | ||||
| 
 | ||||
| # Add only the root, not each workspace item | ||||
| # https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027 | ||||
|  | @ -17,7 +17,7 @@ updates: | |||
|   directory: "/" | ||||
|   schedule: | ||||
|     interval: daily | ||||
|   open-pull-requests-limit: 10 | ||||
|   open-pull-requests-limit: 0 | ||||
|   # List dependencies required to be updated together, sharing the same version numbers. | ||||
|   # Those who simply have the common owner (e.g. @fastify) don't need to be listed. | ||||
|   groups: | ||||
|  |  | |||
|  | @ -20,12 +20,12 @@ jobs: | |||
| 
 | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
| 
 | ||||
|       - run: corepack enable | ||||
| 
 | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@v4.1.0 | ||||
|         uses: actions/setup-node@v4.2.0 | ||||
|         with: | ||||
|           node-version-file: '.node-version' | ||||
|           cache: 'pnpm' | ||||
|  |  | |||
|  | @ -12,9 +12,9 @@ jobs: | |||
| 
 | ||||
|     steps: | ||||
|       - name: Checkout head | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
|       - name: Setup Node.js | ||||
|         uses: actions/setup-node@v4.1.0 | ||||
|         uses: actions/setup-node@v4.2.0 | ||||
|         with: | ||||
|           node-version-file: '.node-version' | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ jobs: | |||
|     if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} | ||||
|     steps: | ||||
|       - name: checkout | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
|         with: | ||||
|           submodules: true | ||||
|           persist-credentials: false | ||||
|  | @ -29,7 +29,7 @@ jobs: | |||
| 
 | ||||
|       - name: setup node | ||||
|         id: setup-node | ||||
|         uses: actions/setup-node@v4.1.0 | ||||
|         uses: actions/setup-node@v4.2.0 | ||||
|         with: | ||||
|           node-version-file: '.node-version' | ||||
|           cache: pnpm | ||||
|  | @ -66,7 +66,7 @@ jobs: | |||
|     if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} | ||||
|     steps: | ||||
|       - name: checkout | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
|         with: | ||||
|           submodules: true | ||||
|           persist-credentials: false | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ jobs: | |||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
|       - name: Check version | ||||
|         run: | | ||||
|           if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ jobs: | |||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
|       - name: Check | ||||
|         run: | | ||||
|           counter=0 | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ jobs: | |||
|   check_copyright_year: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|     - run: | | ||||
|         if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then | ||||
|           echo "Please change copyright year!" | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ jobs: | |||
|       wait_time: ${{ steps.get-wait-time.outputs.wait_time }} | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
| 
 | ||||
|       - name: Check allowed users | ||||
|         id: check-allowed-users | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ jobs: | |||
|           platform=${{ matrix.platform }} | ||||
|           echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV | ||||
|       - name: Check out the repo | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|       - name: Log in to Docker Hub | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ jobs: | |||
|           platform=${{ matrix.platform }} | ||||
|           echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV | ||||
|       - name: Check out the repo | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|       - name: Docker meta | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ jobs: | |||
|       DOCKER_CONTENT_TRUST: 1 | ||||
|       DOCKLE_VERSION: 0.4.14 | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4.1.1 | ||||
|       - uses: actions/checkout@v4.2.2 | ||||
|       - name: Download and install dockle v${{ env.DOCKLE_VERSION }} | ||||
|         run: | | ||||
|           curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb" | ||||
|  |  | |||
|  | @ -30,14 +30,14 @@ jobs: | |||
|             ref: refs/pull/${{ github.event.number }}/merge | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         ref: ${{ matrix.ref }} | ||||
|         submodules: true | ||||
|     - name: Install pnpm | ||||
|       uses: pnpm/action-setup@v4 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v4.1.0 | ||||
|       uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|         cache: 'pnpm' | ||||
|  |  | |||
|  | @ -36,12 +36,12 @@ jobs: | |||
|   pnpm_install: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|         submodules: true | ||||
|     - uses: pnpm/action-setup@v4 | ||||
|     - uses: actions/setup-node@v4.1.0 | ||||
|     - uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version-file: '.node-version' | ||||
|         cache: 'pnpm' | ||||
|  | @ -67,12 +67,12 @@ jobs: | |||
|       eslint-cache-version: v1 | ||||
|       eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }} | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|         submodules: true | ||||
|     - uses: pnpm/action-setup@v4 | ||||
|     - uses: actions/setup-node@v4.1.0 | ||||
|     - uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version-file: '.node-version' | ||||
|         cache: 'pnpm' | ||||
|  | @ -97,12 +97,12 @@ jobs: | |||
|         - sw | ||||
|         - misskey-js | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|         submodules: true | ||||
|     - uses: pnpm/action-setup@v4 | ||||
|     - uses: actions/setup-node@v4.1.0 | ||||
|     - uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version-file: '.node-version' | ||||
|         cache: 'pnpm' | ||||
|  |  | |||
|  | @ -18,12 +18,12 @@ jobs: | |||
|     runs-on: ubuntu-latest | ||||
|     continue-on-error: true | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|         submodules: true | ||||
|     - uses: pnpm/action-setup@v4 | ||||
|     - uses: actions/setup-node@v4.1.0 | ||||
|     - uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version-file: '.node-version' | ||||
|         cache: 'pnpm' | ||||
|  |  | |||
|  | @ -23,13 +23,13 @@ jobs: | |||
|         node-version: [22.11.0] | ||||
| 
 | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4.1.1 | ||||
|       - uses: actions/checkout@v4.2.2 | ||||
|         with: | ||||
|           submodules: true | ||||
|       - name: Install pnpm | ||||
|         uses: pnpm/action-setup@v4 | ||||
|       - name: Use Node.js ${{ matrix.node-version }} | ||||
|         uses: actions/setup-node@v4.1.0 | ||||
|         uses: actions/setup-node@v4.2.0 | ||||
|         with: | ||||
|           node-version: ${{ matrix.node-version }} | ||||
|           cache: 'pnpm' | ||||
|  |  | |||
|  | @ -26,12 +26,12 @@ jobs: | |||
|       NODE_OPTIONS: "--max_old_space_size=7168" | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       if: github.event_name != 'pull_request_target' | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|         submodules: true | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       if: github.event_name == 'pull_request_target' | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|  | @ -46,7 +46,7 @@ jobs: | |||
|     - name: Install pnpm | ||||
|       uses: pnpm/action-setup@v4 | ||||
|     - name: Use Node.js 20.x | ||||
|       uses: actions/setup-node@v4.1.0 | ||||
|       uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version-file: '.node-version' | ||||
|         cache: 'pnpm' | ||||
|  |  | |||
|  | @ -45,7 +45,7 @@ jobs: | |||
|           - 56312:6379 | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         submodules: true | ||||
|     - name: Install pnpm | ||||
|  | @ -66,7 +66,7 @@ jobs: | |||
|           fi | ||||
|         done | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v4.1.0 | ||||
|       uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|         cache: 'pnpm' | ||||
|  | @ -108,13 +108,13 @@ jobs: | |||
|           - 56312:6379 | ||||
| 
 | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4.1.1 | ||||
|       - uses: actions/checkout@v4.2.2 | ||||
|         with: | ||||
|           submodules: true | ||||
|       - name: Install pnpm | ||||
|         uses: pnpm/action-setup@v4 | ||||
|       - name: Use Node.js ${{ matrix.node-version }} | ||||
|         uses: actions/setup-node@v4.1.0 | ||||
|         uses: actions/setup-node@v4.2.0 | ||||
|         with: | ||||
|           node-version: ${{ matrix.node-version }} | ||||
|           cache: 'pnpm' | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ jobs: | |||
|             fi | ||||
|           done | ||||
|       - name: Use Node.js ${{ matrix.node-version }} | ||||
|         uses: actions/setup-node@v4.1.0 | ||||
|         uses: actions/setup-node@v4.2.0 | ||||
|         with: | ||||
|           node-version: ${{ matrix.node-version }} | ||||
|           cache: 'pnpm' | ||||
|  |  | |||
|  | @ -36,13 +36,13 @@ jobs: | |||
|         node-version: [22.11.0] | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         submodules: true | ||||
|     - name: Install pnpm | ||||
|       uses: pnpm/action-setup@v4 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v4.1.0 | ||||
|       uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|         cache: 'pnpm' | ||||
|  | @ -86,7 +86,7 @@ jobs: | |||
|           - 56312:6379 | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         submodules: true | ||||
|     # https://github.com/cypress-io/cypress-docker-images/issues/150 | ||||
|  | @ -98,7 +98,7 @@ jobs: | |||
|     - name: Install pnpm | ||||
|       uses: pnpm/action-setup@v4 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v4.1.0 | ||||
|       uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|         cache: 'pnpm' | ||||
|  |  | |||
|  | @ -31,12 +31,12 @@ jobs: | |||
| 
 | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v4.1.1 | ||||
|         uses: actions/checkout@v4.2.2 | ||||
| 
 | ||||
|       - run: corepack enable | ||||
| 
 | ||||
|       - name: Setup Node.js ${{ matrix.node-version }} | ||||
|         uses: actions/setup-node@v4.1.0 | ||||
|         uses: actions/setup-node@v4.2.0 | ||||
|         with: | ||||
|           node-version: ${{ matrix.node-version }} | ||||
|           cache: 'pnpm' | ||||
|  |  | |||
|  | @ -21,13 +21,13 @@ jobs: | |||
|         node-version: [22.11.0] | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         submodules: true | ||||
|     - name: Install pnpm | ||||
|       uses: pnpm/action-setup@v4 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v4.1.0 | ||||
|       uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|         cache: 'pnpm' | ||||
|  |  | |||
|  | @ -25,13 +25,13 @@ jobs: | |||
|         node-version: [22.11.0] | ||||
| 
 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4.1.1 | ||||
|     - uses: actions/checkout@v4.2.2 | ||||
|       with: | ||||
|         submodules: true | ||||
|     - name: Install pnpm | ||||
|       uses: pnpm/action-setup@v4 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v4.1.0 | ||||
|       uses: actions/setup-node@v4.2.0 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|         cache: 'pnpm' | ||||
|  |  | |||
							
								
								
									
										13
									
								
								CHANGELOG.md
								
								
								
								
							
							
						
						
									
										13
									
								
								CHANGELOG.md
								
								
								
								
							|  | @ -1,8 +1,9 @@ | |||
| ## Unreleased | ||||
| ## 2025.2.1 | ||||
| 
 | ||||
| ### General | ||||
| - Enhance: アンテナでセンシティブなチャンネルのノートを除外できるように `#14177` | ||||
| - Feat: アクセストークン発行時に通知するように | ||||
| - 依存関係の更新 | ||||
| 
 | ||||
| ### Client | ||||
| - Feat: 投稿フォームで画像をプレビュー可能に | ||||
|  | @ -10,13 +11,21 @@ | |||
| - Enhance: アンテナ、リスト等の名前をカラム名のデフォルト値にするように `#13992` | ||||
| - Enhance: クライアントエラー画面の多言語対応 | ||||
| - Enhance: 開発者モードでメニューからファイルIDをコピー出来るように `#15441' | ||||
| - Enhance: ノートに埋め込まれたメディアのコンテキストメニューから管理者用のファイル管理画面を開けるように ( #15440 ) | ||||
| - Enhance: リアクションする際に確認ダイアログを表示できるように | ||||
| - Enhance: CWの注釈で入力済みの文字数を表示 | ||||
| - Fix: コンディショナルロールを手動で割り当てできる導線を削除 `#13529` | ||||
| - Fix: 埋め込みプレイヤーから外部ページに移動できない問題を修正 | ||||
| - Fix: Play の再読込時に UI が以前の状態を引き継いでしまう問題を修正 `#14378` | ||||
| - Fix: カスタム絵文字管理画面(beta)にてisSensitive/localOnlyの絞り込みが上手くいかない問題の修正 ( #15445 ) | ||||
| - Fix: CWの注釈が100文字を超えている場合、ノート投稿ボタンを非アクティブに | ||||
| 
 | ||||
| ### Server | ||||
| - Fix: `following/invalidate`でフォロワーを解除しようとしているユーザーの情報を返すように | ||||
| - Fix: オブジェクトストレージの設定でPrefixを設定していなかった場合nullまたは空文字になる問題を修正 | ||||
| 
 | ||||
| - Fix: pgroongaでの検索時にはじめのキーワードのみが検索に使用される問題を修正   | ||||
|   (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/886) | ||||
| - Fix: メールアドレスの形式が正しくなければ以降の処理を行わないように | ||||
| 
 | ||||
| ## 2025.2.0 | ||||
| 
 | ||||
|  |  | |||
|  | @ -5258,6 +5258,14 @@ export interface Locale extends ILocale { | |||
|      * このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。 | ||||
|      */ | ||||
|     "federationDisabled": string; | ||||
|     /** | ||||
|      * リアクションする際に確認する | ||||
|      */ | ||||
|     "confirmOnReact": string; | ||||
|     /** | ||||
|      * " {emoji} " をリアクションしますか? | ||||
|      */ | ||||
|     "reactAreYouSure": ParameterizedString<"emoji">; | ||||
|     "_accountSettings": { | ||||
|         /** | ||||
|          * コンテンツの表示にログインを必須にする | ||||
|  |  | |||
|  | @ -1310,6 +1310,8 @@ availableRoles: "利用可能なロール" | |||
| acknowledgeNotesAndEnable: "注意事項を理解した上でオンにします。" | ||||
| federationSpecified: "このサーバーはホワイトリスト連合で運用されています。管理者が指定したサーバー以外とやり取りすることはできません。" | ||||
| federationDisabled: "このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。" | ||||
| confirmOnReact: "リアクションする際に確認する" | ||||
| reactAreYouSure: "\" {emoji} \" をリアクションしますか?" | ||||
| 
 | ||||
| _accountSettings: | ||||
|   requireSigninToViewContents: "コンテンツの表示にログインを必須にする" | ||||
|  |  | |||
							
								
								
									
										38
									
								
								package.json
								
								
								
								
							
							
						
						
									
										38
									
								
								package.json
								
								
								
								
							|  | @ -1,12 +1,12 @@ | |||
| { | ||||
| 	"name": "misskey", | ||||
| 	"version": "2025.2.0", | ||||
| 	"version": "2025.2.1-alpha.0", | ||||
| 	"codename": "nasubi", | ||||
| 	"repository": { | ||||
| 		"type": "git", | ||||
| 		"url": "https://github.com/misskey-dev/misskey.git" | ||||
| 	}, | ||||
| 	"packageManager": "pnpm@9.6.0", | ||||
| 	"packageManager": "pnpm@9.15.4", | ||||
| 	"workspaces": [ | ||||
| 		"packages/frontend-shared", | ||||
| 		"packages/frontend", | ||||
|  | @ -47,35 +47,35 @@ | |||
| 		"cleanall": "pnpm clean-all" | ||||
| 	}, | ||||
| 	"resolutions": { | ||||
| 		"chokidar": "3.5.3", | ||||
| 		"chokidar": "3.6.0", | ||||
| 		"lodash": "4.17.21" | ||||
| 	}, | ||||
| 	"dependencies": { | ||||
| 		"cssnano": "6.1.2", | ||||
| 		"cssnano": "7.0.6", | ||||
| 		"execa": "8.0.1", | ||||
| 		"fast-glob": "3.3.2", | ||||
| 		"fast-glob": "3.3.3", | ||||
| 		"ignore-walk": "6.0.5", | ||||
| 		"js-yaml": "4.1.0", | ||||
| 		"postcss": "8.4.49", | ||||
| 		"postcss": "8.5.2", | ||||
| 		"tar": "6.2.1", | ||||
| 		"terser": "5.36.0", | ||||
| 		"typescript": "5.6.3", | ||||
| 		"esbuild": "0.24.0", | ||||
| 		"glob": "11.0.0" | ||||
| 		"terser": "5.39.0", | ||||
| 		"typescript": "5.7.3", | ||||
| 		"esbuild": "0.25.0", | ||||
| 		"glob": "11.0.1" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@misskey-dev/eslint-plugin": "2.0.3", | ||||
| 		"@types/node": "22.9.0", | ||||
| 		"@typescript-eslint/eslint-plugin": "7.17.0", | ||||
| 		"@typescript-eslint/parser": "7.17.0", | ||||
| 		"@misskey-dev/eslint-plugin": "2.1.0", | ||||
| 		"@types/node": "22.13.4", | ||||
| 		"@typescript-eslint/eslint-plugin": "8.24.0", | ||||
| 		"@typescript-eslint/parser": "8.24.0", | ||||
| 		"cross-env": "7.0.3", | ||||
| 		"cypress": "13.15.2", | ||||
| 		"eslint": "9.14.0", | ||||
| 		"globals": "15.12.0", | ||||
| 		"cypress": "14.0.3", | ||||
| 		"eslint": "9.20.1", | ||||
| 		"globals": "15.15.0", | ||||
| 		"ncp": "2.0.0", | ||||
| 		"start-server-and-test": "2.0.8" | ||||
| 		"start-server-and-test": "2.0.10" | ||||
| 	}, | ||||
| 	"optionalDependencies": { | ||||
| 		"@tensorflow/tfjs-core": "4.4.0" | ||||
| 		"@tensorflow/tfjs-core": "4.22.0" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -37,20 +37,20 @@ | |||
| 	}, | ||||
| 	"optionalDependencies": { | ||||
| 		"@swc/core-android-arm64": "1.3.11", | ||||
| 		"@swc/core-darwin-arm64": "1.3.56", | ||||
| 		"@swc/core-darwin-x64": "1.3.56", | ||||
| 		"@swc/core-darwin-arm64": "1.10.16", | ||||
| 		"@swc/core-darwin-x64": "1.10.16", | ||||
| 		"@swc/core-freebsd-x64": "1.3.11", | ||||
| 		"@swc/core-linux-arm-gnueabihf": "1.3.56", | ||||
| 		"@swc/core-linux-arm64-gnu": "1.3.56", | ||||
| 		"@swc/core-linux-arm64-musl": "1.3.56", | ||||
| 		"@swc/core-linux-x64-gnu": "1.3.56", | ||||
| 		"@swc/core-linux-x64-musl": "1.3.56", | ||||
| 		"@swc/core-win32-arm64-msvc": "1.3.56", | ||||
| 		"@swc/core-win32-ia32-msvc": "1.3.56", | ||||
| 		"@swc/core-win32-x64-msvc": "1.3.56", | ||||
| 		"@tensorflow/tfjs": "4.4.0", | ||||
| 		"@tensorflow/tfjs-node": "4.4.0", | ||||
| 		"bufferutil": "4.0.7", | ||||
| 		"@swc/core-linux-arm-gnueabihf": "1.10.16", | ||||
| 		"@swc/core-linux-arm64-gnu": "1.10.16", | ||||
| 		"@swc/core-linux-arm64-musl": "1.10.16", | ||||
| 		"@swc/core-linux-x64-gnu": "1.10.16", | ||||
| 		"@swc/core-linux-x64-musl": "1.10.16", | ||||
| 		"@swc/core-win32-arm64-msvc": "1.10.16", | ||||
| 		"@swc/core-win32-ia32-msvc": "1.10.16", | ||||
| 		"@swc/core-win32-x64-msvc": "1.10.16", | ||||
| 		"@tensorflow/tfjs": "4.22.0", | ||||
| 		"@tensorflow/tfjs-node": "4.22.0", | ||||
| 		"bufferutil": "4.0.9", | ||||
| 		"slacc-android-arm-eabi": "0.0.10", | ||||
| 		"slacc-android-arm64": "0.0.10", | ||||
| 		"slacc-darwin-arm64": "0.0.10", | ||||
|  | @ -64,37 +64,37 @@ | |||
| 		"slacc-linux-x64-musl": "0.0.10", | ||||
| 		"slacc-win32-arm64-msvc": "0.0.10", | ||||
| 		"slacc-win32-x64-msvc": "0.0.10", | ||||
| 		"utf-8-validate": "6.0.3" | ||||
| 		"utf-8-validate": "6.0.5" | ||||
| 	}, | ||||
| 	"dependencies": { | ||||
| 		"@aws-sdk/client-s3": "3.620.0", | ||||
| 		"@aws-sdk/lib-storage": "3.620.0", | ||||
| 		"@bull-board/api": "6.5.0", | ||||
| 		"@bull-board/fastify": "6.5.0", | ||||
| 		"@bull-board/ui": "6.5.0", | ||||
| 		"@aws-sdk/client-s3": "3.749.0", | ||||
| 		"@aws-sdk/lib-storage": "3.749.0", | ||||
| 		"@bull-board/api": "6.7.7", | ||||
| 		"@bull-board/fastify": "6.7.7", | ||||
| 		"@bull-board/ui": "6.7.7", | ||||
| 		"@discordapp/twemoji": "15.1.0", | ||||
| 		"@fastify/accepts": "5.0.1", | ||||
| 		"@fastify/cookie": "11.0.1", | ||||
| 		"@fastify/cors": "10.0.1", | ||||
| 		"@fastify/express": "4.0.1", | ||||
| 		"@fastify/http-proxy": "10.0.1", | ||||
| 		"@fastify/multipart": "9.0.1", | ||||
| 		"@fastify/static": "8.0.2", | ||||
| 		"@fastify/view": "10.0.1", | ||||
| 		"@fastify/accepts": "5.0.2", | ||||
| 		"@fastify/cookie": "11.0.2", | ||||
| 		"@fastify/cors": "10.0.2", | ||||
| 		"@fastify/express": "4.0.2", | ||||
| 		"@fastify/http-proxy": "10.0.2", | ||||
| 		"@fastify/multipart": "9.0.3", | ||||
| 		"@fastify/static": "8.1.0", | ||||
| 		"@fastify/view": "10.0.2", | ||||
| 		"@misskey-dev/sharp-read-bmp": "1.2.0", | ||||
| 		"@misskey-dev/summaly": "5.1.0", | ||||
| 		"@napi-rs/canvas": "0.1.56", | ||||
| 		"@nestjs/common": "10.4.7", | ||||
| 		"@nestjs/core": "10.4.7", | ||||
| 		"@nestjs/testing": "10.4.7", | ||||
| 		"@misskey-dev/summaly": "5.2.0", | ||||
| 		"@napi-rs/canvas": "0.1.67", | ||||
| 		"@nestjs/common": "11.0.9", | ||||
| 		"@nestjs/core": "11.0.9", | ||||
| 		"@nestjs/testing": "11.0.9", | ||||
| 		"@peertube/http-signature": "1.7.0", | ||||
| 		"@sentry/node": "8.38.0", | ||||
| 		"@sentry/profiling-node": "8.38.0", | ||||
| 		"@simplewebauthn/server": "10.0.1", | ||||
| 		"@sinonjs/fake-timers": "11.2.2", | ||||
| 		"@sentry/node": "8.55.0", | ||||
| 		"@sentry/profiling-node": "8.55.0", | ||||
| 		"@simplewebauthn/server": "12.0.0", | ||||
| 		"@sinonjs/fake-timers": "11.3.1", | ||||
| 		"@smithy/node-http-handler": "2.5.0", | ||||
| 		"@swc/cli": "0.3.12", | ||||
| 		"@swc/core": "1.9.2", | ||||
| 		"@swc/cli": "0.6.0", | ||||
| 		"@swc/core": "1.10.16", | ||||
| 		"@twemoji/parser": "15.1.1", | ||||
| 		"accepts": "1.3.8", | ||||
| 		"ajv": "8.17.1", | ||||
|  | @ -103,10 +103,10 @@ | |||
| 		"bcryptjs": "2.4.3", | ||||
| 		"blurhash": "2.0.5", | ||||
| 		"body-parser": "1.20.3", | ||||
| 		"bullmq": "5.26.1", | ||||
| 		"bullmq": "5.41.1", | ||||
| 		"cacheable-lookup": "7.0.0", | ||||
| 		"cbor": "9.0.2", | ||||
| 		"chalk": "5.3.0", | ||||
| 		"chalk": "5.4.1", | ||||
| 		"chalk-template": "1.1.0", | ||||
| 		"chokidar": "3.6.0", | ||||
| 		"cli-highlight": "2.1.11", | ||||
|  | @ -114,46 +114,46 @@ | |||
| 		"content-disposition": "0.5.4", | ||||
| 		"date-fns": "2.30.0", | ||||
| 		"deep-email-validator": "0.1.21", | ||||
| 		"fastify": "5.0.0", | ||||
| 		"fastify": "5.2.1", | ||||
| 		"fastify-raw-body": "5.0.0", | ||||
| 		"feed": "4.2.2", | ||||
| 		"file-type": "19.6.0", | ||||
| 		"fluent-ffmpeg": "2.1.3", | ||||
| 		"form-data": "4.0.1", | ||||
| 		"got": "14.4.4", | ||||
| 		"happy-dom": "15.11.4", | ||||
| 		"form-data": "4.0.2", | ||||
| 		"got": "14.4.6", | ||||
| 		"happy-dom": "16.8.1", | ||||
| 		"hpagent": "1.2.0", | ||||
| 		"htmlescape": "1.1.1", | ||||
| 		"http-link-header": "1.1.3", | ||||
| 		"ioredis": "5.4.1", | ||||
| 		"ioredis": "5.5.0", | ||||
| 		"ip-cidr": "4.0.2", | ||||
| 		"ipaddr.js": "2.2.0", | ||||
| 		"is-svg": "5.1.0", | ||||
| 		"js-yaml": "4.1.0", | ||||
| 		"jsdom": "24.1.1", | ||||
| 		"jsdom": "26.0.0", | ||||
| 		"json5": "2.2.3", | ||||
| 		"jsonld": "8.3.2", | ||||
| 		"jsonld": "8.3.3", | ||||
| 		"jsrsasign": "11.1.0", | ||||
| 		"juice": "11.0.0", | ||||
| 		"meilisearch": "0.45.0", | ||||
| 		"meilisearch": "0.48.2", | ||||
| 		"mfm-js": "0.24.0", | ||||
| 		"microformats-parser": "2.0.2", | ||||
| 		"mime-types": "2.1.35", | ||||
| 		"misskey-js": "workspace:*", | ||||
| 		"misskey-reversi": "workspace:*", | ||||
| 		"ms": "3.0.0-canary.1", | ||||
| 		"nanoid": "5.0.8", | ||||
| 		"nanoid": "5.1.0", | ||||
| 		"nested-property": "4.0.0", | ||||
| 		"node-fetch": "3.3.2", | ||||
| 		"nodemailer": "6.9.16", | ||||
| 		"nodemailer": "6.10.0", | ||||
| 		"nsfwjs": "4.2.0", | ||||
| 		"oauth": "0.10.0", | ||||
| 		"oauth2orize": "1.12.0", | ||||
| 		"oauth2orize-pkce": "0.1.2", | ||||
| 		"os-utils": "0.0.14", | ||||
| 		"otpauth": "9.3.4", | ||||
| 		"otpauth": "9.3.6", | ||||
| 		"parse5": "7.2.1", | ||||
| 		"pg": "8.13.1", | ||||
| 		"pg": "8.13.3", | ||||
| 		"pkce-challenge": "4.1.0", | ||||
| 		"probe-image-size": "7.2.3", | ||||
| 		"promise-limit": "2.7.0", | ||||
|  | @ -167,19 +167,19 @@ | |||
| 		"rename": "1.0.4", | ||||
| 		"rss-parser": "3.13.0", | ||||
| 		"rxjs": "7.8.1", | ||||
| 		"sanitize-html": "2.13.1", | ||||
| 		"secure-json-parse": "2.7.0", | ||||
| 		"sanitize-html": "2.14.0", | ||||
| 		"secure-json-parse": "3.0.2", | ||||
| 		"sharp": "0.33.5", | ||||
| 		"slacc": "0.0.10", | ||||
| 		"strict-event-emitter-types": "2.0.0", | ||||
| 		"stringz": "2.1.0", | ||||
| 		"systeminformation": "5.23.5", | ||||
| 		"systeminformation": "5.25.11", | ||||
| 		"tinycolor2": "1.6.0", | ||||
| 		"tmp": "0.2.3", | ||||
| 		"tsc-alias": "1.8.10", | ||||
| 		"tsconfig-paths": "4.2.0", | ||||
| 		"typeorm": "0.3.20", | ||||
| 		"typescript": "5.6.3", | ||||
| 		"typescript": "5.7.3", | ||||
| 		"ulid": "2.3.0", | ||||
| 		"vary": "1.1.2", | ||||
| 		"web-push": "3.6.7", | ||||
|  | @ -188,8 +188,8 @@ | |||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@jest/globals": "29.7.0", | ||||
| 		"@nestjs/platform-express": "10.4.7", | ||||
| 		"@simplewebauthn/types": "10.0.0", | ||||
| 		"@nestjs/platform-express": "10.4.15", | ||||
| 		"@simplewebauthn/types": "12.0.0", | ||||
| 		"@swc/jest": "0.2.37", | ||||
| 		"@types/accepts": "1.3.7", | ||||
| 		"@types/archiver": "6.0.3", | ||||
|  | @ -204,15 +204,15 @@ | |||
| 		"@types/js-yaml": "4.0.9", | ||||
| 		"@types/jsdom": "21.1.7", | ||||
| 		"@types/jsonld": "1.5.15", | ||||
| 		"@types/jsrsasign": "10.5.14", | ||||
| 		"@types/jsrsasign": "10.5.15", | ||||
| 		"@types/mime-types": "2.1.4", | ||||
| 		"@types/ms": "0.7.34", | ||||
| 		"@types/node": "22.9.0", | ||||
| 		"@types/nodemailer": "6.4.16", | ||||
| 		"@types/node": "22.13.4", | ||||
| 		"@types/nodemailer": "6.4.17", | ||||
| 		"@types/oauth": "0.9.6", | ||||
| 		"@types/oauth2orize": "1.11.5", | ||||
| 		"@types/oauth2orize-pkce": "0.1.2", | ||||
| 		"@types/pg": "8.11.10", | ||||
| 		"@types/pg": "8.11.11", | ||||
| 		"@types/pug": "2.0.10", | ||||
| 		"@types/qrcode": "1.5.5", | ||||
| 		"@types/random-seed": "0.3.5", | ||||
|  | @ -226,18 +226,18 @@ | |||
| 		"@types/tmp": "0.2.6", | ||||
| 		"@types/vary": "1.1.3", | ||||
| 		"@types/web-push": "3.6.4", | ||||
| 		"@types/ws": "8.5.13", | ||||
| 		"@typescript-eslint/eslint-plugin": "7.17.0", | ||||
| 		"@typescript-eslint/parser": "7.17.0", | ||||
| 		"aws-sdk-client-mock": "4.0.1", | ||||
| 		"@types/ws": "8.5.14", | ||||
| 		"@typescript-eslint/eslint-plugin": "8.24.0", | ||||
| 		"@typescript-eslint/parser": "8.24.0", | ||||
| 		"aws-sdk-client-mock": "4.1.0", | ||||
| 		"cross-env": "7.0.3", | ||||
| 		"eslint-plugin-import": "2.30.0", | ||||
| 		"eslint-plugin-import": "2.31.0", | ||||
| 		"execa": "8.0.1", | ||||
| 		"fkill": "9.0.0", | ||||
| 		"jest": "29.7.0", | ||||
| 		"jest-mock": "29.7.0", | ||||
| 		"nodemon": "3.1.7", | ||||
| 		"pid-port": "1.0.0", | ||||
| 		"nodemon": "3.1.9", | ||||
| 		"pid-port": "1.0.2", | ||||
| 		"simple-oauth2": "5.1.0" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -105,8 +105,8 @@ type Source = { | |||
| 
 | ||||
| 	logging?: { | ||||
| 		sql?: { | ||||
| 			disableQueryTruncation? : boolean, | ||||
| 			enableQueryParamLogging? : boolean, | ||||
| 			disableQueryTruncation?: boolean, | ||||
| 			enableQueryParamLogging?: boolean, | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|  | @ -166,8 +166,8 @@ export type Config = { | |||
| 	signToActivityPubGet: boolean | undefined; | ||||
| 	logging?: { | ||||
| 		sql?: { | ||||
| 			disableQueryTruncation? : boolean, | ||||
| 			enableQueryParamLogging? : boolean, | ||||
| 			disableQueryTruncation?: boolean, | ||||
| 			enableQueryParamLogging?: boolean, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ export type CaptchaSetting = { | |||
| 		siteKey: string | null; | ||||
| 		secretKey: string | null; | ||||
| 	} | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export class CaptchaError extends Error { | ||||
| 	public readonly code: CaptchaErrorCode; | ||||
|  | @ -59,11 +59,11 @@ export class CaptchaError extends Error { | |||
| 
 | ||||
| export type CaptchaSaveSuccess = { | ||||
| 	success: true; | ||||
| } | ||||
| }; | ||||
| export type CaptchaSaveFailure = { | ||||
| 	success: false; | ||||
| 	error: CaptchaError; | ||||
| } | ||||
| }; | ||||
| export type CaptchaSaveResult = CaptchaSaveSuccess | CaptchaSaveFailure; | ||||
| 
 | ||||
| type CaptchaResponse = { | ||||
|  |  | |||
|  | @ -164,6 +164,13 @@ export class EmailService { | |||
| 		available: boolean; | ||||
| 		reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp' | 'banned' | 'network' | 'blacklist'; | ||||
| 	}> { | ||||
| 		if (!this.utilityService.validateEmailFormat(emailAddress)) { | ||||
| 			return { | ||||
| 				available: false, | ||||
| 				reason: 'format', | ||||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		const exist = await this.userProfilesRepository.countBy({ | ||||
| 			emailVerified: true, | ||||
| 			email: emailAddress, | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import { DI } from '@/di-symbols.js'; | |||
| import { bindThis } from '@/decorators.js'; | ||||
| import { IdService } from '@/core/IdService.js'; | ||||
| 
 | ||||
| export type FanoutTimelineName = | ||||
| export type FanoutTimelineName = ( | ||||
| 	// home timeline
 | ||||
| 	| `homeTimeline:${string}` | ||||
| 	| `homeTimelineWithFiles:${string}` // only notes with files are included
 | ||||
|  | @ -37,6 +37,7 @@ export type FanoutTimelineName = | |||
| 
 | ||||
| 	// role timelines
 | ||||
| 	| `roleTimeline:${string}` // any notes are included
 | ||||
| ); | ||||
| 
 | ||||
| @Injectable() | ||||
| export class FanoutTimelineService { | ||||
|  |  | |||
|  | @ -211,7 +211,7 @@ type SerializedAll<T> = { | |||
| 
 | ||||
| type UndefinedAsNullAll<T> = { | ||||
| 	[K in keyof T]: T[K] extends undefined ? null : T[K]; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export interface InternalEventTypes { | ||||
| 	userChangeSuspendedState: { id: MiUser['id']; isSuspended: MiUser['isSuspended']; }; | ||||
|  |  | |||
|  | @ -492,7 +492,8 @@ export class MfmService { | |||
| 
 | ||||
| 		appendChildren(nodes, body); | ||||
| 
 | ||||
| 		const serialized = new XMLSerializer().serializeToString(body); | ||||
| 		// Remove the unnecessary namespace
 | ||||
| 		const serialized = new XMLSerializer().serializeToString(body).replace(/^\s*<p xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">/, '<p>'); | ||||
| 
 | ||||
| 		happyDOM.close().catch(err => {}); | ||||
| 
 | ||||
|  |  | |||
|  | @ -220,7 +220,7 @@ export class SearchService { | |||
| 			.leftJoinAndSelect('renote.user', 'renoteUser'); | ||||
| 
 | ||||
| 		if (this.config.fulltextSearch?.provider === 'sqlPgroonga') { | ||||
| 			query.andWhere('note.text &@ :q', { q }); | ||||
| 			query.andWhere('note.text &@~ :q', { q }); | ||||
| 		} else { | ||||
| 			query.andWhere('LOWER(note.text) LIKE :q', { q: `%${ sqlLikeEscape(q.toLowerCase()) }%` }); | ||||
| 		} | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ import { QueueService } from '@/core/QueueService.js'; | |||
| import type { OnApplicationShutdown } from '@nestjs/common'; | ||||
| 
 | ||||
| export type UserWebhookPayload<T extends WebhookEventTypes> = | ||||
| 	T extends 'note' | 'reply' | 'renote' |'mention' ? { | ||||
| 	T extends 'note' | 'reply' | 'renote' | 'mention' ? { | ||||
| 		note: Packed<'Note'>, | ||||
| 	} : | ||||
| 	T extends 'follow' | 'unfollow' ? { | ||||
|  |  | |||
|  | @ -38,6 +38,14 @@ export class UtilityService { | |||
| 		return this.punyHost(uri) === this.toPuny(this.config.host); | ||||
| 	} | ||||
| 
 | ||||
| 	// メールアドレスのバリデーションを行う
 | ||||
| 	// https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
 | ||||
| 	@bindThis | ||||
| 	public validateEmailFormat(email: string): boolean { | ||||
| 		const regexp = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; | ||||
| 		return regexp.test(email); | ||||
| 	} | ||||
| 
 | ||||
| 	@bindThis | ||||
| 	public isBlockedHost(blockedHosts: string[], host: string | null): boolean { | ||||
| 		if (host == null) return false; | ||||
|  |  | |||
|  | @ -127,11 +127,11 @@ export class WebAuthnService { | |||
| 		const { registrationInfo } = verification; | ||||
| 
 | ||||
| 		return { | ||||
| 			credentialID: registrationInfo.credentialID, | ||||
| 			credentialPublicKey: registrationInfo.credentialPublicKey, | ||||
| 			credentialID: registrationInfo.credential.id, | ||||
| 			credentialPublicKey: registrationInfo.credential.publicKey, | ||||
| 			attestationObject: registrationInfo.attestationObject, | ||||
| 			fmt: registrationInfo.fmt, | ||||
| 			counter: registrationInfo.counter, | ||||
| 			counter: registrationInfo.credential.counter, | ||||
| 			userVerified: registrationInfo.userVerified, | ||||
| 			credentialDeviceType: registrationInfo.credentialDeviceType, | ||||
| 			credentialBackedUp: registrationInfo.credentialBackedUp, | ||||
|  | @ -212,9 +212,9 @@ export class WebAuthnService { | |||
| 				expectedChallenge: challenge, | ||||
| 				expectedOrigin: relyingParty.origin, | ||||
| 				expectedRPID: relyingParty.rpId, | ||||
| 				authenticator: { | ||||
| 					credentialID: key.id, | ||||
| 					credentialPublicKey: Buffer.from(key.publicKey, 'base64url'), | ||||
| 				credential: { | ||||
| 					id: key.id, | ||||
| 					publicKey: Buffer.from(key.publicKey, 'base64url'), | ||||
| 					counter: key.counter, | ||||
| 					transports: key.transports ? key.transports as AuthenticatorTransportFuture[] : undefined, | ||||
| 				}, | ||||
|  | @ -292,9 +292,9 @@ export class WebAuthnService { | |||
| 				expectedChallenge: challenge, | ||||
| 				expectedOrigin: relyingParty.origin, | ||||
| 				expectedRPID: relyingParty.rpId, | ||||
| 				authenticator: { | ||||
| 					credentialID: key.id, | ||||
| 					credentialPublicKey: Buffer.from(key.publicKey, 'base64url'), | ||||
| 				credential: { | ||||
| 					id: key.id, | ||||
| 					publicKey: Buffer.from(key.publicKey, 'base64url'), | ||||
| 					counter: key.counter, | ||||
| 					transports: key.transports ? key.transports as AuthenticatorTransportFuture[] : undefined, | ||||
| 				}, | ||||
|  |  | |||
|  | @ -57,12 +57,14 @@ const ajv = new Ajv(); | |||
| 
 | ||||
| function isLocalUser(user: MiUser): user is MiLocalUser; | ||||
| function isLocalUser<T extends { host: MiUser['host'] }>(user: T): user is (T & { host: null; }); | ||||
| 
 | ||||
| function isLocalUser(user: MiUser | { host: MiUser['host'] }): boolean { | ||||
| 	return user.host == null; | ||||
| } | ||||
| 
 | ||||
| function isRemoteUser(user: MiUser): user is MiRemoteUser; | ||||
| function isRemoteUser<T extends { host: MiUser['host'] }>(user: T): user is (T & { host: string; }); | ||||
| 
 | ||||
| function isRemoteUser(user: MiUser | { host: MiUser['host'] }): boolean { | ||||
| 	return !isLocalUser(user); | ||||
| } | ||||
|  | @ -78,7 +80,7 @@ export type UserRelation = { | |||
| 	isBlocked: boolean | ||||
| 	isMuted: boolean | ||||
| 	isRenoteMuted: boolean | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| @Injectable() | ||||
| export class UserEntityService implements OnModuleInit { | ||||
|  |  | |||
|  | @ -143,7 +143,7 @@ type OfSchema = { | |||
| 	readonly anyOf?: ReadonlyArray<Schema>; | ||||
| 	readonly oneOf?: ReadonlyArray<Schema>; | ||||
| 	readonly allOf?: ReadonlyArray<Schema>; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export interface Schema extends OfSchema { | ||||
| 	readonly type?: TypeStringef; | ||||
|  | @ -217,7 +217,7 @@ type ObjectSchemaTypeDef<p extends Schema> = | |||
| 	: | ||||
| 	p['anyOf'] extends ReadonlyArray<Schema> ? never : // see CONTRIBUTING.md
 | ||||
| 	p['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<p['allOf']>> : | ||||
| 	any | ||||
| 	any; | ||||
| 
 | ||||
| type ObjectSchemaType<p extends Schema> = NullOrUndefined<p, ObjectSchemaTypeDef<p>>; | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
|  */ | ||||
| 
 | ||||
| export type JsonValue = JsonArray | JsonObject | string | number | boolean | null; | ||||
| export type JsonObject = {[K in string]?: JsonValue}; | ||||
| export type JsonObject = { [K in string]?: JsonValue }; | ||||
| export type JsonArray = JsonValue[]; | ||||
| 
 | ||||
| export function isJsonObject(value: JsonValue | undefined): value is JsonObject { | ||||
|  |  | |||
|  | @ -288,24 +288,24 @@ export class MiUser { | |||
| export type MiLocalUser = MiUser & { | ||||
| 	host: null; | ||||
| 	uri: null; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type MiPartialLocalUser = Partial<MiUser> & { | ||||
| 	id: MiUser['id']; | ||||
| 	host: null; | ||||
| 	uri: null; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type MiRemoteUser = MiUser & { | ||||
| 	host: string; | ||||
| 	uri: string; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type MiPartialRemoteUser = Partial<MiUser> & { | ||||
| 	id: MiUser['id']; | ||||
| 	host: string; | ||||
| 	uri: string; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export const localUsernameSchema = { type: 'string', pattern: /^\w{1,20}$/.toString().slice(1, -1) } as const; | ||||
| export const passwordSchema = { type: 'string', minLength: 1 } as const; | ||||
|  |  | |||
|  | @ -92,7 +92,7 @@ const sqlLogger = dbLogger.createSubLogger('sql', 'gray'); | |||
| export type LoggerProps = { | ||||
| 	disableQueryTruncation?: boolean; | ||||
| 	enableQueryParamLogging?: boolean; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function highlightSql(sql: string) { | ||||
| 	return highlight.highlight(sql, { | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ export type ModeratorInactivityEvaluationResult = { | |||
| 	isModeratorsInactive: boolean; | ||||
| 	inactiveModerators: MiUser[]; | ||||
| 	remainingTime: ModeratorInactivityRemainingTime; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type ModeratorInactivityRemainingTime = { | ||||
| 	time: number; | ||||
|  |  | |||
|  | @ -107,12 +107,12 @@ export class InboxProcessorService implements OnApplicationShutdown { | |||
| 
 | ||||
| 		// それでもわからなければ終了
 | ||||
| 		if (authUser == null) { | ||||
| 			throw new Bull.UnrecoverableError('skip: failed to resolve user'); | ||||
| 			throw new Bull.UnrecoverableError(`skip: failed to resolve user ${getApId(activity.actor)}`); | ||||
| 		} | ||||
| 
 | ||||
| 		// publicKey がなくても終了
 | ||||
| 		if (authUser.key == null) { | ||||
| 			throw new Bull.UnrecoverableError('skip: failed to resolve user publicKey'); | ||||
| 			throw new Bull.UnrecoverableError(`skip: failed to resolve user publicKey ${getApId(activity.actor)}`); | ||||
| 		} | ||||
| 
 | ||||
| 		// HTTP-Signatureの検証
 | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ export type RelationshipJobData = { | |||
| 	silent?: boolean; | ||||
| 	requestId?: string; | ||||
| 	withReplies?: boolean; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type DbJobData<T extends keyof DbJobMap> = DbJobMap[T]; | ||||
| 
 | ||||
|  | @ -61,11 +61,11 @@ export type DbJobMap = { | |||
| 	importUserLists: DbUserImportJobData; | ||||
| 	importCustomEmojis: DbUserImportJobData; | ||||
| 	deleteAccount: DbUserDeleteJobData; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type DbJobDataWithUser = { | ||||
| 	user: ThinUser; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type DbExportFollowingData = { | ||||
| 	user: ThinUser; | ||||
|  | @ -75,7 +75,7 @@ export type DbExportFollowingData = { | |||
| 
 | ||||
| export type DBExportAntennasData = { | ||||
| 	user: ThinUser | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type DbUserDeleteJobData = { | ||||
| 	user: ThinUser; | ||||
|  | @ -91,7 +91,7 @@ export type DbUserImportJobData = { | |||
| export type DBAntennaImportJobData = { | ||||
| 	user: ThinUser, | ||||
| 	antenna: Antenna | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type DbUserImportToDbJobData = { | ||||
| 	user: ThinUser; | ||||
|  |  | |||
|  | @ -122,7 +122,7 @@ export type IEndpointMeta = (Omit<IEndpointMetaBase, 'requireCrential' | 'requir | |||
| }) | (Omit<IEndpointMetaBase, 'requireAdmin' | 'kind'> & { | ||||
| 	requireAdmin: true, | ||||
| 	kind: (typeof permissions)[number], | ||||
| }) | ||||
| }); | ||||
| 
 | ||||
| export interface IEndpoint { | ||||
| 	name: string; | ||||
|  |  | |||
|  | @ -82,8 +82,8 @@ export default abstract class Channel { | |||
| 		this.connection = connection; | ||||
| 	} | ||||
| 
 | ||||
| 	public send(payload: { type: string, body: JsonValue }): void | ||||
| 	public send(type: string, payload: JsonValue): void | ||||
| 	public send(payload: { type: string, body: JsonValue }): void; | ||||
| 	public send(type: string, payload: JsonValue): void; | ||||
| 	@bindThis | ||||
| 	public send(typeOrPayload: { type: string, body: JsonValue } | string, payload?: JsonValue) { | ||||
| 		const type = payload === undefined ? (typeOrPayload as { type: string, body: JsonValue }).type : (typeOrPayload as string); | ||||
|  | @ -108,4 +108,4 @@ export type MiChannelService<T extends boolean> = { | |||
| 	requireCredential: T; | ||||
| 	kind: T extends true ? string : string | null | undefined; | ||||
| 	create: (id: string, connection: Connection) => Channel; | ||||
| } | ||||
| }; | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ export type LoginUser = SigninResponse & { | |||
| 	client: Misskey.api.APIClient; | ||||
| 	username: string; | ||||
| 	password: string; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| /** used for avoiding overload and some endpoints */ | ||||
| export type Request = < | ||||
|  |  | |||
|  | @ -10,13 +10,13 @@ import { channel, clip, cookie, galleryPost, page, play, post, signup, simpleGet | |||
| import type { SimpleGetResponse } from '../utils.js'; | ||||
| import type * as misskey from 'misskey-js'; | ||||
| 
 | ||||
| // Request Accept
 | ||||
| // Request Accept in lowercase
 | ||||
| const ONLY_AP = 'application/activity+json'; | ||||
| const PREFER_AP = 'application/activity+json, */*'; | ||||
| const PREFER_HTML = 'text/html, */*'; | ||||
| const UNSPECIFIED = '*/*'; | ||||
| 
 | ||||
| // Response Content-Type
 | ||||
| // Response Content-Type in lowercase
 | ||||
| const AP = 'application/activity+json; charset=utf-8'; | ||||
| const HTML = 'text/html; charset=utf-8'; | ||||
| const JSON_UTF8 = 'application/json; charset=utf-8'; | ||||
|  | @ -44,7 +44,8 @@ describe('Webリソース', () => { | |||
| 		const { path, accept, cookie, type } = param; | ||||
| 		const res = await simpleGet(path, accept, cookie); | ||||
| 		assert.strictEqual(res.status, 200); | ||||
| 		assert.strictEqual(res.type, type ?? HTML); | ||||
| 		// Header values are case-insensitive
 | ||||
| 		assert.strictEqual(res.type?.toLowerCase(), (type ?? HTML).toLowerCase()); | ||||
| 		return res; | ||||
| 	}; | ||||
| 
 | ||||
|  | @ -95,8 +96,7 @@ describe('Webリソース', () => { | |||
| 	describe.each([ | ||||
| 		{ path: '/', type: HTML }, | ||||
| 		{ path: '/docs/ja-JP/about', type: HTML }, // "指定されたURLに該当するページはありませんでした。"
 | ||||
| 		// fastify-static gives charset=UTF-8 instead of utf-8 and that's okay
 | ||||
| 		{ path: '/api-doc', type: 'text/html; charset=UTF-8' }, | ||||
| 		{ path: '/api-doc', type: HTML }, | ||||
| 		{ path: '/api.json', type: JSON_UTF8 }, | ||||
| 		{ path: '/api-console', type: HTML }, | ||||
| 		{ path: '/_info_card_', type: HTML }, | ||||
|  |  | |||
|  | @ -24,13 +24,13 @@ describe('MfmService', () => { | |||
| 	describe('toHtml', () => { | ||||
| 		test('br', () => { | ||||
| 			const input = 'foo\nbar\nbaz'; | ||||
| 			const output = '<p><span>foo<br>bar<br>baz</span></p>'; | ||||
| 			const output = '<p><span>foo<br />bar<br />baz</span></p>'; | ||||
| 			assert.equal(mfmService.toHtml(mfm.parse(input)), output); | ||||
| 		}); | ||||
| 
 | ||||
| 		test('br alt', () => { | ||||
| 			const input = 'foo\r\nbar\rbaz'; | ||||
| 			const output = '<p><span>foo<br>bar<br>baz</span></p>'; | ||||
| 			const output = '<p><span>foo<br />bar<br />baz</span></p>'; | ||||
| 			assert.equal(mfmService.toHtml(mfm.parse(input)), output); | ||||
| 		}); | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,12 +12,12 @@ | |||
| 	"dependencies": { | ||||
| 		"@discordapp/twemoji": "15.1.0", | ||||
| 		"@rollup/plugin-json": "6.1.0", | ||||
| 		"@rollup/plugin-replace": "5.0.7", | ||||
| 		"@rollup/pluginutils": "5.1.3", | ||||
| 		"@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.29.0-mi.1913+5921534bc.tar.gz", | ||||
| 		"@rollup/plugin-replace": "6.0.2", | ||||
| 		"@rollup/pluginutils": "5.1.4", | ||||
| 		"@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.30.0-mi.1932+ab127beee.tar.gz", | ||||
| 		"@twemoji/parser": "15.1.1", | ||||
| 		"@vitejs/plugin-vue": "5.2.0", | ||||
| 		"@vue/compiler-sfc": "3.5.12", | ||||
| 		"@vitejs/plugin-vue": "5.2.1", | ||||
| 		"@vue/compiler-sfc": "3.5.13", | ||||
| 		"astring": "1.9.0", | ||||
| 		"buraha": "0.0.1", | ||||
| 		"estree-walker": "3.0.3", | ||||
|  | @ -25,47 +25,46 @@ | |||
| 		"misskey-js": "workspace:*", | ||||
| 		"frontend-shared": "workspace:*", | ||||
| 		"punycode.js": "2.3.1", | ||||
| 		"rollup": "4.26.0", | ||||
| 		"sass": "1.79.4", | ||||
| 		"shiki": "1.22.2", | ||||
| 		"rollup": "4.34.7", | ||||
| 		"sass": "1.85.0", | ||||
| 		"shiki": "2.4.1", | ||||
| 		"tinycolor2": "1.6.0", | ||||
| 		"tsc-alias": "1.8.10", | ||||
| 		"tsconfig-paths": "4.2.0", | ||||
| 		"typescript": "5.6.3", | ||||
| 		"uuid": "10.0.0", | ||||
| 		"typescript": "5.7.3", | ||||
| 		"uuid": "11.0.5", | ||||
| 		"json5": "2.2.3", | ||||
| 		"vite": "5.4.11", | ||||
| 		"vue": "3.5.12" | ||||
| 		"vite": "6.1.0", | ||||
| 		"vue": "3.5.13" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@misskey-dev/summaly": "5.1.0", | ||||
| 		"@misskey-dev/summaly": "5.2.0", | ||||
| 		"@testing-library/vue": "8.1.0", | ||||
| 		"@types/estree": "1.0.6", | ||||
| 		"@types/micromatch": "4.0.9", | ||||
| 		"@types/node": "22.9.0", | ||||
| 		"@types/node": "22.13.4", | ||||
| 		"@types/punycode.js": "npm:@types/punycode@2.1.4", | ||||
| 		"@types/tinycolor2": "1.4.6", | ||||
| 		"@types/uuid": "10.0.0", | ||||
| 		"@types/ws": "8.5.13", | ||||
| 		"@typescript-eslint/eslint-plugin": "7.17.0", | ||||
| 		"@typescript-eslint/parser": "7.17.0", | ||||
| 		"@vitest/coverage-v8": "1.6.0", | ||||
| 		"@vue/runtime-core": "3.5.12", | ||||
| 		"@types/ws": "8.5.14", | ||||
| 		"@typescript-eslint/eslint-plugin": "8.24.0", | ||||
| 		"@typescript-eslint/parser": "8.24.0", | ||||
| 		"@vitest/coverage-v8": "3.0.5", | ||||
| 		"@vue/runtime-core": "3.5.13", | ||||
| 		"acorn": "8.14.0", | ||||
| 		"cross-env": "7.0.3", | ||||
| 		"eslint-plugin-import": "2.31.0", | ||||
| 		"eslint-plugin-vue": "9.31.0", | ||||
| 		"fast-glob": "3.3.2", | ||||
| 		"happy-dom": "10.0.3", | ||||
| 		"eslint-plugin-vue": "9.32.0", | ||||
| 		"fast-glob": "3.3.3", | ||||
| 		"happy-dom": "17.1.0", | ||||
| 		"intersection-observer": "0.12.2", | ||||
| 		"micromatch": "4.0.8", | ||||
| 		"msw": "2.6.4", | ||||
| 		"nodemon": "3.1.7", | ||||
| 		"prettier": "3.3.3", | ||||
| 		"start-server-and-test": "2.0.8", | ||||
| 		"msw": "2.7.0", | ||||
| 		"nodemon": "3.1.9", | ||||
| 		"prettier": "3.5.1", | ||||
| 		"start-server-and-test": "2.0.10", | ||||
| 		"vite-plugin-turbosnap": "1.0.3", | ||||
| 		"vue-component-type-helpers": "2.1.10", | ||||
| 		"vue-component-type-helpers": "2.2.2", | ||||
| 		"vue-eslint-parser": "9.4.3", | ||||
| 		"vue-tsc": "2.1.10" | ||||
| 		"vue-tsc": "2.2.2" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ export type MiPostMessageEvent<T extends PostMessageEventType = PostMessageEvent | |||
| 	type: T; | ||||
| 	iframeId?: string; | ||||
| 	payload?: PostMessageEventPayload[T]; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| let defaultIframeId: string | null = null; | ||||
| 
 | ||||
|  |  | |||
|  | @ -98,4 +98,12 @@ export default [ | |||
| 			'vue/attribute-hyphenation': ['error', 'never'], | ||||
| 		}, | ||||
| 	}, | ||||
| 	{ | ||||
| 		ignores: [ | ||||
| 			// TODO: Error while loading rule '@typescript-eslint/naming-convention': Cannot use 'in' operator to search for 'type' in undefined のため一時的に無効化
 | ||||
| 			// See https://github.com/misskey-dev/misskey/pull/15311
 | ||||
| 			'js/i18n.ts', | ||||
| 			'js-built/', | ||||
| 		], | ||||
| 	}, | ||||
| ]; | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| //#region Embed関連の定義
 | ||||
| 
 | ||||
| /** 埋め込みの対象となるエンティティ(/embed/xxx の xxx の部分と対応させる) */ | ||||
| const embeddableEntities = [ | ||||
| export const embeddableEntities = [ | ||||
| 	'notes', | ||||
| 	'user-timeline', | ||||
| 	'clips', | ||||
|  |  | |||
|  | @ -9,10 +9,10 @@ export type UnicodeEmojiDef = { | |||
| 	name: string; | ||||
| 	char: string; | ||||
| 	category: typeof unicodeEmojiCategories[number]; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| // initial converted from https://github.com/muan/emojilib/commit/242fe68be86ed6536843b83f7e32f376468b38fb
 | ||||
| import _emojilist from './emojilist.json'; | ||||
| import _emojilist from './emojilist.json' with { type: 'json' }; | ||||
| 
 | ||||
| export const emojilist: UnicodeEmojiDef[] = _emojilist.map(x => ({ | ||||
| 	name: x[1] as string, | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
|  * SPDX-FileCopyrightText: syuilo and misskey-project | ||||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
| 
 | ||||
| import type { ILocale, ParameterizedString } from '../../../locales/index.js'; | ||||
| 
 | ||||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any
 | ||||
|  |  | |||
|  | @ -134,7 +134,6 @@ export function scrollToBottom( | |||
| 
 | ||||
| export function isTopVisible(el: HTMLElement, tolerance = 1): boolean { | ||||
| 	const scrollTop = getScrollPosition(el); | ||||
| 	if (_DEV_) console.log(scrollTop, tolerance, scrollTop <= tolerance); | ||||
| 	return scrollTop <= tolerance; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,13 +21,13 @@ | |||
| 		"lint": "pnpm typecheck && pnpm eslint" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@types/node": "22.9.0", | ||||
| 		"@typescript-eslint/eslint-plugin": "7.17.0", | ||||
| 		"@typescript-eslint/parser": "7.17.0", | ||||
| 		"esbuild": "0.24.0", | ||||
| 		"eslint-plugin-vue": "9.31.0", | ||||
| 		"nodemon": "3.1.7", | ||||
| 		"typescript": "5.6.3", | ||||
| 		"@types/node": "22.13.4", | ||||
| 		"@typescript-eslint/eslint-plugin": "8.24.0", | ||||
| 		"@typescript-eslint/parser": "8.24.0", | ||||
| 		"esbuild": "0.25.0", | ||||
| 		"eslint-plugin-vue": "9.32.0", | ||||
| 		"nodemon": "3.1.9", | ||||
| 		"typescript": "5.7.3", | ||||
| 		"vue-eslint-parser": "9.4.3" | ||||
| 	}, | ||||
| 	"files": [ | ||||
|  | @ -35,6 +35,6 @@ | |||
| 	], | ||||
| 	"dependencies": { | ||||
| 		"misskey-js": "workspace:*", | ||||
| 		"vue": "3.5.12" | ||||
| 		"vue": "3.5.13" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -47,6 +47,8 @@ export default [ | |||
| 			'@typescript-eslint/no-empty-interface': ['error', { | ||||
| 				allowSingleExtends: true, | ||||
| 			}], | ||||
| 			// defineExposeが誤検知されてしまう
 | ||||
| 			'@typescript-eslint/no-unused-expressions': 'off', | ||||
| 			'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], | ||||
| 			// window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため
 | ||||
| 			// e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため
 | ||||
|  |  | |||
|  | @ -21,27 +21,27 @@ | |||
| 		"@mcaptcha/vanilla-glue": "0.1.0-alpha-3", | ||||
| 		"@misskey-dev/browser-image-resizer": "2024.1.0", | ||||
| 		"@rollup/plugin-json": "6.1.0", | ||||
| 		"@rollup/plugin-replace": "5.0.7", | ||||
| 		"@rollup/pluginutils": "5.1.3", | ||||
| 		"@rollup/plugin-replace": "6.0.2", | ||||
| 		"@rollup/pluginutils": "5.1.4", | ||||
| 		"@syuilo/aiscript": "0.19.0", | ||||
| 		"@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.29.0-mi.1913+5921534bc.tar.gz", | ||||
| 		"@tabler/icons-webfont": "https://github.com/misskey-dev/tabler-icons/archive/refs/tags/3.30.0-mi.1932+ab127beee.tar.gz", | ||||
| 		"@twemoji/parser": "15.1.1", | ||||
| 		"@vitejs/plugin-vue": "5.2.0", | ||||
| 		"@vue/compiler-sfc": "3.5.12", | ||||
| 		"@vitejs/plugin-vue": "5.2.1", | ||||
| 		"@vue/compiler-sfc": "3.5.13", | ||||
| 		"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15", | ||||
| 		"astring": "1.9.0", | ||||
| 		"broadcast-channel": "7.0.0", | ||||
| 		"buraha": "0.0.1", | ||||
| 		"canvas-confetti": "1.9.3", | ||||
| 		"chart.js": "4.4.6", | ||||
| 		"chart.js": "4.4.7", | ||||
| 		"chartjs-adapter-date-fns": "3.0.0", | ||||
| 		"chartjs-chart-matrix": "2.0.1", | ||||
| 		"chartjs-plugin-gradient": "0.6.1", | ||||
| 		"chartjs-plugin-zoom": "2.0.1", | ||||
| 		"chromatic": "11.18.1", | ||||
| 		"chartjs-plugin-zoom": "2.2.0", | ||||
| 		"chromatic": "11.25.2", | ||||
| 		"compare-versions": "6.1.1", | ||||
| 		"cropperjs": "2.0.0-rc.2", | ||||
| 		"date-fns": "2.30.0", | ||||
| 		"date-fns": "4.1.0", | ||||
| 		"estree-walker": "3.0.3", | ||||
| 		"eventemitter3": "5.0.1", | ||||
| 		"frontend-shared": "workspace:*", | ||||
|  | @ -49,92 +49,91 @@ | |||
| 		"insert-text-at-cursor": "0.3.0", | ||||
| 		"is-file-animated": "1.0.2", | ||||
| 		"json5": "2.2.3", | ||||
| 		"matter-js": "0.19.0", | ||||
| 		"matter-js": "0.20.0", | ||||
| 		"mfm-js": "0.24.0", | ||||
| 		"misskey-bubble-game": "workspace:*", | ||||
| 		"misskey-js": "workspace:*", | ||||
| 		"misskey-reversi": "workspace:*", | ||||
| 		"photoswipe": "5.4.4", | ||||
| 		"punycode.js": "2.3.1", | ||||
| 		"rollup": "4.26.0", | ||||
| 		"sanitize-html": "2.13.1", | ||||
| 		"sass": "1.79.3", | ||||
| 		"shiki": "1.22.2", | ||||
| 		"rollup": "4.34.7", | ||||
| 		"sanitize-html": "2.14.0", | ||||
| 		"sass": "1.85.0", | ||||
| 		"shiki": "2.4.1", | ||||
| 		"strict-event-emitter-types": "2.0.0", | ||||
| 		"textarea-caret": "3.1.0", | ||||
| 		"three": "0.169.0", | ||||
| 		"three": "0.173.0", | ||||
| 		"throttle-debounce": "5.0.2", | ||||
| 		"tinycolor2": "1.6.0", | ||||
| 		"tsc-alias": "1.8.10", | ||||
| 		"tsconfig-paths": "4.2.0", | ||||
| 		"typescript": "5.6.3", | ||||
| 		"uuid": "10.0.0", | ||||
| 		"typescript": "5.7.3", | ||||
| 		"uuid": "11.0.5", | ||||
| 		"v-code-diff": "1.13.1", | ||||
| 		"vite": "5.4.11", | ||||
| 		"vue": "3.5.12", | ||||
| 		"vite": "6.1.0", | ||||
| 		"vue": "3.5.13", | ||||
| 		"vuedraggable": "next" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@misskey-dev/summaly": "5.1.0", | ||||
| 		"@storybook/addon-actions": "8.4.4", | ||||
| 		"@storybook/addon-essentials": "8.4.4", | ||||
| 		"@storybook/addon-interactions": "8.4.4", | ||||
| 		"@storybook/addon-links": "8.4.4", | ||||
| 		"@storybook/addon-mdx-gfm": "8.4.4", | ||||
| 		"@storybook/addon-storysource": "8.4.4", | ||||
| 		"@storybook/blocks": "8.4.4", | ||||
| 		"@storybook/components": "8.4.4", | ||||
| 		"@storybook/core-events": "8.4.4", | ||||
| 		"@storybook/manager-api": "8.4.4", | ||||
| 		"@storybook/preview-api": "8.4.4", | ||||
| 		"@storybook/react": "8.4.4", | ||||
| 		"@storybook/react-vite": "8.4.4", | ||||
| 		"@storybook/test": "8.4.4", | ||||
| 		"@storybook/theming": "8.4.4", | ||||
| 		"@storybook/types": "8.4.4", | ||||
| 		"@storybook/vue3": "8.4.4", | ||||
| 		"@storybook/vue3-vite": "8.4.4", | ||||
| 		"@misskey-dev/summaly": "5.2.0", | ||||
| 		"@storybook/addon-actions": "8.5.6", | ||||
| 		"@storybook/addon-essentials": "8.5.6", | ||||
| 		"@storybook/addon-interactions": "8.5.6", | ||||
| 		"@storybook/addon-links": "8.5.6", | ||||
| 		"@storybook/addon-mdx-gfm": "8.5.6", | ||||
| 		"@storybook/addon-storysource": "8.5.6", | ||||
| 		"@storybook/blocks": "8.5.6", | ||||
| 		"@storybook/components": "8.5.6", | ||||
| 		"@storybook/core-events": "8.5.6", | ||||
| 		"@storybook/manager-api": "8.5.6", | ||||
| 		"@storybook/preview-api": "8.5.6", | ||||
| 		"@storybook/react": "8.5.6", | ||||
| 		"@storybook/react-vite": "8.5.6", | ||||
| 		"@storybook/test": "8.5.6", | ||||
| 		"@storybook/theming": "8.5.6", | ||||
| 		"@storybook/types": "8.5.6", | ||||
| 		"@storybook/vue3": "8.5.6", | ||||
| 		"@storybook/vue3-vite": "8.5.6", | ||||
| 		"@testing-library/vue": "8.1.0", | ||||
| 		"@types/canvas-confetti": "^1.6.4", | ||||
| 		"@types/canvas-confetti": "1.9.0", | ||||
| 		"@types/estree": "1.0.6", | ||||
| 		"@types/matter-js": "0.19.7", | ||||
| 		"@types/matter-js": "0.19.8", | ||||
| 		"@types/micromatch": "4.0.9", | ||||
| 		"@types/node": "22.9.0", | ||||
| 		"@types/node": "22.13.4", | ||||
| 		"@types/punycode.js": "npm:@types/punycode@2.1.4", | ||||
| 		"@types/sanitize-html": "2.13.0", | ||||
| 		"@types/seedrandom": "3.0.8", | ||||
| 		"@types/throttle-debounce": "5.0.2", | ||||
| 		"@types/tinycolor2": "1.4.6", | ||||
| 		"@types/uuid": "10.0.0", | ||||
| 		"@types/ws": "8.5.13", | ||||
| 		"@typescript-eslint/eslint-plugin": "7.17.0", | ||||
| 		"@typescript-eslint/parser": "7.17.0", | ||||
| 		"@vitest/coverage-v8": "1.6.0", | ||||
| 		"@vue/runtime-core": "3.5.12", | ||||
| 		"@types/ws": "8.5.14", | ||||
| 		"@typescript-eslint/eslint-plugin": "8.24.0", | ||||
| 		"@typescript-eslint/parser": "8.24.0", | ||||
| 		"@vitest/coverage-v8": "3.0.5", | ||||
| 		"@vue/runtime-core": "3.5.13", | ||||
| 		"acorn": "8.14.0", | ||||
| 		"cross-env": "7.0.3", | ||||
| 		"cypress": "13.15.2", | ||||
| 		"cypress": "14.0.3", | ||||
| 		"eslint-plugin-import": "2.31.0", | ||||
| 		"eslint-plugin-vue": "9.31.0", | ||||
| 		"fast-glob": "3.3.2", | ||||
| 		"happy-dom": "10.0.3", | ||||
| 		"eslint-plugin-vue": "9.32.0", | ||||
| 		"fast-glob": "3.3.3", | ||||
| 		"happy-dom": "17.1.0", | ||||
| 		"intersection-observer": "0.12.2", | ||||
| 		"micromatch": "4.0.8", | ||||
| 		"msw": "2.6.4", | ||||
| 		"msw": "2.7.0", | ||||
| 		"msw-storybook-addon": "2.0.4", | ||||
| 		"nodemon": "3.1.7", | ||||
| 		"prettier": "3.3.3", | ||||
| 		"react": "18.3.1", | ||||
| 		"react-dom": "18.3.1", | ||||
| 		"nodemon": "3.1.9", | ||||
| 		"prettier": "3.5.1", | ||||
| 		"react": "19.0.0", | ||||
| 		"react-dom": "19.0.0", | ||||
| 		"seedrandom": "3.0.5", | ||||
| 		"start-server-and-test": "2.0.8", | ||||
| 		"storybook": "8.4.4", | ||||
| 		"start-server-and-test": "2.0.10", | ||||
| 		"storybook": "8.5.6", | ||||
| 		"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", | ||||
| 		"vite-plugin-turbosnap": "1.0.3", | ||||
| 		"vitest": "1.6.0", | ||||
| 		"vitest-fetch-mock": "0.2.2", | ||||
| 		"vue-component-type-helpers": "2.1.10", | ||||
| 		"vitest": "3.0.5", | ||||
| 		"vitest-fetch-mock": "0.4.3", | ||||
| 		"vue-component-type-helpers": "2.2.2", | ||||
| 		"vue-eslint-parser": "9.4.3", | ||||
| 		"vue-tsc": "2.1.10" | ||||
| 		"vue-tsc": "2.2.2" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -50,6 +50,8 @@ type CaptchaContainer = { | |||
| }; | ||||
| 
 | ||||
| declare global { | ||||
| 	// Window を拡張してるため、空ではない | ||||
| 	// eslint-disable-next-line @typescript-eslint/no-empty-object-type | ||||
| 	interface Window extends CaptchaContainer { } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -142,6 +142,7 @@ const okButtonDisabledReason = computed<null | 'charactersExceeded' | 'character | |||
| // overload function を使いたいので lint エラーを無視する | ||||
| function done(canceled: true): void; | ||||
| function done(canceled: false, result: Result): void; // eslint-disable-line no-redeclare | ||||
| 
 | ||||
| function done(canceled: boolean, result?: Result): void { // eslint-disable-line no-redeclare | ||||
| 	emit('done', { canceled, result } as { canceled: true } | { canceled: false, result: Result }); | ||||
| 	modal.value?.close(); | ||||
|  |  | |||
|  | @ -217,10 +217,9 @@ function showMenu(ev: MouseEvent) { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	const details: MenuItem[] = []; | ||||
| 	if ($i?.id === props.audio.userId) { | ||||
| 		menu.push({ | ||||
| 			type: 'divider', | ||||
| 		}, { | ||||
| 		details.push({ | ||||
| 			type: 'link', | ||||
| 			text: i18n.ts._fileViewer.title, | ||||
| 			icon: 'ti ti-info-circle', | ||||
|  | @ -228,6 +227,19 @@ function showMenu(ev: MouseEvent) { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (iAmModerator) { | ||||
| 		details.push({ | ||||
| 			type: 'link', | ||||
| 			text: i18n.ts.moderation, | ||||
| 			icon: 'ti ti-photo-exclamation', | ||||
| 			to: `/admin/file/${props.audio.id}`, | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (details.length > 0) { | ||||
| 		menu.push({ type: 'divider' }, ...details); | ||||
| 	} | ||||
| 
 | ||||
| 	if (defaultStore.state.devMode) { | ||||
| 		menu.push({ type: 'divider' }, { | ||||
| 			icon: 'ti ti-id', | ||||
|  |  | |||
|  | @ -133,10 +133,9 @@ function showMenu(ev: MouseEvent) { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	const details: MenuItem[] = []; | ||||
| 	if ($i?.id === props.image.userId) { | ||||
| 		menuItems.push({ | ||||
| 			type: 'divider', | ||||
| 		}, { | ||||
| 		details.push({ | ||||
| 			type: 'link', | ||||
| 			text: i18n.ts._fileViewer.title, | ||||
| 			icon: 'ti ti-info-circle', | ||||
|  | @ -144,6 +143,19 @@ function showMenu(ev: MouseEvent) { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (iAmModerator) { | ||||
| 		details.push({ | ||||
| 			type: 'link', | ||||
| 			text: i18n.ts.moderation, | ||||
| 			icon: 'ti ti-photo-exclamation', | ||||
| 			to: `/admin/file/${props.image.id}`, | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (details.length > 0) { | ||||
| 		menuItems.push({ type: 'divider' }, ...details); | ||||
| 	} | ||||
| 
 | ||||
| 	if (defaultStore.state.devMode) { | ||||
| 		menuItems.push({ type: 'divider' }, { | ||||
| 			icon: 'ti ti-id', | ||||
|  |  | |||
|  | @ -242,10 +242,9 @@ function showMenu(ev: MouseEvent) { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	const details: MenuItem[] = []; | ||||
| 	if ($i?.id === props.video.userId) { | ||||
| 		menu.push({ | ||||
| 			type: 'divider', | ||||
| 		}, { | ||||
| 		details.push({ | ||||
| 			type: 'link', | ||||
| 			text: i18n.ts._fileViewer.title, | ||||
| 			icon: 'ti ti-info-circle', | ||||
|  | @ -253,6 +252,19 @@ function showMenu(ev: MouseEvent) { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (iAmModerator) { | ||||
| 		details.push({ | ||||
| 			type: 'link', | ||||
| 			text: i18n.ts.moderation, | ||||
| 			icon: 'ti ti-photo-exclamation', | ||||
| 			to: `/admin/file/${props.video.id}`, | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	if (details.length > 0) { | ||||
| 		menu.push({ type: 'divider' }, ...details); | ||||
| 	} | ||||
| 
 | ||||
| 	if (defaultStore.state.devMode) { | ||||
| 		menu.push({ type: 'divider' }, { | ||||
| 			icon: 'ti ti-id', | ||||
|  |  | |||
|  | @ -489,7 +489,16 @@ function react(): void { | |||
| 		} | ||||
| 	} else { | ||||
| 		blur(); | ||||
| 		reactionPicker.show(reactButton.value ?? null, note.value, reaction => { | ||||
| 		reactionPicker.show(reactButton.value ?? null, note.value, async (reaction) => { | ||||
| 			if (defaultStore.state.confirmOnReact) { | ||||
| 				const confirm = await os.confirm({ | ||||
| 					type: 'question', | ||||
| 					text: i18n.tsx.reactAreYouSure({ emoji: reaction.replace('@.', '') }), | ||||
| 				}); | ||||
| 
 | ||||
| 				if (confirm.canceled) return; | ||||
| 			} | ||||
| 
 | ||||
| 			sound.playMisskeySfx('reaction'); | ||||
| 
 | ||||
| 			if (props.mock) { | ||||
|  |  | |||
|  | @ -452,7 +452,16 @@ function react(): void { | |||
| 		} | ||||
| 	} else { | ||||
| 		blur(); | ||||
| 		reactionPicker.show(reactButton.value ?? null, note.value, reaction => { | ||||
| 		reactionPicker.show(reactButton.value ?? null, note.value, async (reaction) => { | ||||
| 			if (defaultStore.state.confirmOnReact) { | ||||
| 				const confirm = await os.confirm({ | ||||
| 					type: 'question', | ||||
| 					text: i18n.tsx.reactAreYouSure({ emoji: reaction.replace('@.', '') }), | ||||
| 				}); | ||||
| 
 | ||||
| 				if (confirm.canceled) return; | ||||
| 			} | ||||
| 
 | ||||
| 			sound.playMisskeySfx('reaction'); | ||||
| 
 | ||||
| 			misskeyApi('notes/reactions/create', { | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ import MkModalWindow from '@/components/MkModalWindow.vue'; | |||
| import { notificationTypes } from '@@/js/const.js'; | ||||
| import { i18n } from '@/i18n.js'; | ||||
| 
 | ||||
| type TypesMap = Record<typeof notificationTypes[number], Ref<boolean>> | ||||
| type TypesMap = Record<typeof notificationTypes[number], Ref<boolean>>; | ||||
| 
 | ||||
| const emit = defineEmits<{ | ||||
| 	(ev: 'done', v: { excludeTypes: string[] }): void, | ||||
|  |  | |||
|  | @ -65,7 +65,10 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| 		</div> | ||||
| 	</div> | ||||
| 	<MkInfo v-if="hasNotSpecifiedMentions" warn :class="$style.hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo> | ||||
| 	<input v-show="useCw" ref="cwInputEl" v-model="cw" :class="$style.cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown" @keyup="onKeyup" @compositionend="onCompositionEnd"> | ||||
| 	<div v-show="useCw" :class="$style.cwOuter"> | ||||
| 		<input ref="cwInputEl" v-model="cw" :class="$style.cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown" @keyup="onKeyup" @compositionend="onCompositionEnd"> | ||||
| 		<div v-if="maxCwTextLength - cwTextLength < 20" :class="['_acrylic', $style.cwTextCount, { [$style.cwTextOver]: cwTextLength > maxCwTextLength }]">{{ maxCwTextLength - cwTextLength }}</div>		 | ||||
| 	</div> | ||||
| 	<div :class="[$style.textOuter, { [$style.withCw]: useCw }]"> | ||||
| 		<div v-if="channel" :class="$style.colorBar" :style="{ background: channel.color }"></div> | ||||
| 		<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :readonly="textAreaReadOnly" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @keyup="onKeyup" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/> | ||||
|  | @ -244,6 +247,12 @@ const maxTextLength = computed((): number => { | |||
| 	return instance ? instance.maxNoteTextLength : 1000; | ||||
| }); | ||||
| 
 | ||||
| const cwTextLength = computed((): number => { | ||||
| 	return cw.value?.length ?? 0; | ||||
| }); | ||||
| 
 | ||||
| const maxCwTextLength = 100; | ||||
| 
 | ||||
| const canPost = computed((): boolean => { | ||||
| 	return !props.mock && !posting.value && !posted.value && | ||||
| 		( | ||||
|  | @ -254,6 +263,7 @@ const canPost = computed((): boolean => { | |||
| 			quoteId.value != null | ||||
| 		) && | ||||
| 		(textLength.value <= maxTextLength.value) && | ||||
| 		(cwTextLength.value <= maxCwTextLength) && | ||||
| 		(files.value.length <= 16) && | ||||
| 		(!poll.value || poll.value.choices.length >= 2); | ||||
| }); | ||||
|  | @ -1273,12 +1283,34 @@ html[data-color-scheme=light] .preview { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| .cwOuter { | ||||
| 	width: 100%; | ||||
| 	position: relative; | ||||
| } | ||||
| 
 | ||||
| .cw { | ||||
| 	z-index: 1; | ||||
| 	padding-bottom: 8px; | ||||
| 	border-bottom: solid 0.5px var(--MI_THEME-divider); | ||||
| } | ||||
| 
 | ||||
| .cwTextCount { | ||||
| 	position: absolute; | ||||
| 	top: 0; | ||||
| 	right: 2px; | ||||
| 	padding: 2px 6px; | ||||
| 	font-size: .9em; | ||||
| 	color: var(--MI_THEME-warn); | ||||
| 	border-radius: 6px; | ||||
| 	max-width: 100%; | ||||
| 	min-width: 1.6em; | ||||
| 	text-align: center; | ||||
| 
 | ||||
| 	&.cwTextOver { | ||||
| 		color: #ff2a2a; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .hashtags { | ||||
| 	z-index: 1; | ||||
| 	padding-top: 8px; | ||||
|  |  | |||
|  | @ -90,6 +90,15 @@ async function toggleReaction() { | |||
| 			} | ||||
| 		}); | ||||
| 	} else { | ||||
| 		if (defaultStore.state.confirmOnReact) { | ||||
| 			const confirm = await os.confirm({ | ||||
| 				type: 'question', | ||||
| 				text: i18n.tsx.reactAreYouSure({ emoji: props.reaction.replace('@.', '') }), | ||||
| 			}); | ||||
| 
 | ||||
| 			if (confirm.canceled) return; | ||||
| 		} | ||||
| 
 | ||||
| 		sound.playMisskeySfx('reaction'); | ||||
| 
 | ||||
| 		if (mock) { | ||||
|  |  | |||
|  | @ -3,9 +3,9 @@ | |||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
| 
 | ||||
| export type SortOrderDirection = '+' | '-' | ||||
| export type SortOrderDirection = '+' | '-'; | ||||
| 
 | ||||
| export type SortOrder<T extends string> = { | ||||
| 	key: T; | ||||
| 	direction: SortOrderDirection; | ||||
| } | ||||
| }; | ||||
|  |  | |||
|  | @ -114,7 +114,7 @@ type EventType = { | |||
| 	userCreated: boolean; | ||||
| 	inactiveModeratorsWarning: boolean; | ||||
| 	inactiveModeratorsInvitationOnlyChanged: boolean; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| const emit = defineEmits<{ | ||||
| 	(ev: 'submitted', result: MkSystemWebhookResult): void; | ||||
|  |  | |||
|  | @ -57,15 +57,15 @@ provide('tl_withSensitive', computed(() => props.withSensitive)); | |||
| provide('inChannel', computed(() => props.src === 'channel')); | ||||
| 
 | ||||
| type TimelineQueryType = { | ||||
|   antennaId?: string, | ||||
|   withRenotes?: boolean, | ||||
|   withReplies?: boolean, | ||||
|   withFiles?: boolean, | ||||
|   visibility?: string, | ||||
|   listId?: string, | ||||
|   channelId?: string, | ||||
|   roleId?: string | ||||
| } | ||||
| 	antennaId?: string, | ||||
| 	withRenotes?: boolean, | ||||
| 	withReplies?: boolean, | ||||
| 	withFiles?: boolean, | ||||
| 	visibility?: string, | ||||
| 	listId?: string, | ||||
| 	channelId?: string, | ||||
| 	roleId?: string | ||||
| }; | ||||
| 
 | ||||
| const prComponent = shallowRef<InstanceType<typeof MkPullToRefresh>>(); | ||||
| const tlComponent = shallowRef<InstanceType<typeof MkNotes>>(); | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ import MkTextarea from '@/components/MkTextarea.vue'; | |||
| import MkSwitch from '@/components/MkSwitch.vue'; | ||||
| import MkRadios from '@/components/MkRadios.vue'; | ||||
| 
 | ||||
| type AdminAnnouncementType = Misskey.entities.AdminAnnouncementsCreateRequest & { id: string; } | ||||
| type AdminAnnouncementType = Misskey.entities.AdminAnnouncementsCreateRequest & { id: string; }; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	user: Misskey.entities.User, | ||||
|  |  | |||
|  | @ -15,9 +15,9 @@ export type MkABehavior = 'window' | 'browser' | null; | |||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { computed, inject, shallowRef } from 'vue'; | ||||
| import { url } from '@@/js/config.js'; | ||||
| import * as os from '@/os.js'; | ||||
| import { copyToClipboard } from '@/scripts/copy-to-clipboard.js'; | ||||
| import { url } from '@@/js/config.js'; | ||||
| import { i18n } from '@/i18n.js'; | ||||
| import { useRouter } from '@/router/supplier.js'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -79,7 +79,7 @@ type RowHolder = { | |||
| 	row: GridRow, | ||||
| 	cells: GridCell[], | ||||
| 	origin: DataSource, | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| const emit = defineEmits<{ | ||||
| 	(ev: 'event', event: GridEvent, context: GridContext): void; | ||||
|  |  | |||
|  | @ -18,25 +18,25 @@ export type ValidatorParams = { | |||
| export type ValidatorResult = { | ||||
| 	valid: boolean; | ||||
| 	message?: string; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type GridCellValidator = { | ||||
| 	name?: string; | ||||
| 	ignoreViolation?: boolean; | ||||
| 	validate: (params: ValidatorParams) => ValidatorResult; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type ValidateViolation = { | ||||
| 	valid: boolean; | ||||
| 	params: ValidatorParams; | ||||
| 	violations: ValidateViolationItem[]; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type ValidateViolationItem = { | ||||
| 	valid: boolean; | ||||
| 	validator: GridCellValidator; | ||||
| 	result: ValidatorResult; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export function cellValidation(allCells: GridCell[], cell: GridCell, newValue: CellValue): ValidateViolation { | ||||
| 	const { column, row } = cell; | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ export type CellValue = string | boolean | number | undefined | null | Array<unk | |||
| export type CellAddress = { | ||||
| 	row: number; | ||||
| 	col: number; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export const CELL_ADDRESS_NONE: CellAddress = { | ||||
| 	row: -1, | ||||
|  | @ -32,13 +32,13 @@ export type GridCell = { | |||
| 	contentSize: Size; | ||||
| 	setting: GridCellSetting; | ||||
| 	violation: ValidateViolation; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type GridCellContextMenuFactory = (col: GridColumn, row: GridRow, value: CellValue, context: GridContext) => MenuItem[]; | ||||
| 
 | ||||
| export type GridCellSetting = { | ||||
| 	contextMenuFactory?: GridCellContextMenuFactory; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export function createCell( | ||||
| 	column: GridColumn, | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ export type GridColumn = { | |||
| 	setting: GridColumnSetting; | ||||
| 	width: string; | ||||
| 	contentSize: Size; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export function createColumn(setting: GridColumnSetting, index: number): GridColumn { | ||||
| 	return { | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ export type GridSetting = { | |||
| 
 | ||||
| export type DataSource = Record<string, CellValue>; | ||||
| 
 | ||||
| export type GridState = | ||||
| export type GridState = ( | ||||
| 	'normal' | | ||||
| 	'cellSelecting' | | ||||
| 	'cellEditing' | | ||||
|  | @ -29,19 +29,19 @@ export type GridState = | |||
| 	'colSelecting' | | ||||
| 	'rowSelecting' | | ||||
| 	'hidden' | ||||
| 	; | ||||
| ); | ||||
| 
 | ||||
| export type Size = { | ||||
| 	width: number; | ||||
| 	height: number; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type SizeStyle = number | 'auto' | undefined; | ||||
| 
 | ||||
| export type AdditionalStyle = { | ||||
| 	className?: string; | ||||
| 	style?: Record<string, string | number>; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export class GridEventEmitter extends EventEmitter<{ | ||||
| 	'forceRefreshContentSize': void; | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ export type GridRowStyleRuleConditionParams = { | |||
| export type GridRowStyleRule = { | ||||
| 	condition: (params: GridRowStyleRuleConditionParams) => boolean; | ||||
| 	applyStyle: AdditionalStyle; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type GridRowContextMenuFactory = (row: GridRow, context: GridContext) => MenuItem[]; | ||||
| 
 | ||||
|  | @ -40,7 +40,7 @@ export type GridRowSetting = { | |||
| 	events?: { | ||||
| 		delete?: (rows: GridRow[]) => void; | ||||
| 	} | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type GridRow = { | ||||
| 	index: number; | ||||
|  | @ -48,7 +48,7 @@ export type GridRow = { | |||
| 	using: boolean; | ||||
| 	setting: GridRowSetting; | ||||
| 	additionalStyles: AdditionalStyle[]; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export function createRow(index: number, using: boolean, setting: GridRowSetting): GridRow { | ||||
| 	return { | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
| 
 | ||||
| export type Keys = | ||||
| export type Keys = ( | ||||
| 	'v' | | ||||
| 	'lastVersion' | | ||||
| 	'instance' | | ||||
|  | @ -40,6 +40,7 @@ export type Keys = | |||
| 	'emojis' | // DEPRECATED, stored in indexeddb (13.9.0~);
 | ||||
| 	`channelLastReadedAt:${string}` | | ||||
| 	`idbfallback::${string}` | ||||
| ); | ||||
| 
 | ||||
| // セッション毎に廃棄されるLocalStorage代替(セーフモードなどで使用できそう)
 | ||||
| //const safeSessionStorage = new Map<Keys, string>();
 | ||||
|  |  | |||
|  | @ -6,8 +6,8 @@ | |||
| // NIRAX --- A lightweight router
 | ||||
| 
 | ||||
| import { onMounted, shallowRef } from 'vue'; | ||||
| import type { Component, ShallowRef } from 'vue'; | ||||
| import { EventEmitter } from 'eventemitter3'; | ||||
| import type { Component, ShallowRef } from 'vue'; | ||||
| 
 | ||||
| function safeURIDecode(str: string): string { | ||||
| 	try { | ||||
|  | @ -65,7 +65,7 @@ export type RouterEvent = { | |||
| 		key: string; | ||||
| 	}) => void; | ||||
| 	same: () => void; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export type Resolved = { | ||||
| 	route: RouteDef; | ||||
|  | @ -242,8 +242,6 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter { | |||
| 			hash, | ||||
| 		}; | ||||
| 
 | ||||
| 		if (_DEV_) console.log('Routing: ', path, queryString); | ||||
| 
 | ||||
| 		function check(routes: RouteDef[], _parts: string[]): Resolved | null { | ||||
| 			forEachRouteLoop: | ||||
| 			for (const route of routes) { | ||||
|  |  | |||
|  | @ -109,6 +109,9 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| 						<div> | ||||
| 							<a style="display: inline-block;" class="pepabo" title="GMO Pepabo" href="https://pepabo.com/" target="_blank"><img style="width: 100%;" src="https://assets.misskey-hub.net/sponsors/gmo_pepabo.svg" alt="GMO Pepabo"></a> | ||||
| 						</div> | ||||
| 						<div> | ||||
| 							<a style="display: inline-block;" class="purpledotdigital" title="Purple Dot Digital" href="https://purpledotdigital.com/" target="_blank"><img style="width: 100%;" src="https://assets.misskey-hub.net/sponsors/purple-dot-digital.jpg" alt="Purple Dot Digital"></a> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				</FormSection> | ||||
| 				<FormSection> | ||||
|  |  | |||
|  | @ -71,6 +71,9 @@ export type EmojiSearchQuery = { | |||
| <script setup lang="ts"> | ||||
| import { computed, defineAsyncComponent, onMounted, ref, nextTick, useCssModule } from 'vue'; | ||||
| import * as Misskey from 'misskey-js'; | ||||
| import type { RequestLogItem } from '@/pages/admin/custom-emojis-manager.impl.js'; | ||||
| import type { GridCellValidationEvent, GridCellValueChangeEvent, GridEvent } from '@/components/grid/grid-event.js'; | ||||
| import type { GridSetting } from '@/components/grid/grid.js'; | ||||
| import * as os from '@/os.js'; | ||||
| import { | ||||
| 	emptyStrToEmptyArray, | ||||
|  | @ -86,11 +89,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js'; | |||
| import MkPagingButtons from '@/components/MkPagingButtons.vue'; | ||||
| import { selectFile } from '@/scripts/select-file.js'; | ||||
| import { copyGridDataToClipboard, removeDataFromGrid } from '@/components/grid/grid-utils.js'; | ||||
| import { useLoading } from "@/components/hook/useLoading.js"; | ||||
| 
 | ||||
| import type { RequestLogItem } from '@/pages/admin/custom-emojis-manager.impl.js'; | ||||
| import type { GridCellValidationEvent, GridCellValueChangeEvent, GridEvent } from '@/components/grid/grid-event.js'; | ||||
| import type { GridSetting } from '@/components/grid/grid.js'; | ||||
| import { useLoading } from '@/components/hook/useLoading.js'; | ||||
| 
 | ||||
| type GridItem = { | ||||
| 	checked: boolean; | ||||
|  | @ -109,7 +108,7 @@ type GridItem = { | |||
| 	publicUrl?: string | null; | ||||
| 	originalUrl?: string | null; | ||||
| 	type: string | null; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function setupGrid(): GridSetting { | ||||
| 	const $style = useCssModule(); | ||||
|  | @ -465,8 +464,8 @@ async function refreshCustomEmojis() { | |||
| 		aliases: emptyStrToUndefined(searchQuery.value.aliases), | ||||
| 		category: emptyStrToUndefined(searchQuery.value.category), | ||||
| 		license: emptyStrToUndefined(searchQuery.value.license), | ||||
| 		isSensitive: searchQuery.value.sensitive ? Boolean(searchQuery.value.sensitive).valueOf() : undefined, | ||||
| 		localOnly: searchQuery.value.localOnly ? Boolean(searchQuery.value.localOnly).valueOf() : undefined, | ||||
| 		isSensitive: searchQuery.value.sensitive != null ? Boolean(searchQuery.value.sensitive).valueOf() : undefined, | ||||
| 		localOnly: searchQuery.value.localOnly != null ? Boolean(searchQuery.value.localOnly).valueOf() : undefined, | ||||
| 		updatedAtFrom: emptyStrToUndefined(searchQuery.value.updatedAtFrom), | ||||
| 		updatedAtTo: emptyStrToUndefined(searchQuery.value.updatedAtTo), | ||||
| 		roleIds: searchQuery.value.roles.map(it => it.id), | ||||
|  | @ -593,7 +592,7 @@ const headerActions = computed(() => [{ | |||
| 				dispose(); | ||||
| 			}, | ||||
| 		}); | ||||
| 	} | ||||
| 	}, | ||||
| }]); | ||||
| </script> | ||||
| 
 | ||||
|  |  | |||
|  | @ -124,7 +124,7 @@ type GridItem = { | |||
| 	localOnly: boolean; | ||||
| 	roleIdsThatCanBeUsedThisEmojiAsReaction: { id: string, name: string }[]; | ||||
| 	type: string | null; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function setupGrid(): GridSetting { | ||||
| 	const $style = useCssModule(); | ||||
|  |  | |||
|  | @ -168,7 +168,7 @@ type GridItem = { | |||
| 	url: string; | ||||
| 	name: string; | ||||
| 	host: string; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function setupGrid(): GridSetting { | ||||
| 	const $style = useCssModule(); | ||||
|  |  | |||
|  | @ -65,10 +65,13 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| import { computed, onDeactivated, onUnmounted, ref, watch, shallowRef, defineAsyncComponent } from 'vue'; | ||||
| import * as Misskey from 'misskey-js'; | ||||
| import { Interpreter, Parser, values } from '@syuilo/aiscript'; | ||||
| import { url } from '@@/js/config.js'; | ||||
| import type { Ref } from 'vue'; | ||||
| import type { AsUiComponent, AsUiRoot } from '@/scripts/aiscript/ui.js'; | ||||
| import type { MenuItem } from '@/types/menu.js'; | ||||
| import MkButton from '@/components/MkButton.vue'; | ||||
| import * as os from '@/os.js'; | ||||
| import { misskeyApi } from '@/scripts/misskey-api.js'; | ||||
| import { url } from '@@/js/config.js'; | ||||
| import { i18n } from '@/i18n.js'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata.js'; | ||||
| import MkAsUi from '@/components/MkAsUi.vue'; | ||||
|  | @ -82,10 +85,6 @@ import { isSupportShare } from '@/scripts/navigator.js'; | |||
| import { copyToClipboard } from '@/scripts/copy-to-clipboard.js'; | ||||
| import { pleaseLogin } from '@/scripts/please-login.js'; | ||||
| 
 | ||||
| import type { Ref } from 'vue'; | ||||
| import type { AsUiComponent, AsUiRoot } from '@/scripts/aiscript/ui.js'; | ||||
| import type { MenuItem } from '@/types/menu.js'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	id: string; | ||||
| }>(); | ||||
|  | @ -199,6 +198,8 @@ async function run() { | |||
| 	if (aiscript.value) aiscript.value.abort(); | ||||
| 	if (!flash.value) return; | ||||
| 
 | ||||
| 	components.value = []; | ||||
| 
 | ||||
| 	aiscript.value = new Interpreter({ | ||||
| 		...createAiScriptEnv({ | ||||
| 			storageKey: 'flash:' + flash.value.id, | ||||
|  |  | |||
|  | @ -93,7 +93,7 @@ const noteSearchableScope = instance.noteSearchableScope ?? 'local'; | |||
| 
 | ||||
| const hostSelect = ref<'all' | 'local' | 'specified'>('all'); | ||||
| 
 | ||||
| const setHostSelectWithInput = (after:string|undefined|null, before:string|undefined|null) => { | ||||
| const setHostSelectWithInput = (after: string | undefined | null, before: string | undefined | null) => { | ||||
| 	if (before === after) return; | ||||
| 	if (after === '') hostSelect.value = 'all'; | ||||
| 	else hostSelect.value = 'specified'; | ||||
|  |  | |||
|  | @ -170,6 +170,7 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| 				<MkSwitch v-model="enableHorizontalSwipe">{{ i18n.ts.enableHorizontalSwipe }}</MkSwitch> | ||||
| 				<MkSwitch v-model="alwaysConfirmFollow">{{ i18n.ts.alwaysConfirmFollow }}</MkSwitch> | ||||
| 				<MkSwitch v-model="confirmWhenRevealingSensitiveMedia">{{ i18n.ts.confirmWhenRevealingSensitiveMedia }}</MkSwitch> | ||||
| 				<MkSwitch v-model="confirmOnReact">{{ i18n.ts.confirmOnReact }}</MkSwitch> | ||||
| 			</div> | ||||
| 			<MkSelect v-model="serverDisconnectedBehavior"> | ||||
| 				<template #label>{{ i18n.ts.whenServerDisconnected }}</template> | ||||
|  | @ -320,6 +321,7 @@ const enableHorizontalSwipe = computed(defaultStore.makeGetterSetter('enableHori | |||
| const useNativeUIForVideoAudioPlayer = computed(defaultStore.makeGetterSetter('useNativeUIForVideoAudioPlayer')); | ||||
| const alwaysConfirmFollow = computed(defaultStore.makeGetterSetter('alwaysConfirmFollow')); | ||||
| const confirmWhenRevealingSensitiveMedia = computed(defaultStore.makeGetterSetter('confirmWhenRevealingSensitiveMedia')); | ||||
| const confirmOnReact = computed(defaultStore.makeGetterSetter('confirmOnReact')); | ||||
| const contextMenu = computed(defaultStore.makeGetterSetter('contextMenu')); | ||||
| 
 | ||||
| watch(lang, () => { | ||||
|  |  | |||
|  | @ -6,8 +6,8 @@ | |||
| // PIZZAX --- A lightweight store
 | ||||
| 
 | ||||
| import { onUnmounted, ref, watch } from 'vue'; | ||||
| import type { Ref } from 'vue'; | ||||
| import { BroadcastChannel } from 'broadcast-channel'; | ||||
| import type { Ref } from 'vue'; | ||||
| import { $i } from '@/account.js'; | ||||
| import { misskeyApi } from '@/scripts/misskey-api.js'; | ||||
| import { get, set } from '@/scripts/idb-proxy.js'; | ||||
|  | @ -113,7 +113,6 @@ export class Storage<T extends StateDef> { | |||
| 				this.reactiveState[k].value = this.state[k] = this.mergeState<T[keyof T]['default']>(deviceAccountState[k], v.default); | ||||
| 			} else { | ||||
| 				this.reactiveState[k].value = this.state[k] = v.default; | ||||
| 				if (_DEV_) console.log('Use default value', k, v.default); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -180,12 +179,9 @@ export class Storage<T extends StateDef> { | |||
| 		// (JSON.parse(JSON.stringify(value))の代わり)
 | ||||
| 		const rawValue = deepClone(value); | ||||
| 
 | ||||
| 		if (_DEV_) console.log('set', key, rawValue, value); | ||||
| 
 | ||||
| 		this.reactiveState[key].value = this.state[key] = rawValue; | ||||
| 
 | ||||
| 		return this.addIdbSetJob(async () => { | ||||
| 			if (_DEV_) console.log(`set ${String(key)} start`); | ||||
| 			switch (this.def[key].where) { | ||||
| 				case 'device': { | ||||
| 					this.pizzaxChannel.postMessage({ | ||||
|  | @ -224,7 +220,6 @@ export class Storage<T extends StateDef> { | |||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (_DEV_) console.log(`set ${String(key)} complete`); | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -247,9 +242,9 @@ export class Storage<T extends StateDef> { | |||
| 		getter?: (v: T[K]['default']) => R, | ||||
| 		setter?: (v: R) => T[K]['default'], | ||||
| 	): { | ||||
| 		get: () => R; | ||||
| 		set: (value: R) => void; | ||||
| 	} { | ||||
| 			get: () => R; | ||||
| 			set: (value: R) => void; | ||||
| 		} { | ||||
| 		const valueRef = ref(this.state[key]); | ||||
| 
 | ||||
| 		const stop = watch(this.reactiveState[key], val => { | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ export function createAiScriptEnv(opts: { storageKey: string, token?: string }) | |||
| 				// バグがあればundefinedもあり得るため念のため
 | ||||
| 				if (typeof token.value !== 'string') throw new Error('invalid token'); | ||||
| 			} | ||||
| 			const actualToken: string|null = token?.value ?? opts.token ?? null; | ||||
| 			const actualToken: string | null = token?.value ?? opts.token ?? null; | ||||
| 			if (param == null) { | ||||
| 				throw new errors.AiScriptRuntimeError('expected param'); | ||||
| 			} | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ export type DroppedDirectory = { | |||
| 	isFile: false; | ||||
| 	path: string; | ||||
| 	children: DroppedItem[]; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export async function extractDroppedItems(ev: DragEvent): Promise<DroppedItem[]> { | ||||
| 	const dropItems = ev.dataTransfer?.items; | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
| 
 | ||||
| const defaultLocaleStringFormats: {[index: string]: string} = { | ||||
| const defaultLocaleStringFormats: { [index: string]: string } = { | ||||
| 	'weekday': 'narrow', | ||||
| 	'era': 'narrow', | ||||
| 	'year': 'numeric', | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
|  * {@link KeyboardEvent.code} の値を表す文字列。不足分は適宜追加する | ||||
|  * @see https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_code_values
 | ||||
|  */ | ||||
| export type KeyCode = | ||||
| export type KeyCode = ( | ||||
| 	| 'Backspace' | ||||
| 	| 'Tab' | ||||
| 	| 'Enter' | ||||
|  | @ -94,32 +94,32 @@ export type KeyCode = | |||
| 	| 'Quote' | ||||
| 	| 'Meta' | ||||
| 	| 'AltGraph' | ||||
| 	; | ||||
| ); | ||||
| 
 | ||||
| /** | ||||
|  * 修飾キーを表す文字列。不足分は適宜追加する。 | ||||
|  */ | ||||
| export type KeyModifier = | ||||
| export type KeyModifier = ( | ||||
| 	| 'Shift' | ||||
| 	| 'Control' | ||||
| 	| 'Alt' | ||||
| 	| 'Meta' | ||||
| 	; | ||||
| ); | ||||
| 
 | ||||
| /** | ||||
|  * 押下されたキー以外の状態を表す文字列。不足分は適宜追加する。 | ||||
|  */ | ||||
| export type KeyState = | ||||
| export type KeyState = ( | ||||
| 	| 'composing' | ||||
| 	| 'repeat' | ||||
| 	; | ||||
| ); | ||||
| 
 | ||||
| export type KeyEventHandler = { | ||||
| 	modifiers?: KeyModifier[]; | ||||
| 	states?: KeyState[]; | ||||
| 	code: KeyCode | 'any'; | ||||
| 	handler: (event: KeyboardEvent) => void; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export function handleKeyEvent(event: KeyboardEvent, handlers: KeyEventHandler[]) { | ||||
| 	function checkModifier(ev: KeyboardEvent, modifiers? : KeyModifier[]) { | ||||
|  |  | |||
|  | @ -37,9 +37,9 @@ export class StreamMock extends EventEmitter<StreamEvents> implements IStream { | |||
| 		// do nothing
 | ||||
| 	} | ||||
| 
 | ||||
| 	public send(typeOrPayload: string): void | ||||
| 	public send(typeOrPayload: string, payload: any): void | ||||
| 	public send(typeOrPayload: Record<string, any> | any[]): void | ||||
| 	public send(typeOrPayload: string): void; | ||||
| 	public send(typeOrPayload: string, payload: any): void; | ||||
| 	public send(typeOrPayload: Record<string, any> | any[]): void; | ||||
| 	public send(typeOrPayload: string | Record<string, any> | any[], payload?: any): void { | ||||
| 		// do nothing
 | ||||
| 	} | ||||
|  |  | |||
|  | @ -56,7 +56,7 @@ export type SoundStore = { | |||
| 	fileUrl: string; | ||||
| 
 | ||||
| 	volume: number; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export const postFormActions: PostFormAction[] = []; | ||||
| export const userActions: UserAction[] = []; | ||||
|  | @ -479,6 +479,10 @@ export const defaultStore = markRaw(new Storage('base', { | |||
| 		where: 'device', | ||||
| 		default: false, | ||||
| 	}, | ||||
| 	confirmOnReact: { | ||||
| 		where: 'device', | ||||
| 		default: false, | ||||
| 	}, | ||||
| 
 | ||||
| 	sound_masterVolume: { | ||||
| 		where: 'device', | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| import * as Misskey from 'misskey-js'; | ||||
| import type { ComputedRef, Ref } from 'vue'; | ||||
| 
 | ||||
| interface MenuRadioOptionsDef extends Record<string, any> { } | ||||
| type MenuRadioOptionsDef = Record<string, any>; | ||||
| 
 | ||||
| export type MenuAction = (ev: MouseEvent) => void; | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,7 +24,10 @@ describe('MkUrlPreview', () => { | |||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		fetchMock.mockOnceIf(/^\/url?/, () => { | ||||
| 		fetchMock.mockOnceIf((req) => { | ||||
| 			const url = new URL(req.url); | ||||
| 			return url.pathname === '/url'; | ||||
| 		}, () => { | ||||
| 			return { | ||||
| 				status: 200, | ||||
| 				body: JSON.stringify(summary), | ||||
|  |  | |||
|  | @ -22,23 +22,23 @@ | |||
| 		"lint": "pnpm typecheck && pnpm eslint" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@types/matter-js": "0.19.7", | ||||
| 		"@types/matter-js": "0.19.8", | ||||
| 		"@types/seedrandom": "3.0.8", | ||||
| 		"@types/node": "22.9.0", | ||||
| 		"@typescript-eslint/eslint-plugin": "7.1.0", | ||||
| 		"@typescript-eslint/parser": "7.1.0", | ||||
| 		"nodemon": "3.1.7", | ||||
| 		"execa": "8.0.1", | ||||
| 		"typescript": "5.6.3", | ||||
| 		"esbuild": "0.24.0", | ||||
| 		"glob": "11.0.0" | ||||
| 		"@types/node": "22.13.4", | ||||
| 		"@typescript-eslint/eslint-plugin": "8.24.0", | ||||
| 		"@typescript-eslint/parser": "8.24.0", | ||||
| 		"nodemon": "3.1.9", | ||||
| 		"execa": "9.5.2", | ||||
| 		"typescript": "5.7.3", | ||||
| 		"esbuild": "0.25.0", | ||||
| 		"glob": "11.0.1" | ||||
| 	}, | ||||
| 	"files": [ | ||||
| 		"built" | ||||
| 	], | ||||
| 	"dependencies": { | ||||
| 		"eventemitter3": "5.0.1", | ||||
| 		"matter-js": "0.19.0", | ||||
| 		"matter-js": "0.20.0", | ||||
| 		"seedrandom": "3.0.5" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue