diff --git a/.config/docker_example.yml b/.config/docker_example.yml index 5cb17a44d1..89e6925408 100644 --- a/.config/docker_example.yml +++ b/.config/docker_example.yml @@ -165,8 +165,8 @@ proxyBypassHosts: # Media Proxy #mediaProxy: https://example.com/proxy -# Proxy remote files (default: false) -#proxyRemoteFiles: true +# Proxy remote files (default: true) +proxyRemoteFiles: true # Sign to ActivityPub GET request (default: true) signToActivityPubGet: true diff --git a/.config/example.yml b/.config/example.yml index b996a83fb5..cca44ce88c 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -159,6 +159,9 @@ id: 'aid' #deliverJobMaxAttempts: 12 #inboxJobMaxAttempts: 8 +# Local address used for outgoing requests +#outgoingAddress: 127.0.0.1 + # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 @@ -183,9 +186,9 @@ proxyBypassHosts: # * Perform image compression (on a different server resource than the main process) #mediaProxy: https://example.com/proxy -# Proxy remote files (default: false) +# Proxy remote files (default: true) # Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains. -#proxyRemoteFiles: true +proxyRemoteFiles: true # Movie Thumbnail Generation URL # There is no reference implementation. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0664ecd110..0eee9d503c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "features": { "ghcr.io/devcontainers-contrib/features/pnpm:2": {}, "ghcr.io/devcontainers/features/node:1": { - "version": "20.3.1" + "version": "20.5.0" } }, "forwardPorts": [3000], diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml index 824a046dc0..5cfb6174ca 100644 --- a/.devcontainer/devcontainer.yml +++ b/.devcontainer/devcontainer.yml @@ -165,8 +165,8 @@ proxyBypassHosts: # Media Proxy #mediaProxy: https://example.com/proxy -# Proxy remote files (default: false) -#proxyRemoteFiles: true +# Proxy remote files (default: true) +proxyRemoteFiles: true # Sign to ActivityPub GET request (default: true) signToActivityPubGet: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 730647b086..e8b65dc3b9 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,7 +1,4 @@ contact_links: - - name: 👪 Misskey Forum - url: https://forum.misskey.io/ - about: Ask questions and share knowledge - name: 💬 Misskey official Discord url: https://discord.gg/Wp8gVStHW3 about: Chat freely about Misskey diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e878e5836a..5955f6b5d9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,24 +9,24 @@ updates: directory: "/" schedule: interval: daily - open-pull-requests-limit: 0 + open-pull-requests-limit: 100 + +# Add only the root, not each workspace item +# https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027 - package-ecosystem: npm directory: "/" schedule: interval: daily + # PNPM has an issue with dependabot. See: + # https://github.com/dependabot/dependabot-core/issues/7258 + # https://github.com/pnpm/pnpm/issues/6530 + # TODO: Restore this when the issue is solved open-pull-requests-limit: 0 -- package-ecosystem: npm - directory: "/packages/backend" - schedule: - interval: daily - open-pull-requests-limit: 0 -- package-ecosystem: npm - directory: "/packages/frontend" - schedule: - interval: daily - open-pull-requests-limit: 0 -- package-ecosystem: npm - directory: "/packages/sw" - schedule: - interval: daily - open-pull-requests-limit: 0 + groups: + swc: + patterns: + - "@swc/*" + storybook: + patterns: + - "storybook*" + - "@storybook/*" diff --git a/.github/workflows/api-misskey-js.yml b/.github/workflows/api-misskey-js.yml index ed004c78dc..d0018ffcf9 100644 --- a/.github/workflows/api-misskey-js.yml +++ b/.github/workflows/api-misskey-js.yml @@ -9,12 +9,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3.3.0 + uses: actions/checkout@v3.5.3 - run: corepack enable - name: Setup Node.js - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/check_copyright_year.yml b/.github/workflows/check_copyright_year.yml index 8daea44a83..174b6ab256 100644 --- a/.github/workflows/check_copyright_year.yml +++ b/.github/workflows/check_copyright_year.yml @@ -10,7 +10,7 @@ jobs: check_copyright_year: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.5.3 - run: | if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then echo "Please change copyright year!" diff --git a/.github/workflows/docker-develop.yml b/.github/workflows/docker-develop.yml index 09a2c33e0c..c839c64a72 100644 --- a/.github/workflows/docker-develop.yml +++ b/.github/workflows/docker-develop.yml @@ -13,10 +13,10 @@ jobs: if: github.repository == 'misskey-dev/misskey' steps: - name: Check out the repo - uses: actions/checkout@v3.3.0 + uses: actions/checkout@v3.5.3 - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v2.3.0 + uses: docker/setup-buildx-action@v2.9.1 with: platforms: linux/amd64,linux/arm64 - name: Docker meta diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a465d92eaf..da05f0cabe 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Check out the repo - uses: actions/checkout@v3.3.0 + uses: actions/checkout@v3.5.3 - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v2.3.0 + uses: docker/setup-buildx-action@v2.9.1 with: platforms: linux/amd64,linux/arm64 - name: Docker meta diff --git a/.github/workflows/dockle.yml b/.github/workflows/dockle.yml index 9b79ee54f0..02dbef35df 100644 --- a/.github/workflows/dockle.yml +++ b/.github/workflows/dockle.yml @@ -14,7 +14,7 @@ jobs: env: DOCKER_CONTENT_TRUST: 1 steps: - - uses: actions/checkout@v3.2.0 + - uses: actions/checkout@v3.5.3 - run: | curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v0.4.10/dockle_0.4.10_Linux-64bit.deb" sudo dpkg -i dockle.deb diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0f3702f958..d3ea13c120 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,7 +11,7 @@ jobs: pnpm_install: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 with: fetch-depth: 0 submodules: true @@ -19,7 +19,7 @@ jobs: with: version: 8 run_install: false - - uses: actions/setup-node@v3.6.0 + - uses: actions/setup-node@v3.8.1 with: node-version-file: '.node-version' cache: 'pnpm' @@ -38,7 +38,7 @@ jobs: - sw - misskey-js steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 with: fetch-depth: 0 submodules: true @@ -46,7 +46,7 @@ jobs: with: version: 7 run_install: false - - uses: actions/setup-node@v3.6.0 + - uses: actions/setup-node@v3.8.1 with: node-version-file: '.node-version' cache: 'pnpm' @@ -64,7 +64,7 @@ jobs: - backend - misskey-js steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 with: fetch-depth: 0 submodules: true @@ -72,7 +72,7 @@ jobs: with: version: 7 run_install: false - - uses: actions/setup-node@v3.6.0 + - uses: actions/setup-node@v3.8.1 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/ok-to-test.yml b/.github/workflows/ok-to-test.yml index 87af3a6ba6..71d09f7814 100644 --- a/.github/workflows/ok-to-test.yml +++ b/.github/workflows/ok-to-test.yml @@ -23,7 +23,7 @@ jobs: private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }} - name: Slash Command Dispatch - uses: peter-evans/slash-command-dispatch@v1 + uses: peter-evans/slash-command-dispatch@v3 env: TOKEN: ${{ steps.generate_token.outputs.token }} with: diff --git a/.github/workflows/pr-preview-deploy.yml b/.github/workflows/pr-preview-deploy.yml index 9b786d34aa..fd1417b65b 100644 --- a/.github/workflows/pr-preview-deploy.yml +++ b/.github/workflows/pr-preview-deploy.yml @@ -53,7 +53,7 @@ jobs: # Check out merge commit - name: Fork based /deploy checkout - uses: actions/checkout@v3.3.0 + uses: actions/checkout@v3.5.3 with: ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge' diff --git a/.github/workflows/reviewer_lottery.yml b/.github/workflows/reviewer_lottery.yml index 33228d7465..f8f7d22532 100644 --- a/.github/workflows/reviewer_lottery.yml +++ b/.github/workflows/reviewer_lottery.yml @@ -7,7 +7,7 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: uesteibar/reviewer-lottery@v2 + - uses: actions/checkout@v3.5.3 + - uses: uesteibar/reviewer-lottery@v3 with: repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 1aea8b5459..b068041f3c 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -15,12 +15,12 @@ jobs: NODE_OPTIONS: "--max_old_space_size=7168" steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 if: github.event_name != 'pull_request_target' with: fetch-depth: 0 submodules: true - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 if: github.event_name == 'pull_request_target' with: fetch-depth: 0 @@ -38,7 +38,7 @@ jobs: version: 8 run_install: false - name: Use Node.js 20.x - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version-file: '.node-version' cache: 'pnpm' diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml index 96e64c322e..f0a152731a 100644 --- a/.github/workflows/test-backend.yml +++ b/.github/workflows/test-backend.yml @@ -29,7 +29,7 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 with: submodules: true - name: Install pnpm @@ -38,7 +38,7 @@ jobs: version: 8 run_install: false - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index eef68aa0d1..46a35ed848 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -16,7 +16,7 @@ jobs: node-version: [20.x] steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 with: submodules: true - name: Install pnpm @@ -25,7 +25,7 @@ jobs: version: 8 run_install: false - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -68,7 +68,7 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 with: submodules: true # https://github.com/cypress-io/cypress-docker-images/issues/150 @@ -83,7 +83,7 @@ jobs: version: 7 run_install: false - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -101,7 +101,7 @@ jobs: - name: Cypress install run: pnpm exec cypress install - name: Cypress run - uses: cypress-io/github-action@v5 + uses: cypress-io/github-action@v6 with: install: false start: pnpm start:test diff --git a/.github/workflows/test-misskey-js.yml b/.github/workflows/test-misskey-js.yml index 213657ce1f..bd9c21f5e0 100644 --- a/.github/workflows/test-misskey-js.yml +++ b/.github/workflows/test-misskey-js.yml @@ -21,12 +21,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3.3.0 + uses: actions/checkout@v3.5.3 - run: corepack enable - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.github/workflows/test-production.yml b/.github/workflows/test-production.yml index 8429465b5b..5be24f83ec 100644 --- a/.github/workflows/test-production.yml +++ b/.github/workflows/test-production.yml @@ -19,7 +19,7 @@ jobs: node-version: [20.x] steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.3 with: submodules: true - name: Install pnpm @@ -28,7 +28,7 @@ jobs: version: 8 run_install: false - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' diff --git a/.node-version b/.node-version index dd0fe95cce..6a148f2818 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -20.3.1 +20.5.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b654699d4..e57a2c4fd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -## 13.x.x (unreleased) + +## 2023.9.0 (unreleased) ### General -- +- OAuth 2.0のサポート +- お知らせ機能の強化 + - ユーザー個別のお知らせを作成可能に + - お知らせのバナー表示やダイアログ表示が可能に + - お知らせのアイコンを設定可能に +- チャンネルをセンシティブ指定できるようになりました + +### Client +- プロフィールにその人が作ったPlayの一覧出せるように +- メニューのスイッチの動作を改善 +- 絵文字ピッカーの検索の表示件数を100件に増加 +- 投稿フォームのプレビューの表示状態を記憶するように +- Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように +- Enhance: 自分が押したリアクションのデザインを改善 +- Enhance: ノート検索にローカルのみ検索可能なオプションの追加 +- Enhance: AiScriptで`LOCALE`として現在の設定言語を取得できるように +- `$[rainbow ]`記法が、動きのあるMFMが無効になっていても使用できるようになりました +- Playの操作を行うAPI TokenをAPIコンソールから発行できるように +- Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正 +- Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正 +- Fix: iOSで画面を回転させるとテキストサイズが変わる問題を修正 +- Fix: word mute for sub note is not applied +- Fix: タイムラインを下にスクロールしてノート画面に移動して再び戻ったら以前のスクロール位置を失う問題を修正 +- Fix: Misskeyプラグインをインストールする際のAiScriptバージョンのチェックが0.14.0以降に対応していない問題を修正 +- Fix: 他のサーバーのユーザーへ「メッセージを送信」した時の初期テキストのメンションが間違っている問題を修正 + +### Server +- Fix: ノート検索 `notes/search` にてhostを指定した際に検索結果に反映されるように +- cacheRemoteFilesの初期値はfalseになりました +- ファイルアップロード時等にファイル名の拡張子を修正する関数(correctFilename)の挙動を改善 +- Webhookのペイロードにサーバーのurlが含まれるようになりました +- Fix: 一部のfeatured noteを照会できない問題を修正 +- Fix: muteがapiからのuser list timeline取得で機能しない問題を修正 +- Fix: ジョブキュー管理画面の認証を回避できる問題を修正 +- Fix: 一部のサーバー内部エラーがスタックトレースを返さないように修正 + +## 13.14.2 ### Client - リストTLで、ユーザーが追加・削除されてもTLを初期化しないように +- URL取得変数を関数に変更 CURRENT_URL -> Mk:url() - Fix: モバイル表示のときページ下部がナビゲーションバーに隠れる問題を修正 +- Fix: 一部モーダルダイアログでスクロールできない問題を修正 +- Fix: Selecting all emojis in Custom emoji is impossible +- Fix: PhotoSwipeによるメモリリークの修正 ### Server - Fix: APIのオフセットが壊れていたせいで「もっと見る」でもっと見れない問題を修正 +- Fix: 外部サーバーの投稿がタイムラインに表示されないことがある問題を修正 +- Enhance: Add address bind config option (outgoingAddress) ## 13.14.1 diff --git a/Dockerfile b/Dockerfile index 5431c28aad..ce9d740ab6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax = docker/dockerfile:1.4 -ARG NODE_VERSION=20.3.1-bullseye +ARG NODE_VERSION=20.5.0-bullseye # build assets & compile TypeScript diff --git a/ROADMAP.md b/ROADMAP.md index 420f728758..3077c41e73 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -22,7 +22,7 @@ This is the phase we are at now. We need to make a high-maintenance environment Once Phase 1 is complete and an environment conducive to the development of a stable system is in place, the implementation of new functions can begin gradually. - Improve features for moderation -- OAuth2 support https://github.com/misskey-dev/misskey/issues/8262 +- ~~OAuth2 support https://github.com/misskey-dev/misskey/issues/8262~~ → Done ✔️ - GraphQL support? ## (3) Improve scalability diff --git a/healthcheck.sh b/healthcheck.sh index e97a3f0636..0a36394836 100644 --- a/healthcheck.sh +++ b/healthcheck.sh @@ -1,4 +1,7 @@ #!/bin/bash +# SPDX-FileCopyrightText: syuilo and other misskey contributors +# SPDX-License-Identifier: AGPL-3.0-only + PORT=$(grep '^port:' /misskey/.config/default.yml | awk 'NR==1{print $2; exit}') curl -s -S -o /dev/null "http://localhost:${PORT}" diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 116973a4e6..31b9d153c3 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -645,6 +645,7 @@ optional: "اختياري" createNewClip: "أنشئ مِشبكَا جديدًا" confirmToUnclipAlreadyClippedNote: "هذه الملاحظة تنتمي للمشبك {name} سلفًا، أتريد حذفها منه⸮" public: "علني" +private: "خاص" i18nInfo: "يترجم متطوعون ميسكي إلى عدة لغات، يمكنك المساعدة عبر {link}" manageAccessTokens: "إدارة رموز الوصول" accountInfo: "معلومات الحساب" @@ -986,6 +987,7 @@ later: "لاحقاً" goToMisskey: "لميسكي" additionalEmojiDictionary: "قواميس إيموجي إضافية" installed: "مُثبت" +icon: "الصورة الرمزية" _initialAccountSetting: accountCreated: "نجح إنشاء حسابك!" letsStartAccountSetup: "إذا كنت جديدًا لنعدّ حسابك الشخصي." @@ -1487,22 +1489,22 @@ _notification: fileUploaded: "نجح رفع الملف" youGotMention: "{name} أشار إليك" youGotReply: "ردّ عليك {name}" - youGotQuote: "اقتبس منك {name}" - youRenoted: "إعادت نشر من {name}" + youGotQuote: "اقتبس {name} منشورك" + youRenoted: "أعاد {name} نشر منشورك" youWereFollowed: "يتابعك" youReceivedFollowRequest: "تلقيتَ طلب متابعة" yourFollowRequestAccepted: "قُبل طلب المتابعة" - pollEnded: "ظهرت نتائج الاستطلاع" + pollEnded: "انتهى الاستطلاع" unreadAntennaNote: "هوائي {name}" _types: all: "الكل" follow: "متابِعون جدد" mention: "الإشارات" reply: "الردود" - renote: "أعد النشر" + renote: "أعاد النشر" quote: "الاقتباسات" - reaction: "التفاعلات" - receiveFollowRequest: "طلبات المتابعة المتلقاة" + reaction: "التفاعل" + receiveFollowRequest: "طلبات المتابعة" followRequestAccepted: "طلبات المتابعة المقبولة" app: "إشعارات التطبيقات المرتبطة" _actions: @@ -1510,26 +1512,26 @@ _notification: reply: "رد" renote: "أعد النشر" _deck: - alwaysShowMainColumn: "أظهر العمود الرئيسي دائمًا" - columnAlign: "حاذِ الأعمدة" - addColumn: "أضف عمودًا" - swapLeft: "حرّك لليسار" - swapRight: "حرّك لليمين" - swapUp: "حرّك لأعلى" - swapDown: "حرّك لأسفل" - profile: "الملف الشخصي" + alwaysShowMainColumn: "أظهر العمود الأساسي دائمًا" + columnAlign: "محاذاة الأعمدة" + addColumn: "إضافة عمود" + swapLeft: "التحريك إلى اليسار" + swapRight: "التحريك إلى اليمين" + swapUp: "التحريك إلى الأعلى" + swapDown: "التحريك إلى الأسفل" + profile: "حسابي الشخصي" _columns: - main: "الرئيسي" - widgets: "الودجات" + main: "الرئيسية" + widgets: "التطبيقات المُصغّرة" notifications: "الإشعارات" - tl: "الخيط الزمني" + tl: "الخط الزمني" antenna: "الهوائيات" list: "القوائم" channel: "القنوات" mentions: "الإشارات" direct: "مباشرة" _webhookSettings: - name: "الإسم" - active: "مفعّل" + name: "الاسم" + active: "مُفعّل" _events: - reaction: "عند تلقي تفاعل" + reaction: "عند التفاعل" diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index 78dbd77eb2..12c77732cf 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -628,6 +628,7 @@ createNew: "নতুন" optional: "প্রয়োজনীয় নয়" createNewClip: "নতুন ক্লিপ তৈরি করুন" public: "সর্বজনীন" +private: "ব্যাক্তিগত" i18nInfo: "Misskey স্বেচ্ছাসেবকদের দ্বারা বিভিন্ন ভাষায় অনুবাদ করা হচ্ছে। আপনি {link} এ গিয়ে অনুবাদে সহযোগিতা করতে পারেন।" manageAccessTokens: "অ্যাক্সেস টোকেন পরিচালনা করুন" accountInfo: "অ্যাকাউন্টের তথ্য" @@ -837,6 +838,7 @@ show: "প্রদর্শন" color: "রং" horizontal: "পাশে" youFollowing: "অনুসরণ করা হচ্ছে" +icon: "প্রোফাইল ছবি" _role: priority: "অগ্রাধিকার" _priority: diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index e3a6ec11b2..7e7cb40c11 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -13,12 +13,14 @@ fetchingAsApObject: "Cercant en el Fediverse..." ok: "OK" gotIt: "Ho he entès!" cancel: "Cancel·lar" +noThankYou: "No, gràcies" enterUsername: "Introdueix el teu nom d'usuari" renotedBy: "Impulsat per {usuari}" noNotes: "Cap nota" noNotifications: "Cap notificació" instance: "Servidor" settings: "Preferències" +notificationSettings: "Paràmetres de notificacions" basicSettings: "Configuració bàsica" otherSettings: "Configuració avançada" openInWindow: "Obrir en una nova finestra" @@ -47,8 +49,15 @@ delete: "Elimina" deleteAndEdit: "Elimina i edita" deleteAndEditConfirm: "Segur que vols eliminar aquesta publicació i editar-la? Perdràs totes les reaccions, impulsos i respostes." addToList: "Afegir a una llista" +addToAntenna: "Afegir a l'antena" sendMessage: "Enviar un missatge" +copyRSS: "Copiar RSS" copyUsername: "Copiar nom d'usuari" +copyUserId: "Copiar ID d'usuari" +copyNoteId: "Copiar ID de nota" +copyFileId: "Copiar ID d'arxiu" +copyFolderId: "Copiar ID de carpeta" +copyProfileUrl: "Copiar URL del perfil" searchUser: "Cercar un usuari" reply: "Respondre" loadMore: "Carregar més" @@ -128,6 +137,7 @@ suspendConfirm: "Estàs segur que vols suspendre aquest compte?" unsuspendConfirm: "Estàs segur que vols treure la suspensió d'aquest compte?" selectList: "Tria una llista" selectAntenna: "Tria una antena" +editAntenna: "Modificar antena" selectWidget: "Triar un giny" editWidgets: "Editar ginys" editWidgetsExit: "Fet" @@ -298,8 +308,10 @@ manageAntennas: "Gestiona les antenes" antennaSource: "Font de l'antena" antennaKeywords: "Paraules clau a seguir" antennaExcludeKeywords: "Paraules clau a excloure" +antennaKeywordsDescription: "Separar amb espais per la condició AND o amb salts de línia per la condició OR." notifyAntenna: "Notifica'm les publicacions noves" withFileAntenna: "Només les publicacions amb fitxers" +antennaUsersDescription: "Llistar un nom d'usuari per línia" notesAndReplies: "Amb respostes" silence: "Silencia" silenceConfirm: "Segur que vols silenciar aquest usuari?" @@ -369,6 +381,9 @@ user: "Usuaris" global: "Global" searchByGoogle: "Cercar" file: "Fitxers" +_role: + _options: + antennaMax: "Nombre màxim d'antenes" _email: _follow: title: "t'ha seguit" @@ -385,6 +400,7 @@ _sfx: antenna: "Antenes" _2fa: step2Url: "També pots inserir aquest enllaç i utilitzes una aplicació d'escriptori:" + renewTOTPCancel: "No, gràcies" _antennaSources: all: "Totes les publicacions" homeTimeline: "Publicacions dels usuaris seguits" @@ -430,6 +446,7 @@ _pages: _notification: youRenoted: "Impulsat per {name}" youWereFollowed: "t'ha seguit" + unreadAntennaNote: "Antena {name}" _types: all: "Tots" follow: "Seguint" diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index ceab50075a..21c0e80fc9 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -2,6 +2,7 @@ _lang_: "Čeština" headlineMisskey: "Síť propojená poznámkami" introMisskey: "Vítejte! Misskey je otevřený a decentralizovaný microblogový servis.\n\"Poznámkami\" můžete sdílet co se zrovna děje se všemi ve Vašem okolí. 📡\nPomocí \"reakcí\" můžete sdílet své názory a pocity na ostatní poznámky. 👍\nPojďte objevovat nový svět! 🚀" +poweredByMisskeyDescription: "{name} je jeden ze serverů využívající open source platformu Misskey (nazývaná \"Misskey instance\")." monthAndDay: "{day}. {month}." search: "Vyhledávání" notifications: "Oznámení" @@ -48,8 +49,15 @@ delete: "Smazat" deleteAndEdit: "Smazat a upravit" deleteAndEditConfirm: "Jste si jistí že chcete smazat tuto poznámku a editovat ji? Ztratíte tím všechny reakce, sdílení a odpovědi na ni." addToList: "Přidat do seznamu" +addToAntenna: "Přidat do antény" sendMessage: "Odeslat zprávu" +copyRSS: "Kopírovat RSS" copyUsername: "Kopírovat uživatelské jméno" +copyUserId: "Kopírovat ID uživatele" +copyNoteId: "Kopírovat ID poznámky" +copyFileId: "Kopírovat ID souboru" +copyFolderId: "Kopírovat ID složky" +copyProfileUrl: "Kopírovat URL profilu" searchUser: "Vyhledat uživatele" reply: "Odpovědět" loadMore: "Zobrazit více" @@ -60,6 +68,7 @@ receiveFollowRequest: "Žádost o sledování přijata" followRequestAccepted: "Žádost o sledování přijata" mention: "Zmínění" mentions: "Zmínění" +directNotes: "Přímé poznámky" importAndExport: "Import a export" import: "Importovat" export: "Exportovat" @@ -82,6 +91,7 @@ error: "Chyba" somethingHappened: "Jejda. Něco se nepovedlo." retry: "Opakovat" pageLoadError: "Nepodařilo se načíst stránku" +pageLoadErrorDescription: "Tohle je obvykle způsobeno chybou sítě nebo mezipaměti prohlížeče. Zkuste vymazat mezipaměť a po chvíli čekání to zkuste znovu." serverIsDead: "Server neodpovídá. Počkejte chvíli a zkuste to znovu." youShouldUpgradeClient: "Pro zobrazení této stránky obnovte stránku pro aktualizaci klienta." enterListName: "Jméno seznamu" @@ -100,6 +110,8 @@ renoted: "Přeposláno" cantRenote: "Tento příspěvek nelze přeposlat." cantReRenote: "Odpověď nemůže být odstraněna." quote: "Citovat" +inChannelRenote: "Přeposlání v kanálu" +inChannelQuote: "Citace v kanálu" pinnedNote: "Připnutá poznámka" pinned: "Připnout" you: "Vy" @@ -108,6 +120,7 @@ sensitive: "NSFW" add: "Přidat" reaction: "Reakce" reactions: "Reakce" +reactionSetting: "Reakce zobrazené ve výběru reakcí" reactionSettingDescription2: "Přetažením změníte pořadí, kliknutím smažete, zmáčkněte \"+\" k přidání" rememberNoteVisibility: "Zapamatovat nastavení zobrazení poznámky" attachCancel: "Odstranit přílohu" @@ -116,6 +129,8 @@ unmarkAsSensitive: "Odznačit jako NSFW" enterFileName: "Zadejte název souboru" mute: "Ztlumit" unmute: "Odmlčet" +renoteMute: "Ztlumit poznámky" +renoteUnmute: "Zrušit ztlumení poznámek" block: "Zablokovat" unblock: "Odblokovat" suspend: "Zmrazit" @@ -125,7 +140,10 @@ unblockConfirm: "Jste si jistí že chcete odblokovat tento účet?" suspendConfirm: "Jste si jistí že chcete suspendovat tenhle účet?" unsuspendConfirm: "Jste si jistí že chcete obnovit tenhle účet?" selectList: "Vybrat seznam" +editList: "Upravit seznam" +selectChannel: "Vybrat kanál" selectAntenna: "Vyberte Anténu" +editAntenna: "Upravit anténu" selectWidget: "Zvolte widget" editWidgets: "Upravit widget" editWidgetsExit: "Hotovo" @@ -138,6 +156,8 @@ addEmoji: "Přidat emoji" settingGuide: "Doporučené nastavení" cacheRemoteFiles: "Ukládání vzdálených souborů do mezipaměti" cacheRemoteFilesDescription: "Zakázání tohoto nastavení způsobí, že vzdálené soubory budou odkazovány přímo, místo aby byly ukládány do mezipaměti. Tím se ušetří úložiště na serveru, ale zvýší se provoz, protože se negenerují miniatury." +cacheRemoteSensitiveFiles: "Uložit do mezipaměti vzdálené citlivé soubory" +cacheRemoteSensitiveFilesDescription: "Když je tohle nastavení zrušeno, tak jsou vzdálené citlivé soubory načítány přímo ze vzdálených instancí bez uložení do mezipaměti." flagAsBot: "Tento účet je bot" flagAsBotDescription: "Pokud je tento účet kontrolován programem zaškrtněte tuto možnost. To označí tento účet jako bot pro ostatní vývojáře a zabrání tak nekonečným interakcím s ostatními boty a upraví Misskey systém aby se choval k tomuhle účtu jako bot." flagAsCat: "Tenhle účet je kočka" @@ -146,6 +166,7 @@ flagShowTimelineReplies: "Zobrazovat odpovědi na časové ose" flagShowTimelineRepliesDescription: "Je-li zapnuto, zobrazí odpovědi uživatelů na poznámky jiných uživatelů na vaší časové ose." autoAcceptFollowed: "Automaticky akceptovat následování od účtů které sledujete" addAccount: "Přidat účet" +reloadAccountsList: "Obnovit list účtů" loginFailed: "Přihlášení se nezdařilo." showOnRemote: "Více na původním profilu" general: "Obecně" @@ -186,17 +207,27 @@ instanceInfo: "Informace o instanci" statistics: "Statistiky" clearQueue: "Vyčistit frontu" clearQueueConfirmTitle: "Jste si jisti že zrušit všechny úlohy ve frontě?" +clearQueueConfirmText: "Jakékoliv nedoručené poznámky ve frontě nebudou sdružovány. Většinou tahle operace není zapotřebí." clearCachedFiles: "Vyprázdnit mezipaměť" +clearCachedFilesConfirm: "Jste jistí že chcete smazat všechny vzdálené soubory v mezipaměti?" blockedInstances: "Blokované instance" +blockedInstancesDescription: "Vypište názvy hostitelů instancí, které chcete blokovat odděleně řádkovými zlomky. Uvedené instance již nebudou moci s touto instancí komunikovat." +muteAndBlock: "Ztlumení a blokování" +mutedUsers: "Zltumení uživatelé" +blockedUsers: "Blokovaní uživatelé" noUsers: "Žádní uživatelé" editProfile: "Upravit můj profil" +noteDeleteConfirm: "Jste si jistí že chcete smazat tuhle poznámku?" pinLimitExceeded: "Nemůžete připnout další poznámky." intro: "Instalace Misskey byla dokončena! Prosím vytvořte admina." done: "Hotovo" processing: "Zpracovávám" preview: "Náhled" default: "Výchozí" +defaultValueIs: "Základní hodnota: {value}" noCustomEmojis: "Bez Emoji" +noJobs: "Žádné úlohy" +federating: "Sdružování" blocked: "Blokováno" suspended: "Suspendováno" all: "Vše" @@ -217,6 +248,7 @@ more: "Více!" featured: "Oblíbené poznámky" usernameOrUserId: "Uživatelské jméno nebo uživatelské id" noSuchUser: "Uživatel nebyl nalezen" +lookup: "Vyhledat" announcements: "Oznámení" imageUrl: "URL obrázku" remove: "Smazat" @@ -227,10 +259,13 @@ resetAreYouSure: "Opravdu resetovat?" saved: "Uloženo" messaging: "Zprávy" upload: "Nahrát soubory" +keepOriginalUploading: "Ponechat originální obrázek" +keepOriginalUploadingDescription: "Uloží původní nahraný obrázek jak je. Pokud je to vypnuté, vygeneruje se zobrazení verze na webu při nahrátí." fromDrive: "Z disku" fromUrl: "Z URL" uploadFromUrl: "Nahrát z URL adresy" uploadFromUrlDescription: "URL adresa souboru, který chcete nahrát" +uploadFromUrlRequested: "Upload zažádán" uploadFromUrlMayTakeTime: "Může trvat nějakou dobu, dokud nebude dokončeno nahrávání." explore: "Objevovat" messageRead: "Přečtené" @@ -238,6 +273,10 @@ noMoreHistory: "To je vše" startMessaging: "Zahájit chat" nUsersRead: "přečteno {n} uživateli" agreeTo: "Souhlasím s {0}" +agree: "Souhlasím" +agreeBelow: "Souhlasím s následným" +basicNotesBeforeCreateAccount: "Důležité poznámky" +termsOfService: "Podmínky užívání" start: "Začít" home: "Domů" remoteUserCaution: "Tyto informace nemusí být aktuální jelikož uživatel je ze vzdálené instance." @@ -268,17 +307,24 @@ createFolder: "Vytvořit složku" renameFolder: "Přejmenovat složku" deleteFolder: "Odstranit složku" addFile: "Přidat soubor" +emptyDrive: "Váš disk je prázdný" emptyFolder: "Tato složka je prázdná" unableToDelete: "Nelze smazat" inputNewFileName: "Zadejte nový název" +inputNewDescription: "Zadejte nový popisek" inputNewFolderName: "Zadejte název nové složky" +circularReferenceFolder: "Koncová složka je podsložka složky, kterou chcete přesunout." +hasChildFilesOrFolders: "Nemůžete odstranit složku, která není prázdná." copyUrl: "Kopírovat URL" rename: "Přejmenovat" avatar: "Avatar" banner: "Baner" +displayOfSensitiveMedia: "Zobrazit citlivé média" +whenServerDisconnected: "Když ztratíte spojení se serverem" disconnectedFromServer: "Spojení bylo přerušeno" reload: "Aktualizovat" doNothing: "Ignorovat" +reloadConfirm: "Chcete obnovit časovou osu?" watch: "Sledovat" unwatch: "Přestat sledovat" accept: "Souhlasím" @@ -301,15 +347,22 @@ connectService: "Připojit" disconnectService: "Odpojit" enableLocalTimeline: "Povolit lokální čas" enableGlobalTimeline: "Povolit globální čas" +disablingTimelinesInfo: "Administrátoři a Moderátoři budou mít stálý přístup ke všem časovým osám i přes to že nejsou zapnuté." registration: "Registrace" enableRegistration: "Povolit registraci novým uživatelům" invite: "Pozvat" +driveCapacityPerLocalAccount: "Kapacita disku na lokálního uživatele" +driveCapacityPerRemoteAccount: "Kapacita disku na vzdáleného uživatele" inMb: "V megabajtech" iconUrl: "Favicon URL" bannerUrl: "Baner URL" backgroundImageUrl: "Adresa URL obrázku pozadí" basicInfo: "Základní informace" pinnedUsers: "Připnutí uživatelé" +pinnedUsersDescription: "Seznam uživatelských přezdívek oddělených řádkami bude připnutý v záložce \"Objevit\"." +pinnedPages: "Připnutý stránky" +pinnedPagesDescription: "Zadejte cesty stránek oddělené řádkami, které si přejete mít přípnutý na vrcholu téhle instance." +pinnedClipId: "ID připnutého klipu" pinnedNotes: "Připnutá poznámka" hcaptcha: "hCaptcha" enableHcaptcha: "Aktivovat hCaptchu" @@ -319,30 +372,56 @@ recaptcha: "reCAPTCHA" enableRecaptcha: "Zapnout ReCAPTCHu" recaptchaSiteKey: "Klíč stránky" recaptchaSecretKey: "Tajný Klíč (Secret Key)" +turnstile: "Turnstile" +enableTurnstile: "Povolit Turnstile" turnstileSiteKey: "Klíč stránky" turnstileSecretKey: "Tajný Klíč (Secret Key)" +avoidMultiCaptchaConfirm: "Používání několik Captcha systému může způsobit konflikt mezi nimi. Chtěli byste vypnout ostatní aktivní Captcha systémy? Pokud je chcete nechat zapnuté, stiskněte zrušit." antennas: "Antény" manageAntennas: "Spravovat Antény" name: "Jméno" antennaSource: "Zdroj Antény" +antennaKeywords: "Klíčová slova na poslech" +antennaExcludeKeywords: "Vyloučená klíčová slova" +antennaKeywordsDescription: "Oddělte mezerami pro AND kondice nebo řádkami pro OR kondice." +notifyAntenna: "Upozornit na nové poznámky" +withFileAntenna: "Poznámky jenom se souborama" enableServiceworker: "Povolit ServiceWorker" +antennaUsersDescription: "Vypsat jednoho uživatele na řádek" caseSensitive: "Rozlišuje malá a velká písmena" +withReplies: "Zahrnout odpovědi" connectedTo: "Následující účty jsou připojeny" notesAndReplies: "Poznámky a odpovědi" withFiles: "Včetně souborů" +silence: "Ztlumení" +silenceConfirm: "Jste si jistí že chcete ztlumit tohoto uživatele?" +unsilence: "Zrušit ztlumení" +unsilenceConfirm: "Jste jistí že chcete vrátit zltumení tohoto uživatele?" popularUsers: "Populární uživatelé" recentlyUpdatedUsers: "Nedávno aktívni uživatelé" +recentlyRegisteredUsers: "Nově připojený uživatelé" +recentlyDiscoveredUsers: "Nově objevený uživatelé" +exploreUsersCount: "Existuje {count} uživatelů" +exploreFediverse: "Objevovat Fediverse" popularTags: "Populární tagy" userList: "Seznamy" about: "Informace" aboutMisskey: "O Misskey" administrator: "Administrátor" token: "Token" +2fa: "Dvoufázové ověření" +totp: "Ověřovací aplikace" +totpDescription: "Použít ověřovací aplikaci pro použití jednorázových hesel" moderator: "Moderátor" +moderation: "Moderování" nUsersMentioned: "{n} uživatelů zmínilo" +securityKeyAndPasskey: "Bezpečnostní klíče a tokeny" securityKey: "Bezpečnostní klíč" lastUsed: "Naposledy použito" +lastUsedAt: "Naposledy použito: {t}" unregister: "Odstranit" +passwordLessLogin: "Přihlášení bez hesla" +passwordLessLoginDescription: "Umožní bez-heslové přihlášení pomocí bezpečnostního klíče či tokenu" resetPassword: "Resetovat heslo" newPasswordIs: "Nové heslo je \"{password}\"" reduceUiAnimation: "Snížit UI animace" @@ -391,14 +470,25 @@ or: "Nebo" language: "Jazyk" uiLanguage: "Jazyk uživatelského rozhraní" aboutX: "O {x}" +emojiStyle: "Styl emoji" +native: "Výchozí" +disableDrawer: "Nepoužívat šuplíkové menu" +showNoteActionsOnlyHover: "Zobrazit akce poznámky jenom při naběhnutí myši" noHistory: "Žádná historie" signinHistory: "Historie přihlášení" +enableAdvancedMfm: "Zapnout pokročilé MFM" +enableAnimatedMfm: "Zapnout animované MFM" +doing: "Procesuju..." category: "Kategorie" tags: "Štítky" +docSource: "Zdroj tohoto dokumentu" createAccount: "Vytvořit účet" existingAccount: "Existující účet" regenerate: "Obnovit" fontSize: "Velikost písma" +mediaListWithOneImageAppearance: "Výška seznamu médií s jedním obrázkem" +limitTo: "Omezeno na {x}" +noFollowRequests: "Nemáte žádné žádosti o sledování" openImageInNewTab: "Otevřít obrázek v novém panelu" dashboard: "Přehled" local: "Lokální" @@ -412,15 +502,35 @@ accountSettings: "Nastavení účtu" promotion: "Propagace" promote: "Propagovat" numberOfDays: "Počet dní" +hideThisNote: "Skrýt tuto poznámku" +showFeaturedNotesInTimeline: "Zobrazit významné poznámky v časové ose" +objectStorage: "Úložiště objektů" +useObjectStorage: "Použít úložiště objektů" objectStorageBaseUrl: "Base URL" +objectStorageBaseUrlDesc: "URL použitá jako reference. Upřesněte URL vlastní CDN nebo Proxy pokud používáte jeden z nich. Pro S3 použijte 'https://.s3.amazonaws.com' a pro GCS nebo ekvivalentní služby použijte 'https://storage.googleapis.com/', apd." objectStorageBucket: "Bucket" +objectStorageBucketDesc: "Prosím upřesněte název bucketu používaný poskytovatelem." objectStoragePrefix: "Předpona" +objectStoragePrefixDesc: "Soubory budou ukládány pod složkama s tímhle prefixem." objectStorageEndpoint: "Endpoint" +objectStorageEndpointDesc: "Ponechte tohle prázdné pokud používáte AWS S3, jinak upřesněte endpoint jako \"\" nebo \":\", podle toho jakou službu používáte." objectStorageRegion: "Región" +objectStorageRegionDesc: "Upřesněte region jako například \"xx-east-1\". Pokud vlastní služba nerozlišuje mezi regiony, zadejte \"us-east-1\". Zanechte prázdné pokud používáte AWS konfiguraci či proměnné veličiny." objectStorageUseSSL: "Použít SSL" +objectStorageUseSSLDesc: "Vypněte to pokud nebudete používat HTTPS pro API připojení" +objectStorageUseProxy: "Připojení skrze Proxy" +objectStorageUseProxyDesc: "Vypněte to pokud nebudete používat Proxy pro API připojení." +objectStorageSetPublicRead: "Při nahrátí nastavit na \"public-read\"" +s3ForcePathStyleDesc: "Pokud je povolena funkce s3ForcePathStyle, musí být název Bucketu zahrnut do cesty k adrese URL, nikoli do názvu hostitele adresy URL. Toto nastavení může být nutné povolit při používání služeb, jako je například samostatně hostovaná instance Minio." +serverLogs: "Logy serveru" deleteAll: "Smazat vše" showFixedPostForm: "Zobrazit formulář pro nové příspěvky nad časovou osou" +showFixedPostFormInChannel: "Zobrazit vkládací formulář na vrcholu časové osy (Kanály)" +newNoteRecived: "Jsou k dispozici nové poznámky" +sounds: "Zvuky" +sound: "Zvuky" listen: "Poslouchat" +none: "Žádný" showInPage: "Zobrazit na stránce" popout: "Pop-out" volume: "Hlasitost" @@ -433,29 +543,61 @@ install: "Nainstalovat" uninstall: "Odinstalovat" installedApps: "Autorizované aplikace" nothing: "Nic nebylo nalezeno" +installedDate: "Datum autorizace" lastUsedDate: "Poslední použití" state: "Stav" sort: "Seřadit" ascendingOrder: "Vzestupně" descendingOrder: "Sestupně" scratchpad: "Zápisník" +scratchpadDescription: "Scratchpad poskytuje rozhraní pro AiScript experimenty. Můžete psát, spustit či zkontrolovat výsledky jeho interakce s Misskey." output: "Výstup" script: "Skript" +disablePagesScript: "Vypnout AiScript na stránkách" updateRemoteUser: "Aktualizovat informace o vzdáleném účtu" deleteAllFiles: "Smazat všechny soubory" deleteAllFilesConfirm: "Jste si jistí že chcete smazat všechny soubory?" +removeAllFollowing: "Přestat sledovat všechny sledované uživatele" +removeAllFollowingDescription: "Spuštěním přestanete sledovat všechny účty z {host}. Prosíme spustěte tohle v případě že instance už neexistuje. " userSuspended: "Tomuto uživateli byl pozastaven účet." +userSilenced: "Tenhle uživatel je umlčen." +yourAccountSuspendedTitle: "Tenhle účet je zmrazený" +yourAccountSuspendedDescription: "Tenhle účet byl zmrazen z důvodu porušení smluvní podmínky serveru. Pro přesnější informace kontaktujte administrátora. Prosíme nezakládejte si nový účet." +tokenRevoked: "Nesprávný token" +tokenRevokedDescription: "Tenhle token vyprchal. Prosíme přihlašte se znova." +accountDeleted: "Účet smazán" +accountDeletedDescription: "Tenhle účet byl smazán." menu: "Menu" divider: "Dělící čára" addItem: "Přidat položku" +rearrange: "Přeřadit" relays: "Relay" addRelay: "Přidat Relay" inboxUrl: "Inbox URL" +addedRelays: "Přidané přenosy" +serviceworkerInfo: "Musí být zapnut pro push notifikace." deletedNote: "Odstraněné příspěvky" invisibleNote: "Skryté příspěvky" +enableInfiniteScroll: "Automaticky načítat více" +visibility: "Viditelnost" +poll: "Anketa" +useCw: "Schovat obsah" +enablePlayer: "Otevřít video přehrávač" +disablePlayer: "Zavřít video přehrávač" +expandTweet: "Rozbalit tweet" +themeEditor: "Editor témat" description: "Popis" +describeFile: "Přidat popisek" +enterFileDescription: "Vložit popisek" author: "Autor" +leaveConfirm: "Máte neuložené změny. Opravdu je chcete zahodit?" manage: "Administrace" +plugins: "Pluginy" +preferencesBackups: "Zálohy nastavení" +deck: "Deck" +undeck: "Opustit Deck" +useBlurEffectForModal: "Použít efekt rozostření na okna" +useFullReactionPicker: "Používat plnou velikost výběru emoji" width: "Šířka" height: "Výška" large: "Velké" @@ -465,10 +607,13 @@ generateAccessToken: "Vygenerovat přístupový token" permission: "Oprávnění" enableAll: "Povolit vše" disableAll: "Vypnout vše" +tokenRequested: "Povolit přístup k účtu" +pluginTokenRequestedDescription: "Tenhle plugin bude moct používat oprávnění nastavená zde." notificationType: "Typy oznámení" edit: "Upravit" emailServer: "Mailový server" enableEmail: "Zapnout email dystribuci" +emailConfigInfo: "Používá se na ověření emailové adresy během registrace nebo při zapomenutí hesla." email: "Email" emailAddress: "Emailová adresa" smtpConfig: "Konfigurace SMTP serveru" @@ -476,8 +621,15 @@ smtpHost: "Hostitel" smtpPort: "Port" smtpUser: "Uživatelské jméno" smtpPass: "Heslo" +emptyToDisableSmtpAuth: "Zanechte uživatelské jméno a heslo prázdné pro vypnutí SMTP verifikace." +smtpSecure: "Použít implicitní SSL/TLS pro SMTP připojení" smtpSecureInfo: "Toto vypněte pokud používáte STARTTLS" testEmail: "Otestovat doručení emailů" +wordMute: "Ztlumené slova" +regexpError: "Chyba v regulérním výrazu" +regexpErrorDescription: "Došlo k chybě v regulérním výrazu v řádku {line} tabulky {tab} ztlumených slov:" +instanceMute: "Ztlumené instance" +userSaysSomething: "{name} řekl/a něco" makeActive: "Aktivovat" display: "Zobrazit" copy: "Kopírovat" @@ -489,42 +641,107 @@ database: "Databáze" channel: "Kanály" create: "Vytvořit" notificationSetting: "Nastavení oznámení" +notificationSettingDesc: "Vyberte typy oznámení k zobrazení." useGlobalSetting: "Použít globální nastavení" +useGlobalSettingDesc: "Pokud je to zapnuté, tak nastavení oznámení účtu bude použito. Pokud je to vypnuté, tak se bude moct použít jednotlivá nastavení." other: "Ostatní" +regenerateLoginToken: "Přegenerovat přihlašovací token" +regenerateLoginTokenDescription: "Přegeneruje token interně používaný během přihlášení. Běžně tahle akce není nutná. Pokud bude token přegenerovaný, tak se všechna přihlášená zařízení odhlásí." +setMultipleBySeparatingWithSpace: "Oddělení více položek mezerami." fileIdOrUrl: "ID nebo URL souboru" behavior: "Chování" sample: "Ukázka" +abuseReports: "Nahlášení" +reportAbuse: "Nahlášení" +reportAbuseOf: "Nahlásit {name}" +fillAbuseReportDescription: "Prosíme vyplňte všechny detaily ohledně tohodle nahlášení. Pokud jde o specifickou poznámku, prosíme o přiložení její URL." +abuseReported: "Nahlášení bylo odesláno. Děkujeme převelice." +reporter: "Nahlásil" +reporteeOrigin: "Původ nahlášení" +reporterOrigin: "Původ nahlasovače" +forwardReport: "Přeposlat nahlášení do vzdálené instance" +forwardReportIsAnonymous: "Místo vašeho účtu se ve vzdálené instanci zobrazí anonymní systémový účet jako nahlašovač." send: "Odeslat" +abuseMarkAsResolved: "Označit nahlášení jako vyřešené" openInNewTab: "Otevřít v nové kartě" +openInSideView: "Otevřít v bočním panelu" +defaultNavigationBehaviour: "Výchozí chování navigace" +editTheseSettingsMayBreakAccount: "Uprávou těchto nastavení si můžete poškodit účet." +instanceTicker: "Informace instance o poznámkách" +waitingFor: "Čeká se na {x}" random: "Náhodně" system: "Systém" +switchUi: "Přepnout UI" desktop: "Plocha" clip: "Oříznout" createNew: "Vytvořit nový" optional: "Volitelné" +createNewClip: "Vytvořit nový klip" +unclip: "Odepnout" +confirmToUnclipAlreadyClippedNote: "Tahle poznámku je už součásti \"{name}\" klipu. Chcete ji místo toho odepnout z tohodle klipu?" +public: "Veřejný" +private: "Soukromý" +i18nInfo: "Misskey je překládán do jiných jazyků dobrovolníkama. Můžete pomoci na {link}." +manageAccessTokens: "Spravovat přístupové tokeny" +accountInfo: "Informace o účtu" +notesCount: "Počet poznámek" +repliesCount: "Počet odeslaných odpovědí" +renotesCount: "Počet přeposlaných poznámek" +repliedCount: "Počet přijatých odpovědí" +renotedCount: "Počet přijatých přeposlaných poznámek" +followingCount: "Počet sledovaných účtů" +followersCount: "Počet sledujících" +sentReactionsCount: "Počet odeslaných reakcí" +receivedReactionsCount: "Počet přijatých reakcí" +pollVotesCount: "Počet odeslaných anketových hlasů" +pollVotedCount: "Počet přijatých anketových hlasů" yes: "Ano" no: "Ne" +driveFilesCount: "Počet souborů na disku" +driveUsage: "Využití disku" +noCrawle: "Odmítat indexování crawleru" +noCrawleDescription: "Požádat vyhledávače aby neindexovali váš profil, poznámky, stránky, atd." +lockedAccountInfo: "Pokud nenastavíte viditelnost poznámek na \"Pouze pro sledující\", budou poznámky viditelné všem i přesto že vyžadujete manuální potvrzení pro sledování." +alwaysMarkSensitive: "Výchozně označovat jako citlivý" +loadRawImages: "Načítat originální obrázky místo náhledů" +disableShowingAnimatedImages: "Nepřehrávat animované obrázky" +verificationEmailSent: "Ověřovací email byl zaslán. Ověření dokončíte kliknutím na odkaz v emailu." notSet: "Není nastaveno" emailVerified: "Váš e-mail byl ověřen" +noteFavoritesCount: "Počet oblíbených poznámek" +pageLikesCount: "Počet oblíbených stránek" +pageLikedCount: "Počet přijatých \"Libí se mi\"" contact: "Kontakt" useSystemFont: "Použít výchozí font systému" clips: "Oříznout" experimentalFeatures: "Experimentální funkce" +experimental: "Experimentální" +thisIsExperimentalFeature: "Tohle je experimentální funkce. Její funkce se může změnit a nemusí fungovat tak, jak bylo zamýšleno." developer: "Vývojář" +makeExplorable: "Udělat účet viditelný v \"Objevit\"" +makeExplorableDescription: "Pokud tohle vypnete, tak se účet přestane zobrazovat v sekci \"Objevit\"." +showGapBetweenNotesInTimeline: "Zobrazit mezeru mezi příspěvkama na časové ose" duplicate: "Duplikovat" left: "Vlevo" center: "Uprostřed" wide: "Široké" narrow: "Úzké" +reloadToApplySetting: "Tohle nastavení se použije až po obnovení stránky. Obnovit teď?" +needReloadToApply: "K projevení nastavení je zapotřebí obnovit stránku." +showTitlebar: "Zobrazit řádek s nadpisem" clearCache: "Vyprázdnit mezipaměť" +onlineUsersCount: "{n} uživatelů je online" nUsers: "{n} užívatelů" nNotes: "{n} poznámek" +sendErrorReports: "Odesílat chybové záznamy" +sendErrorReportsDescription: "Pokud je tato funkce zapnutá, budou se při výskytu problému sdílet podrobné informace o chybách se službou Misskey, což pomůže zlepšit kvalitu služby Misskey. Tyto informace budou zahrnovat například verzi operačního systému, jaký prohlížeč používáte, vaši aktivitu v Misskey atd." myTheme: "Moje vzhledy" backgroundColor: "Pozadí" accentColor: "Akcent" textColor: "Barva textu" saveAs: "Uložit jako…" advanced: "Pokročilé" +advancedSettings: "Pokročilá nastavení" value: "Hodnota" createdAt: "Vytvořeno" updatedAt: "Upraveno" @@ -532,7 +749,35 @@ saveConfirm: "Uložit změny?" deleteConfirm: "Opravdu smazat?" invalidValue: "Neplatná hodnota." registry: "Registr" +closeAccount: "Uzavřít účet" +currentVersion: "Aktuální verze" +latestVersion: "Nejnovější verze" +youAreRunningUpToDateClient: "Používáte nejnovější verzi klienta." +newVersionOfClientAvailable: "Nová verze klienta je k dispozici." +usageAmount: "Využití" +capacity: "Kapacita" +inUse: "Používáno" +editCode: "Upravit kód" +apply: "Potvrdit" +receiveAnnouncementFromInstance: "Dostávat oznámení z téhle instance" +emailNotification: "Emailové oznámení" +publish: "Zveřejnit" +inChannelSearch: "Vyhledat v kanálech" +useReactionPickerForContextMenu: "Otevřít výběr reakce na kliknutí pravého tlačítka myši" +typingUsers: "{users} píše..." +jumpToSpecifiedDate: "Skočit do konkrétního datumu" +showingPastTimeline: "Právě je zobrazována stará časová osa" +clear: "Vrátit" +markAllAsRead: "Označit všechno jako přečtené" +goBack: "Zpět" +unlikeConfirm: "Opravdu chcete odstranit like?" +fullView: "Plné zobrazení" +quitFullView: "Odejít z plného zobrazení" +addDescription: "Přidat popis" +userPagePinTip: "Zde můžete zobrazovat poznámky vybráním \"Připnout na profil\" z menu jednotlivých poznámek." +notSpecifiedMentionWarning: "Tahle poznámka zmiňuje uživatele, které nejsou mezi adresáty" info: "Informace" +userInfo: "Informace o uživateli" unknown: "Neznámý" onlineStatus: "Online status" hideOnlineStatus: "Skrýt Váš online status" @@ -552,10 +797,18 @@ user: "Uživatelé" administration: "Administrace" accounts: "Účty" switch: "Přepnout" +noMaintainerInformationWarning: "Informace o správci nejsou nastavené" +noBotProtectionWarning: "Ochrana proti botům není nastavena" configure: "Nastavit" +postToGallery: "Vytvořit nový příspěvek v galerii" +postToHashtag: "Přidat příspěvek k tomuhle hastagu" gallery: "Galerie" recentPosts: "Poslední příspěvky" +popularPosts: "Populární příspěvky" +shareWithNote: "Sdílet s poznámkou" ads: "Reklamy" +expiration: "Ukončit hlasování" +startingperiod: "Začátek" memo: "Memo" priority: "Priorita" high: "Vysoká" @@ -563,63 +816,698 @@ middle: "Střední" low: "Nízká" emailNotConfiguredWarning: "E-mailová adresa není nastavena." ratio: "Poměr" +previewNoteText: "Zobrazit náhled" +customCss: "Vlastní CSS" +customCssWarn: "Tohle nastavení by mělo být použito pouze v případě pokud víte co děláte. Vložením nesprávných hodnot může způsobit nefunkčnost klienta." global: "Globální" +squareAvatars: "Zobrazovat čtvercové avatary" sent: "Odeslat" +received: "Přijaté" +searchResult: "Výsledky hledání" hashtags: "Hashtagy" troubleshooting: "Poradce při potížích" +useBlurEffect: "Použít efekt rozostření v UI" +learnMore: "Zjistit více" +misskeyUpdated: "Misskey byl aktualizován!" whatIsNew: "Zobrazit změny" translate: "Přeložit" +translatedFrom: "Přeloženo z {x}" +accountDeletionInProgress: "Smazání účtu právě probíhá" +usernameInfo: "Jméno které identifikuje váš účet od jiných na tomhle serveru. Můžete použít abecedu (a~z, A~Z), čísla (0~9) nebo podtržítka (_). Uživatelské jména nemůžou být změněna později." +aiChanMode: "Režim Ai" +devMode: "Vývojářský režim" +keepCw: "Zachovat varování o obsahu" +pubSub: "Pub/Sub účty" +lastCommunication: "Poslední komunikace" +resolved: "Vyřešeno" +unresolved: "Nevyřešené" +breakFollow: "Odstranit sledujícího" +breakFollowConfirm: "Opravdu chcete odstranit tohodle sledujícího?" +itsOn: "Zapnuto" +itsOff: "Vypnuto" +on: "Zapnuto" +off: "Vypnuto" +emailRequiredForSignup: "Vyžadovat email pro registraci" +unread: "Nepřečtený" +filter: "Filtr" +controlPanel: "Ovládací panel" +manageAccounts: "Spravovat účty" +makeReactionsPublic: "Nastavit historii reakcí jako veřejnou" +makeReactionsPublicDescription: "Tohle zviditelný seznam vašich předchozích reakcí veřejně." +classic: "Klasický" +muteThread: "Ztlumit vlákno" +unmuteThread: "Zrušit ztlumení vlákna" +ffVisibility: "Viditelnost Sledovaných/Sledujících" +ffVisibilityDescription: "Umožní vám nastavit kdo uvidí koho sledujete a kdo vás sleduje." +continueThread: "Zobrazit pokračování vlákna" +deleteAccountConfirm: "Tohle nenávratně smaže váš účet, chcete pokračovat?" +incorrectPassword: "Nesprávné heslo." +voteConfirm: "Potvrdit hlas pro \"{choice}\"?" hide: "Skrýt" +useDrawerReactionPickerForMobile: "Zobrazit výběr reakcí jako šuplík na mobilním zařízení" +welcomeBackWithName: "Vítejte zpět, {name}" +clickToFinishEmailVerification: "Prosíme klikněte na [{ok}] pro dokončení ověření emailu." +overridedDeviceKind: "Typ zařízení" smartphone: "Telefon" tablet: "Tablet" auto: "Auto" +themeColor: "Barva motivu" size: "Velikost" numberOfColumn: "Počet sloupců" searchByGoogle: "Vyhledávání" +instanceDefaultLightTheme: "Výchozí světlý motiv instance" +instanceDefaultDarkTheme: "Výhozí tmavý motiv instance" +instanceDefaultThemeDescription: "Zadejte kód motivu v objektovém formátu" +mutePeriod: "Délka ztlumení" +period: "Časový limit" indefinitely: "Navždy" tenMinutes: "10 minut" oneHour: "1 hodina" oneDay: "1 den" oneWeek: "1 týden" +oneMonth: "1 měsíc" reflectMayTakeTime: "Může trvat nějakou dobu, než se projeví změny." +failedToFetchAccountInformation: "Nepodařily se načíst informace o účtě" +rateLimitExceeded: "Překročení rychlostního limitu" cropImage: "Oříznout obrázek" +cropImageAsk: "Chcete oříznout tenhle obrázek?" +cropYes: "Uříznout" +cropNo: "Použít tak jak je" file: "Soubor(ů)" recentNHours: "Posledních {n} hodin" recentNDays: "Posledních {n} dnů" +noEmailServerWarning: "Emailový server není nastavený" +thereIsUnresolvedAbuseReportWarning: "Jsou k dispozici nevyřešené nahlášení zneužití" recommended: "Doporučeno" +check: "Zkontrolovat" +driveCapOverrideLabel: "Změnit velikost disku pro tohoto uživatele" +driveCapOverrideCaption: "K vyresetování velikosti na výchozí hodnotu zadejte hodnotu 0 nebo nižší." +requireAdminForView: "Pro zobrazení se musíte přihlásit administrátorským účtem." +isSystemAccount: "Účet automaticky vytvořený a ovládaný serverem." +typeToConfirm: "Prosíme zadejte {x} pro potvrzení" deleteAccount: "Odstranit účet" document: "Dokumentace" +numberOfPageCache: "Počet stránek uložených v mezipaměti" +numberOfPageCacheDescription: "Zvýšením čísla zlepšíte pohodlí pro uživatele ale může to způsobit větší zátěž na server a na paměť." logoutConfirm: "Opravdu se chcete odhlásit?" +lastActiveDate: "Naposledy použito" +statusbar: "Stavový řádek" pleaseSelect: "Vybrat možnost" reverse: "Otočit" colored: "Barevné" +refreshInterval: "Interval obnovení" +label: "Popisek" type: "Typ" speed: "Rychlost" slow: "Pomalá" fast: "Rychlá" +sensitiveMediaDetection: "Detekce citlivého média" +localOnly: "Jenom lokální" +remoteOnly: "Jenom vzdáleně" +failedToUpload: "Nahrání se nezdařilo" +cannotUploadBecauseInappropriate: "Tenhle soubor se nenahrál, protože některé části byly detekovány jako nevhodné." +cannotUploadBecauseNoFreeSpace: "Nahrání se nezdařilo z důvodu nedostatku místa na disku." +cannotUploadBecauseExceedsFileSizeLimit: "Tenhle soubor nemůže být nahráný protože překračuje velikostní limit." +beta: "Beta verze" +enableAutoSensitive: "Automaticky označovat jako citlivé" +enableAutoSensitiveDescription: "Umožňuje automatickou detekci a označování citlivého média skrze strojového účení všude kde je možno. I pokud je tahle možnost vypnutá, může být povolena instancí." +activeEmailValidationDescription: "Umožňuje striktní validaci emailové adresy, která zahrnuje kontrolu pro jednorázové adresy a pokud je možno s ní komunikovat. Pokud je to vypnuté, bude se kontrolovat pouze formát emailu." +navbar: "Navigační panel" +shuffle: "Zamíchat" account: "Účty" +move: "Přesunout" +pushNotification: "Push oznámení" +subscribePushNotification: "Povolit push oznamení" +unsubscribePushNotification: "Vypnout push oznámení" +pushNotificationAlreadySubscribed: "Push oznámení jsou už zapnuté" +pushNotificationNotSupported: "Tenhle prohlížeč nepodporuje push oznámení" +sendPushNotificationReadMessage: "Odstraněnit oznámení push po jejich přečtení" +sendPushNotificationReadMessageCaption: "Tohle může zvýšit spotřebu energie vašeho zařízení." +windowMaximize: "Maximalizovat" +windowMinimize: "Minimalizovat" +windowRestore: "Obnovit" +caption: "Titulek" +loggedInAsBot: "Právě jste přihlášen jako bot" +tools: "Nástroje" +cannotLoad: "Načtení se nezdařilo" +numberOfProfileView: "Počet zobrazení profilu" +like: "To se mi líbí" +unlike: "Už se mi to nelíbí" +numberOfLikes: "Počet \"To se mi líbí\"" show: "Zobrazit" +neverShow: "Znovu nezobrazovat" +remindMeLater: "Možná později" +didYouLikeMisskey: "Oblíbili jste si Misskey?" +pleaseDonate: "{host} používá bezplatný software Misskey. Velmi bychom ocenili vaše dary, aby mohl vývoj Misskey pokračovat!" +roles: "Role" +role: "Role" +noRole: "Role nenalezena" +normalUser: "Normální uživatel" +undefined: "Neurčeno" +assign: "Přiřadit" +unassign: "Zrušit přirazení" color: "Barva" +manageCustomEmojis: "Spravovat vlastní emoji" +youCannotCreateAnymore: "Narazili jste na limit pro vytváření." +cannotPerformTemporary: "Dočasně nedostupné" +cannotPerformTemporaryDescription: "Tuto akci nelze dočasně provést z důvodu překročení limitu provedení. Chvíli počkejte a zkuste to znovu." +invalidParamError: "Neplatné parametry" +invalidParamErrorDescription: "Parametry požadavku jsou neplatné. Obvykle je to způsobeno chybou, ale může to být také způsobeno překročením limitů velikosti vstupů nebo podobně." +permissionDeniedError: "Operace zamítnuta" +permissionDeniedErrorDescription: "Tento účet nemá oprávnění k provedení této akce." +preset: "Předvolba" +selectFromPresets: "Vybrat z předvoleb" +achievements: "Úspěchy" +gotInvalidResponseError: "Neplatná odpověď serveru" +gotInvalidResponseErrorDescription: "Server může být nedostupný nebo na něm probíhá údržba. Zkuste to prosím později." +thisPostMayBeAnnoying: "Tato poznámka může ostatní obtěžovat." +thisPostMayBeAnnoyingHome: "Zveřejnit na domovskou časovou osu" +thisPostMayBeAnnoyingCancel: "Zrušit" +thisPostMayBeAnnoyingIgnore: "I přesto zveřejnit" +collapseRenotes: "Sbalit poznámky, které jste již viděli" +internalServerError: "Interní chyba serveru" +internalServerErrorDescription: "Server narazil na neočekávanou chybu." +copyErrorInfo: "Zkopírovat detaily erroru" +joinThisServer: "Zaregistrovat se v této instanci" +exploreOtherServers: "Podívat se na ostatní instance" +letsLookAtTimeline: "Podívejte se na časovou osu" +disableFederationConfirm: "Chcete opravdu vypnout federace?" +disableFederationConfirmWarn: "I v případě defederace budou příspěvky nadále veřejné, pokud nebude nastaveno jinak. Obvykle to není nutné." +disableFederationOk: "Vypnout" +invitationRequiredToRegister: "Tahle instance je pouze na pozvánku. Musíte zadat validní kód pozvánky." +emailNotSupported: "Tahle instance nepodporuje zasílání emailů" +postToTheChannel: "Vložit do kanálu" +cannotBeChangedLater: "Tohle nemůže být změněno později." +reactionAcceptance: "Přijímání reakcí" +likeOnly: "Jenom \"oblíbené\"" +likeOnlyForRemote: "Všechny (Pouze \"oblíbené\" pro vzdálenou instanci)" +nonSensitiveOnly: "Pouze bez citlivých medií" +nonSensitiveOnlyForLocalLikeOnlyForRemote: "Pouze bez citlivých medií (Pouze vzdálený \"oblíbený\")" +rolesAssignedToMe: "Přiřazené role ke mně" +resetPasswordConfirm: "Opravdu chcete resetovat heslo?" +sensitiveWords: "Citlivá slova" +sensitiveWordsDescription: "Viditelnost všech poznámek obsahujících některé z nakonfigurovaných slov bude automaticky nastavena na \"Domů\". Můžete jich uvést více tak, že je oddělíte pomocí řádků." +sensitiveWordsDescription2: "Použití mezer vytvoří výrazy AND a obklopení klíčových slov lomítky je změní na regulární výraz." +notesSearchNotAvailable: "Vyhledávání poznámek je nedostupné." +license: "Licence" +unfavoriteConfirm: "Opravdu chcete odstranit z oblíbených?" +myClips: "Moje klipy" +drivecleaner: "Čistič disku" +retryAllQueuesNow: "Obnovit všechny běžící fronty" +retryAllQueuesConfirmTitle: "Opravdu chcete obnovit všechno?" +retryAllQueuesConfirmText: "Tohle dočasně zvýší zatěž na server." +enableChartsForRemoteUser: "Vygenerovat grafy dat vzdálených uživatelů" +enableChartsForFederatedInstances: "Vygenerovat grafy dat vzdálených instancí" +showClipButtonInNoteFooter: "Přidat \"Připnout\" do akčního menu poznámky" +largeNoteReactions: "Zvětšit zobrazované reakce" +noteIdOrUrl: "ID nebo URL poznámky" +video: "Video" +videos: "Videa" +dataSaver: "Spořič dat" +accountMigration: "Migrace účtu" +accountMoved: "Tenhle uživatel se přesunul na nový účet:" +accountMovedShort: "Tenhle účet byl migrován." +operationForbidden: "Zakázaná operace" +forceShowAds: "Vždycky zobrazovat reklamy" +addMemo: "Přidat memo" +editMemo: "Upravit memo" +reactionsList: "Reakce" +renotesList: "Poznámky" +notificationDisplay: "Oznámení" +leftTop: "Vlevo nahoře" +rightTop: "Vpravo nahoře" +leftBottom: "Vlevo dole" +rightBottom: "Vpravo dole" +stackAxis: "Směr ukládání" +vertical: "Svisle" +horizontal: "Vodorovně" +position: "Pozice" +serverRules: "Pravidla serveru" +pleaseConfirmBelowBeforeSignup: "Abyste se mohli přihlásit na server, musíte souhlasit s následujícím." +pleaseAgreeAllToContinue: "Musíte souhlasit se vším abyste mohli pokračovat." +continue: "Pokračovat" +preservedUsernames: "Rezervované uživatelské jména" +preservedUsernamesDescription: "Seznam uživatelských jmén na rezervaci oddělené mezerama. Tyhle jména se potom nebudou moc použít při normálním procesu vytvoření účtu ale můžou být použiti manuálně administratorém. Existujících účtů se to nedotkne." +createNoteFromTheFile: "Vytvořit poznámku z tohodle souboru" +archive: "Archiv" +channelArchiveConfirmTitle: "Opravdu chcete archivovat {name}?" +channelArchiveConfirmDescription: "Archivovaný kanál se objeví v seznamu kanálů nebo ve výsledcích hledání. Nové poznámky se nedají vložit do seznamu." +thisChannelArchived: "Tenhle kanál je archivovaný" +displayOfNote: "Zobrazit poznámku" +initialAccountSetting: "Nastavení profilu" +youFollowing: "Sleduji" +preventAiLearning: "Odmítnout použití v strojovém učení (Generative AI)" +preventAiLearningDescription: "Požaduje, aby prohlížeče nepoužívaly zveřejněný textový nebo obrazový materiál atd. v datových sadách pro strojové učení (prediktivní / generativní umělá inteligence). Toho se dosáhne přidáním příznaku \"noai\" HTML-Response k příslušnému obsahu. Úplné prevence však tímto příznakem nelze dosáhnout, protože může být jednoduše ignorován." +options: "Možnosti" +specifyUser: "Upřesnit uživatele" +failedToPreviewUrl: "Náhled se nezdařil" +update: "Aktualizovat" +rolesThatCanBeUsedThisEmojiAsReaction: "Role, které můžou tuhle emoji použít jako reakci" +rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "Pokud nejsou určena role, tak pak každý může použít tenhle emoji." +rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "Role musí být veřejné." +cancelReactionConfirm: "Opravdu chcete odstranit vaší reakci?" +changeReactionConfirm: "Opravdu chcete změnit vaši reakci?" +later: "Později" +goToMisskey: "Jít na Misskey" +additionalEmojiDictionary: "Další slovníky emoji" +installed: "Nainstalováno" +branding: "Značka" +enableServerMachineStats: "Zveřejněnit statistiky hardwaru serveru" +enableIdenticonGeneration: "Povolit generování identicon uživatele" +turnOffToImprovePerformance: "Vypnutí této funkce může zvýšit výkon." +createInviteCode: "Vygenerovat pozvánku" +createWithOptions: "Vygenerovat s nastavením" +createCount: "Počet vytvořených pozvánek" +inviteCodeCreated: "Pozvánka vygenerována" +inviteLimitExceeded: "Překročili jste limit pozvánek, které můžete vygenerovat." +createLimitRemaining: "Limit pozvánek: {limit} zbývá" +inviteLimitResetCycle: "Tento limit se obnoví na hodnotu {limit} v {time}." +expirationDate: "Datum expirace" +noExpirationDate: "Bez expirace" +inviteCodeUsedAt: "Kód pozvánky použitý na" +registeredUserUsingInviteCode: "Pozvánku používá" +waitingForMailAuth: "Čeká se na ověření emailu" +inviteCodeCreator: "Pozvánku vytvořil" +usedAt: "Používá se v" +unused: "Nepoužívaná" +used: "Používaná" +expired: "Prošlá" +doYouAgree: "Souhlasíte?" +beSureToReadThisAsItIsImportant: "Přečtěte si prosím tyto důležité informace." +iHaveReadXCarefullyAndAgree: "Přečetl jsem si text \"{x}\" a souhlasím s ním." +icon: "Avatar" +_initialAccountSetting: + accountCreated: "Váš účet byl úspěšně vytvořen!" + letsStartAccountSetup: "Pro začátek si nastavte svůj profil." + letsFillYourProfile: "Nejprve si nastavte svůj profil." + profileSetting: "Nastavení profilu" + privacySetting: "Nastavení soukromí" + theseSettingsCanEditLater: "Tato nastavení můžete vždy později změnit." + youCanEditMoreSettingsInSettingsPageLater: "Na stránce \"Nastavení\" můžete nakonfigurovat mnoho dalších nastavení. Nezapomeňte ji navštívit později." + followUsers: "Zkuste sledovat některé uživatele, kteří vás zajímají pro vystavění časový osy." + pushNotificationDescription: "Povolení push oznámení vám umožní přijímat oznámení od {name} přímo ve vašem zařízení." + initialAccountSettingCompleted: "Nastavení profilu dokončeno!" + haveFun: "Užívejte {name}!" + ifYouNeedLearnMore: "Pokud se chcete dozvědět více o tom, jak používat {name} (Misskey), navštivte {link}." + skipAreYouSure: "Opravdu chcete přeskočit nastavení profilu?" + laterAreYouSure: "Opravdu chcete provést nastavení profilu později?" +_serverRules: + description: "Soubor pravidel, která se zobrazí před registrací. Doporučuje se nastavit shrnutí podmínek služby." +_accountMigration: + moveFrom: "Migrace jiného účtu na tento účet" + moveFromSub: "Vytvořit alias na jiný účet" + moveFromLabel: "Původní účet #{n}" + moveFromDescription: "Pro účet, ze kterého se chcete přesunout, musíte vytvořit alias na tomto účtu.\nZadejte účet, ze kterého chcete přejít, v následujícím formátu: @username@server.example.com\nChcete-li alias odstranit, ponechte pole prázdné (nedoporučuje se)." + moveTo: "Přesunout tenhle účet do jiného" + moveToLabel: "Cílový účet pro přesunutí:" + moveCannotBeUndone: "Migrace účtu nemůže být vrácena." + moveAccountDescription: "Tím dojde k migraci vašeho účtu na jiný účet.\n ・Sledovatelé z tohoto účtu budou automaticky převedeni na nový účet.\n ・Tento účet zruší sledování všech uživatelů, které aktuálně sleduje.\n ・Na tomto účtu nebude možné vytvářet nové poznámky atd.\n\nZatímco migrace sledovaných uživatelů probíhá automaticky, pro migraci seznamu sledovaných uživatelů je nutné připravit některé kroky ručně. Za tímto účelem proveďte export sledovaných, který později naimportujete na nový účet v nabídce nastavení. Stejný postup platí pro seznamy i pro ztlumené a zablokované uživatele.\n\n(Tento výklad platí pro Misskey v13.12.0 a novější. Jiný software ActivityPub, například Mastodon, může fungovat jinak.)" + moveAccountHowTo: "Chcete-li migrovat, vytvořte nejprve alias tohoto účtu na účtu, na který chcete přejít.\nPo vytvoření aliasu zadejte účet, na který chcete přejít, v následujícím formátu: @username@server.example.com" + startMigration: "Migrovat" + migrationConfirm: "Opravdu chcete migrovat tento účet na {account}? Jednou zahájený proces nelze zastavit ani vrátit zpět a tento účet již nebudete moci používat v původním stavu." + movedAndCannotBeUndone: "\nTento účet byl převeden.\nMigraci nelze vrátit zpět." + postMigrationNote: "Tento účet zruší sledování všech účtů, které aktuálně sleduje, 24 hodin po dokončení migrace.\nPočet sledujících i následovníků se poté vynuluje. Aby se zabránilo tomu, že vaši sledující nebudou moci vidět příspěvky tohoto účtu určené pouze pro sledující, budou však tento účet sledovat i nadále." + movedTo: "Cílový účet pro přesunutí:" +_achievements: + earnedAt: "Odemčeno v" + _types: + _notes1: + title: "Dobrý den Misskey!" + description: "Zveřejněte vaší první poznámku" + flavor: "Užijte si to s Misskey!" + _notes10: + title: "Pár poznámek" + description: "Zveřejněte 10 poznámek" + _notes100: + title: "Hodně poznámek" + description: "Zveřejněte 100 poznámek" + _notes500: + title: "Zahlcen poznámkama" + description: "Zveřejněte 500 poznámek" + _notes1000: + title: "Hora poznámek" + description: "Zveřejněte 1000 poznámek" + _notes5000: + title: "Přetékající poznámky" + description: "Zveřejněte 5000 poznámek" + _notes10000: + title: "Super poznámka" + description: "Zveřejněte 10 000 poznámek" + _notes20000: + title: "Potřebuju... více... poznámek..." + description: "Zveřejněte 20 000 poznámek" + _notes30000: + title: "Poznámky, poznámky, POZNÁMKY!" + description: "Zveřejněte 30 000 poznámek" + _notes40000: + title: "Továrna na poznámky" + description: "Zveřejněte 40 000 poznámek" + _notes50000: + title: "Planeta poznámek" + description: "Zveřejněte 50 000 poznámek" + _notes60000: + title: "Poznámkový kvasar" + description: "Zveřejněte 60 000 poznámek" + _notes70000: + title: "Černá díra poznámek" + description: "Zveřejněte 70 000 poznámek" + _notes80000: + title: "Galaxie poznámek" + description: "Zveřejněte 80 000 poznámek" + _notes90000: + title: "Vesmír poznámek" + description: "Zveřejněte 90 000 poznámek" + _notes100000: + title: "ALL YOUR NOTE ARE BELONG TO US" + description: "Zveřejněte 100 000 poznámek" + flavor: "Máte toho hodně co říct." + _login3: + title: "Začátečník I" + description: "Přihlaste se celkově za 3 dny" + flavor: "Ode dneška mi říkejte Misskista." + _login7: + title: "Začátečník II" + description: "Přihlaste se celkově za 7 dní" + flavor: "Máte pocit, že už jste se v tom vyznali?" + _login15: + title: "Začátečník III" + description: "Přihlaste se celkově za 15 dní" + _login30: + title: "Misskista I" + description: "Přihlaste se celkově za 30 dní" + _login60: + title: "Misskista II" + description: "Přihlaste se celkově za 60 dní" + _login100: + title: "Misskista III" + description: "Přihlaste se celkově za 100 dní" + flavor: "Violent Misskista" + _login200: + title: "Stálý zákazník I" + description: "Přihlaste se celkově za 200 dní" + _login300: + title: "Stálý zákazník II" + description: "Přihlaste se celkově za 300 dní" + _login400: + title: "Stálý zákazník III" + description: "Přihlaste se celkově za 400 dní" + _login500: + title: "Expert I" + description: "Přihlaste se celkově za 500 dní" + flavor: "Moji přátelé, často se říká, že mám rád poznámky." + _login600: + title: "Expert II" + description: "Přihlaste se celkově za 600 dní" + _login700: + title: "Expert III" + description: "Přihlaste se celkově za 700 dní" + _login800: + title: "Mistr poznámek I" + description: "Přihlaste se celkově za 800 dní" + _login900: + title: "Mistr poznámek II" + description: "Přihlaste se celkově za 900 dní" + _login1000: + title: "Mistr poznámek III" + description: "Přihlaste se celkově za 1000 dní" + flavor: "Děkujeme, že používáte Misskey!" + _noteClipped1: + title: "Musím... připnout..." + description: "Připněte si první poznámku" + _noteFavorited1: + title: "Hvězdář" + description: "Oblíbena první poznámka" + _myNoteFavorited1: + title: "Hledání hvězd" + description: "Někdo si oblíbil jednu z vašich poznámek" + _profileFilled: + title: "Dobře připravený" + description: "Nastavte si profil" + _markedAsCat: + title: "Já jsem kočka" + description: "Označte váš účet \"jako kočka\"" + flavor: "Jméno ti dám později." + _following1: + title: "Sledujte prvního uživatele" + description: "Sledujte uživatele" + _following10: + title: "Drž se... drž se..." + description: "Sledujte 10 uživatelů" + _following50: + title: "Hodně přátel" + description: "Sledujte 50 uživatelů" + _following100: + title: "100 přátel" + description: "Sledujte 100 uživatelů" + _following300: + title: "Přetížení přátel" + description: "Sledujte 300 účtů" + _followers1: + title: "První sledující" + description: "Získejte 1 sledujícího" + _followers10: + title: "Sledujte mě!" + description: "Získejte 10 sledujících" + _followers50: + title: "Přicházejí davy" + description: "Získejte 50 sledujících" + _followers100: + title: "Populární" + description: "Získejte 100 sledujících" + _followers300: + title: "Prosíme srovnejte se do jedné řady!" + description: "Získejte 300 sledujících" + _followers500: + title: "Rádiová věž" + description: "Získejte 500 sledujících" + _followers1000: + title: "Influencer" + description: "Získejte 1000 sledujících" + _collectAchievements30: + title: "Sběratel úspěchů" + description: "Získejte 30 úspěchů" + _viewAchievements3min: + title: "Máš rád úspěchy" + description: "Koukejte na váš seznam úspěchů alespoň po dobu 3 minut" + _iLoveMisskey: + title: "Miluju Misskey" + description: "Zveřejněte \" I ❤ #Misskey\"" + flavor: "Vývojový tým Misskey si velmi váží vaší podpory!" + _foundTreasure: + title: "Hon za pokladem" + description: "Našli jste schovaný poklad!" + _client30min: + title: "Krátká pauza" + description: "Mějte otevřený Misskey alespoň po dobu 30 minut" + _client60min: + title: "Žádný \"Miss\" v Misskey" + description: "Mějte otevřený Misskey alespoň po dobu 60 minut" + _noteDeletedWithin1min: + title: "Ups, nevadí" + description: "Vymažte poznámku během minuty co ji zveřejníte" + _postedAtLateNight: + title: "Noční typ" + description: "Zveřejněte poznámku pozdě v noci" + flavor: "Je nejvyšší čas jít spát." + _postedAt0min0sec: + title: "Mluvící hodiny" + description: "Zveřejněte poznámku přesně v 00:00" + flavor: "Klik Klik Klik Bum" + _selfQuote: + title: "Sebereference" + description: "Citujte vlastní poznámku" + _htl20npm: + title: "Plynoucí časová osa" + description: "Mějte rychlost vaší domovské časové osy vyšší než 20 pzm (poznámek za minutu)." + _viewInstanceChart: + title: "Analytik" + description: "Zobrazte graf instance" + _outputHelloWorldOnScratchpad: + title: "Hello, world!" + description: "Dostaňte výpis \"hello world\" do Scratchpadu" + _open3windows: + title: "Splitscreen" + description: "Mějte otevřená alespoň 3 okna zároveň" + _driveFolderCircularReference: + title: "Okružní reference" + description: "Pokuste se o vytvoření rekurzivně vnořené složky v disku" + _reactWithoutRead: + title: "Opravdu jste to četl/a?" + description: "Reagujte na poznámku, která má více než 100 znaků, do 3 sekund od jejího zveřejnění." + _clickedClickHere: + title: "Klikněte sem" + description: "Kliknul si tam" + _justPlainLucky: + title: "Čisté štěstí" + description: "Mějte šanci na získání s pravděpodobností 0,005 % každých 10 sekund." + _setNameToSyuilo: + title: "Boží komplex" + description: "Nastavte si jméno na \"syuilo\"" + _passedSinceAccountCreated1: + title: "Roční výročí" + description: "Od vytvoření vašeho účtu uplynul jeden rok" + _passedSinceAccountCreated2: + title: "Dvouleté výročí" + description: "Od vytvoření vašeho účtu uplynuly dva roky" + _passedSinceAccountCreated3: + title: "Tříleté výročí" + description: "Od vytvoření vašeho účtu uplynuly tři roky" + _loggedInOnBirthday: + title: "Všechno nejlepší!" + description: "Přihlašte se v den vašich narozenin" + _loggedInOnNewYearsDay: + title: "Štastný nový rok!" + description: "Přihlašte se v den nového roku" + flavor: "Na další skvělý rok v této instanci" + _cookieClicked: + title: "Hra, ve které klikáte na sušenky" + description: "Klikněte na soubor cookie" + flavor: "Počkejte, jste na správné webové stránce?" + _brainDiver: + title: "Brain Diver" + description: "Zveřejněte odkaz na Brain Diver" + flavor: "Misskey-Misskey La-Tu-Ma" _role: + new: "Nová role" + edit: "Upravit roli" + name: "Název role" + description: "Popis role" + permission: "Oprávnění role" + descriptionOfPermission: "Moderators může provádět základní operace moderování.\nAdministrators může měnit všechna nastavení instance." + assignTarget: "Přiřadit" + descriptionOfAssignTarget: "Manual ručně změnit, kdo je součástí této role a kdo ne.\nConditional mít uživatelé automaticky přiřazováni a odebíráni z této role na základě podmínky." + manual: "Dokumentace" + conditional: "Podmíněné" + condition: "Podmínky" + isConditionalRole: "Tato role je podmíněná." + isPublic: "Veřejná role" + descriptionOfIsPublic: "Tato role se zobrazí v profilech přiřazených uživatelů." + options: "Nastavení" + policies: "Zásady" + baseRole: "Šablona role" + useBaseValue: "Použít hodnotu šablony role" + chooseRoleToAssign: "Vyberte roli, kterou chcete přiřadit" + iconUrl: "URL ikony" + asBadge: "Zobrazovat jako odznak" + descriptionOfAsBadge: "Ikona této role se zobrazí vedle uživatelského jména uživatelů s touto rolí, pokud je zapnuta." + isExplorable: "Udělat roli objevitelnou" + descriptionOfIsExplorable: "Časová osa této role a seznam uživatelů s touto rolí budou zveřejněny, pokud jsou povoleny." + displayOrder: "Pozice" + descriptionOfDisplayOrder: "Čím vyšší číslo, tím vyšší pozice v uživatelském rozhraní." + canEditMembersByModerator: "Umožnit moderátorům upravovat seznam členů pro tuto roli" + descriptionOfCanEditMembersByModerator: "Po zapnutí této role budou moci moderátoři i administrátoři přiřazovat a odebírat uživatele do této role. Pokud je tato funkce vypnutá, budou moci uživatele přiřazovat pouze správci." priority: "Priorita" _priority: low: "Nízká" middle: "Střední" high: "Vysoká" + _options: + gtlAvailable: "Může zobrazit globální časovou osu" + ltlAvailable: "Může zobrazit místní časovou osu" + canPublicNote: "Může posílat veřejné poznámky" + canInvite: "Může vytvářet kódy pozvánek instance" + inviteLimit: "Limit pozvánek" + inviteLimitCycle: "Limit mezi pozvánkama" + inviteExpirationTime: "Interval vypršení platnosti pozvánky" + canManageCustomEmojis: "Spravovat vlastní emoji" + driveCapacity: "Velikost disku" + alwaysMarkNsfw: "Vždy označovat soubory jako NSFW" + pinMax: "Maximální počet připnutých poznámek" + antennaMax: "Maximální počet antén" + wordMuteMax: "Maximální počet znaků povolených v ztlumených slovech" + webhookMax: "Maximální počet Webhooků" + clipMax: "Maximální počet připnutí" + noteEachClipsMax: "Maximální počet poznámek v připnutí" + userListMax: "Maximální počet seznamů uživatelů" + userEachUserListsMax: "Maximální počet uživatelů v seznamu uživatelů" + rateLimitFactor: "Limit rychlosti" + descriptionOfRateLimitFactor: "Nižší limity rychlosti jsou méně omezující, vyšší více omezující. " + canHideAds: "Může schovat reklamy" + canSearchNotes: "Použití vyhledávání poznámek" + _condition: + isLocal: "Místní uživatel" + isRemote: "Vzdálený uživatel" + createdLessThan: "Od vytvoření účtu uplynulo méně než X" + createdMoreThan: "Od vytvoření účtu uplynulo více než X" + followersLessThanOrEq: "Má X nebo méně sledujících" + followersMoreThanOrEq: "Má X nebo více sledujících" + followingLessThanOrEq: "Sleduje X nebo méně účtů" + followingMoreThanOrEq: "Sleduje X nebo více účtů" + notesLessThanOrEq: "Počet příspěvků je menší než/rovná se" + notesMoreThanOrEq: "Počet příspěvků je větší než/rovná se" + and: "AND kondice" + or: "OR kondice" + not: "NOT kondice" +_sensitiveMediaDetection: + description: "Snižuje náročnost moderování serveru díky automatickému rozpoznávání citlivých médií pomocí strojového učení. Tím se mírně zvýší zatížení serveru." + sensitivity: "Detekce citlivosti" + sensitivityDescription: "Snížení citlivosti povede k menšímu počtu chybných detekcí (falešně pozitivních), zatímco její zvýšení povede k menšímu počtu chybných detekcí (falešně negativních)." + setSensitiveFlagAutomatically: "Označit jako citlivé" + setSensitiveFlagAutomaticallyDescription: "Výsledky interní detekce se zachovají, i když je tato možnost vypnutá." + analyzeVideos: "Povolit analýzy videí" + analyzeVideosDescription: "Kromě obrázků analyzuje i videa. Tím se mírně zvýší zatížení serveru." +_emailUnavailable: + used: "Tato emailová adresa se již používá" + format: "Formát této emailové adresy je neplatný" + disposable: "Jednorázové emailové adresy se nesmí používat" + mx: "Tento e-mailový server je neplatný" + smtp: "Tento emailový server neodpovídá" +_ffVisibility: + public: "Zveřejnit" + followers: "Viditelné pouze pro sledující" + private: "Soukromý" +_signup: + almostThere: "Už to skoro je" + emailAddressInfo: "Zadejte prosím svou emailovou adresu. Nebude zveřejněna." + emailSent: "Na vaši e-mailovou adresu ({email}) byl odeslán potvrzovací e-mail. Kliknutím na přiložený odkaz dokončete vytvoření účtu." +_accountDelete: + accountDelete: "Smazat účet" + mayTakeTime: "Vzhledem k tomu, že odstranění účtu je proces náročný na zdroje, může jeho dokončení trvat určitou dobu v závislosti na tom, kolik obsahu jste vytvořili a kolik souborů jste nahráli." + sendEmail: "Po dokončení odstranění účtu bude na emailovou adresu registrovanou k tomuto účtu zaslán email." + requestAccountDelete: "Žádost o smazání účtu" + started: "Bylo zahájeno mazání." + inProgress: "V současné době probíhá mazání" _ad: back: "Zpět" + reduceFrequencyOfThisAd: "Zobrazovat tuto reklamu méně" + hide: "Schovat" + timezoneinfo: "Den v týdnu se určuje podle časového pásma serveru." +_forgotPassword: + enterEmail: "Zadejte emailovou adresu, kterou jste použili při registraci. Na ni vám pak bude zaslán odkaz, pomocí kterého si můžete obnovit heslo." + ifNoEmail: "Pokud jste při registraci nepoužili email, obraťte se na správce instance." + contactAdmin: "Tato instance nepodporuje používání emailových adres, pro obnovení hesla se obraťte na správce instance." _gallery: my: "Moje galerie" + liked: "Oblíbené příspěvky" + like: "To se mi líbí" + unlike: "Už se mi to nelíbí" _email: _follow: title: "Máte nového následovníka" + _receiveFollowRequest: + title: "Obdrželi jste žádost o sledování" _plugin: install: "Instalovat plugin" + installWarn: "Neinstalujte nedůvěryhodné pluginy." manage: "Správce pluginů" _preferencesBackups: list: "Vytvořit backup" + saveNew: "Uložit novou zálohu" loadFile: "Načíst ze souboru" + apply: "Použít pro toto zařízení" save: "Uložit změny" + inputName: "Zadejte prosím název pro tuto zálohu" + cannotSave: "Uložení selhalo" + nameAlreadyExists: "Záloha s názvem \"{name}\" již existuje. Zadejte prosím jiný název." + applyConfirm: "Opravdu chcete na toto zařízení použít zálohu \"{name}\"? Stávající nastavení tohoto zařízení bude přepsáno." + saveConfirm: "Uložit zálohu jako {name}?" + deleteConfirm: "Odstranit zálohu {name}?" + renameConfirm: "Přejmenovat tuto zálohu z \"{old}\" na \"{new}\"?" + noBackups: "Neexistují žádné zálohy. Nastavení klienta na tomto serveru můžete zálohovat pomocí \"Vytvořit novou zálohu\"." + createdAt: "Vytvořeno v: {date} {time}" + updatedAt: "Aktualizováno: {date} {time}" + cannotLoad: "Načítání selhalo" + invalidFile: "Neplatný typ souboru" _registry: scope: "Rozsah" key: "Klíč" @@ -627,46 +1515,238 @@ _registry: domain: "Doména" createKey: "Vytvořit klíč" _aboutMisskey: + about: "Misskey je open-source software vyvíjený syuilo od roku 2014." + contributors: "Hlavní přispěvatelé" allContributors: "Všichni přispěvatelé" source: "Zdrojový kód" + translation: "Přeložit Misskey" + donate: "Přispějte na Misskey" + morePatrons: "Vážíme si také podpory mnoha dalších pomocníků, kteří zde nejsou uvedeni. Děkujeme! 🥰" + patrons: "Patroni" +_displayOfSensitiveMedia: + respect: "Skrýt média označená jako citlivá" + ignore: "Zobrazit média označená jako citlivá" + force: "Skrýt všechna média" +_instanceTicker: + none: "Nikdy nezobrazovat" + remote: "Zobrazit pro vzdálené uživatelé" + always: "Vždy zobrazovat" +_serverDisconnectedBehavior: + reload: "Automatické znovunačtení" + dialog: "Zobrazení dialogového okna s varováním" + quiet: "Zobrazit nerušivé upozornění" _channel: + create: "Vytvořit kanál" + edit: "Upravit kanál" + setBanner: "Nastavit banner" + removeBanner: "Odstranit banner" featured: "Trendy" + owned: "Vlastněný" + following: "Sledovaný" + usersCount: "{n} Účastníků" + notesCount: "{n} Poznámek" + nameAndDescription: "Název a popis" + nameOnly: "Pouze název" _menuDisplay: + sideFull: "Postranně" + sideIcon: "Postranně (Ikony)" top: "Nahoru" hide: "Skrýt" +_wordMute: + muteWords: "Ztlumená slova" + muteWordsDescription: "Podmínku AND oddělujte mezerami, podmínku OR oddělujte řádkovými zlomy." + muteWordsDescription2: "Chcete-li použít regulární výrazy, obklopte klíčová slova lomítky." + softDescription: "Skrýt poznámky, které splňují nastavené podmínky, z časové osy." + hardDescription: "Zabrání přidání poznámek splňujících nastavené podmínky na časovou osu. Kromě toho nebudou tyto poznámky přidány na časovou osu, ani když se podmínky změní." + soft: "Měkký" + hard: "Tvrdý" + mutedNotes: "Ztlumené poznámky" +_instanceMute: + instanceMuteDescription: "Tímhle se ztlumí všechny poznámky/poznámky z uvedených instancí, včetně poznámek uživatelů, kteří odpovídají uživateli ze ztlumené instance." + instanceMuteDescription2: "Oddělte novými řádky" + title: "Skryje poznámky z uvedených případů." + heading: "Seznam instancí, které mají být ztlumeny" _theme: + explore: "Objevit témata" install: "Nainstalovat vzhled" manage: "Správa vzhledů" code: "Kód vzhledu" description: "Popis" + installed: "{name} byl nainstalován" installedThemes: "Nainstalované vzhledy" + builtinThemes: "Vestavěné temáta" + alreadyInstalled: "Tento vzhled je již nainstalován." + invalid: "Formát tohoto tématu je neplatný" + make: "Vytvořit téma" + base: "Základ" + addConstant: "Přidat konstantu" constant: "Konstanta" defaultValue: "Výchozí hodnota" color: "Barva" + refProp: "Odkázat na vlastnost" + refConst: "Odkázat na konstantu" key: "Klíč" func: "Funkce " + funcKind: "Typ funkce" + argument: "Argument" + basedProp: "Odkazovaná vlastnost" + alpha: "Průhlednost" + darken: "Ztmavit" + lighten: "Zesvětlit" + inputConstantName: "Zadejte název pro tuto konstantu" + importInfo: "Pokud zde zadáte kód motivu, můžete jej importovat do editoru motivu." + deleteConstantConfirm: "Opravdu chcete odstranit konstantu {const}?" keys: + accent: "Akcent" + bg: "Pozadí" + fg: "Text" + focus: "Fokus" + indicator: "Indikátor" + panel: "Panely" shadow: "Stín" header: "Nadpis" + navBg: "Pozadí postranního panelu" + navFg: "Text na postranním panelu" + navHoverFg: "Text na postranním panelu (Hover)" + navActive: "Text na postranním panelu (Aktivní)" + navIndicator: "Indikátor na postranním panelu" link: "Odkaz" hashtag: "Hashtag" mention: "Zmínění" + mentionMe: "Zmínky (mě)" renote: "Přeposlat" + modalBg: "Pozadí Modalu" divider: "Dělící čára" + scrollbarHandle: "Rukojeť posuvníku" + scrollbarHandleHover: "Rukojeť posuvníku (Hover)" + dateLabelFg: "Text štítku s datem" + infoBg: "Pozadí informací" + infoFg: "Text informací" + infoWarnBg: "Pozadí varování" + infoWarnFg: "Text varování" + cwBg: "Pozadí CW tlačítka" + cwFg: "Text CW tlačítka" + cwHoverBg: "Pozadí CW tlačítka (Hover)" + toastBg: "Pozadí oznámení" + toastFg: "Text oznámení" + buttonBg: "Pozadí tlačítka" + buttonHoverBg: "Pozadí tlačítka (Hover)" + inputBorder: "Ohraničení vstupního pole" + listItemHoverBg: "Pozadí položky seznamu (Hover)" + driveFolderBg: "Pozadí složky disku" + wallpaperOverlay: "Překrytí tapety" + badge: "Odznak" + messageBg: "Pozadí chatu" + accentDarken: "Akcent (Ztmavený)" + accentLighten: "Akcent (Zesvětlený)" + fgHighlighted: "Zvýrazněný text" _sfx: note: "Poznámky" + noteMy: "Moje poznámka" notification: "Oznámení" chat: "Zprávy" + chatBg: "Chat (Pozadí)" + antenna: "Antény" + channel: "Oznámení kanálu" _ago: future: "Budoucí" justNow: "Teď" + secondsAgo: "Před {n}s" + minutesAgo: "Před {n}min" + hoursAgo: "Před {n}h" + daysAgo: "Před {n}d" + weeksAgo: "Před {n}t" + monthsAgo: "Před {n}m" + yearsAgo: "Před {n}r" invalid: "Nic nebylo nalezeno" _time: second: "Sekund" minute: "Minut" hour: "Hodin" + day: "Dnů" +_timelineTutorial: + title: "Jak používat Misskey" + step1_1: "Toto je \"časová osa\". Zde se chronologicky zobrazují všechny \"poznámky\" odeslané na {name}." + step1_2: "Existuje několik různých časových plánů. Například \"Domácí časová osa\" bude obsahovat poznámky uživatelů, které sledujete, a \"Místní časová osa\" bude obsahovat poznámky všech uživatelů {name}." + step2_1: "Zkusme zveřejnit poznámku. Můžete tak učinit stisknutím tlačítka s ikonou tužky." + step2_2: "Co takhle napsat sebepředstavení, nebo jen \"Ahoj {name}!\", pokud se vám nechce?" + step3_1: "Dokončil jsi svou první poznámku?" + step3_2: "Na časové ose by se nyní měla zobrazit vaše první poznámka." + step4_1: "K poznámkám můžete také připojit \"Reakce\"." + step4_2: "Chcete-li připojit reakci, stiskněte na poznámce znaménko \"+\" a vyberte emoji, kterým chcete reagovat." _2fa: + alreadyRegistered: "Již jste zaregistrovali dvoufaktorové ověřovací zařízení." + registerTOTP: "Registrovat aplikaci autentizátoru" + passwordToTOTP: "Zadejte své heslo" + step1: "Nejprve si do zařízení nainstalujte aplikaci pro ověřování (například {a} nebo {b})." + step2: "Poté naskenujte QR kód zobrazený na této obrazovce." + step2Click: "Kliknutím na tento QR kód můžete zaregistrovat 2FA do bezpečnostního klíče nebo aplikace autentizace telefonu." + step2Url: "Tuto adresu URL můžete zadat také v případě, že používáte program pro stolní počítače:" + step3Title: "Zadejte ověřovací kód" + step3: "Pro dokončení nastavení zadejte token poskytnutý vaší aplikací." + step4: "Od této chvíle budou všechny budoucí pokusy o přihlášení vyžadovat tento přihlašovací token." + securityKeyNotSupported: "Váš prohlížeč nepodporuje bezpečnostní klíče." + registerTOTPBeforeKey: "Nastavte aplikaci autentizátoru pro registraci bezpečnostního nebo přístupového klíče." + securityKeyInfo: "Kromě ověřování otiskem prstu nebo PIN můžete nastavit také ověřování pomocí hardwarových bezpečnostních klíčů, které podporují FIDO2, a svůj účet tak dále zabezpečit." + chromePasskeyNotSupported: "Chrome passkeys nejsou v současné době podporovány." + registerSecurityKey: "Registrace bezpečnostního nebo přístupového klíče" + securityKeyName: "Zadejte název klíče" + tapSecurityKey: "Při registraci bezpečnostního nebo přístupového klíče postupujte podle svého prohlížeče." + removeKey: "Odstranit bezpečnostní klíč" + removeKeyConfirm: "Opravdu chcete odstranit klíč {name}?" + whyTOTPOnlyRenew: "Aplikaci autentizátoru nelze odstranit, dokud je zaregistrován bezpečnostní klíč." + renewTOTP: "Překonfigurování aplikace autentizátor" + renewTOTPConfirm: "Tohle způsobí, že ověřovací kódy z předchozí aplikace přestanou fungovat." + renewTOTPOk: "Přenastavit" renewTOTPCancel: "Ne děkuji" +_permissions: + "read:account": "Zobrazit informace o účtu" + "write:account": "Upravit informace o účtu" + "read:blocks": "Zobrazit seznam blokovaných uživatelů" + "write:blocks": "Upravit seznam blokovaných uživatelů" + "read:drive": "Přístup k souborům a složkám na disku" + "write:drive": "Úprava nebo odstranění souborů a složek na disku" + "read:favorites": "Zobrazit seznam oblíbených" + "write:favorites": "Upravit seznam oblíbených" + "read:following": "Zobrazit informace o tom, koho sledujete" + "write:following": "Sledování nebo zrušení sledování jiných účtů" + "read:messaging": "Zobrazit chat" + "write:messaging": "Sestavit nebo mazat zprávy chatu" + "read:mutes": "Zobrazit seznam ztlumených uživatelů" + "write:mutes": "Upravit seznam ztlumených uživatelů" + "write:notes": "Sestavit nebo odstranit poznámky" + "read:notifications": "Zobrazit oznámení" + "write:notifications": "Spravit oznámení" + "read:reactions": "Zobrazit vaše reakce" + "write:reactions": "Upravit své reakce" + "write:votes": "Hlasovat v anketě" + "read:pages": "Zobrazit své stránky" + "write:pages": "Upravit nebo odstranit stránky" + "read:page-likes": "Zobrazit to se mi líbí na stránkách" + "write:page-likes": "Upravit to se mi líbí na stránkách" + "read:user-groups": "Zobrazit skupiny uživatelů" + "write:user-groups": "Upravit nebo odstranit skupiny uživatelů" + "read:channels": "Zobrazit své kanály" + "write:channels": "Upravit kanály" + "read:gallery": "Zobrazit galerii" + "write:gallery": "Upravit galerii" + "read:gallery-likes": "Zobrazit seznam to se mi líbí příspěvků v galerii" + "write:gallery-likes": "Upravit seznam to se mi líbí příspěvků v galerii" +_auth: + shareAccessTitle: "Udělovat oprávnění k aplikacím" + shareAccess: "Chcete autorizovat \"{name}\" pro přístup k tomuto účtu?" + shareAccessAsk: "Opravdu chcete této aplikaci povolit přístup k vašemu účtu?" + permission: "{jméno} požaduje tato oprávnění" + permissionAsk: "Tato aplikace požaduje následující oprávnění" + pleaseGoBack: "Vraťte se prosím zpět do aplikace" + callback: "Návrat k aplikaci" + denied: "Přístup odepřen" + pleaseLogin: "Pro autorizaci aplikací se prosím přihlaste." +_antennaSources: + all: "Všechny poznámky" + homeTimeline: "Poznámky sledovaných uživatelů" + users: "Poznámky konkrétních uživatelů" + userList: "Poznámky z určitého seznamu uživatelů" _weekday: sunday: "Neděle" monday: "Pondělí" @@ -678,38 +1758,81 @@ _weekday: _widgets: profile: "Váš profil" instanceInfo: "Informace o instanci" + memo: "Přilepené poznámky" notifications: "Oznámení" timeline: "Časová osa" calendar: "Kalendář" trends: "Trendy" clock: "Hodiny" rss: "RSS čtečka" + rssTicker: "RSS Ticker" activity: "Aktivita" photos: "Fotky" digitalClock: "Digitální hodiny" + unixClock: "Hodiny UNIX" federation: "Federace" + instanceCloud: "Cloud instance" + postForm: "Formulář pro odeslání" slideshow: "Prezentace" button: "Tlačítko" onlineUsers: "Online uživatelé" jobQueue: "Fronta úloh" + serverMetric: "Metriky serveru" aiscript: "AiScript conzole" + aiscriptApp: "Aplikace AiScript" aichan: "Ai" + userList: "Seznam uživatelů" _userList: chooseList: "Vybrat seznam" + clicker: "Clicker" _cw: hide: "Skrýt" show: "Zobrazit více" + chars: "{count} charakterů" + files: "{count} souborů" _poll: + noOnlyOneChoice: "Jsou zapotřebí alespoň dvě možnosti" + choiceN: "Volba {n}" noMore: "Více už přidat nemůžete" + canMultipleVote: "Umožnit výběr více možností" + expiration: "Ukončení ankety" infinite: "Nikdy" + at: "Ukončit v" + after: "Ukončit po" deadlineDate: "Datum ukončení" deadlineTime: "Hodin" duration: "Trvání" + votesCount: "{n} hlasů" + totalVotes: "{n} hlasů celkově" + vote: "Hlasovat v anketě" + showResult: "Zobrazit výsledky" + voted: "Odhlasováno" + closed: "Uzavřeno" + remainingDays: "Zbývá {d} den/dní a {h} hodin/a" + remainingHours: "Zbývá {h} hodin/a a {m} minut/a" + remainingMinutes: "Zbývá {m} minut/a a {s} sekund/a" + remainingSeconds: "Zbývá {s} sekund/a" _visibility: + public: "Veřejný" + publicDescription: "Vaše poznámka bude viditelná pro všechny uživatele" home: "Domů" + homeDescription: "Zveřejnit příspěvek pouze na domovskou časovou osu" followers: "Sledující" + followersDescription: "Zviditelnit pouze pro své sledující" + specified: "Přímý" + specifiedDescription: "Zviditelnit pouze pro určité uživatele" + disableFederation: "Defederace" + disableFederationDescription: "Nepřenášet do jiných instancí" _postForm: + replyPlaceholder: "Odpovědět na tuto poznámku..." + quotePlaceholder: "Citovat tuto poznámku..." + channelPlaceholder: "Zveřejnit příspěvek do kanálu..." _placeholders: + a: "Co máte v plánu?" + b: "Co se děje kolem vás?" + c: "Co máte na mysli?" + d: "Co chcete říct?" + e: "Začít psát..." f: "Čekám, až něco napíšete..." _profile: name: "Jméno" @@ -717,36 +1840,100 @@ _profile: description: "O mně" youCanIncludeHashtags: "V popisku o Vás můžete použít i hastagy." metadata: "Doplňující informace" + metadataEdit: "Upravit doplňující informace" + metadataDescription: "Pomocí nich můžete ve svém profilu zobrazit doplňující informační pole." + metadataLabel: "Popisek" metadataContent: "Obsah" + changeAvatar: "Změnit avatara" + changeBanner: "Změnit banner" _exportOrImport: allNotes: "Všechny poznámky" + favoritedNotes: "Oblíbené poznámky" followingList: "Sledovaní" muteList: "Ztlumit" blockingList: "Zablokovat" userLists: "Seznamy" + excludeMutingUsers: "Vyloučit ztlumené uživatele" + excludeInactiveUsers: "Vyloučit neaktivní uživatele" _charts: federation: "Federace" apRequest: "Požadavek" + usersIncDec: "Rozdíl v počtech uživatelů" usersTotal: "Celkem uživatelů" activeUsers: "Aktivní uživatelé" + notesIncDec: "Rozdíl v počtu poznámek" + localNotesIncDec: "Rozdíl v počtu místních poznámek" + remoteNotesIncDec: "Rozdíl v počtu vzdálených poznámek" notesTotal: "Celkový počet poznámek" + filesIncDec: "Rozdíl v počtu souborů" + filesTotal: "Celkový počet souborů" + storageUsageIncDec: "Rozdíl ve využití úložiště" + storageUsageTotal: "Celkové využití úložiště" +_instanceCharts: + requests: "Požadavky" + users: "Rozdíl v počtech uživatelů" + usersTotal: "Kumulativní počet uživatelů" + notes: "Rozdíl v počtu poznámek" + notesTotal: "Kumulativní počet poznámek" + ff: "Rozdíl v počtu sledovaných uživatelů / sledujících" + ffTotal: "Kumulativní počet sledovaných uživatelů / sledujících" + cacheSize: "Rozdíl ve velikosti mezipaměti" + cacheSizeTotal: "Kumulativní celková velikost mezipaměti" + files: "Rozdíl v počtu souborů" + filesTotal: "Kumulativní počet souborů" _timelines: home: "Domů" + local: "Místní" + social: "Sociální síť" global: "Globální" _play: + new: "Vytvořit Play" + edit: "Upravit Play" + created: "Play vytvořen" + updated: "Play upraven" + deleted: "Play smazán" + pageSetting: "Nastavení Play" + editThisPage: "Upravit tenhle Play" + viewSource: "Zobrazit zdroj" + my: "Moje Plays" + liked: "To se mi líbí Plays" + featured: "Populární" + title: "Titulek" script: "Skript" summary: "Popis" _pages: newPage: "Vytvořit novou stránku" editPage: "Upravit stránku" + readPage: "Prohlížení zdroje této stránky" created: "Stránka byla úspěšně vytvořena" updated: "Stránka byla úspěšně aktualizována" deleted: "Stránka byla úspěšně smazána" pageSetting: "Nastavení stránky" + nameAlreadyExists: "Zadaná adresa URL stránky již existuje" + invalidNameTitle: "Zadaná adresa URL stránky je neplatná" invalidNameText: "Ujistěte se že jméno stránky je vyplněno" + editThisPage: "Upravit tuto stránku" + viewSource: "Zobrazit zdroj" + viewPage: "Zobrazit své stránky" + like: "To se mi líbí" + unlike: "Už se mi to nelíbí" + my: "Moje stránky" + liked: "To se mi líbí stránky" + featured: "Populární" + inspector: "Inspektor" contents: "Obsah" + content: "Blok stránky" + variables: "Proměnné" + title: "Titulek" + url: "URL stránky" + summary: "Přehled stránky" + alignCenter: "Vycentrovat prvky" + hideTitleWhenPinned: "Skrytí názvu stránky při připnutí k profilu" + font: "Písmo" fontSerif: "Serif" fontSansSerif: "Sans Serif" + eyeCatchingImageSet: "Nastavení miniatury" + eyeCatchingImageRemove: "Smazání miniatury" chooseBlock: "Přidat blok" selectType: "Vyberte typ" contentBlocks: "Obsah" @@ -758,8 +1945,28 @@ _pages: section: "Sekce" image: "Obrázky" button: "Tlačítko" + note: "Vestavěná poznámka" + _note: + id: "ID poznámky" + idDescription: "Adresu URL poznámky můžete vložit také sem." + detailed: "Podrobné zobrazení" +_relayStatus: + requesting: "Čeká se" + accepted: "Schváleno" + rejected: "Odmítnuto" _notification: + fileUploaded: "Soubor úspěšně nahrán" + youGotMention: "{name} vás zmínil" + youGotReply: "{name} vám odpověděl" + youGotQuote: "{name} vás citoval" + youRenoted: "Poznámka od {jméno}" youWereFollowed: "Máte nového následovníka" + youReceivedFollowRequest: "Obdrželi jste žádost o sledování" + yourFollowRequestAccepted: "Vaše žádost o sledování byla přijata" + pollEnded: "Výsledky ankety jsou k dispozici" + unreadAntennaNote: "Anténa {name}" + emptyPushNotificationMessage: "Push oznámení byla aktualizována" + achievementEarned: "Úspěch odemčen" _types: all: "Vše" follow: "Sledovaní" @@ -768,17 +1975,64 @@ _notification: renote: "Přeposlat" quote: "Citovat" reaction: "Reakce" + pollEnded: "Anketa končí" + receiveFollowRequest: "Obdržené žádosti o sledování" + followRequestAccepted: "Přijaté žádosti o sledování" + achievementEarned: "Úspěch odemčen" + app: "Oznámení z propojených aplikací" _actions: + followBack: "vás začal sledovat zpět" reply: "Odpovědět" renote: "Přeposlat" _deck: + alwaysShowMainColumn: "Vždy zobrazovat hlavní sloupec" + columnAlign: "Zarovnat sloupce" + addColumn: "Přidat sloupec" + configureColumn: "Nastavení sloupců" + swapLeft: "Prohodit s levým sloupcem" + swapRight: "Prohodit s pravým sloupcem" + swapUp: "Prohodit s výše uvedeným sloupcem" + swapDown: "Prohodit s níže uvedeným sloupcem" + stackLeft: "Nahromadit v levém sloupci" + popRight: "Popnout sloupec na pravou stranu" + profile: "Profil" + newProfile: "Nový profil" + deleteProfile: "Smazat profil" + introduction: "Vytvořte si dokonalé rozhraní volným uspořádáním sloupců!" + introduction2: "Kliknutím na tlačítko + v pravé části obrazovky můžete kdykoli přidat nové sloupce." + widgetsIntroduction: "V nabídce sloupce vyberte možnost \"Upravit widgety\" a přidejte widget." + useSimpleUiForNonRootPages: "Použít zjednodušené uživatelské rozhraní pro navigaci na stránkách" _columns: + main: "Hlavní" + widgets: "Widgety" notifications: "Oznámení" tl: "Časová osa" antenna: "Antény" list: "Seznamy" channel: "Kanály" mentions: "Zmínění" + direct: "Přímý" + roleTimeline: "Časová osa role" +_dialog: + charactersExceeded: "Překročili jste maximální počet znaků! V současné době je na hodnotě {current} z {max}." + charactersBelow: "Nedosahujete minimálního limitu znaků! V současné době je na {current} z {min}." +_disabledTimeline: + title: "Časová osa vypnuta" + description: "Tuto časovou osu nemůžete používat v rámci svých současných rolí." +_drivecleaner: + orderBySizeDesc: "Sestupná velikost souborů" + orderByCreatedAtAsc: "Vzestupné datumy" _webhookSettings: + createWebhook: "Vytvořit Webhook" name: "Jméno" + secret: "Tajné" + events: "Události Webhook" active: "Zapnuto" + _events: + follow: "Při sledování uživatele" + followed: "Při sledování" + note: "Při zveřejňování poznámky" + reply: "Při obdržení odpovědi" + renote: "Při renotaci poznámky" + reaction: "Při obdržení reakce" + mention: "Při zmínce" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 040e8836ef..96de3ff45e 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -156,6 +156,7 @@ addEmoji: "Emoji hinzufügen" settingGuide: "Empfohlene Einstellung" cacheRemoteFiles: "Dateien von fremden Instanzen im Cache speichern" cacheRemoteFilesDescription: "Ist diese Einstellung deaktiviert, so werden Dateien fremder Instanzen direkt von dort geladen. Hierdurch wird Speicherplatz auf diesem Server gespart, aber durch fehlende Generierung von Vorschaubildern mehr Bandbreite verwendet." +youCanCleanRemoteFilesCache: "Klicke auf den 🗑️-Knopf der Dateiverwaltungsansicht, um den Cache zu leeren." cacheRemoteSensitiveFiles: "Sensitive Dateien von fremden Instanzen im Cache speichern" cacheRemoteSensitiveFilesDescription: "Ist diese Einstellung deaktiviert, so werden sensitive Dateien fremder Instanzen direkt von dort ohne Zwischenspeicherung geladen." flagAsBot: "Als Bot markieren" @@ -230,7 +231,7 @@ noJobs: "Keine Jobs vorhanden" federating: "Wird föderiert" blocked: "Blockiert" suspended: "Gesperrt" -all: "Alles" +all: "Alle" subscribing: "Wird abonniert" publishing: "Wird veröffentlicht" notResponding: "Antwortet nicht" @@ -540,7 +541,7 @@ chooseEmoji: "Emoji auswählen" unableToProcess: "Der Vorgang konnte nicht abgeschlossen werden" recentUsed: "Vor kurzem verwendet" install: "Installieren" -uninstall: "Uninstallieren" +uninstall: "Deinstallieren" installedApps: "Authorisierte Anwendungen" nothing: "Hier gibt es nichts zu sehen" installedDate: "Authorisiert am" @@ -680,6 +681,7 @@ createNewClip: "Neuen Clip erstellen" unclip: "Aus Clip entfernen" confirmToUnclipAlreadyClippedNote: "Diese Notiz ist bereits im \"{name}\" Clip enthalten. Möchtest du sie aus diesem Clip entfernen?" public: "Öffentlich" +private: "Privat" i18nInfo: "Misskey wird durch freiwillige Helfer in viele verschiedene Sprachen übersetzt. Auf {link} kannst du mithelfen." manageAccessTokens: "Zugriffstokens verwalten" accountInfo: "Benutzerkonto-Informationen" @@ -1094,6 +1096,21 @@ expired: "Abgelaufen" doYouAgree: "Zustimmen?" beSureToReadThisAsItIsImportant: "Lies bitte diese wichtige Informationen." iHaveReadXCarefullyAndAgree: "Ich habe den Text \"{x}\" gelesen und stimme zu." +dialog: "Dialogfeld" +icon: "Symbol" +forYou: "Für dich" +currentAnnouncements: "Aktuelle Ankündigungen" +pastAnnouncements: "Alte Ankündigungen" +youHaveUnreadAnnouncements: "Es gibt neue Ankündigungen." +_announcement: + forExistingUsers: "Nur für existierende Nutzer" + forExistingUsersDescription: "Ist diese Option aktiviert, wird diese Ankündigung nur Nutzern angezeigt, die zum Zeitpunkt der Ankündigung bereits registriert sind. Ist sie deaktiviert, wird sie auch Nutzern, die sich nach dessen Veröffentlichung registrieren, angezeigt." + needConfirmationToRead: "Separate Lesebestätigung erfordern" + needConfirmationToReadDescription: "Ist dies aktiviert, so wird beim Markieren dieser Ankündigung als gelesen ein separates Bestätigungsfenster angezeigt. Auch wird sie von der \"Alle als gelesen markieren\"-Funktion ausgenommen." + end: "Ankündigung archivieren" + tooManyActiveAnnouncementDescription: "Zu viele aktive Ankündigungen können die Benutzerfreundlichkeit verschlechtern. Es wird empfohlen, veraltete Ankündigungen zu archivieren." + readConfirmTitle: "Als gelesen markieren?" + readConfirmText: "Dies markiert den Inhalt von \"{title}\" als gelesen." _initialAccountSetting: accountCreated: "Dein Konto wurde erfolgreich erstellt!" letsStartAccountSetup: "Lass uns nun dein Konto einrichten." @@ -1730,6 +1747,10 @@ _permissions: "write:gallery": "Deine Galerie bearbeiten" "read:gallery-likes": "Liste deiner mit \"Gefällt mir\" markierten Galerie-Beiträge lesen" "write:gallery-likes": "Liste deiner mit \"Gefällt mir\" markierten Galerie-Beiträge bearbeiten" + "read:flash": "Deine Plays lesen" + "write:flash": "Deine Plays bearbeiten oder löschen" + "read:flash-likes": "Liste der Plays, die mir gefallen, lesen" + "write:flash-likes": "Liste der Plays, die mir gefallen, bearbeiten" _auth: shareAccessTitle: "Verteilung von App-Berechtigungen" shareAccess: "Möchtest du „{name}“ authorisieren, auf dieses Benutzerkonto zugreifen zu können?" diff --git a/locales/el-GR.yml b/locales/el-GR.yml index 41b1ea7c65..558d466f3a 100644 --- a/locales/el-GR.yml +++ b/locales/el-GR.yml @@ -287,6 +287,7 @@ searchByGoogle: "Αναζήτηση" file: "Αρχεία" recommended: "Προτεινόμενα" cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού Χώρου" +icon: "Εικονίδιο" _email: _follow: title: "Έχετε ένα νέο ακόλουθο" diff --git a/locales/en-US.yml b/locales/en-US.yml index ea82525513..7bbe90ed73 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -74,7 +74,7 @@ import: "Import" export: "Export" files: "Files" download: "Download" -driveFileDeleteConfirm: "Are you sure you want to delete \"{name}\"? It will also vanish from all contents that use it." +driveFileDeleteConfirm: "Do you want to remove the file \"{name}\"? Some content using this file will also be removed." unfollowConfirm: "Are you sure you want to unfollow {name}?" exportRequested: "You've requested an export. This may take a while. It will be added to your Drive once completed." importRequested: "You've requested an import. This may take a while." @@ -156,6 +156,7 @@ addEmoji: "Add an emoji" settingGuide: "Recommended settings" cacheRemoteFiles: "Cache remote files" cacheRemoteFilesDescription: "When this setting is disabled, remote files are loaded directly from the remote instance. Disabling this will decrease storage usage, but increase traffic, as thumbnails will not be generated." +youCanCleanRemoteFilesCache: "You can clear the cache by clicking the 🗑️ button in the file management view." cacheRemoteSensitiveFiles: "Cache sensitive remote files" cacheRemoteSensitiveFilesDescription: "When this setting is disabled, sensitive remote files are loaded directly from the remote instance without caching." flagAsBot: "Mark this account as a bot" @@ -680,6 +681,7 @@ createNewClip: "Create new clip" unclip: "Unclip" confirmToUnclipAlreadyClippedNote: "This note is already part of the \"{name}\" clip. Do you want to remove it from this clip instead?" public: "Public" +private: "Private" i18nInfo: "Misskey is being translated into various languages by volunteers. You can help at {link}." manageAccessTokens: "Manage access tokens" accountInfo: "Account Info" @@ -1042,7 +1044,7 @@ vertical: "Vertical" horizontal: "Horizontal" position: "Position" serverRules: "Server rules" -pleaseConfirmBelowBeforeSignup: "Please confirm the below before signing up." +pleaseConfirmBelowBeforeSignup: "To register on this server, you must review and agree to the following:" pleaseAgreeAllToContinue: "You must agree to all above fields to continue." continue: "Continue" preservedUsernames: "Reserved usernames" @@ -1094,6 +1096,21 @@ expired: "Expired" doYouAgree: "Agree?" beSureToReadThisAsItIsImportant: "Please read this important information." iHaveReadXCarefullyAndAgree: "I have read the text \"{x}\" and agree." +dialog: "Dialog" +icon: "Icon" +forYou: "For you" +currentAnnouncements: "Current announcements" +pastAnnouncements: "Past announcements" +youHaveUnreadAnnouncements: "There are unread announcements." +_announcement: + forExistingUsers: "Existing users only" + forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it." + needConfirmationToRead: "Require separate read confirmation" + needConfirmationToReadDescription: "A separate prompt to confirm marking this announcement as read will be displayed if enabled. This announcement will also be excluded from any \"Mark all as read\" functionality." + end: "Archive announcement" + tooManyActiveAnnouncementDescription: "Having too many active announcements may worsen the user experience. Please consider archiving announcements that have become obsolete." + readConfirmTitle: "Mark as read?" + readConfirmText: "This will mark the contents of \"{title}\" as read." _initialAccountSetting: accountCreated: "Your account was successfully created!" letsStartAccountSetup: "For starters, let's set up your profile." @@ -1718,10 +1735,10 @@ _permissions: "read:reactions": "View your reactions" "write:reactions": "Edit your reactions" "write:votes": "Vote on a poll" - "read:pages": "View your pages" - "write:pages": "Edit or delete your pages" - "read:page-likes": "View your likes on pages" - "write:page-likes": "Edit your likes on pages" + "read:pages": "View your Pages" + "write:pages": "Edit or delete your Pages" + "read:page-likes": "View list of liked Pages" + "write:page-likes": "Edit list of liked Pages" "read:user-groups": "View your user groups" "write:user-groups": "Edit or delete your user groups" "read:channels": "View your channels" @@ -1730,6 +1747,10 @@ _permissions: "write:gallery": "Edit your gallery" "read:gallery-likes": "View your list of liked gallery posts" "write:gallery-likes": "Edit your list of liked gallery posts" + "read:flash": "View Play" + "write:flash": "Edit Plays" + "read:flash-likes": "View list of liked Plays" + "write:flash-likes": "Edit list of liked Plays" _auth: shareAccessTitle: "Granting application permissions" shareAccess: "Would you like to authorize \"{name}\" to access this account?" @@ -1999,7 +2020,7 @@ _deck: introduction: "Create the perfect interface for you by arranging columns freely!" introduction2: "Click on the + on the right of the screen to add new colums whenever you want." widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget." - useSimpleUiForNonRootPages: "Use simple UI for navigated pages" + useSimpleUiForNonRootPages: "Use simplified UI to navigated pages" _columns: main: "Main" widgets: "Widgets" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 127dc367e6..7e7e0a8786 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -8,10 +8,10 @@ search: "Buscar" notifications: "Notificaciones" username: "Nombre de usuario" password: "Contraseña" -forgotPassword: "Olvidé mi Contraseña" +forgotPassword: "Olvidé mi contraseña" fetchingAsApObject: "Buscando en el fediverso" ok: "OK" -gotIt: "¡Lo tengo!" +gotIt: "Entendido" cancel: "Cancelar" noThankYou: "No gracias" enterUsername: "Introduce el nombre de usuario" @@ -21,7 +21,7 @@ noNotifications: "No hay notificaciones" instance: "Instancia" settings: "Configuración" notificationSettings: "Configurar las notificaciones" -basicSettings: "Configuración Básica" +basicSettings: "Configuración básica" otherSettings: "Configuración avanzada" openInWindow: "Abrir en una ventana" profile: "Perfil" @@ -156,6 +156,7 @@ addEmoji: "Agregar emoji" settingGuide: "Configuración sugerida" cacheRemoteFiles: "Mantener en cache los archivos remotos" cacheRemoteFilesDescription: "Si desactiva esta configuración, Los archivos remotos se cargarán desde el link directo sin usar la caché. Con eso se puede ahorrar almacenamiento del servidor, pero eso aumentará el tráfico al no crear miniaturas." +youCanCleanRemoteFilesCache: "Puedes vaciar la caché pulsando en el botón 🗑️ en el administrador de archivos." cacheRemoteSensitiveFiles: "Cachear archivos remotos sensibles" cacheRemoteSensitiveFilesDescription: "Cuando esta opción está desactivada, los archivos remotos sensibles son cargador directamente de la instancia origen sin ser cacheados." flagAsBot: "Esta cuenta es un bot" @@ -680,6 +681,7 @@ createNewClip: "Crear clip nuevo" unclip: "Quitar clip" confirmToUnclipAlreadyClippedNote: "Esta nota ya está incluida en el clip \"{name}\". ¿Quiere quitar la nota del clip?" public: "Público" +private: "Privado" i18nInfo: "Misskey está siendo traducido a varios idiomas gracias a voluntarios. Se puede colaborar traduciendo en {link}" manageAccessTokens: "Administrar tokens de acceso" accountInfo: "Información de la Cuenta" @@ -1091,6 +1093,24 @@ usedAt: "Usada el" unused: "Sin usar" used: "Usada" expired: "Caducada" +doYouAgree: "¿Está de acuerdo?" +beSureToReadThisAsItIsImportant: "Por favor lea esto que es importante" +iHaveReadXCarefullyAndAgree: "He leído el texto {x} y estoy de acuerdo" +dialog: "Diálogo" +icon: "Avatar" +forYou: "Para ti" +currentAnnouncements: "Anuncios actuales" +pastAnnouncements: "Anuncios anteriores" +youHaveUnreadAnnouncements: "Hay anuncios sin leer" +_announcement: + forExistingUsers: "Solo para usuarios registrados" + forExistingUsersDescription: "Este anuncio solo se mostrará a aquellos usuarios registrados en el momento de su publicación. Si se deshabilita esta opción, aquellos usuarios que se registren tras su publicación también lo verán." + needConfirmationToRead: "Requerir confirmación de lectura aparte" + needConfirmationToReadDescription: "Si se habilita esta opción, se pedirá una confirmación de lectura aparte. Además, este anuncio será excluido de cualquier funcionalidad de \"Marcar todos como leídos\"." + end: "Anuncios archivados" + tooManyActiveAnnouncementDescription: "Tener demasiados anuncios activos empeora la experiencia de usuario. Por favor, considera archivar aquellos anuncios que hayan quedado obsoletos." + readConfirmTitle: "¿Marcar como leído?" + readConfirmText: "Esto marcará el contenido de \"{title}\" como leído." _initialAccountSetting: accountCreated: "¡La cuenta ha sido creada!" letsStartAccountSetup: "Para empezar, creemos tu perfil." diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index f76a26632d..260488fdb3 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -49,6 +49,7 @@ delete: "Supprimer" deleteAndEdit: "Supprimer et réécrire" deleteAndEditConfirm: "Êtes-vous sûr·e de vouloir supprimer cette note et la reformuler ? Vous perdrez toutes les réactions, renotes et réponses y afférentes." addToList: "Ajouter à une liste" +addToAntenna: "Ajouter à l’antenne" sendMessage: "Envoyer un message" copyRSS: "Copier le RSS" copyUsername: "Copier le nom d’utilisateur·rice" @@ -60,7 +61,7 @@ copyProfileUrl: "Copier l'URL du profil" searchUser: "Chercher un·e utilisateur·rice" reply: "Répondre" loadMore: "Afficher plus …" -showMore: "Afficher plus …" +showMore: "Voir plus" showLess: "Fermer" youGotNewFollower: "Vous suit" receiveFollowRequest: "Demande d’abonnement reçue" @@ -73,13 +74,13 @@ import: "Importer" export: "Exporter" files: "Fichiers" download: "Télécharger" -driveFileDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer le fichier \"{name}\" ? Les notes liées à ce fichier seront aussi supprimées." +driveFileDeleteConfirm: "Êtes-vous sûr de vouloir supprimer le fichier \"{name}\" ? Les notes liées à ce fichier seront aussi supprimées." unfollowConfirm: "Désirez-vous vous désabonner de {name} ?" -exportRequested: "Vous avez demandé une exportation. L’opération pourrait prendre un peu de temps. Une terminée, le fichier résultant sera ajouté au Drive." +exportRequested: "Vous avez demandé une exportation. L’opération pourrait prendre un peu de temps. Une fois terminée, le fichier sera ajouté au Drive." importRequested: "Vous avez initié un import. Cela pourrait prendre un peu de temps." lists: "Listes" noLists: "Vous n’avez aucune liste" -note: "Notes" +note: "Note" notes: "Notes" following: "Abonnements" followers: "Abonné·e·s" @@ -121,7 +122,7 @@ reaction: "Réactions" reactions: "Réactions" reactionSetting: "Réactions à afficher dans le sélecteur de réactions" reactionSettingDescription2: "Déplacer pour réorganiser, cliquer pour effacer, utiliser « + » pour ajouter." -rememberNoteVisibility: "Activer l'option \" se souvenir de la visibilité des notes \" vous permet de réutiliser automatiquement la visibilité utilisée lors de la publication de votre note précédente." +rememberNoteVisibility: "Se souvenir de la visibilité des notes" attachCancel: "Supprimer le fichier attaché" markAsSensitive: "Marquer comme sensible" unmarkAsSensitive: "Supprimer le marquage comme sensible" @@ -137,6 +138,7 @@ unblockConfirm: "Êtes-vous sûr·e de vouloir débloquer ce compte ?" suspendConfirm: "Êtes-vous sûr·e de vouloir suspendre ce compte ?" unsuspendConfirm: "Êtes-vous sûr·e de vouloir annuler la suspension de ce compte ?" selectList: "Sélectionner une liste" +editList: "Modifier la liste" selectChannel: "Sélectionner un canal" selectAntenna: "Sélectionner une antenne" editAntenna: "Modifier l'antenne" @@ -270,6 +272,7 @@ startMessaging: "Commencer à discuter" nUsersRead: "Lu par {n} personnes" agreeTo: "J’accepte {0}" agree: "Accepter" +basicNotesBeforeCreateAccount: "Notes importantes" termsOfService: "Conditions d'utilisation" start: "Commencer" home: "Principal" @@ -664,6 +667,7 @@ createNew: "Créer nouveau" optional: "Facultatif" createNewClip: "Créer un nouveau clip" public: "Public" +private: "Privé" i18nInfo: "Misskey est traduit dans différentes langues par des bénévoles. Vous pouvez contribuer à {link}." manageAccessTokens: "Gérer les jetons d'accès" accountInfo: " Informations du compte " @@ -826,6 +830,8 @@ breakFollow: "Ne plus suivre" breakFollowConfirm: "Êtes-vous sûr de vouloir vous désabonner ?" itsOn: "Activé" itsOff: "Désactivé" +on: "Activé" +off: "Désactivé" emailRequiredForSignup: "Une adresse e-mail est nécessaire pour créer un compte" unread: "Non lu" filter: "Filtre" @@ -941,6 +947,7 @@ preset: "Préréglage" selectFromPresets: "Sélectionner à partir des préréglages" thisPostMayBeAnnoying: "Cette note peut gêner d'autres personnes." thisPostMayBeAnnoyingCancel: "Annuler" +internalServerError: "Erreur interne du serveur" license: "Licence" video: "Vidéo" videos: "Vidéos" @@ -957,6 +964,9 @@ vertical: "Vertical" horizontal: "Latéral" serverRules: "Règles du serveur" youFollowing: "Abonné·e" +goToMisskey: "Retour vers Misskey" +expirationDate: "Date d’expiration" +icon: "Avatar" _achievements: _types: _notes1: diff --git a/locales/hu-HU.yml b/locales/hu-HU.yml new file mode 100644 index 0000000000..fdab9645c1 --- /dev/null +++ b/locales/hu-HU.yml @@ -0,0 +1,103 @@ +--- +_lang_: "Japán" +monthAndDay: "{month}.{day}." +search: "Keresés" +notifications: "Értesítések" +username: "Felhasználónév" +password: "Jelszó" +forgotPassword: "Elfelejtett jelszó" +ok: "OK" +gotIt: "Rendben" +cancel: "Mégse" +noThankYou: "Nem, köszönöm" +enterUsername: "Felhasználónév megadása" +renotedBy: "{user} Renotolta" +noNotes: "Nincs Note" +noNotifications: "Nincs értesítés" +instance: "Szerver" +settings: "Beállítások" +notificationSettings: "Értesítés beállításai" +basicSettings: "Alapbeállítás" +otherSettings: "Egyéb beállítások" +openInWindow: "Megnyitás ablakban" +profile: "Saját profil" +timeline: "Idővonal" +noAccountDescription: "Nincs leírás" +login: "Bejelentkezés" +loggingIn: "Belépés" +logout: "Kijelentkezés" +signup: "Regisztráció" +uploading: "Feltöltés" +save: "Mentés" +users: "Felhasználók" +addUser: "Felhasználó hozzáadása" +favorite: "Kedvencek" +favorites: "Kedvencek" +unfavorite: "Törlés a kedvencek közül." +favorited: "Kedvencek közé rakva." +alreadyFavorited: "Már a kedvencek között van." +cantFavorite: "Nem sikerült a kedvencek közé rakni." +pin: "Rögzítés" +unpin: "Rögzítés feloldása" +copyContent: "Tartalom másolása" +copyLink: "Hivatkozás Másolása" +delete: "Törlés" +deleteAndEdit: "Törlés és szerkesztés" +deleteAndEditConfirm: "Biztosan törlöd ezt a jegyzetet és újrafogalmazza? Így eveszíted az összes reakciót, renote-ot és választ." +addToList: "Hozzáadás a listákhoz" +privacy: "Adatvédelem" +makeFollowManuallyApprove: "Csak jóváhagyással követhetnek" +defaultNoteVisibility: "Alapértelmezett láthatóság" +follow: "Követés" +followRequest: "Követés kérése" +followRequests: "Követési kérések" +unfollow: "Követés visszavonása" +followRequestPending: "Függőben levő követési kérés" +enterEmoji: "Írj egy emoji-t" +renote: "Renote" +unrenote: "Renote visszavonása" +renoted: "Renotolva" +cantRenote: "Nem lehet Renotolni" +cantReRenote: "A Renote nem renotálható" +quote: "Idézet" +inChannelRenote: "Csak csatornán bellüli Renote" +inChannelQuote: "Csak csatornán bellüli idézet" +pinnedNote: "Csatolt jegyzet" +pinned: "Rögzítés" +you: "Te" +clickToShow: "Kattints ide" +sensitive: "Érzékeny" +add: "Hozzáad" +reaction: "Reakciók" +reactions: "Reakciók" +instances: "Szerver" +remove: "Törlés" +pinnedNotes: "Csatolt jegyzet" +smtpUser: "Felhasználónév" +smtpPass: "Jelszó" +user: "Felhasználók" +searchByGoogle: "Keresés" +_theme: + keys: + renote: "Renote" +_sfx: + notification: "Értesítések" +_2fa: + renewTOTPCancel: "Nem, köszönöm" +_widgets: + profile: "Saját profil" + notifications: "Értesítések" + timeline: "Idővonal" +_profile: + username: "Felhasználónév" +_notification: + _types: + renote: "Renote" + quote: "Idézet" + reaction: "Reakciók" + _actions: + renote: "Renote" +_deck: + _columns: + notifications: "Értesítések" + tl: "Idővonal" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 34c995b05e..db55a5b5d8 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -49,11 +49,15 @@ delete: "Hapus" deleteAndEdit: "Hapus dan sunting" deleteAndEditConfirm: "Apakah kamu yakin ingin menghapus note ini dan menyuntingnya? Kamu akan kehilangan semua reaksi, renote dan balasan di note ini." addToList: "Tambahkan ke daftar" +addToAntenna: "Tambahkan ke Antena" sendMessage: "Kirim pesan" copyRSS: "Salin RSS" copyUsername: "Salin nama pengguna" copyUserId: "Salin ID pengguna" copyNoteId: "Salin ID catatan" +copyFileId: "Salin Berkas" +copyFolderId: "Salin Folder" +copyProfileUrl: "Salin Alamat Web Profil" searchUser: "Cari pengguna" reply: "Balas" loadMore: "Selebihnya" @@ -129,12 +133,12 @@ renoteMute: "Matikan renote" renoteUnmute: "Batal mematikan renote" block: "Blokir" unblock: "Buka blokir" -suspend: "Bekukan" -unsuspend: "Buka pembekuan" +suspend: "Tangguhkan" +unsuspend: "Batalkan penangguhan" blockConfirm: "Apakah kamu yakin ingin memblokir akun ini?" unblockConfirm: "Apakah kamu yakin ingin membuka blokir akun ini?" -suspendConfirm: "Apakah kamu yakin ingin membekukan akun ini?" -unsuspendConfirm: "Apakah kamu yakin ingin membuka pembekuan akun ini?" +suspendConfirm: "Apakah kamu yakin ingin menangguhkan akun ini?" +unsuspendConfirm: "Apakah kamu yakin ingin membatalkan penangguhan akun ini?" selectList: "Pilih daftar" editList: "Sunting daftar" selectChannel: "Pilih kanal" @@ -152,6 +156,8 @@ addEmoji: "Tambahkan emoji" settingGuide: "Pengaturan rekomendasi" cacheRemoteFiles: "Tembolokkan berkas dari instansi luar" cacheRemoteFilesDescription: "Ketika pengaturan ini dinonaktifkan, berkas dari instansi luar akan dimuat langsung. Menonaktifkan ini akan mengurangi penggunaan penyimpanan peladen, namun dapat menyebabkan peningkatan lalu lintas bandwidth, karena keluku tidak dihasilkan." +cacheRemoteSensitiveFiles: "Tembolokkan berkas dari instansi luar" +cacheRemoteSensitiveFilesDescription: "Menonaktifkan pengaturan ini menyebabkan berkas sensitif dari instansi luar ditautkan secara langsung, bukan ditembolok." flagAsBot: "Atur akun ini sebagai Bot" flagAsBotDescription: "Jika akun ini dikendalikan oleh program, tetapkanlah opsi ini. Jika diaktifkan, ini akan berfungsi sebagai tanda bagi pengembang lain untuk mencegah interaksi berantai dengan bot lain dan menyesuaikan sistem internal Misskey untuk memperlakukan akun ini sebagai bot." flagAsCat: "Atur akun ini sebagai kucing" @@ -223,7 +229,7 @@ noCustomEmojis: "Tidak ada emoji kustom" noJobs: "Tidak ada kerja" federating: "memfederasi" blocked: "Diblokir" -suspended: "Diberhentikan" +suspended: "Ditangguhkan" all: "Semua" subscribing: "Berlangganan" publishing: "Sedang menyiarkan langsung" @@ -313,6 +319,7 @@ copyUrl: "Salin tautan" rename: "Ubah nama" avatar: "Avatar" banner: "Banner" +displayOfSensitiveMedia: "Tampilkan media NSFW" whenServerDisconnected: "Ketika kehilangan koneksi dengan peladen" disconnectedFromServer: "Terputus koneksi dari peladen" reload: "Muat ulang" @@ -386,10 +393,10 @@ withReplies: "Termasuk balasan" connectedTo: "Akun berikut terhubung" notesAndReplies: "Catatan dan balasan" withFiles: "Media" -silence: "Bungkam" -silenceConfirm: "Apakah kamu yakin ingin membungkam pengguna ini?" -unsilence: "Hapus bungkam" -unsilenceConfirm: "Apakah kamu ingin untuk batal membungkam pengguna ini?" +silence: "Senyapkan" +silenceConfirm: "Apakah kamu yakin ingin menyenyapkan pengguna ini?" +unsilence: "Batalkan senyap" +unsilenceConfirm: "Apakah kamu ingin untuk batal menyenyapkan pengguna ini?" popularUsers: "Pengguna populer" recentlyUpdatedUsers: "Pengguna dengan aktivitas terkini" recentlyRegisteredUsers: "Pengguna baru saja bergabung" @@ -552,10 +559,10 @@ deleteAllFiles: "Hapus semua berkas" deleteAllFilesConfirm: "Apakah kamu yakin ingin menghapus semua berkas?" removeAllFollowing: "Batalkan mengikuti semua pengguna" removeAllFollowingDescription: "Batal mengikuti semua akun dari {host}. Mohon jalankan ini ketika instansi sudah tidak ada lagi." -userSuspended: "Pengguna ini telah dibekukan." -userSilenced: "Pengguna ini telah dibungkam." -yourAccountSuspendedTitle: "Akun ini dibekukan" -yourAccountSuspendedDescription: "Akun ini dibekukan karena melanggar ketentuan penggunaan layanan peladen atau semacamnya. Hubungi admin apabila ingin tahu alasan lebih lanjut. Mohon untuk tidak membuat akun baru." +userSuspended: "Pengguna ini telah ditangguhkan" +userSilenced: "Pengguna ini telah disenyapkan." +yourAccountSuspendedTitle: "Akun ini ditangguhkan" +yourAccountSuspendedDescription: "Akun ini ditangguhkan karena melanggar ketentuan penggunaan layanan peladen atau semacamnya. Hubungi admin apabila ingin mengetahui alasan lebih lanjut. Mohon untuk tidak membuat akun baru." tokenRevoked: "Token tidak valid" tokenRevokedDescription: "Token ini telah kedaluwarsa. Mohon masuk lagi." accountDeleted: "Akun telah dihapus" @@ -673,6 +680,7 @@ createNewClip: "Buat klip baru" unclip: "Batalkan klip" confirmToUnclipAlreadyClippedNote: "Catatan ini sudah disertakan di klip \"{name}\". Yakin ingin membatalkan catatan dari klip ini?" public: "Publik" +private: "Tersembunyi" i18nInfo: "Misskey diterjemahkan ke dalam banyak bahasa oleh sukarelawan. Kamu juga dapat ikut membantu menerjemahkannya di {link}." manageAccessTokens: "Kelola token akses" accountInfo: "Informasi akun" @@ -982,7 +990,7 @@ internalServerErrorDescription: "Peladen sedang mengalami galat tak terduga" copyErrorInfo: "Salin detil galat" joinThisServer: "Gabung peladen ini" exploreOtherServers: "Cari peladen lain" -letsLookAtTimeline: "LIhat timeline" +letsLookAtTimeline: "LIhat lini masa" disableFederationConfirm: "Matikan federasi?" disableFederationConfirmWarn: "Mematikan federasi tidak membuat kiriman menjadi privat. Umumnya, mematikan federasi tidak diperlukan." disableFederationOk: "Matikan federasi" @@ -1066,6 +1074,28 @@ installed: "Terpasang" branding: "Merek" enableServerMachineStats: "Tampilkan informasi mesin peladen menjadi publik" enableIdenticonGeneration: "Nyalakan pembuatan Identicon per pengguna" +turnOffToImprovePerformance: "Matikan untuk tingkatkan performa." +createInviteCode: "Buat kode undangan" +createWithOptions: "Buat dengan opsi" +createCount: "Jumlah undangan" +inviteCodeCreated: "Kode undangan dibuat" +inviteLimitExceeded: "Kamu telah mencapai jumlah maksimum kode undangan yang dapat dibuat." +createLimitRemaining: "Kode undangan yang dapat dibuat: tersisa {limit}" +inviteLimitResetCycle: "Kamu dapat membuat hingga {limit} kode undangan dalam {time}." +expirationDate: "Tanggal kedaluwarsa" +noExpirationDate: "tidak ada tanggal kedaluwarsa" +inviteCodeUsedAt: "Kode undangan digunakan pada" +registeredUserUsingInviteCode: "Undangan digunakan oleh" +waitingForMailAuth: "Menunggu verifikasi surel" +inviteCodeCreator: "Undangan dibuat oleh" +usedAt: "Digunakan pada" +unused: "Tidak digunakan" +used: "Digunakan" +expired: "Kedaluwarsa" +doYouAgree: "Apa kamu setuju?" +beSureToReadThisAsItIsImportant: "Mohon baca informasi penting berikut." +iHaveReadXCarefullyAndAgree: "Saya telah membaca \"{x}\" dan menyetujui." +icon: "Avatar" _initialAccountSetting: accountCreated: "Akun kamu telah sukses dibuat!" letsStartAccountSetup: "Untuk pemula, ayo atur profilmu dulu." @@ -1376,6 +1406,9 @@ _role: ltlAvailable: "Dapat melihat lini masa lokal" canPublicNote: "Dapat mengirim catatan publik" canInvite: "Dapat membuat kode undangan instansi" + inviteLimit: "Batas jumlah undangan" + inviteLimitCycle: "Interval Penerbitan Kode Undangan" + inviteExpirationTime: "Interval kedaluwarsa undangan" canManageCustomEmojis: "Dapat mengelola Emoji kustom" driveCapacity: "Kapasitas Drive" alwaysMarkNsfw: "Selalu tandai berkas sebagai NSFW" @@ -1438,6 +1471,7 @@ _ad: back: "Kembali" reduceFrequencyOfThisAd: "Tampilkan iklan ini lebih sedikit" hide: "Jangan tampilkan" + timezoneinfo: "Hari dalam satu minggu ditentukan dari zona waktu peladen." _forgotPassword: enterEmail: "Masukkan alamat surel yang kamu gunakan pada saat mendaftar. Sebuah tautan untuk mengatur ulang kata sandi kamu akan dikirimkan ke alamat surel tersebut." ifNoEmail: "Apabila kamu tidak menggunakan surel pada saat pendaftaran, mohon hubungi admin segera." @@ -1489,6 +1523,10 @@ _aboutMisskey: donate: "Donasi ke Misskey" morePatrons: "Kami sangat mengapresiasi dukungan dari banyak penolong lain yang tidak tercantum disini. Terima kasih! 🥰" patrons: "Pendukung" +_displayOfSensitiveMedia: + respect: "Sembunyikan media yang ditandai sensitif" + ignore: "Tampilkan media yang ditandai sensitif" + force: "Sembunyikan semua media" _instanceTicker: none: "Jangan tampilkan" remote: "Tampilkan untuk pengguna instansi luar" @@ -1963,6 +2001,7 @@ _deck: introduction: "Buat antarmuka sempurna untukmu dengan menata kolom secara bebas!" introduction2: "Klik \"+\" pada kanan layar untuk menambahkan kolom baru kapanpun yang kamu mau." widgetsIntroduction: "Mohon pilih \"Sunting gawit\" pada menu kolom dan tambahkan gawit." + useSimpleUiForNonRootPages: "Gunakan antarmuka sederhana ke halaman yang dituju" _columns: main: "Utama" widgets: "Widget" diff --git a/locales/index.d.ts b/locales/index.d.ts index db7e3e9575..1f25edd0ef 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -159,6 +159,7 @@ export interface Locale { "settingGuide": string; "cacheRemoteFiles": string; "cacheRemoteFilesDescription": string; + "youCanCleanRemoteFilesCache": string; "cacheRemoteSensitiveFiles": string; "cacheRemoteSensitiveFilesDescription": string; "flagAsBot": string; @@ -683,6 +684,7 @@ export interface Locale { "unclip": string; "confirmToUnclipAlreadyClippedNote": string; "public": string; + "private": string; "i18nInfo": string; "manageAccessTokens": string; "accountInfo": string; @@ -1097,6 +1099,22 @@ export interface Locale { "doYouAgree": string; "beSureToReadThisAsItIsImportant": string; "iHaveReadXCarefullyAndAgree": string; + "dialog": string; + "icon": string; + "forYou": string; + "currentAnnouncements": string; + "pastAnnouncements": string; + "youHaveUnreadAnnouncements": string; + "_announcement": { + "forExistingUsers": string; + "forExistingUsersDescription": string; + "needConfirmationToRead": string; + "needConfirmationToReadDescription": string; + "end": string; + "tooManyActiveAnnouncementDescription": string; + "readConfirmTitle": string; + "readConfirmText": string; + }; "_initialAccountSetting": { "accountCreated": string; "letsStartAccountSetup": string; @@ -1845,6 +1863,10 @@ export interface Locale { "write:gallery": string; "read:gallery-likes": string; "write:gallery-likes": string; + "read:flash": string; + "write:flash": string; + "read:flash-likes": string; + "write:flash-likes": string; }; "_auth": { "shareAccessTitle": string; diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 0df1fd64bf..25c63006bc 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -21,7 +21,7 @@ noNotifications: "Nessuna notifica" instance: "Istanza" settings: "Impostazioni" notificationSettings: "Preferenze di notifica" -basicSettings: "Impostazioni generali" +basicSettings: "Impostazioni base" otherSettings: "Altre impostazioni" openInWindow: "Apri in una finestra" profile: "Profilo" @@ -65,7 +65,7 @@ showMore: "Espandi" showLess: "Comprimi" youGotNewFollower: "Ha iniziato a seguirti" receiveFollowRequest: "Hai ricevuto una richiesta di follow" -followRequestAccepted: "Richiesta di follow accettata" +followRequestAccepted: "Ha accettato la tua richiesta di follow" mention: "Menzioni" mentions: "Menzioni" directNotes: "Note dirette" @@ -156,6 +156,7 @@ addEmoji: "Aggiungi un emoji" settingGuide: "Configurazione suggerita" cacheRemoteFiles: "Memorizza i file remoti nella cache" cacheRemoteFilesDescription: "Disabilitando questa opzione, i file remoti verranno linkati direttamente senza essere memorizzati nella cache. Sarà possibile risparmiare spazio di archiviazione sul server, ma il traffico aumenterà in quanto non verranno generate anteprime." +youCanCleanRemoteFilesCache: "Puoi svuotare tutta la cache cliccando il bottone 🗑️ nella gestione file" cacheRemoteSensitiveFiles: "Memorizza nella cache i file sensibili remoti" cacheRemoteSensitiveFilesDescription: "Disattivando questa opzione, i file sensibili verranno caricati direttamente dall'istanza remota senza essere salvati dal server." flagAsBot: "Io sono un robot" @@ -273,10 +274,10 @@ noMoreHistory: "Non c'è più cronologia da visualizzare" startMessaging: "Nuovo messaggio" nUsersRead: "Letto da {n} persone" agreeTo: "Sono d'accordo con {0}" -agree: "D'accordo" +agree: "Accetto" agreeBelow: "Accetto quanto riportato sotto" basicNotesBeforeCreateAccount: "Note importanti" -termsOfService: "Informativa Privacy" +termsOfService: "Informativa ai sensi degli artt. 13 e 14 del Regolamento UE 2016/679 per la protezione dei dati personali (GDPR)" start: "Inizia!" home: "Home" remoteUserCaution: "Le informazioni potrebbero essere incomplete poiché questo profilo remoto potrebbe non essere completamente federato." @@ -526,9 +527,9 @@ serverLogs: "Log del server" deleteAll: "Cancella cronologia" showFixedPostForm: "Visualizzare la finestra di pubblicazione in cima alla timeline" showFixedPostFormInChannel: "Per i canali, mostra il modulo di pubblicazione in cima alla timeline" -newNoteRecived: "Vedi le nuove note" +newNoteRecived: "Nuove note da leggere" sounds: "Impostazioni suoni" -sound: "Impostazioni suoni" +sound: "Suono" listen: "Ascolta" none: "Nessuno" showInPage: "Visualizza in pagina" @@ -621,10 +622,10 @@ smtpHost: "Server remoto" smtpPort: "Porta" smtpUser: "Nome utente" smtpPass: "Password" -emptyToDisableSmtpAuth: "Lasciare il nome utente e la password vuoti per disabilitare la verifica SMTP" -smtpSecure: "Usare la porta SSL/TLS implicito per le connessioni SMTP" +emptyToDisableSmtpAuth: "Lasciare i campi vuoti se non c'è autenticazione SMTP" +smtpSecure: "Usare SSL/TLS implicito per le connessioni SMTP" smtpSecureInfo: "Disabilitare quando è attivo STARTTLS." -testEmail: "Testa la consegna di posta elettronica" +testEmail: "Verifica il funzionamento" wordMute: "Filtri parole" regexpError: "errore regex" regexpErrorDescription: "Si è verificato un errore nell'espressione regolare alla riga {line} della parola muta {tab}:" @@ -654,7 +655,7 @@ sample: "Esempio" abuseReports: "Segnalazioni" reportAbuse: "Segnalazioni" reportAbuseOf: "Segnala {name}" -fillAbuseReportDescription: "Si prega di spiegare il motivo della segnalazione. Se riguarda una nota precisa, si prega di collegare anche l'URL della nota." +fillAbuseReportDescription: "Per favore, spiegaci il motivo della segnalazione. Se riguarda una Nota precisa, indica anche l'indirizzo URL." abuseReported: "La segnalazione è stata inviata. Grazie." reporter: "il corrispondente" reporteeOrigin: "Origine del segnalato" @@ -680,6 +681,7 @@ createNewClip: "Crea una Clip" unclip: "Togli Nota dalla Clip" confirmToUnclipAlreadyClippedNote: "Questa nota è già inclusa in \"{name}\". Si desidera escludere la nota?" public: "Pubblica" +private: "Invisibile" i18nInfo: "Misskey è tradotto in diverse lingue da volontari. Anche tu puoi contribuire su {link}." manageAccessTokens: "Gestisci token di accesso" accountInfo: "Informazioni profilo" @@ -819,8 +821,8 @@ previewNoteText: "Anteprima del testo" customCss: "CSS personalizzato" customCssWarn: "Questa impostazione deve essere eseguita da una persona esperta. Una configurazione errata può impedire al client di utilizzare correttamente il sistema." global: "Federata" -squareAvatars: "Mostra l'immagine del profilo come quadrato" -sent: "Inviare" +squareAvatars: "Foto profilo squadrate" +sent: "Inviato" received: "Ricevuto" searchResult: "Risultati della Ricerca" hashtags: "Hashtag" @@ -829,8 +831,8 @@ useBlurEffect: "Utilizza effetto sfocatura" learnMore: "Più dettagli" misskeyUpdated: "Misskey è stato aggiornato!" whatIsNew: "Visualizza le informazioni sull'aggiornamento" -translate: "Traduzione" -translatedFrom: "Tradotto da {x}" +translate: "Traduci" +translatedFrom: "Traduzione da {x}" accountDeletionInProgress: "È in corso l'eliminazione del profilo" usernameInfo: "Un nome per identificare univocamente il tuo profilo sull'istanza. Puoi utilizzare caratteri alfanumerici maiuscoli, minuscoli e il trattino basso (_). Non potrai cambiare nome utente in seguito." aiChanMode: "Modalità Ai" @@ -854,11 +856,11 @@ manageAccounts: "Gestisci i profili" makeReactionsPublic: "Pubblicare la lista delle reazioni." makeReactionsPublicDescription: "La lista delle reazioni che avete fatto è a disposizione di tutti." classic: "Classico" -muteThread: "Silenzia la conversazione" +muteThread: "Silenzia conversazione" unmuteThread: "Riattiva la conversazione" ffVisibility: "Visibilità delle connessioni" ffVisibilityDescription: "Puoi scegliere a chi mostrare le tue relazioni con altri profili nel fediverso." -continueThread: "Altri thread." +continueThread: "Altre conversazioni" deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?" incorrectPassword: "La password è errata." voteConfirm: "Votare per「{choice}」?" @@ -1030,8 +1032,8 @@ operationForbidden: "Operazione non consentita" forceShowAds: "Mostra sempre i banner" addMemo: "Aggiungi Memo" editMemo: "Modifica Memo" -reactionsList: "Elenco delle reazioni" -renotesList: "Elenco di Rinota" +reactionsList: "Chi ha reagito?" +renotesList: "Chi ha Rinotato?" notificationDisplay: "Stile delle notifiche" leftTop: "In alto a sinistra" rightTop: "In alto a destra" @@ -1042,8 +1044,8 @@ vertical: "Verticale" horizontal: "Laterale" position: "Posizione" serverRules: "Regolamento" -pleaseConfirmBelowBeforeSignup: "Ai sensi del regolamento EU 679/2016 GDPR, autorizzo il trattamento dati personali come descritto nella informativa Privacy." -pleaseAgreeAllToContinue: "Per continuare, occorre selezionare ed essere d'accordo su tutto." +pleaseConfirmBelowBeforeSignup: "Per iscriversi, occorre essere d'accordo con le seguenti condizioni." +pleaseAgreeAllToContinue: "Occorre accettare tutte le condizioni prima di continuare." continue: "Continua" preservedUsernames: "Nomi utente riservati" preservedUsernamesDescription: "Elenca, uno per linea, i nomi utente che non possono essere registrati durante la creazione del profilo. La restrizione non si applica agli amministratori. Inoltre, i profili già registrati sono esenti." @@ -1082,7 +1084,7 @@ inviteLimitExceeded: "Hai raggiunto il numero massimo di codici invito generabil createLimitRemaining: "Inviti generabili: {limit} rimanenti" inviteLimitResetCycle: "Alle {time}, il limite verrà ripristinato a {limit}" expirationDate: "Scadenza" -noExpirationDate: "Perpetuo" +noExpirationDate: "Senza scadenza" inviteCodeUsedAt: "Codice di invito usato alle" registeredUserUsingInviteCode: "Codice di invito usato da" waitingForMailAuth: "In attesa della verifica email" @@ -1091,6 +1093,24 @@ usedAt: "Usato alle" unused: "Inutilizzato" used: "Utilizzato" expired: "Scaduto" +doYouAgree: "Accetti le condizioni?" +beSureToReadThisAsItIsImportant: "Si prega di leggere attentamente perché è importante." +iHaveReadXCarefullyAndAgree: "Dichiaro di aver letto attentamente \"{x}\" e accettarne le condizioni." +dialog: "Dialogo" +icon: "Foto del profilo" +forYou: "Per te" +currentAnnouncements: "Annunci attuali" +pastAnnouncements: "Annunci precedenti" +youHaveUnreadAnnouncements: "Ci sono Annunci non letti" +_announcement: + forExistingUsers: "Solo ai profili attuali" + forExistingUsersDescription: "L'annuncio sarà visibile solo ai profili esistenti in questo momento. Se disabilitato, sarà visibile anche ai profili che verranno creati dopo la pubblicazione di questo annuncio." + needConfirmationToRead: "Richiede la conferma di lettura" + needConfirmationToReadDescription: "Sarà visualizzata una finestra di dialogo che richiede la conferma di lettura. Inoltre, non è soggetto a conferme di lettura massicce." + end: "Archivia l'annuncio" + tooManyActiveAnnouncementDescription: "L'esperienza delle persone può peggiorare se ci sono troppi annunci attivi. Considera anche l'archiviazione degli annunci conclusi." + readConfirmTitle: "Segnare come già letto?" + readConfirmText: "Hai già letto \"{title}˝?" _initialAccountSetting: accountCreated: "Il tuo profilo è stato creato!" letsStartAccountSetup: "Per iniziare, impostiamo il tuo profilo." @@ -1444,7 +1464,7 @@ _sensitiveMediaDetection: _emailUnavailable: used: "Email già in uso" format: "Formato email non valido" - disposable: "Email non riutilizzabile" + disposable: "Indirizzo email non utilizzabile" mx: "Server email non corretto" smtp: "Il server email non risponde" _ffVisibility: @@ -1486,11 +1506,11 @@ _plugin: installWarn: "Si prega di installare soltanto estensioni che provengono da fonti affidabili." manage: "Gestisci estensioni" _preferencesBackups: - list: "I backup creati." + list: "Elenco di impostazioni salvate in precedenza" saveNew: "Nuovo salvataggio" - loadFile: "Importa file" + loadFile: "Carica da file" apply: "Applicabile a questo dispositivo" - save: "Sovrascrivi il file di salvataggio" + save: "Sovrascrivi il backup" inputName: "Inserire il nome del backup." cannotSave: "Impossibile salvare." nameAlreadyExists: "Il nome del backup \"{name}\" esiste già. Si prega di specificare un nome diverso." @@ -1983,7 +2003,7 @@ _deck: alwaysShowMainColumn: "Mostra sempre la colonna principale" columnAlign: "Allineare colonne" addColumn: "Aggiungi colonna" - configureColumn: "Impostazioni della colonna." + configureColumn: "Impostazioni colonna" swapLeft: "Sposta a sinistra" swapRight: "Sposta a destra" swapUp: "Sposta in alto" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index b2fa9c337e..2e0e64bbef 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -74,7 +74,7 @@ import: "インポート" export: "エクスポート" files: "ファイル" download: "ダウンロード" -driveFileDeleteConfirm: "ファイル「{name}」を削除しますか?このファイルを使用した全てのコンテンツからも削除されます。" +driveFileDeleteConfirm: "ファイル「{name}」を削除しますか?このファイルを使用した一部のコンテンツも削除されます。" unfollowConfirm: "{name}のフォローを解除しますか?" exportRequested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、「ドライブ」に追加されます。" importRequested: "インポートをリクエストしました。これには時間がかかる場合があります。" @@ -155,7 +155,8 @@ emojiUrl: "絵文字画像URL" addEmoji: "絵文字を追加" settingGuide: "おすすめ設定" cacheRemoteFiles: "リモートのファイルをキャッシュする" -cacheRemoteFilesDescription: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。サーバーのストレージを節約できますが、サムネイルが生成されないので通信量が増加します。" +cacheRemoteFilesDescription: "この設定を有効にすると、リモートファイルをこのサーバーのストレージにキャッシュするようになります。画像の表示が高速になりますが、サーバーのストレージを多く消費します。リモートユーザーがどれほどキャッシュを保持するかは、ロールによるドライブ容量制限によって決定されます。この制限を超えた場合、古いファイルからキャッシュが削除されリンクになります。この設定が無効の場合、リモートのファイルを最初からリンクとして保持しますが、画像のサムネイル生成やユーザーのプライバシー保護のために、default.ymlでproxyRemoteFilesをtrueにすることをお勧めします。" +youCanCleanRemoteFilesCache: "ファイル管理の🗑️ボタンで全てのキャッシュを削除できます。" cacheRemoteSensitiveFiles: "リモートのセンシティブなファイルをキャッシュする" cacheRemoteSensitiveFilesDescription: "この設定を無効にすると、リモートのセンシティブなファイルはキャッシュせず直リンクするようになります。" flagAsBot: "Botとして設定" @@ -329,7 +330,7 @@ watch: "ウォッチ" unwatch: "ウォッチ解除" accept: "許可" reject: "拒否" -normal: "正常" +normal: "通常" instanceName: "サーバー名" instanceDescription: "サーバーの紹介" maintainerName: "管理者の名前" @@ -680,6 +681,7 @@ createNewClip: "新しいクリップを作成" unclip: "クリップ解除" confirmToUnclipAlreadyClippedNote: "このノートはすでにクリップ「{name}」に含まれています。ノートをこのクリップから除外しますか?" public: "パブリック" +private: "非公開" i18nInfo: "Misskeyは有志によって様々な言語に翻訳されています。{link}で翻訳に協力できます。" manageAccessTokens: "アクセストークンの管理" accountInfo: "アカウント情報" @@ -1094,6 +1096,22 @@ expired: "期限切れ" doYouAgree: "同意しますか?" beSureToReadThisAsItIsImportant: "重要ですので必ずお読みください。" iHaveReadXCarefullyAndAgree: "「{x}」の内容をよく読み、同意します。" +dialog: "ダイアログ" +icon: "アイコン" +forYou: "あなたへ" +currentAnnouncements: "現在のお知らせ" +pastAnnouncements: "過去のお知らせ" +youHaveUnreadAnnouncements: "未読のお知らせがあります。" + +_announcement: + forExistingUsers: "既存ユーザーのみ" + forExistingUsersDescription: "有効にすると、このお知らせ作成時点で存在するユーザーにのみお知らせが表示されます。無効にすると、このお知らせ作成後にアカウントを作成したユーザーにもお知らせが表示されます。" + needConfirmationToRead: "既読にするのに確認が必要" + needConfirmationToReadDescription: "有効にすると、このお知らせを既読にする際に確認ダイアログが表示されます。また、一括既読操作の対象になりません。" + end: "お知らせを終了" + tooManyActiveAnnouncementDescription: "アクティブなお知らせが多いため、UXが低下する可能性があります。終了したお知らせはアーカイブすることを検討してください。" + readConfirmTitle: "既読にしますか?" + readConfirmText: "「{title}」の内容を読み、既読にします。" _initialAccountSetting: accountCreated: "アカウントの作成が完了しました!" @@ -1763,6 +1781,10 @@ _permissions: "write:gallery": "ギャラリーを操作する" "read:gallery-likes": "ギャラリーのいいねを見る" "write:gallery-likes": "ギャラリーのいいねを操作する" + "read:flash": "Playを見る" + "write:flash": "Playを操作する" + "read:flash-likes": "Playのいいねを見る" + "write:flash-likes": "Playのいいねを操作する" _auth: shareAccessTitle: "アプリへのアクセス許可" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index e8b02f8d5e..c9d092f5c1 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -49,11 +49,15 @@ delete: "ほかす" deleteAndEdit: "ほかして直す" deleteAndEditConfirm: "このノートをほかしてもっかい直す?このノートへのツッコミ、Renote、返信も全部消えるんやけどそれでもええん?" addToList: "リストに入れたる" +addToAntenna: "アンテナに追加" sendMessage: "メッセージを送る" copyRSS: "RSSをコピー" copyUsername: "ユーザー名をコピー" copyUserId: "ユーザーIDをコピー" copyNoteId: "ノートIDをコピー" +copyFileId: "ファイルIDをコピー" +copyFolderId: "フォルダーIDをコピー" +copyProfileUrl: "プロフィールURLをコピー" searchUser: "ユーザーを検索" reply: "返事" loadMore: "まだまだあるで!" @@ -72,7 +76,7 @@ files: "ファイル" download: "ダウンロード" driveFileDeleteConfirm: "ファイル「{name}」をほかしてええか?このファイルを添付したノートも消えてまうで。" unfollowConfirm: "{name}のフォローを解除してもええんか?" -exportRequested: "エクスポートしてな、ってリクエストしたけど、これ多分めっちゃ時間かかるで。エクスポート終わったら「ドライブ」に突っ込んどくで。" +exportRequested: "エクスポートしてな、って言うたけど、これ多分めっちゃ時間かかるで。エクスポート終わったら「ドライブ」に突っ込んどくで。" importRequested: "インポートしてな、ってリクエストしたけど、これ多分めっちゃ時間かかるで。" lists: "リスト" noLists: "リストなんてあらへんで" @@ -152,6 +156,9 @@ addEmoji: "絵文字を追加" settingGuide: "ええ感じの設定" cacheRemoteFiles: "リモートのファイルをキャッシュする" cacheRemoteFilesDescription: "この設定を切っとったら、リモートファイルをキャッシュせんと直リンクするようになるで。サーバーの容量は節約できるけど、サムネイルを作らんなるから通信量が増えるで。" +youCanCleanRemoteFilesCache: "ファイル管理にある🗑️ボタンでキャッシュ全部ほかすで。" +cacheRemoteSensitiveFiles: "リモートのセンシティブなファイルをキャッシュする" +cacheRemoteSensitiveFilesDescription: "この設定を無効にすると、リモートのセンシティブなファイルはキャッシュせず直リンクするようになるで。" flagAsBot: "Botにするで" flagAsBotDescription: "もしこのアカウントをプログラム使うて運用するんやったら、このフラグをオンにしてや。オンにすれば、反応がバーッて連鎖せんように開発者が使うたり、Misskeyのシステム上での扱いがBotに合ったもんになるからな。" flagAsCat: "Catやで" @@ -313,6 +320,7 @@ copyUrl: "URLをコピー" rename: "名前を変えるで" avatar: "アイコン" banner: "バナー" +displayOfSensitiveMedia: "センシティブなメディアの表示" whenServerDisconnected: "サーバーとの接続が失くなってしもうたとき" disconnectedFromServer: "サーバーが機嫌悪いねん" reload: "リロード" @@ -673,6 +681,7 @@ createNewClip: "新しいクリップを作るで" unclip: "クリップ解除するで" confirmToUnclipAlreadyClippedNote: "このノートはすでにクリップ「{name}」に含まれとるで。ノートをこのクリップから除外しよか?" public: "パブリック" +private: "非公開" i18nInfo: "Misskeyは有志によっていろんな言語に翻訳されとるで。{link}で翻訳に協力したってやー。" manageAccessTokens: "アクセストークンの管理" accountInfo: "アカウント情報" @@ -692,7 +701,7 @@ no: "あかん" driveFilesCount: "ドライブのファイル数" driveUsage: "ドライブ使用量やで" noCrawle: "クローラーによるインデックスを拒否するで" -noCrawleDescription: "検索エンジンにあんたのユーザーページ、ノート、Pagesとかのコンテンツを登録(インデックス)せぇへんように頼むで。" +noCrawleDescription: "検索エンジンにあんたのユーザーページ、ノート、Pagesとかのコンテンツを登録(インデックス)せんように頼むで。邪魔すんねんやったら帰って〜。" lockedAccountInfo: "フォローを承認制にしとっても、ノートの公開範囲を「フォロワー」にせぇへん限り、誰でもあんたのノートを見れるで。" alwaysMarkSensitive: "デフォルトでメディアを閲覧注意にするで" loadRawImages: "添付画像のサムネイルをオリジナル画質にするで" @@ -738,7 +747,7 @@ value: "値" createdAt: "作成した日" updatedAt: "更新日時" saveConfirm: "保存するで?" -deleteConfirm: "ホンマに削除するで?" +deleteConfirm: "ホンマにほかすで?" invalidValue: "有効な値じゃないみたいやで。" registry: "レジストリ" closeAccount: "アカウントを閉鎖する" @@ -1063,15 +1072,36 @@ later: "あとで" goToMisskey: "Misskeyへ" additionalEmojiDictionary: "絵文字の追加辞書" installed: "インストール済み" -branding: "あ" +branding: "ブランディング" enableServerMachineStats: "サーバーのマシン情報見せびらかすで" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" turnOffToImprovePerformance: "オフにしたらえらい軽うなるで。" +createInviteCode: "招待コードを作成" +createWithOptions: "オプションを指定して作成" +createCount: "作成数" inviteCodeCreated: "招待コード作ったで" inviteLimitExceeded: "招待コード作りすぎやで。" createLimitRemaining: "作成できる招待コード: 残り {limit} 個やで" +inviteLimitResetCycle: "{time}で最大 {limit} 個の招待コードを作成できるで。" +expirationDate: "有効期限" +noExpirationDate: "有効期限を設けへん" +inviteCodeUsedAt: "招待コードが使用された日時" +registeredUserUsingInviteCode: "招待コードを使用したユーザー" +waitingForMailAuth: "メール認証待ち" +inviteCodeCreator: "招待コードを作成したユーザー" +usedAt: "使用日時" unused: "つこてへん" used: "もうつこてる" +expired: "期限切れ" +doYouAgree: "同意するんか?" +beSureToReadThisAsItIsImportant: "重要やから絶対読んでや。" +iHaveReadXCarefullyAndAgree: "「{x}」の内容をよう読んで、同意するで。" +dialog: "ダイアログ" +icon: "アイコン" +forYou: "あんたへ" +youHaveUnreadAnnouncements: "あんたまだこのお知らせ読んどらんやろ。" +_announcement: + readConfirmTitle: "既読にしてええんやな?" _initialAccountSetting: accountCreated: "アカウント作り終わったで。" letsStartAccountSetup: "アカウントの初期設定をしよか。" @@ -1382,6 +1412,9 @@ _role: ltlAvailable: "ローカルタイムラインの閲覧" canPublicNote: "パブリック投稿の許可" canInvite: "サーバー招待コードの発行" + inviteLimit: "招待コードの作成可能数" + inviteLimitCycle: "招待コードの発行間隔" + inviteExpirationTime: "招待コードの有効期限" canManageCustomEmojis: "カスタム絵文字の管理" driveCapacity: "ドライブ容量" alwaysMarkNsfw: "勝手にファイルにNSFWをくっつける" @@ -1444,6 +1477,7 @@ _ad: back: "戻る" reduceFrequencyOfThisAd: "この広告の表示頻度を下げるで" hide: "表示せん" + timezoneinfo: "曜日はサーバーのタイムゾーンを元に指定されるで。" _forgotPassword: enterEmail: "アカウントに登録したメールアドレスをここに入力してや。そのアドレス宛に、パスワードリセット用のリンクが送られるから待っててな~。" ifNoEmail: "メールアドレスを登録してへんのやったら、管理者まで教えてな~。" @@ -1668,7 +1702,7 @@ _2fa: removeKeyConfirm: "{name}を消すん?" whyTOTPOnlyRenew: "セキュリティキーが登録されとったら、認証アプリの設定は解除できへんで。" renewTOTP: "認証アプリをもっかい設定" - renewTOTPConfirm: "今までの人称アプリの確認コードは使えんくなるけどええか?" + renewTOTPConfirm: "今までの認証アプリの確認コードは使えんくなるけどええか?" renewTOTPOk: "もっかい設定する" renewTOTPCancel: "やめとく" _permissions: @@ -1973,6 +2007,7 @@ _deck: introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょ!" introduction2: "画面の右にある + を押して、いつでもカラムを追加できるで。" widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選んでウィジェットを追加してなー" + useSimpleUiForNonRootPages: "非ルートページは簡易UIで表示" _columns: main: "メイン" widgets: "ウィジェット" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 42a829c125..d57d3f46fc 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -156,6 +156,7 @@ addEmoji: "이모지 추가" settingGuide: "추천 설정" cacheRemoteFiles: "리모트 파일을 캐시" cacheRemoteFilesDescription: "이 설정을 해지하면 리모트 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다." +youCanCleanRemoteFilesCache: "파일 관리 화면의 🗑️ 버튼을 눌러 모든 캐시를 삭제할 수 있습니다." cacheRemoteSensitiveFiles: "리모트의 민감한 파일을 캐시" cacheRemoteSensitiveFilesDescription: "이 설정을 비활성화하면 리모트의 민감한 파일은 캐시하지 않고 리모트에서 직접 가져오도록 합니다." flagAsBot: "나는 봇입니다" @@ -329,7 +330,7 @@ watch: "지켜보기" unwatch: "지켜보기 해제" accept: "허가" reject: "거부" -normal: "정상" +normal: "일반" instanceName: "서버 이름" instanceDescription: "서버 소개" maintainerName: "관리자 이름" @@ -680,6 +681,7 @@ createNewClip: "새 클립 만들기" unclip: "클립 해제" confirmToUnclipAlreadyClippedNote: "이 노트는 이미 \"{name}\" 클립에 포함되어 있습니다. 클립을 해제하시겠습니까?" public: "공개" +private: "비공개" i18nInfo: "Misskey는 자원봉사자들에 의해 다양한 언어로 번역되고 있습니다. {link}에서 번역에 참가할 수 있습니다." manageAccessTokens: "액세스 토큰 관리" accountInfo: "계정 정보" @@ -1091,6 +1093,24 @@ usedAt: "사용 시각" unused: "사용되지 않음" used: "사용됨" expired: "만료됨" +doYouAgree: "동의하십니까?" +beSureToReadThisAsItIsImportant: "중요하므로 반드시 읽어주십시오." +iHaveReadXCarefullyAndAgree: "\"{x}\"의 내용을 읽고 동의합니다." +dialog: "다이얼로그" +icon: "아바타" +forYou: "당신에게" +currentAnnouncements: "현재 공지사항" +pastAnnouncements: "과거 공지사항" +youHaveUnreadAnnouncements: "읽지 않은 공지사항이 있습니다." +_announcement: + forExistingUsers: "기존 유저에게만 알림" + forExistingUsersDescription: "활성화하면 이 공지사항을 게시한 시점에서 이미 가입한 유저에게만 표시합니다. 비활성화하면 게시 후에 가입한 유저에게도 표시합니다." + needConfirmationToRead: "읽음으로 표시하기 전에 확인하기" + needConfirmationToReadDescription: "활성화하면 이 공지사항을 읽음으로 표시하기 전에 확인 알림창을 띄웁니다. '모두 읽음'의 대상에서도 제외됩니다." + end: "공지에서 내리기" + tooManyActiveAnnouncementDescription: "공지사항이 너무 많을 경우, 사용자 경험에 영향을 끼칠 가능성이 있습니다. 오래된 공지사항은 아카이브하시는 것을 권장드립니다." + readConfirmTitle: "읽음으로 표시합니까?" + readConfirmText: "\"{title}\"을(를) 읽음으로 표시합니다." _initialAccountSetting: accountCreated: "계정 생성이 완료되었습니다!" letsStartAccountSetup: "계정의 초기 설정을 진행합니다." diff --git a/locales/lo-LA.yml b/locales/lo-LA.yml index 4f73b70550..10010e9ce4 100644 --- a/locales/lo-LA.yml +++ b/locales/lo-LA.yml @@ -107,7 +107,11 @@ enterEmoji: "ປ້ອນອີໂມຈິ" renote: "Renote" unrenote: "ເລີກ Renote" renoted: "ເກັບບັນທຶກໄວ້" +cantRenote: "ໂພສນີ້ບໍ່ສາມາດຖືກບັນທຶກໄວ້ຄືນໃໝ່ໄດ້" +cantReRenote: "ບໍ່ສາມາດບັນທຶກຄືນໃໝ່ໄດ້" quote: "ລວມຂໍ້ຄວາມອ້າງອີງ" +inChannelRenote: "ຊ່ອງພຽງແຕ່ Renote" +inChannelQuote: "ຊ່ອງເທົ່ານັ້ນ Quote" pinnedNote: "ບັນທຶກທີ່ປັກໝຸດໄວ້" pinned: "ປັກໝຸດໄປຫາໂປຣໄຟລ໌" you: "ເຈົ້າ" @@ -226,9 +230,12 @@ fromUrl: "ຈາກ URL" uploadFromUrl: "ອັບໂຫຼດຈາກ URL" uploadFromUrlDescription: "URL ຂອງໄຟລ໌ທີ່ທ່ານຕ້ອງການອັບໂຫລດ" uploadFromUrlRequested: "ຮ້ອງຂໍການອັບໂຫລດ" +explore: "ສຳຫຼວດ" messageRead: "ອ່ານແລ້ວ" startMessaging: "ເລີ່ມການສົນທະນາໃໝ່" nUsersRead: "ອ່ານໂດຍ {n}" +agree: "ຍອມຮັບ" +termsOfService: "ເງື່ອນໄຂການບໍລິການ" start: "ເລີ່ມຕົ້ນນຳໃຊ້ເລີຍ" home: "ໜ້າຫຼັກ" activity: "ກິດຈະກຳ" @@ -266,6 +273,7 @@ inputNewDescription: "ໃສ່ຄຳບັນຍາຍໃໝ່" inputNewFolderName: "ໃສ່ຊື່ໂຟນເດີໃໝ່" circularReferenceFolder: "ໂຟນເດີປາຍທາງແມ່ນໂຟນເດີຍ່ອຍຂອງໂຟນເດີທີ່ທ່ານຕ້ອງການຍ້າຍ" rename: "ປ່ຽນຊື່" +doNothing: "ບໍ່ສົນໃຈ" watch: "ເບິ່ງ" unwatch: "ຢຸດເບິ່ງ" accept: "ອະນຸຍາດ" @@ -294,7 +302,14 @@ enableRegistration: "ເປີດໃຊ້ການລົງທະບຽນຜ invite: "ເຊີນ" driveCapacityPerLocalAccount: "ຄວາມອາດສາມາດຂັບຕໍ່ຜູ້ໃຊ້ທ້ອງຖິ່ນ" driveCapacityPerRemoteAccount: "ໄດຣຟ໌ຄວາມອາດສາມາດຕໍ່ຜູ້ໃຊ້ທາງໄກ" +basicInfo: "ຂໍ້ມຸນເບື້ອງຕົ້ນ" pinnedNotes: "ບັນທຶກທີ່ປັກໝຸດໄວ້" +hcaptchaSiteKey: "ກະແຈໄຊທ໌" +hcaptchaSecretKey: "ກະແຈລັບ" +recaptcha: "reCAPTCHA" +enableRecaptcha: "ເປີດໃຊ້ງານລີແຄ໋ບຈາ" +recaptchaSiteKey: "ກະແຈໄຊທ໌" +recaptchaSecretKey: "ກະແຈລັບ" turnstileSiteKey: "ກະແຈໄຊທ໌" turnstileSecretKey: "ກະແຈລັບ" name: "ຊື່" @@ -302,24 +317,41 @@ userList: "ລາຍການ" about: "ກ່ຽວກັບ" aboutMisskey: "ກ່ຽວກັບ Misskey" administrator: "ຜູ້ບໍລິຫານ" +token: "ໂທເຄັນ" share: "ແບ່ງປັນ" notFound: "ບໍ່ພົບ" cacheClear: "ລຶບລ້າງແຄສ" +help: "ຊ່ວຍເຫຼືອ" +close: "ປິດ" invites: "ເຊີນ" +members: "ສະມາຊິກ" +transfer: "ໂອນຍ້າຍ" title: "ຫົວຂໍ້" text: "ຂໍ້ຄວາມ" enable: "ເປີດໃຊ້" next: "ຕໍ່ໄປ" +retype: "ເຂົ້າໄປອີກຄັ້ງ" +quoteAttached: "ວົງຢືມ" invitations: "ເຊີນ" +unavailable: "ບໍ່​ສາ​ມາດ​ໃຊ້​ໄດ້" language: "ພາສາ" +aboutX: "ກ່ຽວກັບ {x}" +emojiStyle: "ຮູບແບບອີໂມຈິ" native: "ພາ​ສາ​ແມ່" +noHistory: "​ບໍ່​ມີ​ລາຍ​ການ​ຢູ່​ບ່ອນ​ນີ້" +doing: "ກຳລັງປະມວນຜົນ..." category: "ຫມວດຫມູ່" tags: "ແທ໋ກ" createAccount: "ສ້າງບັນຊີ" existingAccount: "ທີ່ມີຢູ່" dashboard: "ໜ້າປັດ" local: "ທ້ອງຖິ່ນ" +numberOfDays: "ຈຳນວນມື້" +objectStorageBucket: "Bucket" +objectStoragePrefix: "Prefix" +objectStorageEndpoint: "Endpoint" objectStorageRegion: "ພາກ​ພື້ນ" +deleteAll: "ລຶບທັງໝົດ" sounds: "ສຽງ" sound: "ສຽງ" none: "ບໍ່ມີ" @@ -333,18 +365,40 @@ ascendingOrder: "ນ້ອຍໄປຫາໃຫຍ່" descendingOrder: "ໃຫຍ່ຫານ້ອຍ" output: "ຜົນຜະລິດ" script: "ບົດ​ຄວາມ" +menu: "ເມນູ" +rearrange: "ຈັດລຽງຄືນ" +poll: "ການພູນ" +description: "ລາຍລະອຽດ" +author: "ຜູ້ຂຽນ" +manage: "ການຈັດການ" +plugins: "ປລັ໋ກອີນ" +width: "ກວ້າງ" +height: "ຄວາມສູງ" +large: "ໃຫຍ່." +medium: "ປານກາງ" +small: "ເລັກ" +permission: "ການອະນຸຍາດ" +notificationType: "​ປະເພດການ​ແຈ້ງ​ເຕືອນ" +edit: "ແກ້ໄຂ" +email: "ອີເມວ" smtpHost: "ໂຮດສ" smtpUser: "ຊື່ຜູ້ໃຊ້" smtpPass: "ລະຫັດຜ່ານ" clearCache: "ລຶບລ້າງແຄສ" info: "ກ່ຽວກັບ" user: "ຜູ້ໃຊ້ຕ່າງໆ" +administration: "ການຈັດການ" +middle: "ປານກາງ" searchByGoogle: "ຄົ້ນຫາ" file: "ໄຟລ໌" +_role: + _priority: + middle: "ປານກາງ" _email: _follow: title: "ໄດ້ຕິດຕາມທ່ານ" _theme: + description: "ລາຍລະອຽດ" keys: mention: "ໄດ້ກ່າວມາ" renote: "Renote" @@ -383,6 +437,7 @@ _timelines: home: "ໜ້າຫຼັກ" _play: script: "ບົດ​ຄວາມ" + summary: "ລາຍລະອຽດ" _pages: blocks: image: "ຮູບພາບ" diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml index ae2881a7d4..30c7e1dca0 100644 --- a/locales/nl-NL.yml +++ b/locales/nl-NL.yml @@ -426,6 +426,7 @@ pushNotificationAlreadySubscribed: "Pushberichtrn al ingeschakeld" windowMaximize: "Maximaliseren" windowRestore: "Herstellen" loggedInAsBot: "Momenteel als bot ingelogd" +icon: "Avatar" _email: _follow: title: "volgde jou" diff --git a/locales/no-NO.yml b/locales/no-NO.yml index ec2900527b..72229ab0d9 100644 --- a/locales/no-NO.yml +++ b/locales/no-NO.yml @@ -461,6 +461,7 @@ videos: "Videoer" continue: "Fortsett" youFollowing: "Følger" options: "Alternativ" +icon: "Avatar" _initialAccountSetting: theseSettingsCanEditLater: "Du kan endre disse innstillingene senere." _achievements: diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 8b6b4be7d0..c472d42cad 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -644,6 +644,7 @@ createNewClip: "Utwórz nowy klip" unclip: "Odczep" confirmToUnclipAlreadyClippedNote: "Ten wpis jest już częścią klipu \"{name}\". Czy chcesz ją usunąć z tego klipu?" public: "Publiczny" +private: "Prywatne" i18nInfo: "Misskey jest tłumaczone na wiele języków przez wolontariuszy. Możesz pomóc na {link}." manageAccessTokens: "Zarządzaj tokenami dostępu" accountInfo: "Informacje o koncie" @@ -870,6 +871,7 @@ like: "Polub" show: "Wyświetlanie" color: "Kolor" youFollowing: "Śledzeni" +icon: "Awatar" _role: priority: "Priorytet" _priority: @@ -1089,6 +1091,8 @@ _2fa: step3: "Wprowadź token podany w aplikacji, aby ukończyć konfigurację." step4: "Od teraz, przy każdej próbie logowania otrzymasz prośbę o token logowania." removeKeyConfirm: "Usunąć kopię zapasową {name}?" + renewTOTPConfirm: "Spowoduje to, że kody weryfikacyjne z poprzedniej aplikacji przestaną działać" + renewTOTPOk: "Rekonfiguruj" renewTOTPCancel: "Nie teraz" _permissions: "read:account": "Wyświetl informacje o swoim koncie" @@ -1102,8 +1106,10 @@ _permissions: "read:following": "Wyświetlanie informacji o obserwowanych" "write:following": "Obserwowanie lub cofanie obserwacji innych kont" "read:messaging": "Zobacz swoje czaty" + "write:messaging": "Tworzenie lub usuwanie wiadomości czatu" "read:mutes": "Wyświetlanie listy osób, które wyciszyłeś(-aś)" "write:mutes": "Edycja listy osób, które wyciszyłeś(-aś)" + "write:notes": "Tworzenie lub usuwanie wpisów" "read:notifications": "Wyświetlanie powiadomień" "write:notifications": "Działanie na powiadomieniach" "read:reactions": "Wyświetlanie reakcji" @@ -1119,9 +1125,23 @@ _permissions: "write:channels": "Edytuj swoje kanały" "read:gallery": "Zobacz swoją galerię" "write:gallery": "Edytuj swoją galerię" + "read:gallery-likes": "Wyświetlanie listy polubionych postów w galerii" + "write:gallery-likes": "Edytowanie listy polubionych postów w galerii" _auth: + shareAccessTitle: "Przyznawanie uprawnień aplikacji" shareAccess: "Czy chcesz autoryzować „{name}” do dostępu do tego konta?" + shareAccessAsk: "Czy na pewno chcesz zezwolić tej aplikacji na dostęp do Twojego konta?" + permission: "{name} żąda następujących uprawnień" permissionAsk: "Ta aplikacja wymaga następujących uprawnień:" + pleaseGoBack: "Proszę, wróć do aplikacji" + callback: "Powracanie do aplikacji" + denied: "Odmowa dostępu" + pleaseLogin: "Zaloguj się, aby autoryzować aplikacje." +_antennaSources: + all: "Wszystkie wpisy" + homeTimeline: "Wpisy obserwowanych użytkowników" + users: "Wpisy określonych użytkowników" + userList: "Wpisy z określonej listy użytkowników" _weekday: sunday: "Niedziela" monday: "Poniedziałek" @@ -1154,8 +1174,10 @@ _widgets: serverMetric: "Metryka serwera" aiscript: "Konsola AiScript" aichan: "Ai" + userList: "Lista użytkowników" _userList: chooseList: "Wybierz listę" + clicker: "Clicker" _cw: hide: "Ukryj" show: "Załaduj więcej" @@ -1187,10 +1209,16 @@ _visibility: public: "Publiczny" publicDescription: "Twój wpis pojawi się w publicznych osiach czasu" home: "Strona główna" + homeDescription: "Publikuj tylko na głównej osi czasu" followers: "Obserwujący" + followersDescription: "Widoczne tylko dla obserwujących" specified: "Bezpośredni" specifiedDescription: "Napisz tylko określonym użytkownikom" + disableFederationDescription: "Nie przesyłaj do innych instancji" _postForm: + replyPlaceholder: "Odpowiedz na ten wpis..." + quotePlaceholder: "Zacytuj ten wpis…" + channelPlaceholder: "Publikuj na kanale..." _placeholders: a: "Co się dzieje?" b: "Co się wydarzyło?" @@ -1212,17 +1240,29 @@ _profile: changeBanner: "Zmień baner" _exportOrImport: allNotes: "Wszystkie wpisy" + favoritedNotes: "Ulubione wpisy" followingList: "Obserwowani" muteList: "Wycisz" blockingList: "Zablokuj" userLists: "Listy" + excludeMutingUsers: "Wyklucz wyciszonych użytkowników" + excludeInactiveUsers: "Wyklucz nieaktywnych użytkowników" _charts: federation: "Federacja" apRequest: "Żądania" + usersIncDec: "Różnica w liczbie użytkowników" usersTotal: "Łącznie # użytkowników" activeUsers: "Aktywni użytkownicy" + notesIncDec: "Różnica w liczbie wpisów" + notesTotal: "Całkowita liczba wpisów" + filesIncDec: "Różnica w liczbie plików" + filesTotal: "Całkowita liczba plików" + storageUsageIncDec: "Różnica w wykorzystaniu pamięci" + storageUsageTotal: "Całkowite wykorzystanie pamięci" _instanceCharts: requests: "Żądania" + users: "Różnica w liczbie użytkowników" + notes: "Różnica w liczbie wpisów" notesTotal: "Łącznie # wpisów" ff: "Różnica w # obserwujących" ffTotal: "Łączna liczba # obserwujących" @@ -1347,5 +1387,16 @@ _deck: mentions: "Wspomnienia" direct: "Bezpośredni" _webhookSettings: + createWebhook: "Stwórz Webhook" name: "Nazwa" + secret: "Sekret" + events: "Uruchomienie Webhooka" active: "Właczono" + _events: + follow: "Po zaobserwowaniu użytkownika" + followed: "Po zostaniu zaobserwowanym" + note: "Po opublikowaniu wpisu" + reply: "Po otrzymaniu odpowiedzi" + renote: "Po udostępnieniu wpisu" + reaction: "Po otrzymaniu reakcji" + mention: "Po zostaniu wspomnianym" diff --git a/locales/pt-PT.yml b/locales/pt-PT.yml index 29d7de19c2..f67476f113 100644 --- a/locales/pt-PT.yml +++ b/locales/pt-PT.yml @@ -1,9 +1,10 @@ --- _lang_: "Português" headlineMisskey: "Uma rede ligada por notas" -introMisskey: "Bem-vindo! Misskey é um serviço de microblogue descentralizado de código aberto.\nCria \"notas\" e partilha o que te ocorre com todos à tua volta. 📡\nCom \"reações\" podes também expressar logo o que sentes às notas de todos. 👍\nExploremos um novo mundo! 🚀" +introMisskey: "Bem-vindo! O Misskey é um serviço de microblog descentralizado de código aberto.\nCrie \"notas\" para compartilhar o que está acontecendo agora ou para se expressar com todos à sua volta 📡\nVocê também pode adicionar rapidamente reações às notas de outras pessoas usando a função \"Reações\" 👍\nVamos explorar um novo mundo 🚀" +poweredByMisskeyDescription: "{name} é um dos servidores da plataforma de código aberto Misskey." monthAndDay: "{day}/{month}" -search: "Buscar" +search: "Pesquisar" notifications: "Notificações" username: "Nome de usuário" password: "Senha" @@ -12,122 +13,138 @@ fetchingAsApObject: "Buscando no Fediverso" ok: "OK" gotIt: "Entendi" cancel: "Cancelar" +noThankYou: "Não, obrigado" enterUsername: "Digite o nome de usuário" renotedBy: "Repostado por {user}" -noNotes: "Sem posts" +noNotes: "Sem notas" noNotifications: "Sem notificações" instance: "Instância" settings: "Configurações" +notificationSettings: "Configurações de notificação" basicSettings: "Configurações básicas" otherSettings: "Outras configurações" -openInWindow: "Abrir numa janela" +openInWindow: "Abrir em um janela" profile: "Perfil" -timeline: "Timeline" +timeline: "Linha do tempo" noAccountDescription: "Este usuário não tem uma descrição." login: "Iniciar sessão" loggingIn: "Iniciando sessão…" logout: "Sair" signup: "Registrar-se" uploading: "Enviando…" -save: "Guardar" +save: "Salvar" users: "Usuários" addUser: "Adicionar usuário" -favorite: "Favoritar" -favorites: "Favoritar" +favorite: "Adicionar aos favoritos" +favorites: "Favoritos" unfavorite: "Remover dos favoritos" favorited: "Adicionado aos favoritos." alreadyFavorited: "Já adicionado aos favoritos." cantFavorite: "Não foi possível adicionar aos favoritos." -pin: "Afixar no perfil" +pin: "Fixar no perfil" unpin: "Desafixar do perfil" copyContent: "Copiar conteúdos" -copyLink: "Copiar hiperligação" -delete: "Eliminar" -deleteAndEdit: "Eliminar e editar" -deleteAndEditConfirm: "Tens a certeza que pretendes eliminar esta nota e editá-la? Irás perder todas as suas reações, renotas e respostas." +copyLink: "Copiar link" +delete: "Excluir" +deleteAndEdit: "Excluir e editar" +deleteAndEditConfirm: "Deseja excluir esta nota e editá-la novamente? Todas as reações, compartilhamentos e respostas a esta nota também serão excluídas." addToList: "Adicionar a lista" -sendMessage: "Enviar uma mensagem" +addToAntenna: "Adicionar à antena" +sendMessage: "Enviar mensagem" +copyRSS: "Copiar RSS" copyUsername: "Copiar nome de utilizador" -searchUser: "Pesquisar utilizador" +copyUserId: "Copiar ID do utilizador" +copyNoteId: "Copiar ID da publicação" +copyFileId: "Copiar o ID do arquivo" +copyFolderId: "Copiar o ID da pasta" +copyProfileUrl: "Copiar a URL do perfil" +searchUser: "Pesquisar usuário" reply: "Responder" loadMore: "Carregar mais" showMore: "Ver mais" showLess: "Fechar" youGotNewFollower: "Você tem um novo seguidor" -receiveFollowRequest: "Pedido de seguimento recebido" -followRequestAccepted: "Pedido de seguir aceito" +receiveFollowRequest: "Pedido de seguidor recebido" +followRequestAccepted: "Pedido de seguidor aceito" mention: "Menção" mentions: "Menções" directNotes: "Notas diretas" importAndExport: "Importar/Exportar" import: "Importar" export: "Exportar" -files: "Ficheiros" +files: "Arquivos" download: "Descarregar" -driveFileDeleteConfirm: "Tens a certeza que pretendes apagar o ficheiro \"{name}\"? As notas que tenham este ficheiro anexado serão também apagadas." -unfollowConfirm: "Tens a certeza que queres deixar de seguir {name}?" -exportRequested: "Pediste uma exportação. Este processo pode demorar algum tempo. Será adicionado à tua Drive após a conclusão do processo." -importRequested: "Pediste uma importação. Este processo pode demorar algum tempo." +driveFileDeleteConfirm: "Deseja excluir o arquivo '{name}'? Qualquer conteúdo que use este arquivo também será removido." +unfollowConfirm: "Gostaria de deixar de seguir {name}?" +exportRequested: "A sua solicitação de exportação foi enviada. Isso pode levar algum tempo. Assim que a exportação estiver concluída, ela será adicionada ao seu drive." +importRequested: "A sua solicitação de importação foi enviada. Isso pode levar algum tempo." lists: "Listas" -noLists: "Não tens nenhuma lista" +noLists: "Não possui nenhuma lista" note: "Post" notes: "Posts" following: "Seguindo" followers: "Seguidores" -followsYou: "Segue-te" +followsYou: "Te seguem" createList: "Criar lista" -manageLists: "Gerir listas" +manageLists: "Gerenciar listas" error: "Erro" somethingHappened: "Ocorreu um erro" -retry: "Tentar novamente" +retry: "Tente novamente" pageLoadError: "Ocorreu um erro ao carregar a página." -pageLoadErrorDescription: "Isto é normalmente causado por erros de rede ou pela cache do browser. Experimenta limpar a cache e tenta novamente após algum tempo." -serverIsDead: "O servidor não está respondendo. Por favor espere um pouco e tente novamente." -youShouldUpgradeClient: "Para visualizar essa página, por favor recarregue-a para atualizar seu cliente." +pageLoadErrorDescription: "Isso geralmente acontece devido ao cache do navegador ou da rede. Tente limpar o cache ou aguarde um pouco antes de tentar novamente." +serverIsDead: "Não há resposta do servidor. Aguarde um momento e tente novamente." +youShouldUpgradeClient: "Para visualizar esta página, recarregue-a e utilize a nova versão do cliente." enterListName: "Insira um nome para a lista" privacy: "Privacidade" -makeFollowManuallyApprove: "Pedidos de seguimento precisam ser aprovados" +makeFollowManuallyApprove: "Pedidos de seguidores precisam ser aprovados" defaultNoteVisibility: "Visibilidade padrão" follow: "Seguindo" -followRequest: "Mandar pedido de seguimento" -followRequests: "Pedidos de seguimento" +followRequest: "Enviar pedido de seguidor" +followRequests: "Pedidos de seguidor" unfollow: "Deixar de seguir" -followRequestPending: "Pedido de seguimento pendente" +followRequestPending: "Pedido de seguidor pendente" enterEmoji: "Inserir emoji" renote: "Repostar" -unrenote: "Desmarcar" +unrenote: "Remover repostagem" renoted: "Repostado" -cantRenote: "Não pode repostar" +cantRenote: "Não é possível repostar esta postagem" cantReRenote: "Não pode repostar este repost" quote: "Citar" -pinnedNote: "Post fixado" -pinned: "Afixar no perfil" +inChannelRenote: "Repostar no canal" +inChannelQuote: "Citar no canal" +pinnedNote: "Nota fixada" +pinned: "Fixar no perfil" you: "Você" clickToShow: "Clique para ver" sensitive: "Conteúdo sensível" add: "Adicionar" reaction: "Reações" reactions: "Reações" -reactionSetting: "Quais reações a mostrar no selecionador de reações" +reactionSetting: "Quais reações exibir no seletor de reações" reactionSettingDescription2: "Arraste para reordenar, clique para excluir, pressione + para adicionar." rememberNoteVisibility: "Lembrar das configurações de visibilidade de notas" attachCancel: "Remover anexo" markAsSensitive: "Marcar como sensível" unmarkAsSensitive: "Desmarcar como sensível" -enterFileName: "Digite o nome do ficheiro" -mute: "Silenciar" -unmute: "Dessilenciar" +enterFileName: "Digite o nome do arquivo" +mute: "Mutar" +unmute: "Desmutar" +renoteMute: "Mutar repostagens" +renoteUnmute: "Reativar repostagens" block: "Bloquear" unblock: "Desbloquear" suspend: "Suspender" unsuspend: "Cancelar suspensão" -blockConfirm: "Tem certeza que gostaria de bloquear essa conta?" -unblockConfirm: "Tem certeza que gostaria de desbloquear essa conta?" -suspendConfirm: "Tem certeza que gostaria de suspender essa conta?" -unsuspendConfirm: "Tem certeza que gostaria de cancelar a suspensão dessa conta?" -selectList: "Escolhe uma lista" -selectAntenna: "Escolhe uma antena" -selectWidget: "Escolhe um widget" +blockConfirm: "Tem certeza que gostaria de bloquear esta conta?" +unblockConfirm: "Tem certeza que gostaria de desbloquear esta conta?" +suspendConfirm: "Tem certeza que gostaria de suspender esta conta?" +unsuspendConfirm: "Tem certeza que gostaria de cancelar a suspensão desta conta?" +selectList: "Selecione uma lista" +editList: "Editar lista" +selectChannel: "Selecionar canal" +selectAntenna: "Selecione uma antena" +editAntenna: "Editar antena" +selectWidget: "Selecione um widget" editWidgets: "Editar widgets" editWidgetsExit: "Pronto" customEmojis: "Emoji personalizado" @@ -137,17 +154,21 @@ emojiName: "Nome do Emoji" emojiUrl: "URL do Emoji" addEmoji: "Adicionar um Emoji" settingGuide: "Guia de configuração" -cacheRemoteFiles: "Memória transitória de arquivos remotos" -cacheRemoteFilesDescription: "Se você desabilitar essa configuração, os arquivos remotos não serão armazenados em memória transitória e serão vinculados diretamente. Economiza o armazenamento do servidor, mas não gera miniaturas, o que aumenta o tráfego." +cacheRemoteFiles: "Cache de arquivos remotos" +cacheRemoteFilesDescription: "Ao desativar esta configuração, os arquivos remotos não serão mais armazenados em cache e serão vinculados diretamente. Isso economizará espaço de armazenamento no servidor, mas os thumbnails não serão gerados, o que pode aumentar o tráfego de dados." +youCanCleanRemoteFilesCache: "Pode excluir todos os caches com o botão 🗑️ de gestão de arquivos." +cacheRemoteSensitiveFiles: "Fazer cache de arquivos remotos sensíveis" +cacheRemoteSensitiveFilesDescription: "Desativar essa configuração faz com que arquivos remotos sensíveis sejam vinculados diretamente em vez de armazenados em cache." flagAsBot: "Marcar conta como robô" -flagAsBotDescription: "Se esta conta for operada por um programa, ative este sinalizador. Quando ativado, serve como um sinalizador para evitar o encadeamento de reações para outros programadores, e o manuseio do sistema do Misskey é adequado para ‘bots’." +flagAsBotDescription: "Se esta conta for operada por uma aplicação, ative esta opção. Ao ativá-la, ela servirá como um sinalizador para evitar reações em cadeia e ajudar outros desenvolvedores. Além disso, ajustará o tratamento da conta no sistema do Misskey para que se adeque a um Bot." flagAsCat: "Marcar conta como gato" -flagAsCatDescription: "Ative essa opção para marcar essa conta como gato." +flagAsCatDescription: "Ative esta opção para marcar essa conta como gato" flagShowTimelineReplies: "Mostrar respostas na linha de tempo" flagShowTimelineRepliesDescription: "Quando ativado, a linha do tempo mostra as respostas às outras notas do utilizador, além da nota do utilizador." autoAcceptFollowed: "Aprove automaticamente os seguidores dos seguintes utilizadores" addAccount: "Adicionar Conta" -loginFailed: "Não consegui logar" +reloadAccountsList: "Recarregar lista de contas" +loginFailed: "Falha ao logar" showOnRemote: "Exibir remotamente" general: "Geral" wallpaper: "Papel de parede" @@ -157,111 +178,116 @@ searchWith: "Buscar: {q}" youHaveNoLists: "Não tem nenhuma lista" followConfirm: "Tem certeza que quer deixar de seguir {name}?" proxyAccount: "Conta proxy" -proxyAccountDescription: "Uma conta proxy é uma conta que atua como seguidora remota para utilizadores sob determinadas condições. Por exemplo, quando um utilizador lista um utilizador remoto, a atividade não será entregue à instância, a menos que alguém esteja seguindo o utilizador listado, portanto, a conta proxy deve seguir." -host: "hospedeiro" -selectUser: "Selecionar utilizador" -recipient: "Morada" +proxyAccountDescription: "Uma conta de proxy é uma conta que assume o acompanhamento remoto de um usuário sob certas condições específicas. Por exemplo, quando um usuário inclui um usuário remoto em uma lista, mas ninguém na lista está seguindo o usuário remoto, a atividade não é entregue ao servidor. Nesse caso, a conta de proxy entra em ação para seguir o usuário remoto em vez disso." +host: "Host" +selectUser: "Selecionar usuário" +recipient: "Destinatário" annotation: "Anotação" -federation: "União" -instances: "Instância" +federation: "Federação" +instances: "Instâncias" registeredAt: "Registrado em" -latestRequestReceivedAt: "Recebeu a última solicitação" +latestRequestReceivedAt: "Última solicitação recebida" latestStatus: "Status mais recente" storageUsage: "Uso de armazenamento" -charts: "gráfico" -perHour: "por hora" -perDay: "por dia" +charts: "Gráfico" +perHour: "Por Hora" +perDay: "Por dia" stopActivityDelivery: "Parar a entrega de atividades" blockThisInstance: "Bloquear esta instância" -operations: "operar" -software: "Programas" -version: "versão" +operations: "Operações" +software: "Software" +version: "Versão" metadata: "Metadados" -withNFiles: "{n} Um arquivo" +withNFiles: "{n} arquivo(s)" monitor: "monitor" -jobQueue: "Fila de trabalhos" +jobQueue: "Fila de tarefas" cpuAndMemory: "CPU e memória" -network: "rede" -disk: "disco" +network: "Rede" +disk: "Disco" instanceInfo: "Informações da instância" -statistics: "Estatisticas" +statistics: "Estatísticas" clearQueue: "Limpar a fila" -clearQueueConfirmTitle: "Quer limpar a fila?" -clearQueueConfirmText: "Postagens não entregues não serão mais entregues. Normalmente você não precisa fazer isso." -clearCachedFiles: "Limpar memória transitória" -clearCachedFilesConfirm: "Tem certeza de que deseja excluir todos os arquivos remotos armazenados em memória transitória?" +clearQueueConfirmTitle: "Deseja limpar a fila?" +clearQueueConfirmText: "As postagens não entregues deixarão de ser enviadas. Geralmente, não é necessário realizar essa operação." +clearCachedFiles: "Limpar o cache" +clearCachedFilesConfirm: "Deseja excluir todos os arquivos remotos em cache?" blockedInstances: "Instância bloqueada" -blockedInstancesDescription: "Defina os anfitriões das instâncias que deseja bloquear, separados por quebras de linha. Uma instância bloqueada não poderá interagir com esta instância." +blockedInstancesDescription: "Configure os hosts dos servidores que deseja bloquear, separando-os por quebras de linha. Os servidores bloqueados não poderão interagir com este servidor, incluindo os subdomínios." muteAndBlock: "Silenciar e bloquear" -mutedUsers: "Silenciar utilizador" -blockedUsers: "Utilizadores bloqueados" +mutedUsers: "Usuários silenciados" +blockedUsers: "Usuários bloqueados" noUsers: "Sem usuários" editProfile: "Editar Perfil" noteDeleteConfirm: "Deseja excluir esta nota?" -pinLimitExceeded: "Não consigo mais fixar" +pinLimitExceeded: "Não é possível fixar novas notas" intro: "A instalação do Misskey está completa! Crie uma conta de administrador." done: "Concluído" processing: "Em Progresso" preview: "Pré-visualizar" -default: "Padrão" +default: "Predefinição" +defaultValueIs: "Predefinição: {value}" noCustomEmojis: "Não há emojis" -noJobs: "Sem trabalho" -federating: "federar" +noJobs: "Não há tarefas" +federating: "Federando" blocked: "Bloqueado" -suspended: "Cancelar subscrição" +suspended: "Suspenso" all: "Todos" -subscribing: "Subscrito" -publishing: "Executando" +subscribing: "Inscrito" +publishing: "Publicando" notResponding: "Sem resposta" instanceFollowing: "Seguir a instância" instanceFollowers: "Seguidores da instância" -instanceUsers: "Utilizador da instância" +instanceUsers: "Usuários da instância" changePassword: "Mudar senha" security: "Segurança" -retypedNotMatch: "As entradas não coincidem." -currentPassword: "Palavra-passe atual" -newPassword: "Nova palavra-passe" -newPasswordRetype: "Nova senha (redigite)" +retypedNotMatch: "As informações inseridas não coincidem." +currentPassword: "Senha atual" +newPassword: "Nova senha" +newPasswordRetype: "Nova senha (digite novamente)" attachFile: "Anexar arquivo" more: "Mais!" featured: "Destaques" -usernameOrUserId: "Nome de utilizador ou ID de utilizador" -noSuchUser: "Utilizador não encontrado" +usernameOrUserId: "Nome de usuário ou ID do usuário" +noSuchUser: "Usuário não encontrado" lookup: "Buscando" -announcements: "Notícia" +announcements: "Avisos" imageUrl: "URL da imagem" -remove: "Eliminar" -removed: "Foi deletado" +remove: "Remover" +removed: "Removido" removeAreYouSure: "Deseja excluir \"{x}\"?" deleteAreYouSure: "Deseja excluir \"{x}\"?" -resetAreYouSure: "Redefinir agora?" +resetAreYouSure: "Deseja reiniciar?" saved: "Salvo" messaging: "Chat" -upload: "Enviando" +upload: "Fazer upload" keepOriginalUploading: "Manter a imagem original" -keepOriginalUploadingDescription: "Mantenha a versão original ao carregar a imagem. Quando desligado, a imagem para publicação na web será gerada no navegador no momento do upload." -fromDrive: "\nDa unidade" +keepOriginalUploadingDescription: "Ao fazer o upload de uma imagem, ela será mantida em sua versão original. Caso desative esta opção, o navegador irá gerar uma versão da imagem otimizada para publicação na web durante o upload." +fromDrive: "Do drive" fromUrl: "Da URL" -uploadFromUrl: "Carregamento de URL" +uploadFromUrl: "Enviar por URL" uploadFromUrlDescription: "URL do arquivo que você deseja enviar" uploadFromUrlRequested: "Upload solicitado" uploadFromUrlMayTakeTime: "Pode levar algum tempo para que o upload seja concluído." explore: "Explorar" messageRead: "Lida" -noMoreHistory: "Sem mais história" +noMoreHistory: "Não existe histórico anterior" startMessaging: "Iniciar conversação" nUsersRead: "{n} Pessoas leem" agreeTo: "Eu concordo com {0}" +agree: "Concordar" +agreeBelow: "Eu concordo com o seguinte" +basicNotesBeforeCreateAccount: "Observações importantes" +termsOfService: "Termos de Uso" start: "começar" -home: "casa" +home: "Início" remoteUserCaution: "As informações estão incompletas porque é um utilizador remoto." activity: "atividade" images: "imagem" image: "imagem" -birthday: "aniversário" +birthday: "Aniversário" yearsOld: "{age} anos" registeredDate: "Data de registro" -location: "Lugar, colocar" +location: "Localização" theme: "tema" themeForLightMode: "Temas usados ​​no modo de luz" themeForDarkMode: "Temas usados ​​no modo escuro" @@ -270,7 +296,7 @@ dark: "Escuro" lightThemes: "Tema claro" darkThemes: "Tema escuro" syncDeviceDarkMode: "Sincronize com o modo escuro do dispositivo" -drive: "Unidades" +drive: "Drive" fileName: "Nome do Ficheiro" selectFile: "Selecione os arquivos" selectFiles: "Selecione os arquivos" @@ -280,11 +306,11 @@ renameFile: "Renomear ficheiro" folderName: "Nome da pasta" createFolder: "Criar pasta" renameFolder: "Renomear Pasta" -deleteFolder: "Eliminar Pasta" +deleteFolder: "Excluir pasta" addFile: "Adicionar arquivo" -emptyDrive: "A unidade está vazia" +emptyDrive: "O drive está vazio" emptyFolder: "A pasta está vazia" -unableToDelete: "Não é possível eliminar" +unableToDelete: "Não é possível excluir" inputNewFileName: "Por favor, digite um novo nome para a pasta!" inputNewDescription: "Insira uma nova legenda" inputNewFolderName: "Por favor, digite um novo nome para a pasta!" @@ -294,6 +320,7 @@ copyUrl: "Copiar URL" rename: "Renomear" avatar: "Avatar" banner: "Capa" +displayOfSensitiveMedia: "Exibição de mídia sensível" whenServerDisconnected: "Quando a conexão com o servidor é perdida" disconnectedFromServer: "Desconectado do servidor" reload: "Recarregar" @@ -325,8 +352,8 @@ disablingTimelinesInfo: "Se você desabilitar essas linhas do tempo, administrad registration: "Registar" enableRegistration: "Permitir que qualquer pessoa se registre" invite: "Convidar" -driveCapacityPerLocalAccount: "Capacidade da unidade por utilizador local" -driveCapacityPerRemoteAccount: "Capacidade da unidade por utilizador remoto" +driveCapacityPerLocalAccount: "Capacidade do drive por usuário local" +driveCapacityPerRemoteAccount: "Capacidade do drive por usuário remoto" inMb: "Em ‘megabytes’" iconUrl: "URL da imagem do ícone (favicon, etc.)" bannerUrl: "URL da imagem do ‘banner’" @@ -346,6 +373,8 @@ recaptcha: "reCAPTCHA" enableRecaptcha: "Habilitar reCAPTCHA" recaptchaSiteKey: "Chave do sítio ‘web’" recaptchaSecretKey: "Chave secreta" +turnstile: "Controle de acesso" +enableTurnstile: "Ativar controle de acesso" turnstileSiteKey: "Chave do sítio ‘web’" turnstileSecretKey: "Chave secreta" avoidMultiCaptchaConfirm: "O uso de vários captchas pode causar interferência. Deseja desativar outros captchas? Você também pode cancelar e deixar vários captchas ativados." @@ -381,19 +410,26 @@ about: "Informações" aboutMisskey: "Sobre Misskey" administrator: "Administrador" token: "Símbolo" +2fa: "Autenticação de dois fatores" +totp: "Aplicativo Autenticador" +totpDescription: "Digite a senha de uso único informado pelo aplicativo autenticador" moderator: "Moderador" +moderation: "Moderação" nUsersMentioned: "Postado por {n} pessoas" +securityKeyAndPasskey: "Chave de segurança / Chave de acesso" securityKey: "Chave de segurança" lastUsed: "Último uso" +lastUsedAt: "Última utilização: {t}" unregister: "Cancelar registro" passwordLessLogin: "Entrar sem senha" +passwordLessLoginDescription: "Faça login apenas com uma chave de segurança / chave de acesso sem utilização de senha" resetPassword: "Redefinir senha" newPasswordIs: "A nova senha é \"{password}\"" reduceUiAnimation: "Reduzir a animação da ‘interface’ do utilizador" share: "Compartilhar" notFound: "Não encontrado" notFoundDescription: "Não havia página correspondente ao URL especificado." -uploadFolder: "Destino de ‘upload’ padrão" +uploadFolder: "Destino de upload padrão" cacheClear: "Excluir memória transitória" markAsReadAllNotifications: "Marcar todas as notificações como lidas" markAsReadAllUnreadNotes: "Marcar todas as postagens como lidas" @@ -402,15 +438,59 @@ help: "Ajuda" inputMessageHere: "Escrever mensagem aqui" close: "Fechar" invites: "Convidar" +members: "Membros" +transfer: "Transferência" +title: "Título" +text: "Texto" +enable: "Habilitar" +next: "Seguinte" +retype: "Digite novamente" +noteOf: "Publicação de {user}" +quoteAttached: "Com citação" +quoteQuestion: "Anexar como citação?" +noMessagesYet: "Sem conversas até o momento" +newMessageExists: "Há uma nova mensagem" +onlyOneFileCanBeAttached: "Apenas um arquivo pode ser anexado a uma mensagem" +signinRequired: "É necessário se inscrever ou fazer login antes de continuar" invitations: "Convidar" +invitationCode: "Código de convite" +checking: "Verificando..." +available: "Disponível" +unavailable: "Não disponível" +usernameInvalidFormat: "Pode utilizar letras maiúsculas e minúsculas, números e sublinhado (_)" +tooShort: "Muito curto" +tooLong: "Muito longo" +weakPassword: "Senha fraca" +normalPassword: "Senha normal" +strongPassword: "Senha forte" +passwordMatched: "As senhas coincidem" +passwordNotMatched: "As senhas não coincidem" +signinWith: "Faça login com {x}" +signinFailed: "Não foi possível fazer login. Por favor, verifique o nome de usuário e a senha." +or: "Ou" +language: "Idioma" +uiLanguage: "Idioma de exibição da interface " +aboutX: "Sobre {x}" +emojiStyle: "Estilo de emojis" +native: "Nativo" +disableDrawer: "Não mostrar o menu em formato de gaveta" +showNoteActionsOnlyHover: "Exibir as ações da nota somente ao passar o cursor sobre ela" +noHistory: "Ainda não há histórico" +signinHistory: "Histórico de acesso" +enableAdvancedMfm: "Habilitar MFM avançado" +enableAnimatedMfm: "Habilitar MFM animado" +doing: "Processando..." +category: "Categoria" tags: "Etiquetas" docSource: "Fonte deste documento" createAccount: "Criar conta" existingAccount: "Contas existentes" regenerate: "Gerar novamente" fontSize: "Tamanho do texto" -noFollowRequests: "Não há aplicação de acompanhamento" -openImageInNewTab: "Abrir a imagem numa nova aba" +mediaListWithOneImageAppearance: "Altura da lista de mídias com apenas uma imagem" +limitTo: "Até {x}" +noFollowRequests: "Não há pedidos de seguidor pendentes" +openImageInNewTab: "Abrir a imagem em uma nova aba" dashboard: "Painel de controle" local: "Local" remote: "Remoto" @@ -433,8 +513,8 @@ objectStorageBucket: "Bucket" objectStorageBucketDesc: "Especifique o nome do bucket do serviço a ser usado." objectStoragePrefix: "Prefixo" objectStoragePrefixDesc: "Ele é armazenado neste diretório de prefixo." -objectStorageEndpoint: "Ponto final" -objectStorageEndpointDesc: "Especifique vazio para S3, caso contrário, especifique o ponto final para cada serviço. Especifique como''ou': '." +objectStorageEndpoint: "Endpoint" +objectStorageEndpointDesc: "No caso do S3, deixe em branco; para outros serviços, especifique o endpoint de cada serviço. Informe-o no formato '' ou ':'." objectStorageRegion: "Região" objectStorageRegionDesc: "Especifique uma região como 'xx-east-1'. Caso seu serviço não tenha o conceito de região, ele deve estar vazio ou 'us-east-1'." objectStorageUseSSL: "Usar SSL" @@ -442,9 +522,11 @@ objectStorageUseSSLDesc: "Desative-o se não quiser usar https para conexões de objectStorageUseProxy: "Usar proxy" objectStorageUseProxyDesc: "Se você não usa proxy para conexão de API, desative-o." objectStorageSetPublicRead: "Definir 'public-read' ao fazer o upload" +s3ForcePathStyleDesc: "Ao habilitar s3ForcePathStyle, o nome do bucket é especificado como parte do caminho em vez de ser o nome do host na URL. Isso pode ser necessário ao usar serviços auto-hospedados como o Minio." serverLogs: "Registro do servidor" -deleteAll: "Apagar Tudo" +deleteAll: "Excluir tudo" showFixedPostForm: "Exibir o formulário de postagem na parte superior da linha do tempo" +showFixedPostFormInChannel: "Exibir o campo de postagem na parte superior da linha do tempo (canais)" newNoteRecived: "Nova nota recebida" sounds: "Sons" sound: "Sons" @@ -455,45 +537,828 @@ popout: "Sair" volume: "Volume" masterVolume: "volume principal" details: "Detalhes" +chooseEmoji: "Selecione um emoji" +unableToProcess: "Não é possível concluir a operação" +recentUsed: "Usado recentemente" +install: "Instalar" +uninstall: "Desinstalar" +installedApps: "Aplicativos instalados" +nothing: "Não há nada aqui" +installedDate: "Data de instalação" +lastUsedDate: "Data de última utilização" +state: "Estado" +sort: "Ordenação" +ascendingOrder: "Ascendente" +descendingOrder: "Descendente" +scratchpad: "Bloco de rascunho" +scratchpadDescription: "O Bloco de rascunho fornece um ambiente experimental para AiScript. Permite escrever, executar e verificar os resultados do código para interagir com o Misskey." output: "Resultado" -smtpHost: "hospedeiro" +script: "Script" +disablePagesScript: "Desabilitar scripts nas páginas" +updateRemoteUser: "Atualizar informações do usuário remoto" +deleteAllFiles: "Excluir todos os arquivos" +deleteAllFilesConfirm: "Deseja excluir todos os arquivos?" +removeAllFollowing: "Deseja remover todos os seguidores?" +removeAllFollowingDescription: "Deixar de seguir todos de {host}. Faça isso se, por exemplo, o servidor não existir mais." +userSuspended: "Este usuário foi suspenso." +userSilenced: "Este usuário está silenciado." +yourAccountSuspendedTitle: "Esta conta está suspensa" +yourAccountSuspendedDescription: "Esta conta foi suspensa devido a violações dos termos de uso do servidor ou por outros motivos. Para mais detalhes, entre em contato com o administrador. Por favor, não crie uma nova conta." +tokenRevoked: "Token inválido" +tokenRevokedDescription: "Seu token de login expirou. Por favor, faça login novamente." +accountDeleted: "A conta foi removida" +accountDeletedDescription: "Esta conta foi removida." +menu: "Menu\n" +divider: "Separador" +addItem: "Adicionar item" +rearrange: "Reordernar" +relays: "Relays" +addRelay: "Adicionar relay" +inboxUrl: "Inbox URL" +addedRelays: "Relays adicionados" +serviceworkerInfo: "Deve estar habilitado para receber notificações por push." +deletedNote: "Postagem excluída" +invisibleNote: "Notas invisíveis" +enableInfiniteScroll: "Carregar automaticamente" +visibility: "Visibilidade" +poll: "Enquetes" +useCw: "Ocultar conteúdo" +enablePlayer: "Abrir o reprodutor de mídia" +disablePlayer: "Fechar o reprodutor de mídia" +expandTweet: "Expandir tweet" +themeEditor: "Editor de temas" +description: "Descrição" +describeFile: "Adicionar legenda" +enterFileDescription: "Insira uma legenda" +author: "Autor" +leaveConfirm: "Existem alterações não salvas. Deseja descartá-las?" +manage: "Administrar" +plugins: "Plugins" +preferencesBackups: "Definições de Backup" +deck: "Deck" +undeck: "Sair do deck" +useBlurEffectForModal: "Usar efeito de desfoque para modal" +useFullReactionPicker: "Usar o seletor de reações completo" +width: "Largura" +height: "Altura" +large: "Grande" +medium: "Médio" +small: "Pequeno" +generateAccessToken: "Gerar token de acesso" +permission: "Permissões" +enableAll: "Habilitar tudo" +disableAll: "Desabilitar tudo" +tokenRequested: "Autorização de acesso à conta" +pluginTokenRequestedDescription: "Este plugin poderá utilizar as permissões definidas aqui." +notificationType: "Tipos de notificação" +edit: "Editar" +emailServer: "Servidor de e-mail" +enableEmail: "Habilitar envio de e-mails" +emailConfigInfo: "Usado para confirmar o seu endereço de e-mail e redefinir sua senha" +email: "E-mail" +emailAddress: "Endereço de e-mail" +smtpConfig: "Configuração do servidor SMTP" +smtpHost: "Host" +smtpPort: "Porta" smtpUser: "Nome de usuário" smtpPass: "Senha" -clearCache: "Limpar memória transitória" +emptyToDisableSmtpAuth: "Desative a autenticação SMTP deixando o nome de usuário e a senha em branco." +smtpSecure: "Use SSL/TLS implícito para conexões SMTP" +smtpSecureInfo: "Desative esta opção ao utilizar STARTTLS." +testEmail: "Testar envio de e-mail" +wordMute: "Silenciar palavras" +regexpError: "Erro na expressão regular" +regexpErrorDescription: "Ocorreu um erro na expressão regular na linha {line} da palavra mutada {tab}:" +instanceMute: "Instâncias silenciadas" +userSaysSomething: "{name} disse algo" +makeActive: "Ativar" +display: "Visualizar" +copy: "Copiar" +metrics: "Métricas" +overview: "Visão geral" +logs: "Logs" +delayed: "atrasado" +database: "Banco de dados" +channel: "Canais" +create: "Criar" +notificationSetting: "Configurações de notificação" +notificationSettingDesc: "Selecione o tipo de notificação a ser exibido." +useGlobalSetting: "Utilizar a configuração global" +useGlobalSettingDesc: "Ao ativar, serão utilizadas as configurações de notificação da conta. Ao desativar, você poderá configurar individualmente." +other: "Outros" +regenerateLoginToken: "Gerar novo token de login" +regenerateLoginTokenDescription: "Gera novamente o token interno usado para o login. Normalmente, isso não é necessário. Ao regenerar, você será desconectado de todos os dispositivos." +setMultipleBySeparatingWithSpace: "Você pode configurar vários itens separando-os por espaço." +fileIdOrUrl: "ID do arquivo ou URL" +behavior: "Comportamento" +sample: "Exemplo" +abuseReports: "Denúncias" +reportAbuse: "Denúncias" +reportAbuseOf: "Denunciar {name}" +fillAbuseReportDescription: "Por favor, forneça detalhes sobre o motivo da denúncia. Se houver uma nota específica envolvida, inclua também a URL dela." +abuseReported: "Denúncia enviada. Obrigado por sua ajuda." +reporter: "Denunciante" +reporteeOrigin: "Origem da denúncia" +reporterOrigin: "Origem do denunciante" +forwardReport: "Encaminhar a denúncia para o servidor remoto" +forwardReportIsAnonymous: "No servidor remoto, suas informações não serão visíveis, e você será apresentado como uma conta do sistema anônima." +send: "Enviar" +abuseMarkAsResolved: "Marcar denúncia como resolvida" +openInNewTab: "Abrir em nova aba" +openInSideView: "Abrir em visão lateral" +defaultNavigationBehaviour: "Navegação padrão" +editTheseSettingsMayBreakAccount: "Editar essas configurações pode resultar em danos à conta.\"" +instanceTicker: "Informações do servidor das notas" +waitingFor: "Aguardando por {x}" +random: "Aleatório" +system: "Sistema" +switchUi: "Alternar UI" +desktop: "Área de Trabalho" +clip: "Clipe" +createNew: "Criar novo" +optional: "Opcional" +createNewClip: "Criar novo clipe" +unclip: "Remover do clipe" +confirmToUnclipAlreadyClippedNote: "Esta nota já está incluída no clipe \"{name}\". Você deseja remover a nota deste clipe?" +public: "Público" +private: "Privado" +i18nInfo: "Misskey é traduzido para várias línguas por voluntários. Você pode ajudar com as traduções em {link}." +manageAccessTokens: "Gerenciar tokens de acesso" +accountInfo: "Informações da conta" +notesCount: "Número de notas" +repliesCount: "Número de respostas enviadas" +renotesCount: "Número de repostagens feitas" +repliedCount: "Número de respostas recebidas" +renotedCount: "Números de repostagens recebidas" +followingCount: "Número de contas seguidas" +followersCount: "Número de seguidores" +sentReactionsCount: "Número de reações enviadas" +receivedReactionsCount: "Número de reações recebidas" +pollVotesCount: "Número de votos feitos em enquetes" +pollVotedCount: "Número de votos recebidos em enquetes" +yes: "Sim" +no: "Não" +driveFilesCount: "Número de arquivos no drive" +driveUsage: "Capacidade do drive" +noCrawle: "Recusar indexação por crawler" +noCrawleDescription: "Solicitar que os mecanismos de pesquisa externos não indexem o conteúdo de suas páginas de usuário, notas, páginas etc." +lockedAccountInfo: "Mesmo que você defina a aprovação para seguir, a menos que você defina o alcance da nota para 'Apenas seguidores', qualquer pessoa poderá ver suas notas." +alwaysMarkSensitive: "Marcar como sensível por padrão" +loadRawImages: "Exibir as imagens originais ao invés de miniaturas" +disableShowingAnimatedImages: "Não reproduzir imagens animadas" +verificationEmailSent: "Um e-mail de confirmação foi enviado. Siga o link no e-mail para concluir a verificação." +notSet: "Não definido" +emailVerified: "O endereço de e-mail foi confirmado" +noteFavoritesCount: "Número de notas salvas nos favoritos" +pageLikesCount: "Número de páginas curtidas" +pageLikedCount: "Número de curtidas recebidas nas suas páginas" +contact: "Contato" +useSystemFont: "Utilizar a fonte padrão do sistema" +clips: "Clipe" +experimentalFeatures: "Funcionalidades Experimentais" +experimental: "Experimental" +thisIsExperimentalFeature: "Este é um recurso experimental. As funções podem mudar ou pode não funcionar corretamente." +developer: "Programador" +makeExplorable: "Deixe a sua conta mais fácil de encontrar." +makeExplorableDescription: "Se você desativá-lo, outros usuários não poderão encontrar a sua conta na aba Descoberta." +showGapBetweenNotesInTimeline: "Mostrar um espaço entre as notas na linha de tempo" +duplicate: "Duplicar" +left: "Esquerda" +center: "Centralizar" +wide: "Largo" +narrow: "Estreito" +reloadToApplySetting: "As configurações serão refletidas após recarregar a página. Deseja recarregar agora?" +needReloadToApply: "É necessário recarregar a página para refletir as alterações." +showTitlebar: "Exibir barra de título" +clearCache: "Limpar o cache" +onlineUsersCount: "Pessoas Online" +nUsers: "Usuários" +nNotes: "Notas" +sendErrorReports: "Enviar relatórios de erro" +sendErrorReportsDescription: "Ao ativar essa opção, informações detalhadas de erro serão compartilhadas com o Misskey em caso de problemas, o que pode ajudar a melhorar a qualidade do software. As informações de erro podem incluir a versão do sistema operacional, o tipo de navegador e o sua atividade no Misskey." +myTheme: "Meu tema" +backgroundColor: "Cor de fundo" +accentColor: "Cor de destaque" +textColor: "Cor do texto" +saveAs: "Salvar como" +advanced: "Avançado" +advancedSettings: "Configurações avançadas" +value: "Valor" +createdAt: "Data de criação" +updatedAt: "Última atualização" +saveConfirm: "Deseja salvá-lo?" +deleteConfirm: "Confirma a exclusão?" +invalidValue: "Valor inválido" +registry: "Registo" +closeAccount: "Encerrar conta" +currentVersion: "Versão Atual" +latestVersion: "Última versão" +youAreRunningUpToDateClient: "Você está usando a última versão do cliente" +newVersionOfClientAvailable: "Nova versão do cliente disponível" +usageAmount: "Quantidade utilizada" +capacity: "Capacidade" +inUse: "Em uso" +editCode: "Editar código" +apply: "Aplicar" +receiveAnnouncementFromInstance: "Receba as notificações da instância" +emailNotification: "Notificações por e-mail" +publish: "Publicar" +inChannelSearch: "Pesquisar no canal" +useReactionPickerForContextMenu: "Clique com o botão direito do mouse para abrir o seletor de reações." +typingUsers: "digitando" +jumpToSpecifiedDate: "Pular para uma data específica" +showingPastTimeline: "Visualizar linha de tempo anterior" +clear: "Limpar" +markAllAsRead: "Marcar todas como lidas" +goBack: "Voltar" +unlikeConfirm: "Deseja realmente deixar de curtir?" +fullView: "Visão completa" +quitFullView: "Sair da visualização completa" +addDescription: "Adicionar descrição" +userPagePinTip: "Notas podem ser mostradas aqui ao clicar em \"Fixar no Perfil\" no menu de notas individuais." +notSpecifiedMentionWarning: "Esta nota menciona usuários que não foram incluídos como recipientes." info: "Informações" +userInfo: "Informações do Usuário" +unknown: "Desconhecido" +onlineStatus: "On-line" +hideOnlineStatus: "Ocultar o status on-line." +hideOnlineStatusDescription: "Esconder que está Ativo reduzirá a utilidade de certas funções (como, por exemplo, a Pesquisa)." +online: "Online" +active: "Ativo" +offline: "Inativo" +notRecommended: "Não recomendado" +botProtection: "Proteção contra Bot" +instanceBlocking: "Instâncias bloqueadas" +selectAccount: "Selecionar conta" +switchAccount: "Trocar conta" +enabled: "Ativado" +disabled: "Desativado" +quickAction: "Ações rápidas" user: "Usuários" -searchByGoogle: "Buscar" +administration: "Administrar" +accounts: "Contas" +switch: "Trocar" +noMaintainerInformationWarning: "A informação de administrador não foi configurada." +noBotProtectionWarning: "A proteção contra bots não foi configurada." +configure: "Configurar" +postToGallery: "Criar publicação em galeria" +postToHashtag: "Publicar nesta Hashtag" +gallery: "Galeria" +recentPosts: "Notas recentes" +popularPosts: "Notas populares" +shareWithNote: "Compartilhar em Notas" +ads: "Anúncios" +expiration: "Data limite" +startingperiod: "Data de início" +memo: "Nota" +priority: "Prioridade" +high: "Alto" +middle: "Meio" +low: "Baixo" +emailNotConfiguredWarning: "Endereço de e-mail não configurado. " +ratio: "Ratio" +previewNoteText: "Visualizar Nota" +customCss: "CSS Personalizado" +customCssWarn: "Esta configuração só deve ser usada se souber o que está fazendo. Valores impróprios podem causar erros no funcionamento do cliente." +global: "Global" +squareAvatars: "Exibir ícones quadrados" +sent: "Enviar" +received: "Recebido" +searchResult: "Pesquisar" +hashtags: "Hashtags" +troubleshooting: "Resolução de problemas" +useBlurEffect: "Usar efeito de desfoque na UI" +learnMore: "Saiba mais" +misskeyUpdated: "Misskey foi atualizado!" +whatIsNew: "Ver atualizações" +translate: "Traduzir" +translatedFrom: "Traduzido de" +accountDeletionInProgress: "Encerramento de conta em andamento" +usernameInfo: "O nome para identificar exclusivamente a sua conta no servidor. Pode conter letras (az, AZ), números (0~9) e sublinhados (_). O nome de usuário não pode ser alterado posteriormente." +aiChanMode: "Modo AI-chan" +devMode: "Modo de Desenvolvedor" +keepCw: "Manter aviso de conteúdo" +pubSub: "Publicar/Inscrever no perfil" +lastCommunication: "Ultima atualização" +resolved: "Resolvido" +unresolved: "Não resolvido" +breakFollow: "Remover seguidor" +breakFollowConfirm: "Deseja realmente deixar de seguir?" +itsOn: "Ativado" +itsOff: "Desativado" +on: "Ligado" +off: "Desligado" +emailRequiredForSignup: "Tornar o endereço de e-mail obrigatório durante o cadastro" +unread: "Não lido" +filter: "Filtrar" +controlPanel: "Painel de controle" +manageAccounts: "Gerenciar contas" +makeReactionsPublic: "Deixar o histórico de reações em Público" +makeReactionsPublicDescription: "Isto vai deixar o histórico de todas as suas reações visíveis para qualquer um ver." +classic: "Clássico" +muteThread: "Silenciar esta conversa" +unmuteThread: "Desativar silêncio desta conversa" +ffVisibility: "Visibilidade de Seguidos/Seguidores" +ffVisibilityDescription: "Permite configurar quem pode ver quem lhe segue e quem você está seguindo." +continueThread: "Ver mais desta conversa" +deleteAccountConfirm: "Deseja realmente excluir a conta?" +incorrectPassword: "Senha inválida." +voteConfirm: "Deseja confirmar o seu voto em \"{choice}\"?" +hide: "Ocultar" +useDrawerReactionPickerForMobile: "Mostrar em formato de gaveta" +welcomeBackWithName: "Bem-vindo de volta, {name}" +clickToFinishEmailVerification: "Clique em [{ok}] para completar a validação do endereço de e-mail." +overridedDeviceKind: "Sobrepor dispositivo" +smartphone: "Celular" +tablet: "Tablet" +auto: "Automático" +themeColor: "Cor do tema" +size: "Tamanho" +numberOfColumn: "Número da coluna" +searchByGoogle: "Pesquisar" +instanceDefaultLightTheme: "Tema diurno padrão para toda a instância" +instanceDefaultDarkTheme: "Tema noturno para toda a instância" +instanceDefaultThemeDescription: "Insira o código do tema em formato de objeto." +mutePeriod: "Duração de silenciamento" +period: "Data limite" +indefinitely: "Indefinitivamente" +tenMinutes: "10 minutos" +oneHour: "1 hora" +oneDay: "1 dia" +oneWeek: "1 semana" +oneMonth: "1 mês" +reflectMayTakeTime: "As mudanças podem demorar a aparecer." +failedToFetchAccountInformation: "Não foi possível obter informações da conta" +rateLimitExceeded: "Taxa limite excedido" +cropImage: "Recortar imagem" +cropImageAsk: "Deseja recortar esta imagem?" +cropYes: "Recortar" +cropNo: "Manter deste jeito" file: "Ficheiros" +recentNHours: "Últimas {n} horas" +recentNDays: "Últimos {n} dias" +noEmailServerWarning: "Servidor de e-mail não configurado." +thereIsUnresolvedAbuseReportWarning: "Existem denúncias não resolvidas." +recommended: "Recomendado" +check: "Verificar" +driveCapOverrideLabel: "Altere a capacidade do drive para este usuário" +driveCapOverrideCaption: "Altere a capacidade para o valor padrão informando o valor 0 ou inferior." +requireAdminForView: "Para visualizar, é necessário acessar com uma conta de administrador." +isSystemAccount: "É uma conta criada e gerenciada automaticamente pelo sistema." +typeToConfirm: "Para realizar essa operação, digite {x}." +deleteAccount: "Excluir conta" +document: "Documentação" +numberOfPageCache: "Número de cache de página" +numberOfPageCacheDescription: "Aumentar isso melhora a conveniência, mas também resulta em maior carga e uso de memória." +logoutConfirm: "Gostaria de encerrar a sessão?" +lastActiveDate: "Última data de uso" +statusbar: "Barra de status" +pleaseSelect: "Por favor, selecione." +reverse: "Inversão" +colored: "Colorido" +enableAutoSensitiveDescription: "Quando disponível, a marcação de mídia sensível será automaticamente atribuído ao conteúdo de mídia usando aprendizado de máquina. Mesmo que você desative essa função, em alguns servidores, isso pode ser configurado automaticamente." +activeEmailValidationDescription: "A validação do endereço de e-mail do usuário será realizada de forma mais rigorosa, considerando se é um endereço descartável ou se é possível realizar comunicação efetiva. Se desativado, apenas a validade do formato do endereço será verificada como uma sequência de caracteres." +account: "Contas" +like: "Curtir" +unlike: "Remover curtida" +numberOfLikes: "Número de curtidas" +show: "Visualizar" +didYouLikeMisskey: "Você gostou do Misskey?" +pleaseDonate: "O Misskey é um software gratuito utilizado por {host}. Para que possamos continuar o desenvolvimento, pedimos que considerem fazer doações. A sua contribuição é muito importante!" +roles: "Cargos" +role: "Cargo" +noRole: "Nenhum cargo" +unassign: "Remover" +color: "Cor" +manageCustomEmojis: "Gerenciar Emojis customizados" +youCannotCreateAnymore: "Você atingiu o limite de criação." +cannotPerformTemporary: "Ação temporariamente indisponível" +cannotPerformTemporaryDescription: "Esta ação não pôde ser concluída devido ao excesso de pedidos em sucessão. Tente novamente em alguns momentos." +invalidParamError: "Parâmetros inválidos" +invalidParamErrorDescription: "Parâmetros requisitados inválidos. Isto normalmente acontece devido a um erro, mas também pode ocorrer devido à entrada de valores além do limite ou algo semelhante." +permissionDeniedError: "Operação recusada" +permissionDeniedErrorDescription: "Esta conta não tem permissão para executar esta ação." +preset: "Predefinições" +selectFromPresets: "Escolher de predefinições" +achievements: "Conquistas" +gotInvalidResponseError: "Resposta do servidor inválida" +gotInvalidResponseErrorDescription: "Servidor fora do ar ou em manutenção. Favor tentar mais tarde." +thisPostMayBeAnnoying: "Esta nota pode incomodar outras pessoas." +thisPostMayBeAnnoyingHome: "Postar na linha do tempo inicial" +thisPostMayBeAnnoyingCancel: "Cancelar" +thisPostMayBeAnnoyingIgnore: "Postar mesmo assim" +collapseRenotes: "Ocultar Renotes já visualizadas" +internalServerError: "Erro interno de servidor" +emailNotSupported: "O envio de e-mails não é suportado nesta instância" +likeOnly: "Apenas curtidas" +likeOnlyForRemote: "Tudo (somente curtidas remotas)" +nonSensitiveOnlyForLocalLikeOnlyForRemote: "Apenas não sensíveis (somente curtidas remotas)" +rolesAssignedToMe: "Cargos atribuídos a mim" +unfavoriteConfirm: "Deseja realmente remover dos favoritos?" +drivecleaner: "Limpeza do drive" +retryAllQueuesConfirmTitle: "Gostaria de tentar novamente agora?" +horizontal: "Exibir painel lateral inteiro" +preservedUsernamesDescription: "Liste os nomes de usuário que deseja reservar, separando-os por quebras de linha. Os nomes de usuário especificados aqui não poderão ser utilizados durante a criação de contas. No entanto, esta restrição não se aplica quando a conta é criada por um administrador. Além disso, as contas que já existem não serão afetadas." +channelArchiveConfirmTitle: "Deseja realmente arquivar {name}?" +youFollowing: "Seguindo" +preventAiLearningDescription: "Solicita-se que o conteúdo de notas e imagens enviadas não seja usado como objeto de aprendizado por sistemas externos de geração de texto ou imagens. Isso é alcançado incluindo a flag 'noai' na resposta HTML. No entanto, o cumprimento dessa solicitação depende do próprio sistema de IA, portanto, não é garantia total de prevenção de aprendizado." +options: "Opções" +rolesThatCanBeUsedThisEmojiAsReaction: "Cargos que podem utilizar este emoji como reação" +rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "Se nenhum cargo for especificado, qualquer pessoa pode usar este emoji como reação." +rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "Estes cargos devem ser públicos." +waitingForMailAuth: "Verificação de e-mail pendente " +icon: "Avatar" +_initialAccountSetting: + followUsers: "Siga usuários que lhe interessam para criar a sua linha do tempo." +_accountMigration: + moveFromDescription: "Se você deseja migrar de outra conta para esta, é necessário criar um alias aqui. Por favor, insira a conta de origem da migração no seguinte formato: @username@server.example.com. Para excluir o alias, deixe o campo em branco e clique em salvar (não recomendado)." + moveAccountDescription: "Você está migrando para uma nova conta.\n ・Seus seguidores irão automaticamente seguir a nova conta.\n ・Todas as suas conexões de seguidores nesta conta serão removidas.\n ・Você não poderá mais criar novas notas nesta conta.\n\nA migração dos seguidores é automática, mas a migração das pessoas que você segue deve ser feita manualmente. Antes de migrar, exporte quem você está seguindo nesta conta e, assim que migrar, importe essa lista na nova conta.\nO mesmo se aplica para listas, silenciamentos e bloqueios, que também devem ser migrados manualmente.\n\n(Esta descrição se refere ao comportamento do servidor Misskey v13.12.0 ou posterior. Outros softwares ActivityPub, como Mastodon, podem ter comportamentos diferentes.)" + moveAccountHowTo: "Para realizar a migração da conta, primeiro crie um alias para esta conta no destino da migração. Após criar o alias, insira a conta de destino da migração no seguinte formato: @username@server.example.com." + migrationConfirm: "Tem certeza de que deseja migrar esta conta para '{account}'? Uma vez migrada, não poderá ser desfeita e não será possível usar esta conta novamente em seu estado original." + postMigrationNote: "A remoção dos seguidores desta conta será realizada 24 horas após a operação de migração. O número de seguidores e seguidos desta conta se tornará zero. Os seguidores não serão removidos, portanto, eles continuarão a ver as postagens destinadas aos seguidores desta conta." +_achievements: + earnedAt: "Data de aquisição" + _types: + _notes1: + title: "Configurando o meu misskey" + description: "Postou uma nota pela primeira vez" + flavor: "Divirta-se com o Misskey!" + _notes10: + title: "Algumas notas" + description: "Postou 10 notas" + _notes100: + title: "Um monte de notas" + description: "Postou 100 notas" + _notes500: + title: "Coberto por notas" + description: "Postou 500 notas" + _notes1000: + title: "Uma montanha de notas" + description: "Postou 1000 notas" + _notes5000: + title: "Enxurrada de notas" + description: "Postou 5000 notas" + _notes10000: + title: "Super nota" + description: "Postou 10000 notas" + _notes20000: + title: "Preciso... de mais... notas..." + description: "Postou 20000 notas" + _notes30000: + title: "Notas, Notas, NOTAS!" + description: "Postou 30000 notas" + _notes40000: + title: "Fábrica de notas" + description: "Postou 40000 notas" + _notes50000: + title: "Planeta de notas" + description: "Postou 50000 notas" + _notes60000: + title: "Quasar de notas" + description: "Postou 60000 notas" + _notes70000: + title: "Buraco negro de notas" + description: "Postou 70000 notas" + _notes80000: + title: "Galáxia de notas" + description: "Postou 80000 notas" + _notes90000: + title: "Universo de notas" + description: "Postou 90000 notas" + _notes100000: + title: "ALL YOUR NOTE ARE BELONG TO US" + description: "Postou 100000 notas" + flavor: "Você realmente tem muita coisa para escrever" + _login3: + title: "Iniciante I" + description: "Fez login por um total de 3 dias" + flavor: "De hoje em diante, me chame apenas de Misskist" + _login7: + title: "Iniciante II" + description: "Fez login por um total de 7 dias" + flavor: "Pegando o jeito da coisa?" + _login15: + title: "Iniciante III" + description: "Fez login por um total de 15 dias" + _login30: + title: "Misskist I" + description: "Fez login por um total de 30 dias" + _login60: + title: "Misskist II" + description: "Fez login por um total de 60 dias" + _login100: + title: "Misskist III" + description: "Fez login por um total de 100 dias" + flavor: "Misskist violento" + _login200: + title: "Freguês I" + description: "Fez login por um total de 200 dias" + _login300: + title: "Freguês II" + description: "Fez login por um total de 300 dias" + _login400: + title: "Freguês III" + description: "Fez login por um total de 400 dias" + _login500: + title: "Veterano I" + description: "Fez login por um total de 500 dias" + flavor: "Cavalheiros, tudo o que peço são notas" + _login600: + title: "Veterano II" + description: "Fez login por um total de 600 dias" + _login700: + title: "Veterano III" + description: "Fez login por um total de 700 dias" + _login800: + title: "Mestre das notas I" + description: "Fez login por um total de 800 dias" + _login900: + title: "Mestre das notas II" + description: "Fez login por um total de 900 dias" + _login1000: + title: "Mestre das notas III" + description: "Fez login por um total de 1000 dias" + flavor: "Obrigado por utilizar o Misskey!" + _noteClipped1: + title: "Não posso deixar de adicionar ao clipe" + description: "Adicionou a um clipe a sua primeira nota" + _noteFavorited1: + title: "Astrônomo amador" + description: "Adicionou uma nota aos favoritos pela primeira vez" + _myNoteFavorited1: + title: "Cabeça nas estrelas" + description: "Teve uma das suas notas adicionada aos favoritos de alguém" + _profileFilled: + title: "Tudo pronto" + description: "Configurou o seu perfil" + _markedAsCat: + title: "Eu Sou Um Gato" + description: "Marcou a sua conta como um gato" + flavor: "Ainda não tenho um nome." + _following1: + title: "Primeira vez seguindo alguém" + description: "Seguiu um usuário pela primeira vez" + _following10: + title: "Circulando, circulando" + description: "Seguiu 10 usuários" + _following50: + title: "Muitos amigos" + description: "Seguiu 50 usuários" + _following100: + title: "100 amigos" + description: "Seguiu 100 usuários" + _following300: + title: "Sobrecarga de amigos" + description: "Seguiu 300 usuários" + _followers1: + title: "Primeiro seguidor" + description: "Ganhou o seu primeiro seguidor" + _followers10: + title: "Sigam-me os bons!" + description: "Ganhou 10 seguidores" + _followers50: + title: "Aos montes" + description: "Ganhou 50 seguidores" + _followers100: + title: "Popular" + description: "Ganhou 100 seguidores" + _followers300: + title: "Em fila única, por favor" + description: "Ganhou 300 seguidores" + _followers500: + title: "Torre de celular" + description: "Ganhou 500 seguidores" + _followers1000: + title: "Influencer" + description: "Ganhou 1000 seguidores" + _noteDeletedWithin1min: + title: "Deixa pra lá" + description: "Excluí a postagem dentro de 1 minuto após ter publicado" + _driveFolderCircularReference: + title: "Referência circular" +_role: + new: "Novo cargo" + edit: "Editar cargo" + name: "Nome do Cargo" + description: "Descrição do cargo" + permission: "Permissões do cargo" + descriptionOfPermission: "Moderador permite que você execute operações básicas relacionadas à moderação.\nAdministradores podem alterar todas as configurações do servidor." + assignTarget: "Atribuir" + descriptionOfAssignTarget: "Manual para gerenciar manualmente quem está incluído neste cargo.\nCondicional define uma condição e os usuários que corresponderem a ela serão incluídos automaticamente." + manual: "Documentação" + conditional: "Condicional" + condition: "Condição" + isConditionalRole: "Este é um cargo condicional." + isPublic: "Cargo público" + descriptionOfIsPublic: "Este cargo será exibido no perfil do usuário." + options: "Opções" + policies: "Políticas" + baseRole: "Cargo padrão" + useBaseValue: "Usar o valor do cargo padrão" + chooseRoleToAssign: "Selecionar o cargo a ser atribuído" + iconUrl: "URL do ícone" + asBadge: "Exibir como insígnia" + descriptionOfAsBadge: "Quando ativado, o ícone do cargo será exibido ao lado do nome de usuário" + isExplorable: "Fazer o cargo explorável" + descriptionOfIsExplorable: "Ao ativar, a lista de membros será pública na seção 'Explorar' e a linha do tempo do cargo ficará disponível." + displayOrder: "Ordenação" + descriptionOfDisplayOrder: "Quanto maior o número, maior a posição de destaque na interface do usuário." + canEditMembersByModerator: "Permitir a edição de membros deste cargo por moderadores" + descriptionOfCanEditMembersByModerator: "Quando ativado, os moderadores também poderão atribuir/remover usuários deste papel, além dos administradores. Quando desativado, apenas os administradores poderão fazê-lo." + priority: "Prioridade" + _priority: + low: "Baixa" + middle: "Médio" + high: "Alta" + _options: + gtlAvailable: "Visualizar Linha do Tempo Global" + ltlAvailable: "Visualizar Linha do Tempo Local" + canPublicNote: "Permitir postagem pública" + canInvite: "Permitir a criação de códigos de convites para a instância" + inviteLimit: "Limite de códigos de convite" + inviteLimitCycle: "Intervalo de emissão do código de convite" + inviteExpirationTime: "Prazo de validade do código de convite" + canManageCustomEmojis: "Permitir gerenciar emojis personalizados" + driveCapacity: "Capacidade do drive" + alwaysMarkNsfw: "Sempre marcar arquivos como NSFW" + pinMax: "Número máximo de notas fixadas" + antennaMax: "Número máximo de antenas" + wordMuteMax: "Número máximo de caracteres nas palavras silenciadas" + webhookMax: "Número máximo de webhooks" + clipMax: "Número máximo de clipes" + noteEachClipsMax: "Número máximo de notas em um clipe" + userListMax: "Número máximo de listas de usuários" + userEachUserListsMax: "Número máximo de usuários em uma lista" + rateLimitFactor: "Taxa de limitação" + descriptionOfRateLimitFactor: "Valores menores são menos restritivos, valores maiores são mais restritivos." + canHideAds: "Permitir ocultar anúncios" + canSearchNotes: "Permitir a busca de notas" + _condition: + isLocal: "Usuário local" + isRemote: "Usuário remoto" + createdLessThan: "Menos de X passados desde a criação da conta" + createdMoreThan: "Mais de X passados desde a criação da conta" + followersLessThanOrEq: "Possui X ou menos seguidores" + followersMoreThanOrEq: "Possui X ou mais seguidores" + followingLessThanOrEq: "Segue X ou menos contas" + followingMoreThanOrEq: "Segue X ou mais contas" + notesLessThanOrEq: "A quantidade de postagens é menor ou igual a" + notesMoreThanOrEq: "A quantidade de postagens é maior ou igual a" + and: "~ E ~ (Condicional)" + or: "~ OU ~ (Condicional)" + not: "Não ~ (Condicional)" +_sensitiveMediaDetection: + description: "Use o aprendizado de máquina para detectar automaticamente mídias sensíveis para moderação. Isso pode aumentar ligeiramente a carga no servidor." + sensitivityDescription: "Ao reduzir a sensibilidade, as detecções incorretas (falsos positivos) diminuem. Ao aumentar a sensibilidade, as falhas de detecção (falsos negativos) diminuem." +_emailUnavailable: + used: "O endereço de e-mail informado já está sendo utilizado" + format: "Formado de e-mail inválido" + disposable: "Endereços de e-mail descartáveis não devem ser utilizados" + mx: "O servidor de informado é inválido" + smtp: "O servidor de e-mail não está respondendo" +_ffVisibility: + public: "Público" + followers: "Visível apenas para seguidores" + private: "Privado" +_signup: + almostThere: "Quase pronto" + emailAddressInfo: "Por favor, insira o seu endereço de e-mail. Ele não será divulgado." + emailSent: "Um e-mail de confirmação foi enviado para o endereço de e-mail fornecido ({email}). Acesse o link fornecido no e-mail para concluir a criação de sua conta." +_accountDelete: + accountDelete: "Remover Conta" + mayTakeTime: "A exclusão de uma conta é um processo que requer muito recurso, portanto, se você tiver muito conteúdo criados ou arquivos enviados, pode levar algum tempo até ser concluída." + sendEmail: "Quando a exclusão da conta estiver concluída, enviaremos uma notificação para o endereço de e-mail registrado." + requestAccountDelete: "Solicitar exclusão de conta" + started: "O processo de exclusão foi iniciado." + inProgress: "A exclusão está em andamento" +_ad: + back: "Voltar" + reduceFrequencyOfThisAd: "Diminuir frequência deste anúncio" + hide: "Não exibir anúncios" +_forgotPassword: + enterEmail: "Por favor, insira o endereço de e-mail usado no cadastro de sua conta. Um link para redefinição de senha será enviado para esse endereço." + ifNoEmail: "Caso você não tenha registrado um endereço de e-mail, por favor, entre em contato com o administrador." +_gallery: + liked: "Postagens curtidas" + like: "Curtir" + unlike: "Remover curtida" _email: _follow: title: "Você tem um novo seguidor" + _receiveFollowRequest: + title: "Você recebeu um pedido de seguidor" +_preferencesBackups: + cannotSave: "Não foi possível salvar" + applyConfirm: "Deseja aplicar o backup '{name}' ao dispositivo atual? As configurações atuais do dispositivo serão perdidas." + deleteConfirm: "Deseja excluir {name}?" + cannotLoad: "Não foi possível carregar" +_channel: + featured: "Destaques" + following: "Seguindo" + usersCount: "usuários ativos" + notesCount: "notas" + nameAndDescription: "Nome e descrição" +_menuDisplay: + sideFull: "Exibir painel lateral inteiro" + top: "Exibir barra superior" + hide: "Ocultar" _theme: + description: "Descrição" + alpha: "Opacidade" + deleteConstantConfirm: "Confirma a exclusão da constante {const}?" keys: mention: "Menção" renote: "Repostar" + divider: "Separador" _sfx: note: "Posts" notification: "Notificações" chat: "Chat" +_ago: + invalid: "Não há nada aqui" +_timelineTutorial: + step1_2: "Existem vários tipos de linhas do tempo, por exemplo, na 'Linha do Tempo Principal', você verá as notas das pessoas que está seguindo, e na 'Linha do Tempo Local', verá todas as notas de {name}." +_2fa: + securityKeyInfo: "Além da autenticação por impressão digital ou PIN, você também pode configurar a autenticação por chaves de segurança de hardware compatível com FIDO2 para proteger ainda mais a sua conta." + removeKeyConfirm: "Deseja excluir {name}?" + renewTOTPCancel: "Não, obrigado" +_permissions: + "read:account": "Visualizar informações da conta" + "write:account": "Editar informações da conta" + "read:blocks": "Visualizar a sua lista de usuários bloqueados" + "write:blocks": "Editar a sua lista de usuários bloqueados" + "read:drive": "Visualizar os seus arquivos e pastas do drive" + "write:drive": "Editar ou excluir os seus arquivos e pastas do drive" + "read:favorites": "Visualizar a sua lista de favoritos" + "write:favorites": "Editar a sua lista de favoritos" + "read:following": "Visualizar informações de quem você segue" + "write:following": "Seguir ou deixar de seguir outras contas" + "read:messaging": "Visualizar os seus chats" + "write:messaging": "Compor ou editar mensagens de chat" + "read:mutes": "Visualizar a sua lista de usuários silenciados" + "write:mutes": "Editar a sua lista de usuários silenciados" + "write:notes": "Compor ou excluir notas" + "read:notifications": "Visualizar as suas notificações" + "write:notifications": "Gerenciar as suas notificações" + "read:reactions": "Visualizar as suas reações" + "write:reactions": "Editar as suas reações" + "write:votes": "Votar em enquetes" + "read:pages": "Visualizar as suas páginas" + "write:pages": "Editar ou excluir as suas páginas" + "read:page-likes": "Visualizar as suas curtidas em páginas" + "write:page-likes": "Editar as suas curtidas em páginas" + "read:user-groups": "Visualizar os seus grupos de usuários" + "write:user-groups": "Editar ou excluir os seus grupos de usuários" + "read:channels": "Visualizar os seus canais" + "write:channels": "Editar os seus canais" + "read:gallery": "Visualizar a sua galeria" + "write:gallery": "Editar sua galeria" + "read:gallery-likes": "Visualizar a sua lista de curtidas da galeria" + "write:gallery-likes": "Editar a sua lista de curtidas da galeria" _widgets: profile: "Perfil" instanceInfo: "Informações da instância" + memo: "Notas adesivas" notifications: "Notificações" - timeline: "Timeline" - activity: "atividade" - federation: "União" - jobQueue: "Fila de trabalhos" + timeline: "Linha do tempo" + calendar: "Calendário" + trends: "Destaques" + clock: "Relógio" + rss: "Leitor de RSS" + rssTicker: "Ticker RSS" + activity: "Atividades" + photos: "Fotos" + digitalClock: "Relógio digital" + unixClock: "Hora UNIX" + federation: "Federação" + instanceCloud: "Nuvem de instâncias" + postForm: "Campo de postagem" + slideshow: "Apresentação de slides" + button: "Botão" + onlineUsers: "Usuários Online" + jobQueue: "Fila de tarefas" + serverMetric: "Métricas do servidor" + aiscript: "Console AiScript" + aiscriptApp: "AiScript App" + aichan: "Ai" + userList: "Lista de usuários" _userList: - chooseList: "Escolhe uma lista" + chooseList: "Selecione uma lista" + clicker: "Clicker" _cw: show: "Carregar mais" +_poll: + canMultipleVote: "Permitir múltipla seleção" + vote: "Votar em enquetes" _visibility: - home: "casa" + home: "Início" followers: "Seguidores" + followersDescription: "Tornar visível apenas para os meus seguidores" _profile: name: "Nome" username: "Nome de usuário" _exportOrImport: + favoritedNotes: "Notas nos favoritos" followingList: "Seguindo" muteList: "Silenciar" blockingList: "Bloquear" @@ -501,8 +1366,25 @@ _exportOrImport: _charts: federation: "União" _timelines: - home: "casa" + home: "Início" +_play: + new: "Criar Play" + edit: "Editar Play" + created: "Play criado" + updated: "Play editado" + deleted: "Play foi excluído" + pageSetting: "Configurações do Play" + editThisPage: "Editar este Play" + my: "Meus Plays" + liked: "Plays curtidos" + script: "Script" + summary: "Descrição" _pages: + deleted: "Página excluída com sucesso" + viewPage: "Visualizar as suas páginas" + like: "Curtir" + unlike: "Remover curtida" + liked: "Páginas curtidas" blocks: image: "imagem" _relayStatus: @@ -515,12 +1397,12 @@ _notification: youGotReply: "{name} te respondeu" youGotQuote: "{name} te citou" youWereFollowed: "Você tem um novo seguidor" - youReceivedFollowRequest: "Você recebeu um pedido de seguimento" - yourFollowRequestAccepted: "Seu pedido de seguimento foi aceito" + youReceivedFollowRequest: "Você recebeu um pedido de seguidor" + yourFollowRequestAccepted: "Seu pedido de seguidor foi aceito" pollEnded: "Os resultados da enquete agora estão disponíveis" emptyPushNotificationMessage: "As notificações de alerta foram atualizadas" _types: - all: "Todos" + all: "Todas" follow: "Seguindo" mention: "Menção" reply: "Respostas" @@ -528,8 +1410,8 @@ _notification: quote: "Citar" reaction: "Reações" pollEnded: "Enquetes terminando" - receiveFollowRequest: "Recebeu pedidos de seguimento" - followRequestAccepted: "Aceitou pedidos de seguimento" + receiveFollowRequest: "Recebeu pedidos de seguidor" + followRequestAccepted: "Aceitou pedidos de seguidor" app: "Notificações de aplicativos conectados" _actions: followBack: "te seguiu de volta" @@ -545,6 +1427,7 @@ _deck: swapDown: "Trocar de posição com a coluna abaixo" popRight: "Acoplar coluna à direita" profile: "Perfil" + deleteProfile: "Remover perfil" _columns: main: "Principal" widgets: "Widgets" @@ -552,7 +1435,16 @@ _deck: tl: "Timeline" antenna: "Antenas" list: "Listas" + channel: "Canais" mentions: "Menções" direct: "Notas diretas" + roleTimeline: "Linha do tempo do cargo" +_drivecleaner: + orderBySizeDesc: "Tamanho descendente" + orderByCreatedAtAsc: "Data ascendente" _webhookSettings: name: "Nome" + active: "Ativado" + _events: + follow: "Quando seguindo um usuário" + followed: "Quando sendo seguido" diff --git a/locales/ro-RO.yml b/locales/ro-RO.yml index 2d3099858d..1861b28331 100644 --- a/locales/ro-RO.yml +++ b/locales/ro-RO.yml @@ -630,6 +630,7 @@ sent: "Trimite" searchByGoogle: "Caută" file: "Fișiere" show: "Arată" +icon: "Avatar" _role: _priority: middle: "Mediu" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 080ebf1667..9712fdfa2e 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -49,6 +49,7 @@ delete: "Удалить" deleteAndEdit: "Удалить и отредактировать" deleteAndEditConfirm: "Удалить эту заметку и создать отредактированную? Все реакции, ссылки и ответы на существующую будут будут потеряны." addToList: "Добавить в список" +addToAntenna: "Добавить к антенне" sendMessage: "Отправить сообщение" copyRSS: "Скопировать RSS" copyUsername: "Скопировать имя пользователя" @@ -155,6 +156,8 @@ addEmoji: "Добавить эмодзи" settingGuide: "Рекомендуемые настройки" cacheRemoteFiles: "Кешировать внешние файлы" cacheRemoteFilesDescription: "Когда эта настройка отключена, файлы с других сайтов будут загружаться прямо оттуда. Это сэкономит место на сервере, но увеличит трафик, так как не будут создаваться эскизы." +cacheRemoteSensitiveFiles: "Кешировать внешние файлы" +cacheRemoteSensitiveFilesDescription: "Описание удаленных внешних файлов в кэше" flagAsBot: "Аккаунт бота" flagAsBotDescription: "Включите, если этот аккаунт управляется программой. Это позволит системе Misskey учитывать это, а также поможет разработчикам других ботов предотвратить бесконечные циклы взаимодействия." flagAsCat: "Аккаунт кота" @@ -316,6 +319,7 @@ copyUrl: "Копировать ссылку" rename: "Переименовать" avatar: "Аватар" banner: "Шапка" +displayOfSensitiveMedia: "Определение деликатного контента" whenServerDisconnected: "Когда соединение с сервером потеряно" disconnectedFromServer: "Разорвано соединение с сервером" reload: "Перезагрузить" @@ -676,6 +680,7 @@ createNewClip: "Новая подборка" unclip: "Убрать из подборки" confirmToUnclipAlreadyClippedNote: "Эта заметка уже есть в подборке «{name}». Удалить из этой подборки?" public: "Общедоступно" +private: "Показываются только вам" i18nInfo: "Misskey переводят на разные языки добровольцы со всего света. Ваша помощь тоже пригодится здесь: {link}." manageAccessTokens: "Управление токенами доступа" accountInfo: "Сведения об учётной записи" @@ -840,6 +845,8 @@ breakFollow: "Отписка" breakFollowConfirm: "Удалить из подписок пользователя ?" itsOn: "Включено" itsOff: "Выключено" +on: "Вкл" +off: "Выкл" emailRequiredForSignup: "Для регистрации учётной записи нужен адрес электронной почты" unread: "Непрочитанное" filter: "Фильтры" @@ -994,6 +1001,7 @@ cannotBeChangedLater: "Это нельзя изменить позже" reactionAcceptance: "Принятие реакций" likeOnly: "Только лайки" likeOnlyForRemote: "Только лайки с удалённых серверов" +nonSensitiveOnly: "Безопасный серфинг" rolesAssignedToMe: "Мои роли" resetPasswordConfirm: "Сбросить пароль?" sensitiveWords: "Чувствительные слова" @@ -1014,10 +1022,58 @@ noteIdOrUrl: "ID или ссылка на заметку" video: "Видео" videos: "Видео" dataSaver: "Экономия трафика" +accountMigration: "Перенести учётную запись" +accountMoved: "Учетная запись перенесена" +accountMovedShort: "Эта учётная запись перемещена" +operationForbidden: "Эта операция невозможна." +forceShowAds: "Всегда отображать рекламу" +addMemo: "Добавить заметку" +editMemo: "Редактировать заметку" +reactionsList: "Реакции" renotesList: "Репосты" +notificationDisplay: "Отображение уведомления" +leftTop: "Верхний левый угол" +rightTop: "Сверху справа" +leftBottom: "Снизу слева" +rightBottom: "Снизу справа" +vertical: "Вертикальная" horizontal: "Сбоку" +position: "Позиция" +serverRules: "Правила сервера" +pleaseConfirmBelowBeforeSignup: "Для регистрации на данном сервере, необходимо согласится с нижеследующими положениями." +pleaseAgreeAllToContinue: "Чтобы продолжить, необходимо поставить отметки во всех полях \"согласен\"." +continue: "Продолжить" +preservedUsernames: "Зарезервированные имена пользователей" +preservedUsernamesDescription: "Перечислите зарезервированные имена пользователей, отделяя их строками. Они станут недоступны при создании учётной записи. Это ограничение не применяется при создании учётной записи администраторами. Также, уже существующие учётные записи останутся без изменений." +createNoteFromTheFile: "Создать заметку из этого файла" +archive: "Архив" +channelArchiveConfirmTitle: "Переместить {name} в архив?" +channelArchiveConfirmDescription: "Архивированные каналы перестанут отображаться в списке каналов или результатах поиска. В них также нельзя будет добавлять новые записи." +displayOfNote: "Отображение заметок" +initialAccountSetting: "Настройка профиля" youFollowing: "Подписки" +preventAiLearning: "Отказаться от использования в машинном обучении (Генеративный ИИ)" options: "Настройки ролей" +specifyUser: "Указанный пользователь" +failedToPreviewUrl: "Предварительный просмотр недоступен" +update: "Обновить" +later: "Позже" +goToMisskey: "К Misskey" +additionalEmojiDictionary: "Дополнительные словари эмодзи" +installed: "Установлено" +branding: "Бренд" +expirationDate: "Дата истечения" +unused: "Неиспользуемый" +expired: "Срок действия приглашения истёк" +doYouAgree: "Согласны?" +icon: "Аватар" +_initialAccountSetting: + accountCreated: "Аккаунт успешно создан!" + letsStartAccountSetup: "Давайте настроим вашу учётную запись." + profileSetting: "Настройки профиля" + privacySetting: "Настройки конфиденциальности" + initialAccountSettingCompleted: "Первоначальная настройка успешно завершена!" + skipAreYouSure: "Пропустить настройку?" _achievements: earnedAt: "Разблокировано в" _types: @@ -1884,6 +1940,7 @@ _deck: channel: "Каналы" mentions: "Упоминания" direct: "Личное" + roleTimeline: "История Ролей" _dialog: charactersExceeded: "Превышено максимальное количество символов! У вас {current} / из {max}" charactersBelow: "Это ниже минимального количества символов! У вас {current} / из {min}" @@ -1891,5 +1948,6 @@ _disabledTimeline: title: "Лента отключена" description: "Ваша текущая роль не позволяет пользоваться этой лентой." _webhookSettings: + createWebhook: "Создать вебхук" name: "Название" active: "Вкл." diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml index f4c598ac83..3035f27050 100644 --- a/locales/sk-SK.yml +++ b/locales/sk-SK.yml @@ -654,6 +654,7 @@ createNewClip: "Vytvoriť nový klip" unclip: "Odopnúť" confirmToUnclipAlreadyClippedNote: "Táto poznámka je už pripnutá ako \"{name}\". Naozaj ju chcete odopnúť?" public: "Verejné" +private: "Súkromné" i18nInfo: "Misskey je prekladaný do rôznych jazykov dobrovoľníkmi. Pomôcť môžete na {link}." manageAccessTokens: "Spravovať prístupové tokeny" accountInfo: "Informácie o účte" @@ -918,6 +919,7 @@ pleaseDonate: "Misskey je bezplatný softvér, ktorý používa {host}. Prosím, color: "Farba" horizontal: "Strana" youFollowing: "Sledované" +icon: "Avatar" _role: priority: "Priorita" _priority: diff --git a/locales/sv-SE.yml b/locales/sv-SE.yml index 07f43afe2e..5ba206f9f2 100644 --- a/locales/sv-SE.yml +++ b/locales/sv-SE.yml @@ -485,6 +485,7 @@ windowRestore: "Återställ" pleaseDonate: "Misskey är en gratis programvara som används på {host}. Donera gärna för att göra utvecklingen ständigt, tack!" resetPasswordConfirm: "Återställ verkligen ditt lösenord?" dataSaver: "Databesparing" +icon: "Profilbild" _achievements: _types: _open3windows: diff --git a/locales/th-TH.yml b/locales/th-TH.yml index 82032b06c2..370b249b5e 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -74,7 +74,7 @@ import: "นำเข้า" export: "นำออก" files: "ไฟล์" download: "ดาวน์โหลด" -driveFileDeleteConfirm: "นายแน่ใจแล้วหรอ? ว่าต้องการลบไฟล์ \"{name}\" โน้ตย่อที่แนบมากับไฟล์นี้ก็จะถูกลบด้วยนะ" +driveFileDeleteConfirm: "คุณต้องการลบไฟล์ \"{name}\" ใช่หรือไม่? โน้ตย่อที่แนบมากับไฟล์นี้ก็จะถูกลบไปด้วย" unfollowConfirm: "นายแน่ใจแล้วหรอว่าต้องการเลิกติดตาม {name}?" exportRequested: "เมื่อคุณได้ร้องขอการส่งออก อาจจะต้องใช้เวลาสักครู่ และจะถูกเพิ่มในไดรฟ์ของคุณเมื่อเสร็จสิ้นแล้ว" importRequested: "เมื่อคุณได้ร้องขอการนำเข้า อาจจะต้องใช้เวลาสักครู่นะ" @@ -92,13 +92,13 @@ somethingHappened: "อุ๊ย ! มีอะไรบางอย่างผ retry: "ลองใหม่อีกครั้ง" pageLoadError: "เกิดข้อผิดพลาดในการโหลดหน้านี้" pageLoadErrorDescription: "โดยปกติแล้วมักจะเกิดจากข้อผิดพลาดของเครือข่ายหรือแคชของเบราว์เซอร์ ลองล้างแคชแล้วลองใหม่อีกครั้งหลังจากรอสักครู่ " -serverIsDead: "เซิร์ฟเวอร์นี้ไม่มีการตอบสนอง ได้โปรดกรุณารอสักครู่แล้วลองใหม่อีกครั้งนะ" -youShouldUpgradeClient: "หากต้องการดูหน้านี้ได้โปรดกรุณา รีเซ็ตเพื่ออัปเดตไคลเอ็นต์ของคุณนะ" +serverIsDead: "เซิร์ฟเวอร์นี้ไม่มีการตอบสนอง โปรดกรุณารอสักครู่แล้วลองใหม่อีกครั้ง" +youShouldUpgradeClient: "หากต้องการดูหน้านี้ กรุณาโหลดหน้าใหม่เพื่ออัปเดตไคลเอ็นต์ของคุณ" enterListName: "ใส่ชื่อสำหรับรายการลิสต์" privacy: "ความเป็นส่วนตัว" makeFollowManuallyApprove: "ติดตามคำขอที่ต้องได้รับการอนุมัติ" defaultNoteVisibility: "การมองเห็นที่เป็นค่าเริ่มต้น" -follow: "กำลังติดตาม" +follow: "ติดตาม" followRequest: "ส่งคำขอติดตาม" followRequests: "ส่งคำขอติดตาม" unfollow: "เลิกติดตาม" @@ -109,7 +109,7 @@ unrenote: "เลิกรีโน้ต" renoted: "รีโน้ตแล้ว" cantRenote: "โพสต์นี้ไม่สามารถรีโน้ตไว้ใหม่ได้นะ" cantReRenote: "ไม่สามารถรีโน้ตเอาไว้ใหม่ได้นะ" -quote: "อ้างคำพูด" +quote: "อ้างอิง" inChannelRenote: "รีโน้ตช่องแชลแนลเท่านั้น" inChannelQuote: "อ้างช่องเท่านั้น" pinnedNote: "โน้ตที่ปักหมุดเอาไว้" @@ -137,7 +137,7 @@ suspend: "ถูกระงับ" unsuspend: "ยกเลิกระงับ" blockConfirm: "คุณแน่ใจแล้วเหรอ? ว่าต้องการบล็อกบัญชีนี้" unblockConfirm: "คุณแน่ใจแล้วเหรอ? ว่าต้องการปลดบล็อคบัญชีนี้" -suspendConfirm: "นายแน่ใจแล้วเหรอว่าต้องการระงับบัญชีนี้อ่ะ?" +suspendConfirm: "แน่ใจว่าคุณต้องการระงับบัญชีนี้?" unsuspendConfirm: "นายแน่ใจแล้วหรอ? ว่าต้องการยกเลิกการระงับบัญชีนี้" selectList: "เลือกรายการ" editList: "แก้ไขรายการ" @@ -156,6 +156,7 @@ addEmoji: "แทรกอีโมจิ" settingGuide: "การตั้งค่าที่แนะนำ" cacheRemoteFiles: "แคชไฟล์ระยะไกล" cacheRemoteFilesDescription: "เมื่อปิดใช้งานการตั้งค่านี้ ไฟล์ระยะไกลนั้นจะถูกโหลดโดยตรงจากอินสแตนซ์ระยะไกล แต่กรณีการปิดใช้งานนี้จะช่วยลดปริมาณการใช้พื้นที่จัดเก็บข้อมูล แต่เพิ่มปริมาณการใช้งาน เพราะเนื่องจากจะไม่มีการสร้างภาพขนาดย่อ" +youCanCleanRemoteFilesCache: "คุณสามารถล้างแคชได้โดยคลิกที่ปุ่ม 🗑️ ในมุมมองการจัดการไฟล์" cacheRemoteSensitiveFiles: "ไฟล์ระยะไกลที่มีความละเอียดอ่อนแคช" cacheRemoteSensitiveFilesDescription: "เมื่อปิดการใช้งานแล้วการตั้งค่านี้ ไฟล์รีโมตที่มีความละเอียดอ่อนนั้นจะถูกโหลดโดยตรงจากอินสแตนซ์ระยะไกลโดยที่ไม่มีการแคช" flagAsBot: "ทำเครื่องหมายบอกว่าบัญชีนี้เป็นบอท" @@ -183,7 +184,7 @@ selectUser: "เลือกผู้ใช้งาน" recipient: "ผู้รับ" annotation: "ความคิดเห็น" federation: "เฟดิเวิร์ส" -instances: "ตัวอย่าง" +instances: "Server" registeredAt: "จดทะเบียนที่" latestRequestReceivedAt: "ได้รับคำขอล่าสุดไปแล้ว" latestStatus: "สถานะล่าสุด" @@ -254,7 +255,7 @@ imageUrl: "url รูปภาพ" remove: "ลบ" removed: "ถูกลบไปแล้ว" removeAreYouSure: "นายแน่ใจจริงหรอว่าต้องการที่จะลบออก \"{x}\"" -deleteAreYouSure: "นายแน่ใจจริงหรอว่าต้องการที่จะลบออก \"{x}\"" +deleteAreYouSure: "ต้องการลบ {x} หรือไม่คะ?" resetAreYouSure: "รีเซ็ตเลยไหม" saved: "บันทึกแล้ว" messaging: "แชท" @@ -308,8 +309,8 @@ renameFolder: "เปลี่ยนชื่อโฟลเดอร์" deleteFolder: "ลบโฟลเดอร์" addFile: "เพิ่มไฟล์" emptyDrive: "ไดรฟ์ของคุณว่างเปล่านะ" -emptyFolder: "โฟลเดอร์นี้น่าจะว่างเปล่านะ" -unableToDelete: "ไม่สามารถลบออกได้นะ" +emptyFolder: "โฟลเดอร์นี้ว่างเปล่า" +unableToDelete: "ไม่สามารถลบออกได้" inputNewFileName: "ป้อนชื่อไฟล์ใหม่นะ" inputNewDescription: "กรุณาใส่แคปชั่นใหม่" inputNewFolderName: "กรุณาใส่ชื่อโฟลเดอร์ใหม่นะ\n" @@ -363,7 +364,7 @@ pinnedUsersDescription: "ลิสต์ชื่อผู้ใช้โดย pinnedPages: "หน้าที่ปักหมุด" pinnedPagesDescription: "ป้อนเส้นทางของหน้าที่คุณต้องการตรึงไว้ที่หน้าแรกของอินสแตนซ์นี้ โดยคั่นด้วยตัวแบ่งบรรทัด" pinnedClipId: "ID ของคลิปที่จะปักหมุด" -pinnedNotes: "โน้ตที่ปักหมุดเอาไว้" +pinnedNotes: "โน้ตที่ปักหมุดไว้" hcaptcha: "hCaptcha" enableHcaptcha: "เปิดใช้ hCaptcha" hcaptchaSiteKey: "คีย์ไซต์" @@ -404,7 +405,7 @@ recentlyDiscoveredUsers: "ผู้ใช้ที่เพิ่งค้นพ exploreUsersCount: "มีผู้ใช้ {จำนวน} ราย" exploreFediverse: "สำรวจเฟดดิเวิร์ส" popularTags: "แท็กยอดนิยม" -userList: "รายการ" +userList: "ลิสต์" about: "เกี่ยวกับ" aboutMisskey: "เกี่ยวกับ Misskey" administrator: "ผู้ดูแลระบบ" @@ -444,7 +445,7 @@ text: "ข้อความ" enable: "เปิดใช้งาน" next: "ถัด​ไป" retype: "พิมพ์รหัสอีกครั้ง" -noteOf: "โน้ต โดย {ผู้ใช้งาน}" +noteOf: "โน้ต โดย {user}" quoteAttached: "อ้างอิง" quoteQuestion: "นายต้องการที่จะอ้างอิงหรอ?" noMessagesYet: "ยังไม่มีข้อความนะ" @@ -680,6 +681,7 @@ createNewClip: "สร้างคลิปใหม่" unclip: "ลบคลิป" confirmToUnclipAlreadyClippedNote: "โน้ตนี้เป็นส่วนหนึ่งของคลิป \"{name}\" แล้ว คุณต้องการลบออกจากคลิปนี้แทนอย่างงั้นหรอ?" public: "สาธารณะ" +private: "ส่วนตัว" i18nInfo: "Misskey กำลังได้รับการแปลเป็นภาษาต่างๆ โดยอาสาสมัคร คุณสามารถช่วยเหลือได้ที่ {link}" manageAccessTokens: "การจัดการโทเค็นการเข้าถึง" accountInfo: "ข้อมูลบัญชี" @@ -957,7 +959,7 @@ show: "แสดงผล" neverShow: "ไม่ต้องแสดงข้อความนี้อีก" remindMeLater: "ไว้ครั้งหน้าแล้วกัน" didYouLikeMisskey: "คุณเคยชอบ Misskey ไหม?" -pleaseDonate: "{host} ใช้ซอฟต์แวร์ฟรี Misskey เราขอขอบคุณการบริจาคของคุณอย่างสูงเพื่อให้การพัฒนา Misskey สามารถดำเนินต่อไปได้นะ!" +pleaseDonate: "Misskey เป็นซอฟต์แวร์ฟรีที่ใช้งานโดย {host} เราขอขอบคุณการสนับสนุนของคุณอย่างสูงเพื่อให้การพัฒนา Misskey สามารถดำเนินต่อไปได้!" roles: "บทบาท" role: "บทบาท" noRole: "ไม่พบบทบาท" @@ -1091,6 +1093,19 @@ usedAt: "ใช้แล้วที่" unused: "ไม่ใช้แล้ว" used: "ใช้แล้ว" expired: "หมดอายุแล้ว" +doYouAgree: "ยอมรับมั้ย?" +beSureToReadThisAsItIsImportant: "กรุณาอ่านข้อมูลที่สำคัญอันนี้" +iHaveReadXCarefullyAndAgree: "ฉันได้อ่านข้อความ \"{x}\" และยินยอม" +dialog: "ไดอะล็อก" +icon: "ไอคอน" +forYou: "สำหรับคุณ" +_announcement: + forExistingUsersDescription: "การประกาศนี้จะแสดงต่อผู้ใช้ที่มีอยู่ ณ จุดที่เผยแพร่นั้นๆถ้าหากเปิดใช้งาน ถ้าหากปิดใช้งานผู้ที่กำลังสมัครใหม่หลังจากโพสต์แล้วนั้นก็จะเห็นเช่นกัน" + needConfirmationToReadDescription: "ข้อความแจ้งแยก ถ้าหากต้องการเพื่อยืนยันว่ากำลังทำเครื่องหมายประกาศนี้ว่าอ่านแล้วจะแสดงขึ้นถ้าหากเปิดใช้งาน การประกาศนั้นจะไม่รวมอยู่ในฟังก์ชั่นว่า \"ทำเครื่องหมายทั้งหมดว่าอ่านแล้ว\"" + end: "ประกาศเก็บถาวร" + tooManyActiveAnnouncementDescription: "การมีประกาศที่ใช้งานมากเกินไปนั้นอาจจะทำให้ประสบการณ์ของผู้ใช้งานนั้นดูแย่ลง โปรดกรุณาพิจารณาการเก็บประกาศที่ล้าสมัยด้วยนะค่ะ" + readConfirmTitle: "ทำเครื่องหมายบอกว่าอ่านแล้วเลยมั้ย?" + readConfirmText: "การดำเนินการนี้จะทำเครื่องหมายเนื้อหาของ \"{title}\" บอกว่าอ่านแล้วนะ" _initialAccountSetting: accountCreated: "คุณได้สร้างบัญชีของคุณสำเร็จเรียบร้อยแล้ว!" letsStartAccountSetup: "สำหรับผู้เริ่มต้นมาตั้งค่าโปรไฟล์ของคุณกันเถอะ" @@ -1102,7 +1117,7 @@ _initialAccountSetting: followUsers: "ลองติดตามผู้ใช้บางคนที่คุณอาจจะสนใจเพื่อสร้างไทม์ไลน์ของคุณสิ !" pushNotificationDescription: "กำลังเปิดใช้งานการแจ้งเตือนแบบพุชจะช่วยให้คุณได้รับการแจ้งเตือนจาก {name} โดยตรงบนอุปกรณ์ของคุณนะ" initialAccountSettingCompleted: "ตั้งค่าโปรไฟล์เสร็จสมบูรณ์แล้ว!" - haveFun: "สนุกกับ {name}!" + haveFun: "ขอให้สนุก {name}!" ifYouNeedLearnMore: "ถ้าหากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับวิธีใช้ {ชื่อ} (Misskey) กรุณาไปที่ {link}" skipAreYouSure: "ต้องการข้ามการตั้งค่าโปรไฟล์จริงๆแบบนั้นหรอ?" laterAreYouSure: "ต้องการตั้งค่าโปรไฟล์ในภายหลังจริงๆอย่างงั้นหรอ?" @@ -1127,8 +1142,8 @@ _achievements: earnedAt: "ได้รับเมื่อ" _types: _notes1: - title: "เพียงแค่ตั้งค่า msky ของฉัน" - description: "โพสต์โน้ตครั้งแรกของคุณ" + title: "just setting up my msky" + description: "โพสต์โน้ตแรกของคุณ" flavor: "ขอให้มีช่วงเวลาที่ดีกับ Misskey นะคะ!" _notes10: title: "โน้ตบางอย่าง" @@ -1287,7 +1302,7 @@ _achievements: _iLoveMisskey: title: "ฉันรัก Misskey" description: "โพสต์ \"I ❤ #Misskey\"" - flavor: "ทีมผู้พัฒนา Misskey ได้ขอบคุณสำหรับการสนับสนุนของคุณ!" + flavor: "ขอบคุณที่ใช้ Misskey! by ทีมผู้พัฒนา" _foundTreasure: title: "ล่าสมบัติ" description: "คุณพบสมบัติที่ซ่อนอยู่" @@ -1295,7 +1310,7 @@ _achievements: title: "พักผ่อนสักหน่อย" description: "ใช้เวลา 30 นาทีบน Misskey" _client60min: - title: "ไม่พบ \"Miss\" ใน Misskey " + title: "ไม่มี \"Miss\" ใน Misskey " description: "เปิด Misskey ค้างไว้แล้วอย่างน้อย 60 นาที" _noteDeletedWithin1min: title: "ไม่เป็นไร" @@ -1444,7 +1459,7 @@ _sensitiveMediaDetection: _emailUnavailable: used: "ที่อยู่อีเมลนี้ได้ถูกใช้ไปแล้ว" format: "รูปแบบของที่อยู่อีเมลนี้ไม่ถูกต้อง" - disposable: "ที่อยู่อีเมลที่ใช้แล้วทิ้งนั้นไม่สามารถใช้ได้" + disposable: "ไม่สามารถใช้อีเมลชั่วคราวได้" mx: "เซิร์ฟเวอร์อีเมลนี้ไม่ถูกต้อง" smtp: "เซิร์ฟเวอร์อีเมลนี้ไม่มีการตอบสนอง" _ffVisibility: @@ -1514,9 +1529,9 @@ _aboutMisskey: contributors: "ผู้สนับสนุนหลัก" allContributors: "ผู้มีส่วนร่วมทั้งหมด" source: "ซอร์สโค้ด" - translation: "รับแปลภาษา Misskey" + translation: "แปลภาษา Misskey" donate: "บริจาคให้กับ Misskey" - morePatrons: "เราขอขอบคุณสำหรับความช่วยเหลือจากผู้ช่วยอื่นๆ ที่ไม่ได้ระบุไว้ที่นี่นะ ขอขอบคุณ! 🥰" + morePatrons: " ขอบคุณทุกท่านที่ร่วมกันช่วยเหลือตลอดมานะคะ 🥰" patrons: "สมาชิกพันธมิตร" _displayOfSensitiveMedia: respect: "ซ่อนสื่อทำเครื่องหมายบอกว่าละเอียดอ่อน" @@ -1765,7 +1780,7 @@ _widgets: photos: "รูปภาพ" digitalClock: "นาฬิกาดิจิตอล" unixClock: "นาฬิกา UNIX" - federation: "สหพันธ์" + federation: "Fediration" instanceCloud: "อินสแตนซ์คลาวด์" postForm: "แบบฟอร์มการโพสต์" slideshow: "แสดงภาพนิ่ง" @@ -1775,7 +1790,7 @@ _widgets: serverMetric: "ตัวชี้วัดเซิร์ฟเวอร์" aiscript: "AiScript คอนโซล" aiscriptApp: "AiScript แอพ" - aichan: "เอไอ" + aichan: "ไอ" userList: "รายชื่อผู้ใช้" _userList: chooseList: "เลือกรายการ" diff --git a/locales/tr-TR.yml b/locales/tr-TR.yml index 42cc7da3f8..d0b610917c 100644 --- a/locales/tr-TR.yml +++ b/locales/tr-TR.yml @@ -259,6 +259,7 @@ messaging: "Mesajlar" upload: "Yükle" keepOriginalUploading: "Orijinal görseli koru" keepOriginalUploadingDescription: "Orijinal olarak yüklenen görüntüyü olduğu gibi kaydeder. Kapatılırsa, yükleme sırasında web'de görüntülenecek bir sürüm oluşturulur." +fromDrive: "Drive Dosyasından" fromUrl: "Bağlantıdan" uploadFromUrl: "Bağlantıdan yükle" uploadFromUrlDescription: "Yüklemek istediğiniz dosyanın bağlantısı" @@ -305,12 +306,42 @@ renameFolder: "Klasörü Yeniden Adlandır" deleteFolder: "Klasörü sil" addFile: "Dosya ekle" emptyDrive: "Sürücü boş" +emptyFolder: "Bu klasör boş" +unableToDelete: "Silme mümkün değil" +inputNewFileName: "Yeni dosya ismini girin" +inputNewDescription: "Yeni bir başlık gir" +inputNewFolderName: "Yeni klasör ismini girin" +circularReferenceFolder: "Hedef klasör taşınan klasörün bir alt klasörü." hasChildFilesOrFolders: "Klasör boş olmadığından silinemiyor" +copyUrl: "URL'yi kopyala" +rename: "Yeniden adlandır" +avatar: "Avatar" +banner: "Banner" +displayOfSensitiveMedia: "Hassas içerik gösterimi" +whenServerDisconnected: "Sunucu bağlantısı kesildiğinde" +disconnectedFromServer: "Sunucu bağlantısı koptu" +reload: "Yenile" doNothing: "Bir şey yapma" reloadConfirm: "Zaman akışı yenilensin mi?" +watch: "İzle" +unwatch: "İzlemeyi bırak" +accept: "Kabul et" +reject: "Reddet" +normal: "Normal" +instanceName: "Sunucu ismi" +instanceDescription: "Sunucu açıklaması" maintainerName: "Yönetici ismi" +maintainerEmail: "Yöneticinin e-postası" +tosUrl: "Hizmet Koşulları Bağlantısı" +thisYear: "Bu yıl" +thisMonth: "Bu ay" +today: "Bugün" monthX: "{month} ay" +pages: "Sayfalar" +integration: "Entegrasyon" enableRegistration: "Kayıtlara izin ver" +basicInfo: "Temel bilgiler" +pinnedUsers: "Sabitlenmiş kullanıcılar" pinnedNotes: "Sabitlenen" manageAntennas: "Anten ayarları" userList: "Listeler" @@ -322,6 +353,7 @@ smtpHost: "Sağlayıcı" smtpUser: "Kullanıcı Adı" smtpPass: "Şifre" notificationSetting: "Bildirim ayarları" +instanceTicker: "Notların sunucu bilgileri" noCrawleDescription: "Arama motorlarından profilinde, notlarında, sayfalarında vb. dolaşılmamasını ve dizine eklememesini talep et." clearCache: "Ön belleği temizle" onlineUsersCount: "{n} kullanıcı çevrim içi" @@ -338,6 +370,7 @@ pushNotificationNotSupported: "Push bildirimleri sunucu veya tarayıcı tarafın noRole: "Rol bulunamadı" color: "Renk" addMemo: "Kısa not ekle" +icon: "Avatar" _accountDelete: started: "Silme işlemi başlatıldı" _email: diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 1ac07ff9b2..acd73b44e9 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -20,6 +20,7 @@ noNotes: "Немає нотаток" noNotifications: "Немає сповіщень" instance: "Інстанс" settings: "Налаштування" +notificationSettings: "Параметри сповіщень" basicSettings: "Основні налаштування" otherSettings: "Інші налаштування" openInWindow: "Відкрити у вікні" @@ -48,9 +49,12 @@ delete: "Видалити" deleteAndEdit: "Видалити й редагувати" deleteAndEditConfirm: "Ви впевнені, що хочете видалити цю нотатку та відредагувати її? Ви втратите всі реакції, поширення та відповіді на неї." addToList: "Додати до списку" +addToAntenna: "Додати в антени" sendMessage: "Надіслати повідомлення" copyRSS: "Скопіювати RSS" copyUsername: "Скопіювати ім’я користувача" +copyUserId: "Копіювати ID користувача" +copyNoteId: "блокнот ID користувача" searchUser: "Пошук користувачів" reply: "Відповісти" loadMore: "Показати більше" @@ -644,6 +648,7 @@ createNewClip: "Створити нотатку" unclip: "Незакріплений" confirmToUnclipAlreadyClippedNote: "Ця нотатка вже включена до кліпу \"{name}\". Ви хочете виключити нотатку з цього кліпу?" public: "Публічний" +private: "Приватне" i18nInfo: "Misskey перекладається на різні мови волонтерами. Ви можете допомогти: {link}" manageAccessTokens: "Керування токенами доступу" accountInfo: "Інформація про акаунт" @@ -900,6 +905,7 @@ exploreOtherServers: "Знайти інший сервер" letsLookAtTimeline: "Перегляд історії" horizontal: "Збоку" youFollowing: "Підписки" +icon: "Аватар" _achievements: earnedAt: "Відкрито" _types: diff --git a/locales/uz-UZ.yml b/locales/uz-UZ.yml new file mode 100644 index 0000000000..bd83fcb4ff --- /dev/null +++ b/locales/uz-UZ.yml @@ -0,0 +1,1083 @@ +--- +_lang_: "O'zbek tili" +headlineMisskey: "Qaydlar tarmog'i" +introMisskey: "Xush kelibsiz! Misskey ochiq kodli, markazlashmagan mikroblogging xizmati.\nO'zingizni fikrlaringizni atrofingizdagilar bilan ulashish uchun \"Qaydlar\" yarating. 📡\nUstiga-ustak, \"Reaktsiyalar\" yordamida siz boshqalarning xatlari haqidagi o'zingizni xissiyotlaringizni bildiring. 👍\nQani, yangi dunyoni kashf qilaylik! 🚀" +poweredByMisskeyDescription: "{name} ochiq manbali Misskey(\"Misskey instance\" deb ataladi) platformasi tomonidan qurilgan servislardan biri. " +monthAndDay: "{day}/{month}" +search: "Izlash" +notifications: "Xabarnomalar" +username: "Foydalanuvchi nomi" +password: "Parol" +forgotPassword: "Parolni unutib qo'ydim" +fetchingAsApObject: "Fediversedan olib kelinmoqda..." +ok: "Ho'p" +gotIt: "Tushunarli!" +cancel: "Bekor qilish" +noThankYou: "Hozir emas" +enterUsername: "Foydalanuvchini nomini kiriting" +renotedBy: "{user} tomonidan qayta qayd etildi" +noNotes: "Qaydlar mavjud emas" +noNotifications: "Xabarlar mavjud emas" +instance: "Server" +settings: "Sozlamalar" +notificationSettings: "Xabarnoma sozlamalari" +basicSettings: "Asosiy sozlamalar" +otherSettings: "Qo‘shimcha sozlamalar" +openInWindow: "Yangi oynada ochish" +profile: "Profil" +timeline: "Xronologiya" +noAccountDescription: "Ushbu foydalanuvchi hali o'zi haqida ma'lumot yozmagan." +login: "Kirish" +loggingIn: "Kirilmoqda" +logout: "Chiqish" +signup: "Ro'yxatdan o'tish" +uploading: "Yuklanmoqda..." +save: "Saqlash" +users: "Foydalanuvchilar" +addUser: "Foydalanuvchi qo'shish" +favorite: "Sevimli" +favorites: "Sevimlilar" +unfavorite: "Sevimlidan chiqarish" +favorited: "sevimli" +alreadyFavorited: "allaqachon sevimlilar orasida" +cantFavorite: "sevimlilarga qo'shib bo'lmadi" +pin: "Profilga qadab qo'yish" +unpin: "Profildan olib tashlash" +copyContent: "Tarkibini nusxalash" +copyLink: "Havolani nusxalash" +delete: "O'chirib tashlash" +deleteAndEdit: "O'chirish va tahrirlash" +deleteAndEditConfirm: "O'chirib, tahrirlamoqchiligingizga ishonchingiz komilmi? Siz bu qaydga tegishli barcha reaktsiyalar va javoblarni yo'qotasiz." +addToList: "Ro‘yxatga qo‘shish" +addToAntenna: "Antennaga qo'shish" +sendMessage: "Xabar yuborish" +copyRSS: "RSS'ni nusxalash" +copyUsername: "Foydalanuvchi nomini nusxalash" +copyUserId: "Foydalanuvchi IDsini nusxalash" +copyNoteId: "Qayd IDsini ko'chirish" +copyFileId: "Fayl ID raqamini nusxalash" +copyFolderId: "Jild ID raqamini nusxalash" +copyProfileUrl: "Profil manzilini nusxalash" +searchUser: "Foydalanuvchini izlash" +reply: "Javob berish" +loadMore: "Ko‘proq ko‘rish" +showMore: "Ko‘proq ko‘rish" +showLess: "Yopish" +youGotNewFollower: "sizga obuna bo'ldi" +receiveFollowRequest: "Obuna bo'lishga ruxsat qabul qilindi" +followRequestAccepted: "Obuna bo'lishga ruxsat berildi" +mention: "Murojat" +mentions: "Eslatib o'tish" +directNotes: "Bevosita qaydlar" +importAndExport: "Import/eksport" +import: "Import" +export: "Eksport" +files: "Fayllar" +download: "Yuklab olish" +driveFileDeleteConfirm: "\"{name}\" o'chirib tashlamoqchimisiz? Ushbu fayldan foydalanadigan har qanday kontent ham oʻchiriladi." +unfollowConfirm: "{name}ga obunani bekor qilmoqchimisiz?" +exportRequested: "Eksport so'raldi. Bu ozgina vaqt olishi mumkin. Tugatilgandan so'ng sizning Diskingizga qo'shiladi" +importRequested: "Import so'raldi. Bu ozgina vaqt olishi mumkin." +lists: "Ro'yxatlar" +noLists: "Hech qanday ro'yxatlar mavjud emas" +note: "Qayd" +notes: "Qaydlar" +following: "Obuna bo‘lish" +followers: "Obunachilar" +followsYou: "Sizning obunachingiz." +createList: "Ro'yxat yaratish" +manageLists: "Ro'yxatlarni boshqarish." +error: "Xato" +somethingHappened: "Xatolik yuz berdi" +retry: "Qayta urinib ko'rish" +pageLoadError: "Sahifani yuklayotganda xatolik yuz berdi" +pageLoadErrorDescription: "Buni odatda tarmoq muammolarni yoki browser keshi keltirib chiqaradi. Keshni tozalab, keyinroq urinib ko'ring" +serverIsDead: "Server javob bermayabdi. Iltimos kuting va keyinroq urinib ko'ring" +youShouldUpgradeClient: "Iltimos, ushbu sahifani ko'rish uchun sahifani yangilang." +enterListName: "Ro'yxatga nom kiriting" +privacy: "Maxfiylik" +makeFollowManuallyApprove: "Yopiq akkaunt" +defaultNoteVisibility: "Standart ko'rinish" +follow: "Obuna bo‘lish" +followRequest: "Obuna bo'lish uchun ruxsat olish" +followRequests: "Obuna bo'lmoqchilar" +unfollow: "obunani bekor qilish" +followRequestPending: "obuna bo'lishga ruxsat kutilmoqda" +enterEmoji: "Emojini kiriting" +renote: "Qayta qayd etish" +unrenote: "Qayta qayd etishni bekor qilish" +renoted: "Qayta qayd etildi" +cantRenote: "Qayta qayd etish mumkin emas" +cantReRenote: "Repostni qayta joylashtirish mumkin emas." +quote: "Iqtibos keltirish" +inChannelRenote: "Faqat kanalga qayta qayd etish" +inChannelQuote: "Kanaldagi eslatmalar" +pinnedNote: "Qadalgan qayd" +pinned: "Profilga qadab qo'yish" +you: "Siz" +clickToShow: "Ko'rsatish uchun bosing" +sensitive: "Sezuvchan" +add: "Qo'shish" +reaction: "Reaktsiyalar" +reactions: "Reaktsiyalar" +reactionSetting: "Reaksiyalar ro'yxati" +reactionSettingDescription2: "Qayta tartiblash uchun ushlab turib siljiting, oʻchirish uchun bosing, qoʻshish uchun “+” tugmasini bosing." +rememberNoteVisibility: "Qaydning ko'rinish sozlamarini eslab qolish" +attachCancel: "Qo'shimchani olib tashlash" +markAsSensitive: "\"Hamma ko'rishi mumkin emas\" deb belgilash" +unmarkAsSensitive: "\"Hamma ko'rishi mumkin\" deb belgilash" +enterFileName: "Fayl nomini kiriting" +mute: "Ovozni o‘chirish" +unmute: "Ovozni yoqish" +renoteMute: "Qayta qaydlarni ovozini o'chirish" +renoteUnmute: "Qayta qaydlarni ovozini yoqish" +block: "Bloklash" +unblock: "Blokdan chiqarish" +suspend: "To'xtatish" +unsuspend: "Blokdan chiqarish" +blockConfirm: "Haqiqatdan ham quyidagi hisobni bloklashni xohlaysizmi? " +unblockConfirm: "Haqiqatdan ham quyidagi hisobni blokdan chiqarishni xohlaysizmi? " +suspendConfirm: "Bu hisobni to‘xtatib qo‘ymoqchi ekanligingizga ishonchingiz komilmi?" +unsuspendConfirm: "Tasdiqlashni to'xtatib turish" +selectList: "Ro'yxat tanlash" +editList: "Roʻyxatni tahrirlash" +selectChannel: "Kanalni tanlang" +selectAntenna: "Antennani tanlang" +editAntenna: "Antennani tahrirlang" +selectWidget: "Vidjet tanlash" +editWidgets: "Vidjetni tahrirlash" +editWidgetsExit: "Tugadi" +customEmojis: "Maxsus emoji" +emoji: "Emoji" +emojis: "Emoji" +emojiName: "Emoji nomi" +emojiUrl: "Emoji URL'i" +addEmoji: "Emoji qo'shish" +settingGuide: "Tavsiya qilingan sozlamalar" +cacheRemoteFiles: "Tashqi fayllarni keshlash" +cacheRemoteFilesDescription: "Ushbu sozlama o'chirilgan bo'lsa tashqi fayllar bevosita tashqi serverdan yuklanadi. Buni o'chirish ombor ishlatilishini kamaytiradi, lekin traffikni ko'paytiradi, chunki eskizlar generatsiya qilinmaydi." +youCanCleanRemoteFilesCache: "Fayl menejeridagi 🗑️ tugmasi yordamida barcha keshlarni oʻchirib tashlashingiz mumkin." +cacheRemoteSensitiveFiles: "Tashqi fayllarni keshlash" +cacheRemoteSensitiveFilesDescription: "Bu sozlama oʻchiq boʻlsa, \"barcha ko'rishi mumkin bo'lmagan\" fayllar keshlashsiz toʻgʻridan-toʻgʻri masofaviy serverdan yuklanadi." +flagAsBot: "Ushbu akkauntni bot sifatida belgilash" +flagAsBotDescription: "Agar bu akkaunt bot tomonidan boshqaralayotgan bo'lsa, bu sozlamani yoqing. Sozlama yoqilganda, boshqa foydalanuvchilar uchun belgi sifatida ishlaydi, va Misskey ichki tizimlari bu akkauntni bot ekanini biladi." +flagAsCat: "Bu akkauntni mushuk sifatida belgilash" +flagAsCatDescription: "Ushbu akkauntni mushuk sifatida belgilash uchun ushbu sozlamani yoqing." +flagShowTimelineReplies: "Javoblarni xronogoliya bo'yicha ko'rsatish" +flagShowTimelineRepliesDescription: "Bu parametr yoqilganda, lentada foydalanuvchi xabarlariga javob berilgan xabarlar ham ko'rinadi" +autoAcceptFollowed: "Obunachilarni avtomatik ravishda qabul qilish" +addAccount: "Akkaunt qo'shish" +reloadAccountsList: "Hisoblar ro'yxatini yangilash" +loginFailed: "Tizimga kirishda xatolik yuz berdi" +showOnRemote: "Masofaviy boshqaruvni ko'rish" +general: "Asosiy" +wallpaper: "Fon rasmi" +setWallpaper: "Fon rasmini o'rnatish" +removeWallpaper: "Fon rasmini olib tashlash" +searchWith: "Izlash: {q}" +youHaveNoLists: "Sizda hech qanday ro'yxatlar mavjud emas" +followConfirm: "{name} ga obuna bo'lmoqchimisiz?" +proxyAccount: "Proksi hisob" +proxyAccountDescription: "Proksi-hisob qaydnomasi - bu ma'lum shartlar ostida foydalanuvchi uchun masofaviy kuzatuvchi sifatida ishlaydigan hisob. Misol uchun, foydalanuvchi uzoq foydalanuvchini roʻyxatga qoʻyganda, roʻyxatdagi foydalanuvchini hech kim kuzatib turmasa, faoliyat serverga yetkazilmaydi, shuning uchun biz proksi hisobi ularning oʻrniga ularni kuzatishini xohlaymiz." +host: "Host" +selectUser: "Foydalanuvchini tanlang" +recipient: "Qabul qiluvchi" +annotation: "Izohlar" +federation: "Federatsiya" +instances: "Serverlar" +registeredAt: "Ro'yhatdan o'tgan" +latestRequestReceivedAt: "Oxirgi qabul qilingan so'rov" +latestStatus: "So'nggi holat" +storageUsage: "Ishlatilgan xotira" +charts: "Diagrammalar" +perHour: "Soatbay" +perDay: "Kunbay" +stopActivityDelivery: "Faollikni jo'natishi to'xtatish" +blockThisInstance: "Ko;rsatilgan serverni bloklash" +operations: "Amallar" +software: "Dastur" +version: "Versiya" +metadata: "Meta ma'lumot" +withNFiles: "{n} ta fayl(lar)" +monitor: "Kuzatish" +jobQueue: "Vazifalar navbati" +cpuAndMemory: "CPU va Xotira" +network: "Tarmoq" +disk: "Disk" +instanceInfo: "Instans haqida ma'lumot" +statistics: "Statistika" +clearQueue: "Navbatni tozalash" +clearQueueConfirmTitle: "Navbatni tozalamoqchimisiz?" +clearQueueConfirmText: "Yetkazib berilmagan xabarlar yetkazilmaydi. Odatda buni qilish shart emas." +clearCachedFiles: "Keshni tozalash" +clearCachedFilesConfirm: "Barcha keshlangan masofaviy fayllar oʻchirilsinmi?" +blockedInstances: "Bloklangan serverlar" +blockedInstancesDescription: "Bloklanmoqchi bo'lgan serverlaringiz hostlarini yangi qatorlar bilan ajrating. Bloklangan server bu server bilan o‘zaro aloqada bo‘lmaydi. Subdomenlar ham bloklangan." +muteAndBlock: "Ovozsiz va Bloklangan" +mutedUsers: "Ovozsiz foydalanuvchilar" +blockedUsers: "Bloklangan foydalanuvchilar" +noUsers: "Foydalanuvchilar yo‘q" +editProfile: "Profilni o'zgartirish" +noteDeleteConfirm: "Haqiqatan ham bu qaydni oʻchirib tashlamoqchimisiz?" +pinLimitExceeded: "Siz boshqa qaydlarni mahkamlay olmaysiz" +intro: "Misskeyni o'rnatish tugallandi! Iltimos, administrator foydalanuvchi yarating." +done: "Bajarildi" +processing: "Amaliyotda" +preview: "Ko'rish" +default: "Odatiy" +defaultValueIs: "Sukut bo'yicha: {value}" +noCustomEmojis: "Emojilar mavjud emas" +noJobs: "Vazifalar yo'q" +federating: "Ittifoqdosh" +blocked: "Bloklangan" +suspended: "To'xtatilgan" +all: "Barcha" +subscribing: "Obuna bo'lish" +publishing: "Yuborilmoqda" +notResponding: "Javob bermayapti" +instanceFollowing: "server obuna bo'ladi" +instanceFollowers: "server obunachisi" +instanceUsers: "server foydalanuvchisi" +changePassword: "Parolni o‘zgartirish" +security: "Xavfsizlik" +retypedNotMatch: "Maydonlar mos kelmayapti" +currentPassword: "Joriy parol" +newPassword: "Yangi parol" +newPasswordRetype: "Yangi parolni boshqatdan tering" +attachFile: "Fayl biriktirish" +more: "Ko'proq!" +featured: "ta'kidlash" +usernameOrUserId: "Foydalanuvchi nomi yoki identifikatori" +noSuchUser: "Foydalanuvchi topilmadi" +lookup: "So'rov" +announcements: "Bildirishnomalar" +imageUrl: "Rasm URL" +remove: "O'chirib tashlash" +removed: "Muvaffaqiyatli o'chirildi" +removeAreYouSure: "“{x}”ni olib tashlamoqchi ekanligingizga ishonchingiz komilmi?" +deleteAreYouSure: "“{x}”ni chindan ham yo'q qilmoqchimisiz?" +resetAreYouSure: "Haqiqatan ham qayta tiklansinmi?" +saved: "Saqlandi" +messaging: "Suhbat" +upload: "Yuklash" +keepOriginalUploading: "Asl rasmni saqlang" +keepOriginalUploadingDescription: "Rasmlarni yuklashda asl nusxasini saqlaydi. Agar o'chirilgan bo'lsa, brauzer yuklangandan keyin nashr qilish uchun rasm yaratadi." +fromDrive: "Drive orqali" +fromUrl: "URL dan" +uploadFromUrl: "URL orqali yuklash" +uploadFromUrlDescription: "Yuklamoqchi bo'lgan faylingizga havola" +uploadFromUrlRequested: "yuklab olish so'ralgan" +uploadFromUrlMayTakeTime: "Yuklash tugallanishi uchun biroz vaqt ketishi mumkin." +explore: "Ko'rib chiqish" +messageRead: "O‘qildi" +noMoreHistory: "Buning ortida hech qanday hikoya yo'q" +startMessaging: "Yangi suhbatni boshlash" +nUsersRead: "{n} tomonidan o'qildi" +agreeTo: "Men {0} ga roziman" +agree: "Rozi bo'lish" +agreeBelow: "Men quyidagilarga roziman" +basicNotesBeforeCreateAccount: "Muhim qaydlar" +termsOfService: "Foydalanish shartlari" +start: "Boshlash" +home: "Bosh sahifa" +remoteUserCaution: "Bu foydalanuvchi uzoqda bo'lganligi sababli, ko'rsatilgan ma'lumotlar to'liq bo'lmasligi mumkin." +activity: "Faollik" +images: "Rasmlar" +image: "Rasm" +birthday: "Tug'ilgan kun" +yearsOld: "{age} yashar" +registeredDate: "Ro'yxatdan o'tgan sanasi" +location: "Manzil" +theme: "Rang sxemasi" +themeForLightMode: "Yorug' rejim uchun rang sxemasi" +themeForDarkMode: "Qorong'i rejim uchun rang sxemasi" +light: "Yorug'" +dark: "Qorongʻi" +lightThemes: "Yorug‘ rang sxemasi" +darkThemes: "Qorong'i rang sxemasi" +syncDeviceDarkMode: "Qurilmangizning qorong‘i rejimi bilan sinxronlashtiring" +drive: "Disk" +fileName: "Fayl nomi" +selectFile: "Faylni tanlang" +selectFiles: "Fayllarni tanlang" +selectFolder: "Jildni tanlang" +selectFolders: "Jildlarni tanlang" +renameFile: "Faylni nomini tahrirlash" +folderName: "Jild nomi" +createFolder: "Papka qo'shish" +renameFolder: "Papka nomini o‘zgartirish" +deleteFolder: "Papkani o‘chirish" +addFile: "Fayl qo‘shish" +emptyDrive: "Diskingiz bo'sh" +emptyFolder: "Ushbu papka bo'sh" +unableToDelete: "O'chirilmadi" +inputNewFileName: "Yangi fayl nomini kiriting" +inputNewDescription: "Iltimos, yangi sarlavha kiriting." +inputNewFolderName: "Yangi papka nomini kiriting" +circularReferenceFolder: "Belgilangan papka siz ko'chirmoqchi bo'lgan jildning pastki jildidir." +hasChildFilesOrFolders: "Bu papka boʻsh emas va uni oʻchirib boʻlmaydi." +copyUrl: "Bog'lamadan nusxa olish" +rename: "Qayta nomlash" +avatar: "Avatar" +banner: "Banner" +displayOfSensitiveMedia: "Nozik kontentni ko'rish" +whenServerDisconnected: "server bilan aloqa uzilganda" +disconnectedFromServer: "Server bilan ulanish uzulib qoldi" +reload: "Yangilash" +doNothing: "E'tiborsiz qoldirish" +reloadConfirm: "Timeline'ni yangilashni xohlaysizmi?" +watch: "Kuzatmoq" +unwatch: "Kuzatishni to'xtatish" +accept: "Ruxsat" +reject: "Rad etish" +normal: "Yaxshi" +instanceName: "Server nomi" +instanceDescription: "Server tavsifi" +maintainerName: "Qo'llab-quvvatlovchi" +maintainerEmail: "Administratorning elektron pochtasi" +tosUrl: "Foydalanish shartlariga havola" +thisYear: "Joriy yil" +thisMonth: "Shu oy" +today: "Bugun" +dayX: "{day}" +monthX: "{month}" +yearX: "{year}" +pages: "Sahifalar" +integration: "Integratsiya" +connectService: "Ulash" +disconnectService: "Uzish" +enableLocalTimeline: "Mahalliy vaqt mintaqasini yoqing" +enableGlobalTimeline: "Global vaqt mintaqasini yoqing" +disablingTimelinesInfo: "Administratorlar va Moderatorlar har doim barcha vaqt jadvallariga kirish huquqiga ega bo'ladilar, hatto ular yoqilmagan bo'lsa ham." +registration: "Ro'yxatdan o'tish" +enableRegistration: "Ro'yxatdan o'tishni yoqing" +invite: "Taklif qilish" +driveCapacityPerLocalAccount: "Har bir mahalliy foydalanuvchi uchun disk maydoni" +driveCapacityPerRemoteAccount: "Har bir masofaviy foydalanuvchi uchun disk maydoni" +inMb: "Megabaytlarda" +iconUrl: "Ikonkaning URL manzili (masalan: favicon)" +bannerUrl: "Banner URLi" +backgroundImageUrl: "Fon rasmi URL manzili" +basicInfo: "Asosiy ma'lumot" +pinnedUsers: "Qadalgan foydalanuvchilar" +pinnedUsersDescription: "Har bir qatorga bitta foydalanuvchi nomini kiriting. Bu yerda sanab oʻtilgan foydalanuvchilar “Oʻrganish” yorligʻiga bogʻlanadi." +pinnedPages: "Qadalgan Sahifalar" +pinnedClipId: "Qadalgan xabar IDsi" +pinnedNotes: "Qadalgan qayd" +hcaptcha: "hCaptcha" +enableHcaptcha: "hCaptchani yoqish" +hcaptchaSiteKey: "Sayt kaliti" +hcaptchaSecretKey: "Mahfiy kalit" +recaptcha: "reCAPTCHA" +enableRecaptcha: "reCAPTCHA ni yoqish" +recaptchaSiteKey: "Sayt kaliti" +recaptchaSecretKey: "Maxfiy kalit" +turnstile: "Turniket" +enableTurnstile: "Turniketni yoqish" +turnstileSiteKey: "Sayt kaliti" +turnstileSecretKey: "Maxfiy kalit" +avoidMultiCaptchaConfirm: "\nBir nechta Captcha tizimlaridan foydalanish ular o'rtasida noqulaylik olib kelishi mumkin. Hozirda faol bo'lgan boshqa Captcha tizimlarini o'chirib qo'ymoqchimisiz? Agar siz ularning faol bo'lishini istasangiz, bekor qilish tugmasini bosing." +antennas: "Antennalar" +manageAntennas: "Antennalarni boshqarish" +name: "Ism" +antennaSource: "Antenna manbai" +antennaKeywords: "Kalit so'zni qabul qilish" +antennaExcludeKeywords: "Istisno qilingan kalit so'zlar" +antennaKeywordsDescription: "VA sharti uchun bo'shliqlar bilan yoki YOKI sharti uchun qator uzilishlari bilan ajrating." +notifyAntenna: "Yangi qaydlar haqida menga xabar bering" +withFileAntenna: "Faqatgina fayli bor qaydlar" +enableServiceworker: "Bildirish nomalarni olish" +antennaUsersDescription: "Har bir foydalunvchi nomini alohida qatorga yozing" +caseSensitive: "Katta-kichik harfni farqlash" +withReplies: "Javob yo'llash" +connectedTo: "Quyidagi akkountlarga ulangan" +notesAndReplies: "Qaydlar va javoblar" +withFiles: "Fayllar" +silence: "Jim qilish" +silenceConfirm: "Rostdan ham ushbu foydalanuvchini jim qilmoqchimisiz?" +unsilence: "Jim qilishni bekor qilish" +unsilenceConfirm: "Rostdan ham ushbu foydalanuvchini ovozsiz \nqilmoqchimisiz?" +popularUsers: "Mashhur foydalanuvchilar." +recentlyUpdatedUsers: "Yaqinda ro'yxatdan o'tgan foydalanuvchilar" +recentlyRegisteredUsers: "Yaqinda ro'yxatdan o'tgan foydalanuvchilar" +recentlyDiscoveredUsers: "Yangi foydalanuvchilar" +exploreUsersCount: "{count} ta foydalanuvchi bor" +exploreFediverse: "Fediversni ko'rib chiqing" +popularTags: "Ommabop teglar" +userList: "Ro'yxatlar" +about: "Haqida" +aboutMisskey: "Misskey haqida" +administrator: "Administrator" +token: "Tasdiqlash" +2fa: "Ikki faktorli autentifikatsiya" +totp: "Autentifikatsiya ilovasi" +totpDescription: "Bir martalik parollarni kiritish uchun autentifikatsiya ilovasidan foydalaning" +moderator: "Moderator" +moderation: "Moderatsiya" +nUsersMentioned: "{n} tomonidan chop etilgan" +securityKeyAndPasskey: "Xavfsizlik kaliti va maxfiy so'z" +securityKey: "Xavfsizlik kaliti" +lastUsed: "Oxirgi marta foydalanilgan" +lastUsedAt: "Oxirgi marta {t} da foydalanilgan" +unregister: "ro'yxatdan chiqarish" +passwordLessLogin: "Parolsiz kirshni sozlash" +passwordLessLoginDescription: "Parolsiz kirish" +resetPassword: "Parolni tiklash" +newPasswordIs: "Yangi parolingiz {password}" +reduceUiAnimation: "Interfeysdagi animatsiyani kamaytirish" +share: "Yuborish" +notFound: "Topilmadi" +notFoundDescription: "Ushbu sahifa topilmadi" +uploadFolder: "Jildni yuklash" +cacheClear: "Keshni tozalash" +markAsReadAllNotifications: "Bildirishnomalarni o'qilgan deb belgilash" +markAsReadAllUnreadNotes: "Barch xabarlarni oq'ilgan deb belgilash" +markAsReadAllTalkMessages: "Barcha suhbatlarni o'qilgan deb belgilang" +help: "Yordam" +inputMessageHere: "Xabar kiriting" +close: "Yopish" +invites: "Taklif qilish" +members: "A'zolar" +transfer: "topshiriq" +title: "Sarlavha" +text: "Matn" +enable: "Yoqish" +next: "Keyingisi" +retype: "Qayta kiriting" +noteOf: "{user} tomonidan joylandi\n" +quoteAttached: "Iqtibos" +quoteQuestion: "Iqtibos sifatida qo'shilsinmi?" +noMessagesYet: "Bu yerda xabarlar yo'q" +newMessageExists: "Yangi xabarlar bor" +onlyOneFileCanBeAttached: "Faqat bitta faylni biriktirish mumkin" +signinRequired: "Davom etishdan oldin ro'yhatdan o'tishingiz yoki tizimga kirishingiz kerak" +invitations: "Taklif qilish" +invitationCode: "taklif qilish kodi" +checking: "Tekshirilmoqda" +available: "Mavjud" +unavailable: "Mavjud emas" +usernameInvalidFormat: "Siz a~z, A~Z, 0~9, _ dan foydalanishingiz mumkin" +tooShort: "Juda qisqa" +tooLong: "juda uzun" +weakPassword: "Zaif parol" +normalPassword: "Oddiy parol" +strongPassword: "Kuchli parol" +passwordMatched: "Mos keldi" +passwordNotMatched: "mos kelmadi" +signinWith: "{x} bilan tizimga kirish" +signinFailed: "Tizimga kirishda xatolik yuz berdi. Iltimos, foydalanuvchi nomingiz va parolingizni tekshiring." +or: "yoki" +language: "til" +uiLanguage: "Interfeys tili" +aboutX: "{x} haqida" +emojiStyle: "Emoji ko'rinishi" +native: "Mahalliy" +disableDrawer: "Slayd menyusidan foydalanmang" +showNoteActionsOnlyHover: "Eslatma amallarini faqat sichqonchani olib borganda ko‘rsatish" +noHistory: "Tarix yo'q" +signinHistory: "kirish tarixi" +enableAdvancedMfm: "MFMni faollashtirish" +doing: "Bajarilmoqda..." +category: "kategoriya" +tags: "teg" +docSource: "Ushbu hujjatning manbasi" +createAccount: "Akkaunt yaratish" +existingAccount: "mavjud akkaunt" +regenerate: "regeneratsiya" +fontSize: "shrift hajmi" +limitTo: "{x} gacha" +noFollowRequests: "obuna uchun so'rov yo'q" +openImageInNewTab: "Rasmni boshqa oynada ochish" +dashboard: "Boshqaruv paneli" +local: "Mahalliy" +remote: "masofaviy" +total: "Jami" +weekOverWeekChanges: "Oxirgi haftadagi o'zgarishlar" +dayOverDayChanges: "Kecha bo'lgan o'zgarishlar" +appearance: "Tasgqi ko'rinish" +clientSettings: "Klient sozlamalari" +accountSettings: "Profil sozlamalari" +promotion: "rag'batlantirish" +promote: "targ'ib qilish" +numberOfDays: "kunlar soni" +hideThisNote: "bu eslatmani yashiring" +showFeaturedNotesInTimeline: "Tanlangan qaydlarni Timelineda ko'rsatish" +objectStorage: "ob'ektni saqlash" +useObjectStorage: "Ob'ektni saqlashdan foydalaning" +objectStorageBaseUrl: "Asosiy URL" +objectStorageBaseUrlDesc: "Malumot va foydalanish uchun URL. Agar siz CDN yoki proksi-serverdan foydalanayotgan bo'lsangiz, URL manzili, S3: 'https://.s3.amazonaws.com', GCS va boshqalar: 'https://storage.googleapis.com/'." +objectStorageBucket: "Bucket" +objectStorageBucketDesc: "Iltimos, foydalaniladigan xizmatning bucket nomini belgilang." +objectStoragePrefix: "Prefix" +objectStorageEndpoint: "Endpoint" +objectStorageRegion: "Mintaqa" +objectStorageRegionDesc: "'xx-east-1' kabi mintaqani belgilang. Agar xizmatingizda mintaqa tushunchasi bo'lmasa, `us-east-1` dan foydalaning. AWS konfiguratsiya fayllari yoki muhit oʻzgaruvchilariga havola qilishda boʻsh qoldiring." +objectStorageUseSSL: "SSL dan foydalaning" +objectStorageUseSSLDesc: "API ulanishlari uchun https dan foydalanmasangiz, belgini olib tashlang" +objectStorageUseProxy: "Proksi-serverdan foydalaning" +objectStorageUseProxyDesc: "Proksi-serverdan foydalanishni xohlamasangiz, uni o'chiring" +objectStorageSetPublicRead: "Yuklashda \"public-read\" ni o'rnating" +serverLogs: "Server protokoli" +deleteAll: "Hammasini o'chirib tashlash" +showFixedPostForm: "Taqdim etish shaklini vaqt jadvalining yuqori qismida ko'rsating" +newNoteRecived: "Yangi qaydlar mavjud emas" +sounds: "Tovushlar" +sound: "ovoz" +listen: "Eshitish" +none: "Hechnima" +showInPage: "Sahifada ko'rsatish" +popout: "Oching" +volume: "Ovoz balandligi" +details: "Batafsil" +chooseEmoji: "Emojini tanlang" +unableToProcess: "Opertsiya bajarilmadi" +recentUsed: "Oxirgi ishlatilganlar" +install: "O‘rnatish" +uninstall: "O‘chirib tashlash" +installedApps: "O'rnatilgan ilovalar" +nothing: "Hech narsa yo'q" +installedDate: "O'rnatish sanasi" +lastUsedDate: "Oxirgi marta ishlatilgan sana" +state: "Holat" +sort: "saralamoq" +ascendingOrder: "O'sish bo'yicha" +descendingOrder: "Kamayish bo'yicha" +scratchpad: "Qoralama" +output: "Chiqish" +script: "Skript" +disablePagesScript: "AiScriptni sahifalardan o'chirish" +updateRemoteUser: "Masofaviy foydalanuvchi ma'lumotlarini yangilash" +deleteAllFiles: "barcha fayllarni o'chirish" +deleteAllFilesConfirm: "Barcha fayllar oʻchirilsinmi?" +removeAllFollowing: "Barcha obunalarni o'chirish" +userSuspended: "Bu foydalanuvchi muzlatilgan." +userSilenced: "Ushbu foydalanuvchi jim qilingan" +yourAccountSuspendedTitle: "akkaunt muzlatilgan" +yourAccountSuspendedDescription: "Ushbu akkaunt serverning xizmat ko'rsatish shartlarini buzish kabi sabablarga ko'ra to'xtatilgan. Tafsilotlar uchun administratoringizga murojaat qiling. Iltimos, yangi akkaunt yaratmang." +tokenRevoked: "token yaroqsiz" +tokenRevokedDescription: "Kirish tokeningizni muddati tugagan. Iltimos, qaytadan kiring." +accountDeleted: "akkaunt o'chirildi" +accountDeletedDescription: "Bu akkaunt oʻchirildi." +menu: "Menyu" +divider: "Ajratrmoq" +addItem: "Element qo'shish" +rearrange: "Qayta saralash" +inboxUrl: "Qabul qilingan xabarlar URL manzili" +serviceworkerInfo: "bildirishnomalar uchun yoqilgan bo'lishi kerak." +deletedNote: "Oʻchirilgan post" +visibility: "Ko'rinishi" +poll: "So'ro'vnoma" +useCw: "Kontentni yashirish" +enablePlayer: "Video pleyerni ochish" +disablePlayer: "Video pleyerni yopish" +expandTweet: "Xabarni kengaytirish" +themeEditor: "Rang sxemasi muharriri" +description: "tavsif" +describeFile: "sarlavha qo'shing" +enterFileDescription: "sarlavha kiriting" +author: "muallif" +leaveConfirm: "Sizda saqlanmagan oʻzgarishlar bor. Bekor qilinsinmi?" +manage: "Administratsiya" +plugins: "Kengaytmalar, plaginlar" +preferencesBackups: "Sozlamalarni zahiralash" +useBlurEffectForModal: "Modal uchun xiralashtirish effektidan foydalaning" +useFullReactionPicker: "Katta oynada reaksiya tanlash" +width: "kengligi" +height: "balandligi" +large: "Katta" +medium: "O'rta" +small: "kichik" +generateAccessToken: "Kirish tokenini yaratish" +permission: "Ruxsatlar" +enableAll: "Yoqish" +disableAll: "hammasini o'chirib qo'ying" +tokenRequested: "Hisobga kirish" +pluginTokenRequestedDescription: "Bu plagin shu yerda belgilanganlarga qodir bo'ladi" +notificationType: "Bildirishnoma turi" +edit: "Tahrirlash" +emailServer: "Email server" +email: "Email" +emailAddress: "E-pochtangiz:" +smtpConfig: "SMTP server sozlamalari" +smtpHost: "Host" +smtpPort: "Port" +smtpUser: "Foydalanuvchi nomi" +smtpPass: "Parol" +testEmail: "Email jo'natmani testlash" +userSaysSomething: "{name} nimadir dedi" +makeActive: "Faol" +display: "Displey" +copy: "Nusxa olish" +metrics: "Metrikalar" +overview: "Umumiy ma'lumot" +logs: "Jurnallar" +delayed: "Kechiktirildi" +database: "Ma'lumotlar bazasi" +channel: "Kanallar" +create: "Yaratish" +notificationSetting: "Bildirishnoma sozlamalari" +notificationSettingDesc: "Ko'rsatish uchun bildirishnoma turlarini tanlang." +useGlobalSetting: "Global sozlamalardan foydalanish" +other: "Qo‘shimcha" +regenerateLoginToken: "Kirish tokenini qayta yaratish" +setMultipleBySeparatingWithSpace: "Bo'sh joy qoldirib, bir necha ma'lumot kiritish mumkin" +fileIdOrUrl: "Fayl ID'si yoki URL havolasi" +behavior: "Hatti-harakatlar" +sample: "Namuna" +abuseReports: "Shikoyatlar" +reportAbuse: "Shikoyat qilish" +reportAbuseOf: "{name} ustidan shikoyat qilish" +abuseReported: "Shikoyatingiz yetkazildi. Ma'lumot uchun rahmat." +reporter: "Shikoyat qiluvchi" +reporteeOrigin: "Xabarning kelib chiqishi" +reporterOrigin: "Xabarchining joylashuvi" +forwardReport: "Xabarni masofadagi serverga yuborish" +forwardReportIsAnonymous: "Sizning yuborayotgan xabaringiz o'z akkountingiz emas balki anonim tarzda qoladi" +send: "Yuborish" +abuseMarkAsResolved: "Yuborilgan xabarni hal qilingan deb belgilash" +openInNewTab: "Yangi tab da ochish" +openInSideView: "Yon panelda ochish" +defaultNavigationBehaviour: "Standart navigatsiya harakati" +editTheseSettingsMayBreakAccount: "Bu sozlamalarni o'zgartirish hisobingizga zarar yetkazishi mumkin." +waitingFor: "{x}ni kutayapman" +random: "Tasodifiy" +system: "Tizim" +switchUi: "Interfeysni almashtirish" +desktop: "Brauzer rejimi" +clip: "Klip" +createNew: "Yangi yaratish" +optional: "Ixtiyoriy" +createNewClip: "Yangi klip yaratish" +unclip: "qirqish\n" +confirmToUnclipAlreadyClippedNote: "Ushbu xat allaqachon \"{name}\" klipga tegishli. Uni ushbu klipdan olib tashlashni xohlaysizmi?" +public: "Ommaviy" +i18nInfo: "Misskey bir qancha volontyorlar yordamida bir qancha tillarga tarjima qilingan. Ushbu {link} orqali ularga yordam berishingiz mumkin." +manageAccessTokens: "Kirish tokenlarini boshqarish" +accountInfo: "Akkount haqida ma'lumot" +notesCount: "Xatlar soni" +repliesCount: "Yuborilgan javoblar soni" +renotesCount: "Qayta yuborilgan xatlar soni" +repliedCount: "Qabul qilingan javoblar soni" +renotedCount: "Qayta yuborilgan xatlar soni" +followingCount: "Obuna bo'lingan akkountlar soni" +followersCount: "Obunachilar soni" +sentReactionsCount: "Yuborilgan reaksiyalar soni" +receivedReactionsCount: "Qabul qilingan reaksiyalar soni" +pollVotesCount: "Berilgan ovozlar soni" +pollVotedCount: "Qabul qilingan ovozlar soni" +yes: "Ha" +no: "Yo'q" +driveFilesCount: "Diskdagi fayllar soni" +driveUsage: "Ishlatilgan disk joyi" +noCrawleDescription: "Qidiruv tizimlari sizning profilingiz, sahifalaringiz, xatlaringiz va hokazolarni belgilamasligi uchun so'rov yuborish" +lockedAccountInfo: "Xatlaringizni faqatgina obunachilaringizga ko'rsatishni xohlasangiz unda \"Faqat Obunachilar uchun\" xususiyatini yoqishingiz lozim. Bo'lmasa sizning yozgan xatlaringiz hammaga ko'rinadi." +alwaysMarkSensitive: "Avvaldan ta'sirchan kontent deb belgilash" +loadRawImages: "Thumbnaillarsiz Original rasmni yuklash" +disableShowingAnimatedImages: "Animatsiyali rasmlarni ko'rsatmaslik" +verificationEmailSent: "Emailingizga tasdiqlash xabari yuborildi. Iltimos linkda ko'rsatilgan amallarga rioya qiling" +notSet: "Sozlanmagan" +emailVerified: "Elektron pochta manzili tasdiqlandi" +pageLikesCount: "Sahifadagi like'lar soni" +contact: "aloqa uchun manzil" +useSystemFont: "Tizimdagi standart shriftidan foydalaning" +clips: "Klip" +experimentalFeatures: "eksperimental xususiyatlar" +experimental: "eksperimental" +developer: "Dasturchi" +makeExplorable: "Akkauntingizni topishni osonlashtiring" +duplicate: "Dublikat" +left: "Chap(dagi)" +center: "Markaz" +wide: "Keng" +narrow: "Tor" +reloadToApplySetting: "Bu sozlamalar sahifa yangilangandagina kuchga kiradi. Hozir yangilashni istaysizmi?" +needReloadToApply: "Sahifani yangilash talab etiladi." +clearCache: "Keshni tozalash" +onlineUsersCount: "Faol userlar" +nUsers: "{n} ta foydalanuvchi" +myTheme: "Mening rang sxemam" +backgroundColor: "Fon" +accentColor: "Urg'u" +textColor: "Matn" +advanced: "Murakkab" +advancedSettings: "Qo'shimcha sozlashlar" +value: "Qiymati" +createdAt: "Yaratilish vaqti" +updatedAt: "yangilangan sana" +saveConfirm: "O'zgartirishni saqlash?" +deleteConfirm: "o'chirishni tasdiqlash" +invalidValue: "noto'g'ri qiymat" +registry: "ro'yhatga olish" +closeAccount: "hisobni yopish / profilni yopish" +currentVersion: "joriy versiya" +latestVersion: "so'ngi versiya" +youAreRunningUpToDateClient: "siz so'ngi versiyali ilovani ishlatyapsiz" +newVersionOfClientAvailable: "Mijozning yangi versiyasi mavjud." +usageAmount: "foydalanish miqdori" +capacity: "sig'im" +inUse: "allaqachon band" +editCode: "kodni tahrirlash" +apply: "Ilova" +receiveAnnouncementFromInstance: "Serverdan bildirishnomalarni oling" +emailNotification: "E-mail xabarlari" +publish: "Chiqarish" +inChannelSearch: "Kanal qidirish" +useReactionPickerForContextMenu: "kontekst menyusi uchun reaktsiya tanlash vositasidan foydalaning" +typingUsers: "{users} yozmoqda" +jumpToSpecifiedDate: "Muayyan sanaga o'tish" +clear: "aniq" +markAllAsRead: "hammasini o'qilgan deb belgilang" +goBack: "qaytish" +unlikeConfirm: "Un like qilishni xohlaysizmi?" +fullView: "to'liq ko'rish" +quitFullView: "Toʻliq koʻrishdan chiqish" +addDescription: "Tavsif qo'shing" +info: "Haqida" +userInfo: "Foydalanuvchi ma'lumotlari" +unknown: "aniq emas" +onlineStatus: "onlayn holat" +hideOnlineStatus: "onlayn holatni yashirish" +hideOnlineStatusDescription: "Onlayn statusingizni yashirish, qidiruv kabi baʼzi funksiyalardan foydalanish imkoniyatini kamaytirishi mumkin." +online: "onlayn" +active: "Aktiv" +offline: "oflayn" +notRecommended: "tavsiya etilmaydi" +selectAccount: "Akkauntni tanlang" +switchAccount: "akkauntni almashtirish" +enabled: "yaroqli" +disabled: "yaroqsiz" +quickAction: "tezkor harakat" +user: "Foydalanuvchilar" +administration: "Administratsiya" +accounts: "akkaunt" +switch: "almashtirish" +noBotProtectionWarning: "Bot himoyasi sozlanmagan." +configure: "sozlamoq" +postToGallery: "Yangi galleriya posti" +gallery: "Galereya" +recentPosts: "So'nggi postlar" +popularPosts: "Mashhur postlar" +shareWithNote: "Eslatmani ulashish" +ads: "Reklama" +startingperiod: "Boshlanish davri" +memo: "Eslatma" +priority: "Ustuvorlik" +high: "Yuqori" +middle: "O'rta" +low: "Quyi" +ratio: "nisbat" +previewNoteText: "Razm solish" +customCss: "Maxsus CSS" +global: "Global" +squareAvatars: "Kvadrat avatarkalar" +sent: "Yuborish" +received: "Qabul qilingan" +searchResult: "Qidiruv natijalari" +hashtags: "Hashteglar" +troubleshooting: "Muammolarni bartaraf qilish" +useBlurEffect: "Interfeysda xiralashtiruvchi effektlardan foydalanish" +learnMore: "Batafsilroq" +misskeyUpdated: "Misskey yangilandi!" +whatIsNew: "O'zgarishlarni ko'rish" +translate: "Tarjima qilish" +translatedFrom: "{x} tilidan tarjima qilindi" +devMode: "Dasturchi rejimi" +lastCommunication: "Oxirgi muloqot" +resolved: "Hal qilingan" +unresolved: "Hal qilinmagan" +breakFollow: "Obunachini o'chirish" +breakFollowConfirm: "Obunachini o'chirmoqchimisiz?" +itsOn: "Yoqilgan" +itsOff: "O'chirilgan" +on: "Yoqish" +off: "O'chirish" +emailRequiredForSignup: "Ro'yxatdan o'tish uchun email talab qilish" +unread: "Oʻqilmagan xabarlar" +filter: "Filter" +controlPanel: "Boshqaruv paneli" +manageAccounts: "Hisobni boshqarish" +classic: "Klassik" +hide: "Yashirish" +searchByGoogle: "Izlash" +indefinitely: "Hech qachon" +file: "Fayllar" +recommended: "Tavsiya qilingan" +check: "Tekshirish" +requireAdminForView: "Ko'rish uchun adminstrator hisobi bilan tizimga kirgan bo'lishingiz kerak." +isSystemAccount: "Ushbu hisob tizim tomonidan avtomatik tarzda yaratilgan va boshqariladi." +typeToConfirm: "Ushbu amalni bajarish uchun {x}ni kiriting" +deleteAccount: "Hisobni o'chirish" +document: "hujjat" +numberOfPageCache: "Sahifa keshlar soni" +logoutConfirm: "Chiqishni xohlaysizmi?" +lastActiveDate: "oxirgi foydalanish sanasi" +statusbar: "Holat paneli" +pleaseSelect: "Iltimos tanlang" +reverse: "Teskari" +colored: "rangli" +refreshInterval: "yangilash oralig'i" +label: "Yorliq" +type: "turi" +speed: "tezlik" +slow: "Sekin" +fast: "Tez" +localOnly: "Faqat mahalliy" +remoteOnly: "faqat masofadan turib" +failedToUpload: "yuklanmadi" +cannotUploadBecauseInappropriate: "Faylni yuklab bo'lmaydi, chunki unda nomaqbul kontent borligi aniqlangan." +cannotUploadBecauseNoFreeSpace: "Yuklab bo'lmadi, chunki diskda bo'sh joy yo'q." +cannotUploadBecauseExceedsFileSizeLimit: "Faylni yuklash mumkin emas, chunki u fayl hajmi chegarasidan oshib ketgan." +beta: "beta" +account: "akkaunt" +show: "Displey" +color: "Rang" +disableFederationConfirm: "Federatsiyani o'chirmoqchimisiz?" +disableFederationOk: "O'chirish" +emailNotSupported: "Bu server E-pochtalar yuborishni qo'llab-quvvatlamaydi" +postToTheChannel: "Kanalga joylash" +cannotBeChangedLater: "Buni keyinchalik o'zgartirishni iloji yo'q" +likeOnly: "Faqat like'lar" +nonSensitiveOnly: "Xavfsiz rejim" +rolesAssignedToMe: "Mening rollarim" +resetPasswordConfirm: "Qayta parol o'rnatmoqchimisiz?" +sensitiveWords: "Ta'sirchan so'zlar" +icon: "Avatar" +_achievements: + _types: + _viewInstanceChart: + title: "Tahlilchi" +_role: + priority: "Ustuvorlik" + _priority: + low: "Quyi" + middle: "O'rta" + high: "Yuqori" +_ffVisibility: + public: "Chiqarish" +_ad: + back: "qaytish" + hide: "Boshqa ko'rsatilmasin" +_email: + _follow: + title: "sizga obuna bo'ldi" +_registry: + key: "Kalit" + keys: "Kalit" +_instanceTicker: + none: "Boshqa ko'rsatilmasin" + always: "Doimo ko'rsatilsin" +_theme: + install: "Rang sxemasini o'rnatish" + manage: "Rang sxemalarini boshqarish" + code: "Rang sxemasining kodi" + description: "Tavsif" + installed: "{name} o'rnatildi" + installedThemes: "O'rnatilgan rang sxemalari" + alreadyInstalled: "Ushbu rang sxemasi allaqachon o'rnatilgan" + invalid: "Ushbu rang sxemasining formati yaroqsiz" + make: "Rang sxemasini yasash" + base: "Asos" + addConstant: "O'zgarmas qo'shish" + constant: "O'zgarmas" + color: "Rang" + key: "Kalit" + func: "Funksiyalar" + funcKind: "Funksiya turi" + argument: "Argument" + darken: "Qoraytirish" + lighten: "Yoritish" + inputConstantName: "Ushbu o'zgarmas uchun nom kiriting" + deleteConstantConfirm: "Siz rostdan ham {const} o'zgarmasni o'chirmoqchimisiz?" + keys: + accent: "Urg'u" + bg: "Fon" + fg: "Matn" + focus: "Fokus" + panel: "Panel" + shadow: "Soya" + header: "Sarlavha" + navBg: "Yon panel foni" + navFg: "Yon panel matni" + mention: "Murojat" + renote: "Qayta qayd etish" + divider: "Ajratrmoq" + accentDarken: "Urg'u (Qoraytirilgan)" + accentLighten: "Urg'u (Yoritilgan)" + fgHighlighted: "Belgilangan matn" +_sfx: + note: "Qaydlar" + notification: "Xabarnomalar" + chat: "Suhbat" +_ago: + minutesAgo: "{n} daqiqa oldin" + hoursAgo: "{n} soat oldin" + daysAgo: "{n} kun oldin" + invalid: "Hech narsa yo'q" +_2fa: + renewTOTPCancel: "Hozir emas" +_permissions: + "read:blocks": "Bloklangan foydalanuvchilar roʻyxatini koʻring" + "write:blocks": "Bloklangan foydalanuvchilar roʻyxatini tahrirlang" +_weekday: + saturday: "Shanba" +_widgets: + profile: "Profil" + instanceInfo: "Instans haqida ma'lumot" + notifications: "Xabarnomalar" + timeline: "Xronologiya" + clock: "Soat" + activity: "Faollik" + photos: "Rasmlar" + digitalClock: "Raqamli soat" + unixClock: "UNIX soat" + federation: "Federatsiya" + button: "Tugma" + jobQueue: "Vazifalar navbati" + _userList: + chooseList: "Ro'yxat tanlash" +_cw: + show: "Ko‘proq ko‘rish" + chars: "{count} ta belgi(lar)" + files: "{count} ta fayl(lar)" +_poll: + noOnlyOneChoice: "Kamida ikkita tanvol kerak" + infinite: "Hech qachon" + at: "...da tugatish" + after: "...dan keyin tugatish" + deadlineTime: "Vaqt" + duration: "Davomiylik" + votesCount: "{n} ovozlar" + totalVotes: "Umuman {n} ovozlar" + vote: "Ovoz berish" + showResult: "Natijalarni ko'rish" + voted: "Ovoz berildi" + closed: "Yakunladi" + remainingDays: "{d} kun {h} soat qoldi" + remainingHours: "{h} soat {m} daqiqa qoldi" + remainingMinutes: "{m} daqiqa {s} sekund qoldi" + remainingSeconds: "{s} sekund qoldi" +_visibility: + public: "Ommaviy" + publicDescription: "Sizning ovozingiz barcha foydalanuvchilarga ko'rinadi" + home: "Bosh sahifa" + followers: "Obunachilar" + specified: "Bevosita" +_profile: + name: "Ism" + username: "Foydalanuvchi nomi" + description: "Biografiya" + metadata: "Qo'shimcha ma'lumot" + metadataLabel: "Yorliq" + metadataContent: "Tarkib" + changeBanner: "Bannerni o'zgartirish" +_exportOrImport: + allNotes: "Barcha qaydlar" + followingList: "Obuna bo‘lish" + muteList: "Ovozni o‘chirish" + blockingList: "Bloklangan foydalanuvchilar" + userLists: "Ro'yxatlar" +_charts: + federation: "Federatsiya" + apRequest: "So'rovlar" + usersTotal: "Foydalanuvchilarning umumiy soni" + activeUsers: "Faol foydalanuvchilar" + notesTotal: "Qaydlarning umumiy soni" + filesTotal: "Fayllarning umumiy soni" +_instanceCharts: + requests: "So'rovlar" + notes: "Qaydlar sonidagi farq" + cacheSize: "Kesh hajmidagi farq" + files: "Fayllar sonidagi farq" +_timelines: + home: "Bosh sahifa" + local: "Mahalliy" + social: "Ijtimoiy" + global: "Global" +_play: + featured: "Mashhur" + title: "Sarlavha" + script: "Skript" + summary: "Tavsif" +_pages: + newPage: "Yangi Sahifa yaratish" + editPage: "Ushbu Sahifani tahrirlash" + created: "Sahifa muvaffaqiyatli yaratildi" + updated: "Sahifa muvaffaqiyatli tahrirlandi" + deleted: "Sahifa muvaffaqiyatli o'chirildi" + pageSetting: "Sahifa sozlamalari" + nameAlreadyExists: "Ko'rsatilgan Sahifa URL'i allaqachon mavjud" + invalidNameTitle: "Ko'rsatilgan Sahifa URL'i yaroqsiz" + editThisPage: "Ushbu Sahifani tahrirlash" + viewPage: "Sizning Sahifalaringizni ko'rish" + my: "Mening Sahifalarim" + featured: "Mashhur" + contents: "Tarkib" + title: "Sarlavha" + url: "Sahifa URL'i" + summary: "Sahifa bayoni" + font: "Shrift" + fontSerif: "Serif" + fontSansSerif: "Sans Serif" + selectType: "Turni tanlang" + contentBlocks: "Tarkib" + blocks: + text: "Matn" + textarea: "Matn maydoni" + section: "Bo'lim" + image: "Rasmlar" + button: "Tugma" + note: "Biriktirilgan qayd" + _note: + id: "Qayd ID" + detailed: "Batafsil ko'rinishi" +_relayStatus: + requesting: "Kutilmoqda" + accepted: "Tasdiqlandi" + rejected: "Rad etildi" +_notification: + fileUploaded: "Fayl muvaffaqiyatli yuklandi" + youGotMention: "{name} sizni eslab o'tdi" + youGotReply: "{name} sizga javob berdi" + youGotQuote: "{name} sizdan iqtibos keltirdi" + youRenoted: "{name} dan qayta qayd qilish" + youWereFollowed: "sizga obuna bo'ldi" + unreadAntennaNote: "Antenna {name}" + _types: + all: "Barchasi" + follow: "Obuna bo‘lish" + mention: "Murojat" + renote: "Qayta qayd etish" + quote: "Iqtibos keltirish" + reaction: "Reaktsiyalar" + receiveFollowRequest: "Qabul qilingan kuzatuv so'rovlari" + _actions: + reply: "Javob berish" + renote: "Qayta qayd qilish" +_deck: + alwaysShowMainColumn: "Har doim asosiy ustunni ko'rsatish" + columnAlign: "Ustunlarni tekislash" + addColumn: "Ustun qo'shish" + configureColumn: "Ustun sozlamalari" + swapLeft: "Chapdagi ustun bilan joyni almashtirish" + swapRight: "O'ngdagi ustun bilan joyni almashtirish" + swapUp: "Yuqoridagi ustun bilan joyni almashtirish" + swapDown: "Quyidagi ustun bilan joyni almashtirish" + profile: "Profil" + newProfile: "Yangi profil" + deleteProfile: "Profilni o‘chirib tashlash" + _columns: + main: "Asosiy" + notifications: "Xabarnomalar" + tl: "Xronologiya" + antenna: "Antennalar" + list: "Ro‘yxat" + channel: "Kanal" + mentions: "Eslatib o'tish" + direct: "Bevosita qaydlar" + roleTimeline: "Rol xronologiyasi" +_webhookSettings: + name: "Ism" + active: "Yoqilgan" + _events: + renote: "Qayta qayd qilinganda" + mention: "Eslanganda" diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index 898c478bf5..47cd53050d 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -20,6 +20,7 @@ noNotes: "Chưa có bài viết nào." noNotifications: "Chưa có thông báo" instance: "Máy chủ" settings: "Cài đặt" +notificationSettings: "Cài đặt thông báo" basicSettings: "Thiết lập chung" otherSettings: "Thiết lập khác" openInWindow: "Mở trong cửa sổ mới" @@ -48,9 +49,15 @@ delete: "Xóa" deleteAndEdit: "Sửa" deleteAndEditConfirm: "Bạn có chắc muốn sửa tút này? Những biểu cảm, lượt trả lời và đăng lại sẽ bị mất." addToList: "Thêm vào danh sách" +addToAntenna: "Thêm vào Ăngten" sendMessage: "Gửi tin nhắn" copyRSS: "Sao chép RSS" copyUsername: "Chép tên người dùng" +copyUserId: "Sao chép ID người dùng" +copyNoteId: "Sao chép ID ghi chú" +copyFileId: "Sao chép ID tập tin" +copyFolderId: "Sao chép ID thư mục" +copyProfileUrl: "Sao chép URL hồ sơ" searchUser: "Tìm kiếm người dùng" reply: "Trả lời" loadMore: "Tải thêm" @@ -122,6 +129,8 @@ unmarkAsSensitive: "Bỏ đánh dấu nhạy cảm" enterFileName: "Nhập tên tập tin" mute: "Ẩn" unmute: "Bỏ ẩn" +renoteMute: "Mute Renotes" +renoteUnmute: "Unmute Renotes" block: "Chặn" unblock: "Bỏ chặn" suspend: "Vô hiệu hóa" @@ -131,8 +140,10 @@ unblockConfirm: "Bạn có chắc muốn bỏ chặn người này?" suspendConfirm: "Bạn có chắc muốn vô hiệu hóa người này?" unsuspendConfirm: "Bạn có chắc muốn bỏ vô hiệu hóa người này?" selectList: "Chọn danh sách" +editList: "Chỉnh sửa danh sách" selectChannel: "Lựa chọn kênh" selectAntenna: "Chọn một antenna" +editAntenna: "Chỉnh sửa Ăngten" selectWidget: "Chọn tiện ích" editWidgets: "Sửa tiện ích" editWidgetsExit: "Xong" @@ -145,6 +156,8 @@ addEmoji: "Thêm emoji" settingGuide: "Cài đặt đề xuất" cacheRemoteFiles: "Tập tin cache từ xa" cacheRemoteFilesDescription: "Khi tùy chọn này bị tắt, các tập tin từ xa sẽ được tải trực tiếp từ máy chủ khác. Điều này sẽ giúp giảm dung lượng lưu trữ nhưng lại tăng lưu lượng truy cập, vì hình thu nhỏ sẽ không được tạo." +cacheRemoteSensitiveFiles: "Lưu các tập tin nhạy cảm vào bộ nhớ tạm từ xa" +cacheRemoteSensitiveFilesDescription: "Khi bạn tắt tính năng này, các tệp nhạy cảm sẽ được tải trực tiếp từ máy chủ và không được lưu vào bộ nhớ tạm" flagAsBot: "Đánh dấu đây là tài khoản bot" flagAsBotDescription: "Bật tùy chọn này nếu tài khoản này được kiểm soát bởi một chương trình. Nếu được bật, nó sẽ được đánh dấu để các nhà phát triển khác ngăn chặn chuỗi tương tác vô tận với các bot khác và điều chỉnh hệ thống nội bộ của Misskey để coi tài khoản này như một bot." flagAsCat: "Chế độ Mèeeeeeeeeeo!!" @@ -153,6 +166,7 @@ flagShowTimelineReplies: "Hiện lượt trả lời trong bảng tin" flagShowTimelineRepliesDescription: "Hiện lượt trả lời của người bạn theo dõi trên tút của những người khác." autoAcceptFollowed: "Tự động phê duyệt theo dõi từ những người mà bạn đang theo dõi" addAccount: "Thêm tài khoản" +reloadAccountsList: "Cập nhật danh sách tài khoản" loginFailed: "Đăng nhập không thành công" showOnRemote: "Truy cập trang của người này" general: "Tổng quan" @@ -259,8 +273,10 @@ noMoreHistory: "Không còn gì để đọc" startMessaging: "Bắt đầu trò chuyện" nUsersRead: "đọc bởi {n}" agreeTo: "Tôi đồng ý {0}" +agree: "Đồng ý" agreeBelow: "Đồng ý với nội dung dưới đây" basicNotesBeforeCreateAccount: "Những điều cơ bản cần chú ý " +termsOfService: "Điều khoản và Điều kiện" start: "Bắt đầu" home: "Trang chính" remoteUserCaution: "Vì người dùng này ở máy chủ khác, thông tin hiển thị có thể không đầy đủ." @@ -303,6 +319,7 @@ copyUrl: "Sao chép URL" rename: "Đổi tên" avatar: "Ảnh đại diện" banner: "Ảnh bìa" +displayOfSensitiveMedia: "Hiển thị nội dung nhạy cảm (NSFW)" whenServerDisconnected: "Khi mất kết nối tới máy chủ" disconnectedFromServer: "Mất kết nối tới máy chủ" reload: "Tải lại" @@ -456,6 +473,7 @@ aboutX: "Giới thiệu {x}" emojiStyle: "Kiểu cách Emoji" native: "Bản xứ" disableDrawer: "Không dùng menu thanh bên" +showNoteActionsOnlyHover: "Chỉ hiển thị các hành động ghi chú khi di chuột" noHistory: "Không có dữ liệu" signinHistory: "Lịch sử đăng nhập" enableAdvancedMfm: "Xem bài MFM chất lượng cao." @@ -468,6 +486,7 @@ createAccount: "Tạo tài khoản" existingAccount: "Tài khoản hiện có" regenerate: "Tạo lại" fontSize: "Cỡ chữ" +limitTo: "Giới hạn tỷ lệ {x}" noFollowRequests: "Bạn không có yêu cầu theo dõi nào" openImageInNewTab: "Mở ảnh trong tab mới" dashboard: "Trang chính" @@ -504,6 +523,7 @@ objectStorageSetPublicRead: "Đặt \"public-read\" khi tải lên" serverLogs: "Nhật ký máy chủ" deleteAll: "Xóa tất cả" showFixedPostForm: "Hiện khung soạn tút ở phía trên bảng tin" +showFixedPostFormInChannel: "Hiển thị mẫu bài đăng ở phía trên bản tin" newNoteRecived: "Đã nhận tút mới" sounds: "Âm thanh" sound: "Âm thanh" @@ -541,9 +561,14 @@ userSuspended: "Người này đã bị vô hiệu hóa." userSilenced: "Người này đã bị ẩn" yourAccountSuspendedTitle: "Tài khoản bị vô hiệu hóa" yourAccountSuspendedDescription: "Tài khoản này đã bị vô hiệu hóa do vi phạm quy tắc máy chủ hoặc điều tương tự. Liên hệ với quản trị viên nếu bạn muốn biết lý do chi tiết hơn. Vui lòng không tạo tài khoản mới." +tokenRevoked: "Token đã bị từ chối" +tokenRevokedDescription: "Phiên đăng nhập đã hết hạn. Vui lòng đăng nhập lại." +accountDeleted: "Tài khoản đã bị xóa" +accountDeletedDescription: "Tài khoản này đã bị xóa." menu: "Menu" divider: "Phân chia" addItem: "Thêm mục" +rearrange: "Sắp xếp lại" relays: "Chuyển tiếp" addRelay: "Thêm chuyển tiếp" inboxUrl: "URL Hộp thư đến" @@ -653,6 +678,7 @@ createNewClip: "Tạo một ghim mới" unclip: "Bỏ ghim" confirmToUnclipAlreadyClippedNote: "Bài đăng này là một phần của \"{name}\" ghim. Bạn có muốn bỏ khỏi ghim?" public: "Công khai" +private: "Riêng tư" i18nInfo: "Misskey đang được các tình nguyện viên dịch sang nhiều thứ tiếng khác nhau. Bạn có thể hỗ trợ tại {link}." manageAccessTokens: "Tạo mã truy cập" accountInfo: "Thông tin tài khoản" @@ -687,6 +713,8 @@ contact: "Liên hệ" useSystemFont: "Dùng phông chữ mặc định của hệ thống" clips: "Lưu bài viết" experimentalFeatures: "Tính năng thử nghiệm" +experimental: "Thử nghiệm" +thisIsExperimentalFeature: "Tính năng này đang trong quá trình thử nghiệm. Tính năng có thể không hoạt động, hoặc đặc tính kỹ thuật có thể bị thay đổi sau này." developer: "Nhà phát triển" makeExplorable: "Không hiện tôi trong \"Khám phá\"" makeExplorableDescription: "Nếu bạn tắt, tài khoản của bạn sẽ không hiện trong mục \"Khám phá\"." @@ -771,6 +799,7 @@ noMaintainerInformationWarning: "Chưa thiết lập thông tin vận hành." noBotProtectionWarning: "Bảo vệ Bot chưa thiết lập." configure: "Thiết lập" postToGallery: "Tạo tút có ảnh" +postToHashtag: "Đăng bài với hashtag này" gallery: "Thư viện ảnh" recentPosts: "Tút gần đây" popularPosts: "Tút được xem nhiều nhất" @@ -804,6 +833,7 @@ translatedFrom: "Dịch từ {x}" accountDeletionInProgress: "Đang xử lý việc xóa tài khoản" usernameInfo: "Bạn có thể sử dụng chữ cái (a ~ z, A ~ Z), chữ số (0 ~ 9) hoặc dấu gạch dưới (_). Tên người dùng không thể thay đổi sau này." aiChanMode: "Chế độ Ai" +devMode: "Chế độ dành cho nhà phát triển" keepCw: "Giữ cảnh báo nội dung" pubSub: "Tài khoản Chính/Phụ" lastCommunication: "Lần giao tiếp cuối" @@ -813,6 +843,8 @@ breakFollow: "Xóa người theo dõi" breakFollowConfirm: "Bạn bỏ theo dõi tài khoản này không?" itsOn: "Đã bật" itsOff: "Đã tắt" +on: "Bật" +off: "Tắt" emailRequiredForSignup: "Yêu cầu địa chỉ email khi đăng ký" unread: "Chưa đọc" filter: "Bộ lọc" @@ -857,6 +889,7 @@ failedToFetchAccountInformation: "Không thể lấy thông tin tài khoản" rateLimitExceeded: "Giới hạn quá mức" cropImage: "Cắt hình ảnh" cropImageAsk: "Bạn có muốn cắt ảnh này?" +cropYes: "Cắt" cropNo: "Để nguyên" file: "Tập tin" recentNHours: "{n}h trước" @@ -892,6 +925,7 @@ remoteOnly: "Chỉ máy chủ từ xa" failedToUpload: "Tải lên thất bại" cannotUploadBecauseInappropriate: "Không thể tải lên tập tin này vì các phần của tập tin đã được phát hiện có khả năng là NSFW." cannotUploadBecauseNoFreeSpace: "Tải lên không thành công do thiếu dung lượng Drive." +cannotUploadBecauseExceedsFileSizeLimit: "Không thể tải lên tập tin vì kích thước quá lớn." beta: "Beta" enableAutoSensitive: "Tự động đánh dấu NSFW" enableAutoSensitiveDescription: "Cho phép tự động phát hiện và đánh dấu media NSFW thông qua học máy, nếu có thể. Ngay cả khi tùy chọn này bị tắt, nó vẫn có thể được bật trên toàn máy chủ." @@ -904,9 +938,11 @@ pushNotification: "Thông báo đẩy" subscribePushNotification: "Bật thông báo đẩy" unsubscribePushNotification: "Tắt thông báo đẩy" pushNotificationAlreadySubscribed: "Đang bật thông báo đẩy" +pushNotificationNotSupported: "Trình duyệt của bạn không hỗ trợ thông báo đẩy." sendPushNotificationReadMessage: "Xóa thông báo đẩy sau khi đọc thông báo hay tin nhắn" sendPushNotificationReadMessageCaption: "Thông báo như {emptyPushNotificationMessage} sẽ hiển thị trong giây phút. Tiêu tốn pin của máy bạn có thể tăng lên hơn nữa." windowMaximize: "Phóng to" +windowMinimize: "Thu nhỏ tối đa" windowRestore: "Khôi phục" caption: "Mô tả" loggedInAsBot: "Đang đăng nhập bằng tài khoản Bot" @@ -923,12 +959,22 @@ didYouLikeMisskey: "Bạn có ưa thích Mískey không?" pleaseDonate: "Misskey là phần mềm miễn phí mà {host} đang sử dụng. Xin mong bạn quyên góp cho chúng tôi để chúng tôi có thể tiếp tục phát triển dịch vụ này. Xin cảm ơn!!" roles: "Vai trò" role: "Vai trò" +noRole: "Bạn chưa được cấp quyền." normalUser: "Người dùng bình thường" undefined: "Chưa xác định" +assign: "Phân công" +unassign: "Hủy phân công" color: "Màu sắc" manageCustomEmojis: "Quản lý CustomEmoji" +youCannotCreateAnymore: "Bạn đã tới giới hạn tạo." cannotPerformTemporary: "Tạm thời không sử dụng được" cannotPerformTemporaryDescription: "Tạm thời không sử dụng được vì lần số điều kiện quá giới hạn. Thử lại sau mọt lát nữa." +invalidParamError: "Lỗi tham số" +invalidParamErrorDescription: "Có vấn đề với các tham số được request. Thông thường, đây là do bug, nhưng cũng có thể do bạn đã nhập vào quá nhiều ký tự." +permissionDeniedError: "Thao tác bị từ chối" +permissionDeniedErrorDescription: "Tài khoản này không có đủ quyền hạn để thực hiện thao tác này." +preset: "Mẫu thiết lập" +selectFromPresets: "Chọn từ mẫu" achievements: "Thành tích" gotInvalidResponseError: "Không nhận được trả lời chủ máy" gotInvalidResponseErrorDescription: "Chủ máy có lẻ ngừng hoạt động hoặc bảo trí. Thử lại sau một lát nữa. " @@ -945,6 +991,7 @@ exploreOtherServers: "Tìm chủ máy khác" letsLookAtTimeline: "Thử xem Timeline" horizontal: "Thanh bên" youFollowing: "Đang theo dõi" +icon: "Ảnh đại diện" _achievements: earnedAt: "Ngày thu nhận" _types: @@ -1104,6 +1151,7 @@ _achievements: _cookieClicked: flavor: "Bạn nhầm phầm mềm chứ?" _role: + assignTarget: "Phân công" priority: "Ưu tiên" _priority: low: "Thấp" @@ -1346,15 +1394,27 @@ _time: minute: "phút" hour: "giờ" day: "ngày" +_timelineTutorial: + step4_1: "Bạn có thể thêm \"Reaction\" vào ghi chú" + step4_2: "Khi thêm biểu cảm hãy nhấn dấu \"+\"" _2fa: alreadyRegistered: "Bạn đã đăng ký thiết bị xác minh 2 bước." + registerTOTP: "Đăng ký ứng dụng xác thực" passwordToTOTP: "Nhắn mật mã" step1: "Trước tiên, hãy cài đặt một ứng dụng xác minh (chẳng hạn như {a} hoặc {b}) trên thiết bị của bạn." step2: "Sau đó, quét mã QR hiển thị trên màn hình này." + step2Click: "Quét mã QR trên ứng dụng xác thực (Authy, Google authenticator, v.v.)" step2Url: "Bạn cũng có thể nhập URL này nếu sử dụng một chương trình máy tính:" + step3Title: "Nhập mã xác thực" step3: "Nhập mã token do ứng dụng của bạn cung cấp để hoàn tất thiết lập." step4: "Kể từ bây giờ, những lần đăng nhập trong tương lai sẽ yêu cầu mã token đăng nhập đó." + securityKeyNotSupported: "Trình duyệt của bạn không hỗ trợ khóa bảo mật" + registerTOTPBeforeKey: "Vui lòng thiết lập một ứng dụng xác thực để đăng ký khóa bảo mật hoặc mật khẩu." securityKeyInfo: "Bên cạnh xác minh bằng vân tay hoặc mã PIN, bạn cũng có thể thiết lập xác minh thông qua khóa bảo mật phần cứng hỗ trợ FIDO2 để bảo mật hơn nữa cho tài khoản của mình." + chromePasskeyNotSupported: "Mật khẩu Chrome hiện không được hỗ trợ." + registerSecurityKey: "Tạo khóa bảo mật hoặc mã bảo mật" + securityKeyName: "Nhập tên khóa bảo mật" + tapSecurityKey: "Vui lòng làm theo hướng dẫn của trình duyệt để đăng ký mã bảo mật hoặc mã khóa" removeKey: "Xóa mã bảo mật" removeKeyConfirm: "Xóa bản sao lưu {name}?" renewTOTP: "Cài đặt lại ứng dụng xác thực" @@ -1677,5 +1737,11 @@ _dialog: charactersExceeded: "Bạn nhắn quá giới hạn ký tự!! Hiện nay {current} / giới hạn {max}" charactersBelow: "Bạn nhắn quá ít tối thiểu ký tự!! Hiện nay {current} / Tối thiểu {min}" _webhookSettings: + createWebhook: "Tạo Webhook" name: "Tên" + secret: "Mã bí mật" + events: "Sự kiện Webhook" active: "Đã bật" + _events: + reaction: "Khi nhận được sự kiện" + mention: "Khi có người nhắc tới bạn" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index d1b11a3540..2545c19dfb 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -15,7 +15,7 @@ gotIt: "我明白了" cancel: "取消" noThankYou: "不用,谢谢" enterUsername: "输入用户名" -renotedBy: "由 {user} 转贴" +renotedBy: "{user} 转发了" noNotes: "没有帖文" noNotifications: "无通知" instance: "服务器" @@ -156,11 +156,12 @@ addEmoji: "添加表情符号" settingGuide: "推荐配置" cacheRemoteFiles: "缓存远程文件" cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程服务器载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。" +youCanCleanRemoteFilesCache: "可以使用文件管理的🗑️按钮来删除所有的缓存。" cacheRemoteSensitiveFiles: "缓存远程敏感媒体文件" cacheRemoteSensitiveFilesDescription: "如果禁用这项设定,远程服务器的敏感媒体将不会被缓存,而是直接链接。" flagAsBot: "这是一个机器人账号" flagAsBotDescription: "如果此账户由程序控制,请启用此项。启用后,此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为,并让 Misskey 的内部系统将此账户识别为机器人。" -flagAsCat: "将这个账户设定为一只猫" +flagAsCat: "喵!!!!!!!!!!!!" flagAsCatDescription: "如果您想表明此帐户是一只猫,请打开此标志。\n开启后,会在您的头像上出现猫耳朵,并将你的帖子中的「na」替换为「nya」,日文同理。" flagShowTimelineReplies: "在时间线上显示帖子的回复" flagShowTimelineRepliesDescription: "启用时,时间线除了显示用户的帖子外,还会显示其他用户对帖子的回复。" @@ -507,13 +508,13 @@ showFeaturedNotesInTimeline: "在时间线上显示热门推荐" objectStorage: "对象存储" useObjectStorage: "使用对象存储" objectStorageBaseUrl: "Base URL" -objectStorageBaseUrlDesc: "这里是用于引用的 URL,如果您正在使用 CDN 或反向代理,请指定其 URL,例如S3:“https://.s3.amazonaws.com”,GCS:“https://storage.googleapis.com/”" +objectStorageBaseUrlDesc: "这里是用于参考的 URL,如果您正在使用 CDN 或反向代理,请指定其 URL,例如 S3:“https://.s3.amazonaws.com”,GCS:“https://storage.googleapis.com/”" objectStorageBucket: "存储桶" objectStorageBucketDesc: "请指定使用的对象存储服务的存储桶名称。" objectStoragePrefix: "前缀" objectStoragePrefixDesc: "文件将存储在此前缀的目录下。" -objectStorageEndpoint: "Endpoint" -objectStorageEndpointDesc: "如果你使用 AWS S3 请留空。否则请根据你使用的服务商的说明来进行设置,指定 Endpoint 形式为“”或“:”。" +objectStorageEndpoint: "端点" +objectStorageEndpointDesc: "如果你使用 AWS S3 请留空。否则请根据你使用的服务商的说明来进行设置,指定端点形式为“”或“:”。" objectStorageRegion: "可用区" objectStorageRegionDesc: "指定一个可用区,例如“xx-east-1”。 如果您的对象存储服务没有可用区概念,请将其留空或填写“us-east-1”。如果引用 AWS 的配置文件或环境变量,则留空。" objectStorageUseSSL: "使用 SSL" @@ -680,6 +681,7 @@ createNewClip: "新建便签" unclip: "移除便签" confirmToUnclipAlreadyClippedNote: "本帖已包含在便签 \"{name}\" 里。您想要将本帖从该便签中移除吗?" public: "公开" +private: "私密" i18nInfo: "Misskey 已经被志愿者们翻译成了各种语言。如果你也有兴趣,可以通过 {link} 帮助翻译。" manageAccessTokens: "管理 Access Tokens" accountInfo: "账户信息" @@ -1091,6 +1093,24 @@ usedAt: "使用时间" unused: "未使用" used: "已使用" expired: "已过期" +doYouAgree: "你同意吗?" +beSureToReadThisAsItIsImportant: "请好好阅读,这真的很重要。" +iHaveReadXCarefullyAndAgree: "我已经仔细阅读并同意了「{x}」的内容。" +dialog: "对话框" +icon: "头像" +forYou: "您的" +currentAnnouncements: "现在的公告" +pastAnnouncements: "过去的公告" +youHaveUnreadAnnouncements: "您有未读的公告" +_announcement: + forExistingUsers: "仅限现有用户" + forExistingUsersDescription: "若启用,该公告将仅对创建此公告时存在的用户可见。 如果禁用,则在创建此公告后注册的用户也可以看到该公告。" + needConfirmationToRead: "需要确认才能标记为已读" + needConfirmationToReadDescription: "若启用,则会在标记已读时会显示确认对话框。此外,它也会不受批量已读操作的影响。" + end: "结束公告" + tooManyActiveAnnouncementDescription: "若有大量活动公告,可能会造成用户体验可能下降。请考虑归档已完成的公告。" + readConfirmTitle: "标记为已读?" + readConfirmText: "阅读“{title}”的内容并将其标记为已读。" _initialAccountSetting: accountCreated: "账户创建完成了!" letsStartAccountSetup: "来进行帐户的初始设置吧。" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index df4122ef3d..2fc9fd885f 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1,9 +1,9 @@ --- _lang_: "繁體中文" headlineMisskey: "貼文連繫網絡" -introMisskey: "歡迎!Misskey 是一個開源且去中心化的社群網路服務。\n發佈「貼文」向身邊的人分享您的想法!📡\n利用「反應」表達您對貼文的感覺!👍\n讓我們一起探索新的世界吧!🚀" -poweredByMisskeyDescription: "{name}是使用開放原始碼平台Misskey的服務之一(稱為 Misskey 伺服器)。\n" -monthAndDay: "{month}月 {day}日" +introMisskey: "歡迎!Misskey 是一個開放原始碼且去中心化的社群網路服務。\n發布「貼文」向身邊的人分享您的想法!📡\n利用「反應」表達您對貼文的感覺!👍\n讓我們一起探索新的世界吧!🚀" +poweredByMisskeyDescription: "{name}是開放原始碼平臺 Misskey 的伺服器之一。" +monthAndDay: "{month} 月 {day} 日" search: "搜尋" notifications: "通知" username: "使用者名稱" @@ -16,7 +16,7 @@ cancel: "取消" noThankYou: "現在不要" enterUsername: "輸入使用者名稱" renotedBy: "{user} 轉發了" -noNotes: "無貼文。" +noNotes: "無貼文" noNotifications: "沒有通知" instance: "伺服器" settings: "設定" @@ -26,7 +26,7 @@ otherSettings: "其他設定" openInWindow: "在新視窗開啟" profile: "個人檔案" timeline: "時間軸" -noAccountDescription: "此用戶還沒有自我介紹" +noAccountDescription: "此使用者尚未自我介紹" login: "登入" loggingIn: "登入中" logout: "登出" @@ -135,8 +135,8 @@ block: "封鎖" unblock: "解除封鎖" suspend: "凍結" unsuspend: "解除凍結" -blockConfirm: "確定要封鎖此用戶?" -unblockConfirm: "確定解除封鎖此用戶?" +blockConfirm: "確定要封鎖此使用者嗎?" +unblockConfirm: "確定要解除封鎖此使用者嗎?" suspendConfirm: "確定凍結此帳戶?" unsuspendConfirm: "確定解凍此帳戶?" selectList: "選擇清單" @@ -155,15 +155,16 @@ emojiUrl: "表情符號URL" addEmoji: "新增表情符號" settingGuide: "推薦設定" cacheRemoteFiles: "快取遠端檔案" -cacheRemoteFilesDescription: "禁用此設定會停止遠端檔案的緩存,從而節省儲存空間,但資料會因直接連線從而產生額外連接數據。" +cacheRemoteFilesDescription: "禁用此設定會停止建立遠端檔案快取,從而節省伺服器儲存空間,但會因從遠端讀取資料而增加網路數據用量。" +youCanCleanRemoteFilesCache: "按檔案管理的🗑️按鈕,將快取全部刪除。" cacheRemoteSensitiveFiles: "快取遠端的敏感檔案" cacheRemoteSensitiveFilesDescription: "若停用這個設定,則不會快取遠端的敏感檔案,而是直接連結。" flagAsBot: "此使用者是機器人" -flagAsBotDescription: "如果本帳戶是由程式控制,請啟用此選項。啟用後,會作為標示幫助其他開發者防止機器人之間產生無限互動的行為,並會調整Misskey內部系統將本帳戶識別為機器人。" +flagAsBotDescription: "標記本帳戶由程式控制,防止其他程式與本帳戶產生無限互動的行為。" flagAsCat: "此帳戶是一隻貓,喵~~~!!!" flagAsCatDescription: "如果想將本帳戶標示為一隻貓,請開啟此標示" flagShowTimelineReplies: "在時間軸上顯示貼文的回覆" -flagShowTimelineRepliesDescription: "啟用時,時間線除了顯示用戶的貼文以外,還會顯示用戶對其他貼文的回覆。" +flagShowTimelineRepliesDescription: "啟用時,時間線除了顯示使用者的貼文以外,還會顯示使用者對其他貼文的回覆。" autoAcceptFollowed: "自動允許來自追隨中使用者的追隨請求" addAccount: "新增帳戶" reloadAccountsList: "更新帳戶清單的資訊" @@ -177,12 +178,12 @@ searchWith: "搜尋: {q}" youHaveNoLists: "你沒有任何清單" followConfirm: "你真的要追隨{name}嗎?" proxyAccount: "代理帳戶" -proxyAccountDescription: "代理帳戶是在某些情況下充當其他伺服器用戶的帳戶。例如,當使用者將一個來自其他伺服器的帳戶放在列表中時,由於沒有其他使用者追隨該帳戶,該指令不會傳送到該伺服器上,因此會由代理帳戶追隨。" +proxyAccountDescription: "代理帳戶是在特定條件下充當遠端追隨者的帳戶。例如,當使用者新增遠端使用者至其列表時,若沒有本地使用者追隨該遠端使用者,則其活動將不會傳送至伺服器,此時便會由代理帳戶代為追隨以解決問題。" host: "主機" selectUser: "選取使用者" recipient: "收件人" annotation: "註解" -federation: "站台聯邦" +federation: "聯邦宇宙" instances: "伺服器" registeredAt: "初次觀測" latestRequestReceivedAt: "上次收到的請求" @@ -197,10 +198,10 @@ operations: "操作" software: "軟體" version: "版本" metadata: "元資料" -withNFiles: "{n}個檔案" +withNFiles: "{n} 個檔案" monitor: "監視器" jobQueue: "佇列" -cpuAndMemory: "CPU及記憶體用量" +cpuAndMemory: "CPU 及記憶體" network: "網路" disk: "硬碟" instanceInfo: "伺服器資訊" @@ -213,8 +214,8 @@ clearCachedFilesConfirm: "確定要清除所有遠端暫存資料嗎?" blockedInstances: "已封鎖的伺服器" blockedInstancesDescription: "請逐行輸入需要封鎖的伺服器。已封鎖的伺服器將無法與本伺服器進行通訊。" muteAndBlock: "靜音和封鎖" -mutedUsers: "已靜音用戶" -blockedUsers: "已封鎖用戶" +mutedUsers: "被靜音的使用者" +blockedUsers: "被封鎖的使用者" noUsers: "沒有任何使用者" editProfile: "編輯個人檔案" noteDeleteConfirm: "確定刪除此貼文嗎?" @@ -236,7 +237,7 @@ publishing: "直播中" notResponding: "沒有回應" instanceFollowing: "追隨的伺服器" instanceFollowers: "伺服器的追隨者" -instanceUsers: "用戶" +instanceUsers: "伺服器使用者" changePassword: "修改密碼" security: "安全性" retypedNotMatch: "兩次輸入不一致。" @@ -246,7 +247,7 @@ newPasswordRetype: "確認密碼" attachFile: "上傳附件" more: "更多!" featured: "精選" -usernameOrUserId: "使用者名稱或使用者ID" +usernameOrUserId: "使用者名稱或使用者 ID" noSuchUser: "使用者不存在" lookup: "查詢" announcements: "公告" @@ -262,16 +263,16 @@ upload: "上傳" keepOriginalUploading: "保留原圖" keepOriginalUploadingDescription: "上傳圖片時保留原始圖片。關閉時,瀏覽器會在上傳時生成適用於網路傳送的版本。" fromDrive: "從雲端空間" -fromUrl: "從URL" +fromUrl: "從 URL" uploadFromUrl: "從網址上傳" -uploadFromUrlDescription: "您要上傳的文件的URL" +uploadFromUrlDescription: "您要上傳的檔案網址" uploadFromUrlRequested: "已請求上傳" uploadFromUrlMayTakeTime: "還需要一些時間才能完成上傳。" explore: "探索" messageRead: "已讀" noMoreHistory: "沒有更多歷史紀錄" startMessaging: "開始聊天" -nUsersRead: "{n}人已讀" +nUsersRead: "{n} 人已讀" agreeTo: "我同意{0}" agree: "同意" agreeBelow: "同意以下內容" @@ -284,7 +285,7 @@ activity: "動態" images: "圖片" image: "圖片" birthday: "生日" -yearsOld: "{age}歲" +yearsOld: "{age} 歲" registeredDate: "註冊日期" location: "位置" theme: "外觀主題" @@ -292,8 +293,8 @@ themeForLightMode: "在淺色模式下使用的主題" themeForDarkMode: "在深色模式下使用的主題" light: "淺色" dark: "深色" -lightThemes: "明亮主題" -darkThemes: "黑暗主題" +lightThemes: "淺色主題" +darkThemes: "深色主題" syncDeviceDarkMode: "同步至此裝置的深色模式設定" drive: "雲端硬碟" fileName: "檔案名稱" @@ -334,13 +335,13 @@ instanceName: "伺服器名稱" instanceDescription: "伺服器介紹" maintainerName: "管理員名稱" maintainerEmail: "管理員郵箱" -tosUrl: "服務條款URL" +tosUrl: "服務條款 URL" thisYear: "本年" thisMonth: "本月" today: "本日" -dayX: "{day}日" -monthX: "{month}月" -yearX: "{year}年" +dayX: "{day} 日" +monthX: "{month} 月" +yearX: "{year} 年" pages: "頁面" integration: "整合" connectService: "已連結" @@ -351,14 +352,14 @@ disablingTimelinesInfo: "為了方便,即使您關閉了時間線功能,管 registration: "註冊" enableRegistration: "開放新使用者註冊" invite: "邀請" -driveCapacityPerLocalAccount: "每個本地用戶的雲端空間大小" +driveCapacityPerLocalAccount: "每個本地使用者的雲端硬碟容量" driveCapacityPerRemoteAccount: "每個非本地用戶的雲端空間大小" inMb: "以Mbps為單位" iconUrl: "圖標 URL(例如 favicon)" bannerUrl: "橫幅圖片URL" backgroundImageUrl: "背景圖片的來源網址 " basicInfo: "基本資訊" -pinnedUsers: "置頂用戶" +pinnedUsers: "置頂使用者" pinnedUsersDescription: "在「探索」頁面中使用換行標記想要置頂的使用者。" pinnedPages: "釘選頁面" pinnedPagesDescription: "輸入要固定至實例首頁的頁面路徑,以換行符分隔。" @@ -386,7 +387,7 @@ antennaExcludeKeywords: "排除關鍵字" antennaKeywordsDescription: "空格代表「以及」(AND),換行代表「或者」(OR)" notifyAntenna: "通知有新貼文" withFileAntenna: "僅帶有附件的貼文" -enableServiceworker: "啟用 ServiceWorker" +enableServiceworker: "啟用瀏覽器的推播通知" antennaUsersDescription: "填寫使用者名稱,以換行分隔" caseSensitive: "區分大小寫" withReplies: "包含回覆" @@ -394,7 +395,7 @@ connectedTo: "您的帳戶已連接到以下社交帳戶" notesAndReplies: "貼文與回覆" withFiles: "附件" silence: "禁言" -silenceConfirm: "確定要禁言此帳戶嗎?" +silenceConfirm: "確定要禁言此使用者嗎?" unsilence: "解除禁言" unsilenceConfirm: "確定要解除禁言嗎?" popularUsers: "熱門使用者" @@ -426,8 +427,8 @@ resetPassword: "重設密碼" newPasswordIs: "新密碼為「{password}」" reduceUiAnimation: "減少介面的動態視覺" share: "分享" -notFound: "找不到" -notFoundDescription: "找不到該 URL 的頁面" +notFound: "查無項目" +notFoundDescription: "查無此頁" uploadFolder: "預設上傳資料夾" cacheClear: "清除快取" markAsReadAllNotifications: "標記所有通知為已讀" @@ -476,7 +477,7 @@ disableDrawer: "不顯示下拉式選單" showNoteActionsOnlyHover: "僅在游標停留時顯示貼文的操作選項" noHistory: "沒有歷史紀錄" signinHistory: "登入歷史" -enableAdvancedMfm: "啟用高級 MFM" +enableAdvancedMfm: "啟用進階 MFM" enableAnimatedMfm: "啟用 MFM 動畫" doing: "正在進行" category: "類別" @@ -487,7 +488,7 @@ existingAccount: "現有帳戶" regenerate: "再次生成" fontSize: "字體大小" mediaListWithOneImageAppearance: "只有一張圖片時的媒體列表高度" -limitTo: "上限為{x}" +limitTo: "上限為 {x}" noFollowRequests: "沒有追隨您的請求" openImageInNewTab: "於新分頁中開啟圖片" dashboard: "儀表板" @@ -504,10 +505,10 @@ promote: "推廣" numberOfDays: "有效天數" hideThisNote: "隱藏此貼文" showFeaturedNotesInTimeline: "在時間軸上顯示熱門推薦" -objectStorage: "Object Storage (物件儲存)" -useObjectStorage: "使用Object Storage" +objectStorage: "對象存儲" +useObjectStorage: "使用對象存儲" objectStorageBaseUrl: "Base URL" -objectStorageBaseUrlDesc: "引用時的 URL。如果您使用的是 CDN 或反向代理,請指定其 URL,例如 S3(https://.s3.amazonaws.com)、GCS(https://storage.googleapis.com/)。" +objectStorageBaseUrlDesc: "用於引用的 URL。如果您使用的是 CDN 或反向代理,請指定其 URL,例如 S3(https://.s3.amazonaws.com)、GCS(https://storage.googleapis.com/)。" objectStorageBucket: "儲存空間(Bucket)" objectStorageBucketDesc: "請填寫所用服務的儲存空間(Bucket)名稱。 " objectStoragePrefix: "前綴" @@ -532,7 +533,7 @@ sound: "音效" listen: "聆聽" none: "無" showInPage: "在頁面中顯示" -popout: "彈出型窗口" +popout: "彈出式視窗" volume: "音量" masterVolume: "主音量" details: "詳細資訊" @@ -542,7 +543,7 @@ recentUsed: "最近使用" install: "安裝" uninstall: "解除安裝" installedApps: "已授權的應用程式" -nothing: "未發現" +nothing: "無" installedDate: "安裝時間" lastUsedDate: "最後上線日期" state: "狀態" @@ -550,7 +551,7 @@ sort: "排序" ascendingOrder: "昇冪" descendingOrder: "降冪" scratchpad: "暫存記憶體" -scratchpadDescription: "AiScript 控制台為 AiScript 的實驗環境。您可以在此編寫、執行和確認程式碼與 Misskey 互動的结果。" +scratchpadDescription: "AiScript 控制臺為 AiScript 的實驗環境。您可以在此編寫、執行和確認程式碼與 Misskey 互動的結果。" output: "輸出" script: "腳本" disablePagesScript: "停用頁面的 AiScript 腳本" @@ -559,8 +560,8 @@ deleteAllFiles: "刪除所有檔案" deleteAllFilesConfirm: "要刪除所有檔案嗎?" removeAllFollowing: "解除所有追隨" removeAllFollowingDescription: "解除{host}所有的追隨。在伺服器不再存在時執行。" -userSuspended: "該使用者已被停用" -userSilenced: "該用戶已被禁言。" +userSuspended: "該使用者已被停用。" +userSilenced: "該使用者已被禁言。" yourAccountSuspendedTitle: "帳戶已被凍結" yourAccountSuspendedDescription: "該帳戶已因違反伺服器服務條款或其他原因而被凍結。您可以向管理員查詢更多資訊。請不要建立新帳戶。" tokenRevoked: "權杖無效" @@ -680,7 +681,8 @@ createNewClip: "建立新摘錄" unclip: "解除摘錄" confirmToUnclipAlreadyClippedNote: "此貼文已包含在摘錄「{name}」中。 你想將貼文從這個摘錄中排除嗎?" public: "公開" -i18nInfo: "Misskey 已被志願者們翻譯成各種語言版本。您可以瀏覽{link}幫助翻譯。" +private: "私密" +i18nInfo: "Misskey 已被志願者們翻譯成各種語言版本。您可以瀏覽 {link} 幫助翻譯。" manageAccessTokens: "管理存取權杖" accountInfo: "帳戶資訊" notesCount: "貼文數量" @@ -688,7 +690,7 @@ repliesCount: "回覆數量" renotesCount: "轉發數量" repliedCount: "回覆數量" renotedCount: "轉發次數" -followingCount: "正在追隨的用戶數量" +followingCount: "正在追隨的使用者數量" followersCount: "追隨者數量" sentReactionsCount: "反應發送次數" receivedReactionsCount: "收到反應次數" @@ -729,11 +731,11 @@ reloadToApplySetting: "設定將會在頁面重新載入之後生效。要現在 needReloadToApply: "必須重新載入才會生效。" showTitlebar: "顯示標題列" clearCache: "清除快取資料" -onlineUsersCount: "{n}人正在線上" -nUsers: "{n}用戶" -nNotes: "{n}貼文" +onlineUsersCount: "{n} 人上線" +nUsers: "{n} 使用者" +nNotes: "{n} 貼文" sendErrorReports: "傳送錯誤報告" -sendErrorReportsDescription: "啟用後,問題報告將傳送至開發者以提升軟體品質。問題報告可能包括OS版本,瀏覽器類型,行為歷史記錄等。" +sendErrorReportsDescription: "傳送問題報告至開發者以提升軟體品質。問題報告可能包括作業系統版本,瀏覽器類型,行為歷史記錄等。" myTheme: "我的佈景主題" backgroundColor: "背景" accentColor: "重點色彩" @@ -770,13 +772,13 @@ clear: "清除" markAllAsRead: "全部標示為已讀" goBack: "返回" unlikeConfirm: "要取消按讚嗎?" -fullView: "全熒幕顯示" +fullView: "全螢幕顯示" quitFullView: "退出全螢幕顯示" addDescription: "新增描述" -userPagePinTip: "在貼文的選單中選擇\"置頂\",即可置頂該貼文至您的個人檔案頁面。" +userPagePinTip: "在貼文的選單中選擇「置頂」,即可置頂該貼文至您的個人檔案頁面。" notSpecifiedMentionWarning: "此貼文有未指定的提及" info: "資訊" -userInfo: "用戶資料" +userInfo: "使用者資訊" unknown: "未知" onlineStatus: "上線狀態" hideOnlineStatus: "隱藏上線狀態" @@ -835,7 +837,7 @@ accountDeletionInProgress: "正在刪除帳戶" usernameInfo: "在伺服器上您的帳戶是唯一的識別名稱。您可以使用字母 (a ~ z, A ~ Z)、數字 (0 ~ 9) 和下底線 (_)。之後帳戶名是不能更改的。" aiChanMode: "小藍模式" devMode: "開發者模式" -keepCw: "保持 CW" +keepCw: "保持隱藏內容" pubSub: "Pub/Sub 帳戶" lastCommunication: "最近的通信" resolved: "已解決" @@ -849,7 +851,7 @@ off: "關閉" emailRequiredForSignup: "註冊帳戶需要電子郵件地址" unread: "未讀" filter: "篩選" -controlPanel: "控制台" +controlPanel: "控制臺" manageAccounts: "管理帳戶" makeReactionsPublic: "將反應設為公開" makeReactionsPublicDescription: "將您做過的反應設為公開可見。" @@ -893,8 +895,8 @@ cropImageAsk: "要剪裁圖片嗎?" cropYes: "裁剪" cropNo: "使用原圖" file: "檔案" -recentNHours: "過去{n}小時" -recentNDays: "過去{n}天" +recentNHours: "過去 {n} 小時" +recentNDays: "過去 {n} 天" noEmailServerWarning: "尚未設定電子郵件伺服器。" thereIsUnresolvedAbuseReportWarning: "有尚未處理的檢舉。" recommended: "推薦" @@ -930,7 +932,7 @@ cannotUploadBecauseExceedsFileSizeLimit: "由於超過了檔案大小的限制 beta: "測試版" enableAutoSensitive: "自動 NSFW 判定" enableAutoSensitiveDescription: "如果可用,它將使用機器學習技術判斷多媒體內容是否需要標記 NSFW。即使關閉此功能,也可能會依實例規則而自動啟用。" -activeEmailValidationDescription: "積極驗證帳戶的電郵地址,以判斷它是否可以通訊。關閉此選項代表只會檢查地址是否符合格式。" +activeEmailValidationDescription: "積極驗證使用者的電郵地址,以判斷它是否可以通訊。關閉此選項代表只會檢查地址是否符合格式。" navbar: "導覽列" shuffle: "隨機" account: "帳戶" @@ -1015,7 +1017,7 @@ drivecleaner: "雲端硬碟清掃器" retryAllQueuesNow: "立刻重試所有佇列" retryAllQueuesConfirmTitle: "要現在重試嗎?" retryAllQueuesConfirmText: "伺服器的負荷可能會暫時增加。" -enableChartsForRemoteUser: "生成遠端用戶的圖表" +enableChartsForRemoteUser: "生成遠端使用者的圖表" enableChartsForFederatedInstances: "生成遠端伺服器的圖表" showClipButtonInNoteFooter: "新增摘錄至貼文" largeNoteReactions: "放大顯示貼文反應" @@ -1094,6 +1096,21 @@ expired: "過期" doYouAgree: "你同意嗎?" beSureToReadThisAsItIsImportant: "重要,請務必閱讀。" iHaveReadXCarefullyAndAgree: "我已仔細閱讀並同意「{x}」的内容。" +dialog: "對話方塊" +icon: "圖示" +forYou: "給您" +currentAnnouncements: "最新公告" +pastAnnouncements: "歷史公告" +youHaveUnreadAnnouncements: "有未讀的公告。" +_announcement: + forExistingUsers: "僅限既有的使用者" + forExistingUsersDescription: "啟用代表僅向現存使用者顯示;停用代表張貼後註冊的新使用者也會看到。" + needConfirmationToRead: "必須確認才能標記為已讀" + needConfirmationToReadDescription: "啟用代表此公告將顯示對話方塊以確認是否標記為已讀,同時不會受「標記所有公告為已讀」功能影響。" + end: "結束公告" + tooManyActiveAnnouncementDescription: "有過多公告可能會影響使用者體驗。請考慮歸檔已結束的公告。" + readConfirmTitle: "標記為已讀嗎?" + readConfirmText: "閱讀「{title}」的內容並標記為已讀。" _initialAccountSetting: accountCreated: "帳戶已建立完成!" letsStartAccountSetup: "來進行帳戶的初始設定吧。" @@ -1106,7 +1123,7 @@ _initialAccountSetting: pushNotificationDescription: "啟用推送通知,就可以在設備上接收{name}的通知。" initialAccountSettingCompleted: "初始設定完成了!" haveFun: "盡情享受{name}吧!" - ifYouNeedLearnMore: "關於如何使用{name}(Misskey)的詳細資訊,請見{link}。" + ifYouNeedLearnMore: "請瀏覽{link}以更瞭解{name}(Misskey)的使用方法。" skipAreYouSure: "要略過初始設定嗎?" laterAreYouSure: "稍後再重新進行初始設定嗎?" _serverRules: @@ -1119,7 +1136,7 @@ _accountMigration: moveTo: "將這個帳戶遷移至新的帳戶" moveToLabel: "要遷移到的帳戶:" moveCannotBeUndone: "一旦遷移帳戶,就無法取消。" - moveAccountDescription: "這個操作不可撤銷。首先,請確認已在要遷移到的帳戶中為這個帳戶建立了一個別名。建立別名之後,像這樣輸入你要遷移到的帳戶:@person@instance.com" + moveAccountDescription: "遷移至新帳戶。\n ・此帳戶的追隨者將自動追隨新帳戶;\n ・此帳戶的所有追隨者將被取消追隨;\n ・此帳戶不能再發文。\n\n雖然會自動遷移您追隨者,但必須手動遷移您追隨的帳戶。請在遷移前匯出此帳戶的「追隨中」名單,並在遷移後自行匯入。\n列表名單、靜音名單及封鎖名單也必須如此處理。\n\n(此說明適用於本伺服器,以及運行 Misskey v13.12.0 或更新版本的其他伺服器;如 Mastodon 等使用 ActivityPub 協定的其他軟體或有不同的處理方式。)" moveAccountHowTo: "要遷移帳戶,首先要在目標帳戶中為此帳戶建立一個別名。\n 建立別名後,像這樣輸入目標帳戶:@username@server.example.com" startMigration: "遷移" migrationConfirm: "確定要將這個帳戶遷移至 {account} 嗎?一旦遷移就無法撤銷,也就無法以原來的狀態使用這個帳戶。\n另外,請確認在要遷移到的帳戶已經建立了一個別名。" @@ -1242,7 +1259,7 @@ _achievements: title: "有備而來" description: "設定了個人檔案" _markedAsCat: - title: "吾輩乃貓是也" + title: "我是貓" description: "已將帳戶設定為貓" flavor: "還沒有名字。" _following1: @@ -1264,7 +1281,7 @@ _achievements: title: "第一個追隨者" description: "第一次被追隨" _followers10: - title: "Follow me!" + title: "追隨我吧!" description: "追隨者超過10人了" _followers50: title: "成群結隊" @@ -1273,20 +1290,20 @@ _achievements: title: "熱門人物" description: "追隨者超過100人了" _followers300: - title: "請排成一排" + title: "請排隊" description: "追隨者超過300人了" _followers500: - title: "基地台" + title: "基地臺" description: "超過五百名追隨者了" _followers1000: - title: "影響者" + title: "星光熠熠" description: "超過一千名追隨者了" _collectAchievements30: title: "成就收藏家" description: "獲得三十個以上的成就" _viewAchievements3min: - title: "喜愛成就" - description: "看成就列表要花三分鐘以上" + title: "成就發燒友" + description: "看著成就列表超過三分鐘" _iLoveMisskey: title: "I Love Misskey" description: "發佈「I ❤ #Misskey」" @@ -1298,34 +1315,34 @@ _achievements: title: "休息一下" description: "客戶端啟動已超過30分鐘" _client60min: - title: "Misskey看太多" + title: "Misskey 看太多" description: "客戶端啟動已超過60分鐘" _noteDeletedWithin1min: - title: "現在沒有了" - description: "發文後1分鐘內刪文" + title: "欲言又止" + description: "發文後一分鐘內刪文" _postedAtLateNight: - title: "夜行性" + title: "夜貓子" description: "在深夜發佈貼文" flavor: "該去睡覺了。" _postedAt0min0sec: title: "報時" - description: "在0分0秒發佈貼文" - flavor: "啵.啵.啵.嗶ー" + description: "在零分零秒發佈貼文" + flavor: "啵、啵、啵、嗶ーー" _selfQuote: title: "自我引用" description: "引用了自己的貼文" _htl20npm: - title: "流動的TL" - description: "在首頁時間軸的流速超過20npm" + title: "源源不絕" + description: "首頁時間軸在一分鐘內出現超過二十篇貼文" _viewInstanceChart: title: "分析師" description: "顯示了實例的圖表" _outputHelloWorldOnScratchpad: - title: "Hello world!" - description: "在暫存記憶體輸出了 hello world" + title: "Hello, world!" + description: "在 AiScript 控制臺輸出了「hello world」" _open3windows: title: "多重視窗" - description: "開啟了3個以上的視窗" + description: "開啟過三個以上的視窗" _driveFolderCircularReference: title: "循環引用" description: "試圖遞迴套入雲端硬碟資料夾" @@ -1337,33 +1354,33 @@ _achievements: description: "已點擊這裡了" _justPlainLucky: title: "只是運氣好" - description: "每10秒有0.01%的機率獲得" + description: "每十秒有二萬分之一(0.005%)的機率獲得" _setNameToSyuilo: - title: "神的情結" + title: "神與您同在" description: "將名稱設定為 syuilo" _passedSinceAccountCreated1: - title: "一周年" - description: "自建立帳戶開始過了1年" + title: "一週年" + description: "帳戶加入時間已超過一年" _passedSinceAccountCreated2: - title: "二周年" - description: "自建立帳戶開始過了2年" + title: "二週年" + description: "帳戶加入時間已超過兩年" _passedSinceAccountCreated3: - title: "三周年" - description: "自建立帳戶開始過了3年" + title: "三週年" + description: "帳戶加入時間已超過三年" _loggedInOnBirthday: title: "生日快樂" description: "在生日當天登入了" _loggedInOnNewYearsDay: title: "新年快樂" description: "在元旦當天登入了" - flavor: "今年也請對敝實例多多指教" + flavor: "今年也請您多多指教!" _cookieClicked: title: "點擊餅乾的遊戲" description: "點擊了餅乾" flavor: "是不是軟體有問題?" _brainDiver: title: "Brain Driver" - description: "發佈了Brain Driver的連結" + description: "發佈一篇含歌曲《Brain Driver》連結的貼文" flavor: "Misskey-Misskey La-Tu-Ma" _role: new: "建立角色" @@ -1387,7 +1404,7 @@ _role: chooseRoleToAssign: "選擇要指派的角色" iconUrl: "圖示的URL" asBadge: "顯示為徽章" - descriptionOfAsBadge: "開啟的話,角色圖示會顯示在用戶名旁邊。" + descriptionOfAsBadge: "開啟的話,角色圖示會顯示在使用者名稱旁邊。" isExplorable: "讓使用者更容易找到您" descriptionOfIsExplorable: "若開啟則公開角色時間軸。若角色不是公開的,則無法公開時間軸。" displayOrder: "顯示順序" @@ -1425,8 +1442,8 @@ _role: _condition: isLocal: "本地使用者" isRemote: "遠端使用者" - createdLessThan: "自建立帳戶開始~以內" - createdMoreThan: "自建立帳戶開始~經過" + createdLessThan: "帳戶加入時間不超過" + createdMoreThan: "帳戶加入時間已超過" followersLessThanOrEq: "追隨者人數在~以下" followersMoreThanOrEq: "追隨者人數在~以上" followingLessThanOrEq: "追隨人數在~以下" @@ -1452,7 +1469,7 @@ _emailUnavailable: smtp: "郵件伺服器沒有應答" _ffVisibility: public: "公開" - followers: "只有關注你的用戶能看到" + followers: "只有關注您的使用者能看到" private: "私密" _signup: almostThere: "即將完成" @@ -1513,7 +1530,7 @@ _registry: domain: "域" createKey: "新增機碼" _aboutMisskey: - about: "Misskey是由syuilo自2014年起開發的開源軟體。" + about: "Misskey 是由 syuilo 自 2014 年起開發的開放原始碼軟體。" contributors: "主要貢獻者" allContributors: "全體貢獻人員" source: "原始碼" @@ -1541,8 +1558,8 @@ _channel: featured: "熱門貼文" owned: "管理中" following: "追隨中" - usersCount: "有{n}人參與" - notesCount: "有{n}個貼文" + usersCount: "有 {n} 人參與" + notesCount: "有 {n} 篇貼文" nameAndDescription: "名稱與說明" nameOnly: "僅名稱" _menuDisplay: @@ -1560,7 +1577,7 @@ _wordMute: hard: "硬性靜音" mutedNotes: "已靜音的貼文" _instanceMute: - instanceMuteDescription: "包括對被靜音實例上的用戶的回覆,被設定的實例上所有貼文及轉發都會被靜音。" + instanceMuteDescription: "包括對被靜音實例上的使用者的回覆,被設定的實例上所有貼文及轉發都會被靜音。" instanceMuteDescription2: "換行以分隔" title: "將隱藏被設定的實例貼文。" heading: "將實例靜音" @@ -1622,9 +1639,9 @@ _theme: infoFg: "資訊內容" infoWarnBg: "警告背景" infoWarnFg: "警告文字" - cwBg: "CW 按鈕背景" - cwFg: "CW 按鈕文字" - cwHoverBg: "CW 按鈕背景(懸浮)" + cwBg: "隱藏內容按鈕背景" + cwFg: "隱藏內容按鈕文字" + cwHoverBg: "隱藏內容按鈕背景(懸浮)" toastBg: "通知背景" toastFg: "通知文本" buttonBg: "按鈕背景" @@ -1649,14 +1666,14 @@ _sfx: _ago: future: "未來" justNow: "剛剛" - secondsAgo: "{n}秒前" - minutesAgo: "{n}分鐘前" - hoursAgo: "{n}小時前" - daysAgo: "{n}天前" - weeksAgo: "{n}週前" - monthsAgo: "{n}個月前" - yearsAgo: "{n}年前" - invalid: "未發現" + secondsAgo: "{n} 秒前" + minutesAgo: "{n}分鐘前 " + hoursAgo: "{n} 小時前" + daysAgo: "{n} 天前" + weeksAgo: "{n} 週前" + monthsAgo: "{n} 個月前" + yearsAgo: "{n} 年前" + invalid: "無" _time: second: "秒" minute: "分鐘" @@ -1700,13 +1717,13 @@ _2fa: _permissions: "read:account": "查看我的帳戶資訊" "write:account": "更改我的帳戶資訊" - "read:blocks": "已封鎖用戶名單" - "write:blocks": "編輯已封鎖用戶名單" + "read:blocks": "查看封鎖名單" + "write:blocks": "編輯封鎖名單" "read:drive": "存取雲端硬碟" "write:drive": "編輯雲端硬碟的檔案" "read:favorites": "瀏覽我的最愛" "write:favorites": "編輯我的最愛列表" - "read:following": "查看追隨中的用戶資訊" + "read:following": "查看追隨中的使用者資訊" "write:following": "追隨/解除追隨" "read:messaging": "顯示訊息" "write:messaging": "撰寫或刪除訊息" @@ -1730,10 +1747,14 @@ _permissions: "write:gallery": "操作圖庫" "read:gallery-likes": "讀取喜歡的圖片" "write:gallery-likes": "操作喜歡的圖片" + "read:flash": "檢視 Play" + "write:flash": "操作 Play" + "read:flash-likes": "檢視 Play 的讚" + "write:flash-likes": "對 Play 的讚進行操作" _auth: shareAccessTitle: "應用程式的存取權限" shareAccess: "要授權「“{name}”」存取您的帳戶嗎?" - shareAccessAsk: "您確定要授權這個應用程式使用您的帳戶嗎?" + shareAccessAsk: "您確定要授權這個應用程式存取您的帳戶嗎?" permission: "{name}要求以下的權限" permissionAsk: "此應用程式需要以下權限" pleaseGoBack: "請返回至應用程式" @@ -1760,7 +1781,7 @@ _widgets: notifications: "通知" timeline: "時間軸" calendar: "行事曆" - trends: "發燒貼文" + trends: "熱門貼文" clock: "時鐘" rss: "RSS 閱讀器" rssTicker: "RSS 跑馬燈" @@ -1768,15 +1789,15 @@ _widgets: photos: "照片" digitalClock: "電子時鐘" unixClock: "UNIX 時間" - federation: "站台聯邦" + federation: "聯邦宇宙" instanceCloud: "實例雲" - postForm: "發佈窗口" + postForm: "發文視窗" slideshow: "幻燈片" button: "按鈕" - onlineUsers: "線上的用戶" + onlineUsers: "上線使用者" jobQueue: "佇列" serverMetric: "伺服器指標 " - aiscript: "AiScript 控制台" + aiscript: "AiScript 控制臺" aiscriptApp: "AiScript App" aichan: "小藍" userList: "使用者列表" @@ -1789,8 +1810,8 @@ _cw: chars: "{count} 個字元" files: "{count} 個檔案" _poll: - noOnlyOneChoice: "至少需要兩個選項。" - choiceN: "選擇 {n}" + noOnlyOneChoice: "需要至少兩個選項。" + choiceN: "選項 {n}" noMore: "沒辦法再添加選項了" canMultipleVote: "可以多次投票" expiration: "期限" @@ -1812,7 +1833,7 @@ _poll: remainingSeconds: "{s} 秒後截止" _visibility: public: "公開" - publicDescription: "發佈給所有帳戶" + publicDescription: "發佈給所有使用者" home: "首頁" homeDescription: "僅發布至首頁的時間軸" followers: "追隨者" @@ -1837,8 +1858,8 @@ _profile: username: "使用者名稱" description: "關於我" youCanIncludeHashtags: "你也可以在「關於我」中加上 #tag" - metadata: "進階資訊" - metadataEdit: "編輯進階資訊" + metadata: "附加資訊" + metadataEdit: "編輯附加資訊" metadataDescription: "可以在個人資料中以表格形式顯示其他資訊。" metadataLabel: "標籤" metadataContent: "内容" @@ -1851,10 +1872,10 @@ _exportOrImport: muteList: "靜音" blockingList: "封鎖" userLists: "清單" - excludeMutingUsers: "排除被靜音的用戶" + excludeMutingUsers: "排除被靜音的使用者" excludeInactiveUsers: "排除不活躍帳戶" _charts: - federation: "站台聯邦" + federation: "聯邦宇宙" apRequest: "請求" usersIncDec: "使用者增減" usersTotal: "使用者合共" @@ -1895,7 +1916,7 @@ _play: viewSource: "檢視原始碼" my: "自己的 Play" liked: "按讚的 Play" - featured: "人氣" + featured: "熱門" title: "標題" script: "腳本" summary: "描述" @@ -1917,7 +1938,7 @@ _pages: unlike: "收回讚好" my: "我的頁面" liked: "已讚好的頁面" - featured: "人氣" + featured: "熱門" inspector: "面板檢查" contents: "內容" content: "頁面方塊" diff --git a/package.json b/package.json index 6867a7f50c..1c6d089e93 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "misskey", - "version": "13.14.1", + "version": "2023.9.0-beta.2", "codename": "nasubi", "repository": { "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "packageManager": "pnpm@8.6.9", + "packageManager": "pnpm@8.6.10", "workspaces": [ "packages/frontend", "packages/backend", @@ -44,7 +44,7 @@ "lodash": "4.17.21" }, "dependencies": { - "execa": "7.1.1", + "execa": "7.2.0", "gulp": "4.0.2", "gulp-cssnano": "2.1.3", "gulp-rename": "2.0.0", @@ -54,13 +54,13 @@ "typescript": "5.1.6" }, "devDependencies": { - "@types/gulp": "4.0.10", - "@types/gulp-rename": "2.0.1", - "@typescript-eslint/eslint-plugin": "5.61.0", - "@typescript-eslint/parser": "5.61.0", + "@types/gulp": "4.0.13", + "@types/gulp-rename": "2.0.2", + "@typescript-eslint/eslint-plugin": "6.2.0", + "@typescript-eslint/parser": "6.2.0", "cross-env": "7.0.3", - "cypress": "12.17.1", - "eslint": "8.45.0", + "cypress": "12.17.2", + "eslint": "8.46.0", "start-server-and-test": "2.0.0" }, "optionalDependencies": { diff --git a/packages/backend/check_connect.js b/packages/backend/check_connect.js index da78c8ec7c..ea988a7f69 100644 --- a/packages/backend/check_connect.js +++ b/packages/backend/check_connect.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Redis from 'ioredis'; import { loadConfig } from './built/config.js'; diff --git a/packages/backend/migration/1000000000000-Init.js b/packages/backend/migration/1000000000000-Init.js index 1140be7e84..6f04b52ae1 100644 --- a/packages/backend/migration/1000000000000-Init.js +++ b/packages/backend/migration/1000000000000-Init.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class Init1000000000000 { async up(queryRunner) { diff --git a/packages/backend/migration/1556348509290-Pages.js b/packages/backend/migration/1556348509290-Pages.js index 50caa2ce91..05d801227b 100644 --- a/packages/backend/migration/1556348509290-Pages.js +++ b/packages/backend/migration/1556348509290-Pages.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class Pages1556348509290 { async up(queryRunner) { diff --git a/packages/backend/migration/1556746559567-UserProfile.js b/packages/backend/migration/1556746559567-UserProfile.js index 50a9d1a8be..7cc1ba0083 100644 --- a/packages/backend/migration/1556746559567-UserProfile.js +++ b/packages/backend/migration/1556746559567-UserProfile.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class UserProfile1556746559567 { async up(queryRunner) { diff --git a/packages/backend/migration/1557476068003-PinnedUsers.js b/packages/backend/migration/1557476068003-PinnedUsers.js index d9cce25435..12f0b8fc6a 100644 --- a/packages/backend/migration/1557476068003-PinnedUsers.js +++ b/packages/backend/migration/1557476068003-PinnedUsers.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class PinnedUsers1557476068003 { async up(queryRunner) { diff --git a/packages/backend/migration/1557761316509-AddSomeUrls.js b/packages/backend/migration/1557761316509-AddSomeUrls.js index ab8736f7cc..244f64f8ef 100644 --- a/packages/backend/migration/1557761316509-AddSomeUrls.js +++ b/packages/backend/migration/1557761316509-AddSomeUrls.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class AddSomeUrls1557761316509 { async up(queryRunner) { diff --git a/packages/backend/migration/1557932705754-ObjectStorageSetting.js b/packages/backend/migration/1557932705754-ObjectStorageSetting.js index 19a0b9d5cd..736dcafaac 100644 --- a/packages/backend/migration/1557932705754-ObjectStorageSetting.js +++ b/packages/backend/migration/1557932705754-ObjectStorageSetting.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ObjectStorageSetting1557932705754 { async up(queryRunner) { diff --git a/packages/backend/migration/1558072954435-PageLike.js b/packages/backend/migration/1558072954435-PageLike.js index 31b08418a9..d9502a6e03 100644 --- a/packages/backend/migration/1558072954435-PageLike.js +++ b/packages/backend/migration/1558072954435-PageLike.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class PageLike1558072954435 { async up(queryRunner) { diff --git a/packages/backend/migration/1558103093633-UserGroup.js b/packages/backend/migration/1558103093633-UserGroup.js index b670b31c3d..b3cc6eb949 100644 --- a/packages/backend/migration/1558103093633-UserGroup.js +++ b/packages/backend/migration/1558103093633-UserGroup.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class UserGroup1558103093633 { async up(queryRunner) { diff --git a/packages/backend/migration/1558257926829-UserGroupInvite.js b/packages/backend/migration/1558257926829-UserGroupInvite.js index e48bd3a7ff..a87173cdfe 100644 --- a/packages/backend/migration/1558257926829-UserGroupInvite.js +++ b/packages/backend/migration/1558257926829-UserGroupInvite.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class UserGroupInvite1558257926829 { async up(queryRunner) { diff --git a/packages/backend/migration/1558266512381-UserListJoining.js b/packages/backend/migration/1558266512381-UserListJoining.js index 3398aed139..bc94b7f425 100644 --- a/packages/backend/migration/1558266512381-UserListJoining.js +++ b/packages/backend/migration/1558266512381-UserListJoining.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class UserListJoining1558266512381 { async up(queryRunner) { diff --git a/packages/backend/migration/1561706992953-webauthn.js b/packages/backend/migration/1561706992953-webauthn.js index b007ffef14..fa9b1188ca 100644 --- a/packages/backend/migration/1561706992953-webauthn.js +++ b/packages/backend/migration/1561706992953-webauthn.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class webauthn1561706992953 { async up(queryRunner) { diff --git a/packages/backend/migration/1561873850023-ChartIndexes.js b/packages/backend/migration/1561873850023-ChartIndexes.js index 3ce53567fc..c7e93ba7b7 100644 --- a/packages/backend/migration/1561873850023-ChartIndexes.js +++ b/packages/backend/migration/1561873850023-ChartIndexes.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ChartIndexes1561873850023 { async up(queryRunner) { diff --git a/packages/backend/migration/1562422242907-PasswordLessLogin.js b/packages/backend/migration/1562422242907-PasswordLessLogin.js index b73c7db4d3..3df3a6f5f5 100644 --- a/packages/backend/migration/1562422242907-PasswordLessLogin.js +++ b/packages/backend/migration/1562422242907-PasswordLessLogin.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class PasswordLessLogin1562422242907 { async up(queryRunner) { diff --git a/packages/backend/migration/1562444565093-PinnedPage.js b/packages/backend/migration/1562444565093-PinnedPage.js index 9a999a9150..329d49bbed 100644 --- a/packages/backend/migration/1562444565093-PinnedPage.js +++ b/packages/backend/migration/1562444565093-PinnedPage.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class PinnedPage1562444565093 { async up(queryRunner) { diff --git a/packages/backend/migration/1562448332510-PageTitleHideOption.js b/packages/backend/migration/1562448332510-PageTitleHideOption.js index 8fc78d202f..e41db08090 100644 --- a/packages/backend/migration/1562448332510-PageTitleHideOption.js +++ b/packages/backend/migration/1562448332510-PageTitleHideOption.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class PageTitleHideOption1562448332510 { async up(queryRunner) { diff --git a/packages/backend/migration/1562869971568-ModerationLog.js b/packages/backend/migration/1562869971568-ModerationLog.js index dd66d16eec..2eb3015d5c 100644 --- a/packages/backend/migration/1562869971568-ModerationLog.js +++ b/packages/backend/migration/1562869971568-ModerationLog.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ModerationLog1562869971568 { async up(queryRunner) { diff --git a/packages/backend/migration/1563757595828-UsedUsername.js b/packages/backend/migration/1563757595828-UsedUsername.js index 8972df297d..91d9d36b9d 100644 --- a/packages/backend/migration/1563757595828-UsedUsername.js +++ b/packages/backend/migration/1563757595828-UsedUsername.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class UsedUsername1563757595828 { async up(queryRunner) { diff --git a/packages/backend/migration/1565634203341-room.js b/packages/backend/migration/1565634203341-room.js index 679940f244..c2e5fca863 100644 --- a/packages/backend/migration/1565634203341-room.js +++ b/packages/backend/migration/1565634203341-room.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class room1565634203341 { async up(queryRunner) { diff --git a/packages/backend/migration/1571220798684-CustomEmojiCategory.js b/packages/backend/migration/1571220798684-CustomEmojiCategory.js index 37c07366e1..f211af67be 100644 --- a/packages/backend/migration/1571220798684-CustomEmojiCategory.js +++ b/packages/backend/migration/1571220798684-CustomEmojiCategory.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class CustomEmojiCategory1571220798684 { async up(queryRunner) { diff --git a/packages/backend/migration/1572760203493-nodeinfo.js b/packages/backend/migration/1572760203493-nodeinfo.js index 54d5f914a4..c281b0b2db 100644 --- a/packages/backend/migration/1572760203493-nodeinfo.js +++ b/packages/backend/migration/1572760203493-nodeinfo.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class nodeinfo1572760203493 { async up(queryRunner) { diff --git a/packages/backend/migration/1576269851876-TalkFederationId.js b/packages/backend/migration/1576269851876-TalkFederationId.js index 35861d571f..045f9ddb04 100644 --- a/packages/backend/migration/1576269851876-TalkFederationId.js +++ b/packages/backend/migration/1576269851876-TalkFederationId.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class TalkFederationId1576269851876 { constructor() { diff --git a/packages/backend/migration/1576869585998-ProxyRemoteFiles.js b/packages/backend/migration/1576869585998-ProxyRemoteFiles.js index d6d134be40..0dde1ae70c 100644 --- a/packages/backend/migration/1576869585998-ProxyRemoteFiles.js +++ b/packages/backend/migration/1576869585998-ProxyRemoteFiles.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ProxyRemoteFiles1576869585998 { constructor() { diff --git a/packages/backend/migration/1579267006611-v12.js b/packages/backend/migration/1579267006611-v12.js index 7f6318a192..86f9da7e7a 100644 --- a/packages/backend/migration/1579267006611-v12.js +++ b/packages/backend/migration/1579267006611-v12.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v121579267006611 { constructor() { diff --git a/packages/backend/migration/1579270193251-v12-2.js b/packages/backend/migration/1579270193251-v12-2.js index c51ce63066..2593aca573 100644 --- a/packages/backend/migration/1579270193251-v12-2.js +++ b/packages/backend/migration/1579270193251-v12-2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1221579270193251 { constructor() { diff --git a/packages/backend/migration/1579282808087-v12-3.js b/packages/backend/migration/1579282808087-v12-3.js index aeb4f5a873..a816b2e82e 100644 --- a/packages/backend/migration/1579282808087-v12-3.js +++ b/packages/backend/migration/1579282808087-v12-3.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1231579282808087 { constructor() { diff --git a/packages/backend/migration/1579544426412-v12-4.js b/packages/backend/migration/1579544426412-v12-4.js index f1e093413e..600dc270a5 100644 --- a/packages/backend/migration/1579544426412-v12-4.js +++ b/packages/backend/migration/1579544426412-v12-4.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1241579544426412 { constructor() { diff --git a/packages/backend/migration/1579977526288-v12-5.js b/packages/backend/migration/1579977526288-v12-5.js index 6d2b5c584a..73f3343347 100644 --- a/packages/backend/migration/1579977526288-v12-5.js +++ b/packages/backend/migration/1579977526288-v12-5.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1251579977526288 { constructor() { diff --git a/packages/backend/migration/1579993013959-v12-6.js b/packages/backend/migration/1579993013959-v12-6.js index 3941c1391d..5009e0aa88 100644 --- a/packages/backend/migration/1579993013959-v12-6.js +++ b/packages/backend/migration/1579993013959-v12-6.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1261579993013959 { constructor() { diff --git a/packages/backend/migration/1580069531114-v12-7.js b/packages/backend/migration/1580069531114-v12-7.js index 4b4790cb7d..ff943ffa6b 100644 --- a/packages/backend/migration/1580069531114-v12-7.js +++ b/packages/backend/migration/1580069531114-v12-7.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1271580069531114 { constructor() { diff --git a/packages/backend/migration/1580148575182-v12-8.js b/packages/backend/migration/1580148575182-v12-8.js index cc30200c14..20b77b391f 100644 --- a/packages/backend/migration/1580148575182-v12-8.js +++ b/packages/backend/migration/1580148575182-v12-8.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1281580148575182 { constructor() { diff --git a/packages/backend/migration/1580154400017-v12-9.js b/packages/backend/migration/1580154400017-v12-9.js index 3715798f19..f78dc47456 100644 --- a/packages/backend/migration/1580154400017-v12-9.js +++ b/packages/backend/migration/1580154400017-v12-9.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v1291580154400017 { constructor() { diff --git a/packages/backend/migration/1580276619901-v12-10.js b/packages/backend/migration/1580276619901-v12-10.js index d5decb882e..09fa27ae83 100644 --- a/packages/backend/migration/1580276619901-v12-10.js +++ b/packages/backend/migration/1580276619901-v12-10.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v12101580276619901 { constructor() { diff --git a/packages/backend/migration/1580331224276-v12-11.js b/packages/backend/migration/1580331224276-v12-11.js index 129720adbf..f118c34937 100644 --- a/packages/backend/migration/1580331224276-v12-11.js +++ b/packages/backend/migration/1580331224276-v12-11.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v12111580331224276 { constructor() { diff --git a/packages/backend/migration/1580508795118-v12-12.js b/packages/backend/migration/1580508795118-v12-12.js index c5cec23a36..4fba933a08 100644 --- a/packages/backend/migration/1580508795118-v12-12.js +++ b/packages/backend/migration/1580508795118-v12-12.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v12121580508795118 { constructor() { diff --git a/packages/backend/migration/1580543501339-v12-13.js b/packages/backend/migration/1580543501339-v12-13.js index 2fa490392d..9344516309 100644 --- a/packages/backend/migration/1580543501339-v12-13.js +++ b/packages/backend/migration/1580543501339-v12-13.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v12131580543501339 { constructor() { diff --git a/packages/backend/migration/1580864313253-v12-14.js b/packages/backend/migration/1580864313253-v12-14.js index a3756ad029..5034492a70 100644 --- a/packages/backend/migration/1580864313253-v12-14.js +++ b/packages/backend/migration/1580864313253-v12-14.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class v12141580864313253 { constructor() { diff --git a/packages/backend/migration/1581526429287-user-group-invitation.js b/packages/backend/migration/1581526429287-user-group-invitation.js index 181b0aba86..fc81813807 100644 --- a/packages/backend/migration/1581526429287-user-group-invitation.js +++ b/packages/backend/migration/1581526429287-user-group-invitation.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userGroupInvitation1581526429287 { constructor() { diff --git a/packages/backend/migration/1581695816408-user-group-antenna.js b/packages/backend/migration/1581695816408-user-group-antenna.js index 267b58cd9b..8a212c092a 100644 --- a/packages/backend/migration/1581695816408-user-group-antenna.js +++ b/packages/backend/migration/1581695816408-user-group-antenna.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userGroupAntenna1581695816408 { constructor() { diff --git a/packages/backend/migration/1581708415836-drive-user-folder-id-index.js b/packages/backend/migration/1581708415836-drive-user-folder-id-index.js index 43c2ce6cee..6594078db8 100644 --- a/packages/backend/migration/1581708415836-drive-user-folder-id-index.js +++ b/packages/backend/migration/1581708415836-drive-user-folder-id-index.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class driveUserFolderIdIndex1581708415836 { constructor() { diff --git a/packages/backend/migration/1581979837262-promo.js b/packages/backend/migration/1581979837262-promo.js index 4813a5f480..585564a400 100644 --- a/packages/backend/migration/1581979837262-promo.js +++ b/packages/backend/migration/1581979837262-promo.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class promo1581979837262 { constructor() { diff --git a/packages/backend/migration/1582019042083-featured-injecttion.js b/packages/backend/migration/1582019042083-featured-injecttion.js index 7f8790b01b..d270006277 100644 --- a/packages/backend/migration/1582019042083-featured-injecttion.js +++ b/packages/backend/migration/1582019042083-featured-injecttion.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class featuredInjecttion1582019042083 { constructor() { diff --git a/packages/backend/migration/1582210532752-antenna-exclude.js b/packages/backend/migration/1582210532752-antenna-exclude.js index ff8d7b80d8..12eee2364c 100644 --- a/packages/backend/migration/1582210532752-antenna-exclude.js +++ b/packages/backend/migration/1582210532752-antenna-exclude.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class antennaExclude1582210532752 { constructor() { diff --git a/packages/backend/migration/1582875306439-note-reaction-length.js b/packages/backend/migration/1582875306439-note-reaction-length.js index e99501f012..a4413c9533 100644 --- a/packages/backend/migration/1582875306439-note-reaction-length.js +++ b/packages/backend/migration/1582875306439-note-reaction-length.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class noteReactionLength1582875306439 { constructor() { diff --git a/packages/backend/migration/1585361548360-miauth.js b/packages/backend/migration/1585361548360-miauth.js index e59aa3b6ef..d073fa3d26 100644 --- a/packages/backend/migration/1585361548360-miauth.js +++ b/packages/backend/migration/1585361548360-miauth.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class miauth1585361548360 { constructor() { diff --git a/packages/backend/migration/1585385921215-custom-notification.js b/packages/backend/migration/1585385921215-custom-notification.js index c3ddb2be17..a3336e0eca 100644 --- a/packages/backend/migration/1585385921215-custom-notification.js +++ b/packages/backend/migration/1585385921215-custom-notification.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class customNotification1585385921215 { constructor() { diff --git a/packages/backend/migration/1585772678853-ap-url.js b/packages/backend/migration/1585772678853-ap-url.js index 5fb809ff53..f67f5a4542 100644 --- a/packages/backend/migration/1585772678853-ap-url.js +++ b/packages/backend/migration/1585772678853-ap-url.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class apUrl1585772678853 { constructor() { diff --git a/packages/backend/migration/1586624197029-AddObjectStorageUseProxy.js b/packages/backend/migration/1586624197029-AddObjectStorageUseProxy.js index e13bb217e3..16f7599b80 100644 --- a/packages/backend/migration/1586624197029-AddObjectStorageUseProxy.js +++ b/packages/backend/migration/1586624197029-AddObjectStorageUseProxy.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class AddObjectStorageUseProxy1586624197029 { constructor() { diff --git a/packages/backend/migration/1586641139527-remote-reaction.js b/packages/backend/migration/1586641139527-remote-reaction.js index 5b23103a17..666bb42ca6 100644 --- a/packages/backend/migration/1586641139527-remote-reaction.js +++ b/packages/backend/migration/1586641139527-remote-reaction.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class remoteReaction1586641139527 { constructor() { diff --git a/packages/backend/migration/1586708940386-pageAiScript.js b/packages/backend/migration/1586708940386-pageAiScript.js index eed616c111..3d0d0ab915 100644 --- a/packages/backend/migration/1586708940386-pageAiScript.js +++ b/packages/backend/migration/1586708940386-pageAiScript.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class pageAiScript1586708940386 { constructor() { diff --git a/packages/backend/migration/1588044505511-hCaptcha.js b/packages/backend/migration/1588044505511-hCaptcha.js index a33dbd7133..22cc6672c5 100644 --- a/packages/backend/migration/1588044505511-hCaptcha.js +++ b/packages/backend/migration/1588044505511-hCaptcha.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class hCaptcha1588044505511 { constructor() { diff --git a/packages/backend/migration/1589023282116-pubRelay.js b/packages/backend/migration/1589023282116-pubRelay.js index 48a1028d39..ed010699e1 100644 --- a/packages/backend/migration/1589023282116-pubRelay.js +++ b/packages/backend/migration/1589023282116-pubRelay.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class pubRelay1589023282116 { constructor() { diff --git a/packages/backend/migration/1595075960584-blurhash.js b/packages/backend/migration/1595075960584-blurhash.js index f24d3722cf..967676531f 100644 --- a/packages/backend/migration/1595075960584-blurhash.js +++ b/packages/backend/migration/1595075960584-blurhash.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class blurhash1595075960584 { constructor() { diff --git a/packages/backend/migration/1595077605646-blurhash-for-avatar-banner.js b/packages/backend/migration/1595077605646-blurhash-for-avatar-banner.js index f18f6f972a..7df079ac05 100644 --- a/packages/backend/migration/1595077605646-blurhash-for-avatar-banner.js +++ b/packages/backend/migration/1595077605646-blurhash-for-avatar-banner.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class blurhashForAvatarBanner1595077605646 { constructor() { diff --git a/packages/backend/migration/1595676934834-instance-icon-url.js b/packages/backend/migration/1595676934834-instance-icon-url.js index df9d8199bd..6bccff082b 100644 --- a/packages/backend/migration/1595676934834-instance-icon-url.js +++ b/packages/backend/migration/1595676934834-instance-icon-url.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class instanceIconUrl1595676934834 { constructor() { diff --git a/packages/backend/migration/1595771249699-word-mute.js b/packages/backend/migration/1595771249699-word-mute.js index e8e4ac838b..cfd0a5ccc1 100644 --- a/packages/backend/migration/1595771249699-word-mute.js +++ b/packages/backend/migration/1595771249699-word-mute.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class wordMute1595771249699 { constructor() { diff --git a/packages/backend/migration/1595782306083-word-mute2.js b/packages/backend/migration/1595782306083-word-mute2.js index ab1e40a041..64acf2b721 100644 --- a/packages/backend/migration/1595782306083-word-mute2.js +++ b/packages/backend/migration/1595782306083-word-mute2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class wordMute21595782306083 { constructor() { diff --git a/packages/backend/migration/1596548170836-channel.js b/packages/backend/migration/1596548170836-channel.js index 242db7d45a..a26991d4d8 100644 --- a/packages/backend/migration/1596548170836-channel.js +++ b/packages/backend/migration/1596548170836-channel.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class channel1596548170836 { constructor() { diff --git a/packages/backend/migration/1596786425167-channel2.js b/packages/backend/migration/1596786425167-channel2.js index 4b17048fef..4e87b11bb5 100644 --- a/packages/backend/migration/1596786425167-channel2.js +++ b/packages/backend/migration/1596786425167-channel2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class channel21596786425167 { constructor() { diff --git a/packages/backend/migration/1597230137744-objectStorageSetPublicRead.js b/packages/backend/migration/1597230137744-objectStorageSetPublicRead.js index 07283e31df..93e6f186d5 100644 --- a/packages/backend/migration/1597230137744-objectStorageSetPublicRead.js +++ b/packages/backend/migration/1597230137744-objectStorageSetPublicRead.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class objectStorageSetPublicRead1597230137744 { constructor() { diff --git a/packages/backend/migration/1597236229720-IncludingNotificationTypes.js b/packages/backend/migration/1597236229720-IncludingNotificationTypes.js index f498fa7d9a..bda702d999 100644 --- a/packages/backend/migration/1597236229720-IncludingNotificationTypes.js +++ b/packages/backend/migration/1597236229720-IncludingNotificationTypes.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class IncludingNotificationTypes1597236229720 { constructor() { diff --git a/packages/backend/migration/1597385880794-add-sensitive-index.js b/packages/backend/migration/1597385880794-add-sensitive-index.js index 8c5c040ba0..ffb94895d7 100644 --- a/packages/backend/migration/1597385880794-add-sensitive-index.js +++ b/packages/backend/migration/1597385880794-add-sensitive-index.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class addSensitiveIndex1597385880794 { constructor() { diff --git a/packages/backend/migration/1597459042300-channel-unread.js b/packages/backend/migration/1597459042300-channel-unread.js index 3157ab7793..5b94d8296a 100644 --- a/packages/backend/migration/1597459042300-channel-unread.js +++ b/packages/backend/migration/1597459042300-channel-unread.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class channelUnread1597459042300 { constructor() { diff --git a/packages/backend/migration/1597893996136-ChannelNoteIdDescIndex.js b/packages/backend/migration/1597893996136-ChannelNoteIdDescIndex.js index 2bd8aee358..543e511404 100644 --- a/packages/backend/migration/1597893996136-ChannelNoteIdDescIndex.js +++ b/packages/backend/migration/1597893996136-ChannelNoteIdDescIndex.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ChannelNoteIdDescIndex1597893996136 { constructor() { diff --git a/packages/backend/migration/1600353287890-mutingNotificationTypes.js b/packages/backend/migration/1600353287890-mutingNotificationTypes.js index ed3eb7d146..4e0b8ad6eb 100644 --- a/packages/backend/migration/1600353287890-mutingNotificationTypes.js +++ b/packages/backend/migration/1600353287890-mutingNotificationTypes.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class mutingNotificationTypes1600353287890 { constructor() { diff --git a/packages/backend/migration/1603094348345-refine-abuse-user-report.js b/packages/backend/migration/1603094348345-refine-abuse-user-report.js index 4918032a2b..4e052e07c2 100644 --- a/packages/backend/migration/1603094348345-refine-abuse-user-report.js +++ b/packages/backend/migration/1603094348345-refine-abuse-user-report.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class refineAbuseUserReport1603094348345 { constructor() { diff --git a/packages/backend/migration/1603095701770-refine-abuse-user-report2.js b/packages/backend/migration/1603095701770-refine-abuse-user-report2.js index 64e92672f2..2eb205c6e0 100644 --- a/packages/backend/migration/1603095701770-refine-abuse-user-report2.js +++ b/packages/backend/migration/1603095701770-refine-abuse-user-report2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class refineAbuseUserReport21603095701770 { constructor() { diff --git a/packages/backend/migration/1603776877564-instance-theme-color.js b/packages/backend/migration/1603776877564-instance-theme-color.js index 92440d3f64..5f83bc14e6 100644 --- a/packages/backend/migration/1603776877564-instance-theme-color.js +++ b/packages/backend/migration/1603776877564-instance-theme-color.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class instanceThemeColor1603776877564 { constructor() { diff --git a/packages/backend/migration/1603781553011-instance-favicon.js b/packages/backend/migration/1603781553011-instance-favicon.js index f607c49ffb..758b86408f 100644 --- a/packages/backend/migration/1603781553011-instance-favicon.js +++ b/packages/backend/migration/1603781553011-instance-favicon.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class instanceFavicon1603781553011 { constructor() { diff --git a/packages/backend/migration/1604821689616-delete-auto-watch.js b/packages/backend/migration/1604821689616-delete-auto-watch.js index 4706e8bae9..917ef5b10c 100644 --- a/packages/backend/migration/1604821689616-delete-auto-watch.js +++ b/packages/backend/migration/1604821689616-delete-auto-watch.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class deleteAutoWatch1604821689616 { constructor() { diff --git a/packages/backend/migration/1605408848373-clip-description.js b/packages/backend/migration/1605408848373-clip-description.js index edd5505b30..fedc603b3c 100644 --- a/packages/backend/migration/1605408848373-clip-description.js +++ b/packages/backend/migration/1605408848373-clip-description.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class clipDescription1605408848373 { constructor() { diff --git a/packages/backend/migration/1605408971051-comments.js b/packages/backend/migration/1605408971051-comments.js index 400efd5e70..8ab16859d2 100644 --- a/packages/backend/migration/1605408971051-comments.js +++ b/packages/backend/migration/1605408971051-comments.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class comments1605408971051 { constructor() { diff --git a/packages/backend/migration/1605585339718-instance-pinned-pages.js b/packages/backend/migration/1605585339718-instance-pinned-pages.js index 56ccd44c8e..e6f3c2a785 100644 --- a/packages/backend/migration/1605585339718-instance-pinned-pages.js +++ b/packages/backend/migration/1605585339718-instance-pinned-pages.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class instancePinnedPages1605585339718 { constructor() { diff --git a/packages/backend/migration/1605965516823-instance-images.js b/packages/backend/migration/1605965516823-instance-images.js index 710c75981d..848b53f1ba 100644 --- a/packages/backend/migration/1605965516823-instance-images.js +++ b/packages/backend/migration/1605965516823-instance-images.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class instanceImages1605965516823 { constructor() { diff --git a/packages/backend/migration/1606191203881-no-crawle.js b/packages/backend/migration/1606191203881-no-crawle.js index b9ada4354e..5c878f5a24 100644 --- a/packages/backend/migration/1606191203881-no-crawle.js +++ b/packages/backend/migration/1606191203881-no-crawle.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class noCrawle1606191203881 { constructor() { diff --git a/packages/backend/migration/1607151207216-instance-pinned-clip.js b/packages/backend/migration/1607151207216-instance-pinned-clip.js index 9a4195e74c..67db39fede 100644 --- a/packages/backend/migration/1607151207216-instance-pinned-clip.js +++ b/packages/backend/migration/1607151207216-instance-pinned-clip.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class instancePinnedClip1607151207216 { constructor() { diff --git a/packages/backend/migration/1607353487793-isExplorable.js b/packages/backend/migration/1607353487793-isExplorable.js index d9f1ff4c69..95ee07e917 100644 --- a/packages/backend/migration/1607353487793-isExplorable.js +++ b/packages/backend/migration/1607353487793-isExplorable.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class isExplorable1607353487793 { constructor() { diff --git a/packages/backend/migration/1610277136869-registry.js b/packages/backend/migration/1610277136869-registry.js index 184c062ddb..c5fe2c5a62 100644 --- a/packages/backend/migration/1610277136869-registry.js +++ b/packages/backend/migration/1610277136869-registry.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class registry1610277136869 { constructor() { diff --git a/packages/backend/migration/1610277585759-registry2.js b/packages/backend/migration/1610277585759-registry2.js index 591bafae31..f734a235b0 100644 --- a/packages/backend/migration/1610277585759-registry2.js +++ b/packages/backend/migration/1610277585759-registry2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class registry21610277585759 { constructor() { diff --git a/packages/backend/migration/1610283021566-registry3.js b/packages/backend/migration/1610283021566-registry3.js index e0289f17ee..c94546c732 100644 --- a/packages/backend/migration/1610283021566-registry3.js +++ b/packages/backend/migration/1610283021566-registry3.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class registry31610283021566 { constructor() { diff --git a/packages/backend/migration/1611354329133-followersUri.js b/packages/backend/migration/1611354329133-followersUri.js index 669ddb480e..7e5f8c3093 100644 --- a/packages/backend/migration/1611354329133-followersUri.js +++ b/packages/backend/migration/1611354329133-followersUri.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class followersUri1611354329133 { constructor() { diff --git a/packages/backend/migration/1611397665007-gallery.js b/packages/backend/migration/1611397665007-gallery.js index f49b2df468..cd5c39cc10 100644 --- a/packages/backend/migration/1611397665007-gallery.js +++ b/packages/backend/migration/1611397665007-gallery.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class gallery1611397665007 { constructor() { diff --git a/packages/backend/migration/1611547387175-objectStorageS3ForcePathStyle.js b/packages/backend/migration/1611547387175-objectStorageS3ForcePathStyle.js index e4d3c0e8ec..c0b1da1e53 100644 --- a/packages/backend/migration/1611547387175-objectStorageS3ForcePathStyle.js +++ b/packages/backend/migration/1611547387175-objectStorageS3ForcePathStyle.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class objectStorageS3ForcePathStyle1611547387175 { constructor() { diff --git a/packages/backend/migration/1612619156584-announcement-email.js b/packages/backend/migration/1612619156584-announcement-email.js index bcc718d1c2..f8277725f7 100644 --- a/packages/backend/migration/1612619156584-announcement-email.js +++ b/packages/backend/migration/1612619156584-announcement-email.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class announcementEmail1612619156584 { constructor() { diff --git a/packages/backend/migration/1613155914446-emailNotificationTypes.js b/packages/backend/migration/1613155914446-emailNotificationTypes.js index cd49924d2d..3afe491e48 100644 --- a/packages/backend/migration/1613155914446-emailNotificationTypes.js +++ b/packages/backend/migration/1613155914446-emailNotificationTypes.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class emailNotificationTypes1613155914446 { constructor() { diff --git a/packages/backend/migration/1613181457597-user-lang.js b/packages/backend/migration/1613181457597-user-lang.js index d2cd06848e..33e363477f 100644 --- a/packages/backend/migration/1613181457597-user-lang.js +++ b/packages/backend/migration/1613181457597-user-lang.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userLang1613181457597 { constructor() { diff --git a/packages/backend/migration/1613503367223-use-bigint-for-driveUsage.js b/packages/backend/migration/1613503367223-use-bigint-for-driveUsage.js index f2e2c5d357..9c75c0ae54 100644 --- a/packages/backend/migration/1613503367223-use-bigint-for-driveUsage.js +++ b/packages/backend/migration/1613503367223-use-bigint-for-driveUsage.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class useBigintForDriveUsage1613503367223 { constructor() { diff --git a/packages/backend/migration/1615965918224-chart-v2.js b/packages/backend/migration/1615965918224-chart-v2.js index 86fa5b0c00..2c0cacd1d9 100644 --- a/packages/backend/migration/1615965918224-chart-v2.js +++ b/packages/backend/migration/1615965918224-chart-v2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV21615965918224 { constructor() { diff --git a/packages/backend/migration/1615966519402-chart-v2-2.js b/packages/backend/migration/1615966519402-chart-v2-2.js index c62f1b875c..8d6ebf6a81 100644 --- a/packages/backend/migration/1615966519402-chart-v2-2.js +++ b/packages/backend/migration/1615966519402-chart-v2-2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV221615966519402 { constructor() { diff --git a/packages/backend/migration/1618637372000-user-last-active-date.js b/packages/backend/migration/1618637372000-user-last-active-date.js index 6c77ace467..8b4652898d 100644 --- a/packages/backend/migration/1618637372000-user-last-active-date.js +++ b/packages/backend/migration/1618637372000-user-last-active-date.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userLastActiveDate1618637372000 { constructor() { diff --git a/packages/backend/migration/1618639857000-user-hide-online-status.js b/packages/backend/migration/1618639857000-user-hide-online-status.js index e63c8ae11f..1f19a7ebb4 100644 --- a/packages/backend/migration/1618639857000-user-hide-online-status.js +++ b/packages/backend/migration/1618639857000-user-hide-online-status.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userHideOnlineStatus1618639857000 { constructor() { diff --git a/packages/backend/migration/1619942102890-password-reset.js b/packages/backend/migration/1619942102890-password-reset.js index 922d225dc9..9898011774 100644 --- a/packages/backend/migration/1619942102890-password-reset.js +++ b/packages/backend/migration/1619942102890-password-reset.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class passwordReset1619942102890 { constructor() { diff --git a/packages/backend/migration/1620019354680-ad.js b/packages/backend/migration/1620019354680-ad.js index c96d2bfb33..1ae66d71f4 100644 --- a/packages/backend/migration/1620019354680-ad.js +++ b/packages/backend/migration/1620019354680-ad.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ad1620019354680 { constructor() { diff --git a/packages/backend/migration/1620364649428-ad2.js b/packages/backend/migration/1620364649428-ad2.js index db1c3e1de1..b9b26be076 100644 --- a/packages/backend/migration/1620364649428-ad2.js +++ b/packages/backend/migration/1620364649428-ad2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ad21620364649428 { constructor() { diff --git a/packages/backend/migration/1621479946000-add-note-indexes.js b/packages/backend/migration/1621479946000-add-note-indexes.js index dcf97fa4dc..299c1f6c02 100644 --- a/packages/backend/migration/1621479946000-add-note-indexes.js +++ b/packages/backend/migration/1621479946000-add-note-indexes.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class addNoteIndexes1621479946000 { constructor() { diff --git a/packages/backend/migration/1622679304522-user-profile-description-length.js b/packages/backend/migration/1622679304522-user-profile-description-length.js index 22f6c1c5d9..988456fe7d 100644 --- a/packages/backend/migration/1622679304522-user-profile-description-length.js +++ b/packages/backend/migration/1622679304522-user-profile-description-length.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userProfileDescriptionLength1622679304522 { constructor() { diff --git a/packages/backend/migration/1622681548499-log-message-length.js b/packages/backend/migration/1622681548499-log-message-length.js index ac16c0e1ba..e1fa22c88b 100644 --- a/packages/backend/migration/1622681548499-log-message-length.js +++ b/packages/backend/migration/1622681548499-log-message-length.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class logMessageLength1622681548499 { constructor() { diff --git a/packages/backend/migration/1626509500668-fix-remote-file-proxy.js b/packages/backend/migration/1626509500668-fix-remote-file-proxy.js index 30c562007b..906e49cabb 100644 --- a/packages/backend/migration/1626509500668-fix-remote-file-proxy.js +++ b/packages/backend/migration/1626509500668-fix-remote-file-proxy.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class fixRemoteFileProxy1626509500668 { constructor() { diff --git a/packages/backend/migration/1629004542760-chart-reindex.js b/packages/backend/migration/1629004542760-chart-reindex.js index a7d459276d..f1d08ecfe4 100644 --- a/packages/backend/migration/1629004542760-chart-reindex.js +++ b/packages/backend/migration/1629004542760-chart-reindex.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartReindex1629004542760 { constructor() { diff --git a/packages/backend/migration/1629024377804-deepl-integration.js b/packages/backend/migration/1629024377804-deepl-integration.js index 19c49ffcde..465f1bcca9 100644 --- a/packages/backend/migration/1629024377804-deepl-integration.js +++ b/packages/backend/migration/1629024377804-deepl-integration.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class deeplIntegration1629024377804 { constructor() { diff --git a/packages/backend/migration/1629288472000-fix-channel-userId.js b/packages/backend/migration/1629288472000-fix-channel-userId.js index 02a1199b09..9f946ad550 100644 --- a/packages/backend/migration/1629288472000-fix-channel-userId.js +++ b/packages/backend/migration/1629288472000-fix-channel-userId.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class fixChannelUserId1629288472000 { constructor() { diff --git a/packages/backend/migration/1629512953000-user-is-deleted.js b/packages/backend/migration/1629512953000-user-is-deleted.js index a7848d5690..78bbd8bbee 100644 --- a/packages/backend/migration/1629512953000-user-is-deleted.js +++ b/packages/backend/migration/1629512953000-user-is-deleted.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class isUserDeleted1629512953000 { constructor() { diff --git a/packages/backend/migration/1629778475000-deepl-integration2.js b/packages/backend/migration/1629778475000-deepl-integration2.js index 699f06c768..b719dcf57f 100644 --- a/packages/backend/migration/1629778475000-deepl-integration2.js +++ b/packages/backend/migration/1629778475000-deepl-integration2.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class deeplIntegration21629778475000 { constructor() { diff --git a/packages/backend/migration/1629833361000-AddShowTLReplies.js b/packages/backend/migration/1629833361000-AddShowTLReplies.js index 5d4c938a7b..00aef6aeb8 100644 --- a/packages/backend/migration/1629833361000-AddShowTLReplies.js +++ b/packages/backend/migration/1629833361000-AddShowTLReplies.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class addShowTLReplies1629833361000 { constructor() { diff --git a/packages/backend/migration/1629968054000_userInstanceBlocks.js b/packages/backend/migration/1629968054000_userInstanceBlocks.js index 1f202d9f66..e8168e372e 100644 --- a/packages/backend/migration/1629968054000_userInstanceBlocks.js +++ b/packages/backend/migration/1629968054000_userInstanceBlocks.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userInstanceBlocks1629968054000 { constructor() { diff --git a/packages/backend/migration/1633068642000-email-required-for-signup.js b/packages/backend/migration/1633068642000-email-required-for-signup.js index d592f3ca21..230227d364 100644 --- a/packages/backend/migration/1633068642000-email-required-for-signup.js +++ b/packages/backend/migration/1633068642000-email-required-for-signup.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class emailRequiredForSignup1633068642000 { constructor() { diff --git a/packages/backend/migration/1633071909016-user-pending.js b/packages/backend/migration/1633071909016-user-pending.js index 17cf5c11be..f0d037967f 100644 --- a/packages/backend/migration/1633071909016-user-pending.js +++ b/packages/backend/migration/1633071909016-user-pending.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userPending1633071909016 { constructor() { diff --git a/packages/backend/migration/1634486652000-user-public-reactions.js b/packages/backend/migration/1634486652000-user-public-reactions.js index e741122491..09870c79c6 100644 --- a/packages/backend/migration/1634486652000-user-public-reactions.js +++ b/packages/backend/migration/1634486652000-user-public-reactions.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class userPublicReactions1634486652000 { constructor() { diff --git a/packages/backend/migration/1634902659689-delete-log.js b/packages/backend/migration/1634902659689-delete-log.js index 555a0020c3..e4e625536b 100644 --- a/packages/backend/migration/1634902659689-delete-log.js +++ b/packages/backend/migration/1634902659689-delete-log.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class deleteLog1634902659689 { constructor() { diff --git a/packages/backend/migration/1635500777168-note-thread-mute.js b/packages/backend/migration/1635500777168-note-thread-mute.js index a790cace33..9f376c4795 100644 --- a/packages/backend/migration/1635500777168-note-thread-mute.js +++ b/packages/backend/migration/1635500777168-note-thread-mute.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class noteThreadMute1635500777168 { constructor() { diff --git a/packages/backend/migration/1636197624383-ff-visibility.js b/packages/backend/migration/1636197624383-ff-visibility.js index 89028f3c22..aa089d42ac 100644 --- a/packages/backend/migration/1636197624383-ff-visibility.js +++ b/packages/backend/migration/1636197624383-ff-visibility.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class ffVisibility1636197624383 { constructor() { diff --git a/packages/backend/migration/1636697408073-remove-via-mobile.js b/packages/backend/migration/1636697408073-remove-via-mobile.js index 36e96fd21e..c014ceb921 100644 --- a/packages/backend/migration/1636697408073-remove-via-mobile.js +++ b/packages/backend/migration/1636697408073-remove-via-mobile.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class removeViaMobile1636697408073 { name = 'removeViaMobile1636697408073' diff --git a/packages/backend/migration/1637320813000-forwarded-report.js b/packages/backend/migration/1637320813000-forwarded-report.js index 1e39bd5c3f..0d1f48beb4 100644 --- a/packages/backend/migration/1637320813000-forwarded-report.js +++ b/packages/backend/migration/1637320813000-forwarded-report.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class forwardedReport1637320813000 { name = 'forwardedReport1637320813000'; diff --git a/packages/backend/migration/1639325650583-chart-v3.js b/packages/backend/migration/1639325650583-chart-v3.js index e2a4e920c9..e6209e2b70 100644 --- a/packages/backend/migration/1639325650583-chart-v3.js +++ b/packages/backend/migration/1639325650583-chart-v3.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV31639325650583 { name = 'chartV31639325650583' diff --git a/packages/backend/migration/1642611822809-emoji-url.js b/packages/backend/migration/1642611822809-emoji-url.js index d38f8cc08c..212fc957ad 100644 --- a/packages/backend/migration/1642611822809-emoji-url.js +++ b/packages/backend/migration/1642611822809-emoji-url.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class emojiUrl1642611822809 { name = 'emojiUrl1642611822809' diff --git a/packages/backend/migration/1642613870898-drive-file-webpublic-type.js b/packages/backend/migration/1642613870898-drive-file-webpublic-type.js index 15434f7d0c..e50770fff3 100644 --- a/packages/backend/migration/1642613870898-drive-file-webpublic-type.js +++ b/packages/backend/migration/1642613870898-drive-file-webpublic-type.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class driveFileWebpublicType1642613870898 { name = 'driveFileWebpublicType1642613870898' diff --git a/packages/backend/migration/1643963705770-chart-v4.js b/packages/backend/migration/1643963705770-chart-v4.js index 8b320c2b41..af0bd18e58 100644 --- a/packages/backend/migration/1643963705770-chart-v4.js +++ b/packages/backend/migration/1643963705770-chart-v4.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV41643963705770 { name = 'chartV41643963705770' diff --git a/packages/backend/migration/1643966656277-chart-v5.js b/packages/backend/migration/1643966656277-chart-v5.js index df84002f78..b3389a6539 100644 --- a/packages/backend/migration/1643966656277-chart-v5.js +++ b/packages/backend/migration/1643966656277-chart-v5.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV51643966656277 { name = 'chartV51643966656277' diff --git a/packages/backend/migration/1643967331284-chart-v6.js b/packages/backend/migration/1643967331284-chart-v6.js index 119198f4a5..1197bdd717 100644 --- a/packages/backend/migration/1643967331284-chart-v6.js +++ b/packages/backend/migration/1643967331284-chart-v6.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV61643967331284 { name = 'chartV61643967331284' diff --git a/packages/backend/migration/1644010796173-convert-hard-mutes.js b/packages/backend/migration/1644010796173-convert-hard-mutes.js index 207a759b8e..1a5316ac05 100644 --- a/packages/backend/migration/1644010796173-convert-hard-mutes.js +++ b/packages/backend/migration/1644010796173-convert-hard-mutes.js @@ -1,5 +1,9 @@ -import RE2 from 're2'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ +import RE2 from 're2'; export class convertHardMutes1644010796173 { name = 'convertHardMutes1644010796173' diff --git a/packages/backend/migration/1644058404077-chart-v7.js b/packages/backend/migration/1644058404077-chart-v7.js index f05ad003db..a850d5f48f 100644 --- a/packages/backend/migration/1644058404077-chart-v7.js +++ b/packages/backend/migration/1644058404077-chart-v7.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV71644058404077 { name = 'chartV71644058404077' diff --git a/packages/backend/migration/1644059847460-chart-v8.js b/packages/backend/migration/1644059847460-chart-v8.js index a5339c0ebd..2e20159ba9 100644 --- a/packages/backend/migration/1644059847460-chart-v8.js +++ b/packages/backend/migration/1644059847460-chart-v8.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV81644059847460 { name = 'chartV81644059847460' @@ -14,9 +17,9 @@ export class chartV81644059847460 { await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`); await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`); } - + async down(queryRunner) { - + await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`); await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); diff --git a/packages/backend/migration/1644060125705-chart-v9.js b/packages/backend/migration/1644060125705-chart-v9.js index da35d42315..d1d9469ea2 100644 --- a/packages/backend/migration/1644060125705-chart-v9.js +++ b/packages/backend/migration/1644060125705-chart-v9.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV91644060125705 { name = 'chartV91644060125705' @@ -14,9 +17,9 @@ export class chartV91644060125705 { await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___local_users" TYPE integer USING "___local_users"::integer`); await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___remote_users" TYPE integer USING "___remote_users"::integer`); } - + async down(queryRunner) { - + await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); await queryRunner.query(`ALTER TABLE "__chart__hashtag" ALTER COLUMN "___remote_users" TYPE bigint USING "___remote_users"::bigint`); await queryRunner.query(`ALTER TABLE "__chart_day__hashtag" ALTER COLUMN "___local_users" TYPE bigint USING "___local_users"::bigint`); diff --git a/packages/backend/migration/1644073149413-chart-v10.js b/packages/backend/migration/1644073149413-chart-v10.js index 7260bbeca4..466ae59837 100644 --- a/packages/backend/migration/1644073149413-chart-v10.js +++ b/packages/backend/migration/1644073149413-chart-v10.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV101644073149413 { name = 'chartV101644073149413' diff --git a/packages/backend/migration/1644095659741-chart-v11.js b/packages/backend/migration/1644095659741-chart-v11.js index 309fff1d9a..5c98e25d86 100644 --- a/packages/backend/migration/1644095659741-chart-v11.js +++ b/packages/backend/migration/1644095659741-chart-v11.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV111644095659741 { name = 'chartV111644095659741' diff --git a/packages/backend/migration/1644328606241-chart-v12.js b/packages/backend/migration/1644328606241-chart-v12.js index c3c7e44f95..2a7272fd22 100644 --- a/packages/backend/migration/1644328606241-chart-v12.js +++ b/packages/backend/migration/1644328606241-chart-v12.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV121644328606241 { name = 'chartV121644328606241' diff --git a/packages/backend/migration/1644331238153-chart-v13.js b/packages/backend/migration/1644331238153-chart-v13.js index 639f7b4e20..7e33b0a8e9 100644 --- a/packages/backend/migration/1644331238153-chart-v13.js +++ b/packages/backend/migration/1644331238153-chart-v13.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV131644331238153 { name = 'chartV131644331238153' diff --git a/packages/backend/migration/1644344266289-chart-v14.js b/packages/backend/migration/1644344266289-chart-v14.js index a0d9cfc38c..2050d54591 100644 --- a/packages/backend/migration/1644344266289-chart-v14.js +++ b/packages/backend/migration/1644344266289-chart-v14.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV141644344266289 { name = 'chartV141644344266289' diff --git a/packages/backend/migration/1644395759931-instance-theme-color.js b/packages/backend/migration/1644395759931-instance-theme-color.js index 8f335ad210..ac842e4fe5 100644 --- a/packages/backend/migration/1644395759931-instance-theme-color.js +++ b/packages/backend/migration/1644395759931-instance-theme-color.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class instanceThemeColor1644395759931 { name = 'instanceThemeColor1644395759931' diff --git a/packages/backend/migration/1644481657998-chart-v15.js b/packages/backend/migration/1644481657998-chart-v15.js index b50ca87c40..ad5589df8b 100644 --- a/packages/backend/migration/1644481657998-chart-v15.js +++ b/packages/backend/migration/1644481657998-chart-v15.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class chartV151644481657998 { name = 'chartV151644481657998' diff --git a/packages/backend/migration/1644551208096-following-indexes.js b/packages/backend/migration/1644551208096-following-indexes.js index 276473ff6c..795b8e900e 100644 --- a/packages/backend/migration/1644551208096-following-indexes.js +++ b/packages/backend/migration/1644551208096-following-indexes.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class followingIndexes1644551208096 { name = 'followingIndexes1644551208096' diff --git a/packages/backend/migration/1645340161439-remove-max-note-text-length.js b/packages/backend/migration/1645340161439-remove-max-note-text-length.js index c88cb70bfb..84eaeddfa4 100644 --- a/packages/backend/migration/1645340161439-remove-max-note-text-length.js +++ b/packages/backend/migration/1645340161439-remove-max-note-text-length.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class removeMaxNoteTextLength1645340161439 { name = 'removeMaxNoteTextLength1645340161439' diff --git a/packages/backend/migration/1645599900873-federation-chart-pubsub.js b/packages/backend/migration/1645599900873-federation-chart-pubsub.js index fd7cb6d5a1..4f9f501cca 100644 --- a/packages/backend/migration/1645599900873-federation-chart-pubsub.js +++ b/packages/backend/migration/1645599900873-federation-chart-pubsub.js @@ -1,4 +1,7 @@ - +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class federationChartPubsub1645599900873 { name = 'federationChartPubsub1645599900873' diff --git a/packages/backend/migration/1646143552768-instance-default-theme.js b/packages/backend/migration/1646143552768-instance-default-theme.js index 029354fd92..3532916304 100644 --- a/packages/backend/migration/1646143552768-instance-default-theme.js +++ b/packages/backend/migration/1646143552768-instance-default-theme.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class instanceDefaultTheme1646143552768 { name = 'instanceDefaultTheme1646143552768' diff --git a/packages/backend/migration/1646387162108-mute-expires-at.js b/packages/backend/migration/1646387162108-mute-expires-at.js index c8be8f3c54..868f5c87ef 100644 --- a/packages/backend/migration/1646387162108-mute-expires-at.js +++ b/packages/backend/migration/1646387162108-mute-expires-at.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class muteExpiresAt1646387162108 { name = 'muteExpiresAt1646387162108' diff --git a/packages/backend/migration/1646549089451-poll-ended-notification.js b/packages/backend/migration/1646549089451-poll-ended-notification.js index 38a38ce64d..fa7327ff9c 100644 --- a/packages/backend/migration/1646549089451-poll-ended-notification.js +++ b/packages/backend/migration/1646549089451-poll-ended-notification.js @@ -1,3 +1,7 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class pollEndedNotification1646549089451 { name = 'pollEndedNotification1646549089451' diff --git a/packages/backend/migration/1646633030285-chart-federation-active.js b/packages/backend/migration/1646633030285-chart-federation-active.js index 952289c8f8..b9863746ad 100644 --- a/packages/backend/migration/1646633030285-chart-federation-active.js +++ b/packages/backend/migration/1646633030285-chart-federation-active.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class chartFederationActive1646633030285 { name = 'chartFederationActive1646633030285' diff --git a/packages/backend/migration/1646655454495-remove-instance-drive-columns.js b/packages/backend/migration/1646655454495-remove-instance-drive-columns.js index a0ee1b2c43..8fd96ed4c6 100644 --- a/packages/backend/migration/1646655454495-remove-instance-drive-columns.js +++ b/packages/backend/migration/1646655454495-remove-instance-drive-columns.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class removeInstanceDriveColumns1646655454495 { name = 'removeInstanceDriveColumns1646655454495' diff --git a/packages/backend/migration/1646732390560-chart-federation-active-sub-pub.js b/packages/backend/migration/1646732390560-chart-federation-active-sub-pub.js index c9a847cbcf..1b28d012ae 100644 --- a/packages/backend/migration/1646732390560-chart-federation-active-sub-pub.js +++ b/packages/backend/migration/1646732390560-chart-federation-active-sub-pub.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class chartFederationActiveSubPub1646732390560 { name = 'chartFederationActiveSubPub1646732390560' diff --git a/packages/backend/migration/1648548247382-webhook.js b/packages/backend/migration/1648548247382-webhook.js index aea369a5cc..fc2a691918 100644 --- a/packages/backend/migration/1648548247382-webhook.js +++ b/packages/backend/migration/1648548247382-webhook.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class webhook1648548247382 { name = 'webhook1648548247382' diff --git a/packages/backend/migration/1648816172177-webhook-2.js b/packages/backend/migration/1648816172177-webhook-2.js index 2feb68d611..a7bccff82d 100644 --- a/packages/backend/migration/1648816172177-webhook-2.js +++ b/packages/backend/migration/1648816172177-webhook-2.js @@ -1,3 +1,7 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class webhook21648816172177 { name = 'webhook21648816172177' diff --git a/packages/backend/migration/1651224615271-foreign-key.js b/packages/backend/migration/1651224615271-foreign-key.js index 535d21731a..12e4646329 100644 --- a/packages/backend/migration/1651224615271-foreign-key.js +++ b/packages/backend/migration/1651224615271-foreign-key.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class foreignKeyReports1651224615271 { name = 'foreignKeyReports1651224615271' diff --git a/packages/backend/migration/1652859567549-uniform-themecolor.js b/packages/backend/migration/1652859567549-uniform-themecolor.js index 8da1fd7fbb..422e63dfec 100644 --- a/packages/backend/migration/1652859567549-uniform-themecolor.js +++ b/packages/backend/migration/1652859567549-uniform-themecolor.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import tinycolor from 'tinycolor2'; export class uniformThemecolor1652859567549 { diff --git a/packages/backend/migration/1655368940105-nsfw-detection.js b/packages/backend/migration/1655368940105-nsfw-detection.js index 9268f43407..ad37ff6f83 100644 --- a/packages/backend/migration/1655368940105-nsfw-detection.js +++ b/packages/backend/migration/1655368940105-nsfw-detection.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class nsfwDetection1655368940105 { name = 'nsfwDetection1655368940105' diff --git a/packages/backend/migration/1655371960534-nsfw-detection-2.js b/packages/backend/migration/1655371960534-nsfw-detection-2.js index aac6f37dad..e6cc266178 100644 --- a/packages/backend/migration/1655371960534-nsfw-detection-2.js +++ b/packages/backend/migration/1655371960534-nsfw-detection-2.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class nsfwDetection21655371960534 { name = 'nsfwDetection21655371960534' diff --git a/packages/backend/migration/1655388169582-nsfw-detection-3.js b/packages/backend/migration/1655388169582-nsfw-detection-3.js index a5c80cf968..40362cc20c 100644 --- a/packages/backend/migration/1655388169582-nsfw-detection-3.js +++ b/packages/backend/migration/1655388169582-nsfw-detection-3.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class nsfwDetection31655388169582 { name = 'nsfwDetection31655388169582' diff --git a/packages/backend/migration/1655393015659-nsfw-detection-4.js b/packages/backend/migration/1655393015659-nsfw-detection-4.js index e780732623..d74fe9c929 100644 --- a/packages/backend/migration/1655393015659-nsfw-detection-4.js +++ b/packages/backend/migration/1655393015659-nsfw-detection-4.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class nsfwDetection41655393015659 { name = 'nsfwDetection41655393015659' diff --git a/packages/backend/migration/1655813815729-driveCapacityOverrideMb.js b/packages/backend/migration/1655813815729-driveCapacityOverrideMb.js index f257cd112f..7e97f9dc74 100644 --- a/packages/backend/migration/1655813815729-driveCapacityOverrideMb.js +++ b/packages/backend/migration/1655813815729-driveCapacityOverrideMb.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class driveCapacityOverrideMb1655813815729 { name = 'driveCapacityOverrideMb1655813815729' diff --git a/packages/backend/migration/1655918165614-user-ip.js b/packages/backend/migration/1655918165614-user-ip.js index 2294fbaf19..ccb3ceb49d 100644 --- a/packages/backend/migration/1655918165614-user-ip.js +++ b/packages/backend/migration/1655918165614-user-ip.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class userIp1655918165614 { name = 'userIp1655918165614' diff --git a/packages/backend/migration/1656122560740-file-ip.js b/packages/backend/migration/1656122560740-file-ip.js index b59e7a911f..dc02df0e68 100644 --- a/packages/backend/migration/1656122560740-file-ip.js +++ b/packages/backend/migration/1656122560740-file-ip.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class fileIp1656122560740 { name = 'fileIp1656122560740' diff --git a/packages/backend/migration/1656251734807-nsfw-detection-5.js b/packages/backend/migration/1656251734807-nsfw-detection-5.js index 6f0c536907..06da9251b1 100644 --- a/packages/backend/migration/1656251734807-nsfw-detection-5.js +++ b/packages/backend/migration/1656251734807-nsfw-detection-5.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class nsfwDetection51656251734807 { name = 'nsfwDetection51656251734807' diff --git a/packages/backend/migration/1656328812281-ip-2.js b/packages/backend/migration/1656328812281-ip-2.js index b0ee1ebfc7..1b53e697de 100644 --- a/packages/backend/migration/1656328812281-ip-2.js +++ b/packages/backend/migration/1656328812281-ip-2.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class ip21656328812281 { name = 'ip21656328812281' diff --git a/packages/backend/migration/1656408772602-nsfw-detection-6.js b/packages/backend/migration/1656408772602-nsfw-detection-6.js index 7ef223a4c6..0adc8bb793 100644 --- a/packages/backend/migration/1656408772602-nsfw-detection-6.js +++ b/packages/backend/migration/1656408772602-nsfw-detection-6.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class nsfwDetection61656408772602 { name = 'nsfwDetection61656408772602' diff --git a/packages/backend/migration/1656772790599-user-moderation-note.js b/packages/backend/migration/1656772790599-user-moderation-note.js index 133bcffe1a..63a993851f 100644 --- a/packages/backend/migration/1656772790599-user-moderation-note.js +++ b/packages/backend/migration/1656772790599-user-moderation-note.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class userModerationNote1656772790599 { name = 'userModerationNote1656772790599' diff --git a/packages/backend/migration/1657346559800-active-email-validation.js b/packages/backend/migration/1657346559800-active-email-validation.js index f8e03eeb07..44b1f3f4fa 100644 --- a/packages/backend/migration/1657346559800-active-email-validation.js +++ b/packages/backend/migration/1657346559800-active-email-validation.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class activeEmailValidation1657346559800 { name = 'activeEmailValidation1657346559800' diff --git a/packages/backend/migration/1664694635394-turnstile.js b/packages/backend/migration/1664694635394-turnstile.js index 4a33443950..3ec6da9136 100644 --- a/packages/backend/migration/1664694635394-turnstile.js +++ b/packages/backend/migration/1664694635394-turnstile.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class turnstile1664694635394 { name = 'turnstile1664694635394' diff --git a/packages/backend/migration/1665091090561-add-renote-muting.js b/packages/backend/migration/1665091090561-add-renote-muting.js index d2ed2bd2e9..a22d7037f3 100644 --- a/packages/backend/migration/1665091090561-add-renote-muting.js +++ b/packages/backend/migration/1665091090561-add-renote-muting.js @@ -1,3 +1,7 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export class addRenoteMuting1665091090561 { constructor() { @@ -12,5 +16,9 @@ export class addRenoteMuting1665091090561 { } async down(queryRunner) { + await queryRunner.query(`DROP INDEX "IDX_renote_muting_muterId"`); + await queryRunner.query(`DROP INDEX "IDX_renote_muting_muteeId"`); + await queryRunner.query(`DROP INDEX "IDX_renote_muting_createdAt"`); + await queryRunner.query(`DROP TABLE "renote_muting"`); } } diff --git a/packages/backend/migration/1669138716634-whetherPushNotifyToSendReadMessage.js b/packages/backend/migration/1669138716634-whetherPushNotifyToSendReadMessage.js index 2265b00617..a317468ac9 100644 --- a/packages/backend/migration/1669138716634-whetherPushNotifyToSendReadMessage.js +++ b/packages/backend/migration/1669138716634-whetherPushNotifyToSendReadMessage.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class whetherPushNotifyToSendReadMessage1669138716634 { name = 'whetherPushNotifyToSendReadMessage1669138716634' diff --git a/packages/backend/migration/1671924750884-RetentionAggregation.js b/packages/backend/migration/1671924750884-RetentionAggregation.js index ed81a4b5e9..5057bf1060 100644 --- a/packages/backend/migration/1671924750884-RetentionAggregation.js +++ b/packages/backend/migration/1671924750884-RetentionAggregation.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RetentionAggregation1671924750884 { name = 'RetentionAggregation1671924750884' diff --git a/packages/backend/migration/1671926422832-RetentionAggregation2.js b/packages/backend/migration/1671926422832-RetentionAggregation2.js index 725429e6ef..665e24d721 100644 --- a/packages/backend/migration/1671926422832-RetentionAggregation2.js +++ b/packages/backend/migration/1671926422832-RetentionAggregation2.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RetentionAggregation21671926422832 { name = 'RetentionAggregation21671926422832' diff --git a/packages/backend/migration/1672562400597-PerUserPvChart.js b/packages/backend/migration/1672562400597-PerUserPvChart.js index 4da6b9a8b3..1fbe1eb14a 100644 --- a/packages/backend/migration/1672562400597-PerUserPvChart.js +++ b/packages/backend/migration/1672562400597-PerUserPvChart.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class PerUserPvChart1672562400597 { name = 'PerUserPvChart1672562400597' diff --git a/packages/backend/migration/1672703171386-remove-latestRequestSentAt.js b/packages/backend/migration/1672703171386-remove-latestRequestSentAt.js index c9b28dd7e1..f053e5c20c 100644 --- a/packages/backend/migration/1672703171386-remove-latestRequestSentAt.js +++ b/packages/backend/migration/1672703171386-remove-latestRequestSentAt.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class removeLatestRequestSentAt1672703171386 { name = 'removeLatestRequestSentAt1672703171386' diff --git a/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js b/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js index 38a6769851..b71f7e1306 100644 --- a/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js +++ b/packages/backend/migration/1672704017999-remove-lastCommunicatedAt.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class removeLastCommunicatedAt1672704017999 { name = 'removeLastCommunicatedAt1672704017999' diff --git a/packages/backend/migration/1672704136584-remove-latestStatus.js b/packages/backend/migration/1672704136584-remove-latestStatus.js index 937c2fe8fd..f08ed96a45 100644 --- a/packages/backend/migration/1672704136584-remove-latestStatus.js +++ b/packages/backend/migration/1672704136584-remove-latestStatus.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class removeLatestStatus1672704136584 { name = 'removeLatestStatus1672704136584' diff --git a/packages/backend/migration/1672822262496-Flash.js b/packages/backend/migration/1672822262496-Flash.js index 6c2338fab2..e45055b3cc 100644 --- a/packages/backend/migration/1672822262496-Flash.js +++ b/packages/backend/migration/1672822262496-Flash.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class Flash1672822262496 { name = 'Flash1672822262496' diff --git a/packages/backend/migration/1673336077243-PollChoiceLength.js b/packages/backend/migration/1673336077243-PollChoiceLength.js index 810c626e04..8c4a5007e4 100644 --- a/packages/backend/migration/1673336077243-PollChoiceLength.js +++ b/packages/backend/migration/1673336077243-PollChoiceLength.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class PollChoiceLength1673336077243 { name = 'PollChoiceLength1673336077243' diff --git a/packages/backend/migration/1673500412259-Role.js b/packages/backend/migration/1673500412259-Role.js index a8acedf5b7..2bf6a7f4e8 100644 --- a/packages/backend/migration/1673500412259-Role.js +++ b/packages/backend/migration/1673500412259-Role.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class Role1673500412259 { name = 'Role1673500412259' diff --git a/packages/backend/migration/1673515526953-RoleColor.js b/packages/backend/migration/1673515526953-RoleColor.js index 343eedf346..693dcfb0b6 100644 --- a/packages/backend/migration/1673515526953-RoleColor.js +++ b/packages/backend/migration/1673515526953-RoleColor.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RoleColor1673515526953 { name = 'RoleColor1673515526953' diff --git a/packages/backend/migration/1673522856499-RoleIroiro.js b/packages/backend/migration/1673522856499-RoleIroiro.js index a1e64d49fe..10a6eef162 100644 --- a/packages/backend/migration/1673522856499-RoleIroiro.js +++ b/packages/backend/migration/1673522856499-RoleIroiro.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RoleIroiro1673522856499 { name = 'RoleIroiro1673522856499' diff --git a/packages/backend/migration/1673524604156-RoleLastUsedAt.js b/packages/backend/migration/1673524604156-RoleLastUsedAt.js index 786ef07f5e..5bbd0c39ac 100644 --- a/packages/backend/migration/1673524604156-RoleLastUsedAt.js +++ b/packages/backend/migration/1673524604156-RoleLastUsedAt.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RoleLastUsedAt1673524604156 { name = 'RoleLastUsedAt1673524604156' diff --git a/packages/backend/migration/1673570377815-RoleConditional.js b/packages/backend/migration/1673570377815-RoleConditional.js index 11ae4f00c6..d2b25d121e 100644 --- a/packages/backend/migration/1673570377815-RoleConditional.js +++ b/packages/backend/migration/1673570377815-RoleConditional.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RoleConditional1673570377815 { name = 'RoleConditional1673570377815' diff --git a/packages/backend/migration/1673575973645-MetaClean.js b/packages/backend/migration/1673575973645-MetaClean.js index 11be4c1cdd..7671785d94 100644 --- a/packages/backend/migration/1673575973645-MetaClean.js +++ b/packages/backend/migration/1673575973645-MetaClean.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class MetaClean1673575973645 { name = 'MetaClean1673575973645' diff --git a/packages/backend/migration/1673783015567-Policies.js b/packages/backend/migration/1673783015567-Policies.js index 8b36921d41..4f76752c9f 100644 --- a/packages/backend/migration/1673783015567-Policies.js +++ b/packages/backend/migration/1673783015567-Policies.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class Policies1673783015567 { name = 'Policies1673783015567' diff --git a/packages/backend/migration/1673812883772-firstRetrievedAt.js b/packages/backend/migration/1673812883772-firstRetrievedAt.js index 5603bbc7c4..82990e30b6 100644 --- a/packages/backend/migration/1673812883772-firstRetrievedAt.js +++ b/packages/backend/migration/1673812883772-firstRetrievedAt.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class firstRetrievedAt1673812883772 { name = 'firstRetrievedAt1673812883772' diff --git a/packages/backend/migration/1674086433654-flashScriptLength.js b/packages/backend/migration/1674086433654-flashScriptLength.js index a4d149fe15..996fe8c691 100644 --- a/packages/backend/migration/1674086433654-flashScriptLength.js +++ b/packages/backend/migration/1674086433654-flashScriptLength.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class flashScriptLength1674086433654 { name = 'flashScriptLength1674086433654' diff --git a/packages/backend/migration/1674118260469-achievement.js b/packages/backend/migration/1674118260469-achievement.js index 131ab96f80..5d79dc669e 100644 --- a/packages/backend/migration/1674118260469-achievement.js +++ b/packages/backend/migration/1674118260469-achievement.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class achievement1674118260469 { name = 'achievement1674118260469' diff --git a/packages/backend/migration/1674255666603-loggedInDates.js b/packages/backend/migration/1674255666603-loggedInDates.js index 6d75ab6436..a6cf4b400f 100644 --- a/packages/backend/migration/1674255666603-loggedInDates.js +++ b/packages/backend/migration/1674255666603-loggedInDates.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class loggedInDates1674255666603 { name = 'loggedInDates1674255666603' diff --git a/packages/backend/migration/1675053125067-fixforeignkeyreports.js b/packages/backend/migration/1675053125067-fixforeignkeyreports.js index ca5c10b11f..d24dc5ec5a 100644 --- a/packages/backend/migration/1675053125067-fixforeignkeyreports.js +++ b/packages/backend/migration/1675053125067-fixforeignkeyreports.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class fixforeignkeyreports1675053125067 { name = 'fixforeignkeyreports1675053125067' diff --git a/packages/backend/migration/1675404035646-cleanup.js b/packages/backend/migration/1675404035646-cleanup.js index 09b22ee393..c4e4332bbc 100644 --- a/packages/backend/migration/1675404035646-cleanup.js +++ b/packages/backend/migration/1675404035646-cleanup.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class cleanup1675404035646 { name = 'cleanup1675404035646' diff --git a/packages/backend/migration/1675557528704-role-icon-badge.js b/packages/backend/migration/1675557528704-role-icon-badge.js index 0ebca088e3..ee39c07a51 100644 --- a/packages/backend/migration/1675557528704-role-icon-badge.js +++ b/packages/backend/migration/1675557528704-role-icon-badge.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class roleIconBadge1675557528704 { name = 'roleIconBadge1675557528704' diff --git a/packages/backend/migration/1676434944993-drop-group.js b/packages/backend/migration/1676434944993-drop-group.js index c856046eb9..1db2d5818f 100644 --- a/packages/backend/migration/1676434944993-drop-group.js +++ b/packages/backend/migration/1676434944993-drop-group.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class dropGroup1676434944993 { name = 'dropGroup1676434944993' diff --git a/packages/backend/migration/1676438468213-ad3.js b/packages/backend/migration/1676438468213-ad3.js index 18f56e8d36..8347f56b95 100644 --- a/packages/backend/migration/1676438468213-ad3.js +++ b/packages/backend/migration/1676438468213-ad3.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class ad1676438468213 { name = 'ad1676438468213'; async up(queryRunner) { diff --git a/packages/backend/migration/1677054292210-ad4.js b/packages/backend/migration/1677054292210-ad4.js index 48499319b4..037e21059c 100644 --- a/packages/backend/migration/1677054292210-ad4.js +++ b/packages/backend/migration/1677054292210-ad4.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class ad1677054292210 { name = 'ad1677054292210'; async up(queryRunner) { diff --git a/packages/backend/migration/1677570181236-role-assignment-expires-at.js b/packages/backend/migration/1677570181236-role-assignment-expires-at.js index 3ac2edab0a..e44bca1d20 100644 --- a/packages/backend/migration/1677570181236-role-assignment-expires-at.js +++ b/packages/backend/migration/1677570181236-role-assignment-expires-at.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class roleAssignmentExpiresAt1677570181236 { name = 'roleAssignmentExpiresAt1677570181236' diff --git a/packages/backend/migration/1678164627293-per-note-reaction-acceptance.js b/packages/backend/migration/1678164627293-per-note-reaction-acceptance.js index f1765dd146..c85aafbd4c 100644 --- a/packages/backend/migration/1678164627293-per-note-reaction-acceptance.js +++ b/packages/backend/migration/1678164627293-per-note-reaction-acceptance.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class perNoteReactionAcceptance1678164627293 { name = 'perNoteReactionAcceptance1678164627293' diff --git a/packages/backend/migration/1678426061773-tweak-varchar-length.js b/packages/backend/migration/1678426061773-tweak-varchar-length.js index 984c41dba6..2541f99a19 100644 --- a/packages/backend/migration/1678426061773-tweak-varchar-length.js +++ b/packages/backend/migration/1678426061773-tweak-varchar-length.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class tweakVarcharLength1678426061773 { name = 'tweakVarcharLength1678426061773' diff --git a/packages/backend/migration/1678427401214-remove-unused.js b/packages/backend/migration/1678427401214-remove-unused.js index ee643e7776..59f42da080 100644 --- a/packages/backend/migration/1678427401214-remove-unused.js +++ b/packages/backend/migration/1678427401214-remove-unused.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class removeUnused1678427401214 { name = 'removeUnused1678427401214' diff --git a/packages/backend/migration/1678602320354-role-display-order.js b/packages/backend/migration/1678602320354-role-display-order.js index de8f6f1033..0ab7b0c3e2 100644 --- a/packages/backend/migration/1678602320354-role-display-order.js +++ b/packages/backend/migration/1678602320354-role-display-order.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class roleDisplayOrder1678602320354 { name = 'roleDisplayOrder1678602320354' diff --git a/packages/backend/migration/1678694614599-sensitive-words.js b/packages/backend/migration/1678694614599-sensitive-words.js index 6d4c5730c7..5f69424eca 100644 --- a/packages/backend/migration/1678694614599-sensitive-words.js +++ b/packages/backend/migration/1678694614599-sensitive-words.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class sensitiveWords1678694614599 { name = 'sensitiveWords1678694614599' diff --git a/packages/backend/migration/1678869617549-retention-date-key.js b/packages/backend/migration/1678869617549-retention-date-key.js index 1a31b9a750..55bf6248e6 100644 --- a/packages/backend/migration/1678869617549-retention-date-key.js +++ b/packages/backend/migration/1678869617549-retention-date-key.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class retentionDateKey1678869617549 { name = 'retentionDateKey1678869617549' diff --git a/packages/backend/migration/1678945242650-add-props-for-custom-emoji.js b/packages/backend/migration/1678945242650-add-props-for-custom-emoji.js index 656a921770..0054e78f88 100644 --- a/packages/backend/migration/1678945242650-add-props-for-custom-emoji.js +++ b/packages/backend/migration/1678945242650-add-props-for-custom-emoji.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class addPropsForCustomEmoji1678945242650 { name = 'addPropsForCustomEmoji1678945242650' diff --git a/packages/backend/migration/1678953978856-clip-favorite.js b/packages/backend/migration/1678953978856-clip-favorite.js index aa5dc93a6e..13145497bb 100644 --- a/packages/backend/migration/1678953978856-clip-favorite.js +++ b/packages/backend/migration/1678953978856-clip-favorite.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class clipFavorite1678953978856 { name = 'clipFavorite1678953978856' diff --git a/packages/backend/migration/1679309757174-antenna-active.js b/packages/backend/migration/1679309757174-antenna-active.js index 69e845c142..0b2bcc69ff 100644 --- a/packages/backend/migration/1679309757174-antenna-active.js +++ b/packages/backend/migration/1679309757174-antenna-active.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class antennaActive1679309757174 { name = 'antennaActive1679309757174' diff --git a/packages/backend/migration/1679639483253-enableChartsForRemoteUser.js b/packages/backend/migration/1679639483253-enableChartsForRemoteUser.js index 42faab7466..68576064f2 100644 --- a/packages/backend/migration/1679639483253-enableChartsForRemoteUser.js +++ b/packages/backend/migration/1679639483253-enableChartsForRemoteUser.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class enableChartsForRemoteUser1679639483253 { name = 'enableChartsForRemoteUser1679639483253' diff --git a/packages/backend/migration/1679651580149-cleanup.js b/packages/backend/migration/1679651580149-cleanup.js index 1f00f3cc1f..7049891cf0 100644 --- a/packages/backend/migration/1679651580149-cleanup.js +++ b/packages/backend/migration/1679651580149-cleanup.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class cleanup1679651580149 { name = 'cleanup1679651580149' diff --git a/packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js b/packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js index 0733339841..f3a07cbd1d 100644 --- a/packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js +++ b/packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class enableChartsForFederatedInstances1679652081809 { name = 'enableChartsForFederatedInstances1679652081809' diff --git a/packages/backend/migration/1680228513388-channelFavorite.js b/packages/backend/migration/1680228513388-channelFavorite.js index afc676959a..58eb7359f2 100644 --- a/packages/backend/migration/1680228513388-channelFavorite.js +++ b/packages/backend/migration/1680228513388-channelFavorite.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class channelFavorite1680228513388 { name = 'channelFavorite1680228513388' diff --git a/packages/backend/migration/1680238118084-channelNotePining.js b/packages/backend/migration/1680238118084-channelNotePining.js index 126eae87ea..f1f192d7bb 100644 --- a/packages/backend/migration/1680238118084-channelNotePining.js +++ b/packages/backend/migration/1680238118084-channelNotePining.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class channelNotePining1680238118084 { name = 'channelNotePining1680238118084' diff --git a/packages/backend/migration/1680491187535-cleanup.js b/packages/backend/migration/1680491187535-cleanup.js index 1e609ca060..006b403bd1 100644 --- a/packages/backend/migration/1680491187535-cleanup.js +++ b/packages/backend/migration/1680491187535-cleanup.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class cleanup1680491187535 { name = 'cleanup1680491187535' diff --git a/packages/backend/migration/1680582195041-cleanup.js b/packages/backend/migration/1680582195041-cleanup.js index c587e456a5..7d941be8cf 100644 --- a/packages/backend/migration/1680582195041-cleanup.js +++ b/packages/backend/migration/1680582195041-cleanup.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class cleanup1680582195041 { name = 'cleanup1680582195041' @@ -6,6 +11,6 @@ export class cleanup1680582195041 { } async down(queryRunner) { - + } } diff --git a/packages/backend/migration/1680702787050-UserMemo.js b/packages/backend/migration/1680702787050-UserMemo.js index 7446bf8da5..104d66ce24 100644 --- a/packages/backend/migration/1680702787050-UserMemo.js +++ b/packages/backend/migration/1680702787050-UserMemo.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class UserMemo1680702787050 { name = 'UserMemo1680702787050' diff --git a/packages/backend/migration/1680775031481-avatar-url-and-banner-url.js b/packages/backend/migration/1680775031481-avatar-url-and-banner-url.js index 7c5fe7ac5e..c613ee511e 100644 --- a/packages/backend/migration/1680775031481-avatar-url-and-banner-url.js +++ b/packages/backend/migration/1680775031481-avatar-url-and-banner-url.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class AvatarUrlAndBannerUrl1680775031481 { name = 'AvatarUrlAndBannerUrl1680775031481' diff --git a/packages/backend/migration/1680931179228-account-move.js b/packages/backend/migration/1680931179228-account-move.js index 821318d1bc..203d838f57 100644 --- a/packages/backend/migration/1680931179228-account-move.js +++ b/packages/backend/migration/1680931179228-account-move.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class AccountMove1680931179228 { name = 'AccountMove1680931179228' diff --git a/packages/backend/migration/1681400427971-serverRules.js b/packages/backend/migration/1681400427971-serverRules.js index 2364e8e1d2..70a74ebfff 100644 --- a/packages/backend/migration/1681400427971-serverRules.js +++ b/packages/backend/migration/1681400427971-serverRules.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class ServerRules1681400427971 { name = 'ServerRules1681400427971' diff --git a/packages/backend/migration/1681870960239-RoleTLSetting.js b/packages/backend/migration/1681870960239-RoleTLSetting.js index 2280f44eaa..07b9bc4e35 100644 --- a/packages/backend/migration/1681870960239-RoleTLSetting.js +++ b/packages/backend/migration/1681870960239-RoleTLSetting.js @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RoleTLSetting1681870960239 { name = 'RoleTLSetting1681870960239' async up(queryRunner) { await queryRunner.query(`ALTER TABLE "role" ADD "isExplorable" boolean NOT NULL DEFAULT false`); } - + async down(queryRunner) { await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "isExplorable"`); } diff --git a/packages/backend/migration/1682190963894-movedAt.js b/packages/backend/migration/1682190963894-movedAt.js index 1f8f030a5c..cc33da8747 100644 --- a/packages/backend/migration/1682190963894-movedAt.js +++ b/packages/backend/migration/1682190963894-movedAt.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class MovedAt1682190963894 { name = 'MovedAt1682190963894' diff --git a/packages/backend/migration/1682754135458-preservedUsernames.js b/packages/backend/migration/1682754135458-preservedUsernames.js index 46a0826f43..61723e4abd 100644 --- a/packages/backend/migration/1682754135458-preservedUsernames.js +++ b/packages/backend/migration/1682754135458-preservedUsernames.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class PreservedUsernames1682754135458 { name = 'PreservedUsernames1682754135458' diff --git a/packages/backend/migration/1682985520254-channelColor.js b/packages/backend/migration/1682985520254-channelColor.js index 294b7372b2..43f1f48334 100644 --- a/packages/backend/migration/1682985520254-channelColor.js +++ b/packages/backend/migration/1682985520254-channelColor.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class ChannelColor1682985520254 { name = 'ChannelColor1682985520254' diff --git a/packages/backend/migration/1683328299359-channelArchive.js b/packages/backend/migration/1683328299359-channelArchive.js index 83695ff537..759dcbfdae 100644 --- a/packages/backend/migration/1683328299359-channelArchive.js +++ b/packages/backend/migration/1683328299359-channelArchive.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class ChannelArchive1683328299359 { name = 'ChannelArchive1683328299359' diff --git a/packages/backend/migration/1683682889948-prevent-ai-larning.js b/packages/backend/migration/1683682889948-prevent-ai-larning.js index 9d1a19c10b..1dc3eec21f 100644 --- a/packages/backend/migration/1683682889948-prevent-ai-larning.js +++ b/packages/backend/migration/1683682889948-prevent-ai-larning.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class PreventAiLarning1683682889948 { name = 'PreventAiLarning1683682889948' diff --git a/packages/backend/migration/1683683083083-public-reactions-default-true.js b/packages/backend/migration/1683683083083-public-reactions-default-true.js index 195ea02a5e..32cbe33b2f 100644 --- a/packages/backend/migration/1683683083083-public-reactions-default-true.js +++ b/packages/backend/migration/1683683083083-public-reactions-default-true.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class PublicReactionsDefaultTrue1683683083083 { name = 'PublicReactionsDefaultTrue1683683083083' diff --git a/packages/backend/migration/1683789676867-fix-typo.js b/packages/backend/migration/1683789676867-fix-typo.js index c0dbbf0050..5cd686e2f1 100644 --- a/packages/backend/migration/1683789676867-fix-typo.js +++ b/packages/backend/migration/1683789676867-fix-typo.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class FixTypo1683789676867 { name = 'FixTypo1683789676867' diff --git a/packages/backend/migration/1683847157541-UserList.js b/packages/backend/migration/1683847157541-UserList.js index b50a50eed8..f9e79a43a1 100644 --- a/packages/backend/migration/1683847157541-UserList.js +++ b/packages/backend/migration/1683847157541-UserList.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class UserList1683847157541 { name = 'UserList1683847157541' diff --git a/packages/backend/migration/1683869758873-UserListFavorites.js b/packages/backend/migration/1683869758873-UserListFavorites.js index ac9c4c42b9..aef4597a75 100644 --- a/packages/backend/migration/1683869758873-UserListFavorites.js +++ b/packages/backend/migration/1683869758873-UserListFavorites.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class UserListFavorites1683869758873 { name = 'UserListFavorites1683869758873' diff --git a/packages/backend/migration/1684206886988-remove-showTimelineReplies.js b/packages/backend/migration/1684206886988-remove-showTimelineReplies.js index 690653bd7c..a0798f85c6 100644 --- a/packages/backend/migration/1684206886988-remove-showTimelineReplies.js +++ b/packages/backend/migration/1684206886988-remove-showTimelineReplies.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RemoveShowTimelineReplies1684206886988 { name = 'RemoveShowTimelineReplies1684206886988' diff --git a/packages/backend/migration/1684386446061-emoji-improve.js b/packages/backend/migration/1684386446061-emoji-improve.js index 40b0a2bc5e..7bded84cc9 100644 --- a/packages/backend/migration/1684386446061-emoji-improve.js +++ b/packages/backend/migration/1684386446061-emoji-improve.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class EmojiImprove1684386446061 { name = 'EmojiImprove1684386446061' diff --git a/packages/backend/migration/1685973839966-errorImageUrl.js b/packages/backend/migration/1685973839966-errorImageUrl.js index fd5d467162..c4a1567b9b 100644 --- a/packages/backend/migration/1685973839966-errorImageUrl.js +++ b/packages/backend/migration/1685973839966-errorImageUrl.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class ErrorImageUrl1685973839966 { name = 'ErrorImageUrl1685973839966' diff --git a/packages/backend/migration/1688280713783-add-meta-options.js b/packages/backend/migration/1688280713783-add-meta-options.js index 12406fe085..ade8378c00 100644 --- a/packages/backend/migration/1688280713783-add-meta-options.js +++ b/packages/backend/migration/1688280713783-add-meta-options.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class AddMetaOptions1688280713783 { name = 'AddMetaOptions1688280713783' diff --git a/packages/backend/migration/1688720440658-refactor-invite-system.js b/packages/backend/migration/1688720440658-refactor-invite-system.js index 0dd49f7027..20f178612d 100644 --- a/packages/backend/migration/1688720440658-refactor-invite-system.js +++ b/packages/backend/migration/1688720440658-refactor-invite-system.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class RefactorInviteSystem1688720440658 { name = 'RefactorInviteSystem1688720440658' diff --git a/packages/backend/migration/1688880985544-add-index-to-relations.js b/packages/backend/migration/1688880985544-add-index-to-relations.js index d6b5c57f55..6daac20329 100644 --- a/packages/backend/migration/1688880985544-add-index-to-relations.js +++ b/packages/backend/migration/1688880985544-add-index-to-relations.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class AddIndexToRelations1688880985544 { name = 'AddIndexToRelations1688880985544' diff --git a/packages/backend/migration/1689102832143-nsfw-cache.js b/packages/backend/migration/1689102832143-nsfw-cache.js index cdce0dae09..419588296e 100644 --- a/packages/backend/migration/1689102832143-nsfw-cache.js +++ b/packages/backend/migration/1689102832143-nsfw-cache.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class NsfwCache1689102832143 { name = 'NsfwCache1689102832143' diff --git a/packages/backend/migration/1690417561185-fix-renote-muting.js b/packages/backend/migration/1690417561185-fix-renote-muting.js new file mode 100644 index 0000000000..14150b0362 --- /dev/null +++ b/packages/backend/migration/1690417561185-fix-renote-muting.js @@ -0,0 +1,12 @@ +export class FixRenoteMuting1690417561185 { + name = 'FixRenoteMuting1690417561185' + + async up(queryRunner) { + await queryRunner.query(`DELETE FROM "renote_muting" WHERE "muteeId" NOT IN (SELECT "id" FROM "user")`); + await queryRunner.query(`DELETE FROM "renote_muting" WHERE "muterId" NOT IN (SELECT "id" FROM "user")`); + } + + async down(queryRunner) { + + } +} diff --git a/packages/backend/migration/1690417561186-ChangeCacheRemoteFilesDefault.js b/packages/backend/migration/1690417561186-ChangeCacheRemoteFilesDefault.js new file mode 100644 index 0000000000..7eda5debe5 --- /dev/null +++ b/packages/backend/migration/1690417561186-ChangeCacheRemoteFilesDefault.js @@ -0,0 +1,11 @@ +export class ChangeCacheRemoteFilesDefault1690417561186 { + name = 'ChangeCacheRemoteFilesDefault1690417561186' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "cacheRemoteFiles" SET DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "cacheRemoteFiles" SET DEFAULT true`); + } +} diff --git a/packages/backend/migration/1690417561187-Fix.js b/packages/backend/migration/1690417561187-Fix.js new file mode 100644 index 0000000000..e780e66d7b --- /dev/null +++ b/packages/backend/migration/1690417561187-Fix.js @@ -0,0 +1,81 @@ +export class Fix1690417561187 { + name = 'Fix1690417561187' + + async up(queryRunner) { + await queryRunner.query(`DROP INDEX "public"."IDX_2cd3b2a6b4cf0b910b260afe08"`); + await queryRunner.query(`DROP INDEX "public"."IDX_renote_muting_createdAt"`); + await queryRunner.query(`DROP INDEX "public"."IDX_renote_muting_muteeId"`); + await queryRunner.query(`DROP INDEX "public"."IDX_renote_muting_muterId"`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isRoot" IS 'Whether the User is the root.'`); + await queryRunner.query(`COMMENT ON COLUMN "ad"."startsAt" IS 'The expired date of the Ad.'`); + await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "lastUsedAt" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "mascotImageUrl" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "preservedUsernames" SET DEFAULT '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey" }'`); + await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."createdAt" IS 'The created date of the Muting.'`); + await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muteeId" IS 'The mutee user ID.'`); + await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muterId" IS 'The muter user ID.'`); + await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b"`); + await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "UQ_da851e06d0dfe2ef397d8b1bf1b"`); + await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c"`); + await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "UQ_e263909ca4fe5d57f8d4230dd5c"`); + await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6"`); + await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "UQ_f4853eb41ab722fe05f81cedeb6"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "UQ_51cb79b5555effaf7d69ba1cff9"`); + await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`); + await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "UQ_10c146e4b39b443ede016f6736d"`); + await queryRunner.query(`CREATE INDEX "IDX_3fcc2c589eaefc205e0714b99c" ON "ad" ("startsAt") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_c71faf11f0a28a5c0bb506203c" ON "channel_favorite" ("userId", "channelId") `); + await queryRunner.query(`CREATE INDEX "IDX_f7b9d338207e40e768e4a5265a" ON "instance" ("firstRetrievedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_d1259a2c2b7bb413ff449e8711" ON "renote_muting" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_7eac97594bcac5ffcf2068089b" ON "renote_muting" ("muteeId") `); + await queryRunner.query(`CREATE INDEX "IDX_7aa72a5fe76019bfe8e5e0e8b7" ON "renote_muting" ("muterId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0d801c609cec4e9eb4b6b4490c" ON "renote_muting" ("muterId", "muteeId") `); + await queryRunner.query(`ALTER TABLE "renote_muting" ADD CONSTRAINT "FK_7eac97594bcac5ffcf2068089b6" FOREIGN KEY ("muteeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "renote_muting" ADD CONSTRAINT "FK_7aa72a5fe76019bfe8e5e0e8b7d" FOREIGN KEY ("muterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9"`); + await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6"`); + await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c"`); + await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b"`); + await queryRunner.query(`ALTER TABLE "renote_muting" DROP CONSTRAINT "FK_7aa72a5fe76019bfe8e5e0e8b7d"`); + await queryRunner.query(`ALTER TABLE "renote_muting" DROP CONSTRAINT "FK_7eac97594bcac5ffcf2068089b6"`); + await queryRunner.query(`DROP INDEX "public"."IDX_0d801c609cec4e9eb4b6b4490c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_7aa72a5fe76019bfe8e5e0e8b7"`); + await queryRunner.query(`DROP INDEX "public"."IDX_7eac97594bcac5ffcf2068089b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_d1259a2c2b7bb413ff449e8711"`); + await queryRunner.query(`DROP INDEX "public"."IDX_f7b9d338207e40e768e4a5265a"`); + await queryRunner.query(`DROP INDEX "public"."IDX_c71faf11f0a28a5c0bb506203c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3fcc2c589eaefc205e0714b99c"`); + await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "UQ_10c146e4b39b443ede016f6736d" UNIQUE ("userId")`); + await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "UQ_51cb79b5555effaf7d69ba1cff9" UNIQUE ("userId")`); + await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "UQ_f4853eb41ab722fe05f81cedeb6" UNIQUE ("userId")`); + await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "UQ_e263909ca4fe5d57f8d4230dd5c" UNIQUE ("noteId")`); + await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "UQ_da851e06d0dfe2ef397d8b1bf1b" UNIQUE ("noteId")`); + await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muterId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."muteeId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "renote_muting"."createdAt" IS NULL`); + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "preservedUsernames" SET DEFAULT '{admin,administrator,root,system,maintainer,host,mod,moderator,owner,superuser,staff,auth,i,me,everyone,all,mention,mentions,example,user,users,account,accounts,official,help,helps,support,supports,info,information,informations,announce,announces,announcement,announcements,notice,notification,notifications,dev,developer,developers,tech,misskey}'`); + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "mascotImageUrl" SET DEFAULT '/assets/ai.png'`); + await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "lastUsedAt" SET DEFAULT '2023-04-25 06:51:20.985478+00'`); + await queryRunner.query(`COMMENT ON COLUMN "ad"."startsAt" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "user"."isRoot" IS 'Whether the User is the admin.'`); + await queryRunner.query(`CREATE INDEX "IDX_renote_muting_muterId" ON "muting" ("muterId") `); + await queryRunner.query(`CREATE INDEX "IDX_renote_muting_muteeId" ON "muting" ("muteeId") `); + await queryRunner.query(`CREATE INDEX "IDX_renote_muting_createdAt" ON "muting" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_2cd3b2a6b4cf0b910b260afe08" ON "instance" ("firstRetrievedAt") `); + } +} diff --git a/packages/backend/migration/1690782653311-SensitiveChannel.js b/packages/backend/migration/1690782653311-SensitiveChannel.js new file mode 100644 index 0000000000..e76dda5180 --- /dev/null +++ b/packages/backend/migration/1690782653311-SensitiveChannel.js @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class SensitiveChannel1690782653311 { + name = 'SensitiveChannel1690782653311' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "channel" + ADD "isSensitive" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "channel" DROP COLUMN "isSensitive"`); + } +} diff --git a/packages/backend/migration/1690796169261-play-visibility.js b/packages/backend/migration/1690796169261-play-visibility.js new file mode 100644 index 0000000000..c57fa7a109 --- /dev/null +++ b/packages/backend/migration/1690796169261-play-visibility.js @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class PlayVisibility1689102832143 { + name = 'PlayVisibility1690796169261' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "public"."flash" ADD "visibility" character varying(512) DEFAULT 'public'`, undefined); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "public"."flash" DROP COLUMN "visibility"`, undefined); + } +} diff --git a/packages/backend/migration/1691649257651-refine-announcement.js b/packages/backend/migration/1691649257651-refine-announcement.js new file mode 100644 index 0000000000..d8d63f3103 --- /dev/null +++ b/packages/backend/migration/1691649257651-refine-announcement.js @@ -0,0 +1,27 @@ +export class RefineAnnouncement1691649257651 { + name = 'RefineAnnouncement1691649257651' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement" ADD "display" character varying(256) NOT NULL DEFAULT 'normal'`); + await queryRunner.query(`ALTER TABLE "announcement" ADD "needConfirmationToRead" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "announcement" ADD "isActive" boolean NOT NULL DEFAULT true`); + await queryRunner.query(`ALTER TABLE "announcement" ADD "forExistingUsers" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "announcement" ADD "userId" character varying(32)`); + await queryRunner.query(`CREATE INDEX "IDX_bc1afcc8ef7e9400cdc3c0a87e" ON "announcement" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_da795d3a83187e8832005ba19d" ON "announcement" ("forExistingUsers") `); + await queryRunner.query(`CREATE INDEX "IDX_fd25dfe3da37df1715f11ba6ec" ON "announcement" ("userId") `); + await queryRunner.query(`ALTER TABLE "announcement" ADD CONSTRAINT "FK_fd25dfe3da37df1715f11ba6ec8" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement" DROP CONSTRAINT "FK_fd25dfe3da37df1715f11ba6ec8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_fd25dfe3da37df1715f11ba6ec"`); + await queryRunner.query(`DROP INDEX "public"."IDX_da795d3a83187e8832005ba19d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_bc1afcc8ef7e9400cdc3c0a87e"`); + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "userId"`); + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "forExistingUsers"`); + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "isActive"`); + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "needConfirmationToRead"`); + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "display"`); + } +} diff --git a/packages/backend/migration/1691657412740-refine-announcement-2.js b/packages/backend/migration/1691657412740-refine-announcement-2.js new file mode 100644 index 0000000000..8791f99f44 --- /dev/null +++ b/packages/backend/migration/1691657412740-refine-announcement-2.js @@ -0,0 +1,11 @@ +export class RefineAnnouncement21691657412740 { + name = 'RefineAnnouncement21691657412740' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement" ADD "icon" character varying(256) NOT NULL DEFAULT 'info'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "icon"`); + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 7f64c2a9ac..8c5b67ced6 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -28,6 +28,7 @@ "@swc/core-android-arm64": "1.3.11", "@swc/core-darwin-arm64": "1.3.56", "@swc/core-darwin-x64": "1.3.56", + "@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", @@ -39,51 +40,54 @@ "@tensorflow/tfjs": "4.4.0", "@tensorflow/tfjs-node": "4.4.0", "bufferutil": "^4.0.7", - "slacc-android-arm-eabi": "0.0.9", - "slacc-android-arm64": "0.0.9", - "slacc-darwin-arm64": "0.0.9", - "slacc-darwin-universal": "0.0.9", - "slacc-darwin-x64": "0.0.9", - "slacc-freebsd-x64": "0.0.9", - "slacc-linux-arm-gnueabihf": "0.0.9", - "slacc-linux-arm64-gnu": "0.0.9", - "slacc-linux-arm64-musl": "0.0.9", - "slacc-linux-x64-gnu": "0.0.9", - "slacc-win32-arm64-msvc": "0.0.9", - "slacc-win32-x64-msvc": "0.0.9", + "slacc-android-arm-eabi": "0.0.10", + "slacc-android-arm64": "0.0.10", + "slacc-darwin-arm64": "0.0.10", + "slacc-darwin-universal": "0.0.10", + "slacc-darwin-x64": "0.0.10", + "slacc-freebsd-x64": "0.0.10", + "slacc-linux-arm-gnueabihf": "0.0.10", + "slacc-linux-arm64-gnu": "0.0.10", + "slacc-linux-arm64-musl": "0.0.10", + "slacc-linux-x64-gnu": "0.0.10", + "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" }, "dependencies": { "@aws-sdk/client-s3": "3.367.0", "@aws-sdk/lib-storage": "3.367.0", "@aws-sdk/node-http-handler": "3.360.0", - "@bull-board/api": "5.6.1", - "@bull-board/fastify": "5.6.1", - "@bull-board/ui": "5.6.1", + "@bull-board/api": "5.7.1", + "@bull-board/fastify": "5.7.1", + "@bull-board/ui": "5.7.1", "@discordapp/twemoji": "14.1.2", "@fastify/accepts": "4.2.0", "@fastify/cookie": "8.3.0", "@fastify/cors": "8.3.0", + "@fastify/express": "2.3.0", "@fastify/http-proxy": "9.2.1", - "@fastify/multipart": "7.7.1", + "@fastify/multipart": "7.7.3", "@fastify/static": "6.10.2", "@fastify/view": "8.0.0", - "@nestjs/common": "10.1.0", - "@nestjs/core": "10.1.0", - "@nestjs/testing": "10.1.0", + "@nestjs/common": "10.1.2", + "@nestjs/core": "10.1.2", + "@nestjs/testing": "10.1.2", "@peertube/http-signature": "1.7.0", "@sinonjs/fake-timers": "10.3.0", "@swc/cli": "0.1.62", - "@swc/core": "1.3.70", + "@swc/core": "1.3.72", "accepts": "1.3.8", "ajv": "8.12.0", "archiver": "5.3.1", "async-mutex": "^0.4.0", "bcryptjs": "2.4.3", "blurhash": "2.0.5", - "bullmq": "4.4.0", + "body-parser": "1.20.2", + "bullmq": "4.6.3", "cacheable-lookup": "7.0.0", - "cbor": "9.0.0", + "cbor": "9.0.1", "chalk": "5.3.0", "chalk-template": "1.1.0", "chokidar": "3.5.3", @@ -92,7 +96,7 @@ "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", - "fastify": "4.20.0", + "fastify": "4.21.0", "feed": "4.2.2", "file-type": "18.5.0", "fluent-ffmpeg": "2.1.2", @@ -100,6 +104,7 @@ "got": "13.0.0", "happy-dom": "10.0.3", "hpagent": "1.2.0", + "http-link-header": "1.1.1", "ioredis": "5.3.2", "ip-cidr": "3.1.0", "ipaddr.js": "2.1.0", @@ -111,18 +116,22 @@ "jsrsasign": "10.8.6", "meilisearch": "0.33.0", "mfm-js": "0.23.3", + "microformats-parser": "1.4.1", "mime-types": "2.1.35", "misskey-js": "workspace:*", "ms": "3.0.0-canary.1", "nested-property": "4.0.0", - "node-fetch": "3.3.1", - "nodemailer": "6.9.3", + "node-fetch": "3.3.2", + "nodemailer": "6.9.4", "nsfwjs": "2.4.2", "oauth": "0.10.0", + "oauth2orize": "1.11.1", + "oauth2orize-pkce": "0.1.2", "os-utils": "0.0.14", - "otpauth": "9.1.3", + "otpauth": "9.1.4", "parse5": "7.1.2", "pg": "8.11.1", + "pkce-challenge": "4.0.1", "probe-image-size": "7.2.3", "promise-limit": "2.7.0", "pug": "3.0.2", @@ -131,21 +140,20 @@ "qrcode": "1.5.3", "random-seed": "0.3.0", "ratelimiter": "3.4.1", - "re2": "1.19.1", + "re2": "1.20.1", "redis-lock": "0.1.4", "reflect-metadata": "0.1.13", "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.1", "sanitize-html": "2.11.0", - "semver": "7.5.4", - "sharp": "0.32.3", + "sharp": "0.32.4", "sharp-read-bmp": "github:misskey-dev/sharp-read-bmp", - "slacc": "0.0.9", + "slacc": "0.0.10", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "summaly": "github:misskey-dev/summaly", - "systeminformation": "5.18.7", + "systeminformation": "5.18.9", "tinycolor2": "1.6.0", "tmp": "0.2.1", "tsc-alias": "1.8.7", @@ -155,31 +163,35 @@ "typescript": "5.1.6", "ulid": "2.3.0", "vary": "1.1.2", - "web-push": "3.6.3", + "web-push": "3.6.4", "ws": "8.13.0", "xev": "3.0.2" }, "devDependencies": { - "@jest/globals": "29.6.1", - "@swc/jest": "0.2.26", + "@jest/globals": "29.6.2", + "@swc/jest": "0.2.27", "@types/accepts": "1.3.5", "@types/archiver": "5.3.2", "@types/bcryptjs": "2.4.2", + "@types/body-parser": "1.19.2", "@types/cbor": "6.0.0", "@types/color-convert": "2.0.0", "@types/content-disposition": "0.5.5", "@types/fluent-ffmpeg": "2.1.21", + "@types/http-link-header": "1.0.3", "@types/jest": "29.5.3", "@types/js-yaml": "4.0.5", "@types/jsdom": "21.1.1", "@types/jsonld": "1.5.9", "@types/jsrsasign": "10.5.8", "@types/mime-types": "2.1.1", - "@types/ms": "^0.7.31", - "@types/node": "20.4.2", + "@types/ms": "0.7.31", + "@types/node": "20.4.5", "@types/node-fetch": "3.0.3", - "@types/nodemailer": "6.4.8", + "@types/nodemailer": "6.4.9", "@types/oauth": "0.9.1", + "@types/oauth2orize": "1.11.0", + "@types/oauth2orize-pkce": "0.1.0", "@types/pg": "8.10.2", "@types/pug": "2.0.6", "@types/punycode": "2.1.0", @@ -190,20 +202,22 @@ "@types/sanitize-html": "2.9.0", "@types/semver": "7.5.0", "@types/sharp": "0.32.0", + "@types/simple-oauth2": "5.0.4", "@types/sinonjs__fake-timers": "8.1.2", "@types/tinycolor2": "1.4.3", "@types/tmp": "0.2.3", "@types/vary": "1.1.0", "@types/web-push": "3.3.2", "@types/ws": "8.5.5", - "@typescript-eslint/eslint-plugin": "5.61.0", - "@typescript-eslint/parser": "5.61.0", + "@typescript-eslint/eslint-plugin": "6.2.0", + "@typescript-eslint/parser": "6.2.0", "aws-sdk-client-mock": "3.0.0", "cross-env": "7.0.3", - "eslint": "8.45.0", - "eslint-plugin-import": "2.27.5", - "execa": "7.1.1", - "jest": "29.6.1", - "jest-mock": "29.6.1" + "eslint": "8.46.0", + "eslint-plugin-import": "2.28.0", + "execa": "7.2.0", + "jest": "29.6.2", + "jest-mock": "29.6.2", + "simple-oauth2": "5.0.0" } } diff --git a/packages/backend/src/@types/hcaptcha.d.ts b/packages/backend/src/@types/hcaptcha.d.ts index afed587560..43e67dd340 100644 --- a/packages/backend/src/@types/hcaptcha.d.ts +++ b/packages/backend/src/@types/hcaptcha.d.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + declare module 'hcaptcha' { interface IVerifyResponse { success: boolean; diff --git a/packages/backend/src/@types/http-signature.d.ts b/packages/backend/src/@types/http-signature.d.ts index f2f9bfcc31..1f3b48aa54 100644 --- a/packages/backend/src/@types/http-signature.d.ts +++ b/packages/backend/src/@types/http-signature.d.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + declare module '@peertube/http-signature' { import type { IncomingMessage, ClientRequest } from 'node:http'; diff --git a/packages/backend/src/@types/os-utils.d.ts b/packages/backend/src/@types/os-utils.d.ts index 390df17d39..8c44232c14 100644 --- a/packages/backend/src/@types/os-utils.d.ts +++ b/packages/backend/src/@types/os-utils.d.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + declare module 'os-utils' { type FreeCommandCallback = (usedmem: number) => void; diff --git a/packages/backend/src/@types/package.json.d.ts b/packages/backend/src/@types/package.json.d.ts index abe5fae687..197b4b6bf0 100644 --- a/packages/backend/src/@types/package.json.d.ts +++ b/packages/backend/src/@types/package.json.d.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + declare module '*/package.json' { interface IRepository { type: string; diff --git a/packages/backend/src/@types/probe-image-size.d.ts b/packages/backend/src/@types/probe-image-size.d.ts index 416e819acb..4d312cba34 100644 --- a/packages/backend/src/@types/probe-image-size.d.ts +++ b/packages/backend/src/@types/probe-image-size.d.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + declare module 'probe-image-size' { import type { ReadStream } from 'node:fs'; diff --git a/packages/backend/src/@types/redis-lock.d.ts b/packages/backend/src/@types/redis-lock.d.ts index 9242656a98..c607d600d8 100644 --- a/packages/backend/src/@types/redis-lock.d.ts +++ b/packages/backend/src/@types/redis-lock.d.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + declare module 'redis-lock' { import type Redis from 'ioredis'; diff --git a/packages/backend/src/GlobalModule.ts b/packages/backend/src/GlobalModule.ts index 4caf4c3e96..9f1ee9fcaa 100644 --- a/packages/backend/src/GlobalModule.ts +++ b/packages/backend/src/GlobalModule.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { setTimeout } from 'node:timers/promises'; import { Global, Inject, Module } from '@nestjs/common'; import * as Redis from 'ioredis'; diff --git a/packages/backend/src/MainModule.ts b/packages/backend/src/MainModule.ts index fc568e883e..90aba0cc91 100644 --- a/packages/backend/src/MainModule.ts +++ b/packages/backend/src/MainModule.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Module } from '@nestjs/common'; import { ServerModule } from '@/server/ServerModule.js'; import { GlobalModule } from '@/GlobalModule.js'; diff --git a/packages/backend/src/NestLogger.ts b/packages/backend/src/NestLogger.ts index 448098b831..e18e9e88a7 100644 --- a/packages/backend/src/NestLogger.ts +++ b/packages/backend/src/NestLogger.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { LoggerService } from '@nestjs/common'; import Logger from '@/logger.js'; diff --git a/packages/backend/src/boot/common.ts b/packages/backend/src/boot/common.ts index 3995545d7f..ca2b729156 100644 --- a/packages/backend/src/boot/common.ts +++ b/packages/backend/src/boot/common.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { NestFactory } from '@nestjs/core'; import { ChartManagementService } from '@/core/chart/ChartManagementService.js'; import { QueueProcessorService } from '@/queue/QueueProcessorService.js'; diff --git a/packages/backend/src/boot/index.ts b/packages/backend/src/boot/index.ts index f4daf30690..fc8fc2ffb4 100644 --- a/packages/backend/src/boot/index.ts +++ b/packages/backend/src/boot/index.ts @@ -1,3 +1,7 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ /** * Misskey Entry Point! diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index c253f697f7..0bf23c770b 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; @@ -5,7 +10,6 @@ import * as os from 'node:os'; import cluster from 'node:cluster'; import chalk from 'chalk'; import chalkTemplate from 'chalk-template'; -import semver from 'semver'; import Logger from '@/logger.js'; import { loadConfig } from '@/config.js'; import type { Config } from '@/config.js'; diff --git a/packages/backend/src/boot/worker.ts b/packages/backend/src/boot/worker.ts index ab75aaa572..0399c9fe5c 100644 --- a/packages/backend/src/boot/worker.ts +++ b/packages/backend/src/boot/worker.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import cluster from 'node:cluster'; import { envOption } from '@/env.js'; import { jobQueue, server } from './common.js'; diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index 253975096e..3c70e0bbe3 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /** * Config loader */ @@ -71,6 +76,7 @@ export type Source = { id: string; + outgoingAddress?: string; outgoingAddressFamily?: 'ipv4' | 'ipv6' | 'dual'; deliverJobConcurrency?: number; @@ -192,7 +198,7 @@ function convertRedisOptions(options: RedisOptionsSource, host: string): RedisOp ...options, password: options.pass, prefix: options.prefix ?? host, - family: options.family == null ? 0 : options.family, + family: options.family ?? 0, keyPrefix: `${options.prefix ?? host}:`, db: options.db ?? 0, }; diff --git a/packages/backend/src/const.ts b/packages/backend/src/const.ts index ee1a9a3093..716a8de382 100644 --- a/packages/backend/src/const.ts +++ b/packages/backend/src/const.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const MAX_NOTE_TEXT_LENGTH = 3000; export const USER_ONLINE_THRESHOLD = 1000 * 60 * 10; // 10min diff --git a/packages/backend/src/core/AccountMoveService.ts b/packages/backend/src/core/AccountMoveService.ts index 111fcfd734..84cc5def1f 100644 --- a/packages/backend/src/core/AccountMoveService.ts +++ b/packages/backend/src/core/AccountMoveService.ts @@ -1,11 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull, In, MoreThan, Not } from 'typeorm'; import { bindThis } from '@/decorators.js'; import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; -import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js'; -import type { BlockingsRepository, FollowingsRepository, InstancesRepository, Muting, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js'; +import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js'; +import type { BlockingsRepository, FollowingsRepository, InstancesRepository, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js'; import type { RelationshipJobData, ThinUser } from '@/queue/types.js'; import { IdService } from '@/core/IdService.js'; @@ -26,9 +30,6 @@ import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js'; @Injectable() export class AccountMoveService { constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -70,12 +71,12 @@ export class AccountMoveService { * After delivering Move activity, its local followers unfollow the old account and then follow the new one. */ @bindThis - public async moveFromLocal(src: LocalUser, dst: LocalUser | RemoteUser): Promise { + public async moveFromLocal(src: MiLocalUser, dst: MiLocalUser | MiRemoteUser): Promise { const srcUri = this.userEntityService.getUserUri(src); const dstUri = this.userEntityService.getUserUri(dst); // add movedToUri to indicate that the user has moved - const update = {} as Partial; + const update = {} as Partial; update.alsoKnownAs = src.alsoKnownAs?.includes(dstUri) ? src.alsoKnownAs : src.alsoKnownAs?.concat([dstUri]) ?? [dstUri]; update.movedToUri = dstUri; update.movedAt = new Date(); @@ -113,7 +114,7 @@ export class AccountMoveService { } @bindThis - public async postMoveProcess(src: User, dst: User): Promise { + public async postMoveProcess(src: MiUser, dst: MiUser): Promise { // Copy blockings and mutings, and update lists try { await Promise.all([ @@ -212,7 +213,7 @@ export class AccountMoveService { * @returns Promise */ @bindThis - public async updateLists(src: ThinUser, dst: User): Promise { + public async updateLists(src: ThinUser, dst: MiUser): Promise { // Return if there is no list to be updated. const oldJoinings = await this.userListJoiningsRepository.find({ where: { @@ -259,7 +260,7 @@ export class AccountMoveService { } @bindThis - private async adjustFollowingCounts(localFollowerIds: string[], oldAccount: User): Promise { + private async adjustFollowingCounts(localFollowerIds: string[], oldAccount: MiUser): Promise { if (localFollowerIds.length === 0) return; // Set the old account's following and followers counts to 0. @@ -300,11 +301,11 @@ export class AccountMoveService { */ @bindThis public async validateAlsoKnownAs( - dst: LocalUser | RemoteUser, - check: (oldUser: LocalUser | RemoteUser | null, newUser: LocalUser | RemoteUser) => boolean | Promise = () => true, + dst: MiLocalUser | MiRemoteUser, + check: (oldUser: MiLocalUser | MiRemoteUser | null, newUser: MiLocalUser | MiRemoteUser) => boolean | Promise = () => true, instant = false, - ): Promise { - let resultUser: LocalUser | RemoteUser | null = null; + ): Promise { + let resultUser: MiLocalUser | MiRemoteUser | null = null; if (this.userEntityService.isRemoteUser(dst)) { if ((new Date()).getTime() - (dst.lastFetchedAt?.getTime() ?? 0) > 10 * 1000) { diff --git a/packages/backend/src/core/AccountUpdateService.ts b/packages/backend/src/core/AccountUpdateService.ts index b146fc66be..6a796407dc 100644 --- a/packages/backend/src/core/AccountUpdateService.ts +++ b/packages/backend/src/core/AccountUpdateService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { RelayService } from '@/core/RelayService.js'; import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js'; @@ -12,9 +16,6 @@ import { bindThis } from '@/decorators.js'; @Injectable() export class AccountUpdateService { constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -26,7 +27,7 @@ export class AccountUpdateService { } @bindThis - public async publishToFollowers(userId: User['id']) { + public async publishToFollowers(userId: MiUser['id']) { const user = await this.usersRepository.findOneBy({ id: userId }); if (user == null) throw new Error('user not found'); diff --git a/packages/backend/src/core/AchievementService.ts b/packages/backend/src/core/AchievementService.ts index 9e223f1492..aa810015ed 100644 --- a/packages/backend/src/core/AchievementService.ts +++ b/packages/backend/src/core/AchievementService.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { UserProfilesRepository, UsersRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { UserProfilesRepository } from '@/models/index.js'; +import type { MiUser } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { NotificationService } from '@/core/NotificationService.js'; @@ -85,9 +90,6 @@ export const ACHIEVEMENT_TYPES = [ @Injectable() export class AchievementService { constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, @@ -97,7 +99,7 @@ export class AchievementService { @bindThis public async create( - userId: User['id'], + userId: MiUser['id'], type: typeof ACHIEVEMENT_TYPES[number], ): Promise { if (!ACHIEVEMENT_TYPES.includes(type)) return; diff --git a/packages/backend/src/core/AiService.ts b/packages/backend/src/core/AiService.ts index c0596446dd..4e876495a6 100644 --- a/packages/backend/src/core/AiService.ts +++ b/packages/backend/src/core/AiService.ts @@ -1,12 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import * as nsfw from 'nsfwjs'; import si from 'systeminformation'; import { Mutex } from 'async-mutex'; -import type { Config } from '@/config.js'; -import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; const _filename = fileURLToPath(import.meta.url); @@ -21,8 +24,6 @@ export class AiService { private modelLoadMutex: Mutex = new Mutex(); constructor( - @Inject(DI.config) - private config: Config, ) { } diff --git a/packages/backend/src/core/AnnouncementService.ts b/packages/backend/src/core/AnnouncementService.ts new file mode 100644 index 0000000000..64e8ae758c --- /dev/null +++ b/packages/backend/src/core/AnnouncementService.ts @@ -0,0 +1,135 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Brackets } from 'typeorm'; +import { DI } from '@/di-symbols.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { AnnouncementReadsRepository, AnnouncementsRepository, MiAnnouncement, MiAnnouncementRead } from '@/models/index.js'; +import { bindThis } from '@/decorators.js'; +import { Packed } from '@/misc/json-schema.js'; +import { IdService } from '@/core/IdService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; + +@Injectable() +export class AnnouncementService { + constructor( + @Inject(DI.announcementsRepository) + private announcementsRepository: AnnouncementsRepository, + + @Inject(DI.announcementReadsRepository) + private announcementReadsRepository: AnnouncementReadsRepository, + + private idService: IdService, + private globalEventService: GlobalEventService, + ) { + } + + @bindThis + public async getReads(userId: MiUser['id']): Promise { + return this.announcementReadsRepository.findBy({ + userId: userId, + }); + } + + @bindThis + public async getUnreadAnnouncements(user: MiUser): Promise { + const readsQuery = this.announcementReadsRepository.createQueryBuilder('read') + .select('read.announcementId') + .where('read.userId = :userId', { userId: user.id }); + + const q = this.announcementsRepository.createQueryBuilder('announcement') + .where('announcement.isActive = true') + .andWhere(new Brackets(qb => { + qb.orWhere('announcement.userId = :userId', { userId: user.id }); + qb.orWhere('announcement.userId IS NULL'); + })) + .andWhere(new Brackets(qb => { + qb.orWhere('announcement.forExistingUsers = false'); + qb.orWhere('announcement.createdAt > :createdAt', { createdAt: user.createdAt }); + })) + .andWhere(`announcement.id NOT IN (${ readsQuery.getQuery() })`); + + q.setParameters(readsQuery.getParameters()); + + return q.getMany(); + } + + @bindThis + public async create(values: Partial): Promise<{ raw: MiAnnouncement; packed: Packed<'Announcement'> }> { + const announcement = await this.announcementsRepository.insert({ + id: this.idService.genId(), + createdAt: new Date(), + updatedAt: null, + title: values.title, + text: values.text, + imageUrl: values.imageUrl, + icon: values.icon, + display: values.display, + forExistingUsers: values.forExistingUsers, + needConfirmationToRead: values.needConfirmationToRead, + userId: values.userId, + }).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0])); + + const packed = (await this.packMany([announcement]))[0]; + + if (values.userId) { + this.globalEventService.publishMainStream(values.userId, 'announcementCreated', { + announcement: packed, + }); + } else { + this.globalEventService.publishBroadcastStream('announcementCreated', { + announcement: packed, + }); + } + + return { + raw: announcement, + packed: packed, + }; + } + + @bindThis + public async read(user: MiUser, announcementId: MiAnnouncement['id']): Promise { + try { + await this.announcementReadsRepository.insert({ + id: this.idService.genId(), + createdAt: new Date(), + announcementId: announcementId, + userId: user.id, + }); + } catch (e) { + return; + } + + if ((await this.getUnreadAnnouncements(user)).length === 0) { + this.globalEventService.publishMainStream(user.id, 'readAllAnnouncements'); + } + } + + @bindThis + public async packMany( + announcements: MiAnnouncement[], + me?: { id: MiUser['id'] } | null | undefined, + options?: { + reads?: MiAnnouncementRead[]; + }, + ): Promise[]> { + const reads = me ? (options?.reads ?? await this.getReads(me.id)) : []; + return announcements.map(announcement => ({ + id: announcement.id, + createdAt: announcement.createdAt.toISOString(), + updatedAt: announcement.updatedAt?.toISOString() ?? null, + text: announcement.text, + title: announcement.title, + imageUrl: announcement.imageUrl, + icon: announcement.icon, + display: announcement.display, + needConfirmationToRead: announcement.needConfirmationToRead, + forYou: announcement.userId === me?.id, + isRead: reads.some(read => read.announcementId === announcement.id), + })); + } +} diff --git a/packages/backend/src/core/AntennaService.ts b/packages/backend/src/core/AntennaService.ts index 9310fd8b52..c64b941413 100644 --- a/packages/backend/src/core/AntennaService.ts +++ b/packages/backend/src/core/AntennaService.ts @@ -1,18 +1,18 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; -import type { Antenna } from '@/models/entities/Antenna.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { User } from '@/models/entities/User.js'; -import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; -import { AntennaEntityService } from '@/core/entities/AntennaEntityService.js'; -import { IdService } from '@/core/IdService.js'; -import { isUserRelated } from '@/misc/is-user-related.js'; +import type { MiAntenna } from '@/models/entities/Antenna.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiUser } from '@/models/entities/User.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { PushNotificationService } from '@/core/PushNotificationService.js'; import * as Acct from '@/misc/acct.js'; import type { Packed } from '@/misc/json-schema.js'; import { DI } from '@/di-symbols.js'; -import type { MutingsRepository, NotesRepository, AntennasRepository, UserListJoiningsRepository } from '@/models/index.js'; +import type { AntennasRepository, UserListJoiningsRepository } from '@/models/index.js'; import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; import { StreamMessages } from '@/server/api/stream/types.js'; @@ -21,7 +21,7 @@ import type { OnApplicationShutdown } from '@nestjs/common'; @Injectable() export class AntennaService implements OnApplicationShutdown { private antennasFetched: boolean; - private antennas: Antenna[]; + private antennas: MiAntenna[]; constructor( @Inject(DI.redis) @@ -30,12 +30,6 @@ export class AntennaService implements OnApplicationShutdown { @Inject(DI.redisForSub) private redisForSub: Redis.Redis, - @Inject(DI.mutingsRepository) - private mutingsRepository: MutingsRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - @Inject(DI.antennasRepository) private antennasRepository: AntennasRepository, @@ -43,11 +37,7 @@ export class AntennaService implements OnApplicationShutdown { private userListJoiningsRepository: UserListJoiningsRepository, private utilityService: UtilityService, - private idService: IdService, private globalEventService: GlobalEventService, - private pushNotificationService: PushNotificationService, - private noteEntityService: NoteEntityService, - private antennaEntityService: AntennaEntityService, ) { this.antennasFetched = false; this.antennas = []; @@ -86,7 +76,7 @@ export class AntennaService implements OnApplicationShutdown { } @bindThis - public async addNoteToAntennas(note: Note, noteUser: { id: User['id']; username: string; host: string | null; }): Promise { + public async addNoteToAntennas(note: MiNote, noteUser: { id: MiUser['id']; username: string; host: string | null; }): Promise { const antennas = await this.getAntennas(); const antennasWithMatchResult = await Promise.all(antennas.map(antenna => this.checkHitAntenna(antenna, note, noteUser).then(hit => [antenna, hit] as const))); const matchedAntennas = antennasWithMatchResult.filter(([, hit]) => hit).map(([antenna]) => antenna); @@ -109,7 +99,7 @@ export class AntennaService implements OnApplicationShutdown { // NOTE: フォローしているユーザーのノート、リストのユーザーのノート、グループのユーザーのノート指定はパフォーマンス上の理由で無効になっている @bindThis - public async checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { id: User['id']; username: string; host: string | null; }): Promise { + public async checkHitAntenna(antenna: MiAntenna, note: (MiNote | Packed<'Note'>), noteUser: { id: MiUser['id']; username: string; host: string | null; }): Promise { if (note.visibility === 'specified') return false; if (note.visibility === 'followers') return false; diff --git a/packages/backend/src/core/AppLockService.ts b/packages/backend/src/core/AppLockService.ts index 6ccaec26ba..7a1293a6de 100644 --- a/packages/backend/src/core/AppLockService.ts +++ b/packages/backend/src/core/AppLockService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { promisify } from 'node:util'; import { Inject, Injectable } from '@nestjs/common'; import redisLock from 'redis-lock'; diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index cd6b68e721..15be5f398c 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; -import type { BlockingsRepository, ChannelFollowingsRepository, FollowingsRepository, MutingsRepository, RenoteMutingsRepository, UserProfile, UserProfilesRepository, UsersRepository } from '@/models/index.js'; +import type { BlockingsRepository, ChannelFollowingsRepository, FollowingsRepository, MutingsRepository, RenoteMutingsRepository, MiUserProfile, UserProfilesRepository, UsersRepository } from '@/models/index.js'; import { MemoryKVCache, RedisKVCache } from '@/misc/cache.js'; -import type { LocalUser, User } from '@/models/entities/User.js'; +import type { MiLocalUser, MiUser } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -11,11 +16,11 @@ import type { OnApplicationShutdown } from '@nestjs/common'; @Injectable() export class CacheService implements OnApplicationShutdown { - public userByIdCache: MemoryKVCache; - public localUserByNativeTokenCache: MemoryKVCache; - public localUserByIdCache: MemoryKVCache; - public uriPersonCache: MemoryKVCache; - public userProfileCache: RedisKVCache; + public userByIdCache: MemoryKVCache; + public localUserByNativeTokenCache: MemoryKVCache; + public localUserByIdCache: MemoryKVCache; + public uriPersonCache: MemoryKVCache; + public userProfileCache: RedisKVCache; public userMutingsCache: RedisKVCache>; public userBlockingCache: RedisKVCache>; public userBlockedCache: RedisKVCache>; // NOTE: 「被」Blockキャッシュ @@ -55,14 +60,14 @@ export class CacheService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - const localUserByIdCache = new MemoryKVCache(1000 * 60 * 60 * 6 /* 6h */); + const localUserByIdCache = new MemoryKVCache(1000 * 60 * 60 * 6 /* 6h */); this.localUserByIdCache = localUserByIdCache; // ローカルユーザーならlocalUserByIdCacheにデータを追加し、こちらにはid(文字列)だけを追加する - const userByIdCache = new MemoryKVCache(1000 * 60 * 60 * 6 /* 6h */, { + const userByIdCache = new MemoryKVCache(1000 * 60 * 60 * 6 /* 6h */, { toMapConverter: user => { if (user.host === null) { - localUserByIdCache.set(user.id, user as LocalUser); + localUserByIdCache.set(user.id, user as MiLocalUser); return user.id; } @@ -72,7 +77,7 @@ export class CacheService implements OnApplicationShutdown { }); this.userByIdCache = userByIdCache; - this.localUserByNativeTokenCache = new MemoryKVCache(Infinity, { + this.localUserByNativeTokenCache = new MemoryKVCache(Infinity, { toMapConverter: user => { if (user === null) return null; @@ -81,7 +86,7 @@ export class CacheService implements OnApplicationShutdown { }, fromMapConverter: id => id === null ? null : localUserByIdCache.get(id), }); - this.uriPersonCache = new MemoryKVCache(Infinity, { + this.uriPersonCache = new MemoryKVCache(Infinity, { toMapConverter: user => { if (user === null) return null; @@ -91,7 +96,7 @@ export class CacheService implements OnApplicationShutdown { fromMapConverter: id => id === null ? null : userByIdCache.get(id), }); - this.userProfileCache = new RedisKVCache(this.redisClient, 'userProfile', { + this.userProfileCache = new RedisKVCache(this.redisClient, 'userProfile', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m fetcher: (key) => this.userProfilesRepository.findOneByOrFail({ userId: key }), @@ -173,7 +178,7 @@ export class CacheService implements OnApplicationShutdown { break; } case 'userTokenRegenerated': { - const user = await this.usersRepository.findOneByOrFail({ id: body.id }) as LocalUser; + const user = await this.usersRepository.findOneByOrFail({ id: body.id }) as MiLocalUser; this.localUserByNativeTokenCache.delete(body.oldToken); this.localUserByNativeTokenCache.set(body.newToken, user); break; @@ -192,7 +197,7 @@ export class CacheService implements OnApplicationShutdown { } @bindThis - public findUserById(userId: User['id']) { + public findUserById(userId: MiUser['id']) { return this.userByIdCache.fetch(userId, () => this.usersRepository.findOneByOrFail({ id: userId })); } diff --git a/packages/backend/src/core/CaptchaService.ts b/packages/backend/src/core/CaptchaService.ts index 10cfdba254..f64196f4fc 100644 --- a/packages/backend/src/core/CaptchaService.ts +++ b/packages/backend/src/core/CaptchaService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; diff --git a/packages/backend/src/core/CoreModule.ts b/packages/backend/src/core/CoreModule.ts index c7c98b3bdd..51d4f9cfa9 100644 --- a/packages/backend/src/core/CoreModule.ts +++ b/packages/backend/src/core/CoreModule.ts @@ -1,7 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Module } from '@nestjs/common'; import { AccountMoveService } from './AccountMoveService.js'; import { AccountUpdateService } from './AccountUpdateService.js'; import { AiService } from './AiService.js'; +import { AnnouncementService } from './AnnouncementService.js'; import { AntennaService } from './AntennaService.js'; import { AppLockService } from './AppLockService.js'; import { AchievementService } from './AchievementService.js'; @@ -125,6 +131,7 @@ const $LoggerService: Provider = { provide: 'LoggerService', useExisting: Logger const $AccountMoveService: Provider = { provide: 'AccountMoveService', useExisting: AccountMoveService }; const $AccountUpdateService: Provider = { provide: 'AccountUpdateService', useExisting: AccountUpdateService }; const $AiService: Provider = { provide: 'AiService', useExisting: AiService }; +const $AnnouncementService: Provider = { provide: 'AnnouncementService', useExisting: AnnouncementService }; const $AntennaService: Provider = { provide: 'AntennaService', useExisting: AntennaService }; const $AppLockService: Provider = { provide: 'AppLockService', useExisting: AppLockService }; const $AchievementService: Provider = { provide: 'AchievementService', useExisting: AchievementService }; @@ -252,6 +259,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting AccountMoveService, AccountUpdateService, AiService, + AnnouncementService, AntennaService, AppLockService, AchievementService, @@ -372,6 +380,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $AccountMoveService, $AccountUpdateService, $AiService, + $AnnouncementService, $AntennaService, $AppLockService, $AchievementService, @@ -493,6 +502,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting AccountMoveService, AccountUpdateService, AiService, + AnnouncementService, AntennaService, AppLockService, AchievementService, @@ -612,6 +622,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $AccountMoveService, $AccountUpdateService, $AiService, + $AnnouncementService, $AntennaService, $AppLockService, $AchievementService, diff --git a/packages/backend/src/core/CreateSystemUserService.ts b/packages/backend/src/core/CreateSystemUserService.ts index cef664bf0b..7f57128bae 100644 --- a/packages/backend/src/core/CreateSystemUserService.ts +++ b/packages/backend/src/core/CreateSystemUserService.ts @@ -1,13 +1,18 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import bcrypt from 'bcryptjs'; import { IsNull, DataSource } from 'typeorm'; import { genRsaKeyPair } from '@/misc/gen-key-pair.js'; -import { User } from '@/models/entities/User.js'; -import { UserProfile } from '@/models/entities/UserProfile.js'; +import { MiUser } from '@/models/entities/User.js'; +import { MiUserProfile } from '@/models/entities/UserProfile.js'; import { IdService } from '@/core/IdService.js'; -import { UserKeypair } from '@/models/entities/UserKeypair.js'; -import { UsedUsername } from '@/models/entities/UsedUsername.js'; +import { MiUserKeypair } from '@/models/entities/UserKeypair.js'; +import { MiUsedUsername } from '@/models/entities/UsedUsername.js'; import { DI } from '@/di-symbols.js'; import generateNativeUserToken from '@/misc/generate-native-user-token.js'; import { bindThis } from '@/decorators.js'; @@ -23,7 +28,7 @@ export class CreateSystemUserService { } @bindThis - public async createSystemUser(username: string): Promise { + public async createSystemUser(username: string): Promise { const password = randomUUID(); // Generate hash of password @@ -35,18 +40,18 @@ export class CreateSystemUserService { const keyPair = await genRsaKeyPair(); - let account!: User; + let account!: MiUser; // Start transaction await this.db.transaction(async transactionalEntityManager => { - const exist = await transactionalEntityManager.findOneBy(User, { + const exist = await transactionalEntityManager.findOneBy(MiUser, { usernameLower: username.toLowerCase(), host: IsNull(), }); if (exist) throw new Error('the user is already exists'); - account = await transactionalEntityManager.insert(User, { + account = await transactionalEntityManager.insert(MiUser, { id: this.idService.genId(), createdAt: new Date(), username: username, @@ -57,21 +62,21 @@ export class CreateSystemUserService { isLocked: true, isExplorable: false, isBot: true, - }).then(x => transactionalEntityManager.findOneByOrFail(User, x.identifiers[0])); + }).then(x => transactionalEntityManager.findOneByOrFail(MiUser, x.identifiers[0])); - await transactionalEntityManager.insert(UserKeypair, { + await transactionalEntityManager.insert(MiUserKeypair, { publicKey: keyPair.publicKey, privateKey: keyPair.privateKey, userId: account.id, }); - await transactionalEntityManager.insert(UserProfile, { + await transactionalEntityManager.insert(MiUserProfile, { userId: account.id, autoAcceptFollowed: false, password: hash, }); - await transactionalEntityManager.insert(UsedUsername, { + await transactionalEntityManager.insert(MiUsedUsername, { createdAt: new Date(), username: username.toLowerCase(), }); diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 661d956bd6..8fd993345b 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -1,17 +1,21 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; -import { DataSource, In, IsNull } from 'typeorm'; +import { In, IsNull } from 'typeorm'; import * as Redis from 'ioredis'; import { DI } from '@/di-symbols.js'; import { IdService } from '@/core/IdService.js'; import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { Emoji } from '@/models/entities/Emoji.js'; -import type { EmojisRepository, Role } from '@/models/index.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiEmoji } from '@/models/entities/Emoji.js'; +import type { EmojisRepository, MiRole } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; import { MemoryKVCache, RedisSingleCache } from '@/misc/cache.js'; import { UtilityService } from '@/core/UtilityService.js'; -import type { Config } from '@/config.js'; import { query } from '@/misc/prelude/url.js'; import type { Serialized } from '@/server/api/stream/types.js'; @@ -19,19 +23,13 @@ const parseEmojiStrRegexp = /^(\w+)(?:@([\w.-]+))?$/; @Injectable() export class CustomEmojiService implements OnApplicationShutdown { - private cache: MemoryKVCache; - public localEmojisCache: RedisSingleCache>; + private cache: MemoryKVCache; + public localEmojisCache: RedisSingleCache>; constructor( @Inject(DI.redis) private redisClient: Redis.Redis, - @Inject(DI.config) - private config: Config, - - @Inject(DI.db) - private db: DataSource, - @Inject(DI.emojisRepository) private emojisRepository: EmojisRepository, @@ -40,16 +38,16 @@ export class CustomEmojiService implements OnApplicationShutdown { private emojiEntityService: EmojiEntityService, private globalEventService: GlobalEventService, ) { - this.cache = new MemoryKVCache(1000 * 60 * 60 * 12); + this.cache = new MemoryKVCache(1000 * 60 * 60 * 12); - this.localEmojisCache = new RedisSingleCache>(this.redisClient, 'localEmojis', { + this.localEmojisCache = new RedisSingleCache>(this.redisClient, 'localEmojis', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60 * 3, // 3m fetcher: () => this.emojisRepository.find({ where: { host: IsNull() } }).then(emojis => new Map(emojis.map(emoji => [emoji.name, emoji]))), toRedisConverter: (value) => JSON.stringify(Array.from(value.values())), fromRedisConverter: (value) => { if (!Array.isArray(JSON.parse(value))) return undefined; // 古いバージョンの壊れたキャッシュが残っていることがある(そのうち消す) - return new Map(JSON.parse(value).map((x: Serialized) => [x.name, { + return new Map(JSON.parse(value).map((x: Serialized) => [x.name, { ...x, updatedAt: x.updatedAt ? new Date(x.updatedAt) : null, }])); @@ -59,7 +57,7 @@ export class CustomEmojiService implements OnApplicationShutdown { @bindThis public async add(data: { - driveFile: DriveFile; + driveFile: MiDriveFile; name: string; category: string | null; aliases: string[]; @@ -67,8 +65,8 @@ export class CustomEmojiService implements OnApplicationShutdown { license: string | null; isSensitive: boolean; localOnly: boolean; - roleIdsThatCanBeUsedThisEmojiAsReaction: Role['id'][]; - }): Promise { + roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][]; + }): Promise { const emoji = await this.emojisRepository.insert({ id: this.idService.genId(), updatedAt: new Date(), @@ -97,15 +95,15 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async update(id: Emoji['id'], data: { - driveFile?: DriveFile; + public async update(id: MiEmoji['id'], data: { + driveFile?: MiDriveFile; name?: string; category?: string | null; aliases?: string[]; license?: string | null; isSensitive?: boolean; localOnly?: boolean; - roleIdsThatCanBeUsedThisEmojiAsReaction?: Role['id'][]; + roleIdsThatCanBeUsedThisEmojiAsReaction?: MiRole['id'][]; }): Promise { const emoji = await this.emojisRepository.findOneByOrFail({ id: id }); const sameNameEmoji = await this.emojisRepository.findOneBy({ name: data.name, host: IsNull() }); @@ -145,7 +143,7 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async addAliasesBulk(ids: Emoji['id'][], aliases: string[]) { + public async addAliasesBulk(ids: MiEmoji['id'][], aliases: string[]) { const emojis = await this.emojisRepository.findBy({ id: In(ids), }); @@ -165,7 +163,7 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async setAliasesBulk(ids: Emoji['id'][], aliases: string[]) { + public async setAliasesBulk(ids: MiEmoji['id'][], aliases: string[]) { await this.emojisRepository.update({ id: In(ids), }, { @@ -181,7 +179,7 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async removeAliasesBulk(ids: Emoji['id'][], aliases: string[]) { + public async removeAliasesBulk(ids: MiEmoji['id'][], aliases: string[]) { const emojis = await this.emojisRepository.findBy({ id: In(ids), }); @@ -201,7 +199,7 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async setCategoryBulk(ids: Emoji['id'][], category: string | null) { + public async setCategoryBulk(ids: MiEmoji['id'][], category: string | null) { await this.emojisRepository.update({ id: In(ids), }, { @@ -217,7 +215,7 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async setLicenseBulk(ids: Emoji['id'][], license: string | null) { + public async setLicenseBulk(ids: MiEmoji['id'][], license: string | null) { await this.emojisRepository.update({ id: In(ids), }, { @@ -233,7 +231,7 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async delete(id: Emoji['id']) { + public async delete(id: MiEmoji['id']) { const emoji = await this.emojisRepository.findOneByOrFail({ id: id }); await this.emojisRepository.delete(emoji.id); @@ -246,7 +244,7 @@ export class CustomEmojiService implements OnApplicationShutdown { } @bindThis - public async deleteBulk(ids: Emoji['id'][]) { + public async deleteBulk(ids: MiEmoji['id'][]) { const emojis = await this.emojisRepository.findBy({ id: In(ids), }); diff --git a/packages/backend/src/core/DeleteAccountService.ts b/packages/backend/src/core/DeleteAccountService.ts index 3a0592441b..3e90d39455 100644 --- a/packages/backend/src/core/DeleteAccountService.ts +++ b/packages/backend/src/core/DeleteAccountService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; import { QueueService } from '@/core/QueueService.js'; import { UserSuspendService } from '@/core/UserSuspendService.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @@ -14,7 +18,6 @@ export class DeleteAccountService { private userSuspendService: UserSuspendService, private queueService: QueueService, - private globalEventService: GlobalEventService, ) { } diff --git a/packages/backend/src/core/DownloadService.ts b/packages/backend/src/core/DownloadService.ts index 09039a8b57..5474272b00 100644 --- a/packages/backend/src/core/DownloadService.ts +++ b/packages/backend/src/core/DownloadService.ts @@ -1,6 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; -import * as stream from 'node:stream'; -import * as util from 'node:util'; +import * as stream from 'node:stream/promises'; import { Inject, Injectable } from '@nestjs/common'; import ipaddr from 'ipaddr.js'; import chalk from 'chalk'; @@ -14,7 +18,6 @@ import { StatusError } from '@/misc/status-error.js'; import { LoggerService } from '@/core/LoggerService.js'; import type Logger from '@/logger.js'; -const pipeline = util.promisify(stream.pipeline); import { bindThis } from '@/decorators.js'; @Injectable() @@ -102,7 +105,7 @@ export class DownloadService { }); try { - await pipeline(req, fs.createWriteStream(path)); + await stream.pipeline(req, fs.createWriteStream(path)); } catch (e) { if (e instanceof Got.HTTPError) { throw new StatusError(`${e.response.statusCode} ${e.response.statusMessage}`, e.response.statusCode, e.response.statusMessage); @@ -129,7 +132,7 @@ export class DownloadService { // write content at URL to temp file await this.downloadUrl(url, path); - const text = await util.promisify(fs.readFile)(path, 'utf8'); + const text = await fs.promises.readFile(path, 'utf8'); return text; } finally { diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 355e5e8c0d..77f60bf6e9 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { randomUUID } from 'node:crypto'; import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; @@ -9,9 +14,9 @@ import { DI } from '@/di-symbols.js'; import type { DriveFilesRepository, UsersRepository, DriveFoldersRepository, UserProfilesRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import Logger from '@/logger.js'; -import type { RemoteUser, User } from '@/models/entities/User.js'; +import type { MiRemoteUser, MiUser } from '@/models/entities/User.js'; import { MetaService } from '@/core/MetaService.js'; -import { DriveFile } from '@/models/entities/DriveFile.js'; +import { MiDriveFile } from '@/models/entities/DriveFile.js'; import { IdService } from '@/core/IdService.js'; import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js'; import { FILE_TYPE_BROWSERSAFE } from '@/const.js'; @@ -22,7 +27,7 @@ import { VideoProcessingService } from '@/core/VideoProcessingService.js'; import { ImageProcessingService } from '@/core/ImageProcessingService.js'; import type { IImage } from '@/core/ImageProcessingService.js'; import { QueueService } from '@/core/QueueService.js'; -import type { DriveFolder } from '@/models/entities/DriveFolder.js'; +import type { MiDriveFolder } from '@/models/entities/DriveFolder.js'; import { createTemp } from '@/misc/create-temp.js'; import DriveChart from '@/core/chart/charts/drive.js'; import PerUserDriveChart from '@/core/chart/charts/per-user-drive.js'; @@ -40,7 +45,7 @@ import { isMimeImage } from '@/misc/is-mime-image.js'; type AddFileArgs = { /** User who wish to add file */ - user: { id: User['id']; host: User['host'] } | null; + user: { id: MiUser['id']; host: MiUser['host'] } | null; /** File path */ path: string; /** Name */ @@ -68,8 +73,8 @@ type AddFileArgs = { type UploadFromUrlArgs = { url: string; - user: { id: User['id']; host: User['host'] } | null; - folderId?: DriveFolder['id'] | null; + user: { id: MiUser['id']; host: MiUser['host'] } | null; + folderId?: MiDriveFolder['id'] | null; uri?: string | null; sensitive?: boolean; force?: boolean; @@ -133,7 +138,7 @@ export class DriveService { * @param size Size for original */ @bindThis - private async save(file: DriveFile, path: string, name: string, type: string, hash: string, size: number): Promise { + private async save(file: MiDriveFile, path: string, name: string, type: string, hash: string, size: number): Promise { // thunbnail, webpublic を必要なら生成 const alts = await this.generateAlts(path, type, !file.uri); @@ -327,7 +332,7 @@ export class DriveService { this.registerLogger.debug('web image not created (not an required image)'); } } catch (err) { - this.registerLogger.warn('web image not created (an error occured)', err as Error); + this.registerLogger.warn('web image not created (an error occurred)', err as Error); } } else { if (satisfyWebpublic) this.registerLogger.info('web image not created (original satisfies webpublic)'); @@ -346,7 +351,7 @@ export class DriveService { thumbnail = await this.imageProcessingService.convertSharpToWebp(img, 498, 422); } } catch (err) { - this.registerLogger.warn('thumbnail not created (an error occured)', err as Error); + this.registerLogger.warn('thumbnail not created (an error occurred)', err as Error); } // #endregion thumbnail @@ -400,7 +405,7 @@ export class DriveService { // Expire oldest file (without avatar or banner) of remote user @bindThis - private async expireOldFile(user: RemoteUser, driveCapacity: number) { + private async expireOldFile(user: MiRemoteUser, driveCapacity: number) { const q = this.driveFilesRepository.createQueryBuilder('file') .where('file.userId = :userId', { userId: user.id }) .andWhere('file.isLink = FALSE'); @@ -446,7 +451,7 @@ export class DriveService { requestIp = null, requestHeaders = null, ext = null, - }: AddFileArgs): Promise { + }: AddFileArgs): Promise { let skipNsfwCheck = false; const instance = await this.metaService.fetch(); const userRoleNSFW = user && (await this.roleService.getUserPolicies(user.id)).alwaysMarkNsfw; @@ -515,7 +520,7 @@ export class DriveService { if (isLocalUser) { throw new IdentifiableError('c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6', 'No free space.'); } - await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as RemoteUser, driveCapacity - info.size); + await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as MiRemoteUser, driveCapacity - info.size); } } //#endregion @@ -553,7 +558,7 @@ export class DriveService { const folder = await fetchFolder(); - let file = new DriveFile(); + let file = new MiDriveFile(); file.id = this.idService.genId(); file.createdAt = new Date(); file.userId = user ? user.id : null; @@ -569,9 +574,7 @@ export class DriveService { file.maybePorn = info.porn; file.isSensitive = user ? this.userEntityService.isLocalUser(user) && profile!.alwaysMarkNsfw ? true : - (sensitive !== null && sensitive !== undefined) - ? sensitive - : false + sensitive ?? false : false; if (info.sensitive && profile!.autoSensitive) file.isSensitive = true; @@ -611,7 +614,7 @@ export class DriveService { file = await this.driveFilesRepository.findOneBy({ uri: file.uri!, userId: user ? user.id : IsNull(), - }) as DriveFile; + }) as MiDriveFile; } else { this.registerLogger.error(err as Error); throw err; @@ -645,7 +648,7 @@ export class DriveService { } @bindThis - public async deleteFile(file: DriveFile, isExpired = false) { + public async deleteFile(file: MiDriveFile, isExpired = false) { if (file.storedInternal) { this.internalStorageService.del(file.accessKey!); @@ -672,7 +675,7 @@ export class DriveService { } @bindThis - public async deleteFileSync(file: DriveFile, isExpired = false) { + public async deleteFileSync(file: MiDriveFile, isExpired = false) { if (file.storedInternal) { this.internalStorageService.del(file.accessKey!); @@ -703,7 +706,7 @@ export class DriveService { } @bindThis - private async deletePostProcess(file: DriveFile, isExpired = false) { + private async deletePostProcess(file: MiDriveFile, isExpired = false) { // リモートファイル期限切れ削除後は直リンクにする if (isExpired && file.userHost !== null && file.uri != null) { this.driveFilesRepository.update(file.id, { @@ -766,7 +769,7 @@ export class DriveService { comment = null, requestIp = null, requestHeaders = null, - }: UploadFromUrlArgs): Promise { + }: UploadFromUrlArgs): Promise { // Create temp file const [path, cleanup] = await createTemp(); diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index a04e9c1225..162634593e 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as nodemailer from 'nodemailer'; import { Inject, Injectable } from '@nestjs/common'; import { validate as validateEmail } from 'deep-email-validator'; diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index a762038942..e7b85b750b 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import * as Redis from 'ioredis'; import type { InstancesRepository } from '@/models/index.js'; -import type { Instance } from '@/models/entities/Instance.js'; +import type { MiInstance } from '@/models/entities/Instance.js'; import { MemoryKVCache, RedisKVCache } from '@/misc/cache.js'; import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; @@ -10,7 +15,7 @@ import { bindThis } from '@/decorators.js'; @Injectable() export class FederatedInstanceService implements OnApplicationShutdown { - public federatedInstanceCache: RedisKVCache; + public federatedInstanceCache: RedisKVCache; constructor( @Inject(DI.redis) @@ -22,7 +27,7 @@ export class FederatedInstanceService implements OnApplicationShutdown { private utilityService: UtilityService, private idService: IdService, ) { - this.federatedInstanceCache = new RedisKVCache(this.redisClient, 'federatedInstance', { + this.federatedInstanceCache = new RedisKVCache(this.redisClient, 'federatedInstance', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60 * 3, // 3m fetcher: (key) => this.instancesRepository.findOneBy({ host: key }), @@ -41,7 +46,7 @@ export class FederatedInstanceService implements OnApplicationShutdown { } @bindThis - public async fetch(host: string): Promise { + public async fetch(host: string): Promise { host = this.utilityService.toPuny(host); const cached = await this.federatedInstanceCache.get(host); @@ -65,7 +70,7 @@ export class FederatedInstanceService implements OnApplicationShutdown { } @bindThis - public async update(id: Instance['id'], data: Partial): Promise { + public async update(id: MiInstance['id'], data: Partial): Promise { const result = await this.instancesRepository.createQueryBuilder().update() .set(data) .where('id = :id', { id }) diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts index 88706f1a48..4563006f68 100644 --- a/packages/backend/src/core/FetchInstanceMetadataService.ts +++ b/packages/backend/src/core/FetchInstanceMetadataService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import { JSDOM } from 'jsdom'; import tinycolor from 'tinycolor2'; import * as Redis from 'ioredis'; -import type { Instance } from '@/models/entities/Instance.js'; +import type { MiInstance } from '@/models/entities/Instance.js'; import type Logger from '@/logger.js'; import { DI } from '@/di-symbols.js'; import { LoggerService } from '@/core/LoggerService.js'; @@ -57,7 +62,7 @@ export class FetchInstanceMetadataService { } @bindThis - public async fetchInstanceMetadata(instance: Instance, force = false): Promise { + public async fetchInstanceMetadata(instance: MiInstance, force = false): Promise { const host = instance.host; // Acquire mutex to ensure no parallel runs if (!await this.tryLock(host)) return; @@ -70,9 +75,9 @@ export class FetchInstanceMetadataService { return; } } - + this.logger.info(`Fetching metadata of ${instance.host} ...`); - + const [info, dom, manifest] = await Promise.all([ this.fetchNodeinfo(instance).catch(() => null), this.fetchDom(instance).catch(() => null), @@ -103,7 +108,7 @@ export class FetchInstanceMetadataService { if (name) updates.name = name; if (description) updates.description = description; - if (icon || favicon) updates.iconUrl = (icon && !icon.includes('data:image/png;base64')) ? icon : favicon; + if (icon ?? favicon) updates.iconUrl = (icon && !icon.includes('data:image/png;base64')) ? icon : favicon; if (favicon) updates.faviconUrl = favicon; if (themeColor) updates.themeColor = themeColor; @@ -118,7 +123,7 @@ export class FetchInstanceMetadataService { } @bindThis - private async fetchNodeinfo(instance: Instance): Promise { + private async fetchNodeinfo(instance: MiInstance): Promise { this.logger.info(`Fetching nodeinfo of ${instance.host} ...`); try { @@ -137,10 +142,10 @@ export class FetchInstanceMetadataService { const links = wellknown.links as any[]; - const lnik1_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/1.0'); - const lnik2_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0'); - const lnik2_1 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.1'); - const link = lnik2_1 ?? lnik2_0 ?? lnik1_0; + const link1_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/1.0'); + const link2_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0'); + const link2_1 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.1'); + const link = link2_1 ?? link2_0 ?? link1_0; if (link == null) { throw new Error('No nodeinfo link provided'); @@ -162,7 +167,7 @@ export class FetchInstanceMetadataService { } @bindThis - private async fetchDom(instance: Instance): Promise { + private async fetchDom(instance: MiInstance): Promise { this.logger.info(`Fetching HTML of ${instance.host} ...`); const url = 'https://' + instance.host; @@ -176,7 +181,7 @@ export class FetchInstanceMetadataService { } @bindThis - private async fetchManifest(instance: Instance): Promise | null> { + private async fetchManifest(instance: MiInstance): Promise | null> { const url = 'https://' + instance.host; const manifestUrl = url + '/manifest.json'; @@ -187,7 +192,7 @@ export class FetchInstanceMetadataService { } @bindThis - private async fetchFaviconUrl(instance: Instance, doc: DOMWindow['document'] | null): Promise { + private async fetchFaviconUrl(instance: MiInstance, doc: DOMWindow['document'] | null): Promise { const url = 'https://' + instance.host; if (doc) { @@ -213,7 +218,7 @@ export class FetchInstanceMetadataService { } @bindThis - private async fetchIconUrl(instance: Instance, doc: DOMWindow['document'] | null, manifest: Record | null): Promise { + private async fetchIconUrl(instance: MiInstance, doc: DOMWindow['document'] | null, manifest: Record | null): Promise { if (manifest && manifest.icons && manifest.icons.length > 0 && manifest.icons[0].src) { const url = 'https://' + instance.host; return (new URL(manifest.icons[0].src, url)).href; diff --git a/packages/backend/src/core/FileInfoService.ts b/packages/backend/src/core/FileInfoService.ts index d43575b336..fdea59a8ad 100644 --- a/packages/backend/src/core/FileInfoService.ts +++ b/packages/backend/src/core/FileInfoService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import * as crypto from 'node:crypto'; import { join } from 'node:path'; -import * as stream from 'node:stream'; -import * as util from 'node:util'; +import * as stream from 'node:stream/promises'; import { Injectable } from '@nestjs/common'; import { FSWatcher } from 'chokidar'; import * as fileType from 'file-type'; @@ -16,8 +20,6 @@ import { createTempDir } from '@/misc/create-temp.js'; import { AiService } from '@/core/AiService.js'; import { bindThis } from '@/decorators.js'; -const pipeline = util.promisify(stream.pipeline); - export type FileInfo = { size: number; md5: string; @@ -371,8 +373,7 @@ export class FileInfoService { */ @bindThis public async getFileSize(path: string): Promise { - const getStat = util.promisify(fs.stat); - return (await getStat(path)).size; + return (await fs.promises.stat(path)).size; } /** @@ -381,7 +382,7 @@ export class FileInfoService { @bindThis private async calcHash(path: string): Promise { const hash = crypto.createHash('md5').setEncoding('hex'); - await pipeline(fs.createReadStream(path), hash); + await stream.pipeline(fs.createReadStream(path), hash); return hash.read(); } diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts index 19d9370083..224eb3c599 100644 --- a/packages/backend/src/core/GlobalEventService.ts +++ b/packages/backend/src/core/GlobalEventService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; -import type { User } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { UserList } from '@/models/entities/UserList.js'; -import type { Antenna } from '@/models/entities/Antenna.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiUserList } from '@/models/entities/UserList.js'; +import type { MiAntenna } from '@/models/entities/Antenna.js'; import type { StreamChannels, AdminStreamTypes, @@ -20,7 +25,7 @@ import type { Packed } from '@/misc/json-schema.js'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import { bindThis } from '@/decorators.js'; -import { Role } from '@/models/index.js'; +import { MiRole } from '@/models/index.js'; @Injectable() export class GlobalEventService { @@ -56,17 +61,17 @@ export class GlobalEventService { } @bindThis - public publishMainStream(userId: User['id'], type: K, value?: MainStreamTypes[K]): void { + public publishMainStream(userId: MiUser['id'], type: K, value?: MainStreamTypes[K]): void { this.publish(`mainStream:${userId}`, type, typeof value === 'undefined' ? null : value); } @bindThis - public publishDriveStream(userId: User['id'], type: K, value?: DriveStreamTypes[K]): void { + public publishDriveStream(userId: MiUser['id'], type: K, value?: DriveStreamTypes[K]): void { this.publish(`driveStream:${userId}`, type, typeof value === 'undefined' ? null : value); } @bindThis - public publishNoteStream(noteId: Note['id'], type: K, value?: NoteStreamTypes[K]): void { + public publishNoteStream(noteId: MiNote['id'], type: K, value?: NoteStreamTypes[K]): void { this.publish(`noteStream:${noteId}`, type, { id: noteId, body: value, @@ -74,17 +79,17 @@ export class GlobalEventService { } @bindThis - public publishUserListStream(listId: UserList['id'], type: K, value?: UserListStreamTypes[K]): void { + public publishUserListStream(listId: MiUserList['id'], type: K, value?: UserListStreamTypes[K]): void { this.publish(`userListStream:${listId}`, type, typeof value === 'undefined' ? null : value); } @bindThis - public publishAntennaStream(antennaId: Antenna['id'], type: K, value?: AntennaStreamTypes[K]): void { + public publishAntennaStream(antennaId: MiAntenna['id'], type: K, value?: AntennaStreamTypes[K]): void { this.publish(`antennaStream:${antennaId}`, type, typeof value === 'undefined' ? null : value); } @bindThis - public publishRoleTimelineStream(roleId: Role['id'], type: K, value?: RoleTimelineStreamTypes[K]): void { + public publishRoleTimelineStream(roleId: MiRole['id'], type: K, value?: RoleTimelineStreamTypes[K]): void { this.publish(`roleTimelineStream:${roleId}`, type, typeof value === 'undefined' ? null : value); } @@ -94,7 +99,7 @@ export class GlobalEventService { } @bindThis - public publishAdminStream(userId: User['id'], type: K, value?: AdminStreamTypes[K]): void { + public publishAdminStream(userId: MiUser['id'], type: K, value?: AdminStreamTypes[K]): void { this.publish(`adminStream:${userId}`, type, typeof value === 'undefined' ? null : value); } } diff --git a/packages/backend/src/core/HashtagService.ts b/packages/backend/src/core/HashtagService.ts index 851e42e7ba..eec160275f 100644 --- a/packages/backend/src/core/HashtagService.ts +++ b/packages/backend/src/core/HashtagService.ts @@ -1,19 +1,21 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { IdService } from '@/core/IdService.js'; -import type { Hashtag } from '@/models/entities/Hashtag.js'; -import type { HashtagsRepository, UsersRepository } from '@/models/index.js'; +import type { MiHashtag } from '@/models/entities/Hashtag.js'; +import type { HashtagsRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @Injectable() export class HashtagService { constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.hashtagsRepository) private hashtagsRepository: HashtagsRepository, @@ -23,14 +25,14 @@ export class HashtagService { } @bindThis - public async updateHashtags(user: { id: User['id']; host: User['host']; }, tags: string[]) { + public async updateHashtags(user: { id: MiUser['id']; host: MiUser['host']; }, tags: string[]) { for (const tag of tags) { await this.updateHashtag(user, tag); } } @bindThis - public async updateUsertags(user: User, tags: string[]) { + public async updateUsertags(user: MiUser, tags: string[]) { for (const tag of tags) { await this.updateHashtag(user, tag, true, true); } @@ -41,7 +43,7 @@ export class HashtagService { } @bindThis - public async updateHashtag(user: { id: User['id']; host: User['host']; }, tag: string, isUserAttached = false, inc = true) { + public async updateHashtag(user: { id: MiUser['id']; host: MiUser['host']; }, tag: string, isUserAttached = false, inc = true) { tag = normalizeForSearch(tag); const index = await this.hashtagsRepository.findOneBy({ name: tag }); @@ -121,7 +123,7 @@ export class HashtagService { attachedLocalUsersCount: this.userEntityService.isLocalUser(user) ? 1 : 0, attachedRemoteUserIds: this.userEntityService.isRemoteUser(user) ? [user.id] : [], attachedRemoteUsersCount: this.userEntityService.isRemoteUser(user) ? 1 : 0, - } as Hashtag); + } as MiHashtag); } else { this.hashtagsRepository.insert({ id: this.idService.genId(), @@ -138,7 +140,7 @@ export class HashtagService { attachedLocalUsersCount: 0, attachedRemoteUserIds: [], attachedRemoteUsersCount: 0, - } as Hashtag); + } as MiHashtag); } } } diff --git a/packages/backend/src/core/HttpRequestService.ts b/packages/backend/src/core/HttpRequestService.ts index 3bb999ff8b..73bb3dc7e9 100644 --- a/packages/backend/src/core/HttpRequestService.ts +++ b/packages/backend/src/core/HttpRequestService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as http from 'node:http'; import * as https from 'node:https'; import * as net from 'node:net'; @@ -48,12 +53,14 @@ export class HttpRequestService { keepAlive: true, keepAliveMsecs: 30 * 1000, lookup: cache.lookup as unknown as net.LookupFunction, + localAddress: config.outgoingAddress, }); this.https = new https.Agent({ keepAlive: true, keepAliveMsecs: 30 * 1000, lookup: cache.lookup as unknown as net.LookupFunction, + localAddress: config.outgoingAddress, }); const maxSockets = Math.max(256, config.deliverJobConcurrency ?? 128); @@ -66,6 +73,7 @@ export class HttpRequestService { maxFreeSockets: 256, scheduling: 'lifo', proxy: config.proxy, + localAddress: config.outgoingAddress, }) : this.http; @@ -77,6 +85,7 @@ export class HttpRequestService { maxFreeSockets: 256, scheduling: 'lifo', proxy: config.proxy, + localAddress: config.outgoingAddress, }) : this.https; } @@ -88,7 +97,7 @@ export class HttpRequestService { */ @bindThis public getAgentByUrl(url: URL, bypassProxy = false): http.Agent | https.Agent { - if (bypassProxy || (this.config.proxyBypassHosts || []).includes(url.hostname)) { + if (bypassProxy || (this.config.proxyBypassHosts ?? []).includes(url.hostname)) { return url.protocol === 'http:' ? this.http : this.https; } else { return url.protocol === 'http:' ? this.httpAgent : this.httpsAgent; diff --git a/packages/backend/src/core/IdService.ts b/packages/backend/src/core/IdService.ts index 4d129407cb..186fd36b42 100644 --- a/packages/backend/src/core/IdService.ts +++ b/packages/backend/src/core/IdService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { ulid } from 'ulid'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/core/ImageProcessingService.ts b/packages/backend/src/core/ImageProcessingService.ts index 3246475d12..8e800eb8f5 100644 --- a/packages/backend/src/core/ImageProcessingService.ts +++ b/packages/backend/src/core/ImageProcessingService.ts @@ -1,7 +1,10 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import sharp from 'sharp'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; export type IImage = { data: Buffer; @@ -45,8 +48,6 @@ import { Readable } from 'node:stream'; @Injectable() export class ImageProcessingService { constructor( - @Inject(DI.config) - private config: Config, ) { } diff --git a/packages/backend/src/core/InstanceActorService.ts b/packages/backend/src/core/InstanceActorService.ts index 2e047dc5c1..8e576774d4 100644 --- a/packages/backend/src/core/InstanceActorService.ts +++ b/packages/backend/src/core/InstanceActorService.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; -import type { LocalUser } from '@/models/entities/User.js'; +import type { MiLocalUser } from '@/models/entities/User.js'; import type { UsersRepository } from '@/models/index.js'; import { MemorySingleCache } from '@/misc/cache.js'; import { DI } from '@/di-symbols.js'; @@ -11,7 +16,7 @@ const ACTOR_USERNAME = 'instance.actor' as const; @Injectable() export class InstanceActorService { - private cache: MemorySingleCache; + private cache: MemorySingleCache; constructor( @Inject(DI.usersRepository) @@ -19,24 +24,24 @@ export class InstanceActorService { private createSystemUserService: CreateSystemUserService, ) { - this.cache = new MemorySingleCache(Infinity); + this.cache = new MemorySingleCache(Infinity); } @bindThis - public async getInstanceActor(): Promise { + public async getInstanceActor(): Promise { const cached = this.cache.get(); if (cached) return cached; const user = await this.usersRepository.findOneBy({ host: IsNull(), username: ACTOR_USERNAME, - }) as LocalUser | undefined; + }) as MiLocalUser | undefined; if (user) { this.cache.set(user); return user; } else { - const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME) as LocalUser; + const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME) as MiLocalUser; this.cache.set(created); return created; } diff --git a/packages/backend/src/core/InternalStorageService.ts b/packages/backend/src/core/InternalStorageService.ts index 7c03af7de7..22129bb348 100644 --- a/packages/backend/src/core/InternalStorageService.ts +++ b/packages/backend/src/core/InternalStorageService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import * as Path from 'node:path'; import { fileURLToPath } from 'node:url'; diff --git a/packages/backend/src/core/LoggerService.ts b/packages/backend/src/core/LoggerService.ts index 14df9aa40c..46b000ee63 100644 --- a/packages/backend/src/core/LoggerService.ts +++ b/packages/backend/src/core/LoggerService.ts @@ -1,6 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; import type { KEYWORD } from 'color-convert/conversions.js'; @@ -8,8 +11,6 @@ import type { KEYWORD } from 'color-convert/conversions.js'; @Injectable() export class LoggerService { constructor( - @Inject(DI.config) - private config: Config, ) { } diff --git a/packages/backend/src/core/MetaService.ts b/packages/backend/src/core/MetaService.ts index aae0a9134b..f9619861bb 100644 --- a/packages/backend/src/core/MetaService.ts +++ b/packages/backend/src/core/MetaService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DataSource } from 'typeorm'; import * as Redis from 'ioredis'; import { DI } from '@/di-symbols.js'; -import { Meta } from '@/models/entities/Meta.js'; +import { MiMeta } from '@/models/entities/Meta.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { bindThis } from '@/decorators.js'; import { StreamMessages } from '@/server/api/stream/types.js'; @@ -10,7 +15,7 @@ import type { OnApplicationShutdown } from '@nestjs/common'; @Injectable() export class MetaService implements OnApplicationShutdown { - private cache: Meta | undefined; + private cache: MiMeta | undefined; private intervalId: NodeJS.Timer; constructor( @@ -54,12 +59,12 @@ export class MetaService implements OnApplicationShutdown { } @bindThis - public async fetch(noCache = false): Promise { + public async fetch(noCache = false): Promise { if (!noCache && this.cache) return this.cache; return await this.db.transaction(async transactionalEntityManager => { // 過去のバグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する - const metas = await transactionalEntityManager.find(Meta, { + const metas = await transactionalEntityManager.find(MiMeta, { order: { id: 'DESC', }, @@ -74,13 +79,13 @@ export class MetaService implements OnApplicationShutdown { // metaが空のときfetchMetaが同時に呼ばれるとここが同時に呼ばれてしまうことがあるのでフェイルセーフなupsertを使う const saved = await transactionalEntityManager .upsert( - Meta, + MiMeta, { id: 'x', }, ['id'], ) - .then((x) => transactionalEntityManager.findOneByOrFail(Meta, x.identifiers[0])); + .then((x) => transactionalEntityManager.findOneByOrFail(MiMeta, x.identifiers[0])); this.cache = saved; return saved; @@ -89,9 +94,9 @@ export class MetaService implements OnApplicationShutdown { } @bindThis - public async update(data: Partial): Promise { + public async update(data: Partial): Promise { const updated = await this.db.transaction(async transactionalEntityManager => { - const metas = await transactionalEntityManager.find(Meta, { + const metas = await transactionalEntityManager.find(MiMeta, { order: { id: 'DESC', }, @@ -100,9 +105,9 @@ export class MetaService implements OnApplicationShutdown { const meta = metas[0]; if (meta) { - await transactionalEntityManager.update(Meta, meta.id, data); + await transactionalEntityManager.update(MiMeta, meta.id, data); - const metas = await transactionalEntityManager.find(Meta, { + const metas = await transactionalEntityManager.find(MiMeta, { order: { id: 'DESC', }, @@ -110,7 +115,7 @@ export class MetaService implements OnApplicationShutdown { return metas[0]; } else { - return await transactionalEntityManager.save(Meta, data); + return await transactionalEntityManager.save(MiMeta, data); } }); diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts index 38aaa84524..b6f84da475 100644 --- a/packages/backend/src/core/MfmService.ts +++ b/packages/backend/src/core/MfmService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import * as parse5 from 'parse5'; diff --git a/packages/backend/src/core/ModerationLogService.ts b/packages/backend/src/core/ModerationLogService.ts index 80e8cb9e52..be01fbf9fa 100644 --- a/packages/backend/src/core/ModerationLogService.ts +++ b/packages/backend/src/core/ModerationLogService.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { ModerationLogsRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { IdService } from '@/core/IdService.js'; import { bindThis } from '@/decorators.js'; @@ -16,7 +21,7 @@ export class ModerationLogService { } @bindThis - public async insertModerationLog(moderator: { id: User['id'] }, type: string, info?: Record) { + public async insertModerationLog(moderator: { id: MiUser['id'] }, type: string, info?: Record) { await this.moderationLogsRepository.insert({ id: this.idService.genId(), createdAt: new Date(), diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 648ff76483..2ccc610cf3 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { setImmediate } from 'node:timers/promises'; import * as mfm from 'mfm-js'; import { In, DataSource } from 'typeorm'; @@ -8,21 +13,21 @@ import { extractMentions } from '@/misc/extract-mentions.js'; import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js'; import { extractHashtags } from '@/misc/extract-hashtags.js'; import type { IMentionedRemoteUsers } from '@/models/entities/Note.js'; -import { Note } from '@/models/entities/Note.js'; -import type { ChannelFollowingsRepository, ChannelsRepository, InstancesRepository, MutedNotesRepository, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { App } from '@/models/entities/App.js'; +import { MiNote } from '@/models/entities/Note.js'; +import type { ChannelsRepository, InstancesRepository, MutedNotesRepository, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiApp } from '@/models/entities/App.js'; import { concat } from '@/misc/prelude/array.js'; import { IdService } from '@/core/IdService.js'; -import type { User, LocalUser, RemoteUser } from '@/models/entities/User.js'; +import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; import type { IPoll } from '@/models/entities/Poll.js'; -import { Poll } from '@/models/entities/Poll.js'; +import { MiPoll } from '@/models/entities/Poll.js'; import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js'; import { checkWordMute } from '@/misc/check-word-mute.js'; -import type { Channel } from '@/models/entities/Channel.js'; +import type { MiChannel } from '@/models/entities/Channel.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { MemorySingleCache } from '@/misc/cache.js'; -import type { UserProfile } from '@/models/entities/UserProfile.js'; +import type { MiUserProfile } from '@/models/entities/UserProfile.js'; import { RelayService } from '@/core/RelayService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { DI } from '@/di-symbols.js'; @@ -49,23 +54,23 @@ import { RoleService } from '@/core/RoleService.js'; import { MetaService } from '@/core/MetaService.js'; import { SearchService } from '@/core/SearchService.js'; -const mutedWordsCache = new MemorySingleCache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5); +const mutedWordsCache = new MemorySingleCache<{ userId: MiUserProfile['userId']; mutedWords: MiUserProfile['mutedWords']; }[]>(1000 * 60 * 5); type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; class NotificationManager { - private notifier: { id: User['id']; }; - private note: Note; + private notifier: { id: MiUser['id']; }; + private note: MiNote; private queue: { - target: LocalUser['id']; + target: MiLocalUser['id']; reason: NotificationType; }[]; constructor( private mutingsRepository: MutingsRepository, private notificationService: NotificationService, - notifier: { id: User['id']; }, - note: Note, + notifier: { id: MiUser['id']; }, + note: MiNote, ) { this.notifier = notifier; this.note = note; @@ -73,7 +78,7 @@ class NotificationManager { } @bindThis - public push(notifiee: LocalUser['id'], reason: NotificationType) { + public push(notifiee: MiLocalUser['id'], reason: NotificationType) { // 自分自身へは通知しない if (this.notifier.id === notifiee) return; @@ -114,32 +119,32 @@ class NotificationManager { } type MinimumUser = { - id: User['id']; - host: User['host']; - username: User['username']; - uri: User['uri']; + id: MiUser['id']; + host: MiUser['host']; + username: MiUser['username']; + uri: MiUser['uri']; }; type Option = { createdAt?: Date | null; name?: string | null; text?: string | null; - reply?: Note | null; - renote?: Note | null; - files?: DriveFile[] | null; + reply?: MiNote | null; + renote?: MiNote | null; + files?: MiDriveFile[] | null; poll?: IPoll | null; localOnly?: boolean | null; - reactionAcceptance?: Note['reactionAcceptance']; + reactionAcceptance?: MiNote['reactionAcceptance']; cw?: string | null; visibility?: string; visibleUsers?: MinimumUser[] | null; - channel?: Channel | null; + channel?: MiChannel | null; apMentions?: MinimumUser[] | null; apHashtags?: string[] | null; apEmojis?: string[] | null; uri?: string | null; url?: string | null; - app?: App | null; + app?: MiApp | null; }; @Injectable() @@ -177,9 +182,6 @@ export class NoteCreateService implements OnApplicationShutdown { @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, - @Inject(DI.channelFollowingsRepository) - private channelFollowingsRepository: ChannelFollowingsRepository, - @Inject(DI.noteThreadMutingsRepository) private noteThreadMutingsRepository: NoteThreadMutingsRepository, @@ -209,12 +211,12 @@ export class NoteCreateService implements OnApplicationShutdown { @bindThis public async create(user: { - id: User['id']; - username: User['username']; - host: User['host']; - createdAt: User['createdAt']; - isBot: User['isBot']; - }, data: Option, silent = false): Promise { + id: MiUser['id']; + username: MiUser['username']; + host: MiUser['host']; + createdAt: MiUser['createdAt']; + isBot: MiUser['isBot']; + }, data: Option, silent = false): Promise { // チャンネル外にリプライしたら対象のスコープに合わせる // (クライアントサイドでやっても良い処理だと思うけどとりあえずサーバーサイドで) if (data.reply && data.channel && data.reply.channelId !== data.channel.id) { @@ -346,8 +348,8 @@ export class NoteCreateService implements OnApplicationShutdown { } @bindThis - private async insertNote(user: { id: User['id']; host: User['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]) { - const insert = new Note({ + private async insertNote(user: { id: MiUser['id']; host: MiUser['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]) { + const insert = new MiNote({ id: this.idService.genId(data.createdAt!), createdAt: data.createdAt!, fileIds: data.files ? data.files.map(file => file.id) : [], @@ -362,7 +364,7 @@ export class NoteCreateService implements OnApplicationShutdown { name: data.name, text: data.text, hasPoll: data.poll != null, - cw: data.cw == null ? null : data.cw, + cw: data.cw ?? null, tags: tags.map(tag => normalizeForSearch(tag)), emojis, userId: user.id, @@ -397,7 +399,7 @@ export class NoteCreateService implements OnApplicationShutdown { const url = profile != null ? profile.url : null; return { uri: u.uri, - url: url == null ? undefined : url, + url: url ?? undefined, username: u.username, host: u.host, } as IMentionedRemoteUsers[0]; @@ -409,9 +411,9 @@ export class NoteCreateService implements OnApplicationShutdown { if (insert.hasPoll) { // Start transaction await this.db.transaction(async transactionalEntityManager => { - await transactionalEntityManager.insert(Note, insert); + await transactionalEntityManager.insert(MiNote, insert); - const poll = new Poll({ + const poll = new MiPoll({ noteId: insert.id, choices: data.poll!.choices, expiresAt: data.poll!.expiresAt, @@ -422,7 +424,7 @@ export class NoteCreateService implements OnApplicationShutdown { userHost: user.host, }); - await transactionalEntityManager.insert(Poll, poll); + await transactionalEntityManager.insert(MiPoll, poll); }); } else { await this.notesRepository.insert(insert); @@ -444,12 +446,12 @@ export class NoteCreateService implements OnApplicationShutdown { } @bindThis - private async postNoteCreated(note: Note, user: { - id: User['id']; - username: User['username']; - host: User['host']; - createdAt: User['createdAt']; - isBot: User['isBot']; + private async postNoteCreated(note: MiNote, user: { + id: MiUser['id']; + username: MiUser['username']; + host: MiUser['host']; + createdAt: MiUser['createdAt']; + isBot: MiUser['isBot']; }, data: Option, silent: boolean, tags: string[], mentionedUsers: MinimumUser[]) { const meta = await this.metaService.fetch(); @@ -623,7 +625,7 @@ export class NoteCreateService implements OnApplicationShutdown { // メンションされたリモートユーザーに配送 for (const u of mentionedUsers.filter(u => this.userEntityService.isRemoteUser(u))) { - dm.addDirectRecipe(u as RemoteUser); + dm.addDirectRecipe(u as MiRemoteUser); } // 投稿がリプライかつ投稿者がローカルユーザーかつリプライ先の投稿の投稿者がリモートユーザーなら配送 @@ -701,7 +703,7 @@ export class NoteCreateService implements OnApplicationShutdown { } @bindThis - private incRenoteCount(renote: Note) { + private incRenoteCount(renote: MiNote) { this.notesRepository.createQueryBuilder().update() .set({ renoteCount: () => '"renoteCount" + 1', @@ -712,7 +714,7 @@ export class NoteCreateService implements OnApplicationShutdown { } @bindThis - private async createMentionedEvents(mentionedUsers: MinimumUser[], note: Note, nm: NotificationManager) { + private async createMentionedEvents(mentionedUsers: MinimumUser[], note: MiNote, nm: NotificationManager) { for (const u of mentionedUsers.filter(u => this.userEntityService.isLocalUser(u))) { const isThreadMuted = await this.noteThreadMutingsRepository.exist({ where: { @@ -744,12 +746,12 @@ export class NoteCreateService implements OnApplicationShutdown { } @bindThis - private saveReply(reply: Note, note: Note) { + private saveReply(reply: MiNote, note: MiNote) { this.notesRepository.increment({ id: reply.id }, 'repliesCount', 1); } @bindThis - private async renderNoteOrRenoteActivity(data: Option, note: Note) { + private async renderNoteOrRenoteActivity(data: Option, note: MiNote) { if (data.localOnly) return null; const content = data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length === 0) @@ -760,14 +762,14 @@ export class NoteCreateService implements OnApplicationShutdown { } @bindThis - private index(note: Note) { + private index(note: MiNote) { if (note.text == null && note.cw == null) return; this.searchService.indexNote(note); } @bindThis - private incNotesCountOfUser(user: { id: User['id']; }) { + private incNotesCountOfUser(user: { id: MiUser['id']; }) { this.usersRepository.createQueryBuilder().update() .set({ updatedAt: new Date(), @@ -778,13 +780,13 @@ export class NoteCreateService implements OnApplicationShutdown { } @bindThis - private async extractMentionedUsers(user: { host: User['host']; }, tokens: mfm.MfmNode[]): Promise { + private async extractMentionedUsers(user: { host: MiUser['host']; }, tokens: mfm.MfmNode[]): Promise { if (tokens == null) return []; const mentions = extractMentions(tokens); let mentionedUsers = (await Promise.all(mentions.map(m => this.remoteUserResolveService.resolveUser(m.username, m.host ?? user.host).catch(() => null), - ))).filter(x => x != null) as User[]; + ))).filter(x => x != null) as MiUser[]; // Drop duplicate users mentionedUsers = mentionedUsers.filter((u, i, self) => diff --git a/packages/backend/src/core/NoteDeleteService.ts b/packages/backend/src/core/NoteDeleteService.ts index f77ea8aab4..07708bd028 100644 --- a/packages/backend/src/core/NoteDeleteService.ts +++ b/packages/backend/src/core/NoteDeleteService.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets, In } from 'typeorm'; import { Injectable, Inject } from '@nestjs/common'; -import type { User, LocalUser, RemoteUser } from '@/models/entities/User.js'; -import type { Note, IMentionedRemoteUsers } from '@/models/entities/Note.js'; +import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; +import type { MiNote, IMentionedRemoteUsers } from '@/models/entities/Note.js'; import type { InstancesRepository, NotesRepository, UsersRepository } from '@/models/index.js'; import { RelayService } from '@/core/RelayService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; @@ -53,7 +58,7 @@ export class NoteDeleteService { * @param user 投稿者 * @param note 投稿 */ - async delete(user: { id: User['id']; uri: User['uri']; host: User['host']; isBot: User['isBot']; }, note: Note, quiet = false) { + async delete(user: { id: MiUser['id']; uri: MiUser['uri']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote, quiet = false) { const deletedAt = new Date(); const cascadingNotes = await this.findCascadingNotes(note); @@ -74,7 +79,7 @@ export class NoteDeleteService { //#region ローカルの投稿なら削除アクティビティを配送 if (this.userEntityService.isLocalUser(user) && !note.localOnly) { - let renote: Note | null = null; + let renote: MiNote | null = null; // if deletd note is renote if (note.renoteId && note.text == null && !note.hasPoll && (note.fileIds == null || note.fileIds.length === 0)) { @@ -129,8 +134,8 @@ export class NoteDeleteService { } @bindThis - private async findCascadingNotes(note: Note): Promise { - const recursive = async (noteId: string): Promise => { + private async findCascadingNotes(note: MiNote): Promise { + const recursive = async (noteId: string): Promise => { const query = this.notesRepository.createQueryBuilder('note') .where('note.replyId = :noteId', { noteId }) .orWhere(new Brackets(q => { @@ -146,13 +151,13 @@ export class NoteDeleteService { ].flat(); }; - const cascadingNotes: Note[] = await recursive(note.id); + const cascadingNotes: MiNote[] = await recursive(note.id); return cascadingNotes; } @bindThis - private async getMentionedRemoteUsers(note: Note) { + private async getMentionedRemoteUsers(note: MiNote) { const where = [] as any[]; // mention / reply / dm @@ -174,11 +179,11 @@ export class NoteDeleteService { return await this.usersRepository.find({ where, - }) as RemoteUser[]; + }) as MiRemoteUser[]; } @bindThis - private async deliverToConcerned(user: { id: LocalUser['id']; host: null; }, note: Note, content: any) { + private async deliverToConcerned(user: { id: MiLocalUser['id']; host: null; }, note: MiNote, content: any) { this.apDeliverManagerService.deliverToFollowers(user, content); this.relayService.deliverToRelays(user, content); const remoteUsers = await this.getMentionedRemoteUsers(note); diff --git a/packages/backend/src/core/NotePiningService.ts b/packages/backend/src/core/NotePiningService.ts index 3a9f832ac0..7f1381a41a 100644 --- a/packages/backend/src/core/NotePiningService.ts +++ b/packages/backend/src/core/NotePiningService.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { NotesRepository, UserNotePiningsRepository, UsersRepository } from '@/models/index.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; -import type { User } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { IdService } from '@/core/IdService.js'; -import type { UserNotePining } from '@/models/entities/UserNotePining.js'; +import type { MiUserNotePining } from '@/models/entities/UserNotePining.js'; import { RelayService } from '@/core/RelayService.js'; import type { Config } from '@/config.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -44,7 +49,7 @@ export class NotePiningService { * @param noteId */ @bindThis - public async addPinned(user: { id: User['id']; host: User['host']; }, noteId: Note['id']) { + public async addPinned(user: { id: MiUser['id']; host: MiUser['host']; }, noteId: MiNote['id']) { // Fetch pinee const note = await this.notesRepository.findOneBy({ id: noteId, @@ -70,7 +75,7 @@ export class NotePiningService { createdAt: new Date(), userId: user.id, noteId: note.id, - } as UserNotePining); + } as MiUserNotePining); // Deliver to remote followers if (this.userEntityService.isLocalUser(user)) { @@ -84,7 +89,7 @@ export class NotePiningService { * @param noteId */ @bindThis - public async removePinned(user: { id: User['id']; host: User['host']; }, noteId: Note['id']) { + public async removePinned(user: { id: MiUser['id']; host: MiUser['host']; }, noteId: MiNote['id']) { // Fetch unpinee const note = await this.notesRepository.findOneBy({ id: noteId, @@ -107,7 +112,7 @@ export class NotePiningService { } @bindThis - public async deliverPinnedChange(userId: User['id'], noteId: Note['id'], isAddition: boolean) { + public async deliverPinnedChange(userId: MiUser['id'], noteId: MiNote['id'], isAddition: boolean) { const user = await this.usersRepository.findOneBy({ id: userId }); if (user == null) throw new Error('user not found'); diff --git a/packages/backend/src/core/NoteReadService.ts b/packages/backend/src/core/NoteReadService.ts index 52e9bd369a..0197486263 100644 --- a/packages/backend/src/core/NoteReadService.ts +++ b/packages/backend/src/core/NoteReadService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { setTimeout } from 'node:timers/promises'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import type { Packed } from '@/misc/json-schema.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { IdService } from '@/core/IdService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import type { NoteUnreadsRepository, MutingsRepository, NoteThreadMutingsRepository } from '@/models/index.js'; @@ -30,7 +35,7 @@ export class NoteReadService implements OnApplicationShutdown { } @bindThis - public async insertNoteUnread(userId: User['id'], note: Note, params: { + public async insertNoteUnread(userId: MiUser['id'], note: MiNote, params: { // NOTE: isSpecifiedがtrueならisMentionedは必ずfalse isSpecified: boolean; isMentioned: boolean; @@ -79,11 +84,11 @@ export class NoteReadService implements OnApplicationShutdown { @bindThis public async read( - userId: User['id'], - notes: (Note | Packed<'Note'>)[], + userId: MiUser['id'], + notes: (MiNote | Packed<'Note'>)[], ): Promise { - const readMentions: (Note | Packed<'Note'>)[] = []; - const readSpecifiedNotes: (Note | Packed<'Note'>)[] = []; + const readMentions: (MiNote | Packed<'Note'>)[] = []; + const readSpecifiedNotes: (MiNote | Packed<'Note'>)[] = []; for (const note of notes) { if (note.mentions && note.mentions.includes(userId)) { diff --git a/packages/backend/src/core/NotificationService.ts b/packages/backend/src/core/NotificationService.ts index 8e25f82284..02c577c199 100644 --- a/packages/backend/src/core/NotificationService.ts +++ b/packages/backend/src/core/NotificationService.ts @@ -1,12 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { setTimeout } from 'node:timers/promises'; import * as Redis from 'ioredis'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { MutingsRepository, UserProfile, UserProfilesRepository, UsersRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; -import type { Notification } from '@/models/entities/Notification.js'; -import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import type { UsersRepository } from '@/models/index.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNotification } from '@/models/entities/Notification.js'; import { bindThis } from '@/decorators.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { PushNotificationService } from '@/core/PushNotificationService.js'; @@ -25,14 +29,7 @@ export class NotificationService implements OnApplicationShutdown { @Inject(DI.usersRepository) private usersRepository: UsersRepository, - @Inject(DI.userProfilesRepository) - private userProfilesRepository: UserProfilesRepository, - - @Inject(DI.mutingsRepository) - private mutingsRepository: MutingsRepository, - private notificationEntityService: NotificationEntityService, - private userEntityService: UserEntityService, private idService: IdService, private globalEventService: GlobalEventService, private pushNotificationService: PushNotificationService, @@ -42,7 +39,7 @@ export class NotificationService implements OnApplicationShutdown { @bindThis public async readAllNotification( - userId: User['id'], + userId: MiUser['id'], force = false, ) { const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${userId}`); @@ -64,17 +61,17 @@ export class NotificationService implements OnApplicationShutdown { } @bindThis - private postReadAllNotifications(userId: User['id']) { + private postReadAllNotifications(userId: MiUser['id']) { this.globalEventService.publishMainStream(userId, 'readAllNotifications'); this.pushNotificationService.pushNotification(userId, 'readAllNotifications', undefined); } @bindThis public async createNotification( - notifieeId: User['id'], - type: Notification['type'], - data: Partial, - ): Promise { + notifieeId: MiUser['id'], + type: MiNotification['type'], + data: Partial, + ): Promise { const profile = await this.cacheService.userProfileCache.fetch(notifieeId); const isMuted = profile.mutingNotificationTypes.includes(type); if (isMuted) return null; @@ -95,7 +92,7 @@ export class NotificationService implements OnApplicationShutdown { createdAt: new Date(), type: type, ...data, - } as Notification; + } as MiNotification; const redisIdPromise = this.redisClient.xadd( `notificationTimeline:${notifieeId}`, @@ -129,7 +126,7 @@ export class NotificationService implements OnApplicationShutdown { // TODO: locale ファイルをクライアント用とサーバー用で分けたい @bindThis - private async emailNotificationFollow(userId: User['id'], follower: User) { + private async emailNotificationFollow(userId: MiUser['id'], follower: MiUser) { /* const userProfile = await UserProfiles.findOneByOrFail({ userId: userId }); if (!userProfile.email || !userProfile.emailNotificationTypes.includes('follow')) return; @@ -141,7 +138,7 @@ export class NotificationService implements OnApplicationShutdown { } @bindThis - private async emailNotificationReceiveFollowRequest(userId: User['id'], follower: User) { + private async emailNotificationReceiveFollowRequest(userId: MiUser['id'], follower: MiUser) { /* const userProfile = await UserProfiles.findOneByOrFail({ userId: userId }); if (!userProfile.email || !userProfile.emailNotificationTypes.includes('receiveFollowRequest')) return; diff --git a/packages/backend/src/core/PollService.ts b/packages/backend/src/core/PollService.ts index be19400052..551c779769 100644 --- a/packages/backend/src/core/PollService.ts +++ b/packages/backend/src/core/PollService.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import type { NotesRepository, UsersRepository, PollsRepository, PollVotesRepository, User } from '@/models/index.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { NotesRepository, UsersRepository, PollsRepository, PollVotesRepository, MiUser } from '@/models/index.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { RelayService } from '@/core/RelayService.js'; import { IdService } from '@/core/IdService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; @@ -37,7 +42,7 @@ export class PollService { } @bindThis - public async vote(user: User, note: Note, choice: number) { + public async vote(user: MiUser, note: MiNote, choice: number) { const poll = await this.pollsRepository.findOneBy({ noteId: note.id }); if (poll == null) throw new Error('poll not found'); @@ -87,7 +92,7 @@ export class PollService { } @bindThis - public async deliverQuestionUpdate(noteId: Note['id']) { + public async deliverQuestionUpdate(noteId: MiNote['id']) { const note = await this.notesRepository.findOneBy({ id: noteId }); if (note == null) throw new Error('note not found'); diff --git a/packages/backend/src/core/ProxyAccountService.ts b/packages/backend/src/core/ProxyAccountService.ts index 780e56ef10..9fb0a45df9 100644 --- a/packages/backend/src/core/ProxyAccountService.ts +++ b/packages/backend/src/core/ProxyAccountService.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; -import type { LocalUser } from '@/models/entities/User.js'; +import type { MiLocalUser } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { MetaService } from '@/core/MetaService.js'; import { bindThis } from '@/decorators.js'; @@ -16,9 +21,9 @@ export class ProxyAccountService { } @bindThis - public async fetch(): Promise { + public async fetch(): Promise { const meta = await this.metaService.fetch(); if (meta.proxyAccountId == null) return null; - return await this.usersRepository.findOneByOrFail({ id: meta.proxyAccountId }) as LocalUser; + return await this.usersRepository.findOneByOrFail({ id: meta.proxyAccountId }) as MiLocalUser; } } diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts index e1c3d3943c..93928e3cd7 100644 --- a/packages/backend/src/core/PushNotificationService.ts +++ b/packages/backend/src/core/PushNotificationService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import push from 'web-push'; import * as Redis from 'ioredis'; @@ -5,7 +10,7 @@ import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import type { Packed } from '@/misc/json-schema.js'; import { getNoteSummary } from '@/misc/get-note-summary.js'; -import type { SwSubscription, SwSubscriptionsRepository } from '@/models/index.js'; +import type { MiSwSubscription, SwSubscriptionsRepository } from '@/models/index.js'; import { MetaService } from '@/core/MetaService.js'; import { bindThis } from '@/decorators.js'; import { RedisKVCache } from '@/misc/cache.js'; @@ -43,7 +48,7 @@ function truncateBody(type: T, body: Pus @Injectable() export class PushNotificationService implements OnApplicationShutdown { - private subscriptionsCache: RedisKVCache; + private subscriptionsCache: RedisKVCache; constructor( @Inject(DI.config) @@ -57,7 +62,7 @@ export class PushNotificationService implements OnApplicationShutdown { private metaService: MetaService, ) { - this.subscriptionsCache = new RedisKVCache(this.redisClient, 'userSwSubscriptions', { + this.subscriptionsCache = new RedisKVCache(this.redisClient, 'userSwSubscriptions', { lifetime: 1000 * 60 * 60 * 1, // 1h memoryCacheLifetime: 1000 * 60 * 3, // 3m fetcher: (key) => this.swSubscriptionsRepository.findBy({ userId: key }), diff --git a/packages/backend/src/core/QueryService.ts b/packages/backend/src/core/QueryService.ts index 435d5d2389..30fc671589 100644 --- a/packages/backend/src/core/QueryService.ts +++ b/packages/backend/src/core/QueryService.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Brackets, ObjectLiteral } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import type { UserProfilesRepository, FollowingsRepository, ChannelFollowingsRepository, MutedNotesRepository, BlockingsRepository, NoteThreadMutingsRepository, MutingsRepository, RenoteMutingsRepository } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; import type { SelectQueryBuilder } from 'typeorm'; @@ -64,7 +69,7 @@ export class QueryService { // ここでいうBlockedは被Blockedの意 @bindThis - public generateBlockedUserQuery(q: SelectQueryBuilder, me: { id: User['id'] }): void { + public generateBlockedUserQuery(q: SelectQueryBuilder, me: { id: MiUser['id'] }): void { const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking') .select('blocking.blockerId') .where('blocking.blockeeId = :blockeeId', { blockeeId: me.id }); @@ -87,7 +92,7 @@ export class QueryService { } @bindThis - public generateBlockQueryForUsers(q: SelectQueryBuilder, me: { id: User['id'] }): void { + public generateBlockQueryForUsers(q: SelectQueryBuilder, me: { id: MiUser['id'] }): void { const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking') .select('blocking.blockeeId') .where('blocking.blockerId = :blockerId', { blockerId: me.id }); @@ -104,7 +109,7 @@ export class QueryService { } @bindThis - public generateChannelQuery(q: SelectQueryBuilder, me?: { id: User['id'] } | null): void { + public generateChannelQuery(q: SelectQueryBuilder, me?: { id: MiUser['id'] } | null): void { if (me == null) { q.andWhere('note.channelId IS NULL'); } else { @@ -126,7 +131,7 @@ export class QueryService { } @bindThis - public generateMutedNoteQuery(q: SelectQueryBuilder, me: { id: User['id'] }): void { + public generateMutedNoteQuery(q: SelectQueryBuilder, me: { id: MiUser['id'] }): void { const mutedQuery = this.mutedNotesRepository.createQueryBuilder('muted') .select('muted.noteId') .where('muted.userId = :userId', { userId: me.id }); @@ -137,7 +142,7 @@ export class QueryService { } @bindThis - public generateMutedNoteThreadQuery(q: SelectQueryBuilder, me: { id: User['id'] }): void { + public generateMutedNoteThreadQuery(q: SelectQueryBuilder, me: { id: MiUser['id'] }): void { const mutedQuery = this.noteThreadMutingsRepository.createQueryBuilder('threadMuted') .select('threadMuted.threadId') .where('threadMuted.userId = :userId', { userId: me.id }); @@ -152,7 +157,7 @@ export class QueryService { } @bindThis - public generateMutedUserQuery(q: SelectQueryBuilder, me: { id: User['id'] }, exclude?: User): void { + public generateMutedUserQuery(q: SelectQueryBuilder, me: { id: MiUser['id'] }, exclude?: MiUser): void { const mutingQuery = this.mutingsRepository.createQueryBuilder('muting') .select('muting.muteeId') .where('muting.muterId = :muterId', { muterId: me.id }); @@ -197,7 +202,7 @@ export class QueryService { } @bindThis - public generateMutedUserQueryForUsers(q: SelectQueryBuilder, me: { id: User['id'] }): void { + public generateMutedUserQueryForUsers(q: SelectQueryBuilder, me: { id: MiUser['id'] }): void { const mutingQuery = this.mutingsRepository.createQueryBuilder('muting') .select('muting.muteeId') .where('muting.muterId = :muterId', { muterId: me.id }); @@ -208,7 +213,7 @@ export class QueryService { } @bindThis - public generateRepliesQuery(q: SelectQueryBuilder, withReplies: boolean, me?: Pick | null): void { + public generateRepliesQuery(q: SelectQueryBuilder, withReplies: boolean, me?: Pick | null): void { if (me == null) { q.andWhere(new Brackets(qb => { qb .where('note.replyId IS NULL') // 返信ではない @@ -234,7 +239,7 @@ export class QueryService { } @bindThis - public generateVisibilityQuery(q: SelectQueryBuilder, me?: { id: User['id'] } | null): void { + public generateVisibilityQuery(q: SelectQueryBuilder, me?: { id: MiUser['id'] } | null): void { // This code must always be synchronized with the checks in Notes.isVisibleForMe. if (me == null) { q.andWhere(new Brackets(qb => { qb @@ -274,7 +279,7 @@ export class QueryService { } @bindThis - public generateMutedUserRenotesQueryForNotes(q: SelectQueryBuilder, me: { id: User['id'] }): void { + public generateMutedUserRenotesQueryForNotes(q: SelectQueryBuilder, me: { id: MiUser['id'] }): void { const mutingQuery = this.renoteMutingsRepository.createQueryBuilder('renote_muting') .select('renote_muting.muteeId') .where('renote_muting.muterId = :muterId', { muterId: me.id }); diff --git a/packages/backend/src/core/QueueModule.ts b/packages/backend/src/core/QueueModule.ts index 3384ca4577..4444dc9787 100644 --- a/packages/backend/src/core/QueueModule.ts +++ b/packages/backend/src/core/QueueModule.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { setTimeout } from 'node:timers/promises'; import { Inject, Module, OnApplicationShutdown } from '@nestjs/common'; import * as Bull from 'bullmq'; diff --git a/packages/backend/src/core/QueueService.ts b/packages/backend/src/core/QueueService.ts index 546b4cee1b..310d5e5d9c 100644 --- a/packages/backend/src/core/QueueService.ts +++ b/packages/backend/src/core/QueueService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import type { IActivity } from '@/core/activitypub/type.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { Webhook, webhookEventTypes } from '@/models/entities/Webhook.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiWebhook, webhookEventTypes } from '@/models/entities/Webhook.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @@ -232,7 +237,7 @@ export class QueueService { } @bindThis - public createImportFollowingJob(user: ThinUser, fileId: DriveFile['id']) { + public createImportFollowingJob(user: ThinUser, fileId: MiDriveFile['id']) { return this.dbQueue.add('importFollowing', { user: { id: user.id }, fileId: fileId, @@ -249,7 +254,7 @@ export class QueueService { } @bindThis - public createImportMutingJob(user: ThinUser, fileId: DriveFile['id']) { + public createImportMutingJob(user: ThinUser, fileId: MiDriveFile['id']) { return this.dbQueue.add('importMuting', { user: { id: user.id }, fileId: fileId, @@ -260,7 +265,7 @@ export class QueueService { } @bindThis - public createImportBlockingJob(user: ThinUser, fileId: DriveFile['id']) { + public createImportBlockingJob(user: ThinUser, fileId: MiDriveFile['id']) { return this.dbQueue.add('importBlocking', { user: { id: user.id }, fileId: fileId, @@ -293,7 +298,7 @@ export class QueueService { } @bindThis - public createImportUserListsJob(user: ThinUser, fileId: DriveFile['id']) { + public createImportUserListsJob(user: ThinUser, fileId: MiDriveFile['id']) { return this.dbQueue.add('importUserLists', { user: { id: user.id }, fileId: fileId, @@ -304,7 +309,7 @@ export class QueueService { } @bindThis - public createImportCustomEmojisJob(user: ThinUser, fileId: DriveFile['id']) { + public createImportCustomEmojisJob(user: ThinUser, fileId: MiDriveFile['id']) { return this.dbQueue.add('importCustomEmojis', { user: { id: user.id }, fileId: fileId, @@ -407,7 +412,7 @@ export class QueueService { } @bindThis - public webhookDeliver(webhook: Webhook, type: typeof webhookEventTypes[number], content: unknown) { + public webhookDeliver(webhook: MiWebhook, type: typeof webhookEventTypes[number], content: unknown) { const data = { type, content, diff --git a/packages/backend/src/core/ReactionService.ts b/packages/backend/src/core/ReactionService.ts index 4b01b6af7e..b8bdfff02e 100644 --- a/packages/backend/src/core/ReactionService.ts +++ b/packages/backend/src/core/ReactionService.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { EmojisRepository, NoteReactionsRepository, UsersRepository, NotesRepository } from '@/models/index.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; -import type { RemoteUser, User } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiRemoteUser, MiUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { IdService } from '@/core/IdService.js'; -import type { NoteReaction } from '@/models/entities/NoteReaction.js'; +import type { MiNoteReaction } from '@/models/entities/NoteReaction.js'; import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { NotificationService } from '@/core/NotificationService.js'; @@ -90,7 +95,7 @@ export class ReactionService { } @bindThis - public async create(user: { id: User['id']; host: User['host']; isBot: User['isBot'] }, note: Note, _reaction?: string | null) { + public async create(user: { id: MiUser['id']; host: MiUser['host']; isBot: MiUser['isBot'] }, note: MiNote, _reaction?: string | null) { // Check blocking if (note.userId !== user.id) { const blocked = await this.userBlockingService.checkBlocked(note.userId, user.id); @@ -141,7 +146,7 @@ export class ReactionService { } } - const record: NoteReaction = { + const record: MiNoteReaction = { id: this.idService.genId(), createdAt: new Date(), noteId: note.id, @@ -226,7 +231,7 @@ export class ReactionService { const dm = this.apDeliverManagerService.createDeliverManager(user, content); if (note.userHost !== null) { const reactee = await this.usersRepository.findOneBy({ id: note.userId }); - dm.addDirectRecipe(reactee as RemoteUser); + dm.addDirectRecipe(reactee as MiRemoteUser); } if (['public', 'home', 'followers'].includes(note.visibility)) { @@ -234,7 +239,7 @@ export class ReactionService { } else if (note.visibility === 'specified') { const visibleUsers = await Promise.all(note.visibleUserIds.map(id => this.usersRepository.findOneBy({ id }))); for (const u of visibleUsers.filter(u => u && this.userEntityService.isRemoteUser(u))) { - dm.addDirectRecipe(u as RemoteUser); + dm.addDirectRecipe(u as MiRemoteUser); } } @@ -244,7 +249,7 @@ export class ReactionService { } @bindThis - public async delete(user: { id: User['id']; host: User['host']; isBot: User['isBot']; }, note: Note) { + public async delete(user: { id: MiUser['id']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote) { // if already unreacted const exist = await this.noteReactionsRepository.findOneBy({ noteId: note.id, @@ -284,7 +289,7 @@ export class ReactionService { const dm = this.apDeliverManagerService.createDeliverManager(user, content); if (note.userHost !== null) { const reactee = await this.usersRepository.findOneBy({ id: note.userId }); - dm.addDirectRecipe(reactee as RemoteUser); + dm.addDirectRecipe(reactee as MiRemoteUser); } dm.addFollowersRecipe(); dm.execute(); diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts index c0113a21d7..89f245e86d 100644 --- a/packages/backend/src/core/RelayService.ts +++ b/packages/backend/src/core/RelayService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; -import type { LocalUser, User } from '@/models/entities/User.js'; +import type { MiLocalUser, MiUser } from '@/models/entities/User.js'; import type { RelaysRepository, UsersRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; import { MemorySingleCache } from '@/misc/cache.js'; -import type { Relay } from '@/models/entities/Relay.js'; +import type { MiRelay } from '@/models/entities/Relay.js'; import { QueueService } from '@/core/QueueService.js'; import { CreateSystemUserService } from '@/core/CreateSystemUserService.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; @@ -16,7 +21,7 @@ const ACTOR_USERNAME = 'relay.actor' as const; @Injectable() export class RelayService { - private relaysCache: MemorySingleCache; + private relaysCache: MemorySingleCache; constructor( @Inject(DI.usersRepository) @@ -30,24 +35,24 @@ export class RelayService { private createSystemUserService: CreateSystemUserService, private apRendererService: ApRendererService, ) { - this.relaysCache = new MemorySingleCache(1000 * 60 * 10); + this.relaysCache = new MemorySingleCache(1000 * 60 * 10); } @bindThis - private async getRelayActor(): Promise { + private async getRelayActor(): Promise { const user = await this.usersRepository.findOneBy({ host: IsNull(), username: ACTOR_USERNAME, }); - if (user) return user as LocalUser; + if (user) return user as MiLocalUser; const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME); - return created as LocalUser; + return created as MiLocalUser; } @bindThis - public async addRelay(inbox: string): Promise { + public async addRelay(inbox: string): Promise { const relay = await this.relaysRepository.insert({ id: this.idService.genId(), inbox, @@ -82,7 +87,7 @@ export class RelayService { } @bindThis - public async listRelay(): Promise { + public async listRelay(): Promise { const relays = await this.relaysRepository.find(); return relays; } @@ -106,7 +111,7 @@ export class RelayService { } @bindThis - public async deliverToRelays(user: { id: User['id']; host: null; }, activity: any): Promise { + public async deliverToRelays(user: { id: MiUser['id']; host: null; }, activity: any): Promise { if (activity == null) return; const relays = await this.relaysCache.fetch(() => this.relaysRepository.findBy({ diff --git a/packages/backend/src/core/RemoteLoggerService.ts b/packages/backend/src/core/RemoteLoggerService.ts index 3d45605836..5d13988ed7 100644 --- a/packages/backend/src/core/RemoteLoggerService.ts +++ b/packages/backend/src/core/RemoteLoggerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import { LoggerService } from '@/core/LoggerService.js'; diff --git a/packages/backend/src/core/RemoteUserResolveService.ts b/packages/backend/src/core/RemoteUserResolveService.ts index e19a245e18..ca538ed6cd 100644 --- a/packages/backend/src/core/RemoteUserResolveService.ts +++ b/packages/backend/src/core/RemoteUserResolveService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import chalk from 'chalk'; import { IsNull } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { UsersRepository } from '@/models/index.js'; -import type { LocalUser, RemoteUser } from '@/models/entities/User.js'; +import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { UtilityService } from '@/core/UtilityService.js'; @@ -35,7 +40,7 @@ export class RemoteUserResolveService { } @bindThis - public async resolveUser(username: string, host: string | null): Promise { + public async resolveUser(username: string, host: string | null): Promise { const usernameLower = username.toLowerCase(); if (host == null) { @@ -46,7 +51,7 @@ export class RemoteUserResolveService { } else { return u; } - }) as LocalUser; + }) as MiLocalUser; } host = this.utilityService.toPuny(host); @@ -59,10 +64,10 @@ export class RemoteUserResolveService { } else { return u; } - }) as LocalUser; + }) as MiLocalUser; } - const user = await this.usersRepository.findOneBy({ usernameLower, host }) as RemoteUser | null; + const user = await this.usersRepository.findOneBy({ usernameLower, host }) as MiRemoteUser | null; const acctLower = `${usernameLower}@${host}`; @@ -81,7 +86,7 @@ export class RemoteUserResolveService { } else { return u; } - })) as LocalUser; + })) as MiLocalUser; } } @@ -127,7 +132,7 @@ export class RemoteUserResolveService { if (u == null) { throw new Error('user not found'); } else { - return u as LocalUser | RemoteUser; + return u as MiLocalUser | MiRemoteUser; } }); } diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index d065b460c6..f755f3ecfb 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; import { In } from 'typeorm'; -import type { Role, RoleAssignment, RoleAssignmentsRepository, RolesRepository, UsersRepository } from '@/models/index.js'; +import type { MiRole, MiRoleAssignment, RoleAssignmentsRepository, RolesRepository, UsersRepository } from '@/models/index.js'; import { MemoryKVCache, MemorySingleCache } from '@/misc/cache.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { MetaService } from '@/core/MetaService.js'; @@ -66,8 +71,8 @@ export const DEFAULT_POLICIES: RolePolicies = { @Injectable() export class RoleService implements OnApplicationShutdown { - private rolesCache: MemorySingleCache; - private roleAssignmentByUserIdCache: MemoryKVCache; + private rolesCache: MemorySingleCache; + private roleAssignmentByUserIdCache: MemoryKVCache; public static AlreadyAssignedError = class extends Error {}; public static NotAssignedError = class extends Error {}; @@ -96,8 +101,8 @@ export class RoleService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - this.rolesCache = new MemorySingleCache(1000 * 60 * 60 * 1); - this.roleAssignmentByUserIdCache = new MemoryKVCache(1000 * 60 * 60 * 1); + this.rolesCache = new MemorySingleCache(1000 * 60 * 60 * 1); + this.roleAssignmentByUserIdCache = new MemoryKVCache(1000 * 60 * 60 * 1); this.redisForSub.on('message', this.onMessage); } @@ -168,7 +173,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - private evalCond(user: User, value: RoleCondFormulaValue): boolean { + private evalCond(user: MiUser, value: RoleCondFormulaValue): boolean { try { switch (value.type) { case 'and': { @@ -220,7 +225,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getUserAssigns(userId: User['id']) { + public async getUserAssigns(userId: MiUser['id']) { const now = Date.now(); let assigns = await this.roleAssignmentByUserIdCache.fetch(userId, () => this.roleAssignmentsRepository.findBy({ userId })); // 期限切れのロールを除外 @@ -229,7 +234,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getUserRoles(userId: User['id']) { + public async getUserRoles(userId: MiUser['id']) { const roles = await this.rolesCache.fetch(() => this.rolesRepository.findBy({})); const assigns = await this.getUserAssigns(userId); const assignedRoles = roles.filter(r => assigns.map(x => x.roleId).includes(r.id)); @@ -242,7 +247,7 @@ export class RoleService implements OnApplicationShutdown { * 指定ユーザーのバッジロール一覧取得 */ @bindThis - public async getUserBadgeRoles(userId: User['id']) { + public async getUserBadgeRoles(userId: MiUser['id']) { const now = Date.now(); let assigns = await this.roleAssignmentByUserIdCache.fetch(userId, () => this.roleAssignmentsRepository.findBy({ userId })); // 期限切れのロールを除外 @@ -261,7 +266,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getUserPolicies(userId: User['id'] | null): Promise { + public async getUserPolicies(userId: MiUser['id'] | null): Promise { const meta = await this.metaService.fetch(); const basePolicies = { ...DEFAULT_POLICIES, ...meta.policies }; @@ -309,19 +314,19 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async isModerator(user: { id: User['id']; isRoot: User['isRoot'] } | null): Promise { + public async isModerator(user: { id: MiUser['id']; isRoot: MiUser['isRoot'] } | null): Promise { if (user == null) return false; return user.isRoot || (await this.getUserRoles(user.id)).some(r => r.isModerator || r.isAdministrator); } @bindThis - public async isAdministrator(user: { id: User['id']; isRoot: User['isRoot'] } | null): Promise { + public async isAdministrator(user: { id: MiUser['id']; isRoot: MiUser['isRoot'] } | null): Promise { if (user == null) return false; return user.isRoot || (await this.getUserRoles(user.id)).some(r => r.isAdministrator); } @bindThis - public async isExplorable(role: { id: Role['id']} | null): Promise { + public async isExplorable(role: { id: MiRole['id']} | null): Promise { if (role == null) return false; const check = await this.rolesRepository.findOneBy({ id: role.id }); if (check == null) return false; @@ -329,7 +334,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getModeratorIds(includeAdmins = true): Promise { + public async getModeratorIds(includeAdmins = true): Promise { const roles = await this.rolesCache.fetch(() => this.rolesRepository.findBy({})); const moderatorRoles = includeAdmins ? roles.filter(r => r.isModerator || r.isAdministrator) : roles.filter(r => r.isModerator); const assigns = moderatorRoles.length > 0 ? await this.roleAssignmentsRepository.findBy({ @@ -340,7 +345,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getModerators(includeAdmins = true): Promise { + public async getModerators(includeAdmins = true): Promise { const ids = await this.getModeratorIds(includeAdmins); const users = ids.length > 0 ? await this.usersRepository.findBy({ id: In(ids), @@ -349,7 +354,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getAdministratorIds(): Promise { + public async getAdministratorIds(): Promise { const roles = await this.rolesCache.fetch(() => this.rolesRepository.findBy({})); const administratorRoles = roles.filter(r => r.isAdministrator); const assigns = administratorRoles.length > 0 ? await this.roleAssignmentsRepository.findBy({ @@ -360,7 +365,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async getAdministrators(): Promise { + public async getAdministrators(): Promise { const ids = await this.getAdministratorIds(); const users = ids.length > 0 ? await this.usersRepository.findBy({ id: In(ids), @@ -369,7 +374,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async assign(userId: User['id'], roleId: Role['id'], expiresAt: Date | null = null): Promise { + public async assign(userId: MiUser['id'], roleId: MiRole['id'], expiresAt: Date | null = null): Promise { const now = new Date(); const existing = await this.roleAssignmentsRepository.findOneBy({ @@ -404,7 +409,7 @@ export class RoleService implements OnApplicationShutdown { } @bindThis - public async unassign(userId: User['id'], roleId: Role['id']): Promise { + public async unassign(userId: MiUser['id'], roleId: MiRole['id']): Promise { const now = new Date(); const existing = await this.roleAssignmentsRepository.findOneBy({ roleId, userId }); diff --git a/packages/backend/src/core/S3Service.ts b/packages/backend/src/core/S3Service.ts index 01ce12ffdd..eb0458f53b 100644 --- a/packages/backend/src/core/S3Service.ts +++ b/packages/backend/src/core/S3Service.ts @@ -1,13 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import * as http from 'node:http'; import * as https from 'node:https'; -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { DeleteObjectCommand, S3Client } from '@aws-sdk/client-s3'; import { Upload } from '@aws-sdk/lib-storage'; import { NodeHttpHandler, NodeHttpHandlerOptions } from '@aws-sdk/node-http-handler'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; -import type { Meta } from '@/models/entities/Meta.js'; +import type { MiMeta } from '@/models/entities/Meta.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; import type { DeleteObjectCommandInput, PutObjectCommandInput } from '@aws-sdk/client-s3'; @@ -15,15 +18,12 @@ import type { DeleteObjectCommandInput, PutObjectCommandInput } from '@aws-sdk/c @Injectable() export class S3Service { constructor( - @Inject(DI.config) - private config: Config, - private httpRequestService: HttpRequestService, ) { } @bindThis - public getS3Client(meta: Meta): S3Client { + public getS3Client(meta: MiMeta): S3Client { const u = meta.objectStorageEndpoint ? `${meta.objectStorageUseSSL ? 'https' : 'http'}://${meta.objectStorageEndpoint}` : `${meta.objectStorageUseSSL ? 'https' : 'http'}://example.net`; // dummy url to select http(s) agent @@ -50,7 +50,7 @@ export class S3Service { } @bindThis - public async upload(meta: Meta, input: PutObjectCommandInput) { + public async upload(meta: MiMeta, input: PutObjectCommandInput) { const client = this.getS3Client(meta); return new Upload({ client, @@ -62,7 +62,7 @@ export class S3Service { } @bindThis - public delete(meta: Meta, input: DeleteObjectCommandInput) { + public delete(meta: MiMeta, input: DeleteObjectCommandInput) { const client = this.getS3Client(meta); return client.send(new DeleteObjectCommand(input)); } diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index 392799da75..f21bd790be 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import { bindThis } from '@/decorators.js'; -import { Note } from '@/models/entities/Note.js'; -import { User } from '@/models/index.js'; +import { MiNote } from '@/models/entities/Note.js'; +import { MiUser } from '@/models/index.js'; import type { NotesRepository } from '@/models/index.js'; import { sqlLikeEscape } from '@/misc/sql-like-escape.js'; import { QueryService } from '@/core/QueryService.js'; @@ -20,6 +25,8 @@ type Q = { op: '<', k: K, v: number } | { op: '>=', k: K, v: number } | { op: '<=', k: K, v: number } | + { op: 'is null', k: K} | + { op: 'is not null', k: K} | { op: 'and', qs: Q[] } | { op: 'or', qs: Q[] } | { op: 'not', q: Q }; @@ -45,6 +52,8 @@ function compileQuery(q: Q): string { case '<=': return `(${q.k} <= ${compileValue(q.v)})`; case 'and': return q.qs.length === 0 ? '' : `(${ q.qs.map(_q => compileQuery(_q)).join(' AND ') })`; case 'or': return q.qs.length === 0 ? '' : `(${ q.qs.map(_q => compileQuery(_q)).join(' OR ') })`; + case 'is null': return `(${q.k} IS NULL)`; + case 'is not null': return `(${q.k} IS NOT NULL)`; case 'not': return `(NOT ${compileQuery(q.q)})`; default: throw new Error('unrecognized query operator'); } @@ -100,7 +109,7 @@ export class SearchService { } @bindThis - public async indexNote(note: Note): Promise { + public async indexNote(note: MiNote): Promise { if (note.text == null && note.cw == null) return; if (!['home', 'public'].includes(note.visibility)) return; @@ -136,7 +145,7 @@ export class SearchService { } @bindThis - public async unindexNote(note: Note): Promise { + public async unindexNote(note: MiNote): Promise { if (!['home', 'public'].includes(note.visibility)) return; if (this.meilisearch) { @@ -145,15 +154,15 @@ export class SearchService { } @bindThis - public async searchNote(q: string, me: User | null, opts: { - userId?: Note['userId'] | null; - channelId?: Note['channelId'] | null; + public async searchNote(q: string, me: MiUser | null, opts: { + userId?: MiNote['userId'] | null; + channelId?: MiNote['channelId'] | null; host?: string | null; }, pagination: { - untilId?: Note['id']; - sinceId?: Note['id']; + untilId?: MiNote['id']; + sinceId?: MiNote['id']; limit?: number; - }): Promise { + }): Promise { if (this.meilisearch) { const filter: Q = { op: 'and', @@ -165,7 +174,7 @@ export class SearchService { if (opts.channelId) filter.qs.push({ op: '=', k: 'channelId', v: opts.channelId }); if (opts.host) { if (opts.host === '.') { - // TODO: Meilisearchが2023/05/07現在値がNULLかどうかのクエリが書けない + filter.qs.push({ op: 'is null', k: 'userHost' }); } else { filter.qs.push({ op: '=', k: 'userHost', v: opts.host }); } @@ -199,6 +208,14 @@ export class SearchService { .leftJoinAndSelect('reply.user', 'replyUser') .leftJoinAndSelect('renote.user', 'renoteUser'); + if (opts.host) { + if (opts.host === '.') { + query.andWhere('user.host IS NULL'); + } else { + query.andWhere('user.host = :host', { host: opts.host }); + } + } + this.queryService.generateVisibilityQuery(query, me); if (me) this.queryService.generateMutedUserQuery(query, me); if (me) this.queryService.generateBlockedUserQuery(query, me); diff --git a/packages/backend/src/core/SignupService.ts b/packages/backend/src/core/SignupService.ts index 070a9a9e3e..e719d5918e 100644 --- a/packages/backend/src/core/SignupService.ts +++ b/packages/backend/src/core/SignupService.ts @@ -1,15 +1,19 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { generateKeyPair } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import bcrypt from 'bcryptjs'; import { DataSource, IsNull } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { UsedUsernamesRepository, UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; -import { User } from '@/models/entities/User.js'; -import { UserProfile } from '@/models/entities/UserProfile.js'; +import { MiUser } from '@/models/entities/User.js'; +import { MiUserProfile } from '@/models/entities/UserProfile.js'; import { IdService } from '@/core/IdService.js'; -import { UserKeypair } from '@/models/entities/UserKeypair.js'; -import { UsedUsername } from '@/models/entities/UsedUsername.js'; +import { MiUserKeypair } from '@/models/entities/UserKeypair.js'; +import { MiUsedUsername } from '@/models/entities/UsedUsername.js'; import generateUserToken from '@/misc/generate-native-user-token.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -23,9 +27,6 @@ export class SignupService { @Inject(DI.db) private db: DataSource, - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -42,9 +43,9 @@ export class SignupService { @bindThis public async signup(opts: { - username: User['username']; + username: MiUser['username']; password?: string | null; - passwordHash?: UserProfile['password'] | null; + passwordHash?: MiUserProfile['password'] | null; host?: string | null; ignorePreservedUsernames?: boolean; }) { @@ -107,18 +108,18 @@ export class SignupService { err ? rej(err) : res([publicKey, privateKey]), )); - let account!: User; + let account!: MiUser; // Start transaction await this.db.transaction(async transactionalEntityManager => { - const exist = await transactionalEntityManager.findOneBy(User, { + const exist = await transactionalEntityManager.findOneBy(MiUser, { usernameLower: username.toLowerCase(), host: IsNull(), }); if (exist) throw new Error(' the username is already used'); - account = await transactionalEntityManager.save(new User({ + account = await transactionalEntityManager.save(new MiUser({ id: this.idService.genId(), createdAt: new Date(), username: username, @@ -128,19 +129,19 @@ export class SignupService { isRoot: isTheFirstUser, })); - await transactionalEntityManager.save(new UserKeypair({ + await transactionalEntityManager.save(new MiUserKeypair({ publicKey: keyPair[0], privateKey: keyPair[1], userId: account.id, })); - await transactionalEntityManager.save(new UserProfile({ + await transactionalEntityManager.save(new MiUserProfile({ userId: account.id, autoAcceptFollowed: true, password: hash, })); - await transactionalEntityManager.save(new UsedUsername({ + await transactionalEntityManager.save(new MiUsedUsername({ createdAt: new Date(), username: username.toLowerCase(), })); diff --git a/packages/backend/src/core/TwoFactorAuthenticationService.ts b/packages/backend/src/core/TwoFactorAuthenticationService.ts index d4cf186a24..ecf7676f4b 100644 --- a/packages/backend/src/core/TwoFactorAuthenticationService.ts +++ b/packages/backend/src/core/TwoFactorAuthenticationService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as crypto from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import * as jsrsasign from 'jsrsasign'; import { DI } from '@/di-symbols.js'; -import type { UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { bindThis } from '@/decorators.js'; @@ -110,9 +114,6 @@ export class TwoFactorAuthenticationService { constructor( @Inject(DI.config) private config: Config, - - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, ) { } diff --git a/packages/backend/src/core/UserBlockingService.ts b/packages/backend/src/core/UserBlockingService.ts index 3ca22f8bbc..44e2066a11 100644 --- a/packages/backend/src/core/UserBlockingService.ts +++ b/packages/backend/src/core/UserBlockingService.ts @@ -1,9 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ import { Inject, Injectable, OnModuleInit } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; import { IdService } from '@/core/IdService.js'; -import type { User } from '@/models/entities/User.js'; -import type { Blocking } from '@/models/entities/Blocking.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiBlocking } from '@/models/entities/Blocking.js'; import { QueueService } from '@/core/QueueService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; @@ -54,7 +58,7 @@ export class UserBlockingService implements OnModuleInit { } @bindThis - public async block(blocker: User, blockee: User, silent = false) { + public async block(blocker: MiUser, blockee: MiUser, silent = false) { await Promise.all([ this.cancelRequest(blocker, blockee, silent), this.cancelRequest(blockee, blocker, silent), @@ -70,7 +74,7 @@ export class UserBlockingService implements OnModuleInit { blockerId: blocker.id, blockee, blockeeId: blockee.id, - } as Blocking; + } as MiBlocking; await this.blockingsRepository.insert(blocking); @@ -89,7 +93,7 @@ export class UserBlockingService implements OnModuleInit { } @bindThis - private async cancelRequest(follower: User, followee: User, silent = false) { + private async cancelRequest(follower: MiUser, followee: MiUser, silent = false) { const request = await this.followRequestsRepository.findOneBy({ followeeId: followee.id, followerId: follower.id, @@ -139,7 +143,7 @@ export class UserBlockingService implements OnModuleInit { } @bindThis - private async removeFromList(listOwner: User, user: User) { + private async removeFromList(listOwner: MiUser, user: MiUser) { const userLists = await this.userListsRepository.findBy({ userId: listOwner.id, }); @@ -153,7 +157,7 @@ export class UserBlockingService implements OnModuleInit { } @bindThis - public async unblock(blocker: User, blockee: User) { + public async unblock(blocker: MiUser, blockee: MiUser) { const blocking = await this.blockingsRepository.findOneBy({ blockerId: blocker.id, blockeeId: blockee.id, @@ -187,7 +191,7 @@ export class UserBlockingService implements OnModuleInit { } @bindThis - public async checkBlocked(blockerId: User['id'], blockeeId: User['id']): Promise { + public async checkBlocked(blockerId: MiUser['id'], blockeeId: MiUser['id']): Promise { return (await this.cacheService.userBlockingCache.fetch(blockerId)).has(blockeeId); } } diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 44269d3b8a..c99a3e6a11 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; import { IsNull } from 'typeorm'; -import type { LocalUser, PartialLocalUser, PartialRemoteUser, RemoteUser, User } from '@/models/entities/User.js'; +import type { MiLocalUser, MiPartialLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { QueueService } from '@/core/QueueService.js'; import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js'; @@ -27,16 +32,16 @@ import Logger from '../logger.js'; const logger = new Logger('following/create'); -type Local = LocalUser | { - id: LocalUser['id']; - host: LocalUser['host']; - uri: LocalUser['uri'] +type Local = MiLocalUser | { + id: MiLocalUser['id']; + host: MiLocalUser['host']; + uri: MiLocalUser['uri'] }; -type Remote = RemoteUser | { - id: RemoteUser['id']; - host: RemoteUser['host']; - uri: RemoteUser['uri']; - inbox: RemoteUser['inbox']; +type Remote = MiRemoteUser | { + id: MiRemoteUser['id']; + host: MiRemoteUser['host']; + uri: MiRemoteUser['uri']; + inbox: MiRemoteUser['inbox']; }; type Both = Local | Remote; @@ -86,11 +91,11 @@ export class UserFollowingService implements OnModuleInit { } @bindThis - public async follow(_follower: { id: User['id'] }, _followee: { id: User['id'] }, requestId?: string, silent = false): Promise { + public async follow(_follower: { id: MiUser['id'] }, _followee: { id: MiUser['id'] }, requestId?: string, silent = false): Promise { const [follower, followee] = await Promise.all([ this.usersRepository.findOneByOrFail({ id: _follower.id }), this.usersRepository.findOneByOrFail({ id: _followee.id }), - ]) as [LocalUser | RemoteUser, LocalUser | RemoteUser]; + ]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser]; // check blocking const [blocking, blocked] = await Promise.all([ @@ -175,10 +180,10 @@ export class UserFollowingService implements OnModuleInit { @bindThis private async insertFollowingDoc( followee: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox'] + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox'] }, follower: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox'] + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox'] }, silent = false, ): Promise { @@ -307,10 +312,10 @@ export class UserFollowingService implements OnModuleInit { @bindThis public async unfollow( follower: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox']; }, followee: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox']; }, silent = false, ): Promise { @@ -353,21 +358,21 @@ export class UserFollowingService implements OnModuleInit { } if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { - const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as PartialLocalUser, followee as PartialRemoteUser), follower)); + const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as MiPartialLocalUser, followee as MiPartialRemoteUser), follower)); this.queueService.deliver(follower, content, followee.inbox, false); } if (this.userEntityService.isLocalUser(followee) && this.userEntityService.isRemoteUser(follower)) { // local user has null host - const content = this.apRendererService.addContext(this.apRendererService.renderReject(this.apRendererService.renderFollow(follower as PartialRemoteUser, followee as PartialLocalUser), followee)); + const content = this.apRendererService.addContext(this.apRendererService.renderReject(this.apRendererService.renderFollow(follower as MiPartialRemoteUser, followee as MiPartialLocalUser), followee)); this.queueService.deliver(followee, content, follower.inbox, false); } } @bindThis private async decrementFollowing( - follower: User, - followee: User, + follower: MiUser, + followee: MiUser, ): Promise { this.globalEventService.publishInternalEvent('unfollow', { followerId: follower.id, followeeId: followee.id }); @@ -439,10 +444,10 @@ export class UserFollowingService implements OnModuleInit { @bindThis public async createFollowRequest( follower: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox']; }, followee: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox']; }, requestId?: string, ): Promise { @@ -489,7 +494,7 @@ export class UserFollowingService implements OnModuleInit { } if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { - const content = this.apRendererService.addContext(this.apRendererService.renderFollow(follower as PartialLocalUser, followee as PartialRemoteUser, requestId ?? `${this.config.url}/follows/${followRequest.id}`)); + const content = this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiPartialLocalUser, followee as MiPartialRemoteUser, requestId ?? `${this.config.url}/follows/${followRequest.id}`)); this.queueService.deliver(follower, content, followee.inbox, false); } } @@ -497,14 +502,14 @@ export class UserFollowingService implements OnModuleInit { @bindThis public async cancelFollowRequest( followee: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox'] + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox'] }, follower: { - id: User['id']; host: User['host']; uri: User['host'] + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host'] }, ): Promise { if (this.userEntityService.isRemoteUser(followee)) { - const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as PartialLocalUser | PartialRemoteUser, followee as PartialRemoteUser), follower)); + const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as MiPartialLocalUser | MiPartialRemoteUser, followee as MiPartialRemoteUser), follower)); if (this.userEntityService.isLocalUser(follower)) { // 本来このチェックは不要だけどTSに怒られるので this.queueService.deliver(follower, content, followee.inbox, false); @@ -535,9 +540,9 @@ export class UserFollowingService implements OnModuleInit { @bindThis public async acceptFollowRequest( followee: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox']; }, - follower: User, + follower: MiUser, ): Promise { const request = await this.followRequestsRepository.findOneBy({ followeeId: followee.id, @@ -551,7 +556,7 @@ export class UserFollowingService implements OnModuleInit { await this.insertFollowingDoc(followee, follower); if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { - const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee as PartialLocalUser, request.requestId!), followee)); + const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee as MiPartialLocalUser, request.requestId!), followee)); this.queueService.deliver(followee, content, follower.inbox, false); } @@ -563,7 +568,7 @@ export class UserFollowingService implements OnModuleInit { @bindThis public async acceptAllFollowRequests( user: { - id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; + id: MiUser['id']; host: MiUser['host']; uri: MiUser['host']; inbox: MiUser['inbox']; sharedInbox: MiUser['sharedInbox']; }, ): Promise { const requests = await this.followRequestsRepository.findBy({ diff --git a/packages/backend/src/core/UserKeypairService.ts b/packages/backend/src/core/UserKeypairService.ts index d768f08650..f321727601 100644 --- a/packages/backend/src/core/UserKeypairService.ts +++ b/packages/backend/src/core/UserKeypairService.ts @@ -1,15 +1,20 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import * as Redis from 'ioredis'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import type { UserKeypairsRepository } from '@/models/index.js'; import { RedisKVCache } from '@/misc/cache.js'; -import type { UserKeypair } from '@/models/entities/UserKeypair.js'; +import type { MiUserKeypair } from '@/models/entities/UserKeypair.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @Injectable() export class UserKeypairService implements OnApplicationShutdown { - private cache: RedisKVCache; + private cache: RedisKVCache; constructor( @Inject(DI.redis) @@ -18,7 +23,7 @@ export class UserKeypairService implements OnApplicationShutdown { @Inject(DI.userKeypairsRepository) private userKeypairsRepository: UserKeypairsRepository, ) { - this.cache = new RedisKVCache(this.redisClient, 'userKeypair', { + this.cache = new RedisKVCache(this.redisClient, 'userKeypair', { lifetime: 1000 * 60 * 60 * 24, // 24h memoryCacheLifetime: Infinity, fetcher: (key) => this.userKeypairsRepository.findOneByOrFail({ userId: key }), @@ -28,7 +33,7 @@ export class UserKeypairService implements OnApplicationShutdown { } @bindThis - public async getUserKeypair(userId: User['id']): Promise { + public async getUserKeypair(userId: MiUser['id']): Promise { return await this.cache.fetch(userId); } diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index 08cc907ebf..3a56a2e96c 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { UserListJoiningsRepository, UsersRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; -import type { UserList } from '@/models/entities/UserList.js'; -import type { UserListJoining } from '@/models/entities/UserListJoining.js'; +import type { UserListJoiningsRepository } from '@/models/index.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiUserList } from '@/models/entities/UserList.js'; +import type { MiUserListJoining } from '@/models/entities/UserListJoining.js'; import { IdService } from '@/core/IdService.js'; -import { UserFollowingService } from '@/core/UserFollowingService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -18,15 +22,11 @@ export class UserListService { public static TooManyUsersError = class extends Error {}; constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.userListJoiningsRepository) private userListJoiningsRepository: UserListJoiningsRepository, private userEntityService: UserEntityService, private idService: IdService, - private userFollowingService: UserFollowingService, private roleService: RoleService, private globalEventService: GlobalEventService, private proxyAccountService: ProxyAccountService, @@ -35,7 +35,7 @@ export class UserListService { } @bindThis - public async push(target: User, list: UserList, me: User) { + public async push(target: MiUser, list: MiUserList, me: MiUser) { const currentCount = await this.userListJoiningsRepository.countBy({ userListId: list.id, }); @@ -48,7 +48,7 @@ export class UserListService { createdAt: new Date(), userId: target.id, userListId: list.id, - } as UserListJoining); + } as MiUserListJoining); this.globalEventService.publishUserListStream(list.id, 'userAdded', await this.userEntityService.pack(target)); diff --git a/packages/backend/src/core/UserMutingService.ts b/packages/backend/src/core/UserMutingService.ts index d201ec6c04..1f0b2c215b 100644 --- a/packages/backend/src/core/UserMutingService.ts +++ b/packages/backend/src/core/UserMutingService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; -import type { MutingsRepository, Muting } from '@/models/index.js'; +import type { MutingsRepository, MiMuting } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { CacheService } from '@/core/CacheService.js'; @@ -19,7 +24,7 @@ export class UserMutingService { } @bindThis - public async mute(user: User, target: User, expiresAt: Date | null = null): Promise { + public async mute(user: MiUser, target: MiUser, expiresAt: Date | null = null): Promise { await this.mutingsRepository.insert({ id: this.idService.genId(), createdAt: new Date(), @@ -32,7 +37,7 @@ export class UserMutingService { } @bindThis - public async unmute(mutings: Muting[]): Promise { + public async unmute(mutings: MiMuting[]): Promise { if (mutings.length === 0) return; await this.mutingsRepository.delete({ diff --git a/packages/backend/src/core/UserSuspendService.ts b/packages/backend/src/core/UserSuspendService.ts index 28ae32681d..938aeb600c 100644 --- a/packages/backend/src/core/UserSuspendService.ts +++ b/packages/backend/src/core/UserSuspendService.ts @@ -1,11 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Not, IsNull } from 'typeorm'; -import type { FollowingsRepository, UsersRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { FollowingsRepository } from '@/models/index.js'; +import type { MiUser } from '@/models/entities/User.js'; import { QueueService } from '@/core/QueueService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -13,12 +17,6 @@ import { bindThis } from '@/decorators.js'; @Injectable() export class UserSuspendService { constructor( - @Inject(DI.config) - private config: Config, - - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, @@ -30,7 +28,7 @@ export class UserSuspendService { } @bindThis - public async doPostSuspend(user: { id: User['id']; host: User['host'] }): Promise { + public async doPostSuspend(user: { id: MiUser['id']; host: MiUser['host'] }): Promise { this.globalEventService.publishInternalEvent('userChangeSuspendedState', { id: user.id, isSuspended: true }); if (this.userEntityService.isLocalUser(user)) { @@ -60,7 +58,7 @@ export class UserSuspendService { } @bindThis - public async doPostUnsuspend(user: User): Promise { + public async doPostUnsuspend(user: MiUser): Promise { this.globalEventService.publishInternalEvent('userChangeSuspendedState', { id: user.id, isSuspended: false }); if (this.userEntityService.isLocalUser(user)) { diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts index d00708a442..d2d2776bd2 100644 --- a/packages/backend/src/core/UtilityService.ts +++ b/packages/backend/src/core/UtilityService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import { toASCII } from 'punycode'; import { Inject, Injectable } from '@nestjs/common'; diff --git a/packages/backend/src/core/VideoProcessingService.ts b/packages/backend/src/core/VideoProcessingService.ts index 06f832ab09..ffb7573358 100644 --- a/packages/backend/src/core/VideoProcessingService.ts +++ b/packages/backend/src/core/VideoProcessingService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import FFmpeg from 'fluent-ffmpeg'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/core/WebfingerService.ts b/packages/backend/src/core/WebfingerService.ts index 6b2428cdf0..3d5747aebd 100644 --- a/packages/backend/src/core/WebfingerService.ts +++ b/packages/backend/src/core/WebfingerService.ts @@ -1,7 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; +import { Injectable } from '@nestjs/common'; import { query as urlQuery } from '@/misc/prelude/url.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; @@ -22,9 +25,6 @@ const mRegex = /^([^@]+)@(.*)/; @Injectable() export class WebfingerService { constructor( - @Inject(DI.config) - private config: Config, - private httpRequestService: HttpRequestService, ) { } diff --git a/packages/backend/src/core/WebhookService.ts b/packages/backend/src/core/WebhookService.ts index b6f5263901..3b43c1224c 100644 --- a/packages/backend/src/core/WebhookService.ts +++ b/packages/backend/src/core/WebhookService.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; import type { WebhooksRepository } from '@/models/index.js'; -import type { Webhook } from '@/models/entities/Webhook.js'; +import type { MiWebhook } from '@/models/entities/Webhook.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { StreamMessages } from '@/server/api/stream/types.js'; @@ -10,7 +15,7 @@ import type { OnApplicationShutdown } from '@nestjs/common'; @Injectable() export class WebhookService implements OnApplicationShutdown { private webhooksFetched = false; - private webhooks: Webhook[] = []; + private webhooks: MiWebhook[] = []; constructor( @Inject(DI.redisForSub) diff --git a/packages/backend/src/core/activitypub/ApAudienceService.ts b/packages/backend/src/core/activitypub/ApAudienceService.ts index f2d84341f4..f3432f8334 100644 --- a/packages/backend/src/core/activitypub/ApAudienceService.ts +++ b/packages/backend/src/core/activitypub/ApAudienceService.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import promiseLimit from 'promise-limit'; -import type { RemoteUser, User } from '@/models/entities/User.js'; +import type { MiRemoteUser, MiUser } from '@/models/entities/User.js'; import { concat, unique } from '@/misc/prelude/array.js'; import { bindThis } from '@/decorators.js'; import { getApIds } from './type.js'; @@ -12,8 +17,8 @@ type Visibility = 'public' | 'home' | 'followers' | 'specified'; type AudienceInfo = { visibility: Visibility, - mentionedUsers: User[], - visibleUsers: User[], + mentionedUsers: MiUser[], + visibleUsers: MiUser[], }; type GroupedAudience = Record<'public' | 'followers' | 'other', string[]>; @@ -26,16 +31,16 @@ export class ApAudienceService { } @bindThis - public async parseAudience(actor: RemoteUser, to?: ApObject, cc?: ApObject, resolver?: Resolver): Promise { + public async parseAudience(actor: MiRemoteUser, to?: ApObject, cc?: ApObject, resolver?: Resolver): Promise { const toGroups = this.groupingAudience(getApIds(to), actor); const ccGroups = this.groupingAudience(getApIds(cc), actor); const others = unique(concat([toGroups.other, ccGroups.other])); - const limit = promiseLimit(2); + const limit = promiseLimit(2); const mentionedUsers = (await Promise.all( others.map(id => limit(() => this.apPersonService.resolvePerson(id, resolver).catch(() => null))), - )).filter((x): x is User => x != null); + )).filter((x): x is MiUser => x != null); if (toGroups.public.length > 0) { return { @@ -69,7 +74,7 @@ export class ApAudienceService { } @bindThis - private groupingAudience(ids: string[], actor: RemoteUser): GroupedAudience { + private groupingAudience(ids: string[], actor: MiRemoteUser): GroupedAudience { const groups: GroupedAudience = { public: [], followers: [], @@ -101,7 +106,7 @@ export class ApAudienceService { } @bindThis - private isFollowers(id: string, actor: RemoteUser): boolean { + private isFollowers(id: string, actor: MiRemoteUser): boolean { return id === (actor.followersUri ?? `${actor.uri}/followers`); } } diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index d5a530c903..b691588320 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -1,13 +1,18 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { MemoryKVCache } from '@/misc/cache.js'; -import type { UserPublickey } from '@/models/entities/UserPublickey.js'; +import type { MiUserPublickey } from '@/models/entities/UserPublickey.js'; import { CacheService } from '@/core/CacheService.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { bindThis } from '@/decorators.js'; -import { LocalUser, RemoteUser } from '@/models/entities/User.js'; +import { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; import { getApId } from './type.js'; import { ApPersonService } from './models/ApPersonService.js'; import type { IObject } from './type.js'; @@ -30,8 +35,8 @@ export type UriParseResult = { @Injectable() export class ApDbResolverService implements OnApplicationShutdown { - private publicKeyCache: MemoryKVCache; - private publicKeyByUserIdCache: MemoryKVCache; + private publicKeyCache: MemoryKVCache; + private publicKeyByUserIdCache: MemoryKVCache; constructor( @Inject(DI.config) @@ -49,8 +54,8 @@ export class ApDbResolverService implements OnApplicationShutdown { private cacheService: CacheService, private apPersonService: ApPersonService, ) { - this.publicKeyCache = new MemoryKVCache(Infinity); - this.publicKeyByUserIdCache = new MemoryKVCache(Infinity); + this.publicKeyCache = new MemoryKVCache(Infinity); + this.publicKeyByUserIdCache = new MemoryKVCache(Infinity); } @bindThis @@ -73,7 +78,7 @@ export class ApDbResolverService implements OnApplicationShutdown { * AP Note => Misskey Note in DB */ @bindThis - public async getNoteFromApId(value: string | IObject): Promise { + public async getNoteFromApId(value: string | IObject): Promise { const parsed = this.parseUri(value); if (parsed.local) { @@ -93,7 +98,7 @@ export class ApDbResolverService implements OnApplicationShutdown { * AP Person => Misskey User in DB */ @bindThis - public async getUserFromApId(value: string | IObject): Promise { + public async getUserFromApId(value: string | IObject): Promise { const parsed = this.parseUri(value); if (parsed.local) { @@ -102,12 +107,12 @@ export class ApDbResolverService implements OnApplicationShutdown { return await this.cacheService.userByIdCache.fetchMaybe( parsed.id, () => this.usersRepository.findOneBy({ id: parsed.id }).then(x => x ?? undefined), - ) as LocalUser | undefined ?? null; + ) as MiLocalUser | undefined ?? null; } else { return await this.cacheService.uriPersonCache.fetch( parsed.uri, () => this.usersRepository.findOneBy({ uri: parsed.uri }), - ) as RemoteUser | null; + ) as MiRemoteUser | null; } } @@ -116,8 +121,8 @@ export class ApDbResolverService implements OnApplicationShutdown { */ @bindThis public async getAuthUserFromKeyId(keyId: string): Promise<{ - user: RemoteUser; - key: UserPublickey; + user: MiRemoteUser; + key: MiUserPublickey; } | null> { const key = await this.publicKeyCache.fetch(keyId, async () => { const key = await this.userPublickeysRepository.findOneBy({ @@ -132,7 +137,7 @@ export class ApDbResolverService implements OnApplicationShutdown { if (key == null) return null; return { - user: await this.cacheService.findUserById(key.userId) as RemoteUser, + user: await this.cacheService.findUserById(key.userId) as MiRemoteUser, key, }; } @@ -142,10 +147,10 @@ export class ApDbResolverService implements OnApplicationShutdown { */ @bindThis public async getAuthUserFromApId(uri: string): Promise<{ - user: RemoteUser; - key: UserPublickey | null; + user: MiRemoteUser; + key: MiUserPublickey | null; } | null> { - const user = await this.apPersonService.resolvePerson(uri) as RemoteUser; + const user = await this.apPersonService.resolvePerson(uri) as MiRemoteUser; const key = await this.publicKeyByUserIdCache.fetch( user.id, diff --git a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts index 09461973d9..da1e171063 100644 --- a/packages/backend/src/core/activitypub/ApDeliverManagerService.ts +++ b/packages/backend/src/core/activitypub/ApDeliverManagerService.ts @@ -1,9 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull, Not } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { FollowingsRepository, UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; -import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js'; +import type { FollowingsRepository } from '@/models/index.js'; +import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js'; import { QueueService } from '@/core/QueueService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -20,7 +24,7 @@ interface IFollowersRecipe extends IRecipe { interface IDirectRecipe extends IRecipe { type: 'Direct'; - to: RemoteUser; + to: MiRemoteUser; } const isFollowers = (recipe: IRecipe): recipe is IFollowersRecipe => @@ -47,7 +51,7 @@ class DeliverManager { private followingsRepository: FollowingsRepository, private queueService: QueueService, - actor: { id: User['id']; host: null; }, + actor: { id: MiUser['id']; host: null; }, activity: IActivity | null, ) { // 型で弾いてはいるが一応ローカルユーザーかチェック @@ -78,7 +82,7 @@ class DeliverManager { * @param to To */ @bindThis - public addDirectRecipe(to: RemoteUser): void { + public addDirectRecipe(to: MiRemoteUser): void { const recipe: IDirectRecipe = { type: 'Direct', to, @@ -147,12 +151,6 @@ class DeliverManager { @Injectable() export class ApDeliverManagerService { constructor( - @Inject(DI.config) - private config: Config, - - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, @@ -167,7 +165,7 @@ export class ApDeliverManagerService { * @param activity Activity */ @bindThis - public async deliverToFollowers(actor: { id: LocalUser['id']; host: null; }, activity: IActivity): Promise { + public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity): Promise { const manager = new DeliverManager( this.userEntityService, this.followingsRepository, @@ -186,7 +184,7 @@ export class ApDeliverManagerService { * @param to Target user */ @bindThis - public async deliverToUser(actor: { id: LocalUser['id']; host: null; }, activity: IActivity, to: RemoteUser): Promise { + public async deliverToUser(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, to: MiRemoteUser): Promise { const manager = new DeliverManager( this.userEntityService, this.followingsRepository, @@ -199,7 +197,7 @@ export class ApDeliverManagerService { } @bindThis - public createDeliverManager(actor: { id: User['id']; host: null; }, activity: IActivity | null): DeliverManager { + public createDeliverManager(actor: { id: MiUser['id']; host: null; }, activity: IActivity | null): DeliverManager { return new DeliverManager( this.userEntityService, this.followingsRepository, diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 8d5f4883e4..d29e2cd687 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; @@ -13,17 +18,15 @@ import { concat, toArray, toSingle, unique } from '@/misc/prelude/array.js'; import { AppLockService } from '@/core/AppLockService.js'; import type Logger from '@/logger.js'; import { MetaService } from '@/core/MetaService.js'; -import { AccountMoveService } from '@/core/AccountMoveService.js'; import { IdService } from '@/core/IdService.js'; import { StatusError } from '@/misc/status-error.js'; import { UtilityService } from '@/core/UtilityService.js'; -import { CacheService } from '@/core/CacheService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { QueueService } from '@/core/QueueService.js'; import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; -import type { RemoteUser } from '@/models/entities/User.js'; +import type { MiRemoteUser } from '@/models/entities/User.js'; import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; import { ApNoteService } from './models/ApNoteService.js'; import { ApLoggerService } from './ApLoggerService.js'; @@ -78,15 +81,13 @@ export class ApInboxService { private apNoteService: ApNoteService, private apPersonService: ApPersonService, private apQuestionService: ApQuestionService, - private accountMoveService: AccountMoveService, - private cacheService: CacheService, private queueService: QueueService, ) { this.logger = this.apLoggerService.logger; } @bindThis - public async performActivity(actor: RemoteUser, activity: IObject): Promise { + public async performActivity(actor: MiRemoteUser, activity: IObject): Promise { if (isCollectionOrOrderedCollection(activity)) { const resolver = this.apResolverService.createResolver(); for (const item of toArray(isCollection(activity) ? activity.items : activity.orderedItems)) { @@ -114,7 +115,7 @@ export class ApInboxService { } @bindThis - public async performOneActivity(actor: RemoteUser, activity: IObject): Promise { + public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise { if (actor.isSuspended) return; if (isCreate(activity)) { @@ -151,7 +152,7 @@ export class ApInboxService { } @bindThis - private async follow(actor: RemoteUser, activity: IFollow): Promise { + private async follow(actor: MiRemoteUser, activity: IFollow): Promise { const followee = await this.apDbResolverService.getUserFromApId(activity.object); if (followee == null) { @@ -168,7 +169,7 @@ export class ApInboxService { } @bindThis - private async like(actor: RemoteUser, activity: ILike): Promise { + private async like(actor: MiRemoteUser, activity: ILike): Promise { const targetUri = getApId(activity.object); const note = await this.apNoteService.fetchNote(targetUri); @@ -186,7 +187,7 @@ export class ApInboxService { } @bindThis - private async accept(actor: RemoteUser, activity: IAccept): Promise { + private async accept(actor: MiRemoteUser, activity: IAccept): Promise { const uri = activity.id ?? activity; this.logger.info(`Accept: ${uri}`); @@ -204,7 +205,7 @@ export class ApInboxService { } @bindThis - private async acceptFollow(actor: RemoteUser, activity: IFollow): Promise { + private async acceptFollow(actor: MiRemoteUser, activity: IFollow): Promise { // ※ activityはこっちから投げたフォローリクエストなので、activity.actorは存在するローカルユーザーである必要がある const follower = await this.apDbResolverService.getUserFromApId(activity.actor); @@ -228,7 +229,7 @@ export class ApInboxService { } @bindThis - private async add(actor: RemoteUser, activity: IAdd): Promise { + private async add(actor: MiRemoteUser, activity: IAdd): Promise { if (actor.uri !== activity.actor) { throw new Error('invalid actor'); } @@ -248,7 +249,7 @@ export class ApInboxService { } @bindThis - private async announce(actor: RemoteUser, activity: IAnnounce): Promise { + private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise { const uri = getApId(activity); this.logger.info(`Announce: ${uri}`); @@ -259,7 +260,7 @@ export class ApInboxService { } @bindThis - private async announceNote(actor: RemoteUser, activity: IAnnounce, targetUri: string): Promise { + private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise { const uri = getApId(activity); if (actor.isSuspended) { @@ -319,7 +320,7 @@ export class ApInboxService { } @bindThis - private async block(actor: RemoteUser, activity: IBlock): Promise { + private async block(actor: MiRemoteUser, activity: IBlock): Promise { // ※ activity.objectにブロック対象があり、それは存在するローカルユーザーのはず const blockee = await this.apDbResolverService.getUserFromApId(activity.object); @@ -337,7 +338,7 @@ export class ApInboxService { } @bindThis - private async create(actor: RemoteUser, activity: ICreate): Promise { + private async create(actor: MiRemoteUser, activity: ICreate): Promise { const uri = getApId(activity); this.logger.info(`Create: ${uri}`); @@ -373,7 +374,7 @@ export class ApInboxService { } @bindThis - private async createNote(resolver: Resolver, actor: RemoteUser, note: IObject, silent = false, activity?: ICreate): Promise { + private async createNote(resolver: Resolver, actor: MiRemoteUser, note: IObject, silent = false, activity?: ICreate): Promise { const uri = getApId(note); if (typeof note === 'object') { @@ -408,7 +409,7 @@ export class ApInboxService { } @bindThis - private async delete(actor: RemoteUser, activity: IDelete): Promise { + private async delete(actor: MiRemoteUser, activity: IDelete): Promise { if (actor.uri !== activity.actor) { throw new Error('invalid actor'); } @@ -450,7 +451,7 @@ export class ApInboxService { } @bindThis - private async deleteActor(actor: RemoteUser, uri: string): Promise { + private async deleteActor(actor: MiRemoteUser, uri: string): Promise { this.logger.info(`Deleting the Actor: ${uri}`); if (actor.uri !== uri) { @@ -474,7 +475,7 @@ export class ApInboxService { } @bindThis - private async deleteNote(actor: RemoteUser, uri: string): Promise { + private async deleteNote(actor: MiRemoteUser, uri: string): Promise { this.logger.info(`Deleting the Note: ${uri}`); const unlock = await this.appLockService.getApLock(uri); @@ -498,7 +499,7 @@ export class ApInboxService { } @bindThis - private async flag(actor: RemoteUser, activity: IFlag): Promise { + private async flag(actor: MiRemoteUser, activity: IFlag): Promise { // objectは `(User|Note) | (User|Note)[]` だけど、全パターンDBスキーマと対応させられないので // 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する const uris = getApIds(activity.object); @@ -526,7 +527,7 @@ export class ApInboxService { } @bindThis - private async reject(actor: RemoteUser, activity: IReject): Promise { + private async reject(actor: MiRemoteUser, activity: IReject): Promise { const uri = activity.id ?? activity; this.logger.info(`Reject: ${uri}`); @@ -544,7 +545,7 @@ export class ApInboxService { } @bindThis - private async rejectFollow(actor: RemoteUser, activity: IFollow): Promise { + private async rejectFollow(actor: MiRemoteUser, activity: IFollow): Promise { // ※ activityはこっちから投げたフォローリクエストなので、activity.actorは存在するローカルユーザーである必要がある const follower = await this.apDbResolverService.getUserFromApId(activity.actor); @@ -568,7 +569,7 @@ export class ApInboxService { } @bindThis - private async remove(actor: RemoteUser, activity: IRemove): Promise { + private async remove(actor: MiRemoteUser, activity: IRemove): Promise { if (actor.uri !== activity.actor) { throw new Error('invalid actor'); } @@ -588,7 +589,7 @@ export class ApInboxService { } @bindThis - private async undo(actor: RemoteUser, activity: IUndo): Promise { + private async undo(actor: MiRemoteUser, activity: IUndo): Promise { if (actor.uri !== activity.actor) { throw new Error('invalid actor'); } @@ -615,7 +616,7 @@ export class ApInboxService { } @bindThis - private async undoAccept(actor: RemoteUser, activity: IAccept): Promise { + private async undoAccept(actor: MiRemoteUser, activity: IAccept): Promise { const follower = await this.apDbResolverService.getUserFromApId(activity.object); if (follower == null) { return 'skip: follower not found'; @@ -637,7 +638,7 @@ export class ApInboxService { } @bindThis - private async undoAnnounce(actor: RemoteUser, activity: IAnnounce): Promise { + private async undoAnnounce(actor: MiRemoteUser, activity: IAnnounce): Promise { const uri = getApId(activity); const note = await this.notesRepository.findOneBy({ @@ -652,7 +653,7 @@ export class ApInboxService { } @bindThis - private async undoBlock(actor: RemoteUser, activity: IBlock): Promise { + private async undoBlock(actor: MiRemoteUser, activity: IBlock): Promise { const blockee = await this.apDbResolverService.getUserFromApId(activity.object); if (blockee == null) { @@ -668,7 +669,7 @@ export class ApInboxService { } @bindThis - private async undoFollow(actor: RemoteUser, activity: IFollow): Promise { + private async undoFollow(actor: MiRemoteUser, activity: IFollow): Promise { const followee = await this.apDbResolverService.getUserFromApId(activity.object); if (followee == null) { return 'skip: followee not found'; @@ -706,7 +707,7 @@ export class ApInboxService { } @bindThis - private async undoLike(actor: RemoteUser, activity: ILike): Promise { + private async undoLike(actor: MiRemoteUser, activity: ILike): Promise { const targetUri = getApId(activity.object); const note = await this.apNoteService.fetchNote(targetUri); @@ -721,7 +722,7 @@ export class ApInboxService { } @bindThis - private async update(actor: RemoteUser, activity: IUpdate): Promise { + private async update(actor: MiRemoteUser, activity: IUpdate): Promise { if (actor.uri !== activity.actor) { return 'skip: invalid actor'; } @@ -747,7 +748,7 @@ export class ApInboxService { } @bindThis - private async move(actor: RemoteUser, activity: IMove): Promise { + private async move(actor: MiRemoteUser, activity: IMove): Promise { // fetch the new and old accounts const targetUri = getApHrefNullable(activity.target); if (!targetUri) return 'skip: invalid activity target'; diff --git a/packages/backend/src/core/activitypub/ApLoggerService.ts b/packages/backend/src/core/activitypub/ApLoggerService.ts index eeffab1b6d..cd9597e423 100644 --- a/packages/backend/src/core/activitypub/ApLoggerService.ts +++ b/packages/backend/src/core/activitypub/ApLoggerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import { RemoteLoggerService } from '@/core/RemoteLoggerService.js'; diff --git a/packages/backend/src/core/activitypub/ApMfmService.ts b/packages/backend/src/core/activitypub/ApMfmService.ts index d7269eca92..5dd4b7f6df 100644 --- a/packages/backend/src/core/activitypub/ApMfmService.ts +++ b/packages/backend/src/core/activitypub/ApMfmService.ts @@ -1,9 +1,12 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import * as mfm from 'mfm-js'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; import { MfmService } from '@/core/MfmService.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { bindThis } from '@/decorators.js'; import { extractApHashtagObjects } from './models/tag.js'; import type { IObject } from './type.js'; @@ -11,9 +14,6 @@ import type { IObject } from './type.js'; @Injectable() export class ApMfmService { constructor( - @Inject(DI.config) - private config: Config, - private mfmService: MfmService, ) { } @@ -25,7 +25,7 @@ export class ApMfmService { } @bindThis - public getNoteHtml(note: Note): string | null { + public getNoteHtml(note: MiNote): string | null { if (!note.text) return ''; return this.mfmService.toHtml(mfm.parse(note.text), JSON.parse(note.mentionedRemoteUsers)); } diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 797c6267b1..f345494edb 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -1,24 +1,29 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { createPublicKey, randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; import * as mfm from 'mfm-js'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; -import type { PartialLocalUser, LocalUser, PartialRemoteUser, RemoteUser, User } from '@/models/entities/User.js'; -import type { IMentionedRemoteUsers, Note } from '@/models/entities/Note.js'; -import type { Blocking } from '@/models/entities/Blocking.js'; -import type { Relay } from '@/models/entities/Relay.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { NoteReaction } from '@/models/entities/NoteReaction.js'; -import type { Emoji } from '@/models/entities/Emoji.js'; -import type { Poll } from '@/models/entities/Poll.js'; -import type { PollVote } from '@/models/entities/PollVote.js'; +import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js'; +import type { IMentionedRemoteUsers, MiNote } from '@/models/entities/Note.js'; +import type { MiBlocking } from '@/models/entities/Blocking.js'; +import type { MiRelay } from '@/models/entities/Relay.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiNoteReaction } from '@/models/entities/NoteReaction.js'; +import type { MiEmoji } from '@/models/entities/Emoji.js'; +import type { MiPoll } from '@/models/entities/Poll.js'; +import type { MiPollVote } from '@/models/entities/PollVote.js'; import { UserKeypairService } from '@/core/UserKeypairService.js'; import { MfmService } from '@/core/MfmService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; -import type { UserKeypair } from '@/models/entities/UserKeypair.js'; -import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, EmojisRepository, PollsRepository } from '@/models/index.js'; +import type { MiUserKeypair } from '@/models/entities/UserKeypair.js'; +import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, PollsRepository } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { isNotNull } from '@/misc/is-not-null.js'; @@ -44,9 +49,6 @@ export class ApRendererService { @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, - @Inject(DI.emojisRepository) - private emojisRepository: EmojisRepository, - @Inject(DI.pollsRepository) private pollsRepository: PollsRepository, @@ -61,7 +63,7 @@ export class ApRendererService { } @bindThis - public renderAccept(object: string | IObject, user: { id: User['id']; host: null }): IAccept { + public renderAccept(object: string | IObject, user: { id: MiUser['id']; host: null }): IAccept { return { type: 'Accept', actor: this.userEntityService.genLocalUserUri(user.id), @@ -70,7 +72,7 @@ export class ApRendererService { } @bindThis - public renderAdd(user: LocalUser, target: string | IObject | undefined, object: string | IObject): IAdd { + public renderAdd(user: MiLocalUser, target: string | IObject | undefined, object: string | IObject): IAdd { return { type: 'Add', actor: this.userEntityService.genLocalUserUri(user.id), @@ -80,7 +82,7 @@ export class ApRendererService { } @bindThis - public renderAnnounce(object: string | IObject, note: Note): IAnnounce { + public renderAnnounce(object: string | IObject, note: MiNote): IAnnounce { const attributedTo = this.userEntityService.genLocalUserUri(note.userId); let to: string[] = []; @@ -116,7 +118,7 @@ export class ApRendererService { * @param block The block to be rendered. The blockee relation must be loaded. */ @bindThis - public renderBlock(block: Blocking): IBlock { + public renderBlock(block: MiBlocking): IBlock { if (block.blockee?.uri == null) { throw new Error('renderBlock: missing blockee uri'); } @@ -130,7 +132,7 @@ export class ApRendererService { } @bindThis - public renderCreate(object: IObject, note: Note): ICreate { + public renderCreate(object: IObject, note: MiNote): ICreate { const activity: ICreate = { id: `${this.config.url}/notes/${note.id}/activity`, actor: this.userEntityService.genLocalUserUri(note.userId), @@ -146,7 +148,7 @@ export class ApRendererService { } @bindThis - public renderDelete(object: IObject | string, user: { id: User['id']; host: null }): IDelete { + public renderDelete(object: IObject | string, user: { id: MiUser['id']; host: null }): IDelete { return { type: 'Delete', actor: this.userEntityService.genLocalUserUri(user.id), @@ -156,7 +158,7 @@ export class ApRendererService { } @bindThis - public renderDocument(file: DriveFile): IApDocument { + public renderDocument(file: MiDriveFile): IApDocument { return { type: 'Document', mediaType: file.webpublicType ?? file.type, @@ -166,7 +168,7 @@ export class ApRendererService { } @bindThis - public renderEmoji(emoji: Emoji): IApEmoji { + public renderEmoji(emoji: MiEmoji): IApEmoji { return { id: `${this.config.url}/emojis/${emoji.name}`, type: 'Emoji', @@ -183,7 +185,7 @@ export class ApRendererService { // to anonymise reporters, the reporting actor must be a system user @bindThis - public renderFlag(user: LocalUser, object: IObject | string, content: string): IFlag { + public renderFlag(user: MiLocalUser, object: IObject | string, content: string): IFlag { return { type: 'Flag', actor: this.userEntityService.genLocalUserUri(user.id), @@ -193,7 +195,7 @@ export class ApRendererService { } @bindThis - public renderFollowRelay(relay: Relay, relayActor: LocalUser): IFollow { + public renderFollowRelay(relay: MiRelay, relayActor: MiLocalUser): IFollow { return { id: `${this.config.url}/activities/follow-relay/${relay.id}`, type: 'Follow', @@ -207,15 +209,15 @@ export class ApRendererService { * @param id Follower|Followee ID */ @bindThis - public async renderFollowUser(id: User['id']): Promise { - const user = await this.usersRepository.findOneByOrFail({ id: id }) as PartialLocalUser | PartialRemoteUser; + public async renderFollowUser(id: MiUser['id']): Promise { + const user = await this.usersRepository.findOneByOrFail({ id: id }) as MiPartialLocalUser | MiPartialRemoteUser; return this.userEntityService.getUserUri(user); } @bindThis public renderFollow( - follower: PartialLocalUser | PartialRemoteUser, - followee: PartialLocalUser | PartialRemoteUser, + follower: MiPartialLocalUser | MiPartialRemoteUser, + followee: MiPartialLocalUser | MiPartialRemoteUser, requestId?: string, ): IFollow { return { @@ -236,7 +238,7 @@ export class ApRendererService { } @bindThis - public renderImage(file: DriveFile): IApImage { + public renderImage(file: MiDriveFile): IApImage { return { type: 'Image', url: this.driveFileEntityService.getPublicUrl(file), @@ -246,7 +248,7 @@ export class ApRendererService { } @bindThis - public renderKey(user: LocalUser, key: UserKeypair, postfix?: string): IKey { + public renderKey(user: MiLocalUser, key: MiUserKeypair, postfix?: string): IKey { return { id: `${this.config.url}/users/${user.id}${postfix ?? '/publickey'}`, type: 'Key', @@ -259,7 +261,7 @@ export class ApRendererService { } @bindThis - public async renderLike(noteReaction: NoteReaction, note: { uri: string | null }): Promise { + public async renderLike(noteReaction: MiNoteReaction, note: { uri: string | null }): Promise { const reaction = noteReaction.reaction; const object: ILike = { @@ -282,18 +284,18 @@ export class ApRendererService { } @bindThis - public renderMention(mention: PartialLocalUser | PartialRemoteUser): IApMention { + public renderMention(mention: MiPartialLocalUser | MiPartialRemoteUser): IApMention { return { type: 'Mention', href: this.userEntityService.getUserUri(mention), - name: this.userEntityService.isRemoteUser(mention) ? `@${mention.username}@${mention.host}` : `@${(mention as LocalUser).username}`, + name: this.userEntityService.isRemoteUser(mention) ? `@${mention.username}@${mention.host}` : `@${(mention as MiLocalUser).username}`, }; } @bindThis public renderMove( - src: PartialLocalUser | PartialRemoteUser, - dst: PartialLocalUser | PartialRemoteUser, + src: MiPartialLocalUser | MiPartialRemoteUser, + dst: MiPartialLocalUser | MiPartialRemoteUser, ): IMove { const actor = this.userEntityService.getUserUri(src); const target = this.userEntityService.getUserUri(dst); @@ -307,15 +309,15 @@ export class ApRendererService { } @bindThis - public async renderNote(note: Note, dive = true): Promise { - const getPromisedFiles = async (ids: string[]): Promise => { + public async renderNote(note: MiNote, dive = true): Promise { + const getPromisedFiles = async (ids: string[]): Promise => { if (ids.length === 0) return []; const items = await this.driveFilesRepository.findBy({ id: In(ids) }); - return ids.map(id => items.find(item => item.id === id)).filter((item): item is DriveFile => item != null); + return ids.map(id => items.find(item => item.id === id)).filter((item): item is MiDriveFile => item != null); }; let inReplyTo; - let inReplyToNote: Note | null; + let inReplyToNote: MiNote | null; if (note.replyId) { inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId }); @@ -374,12 +376,12 @@ export class ApRendererService { }) : []; const hashtagTags = note.tags.map(tag => this.renderHashtag(tag)); - const mentionTags = mentionedUsers.map(u => this.renderMention(u as LocalUser | RemoteUser)); + const mentionTags = mentionedUsers.map(u => this.renderMention(u as MiLocalUser | MiRemoteUser)); const files = await getPromisedFiles(note.fileIds); const text = note.text ?? ''; - let poll: Poll | null = null; + let poll: MiPoll | null = null; if (note.hasPoll) { poll = await this.pollsRepository.findOneBy({ noteId: note.id }); @@ -447,7 +449,7 @@ export class ApRendererService { } @bindThis - public async renderPerson(user: LocalUser) { + public async renderPerson(user: MiLocalUser) { const id = this.userEntityService.genLocalUserUri(user.id); const isSystem = user.username.includes('.'); @@ -521,7 +523,7 @@ export class ApRendererService { } @bindThis - public renderQuestion(user: { id: User['id'] }, note: Note, poll: Poll): IQuestion { + public renderQuestion(user: { id: MiUser['id'] }, note: MiNote, poll: MiPoll): IQuestion { return { type: 'Question', id: `${this.config.url}/questions/${note.id}`, @@ -539,7 +541,7 @@ export class ApRendererService { } @bindThis - public renderReject(object: string | IObject, user: { id: User['id'] }): IReject { + public renderReject(object: string | IObject, user: { id: MiUser['id'] }): IReject { return { type: 'Reject', actor: this.userEntityService.genLocalUserUri(user.id), @@ -548,7 +550,7 @@ export class ApRendererService { } @bindThis - public renderRemove(user: { id: User['id'] }, target: string | IObject | undefined, object: string | IObject): IRemove { + public renderRemove(user: { id: MiUser['id'] }, target: string | IObject | undefined, object: string | IObject): IRemove { return { type: 'Remove', actor: this.userEntityService.genLocalUserUri(user.id), @@ -566,7 +568,7 @@ export class ApRendererService { } @bindThis - public renderUndo(object: string | IObject, user: { id: User['id'] }): IUndo { + public renderUndo(object: string | IObject, user: { id: MiUser['id'] }): IUndo { const id = typeof object !== 'string' && typeof object.id === 'string' && object.id.startsWith(this.config.url) ? `${object.id}/undo` : undefined; return { @@ -579,7 +581,7 @@ export class ApRendererService { } @bindThis - public renderUpdate(object: string | IObject, user: { id: User['id'] }): IUpdate { + public renderUpdate(object: string | IObject, user: { id: MiUser['id'] }): IUpdate { return { id: `${this.config.url}/users/${user.id}#updates/${new Date().getTime()}`, actor: this.userEntityService.genLocalUserUri(user.id), @@ -591,7 +593,7 @@ export class ApRendererService { } @bindThis - public renderVote(user: { id: User['id'] }, vote: PollVote, note: Note, poll: Poll, pollOwner: RemoteUser): ICreate { + public renderVote(user: { id: MiUser['id'] }, vote: MiPollVote, note: MiNote, poll: MiPoll, pollOwner: MiRemoteUser): ICreate { return { id: `${this.config.url}/users/${user.id}#votes/${vote.id}/activity`, actor: this.userEntityService.genLocalUserUri(user.id), @@ -649,7 +651,7 @@ export class ApRendererService { } @bindThis - public async attachLdSignature(activity: any, user: { id: User['id']; host: null; }): Promise { + public async attachLdSignature(activity: any, user: { id: MiUser['id']; host: null; }): Promise { const keypair = await this.userKeypairService.getUserKeypair(user.id); const ldSignature = this.ldSignatureService.use(); @@ -708,7 +710,7 @@ export class ApRendererService { } @bindThis - private async getEmojis(names: string[]): Promise { + private async getEmojis(names: string[]): Promise { if (names.length === 0) return []; const allEmojis = await this.customEmojiService.localEmojisCache.fetch(); diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts index 44676cac20..fb44a55de2 100644 --- a/packages/backend/src/core/activitypub/ApRequestService.ts +++ b/packages/backend/src/core/activitypub/ApRequestService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as crypto from 'node:crypto'; import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { UserKeypairService } from '@/core/UserKeypairService.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; import { LoggerService } from '@/core/LoggerService.js'; @@ -140,7 +145,7 @@ export class ApRequestService { } @bindThis - public async signedPost(user: { id: User['id'] }, url: string, object: unknown): Promise { + public async signedPost(user: { id: MiUser['id'] }, url: string, object: unknown): Promise { const body = JSON.stringify(object); const keypair = await this.userKeypairService.getUserKeypair(user.id); @@ -169,7 +174,7 @@ export class ApRequestService { * @param url URL to fetch */ @bindThis - public async signedGet(url: string, user: { id: User['id'] }): Promise { + public async signedGet(url: string, user: { id: MiUser['id'] }): Promise { const keypair = await this.userKeypairService.getUserKeypair(user.id); const req = ApRequestCreator.createSignedGet({ diff --git a/packages/backend/src/core/activitypub/ApResolverService.ts b/packages/backend/src/core/activitypub/ApResolverService.ts index aa4720c56e..34913fabe8 100644 --- a/packages/backend/src/core/activitypub/ApResolverService.ts +++ b/packages/backend/src/core/activitypub/ApResolverService.ts @@ -1,5 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { LocalUser, RemoteUser } from '@/models/entities/User.js'; +import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; import { InstanceActorService } from '@/core/InstanceActorService.js'; import type { NotesRepository, PollsRepository, NoteReactionsRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; @@ -18,7 +23,7 @@ import type { IObject, ICollection, IOrderedCollection } from './type.js'; export class Resolver { private history: Set; - private user?: LocalUser; + private user?: MiLocalUser; private logger: Logger; constructor( @@ -129,7 +134,7 @@ export class Resolver { }); case 'users': return this.usersRepository.findOneByOrFail({ id: parsed.id }) - .then(user => this.apRendererService.renderPerson(user as LocalUser)); + .then(user => this.apRendererService.renderPerson(user as MiLocalUser)); case 'questions': // Polls are indexed by the note they are attached to. return Promise.all([ @@ -147,7 +152,7 @@ export class Resolver { return Promise.all( [parsed.id, parsed.rest].map(id => this.usersRepository.findOneByOrFail({ id })), ) - .then(([follower, followee]) => this.apRendererService.addContext(this.apRendererService.renderFollow(follower as LocalUser | RemoteUser, followee as LocalUser | RemoteUser, url))); + .then(([follower, followee]) => this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiLocalUser | MiRemoteUser, followee as MiLocalUser | MiRemoteUser, url))); default: throw new Error(`resolveLocal: type ${parsed.type} unhandled`); } diff --git a/packages/backend/src/core/activitypub/LdSignatureService.ts b/packages/backend/src/core/activitypub/LdSignatureService.ts index af7e243229..39b5ff8abc 100644 --- a/packages/backend/src/core/activitypub/LdSignatureService.ts +++ b/packages/backend/src/core/activitypub/LdSignatureService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as crypto from 'node:crypto'; import { Injectable } from '@nestjs/common'; import { HttpRequestService } from '@/core/HttpRequestService.js'; diff --git a/packages/backend/src/core/activitypub/misc/contexts.ts b/packages/backend/src/core/activitypub/misc/contexts.ts index 2bcd3811b2..71c440e5cc 100644 --- a/packages/backend/src/core/activitypub/misc/contexts.ts +++ b/packages/backend/src/core/activitypub/misc/contexts.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { JsonLd } from 'jsonld/jsonld-spec.js'; /* eslint:disable:quotemark indent */ diff --git a/packages/backend/src/core/activitypub/models/ApImageService.ts b/packages/backend/src/core/activitypub/models/ApImageService.ts index 1f2984894c..fa17a778bf 100644 --- a/packages/backend/src/core/activitypub/models/ApImageService.ts +++ b/packages/backend/src/core/activitypub/models/ApImageService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { DriveFilesRepository } from '@/models/index.js'; -import type { RemoteUser } from '@/models/entities/User.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiRemoteUser } from '@/models/entities/User.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { MetaService } from '@/core/MetaService.js'; import { truncate } from '@/misc/truncate.js'; import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/const.js'; @@ -34,7 +39,7 @@ export class ApImageService { * Imageを作成します。 */ @bindThis - public async createImage(actor: RemoteUser, value: string | IObject): Promise { + public async createImage(actor: MiRemoteUser, value: string | IObject): Promise { // 投稿者が凍結されていたらスキップ if (actor.isSuspended) { throw new Error('actor has been suspended'); @@ -85,7 +90,7 @@ export class ApImageService { * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 */ @bindThis - public async resolveImage(actor: RemoteUser, value: string | IObject): Promise { + public async resolveImage(actor: MiRemoteUser, value: string | IObject): Promise { // TODO // リモートサーバーからフェッチしてきて登録 diff --git a/packages/backend/src/core/activitypub/models/ApMentionService.ts b/packages/backend/src/core/activitypub/models/ApMentionService.ts index 62ae3cf93d..f4045301de 100644 --- a/packages/backend/src/core/activitypub/models/ApMentionService.ts +++ b/packages/backend/src/core/activitypub/models/ApMentionService.ts @@ -1,34 +1,33 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import promiseLimit from 'promise-limit'; -import { DI } from '@/di-symbols.js'; -import type { User } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { MiUser } from '@/models/index.js'; import { toArray, unique } from '@/misc/prelude/array.js'; import { bindThis } from '@/decorators.js'; import { isMention } from '../type.js'; -import { ApResolverService, Resolver } from '../ApResolverService.js'; +import { Resolver } from '../ApResolverService.js'; import { ApPersonService } from './ApPersonService.js'; import type { IObject, IApMention } from '../type.js'; @Injectable() export class ApMentionService { constructor( - @Inject(DI.config) - private config: Config, - - private apResolverService: ApResolverService, private apPersonService: ApPersonService, ) { } @bindThis - public async extractApMentions(tags: IObject | IObject[] | null | undefined, resolver: Resolver): Promise { + public async extractApMentions(tags: IObject | IObject[] | null | undefined, resolver: Resolver): Promise { const hrefs = unique(this.extractApMentionObjects(tags).map(x => x.href)); - const limit = promiseLimit(2); + const limit = promiseLimit(2); const mentionedUsers = (await Promise.all( hrefs.map(x => limit(() => this.apPersonService.resolvePerson(x, resolver).catch(() => null))), - )).filter((x): x is User => x != null); + )).filter((x): x is MiUser => x != null); return mentionedUsers; } diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts index 46ed976a6b..6a9c69696f 100644 --- a/packages/backend/src/core/activitypub/models/ApNoteService.ts +++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts @@ -1,16 +1,21 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { forwardRef, Inject, Injectable } from '@nestjs/common'; import promiseLimit from 'promise-limit'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { PollsRepository, EmojisRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; -import type { RemoteUser } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiRemoteUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { toArray, toSingle, unique } from '@/misc/prelude/array.js'; -import type { Emoji } from '@/models/entities/Emoji.js'; +import type { MiEmoji } from '@/models/entities/Emoji.js'; import { MetaService } from '@/core/MetaService.js'; import { AppLockService } from '@/core/AppLockService.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { NoteCreateService } from '@/core/NoteCreateService.js'; import type Logger from '@/logger.js'; import { IdService } from '@/core/IdService.js'; @@ -96,7 +101,7 @@ export class ApNoteService { * Misskeyに対象のNoteが登録されていればそれを返します。 */ @bindThis - public async fetchNote(object: string | IObject): Promise { + public async fetchNote(object: string | IObject): Promise { return await this.apDbResolverService.getNoteFromApId(object); } @@ -104,7 +109,7 @@ export class ApNoteService { * Noteを作成します。 */ @bindThis - public async createNote(value: string | IObject, resolver?: Resolver, silent = false): Promise { + public async createNote(value: string | IObject, resolver?: Resolver, silent = false): Promise { // eslint-disable-next-line no-param-reassign if (resolver == null) resolver = this.apResolverService.createResolver(); @@ -126,13 +131,13 @@ export class ApNoteService { this.logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); if (note.id && !checkHttps(note.id)) { - throw new Error('unexpected shcema of note.id: ' + note.id); + throw new Error('unexpected schema of note.id: ' + note.id); } const url = getOneApHrefNullable(note.url); if (url && !checkHttps(url)) { - throw new Error('unexpected shcema of note url: ' + url); + throw new Error('unexpected schema of note url: ' + url); } this.logger.info(`Creating the Note: ${note.id}`); @@ -142,7 +147,7 @@ export class ApNoteService { throw new Error('invalid note.attributedTo: ' + note.attributedTo); } - const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo), resolver) as RemoteUser; + const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo), resolver) as MiRemoteUser; // 投稿者が凍結されていたらスキップ if (actor.isSuspended) { @@ -167,7 +172,7 @@ export class ApNoteService { // 添付ファイル // TODO: attachmentは必ずしもImageではない // TODO: attachmentは必ずしも配列ではない - const limit = promiseLimit(2); + const limit = promiseLimit(2); const files = (await Promise.all(toArray(note.attachment).map(attach => ( limit(() => this.apImageService.resolveImage(actor, { ...attach, @@ -176,7 +181,7 @@ export class ApNoteService { )))); // リプライ - const reply: Note | null = note.inReplyTo + const reply: MiNote | null = note.inReplyTo ? await this.resolveNote(note.inReplyTo, { resolver }) .then(x => { if (x == null) { @@ -193,11 +198,11 @@ export class ApNoteService { : null; // 引用 - let quote: Note | undefined | null = null; + let quote: MiNote | undefined | null = null; - if (note._misskey_quote || note.quoteUrl) { + if (note._misskey_quote ?? note.quoteUrl) { const tryResolveNote = async (uri: string): Promise< - | { status: 'ok'; res: Note } + | { status: 'ok'; res: MiNote } | { status: 'permerror' | 'temperror' } > => { if (!/^https?:/.test(uri)) return { status: 'permerror' }; @@ -215,7 +220,7 @@ export class ApNoteService { const uris = unique([note._misskey_quote, note.quoteUrl].filter((x): x is string => typeof x === 'string')); const results = await Promise.all(uris.map(tryResolveNote)); - quote = results.filter((x): x is { status: 'ok', res: Note } => x.status === 'ok').map(x => x.res).at(0); + quote = results.filter((x): x is { status: 'ok', res: MiNote } => x.status === 'ok').map(x => x.res).at(0); if (!quote) { if (results.some(x => x.status === 'temperror')) { throw new Error('quote resolve failed'); @@ -266,24 +271,36 @@ export class ApNoteService { const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined); - return await this.noteCreateService.create(actor, { - createdAt: note.published ? new Date(note.published) : null, - files, - reply, - renote: quote, - name: note.name, - cw, - text, - localOnly: false, - visibility, - visibleUsers, - apMentions, - apHashtags, - apEmojis, - poll, - uri: note.id, - url: url, - }, silent); + try { + return await this.noteCreateService.create(actor, { + createdAt: note.published ? new Date(note.published) : null, + files, + reply, + renote: quote, + name: note.name, + cw, + text, + localOnly: false, + visibility, + visibleUsers, + apMentions, + apHashtags, + apEmojis, + poll, + uri: note.id, + url: url, + }, silent); + } catch (err: any) { + if (err.name !== 'duplicated') { + throw err; + } + this.logger.info('The note is already inserted while creating itself, reading again'); + const duplicate = await this.fetchNote(value); + if (!duplicate) { + throw new Error('The note creation failed with duplication error even when there is no duplication'); + } + return duplicate; + } } /** @@ -293,7 +310,7 @@ export class ApNoteService { * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 */ @bindThis - public async resolveNote(value: string | IObject, options: { sentFrom?: URL, resolver?: Resolver } = {}): Promise { + public async resolveNote(value: string | IObject, options: { sentFrom?: URL, resolver?: Resolver } = {}): Promise { const uri = getApId(value); // ブロックしていたら中断 @@ -325,7 +342,7 @@ export class ApNoteService { } @bindThis - public async extractEmojis(tags: IObject | IObject[], host: string): Promise { + public async extractEmojis(tags: IObject | IObject[], host: string): Promise { // eslint-disable-next-line no-param-reassign host = this.utilityService.toPuny(host); diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index 8fc083719d..ff0133993f 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import promiseLimit from 'promise-limit'; import { DataSource } from 'typeorm'; @@ -5,26 +10,26 @@ import { ModuleRef } from '@nestjs/core'; import { DI } from '@/di-symbols.js'; import type { FollowingsRepository, InstancesRepository, UserProfilesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; -import type { LocalUser, RemoteUser } from '@/models/entities/User.js'; -import { User } from '@/models/entities/User.js'; +import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; +import { MiUser } from '@/models/entities/User.js'; import { truncate } from '@/misc/truncate.js'; import type { CacheService } from '@/core/CacheService.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js'; import type Logger from '@/logger.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import type { IdService } from '@/core/IdService.js'; import type { MfmService } from '@/core/MfmService.js'; import { toArray } from '@/misc/prelude/array.js'; import type { GlobalEventService } from '@/core/GlobalEventService.js'; import type { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import type { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; -import { UserProfile } from '@/models/entities/UserProfile.js'; -import { UserPublickey } from '@/models/entities/UserPublickey.js'; +import { MiUserProfile } from '@/models/entities/UserProfile.js'; +import { MiUserPublickey } from '@/models/entities/UserPublickey.js'; import type UsersChart from '@/core/chart/charts/users.js'; import type InstanceChart from '@/core/chart/charts/instance.js'; import type { HashtagService } from '@/core/HashtagService.js'; -import { UserNotePining } from '@/models/entities/UserNotePining.js'; +import { MiUserNotePining } from '@/models/entities/UserNotePining.js'; import { StatusError } from '@/misc/status-error.js'; import type { UtilityService } from '@/core/UtilityService.js'; import type { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -196,20 +201,20 @@ export class ApPersonService implements OnModuleInit { * Misskeyに対象のPersonが登録されていればそれを返し、登録がなければnullを返します。 */ @bindThis - public async fetchPerson(uri: string): Promise { - const cached = this.cacheService.uriPersonCache.get(uri) as LocalUser | RemoteUser | null | undefined; + public async fetchPerson(uri: string): Promise { + const cached = this.cacheService.uriPersonCache.get(uri) as MiLocalUser | MiRemoteUser | null | undefined; if (cached) return cached; // URIがこのサーバーを指しているならデータベースからフェッチ if (uri.startsWith(`${this.config.url}/`)) { const id = uri.split('/').pop(); - const u = await this.usersRepository.findOneBy({ id }) as LocalUser | null; + const u = await this.usersRepository.findOneBy({ id }) as MiLocalUser | null; if (u) this.cacheService.uriPersonCache.set(uri, u); return u; } //#region このサーバーに既に登録されていたらそれを返す - const exist = await this.usersRepository.findOneBy({ uri }) as LocalUser | RemoteUser | null; + const exist = await this.usersRepository.findOneBy({ uri }) as MiLocalUser | MiRemoteUser | null; if (exist) { this.cacheService.uriPersonCache.set(uri, exist); @@ -220,7 +225,7 @@ export class ApPersonService implements OnModuleInit { return null; } - private async resolveAvatarAndBanner(user: RemoteUser, icon: any, image: any): Promise> { + private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any): Promise> { const [avatar, banner] = await Promise.all([icon, image].map(img => { if (img == null) return null; if (user == null) throw new Error('failed to create user: user is null'); @@ -241,7 +246,7 @@ export class ApPersonService implements OnModuleInit { * Personを作成します。 */ @bindThis - public async createPerson(uri: string, resolver?: Resolver): Promise { + public async createPerson(uri: string, resolver?: Resolver): Promise { if (typeof uri !== 'string') throw new Error('uri is not string'); if (uri.startsWith(this.config.url)) { @@ -275,13 +280,13 @@ export class ApPersonService implements OnModuleInit { } // Create user - let user: RemoteUser | null = null; + let user: MiRemoteUser | null = null; //#region カスタム絵文字取得 const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host) .then(_emojis => _emojis.map(emoji => emoji.name)) .catch(err => { - this.logger.error(`error occured while fetching user emojis`, { stack: err }); + this.logger.error('error occurred while fetching user emojis', { stack: err }); return []; }); //#endregion @@ -289,7 +294,7 @@ export class ApPersonService implements OnModuleInit { try { // Start transaction await this.db.transaction(async transactionalEntityManager => { - user = await transactionalEntityManager.save(new User({ + user = await transactionalEntityManager.save(new MiUser({ id: this.idService.genId(), avatarId: null, bannerId: null, @@ -313,9 +318,9 @@ export class ApPersonService implements OnModuleInit { isBot, isCat: (person as any).isCat === true, emojis, - })) as RemoteUser; + })) as MiRemoteUser; - await transactionalEntityManager.save(new UserProfile({ + await transactionalEntityManager.save(new MiUserProfile({ userId: user.id, description: person.summary ? this.apMfmService.htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, url, @@ -326,7 +331,7 @@ export class ApPersonService implements OnModuleInit { })); if (person.publicKey) { - await transactionalEntityManager.save(new UserPublickey({ + await transactionalEntityManager.save(new MiUserPublickey({ userId: user.id, keyId: person.publicKey.id, keyPem: person.publicKey.publicKeyPem, @@ -340,7 +345,7 @@ export class ApPersonService implements OnModuleInit { const u = await this.usersRepository.findOneBy({ uri: person.id }); if (u == null) throw new Error('already registered'); - user = u as RemoteUser; + user = u as MiRemoteUser; } else { this.logger.error(e instanceof Error ? e : new Error(e as string)); throw e; @@ -375,7 +380,7 @@ export class ApPersonService implements OnModuleInit { // Register to the cache this.cacheService.uriPersonCache.set(user.uri, user); } catch (err) { - this.logger.error('error occured while fetching user avatar/banner', { stack: err }); + this.logger.error('error occurred while fetching user avatar/banner', { stack: err }); } //#endregion @@ -402,7 +407,7 @@ export class ApPersonService implements OnModuleInit { if (uri.startsWith(`${this.config.url}/`)) return; //#region このサーバーに既に登録されているか - const exist = await this.fetchPerson(uri) as RemoteUser | null; + const exist = await this.fetchPerson(uri) as MiRemoteUser | null; if (exist === null) return; //#endregion @@ -451,7 +456,7 @@ export class ApPersonService implements OnModuleInit { alsoKnownAs: person.alsoKnownAs ?? null, isExplorable: person.discoverable, ...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))), - } as Partial & Pick; + } as Partial & Pick; const moving = ((): boolean => { // 移行先がない→ある @@ -537,7 +542,7 @@ export class ApPersonService implements OnModuleInit { * リモートサーバーからフェッチしてMisskeyに登録しそれを返します。 */ @bindThis - public async resolvePerson(uri: string, resolver?: Resolver): Promise { + public async resolvePerson(uri: string, resolver?: Resolver): Promise { //#region このサーバーに既に登録されていたらそれを返す const exist = await this.fetchPerson(uri); if (exist) return exist; @@ -567,7 +572,7 @@ export class ApPersonService implements OnModuleInit { } @bindThis - public async updateFeatured(userId: User['id'], resolver?: Resolver): Promise { + public async updateFeatured(userId: MiUser['id'], resolver?: Resolver): Promise { const user = await this.usersRepository.findOneByOrFail({ id: userId }); if (!this.userEntityService.isRemoteUser(user)) return; if (!user.featured) return; @@ -585,7 +590,7 @@ export class ApPersonService implements OnModuleInit { const items = await Promise.all(toArray(unresolvedItems).map(x => _resolver.resolve(x))); // Resolve and regist Notes - const limit = promiseLimit(2); + const limit = promiseLimit(2); const featuredNotes = await Promise.all(items .filter(item => getApType(item) === 'Note') // TODO: Noteでなくてもいいかも .slice(0, 5) @@ -595,13 +600,13 @@ export class ApPersonService implements OnModuleInit { })))); await this.db.transaction(async transactionalEntityManager => { - await transactionalEntityManager.delete(UserNotePining, { userId: user.id }); + await transactionalEntityManager.delete(MiUserNotePining, { userId: user.id }); // とりあえずidを別の時間で生成して順番を維持 let td = 0; - for (const note of featuredNotes.filter((note): note is Note => note != null)) { + for (const note of featuredNotes.filter((note): note is MiNote => note != null)) { td -= 1000; - transactionalEntityManager.insert(UserNotePining, { + transactionalEntityManager.insert(MiUserNotePining, { id: this.idService.genId(new Date(Date.now() + td)), createdAt: new Date(), userId: user.id, @@ -617,7 +622,7 @@ export class ApPersonService implements OnModuleInit { * @param movePreventUris ここに列挙されたURIにsrc.movedToUriが含まれる場合、移行処理はしない(無限ループ防止) */ @bindThis - private async processRemoteMove(src: RemoteUser, movePreventUris: string[] = []): Promise { + private async processRemoteMove(src: MiRemoteUser, movePreventUris: string[] = []): Promise { if (!src.movedToUri) return 'skip: no movedToUri'; if (src.uri === src.movedToUri) return 'skip: movedTo itself (src)'; // ??? if (movePreventUris.length > 10) return 'skip: too many moves'; @@ -627,7 +632,7 @@ export class ApPersonService implements OnModuleInit { if (dst && this.userEntityService.isLocalUser(dst)) { // targetがローカルユーザーだった場合データベースから引っ張ってくる - dst = await this.usersRepository.findOneByOrFail({ uri: src.movedToUri }) as LocalUser; + dst = await this.usersRepository.findOneByOrFail({ uri: src.movedToUri }) as MiLocalUser; } else if (dst) { if (movePreventUris.includes(src.movedToUri)) return 'skip: circular move'; diff --git a/packages/backend/src/core/activitypub/models/ApQuestionService.ts b/packages/backend/src/core/activitypub/models/ApQuestionService.ts index 229a44f90f..8d8c0a5811 100644 --- a/packages/backend/src/core/activitypub/models/ApQuestionService.ts +++ b/packages/backend/src/core/activitypub/models/ApQuestionService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { NotesRepository, PollsRepository } from '@/models/index.js'; diff --git a/packages/backend/src/core/activitypub/models/icon.ts b/packages/backend/src/core/activitypub/models/icon.ts index 50794a937d..9fed78020d 100644 --- a/packages/backend/src/core/activitypub/models/icon.ts +++ b/packages/backend/src/core/activitypub/models/icon.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export type IIcon = { type: string; mediaType?: string; diff --git a/packages/backend/src/core/activitypub/models/identifier.ts b/packages/backend/src/core/activitypub/models/identifier.ts index f6c3bb8c88..22a7b0a76e 100644 --- a/packages/backend/src/core/activitypub/models/identifier.ts +++ b/packages/backend/src/core/activitypub/models/identifier.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export type IIdentifier = { type: string; name: string; diff --git a/packages/backend/src/core/activitypub/models/tag.ts b/packages/backend/src/core/activitypub/models/tag.ts index 9aeb843562..772ea11864 100644 --- a/packages/backend/src/core/activitypub/models/tag.ts +++ b/packages/backend/src/core/activitypub/models/tag.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { toArray } from '@/misc/prelude/array.js'; import { isHashtag } from '../type.js'; import type { IObject, IApHashtag } from '../type.js'; diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts index 4bb0fa61ec..16ff86e894 100644 --- a/packages/backend/src/core/activitypub/type.ts +++ b/packages/backend/src/core/activitypub/type.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export type Obj = { [x: string]: any }; export type ApObject = IObject | string | (IObject | string)[]; diff --git a/packages/backend/src/core/chart/ChartLoggerService.ts b/packages/backend/src/core/chart/ChartLoggerService.ts index afd3bab5a2..bd90efec64 100644 --- a/packages/backend/src/core/chart/ChartLoggerService.ts +++ b/packages/backend/src/core/chart/ChartLoggerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import { LoggerService } from '@/core/LoggerService.js'; diff --git a/packages/backend/src/core/chart/ChartManagementService.ts b/packages/backend/src/core/chart/ChartManagementService.ts index b0e9e534df..6b626d3980 100644 --- a/packages/backend/src/core/chart/ChartManagementService.ts +++ b/packages/backend/src/core/chart/ChartManagementService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; diff --git a/packages/backend/src/core/chart/charts/active-users.ts b/packages/backend/src/core/chart/charts/active-users.ts index bc0ba25cbb..ff9db46bc2 100644 --- a/packages/backend/src/core/chart/charts/active-users.ts +++ b/packages/backend/src/core/chart/charts/active-users.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { AppLockService } from '@/core/AppLockService.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import Chart from '../core.js'; @@ -16,9 +21,8 @@ const year = 1000 * 60 * 60 * 24 * 365; /** * アクティブユーザーに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class ActiveUsersChart extends Chart { +export default class ActiveUsersChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -38,7 +42,7 @@ export default class ActiveUsersChart extends Chart { } @bindThis - public async read(user: { id: User['id'], host: null, createdAt: User['createdAt'] }): Promise { + public async read(user: { id: MiUser['id'], host: null, createdAt: MiUser['createdAt'] }): Promise { await this.commit({ 'read': [user.id], 'registeredWithinWeek': (Date.now() - user.createdAt.getTime() < week) ? [user.id] : [], @@ -51,7 +55,7 @@ export default class ActiveUsersChart extends Chart { } @bindThis - public async write(user: { id: User['id'], host: null, createdAt: User['createdAt'] }): Promise { + public async write(user: { id: MiUser['id'], host: null, createdAt: MiUser['createdAt'] }): Promise { await this.commit({ 'write': [user.id], }); diff --git a/packages/backend/src/core/chart/charts/ap-request.ts b/packages/backend/src/core/chart/charts/ap-request.ts index ce377460c8..03c9b42be1 100644 --- a/packages/backend/src/core/chart/charts/ap-request.ts +++ b/packages/backend/src/core/chart/charts/ap-request.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { AppLockService } from '@/core/AppLockService.js'; @@ -11,9 +16,8 @@ import type { KVs } from '../core.js'; /** * Chart about ActivityPub requests */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class ApRequestChart extends Chart { +export default class ApRequestChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/core/chart/charts/drive.ts b/packages/backend/src/core/chart/charts/drive.ts index b63db591fb..2fe0f76163 100644 --- a/packages/backend/src/core/chart/charts/drive.ts +++ b/packages/backend/src/core/chart/charts/drive.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @@ -12,9 +17,8 @@ import type { KVs } from '../core.js'; /** * ドライブに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class DriveChart extends Chart { +export default class DriveChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -34,7 +38,7 @@ export default class DriveChart extends Chart { } @bindThis - public async update(file: DriveFile, isAdditional: boolean): Promise { + public async update(file: MiDriveFile, isAdditional: boolean): Promise { const fileSizeKb = file.size / 1000; await this.commit(file.userHost === null ? { 'local.incCount': isAdditional ? 1 : 0, diff --git a/packages/backend/src/core/chart/charts/entities/active-users.ts b/packages/backend/src/core/chart/charts/entities/active-users.ts index e291e37c1b..e68022ef29 100644 --- a/packages/backend/src/core/chart/charts/entities/active-users.ts +++ b/packages/backend/src/core/chart/charts/entities/active-users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'activeUsers'; diff --git a/packages/backend/src/core/chart/charts/entities/ap-request.ts b/packages/backend/src/core/chart/charts/entities/ap-request.ts index 3a9f3dacfd..a824515255 100644 --- a/packages/backend/src/core/chart/charts/entities/ap-request.ts +++ b/packages/backend/src/core/chart/charts/entities/ap-request.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'apRequest'; diff --git a/packages/backend/src/core/chart/charts/entities/drive.ts b/packages/backend/src/core/chart/charts/entities/drive.ts index 4bf5bb729e..4a56bd45c5 100644 --- a/packages/backend/src/core/chart/charts/entities/drive.ts +++ b/packages/backend/src/core/chart/charts/entities/drive.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'drive'; diff --git a/packages/backend/src/core/chart/charts/entities/federation.ts b/packages/backend/src/core/chart/charts/entities/federation.ts index a8466b0b4c..e067c71a7f 100644 --- a/packages/backend/src/core/chart/charts/entities/federation.ts +++ b/packages/backend/src/core/chart/charts/entities/federation.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'federation'; diff --git a/packages/backend/src/core/chart/charts/entities/instance.ts b/packages/backend/src/core/chart/charts/entities/instance.ts index 06962120e2..4ea10d56d1 100644 --- a/packages/backend/src/core/chart/charts/entities/instance.ts +++ b/packages/backend/src/core/chart/charts/entities/instance.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'instance'; diff --git a/packages/backend/src/core/chart/charts/entities/notes.ts b/packages/backend/src/core/chart/charts/entities/notes.ts index 9387dbfb2c..26e2529b17 100644 --- a/packages/backend/src/core/chart/charts/entities/notes.ts +++ b/packages/backend/src/core/chart/charts/entities/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'notes'; diff --git a/packages/backend/src/core/chart/charts/entities/per-user-drive.ts b/packages/backend/src/core/chart/charts/entities/per-user-drive.ts index 6111640ea0..aec3dd5140 100644 --- a/packages/backend/src/core/chart/charts/entities/per-user-drive.ts +++ b/packages/backend/src/core/chart/charts/entities/per-user-drive.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'perUserDrive'; diff --git a/packages/backend/src/core/chart/charts/entities/per-user-following.ts b/packages/backend/src/core/chart/charts/entities/per-user-following.ts index 4118daa474..afb5813058 100644 --- a/packages/backend/src/core/chart/charts/entities/per-user-following.ts +++ b/packages/backend/src/core/chart/charts/entities/per-user-following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'perUserFollowing'; diff --git a/packages/backend/src/core/chart/charts/entities/per-user-notes.ts b/packages/backend/src/core/chart/charts/entities/per-user-notes.ts index c1fa174452..60a0b01c8e 100644 --- a/packages/backend/src/core/chart/charts/entities/per-user-notes.ts +++ b/packages/backend/src/core/chart/charts/entities/per-user-notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'perUserNotes'; diff --git a/packages/backend/src/core/chart/charts/entities/per-user-pv.ts b/packages/backend/src/core/chart/charts/entities/per-user-pv.ts index 64c8ed1fb1..78d4464d7e 100644 --- a/packages/backend/src/core/chart/charts/entities/per-user-pv.ts +++ b/packages/backend/src/core/chart/charts/entities/per-user-pv.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'perUserPv'; diff --git a/packages/backend/src/core/chart/charts/entities/per-user-reactions.ts b/packages/backend/src/core/chart/charts/entities/per-user-reactions.ts index 5e1a6c7b30..761101d479 100644 --- a/packages/backend/src/core/chart/charts/entities/per-user-reactions.ts +++ b/packages/backend/src/core/chart/charts/entities/per-user-reactions.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'perUserReaction'; diff --git a/packages/backend/src/core/chart/charts/entities/test-grouped.ts b/packages/backend/src/core/chart/charts/entities/test-grouped.ts index 66b6e8e864..15eb1fd1f8 100644 --- a/packages/backend/src/core/chart/charts/entities/test-grouped.ts +++ b/packages/backend/src/core/chart/charts/entities/test-grouped.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'testGrouped'; diff --git a/packages/backend/src/core/chart/charts/entities/test-intersection.ts b/packages/backend/src/core/chart/charts/entities/test-intersection.ts index a3bdcb367f..2ef63977a5 100644 --- a/packages/backend/src/core/chart/charts/entities/test-intersection.ts +++ b/packages/backend/src/core/chart/charts/entities/test-intersection.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'testIntersection'; diff --git a/packages/backend/src/core/chart/charts/entities/test-unique.ts b/packages/backend/src/core/chart/charts/entities/test-unique.ts index b2cfb71b05..56233585db 100644 --- a/packages/backend/src/core/chart/charts/entities/test-unique.ts +++ b/packages/backend/src/core/chart/charts/entities/test-unique.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'testUnique'; diff --git a/packages/backend/src/core/chart/charts/entities/test.ts b/packages/backend/src/core/chart/charts/entities/test.ts index 7cba21e16a..163db4e79f 100644 --- a/packages/backend/src/core/chart/charts/entities/test.ts +++ b/packages/backend/src/core/chart/charts/entities/test.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'test'; diff --git a/packages/backend/src/core/chart/charts/entities/users.ts b/packages/backend/src/core/chart/charts/entities/users.ts index c0b83094ae..c7bffd3fd4 100644 --- a/packages/backend/src/core/chart/charts/entities/users.ts +++ b/packages/backend/src/core/chart/charts/entities/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Chart from '../../core.js'; export const name = 'users'; diff --git a/packages/backend/src/core/chart/charts/federation.ts b/packages/backend/src/core/chart/charts/federation.ts index ae4eb6e48d..f7d084d3e2 100644 --- a/packages/backend/src/core/chart/charts/federation.ts +++ b/packages/backend/src/core/chart/charts/federation.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import type { FollowingsRepository, InstancesRepository } from '@/models/index.js'; @@ -13,9 +18,8 @@ import type { KVs } from '../core.js'; /** * フェデレーションに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class FederationChart extends Chart { +export default class FederationChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/core/chart/charts/instance.ts b/packages/backend/src/core/chart/charts/instance.ts index 8ca88d80e3..8dbb132e25 100644 --- a/packages/backend/src/core/chart/charts/instance.ts +++ b/packages/backend/src/core/chart/charts/instance.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import type { DriveFilesRepository, FollowingsRepository, UsersRepository, NotesRepository } from '@/models/index.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { UtilityService } from '@/core/UtilityService.js'; @@ -15,9 +20,8 @@ import type { KVs } from '../core.js'; /** * インスタンスごとのチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class InstanceChart extends Chart { +export default class InstanceChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -93,7 +97,7 @@ export default class InstanceChart extends Chart { } @bindThis - public async updateNote(host: string, note: Note, isAdditional: boolean): Promise { + public async updateNote(host: string, note: MiNote, isAdditional: boolean): Promise { await this.commit({ 'notes.total': isAdditional ? 1 : -1, 'notes.inc': isAdditional ? 1 : 0, @@ -124,7 +128,7 @@ export default class InstanceChart extends Chart { } @bindThis - public async updateDrive(file: DriveFile, isAdditional: boolean): Promise { + public async updateDrive(file: MiDriveFile, isAdditional: boolean): Promise { const fileSizeKb = file.size / 1000; await this.commit({ 'drive.totalFiles': isAdditional ? 1 : -1, diff --git a/packages/backend/src/core/chart/charts/notes.ts b/packages/backend/src/core/chart/charts/notes.ts index 23dc248fec..31dfad224a 100644 --- a/packages/backend/src/core/chart/charts/notes.ts +++ b/packages/backend/src/core/chart/charts/notes.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { Not, IsNull, DataSource } from 'typeorm'; import type { NotesRepository } from '@/models/index.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @@ -13,9 +18,8 @@ import type { KVs } from '../core.js'; /** * ノートに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class NotesChart extends Chart { +export default class NotesChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -46,7 +50,7 @@ export default class NotesChart extends Chart { } @bindThis - public async update(note: Note, isAdditional: boolean): Promise { + public async update(note: MiNote, isAdditional: boolean): Promise { const prefix = note.userHost === null ? 'local' : 'remote'; await this.commit({ diff --git a/packages/backend/src/core/chart/charts/per-user-drive.ts b/packages/backend/src/core/chart/charts/per-user-drive.ts index ffba04b041..be5adc71c8 100644 --- a/packages/backend/src/core/chart/charts/per-user-drive.ts +++ b/packages/backend/src/core/chart/charts/per-user-drive.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import type { DriveFilesRepository } from '@/models/index.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; @@ -14,9 +19,8 @@ import type { KVs } from '../core.js'; /** * ユーザーごとのドライブに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class PerUserDriveChart extends Chart { +export default class PerUserDriveChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -48,7 +52,7 @@ export default class PerUserDriveChart extends Chart { } @bindThis - public async update(file: DriveFile, isAdditional: boolean): Promise { + public async update(file: MiDriveFile, isAdditional: boolean): Promise { const fileSizeKb = file.size / 1000; await this.commit({ 'totalCount': isAdditional ? 1 : -1, diff --git a/packages/backend/src/core/chart/charts/per-user-following.ts b/packages/backend/src/core/chart/charts/per-user-following.ts index aea6d44a9a..7536e1dcb9 100644 --- a/packages/backend/src/core/chart/charts/per-user-following.ts +++ b/packages/backend/src/core/chart/charts/per-user-following.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { Not, IsNull, DataSource } from 'typeorm'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -14,9 +19,8 @@ import type { KVs } from '../core.js'; /** * ユーザーごとのフォローに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class PerUserFollowingChart extends Chart { +export default class PerUserFollowingChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -57,7 +61,7 @@ export default class PerUserFollowingChart extends Chart { } @bindThis - public async update(follower: { id: User['id']; host: User['host']; }, followee: { id: User['id']; host: User['host']; }, isFollow: boolean): Promise { + public async update(follower: { id: MiUser['id']; host: MiUser['host']; }, followee: { id: MiUser['id']; host: MiUser['host']; }, isFollow: boolean): Promise { const prefixFollower = this.userEntityService.isLocalUser(follower) ? 'local' : 'remote'; const prefixFollowee = this.userEntityService.isLocalUser(followee) ? 'local' : 'remote'; diff --git a/packages/backend/src/core/chart/charts/per-user-notes.ts b/packages/backend/src/core/chart/charts/per-user-notes.ts index d8966f34c1..4a6dae769e 100644 --- a/packages/backend/src/core/chart/charts/per-user-notes.ts +++ b/packages/backend/src/core/chart/charts/per-user-notes.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; -import type { User } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import type { NotesRepository } from '@/models/index.js'; @@ -14,9 +19,8 @@ import type { KVs } from '../core.js'; /** * ユーザーごとのノートに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class PerUserNotesChart extends Chart { +export default class PerUserNotesChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -45,7 +49,7 @@ export default class PerUserNotesChart extends Chart { } @bindThis - public update(user: { id: User['id'] }, note: Note, isAdditional: boolean): void { + public update(user: { id: MiUser['id'] }, note: MiNote, isAdditional: boolean): void { this.commit({ 'total': isAdditional ? 1 : -1, 'inc': isAdditional ? 1 : 0, diff --git a/packages/backend/src/core/chart/charts/per-user-pv.ts b/packages/backend/src/core/chart/charts/per-user-pv.ts index 53c89d8a9a..ad01e0483e 100644 --- a/packages/backend/src/core/chart/charts/per-user-pv.ts +++ b/packages/backend/src/core/chart/charts/per-user-pv.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @@ -12,9 +17,8 @@ import type { KVs } from '../core.js'; /** * ユーザーごとのプロフィール被閲覧数に関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class PerUserPvChart extends Chart { +export default class PerUserPvChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -34,7 +38,7 @@ export default class PerUserPvChart extends Chart { } @bindThis - public async commitByUser(user: { id: User['id'] }, key: string): Promise { + public async commitByUser(user: { id: MiUser['id'] }, key: string): Promise { await this.commit({ 'upv.user': [key], 'pv.user': 1, @@ -42,7 +46,7 @@ export default class PerUserPvChart extends Chart { } @bindThis - public async commitByVisitor(user: { id: User['id'] }, key: string): Promise { + public async commitByVisitor(user: { id: MiUser['id'] }, key: string): Promise { await this.commit({ 'upv.visitor': [key], 'pv.visitor': 1, diff --git a/packages/backend/src/core/chart/charts/per-user-reactions.ts b/packages/backend/src/core/chart/charts/per-user-reactions.ts index 7bc6d4b521..d6d54bef3b 100644 --- a/packages/backend/src/core/chart/charts/per-user-reactions.ts +++ b/packages/backend/src/core/chart/charts/per-user-reactions.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; -import type { User } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -14,9 +19,8 @@ import type { KVs } from '../core.js'; /** * ユーザーごとのリアクションに関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class PerUserReactionsChart extends Chart { +export default class PerUserReactionsChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -37,7 +41,7 @@ export default class PerUserReactionsChart extends Chart { } @bindThis - public async update(user: { id: User['id'], host: User['host'] }, note: Note): Promise { + public async update(user: { id: MiUser['id'], host: MiUser['host'] }, note: MiNote): Promise { const prefix = this.userEntityService.isLocalUser(user) ? 'local' : 'remote'; this.commit({ [`${prefix}.count`]: 1, diff --git a/packages/backend/src/core/chart/charts/test-grouped.ts b/packages/backend/src/core/chart/charts/test-grouped.ts index 128967bc65..00fb872237 100644 --- a/packages/backend/src/core/chart/charts/test-grouped.ts +++ b/packages/backend/src/core/chart/charts/test-grouped.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { AppLockService } from '@/core/AppLockService.js'; @@ -11,9 +16,8 @@ import type { KVs } from '../core.js'; /** * For testing */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class TestGroupedChart extends Chart { +export default class TestGroupedChart extends Chart { // eslint-disable-line import/no-default-export private total = {} as Record; constructor( diff --git a/packages/backend/src/core/chart/charts/test-intersection.ts b/packages/backend/src/core/chart/charts/test-intersection.ts index 6b4eed9062..45a7e805c5 100644 --- a/packages/backend/src/core/chart/charts/test-intersection.ts +++ b/packages/backend/src/core/chart/charts/test-intersection.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { AppLockService } from '@/core/AppLockService.js'; @@ -11,9 +16,8 @@ import type { KVs } from '../core.js'; /** * For testing */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class TestIntersectionChart extends Chart { +export default class TestIntersectionChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/core/chart/charts/test-unique.ts b/packages/backend/src/core/chart/charts/test-unique.ts index 5d2b3f8ab1..e9d38eaf13 100644 --- a/packages/backend/src/core/chart/charts/test-unique.ts +++ b/packages/backend/src/core/chart/charts/test-unique.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { AppLockService } from '@/core/AppLockService.js'; @@ -11,9 +16,8 @@ import type { KVs } from '../core.js'; /** * For testing */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class TestUniqueChart extends Chart { +export default class TestUniqueChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/core/chart/charts/test.ts b/packages/backend/src/core/chart/charts/test.ts index 238351d8b3..4dd6063b5b 100644 --- a/packages/backend/src/core/chart/charts/test.ts +++ b/packages/backend/src/core/chart/charts/test.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { AppLockService } from '@/core/AppLockService.js'; @@ -11,9 +16,8 @@ import type { KVs } from '../core.js'; /** * For testing */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class TestChart extends Chart { +export default class TestChart extends Chart { // eslint-disable-line import/no-default-export public total = 0; // publicにするのはテストのため constructor( diff --git a/packages/backend/src/core/chart/charts/users.ts b/packages/backend/src/core/chart/charts/users.ts index 7bc3602439..ca1e933497 100644 --- a/packages/backend/src/core/chart/charts/users.ts +++ b/packages/backend/src/core/chart/charts/users.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import { Not, IsNull, DataSource } from 'typeorm'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { AppLockService } from '@/core/AppLockService.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -14,9 +19,8 @@ import type { KVs } from '../core.js'; /** * ユーザー数に関するチャート */ -// eslint-disable-next-line import/no-default-export @Injectable() -export default class UsersChart extends Chart { +export default class UsersChart extends Chart { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, @@ -48,7 +52,7 @@ export default class UsersChart extends Chart { } @bindThis - public async update(user: { id: User['id'], host: User['host'] }, isAdditional: boolean): Promise { + public async update(user: { id: MiUser['id'], host: MiUser['host'] }, isAdditional: boolean): Promise { const prefix = this.userEntityService.isLocalUser(user) ? 'local' : 'remote'; await this.commit({ diff --git a/packages/backend/src/core/chart/core.ts b/packages/backend/src/core/chart/core.ts index 7a89233eda..8d0a89f2d6 100644 --- a/packages/backend/src/core/chart/core.ts +++ b/packages/backend/src/core/chart/core.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /** * チャートエンジン * diff --git a/packages/backend/src/core/chart/entities.ts b/packages/backend/src/core/chart/entities.ts index b44e2e38b7..b6a1299a2f 100644 --- a/packages/backend/src/core/chart/entities.ts +++ b/packages/backend/src/core/chart/entities.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { entity as FederationChart } from './charts/entities/federation.js'; import { entity as NotesChart } from './charts/entities/notes.js'; import { entity as UsersChart } from './charts/entities/users.js'; diff --git a/packages/backend/src/core/entities/AbuseUserReportEntityService.ts b/packages/backend/src/core/entities/AbuseUserReportEntityService.ts index 94ae1856b9..f9f11a62b0 100644 --- a/packages/backend/src/core/entities/AbuseUserReportEntityService.ts +++ b/packages/backend/src/core/entities/AbuseUserReportEntityService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { AbuseUserReportsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js'; +import type { MiAbuseUserReport } from '@/models/entities/AbuseUserReport.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -18,7 +23,7 @@ export class AbuseUserReportEntityService { @bindThis public async pack( - src: AbuseUserReport['id'] | AbuseUserReport, + src: MiAbuseUserReport['id'] | MiAbuseUserReport, ) { const report = typeof src === 'object' ? src : await this.abuseUserReportsRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/core/entities/AntennaEntityService.ts b/packages/backend/src/core/entities/AntennaEntityService.ts index 328511f5df..7826ca5d70 100644 --- a/packages/backend/src/core/entities/AntennaEntityService.ts +++ b/packages/backend/src/core/entities/AntennaEntityService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { AntennasRepository } from '@/models/index.js'; import type { Packed } from '@/misc/json-schema.js'; -import type { Antenna } from '@/models/entities/Antenna.js'; +import type { MiAntenna } from '@/models/entities/Antenna.js'; import { bindThis } from '@/decorators.js'; @Injectable() @@ -15,7 +20,7 @@ export class AntennaEntityService { @bindThis public async pack( - src: Antenna['id'] | Antenna, + src: MiAntenna['id'] | MiAntenna, ): Promise> { const antenna = typeof src === 'object' ? src : await this.antennasRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/core/entities/AppEntityService.ts b/packages/backend/src/core/entities/AppEntityService.ts index 0b4c3935c7..cdcbc635a0 100644 --- a/packages/backend/src/core/entities/AppEntityService.ts +++ b/packages/backend/src/core/entities/AppEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { AccessTokensRepository, AppsRepository } from '@/models/index.js'; import type { Packed } from '@/misc/json-schema.js'; -import type { App } from '@/models/entities/App.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiApp } from '@/models/entities/App.js'; +import type { MiUser } from '@/models/entities/User.js'; import { bindThis } from '@/decorators.js'; @Injectable() @@ -19,8 +24,8 @@ export class AppEntityService { @bindThis public async pack( - src: App['id'] | App, - me?: { id: User['id'] } | null | undefined, + src: MiApp['id'] | MiApp, + me?: { id: MiUser['id'] } | null | undefined, options?: { detail?: boolean, includeSecret?: boolean, diff --git a/packages/backend/src/core/entities/AuthSessionEntityService.ts b/packages/backend/src/core/entities/AuthSessionEntityService.ts index a1874c63ab..f6bac7f046 100644 --- a/packages/backend/src/core/entities/AuthSessionEntityService.ts +++ b/packages/backend/src/core/entities/AuthSessionEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { AuthSessionsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { AuthSession } from '@/models/entities/AuthSession.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiAuthSession } from '@/models/entities/AuthSession.js'; +import type { MiUser } from '@/models/entities/User.js'; import { bindThis } from '@/decorators.js'; import { AppEntityService } from './AppEntityService.js'; @@ -19,8 +24,8 @@ export class AuthSessionEntityService { @bindThis public async pack( - src: AuthSession['id'] | AuthSession, - me?: { id: User['id'] } | null | undefined, + src: MiAuthSession['id'] | MiAuthSession, + me?: { id: MiUser['id'] } | null | undefined, ) { const session = typeof src === 'object' ? src : await this.authSessionsRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/core/entities/BlockingEntityService.ts b/packages/backend/src/core/entities/BlockingEntityService.ts index e169c7e90a..4a810a2f00 100644 --- a/packages/backend/src/core/entities/BlockingEntityService.ts +++ b/packages/backend/src/core/entities/BlockingEntityService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { BlockingsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; -import type { Blocking } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiBlocking } from '@/models/entities/Blocking.js'; +import type { MiUser } from '@/models/entities/User.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -20,8 +25,8 @@ export class BlockingEntityService { @bindThis public async pack( - src: Blocking['id'] | Blocking, - me?: { id: User['id'] } | null | undefined, + src: MiBlocking['id'] | MiBlocking, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const blocking = typeof src === 'object' ? src : await this.blockingsRepository.findOneByOrFail({ id: src }); @@ -38,7 +43,7 @@ export class BlockingEntityService { @bindThis public packMany( blockings: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(blockings.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/ChannelEntityService.ts b/packages/backend/src/core/entities/ChannelEntityService.ts index de99ce72c4..e4586d1944 100644 --- a/packages/backend/src/core/entities/ChannelEntityService.ts +++ b/packages/backend/src/core/entities/ChannelEntityService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { ChannelFavoritesRepository, ChannelFollowingsRepository, ChannelsRepository, DriveFilesRepository, NoteUnreadsRepository, NotesRepository } from '@/models/index.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { Channel } from '@/models/entities/Channel.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiChannel } from '@/models/entities/Channel.js'; import { bindThis } from '@/decorators.js'; import { DriveFileEntityService } from './DriveFileEntityService.js'; import { NoteEntityService } from './NoteEntityService.js'; @@ -38,8 +43,8 @@ export class ChannelEntityService { @bindThis public async pack( - src: Channel['id'] | Channel, - me?: { id: User['id'] } | null | undefined, + src: MiChannel['id'] | MiChannel, + me?: { id: MiUser['id'] } | null | undefined, detailed?: boolean, ): Promise> { const channel = typeof src === 'object' ? src : await this.channelsRepository.findOneByOrFail({ id: src }); @@ -87,6 +92,7 @@ export class ChannelEntityService { isArchived: channel.isArchived, usersCount: channel.usersCount, notesCount: channel.notesCount, + isSensitive: channel.isSensitive, ...(me ? { isFollowing, diff --git a/packages/backend/src/core/entities/ClipEntityService.ts b/packages/backend/src/core/entities/ClipEntityService.ts index f558cbc33d..63619ac9d3 100644 --- a/packages/backend/src/core/entities/ClipEntityService.ts +++ b/packages/backend/src/core/entities/ClipEntityService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import type { ClipFavoritesRepository, ClipsRepository, User } from '@/models/index.js'; +import type { ClipFavoritesRepository, ClipsRepository, MiUser } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { Clip } from '@/models/entities/Clip.js'; +import type { MiClip } from '@/models/entities/Clip.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -23,8 +28,8 @@ export class ClipEntityService { @bindThis public async pack( - src: Clip['id'] | Clip, - me?: { id: User['id'] } | null | undefined, + src: MiClip['id'] | MiClip, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const meId = me ? me.id : null; const clip = typeof src === 'object' ? src : await this.clipsRepository.findOneByOrFail({ id: src }); @@ -45,8 +50,8 @@ export class ClipEntityService { @bindThis public packMany( - clips: Clip[], - me?: { id: User['id'] } | null | undefined, + clips: MiClip[], + me?: { id: MiUser['id'] } | null | undefined, ) { return Promise.all(clips.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts index 80442af09b..a09de58b4f 100644 --- a/packages/backend/src/core/entities/DriveFileEntityService.ts +++ b/packages/backend/src/core/entities/DriveFileEntityService.ts @@ -1,14 +1,22 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { forwardRef, Inject, Injectable } from '@nestjs/common'; -import { DataSource, In } from 'typeorm'; +import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { NotesRepository, DriveFilesRepository } from '@/models/index.js'; +import type { DriveFilesRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import type { Packed } from '@/misc/json-schema.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { User } from '@/models/entities/User.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { appendQuery, query } from '@/misc/prelude/url.js'; import { deepClone } from '@/misc/clone.js'; +import { bindThis } from '@/decorators.js'; +import { isMimeImage } from '@/misc/is-mime-image.js'; +import { isNotNull } from '@/misc/is-not-null.js'; import { UtilityService } from '../UtilityService.js'; import { VideoProcessingService } from '../VideoProcessingService.js'; import { UserEntityService } from './UserEntityService.js'; @@ -19,9 +27,6 @@ type PackOptions = { self?: boolean, withUser?: boolean, }; -import { bindThis } from '@/decorators.js'; -import { isMimeImage } from '@/misc/is-mime-image.js'; -import { isNotNull } from '@/misc/is-not-null.js'; @Injectable() export class DriveFileEntityService { @@ -29,12 +34,6 @@ export class DriveFileEntityService { @Inject(DI.config) private config: Config, - @Inject(DI.db) - private db: DataSource, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -60,7 +59,7 @@ export class DriveFileEntityService { } @bindThis - public getPublicProperties(file: DriveFile): DriveFile['properties'] { + public getPublicProperties(file: MiDriveFile): MiDriveFile['properties'] { if (file.properties.orientation != null) { const properties = deepClone(file.properties); if (file.properties.orientation >= 5) { @@ -85,7 +84,7 @@ export class DriveFileEntityService { } @bindThis - public getThumbnailUrl(file: DriveFile): string | null { + public getThumbnailUrl(file: MiDriveFile): string | null { if (file.type.startsWith('video')) { if (file.thumbnailUrl) return file.thumbnailUrl; @@ -108,7 +107,7 @@ export class DriveFileEntityService { } @bindThis - public getPublicUrl(file: DriveFile, mode?: 'avatar'): string { // static = thumbnail + public getPublicUrl(file: MiDriveFile, mode?: 'avatar'): string { // static = thumbnail // リモートかつメディアプロキシ if (file.uri != null && file.userHost != null && this.config.externalMediaProxyEnabled) { return this.getProxiedUrl(file.uri, mode); @@ -134,7 +133,7 @@ export class DriveFileEntityService { } @bindThis - public async calcDriveUsageOf(user: User['id'] | { id: User['id'] }): Promise { + public async calcDriveUsageOf(user: MiUser['id'] | { id: MiUser['id'] }): Promise { const id = typeof user === 'object' ? user.id : user; const { sum } = await this.driveFilesRepository @@ -185,7 +184,7 @@ export class DriveFileEntityService { @bindThis public async pack( - src: DriveFile['id'] | DriveFile, + src: MiDriveFile['id'] | MiDriveFile, options?: PackOptions, ): Promise> { const opts = Object.assign({ @@ -219,7 +218,7 @@ export class DriveFileEntityService { @bindThis public async packNullable( - src: DriveFile['id'] | DriveFile, + src: MiDriveFile['id'] | MiDriveFile, options?: PackOptions, ): Promise | null> { const opts = Object.assign({ @@ -254,7 +253,7 @@ export class DriveFileEntityService { @bindThis public async packMany( - files: DriveFile[], + files: MiDriveFile[], options?: PackOptions, ): Promise[]> { const items = await Promise.all(files.map(f => this.packNullable(f, options))); @@ -263,7 +262,7 @@ export class DriveFileEntityService { @bindThis public async packManyByIdsMap( - fileIds: DriveFile['id'][], + fileIds: MiDriveFile['id'][], options?: PackOptions, ): Promise['id'], Packed<'DriveFile'> | null>> { if (fileIds.length === 0) return new Map(); @@ -278,7 +277,7 @@ export class DriveFileEntityService { @bindThis public async packManyByIds( - fileIds: DriveFile['id'][], + fileIds: MiDriveFile['id'][], options?: PackOptions, ): Promise[]> { if (fileIds.length === 0) return []; diff --git a/packages/backend/src/core/entities/DriveFolderEntityService.ts b/packages/backend/src/core/entities/DriveFolderEntityService.ts index 13929b145f..da401c41fc 100644 --- a/packages/backend/src/core/entities/DriveFolderEntityService.ts +++ b/packages/backend/src/core/entities/DriveFolderEntityService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { DriveFilesRepository, DriveFoldersRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { DriveFolder } from '@/models/entities/DriveFolder.js'; +import type { MiDriveFolder } from '@/models/entities/DriveFolder.js'; import { bindThis } from '@/decorators.js'; @Injectable() @@ -20,7 +25,7 @@ export class DriveFolderEntityService { @bindThis public async pack( - src: DriveFolder['id'] | DriveFolder, + src: MiDriveFolder['id'] | MiDriveFolder, options?: { detail: boolean }, diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts index 4a18cd1b3b..cabd46b950 100644 --- a/packages/backend/src/core/entities/EmojiEntityService.ts +++ b/packages/backend/src/core/entities/EmojiEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { EmojisRepository } from '@/models/index.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { Emoji } from '@/models/entities/Emoji.js'; +import type { MiEmoji } from '@/models/entities/Emoji.js'; import { bindThis } from '@/decorators.js'; @Injectable() @@ -16,7 +21,7 @@ export class EmojiEntityService { @bindThis public async packSimple( - src: Emoji['id'] | Emoji, + src: MiEmoji['id'] | MiEmoji, ): Promise> { const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src }); @@ -40,7 +45,7 @@ export class EmojiEntityService { @bindThis public async packDetailed( - src: Emoji['id'] | Emoji, + src: MiEmoji['id'] | MiEmoji, ): Promise> { const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/core/entities/FlashEntityService.ts b/packages/backend/src/core/entities/FlashEntityService.ts index 92345457c9..be0d176af5 100644 --- a/packages/backend/src/core/entities/FlashEntityService.ts +++ b/packages/backend/src/core/entities/FlashEntityService.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { FlashsRepository, FlashLikesRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { Flash } from '@/models/entities/Flash.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiFlash } from '@/models/entities/Flash.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -24,8 +29,8 @@ export class FlashEntityService { @bindThis public async pack( - src: Flash['id'] | Flash, - me?: { id: User['id'] } | null | undefined, + src: MiFlash['id'] | MiFlash, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const meId = me ? me.id : null; const flash = typeof src === 'object' ? src : await this.flashsRepository.findOneByOrFail({ id: src }); @@ -46,8 +51,8 @@ export class FlashEntityService { @bindThis public packMany( - flashs: Flash[], - me?: { id: User['id'] } | null | undefined, + flashs: MiFlash[], + me?: { id: MiUser['id'] } | null | undefined, ) { return Promise.all(flashs.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/FlashLikeEntityService.ts b/packages/backend/src/core/entities/FlashLikeEntityService.ts index 0351ec3014..0db82fee00 100644 --- a/packages/backend/src/core/entities/FlashLikeEntityService.ts +++ b/packages/backend/src/core/entities/FlashLikeEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { FlashLikesRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { FlashLike } from '@/models/entities/FlashLike.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiFlashLike } from '@/models/entities/FlashLike.js'; import { bindThis } from '@/decorators.js'; import { FlashEntityService } from './FlashEntityService.js'; @@ -19,8 +24,8 @@ export class FlashLikeEntityService { @bindThis public async pack( - src: FlashLike['id'] | FlashLike, - me?: { id: User['id'] } | null | undefined, + src: MiFlashLike['id'] | MiFlashLike, + me?: { id: MiUser['id'] } | null | undefined, ) { const like = typeof src === 'object' ? src : await this.flashLikesRepository.findOneByOrFail({ id: src }); @@ -33,7 +38,7 @@ export class FlashLikeEntityService { @bindThis public packMany( likes: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(likes.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/FollowRequestEntityService.ts b/packages/backend/src/core/entities/FollowRequestEntityService.ts index 6f6f4be412..bcf0deb5b1 100644 --- a/packages/backend/src/core/entities/FollowRequestEntityService.ts +++ b/packages/backend/src/core/entities/FollowRequestEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { FollowRequestsRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { FollowRequest } from '@/models/entities/FollowRequest.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiFollowRequest } from '@/models/entities/FollowRequest.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -19,8 +24,8 @@ export class FollowRequestEntityService { @bindThis public async pack( - src: FollowRequest['id'] | FollowRequest, - me?: { id: User['id'] } | null | undefined, + src: MiFollowRequest['id'] | MiFollowRequest, + me?: { id: MiUser['id'] } | null | undefined, ) { const request = typeof src === 'object' ? src : await this.followRequestsRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/core/entities/FollowingEntityService.ts b/packages/backend/src/core/entities/FollowingEntityService.ts index 55ba4e67ad..d292584ac8 100644 --- a/packages/backend/src/core/entities/FollowingEntityService.ts +++ b/packages/backend/src/core/entities/FollowingEntityService.ts @@ -1,33 +1,38 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { FollowingsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { Following } from '@/models/entities/Following.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiFollowing } from '@/models/entities/Following.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; -type LocalFollowerFollowing = Following & { +type LocalFollowerFollowing = MiFollowing & { followerHost: null; followerInbox: null; followerSharedInbox: null; }; -type RemoteFollowerFollowing = Following & { +type RemoteFollowerFollowing = MiFollowing & { followerHost: string; followerInbox: string; followerSharedInbox: string; }; -type LocalFolloweeFollowing = Following & { +type LocalFolloweeFollowing = MiFollowing & { followeeHost: null; followeeInbox: null; followeeSharedInbox: null; }; -type RemoteFolloweeFollowing = Following & { +type RemoteFolloweeFollowing = MiFollowing & { followeeHost: string; followeeInbox: string; followeeSharedInbox: string; @@ -44,29 +49,29 @@ export class FollowingEntityService { } @bindThis - public isLocalFollower(following: Following): following is LocalFollowerFollowing { + public isLocalFollower(following: MiFollowing): following is LocalFollowerFollowing { return following.followerHost == null; } @bindThis - public isRemoteFollower(following: Following): following is RemoteFollowerFollowing { + public isRemoteFollower(following: MiFollowing): following is RemoteFollowerFollowing { return following.followerHost != null; } @bindThis - public isLocalFollowee(following: Following): following is LocalFolloweeFollowing { + public isLocalFollowee(following: MiFollowing): following is LocalFolloweeFollowing { return following.followeeHost == null; } @bindThis - public isRemoteFollowee(following: Following): following is RemoteFolloweeFollowing { + public isRemoteFollowee(following: MiFollowing): following is RemoteFolloweeFollowing { return following.followeeHost != null; } @bindThis public async pack( - src: Following['id'] | Following, - me?: { id: User['id'] } | null | undefined, + src: MiFollowing['id'] | MiFollowing, + me?: { id: MiUser['id'] } | null | undefined, opts?: { populateFollowee?: boolean; populateFollower?: boolean; @@ -93,7 +98,7 @@ export class FollowingEntityService { @bindThis public packMany( followings: any[], - me?: { id: User['id'] } | null | undefined, + me?: { id: MiUser['id'] } | null | undefined, opts?: { populateFollowee?: boolean; populateFollower?: boolean; diff --git a/packages/backend/src/core/entities/GalleryLikeEntityService.ts b/packages/backend/src/core/entities/GalleryLikeEntityService.ts index 73c264da94..68d50606f1 100644 --- a/packages/backend/src/core/entities/GalleryLikeEntityService.ts +++ b/packages/backend/src/core/entities/GalleryLikeEntityService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { GalleryLikesRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; -import type { GalleryLike } from '@/models/entities/GalleryLike.js'; +import type { MiGalleryLike } from '@/models/entities/GalleryLike.js'; import { bindThis } from '@/decorators.js'; import { GalleryPostEntityService } from './GalleryPostEntityService.js'; @@ -18,7 +23,7 @@ export class GalleryLikeEntityService { @bindThis public async pack( - src: GalleryLike['id'] | GalleryLike, + src: MiGalleryLike['id'] | MiGalleryLike, me?: any, ) { const like = typeof src === 'object' ? src : await this.galleryLikesRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/core/entities/GalleryPostEntityService.ts b/packages/backend/src/core/entities/GalleryPostEntityService.ts index c44a5df118..35d1a11f5c 100644 --- a/packages/backend/src/core/entities/GalleryPostEntityService.ts +++ b/packages/backend/src/core/entities/GalleryPostEntityService.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { GalleryLikesRepository, GalleryPostsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { GalleryPost } from '@/models/entities/GalleryPost.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiGalleryPost } from '@/models/entities/GalleryPost.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; import { DriveFileEntityService } from './DriveFileEntityService.js'; @@ -26,8 +31,8 @@ export class GalleryPostEntityService { @bindThis public async pack( - src: GalleryPost['id'] | GalleryPost, - me?: { id: User['id'] } | null | undefined, + src: MiGalleryPost['id'] | MiGalleryPost, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const meId = me ? me.id : null; const post = typeof src === 'object' ? src : await this.galleryPostsRepository.findOneByOrFail({ id: src }); @@ -52,8 +57,8 @@ export class GalleryPostEntityService { @bindThis public packMany( - posts: GalleryPost[], - me?: { id: User['id'] } | null | undefined, + posts: MiGalleryPost[], + me?: { id: MiUser['id'] } | null | undefined, ) { return Promise.all(posts.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/HashtagEntityService.ts b/packages/backend/src/core/entities/HashtagEntityService.ts index 2cd79b8f8c..21c5d13926 100644 --- a/packages/backend/src/core/entities/HashtagEntityService.ts +++ b/packages/backend/src/core/entities/HashtagEntityService.ts @@ -1,25 +1,23 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { HashtagsRepository } from '@/models/index.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { Hashtag } from '@/models/entities/Hashtag.js'; +import type { MiHashtag } from '@/models/entities/Hashtag.js'; import { bindThis } from '@/decorators.js'; -import { UserEntityService } from './UserEntityService.js'; @Injectable() export class HashtagEntityService { constructor( - @Inject(DI.hashtagsRepository) - private hashtagsRepository: HashtagsRepository, - - private userEntityService: UserEntityService, ) { } @bindThis public async pack( - src: Hashtag, + src: MiHashtag, ): Promise> { return { tag: src.name, @@ -34,7 +32,7 @@ export class HashtagEntityService { @bindThis public packMany( - hashtags: Hashtag[], + hashtags: MiHashtag[], ) { return Promise.all(hashtags.map(x => this.pack(x))); } diff --git a/packages/backend/src/core/entities/InstanceEntityService.ts b/packages/backend/src/core/entities/InstanceEntityService.ts index 3bf84ed375..1de7564b0c 100644 --- a/packages/backend/src/core/entities/InstanceEntityService.ts +++ b/packages/backend/src/core/entities/InstanceEntityService.ts @@ -1,9 +1,12 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { InstancesRepository } from '@/models/index.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { Instance } from '@/models/entities/Instance.js'; +import type { MiInstance } from '@/models/entities/Instance.js'; import { MetaService } from '@/core/MetaService.js'; import { bindThis } from '@/decorators.js'; import { UtilityService } from '../UtilityService.js'; @@ -11,9 +14,6 @@ import { UtilityService } from '../UtilityService.js'; @Injectable() export class InstanceEntityService { constructor( - @Inject(DI.instancesRepository) - private instancesRepository: InstancesRepository, - private metaService: MetaService, private utilityService: UtilityService, @@ -22,7 +22,7 @@ export class InstanceEntityService { @bindThis public async pack( - instance: Instance, + instance: MiInstance, ): Promise> { const meta = await this.metaService.fetch(); return { @@ -52,7 +52,7 @@ export class InstanceEntityService { @bindThis public packMany( - instances: Instance[], + instances: MiInstance[], ) { return Promise.all(instances.map(x => this.pack(x))); } diff --git a/packages/backend/src/core/entities/InviteCodeEntityService.ts b/packages/backend/src/core/entities/InviteCodeEntityService.ts index 2d8e7a4681..03248ada72 100644 --- a/packages/backend/src/core/entities/InviteCodeEntityService.ts +++ b/packages/backend/src/core/entities/InviteCodeEntityService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { RegistrationTicketsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; -import type { User } from '@/models/entities/User.js'; -import type { RegistrationTicket } from '@/models/entities/RegistrationTicket.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiRegistrationTicket } from '@/models/entities/RegistrationTicket.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -20,8 +25,8 @@ export class InviteCodeEntityService { @bindThis public async pack( - src: RegistrationTicket['id'] | RegistrationTicket, - me?: { id: User['id'] } | null | undefined, + src: MiRegistrationTicket['id'] | MiRegistrationTicket, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const target = typeof src === 'object' ? src : await this.registrationTicketsRepository.findOneOrFail({ where: { @@ -45,7 +50,7 @@ export class InviteCodeEntityService { @bindThis public packMany( targets: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(targets.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/ModerationLogEntityService.ts b/packages/backend/src/core/entities/ModerationLogEntityService.ts index 59815d2639..399de8d4d9 100644 --- a/packages/backend/src/core/entities/ModerationLogEntityService.ts +++ b/packages/backend/src/core/entities/ModerationLogEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { ModerationLogsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { } from '@/models/entities/Blocking.js'; -import type { ModerationLog } from '@/models/entities/ModerationLog.js'; +import type { MiModerationLog } from '@/models/entities/ModerationLog.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -19,7 +24,7 @@ export class ModerationLogEntityService { @bindThis public async pack( - src: ModerationLog['id'] | ModerationLog, + src: MiModerationLog['id'] | MiModerationLog, ) { const log = typeof src === 'object' ? src : await this.moderationLogsRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/core/entities/MutingEntityService.ts b/packages/backend/src/core/entities/MutingEntityService.ts index 561d53292e..4239044106 100644 --- a/packages/backend/src/core/entities/MutingEntityService.ts +++ b/packages/backend/src/core/entities/MutingEntityService.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { MutingsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { Muting } from '@/models/entities/Muting.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiMuting } from '@/models/entities/Muting.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -21,8 +26,8 @@ export class MutingEntityService { @bindThis public async pack( - src: Muting['id'] | Muting, - me?: { id: User['id'] } | null | undefined, + src: MiMuting['id'] | MiMuting, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const muting = typeof src === 'object' ? src : await this.mutingsRepository.findOneByOrFail({ id: src }); @@ -40,7 +45,7 @@ export class MutingEntityService { @bindThis public packMany( mutings: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(mutings.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index 546e5f56d2..52c1378b67 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -1,15 +1,20 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import { DataSource, In } from 'typeorm'; +import { In } from 'typeorm'; import * as mfm from 'mfm-js'; import { ModuleRef } from '@nestjs/core'; import { DI } from '@/di-symbols.js'; import type { Packed } from '@/misc/json-schema.js'; import { nyaize } from '@/misc/nyaize.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { User } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { NoteReaction } from '@/models/entities/NoteReaction.js'; -import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepository, PollVotesRepository, NoteReactionsRepository, ChannelsRepository, DriveFilesRepository } from '@/models/index.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiNoteReaction } from '@/models/entities/NoteReaction.js'; +import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepository, PollVotesRepository, NoteReactionsRepository, ChannelsRepository } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; import { isNotNull } from '@/misc/is-not-null.js'; import type { OnModuleInit } from '@nestjs/common'; @@ -28,9 +33,6 @@ export class NoteEntityService implements OnModuleInit { constructor( private moduleRef: ModuleRef, - @Inject(DI.db) - private db: DataSource, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -52,9 +54,6 @@ export class NoteEntityService implements OnModuleInit { @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - //private userEntityService: UserEntityService, //private driveFileEntityService: DriveFileEntityService, //private customEmojiService: CustomEmojiService, @@ -70,7 +69,7 @@ export class NoteEntityService implements OnModuleInit { } @bindThis - private async hideNote(packedNote: Packed<'Note'>, meId: User['id'] | null) { + private async hideNote(packedNote: Packed<'Note'>, meId: MiUser['id'] | null) { // TODO: isVisibleForMe を使うようにしても良さそう(型違うけど) let hide = false; @@ -129,7 +128,7 @@ export class NoteEntityService implements OnModuleInit { } @bindThis - private async populatePoll(note: Note, meId: User['id'] | null) { + private async populatePoll(note: MiNote, meId: MiUser['id'] | null) { const poll = await this.pollsRepository.findOneByOrFail({ noteId: note.id }); const choices = poll.choices.map(c => ({ text: c, @@ -168,8 +167,8 @@ export class NoteEntityService implements OnModuleInit { } @bindThis - private async populateMyReaction(note: Note, meId: User['id'], _hint_?: { - myReactions: Map; + private async populateMyReaction(note: MiNote, meId: MiUser['id'], _hint_?: { + myReactions: Map; }) { if (_hint_?.myReactions) { const reaction = _hint_.myReactions.get(note.id); @@ -199,7 +198,7 @@ export class NoteEntityService implements OnModuleInit { } @bindThis - public async isVisibleForMe(note: Note, meId: User['id'] | null): Promise { + public async isVisibleForMe(note: MiNote, meId: MiUser['id'] | null): Promise { // This code must always be synchronized with the checks in generateVisibilityQuery. // visibility が specified かつ自分が指定されていなかったら非表示 if (note.visibility === 'specified') { @@ -253,7 +252,7 @@ export class NoteEntityService implements OnModuleInit { } @bindThis - public async packAttachedFiles(fileIds: Note['fileIds'], packedFiles: Map | null>): Promise[]> { + public async packAttachedFiles(fileIds: MiNote['fileIds'], packedFiles: Map | null>): Promise[]> { const missingIds = []; for (const id of fileIds) { if (!packedFiles.has(id)) missingIds.push(id); @@ -269,14 +268,14 @@ export class NoteEntityService implements OnModuleInit { @bindThis public async pack( - src: Note['id'] | Note, - me?: { id: User['id'] } | null | undefined, + src: MiNote['id'] | MiNote, + me?: { id: MiUser['id'] } | null | undefined, options?: { detail?: boolean; skipHide?: boolean; _hint_?: { - myReactions: Map; - packedFiles: Map | null>; + myReactions: Map; + packedFiles: Map | null>; }; }, ): Promise> { @@ -334,6 +333,7 @@ export class NoteEntityService implements OnModuleInit { id: channel.id, name: channel.name, color: channel.color, + isSensitive: channel.isSensitive, } : undefined, mentions: note.mentions.length > 0 ? note.mentions : undefined, uri: note.uri ?? undefined, @@ -386,8 +386,8 @@ export class NoteEntityService implements OnModuleInit { @bindThis public async packMany( - notes: Note[], - me?: { id: User['id'] } | null | undefined, + notes: MiNote[], + me?: { id: MiUser['id'] } | null | undefined, options?: { detail?: boolean; skipHide?: boolean; @@ -396,7 +396,7 @@ export class NoteEntityService implements OnModuleInit { if (notes.length === 0) return []; const meId = me ? me.id : null; - const myReactionsMap = new Map(); + const myReactionsMap = new Map(); if (meId) { const renoteIds = notes.filter(n => n.renoteId != null).map(n => n.renoteId!); // パフォーマンスのためノートが作成されてから1秒以上経っていない場合はリアクションを取得しない @@ -426,7 +426,7 @@ export class NoteEntityService implements OnModuleInit { } @bindThis - public aggregateNoteEmojis(notes: Note[]) { + public aggregateNoteEmojis(notes: MiNote[]) { let emojis: { name: string | null; host: string | null; }[] = []; for (const note of notes) { emojis = emojis.concat(note.emojis diff --git a/packages/backend/src/core/entities/NoteFavoriteEntityService.ts b/packages/backend/src/core/entities/NoteFavoriteEntityService.ts index badb8fb816..c0f43cac96 100644 --- a/packages/backend/src/core/entities/NoteFavoriteEntityService.ts +++ b/packages/backend/src/core/entities/NoteFavoriteEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { NoteFavoritesRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { NoteFavorite } from '@/models/entities/NoteFavorite.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNoteFavorite } from '@/models/entities/NoteFavorite.js'; import { bindThis } from '@/decorators.js'; import { NoteEntityService } from './NoteEntityService.js'; @@ -19,8 +24,8 @@ export class NoteFavoriteEntityService { @bindThis public async pack( - src: NoteFavorite['id'] | NoteFavorite, - me?: { id: User['id'] } | null | undefined, + src: MiNoteFavorite['id'] | MiNoteFavorite, + me?: { id: MiUser['id'] } | null | undefined, ) { const favorite = typeof src === 'object' ? src : await this.noteFavoritesRepository.findOneByOrFail({ id: src }); @@ -35,7 +40,7 @@ export class NoteFavoriteEntityService { @bindThis public packMany( favorites: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(favorites.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/NoteReactionEntityService.ts b/packages/backend/src/core/entities/NoteReactionEntityService.ts index d454ddb70a..c50533a32f 100644 --- a/packages/backend/src/core/entities/NoteReactionEntityService.ts +++ b/packages/backend/src/core/entities/NoteReactionEntityService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { NoteReactionsRepository } from '@/models/index.js'; @@ -5,8 +10,8 @@ import type { Packed } from '@/misc/json-schema.js'; import { bindThis } from '@/decorators.js'; import type { OnModuleInit } from '@nestjs/common'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { NoteReaction } from '@/models/entities/NoteReaction.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiNoteReaction } from '@/models/entities/NoteReaction.js'; import type { ReactionService } from '../ReactionService.js'; import type { UserEntityService } from './UserEntityService.js'; import type { NoteEntityService } from './NoteEntityService.js'; @@ -38,8 +43,8 @@ export class NoteReactionEntityService implements OnModuleInit { @bindThis public async pack( - src: NoteReaction['id'] | NoteReaction, - me?: { id: User['id'] } | null | undefined, + src: MiNoteReaction['id'] | MiNoteReaction, + me?: { id: MiUser['id'] } | null | undefined, options?: { withNote: boolean; }, diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts index 02c6982847..42419d61a1 100644 --- a/packages/backend/src/core/entities/NotificationEntityService.ts +++ b/packages/backend/src/core/entities/NotificationEntityService.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { AccessTokensRepository, FollowRequestsRepository, NoteReactionsRepository, NotesRepository, User, UsersRepository } from '@/models/index.js'; +import type { AccessTokensRepository, FollowRequestsRepository, NotesRepository, MiUser, UsersRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { Notification } from '@/models/entities/Notification.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNotification } from '@/models/entities/Notification.js'; +import type { MiNote } from '@/models/entities/Note.js'; import type { Packed } from '@/misc/json-schema.js'; import { bindThis } from '@/decorators.js'; import { isNotNull } from '@/misc/is-not-null.js'; @@ -32,9 +37,6 @@ export class NotificationEntityService implements OnModuleInit { @Inject(DI.usersRepository) private usersRepository: UsersRepository, - @Inject(DI.noteReactionsRepository) - private noteReactionsRepository: NoteReactionsRepository, - @Inject(DI.followRequestsRepository) private followRequestsRepository: FollowRequestsRepository, @@ -55,15 +57,15 @@ export class NotificationEntityService implements OnModuleInit { @bindThis public async pack( - src: Notification, - meId: User['id'], + src: MiNotification, + meId: MiUser['id'], // eslint-disable-next-line @typescript-eslint/ban-types options: { }, hint?: { - packedNotes: Map>; - packedUsers: Map>; + packedNotes: Map>; + packedUsers: Map>; }, ): Promise> { const notification = src; @@ -106,8 +108,8 @@ export class NotificationEntityService implements OnModuleInit { @bindThis public async packMany( - notifications: Notification[], - meId: User['id'], + notifications: MiNotification[], + meId: MiUser['id'], ) { if (notifications.length === 0) return []; diff --git a/packages/backend/src/core/entities/PageEntityService.ts b/packages/backend/src/core/entities/PageEntityService.ts index 94b26a5017..382ff31b4c 100644 --- a/packages/backend/src/core/entities/PageEntityService.ts +++ b/packages/backend/src/core/entities/PageEntityService.ts @@ -1,12 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { DriveFilesRepository, PagesRepository, PageLikesRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { Page } from '@/models/entities/Page.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiPage } from '@/models/entities/Page.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; import { DriveFileEntityService } from './DriveFileEntityService.js'; @@ -30,13 +35,13 @@ export class PageEntityService { @bindThis public async pack( - src: Page['id'] | Page, - me?: { id: User['id'] } | null | undefined, + src: MiPage['id'] | MiPage, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const meId = me ? me.id : null; const page = typeof src === 'object' ? src : await this.pagesRepository.findOneByOrFail({ id: src }); - const attachedFiles: Promise[] = []; + const attachedFiles: Promise[] = []; const collectFile = (xs: any[]) => { for (const x of xs) { if (x.type === 'image') { @@ -95,7 +100,7 @@ export class PageEntityService { script: page.script, eyeCatchingImageId: page.eyeCatchingImageId, eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId) : null, - attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter((x): x is DriveFile => x != null)), + attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter((x): x is MiDriveFile => x != null)), likedCount: page.likedCount, isLiked: meId ? await this.pageLikesRepository.exist({ where: { pageId: page.id, userId: meId } }) : undefined, }); @@ -103,8 +108,8 @@ export class PageEntityService { @bindThis public packMany( - pages: Page[], - me?: { id: User['id'] } | null | undefined, + pages: MiPage[], + me?: { id: MiUser['id'] } | null | undefined, ) { return Promise.all(pages.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/PageLikeEntityService.ts b/packages/backend/src/core/entities/PageLikeEntityService.ts index 99465d0ea3..4af0deb069 100644 --- a/packages/backend/src/core/entities/PageLikeEntityService.ts +++ b/packages/backend/src/core/entities/PageLikeEntityService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { PageLikesRepository } from '@/models/index.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { PageLike } from '@/models/entities/PageLike.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiPageLike } from '@/models/entities/PageLike.js'; import { bindThis } from '@/decorators.js'; import { PageEntityService } from './PageEntityService.js'; @@ -19,8 +24,8 @@ export class PageLikeEntityService { @bindThis public async pack( - src: PageLike['id'] | PageLike, - me?: { id: User['id'] } | null | undefined, + src: MiPageLike['id'] | MiPageLike, + me?: { id: MiUser['id'] } | null | undefined, ) { const like = typeof src === 'object' ? src : await this.pageLikesRepository.findOneByOrFail({ id: src }); @@ -33,7 +38,7 @@ export class PageLikeEntityService { @bindThis public packMany( likes: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(likes.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/RenoteMutingEntityService.ts b/packages/backend/src/core/entities/RenoteMutingEntityService.ts index f8871e0495..ddc5b971c3 100644 --- a/packages/backend/src/core/entities/RenoteMutingEntityService.ts +++ b/packages/backend/src/core/entities/RenoteMutingEntityService.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { RenoteMutingsRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { RenoteMuting } from '@/models/entities/RenoteMuting.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiRenoteMuting } from '@/models/entities/RenoteMuting.js'; import { bindThis } from '@/decorators.js'; import { UserEntityService } from './UserEntityService.js'; @@ -21,8 +26,8 @@ export class RenoteMutingEntityService { @bindThis public async pack( - src: RenoteMuting['id'] | RenoteMuting, - me?: { id: User['id'] } | null | undefined, + src: MiRenoteMuting['id'] | MiRenoteMuting, + me?: { id: MiUser['id'] } | null | undefined, ): Promise> { const muting = typeof src === 'object' ? src : await this.renoteMutingsRepository.findOneByOrFail({ id: src }); @@ -39,7 +44,7 @@ export class RenoteMutingEntityService { @bindThis public packMany( mutings: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(mutings.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/RoleEntityService.ts b/packages/backend/src/core/entities/RoleEntityService.ts index 54818782dd..cd6ecee4c6 100644 --- a/packages/backend/src/core/entities/RoleEntityService.ts +++ b/packages/backend/src/core/entities/RoleEntityService.ts @@ -1,13 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Brackets } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { RoleAssignmentsRepository, RolesRepository } from '@/models/index.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { User } from '@/models/entities/User.js'; -import type { Role } from '@/models/entities/Role.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiRole } from '@/models/entities/Role.js'; import { bindThis } from '@/decorators.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; -import { UserEntityService } from './UserEntityService.js'; @Injectable() export class RoleEntityService { @@ -17,15 +21,13 @@ export class RoleEntityService { @Inject(DI.roleAssignmentsRepository) private roleAssignmentsRepository: RoleAssignmentsRepository, - - private userEntityService: UserEntityService, ) { } @bindThis public async pack( - src: Role['id'] | Role, - me?: { id: User['id'] } | null | undefined, + src: MiRole['id'] | MiRole, + me?: { id: MiUser['id'] } | null | undefined, ) { const role = typeof src === 'object' ? src : await this.rolesRepository.findOneByOrFail({ id: src }); @@ -71,7 +73,7 @@ export class RoleEntityService { @bindThis public packMany( roles: any[], - me: { id: User['id'] }, + me: { id: MiUser['id'] }, ) { return Promise.all(roles.map(x => this.pack(x, me))); } diff --git a/packages/backend/src/core/entities/SigninEntityService.ts b/packages/backend/src/core/entities/SigninEntityService.ts index a6c4407ce8..59ad57e4a3 100644 --- a/packages/backend/src/core/entities/SigninEntityService.ts +++ b/packages/backend/src/core/entities/SigninEntityService.ts @@ -1,24 +1,22 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { SigninsRepository } from '@/models/index.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import type { } from '@/models/entities/Blocking.js'; -import type { Signin } from '@/models/entities/Signin.js'; +import type { MiSignin } from '@/models/entities/Signin.js'; import { bindThis } from '@/decorators.js'; -import { UserEntityService } from './UserEntityService.js'; @Injectable() export class SigninEntityService { constructor( - @Inject(DI.signinsRepository) - private signinsRepository: SigninsRepository, - - private userEntityService: UserEntityService, ) { } @bindThis public async pack( - src: Signin, + src: MiSignin, ) { return src; } diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 7d248f8524..236ee9f0b4 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -1,5 +1,9 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import { In, Not } from 'typeorm'; import * as Redis from 'ioredis'; import _Ajv from 'ajv'; import { ModuleRef } from '@nestjs/core'; @@ -9,15 +13,15 @@ import type { Packed } from '@/misc/json-schema.js'; import type { Promiseable } from '@/misc/prelude/await-all.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js'; -import type { LocalUser, PartialLocalUser, PartialRemoteUser, RemoteUser, User } from '@/models/entities/User.js'; +import type { MiLocalUser, MiPartialLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js'; import { birthdaySchema, descriptionSchema, localUsernameSchema, locationSchema, nameSchema, passwordSchema } from '@/models/entities/User.js'; -import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, ChannelFollowingsRepository, UserNotePiningsRepository, UserProfilesRepository, InstancesRepository, AnnouncementReadsRepository, AnnouncementsRepository, PagesRepository, UserProfile, RenoteMutingsRepository, UserMemoRepository } from '@/models/index.js'; +import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, UserNotePiningsRepository, UserProfilesRepository, AnnouncementReadsRepository, AnnouncementsRepository, MiUserProfile, RenoteMutingsRepository, UserMemoRepository } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; import { RoleService } from '@/core/RoleService.js'; import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import type { OnModuleInit } from '@nestjs/common'; -import type { AntennaService } from '../AntennaService.js'; +import type { AnnouncementService } from '../AnnouncementService.js'; import type { CustomEmojiService } from '../CustomEmojiService.js'; import type { NoteEntityService } from './NoteEntityService.js'; import type { DriveFileEntityService } from './DriveFileEntityService.js'; @@ -34,15 +38,15 @@ type IsMeAndIsUserDetailed(user: T): user is (T & { host: null; }); -function isLocalUser(user: User | { host: User['host'] }): boolean { +function isLocalUser(user: MiUser): user is MiLocalUser; +function isLocalUser(user: T): user is (T & { host: null; }); +function isLocalUser(user: MiUser | { host: MiUser['host'] }): boolean { return user.host == null; } -function isRemoteUser(user: User): user is RemoteUser; -function isRemoteUser(user: T): user is (T & { host: string; }); -function isRemoteUser(user: User | { host: User['host'] }): boolean { +function isRemoteUser(user: MiUser): user is MiRemoteUser; +function isRemoteUser(user: T): user is (T & { host: string; }); +function isRemoteUser(user: MiUser | { host: MiUser['host'] }): boolean { return !isLocalUser(user); } @@ -53,7 +57,7 @@ export class UserEntityService implements OnModuleInit { private driveFileEntityService: DriveFileEntityService; private pageEntityService: PageEntityService; private customEmojiService: CustomEmojiService; - private antennaService: AntennaService; + private announcementService: AnnouncementService; private roleService: RoleService; private federatedInstanceService: FederatedInstanceService; @@ -93,27 +97,18 @@ export class UserEntityService implements OnModuleInit { @Inject(DI.noteUnreadsRepository) private noteUnreadsRepository: NoteUnreadsRepository, - @Inject(DI.channelFollowingsRepository) - private channelFollowingsRepository: ChannelFollowingsRepository, - @Inject(DI.userNotePiningsRepository) private userNotePiningsRepository: UserNotePiningsRepository, @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, - @Inject(DI.instancesRepository) - private instancesRepository: InstancesRepository, - @Inject(DI.announcementReadsRepository) private announcementReadsRepository: AnnouncementReadsRepository, @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, - @Inject(DI.pagesRepository) - private pagesRepository: PagesRepository, - @Inject(DI.userMemosRepository) private userMemosRepository: UserMemoRepository, @@ -132,7 +127,7 @@ export class UserEntityService implements OnModuleInit { this.driveFileEntityService = this.moduleRef.get('DriveFileEntityService'); this.pageEntityService = this.moduleRef.get('PageEntityService'); this.customEmojiService = this.moduleRef.get('CustomEmojiService'); - this.antennaService = this.moduleRef.get('AntennaService'); + this.announcementService = this.moduleRef.get('AnnouncementService'); this.roleService = this.moduleRef.get('RoleService'); this.federatedInstanceService = this.moduleRef.get('FederatedInstanceService'); } @@ -150,7 +145,7 @@ export class UserEntityService implements OnModuleInit { public isRemoteUser = isRemoteUser; @bindThis - public async getRelation(me: User['id'], target: User['id']) { + public async getRelation(me: MiUser['id'], target: MiUser['id']) { return awaitAll({ id: target, isFollowing: this.followingsRepository.count({ @@ -213,20 +208,7 @@ export class UserEntityService implements OnModuleInit { } @bindThis - public async getHasUnreadAnnouncement(userId: User['id']): Promise { - const reads = await this.announcementReadsRepository.findBy({ - userId: userId, - }); - - const count = await this.announcementsRepository.countBy(reads.length > 0 ? { - id: Not(In(reads.map(read => read.announcementId))), - } : {}); - - return count > 0; - } - - @bindThis - public async getHasUnreadAntenna(userId: User['id']): Promise { + public async getHasUnreadAntenna(userId: MiUser['id']): Promise { /* const myAntennas = (await this.antennaService.getAntennas()).filter(a => a.userId === userId); @@ -243,7 +225,7 @@ export class UserEntityService implements OnModuleInit { } @bindThis - public async getHasUnreadNotification(userId: User['id']): Promise { + public async getHasUnreadNotification(userId: MiUser['id']): Promise { const latestReadNotificationId = await this.redisClient.get(`latestReadNotification:${userId}`); const latestNotificationIdsRes = await this.redisClient.xrevrange( @@ -257,7 +239,7 @@ export class UserEntityService implements OnModuleInit { } @bindThis - public async getHasPendingReceivedFollowRequest(userId: User['id']): Promise { + public async getHasPendingReceivedFollowRequest(userId: MiUser['id']): Promise { const count = await this.followRequestsRepository.countBy({ followeeId: userId, }); @@ -266,7 +248,7 @@ export class UserEntityService implements OnModuleInit { } @bindThis - public getOnlineStatus(user: User): 'unknown' | 'online' | 'active' | 'offline' { + public getOnlineStatus(user: MiUser): 'unknown' | 'online' | 'active' | 'offline' { if (user.hideOnlineStatus) return 'unknown'; if (user.lastActiveDate == null) return 'unknown'; const elapsed = Date.now() - user.lastActiveDate.getTime(); @@ -278,12 +260,12 @@ export class UserEntityService implements OnModuleInit { } @bindThis - public getIdenticonUrl(user: User): string { + public getIdenticonUrl(user: MiUser): string { return `${this.config.url}/identicon/${user.username.toLowerCase()}@${user.host ?? this.config.host}`; } @bindThis - public getUserUri(user: LocalUser | PartialLocalUser | RemoteUser | PartialRemoteUser): string { + public getUserUri(user: MiLocalUser | MiPartialLocalUser | MiRemoteUser | MiPartialRemoteUser): string { return this.isRemoteUser(user) ? user.uri : this.genLocalUserUri(user.id); } @@ -294,12 +276,12 @@ export class UserEntityService implements OnModuleInit { } public async pack( - src: User['id'] | User, - me?: { id: User['id']; } | null | undefined, + src: MiUser['id'] | MiUser, + me?: { id: MiUser['id']; } | null | undefined, options?: { detail?: D, includeSecrets?: boolean, - userProfile?: UserProfile, + userProfile?: MiUserProfile, }, ): Promise> { const opts = Object.assign({ @@ -329,7 +311,7 @@ export class UserEntityService implements OnModuleInit { const meId = me ? me.id : null; const isMe = meId === user.id; - const iAmModerator = me ? await this.roleService.isModerator(me as User) : false; + const iAmModerator = me ? await this.roleService.isModerator(me as MiUser) : false; const relation = meId && !isMe && opts.detail ? await this.getRelation(meId, user.id) : null; const pins = opts.detail ? await this.userNotePiningsRepository.createQueryBuilder('pin') @@ -351,6 +333,7 @@ export class UserEntityService implements OnModuleInit { const isModerator = isMe && opts.detail ? this.roleService.isModerator(user) : null; const isAdmin = isMe && opts.detail ? this.roleService.isAdministrator(user) : null; + const unreadAnnouncements = isMe && opts.detail ? await this.announcementService.getUnreadAnnouncements(user) : null; const falsy = opts.detail ? false : undefined; @@ -460,7 +443,8 @@ export class UserEntityService implements OnModuleInit { where: { userId: user.id, isMentioned: true }, take: 1, }).then(count => count > 0), - hasUnreadAnnouncement: this.getHasUnreadAnnouncement(user.id), + hasUnreadAnnouncement: unreadAnnouncements!.length > 0, + unreadAnnouncements, hasUnreadAntenna: this.getHasUnreadAntenna(user.id), hasUnreadChannel: false, // 後方互換性のため hasUnreadNotification: this.getHasUnreadNotification(user.id), @@ -507,8 +491,8 @@ export class UserEntityService implements OnModuleInit { } public packMany( - users: (User['id'] | User)[], - me?: { id: User['id'] } | null | undefined, + users: (MiUser['id'] | MiUser)[], + me?: { id: MiUser['id'] } | null | undefined, options?: { detail?: D, includeSecrets?: boolean, diff --git a/packages/backend/src/core/entities/UserListEntityService.ts b/packages/backend/src/core/entities/UserListEntityService.ts index 8628819278..d1d9838dfa 100644 --- a/packages/backend/src/core/entities/UserListEntityService.ts +++ b/packages/backend/src/core/entities/UserListEntityService.ts @@ -1,11 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { UserListJoiningsRepository, UserListsRepository } from '@/models/index.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/entities/Blocking.js'; -import type { UserList } from '@/models/entities/UserList.js'; +import type { MiUserList } from '@/models/entities/UserList.js'; import { bindThis } from '@/decorators.js'; -import { UserEntityService } from './UserEntityService.js'; @Injectable() export class UserListEntityService { @@ -15,14 +19,12 @@ export class UserListEntityService { @Inject(DI.userListJoiningsRepository) private userListJoiningsRepository: UserListJoiningsRepository, - - private userEntityService: UserEntityService, ) { } @bindThis public async pack( - src: UserList['id'] | UserList, + src: MiUserList['id'] | MiUserList, ): Promise> { const userList = typeof src === 'object' ? src : await this.userListsRepository.findOneByOrFail({ id: src }); diff --git a/packages/backend/src/daemons/DaemonModule.ts b/packages/backend/src/daemons/DaemonModule.ts index 683f9cbfe3..7543a2ea3d 100644 --- a/packages/backend/src/daemons/DaemonModule.ts +++ b/packages/backend/src/daemons/DaemonModule.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Module } from '@nestjs/common'; import { CoreModule } from '@/core/CoreModule.js'; import { GlobalModule } from '@/GlobalModule.js'; diff --git a/packages/backend/src/daemons/JanitorService.ts b/packages/backend/src/daemons/JanitorService.ts index f826d50625..6f5e5a7f3b 100644 --- a/packages/backend/src/daemons/JanitorService.ts +++ b/packages/backend/src/daemons/JanitorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { LessThan } from 'typeorm'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/daemons/QueueStatsService.ts b/packages/backend/src/daemons/QueueStatsService.ts index 4d0cb96a2f..dc9482f022 100644 --- a/packages/backend/src/daemons/QueueStatsService.ts +++ b/packages/backend/src/daemons/QueueStatsService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import Xev from 'xev'; import * as Bull from 'bullmq'; diff --git a/packages/backend/src/daemons/ServerStatsService.ts b/packages/backend/src/daemons/ServerStatsService.ts index 375fd5e516..95026099e8 100644 --- a/packages/backend/src/daemons/ServerStatsService.ts +++ b/packages/backend/src/daemons/ServerStatsService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import si from 'systeminformation'; import Xev from 'xev'; diff --git a/packages/backend/src/decorators.ts b/packages/backend/src/decorators.ts index db23317eef..6b439978db 100644 --- a/packages/backend/src/decorators.ts +++ b/packages/backend/src/decorators.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // https://github.com/andreypopp/autobind-decorator /** diff --git a/packages/backend/src/di-symbols.ts b/packages/backend/src/di-symbols.ts index 4a073f102f..c911f60566 100644 --- a/packages/backend/src/di-symbols.ts +++ b/packages/backend/src/di-symbols.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const DI = { config: Symbol('config'), db: Symbol('db'), diff --git a/packages/backend/src/env.ts b/packages/backend/src/env.ts index d7c8304b47..af1c3bdd3c 100644 --- a/packages/backend/src/env.ts +++ b/packages/backend/src/env.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + const envOption = { onlyQueue: false, onlyServer: false, diff --git a/packages/backend/src/global.d.ts b/packages/backend/src/global.d.ts index 7343aa1994..a9e6243cc4 100644 --- a/packages/backend/src/global.d.ts +++ b/packages/backend/src/global.d.ts @@ -1 +1,6 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + type FIXME = any; diff --git a/packages/backend/src/logger.ts b/packages/backend/src/logger.ts index 465b557ce4..5c10559ec6 100644 --- a/packages/backend/src/logger.ts +++ b/packages/backend/src/logger.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import cluster from 'node:cluster'; import chalk from 'chalk'; import { default as convertColor } from 'color-convert'; @@ -13,6 +18,7 @@ type Context = { type Level = 'error' | 'success' | 'warning' | 'debug' | 'info'; +// eslint-disable-next-line import/no-default-export export default class Logger { private context: Context; private parentLogger: Logger | null = null; diff --git a/packages/backend/src/misc/acct.ts b/packages/backend/src/misc/acct.ts index fb3b657cf7..5db72746c0 100644 --- a/packages/backend/src/misc/acct.ts +++ b/packages/backend/src/misc/acct.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export type Acct = { username: string; host: string | null; diff --git a/packages/backend/src/misc/api-permissions.ts b/packages/backend/src/misc/api-permissions.ts index 160cdf9fd6..57c9308844 100644 --- a/packages/backend/src/misc/api-permissions.ts +++ b/packages/backend/src/misc/api-permissions.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const kinds = [ 'read:account', 'write:account', diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index e825d51371..046d4d6c2f 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as Redis from 'ioredis'; import { bindThis } from '@/decorators.js'; diff --git a/packages/backend/src/misc/check-https.ts b/packages/backend/src/misc/check-https.ts index 612032fe97..0b13ccabdd 100644 --- a/packages/backend/src/misc/check-https.ts +++ b/packages/backend/src/misc/check-https.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function checkHttps(url: string): boolean { return url.startsWith('https://') || (url.startsWith('http://') && process.env.NODE_ENV !== 'production'); diff --git a/packages/backend/src/misc/check-word-mute.ts b/packages/backend/src/misc/check-word-mute.ts index 910bebfcfe..a7a60c20e9 100644 --- a/packages/backend/src/misc/check-word-mute.ts +++ b/packages/backend/src/misc/check-word-mute.ts @@ -1,16 +1,21 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { AhoCorasick } from 'slacc'; import RE2 from 're2'; -import type { Note } from '@/models/entities/Note.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiUser } from '@/models/entities/User.js'; type NoteLike = { - userId: Note['userId']; - text: Note['text']; - cw?: Note['cw']; + userId: MiNote['userId']; + text: MiNote['text']; + cw?: MiNote['cw']; }; type UserLike = { - id: User['id']; + id: MiUser['id']; }; const acCache = new Map(); diff --git a/packages/backend/src/misc/clone.ts b/packages/backend/src/misc/clone.ts index 16fad24129..9d20deac3b 100644 --- a/packages/backend/src/misc/clone.ts +++ b/packages/backend/src/misc/clone.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // structredCloneが遅いため // SEE: http://var.blog.jp/archives/86038606.html diff --git a/packages/backend/src/misc/content-disposition.ts b/packages/backend/src/misc/content-disposition.ts index b2aec471d5..1ac8c88d21 100644 --- a/packages/backend/src/misc/content-disposition.ts +++ b/packages/backend/src/misc/content-disposition.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import cd from 'content-disposition'; export function contentDisposition(type: 'inline' | 'attachment', filename: string): string { diff --git a/packages/backend/src/misc/correct-filename.ts b/packages/backend/src/misc/correct-filename.ts index 23a0699f39..9130af44c3 100644 --- a/packages/backend/src/misc/correct-filename.ts +++ b/packages/backend/src/misc/correct-filename.ts @@ -1,15 +1,58 @@ -// 与えられた拡張子とファイル名が一致しているかどうかを確認し、 -// 一致していない場合は拡張子を付与して返す +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +/** + * Array.includes()よりSet.has()の方が高速 + */ +const targetExtsToSkip = new Set([ + '.gz', + '.tar', + '.tgz', + '.bz2', + '.xz', + '.zip', + '.7z', +]); + +const extRegExp = /\.[0-9a-zA-Z]+$/i; + +/** + * 与えられた拡張子とファイル名が一致しているかどうかを確認し、 + * 一致していない場合は拡張子を付与して返す + * + * extはfile-typeのextを想定 + */ export function correctFilename(filename: string, ext: string | null) { - const dotExt = ext ? ext.startsWith('.') ? ext : `.${ext}` : '.unknown'; - if (filename.endsWith(dotExt)) { - return filename; - } - if (ext === 'jpg' && filename.endsWith('.jpeg')) { - return filename; - } - if (ext === 'tif' && filename.endsWith('.tiff')) { + const dotExt = ext ? ext[0] === '.' ? ext : `.${ext}` : '.unknown'; + + const match = extRegExp.exec(filename); + if (!match || !match[0]) { + // filenameが拡張子を持っていない場合は拡張子をつける + return `${filename}${dotExt}`; + } + + const filenameExt = match[0].toLowerCase(); + if ( + // 未知のファイル形式かつ拡張子がある場合は何もしない + ext === null || + // 拡張子が一致している場合は何もしない + filenameExt === dotExt || + + // jpeg, tiffを同一視 + dotExt === '.jpg' && filenameExt === '.jpeg' || + dotExt === '.tif' && filenameExt === '.tiff' || + // dllもexeもportable executableなので判定が正しく行われない + dotExt === '.exe' && filenameExt === '.dll' || + + // 圧縮形式っぽければ下手に拡張子を変えない + // https://github.com/misskey-dev/misskey/issues/11482 + targetExtsToSkip.has(dotExt) + ) { return filename; } + + // 拡張子があるが一致していないなどの場合は拡張子を付け足す return `${filename}${dotExt}`; } diff --git a/packages/backend/src/misc/create-temp.ts b/packages/backend/src/misc/create-temp.ts index 7b8942e308..2bb0e88489 100644 --- a/packages/backend/src/misc/create-temp.ts +++ b/packages/backend/src/misc/create-temp.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as tmp from 'tmp'; export function createTemp(): Promise<[string, () => void]> { diff --git a/packages/backend/src/misc/dev-null.ts b/packages/backend/src/misc/dev-null.ts index 6706af5e52..f510177c0b 100644 --- a/packages/backend/src/misc/dev-null.ts +++ b/packages/backend/src/misc/dev-null.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Writable, WritableOptions } from 'node:stream'; export class DevNull extends Writable implements NodeJS.WritableStream { diff --git a/packages/backend/src/misc/emoji-regex.ts b/packages/backend/src/misc/emoji-regex.ts index 1c6f5776db..24e4092aeb 100644 --- a/packages/backend/src/misc/emoji-regex.ts +++ b/packages/backend/src/misc/emoji-regex.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // taken from twemoji-parser/dist/lib/regex.js const twemojiRegex = /(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef0-\udef6]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedd-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7c\ude80-\ude86\ude90-\udeac\udeb0-\udeba\udec0-\udec2\uded0-\uded9\udee0-\udee7]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g; diff --git a/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts b/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts index 14c25922ad..0b898d47e8 100644 --- a/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts +++ b/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as mfm from 'mfm-js'; import { unique } from '@/misc/prelude/array.js'; diff --git a/packages/backend/src/misc/extract-hashtags.ts b/packages/backend/src/misc/extract-hashtags.ts index d293fd7f52..3bd56e98eb 100644 --- a/packages/backend/src/misc/extract-hashtags.ts +++ b/packages/backend/src/misc/extract-hashtags.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as mfm from 'mfm-js'; import { unique } from '@/misc/prelude/array.js'; diff --git a/packages/backend/src/misc/extract-mentions.ts b/packages/backend/src/misc/extract-mentions.ts index c8762e797b..272eb92192 100644 --- a/packages/backend/src/misc/extract-mentions.ts +++ b/packages/backend/src/misc/extract-mentions.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // test is located in test/extract-mentions import * as mfm from 'mfm-js'; diff --git a/packages/backend/src/misc/fastify-reply-error.ts b/packages/backend/src/misc/fastify-reply-error.ts index 4e987175e2..7c889bab7a 100644 --- a/packages/backend/src/misc/fastify-reply-error.ts +++ b/packages/backend/src/misc/fastify-reply-error.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // https://www.fastify.io/docs/latest/Reference/Reply/#async-await-and-promises export class FastifyReplyError extends Error { public message: string; diff --git a/packages/backend/src/misc/gen-identicon.ts b/packages/backend/src/misc/gen-identicon.ts index b40745973e..c36b00af63 100644 --- a/packages/backend/src/misc/gen-identicon.ts +++ b/packages/backend/src/misc/gen-identicon.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /** * Identicon generator * https://en.wikipedia.org/wiki/Identicon diff --git a/packages/backend/src/misc/gen-key-pair.ts b/packages/backend/src/misc/gen-key-pair.ts index e2ad598501..c0815613e7 100644 --- a/packages/backend/src/misc/gen-key-pair.ts +++ b/packages/backend/src/misc/gen-key-pair.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as crypto from 'node:crypto'; import * as util from 'node:util'; diff --git a/packages/backend/src/misc/generate-invite-code.ts b/packages/backend/src/misc/generate-invite-code.ts index 617b27361d..7c88561179 100644 --- a/packages/backend/src/misc/generate-invite-code.ts +++ b/packages/backend/src/misc/generate-invite-code.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { secureRndstr } from './secure-rndstr.js'; const CHARS = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'; // [0-9A-Z] w/o [01IO] (32 patterns) diff --git a/packages/backend/src/misc/generate-native-user-token.ts b/packages/backend/src/misc/generate-native-user-token.ts index 7292d765a8..094c625120 100644 --- a/packages/backend/src/misc/generate-native-user-token.ts +++ b/packages/backend/src/misc/generate-native-user-token.ts @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { secureRndstr } from '@/misc/secure-rndstr.js'; +// eslint-disable-next-line import/no-default-export export default () => secureRndstr(16); diff --git a/packages/backend/src/misc/get-ip-hash.ts b/packages/backend/src/misc/get-ip-hash.ts index 1a86fb8814..3a01e4f578 100644 --- a/packages/backend/src/misc/get-ip-hash.ts +++ b/packages/backend/src/misc/get-ip-hash.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import IPCIDR from 'ip-cidr'; export function getIpHash(ip: string): string { diff --git a/packages/backend/src/misc/get-note-summary.ts b/packages/backend/src/misc/get-note-summary.ts index 964f20b25b..1bda5cdcf7 100644 --- a/packages/backend/src/misc/get-note-summary.ts +++ b/packages/backend/src/misc/get-note-summary.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { Packed } from './json-schema.js'; /** diff --git a/packages/backend/src/misc/get-reaction-emoji.ts b/packages/backend/src/misc/get-reaction-emoji.ts index c2e0b98582..80ef7ff7bc 100644 --- a/packages/backend/src/misc/get-reaction-emoji.ts +++ b/packages/backend/src/misc/get-reaction-emoji.ts @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +// eslint-disable-next-line import/no-default-export export default function(reaction: string): string { switch (reaction) { case 'like': return '👍'; diff --git a/packages/backend/src/misc/i18n.ts b/packages/backend/src/misc/i18n.ts index b1c727827d..4c9d1a08e3 100644 --- a/packages/backend/src/misc/i18n.ts +++ b/packages/backend/src/misc/i18n.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class I18n> { public locale: T; diff --git a/packages/backend/src/misc/id/aid.ts b/packages/backend/src/misc/id/aid.ts index f0cbc9900d..ec8aa849c9 100644 --- a/packages/backend/src/misc/id/aid.ts +++ b/packages/backend/src/misc/id/aid.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // AID // 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さ2の[ノイズ文字列] diff --git a/packages/backend/src/misc/id/meid.ts b/packages/backend/src/misc/id/meid.ts index 337416b059..82cda37237 100644 --- a/packages/backend/src/misc/id/meid.ts +++ b/packages/backend/src/misc/id/meid.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + const CHARS = '0123456789abcdef'; // same as object-id diff --git a/packages/backend/src/misc/id/meidg.ts b/packages/backend/src/misc/id/meidg.ts index 19d0bc1fd2..fba7156718 100644 --- a/packages/backend/src/misc/id/meidg.ts +++ b/packages/backend/src/misc/id/meidg.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + const CHARS = '0123456789abcdef'; // 4bit Fixed hex value 'g' diff --git a/packages/backend/src/misc/id/object-id.ts b/packages/backend/src/misc/id/object-id.ts index aec3447bd7..e3b6e8e433 100644 --- a/packages/backend/src/misc/id/object-id.ts +++ b/packages/backend/src/misc/id/object-id.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + const CHARS = '0123456789abcdef'; // same as meid diff --git a/packages/backend/src/misc/id/ulid.ts b/packages/backend/src/misc/id/ulid.ts index bfbc363cf5..00dd67dafe 100644 --- a/packages/backend/src/misc/id/ulid.ts +++ b/packages/backend/src/misc/id/ulid.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // Crockford's Base32 // https://github.com/ulid/spec#encoding const CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; diff --git a/packages/backend/src/misc/identifiable-error.ts b/packages/backend/src/misc/identifiable-error.ts index e394123f1b..71a4773fac 100644 --- a/packages/backend/src/misc/identifiable-error.ts +++ b/packages/backend/src/misc/identifiable-error.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /** * ID付きエラー */ diff --git a/packages/backend/src/misc/is-duplicate-key-value-error.ts b/packages/backend/src/misc/is-duplicate-key-value-error.ts index f5343d187c..91e0a6b93d 100644 --- a/packages/backend/src/misc/is-duplicate-key-value-error.ts +++ b/packages/backend/src/misc/is-duplicate-key-value-error.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { QueryFailedError } from 'typeorm'; export function isDuplicateKeyValueError(e: unknown | Error): boolean { diff --git a/packages/backend/src/misc/is-instance-muted.ts b/packages/backend/src/misc/is-instance-muted.ts index 73ad0b3b82..b231058a95 100644 --- a/packages/backend/src/misc/is-instance-muted.ts +++ b/packages/backend/src/misc/is-instance-muted.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { Packed } from './json-schema.js'; export function isInstanceMuted(note: Packed<'Note'>, mutedInstances: Set): boolean { diff --git a/packages/backend/src/misc/is-mime-image.ts b/packages/backend/src/misc/is-mime-image.ts index 46a66efc0f..1a5a8cf0f4 100644 --- a/packages/backend/src/misc/is-mime-image.ts +++ b/packages/backend/src/misc/is-mime-image.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { FILE_TYPE_BROWSERSAFE } from '@/const.js'; const dictionary = { diff --git a/packages/backend/src/misc/is-native-token.ts b/packages/backend/src/misc/is-native-token.ts index 2833c570c8..618e60b7d8 100644 --- a/packages/backend/src/misc/is-native-token.ts +++ b/packages/backend/src/misc/is-native-token.ts @@ -1 +1,7 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +// eslint-disable-next-line import/no-default-export export default (token: string) => token.length === 16; diff --git a/packages/backend/src/misc/is-not-null.ts b/packages/backend/src/misc/is-not-null.ts index d89a1957be..153a9e51ef 100644 --- a/packages/backend/src/misc/is-not-null.ts +++ b/packages/backend/src/misc/is-not-null.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // we are using {} as "any non-nullish value" as expected // eslint-disable-next-line @typescript-eslint/ban-types export function isNotNull(input: T | undefined | null): input is T { diff --git a/packages/backend/src/misc/is-quote.ts b/packages/backend/src/misc/is-quote.ts index 248b25a0bf..c9f3af15fc 100644 --- a/packages/backend/src/misc/is-quote.ts +++ b/packages/backend/src/misc/is-quote.ts @@ -1,5 +1,11 @@ -import type { Note } from '@/models/entities/Note.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ -export default function(note: Note): boolean { +import type { MiNote } from '@/models/entities/Note.js'; + +// eslint-disable-next-line import/no-default-export +export default function(note: MiNote): boolean { return note.renoteId != null && (note.text != null || note.hasPoll || (note.fileIds != null && note.fileIds.length > 0)); } diff --git a/packages/backend/src/misc/is-user-related.ts b/packages/backend/src/misc/is-user-related.ts index e6bbdb5d35..edd65a3c1c 100644 --- a/packages/backend/src/misc/is-user-related.ts +++ b/packages/backend/src/misc/is-user-related.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function isUserRelated(note: any, userIds: Set): boolean { if (userIds.has(note.userId)) { return true; diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts index ec6bc4a5fb..80c1041c62 100644 --- a/packages/backend/src/misc/json-schema.ts +++ b/packages/backend/src/misc/json-schema.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { packedUserLiteSchema, packedUserDetailedNotMeOnlySchema, @@ -30,6 +35,7 @@ import { packedQueueCountSchema } from '@/models/json-schema/queue.js'; import { packedGalleryPostSchema } from '@/models/json-schema/gallery-post.js'; import { packedEmojiDetailedSchema, packedEmojiSimpleSchema } from '@/models/json-schema/emoji.js'; import { packedFlashSchema } from '@/models/json-schema/flash.js'; +import { packedAnnouncementSchema } from '@/models/json-schema/announcement.js'; export const refs = { UserLite: packedUserLiteSchema, @@ -41,6 +47,7 @@ export const refs = { User: packedUserSchema, UserList: packedUserListSchema, + Announcement: packedAnnouncementSchema, App: packedAppSchema, Note: packedNoteSchema, NoteReaction: packedNoteReactionSchema, diff --git a/packages/backend/src/misc/langmap.ts b/packages/backend/src/misc/langmap.ts index 5ee85e6c09..9e287677df 100644 --- a/packages/backend/src/misc/langmap.ts +++ b/packages/backend/src/misc/langmap.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // TODO: sharedに置いてフロントエンドのと統合したい export const langmap = { 'ach': { diff --git a/packages/backend/src/misc/normalize-for-search.ts b/packages/backend/src/misc/normalize-for-search.ts index 200540566e..9d96f4169d 100644 --- a/packages/backend/src/misc/normalize-for-search.ts +++ b/packages/backend/src/misc/normalize-for-search.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function normalizeForSearch(tag: string): string { // ref. // - https://analytics-note.xyz/programming/unicode-normalization-forms/ diff --git a/packages/backend/src/misc/nyaize.ts b/packages/backend/src/misc/nyaize.ts index 350f8d2172..0ac77e1006 100644 --- a/packages/backend/src/misc/nyaize.ts +++ b/packages/backend/src/misc/nyaize.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function nyaize(text: string): string { return text // ja-JP diff --git a/packages/backend/src/misc/prelude/array.ts b/packages/backend/src/misc/prelude/array.ts index 2524eacfb3..b2f29bcecf 100644 --- a/packages/backend/src/misc/prelude/array.ts +++ b/packages/backend/src/misc/prelude/array.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { EndoRelation, Predicate } from './relation.js'; /** diff --git a/packages/backend/src/misc/prelude/await-all.ts b/packages/backend/src/misc/prelude/await-all.ts index fd9832d6f8..6b8a91f8a5 100644 --- a/packages/backend/src/misc/prelude/await-all.ts +++ b/packages/backend/src/misc/prelude/await-all.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export type Promiseable = { [K in keyof T]: Promise | T[K]; }; diff --git a/packages/backend/src/misc/prelude/math.ts b/packages/backend/src/misc/prelude/math.ts index 07b94bec30..87b5017d09 100644 --- a/packages/backend/src/misc/prelude/math.ts +++ b/packages/backend/src/misc/prelude/math.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function gcd(a: number, b: number): number { return b === 0 ? a : gcd(b, a % b); } diff --git a/packages/backend/src/misc/prelude/maybe.ts b/packages/backend/src/misc/prelude/maybe.ts index df7c4ed52a..17c100b80d 100644 --- a/packages/backend/src/misc/prelude/maybe.ts +++ b/packages/backend/src/misc/prelude/maybe.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export interface IMaybe { isJust(): this is IJust; } diff --git a/packages/backend/src/misc/prelude/relation.ts b/packages/backend/src/misc/prelude/relation.ts index 1f4703f52f..3456c1a0bc 100644 --- a/packages/backend/src/misc/prelude/relation.ts +++ b/packages/backend/src/misc/prelude/relation.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export type Predicate = (a: T) => boolean; export type Relation = (a: T, b: U) => boolean; diff --git a/packages/backend/src/misc/prelude/string.ts b/packages/backend/src/misc/prelude/string.ts index b907e0a2e1..a727ab7f1d 100644 --- a/packages/backend/src/misc/prelude/string.ts +++ b/packages/backend/src/misc/prelude/string.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function concat(xs: string[]): string { return xs.join(''); } diff --git a/packages/backend/src/misc/prelude/symbol.ts b/packages/backend/src/misc/prelude/symbol.ts index 51e12f7450..91c058a845 100644 --- a/packages/backend/src/misc/prelude/symbol.ts +++ b/packages/backend/src/misc/prelude/symbol.ts @@ -1 +1,6 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const fallback = Symbol('fallback'); diff --git a/packages/backend/src/misc/prelude/time.ts b/packages/backend/src/misc/prelude/time.ts index b21978b186..4479db1081 100644 --- a/packages/backend/src/misc/prelude/time.ts +++ b/packages/backend/src/misc/prelude/time.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + const dateTimeIntervals = { 'day': 86400000, 'hour': 3600000, diff --git a/packages/backend/src/misc/prelude/url.ts b/packages/backend/src/misc/prelude/url.ts index 5239678280..633eb98218 100644 --- a/packages/backend/src/misc/prelude/url.ts +++ b/packages/backend/src/misc/prelude/url.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /* objを検査して * 1. 配列に何も入っていない時はクエリを付けない * 2. プロパティがundefinedの時はクエリを付けない diff --git a/packages/backend/src/misc/prelude/xml.ts b/packages/backend/src/misc/prelude/xml.ts index b4469a1d8d..bca116a7ec 100644 --- a/packages/backend/src/misc/prelude/xml.ts +++ b/packages/backend/src/misc/prelude/xml.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + const map: Record = { '&': '&', '<': '<', diff --git a/packages/backend/src/misc/reset-db.ts b/packages/backend/src/misc/reset-db.ts index 835cd2ba28..a571460a59 100644 --- a/packages/backend/src/misc/reset-db.ts +++ b/packages/backend/src/misc/reset-db.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { DataSource } from 'typeorm'; export async function resetDb(db: DataSource) { diff --git a/packages/backend/src/misc/safe-for-sql.ts b/packages/backend/src/misc/safe-for-sql.ts index 02eb7f0a26..d7bdd0a81c 100644 --- a/packages/backend/src/misc/safe-for-sql.ts +++ b/packages/backend/src/misc/safe-for-sql.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function safeForSql(text: string): boolean { return !/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text); } diff --git a/packages/backend/src/misc/secure-rndstr.ts b/packages/backend/src/misc/secure-rndstr.ts index cde64c8142..01368d808a 100644 --- a/packages/backend/src/misc/secure-rndstr.ts +++ b/packages/backend/src/misc/secure-rndstr.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as crypto from 'node:crypto'; export const L_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'; diff --git a/packages/backend/src/misc/show-machine-info.ts b/packages/backend/src/misc/show-machine-info.ts index fa5a53e313..ed0fa651f1 100644 --- a/packages/backend/src/misc/show-machine-info.ts +++ b/packages/backend/src/misc/show-machine-info.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as os from 'node:os'; import sysUtils from 'systeminformation'; import type Logger from '@/logger.js'; diff --git a/packages/backend/src/misc/sql-like-escape.ts b/packages/backend/src/misc/sql-like-escape.ts index 8470dca3de..85cc7405e1 100644 --- a/packages/backend/src/misc/sql-like-escape.ts +++ b/packages/backend/src/misc/sql-like-escape.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export function sqlLikeEscape(s: string) { return s.replace(/([%_])/g, '\\$1'); } diff --git a/packages/backend/src/misc/status-error.ts b/packages/backend/src/misc/status-error.ts index 0a33f8acaf..4285685d24 100644 --- a/packages/backend/src/misc/status-error.ts +++ b/packages/backend/src/misc/status-error.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export class StatusError extends Error { public statusCode: number; public statusMessage?: string; diff --git a/packages/backend/src/misc/truncate.ts b/packages/backend/src/misc/truncate.ts index cb120331a1..b65202fbd4 100644 --- a/packages/backend/src/misc/truncate.ts +++ b/packages/backend/src/misc/truncate.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { substring } from 'stringz'; export function truncate(input: string, size: number): string; diff --git a/packages/backend/src/models/RepositoryModule.ts b/packages/backend/src/models/RepositoryModule.ts index 4231acc046..b8372b1470 100644 --- a/packages/backend/src/models/RepositoryModule.ts +++ b/packages/backend/src/models/RepositoryModule.ts @@ -1,402 +1,407 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Module } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import { User, Note, Announcement, AnnouncementRead, App, NoteFavorite, NoteThreadMuting, NoteReaction, NoteUnread, Poll, PollVote, UserProfile, UserKeypair, UserPending, AttestationChallenge, UserSecurityKey, UserPublickey, UserList, UserListJoining, UserNotePining, UserIp, UsedUsername, Following, FollowRequest, Instance, Emoji, DriveFile, DriveFolder, Meta, Muting, RenoteMuting, Blocking, SwSubscription, Hashtag, AbuseUserReport, RegistrationTicket, AuthSession, AccessToken, Signin, Page, PageLike, GalleryPost, GalleryLike, ModerationLog, Clip, ClipNote, Antenna, PromoNote, PromoRead, Relay, MutedNote, Channel, ChannelFollowing, ChannelFavorite, RegistryItem, Webhook, Ad, PasswordResetRequest, RetentionAggregation, FlashLike, Flash, Role, RoleAssignment, ClipFavorite, UserMemo, UserListFavorite } from './index.js'; +import { MiAbuseUserReport, MiAccessToken, MiAd, MiAnnouncement, MiAnnouncementRead, MiAntenna, MiApp, MiAttestationChallenge, MiAuthSession, MiBlocking, MiChannel, MiChannelFavorite, MiChannelFollowing, MiClip, MiClipFavorite, MiClipNote, MiDriveFile, MiDriveFolder, MiEmoji, MiFlash, MiFlashLike, MiFollowRequest, MiFollowing, MiGalleryLike, MiGalleryPost, MiHashtag, MiInstance, MiMeta, MiModerationLog, MiMutedNote, MiMuting, MiNote, MiNoteFavorite, MiNoteReaction, MiNoteThreadMuting, MiNoteUnread, MiPage, MiPageLike, MiPasswordResetRequest, MiPoll, MiPollVote, MiPromoNote, MiPromoRead, MiRegistrationTicket, MiRegistryItem, MiRelay, MiRenoteMuting, MiRetentionAggregation, MiRole, MiRoleAssignment, MiSignin, MiSwSubscription, MiUsedUsername, MiUser, MiUserIp, MiUserKeypair, MiUserList, MiUserListFavorite, MiUserListJoining, MiUserMemo, MiUserNotePining, MiUserPending, MiUserProfile, MiUserPublickey, MiUserSecurityKey, MiWebhook } from './index.js'; import type { DataSource } from 'typeorm'; import type { Provider } from '@nestjs/common'; const $usersRepository: Provider = { provide: DI.usersRepository, - useFactory: (db: DataSource) => db.getRepository(User), + useFactory: (db: DataSource) => db.getRepository(MiUser), inject: [DI.db], }; const $notesRepository: Provider = { provide: DI.notesRepository, - useFactory: (db: DataSource) => db.getRepository(Note), + useFactory: (db: DataSource) => db.getRepository(MiNote), inject: [DI.db], }; const $announcementsRepository: Provider = { provide: DI.announcementsRepository, - useFactory: (db: DataSource) => db.getRepository(Announcement), + useFactory: (db: DataSource) => db.getRepository(MiAnnouncement), inject: [DI.db], }; const $announcementReadsRepository: Provider = { provide: DI.announcementReadsRepository, - useFactory: (db: DataSource) => db.getRepository(AnnouncementRead), + useFactory: (db: DataSource) => db.getRepository(MiAnnouncementRead), inject: [DI.db], }; const $appsRepository: Provider = { provide: DI.appsRepository, - useFactory: (db: DataSource) => db.getRepository(App), + useFactory: (db: DataSource) => db.getRepository(MiApp), inject: [DI.db], }; const $noteFavoritesRepository: Provider = { provide: DI.noteFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(NoteFavorite), + useFactory: (db: DataSource) => db.getRepository(MiNoteFavorite), inject: [DI.db], }; const $noteThreadMutingsRepository: Provider = { provide: DI.noteThreadMutingsRepository, - useFactory: (db: DataSource) => db.getRepository(NoteThreadMuting), + useFactory: (db: DataSource) => db.getRepository(MiNoteThreadMuting), inject: [DI.db], }; const $noteReactionsRepository: Provider = { provide: DI.noteReactionsRepository, - useFactory: (db: DataSource) => db.getRepository(NoteReaction), + useFactory: (db: DataSource) => db.getRepository(MiNoteReaction), inject: [DI.db], }; const $noteUnreadsRepository: Provider = { provide: DI.noteUnreadsRepository, - useFactory: (db: DataSource) => db.getRepository(NoteUnread), + useFactory: (db: DataSource) => db.getRepository(MiNoteUnread), inject: [DI.db], }; const $pollsRepository: Provider = { provide: DI.pollsRepository, - useFactory: (db: DataSource) => db.getRepository(Poll), + useFactory: (db: DataSource) => db.getRepository(MiPoll), inject: [DI.db], }; const $pollVotesRepository: Provider = { provide: DI.pollVotesRepository, - useFactory: (db: DataSource) => db.getRepository(PollVote), + useFactory: (db: DataSource) => db.getRepository(MiPollVote), inject: [DI.db], }; const $userProfilesRepository: Provider = { provide: DI.userProfilesRepository, - useFactory: (db: DataSource) => db.getRepository(UserProfile), + useFactory: (db: DataSource) => db.getRepository(MiUserProfile), inject: [DI.db], }; const $userKeypairsRepository: Provider = { provide: DI.userKeypairsRepository, - useFactory: (db: DataSource) => db.getRepository(UserKeypair), + useFactory: (db: DataSource) => db.getRepository(MiUserKeypair), inject: [DI.db], }; const $userPendingsRepository: Provider = { provide: DI.userPendingsRepository, - useFactory: (db: DataSource) => db.getRepository(UserPending), + useFactory: (db: DataSource) => db.getRepository(MiUserPending), inject: [DI.db], }; const $attestationChallengesRepository: Provider = { provide: DI.attestationChallengesRepository, - useFactory: (db: DataSource) => db.getRepository(AttestationChallenge), + useFactory: (db: DataSource) => db.getRepository(MiAttestationChallenge), inject: [DI.db], }; const $userSecurityKeysRepository: Provider = { provide: DI.userSecurityKeysRepository, - useFactory: (db: DataSource) => db.getRepository(UserSecurityKey), + useFactory: (db: DataSource) => db.getRepository(MiUserSecurityKey), inject: [DI.db], }; const $userPublickeysRepository: Provider = { provide: DI.userPublickeysRepository, - useFactory: (db: DataSource) => db.getRepository(UserPublickey), + useFactory: (db: DataSource) => db.getRepository(MiUserPublickey), inject: [DI.db], }; const $userListsRepository: Provider = { provide: DI.userListsRepository, - useFactory: (db: DataSource) => db.getRepository(UserList), + useFactory: (db: DataSource) => db.getRepository(MiUserList), inject: [DI.db], }; const $userListFavoritesRepository: Provider = { provide: DI.userListFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(UserListFavorite), + useFactory: (db: DataSource) => db.getRepository(MiUserListFavorite), inject: [DI.db], }; const $userListJoiningsRepository: Provider = { provide: DI.userListJoiningsRepository, - useFactory: (db: DataSource) => db.getRepository(UserListJoining), + useFactory: (db: DataSource) => db.getRepository(MiUserListJoining), inject: [DI.db], }; const $userNotePiningsRepository: Provider = { provide: DI.userNotePiningsRepository, - useFactory: (db: DataSource) => db.getRepository(UserNotePining), + useFactory: (db: DataSource) => db.getRepository(MiUserNotePining), inject: [DI.db], }; const $userIpsRepository: Provider = { provide: DI.userIpsRepository, - useFactory: (db: DataSource) => db.getRepository(UserIp), + useFactory: (db: DataSource) => db.getRepository(MiUserIp), inject: [DI.db], }; const $usedUsernamesRepository: Provider = { provide: DI.usedUsernamesRepository, - useFactory: (db: DataSource) => db.getRepository(UsedUsername), + useFactory: (db: DataSource) => db.getRepository(MiUsedUsername), inject: [DI.db], }; const $followingsRepository: Provider = { provide: DI.followingsRepository, - useFactory: (db: DataSource) => db.getRepository(Following), + useFactory: (db: DataSource) => db.getRepository(MiFollowing), inject: [DI.db], }; const $followRequestsRepository: Provider = { provide: DI.followRequestsRepository, - useFactory: (db: DataSource) => db.getRepository(FollowRequest), + useFactory: (db: DataSource) => db.getRepository(MiFollowRequest), inject: [DI.db], }; const $instancesRepository: Provider = { provide: DI.instancesRepository, - useFactory: (db: DataSource) => db.getRepository(Instance), + useFactory: (db: DataSource) => db.getRepository(MiInstance), inject: [DI.db], }; const $emojisRepository: Provider = { provide: DI.emojisRepository, - useFactory: (db: DataSource) => db.getRepository(Emoji), + useFactory: (db: DataSource) => db.getRepository(MiEmoji), inject: [DI.db], }; const $driveFilesRepository: Provider = { provide: DI.driveFilesRepository, - useFactory: (db: DataSource) => db.getRepository(DriveFile), + useFactory: (db: DataSource) => db.getRepository(MiDriveFile), inject: [DI.db], }; const $driveFoldersRepository: Provider = { provide: DI.driveFoldersRepository, - useFactory: (db: DataSource) => db.getRepository(DriveFolder), + useFactory: (db: DataSource) => db.getRepository(MiDriveFolder), inject: [DI.db], }; const $metasRepository: Provider = { provide: DI.metasRepository, - useFactory: (db: DataSource) => db.getRepository(Meta), + useFactory: (db: DataSource) => db.getRepository(MiMeta), inject: [DI.db], }; const $mutingsRepository: Provider = { provide: DI.mutingsRepository, - useFactory: (db: DataSource) => db.getRepository(Muting), + useFactory: (db: DataSource) => db.getRepository(MiMuting), inject: [DI.db], }; const $renoteMutingsRepository: Provider = { provide: DI.renoteMutingsRepository, - useFactory: (db: DataSource) => db.getRepository(RenoteMuting), + useFactory: (db: DataSource) => db.getRepository(MiRenoteMuting), inject: [DI.db], }; const $blockingsRepository: Provider = { provide: DI.blockingsRepository, - useFactory: (db: DataSource) => db.getRepository(Blocking), + useFactory: (db: DataSource) => db.getRepository(MiBlocking), inject: [DI.db], }; const $swSubscriptionsRepository: Provider = { provide: DI.swSubscriptionsRepository, - useFactory: (db: DataSource) => db.getRepository(SwSubscription), + useFactory: (db: DataSource) => db.getRepository(MiSwSubscription), inject: [DI.db], }; const $hashtagsRepository: Provider = { provide: DI.hashtagsRepository, - useFactory: (db: DataSource) => db.getRepository(Hashtag), + useFactory: (db: DataSource) => db.getRepository(MiHashtag), inject: [DI.db], }; const $abuseUserReportsRepository: Provider = { provide: DI.abuseUserReportsRepository, - useFactory: (db: DataSource) => db.getRepository(AbuseUserReport), + useFactory: (db: DataSource) => db.getRepository(MiAbuseUserReport), inject: [DI.db], }; const $registrationTicketsRepository: Provider = { provide: DI.registrationTicketsRepository, - useFactory: (db: DataSource) => db.getRepository(RegistrationTicket), + useFactory: (db: DataSource) => db.getRepository(MiRegistrationTicket), inject: [DI.db], }; const $authSessionsRepository: Provider = { provide: DI.authSessionsRepository, - useFactory: (db: DataSource) => db.getRepository(AuthSession), + useFactory: (db: DataSource) => db.getRepository(MiAuthSession), inject: [DI.db], }; const $accessTokensRepository: Provider = { provide: DI.accessTokensRepository, - useFactory: (db: DataSource) => db.getRepository(AccessToken), + useFactory: (db: DataSource) => db.getRepository(MiAccessToken), inject: [DI.db], }; const $signinsRepository: Provider = { provide: DI.signinsRepository, - useFactory: (db: DataSource) => db.getRepository(Signin), + useFactory: (db: DataSource) => db.getRepository(MiSignin), inject: [DI.db], }; const $pagesRepository: Provider = { provide: DI.pagesRepository, - useFactory: (db: DataSource) => db.getRepository(Page), + useFactory: (db: DataSource) => db.getRepository(MiPage), inject: [DI.db], }; const $pageLikesRepository: Provider = { provide: DI.pageLikesRepository, - useFactory: (db: DataSource) => db.getRepository(PageLike), + useFactory: (db: DataSource) => db.getRepository(MiPageLike), inject: [DI.db], }; const $galleryPostsRepository: Provider = { provide: DI.galleryPostsRepository, - useFactory: (db: DataSource) => db.getRepository(GalleryPost), + useFactory: (db: DataSource) => db.getRepository(MiGalleryPost), inject: [DI.db], }; const $galleryLikesRepository: Provider = { provide: DI.galleryLikesRepository, - useFactory: (db: DataSource) => db.getRepository(GalleryLike), + useFactory: (db: DataSource) => db.getRepository(MiGalleryLike), inject: [DI.db], }; const $moderationLogsRepository: Provider = { provide: DI.moderationLogsRepository, - useFactory: (db: DataSource) => db.getRepository(ModerationLog), + useFactory: (db: DataSource) => db.getRepository(MiModerationLog), inject: [DI.db], }; const $clipsRepository: Provider = { provide: DI.clipsRepository, - useFactory: (db: DataSource) => db.getRepository(Clip), + useFactory: (db: DataSource) => db.getRepository(MiClip), inject: [DI.db], }; const $clipNotesRepository: Provider = { provide: DI.clipNotesRepository, - useFactory: (db: DataSource) => db.getRepository(ClipNote), + useFactory: (db: DataSource) => db.getRepository(MiClipNote), inject: [DI.db], }; const $clipFavoritesRepository: Provider = { provide: DI.clipFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(ClipFavorite), + useFactory: (db: DataSource) => db.getRepository(MiClipFavorite), inject: [DI.db], }; const $antennasRepository: Provider = { provide: DI.antennasRepository, - useFactory: (db: DataSource) => db.getRepository(Antenna), + useFactory: (db: DataSource) => db.getRepository(MiAntenna), inject: [DI.db], }; const $promoNotesRepository: Provider = { provide: DI.promoNotesRepository, - useFactory: (db: DataSource) => db.getRepository(PromoNote), + useFactory: (db: DataSource) => db.getRepository(MiPromoNote), inject: [DI.db], }; const $promoReadsRepository: Provider = { provide: DI.promoReadsRepository, - useFactory: (db: DataSource) => db.getRepository(PromoRead), + useFactory: (db: DataSource) => db.getRepository(MiPromoRead), inject: [DI.db], }; const $relaysRepository: Provider = { provide: DI.relaysRepository, - useFactory: (db: DataSource) => db.getRepository(Relay), + useFactory: (db: DataSource) => db.getRepository(MiRelay), inject: [DI.db], }; const $mutedNotesRepository: Provider = { provide: DI.mutedNotesRepository, - useFactory: (db: DataSource) => db.getRepository(MutedNote), + useFactory: (db: DataSource) => db.getRepository(MiMutedNote), inject: [DI.db], }; const $channelsRepository: Provider = { provide: DI.channelsRepository, - useFactory: (db: DataSource) => db.getRepository(Channel), + useFactory: (db: DataSource) => db.getRepository(MiChannel), inject: [DI.db], }; const $channelFollowingsRepository: Provider = { provide: DI.channelFollowingsRepository, - useFactory: (db: DataSource) => db.getRepository(ChannelFollowing), + useFactory: (db: DataSource) => db.getRepository(MiChannelFollowing), inject: [DI.db], }; const $channelFavoritesRepository: Provider = { provide: DI.channelFavoritesRepository, - useFactory: (db: DataSource) => db.getRepository(ChannelFavorite), + useFactory: (db: DataSource) => db.getRepository(MiChannelFavorite), inject: [DI.db], }; const $registryItemsRepository: Provider = { provide: DI.registryItemsRepository, - useFactory: (db: DataSource) => db.getRepository(RegistryItem), + useFactory: (db: DataSource) => db.getRepository(MiRegistryItem), inject: [DI.db], }; const $webhooksRepository: Provider = { provide: DI.webhooksRepository, - useFactory: (db: DataSource) => db.getRepository(Webhook), + useFactory: (db: DataSource) => db.getRepository(MiWebhook), inject: [DI.db], }; const $adsRepository: Provider = { provide: DI.adsRepository, - useFactory: (db: DataSource) => db.getRepository(Ad), + useFactory: (db: DataSource) => db.getRepository(MiAd), inject: [DI.db], }; const $passwordResetRequestsRepository: Provider = { provide: DI.passwordResetRequestsRepository, - useFactory: (db: DataSource) => db.getRepository(PasswordResetRequest), + useFactory: (db: DataSource) => db.getRepository(MiPasswordResetRequest), inject: [DI.db], }; const $retentionAggregationsRepository: Provider = { provide: DI.retentionAggregationsRepository, - useFactory: (db: DataSource) => db.getRepository(RetentionAggregation), + useFactory: (db: DataSource) => db.getRepository(MiRetentionAggregation), inject: [DI.db], }; const $flashsRepository: Provider = { provide: DI.flashsRepository, - useFactory: (db: DataSource) => db.getRepository(Flash), + useFactory: (db: DataSource) => db.getRepository(MiFlash), inject: [DI.db], }; const $flashLikesRepository: Provider = { provide: DI.flashLikesRepository, - useFactory: (db: DataSource) => db.getRepository(FlashLike), + useFactory: (db: DataSource) => db.getRepository(MiFlashLike), inject: [DI.db], }; const $rolesRepository: Provider = { provide: DI.rolesRepository, - useFactory: (db: DataSource) => db.getRepository(Role), + useFactory: (db: DataSource) => db.getRepository(MiRole), inject: [DI.db], }; const $roleAssignmentsRepository: Provider = { provide: DI.roleAssignmentsRepository, - useFactory: (db: DataSource) => db.getRepository(RoleAssignment), + useFactory: (db: DataSource) => db.getRepository(MiRoleAssignment), inject: [DI.db], }; const $userMemosRepository: Provider = { provide: DI.userMemosRepository, - useFactory: (db: DataSource) => db.getRepository(UserMemo), + useFactory: (db: DataSource) => db.getRepository(MiUserMemo), inject: [DI.db], }; diff --git a/packages/backend/src/models/entities/AbuseUserReport.ts b/packages/backend/src/models/entities/AbuseUserReport.ts index 07305cf23a..522cc502cc 100644 --- a/packages/backend/src/models/entities/AbuseUserReport.ts +++ b/packages/backend/src/models/entities/AbuseUserReport.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class AbuseUserReport { +@Entity('abuse_user_report') +export class MiAbuseUserReport { @PrimaryColumn(id()) public id: string; @@ -15,35 +20,35 @@ export class AbuseUserReport { @Index() @Column(id()) - public targetUserId: User['id']; + public targetUserId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public targetUser: User | null; + public targetUser: MiUser | null; @Index() @Column(id()) - public reporterId: User['id']; + public reporterId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public reporter: User | null; + public reporter: MiUser | null; @Column({ ...id(), nullable: true, }) - public assigneeId: User['id'] | null; + public assigneeId: MiUser['id'] | null; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'SET NULL', }) @JoinColumn() - public assignee: User | null; + public assignee: MiUser | null; @Index() @Column('boolean', { diff --git a/packages/backend/src/models/entities/AccessToken.ts b/packages/backend/src/models/entities/AccessToken.ts index 8e987ffeef..08bd2483ee 100644 --- a/packages/backend/src/models/entities/AccessToken.ts +++ b/packages/backend/src/models/entities/AccessToken.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { App } from './App.js'; +import { MiUser } from './User.js'; +import { MiApp } from './App.js'; -@Entity() -export class AccessToken { +@Entity('access_token') +export class MiAccessToken { @PrimaryColumn(id()) public id: string; @@ -39,25 +44,25 @@ export class AccessToken { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column({ ...id(), nullable: true, }) - public appId: App['id'] | null; + public appId: MiApp['id'] | null; - @ManyToOne(type => App, { + @ManyToOne(type => MiApp, { onDelete: 'CASCADE', }) @JoinColumn() - public app: App | null; + public app: MiApp | null; @Column('varchar', { length: 128, diff --git a/packages/backend/src/models/entities/Ad.ts b/packages/backend/src/models/entities/Ad.ts index a496a6d276..2f84e7144e 100644 --- a/packages/backend/src/models/entities/Ad.ts +++ b/packages/backend/src/models/entities/Ad.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, Column, PrimaryColumn } from 'typeorm'; import { id } from '../id.js'; -@Entity() -export class Ad { +@Entity('ad') +export class MiAd { @PrimaryColumn(id()) public id: string; @@ -59,7 +64,7 @@ export class Ad { default: 0, nullable: false, }) public dayOfWeek: number; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/Announcement.ts b/packages/backend/src/models/entities/Announcement.ts index beb2f82462..9a2722b39c 100644 --- a/packages/backend/src/models/entities/Announcement.ts +++ b/packages/backend/src/models/entities/Announcement.ts @@ -1,8 +1,14 @@ -import { Entity, Index, Column, PrimaryColumn } from 'typeorm'; -import { id } from '../id.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ -@Entity() -export class Announcement { +import { Entity, Index, Column, PrimaryColumn, ManyToOne, JoinColumn } from 'typeorm'; +import { id } from '../id.js'; +import { MiUser } from './User.js'; + +@Entity('announcement') +export class MiAnnouncement { @PrimaryColumn(id()) public id: string; @@ -33,7 +39,53 @@ export class Announcement { }) public imageUrl: string | null; - constructor(data: Partial) { + // info, warning, error, success + @Column('varchar', { + length: 256, nullable: false, + default: 'info', + }) + public icon: string; + + // normal ... お知らせページ掲載 + // banner ... お知らせページ掲載 + バナー表示 + // dialog ... お知らせページ掲載 + ダイアログ表示 + @Column('varchar', { + length: 256, nullable: false, + default: 'normal', + }) + public display: string; + + @Column('boolean', { + default: false, + }) + public needConfirmationToRead: boolean; + + @Index() + @Column('boolean', { + default: true, + }) + public isActive: boolean; + + @Index() + @Column('boolean', { + default: false, + }) + public forExistingUsers: boolean; + + @Index() + @Column({ + ...id(), + nullable: true, + }) + public userId: MiUser['id'] | null; + + @ManyToOne(type => MiUser, { + onDelete: 'CASCADE', + }) + @JoinColumn() + public user: MiUser | null; + + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/AnnouncementRead.ts b/packages/backend/src/models/entities/AnnouncementRead.ts index 72cf688800..89dadaab37 100644 --- a/packages/backend/src/models/entities/AnnouncementRead.ts +++ b/packages/backend/src/models/entities/AnnouncementRead.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Announcement } from './Announcement.js'; +import { MiUser } from './User.js'; +import { MiAnnouncement } from './Announcement.js'; -@Entity() +@Entity('announcement_read') @Index(['userId', 'announcementId'], { unique: true }) -export class AnnouncementRead { +export class MiAnnouncementRead { @PrimaryColumn(id()) public id: string; @@ -16,21 +21,21 @@ export class AnnouncementRead { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column(id()) - public announcementId: Announcement['id']; + public announcementId: MiAnnouncement['id']; - @ManyToOne(type => Announcement, { + @ManyToOne(type => MiAnnouncement, { onDelete: 'CASCADE', }) @JoinColumn() - public announcement: Announcement | null; + public announcement: MiAnnouncement | null; } diff --git a/packages/backend/src/models/entities/Antenna.ts b/packages/backend/src/models/entities/Antenna.ts index e63e7f2c72..e73a4d55c6 100644 --- a/packages/backend/src/models/entities/Antenna.ts +++ b/packages/backend/src/models/entities/Antenna.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { UserList } from './UserList.js'; +import { MiUser } from './User.js'; +import { MiUserList } from './UserList.js'; -@Entity() -export class Antenna { +@Entity('antenna') +export class MiAntenna { @PrimaryColumn(id()) public id: string; @@ -22,13 +27,13 @@ export class Antenna { ...id(), comment: 'The owner ID.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, @@ -43,13 +48,13 @@ export class Antenna { ...id(), nullable: true, }) - public userListId: UserList['id'] | null; + public userListId: MiUserList['id'] | null; - @ManyToOne(type => UserList, { + @ManyToOne(type => MiUserList, { onDelete: 'CASCADE', }) @JoinColumn() - public userList: UserList | null; + public userList: MiUserList | null; @Column('varchar', { length: 1024, array: true, diff --git a/packages/backend/src/models/entities/App.ts b/packages/backend/src/models/entities/App.ts index 3a1ea7732e..99c41a2035 100644 --- a/packages/backend/src/models/entities/App.ts +++ b/packages/backend/src/models/entities/App.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, PrimaryColumn, Column, Index, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class App { +@Entity('app') +export class MiApp { @PrimaryColumn(id()) public id: string; @@ -19,13 +24,13 @@ export class App { nullable: true, comment: 'The owner ID.', }) - public userId: User['id'] | null; + public userId: MiUser['id'] | null; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'SET NULL', nullable: true, }) - public user: User | null; + public user: MiUser | null; @Index() @Column('varchar', { diff --git a/packages/backend/src/models/entities/AttestationChallenge.ts b/packages/backend/src/models/entities/AttestationChallenge.ts index 4795642657..dace378eff 100644 --- a/packages/backend/src/models/entities/AttestationChallenge.ts +++ b/packages/backend/src/models/entities/AttestationChallenge.ts @@ -1,21 +1,26 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, JoinColumn, Column, ManyToOne, Index } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class AttestationChallenge { +@Entity('attestation_challenge') +export class MiAttestationChallenge { @PrimaryColumn(id()) public id: string; @Index() @PrimaryColumn(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column('varchar', { @@ -36,7 +41,7 @@ export class AttestationChallenge { }) public registrationChallenge: boolean; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/AuthSession.ts b/packages/backend/src/models/entities/AuthSession.ts index 6b2f50e8d6..1aabf836db 100644 --- a/packages/backend/src/models/entities/AuthSession.ts +++ b/packages/backend/src/models/entities/AuthSession.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, PrimaryColumn, Index, Column, ManyToOne, JoinColumn } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { App } from './App.js'; +import { MiUser } from './User.js'; +import { MiApp } from './App.js'; -@Entity() -export class AuthSession { +@Entity('auth_session') +export class MiAuthSession { @PrimaryColumn(id()) public id: string; @@ -23,21 +28,21 @@ export class AuthSession { ...id(), nullable: true, }) - public userId: User['id'] | null; + public userId: MiUser['id'] | null; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', nullable: true, }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public appId: App['id']; + public appId: MiApp['id']; - @ManyToOne(type => App, { + @ManyToOne(type => MiApp, { onDelete: 'CASCADE', }) @JoinColumn() - public app: App | null; + public app: MiApp | null; } diff --git a/packages/backend/src/models/entities/Blocking.ts b/packages/backend/src/models/entities/Blocking.ts index 9892ff308e..8bedb4395c 100644 --- a/packages/backend/src/models/entities/Blocking.ts +++ b/packages/backend/src/models/entities/Blocking.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('blocking') @Index(['blockerId', 'blockeeId'], { unique: true }) -export class Blocking { +export class MiBlocking { @PrimaryColumn(id()) public id: string; @@ -19,24 +24,24 @@ export class Blocking { ...id(), comment: 'The blockee user ID.', }) - public blockeeId: User['id']; + public blockeeId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public blockee: User | null; + public blockee: MiUser | null; @Index() @Column({ ...id(), comment: 'The blocker user ID.', }) - public blockerId: User['id']; + public blockerId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public blocker: User | null; + public blocker: MiUser | null; } diff --git a/packages/backend/src/models/entities/Channel.ts b/packages/backend/src/models/entities/Channel.ts index d7c4583da3..9a89b650a9 100644 --- a/packages/backend/src/models/entities/Channel.ts +++ b/packages/backend/src/models/entities/Channel.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { DriveFile } from './DriveFile.js'; +import { MiUser } from './User.js'; +import { MiDriveFile } from './DriveFile.js'; -@Entity() -export class Channel { +@Entity('channel') +export class MiChannel { @PrimaryColumn(id()) public id: string; @@ -26,13 +31,13 @@ export class Channel { nullable: true, comment: 'The owner ID.', }) - public userId: User['id'] | null; + public userId: MiUser['id'] | null; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'SET NULL', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, @@ -51,13 +56,13 @@ export class Channel { nullable: true, comment: 'The ID of banner Channel.', }) - public bannerId: DriveFile['id'] | null; + public bannerId: MiDriveFile['id'] | null; - @ManyToOne(type => DriveFile, { + @ManyToOne(type => MiDriveFile, { onDelete: 'SET NULL', }) @JoinColumn() - public banner: DriveFile | null; + public banner: MiDriveFile | null; @Column('varchar', { array: true, length: 128, default: '{}', @@ -89,4 +94,9 @@ export class Channel { comment: 'The count of users.', }) public usersCount: number; + + @Column('boolean', { + default: false, + }) + public isSensitive: boolean; } diff --git a/packages/backend/src/models/entities/ChannelFavorite.ts b/packages/backend/src/models/entities/ChannelFavorite.ts index cfb2c892cf..c2be68ab7d 100644 --- a/packages/backend/src/models/entities/ChannelFavorite.ts +++ b/packages/backend/src/models/entities/ChannelFavorite.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Channel } from './Channel.js'; +import { MiUser } from './User.js'; +import { MiChannel } from './Channel.js'; -@Entity() +@Entity('channel_favorite') @Index(['userId', 'channelId'], { unique: true }) -export class ChannelFavorite { +export class MiChannelFavorite { @PrimaryColumn(id()) public id: string; @@ -19,23 +24,23 @@ export class ChannelFavorite { @Column({ ...id(), }) - public channelId: Channel['id']; + public channelId: MiChannel['id']; - @ManyToOne(type => Channel, { + @ManyToOne(type => MiChannel, { onDelete: 'CASCADE', }) @JoinColumn() - public channel: Channel | null; + public channel: MiChannel | null; @Index() @Column({ ...id(), }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; } diff --git a/packages/backend/src/models/entities/ChannelFollowing.ts b/packages/backend/src/models/entities/ChannelFollowing.ts index c65c38b67d..dc33eb144b 100644 --- a/packages/backend/src/models/entities/ChannelFollowing.ts +++ b/packages/backend/src/models/entities/ChannelFollowing.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Channel } from './Channel.js'; +import { MiUser } from './User.js'; +import { MiChannel } from './Channel.js'; -@Entity() +@Entity('channel_following') @Index(['followerId', 'followeeId'], { unique: true }) -export class ChannelFollowing { +export class MiChannelFollowing { @PrimaryColumn(id()) public id: string; @@ -20,24 +25,24 @@ export class ChannelFollowing { ...id(), comment: 'The followee channel ID.', }) - public followeeId: Channel['id']; + public followeeId: MiChannel['id']; - @ManyToOne(type => Channel, { + @ManyToOne(type => MiChannel, { onDelete: 'CASCADE', }) @JoinColumn() - public followee: Channel | null; + public followee: MiChannel | null; @Index() @Column({ ...id(), comment: 'The follower user ID.', }) - public followerId: User['id']; + public followerId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public follower: User | null; + public follower: MiUser | null; } diff --git a/packages/backend/src/models/entities/Clip.ts b/packages/backend/src/models/entities/Clip.ts index 825a32c981..f8bc2f2173 100644 --- a/packages/backend/src/models/entities/Clip.ts +++ b/packages/backend/src/models/entities/Clip.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class Clip { +@Entity('clip') +export class MiClip { @PrimaryColumn(id()) public id: string; @@ -23,13 +28,13 @@ export class Clip { ...id(), comment: 'The owner ID.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, diff --git a/packages/backend/src/models/entities/ClipFavorite.ts b/packages/backend/src/models/entities/ClipFavorite.ts index 623471e671..74d765411d 100644 --- a/packages/backend/src/models/entities/ClipFavorite.ts +++ b/packages/backend/src/models/entities/ClipFavorite.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Clip } from './Clip.js'; +import { MiUser } from './User.js'; +import { MiClip } from './Clip.js'; -@Entity() +@Entity('clip_favorite') @Index(['userId', 'clipId'], { unique: true }) -export class ClipFavorite { +export class MiClipFavorite { @PrimaryColumn(id()) public id: string; @@ -14,20 +19,20 @@ export class ClipFavorite { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public clipId: Clip['id']; + public clipId: MiClip['id']; - @ManyToOne(type => Clip, { + @ManyToOne(type => MiClip, { onDelete: 'CASCADE', }) @JoinColumn() - public clip: Clip | null; + public clip: MiClip | null; } diff --git a/packages/backend/src/models/entities/ClipNote.ts b/packages/backend/src/models/entities/ClipNote.ts index bc9ef4b874..ed5458864f 100644 --- a/packages/backend/src/models/entities/ClipNote.ts +++ b/packages/backend/src/models/entities/ClipNote.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm'; import { id } from '../id.js'; -import { Note } from './Note.js'; -import { Clip } from './Clip.js'; +import { MiNote } from './Note.js'; +import { MiClip } from './Clip.js'; -@Entity() +@Entity('clip_note') @Index(['noteId', 'clipId'], { unique: true }) -export class ClipNote { +export class MiClipNote { @PrimaryColumn(id()) public id: string; @@ -14,24 +19,24 @@ export class ClipNote { ...id(), comment: 'The note ID.', }) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; @Index() @Column({ ...id(), comment: 'The clip ID.', }) - public clipId: Clip['id']; + public clipId: MiClip['id']; - @ManyToOne(type => Clip, { + @ManyToOne(type => MiClip, { onDelete: 'CASCADE', }) @JoinColumn() - public clip: Clip | null; + public clip: MiClip | null; } diff --git a/packages/backend/src/models/entities/DriveFile.ts b/packages/backend/src/models/entities/DriveFile.ts index 7b9670fb92..55d6a9826c 100644 --- a/packages/backend/src/models/entities/DriveFile.ts +++ b/packages/backend/src/models/entities/DriveFile.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { DriveFolder } from './DriveFolder.js'; +import { MiUser } from './User.js'; +import { MiDriveFolder } from './DriveFolder.js'; -@Entity() +@Entity('drive_file') @Index(['userId', 'folderId', 'id']) -export class DriveFile { +export class MiDriveFile { @PrimaryColumn(id()) public id: string; @@ -21,13 +26,13 @@ export class DriveFile { nullable: true, comment: 'The owner ID.', }) - public userId: User['id'] | null; + public userId: MiUser['id'] | null; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'SET NULL', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column('varchar', { @@ -141,13 +146,13 @@ export class DriveFile { nullable: true, comment: 'The parent folder ID. If null, it means the DriveFile is located in root.', }) - public folderId: DriveFolder['id'] | null; + public folderId: MiDriveFolder['id'] | null; - @ManyToOne(type => DriveFolder, { + @ManyToOne(type => MiDriveFolder, { onDelete: 'SET NULL', }) @JoinColumn() - public folder: DriveFolder | null; + public folder: MiDriveFolder | null; @Index() @Column('boolean', { diff --git a/packages/backend/src/models/entities/DriveFolder.ts b/packages/backend/src/models/entities/DriveFolder.ts index 2a73a0875d..614974af13 100644 --- a/packages/backend/src/models/entities/DriveFolder.ts +++ b/packages/backend/src/models/entities/DriveFolder.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { JoinColumn, ManyToOne, Entity, PrimaryColumn, Index, Column } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class DriveFolder { +@Entity('drive_folder') +export class MiDriveFolder { @PrimaryColumn(id()) public id: string; @@ -25,13 +30,13 @@ export class DriveFolder { nullable: true, comment: 'The owner ID.', }) - public userId: User['id'] | null; + public userId: MiUser['id'] | null; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column({ @@ -39,11 +44,11 @@ export class DriveFolder { nullable: true, comment: 'The parent folder ID. If null, it means the DriveFolder is located in root.', }) - public parentId: DriveFolder['id'] | null; + public parentId: MiDriveFolder['id'] | null; - @ManyToOne(type => DriveFolder, { + @ManyToOne(type => MiDriveFolder, { onDelete: 'SET NULL', }) @JoinColumn() - public parent: DriveFolder | null; + public parent: MiDriveFolder | null; } diff --git a/packages/backend/src/models/entities/Emoji.ts b/packages/backend/src/models/entities/Emoji.ts index 8fd3e65f5e..a3ae1f2580 100644 --- a/packages/backend/src/models/entities/Emoji.ts +++ b/packages/backend/src/models/entities/Emoji.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, Column } from 'typeorm'; import { id } from '../id.js'; -@Entity() +@Entity('emoji') @Index(['name', 'host'], { unique: true }) -export class Emoji { +export class MiEmoji { @PrimaryColumn(id()) public id: string; diff --git a/packages/backend/src/models/entities/Flash.ts b/packages/backend/src/models/entities/Flash.ts index 4ccc908a6a..38e023332e 100644 --- a/packages/backend/src/models/entities/Flash.ts +++ b/packages/backend/src/models/entities/Flash.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class Flash { +@Entity('flash') +export class MiFlash { @PrimaryColumn(id()) public id: string; @@ -34,13 +39,13 @@ export class Flash { ...id(), comment: 'The ID of author.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 65536, @@ -56,4 +61,13 @@ export class Flash { default: 0, }) public likedCount: number; + + /** + * public ... 公開 + * private ... プロフィールには表示しない + */ + @Column('varchar', { + length: 512, default: 'public', + }) + public visibility: 'public' | 'private'; } diff --git a/packages/backend/src/models/entities/FlashLike.ts b/packages/backend/src/models/entities/FlashLike.ts index 81d39191ca..9486be3ea6 100644 --- a/packages/backend/src/models/entities/FlashLike.ts +++ b/packages/backend/src/models/entities/FlashLike.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Flash } from './Flash.js'; +import { MiUser } from './User.js'; +import { MiFlash } from './Flash.js'; -@Entity() +@Entity('flash_like') @Index(['userId', 'flashId'], { unique: true }) -export class FlashLike { +export class MiFlashLike { @PrimaryColumn(id()) public id: string; @@ -14,20 +19,20 @@ export class FlashLike { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public flashId: Flash['id']; + public flashId: MiFlash['id']; - @ManyToOne(type => Flash, { + @ManyToOne(type => MiFlash, { onDelete: 'CASCADE', }) @JoinColumn() - public flash: Flash | null; + public flash: MiFlash | null; } diff --git a/packages/backend/src/models/entities/FollowRequest.ts b/packages/backend/src/models/entities/FollowRequest.ts index 0988e7e504..28385931b7 100644 --- a/packages/backend/src/models/entities/FollowRequest.ts +++ b/packages/backend/src/models/entities/FollowRequest.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('follow_request') @Index(['followerId', 'followeeId'], { unique: true }) -export class FollowRequest { +export class MiFollowRequest { @PrimaryColumn(id()) public id: string; @@ -18,26 +23,26 @@ export class FollowRequest { ...id(), comment: 'The followee user ID.', }) - public followeeId: User['id']; + public followeeId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public followee: User | null; + public followee: MiUser | null; @Index() @Column({ ...id(), comment: 'The follower user ID.', }) - public followerId: User['id']; + public followerId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public follower: User | null; + public follower: MiUser | null; @Column('varchar', { length: 128, nullable: true, diff --git a/packages/backend/src/models/entities/Following.ts b/packages/backend/src/models/entities/Following.ts index 112afd7e6e..df509cf944 100644 --- a/packages/backend/src/models/entities/Following.ts +++ b/packages/backend/src/models/entities/Following.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('following') @Index(['followerId', 'followeeId'], { unique: true }) -export class Following { +export class MiFollowing { @PrimaryColumn(id()) public id: string; @@ -19,26 +24,26 @@ export class Following { ...id(), comment: 'The followee user ID.', }) - public followeeId: User['id']; + public followeeId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public followee: User | null; + public followee: MiUser | null; @Index() @Column({ ...id(), comment: 'The follower user ID.', }) - public followerId: User['id']; + public followerId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public follower: User | null; + public follower: MiUser | null; //#region Denormalized fields @Index() diff --git a/packages/backend/src/models/entities/GalleryLike.ts b/packages/backend/src/models/entities/GalleryLike.ts index cc54b528e9..40aeeaad0c 100644 --- a/packages/backend/src/models/entities/GalleryLike.ts +++ b/packages/backend/src/models/entities/GalleryLike.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { GalleryPost } from './GalleryPost.js'; +import { MiUser } from './User.js'; +import { MiGalleryPost } from './GalleryPost.js'; -@Entity() +@Entity('gallery_like') @Index(['userId', 'postId'], { unique: true }) -export class GalleryLike { +export class MiGalleryLike { @PrimaryColumn(id()) public id: string; @@ -14,20 +19,20 @@ export class GalleryLike { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public postId: GalleryPost['id']; + public postId: MiGalleryPost['id']; - @ManyToOne(type => GalleryPost, { + @ManyToOne(type => MiGalleryPost, { onDelete: 'CASCADE', }) @JoinColumn() - public post: GalleryPost | null; + public post: MiGalleryPost | null; } diff --git a/packages/backend/src/models/entities/GalleryPost.ts b/packages/backend/src/models/entities/GalleryPost.ts index 36e879afa7..777fe942e1 100644 --- a/packages/backend/src/models/entities/GalleryPost.ts +++ b/packages/backend/src/models/entities/GalleryPost.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import type { DriveFile } from './DriveFile.js'; +import { MiUser } from './User.js'; +import type { MiDriveFile } from './DriveFile.js'; -@Entity() -export class GalleryPost { +@Entity('gallery_post') +export class MiGalleryPost { @PrimaryColumn(id()) public id: string; @@ -35,20 +40,20 @@ export class GalleryPost { ...id(), comment: 'The ID of author.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column({ ...id(), array: true, default: '{}', }) - public fileIds: DriveFile['id'][]; + public fileIds: MiDriveFile['id'][]; @Index() @Column('boolean', { @@ -69,7 +74,7 @@ export class GalleryPost { }) public tags: string[]; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/Hashtag.ts b/packages/backend/src/models/entities/Hashtag.ts index 2d6bfaa045..30fea91b7d 100644 --- a/packages/backend/src/models/entities/Hashtag.ts +++ b/packages/backend/src/models/entities/Hashtag.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, PrimaryColumn, Index, Column } from 'typeorm'; import { id } from '../id.js'; -import type { User } from './User.js'; +import type { MiUser } from './User.js'; -@Entity() -export class Hashtag { +@Entity('hashtag') +export class MiHashtag { @PrimaryColumn(id()) public id: string; @@ -17,7 +22,7 @@ export class Hashtag { ...id(), array: true, }) - public mentionedUserIds: User['id'][]; + public mentionedUserIds: MiUser['id'][]; @Index() @Column('integer', { @@ -29,7 +34,7 @@ export class Hashtag { ...id(), array: true, }) - public mentionedLocalUserIds: User['id'][]; + public mentionedLocalUserIds: MiUser['id'][]; @Index() @Column('integer', { @@ -41,7 +46,7 @@ export class Hashtag { ...id(), array: true, }) - public mentionedRemoteUserIds: User['id'][]; + public mentionedRemoteUserIds: MiUser['id'][]; @Index() @Column('integer', { @@ -53,7 +58,7 @@ export class Hashtag { ...id(), array: true, }) - public attachedUserIds: User['id'][]; + public attachedUserIds: MiUser['id'][]; @Index() @Column('integer', { @@ -65,7 +70,7 @@ export class Hashtag { ...id(), array: true, }) - public attachedLocalUserIds: User['id'][]; + public attachedLocalUserIds: MiUser['id'][]; @Index() @Column('integer', { @@ -77,7 +82,7 @@ export class Hashtag { ...id(), array: true, }) - public attachedRemoteUserIds: User['id'][]; + public attachedRemoteUserIds: MiUser['id'][]; @Index() @Column('integer', { diff --git a/packages/backend/src/models/entities/Instance.ts b/packages/backend/src/models/entities/Instance.ts index 09328b57f8..8c562ffa80 100644 --- a/packages/backend/src/models/entities/Instance.ts +++ b/packages/backend/src/models/entities/Instance.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, PrimaryColumn, Index, Column } from 'typeorm'; import { id } from '../id.js'; -@Entity() -export class Instance { +@Entity('instance') +export class MiInstance { @PrimaryColumn(id()) public id: string; diff --git a/packages/backend/src/models/entities/Meta.ts b/packages/backend/src/models/entities/Meta.ts index 7bb1b67712..5a9c875a78 100644 --- a/packages/backend/src/models/entities/Meta.ts +++ b/packages/backend/src/models/entities/Meta.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Column, PrimaryColumn, ManyToOne, JoinColumn } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class Meta { +@Entity('meta') +export class MiMeta { @PrimaryColumn({ type: 'varchar', length: 32, @@ -121,7 +126,7 @@ export class Meta { public infoImageUrl: string | null; @Column('boolean', { - default: true, + default: false, }) public cacheRemoteFiles: boolean; @@ -134,13 +139,13 @@ export class Meta { ...id(), nullable: true, }) - public proxyAccountId: User['id'] | null; + public proxyAccountId: MiUser['id'] | null; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'SET NULL', }) @JoinColumn() - public proxyAccount: User | null; + public proxyAccount: MiUser | null; @Column('boolean', { default: false, diff --git a/packages/backend/src/models/entities/ModerationLog.ts b/packages/backend/src/models/entities/ModerationLog.ts index ab6a226cf7..027645de6b 100644 --- a/packages/backend/src/models/entities/ModerationLog.ts +++ b/packages/backend/src/models/entities/ModerationLog.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class ModerationLog { +@Entity('moderation_log') +export class MiModerationLog { @PrimaryColumn(id()) public id: string; @@ -14,13 +19,13 @@ export class ModerationLog { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, diff --git a/packages/backend/src/models/entities/MutedNote.ts b/packages/backend/src/models/entities/MutedNote.ts index 78347d8917..d33af90a97 100644 --- a/packages/backend/src/models/entities/MutedNote.ts +++ b/packages/backend/src/models/entities/MutedNote.ts @@ -1,12 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm'; import { id } from '../id.js'; import { mutedNoteReasons } from '../../types.js'; -import { Note } from './Note.js'; -import { User } from './User.js'; +import { MiNote } from './Note.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('muted_note') @Index(['noteId', 'userId'], { unique: true }) -export class MutedNote { +export class MiMutedNote { @PrimaryColumn(id()) public id: string; @@ -15,26 +20,26 @@ export class MutedNote { ...id(), comment: 'The note ID.', }) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; @Index() @Column({ ...id(), comment: 'The user ID.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; /** * ミュートされた理由。 diff --git a/packages/backend/src/models/entities/Muting.ts b/packages/backend/src/models/entities/Muting.ts index bf5498b96a..b1f12f0118 100644 --- a/packages/backend/src/models/entities/Muting.ts +++ b/packages/backend/src/models/entities/Muting.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('muting') @Index(['muterId', 'muteeId'], { unique: true }) -export class Muting { +export class MiMuting { @PrimaryColumn(id()) public id: string; @@ -25,24 +30,24 @@ export class Muting { ...id(), comment: 'The mutee user ID.', }) - public muteeId: User['id']; + public muteeId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public mutee: User | null; + public mutee: MiUser | null; @Index() @Column({ ...id(), comment: 'The muter user ID.', }) - public muterId: User['id']; + public muterId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public muter: User | null; + public muter: MiUser | null; } diff --git a/packages/backend/src/models/entities/Note.ts b/packages/backend/src/models/entities/Note.ts index 4f49a05950..42343f015b 100644 --- a/packages/backend/src/models/entities/Note.ts +++ b/packages/backend/src/models/entities/Note.ts @@ -1,15 +1,20 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; import { id } from '../id.js'; import { noteVisibilities } from '../../types.js'; -import { User } from './User.js'; -import { Channel } from './Channel.js'; -import type { DriveFile } from './DriveFile.js'; +import { MiUser } from './User.js'; +import { MiChannel } from './Channel.js'; +import type { MiDriveFile } from './DriveFile.js'; -@Entity() +@Entity('note') @Index('IDX_NOTE_TAGS', { synchronize: false }) @Index('IDX_NOTE_MENTIONS', { synchronize: false }) @Index('IDX_NOTE_VISIBLE_USER_IDS', { synchronize: false }) -export class Note { +export class MiNote { @PrimaryColumn(id()) public id: string; @@ -25,13 +30,13 @@ export class Note { nullable: true, comment: 'The ID of reply target.', }) - public replyId: Note['id'] | null; + public replyId: MiNote['id'] | null; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public reply: Note | null; + public reply: MiNote | null; @Index() @Column({ @@ -39,13 +44,13 @@ export class Note { nullable: true, comment: 'The ID of renote target.', }) - public renoteId: Note['id'] | null; + public renoteId: MiNote['id'] | null; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public renote: Note | null; + public renote: MiNote | null; @Index() @Column('varchar', { @@ -74,13 +79,13 @@ export class Note { ...id(), comment: 'The ID of author.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('boolean', { default: false, @@ -139,7 +144,7 @@ export class Note { ...id(), array: true, default: '{}', }) - public fileIds: DriveFile['id'][]; + public fileIds: MiDriveFile['id'][]; @Index() @Column('varchar', { @@ -152,14 +157,14 @@ export class Note { ...id(), array: true, default: '{}', }) - public visibleUserIds: User['id'][]; + public visibleUserIds: MiUser['id'][]; @Index() @Column({ ...id(), array: true, default: '{}', }) - public mentions: User['id'][]; + public mentions: MiUser['id'][]; @Column('text', { default: '[]', @@ -188,13 +193,13 @@ export class Note { nullable: true, comment: 'The ID of source channel.', }) - public channelId: Channel['id'] | null; + public channelId: MiChannel['id'] | null; - @ManyToOne(type => Channel, { + @ManyToOne(type => MiChannel, { onDelete: 'CASCADE', }) @JoinColumn() - public channel: Channel | null; + public channel: MiChannel | null; //#region Denormalized fields @Index() @@ -209,7 +214,7 @@ export class Note { nullable: true, comment: '[Denormalized]', }) - public replyUserId: User['id'] | null; + public replyUserId: MiUser['id'] | null; @Column('varchar', { length: 128, nullable: true, @@ -222,7 +227,7 @@ export class Note { nullable: true, comment: '[Denormalized]', }) - public renoteUserId: User['id'] | null; + public renoteUserId: MiUser['id'] | null; @Column('varchar', { length: 128, nullable: true, @@ -231,7 +236,7 @@ export class Note { public renoteUserHost: string | null; //#endregion - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/NoteFavorite.ts b/packages/backend/src/models/entities/NoteFavorite.ts index 80c97cb531..1b637e6b92 100644 --- a/packages/backend/src/models/entities/NoteFavorite.ts +++ b/packages/backend/src/models/entities/NoteFavorite.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { Note } from './Note.js'; -import { User } from './User.js'; +import { MiNote } from './Note.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('note_favorite') @Index(['userId', 'noteId'], { unique: true }) -export class NoteFavorite { +export class MiNoteFavorite { @PrimaryColumn(id()) public id: string; @@ -16,20 +21,20 @@ export class NoteFavorite { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; } diff --git a/packages/backend/src/models/entities/NoteReaction.ts b/packages/backend/src/models/entities/NoteReaction.ts index c3c381af56..19511abd12 100644 --- a/packages/backend/src/models/entities/NoteReaction.ts +++ b/packages/backend/src/models/entities/NoteReaction.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Note } from './Note.js'; +import { MiUser } from './User.js'; +import { MiNote } from './Note.js'; -@Entity() +@Entity('note_reaction') @Index(['userId', 'noteId'], { unique: true }) -export class NoteReaction { +export class MiNoteReaction { @PrimaryColumn(id()) public id: string; @@ -17,23 +22,23 @@ export class NoteReaction { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user?: User | null; + public user?: MiUser | null; @Index() @Column(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note?: Note | null; + public note?: MiNote | null; // TODO: 対象noteのuserIdを非正規化したい(「受け取ったリアクション一覧」のようなものを(JOIN無しで)実装したいため) diff --git a/packages/backend/src/models/entities/NoteThreadMuting.ts b/packages/backend/src/models/entities/NoteThreadMuting.ts index 3c884fe615..d8ccbe0f74 100644 --- a/packages/backend/src/models/entities/NoteThreadMuting.ts +++ b/packages/backend/src/models/entities/NoteThreadMuting.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('note_thread_muting') @Index(['userId', 'threadId'], { unique: true }) -export class NoteThreadMuting { +export class MiNoteThreadMuting { @PrimaryColumn(id()) public id: string; @@ -16,13 +21,13 @@ export class NoteThreadMuting { @Column({ ...id(), }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column('varchar', { diff --git a/packages/backend/src/models/entities/NoteUnread.ts b/packages/backend/src/models/entities/NoteUnread.ts index af91234d0f..0f111cc1b0 100644 --- a/packages/backend/src/models/entities/NoteUnread.ts +++ b/packages/backend/src/models/entities/NoteUnread.ts @@ -1,34 +1,39 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Note } from './Note.js'; -import type { Channel } from './Channel.js'; +import { MiUser } from './User.js'; +import { MiNote } from './Note.js'; +import type { MiChannel } from './Channel.js'; -@Entity() +@Entity('note_unread') @Index(['userId', 'noteId'], { unique: true }) -export class NoteUnread { +export class MiNoteUnread { @PrimaryColumn(id()) public id: string; @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; /** * メンションか否か @@ -50,7 +55,7 @@ export class NoteUnread { ...id(), comment: '[Denormalized]', }) - public noteUserId: User['id']; + public noteUserId: MiUser['id']; @Index() @Column({ @@ -58,6 +63,6 @@ export class NoteUnread { nullable: true, comment: '[Denormalized]', }) - public noteChannelId: Channel['id'] | null; + public noteChannelId: MiChannel['id'] | null; //#endregion } diff --git a/packages/backend/src/models/entities/Notification.ts b/packages/backend/src/models/entities/Notification.ts index aa6f997124..94c7084cf0 100644 --- a/packages/backend/src/models/entities/Notification.ts +++ b/packages/backend/src/models/entities/Notification.ts @@ -1,10 +1,15 @@ -import { notificationTypes } from '@/types.js'; -import { User } from './User.js'; -import { Note } from './Note.js'; -import { FollowRequest } from './FollowRequest.js'; -import { AccessToken } from './AccessToken.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ -export type Notification = { +import { notificationTypes } from '@/types.js'; +import { MiUser } from './User.js'; +import { MiNote } from './Note.js'; +import { MiFollowRequest } from './FollowRequest.js'; +import { MiAccessToken } from './AccessToken.js'; + +export type MiNotification = { id: string; // RedisのためDateではなくstring @@ -13,7 +18,7 @@ export type Notification = { /** * 通知の送信者(initiator) */ - notifierId: User['id'] | null; + notifierId: MiUser['id'] | null; /** * 通知の種類。 @@ -31,9 +36,9 @@ export type Notification = { */ type: typeof notificationTypes[number]; - noteId: Note['id'] | null; + noteId: MiNote['id'] | null; - followRequestId: FollowRequest['id'] | null; + followRequestId: MiFollowRequest['id'] | null; reaction: string | null; @@ -61,5 +66,5 @@ export type Notification = { /** * アプリ通知のアプリ(のトークン) */ - appAccessTokenId: AccessToken['id'] | null; + appAccessTokenId: MiAccessToken['id'] | null; } diff --git a/packages/backend/src/models/entities/Page.ts b/packages/backend/src/models/entities/Page.ts index 6078bc1bc7..30131af85c 100644 --- a/packages/backend/src/models/entities/Page.ts +++ b/packages/backend/src/models/entities/Page.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { DriveFile } from './DriveFile.js'; +import { MiUser } from './User.js'; +import { MiDriveFile } from './DriveFile.js'; -@Entity() +@Entity('page') @Index(['userId', 'name'], { unique: true }) -export class Page { +export class MiPage { @PrimaryColumn(id()) public id: string; @@ -55,25 +60,25 @@ export class Page { ...id(), comment: 'The ID of author.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column({ ...id(), nullable: true, }) - public eyeCatchingImageId: DriveFile['id'] | null; + public eyeCatchingImageId: MiDriveFile['id'] | null; - @ManyToOne(type => DriveFile, { + @ManyToOne(type => MiDriveFile, { onDelete: 'CASCADE', }) @JoinColumn() - public eyeCatchingImage: DriveFile | null; + public eyeCatchingImage: MiDriveFile | null; @Column('jsonb', { default: [], @@ -104,14 +109,14 @@ export class Page { ...id(), array: true, default: '{}', }) - public visibleUserIds: User['id'][]; + public visibleUserIds: MiUser['id'][]; @Column('integer', { default: 0, }) public likedCount: number; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/PageLike.ts b/packages/backend/src/models/entities/PageLike.ts index f8c5943a3e..36f5177cff 100644 --- a/packages/backend/src/models/entities/PageLike.ts +++ b/packages/backend/src/models/entities/PageLike.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Page } from './Page.js'; +import { MiUser } from './User.js'; +import { MiPage } from './Page.js'; -@Entity() +@Entity('page_like') @Index(['userId', 'pageId'], { unique: true }) -export class PageLike { +export class MiPageLike { @PrimaryColumn(id()) public id: string; @@ -14,20 +19,20 @@ export class PageLike { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public pageId: Page['id']; + public pageId: MiPage['id']; - @ManyToOne(type => Page, { + @ManyToOne(type => MiPage, { onDelete: 'CASCADE', }) @JoinColumn() - public page: Page | null; + public page: MiPage | null; } diff --git a/packages/backend/src/models/entities/PasswordResetRequest.ts b/packages/backend/src/models/entities/PasswordResetRequest.ts index 939fcc460f..4c608d979c 100644 --- a/packages/backend/src/models/entities/PasswordResetRequest.ts +++ b/packages/backend/src/models/entities/PasswordResetRequest.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, Column, ManyToOne, JoinColumn } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class PasswordResetRequest { +@Entity('password_reset_request') +export class MiPasswordResetRequest { @PrimaryColumn(id()) public id: string; @@ -20,11 +25,11 @@ export class PasswordResetRequest { @Column({ ...id(), }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; } diff --git a/packages/backend/src/models/entities/Poll.ts b/packages/backend/src/models/entities/Poll.ts index ee1d646020..557fd1be11 100644 --- a/packages/backend/src/models/entities/Poll.ts +++ b/packages/backend/src/models/entities/Poll.ts @@ -1,19 +1,24 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm'; import { id } from '../id.js'; import { noteVisibilities } from '../../types.js'; -import { Note } from './Note.js'; -import type { User } from './User.js'; +import { MiNote } from './Note.js'; +import type { MiUser } from './User.js'; -@Entity() -export class Poll { +@Entity('poll') +export class MiPoll { @PrimaryColumn(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @OneToOne(type => Note, { + @OneToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; @Column('timestamp with time zone', { nullable: true, @@ -45,7 +50,7 @@ export class Poll { ...id(), comment: '[Denormalized]', }) - public userId: User['id']; + public userId: MiUser['id']; @Index() @Column('varchar', { @@ -55,7 +60,7 @@ export class Poll { public userHost: string | null; //#endregion - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/PollVote.ts b/packages/backend/src/models/entities/PollVote.ts index d447a7be8f..5070ab16c0 100644 --- a/packages/backend/src/models/entities/PollVote.ts +++ b/packages/backend/src/models/entities/PollVote.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Note } from './Note.js'; +import { MiUser } from './User.js'; +import { MiNote } from './Note.js'; -@Entity() +@Entity('poll_vote') @Index(['userId', 'noteId', 'choice'], { unique: true }) -export class PollVote { +export class MiPollVote { @PrimaryColumn(id()) public id: string; @@ -17,23 +22,23 @@ export class PollVote { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; @Column('integer') public choice: number; diff --git a/packages/backend/src/models/entities/PromoNote.ts b/packages/backend/src/models/entities/PromoNote.ts index 958008338a..9daf915b51 100644 --- a/packages/backend/src/models/entities/PromoNote.ts +++ b/packages/backend/src/models/entities/PromoNote.ts @@ -1,18 +1,23 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm'; import { id } from '../id.js'; -import { Note } from './Note.js'; -import type { User } from './User.js'; +import { MiNote } from './Note.js'; +import type { MiUser } from './User.js'; -@Entity() -export class PromoNote { +@Entity('promo_note') +export class MiPromoNote { @PrimaryColumn(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @OneToOne(type => Note, { + @OneToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; @Column('timestamp with time zone') public expiresAt: Date; @@ -23,6 +28,6 @@ export class PromoNote { ...id(), comment: '[Denormalized]', }) - public userId: User['id']; + public userId: MiUser['id']; //#endregion } diff --git a/packages/backend/src/models/entities/PromoRead.ts b/packages/backend/src/models/entities/PromoRead.ts index 27f5d0dc11..83a12858e8 100644 --- a/packages/backend/src/models/entities/PromoRead.ts +++ b/packages/backend/src/models/entities/PromoRead.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { Note } from './Note.js'; -import { User } from './User.js'; +import { MiNote } from './Note.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('promo_read') @Index(['userId', 'noteId'], { unique: true }) -export class PromoRead { +export class MiPromoRead { @PrimaryColumn(id()) public id: string; @@ -16,20 +21,20 @@ export class PromoRead { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; } diff --git a/packages/backend/src/models/entities/RegistrationTicket.ts b/packages/backend/src/models/entities/RegistrationTicket.ts index 4c42b20be8..2b1c541a28 100644 --- a/packages/backend/src/models/entities/RegistrationTicket.ts +++ b/packages/backend/src/models/entities/RegistrationTicket.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, Column, ManyToOne, JoinColumn, OneToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class RegistrationTicket { +@Entity('registration_ticket') +export class MiRegistrationTicket { @PrimaryColumn(id()) public id: string; @@ -21,31 +26,31 @@ export class RegistrationTicket { @Column('timestamp with time zone') public createdAt: Date; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public createdBy: User | null; + public createdBy: MiUser | null; @Index() @Column({ ...id(), nullable: true, }) - public createdById: User['id'] | null; + public createdById: MiUser['id'] | null; - @OneToOne(type => User, { + @OneToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public usedBy: User | null; + public usedBy: MiUser | null; @Index() @Column({ ...id(), nullable: true, }) - public usedById: User['id'] | null; + public usedById: MiUser['id'] | null; @Column('timestamp with time zone', { nullable: true, diff --git a/packages/backend/src/models/entities/RegistryItem.ts b/packages/backend/src/models/entities/RegistryItem.ts index 670a236ea0..fdfa4212d0 100644 --- a/packages/backend/src/models/entities/RegistryItem.ts +++ b/packages/backend/src/models/entities/RegistryItem.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; // TODO: 同じdomain、同じscope、同じkeyのレコードは二つ以上存在しないように制約付けたい -@Entity() -export class RegistryItem { +@Entity('registry_item') +export class MiRegistryItem { @PrimaryColumn(id()) public id: string; @@ -23,13 +28,13 @@ export class RegistryItem { ...id(), comment: 'The owner ID.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 1024, diff --git a/packages/backend/src/models/entities/Relay.ts b/packages/backend/src/models/entities/Relay.ts index 94d1929574..f73ab193a6 100644 --- a/packages/backend/src/models/entities/Relay.ts +++ b/packages/backend/src/models/entities/Relay.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, Column } from 'typeorm'; import { id } from '../id.js'; -@Entity() -export class Relay { +@Entity('relay') +export class MiRelay { @PrimaryColumn(id()) public id: string; diff --git a/packages/backend/src/models/entities/RenoteMuting.ts b/packages/backend/src/models/entities/RenoteMuting.ts index 2f803a5fa8..fc87b82b7d 100644 --- a/packages/backend/src/models/entities/RenoteMuting.ts +++ b/packages/backend/src/models/entities/RenoteMuting.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('renote_muting') @Index(['muterId', 'muteeId'], { unique: true }) -export class RenoteMuting { +export class MiRenoteMuting { @PrimaryColumn(id()) public id: string; @@ -19,24 +24,24 @@ export class RenoteMuting { ...id(), comment: 'The mutee user ID.', }) - public muteeId: User['id']; + public muteeId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public mutee: User | null; + public mutee: MiUser | null; @Index() @Column({ ...id(), comment: 'The muter user ID.', }) - public muterId: User['id']; + public muterId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public muter: User | null; + public muter: MiUser | null; } diff --git a/packages/backend/src/models/entities/RetentionAggregation.ts b/packages/backend/src/models/entities/RetentionAggregation.ts index c7bf38b3af..7d7874a601 100644 --- a/packages/backend/src/models/entities/RetentionAggregation.ts +++ b/packages/backend/src/models/entities/RetentionAggregation.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, PrimaryColumn, Index, Column } from 'typeorm'; import { id } from '../id.js'; -import type { User } from './User.js'; +import type { MiUser } from './User.js'; -@Entity() -export class RetentionAggregation { +@Entity('retention_aggregation') +export class MiRetentionAggregation { @PrimaryColumn(id()) public id: string; @@ -28,7 +33,7 @@ export class RetentionAggregation { ...id(), array: true, }) - public userIds: User['id'][]; + public userIds: MiUser['id'][]; @Column('integer', { }) diff --git a/packages/backend/src/models/entities/Role.ts b/packages/backend/src/models/entities/Role.ts index 61f40d59da..52e1f0c347 100644 --- a/packages/backend/src/models/entities/Role.ts +++ b/packages/backend/src/models/entities/Role.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Column, PrimaryColumn } from 'typeorm'; import { id } from '../id.js'; @@ -79,8 +84,8 @@ export type RoleCondFormulaValue = CondFormulaValueNotesLessThanOrEq | CondFormulaValueNotesMoreThanOrEq; -@Entity() -export class Role { +@Entity('role') +export class MiRole { @PrimaryColumn(id()) public id: string; diff --git a/packages/backend/src/models/entities/RoleAssignment.ts b/packages/backend/src/models/entities/RoleAssignment.ts index 972810940f..5a2dacb91a 100644 --- a/packages/backend/src/models/entities/RoleAssignment.ts +++ b/packages/backend/src/models/entities/RoleAssignment.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { Role } from './Role.js'; -import { User } from './User.js'; +import { MiRole } from './Role.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('role_assignment') @Index(['userId', 'roleId'], { unique: true }) -export class RoleAssignment { +export class MiRoleAssignment { @PrimaryColumn(id()) public id: string; @@ -19,26 +24,26 @@ export class RoleAssignment { ...id(), comment: 'The user ID.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column({ ...id(), comment: 'The role ID.', }) - public roleId: Role['id']; + public roleId: MiRole['id']; - @ManyToOne(type => Role, { + @ManyToOne(type => MiRole, { onDelete: 'CASCADE', }) @JoinColumn() - public role: Role | null; + public role: MiRole | null; @Index() @Column('timestamp with time zone', { diff --git a/packages/backend/src/models/entities/Signin.ts b/packages/backend/src/models/entities/Signin.ts index 380bf028a6..709a998889 100644 --- a/packages/backend/src/models/entities/Signin.ts +++ b/packages/backend/src/models/entities/Signin.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class Signin { +@Entity('signin') +export class MiSignin { @PrimaryColumn(id()) public id: string; @@ -14,13 +19,13 @@ export class Signin { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, diff --git a/packages/backend/src/models/entities/SwSubscription.ts b/packages/backend/src/models/entities/SwSubscription.ts index 0658294983..9c3f97cf99 100644 --- a/packages/backend/src/models/entities/SwSubscription.ts +++ b/packages/backend/src/models/entities/SwSubscription.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class SwSubscription { +@Entity('sw_subscription') +export class MiSwSubscription { @PrimaryColumn(id()) public id: string; @@ -12,13 +17,13 @@ export class SwSubscription { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 512, diff --git a/packages/backend/src/models/entities/UsedUsername.ts b/packages/backend/src/models/entities/UsedUsername.ts index eb90bef6ca..c75bf424c1 100644 --- a/packages/backend/src/models/entities/UsedUsername.ts +++ b/packages/backend/src/models/entities/UsedUsername.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Column } from 'typeorm'; -@Entity() -export class UsedUsername { +@Entity('used_username') +export class MiUsedUsername { @PrimaryColumn('varchar', { length: 128, }) @@ -10,7 +15,7 @@ export class UsedUsername { @Column('timestamp with time zone') public createdAt: Date; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/User.ts b/packages/backend/src/models/entities/User.ts index 6669890cf6..9db141becf 100644 --- a/packages/backend/src/models/entities/User.ts +++ b/packages/backend/src/models/entities/User.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm'; import { id } from '../id.js'; -import { DriveFile } from './DriveFile.js'; +import { MiDriveFile } from './DriveFile.js'; -@Entity() +@Entity('user') @Index(['usernameLower', 'host'], { unique: true }) -export class User { +export class MiUser { @PrimaryColumn(id()) public id: string; @@ -98,26 +103,26 @@ export class User { nullable: true, comment: 'The ID of avatar DriveFile.', }) - public avatarId: DriveFile['id'] | null; + public avatarId: MiDriveFile['id'] | null; - @OneToOne(type => DriveFile, { + @OneToOne(type => MiDriveFile, { onDelete: 'SET NULL', }) @JoinColumn() - public avatar: DriveFile | null; + public avatar: MiDriveFile | null; @Column({ ...id(), nullable: true, comment: 'The ID of banner DriveFile.', }) - public bannerId: DriveFile['id'] | null; + public bannerId: MiDriveFile['id'] | null; - @OneToOne(type => DriveFile, { + @OneToOne(type => MiDriveFile, { onDelete: 'SET NULL', }) @JoinColumn() - public banner: DriveFile | null; + public banner: MiDriveFile | null; @Column('varchar', { length: 512, nullable: true, @@ -239,7 +244,7 @@ export class User { }) public token: string | null; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { @@ -248,24 +253,24 @@ export class User { } } -export type LocalUser = User & { +export type MiLocalUser = MiUser & { host: null; uri: null; } -export type PartialLocalUser = Partial & { - id: User['id']; +export type MiPartialLocalUser = Partial & { + id: MiUser['id']; host: null; uri: null; } -export type RemoteUser = User & { +export type MiRemoteUser = MiUser & { host: string; uri: string; } -export type PartialRemoteUser = Partial & { - id: User['id']; +export type MiPartialRemoteUser = Partial & { + id: MiUser['id']; host: string; uri: string; } diff --git a/packages/backend/src/models/entities/UserIp.ts b/packages/backend/src/models/entities/UserIp.ts index 628e3d0361..8384984e6b 100644 --- a/packages/backend/src/models/entities/UserIp.ts +++ b/packages/backend/src/models/entities/UserIp.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Index, Column, PrimaryGeneratedColumn } from 'typeorm'; import { id } from '../id.js'; -import type { User } from './User.js'; +import type { MiUser } from './User.js'; -@Entity() +@Entity('user_ip') @Index(['userId', 'ip'], { unique: true }) -export class UserIp { +export class MiUserIp { @PrimaryGeneratedColumn() public id: string; @@ -14,7 +19,7 @@ export class UserIp { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; @Column('varchar', { length: 128, diff --git a/packages/backend/src/models/entities/UserKeypair.ts b/packages/backend/src/models/entities/UserKeypair.ts index 3cd02d3c4f..c9ea7d11f8 100644 --- a/packages/backend/src/models/entities/UserKeypair.ts +++ b/packages/backend/src/models/entities/UserKeypair.ts @@ -1,17 +1,22 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, JoinColumn, Column, OneToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class UserKeypair { +@Entity('user_keypair') +export class MiUserKeypair { @PrimaryColumn(id()) - public userId: User['id']; + public userId: MiUser['id']; - @OneToOne(type => User, { + @OneToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 4096, @@ -23,7 +28,7 @@ export class UserKeypair { }) public privateKey: string; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/UserList.ts b/packages/backend/src/models/entities/UserList.ts index 94f3dc3cb3..a6216b5670 100644 --- a/packages/backend/src/models/entities/UserList.ts +++ b/packages/backend/src/models/entities/UserList.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class UserList { +@Entity('user_list') +export class MiUserList { @PrimaryColumn(id()) public id: string; @@ -17,7 +22,7 @@ export class UserList { ...id(), comment: 'The owner ID.', }) - public userId: User['id']; + public userId: MiUser['id']; @Index() @Column('boolean', { @@ -25,11 +30,11 @@ export class UserList { }) public isPublic: boolean; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, diff --git a/packages/backend/src/models/entities/UserListFavorite.ts b/packages/backend/src/models/entities/UserListFavorite.ts index e57abb460a..f3c4c1a4d8 100644 --- a/packages/backend/src/models/entities/UserListFavorite.ts +++ b/packages/backend/src/models/entities/UserListFavorite.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { UserList } from './UserList.js'; +import { MiUser } from './User.js'; +import { MiUserList } from './UserList.js'; -@Entity() +@Entity('user_list_favorite') @Index(['userId', 'userListId'], { unique: true }) -export class UserListFavorite { +export class MiUserListFavorite { @PrimaryColumn(id()) public id: string; @@ -14,20 +19,20 @@ export class UserListFavorite { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public userListId: UserList['id']; + public userListId: MiUserList['id']; - @ManyToOne(type => UserList, { + @ManyToOne(type => MiUserList, { onDelete: 'CASCADE', }) @JoinColumn() - public userList: UserList | null; + public userList: MiUserList | null; } diff --git a/packages/backend/src/models/entities/UserListJoining.ts b/packages/backend/src/models/entities/UserListJoining.ts index a40793a3e8..e4912024c1 100644 --- a/packages/backend/src/models/entities/UserListJoining.ts +++ b/packages/backend/src/models/entities/UserListJoining.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; -import { UserList } from './UserList.js'; +import { MiUser } from './User.js'; +import { MiUserList } from './UserList.js'; -@Entity() +@Entity('user_list_joining') @Index(['userId', 'userListId'], { unique: true }) -export class UserListJoining { +export class MiUserListJoining { @PrimaryColumn(id()) public id: string; @@ -19,24 +24,24 @@ export class UserListJoining { ...id(), comment: 'The user ID.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column({ ...id(), comment: 'The list ID.', }) - public userListId: UserList['id']; + public userListId: MiUserList['id']; - @ManyToOne(type => UserList, { + @ManyToOne(type => MiUserList, { onDelete: 'CASCADE', }) @JoinColumn() - public userList: UserList | null; + public userList: MiUserList | null; } diff --git a/packages/backend/src/models/entities/UserMemo.ts b/packages/backend/src/models/entities/UserMemo.ts index 7dc34b4346..9b89080509 100644 --- a/packages/backend/src/models/entities/UserMemo.ts +++ b/packages/backend/src/models/entities/UserMemo.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Column, Entity, Index, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('user_memo') @Index(['userId', 'targetUserId'], { unique: true }) -export class UserMemo { +export class MiUserMemo { @PrimaryColumn(id()) public id: string; @@ -13,26 +18,26 @@ export class UserMemo { ...id(), comment: 'The ID of author.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column({ ...id(), comment: 'The ID of target user.', }) - public targetUserId: User['id']; + public targetUserId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public targetUser: User | null; + public targetUser: MiUser | null; @Column('varchar', { length: 2048, diff --git a/packages/backend/src/models/entities/UserNotePining.ts b/packages/backend/src/models/entities/UserNotePining.ts index fee95d4f7d..95bcb158b6 100644 --- a/packages/backend/src/models/entities/UserNotePining.ts +++ b/packages/backend/src/models/entities/UserNotePining.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { Note } from './Note.js'; -import { User } from './User.js'; +import { MiNote } from './Note.js'; +import { MiUser } from './User.js'; -@Entity() +@Entity('user_note_pining') @Index(['userId', 'noteId'], { unique: true }) -export class UserNotePining { +export class MiUserNotePining { @PrimaryColumn(id()) public id: string; @@ -16,20 +21,20 @@ export class UserNotePining { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column(id()) - public noteId: Note['id']; + public noteId: MiNote['id']; - @ManyToOne(type => Note, { + @ManyToOne(type => MiNote, { onDelete: 'CASCADE', }) @JoinColumn() - public note: Note | null; + public note: MiNote | null; } diff --git a/packages/backend/src/models/entities/UserPending.ts b/packages/backend/src/models/entities/UserPending.ts index 7637948841..8c9e01e59c 100644 --- a/packages/backend/src/models/entities/UserPending.ts +++ b/packages/backend/src/models/entities/UserPending.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, Column } from 'typeorm'; import { id } from '../id.js'; -@Entity() -export class UserPending { +@Entity('user_pending') +export class MiUserPending { @PrimaryColumn(id()) public id: string; diff --git a/packages/backend/src/models/entities/UserProfile.ts b/packages/backend/src/models/entities/UserProfile.ts index c4ed9db9bb..54144cb429 100644 --- a/packages/backend/src/models/entities/UserProfile.ts +++ b/packages/backend/src/models/entities/UserProfile.ts @@ -1,21 +1,26 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm'; import { obsoleteNotificationTypes, ffVisibility, notificationTypes } from '@/types.js'; import { id } from '../id.js'; -import { User } from './User.js'; -import { Page } from './Page.js'; +import { MiUser } from './User.js'; +import { MiPage } from './Page.js'; // TODO: このテーブルで管理している情報すべてレジストリで管理するようにしても良いかも // ただ、「emailVerified が true なユーザーを find する」のようなクエリは書けなくなるからウーン -@Entity() -export class UserProfile { +@Entity('user_profile') +export class MiUserProfile { @PrimaryColumn(id()) - public userId: User['id']; + public userId: MiUser['id']; - @OneToOne(type => User, { + @OneToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, nullable: true, @@ -181,13 +186,13 @@ export class UserProfile { ...id(), nullable: true, }) - public pinnedPageId: Page['id'] | null; + public pinnedPageId: MiPage['id'] | null; - @OneToOne(type => Page, { + @OneToOne(type => MiPage, { onDelete: 'SET NULL', }) @JoinColumn() - public pinnedPage: Page | null; + public pinnedPage: MiPage | null; @Index() @Column('boolean', { @@ -239,7 +244,7 @@ export class UserProfile { public userHost: string | null; //#endregion - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/UserPublickey.ts b/packages/backend/src/models/entities/UserPublickey.ts index 7b505e5b4c..afa37cf7ea 100644 --- a/packages/backend/src/models/entities/UserPublickey.ts +++ b/packages/backend/src/models/entities/UserPublickey.ts @@ -1,17 +1,22 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class UserPublickey { +@Entity('user_publickey') +export class MiUserPublickey { @PrimaryColumn(id()) - public userId: User['id']; + public userId: MiUser['id']; - @OneToOne(type => User, { + @OneToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index({ unique: true }) @Column('varchar', { @@ -24,7 +29,7 @@ export class UserPublickey { }) public keyPem: string; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/UserSecurityKey.ts b/packages/backend/src/models/entities/UserSecurityKey.ts index 947692a32b..ce1c270d46 100644 --- a/packages/backend/src/models/entities/UserSecurityKey.ts +++ b/packages/backend/src/models/entities/UserSecurityKey.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, JoinColumn, Column, ManyToOne, Index } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; -@Entity() -export class UserSecurityKey { +@Entity('user_security_key') +export class MiUserSecurityKey { @PrimaryColumn('varchar', { comment: 'Variable-length id given to navigator.credentials.get()', }) @@ -11,13 +16,13 @@ export class UserSecurityKey { @Index() @Column(id()) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Index() @Column('varchar', { @@ -38,7 +43,7 @@ export class UserSecurityKey { }) public name: string; - constructor(data: Partial) { + constructor(data: Partial) { if (data == null) return; for (const [k, v] of Object.entries(data)) { diff --git a/packages/backend/src/models/entities/Webhook.ts b/packages/backend/src/models/entities/Webhook.ts index eabb604de9..f08d15825a 100644 --- a/packages/backend/src/models/entities/Webhook.ts +++ b/packages/backend/src/models/entities/Webhook.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm'; import { id } from '../id.js'; -import { User } from './User.js'; +import { MiUser } from './User.js'; export const webhookEventTypes = ['mention', 'unfollow', 'follow', 'followed', 'note', 'reply', 'renote', 'reaction'] as const; -@Entity() -export class Webhook { +@Entity('webhook') +export class MiWebhook { @PrimaryColumn(id()) public id: string; @@ -19,13 +24,13 @@ export class Webhook { ...id(), comment: 'The owner ID.', }) - public userId: User['id']; + public userId: MiUser['id']; - @ManyToOne(type => User, { + @ManyToOne(type => MiUser, { onDelete: 'CASCADE', }) @JoinColumn() - public user: User | null; + public user: MiUser | null; @Column('varchar', { length: 128, diff --git a/packages/backend/src/models/id.ts b/packages/backend/src/models/id.ts index d614fc5048..81e83b8db9 100644 --- a/packages/backend/src/models/id.ts +++ b/packages/backend/src/models/id.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const id = () => ({ type: 'varchar' as const, length: 32, diff --git a/packages/backend/src/models/index.ts b/packages/backend/src/models/index.ts index 627281df73..d14234b792 100644 --- a/packages/backend/src/models/index.ts +++ b/packages/backend/src/models/index.ts @@ -1,203 +1,208 @@ -import { AbuseUserReport } from '@/models/entities/AbuseUserReport.js'; -import { AccessToken } from '@/models/entities/AccessToken.js'; -import { Ad } from '@/models/entities/Ad.js'; -import { Announcement } from '@/models/entities/Announcement.js'; -import { AnnouncementRead } from '@/models/entities/AnnouncementRead.js'; -import { Antenna } from '@/models/entities/Antenna.js'; -import { App } from '@/models/entities/App.js'; -import { AttestationChallenge } from '@/models/entities/AttestationChallenge.js'; -import { AuthSession } from '@/models/entities/AuthSession.js'; -import { Blocking } from '@/models/entities/Blocking.js'; -import { ChannelFollowing } from '@/models/entities/ChannelFollowing.js'; -import { ChannelFavorite } from '@/models/entities/ChannelFavorite.js'; -import { Clip } from '@/models/entities/Clip.js'; -import { ClipNote } from '@/models/entities/ClipNote.js'; -import { ClipFavorite } from '@/models/entities/ClipFavorite.js'; -import { DriveFile } from '@/models/entities/DriveFile.js'; -import { DriveFolder } from '@/models/entities/DriveFolder.js'; -import { Emoji } from '@/models/entities/Emoji.js'; -import { Following } from '@/models/entities/Following.js'; -import { FollowRequest } from '@/models/entities/FollowRequest.js'; -import { GalleryLike } from '@/models/entities/GalleryLike.js'; -import { GalleryPost } from '@/models/entities/GalleryPost.js'; -import { Hashtag } from '@/models/entities/Hashtag.js'; -import { Instance } from '@/models/entities/Instance.js'; -import { Meta } from '@/models/entities/Meta.js'; -import { ModerationLog } from '@/models/entities/ModerationLog.js'; -import { MutedNote } from '@/models/entities/MutedNote.js'; -import { Muting } from '@/models/entities/Muting.js'; -import { RenoteMuting } from '@/models/entities/RenoteMuting.js'; -import { Note } from '@/models/entities/Note.js'; -import { NoteFavorite } from '@/models/entities/NoteFavorite.js'; -import { NoteReaction } from '@/models/entities/NoteReaction.js'; -import { NoteThreadMuting } from '@/models/entities/NoteThreadMuting.js'; -import { NoteUnread } from '@/models/entities/NoteUnread.js'; -import { Page } from '@/models/entities/Page.js'; -import { PageLike } from '@/models/entities/PageLike.js'; -import { PasswordResetRequest } from '@/models/entities/PasswordResetRequest.js'; -import { Poll } from '@/models/entities/Poll.js'; -import { PollVote } from '@/models/entities/PollVote.js'; -import { PromoNote } from '@/models/entities/PromoNote.js'; -import { PromoRead } from '@/models/entities/PromoRead.js'; -import { RegistrationTicket } from '@/models/entities/RegistrationTicket.js'; -import { RegistryItem } from '@/models/entities/RegistryItem.js'; -import { Relay } from '@/models/entities/Relay.js'; -import { Signin } from '@/models/entities/Signin.js'; -import { SwSubscription } from '@/models/entities/SwSubscription.js'; -import { UsedUsername } from '@/models/entities/UsedUsername.js'; -import { User } from '@/models/entities/User.js'; -import { UserIp } from '@/models/entities/UserIp.js'; -import { UserKeypair } from '@/models/entities/UserKeypair.js'; -import { UserList } from '@/models/entities/UserList.js'; -import { UserListJoining } from '@/models/entities/UserListJoining.js'; -import { UserNotePining } from '@/models/entities/UserNotePining.js'; -import { UserPending } from '@/models/entities/UserPending.js'; -import { UserProfile } from '@/models/entities/UserProfile.js'; -import { UserPublickey } from '@/models/entities/UserPublickey.js'; -import { UserSecurityKey } from '@/models/entities/UserSecurityKey.js'; -import { UserMemo } from '@/models/entities/UserMemo.js'; -import { Webhook } from '@/models/entities/Webhook.js'; -import { Channel } from '@/models/entities/Channel.js'; -import { RetentionAggregation } from '@/models/entities/RetentionAggregation.js'; -import { Role } from '@/models/entities/Role.js'; -import { RoleAssignment } from '@/models/entities/RoleAssignment.js'; -import { Flash } from '@/models/entities/Flash.js'; -import { FlashLike } from '@/models/entities/FlashLike.js'; -import { UserListFavorite } from './entities/UserListFavorite.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { MiAbuseUserReport } from '@/models/entities/AbuseUserReport.js'; +import { MiAccessToken } from '@/models/entities/AccessToken.js'; +import { MiAd } from '@/models/entities/Ad.js'; +import { MiAnnouncement } from '@/models/entities/Announcement.js'; +import { MiAnnouncementRead } from '@/models/entities/AnnouncementRead.js'; +import { MiAntenna } from '@/models/entities/Antenna.js'; +import { MiApp } from '@/models/entities/App.js'; +import { MiAttestationChallenge } from '@/models/entities/AttestationChallenge.js'; +import { MiAuthSession } from '@/models/entities/AuthSession.js'; +import { MiBlocking } from '@/models/entities/Blocking.js'; +import { MiChannelFollowing } from '@/models/entities/ChannelFollowing.js'; +import { MiChannelFavorite } from '@/models/entities/ChannelFavorite.js'; +import { MiClip } from '@/models/entities/Clip.js'; +import { MiClipNote } from '@/models/entities/ClipNote.js'; +import { MiClipFavorite } from '@/models/entities/ClipFavorite.js'; +import { MiDriveFile } from '@/models/entities/DriveFile.js'; +import { MiDriveFolder } from '@/models/entities/DriveFolder.js'; +import { MiEmoji } from '@/models/entities/Emoji.js'; +import { MiFollowing } from '@/models/entities/Following.js'; +import { MiFollowRequest } from '@/models/entities/FollowRequest.js'; +import { MiGalleryLike } from '@/models/entities/GalleryLike.js'; +import { MiGalleryPost } from '@/models/entities/GalleryPost.js'; +import { MiHashtag } from '@/models/entities/Hashtag.js'; +import { MiInstance } from '@/models/entities/Instance.js'; +import { MiMeta } from '@/models/entities/Meta.js'; +import { MiModerationLog } from '@/models/entities/ModerationLog.js'; +import { MiMutedNote } from '@/models/entities/MutedNote.js'; +import { MiMuting } from '@/models/entities/Muting.js'; +import { MiRenoteMuting } from '@/models/entities/RenoteMuting.js'; +import { MiNote } from '@/models/entities/Note.js'; +import { MiNoteFavorite } from '@/models/entities/NoteFavorite.js'; +import { MiNoteReaction } from '@/models/entities/NoteReaction.js'; +import { MiNoteThreadMuting } from '@/models/entities/NoteThreadMuting.js'; +import { MiNoteUnread } from '@/models/entities/NoteUnread.js'; +import { MiPage } from '@/models/entities/Page.js'; +import { MiPageLike } from '@/models/entities/PageLike.js'; +import { MiPasswordResetRequest } from '@/models/entities/PasswordResetRequest.js'; +import { MiPoll } from '@/models/entities/Poll.js'; +import { MiPollVote } from '@/models/entities/PollVote.js'; +import { MiPromoNote } from '@/models/entities/PromoNote.js'; +import { MiPromoRead } from '@/models/entities/PromoRead.js'; +import { MiRegistrationTicket } from '@/models/entities/RegistrationTicket.js'; +import { MiRegistryItem } from '@/models/entities/RegistryItem.js'; +import { MiRelay } from '@/models/entities/Relay.js'; +import { MiSignin } from '@/models/entities/Signin.js'; +import { MiSwSubscription } from '@/models/entities/SwSubscription.js'; +import { MiUsedUsername } from '@/models/entities/UsedUsername.js'; +import { MiUser } from '@/models/entities/User.js'; +import { MiUserIp } from '@/models/entities/UserIp.js'; +import { MiUserKeypair } from '@/models/entities/UserKeypair.js'; +import { MiUserList } from '@/models/entities/UserList.js'; +import { MiUserListJoining } from '@/models/entities/UserListJoining.js'; +import { MiUserNotePining } from '@/models/entities/UserNotePining.js'; +import { MiUserPending } from '@/models/entities/UserPending.js'; +import { MiUserProfile } from '@/models/entities/UserProfile.js'; +import { MiUserPublickey } from '@/models/entities/UserPublickey.js'; +import { MiUserSecurityKey } from '@/models/entities/UserSecurityKey.js'; +import { MiUserMemo } from '@/models/entities/UserMemo.js'; +import { MiWebhook } from '@/models/entities/Webhook.js'; +import { MiChannel } from '@/models/entities/Channel.js'; +import { MiRetentionAggregation } from '@/models/entities/RetentionAggregation.js'; +import { MiRole } from '@/models/entities/Role.js'; +import { MiRoleAssignment } from '@/models/entities/RoleAssignment.js'; +import { MiFlash } from '@/models/entities/Flash.js'; +import { MiFlashLike } from '@/models/entities/FlashLike.js'; +import { MiUserListFavorite } from './entities/UserListFavorite.js'; import type { Repository } from 'typeorm'; export { - AbuseUserReport, - AccessToken, - Ad, - Announcement, - AnnouncementRead, - Antenna, - App, - AttestationChallenge, - AuthSession, - Blocking, - ChannelFollowing, - ChannelFavorite, - Clip, - ClipNote, - ClipFavorite, - DriveFile, - DriveFolder, - Emoji, - Following, - FollowRequest, - GalleryLike, - GalleryPost, - Hashtag, - Instance, - Meta, - ModerationLog, - MutedNote, - Muting, - RenoteMuting, - Note, - NoteFavorite, - NoteReaction, - NoteThreadMuting, - NoteUnread, - Page, - PageLike, - PasswordResetRequest, - Poll, - PollVote, - PromoNote, - PromoRead, - RegistrationTicket, - RegistryItem, - Relay, - Signin, - SwSubscription, - UsedUsername, - User, - UserIp, - UserKeypair, - UserList, - UserListFavorite, - UserListJoining, - UserNotePining, - UserPending, - UserProfile, - UserPublickey, - UserSecurityKey, - Webhook, - Channel, - RetentionAggregation, - Role, - RoleAssignment, - Flash, - FlashLike, - UserMemo, + MiAbuseUserReport, + MiAccessToken, + MiAd, + MiAnnouncement, + MiAnnouncementRead, + MiAntenna, + MiApp, + MiAttestationChallenge, + MiAuthSession, + MiBlocking, + MiChannelFollowing, + MiChannelFavorite, + MiClip, + MiClipNote, + MiClipFavorite, + MiDriveFile, + MiDriveFolder, + MiEmoji, + MiFollowing, + MiFollowRequest, + MiGalleryLike, + MiGalleryPost, + MiHashtag, + MiInstance, + MiMeta, + MiModerationLog, + MiMutedNote, + MiMuting, + MiRenoteMuting, + MiNote, + MiNoteFavorite, + MiNoteReaction, + MiNoteThreadMuting, + MiNoteUnread, + MiPage, + MiPageLike, + MiPasswordResetRequest, + MiPoll, + MiPollVote, + MiPromoNote, + MiPromoRead, + MiRegistrationTicket, + MiRegistryItem, + MiRelay, + MiSignin, + MiSwSubscription, + MiUsedUsername, + MiUser, + MiUserIp, + MiUserKeypair, + MiUserList, + MiUserListFavorite, + MiUserListJoining, + MiUserNotePining, + MiUserPending, + MiUserProfile, + MiUserPublickey, + MiUserSecurityKey, + MiWebhook, + MiChannel, + MiRetentionAggregation, + MiRole, + MiRoleAssignment, + MiFlash, + MiFlashLike, + MiUserMemo, }; -export type AbuseUserReportsRepository = Repository; -export type AccessTokensRepository = Repository; -export type AdsRepository = Repository; -export type AnnouncementsRepository = Repository; -export type AnnouncementReadsRepository = Repository; -export type AntennasRepository = Repository; -export type AppsRepository = Repository; -export type AttestationChallengesRepository = Repository; -export type AuthSessionsRepository = Repository; -export type BlockingsRepository = Repository; -export type ChannelFollowingsRepository = Repository; -export type ChannelFavoritesRepository = Repository; -export type ClipsRepository = Repository; -export type ClipNotesRepository = Repository; -export type ClipFavoritesRepository = Repository; -export type DriveFilesRepository = Repository; -export type DriveFoldersRepository = Repository; -export type EmojisRepository = Repository; -export type FollowingsRepository = Repository; -export type FollowRequestsRepository = Repository; -export type GalleryLikesRepository = Repository; -export type GalleryPostsRepository = Repository; -export type HashtagsRepository = Repository; -export type InstancesRepository = Repository; -export type MetasRepository = Repository; -export type ModerationLogsRepository = Repository; -export type MutedNotesRepository = Repository; -export type MutingsRepository = Repository; -export type RenoteMutingsRepository = Repository; -export type NotesRepository = Repository; -export type NoteFavoritesRepository = Repository; -export type NoteReactionsRepository = Repository; -export type NoteThreadMutingsRepository = Repository; -export type NoteUnreadsRepository = Repository; -export type PagesRepository = Repository; -export type PageLikesRepository = Repository; -export type PasswordResetRequestsRepository = Repository; -export type PollsRepository = Repository; -export type PollVotesRepository = Repository; -export type PromoNotesRepository = Repository; -export type PromoReadsRepository = Repository; -export type RegistrationTicketsRepository = Repository; -export type RegistryItemsRepository = Repository; -export type RelaysRepository = Repository; -export type SigninsRepository = Repository; -export type SwSubscriptionsRepository = Repository; -export type UsedUsernamesRepository = Repository; -export type UsersRepository = Repository; -export type UserIpsRepository = Repository; -export type UserKeypairsRepository = Repository; -export type UserListsRepository = Repository; -export type UserListFavoritesRepository = Repository; -export type UserListJoiningsRepository = Repository; -export type UserNotePiningsRepository = Repository; -export type UserPendingsRepository = Repository; -export type UserProfilesRepository = Repository; -export type UserPublickeysRepository = Repository; -export type UserSecurityKeysRepository = Repository; -export type WebhooksRepository = Repository; -export type ChannelsRepository = Repository; -export type RetentionAggregationsRepository = Repository; -export type RolesRepository = Repository; -export type RoleAssignmentsRepository = Repository; -export type FlashsRepository = Repository; -export type FlashLikesRepository = Repository; -export type UserMemoRepository = Repository; +export type AbuseUserReportsRepository = Repository; +export type AccessTokensRepository = Repository; +export type AdsRepository = Repository; +export type AnnouncementsRepository = Repository; +export type AnnouncementReadsRepository = Repository; +export type AntennasRepository = Repository; +export type AppsRepository = Repository; +export type AttestationChallengesRepository = Repository; +export type AuthSessionsRepository = Repository; +export type BlockingsRepository = Repository; +export type ChannelFollowingsRepository = Repository; +export type ChannelFavoritesRepository = Repository; +export type ClipsRepository = Repository; +export type ClipNotesRepository = Repository; +export type ClipFavoritesRepository = Repository; +export type DriveFilesRepository = Repository; +export type DriveFoldersRepository = Repository; +export type EmojisRepository = Repository; +export type FollowingsRepository = Repository; +export type FollowRequestsRepository = Repository; +export type GalleryLikesRepository = Repository; +export type GalleryPostsRepository = Repository; +export type HashtagsRepository = Repository; +export type InstancesRepository = Repository; +export type MetasRepository = Repository; +export type ModerationLogsRepository = Repository; +export type MutedNotesRepository = Repository; +export type MutingsRepository = Repository; +export type RenoteMutingsRepository = Repository; +export type NotesRepository = Repository; +export type NoteFavoritesRepository = Repository; +export type NoteReactionsRepository = Repository; +export type NoteThreadMutingsRepository = Repository; +export type NoteUnreadsRepository = Repository; +export type PagesRepository = Repository; +export type PageLikesRepository = Repository; +export type PasswordResetRequestsRepository = Repository; +export type PollsRepository = Repository; +export type PollVotesRepository = Repository; +export type PromoNotesRepository = Repository; +export type PromoReadsRepository = Repository; +export type RegistrationTicketsRepository = Repository; +export type RegistryItemsRepository = Repository; +export type RelaysRepository = Repository; +export type SigninsRepository = Repository; +export type SwSubscriptionsRepository = Repository; +export type UsedUsernamesRepository = Repository; +export type UsersRepository = Repository; +export type UserIpsRepository = Repository; +export type UserKeypairsRepository = Repository; +export type UserListsRepository = Repository; +export type UserListFavoritesRepository = Repository; +export type UserListJoiningsRepository = Repository; +export type UserNotePiningsRepository = Repository; +export type UserPendingsRepository = Repository; +export type UserProfilesRepository = Repository; +export type UserPublickeysRepository = Repository; +export type UserSecurityKeysRepository = Repository; +export type WebhooksRepository = Repository; +export type ChannelsRepository = Repository; +export type RetentionAggregationsRepository = Repository; +export type RolesRepository = Repository; +export type RoleAssignmentsRepository = Repository; +export type FlashsRepository = Repository; +export type FlashLikesRepository = Repository; +export type UserMemoRepository = Repository; diff --git a/packages/backend/src/models/json-schema/announcement.ts b/packages/backend/src/models/json-schema/announcement.ts new file mode 100644 index 0000000000..c7e24c7f29 --- /dev/null +++ b/packages/backend/src/models/json-schema/announcement.ts @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export const packedAnnouncementSchema = { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: 'string', + optional: false, nullable: false, + format: 'date-time', + }, + updatedAt: { + type: 'string', + optional: false, nullable: true, + format: 'date-time', + }, + text: { + type: 'string', + optional: false, nullable: false, + }, + title: { + type: 'string', + optional: false, nullable: false, + }, + imageUrl: { + type: 'string', + optional: false, nullable: true, + }, + icon: { + type: 'string', + optional: false, nullable: false, + }, + display: { + type: 'string', + optional: false, nullable: false, + }, + forYou: { + type: 'boolean', + optional: false, nullable: false, + }, + needConfirmationToRead: { + type: 'boolean', + optional: false, nullable: false, + }, + isRead: { + type: 'boolean', + optional: true, nullable: false, + }, + }, +} as const; diff --git a/packages/backend/src/models/json-schema/antenna.ts b/packages/backend/src/models/json-schema/antenna.ts index 4483510610..3f58cbee6c 100644 --- a/packages/backend/src/models/json-schema/antenna.ts +++ b/packages/backend/src/models/json-schema/antenna.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedAntennaSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/app.ts b/packages/backend/src/models/json-schema/app.ts index c80dc81c33..9e0916299c 100644 --- a/packages/backend/src/models/json-schema/app.ts +++ b/packages/backend/src/models/json-schema/app.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedAppSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/blocking.ts b/packages/backend/src/models/json-schema/blocking.ts index 5532322420..0b58f1f8d7 100644 --- a/packages/backend/src/models/json-schema/blocking.ts +++ b/packages/backend/src/models/json-schema/blocking.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedBlockingSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/channel.ts b/packages/backend/src/models/json-schema/channel.ts index fd61a70c0e..f1019d1461 100644 --- a/packages/backend/src/models/json-schema/channel.ts +++ b/packages/backend/src/models/json-schema/channel.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedChannelSchema = { type: 'object', properties: { @@ -67,5 +72,9 @@ export const packedChannelSchema = { type: 'string', optional: false, nullable: false, }, + isSensitive: { + type: 'boolean', + optional: false, nullable: false, + }, }, } as const; diff --git a/packages/backend/src/models/json-schema/clip.ts b/packages/backend/src/models/json-schema/clip.ts index 7310e59013..64f7a2ad9c 100644 --- a/packages/backend/src/models/json-schema/clip.ts +++ b/packages/backend/src/models/json-schema/clip.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedClipSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/drive-file.ts b/packages/backend/src/models/json-schema/drive-file.ts index 4359076612..87f1340812 100644 --- a/packages/backend/src/models/json-schema/drive-file.ts +++ b/packages/backend/src/models/json-schema/drive-file.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedDriveFileSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/drive-folder.ts b/packages/backend/src/models/json-schema/drive-folder.ts index 88cb8ab4a2..51107d423f 100644 --- a/packages/backend/src/models/json-schema/drive-folder.ts +++ b/packages/backend/src/models/json-schema/drive-folder.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedDriveFolderSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/emoji.ts b/packages/backend/src/models/json-schema/emoji.ts index 63f56e77cb..99a58f8773 100644 --- a/packages/backend/src/models/json-schema/emoji.ts +++ b/packages/backend/src/models/json-schema/emoji.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedEmojiSimpleSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/federation-instance.ts b/packages/backend/src/models/json-schema/federation-instance.ts index 42d93dfac9..ac07519f16 100644 --- a/packages/backend/src/models/json-schema/federation-instance.ts +++ b/packages/backend/src/models/json-schema/federation-instance.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedFederationInstanceSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/flash.ts b/packages/backend/src/models/json-schema/flash.ts index 8471a138ec..9453ba1dce 100644 --- a/packages/backend/src/models/json-schema/flash.ts +++ b/packages/backend/src/models/json-schema/flash.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedFlashSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/following.ts b/packages/backend/src/models/json-schema/following.ts index 2bcffbfc4d..3a24ebb619 100644 --- a/packages/backend/src/models/json-schema/following.ts +++ b/packages/backend/src/models/json-schema/following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedFollowingSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/gallery-post.ts b/packages/backend/src/models/json-schema/gallery-post.ts index fc503d4a64..cf260c0bf5 100644 --- a/packages/backend/src/models/json-schema/gallery-post.ts +++ b/packages/backend/src/models/json-schema/gallery-post.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedGalleryPostSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/hashtag.ts b/packages/backend/src/models/json-schema/hashtag.ts index 98f8827640..a48e972a5d 100644 --- a/packages/backend/src/models/json-schema/hashtag.ts +++ b/packages/backend/src/models/json-schema/hashtag.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedHashtagSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/invite-code.ts b/packages/backend/src/models/json-schema/invite-code.ts index b70a779f29..cd8bf98d90 100644 --- a/packages/backend/src/models/json-schema/invite-code.ts +++ b/packages/backend/src/models/json-schema/invite-code.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedInviteCodeSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/muting.ts b/packages/backend/src/models/json-schema/muting.ts index 3ab99e17e7..dde9dc0288 100644 --- a/packages/backend/src/models/json-schema/muting.ts +++ b/packages/backend/src/models/json-schema/muting.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedMutingSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/note-favorite.ts b/packages/backend/src/models/json-schema/note-favorite.ts index d133f7367d..3f0007d917 100644 --- a/packages/backend/src/models/json-schema/note-favorite.ts +++ b/packages/backend/src/models/json-schema/note-favorite.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedNoteFavoriteSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/note-reaction.ts b/packages/backend/src/models/json-schema/note-reaction.ts index 0d8fc5449b..e3335f426e 100644 --- a/packages/backend/src/models/json-schema/note-reaction.ts +++ b/packages/backend/src/models/json-schema/note-reaction.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedNoteReactionSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/note.ts b/packages/backend/src/models/json-schema/note.ts index 58ef425dcd..eb744aa109 100644 --- a/packages/backend/src/models/json-schema/note.ts +++ b/packages/backend/src/models/json-schema/note.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedNoteSchema = { type: 'object', properties: { @@ -134,6 +139,10 @@ export const packedNoteSchema = { type: 'string', optional: false, nullable: true, }, + isSensitive: { + type: 'boolean', + optional: true, nullable: false, + } }, }, }, diff --git a/packages/backend/src/models/json-schema/notification.ts b/packages/backend/src/models/json-schema/notification.ts index e88ca61ba0..2c434913da 100644 --- a/packages/backend/src/models/json-schema/notification.ts +++ b/packages/backend/src/models/json-schema/notification.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { notificationTypes } from '@/types.js'; export const packedNotificationSchema = { diff --git a/packages/backend/src/models/json-schema/page.ts b/packages/backend/src/models/json-schema/page.ts index 55ba3ce7f7..3f20a4b802 100644 --- a/packages/backend/src/models/json-schema/page.ts +++ b/packages/backend/src/models/json-schema/page.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedPageSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/queue.ts b/packages/backend/src/models/json-schema/queue.ts index 7ceeda26af..43da6e605d 100644 --- a/packages/backend/src/models/json-schema/queue.ts +++ b/packages/backend/src/models/json-schema/queue.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedQueueCountSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/renote-muting.ts b/packages/backend/src/models/json-schema/renote-muting.ts index 69ed8510da..feed1ceb09 100644 --- a/packages/backend/src/models/json-schema/renote-muting.ts +++ b/packages/backend/src/models/json-schema/renote-muting.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedRenoteMutingSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/user-list.ts b/packages/backend/src/models/json-schema/user-list.ts index 1e620516e4..e257d9984c 100644 --- a/packages/backend/src/models/json-schema/user-list.ts +++ b/packages/backend/src/models/json-schema/user-list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedUserListSchema = { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index f9a20ac398..0c205654eb 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const packedUserLiteSchema = { type: 'object', properties: { diff --git a/packages/backend/src/postgres.ts b/packages/backend/src/postgres.ts index 488979c409..6c2f4b21f0 100644 --- a/packages/backend/src/postgres.ts +++ b/packages/backend/src/postgres.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // https://github.com/typeorm/typeorm/issues/2400 import pg from 'pg'; pg.types.setTypeParser(20, Number); @@ -6,72 +11,72 @@ import { DataSource, Logger } from 'typeorm'; import * as highlight from 'cli-highlight'; import { entities as charts } from '@/core/chart/entities.js'; -import { AbuseUserReport } from '@/models/entities/AbuseUserReport.js'; -import { AccessToken } from '@/models/entities/AccessToken.js'; -import { Ad } from '@/models/entities/Ad.js'; -import { Announcement } from '@/models/entities/Announcement.js'; -import { AnnouncementRead } from '@/models/entities/AnnouncementRead.js'; -import { Antenna } from '@/models/entities/Antenna.js'; -import { App } from '@/models/entities/App.js'; -import { AttestationChallenge } from '@/models/entities/AttestationChallenge.js'; -import { AuthSession } from '@/models/entities/AuthSession.js'; -import { Blocking } from '@/models/entities/Blocking.js'; -import { ChannelFollowing } from '@/models/entities/ChannelFollowing.js'; -import { ChannelFavorite } from '@/models/entities/ChannelFavorite.js'; -import { Clip } from '@/models/entities/Clip.js'; -import { ClipNote } from '@/models/entities/ClipNote.js'; -import { ClipFavorite } from '@/models/entities/ClipFavorite.js'; -import { DriveFile } from '@/models/entities/DriveFile.js'; -import { DriveFolder } from '@/models/entities/DriveFolder.js'; -import { Emoji } from '@/models/entities/Emoji.js'; -import { Following } from '@/models/entities/Following.js'; -import { FollowRequest } from '@/models/entities/FollowRequest.js'; -import { GalleryLike } from '@/models/entities/GalleryLike.js'; -import { GalleryPost } from '@/models/entities/GalleryPost.js'; -import { Hashtag } from '@/models/entities/Hashtag.js'; -import { Instance } from '@/models/entities/Instance.js'; -import { Meta } from '@/models/entities/Meta.js'; -import { ModerationLog } from '@/models/entities/ModerationLog.js'; -import { MutedNote } from '@/models/entities/MutedNote.js'; -import { Muting } from '@/models/entities/Muting.js'; -import { RenoteMuting } from '@/models/entities/RenoteMuting.js'; -import { Note } from '@/models/entities/Note.js'; -import { NoteFavorite } from '@/models/entities/NoteFavorite.js'; -import { NoteReaction } from '@/models/entities/NoteReaction.js'; -import { NoteThreadMuting } from '@/models/entities/NoteThreadMuting.js'; -import { NoteUnread } from '@/models/entities/NoteUnread.js'; -import { Page } from '@/models/entities/Page.js'; -import { PageLike } from '@/models/entities/PageLike.js'; -import { PasswordResetRequest } from '@/models/entities/PasswordResetRequest.js'; -import { Poll } from '@/models/entities/Poll.js'; -import { PollVote } from '@/models/entities/PollVote.js'; -import { PromoNote } from '@/models/entities/PromoNote.js'; -import { PromoRead } from '@/models/entities/PromoRead.js'; -import { RegistrationTicket } from '@/models/entities/RegistrationTicket.js'; -import { RegistryItem } from '@/models/entities/RegistryItem.js'; -import { Relay } from '@/models/entities/Relay.js'; -import { Signin } from '@/models/entities/Signin.js'; -import { SwSubscription } from '@/models/entities/SwSubscription.js'; -import { UsedUsername } from '@/models/entities/UsedUsername.js'; -import { User } from '@/models/entities/User.js'; -import { UserIp } from '@/models/entities/UserIp.js'; -import { UserKeypair } from '@/models/entities/UserKeypair.js'; -import { UserList } from '@/models/entities/UserList.js'; -import { UserListFavorite } from '@/models/entities/UserListFavorite.js'; -import { UserListJoining } from '@/models/entities/UserListJoining.js'; -import { UserNotePining } from '@/models/entities/UserNotePining.js'; -import { UserPending } from '@/models/entities/UserPending.js'; -import { UserProfile } from '@/models/entities/UserProfile.js'; -import { UserPublickey } from '@/models/entities/UserPublickey.js'; -import { UserSecurityKey } from '@/models/entities/UserSecurityKey.js'; -import { Webhook } from '@/models/entities/Webhook.js'; -import { Channel } from '@/models/entities/Channel.js'; -import { RetentionAggregation } from '@/models/entities/RetentionAggregation.js'; -import { Role } from '@/models/entities/Role.js'; -import { RoleAssignment } from '@/models/entities/RoleAssignment.js'; -import { Flash } from '@/models/entities/Flash.js'; -import { FlashLike } from '@/models/entities/FlashLike.js'; -import { UserMemo } from '@/models/entities/UserMemo.js'; +import { MiAbuseUserReport } from '@/models/entities/AbuseUserReport.js'; +import { MiAccessToken } from '@/models/entities/AccessToken.js'; +import { MiAd } from '@/models/entities/Ad.js'; +import { MiAnnouncement } from '@/models/entities/Announcement.js'; +import { MiAnnouncementRead } from '@/models/entities/AnnouncementRead.js'; +import { MiAntenna } from '@/models/entities/Antenna.js'; +import { MiApp } from '@/models/entities/App.js'; +import { MiAttestationChallenge } from '@/models/entities/AttestationChallenge.js'; +import { MiAuthSession } from '@/models/entities/AuthSession.js'; +import { MiBlocking } from '@/models/entities/Blocking.js'; +import { MiChannelFollowing } from '@/models/entities/ChannelFollowing.js'; +import { MiChannelFavorite } from '@/models/entities/ChannelFavorite.js'; +import { MiClip } from '@/models/entities/Clip.js'; +import { MiClipNote } from '@/models/entities/ClipNote.js'; +import { MiClipFavorite } from '@/models/entities/ClipFavorite.js'; +import { MiDriveFile } from '@/models/entities/DriveFile.js'; +import { MiDriveFolder } from '@/models/entities/DriveFolder.js'; +import { MiEmoji } from '@/models/entities/Emoji.js'; +import { MiFollowing } from '@/models/entities/Following.js'; +import { MiFollowRequest } from '@/models/entities/FollowRequest.js'; +import { MiGalleryLike } from '@/models/entities/GalleryLike.js'; +import { MiGalleryPost } from '@/models/entities/GalleryPost.js'; +import { MiHashtag } from '@/models/entities/Hashtag.js'; +import { MiInstance } from '@/models/entities/Instance.js'; +import { MiMeta } from '@/models/entities/Meta.js'; +import { MiModerationLog } from '@/models/entities/ModerationLog.js'; +import { MiMutedNote } from '@/models/entities/MutedNote.js'; +import { MiMuting } from '@/models/entities/Muting.js'; +import { MiRenoteMuting } from '@/models/entities/RenoteMuting.js'; +import { MiNote } from '@/models/entities/Note.js'; +import { MiNoteFavorite } from '@/models/entities/NoteFavorite.js'; +import { MiNoteReaction } from '@/models/entities/NoteReaction.js'; +import { MiNoteThreadMuting } from '@/models/entities/NoteThreadMuting.js'; +import { MiNoteUnread } from '@/models/entities/NoteUnread.js'; +import { MiPage } from '@/models/entities/Page.js'; +import { MiPageLike } from '@/models/entities/PageLike.js'; +import { MiPasswordResetRequest } from '@/models/entities/PasswordResetRequest.js'; +import { MiPoll } from '@/models/entities/Poll.js'; +import { MiPollVote } from '@/models/entities/PollVote.js'; +import { MiPromoNote } from '@/models/entities/PromoNote.js'; +import { MiPromoRead } from '@/models/entities/PromoRead.js'; +import { MiRegistrationTicket } from '@/models/entities/RegistrationTicket.js'; +import { MiRegistryItem } from '@/models/entities/RegistryItem.js'; +import { MiRelay } from '@/models/entities/Relay.js'; +import { MiSignin } from '@/models/entities/Signin.js'; +import { MiSwSubscription } from '@/models/entities/SwSubscription.js'; +import { MiUsedUsername } from '@/models/entities/UsedUsername.js'; +import { MiUser } from '@/models/entities/User.js'; +import { MiUserIp } from '@/models/entities/UserIp.js'; +import { MiUserKeypair } from '@/models/entities/UserKeypair.js'; +import { MiUserList } from '@/models/entities/UserList.js'; +import { MiUserListFavorite } from '@/models/entities/UserListFavorite.js'; +import { MiUserListJoining } from '@/models/entities/UserListJoining.js'; +import { MiUserNotePining } from '@/models/entities/UserNotePining.js'; +import { MiUserPending } from '@/models/entities/UserPending.js'; +import { MiUserProfile } from '@/models/entities/UserProfile.js'; +import { MiUserPublickey } from '@/models/entities/UserPublickey.js'; +import { MiUserSecurityKey } from '@/models/entities/UserSecurityKey.js'; +import { MiWebhook } from '@/models/entities/Webhook.js'; +import { MiChannel } from '@/models/entities/Channel.js'; +import { MiRetentionAggregation } from '@/models/entities/RetentionAggregation.js'; +import { MiRole } from '@/models/entities/Role.js'; +import { MiRoleAssignment } from '@/models/entities/RoleAssignment.js'; +import { MiFlash } from '@/models/entities/Flash.js'; +import { MiFlashLike } from '@/models/entities/FlashLike.js'; +import { MiUserMemo } from '@/models/entities/UserMemo.js'; import { Config } from '@/config.js'; import MisskeyLogger from '@/logger.js'; @@ -121,72 +126,72 @@ class MyCustomLogger implements Logger { } export const entities = [ - Announcement, - AnnouncementRead, - Meta, - Instance, - App, - AuthSession, - AccessToken, - User, - UserProfile, - UserKeypair, - UserPublickey, - UserList, - UserListFavorite, - UserListJoining, - UserNotePining, - UserSecurityKey, - UsedUsername, - AttestationChallenge, - Following, - FollowRequest, - Muting, - RenoteMuting, - Blocking, - Note, - NoteFavorite, - NoteReaction, - NoteThreadMuting, - NoteUnread, - Page, - PageLike, - GalleryPost, - GalleryLike, - DriveFile, - DriveFolder, - Poll, - PollVote, - Emoji, - Hashtag, - SwSubscription, - AbuseUserReport, - RegistrationTicket, - Signin, - ModerationLog, - Clip, - ClipNote, - ClipFavorite, - Antenna, - PromoNote, - PromoRead, - Relay, - MutedNote, - Channel, - ChannelFollowing, - ChannelFavorite, - RegistryItem, - Ad, - PasswordResetRequest, - UserPending, - Webhook, - UserIp, - RetentionAggregation, - Role, - RoleAssignment, - Flash, - FlashLike, - UserMemo, + MiAnnouncement, + MiAnnouncementRead, + MiMeta, + MiInstance, + MiApp, + MiAuthSession, + MiAccessToken, + MiUser, + MiUserProfile, + MiUserKeypair, + MiUserPublickey, + MiUserList, + MiUserListFavorite, + MiUserListJoining, + MiUserNotePining, + MiUserSecurityKey, + MiUsedUsername, + MiAttestationChallenge, + MiFollowing, + MiFollowRequest, + MiMuting, + MiRenoteMuting, + MiBlocking, + MiNote, + MiNoteFavorite, + MiNoteReaction, + MiNoteThreadMuting, + MiNoteUnread, + MiPage, + MiPageLike, + MiGalleryPost, + MiGalleryLike, + MiDriveFile, + MiDriveFolder, + MiPoll, + MiPollVote, + MiEmoji, + MiHashtag, + MiSwSubscription, + MiAbuseUserReport, + MiRegistrationTicket, + MiSignin, + MiModerationLog, + MiClip, + MiClipNote, + MiClipFavorite, + MiAntenna, + MiPromoNote, + MiPromoRead, + MiRelay, + MiMutedNote, + MiChannel, + MiChannelFollowing, + MiChannelFavorite, + MiRegistryItem, + MiAd, + MiPasswordResetRequest, + MiUserPending, + MiWebhook, + MiUserIp, + MiRetentionAggregation, + MiRole, + MiRoleAssignment, + MiFlash, + MiFlashLike, + MiUserMemo, ...charts, ]; @@ -227,7 +232,7 @@ export function createPostgresDataSource(config: Config) { options: { host: config.redis.host, port: config.redis.port, - family: config.redis.family == null ? 0 : config.redis.family, + family: config.redis.family ?? 0, password: config.redis.pass, keyPrefix: `${config.redis.prefix}:query:`, db: config.redis.db ?? 0, diff --git a/packages/backend/src/queue/QueueLoggerService.ts b/packages/backend/src/queue/QueueLoggerService.ts index 648af893c2..618d1d5c2f 100644 --- a/packages/backend/src/queue/QueueLoggerService.ts +++ b/packages/backend/src/queue/QueueLoggerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import { LoggerService } from '@/core/LoggerService.js'; diff --git a/packages/backend/src/queue/QueueProcessorModule.ts b/packages/backend/src/queue/QueueProcessorModule.ts index e1c6b93d9b..e6327002c5 100644 --- a/packages/backend/src/queue/QueueProcessorModule.ts +++ b/packages/backend/src/queue/QueueProcessorModule.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Module } from '@nestjs/common'; import { CoreModule } from '@/core/CoreModule.js'; import { GlobalModule } from '@/GlobalModule.js'; diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index f575b1718e..5201bfed8e 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import * as Bull from 'bullmq'; import type { Config } from '@/config.js'; diff --git a/packages/backend/src/queue/const.ts b/packages/backend/src/queue/const.ts index d49951a1c3..87d075304d 100644 --- a/packages/backend/src/queue/const.ts +++ b/packages/backend/src/queue/const.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Config } from '@/config.js'; import type * as Bull from 'bullmq'; @@ -16,7 +21,7 @@ export function baseQueueOptions(config: Config, queueName: typeof QUEUE[keyof t return { connection: { ...config.redisForJobQueue, - keyPrefix: undefined + keyPrefix: undefined, }, prefix: config.redisForJobQueue.prefix ? `${config.redisForJobQueue.prefix}:queue:${queueName}` : `queue:${queueName}`, }; diff --git a/packages/backend/src/queue/processors/AggregateRetentionProcessorService.ts b/packages/backend/src/queue/processors/AggregateRetentionProcessorService.ts index 600ce0828f..757bfa3079 100644 --- a/packages/backend/src/queue/processors/AggregateRetentionProcessorService.ts +++ b/packages/backend/src/queue/processors/AggregateRetentionProcessorService.ts @@ -1,7 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull, MoreThan } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; import type { RetentionAggregationsRepository, UsersRepository } from '@/models/index.js'; @@ -16,9 +20,6 @@ export class AggregateRetentionProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts b/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts index c4ee212bab..d87f4537c8 100644 --- a/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts +++ b/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { MutingsRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; import { UserMutingService } from '@/core/UserMutingService.js'; @@ -14,9 +18,6 @@ export class CheckExpiredMutingsProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.mutingsRepository) private mutingsRepository: MutingsRepository, diff --git a/packages/backend/src/queue/processors/CleanChartsProcessorService.ts b/packages/backend/src/queue/processors/CleanChartsProcessorService.ts index 22d7c1b4fb..55c444eee6 100644 --- a/packages/backend/src/queue/processors/CleanChartsProcessorService.ts +++ b/packages/backend/src/queue/processors/CleanChartsProcessorService.ts @@ -1,6 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import FederationChart from '@/core/chart/charts/federation.js'; import NotesChart from '@/core/chart/charts/notes.js'; @@ -23,9 +26,6 @@ export class CleanChartsProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - private federationChart: FederationChart, private notesChart: NotesChart, private usersChart: UsersChart, diff --git a/packages/backend/src/queue/processors/CleanProcessorService.ts b/packages/backend/src/queue/processors/CleanProcessorService.ts index cefa6da5e9..03a33e76ac 100644 --- a/packages/backend/src/queue/processors/CleanProcessorService.ts +++ b/packages/backend/src/queue/processors/CleanProcessorService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { In, LessThan } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { AntennasRepository, MutedNotesRepository, RoleAssignmentsRepository, UserIpsRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; @@ -14,9 +18,6 @@ export class CleanProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.userIpsRepository) private userIpsRepository: UserIpsRepository, diff --git a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts index 6f887089eb..12cedd7d3d 100644 --- a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts +++ b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull, MoreThan, Not } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { DriveFile, DriveFilesRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { MiDriveFile, DriveFilesRepository } from '@/models/index.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { bindThis } from '@/decorators.js'; @@ -14,9 +18,6 @@ export class CleanRemoteFilesProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -31,7 +32,7 @@ export class CleanRemoteFilesProcessorService { this.logger.info('Deleting cached remote files...'); let deletedCount = 0; - let cursor: DriveFile['id'] | null = null; + let cursor: MiDriveFile['id'] | null = null; while (true) { const files = await this.driveFilesRepository.find({ diff --git a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts index 3b7db5f05c..39155bf383 100644 --- a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts +++ b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts @@ -1,12 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { MoreThan } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { DriveFilesRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { EmailService } from '@/core/EmailService.js'; import { bindThis } from '@/decorators.js'; import { SearchService } from '@/core/SearchService.js'; @@ -19,9 +23,6 @@ export class DeleteAccountProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -52,7 +53,7 @@ export class DeleteAccountProcessorService { } { // Delete notes - let cursor: Note['id'] | null = null; + let cursor: MiNote['id'] | null = null; while (true) { const notes = await this.notesRepository.find({ @@ -64,7 +65,7 @@ export class DeleteAccountProcessorService { order: { id: 1, }, - }) as Note[]; + }) as MiNote[]; if (notes.length === 0) { break; @@ -83,7 +84,7 @@ export class DeleteAccountProcessorService { } { // Delete files - let cursor: DriveFile['id'] | null = null; + let cursor: MiDriveFile['id'] | null = null; while (true) { const files = await this.driveFilesRepository.find({ @@ -95,7 +96,7 @@ export class DeleteAccountProcessorService { order: { id: 1, }, - }) as DriveFile[]; + }) as MiDriveFile[]; if (files.length === 0) { break; diff --git a/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts b/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts index 07e3762330..ae395f540d 100644 --- a/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts +++ b/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { MoreThan } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { UsersRepository, DriveFilesRepository, DriveFile } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { UsersRepository, DriveFilesRepository, MiDriveFile } from '@/models/index.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { bindThis } from '@/decorators.js'; @@ -15,9 +19,6 @@ export class DeleteDriveFilesProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -40,7 +41,7 @@ export class DeleteDriveFilesProcessorService { } let deletedCount = 0; - let cursor: DriveFile['id'] | null = null; + let cursor: MiDriveFile['id'] | null = null; while (true) { const files = await this.driveFilesRepository.find({ diff --git a/packages/backend/src/queue/processors/DeleteFileProcessorService.ts b/packages/backend/src/queue/processors/DeleteFileProcessorService.ts index edf87bd921..a4638bfaaf 100644 --- a/packages/backend/src/queue/processors/DeleteFileProcessorService.ts +++ b/packages/backend/src/queue/processors/DeleteFileProcessorService.ts @@ -1,6 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { bindThis } from '@/decorators.js'; @@ -13,9 +16,6 @@ export class DeleteFileProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - private driveService: DriveService, private queueLoggerService: QueueLoggerService, ) { diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index 406e9df850..17fa32c2a1 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -1,15 +1,19 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Bull from 'bullmq'; import { DI } from '@/di-symbols.js'; -import type { DriveFilesRepository, InstancesRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { InstancesRepository } from '@/models/index.js'; import type Logger from '@/logger.js'; import { MetaService } from '@/core/MetaService.js'; import { ApRequestService } from '@/core/activitypub/ApRequestService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; import { MemorySingleCache } from '@/misc/cache.js'; -import type { Instance } from '@/models/entities/Instance.js'; +import type { MiInstance } from '@/models/entities/Instance.js'; import InstanceChart from '@/core/chart/charts/instance.js'; import ApRequestChart from '@/core/chart/charts/ap-request.js'; import FederationChart from '@/core/chart/charts/federation.js'; @@ -22,19 +26,13 @@ import type { DeliverJobData } from '../types.js'; @Injectable() export class DeliverProcessorService { private logger: Logger; - private suspendedHostsCache: MemorySingleCache; + private suspendedHostsCache: MemorySingleCache; private latest: string | null; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - private metaService: MetaService, private utilityService: UtilityService, private federatedInstanceService: FederatedInstanceService, @@ -46,7 +44,7 @@ export class DeliverProcessorService { private queueLoggerService: QueueLoggerService, ) { this.logger = this.queueLoggerService.logger.createSubLogger('deliver'); - this.suspendedHostsCache = new MemorySingleCache(1000 * 60 * 60); + this.suspendedHostsCache = new MemorySingleCache(1000 * 60 * 60); } @bindThis diff --git a/packages/backend/src/queue/processors/EndedPollNotificationProcessorService.ts b/packages/backend/src/queue/processors/EndedPollNotificationProcessorService.ts index 21501592f2..d855ee5707 100644 --- a/packages/backend/src/queue/processors/EndedPollNotificationProcessorService.ts +++ b/packages/backend/src/queue/processors/EndedPollNotificationProcessorService.ts @@ -1,7 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { PollVotesRepository, NotesRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { NotificationService } from '@/core/NotificationService.js'; import { bindThis } from '@/decorators.js'; @@ -14,9 +18,6 @@ export class EndedPollNotificationProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts index 21c0bfe80e..243a4f97f2 100644 --- a/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { format as DateFormat } from 'date-fns'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { AntennasRepository, UsersRepository, UserListJoiningsRepository, User } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { AntennasRepository, UsersRepository, UserListJoiningsRepository, MiUser } from '@/models/index.js'; import Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { bindThis } from '@/decorators.js'; @@ -19,9 +23,6 @@ export class ExportAntennasProcessorService { private logger: Logger; constructor ( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -62,7 +63,7 @@ export class ExportAntennasProcessorService { const antennas = await this.antennsRepository.findBy({ userId: job.data.user.id }); write('['); for (const [index, antenna] of antennas.entries()) { - let users: User[] | undefined; + let users: MiUser[] | undefined; if (antenna.userListId !== null) { const joinings = await this.userListJoiningsRepository.findBy({ userListId: antenna.userListId }); users = await this.usersRepository.findBy({ diff --git a/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts b/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts index d100c6d09f..8e27cacb58 100644 --- a/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { MoreThan } from 'typeorm'; import { format as dateFormat } from 'date-fns'; import { DI } from '@/di-symbols.js'; -import type { UsersRepository, BlockingsRepository, Blocking } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { UsersRepository, BlockingsRepository, MiBlocking } from '@/models/index.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { createTemp } from '@/misc/create-temp.js'; @@ -19,9 +23,6 @@ export class ExportBlockingProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -53,7 +54,7 @@ export class ExportBlockingProcessorService { const stream = fs.createWriteStream(path, { flags: 'a' }); let exportedCount = 0; - let cursor: Blocking['id'] | null = null; + let cursor: MiBlocking['id'] | null = null; while (true) { const blockings = await this.blockingsRepository.find({ diff --git a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts index 3203d9f3e5..688a0a1ccd 100644 --- a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; diff --git a/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts b/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts index 2be42b1a7a..afa1fa4ce7 100644 --- a/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts @@ -1,15 +1,19 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { MoreThan } from 'typeorm'; import { format as dateFormat } from 'date-fns'; import { DI } from '@/di-symbols.js'; -import type { NoteFavorite, NoteFavoritesRepository, NotesRepository, PollsRepository, User, UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { MiNoteFavorite, NoteFavoritesRepository, PollsRepository, MiUser, UsersRepository } from '@/models/index.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { createTemp } from '@/misc/create-temp.js'; -import type { Poll } from '@/models/entities/Poll.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiPoll } from '@/models/entities/Poll.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { bindThis } from '@/decorators.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type * as Bull from 'bullmq'; @@ -20,18 +24,12 @@ export class ExportFavoritesProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @Inject(DI.pollsRepository) private pollsRepository: PollsRepository, - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - @Inject(DI.noteFavoritesRepository) private noteFavoritesRepository: NoteFavoritesRepository, @@ -74,7 +72,7 @@ export class ExportFavoritesProcessorService { await write('['); let exportedFavoritesCount = 0; - let cursor: NoteFavorite['id'] | null = null; + let cursor: MiNoteFavorite['id'] | null = null; while (true) { const favorites = await this.noteFavoritesRepository.find({ @@ -87,7 +85,7 @@ export class ExportFavoritesProcessorService { id: 1, }, relations: ['note', 'note.user'], - }) as (NoteFavorite & { note: Note & { user: User } })[]; + }) as (MiNoteFavorite & { note: MiNote & { user: MiUser } })[]; if (favorites.length === 0) { job.updateProgress(100); @@ -97,7 +95,7 @@ export class ExportFavoritesProcessorService { cursor = favorites.at(-1)?.id ?? null; for (const favorite of favorites) { - let poll: Poll | undefined; + let poll: MiPoll | undefined; if (favorite.note.hasPoll) { poll = await this.pollsRepository.findOneByOrFail({ noteId: favorite.note.id }); } @@ -129,7 +127,7 @@ export class ExportFavoritesProcessorService { } } -function serialize(favorite: NoteFavorite & { note: Note & { user: User } }, poll: Poll | null = null): Record { +function serialize(favorite: MiNoteFavorite & { note: MiNote & { user: MiUser } }, poll: MiPoll | null = null): Record { return { id: favorite.id, createdAt: favorite.createdAt, diff --git a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts index d54e5e0b34..7f29d7299a 100644 --- a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts @@ -1,14 +1,18 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { In, MoreThan, Not } from 'typeorm'; import { format as dateFormat } from 'date-fns'; import { DI } from '@/di-symbols.js'; import type { UsersRepository, FollowingsRepository, MutingsRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { createTemp } from '@/misc/create-temp.js'; -import type { Following } from '@/models/entities/Following.js'; +import type { MiFollowing } from '@/models/entities/Following.js'; import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; @@ -20,9 +24,6 @@ export class ExportFollowingProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -56,7 +57,7 @@ export class ExportFollowingProcessorService { try { const stream = fs.createWriteStream(path, { flags: 'a' }); - let cursor: Following['id'] | null = null; + let cursor: MiFollowing['id'] | null = null; const mutings = job.data.excludeMuting ? await this.mutingsRepository.findBy({ muterId: user.id, @@ -73,7 +74,7 @@ export class ExportFollowingProcessorService { order: { id: 1, }, - }) as Following[]; + }) as MiFollowing[]; if (followings.length === 0) { break; diff --git a/packages/backend/src/queue/processors/ExportMutingProcessorService.ts b/packages/backend/src/queue/processors/ExportMutingProcessorService.ts index 030e38931e..1bb8da06f5 100644 --- a/packages/backend/src/queue/processors/ExportMutingProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportMutingProcessorService.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { IsNull, MoreThan } from 'typeorm'; import { format as dateFormat } from 'date-fns'; import { DI } from '@/di-symbols.js'; -import type { MutingsRepository, UsersRepository, BlockingsRepository, Muting } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { MutingsRepository, UsersRepository, MiMuting } from '@/models/index.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { createTemp } from '@/misc/create-temp.js'; @@ -19,15 +23,9 @@ export class ExportMutingProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, - @Inject(DI.blockingsRepository) - private blockingsRepository: BlockingsRepository, - @Inject(DI.mutingsRepository) private mutingsRepository: MutingsRepository, @@ -56,7 +54,7 @@ export class ExportMutingProcessorService { const stream = fs.createWriteStream(path, { flags: 'a' }); let exportedCount = 0; - let cursor: Muting['id'] | null = null; + let cursor: MiMuting['id'] | null = null; while (true) { const mutes = await this.mutingsRepository.find({ diff --git a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts index 94c81a3cf8..0dcda341fd 100644 --- a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts @@ -1,15 +1,19 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { MoreThan } from 'typeorm'; import { format as dateFormat } from 'date-fns'; import { DI } from '@/di-symbols.js'; import type { NotesRepository, PollsRepository, UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { createTemp } from '@/misc/create-temp.js'; -import type { Poll } from '@/models/entities/Poll.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiPoll } from '@/models/entities/Poll.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { bindThis } from '@/decorators.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { Packed } from '@/misc/json-schema.js'; @@ -22,9 +26,6 @@ export class ExportNotesProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -75,7 +76,7 @@ export class ExportNotesProcessorService { await write('['); let exportedNotesCount = 0; - let cursor: Note['id'] | null = null; + let cursor: MiNote['id'] | null = null; while (true) { const notes = await this.notesRepository.find({ @@ -87,7 +88,7 @@ export class ExportNotesProcessorService { order: { id: 1, }, - }) as Note[]; + }) as MiNote[]; if (notes.length === 0) { job.updateProgress(100); @@ -97,7 +98,7 @@ export class ExportNotesProcessorService { cursor = notes.at(-1)?.id ?? null; for (const note of notes) { - let poll: Poll | undefined; + let poll: MiPoll | undefined; if (note.hasPoll) { poll = await this.pollsRepository.findOneByOrFail({ noteId: note.id }); } @@ -130,7 +131,7 @@ export class ExportNotesProcessorService { } } -function serialize(note: Note, poll: Poll | null = null, files: Packed<'DriveFile'>[]): Record { +function serialize(note: MiNote, poll: MiPoll | null = null, files: Packed<'DriveFile'>[]): Record { return { id: note.id, text: note.text, diff --git a/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts index ec63358053..ba3e18b563 100644 --- a/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; import { format as dateFormat } from 'date-fns'; import { DI } from '@/di-symbols.js'; import type { UserListJoiningsRepository, UserListsRepository, UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import { createTemp } from '@/misc/create-temp.js'; @@ -19,9 +23,6 @@ export class ExportUserListsProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts index 74ef20fdd8..9ff9a8a528 100644 --- a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable, Inject } from '@nestjs/common'; import _Ajv from 'ajv'; import { IdService } from '@/core/IdService.js'; diff --git a/packages/backend/src/queue/processors/ImportBlockingProcessorService.ts b/packages/backend/src/queue/processors/ImportBlockingProcessorService.ts index 2f1a9e5b03..1d4c3d907e 100644 --- a/packages/backend/src/queue/processors/ImportBlockingProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportBlockingProcessorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts index 37b929cb03..54e92d3129 100644 --- a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts @@ -1,10 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import { ZipReader } from 'slacc'; -import { DataSource } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { EmojisRepository, DriveFilesRepository, UsersRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { EmojisRepository, DriveFilesRepository } from '@/models/index.js'; import type Logger from '@/logger.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { createTempDir } from '@/misc/create-temp.js'; @@ -21,15 +24,6 @@ export class ImportCustomEmojisProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - - @Inject(DI.db) - private db: DataSource, - - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts index 15bee9672e..585311982f 100644 --- a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/queue/processors/ImportMutingProcessorService.ts b/packages/backend/src/queue/processors/ImportMutingProcessorService.ts index 723935cd31..174046c561 100644 --- a/packages/backend/src/queue/processors/ImportMutingProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportMutingProcessorService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { UsersRepository, DriveFilesRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import * as Acct from '@/misc/acct.js'; import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js'; @@ -19,9 +23,6 @@ export class ImportMutingProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts index 824ee8157a..a434b4da95 100644 --- a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { UsersRepository, DriveFilesRepository, UserListJoiningsRepository, UserListsRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import * as Acct from '@/misc/acct.js'; import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js'; @@ -20,9 +24,6 @@ export class ImportUserListsProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index ce1d7aaa1b..ba00cc2ac8 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -1,20 +1,22 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import httpSignature from '@peertube/http-signature'; import * as Bull from 'bullmq'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; import type Logger from '@/logger.js'; import { MetaService } from '@/core/MetaService.js'; -import { ApRequestService } from '@/core/activitypub/ApRequestService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; import InstanceChart from '@/core/chart/charts/instance.js'; import ApRequestChart from '@/core/chart/charts/ap-request.js'; import FederationChart from '@/core/chart/charts/federation.js'; import { getApId } from '@/core/activitypub/type.js'; -import type { RemoteUser } from '@/models/entities/User.js'; -import type { UserPublickey } from '@/models/entities/UserPublickey.js'; +import type { MiRemoteUser } from '@/models/entities/User.js'; +import type { MiUserPublickey } from '@/models/entities/UserPublickey.js'; import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js'; import { StatusError } from '@/misc/status-error.js'; import { UtilityService } from '@/core/UtilityService.js'; @@ -30,16 +32,12 @@ export class InboxProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - private utilityService: UtilityService, private metaService: MetaService, private apInboxService: ApInboxService, private federatedInstanceService: FederatedInstanceService, private fetchInstanceMetadataService: FetchInstanceMetadataService, private ldSignatureService: LdSignatureService, - private apRequestService: ApRequestService, private apPersonService: ApPersonService, private apDbResolverService: ApDbResolverService, private instanceChart: InstanceChart, @@ -76,8 +74,8 @@ export class InboxProcessorService { // HTTP-Signature keyIdを元にDBから取得 let authUser: { - user: RemoteUser; - key: UserPublickey | null; + user: MiRemoteUser; + key: MiUserPublickey | null; } | null = await this.apDbResolverService.getAuthUserFromKeyId(signature.keyId); // keyIdでわからなければ、activity.actorを元にDBから取得 || activity.actorを元にリモートから取得 diff --git a/packages/backend/src/queue/processors/RelationshipProcessorService.ts b/packages/backend/src/queue/processors/RelationshipProcessorService.ts index 816c5fc5ec..67a50dc789 100644 --- a/packages/backend/src/queue/processors/RelationshipProcessorService.ts +++ b/packages/backend/src/queue/processors/RelationshipProcessorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { UserFollowingService } from '@/core/UserFollowingService.js'; @@ -7,7 +12,7 @@ import type Logger from '@/logger.js'; import type { UsersRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; -import { LocalUser, RemoteUser } from '@/models/entities/User.js'; +import { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; import { RelationshipJobData } from '../types.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type * as Bull from 'bullmq'; @@ -40,7 +45,7 @@ export class RelationshipProcessorService { const [follower, followee] = await Promise.all([ this.usersRepository.findOneByOrFail({ id: job.data.from.id }), this.usersRepository.findOneByOrFail({ id: job.data.to.id }), - ]) as [LocalUser | RemoteUser, LocalUser | RemoteUser]; + ]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser]; await this.userFollowingService.unfollow(follower, followee, job.data.silent); return 'ok'; } diff --git a/packages/backend/src/queue/processors/ResyncChartsProcessorService.ts b/packages/backend/src/queue/processors/ResyncChartsProcessorService.ts index eab8e1e68d..b3b055ef8c 100644 --- a/packages/backend/src/queue/processors/ResyncChartsProcessorService.ts +++ b/packages/backend/src/queue/processors/ResyncChartsProcessorService.ts @@ -1,18 +1,13 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; -import FederationChart from '@/core/chart/charts/federation.js'; import NotesChart from '@/core/chart/charts/notes.js'; import UsersChart from '@/core/chart/charts/users.js'; -import ActiveUsersChart from '@/core/chart/charts/active-users.js'; -import InstanceChart from '@/core/chart/charts/instance.js'; -import PerUserNotesChart from '@/core/chart/charts/per-user-notes.js'; import DriveChart from '@/core/chart/charts/drive.js'; -import PerUserReactionsChart from '@/core/chart/charts/per-user-reactions.js'; -import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js'; -import PerUserDriveChart from '@/core/chart/charts/per-user-drive.js'; -import ApRequestChart from '@/core/chart/charts/ap-request.js'; import { bindThis } from '@/decorators.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type * as Bull from 'bullmq'; @@ -22,21 +17,9 @@ export class ResyncChartsProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - - private federationChart: FederationChart, private notesChart: NotesChart, private usersChart: UsersChart, - private activeUsersChart: ActiveUsersChart, - private instanceChart: InstanceChart, - private perUserNotesChart: PerUserNotesChart, private driveChart: DriveChart, - private perUserReactionsChart: PerUserReactionsChart, - private perUserFollowingChart: PerUserFollowingChart, - private perUserDriveChart: PerUserDriveChart, - private apRequestChart: ApRequestChart, - private queueLoggerService: QueueLoggerService, ) { this.logger = this.queueLoggerService.logger.createSubLogger('resync-charts'); diff --git a/packages/backend/src/queue/processors/TickChartsProcessorService.ts b/packages/backend/src/queue/processors/TickChartsProcessorService.ts index f1696bf567..7b1efb71e0 100644 --- a/packages/backend/src/queue/processors/TickChartsProcessorService.ts +++ b/packages/backend/src/queue/processors/TickChartsProcessorService.ts @@ -1,6 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import FederationChart from '@/core/chart/charts/federation.js'; import NotesChart from '@/core/chart/charts/notes.js'; @@ -23,9 +26,6 @@ export class TickChartsProcessorService { private logger: Logger; constructor( - @Inject(DI.config) - private config: Config, - private federationChart: FederationChart, private notesChart: NotesChart, private usersChart: UsersChart, diff --git a/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts b/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts index 25e91761ef..92b3720a56 100644 --- a/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/WebhookDeliverProcessorService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Bull from 'bullmq'; import { DI } from '@/di-symbols.js'; @@ -42,6 +47,7 @@ export class WebhookDeliverProcessorService { 'Content-Type': 'application/json', }, body: JSON.stringify({ + server: this.config.url, hookId: job.data.webhookId, userId: job.data.userId, eventId: job.data.eventId, diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts index 776dd3aa12..85af9d5315 100644 --- a/packages/backend/src/queue/types.ts +++ b/packages/backend/src/queue/types.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { User } from '@/models/entities/User.js'; -import type { Webhook } from '@/models/entities/Webhook.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiWebhook } from '@/models/entities/Webhook.js'; import type { IActivity } from '@/core/activitypub/type.js'; import type httpSignature from '@peertube/http-signature'; @@ -73,7 +78,7 @@ export type DbUserDeleteJobData = { export type DbUserImportJobData = { user: ThinUser; - fileId: DriveFile['id']; + fileId: MiDriveFile['id']; }; export type DBAntennaImportJobData = { @@ -93,14 +98,14 @@ export type ObjectStorageFileJobData = { }; export type EndedPollNotificationJobData = { - noteId: Note['id']; + noteId: MiNote['id']; }; export type WebhookDeliverJobData = { type: string; content: unknown; - webhookId: Webhook['id']; - userId: User['id']; + webhookId: MiWebhook['id']; + userId: MiUser['id']; to: string; secret: string; createdAt: number; @@ -108,5 +113,5 @@ export type WebhookDeliverJobData = { }; export type ThinUser = { - id: User['id']; + id: MiUser['id']; }; diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 634f5f0a4e..86edab396b 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IncomingMessage } from 'node:http'; import { Inject, Injectable } from '@nestjs/common'; import fastifyAccepts from '@fastify/accepts'; @@ -11,11 +16,11 @@ import * as url from '@/misc/prelude/url.js'; import type { Config } from '@/config.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { QueueService } from '@/core/QueueService.js'; -import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js'; +import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js'; import { UserKeypairService } from '@/core/UserKeypairService.js'; -import type { Following } from '@/models/entities/Following.js'; +import type { MiFollowing } from '@/models/entities/Following.js'; import { countIf } from '@/misc/prelude/array.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { QueryService } from '@/core/QueryService.js'; import { UtilityService } from '@/core/UtilityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -82,7 +87,7 @@ export class ActivityPubServerService { * @param note Note */ @bindThis - private async packActivity(note: Note): Promise { + private async packActivity(note: MiNote): Promise { if (note.renoteId && note.text == null && !note.hasPoll && (note.fileIds == null || note.fileIds.length === 0)) { const renote = await this.notesRepository.findOneByOrFail({ id: note.renoteId }); return this.apRendererService.renderAnnounce(renote.uri ? renote.uri : `${this.config.url}/notes/${renote.id}`, note); @@ -153,7 +158,7 @@ export class ActivityPubServerService { if (page) { const query = { followeeId: user.id, - } as FindOptionsWhere; + } as FindOptionsWhere; // カーソルが指定されている場合 if (cursor) { @@ -245,7 +250,7 @@ export class ActivityPubServerService { if (page) { const query = { followerId: user.id, - } as FindOptionsWhere; + } as FindOptionsWhere; // カーソルが指定されている場合 if (cursor) { @@ -419,7 +424,7 @@ export class ActivityPubServerService { } @bindThis - private async userInfo(request: FastifyRequest, reply: FastifyReply, user: User | null) { + private async userInfo(request: FastifyRequest, reply: FastifyReply, user: MiUser | null) { if (user == null) { reply.code(404); return; @@ -427,7 +432,7 @@ export class ActivityPubServerService { reply.header('Cache-Control', 'public, max-age=180'); this.setResponseType(request, reply); - return (this.apRendererService.addContext(await this.apRendererService.renderPerson(user as LocalUser))); + return (this.apRendererService.addContext(await this.apRendererService.renderPerson(user as MiLocalUser))); } @bindThis @@ -643,7 +648,7 @@ export class ActivityPubServerService { id: request.params.followee, host: Not(IsNull()), }), - ]) as [LocalUser | RemoteUser | null, LocalUser | RemoteUser | null]; + ]) as [MiLocalUser | MiRemoteUser | null, MiLocalUser | MiRemoteUser | null]; if (follower == null || followee == null) { reply.code(404); @@ -678,7 +683,7 @@ export class ActivityPubServerService { id: followRequest.followeeId, host: Not(IsNull()), }), - ]) as [LocalUser | RemoteUser | null, LocalUser | RemoteUser | null]; + ]) as [MiLocalUser | MiRemoteUser | null, MiLocalUser | MiRemoteUser | null]; if (follower == null || followee == null) { reply.code(404); diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts index 2547d73365..9df6ba2a76 100644 --- a/packages/backend/src/server/FileServerService.ts +++ b/packages/backend/src/server/FileServerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; @@ -6,7 +11,7 @@ import rename from 'rename'; import sharp from 'sharp'; import { sharpBmp } from 'sharp-read-bmp'; import type { Config } from '@/config.js'; -import type { DriveFile, DriveFilesRepository } from '@/models/index.js'; +import type { MiDriveFile, DriveFilesRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { createTemp } from '@/misc/create-temp.js'; import { FILE_TYPE_BROWSERSAFE } from '@/const.js'; @@ -367,8 +372,8 @@ export class FileServerService { @bindThis private async getStreamAndTypeFromUrl(url: string): Promise< - { state: 'remote'; fileRole?: 'thumbnail' | 'webpublic' | 'original'; file?: DriveFile; mime: string; ext: string | null; path: string; cleanup: () => void; filename: string; } - | { state: 'stored_internal'; fileRole: 'thumbnail' | 'webpublic' | 'original'; file: DriveFile; filename: string; mime: string; ext: string | null; path: string; } + { state: 'remote'; fileRole?: 'thumbnail' | 'webpublic' | 'original'; file?: MiDriveFile; mime: string; ext: string | null; path: string; cleanup: () => void; filename: string; } + | { state: 'stored_internal'; fileRole: 'thumbnail' | 'webpublic' | 'original'; file: MiDriveFile; filename: string; mime: string; ext: string | null; path: string; } | '404' | '204' > { @@ -406,8 +411,8 @@ export class FileServerService { @bindThis private async getFileFromKey(key: string): Promise< - { state: 'remote'; fileRole: 'thumbnail' | 'webpublic' | 'original'; file: DriveFile; filename: string; url: string; mime: string; ext: string | null; path: string; cleanup: () => void; } - | { state: 'stored_internal'; fileRole: 'thumbnail' | 'webpublic' | 'original'; file: DriveFile; filename: string; mime: string; ext: string | null; path: string; } + { state: 'remote'; fileRole: 'thumbnail' | 'webpublic' | 'original'; file: MiDriveFile; filename: string; url: string; mime: string; ext: string | null; path: string; cleanup: () => void; } + | { state: 'stored_internal'; fileRole: 'thumbnail' | 'webpublic' | 'original'; file: MiDriveFile; filename: string; mime: string; ext: string | null; path: string; } | '404' | '204' > { diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index 666a91fcee..95cc697768 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -1,6 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import type { NotesRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { MetaService } from '@/core/MetaService.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; @@ -21,12 +25,6 @@ export class NodeinfoServerService { @Inject(DI.config) private config: Config, - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - private userEntityService: UserEntityService, private metaService: MetaService, private notesChart: NotesChart, diff --git a/packages/backend/src/server/ServerModule.ts b/packages/backend/src/server/ServerModule.ts index da86b2c1d3..fa81380f01 100644 --- a/packages/backend/src/server/ServerModule.ts +++ b/packages/backend/src/server/ServerModule.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Module } from '@nestjs/common'; import { EndpointsModule } from '@/server/api/EndpointsModule.js'; import { CoreModule } from '@/core/CoreModule.js'; @@ -36,6 +41,7 @@ import { UserListChannelService } from './api/stream/channels/user-list.js'; import { OpenApiServerService } from './api/openapi/OpenApiServerService.js'; import { ClientLoggerService } from './web/ClientLoggerService.js'; import { RoleTimelineChannelService } from './api/stream/channels/role-timeline.js'; +import { OAuth2ProviderService } from './oauth/OAuth2ProviderService.js'; @Module({ imports: [ @@ -78,6 +84,7 @@ import { RoleTimelineChannelService } from './api/stream/channels/role-timeline. ServerStatsChannelService, UserListChannelService, OpenApiServerService, + OAuth2ProviderService, ], exports: [ ServerService, diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 051920958e..b40eeb31b1 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import cluster from 'node:cluster'; import * as fs from 'node:fs'; import { fileURLToPath } from 'node:url'; @@ -25,6 +30,7 @@ import { WellKnownServerService } from './WellKnownServerService.js'; import { FileServerService } from './FileServerService.js'; import { ClientServerService } from './web/ClientServerService.js'; import { OpenApiServerService } from './api/openapi/OpenApiServerService.js'; +import { OAuth2ProviderService } from './oauth/OAuth2ProviderService.js'; const _dirname = fileURLToPath(new URL('.', import.meta.url)); @@ -58,12 +64,13 @@ export class ServerService implements OnApplicationShutdown { private clientServerService: ClientServerService, private globalEventService: GlobalEventService, private loggerService: LoggerService, + private oauth2ProviderService: OAuth2ProviderService, ) { this.logger = this.loggerService.getLogger('server', 'gray', false); } @bindThis - public async launch() { + public async launch(): Promise { const fastify = Fastify({ trustProxy: true, logger: !['production', 'test'].includes(process.env.NODE_ENV ?? ''), @@ -92,6 +99,7 @@ export class ServerService implements OnApplicationShutdown { fastify.register(this.activityPubServerService.createServer); fastify.register(this.nodeinfoServerService.createServer); fastify.register(this.wellKnownServerService.createServer); + fastify.register(this.oauth2ProviderService.createServer); fastify.get<{ Params: { path: string }; Querystring: { static?: any; badge?: any; }; }>('/emoji/:path(.*)', async (request, reply) => { const path = request.params.path; diff --git a/packages/backend/src/server/WellKnownServerService.ts b/packages/backend/src/server/WellKnownServerService.ts index aabe631fb2..43c8dcf2c1 100644 --- a/packages/backend/src/server/WellKnownServerService.ts +++ b/packages/backend/src/server/WellKnownServerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import vary from 'vary'; @@ -6,7 +11,7 @@ import { DI } from '@/di-symbols.js'; import type { UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { escapeAttribute, escapeValue } from '@/misc/prelude/xml.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import * as Acct from '@/misc/acct.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -88,13 +93,13 @@ fastify.get('/.well-known/change-password', async (request, reply) => { */ fastify.get<{ Querystring: { resource: string } }>(webFingerPath, async (request, reply) => { - const fromId = (id: User['id']): FindOptionsWhere => ({ + const fromId = (id: MiUser['id']): FindOptionsWhere => ({ id, host: IsNull(), isSuspended: false, }); - const generateQuery = (resource: string): FindOptionsWhere | number => + const generateQuery = (resource: string): FindOptionsWhere | number => resource.startsWith(`${this.config.url.toLowerCase()}/users/`) ? fromId(resource.split('/').pop()!) : fromAcct(Acct.parse( @@ -102,7 +107,7 @@ fastify.get('/.well-known/change-password', async (request, reply) => { resource.startsWith('acct:') ? resource.slice('acct:'.length) : resource)); - const fromAcct = (acct: Acct.Acct): FindOptionsWhere | number => + const fromAcct = (acct: Acct.Acct): FindOptionsWhere | number => !acct.host || acct.host === this.config.host.toLowerCase() ? { usernameLower: acct.username, host: IsNull(), diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index c4c02e7afe..5d5a8f3706 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -1,12 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { randomUUID } from 'node:crypto'; -import { pipeline } from 'node:stream'; import * as fs from 'node:fs'; -import { promisify } from 'node:util'; +import * as stream from 'node:stream/promises'; import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import { getIpHash } from '@/misc/get-ip-hash.js'; -import type { LocalUser, User } from '@/models/entities/User.js'; -import type { AccessToken } from '@/models/entities/AccessToken.js'; +import type { MiLocalUser, MiUser } from '@/models/entities/User.js'; +import type { MiAccessToken } from '@/models/entities/AccessToken.js'; import type Logger from '@/logger.js'; import type { UserIpsRepository } from '@/models/index.js'; import { MetaService } from '@/core/MetaService.js'; @@ -21,8 +25,6 @@ import type { FastifyRequest, FastifyReply } from 'fastify'; import type { OnApplicationShutdown } from '@nestjs/common'; import type { IEndpointMeta, IEndpoint } from './endpoints.js'; -const pump = promisify(pipeline); - const accessDenied = { message: 'Access denied.', code: 'ACCESS_DENIED', @@ -32,7 +34,7 @@ const accessDenied = { @Injectable() export class ApiCallService implements OnApplicationShutdown { private logger: Logger; - private userIpHistories: Map>; + private userIpHistories: Map>; private userIpHistoriesClearIntervalId: NodeJS.Timer; constructor( @@ -46,7 +48,7 @@ export class ApiCallService implements OnApplicationShutdown { private apiLoggerService: ApiLoggerService, ) { this.logger = this.apiLoggerService.logger; - this.userIpHistories = new Map>(); + this.userIpHistories = new Map>(); this.userIpHistoriesClearIntervalId = setInterval(() => { this.userIpHistories.clear(); @@ -138,7 +140,7 @@ export class ApiCallService implements OnApplicationShutdown { } const [path] = await createTemp(); - await pump(multipartData.file, fs.createWriteStream(path)); + await stream.pipeline(multipartData.file, fs.createWriteStream(path)); const fields = {} as Record; for (const [k, v] of Object.entries(multipartData.fields)) { @@ -194,7 +196,7 @@ export class ApiCallService implements OnApplicationShutdown { } @bindThis - private async logIp(request: FastifyRequest, user: LocalUser) { + private async logIp(request: FastifyRequest, user: MiLocalUser) { const meta = await this.metaService.fetch(); if (!meta.enableIpLogging) return; const ip = request.ip; @@ -220,8 +222,8 @@ export class ApiCallService implements OnApplicationShutdown { @bindThis private async call( ep: IEndpoint & { exec: any }, - user: LocalUser | null | undefined, - token: AccessToken | null | undefined, + user: MiLocalUser | null | undefined, + token: MiAccessToken | null | undefined, data: any, file: { name: string; diff --git a/packages/backend/src/server/api/ApiLoggerService.ts b/packages/backend/src/server/api/ApiLoggerService.ts index 7f534b1efd..2339366a5d 100644 --- a/packages/backend/src/server/api/ApiLoggerService.ts +++ b/packages/backend/src/server/api/ApiLoggerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import { LoggerService } from '@/core/LoggerService.js'; diff --git a/packages/backend/src/server/api/ApiServerService.ts b/packages/backend/src/server/api/ApiServerService.ts index d3b1c7786d..96b6a821d5 100644 --- a/packages/backend/src/server/api/ApiServerService.ts +++ b/packages/backend/src/server/api/ApiServerService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import cors from '@fastify/cors'; import multipart from '@fastify/multipart'; import fastifyCookie from '@fastify/cookie'; import { ModuleRef } from '@nestjs/core'; import type { Config } from '@/config.js'; -import type { UsersRepository, InstancesRepository, AccessTokensRepository } from '@/models/index.js'; +import type { InstancesRepository, AccessTokensRepository } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -22,9 +27,6 @@ export class ApiServerService { @Inject(DI.config) private config: Config, - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts index 8b0fff80d9..8b031ab334 100644 --- a/packages/backend/src/server/api/AuthenticateService.ts +++ b/packages/backend/src/server/api/AuthenticateService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { AccessTokensRepository, AppsRepository, UsersRepository } from '@/models/index.js'; -import type { LocalUser } from '@/models/entities/User.js'; -import type { AccessToken } from '@/models/entities/AccessToken.js'; +import type { MiLocalUser } from '@/models/entities/User.js'; +import type { MiAccessToken } from '@/models/entities/AccessToken.js'; import { MemoryKVCache } from '@/misc/cache.js'; -import type { App } from '@/models/entities/App.js'; +import type { MiApp } from '@/models/entities/App.js'; import { CacheService } from '@/core/CacheService.js'; import isNativeToken from '@/misc/is-native-token.js'; import { bindThis } from '@/decorators.js'; @@ -18,7 +23,7 @@ export class AuthenticationError extends Error { @Injectable() export class AuthenticateService implements OnApplicationShutdown { - private appCache: MemoryKVCache; + private appCache: MemoryKVCache; constructor( @Inject(DI.usersRepository) @@ -32,18 +37,18 @@ export class AuthenticateService implements OnApplicationShutdown { private cacheService: CacheService, ) { - this.appCache = new MemoryKVCache(Infinity); + this.appCache = new MemoryKVCache(Infinity); } @bindThis - public async authenticate(token: string | null | undefined): Promise<[LocalUser | null, AccessToken | null]> { + public async authenticate(token: string | null | undefined): Promise<[MiLocalUser | null, MiAccessToken | null]> { if (token == null) { return [null, null]; } if (isNativeToken(token)) { const user = await this.cacheService.localUserByNativeTokenCache.fetch(token, - () => this.usersRepository.findOneBy({ token }) as Promise); + () => this.usersRepository.findOneBy({ token }) as Promise); if (user == null) { throw new AuthenticationError('user not found'); @@ -70,7 +75,7 @@ export class AuthenticateService implements OnApplicationShutdown { const user = await this.cacheService.localUserByIdCache.fetch(accessToken.userId, () => this.usersRepository.findOneBy({ id: accessToken.userId, - }) as Promise); + }) as Promise); if (accessToken.appId) { const app = await this.appCache.fetch(accessToken.appId, @@ -79,7 +84,7 @@ export class AuthenticateService implements OnApplicationShutdown { return [user, { id: accessToken.id, permission: app.permission, - } as AccessToken]; + } as MiAccessToken]; } else { return [user, accessToken]; } diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index 44e9a684b1..48f1de701e 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Module } from '@nestjs/common'; import { CoreModule } from '@/core/CoreModule.js'; @@ -331,6 +336,7 @@ import * as ep___users_lists_unfavorite from './endpoints/users/lists/unfavorite import * as ep___users_lists_create_from_public from './endpoints/users/lists/create-from-public.js'; import * as ep___users_notes from './endpoints/users/notes.js'; import * as ep___users_pages from './endpoints/users/pages.js'; +import * as ep___users_flashs from './endpoints/users/flashs.js'; import * as ep___users_reactions from './endpoints/users/reactions.js'; import * as ep___users_recommendation from './endpoints/users/recommendation.js'; import * as ep___users_relation from './endpoints/users/relation.js'; @@ -677,6 +683,7 @@ const $users_lists_unfavorite: Provider = { provide: 'ep:users/lists/unfavorite' const $users_lists_create_from_public: Provider = { provide: 'ep:users/lists/create-from-public', useClass: ep___users_lists_create_from_public.default }; const $users_notes: Provider = { provide: 'ep:users/notes', useClass: ep___users_notes.default }; const $users_pages: Provider = { provide: 'ep:users/pages', useClass: ep___users_pages.default }; +const $users_flashs: Provider = { provide: 'ep:users/flashs', useClass: ep___users_flashs.default }; const $users_reactions: Provider = { provide: 'ep:users/reactions', useClass: ep___users_reactions.default }; const $users_recommendation: Provider = { provide: 'ep:users/recommendation', useClass: ep___users_recommendation.default }; const $users_relation: Provider = { provide: 'ep:users/relation', useClass: ep___users_relation.default }; @@ -1027,6 +1034,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $users_lists_create_from_public, $users_notes, $users_pages, + $users_flashs, $users_reactions, $users_recommendation, $users_relation, @@ -1368,6 +1376,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $users_lists_create_from_public, $users_notes, $users_pages, + $users_flashs, $users_reactions, $users_recommendation, $users_relation, diff --git a/packages/backend/src/server/api/GetterService.ts b/packages/backend/src/server/api/GetterService.ts index c94884a78c..834a6ce4ca 100644 --- a/packages/backend/src/server/api/GetterService.ts +++ b/packages/backend/src/server/api/GetterService.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { NotesRepository, UsersRepository } from '@/models/index.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; -import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -24,7 +29,7 @@ export class GetterService { * Get note for API processing */ @bindThis - public async getNote(noteId: Note['id']) { + public async getNote(noteId: MiNote['id']) { const note = await this.notesRepository.findOneBy({ id: noteId }); if (note == null) { @@ -38,21 +43,21 @@ export class GetterService { * Get user for API processing */ @bindThis - public async getUser(userId: User['id']) { + public async getUser(userId: MiUser['id']) { const user = await this.usersRepository.findOneBy({ id: userId }); if (user == null) { throw new IdentifiableError('15348ddd-432d-49c2-8a5a-8069753becff', 'No such user.'); } - return user as LocalUser | RemoteUser; + return user as MiLocalUser | MiRemoteUser; } /** * Get remote user for API processing */ @bindThis - public async getRemoteUser(userId: User['id']) { + public async getRemoteUser(userId: MiUser['id']) { const user = await this.getUser(userId); if (!this.userEntityService.isRemoteUser(user)) { @@ -66,7 +71,7 @@ export class GetterService { * Get local user for API processing */ @bindThis - public async getLocalUser(userId: User['id']) { + public async getLocalUser(userId: MiUser['id']) { const user = await this.getUser(userId); if (!this.userEntityService.isLocalUser(user)) { diff --git a/packages/backend/src/server/api/RateLimiterService.ts b/packages/backend/src/server/api/RateLimiterService.ts index f6ffbfab50..0e644aa091 100644 --- a/packages/backend/src/server/api/RateLimiterService.ts +++ b/packages/backend/src/server/api/RateLimiterService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import Limiter from 'ratelimiter'; import * as Redis from 'ioredis'; diff --git a/packages/backend/src/server/api/SigninApiService.ts b/packages/backend/src/server/api/SigninApiService.ts index bd3d8a28da..d68b2617e3 100644 --- a/packages/backend/src/server/api/SigninApiService.ts +++ b/packages/backend/src/server/api/SigninApiService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { randomBytes } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import bcrypt from 'bcryptjs'; @@ -7,7 +12,7 @@ import { DI } from '@/di-symbols.js'; import type { UserSecurityKeysRepository, SigninsRepository, UserProfilesRepository, AttestationChallengesRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { getIpHash } from '@/misc/get-ip-hash.js'; -import type { LocalUser } from '@/models/entities/User.js'; +import type { MiLocalUser } from '@/models/entities/User.js'; import { IdService } from '@/core/IdService.js'; import { TwoFactorAuthenticationService } from '@/core/TwoFactorAuthenticationService.js'; import { bindThis } from '@/decorators.js'; @@ -105,7 +110,7 @@ export class SigninApiService { const user = await this.usersRepository.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull(), - }) as LocalUser; + }) as MiLocalUser; if (user == null) { return error(404, { diff --git a/packages/backend/src/server/api/SigninService.ts b/packages/backend/src/server/api/SigninService.ts index 96666f1f49..9f731e01bd 100644 --- a/packages/backend/src/server/api/SigninService.ts +++ b/packages/backend/src/server/api/SigninService.ts @@ -1,9 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; import type { SigninsRepository } from '@/models/index.js'; -import type { Config } from '@/config.js'; import { IdService } from '@/core/IdService.js'; -import type { LocalUser } from '@/models/entities/User.js'; +import type { MiLocalUser } from '@/models/entities/User.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { SigninEntityService } from '@/core/entities/SigninEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -12,9 +16,6 @@ import type { FastifyRequest, FastifyReply } from 'fastify'; @Injectable() export class SigninService { constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.signinsRepository) private signinsRepository: SigninsRepository, @@ -25,7 +26,7 @@ export class SigninService { } @bindThis - public signin(request: FastifyRequest, reply: FastifyReply, user: LocalUser) { + public signin(request: FastifyRequest, reply: FastifyReply, user: MiLocalUser) { setImmediate(async () => { // Append signin history const record = await this.signinsRepository.insert({ diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index 7b215cea79..6e0351d298 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import bcrypt from 'bcryptjs'; import { IsNull } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, RegistrationTicket } from '@/models/index.js'; +import type { RegistrationTicketsRepository, UsedUsernamesRepository, UserPendingsRepository, UserProfilesRepository, UsersRepository, MiRegistrationTicket } from '@/models/index.js'; import type { Config } from '@/config.js'; import { MetaService } from '@/core/MetaService.js'; import { CaptchaService } from '@/core/CaptchaService.js'; @@ -10,7 +15,7 @@ import { IdService } from '@/core/IdService.js'; import { SignupService } from '@/core/SignupService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { EmailService } from '@/core/EmailService.js'; -import { LocalUser } from '@/models/entities/User.js'; +import { MiLocalUser } from '@/models/entities/User.js'; import { FastifyReplyError } from '@/misc/fastify-reply-error.js'; import { bindThis } from '@/decorators.js'; import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js'; @@ -109,7 +114,7 @@ export class SignupApiService { } } - let ticket: RegistrationTicket | null = null; + let ticket: MiRegistrationTicket | null = null; if (instance.disableRegistration) { if (invitationCode == null || typeof invitationCode !== 'string') { @@ -246,7 +251,7 @@ export class SignupApiService { }); } - return this.signinService.signin(request, reply, account as LocalUser); + return this.signinService.signin(request, reply, account as MiLocalUser); } catch (err) { throw new FastifyReplyError(400, typeof err === 'string' ? err : (err as Error).toString()); } diff --git a/packages/backend/src/server/api/StreamingApiServerService.ts b/packages/backend/src/server/api/StreamingApiServerService.ts index e4291becf0..74c4691435 100644 --- a/packages/backend/src/server/api/StreamingApiServerService.ts +++ b/packages/backend/src/server/api/StreamingApiServerService.ts @@ -1,16 +1,19 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { EventEmitter } from 'events'; import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; import * as WebSocket from 'ws'; import { DI } from '@/di-symbols.js'; -import type { UsersRepository, AccessToken } from '@/models/index.js'; -import type { Config } from '@/config.js'; +import type { UsersRepository, MiAccessToken } from '@/models/index.js'; import { NoteReadService } from '@/core/NoteReadService.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { NotificationService } from '@/core/NotificationService.js'; import { bindThis } from '@/decorators.js'; import { CacheService } from '@/core/CacheService.js'; -import { LocalUser } from '@/models/entities/User.js'; +import { MiLocalUser } from '@/models/entities/User.js'; import { AuthenticateService, AuthenticationError } from './AuthenticateService.js'; import MainStreamConnection from './stream/index.js'; import { ChannelsService } from './stream/ChannelsService.js'; @@ -23,9 +26,6 @@ export class StreamingApiServerService { #cleanConnectionsIntervalId: NodeJS.Timeout | null = null; constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.redisForSub) private redisForSub: Redis.Redis, @@ -55,8 +55,8 @@ export class StreamingApiServerService { const q = new URL(request.url, `http://${request.headers.host}`).searchParams; - let user: LocalUser | null = null; - let app: AccessToken | null = null; + let user: MiLocalUser | null = null; + let app: MiAccessToken | null = null; // https://datatracker.ietf.org/doc/html/rfc6750.html#section-2.1 // Note that the standard WHATWG WebSocket API does not support setting any headers, @@ -112,8 +112,8 @@ export class StreamingApiServerService { this.#wss.on('connection', async (connection: WebSocket.WebSocket, request: http.IncomingMessage, ctx: { stream: MainStreamConnection, - user: LocalUser | null; - app: AccessToken | null + user: MiLocalUser | null; + app: MiAccessToken | null }) => { const { stream, user, app } = ctx; diff --git a/packages/backend/src/server/api/endpoint-base.ts b/packages/backend/src/server/api/endpoint-base.ts index 364fa7a19b..531311e475 100644 --- a/packages/backend/src/server/api/endpoint-base.ts +++ b/packages/backend/src/server/api/endpoint-base.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as fs from 'node:fs'; import _Ajv from 'ajv'; import type { Schema, SchemaType } from '@/misc/json-schema.js'; -import type { LocalUser } from '@/models/entities/User.js'; -import type { AccessToken } from '@/models/entities/AccessToken.js'; +import type { MiLocalUser } from '@/models/entities/User.js'; +import type { MiAccessToken } from '@/models/entities/AccessToken.js'; import { ApiError } from './error.js'; import type { IEndpointMeta } from './endpoints.js'; @@ -23,16 +28,16 @@ type File = { // TODO: paramsの型をT['params']のスキーマ定義から推論する type Executor = - (params: SchemaType, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record | null) => + (params: SchemaType, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record | null) => Promise>>; export abstract class Endpoint { - public exec: (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, ip?: string | null, headers?: Record | null) => Promise; + public exec: (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record | null) => Promise; constructor(meta: T, paramDef: Ps, cb: Executor) { const validate = ajv.compile(paramDef); - this.exec = (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: AccessToken | null, file?: File, ip?: string | null, headers?: Record | null) => { + this.exec = (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record | null) => { let cleanup: undefined | (() => void) = undefined; if (meta.requireFile) { diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 41c3a29eec..3924b43d16 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { Schema } from '@/misc/json-schema.js'; import { RolePolicies } from '@/core/RoleService.js'; @@ -331,6 +336,7 @@ import * as ep___users_lists_create_from_public from './endpoints/users/lists/cr import * as ep___users_lists_update from './endpoints/users/lists/update.js'; import * as ep___users_notes from './endpoints/users/notes.js'; import * as ep___users_pages from './endpoints/users/pages.js'; +import * as ep___users_flashs from './endpoints/users/flashs.js'; import * as ep___users_reactions from './endpoints/users/reactions.js'; import * as ep___users_recommendation from './endpoints/users/recommendation.js'; import * as ep___users_relation from './endpoints/users/relation.js'; @@ -674,6 +680,7 @@ const eps = [ ['users/lists/create-from-public', ep___users_lists_create_from_public], ['users/notes', ep___users_notes], ['users/pages', ep___users_pages], + ['users/flashs', ep___users_flashs], ['users/reactions', ep___users_reactions], ['users/recommendation', ep___users_recommendation], ['users/relation', ep___users_relation], @@ -800,4 +807,5 @@ const endpoints: IEndpoint[] = (eps as [string, any]).map(([name, ep]) => { }; }); +// eslint-disable-next-line import/no-default-export export default endpoints; diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts index b8ea74b7c5..9a07b31815 100644 --- a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts +++ b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AbuseUserReportsRepository } from '@/models/index.js'; @@ -87,9 +92,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.abuseUserReportsRepository) private abuseUserReportsRepository: AbuseUserReportsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts index 8a3541dffe..48af74f10e 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['username', 'password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts b/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts index 16232813a8..1dd60eb269 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/index.js'; import { QueueService } from '@/core/QueueService.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { UserSuspendService } from '@/core/UserSuspendService.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -22,16 +26,14 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, private userEntityService: UserEntityService, private queueService: QueueService, - private globalEventService: GlobalEventService, private userSuspendService: UserSuspendService, ) { super(meta, paramDef, async (ps, me) => { diff --git a/packages/backend/src/server/api/endpoints/admin/ad/create.ts b/packages/backend/src/server/api/endpoints/admin/ad/create.ts index 757030839e..5ebb103085 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AdsRepository } from '@/models/index.js'; @@ -27,9 +32,8 @@ export const paramDef = { required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'imageUrl', 'dayOfWeek'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.adsRepository) private adsRepository: AdsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/ad/delete.ts b/packages/backend/src/server/api/endpoints/admin/ad/delete.ts index f4c9885408..8ee99c2281 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AdsRepository } from '@/models/index.js'; @@ -27,9 +32,8 @@ export const paramDef = { required: ['id'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.adsRepository) private adsRepository: AdsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/ad/list.ts b/packages/backend/src/server/api/endpoints/admin/ad/list.ts index 725ddb58be..97b1b25dc2 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AdsRepository } from '@/models/index.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.adsRepository) private adsRepository: AdsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/ad/update.ts b/packages/backend/src/server/api/endpoints/admin/ad/update.ts index 70082290ba..9b07ee51a9 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AdsRepository } from '@/models/index.js'; @@ -36,9 +41,8 @@ export const paramDef = { required: ['id', 'memo', 'url', 'imageUrl', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'dayOfWeek'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.adsRepository) private adsRepository: AdsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts index 751b6be7f4..c2f69bb159 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts @@ -1,8 +1,11 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { AnnouncementsRepository } from '@/models/index.js'; -import { IdService } from '@/core/IdService.js'; -import { DI } from '@/di-symbols.js'; +import { AnnouncementService } from '@/core/AnnouncementService.js'; export const meta = { tags: ['admin'], @@ -52,30 +55,35 @@ export const paramDef = { title: { type: 'string', minLength: 1 }, text: { type: 'string', minLength: 1 }, imageUrl: { type: 'string', nullable: true, minLength: 1 }, + icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'], default: 'info' }, + display: { type: 'string', enum: ['normal', 'banner', 'dialog'], default: 'normal' }, + forExistingUsers: { type: 'boolean', default: false }, + needConfirmationToRead: { type: 'boolean', default: false }, + userId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, }, required: ['title', 'text', 'imageUrl'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.announcementsRepository) - private announcementsRepository: AnnouncementsRepository, - - private idService: IdService, + private announcementService: AnnouncementService, ) { super(meta, paramDef, async (ps, me) => { - const announcement = await this.announcementsRepository.insert({ - id: this.idService.genId(), + const { raw, packed } = await this.announcementService.create({ createdAt: new Date(), updatedAt: null, title: ps.title, text: ps.text, imageUrl: ps.imageUrl, - }).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0])); + icon: ps.icon, + display: ps.display, + forExistingUsers: ps.forExistingUsers, + needConfirmationToRead: ps.needConfirmationToRead, + userId: ps.userId, + }); - return Object.assign({}, announcement, { createdAt: announcement.createdAt.toISOString(), updatedAt: null }); + return packed; }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts b/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts index 18d50b8b2a..1a4061624f 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AnnouncementsRepository } from '@/models/index.js'; @@ -27,9 +32,8 @@ export const paramDef = { required: ['id'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts index 11231f6e04..2b4080bb02 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { AnnouncementsRepository, AnnouncementReadsRepository } from '@/models/index.js'; -import type { Announcement } from '@/models/entities/Announcement.js'; +import type { MiAnnouncement } from '@/models/entities/Announcement.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import { DI } from '@/di-symbols.js'; @@ -61,13 +66,13 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + userId: { type: 'string', format: 'misskey:id', nullable: true }, }, required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, @@ -79,10 +84,15 @@ export default class extends Endpoint { ) { super(meta, paramDef, async (ps, me) => { const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId); + if (ps.userId) { + query.andWhere('announcement.userId = :userId', { userId: ps.userId }); + } else { + query.andWhere('announcement.userId IS NULL'); + } const announcements = await query.limit(ps.limit).getMany(); - const reads = new Map(); + const reads = new Map(); for (const announcement of announcements) { reads.set(announcement, await this.announcementReadsRepository.countBy({ @@ -97,6 +107,12 @@ export default class extends Endpoint { title: announcement.title, text: announcement.text, imageUrl: announcement.imageUrl, + icon: announcement.icon, + display: announcement.display, + isActive: announcement.isActive, + forExistingUsers: announcement.forExistingUsers, + needConfirmationToRead: announcement.needConfirmationToRead, + userId: announcement.userId, reads: reads.get(announcement)!, })); }); diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts index 8cf9341a71..1b35f7ecd0 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AnnouncementsRepository } from '@/models/index.js'; @@ -26,13 +31,17 @@ export const paramDef = { title: { type: 'string', minLength: 1 }, text: { type: 'string', minLength: 1 }, imageUrl: { type: 'string', nullable: true, minLength: 0 }, + icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'] }, + display: { type: 'string', enum: ['normal', 'banner', 'dialog'] }, + forExistingUsers: { type: 'boolean' }, + needConfirmationToRead: { type: 'boolean' }, + isActive: { type: 'boolean' }, }, - required: ['id', 'title', 'text', 'imageUrl'], + required: ['id'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, @@ -48,6 +57,11 @@ export default class extends Endpoint { text: ps.text, /* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- 空の文字列の場合、nullを渡すようにするため */ imageUrl: ps.imageUrl || null, + display: ps.display, + icon: ps.icon, + forExistingUsers: ps.forExistingUsers, + needConfirmationToRead: ps.needConfirmationToRead, + isActive: ps.isActive, }); }); } diff --git a/packages/backend/src/server/api/endpoints/admin/delete-account.ts b/packages/backend/src/server/api/endpoints/admin/delete-account.ts index d0485fddd8..2738550a51 100644 --- a/packages/backend/src/server/api/endpoints/admin/delete-account.ts +++ b/packages/backend/src/server/api/endpoints/admin/delete-account.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -22,9 +27,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts b/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts index c193ed3fb3..f6bb5c24dc 100644 --- a/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts index a8964af449..8af44029c5 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueueService } from '@/core/QueueService.js'; @@ -15,9 +20,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts index 4f7e02fe92..995deb5f3b 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/drive/files.ts b/packages/backend/src/server/api/endpoints/admin/drive/files.ts index 2901fdb774..1a319cef96 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/files.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/files.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { DriveFilesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -41,9 +46,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts index 1d27ac2137..fa0c92df71 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { DriveFilesRepository, UsersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -148,9 +153,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts index 6e604ed885..66ee4cab3b 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -22,9 +27,8 @@ export const paramDef = { required: ['ids', 'aliases'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts index 200ede0b06..412b912179 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/index.js'; @@ -47,9 +52,8 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts index 82dca9cc70..57bf56326c 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts @@ -1,9 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import { DataSource } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { EmojisRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { DI } from '@/di-symbols.js'; import { DriveService } from '@/core/DriveService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; @@ -47,13 +51,9 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.db) - private db: DataSource, - @Inject(DI.emojisRepository) private emojisRepository: EmojisRepository, @@ -69,7 +69,7 @@ export default class extends Endpoint { throw new ApiError(meta.errors.noSuchEmoji); } - let driveFile: DriveFile; + let driveFile: MiDriveFile; try { // Create file diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts index 9f8263629b..4221913049 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['ids'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts b/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts index 429c819fe0..f020e22182 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -25,9 +30,8 @@ export const paramDef = { required: ['id'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts index e26f0506ce..208616c0ac 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueueService } from '@/core/QueueService.js'; @@ -16,9 +21,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts index 8d50413e95..88190cb7c3 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { EmojisRepository } from '@/models/index.js'; @@ -72,9 +77,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.emojisRepository) private emojisRepository: EmojisRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts index 29b20fab86..a58ca4b8d9 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { EmojisRepository } from '@/models/index.js'; -import type { Emoji } from '@/models/entities/Emoji.js'; +import type { MiEmoji } from '@/models/entities/Emoji.js'; import { QueryService } from '@/core/QueryService.js'; import { DI } from '@/di-symbols.js'; import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; @@ -66,9 +71,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.emojisRepository) private emojisRepository: EmojisRepository, @@ -80,7 +84,7 @@ export default class extends Endpoint { const q = this.queryService.makePaginationQuery(this.emojisRepository.createQueryBuilder('emoji'), ps.sinceId, ps.untilId) .andWhere('emoji.host IS NULL'); - let emojis: Emoji[]; + let emojis: MiEmoji[]; if (ps.query) { //q.andWhere('emoji.name ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` }); diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts index 83f882cac5..a5dd6d5e3a 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -22,9 +27,8 @@ export const paramDef = { required: ['ids', 'aliases'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts index 1d3a432bb7..515053f57b 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -22,9 +27,8 @@ export const paramDef = { required: ['ids', 'aliases'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts index 453968c7a9..8e834ad1dd 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['ids'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts index b90b9757be..2dc9595a7e 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['ids'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private customEmojiService: CustomEmojiService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts index edc1af5a53..f3bd3dc716 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; @@ -54,9 +59,8 @@ export const paramDef = { required: ['id', 'name', 'aliases'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts b/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts index 38fe99b222..4ac5640b28 100644 --- a/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts +++ b/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts b/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts index b7f2858a77..6b3f1a68d8 100644 --- a/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts +++ b/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { InstancesRepository } from '@/models/index.js'; @@ -20,9 +25,8 @@ export const paramDef = { required: ['host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts b/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts index 83f729953a..31debfc9a7 100644 --- a/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts +++ b/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { FollowingsRepository, UsersRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts index 4fd74e591d..3d36f5e3a4 100644 --- a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts +++ b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { InstancesRepository } from '@/models/index.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: ['host', 'isSuspended'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts b/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts index 8ffd2b01e7..4bd9e7de7f 100644 --- a/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts +++ b/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -16,9 +21,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts b/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts index 09d61bd741..f953b889a3 100644 --- a/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts +++ b/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DataSource } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -27,9 +32,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts b/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts index bfcc8a700b..d50fdb377f 100644 --- a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts +++ b/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserIpsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userIpsRepository) private userIpsRepository: UserIpsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/invite/create.ts b/packages/backend/src/server/api/endpoints/admin/invite/create.ts index 664b4d819f..eca633405d 100644 --- a/packages/backend/src/server/api/endpoints/admin/invite/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/invite/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistrationTicketsRepository } from '@/models/index.js'; @@ -47,9 +52,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registrationTicketsRepository) private registrationTicketsRepository: RegistrationTicketsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/invite/list.ts b/packages/backend/src/server/api/endpoints/admin/invite/list.ts index d8bf6e286f..8ac1b332dd 100644 --- a/packages/backend/src/server/api/endpoints/admin/invite/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/invite/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistrationTicketsRepository } from '@/models/index.js'; @@ -31,9 +36,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registrationTicketsRepository) private registrationTicketsRepository: RegistrationTicketsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 084bdb598b..9b6dee296e 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { MetaService } from '@/core/MetaService.js'; @@ -288,9 +293,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, diff --git a/packages/backend/src/server/api/endpoints/admin/promo/create.ts b/packages/backend/src/server/api/endpoints/admin/promo/create.ts index 8401cf51d9..d20d5d625d 100644 --- a/packages/backend/src/server/api/endpoints/admin/promo/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/promo/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { PromoNotesRepository } from '@/models/index.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['noteId', 'expiresAt'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.promoNotesRepository) private promoNotesRepository: PromoNotesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/queue/clear.ts b/packages/backend/src/server/api/endpoints/admin/queue/clear.ts index 099e2ff220..b61c580034 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/clear.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/clear.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; @@ -16,9 +21,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private moderationLogService: ModerationLogService, private queueService: QueueService, diff --git a/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts b/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts index 9442bda5eb..1515ae4c74 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -39,9 +44,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject('queue:deliver') public deliverQueue: DeliverQueue, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts b/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts index 55a3410d49..febe0d07c6 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -39,9 +44,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject('queue:inbox') public inboxQueue: InboxQueue, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/queue/promote.ts b/packages/backend/src/server/api/endpoints/admin/queue/promote.ts index 8330d6c82f..8d16cddd00 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/promote.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/promote.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: ['type'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private moderationLogService: ModerationLogService, private queueService: QueueService, diff --git a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts index 7f3732c970..901195e9a5 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, WebhookDeliverQueue } from '@/core/QueueModule.js'; @@ -38,9 +43,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject('queue:system') public systemQueue: SystemQueue, @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, diff --git a/packages/backend/src/server/api/endpoints/admin/relays/add.ts b/packages/backend/src/server/api/endpoints/admin/relays/add.ts index f2d4aa8996..b675db2b89 100644 --- a/packages/backend/src/server/api/endpoints/admin/relays/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/relays/add.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URL } from 'node:url'; import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -54,9 +59,8 @@ export const paramDef = { required: ['inbox'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private relayService: RelayService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/relays/list.ts b/packages/backend/src/server/api/endpoints/admin/relays/list.ts index 910c90e78e..0633c57ed5 100644 --- a/packages/backend/src/server/api/endpoints/admin/relays/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/relays/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { RelayService } from '@/core/RelayService.js'; @@ -46,9 +51,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private relayService: RelayService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/relays/remove.ts b/packages/backend/src/server/api/endpoints/admin/relays/remove.ts index 5e26f61fa7..661b4243c4 100644 --- a/packages/backend/src/server/api/endpoints/admin/relays/remove.ts +++ b/packages/backend/src/server/api/endpoints/admin/relays/remove.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { RelayService } from '@/core/RelayService.js'; @@ -17,9 +22,8 @@ export const paramDef = { required: ['inbox'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private relayService: RelayService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/reset-password.ts b/packages/backend/src/server/api/endpoints/admin/reset-password.ts index e9c3b0e69f..77217e2ed2 100644 --- a/packages/backend/src/server/api/endpoints/admin/reset-password.ts +++ b/packages/backend/src/server/api/endpoints/admin/reset-password.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import bcrypt from 'bcryptjs'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts index aead894611..973dc2e700 100644 --- a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts +++ b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository, AbuseUserReportsRepository } from '@/models/index.js'; @@ -24,9 +29,8 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/assign.ts b/packages/backend/src/server/api/endpoints/admin/roles/assign.ts index b80aaba122..96887d2198 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/assign.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/assign.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository, UsersRepository } from '@/models/index.js'; @@ -48,9 +53,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/create.ts b/packages/backend/src/server/api/endpoints/admin/roles/create.ts index 916172f54a..37602490d1 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository } from '@/models/index.js'; @@ -50,9 +55,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/delete.ts b/packages/backend/src/server/api/endpoints/admin/roles/delete.ts index b56ebdb3ee..4a7694c3a6 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/delete.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository } from '@/models/index.js'; @@ -30,9 +35,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/list.ts b/packages/backend/src/server/api/endpoints/admin/roles/list.ts index edaf638ea9..07e4ec1573 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/show.ts b/packages/backend/src/server/api/endpoints/admin/roles/show.ts index 01028a086f..c5908ed47a 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/show.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository } from '@/models/index.js'; @@ -30,9 +35,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/unassign.ts b/packages/backend/src/server/api/endpoints/admin/roles/unassign.ts index 45c4f76943..15bebdc330 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/unassign.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/unassign.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository, UsersRepository } from '@/models/index.js'; @@ -50,9 +55,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/update-default-policies.ts b/packages/backend/src/server/api/endpoints/admin/roles/update-default-policies.ts index 5a34eee96c..b4e7e29e90 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/update-default-policies.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/update-default-policies.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; @@ -22,9 +27,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private metaService: MetaService, private globalEventService: GlobalEventService, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/update.ts b/packages/backend/src/server/api/endpoints/admin/roles/update.ts index 1fedab4540..a622e99f38 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository } from '@/models/index.js'; @@ -59,9 +64,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/roles/users.ts b/packages/backend/src/server/api/endpoints/admin/roles/users.ts index 63650bb2bf..a7fe9562a6 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/users.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Brackets } from 'typeorm'; import type { RoleAssignmentsRepository, RolesRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: ['roleId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/send-email.ts b/packages/backend/src/server/api/endpoints/admin/send-email.ts index 5ddc62f476..b9f2c6a6f1 100644 --- a/packages/backend/src/server/api/endpoints/admin/send-email.ts +++ b/packages/backend/src/server/api/endpoints/admin/send-email.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { EmailService } from '@/core/EmailService.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['to', 'subject', 'text'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private emailService: EmailService, ) { diff --git a/packages/backend/src/server/api/endpoints/admin/server-info.ts b/packages/backend/src/server/api/endpoints/admin/server-info.ts index 4ef4fdc665..3169373b0e 100644 --- a/packages/backend/src/server/api/endpoints/admin/server-info.ts +++ b/packages/backend/src/server/api/endpoints/admin/server-info.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as os from 'node:os'; import si from 'systeminformation'; import { Inject, Injectable } from '@nestjs/common'; @@ -95,9 +100,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts b/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts index 69c95ef19c..43c9a12c59 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ModerationLogsRepository } from '@/models/index.js'; @@ -61,9 +66,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.moderationLogsRepository) private moderationLogsRepository: ModerationLogsRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index 6f805b6b4e..26f4c91f7a 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, SigninsRepository, UserProfilesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -25,9 +30,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/show-users.ts b/packages/backend/src/server/api/endpoints/admin/show-users.ts index 2ae5bc3de3..4008f8d78e 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-users.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -42,9 +47,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/suspend-user.ts b/packages/backend/src/server/api/endpoints/admin/suspend-user.ts index eabbceac0e..d885e47de0 100644 --- a/packages/backend/src/server/api/endpoints/admin/suspend-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/suspend-user.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull, Not } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import type { RelationshipJobData } from '@/queue/types.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; import { UserSuspendService } from '@/core/UserSuspendService.js'; @@ -26,9 +31,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -68,7 +72,7 @@ export default class extends Endpoint { } @bindThis - private async unFollowAll(follower: User) { + private async unFollowAll(follower: MiUser) { const followings = await this.followingsRepository.find({ where: { followerId: follower.id, diff --git a/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts b/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts index 2805c21a74..0980e3d420 100644 --- a/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/index.js'; @@ -20,9 +25,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index b29a4e8398..392a4a2c2a 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -1,10 +1,13 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; -import { DataSource } from 'typeorm'; -import type { Meta } from '@/models/entities/Meta.js'; +import type { MiMeta } from '@/models/entities/Meta.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { DI } from '@/di-symbols.js'; import { MetaService } from '@/core/MetaService.js'; import { ServerStatsService } from '@/daemons/ServerStatsService.js'; @@ -107,20 +110,16 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private moduleRef: ModuleRef, - @Inject(DI.db) - private db: DataSource, - private metaService: MetaService, private moderationLogService: ModerationLogService, ) { super(meta, paramDef, async (ps, me) => { - const set = {} as Partial; + const set = {} as Partial; if (typeof ps.disableRegistration === 'boolean') { set.disableRegistration = ps.disableRegistration; diff --git a/packages/backend/src/server/api/endpoints/admin/update-user-note.ts b/packages/backend/src/server/api/endpoints/admin/update-user-note.ts index 33808ee70f..e155f8c934 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-user-note.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-user-note.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserProfilesRepository, UsersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['userId', 'text'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/announcements.ts b/packages/backend/src/server/api/endpoints/announcements.ts index 735af51ee2..bd4dc0b8bc 100644 --- a/packages/backend/src/server/api/endpoints/announcements.ts +++ b/packages/backend/src/server/api/endpoints/announcements.ts @@ -1,6 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; +import { Brackets } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; +import { AnnouncementService } from '@/core/AnnouncementService.js'; import { DI } from '@/di-symbols.js'; import type { AnnouncementReadsRepository, AnnouncementsRepository } from '@/models/index.js'; @@ -15,40 +22,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string', - optional: false, nullable: false, - format: 'date-time', - }, - updatedAt: { - type: 'string', - optional: false, nullable: true, - format: 'date-time', - }, - text: { - type: 'string', - optional: false, nullable: false, - }, - title: { - type: 'string', - optional: false, nullable: false, - }, - imageUrl: { - type: 'string', - optional: false, nullable: true, - }, - isRead: { - type: 'boolean', - optional: true, nullable: false, - }, - }, + ref: 'Announcement', }, }, } as const; @@ -57,16 +31,15 @@ export const paramDef = { type: 'object', properties: { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - withUnreads: { type: 'boolean', default: false }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + isActive: { type: 'boolean', default: true }, }, required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.announcementsRepository) private announcementsRepository: AnnouncementsRepository, @@ -75,27 +48,19 @@ export default class extends Endpoint { private announcementReadsRepository: AnnouncementReadsRepository, private queryService: QueryService, + private announcementService: AnnouncementService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId); + const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId) + .where('announcement.isActive = :isActive', { isActive: ps.isActive }) + .andWhere(new Brackets(qb => { + if (me) qb.orWhere('announcement.userId = :meId', { meId: me.id }); + qb.orWhere('announcement.userId IS NULL'); + })); const announcements = await query.limit(ps.limit).getMany(); - if (me) { - const reads = (await this.announcementReadsRepository.findBy({ - userId: me.id, - })).map(x => x.announcementId); - - for (const announcement of announcements) { - (announcement as any).isRead = reads.includes(announcement.id); - } - } - - return (ps.withUnreads ? announcements.filter((a: any) => !a.isRead) : announcements).map((a) => ({ - ...a, - createdAt: a.createdAt.toISOString(), - updatedAt: a.updatedAt?.toISOString() ?? null, - })); + return this.announcementService.packMany(announcements, me); }); } } diff --git a/packages/backend/src/server/api/endpoints/antennas/create.ts b/packages/backend/src/server/api/endpoints/antennas/create.ts index 5754a9f12a..1f6a3fa736 100644 --- a/packages/backend/src/server/api/endpoints/antennas/create.ts +++ b/packages/backend/src/server/api/endpoints/antennas/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { IdService } from '@/core/IdService.js'; @@ -65,9 +70,8 @@ export const paramDef = { required: ['name', 'src', 'keywords', 'excludeKeywords', 'users', 'caseSensitive', 'withReplies', 'withFile', 'notify'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.antennasRepository) private antennasRepository: AntennasRepository, @@ -81,8 +85,8 @@ export default class extends Endpoint { private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { - if ((ps.keywords.length === 0) || ps.keywords[0].every(x => x === '')) { - throw new Error('invalid param'); + if (ps.keywords.flat().every(x => x === '') && ps.excludeKeywords.flat().every(x => x === '')) { + throw new Error('either keywords or excludeKeywords is required.'); } const currentAntennasCount = await this.antennasRepository.countBy({ diff --git a/packages/backend/src/server/api/endpoints/antennas/delete.ts b/packages/backend/src/server/api/endpoints/antennas/delete.ts index 5da7a2cb66..f59911017d 100644 --- a/packages/backend/src/server/api/endpoints/antennas/delete.ts +++ b/packages/backend/src/server/api/endpoints/antennas/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AntennasRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: ['antennaId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.antennasRepository) private antennasRepository: AntennasRepository, diff --git a/packages/backend/src/server/api/endpoints/antennas/list.ts b/packages/backend/src/server/api/endpoints/antennas/list.ts index a0f8979574..71d5b746a6 100644 --- a/packages/backend/src/server/api/endpoints/antennas/list.ts +++ b/packages/backend/src/server/api/endpoints/antennas/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AntennasRepository } from '@/models/index.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.antennasRepository) private antennasRepository: AntennasRepository, diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts index 2c4247cb70..4b49f8aead 100644 --- a/packages/backend/src/server/api/endpoints/antennas/notes.ts +++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -48,9 +53,8 @@ export const paramDef = { required: ['antennaId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.redis) private redisClient: Redis.Redis, diff --git a/packages/backend/src/server/api/endpoints/antennas/show.ts b/packages/backend/src/server/api/endpoints/antennas/show.ts index ef7ed5b72c..b2168dacf0 100644 --- a/packages/backend/src/server/api/endpoints/antennas/show.ts +++ b/packages/backend/src/server/api/endpoints/antennas/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AntennasRepository } from '@/models/index.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['antennaId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.antennasRepository) private antennasRepository: AntennasRepository, diff --git a/packages/backend/src/server/api/endpoints/antennas/update.ts b/packages/backend/src/server/api/endpoints/antennas/update.ts index 55218b644b..6247c5469f 100644 --- a/packages/backend/src/server/api/endpoints/antennas/update.ts +++ b/packages/backend/src/server/api/endpoints/antennas/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AntennasRepository, UserListsRepository } from '@/models/index.js'; @@ -64,9 +69,8 @@ export const paramDef = { required: ['antennaId', 'name', 'src', 'keywords', 'excludeKeywords', 'users', 'caseSensitive', 'withReplies', 'withFile', 'notify'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.antennasRepository) private antennasRepository: AntennasRepository, @@ -78,6 +82,9 @@ export default class extends Endpoint { private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { + if (ps.keywords.flat().every(x => x === '') && ps.excludeKeywords.flat().every(x => x === '')) { + throw new Error('either keywords or excludeKeywords is required.'); + } // Fetch the antenna const antenna = await this.antennasRepository.findOneBy({ id: ps.antennaId, diff --git a/packages/backend/src/server/api/endpoints/ap/get.ts b/packages/backend/src/server/api/endpoints/ap/get.ts index c45a86761c..a4a7fd2037 100644 --- a/packages/backend/src/server/api/endpoints/ap/get.ts +++ b/packages/backend/src/server/api/endpoints/ap/get.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -30,9 +35,8 @@ export const paramDef = { required: ['uri'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private apResolverService: ApResolverService, ) { diff --git a/packages/backend/src/server/api/endpoints/ap/show.ts b/packages/backend/src/server/api/endpoints/ap/show.ts index a103d4196a..f3ca931f24 100644 --- a/packages/backend/src/server/api/endpoints/ap/show.ts +++ b/packages/backend/src/server/api/endpoints/ap/show.ts @@ -1,9 +1,13 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, NotesRepository } from '@/models/index.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { LocalUser, User } from '@/models/entities/User.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiLocalUser, MiUser } from '@/models/entities/User.js'; import { isActor, isPost, getApId } from '@/core/activitypub/type.js'; import type { SchemaType } from '@/misc/json-schema.js'; import { ApResolverService } from '@/core/activitypub/ApResolverService.js'; @@ -14,7 +18,6 @@ import { ApNoteService } from '@/core/activitypub/models/ApNoteService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { UtilityService } from '@/core/UtilityService.js'; -import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; import { ApiError } from '../../error.js'; @@ -81,16 +84,9 @@ export const paramDef = { required: ['uri'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - private utilityService: UtilityService, private userEntityService: UserEntityService, private noteEntityService: NoteEntityService, @@ -114,7 +110,7 @@ export default class extends Endpoint { * URIからUserかNoteを解決する */ @bindThis - private async fetchAny(uri: string, me: LocalUser | null | undefined): Promise | null> { + private async fetchAny(uri: string, me: MiLocalUser | null | undefined): Promise | null> { // ブロックしてたら中断 const fetchedMeta = await this.metaService.fetch(); if (this.utilityService.isBlockedHost(fetchedMeta.blockedHosts, this.utilityService.extractDbHost(uri))) return null; @@ -147,7 +143,7 @@ export default class extends Endpoint { } @bindThis - private async mergePack(me: LocalUser | null | undefined, user: User | null | undefined, note: Note | null | undefined): Promise | null> { + private async mergePack(me: MiLocalUser | null | undefined, user: MiUser | null | undefined, note: MiNote | null | undefined): Promise | null> { if (user != null) { return { type: 'User', diff --git a/packages/backend/src/server/api/endpoints/app/create.ts b/packages/backend/src/server/api/endpoints/app/create.ts index aaef02d03f..2afd98ffe7 100644 --- a/packages/backend/src/server/api/endpoints/app/create.ts +++ b/packages/backend/src/server/api/endpoints/app/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AppsRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['name', 'description', 'permission'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.appsRepository) private appsRepository: AppsRepository, diff --git a/packages/backend/src/server/api/endpoints/app/show.ts b/packages/backend/src/server/api/endpoints/app/show.ts index eaafa8dc1b..5291bbb4f1 100644 --- a/packages/backend/src/server/api/endpoints/app/show.ts +++ b/packages/backend/src/server/api/endpoints/app/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AppsRepository } from '@/models/index.js'; @@ -31,9 +36,8 @@ export const paramDef = { required: ['appId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.appsRepository) private appsRepository: AppsRepository, diff --git a/packages/backend/src/server/api/endpoints/auth/accept.ts b/packages/backend/src/server/api/endpoints/auth/accept.ts index aa199ab730..31457afaae 100644 --- a/packages/backend/src/server/api/endpoints/auth/accept.ts +++ b/packages/backend/src/server/api/endpoints/auth/accept.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as crypto from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -31,9 +36,8 @@ export const paramDef = { required: ['token'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.appsRepository) private appsRepository: AppsRepository, diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts index 631fb4f024..ed906f816c 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/generate.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -45,9 +50,8 @@ export const paramDef = { required: ['appSecret'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, diff --git a/packages/backend/src/server/api/endpoints/auth/session/show.ts b/packages/backend/src/server/api/endpoints/auth/session/show.ts index db3bf7aa63..4cf47d2388 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/show.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AuthSessionsRepository } from '@/models/index.js'; @@ -48,9 +53,8 @@ export const paramDef = { required: ['token'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.authSessionsRepository) private authSessionsRepository: AuthSessionsRepository, diff --git a/packages/backend/src/server/api/endpoints/auth/session/userkey.ts b/packages/backend/src/server/api/endpoints/auth/session/userkey.ts index b1e7bbfded..ab7393f997 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/userkey.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/userkey.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, AppsRepository, AccessTokensRepository, AuthSessionsRepository } from '@/models/index.js'; +import type { AppsRepository, AccessTokensRepository, AuthSessionsRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; @@ -57,13 +62,9 @@ export const paramDef = { required: ['appSecret', 'token'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.appsRepository) private appsRepository: AppsRepository, diff --git a/packages/backend/src/server/api/endpoints/blocking/create.ts b/packages/backend/src/server/api/endpoints/blocking/create.ts index 4ad40c8f1c..dc1d7379d3 100644 --- a/packages/backend/src/server/api/endpoints/blocking/create.ts +++ b/packages/backend/src/server/api/endpoints/blocking/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -55,9 +60,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/blocking/delete.ts b/packages/backend/src/server/api/endpoints/blocking/delete.ts index ad3d9f22b3..c5cf104b86 100644 --- a/packages/backend/src/server/api/endpoints/blocking/delete.ts +++ b/packages/backend/src/server/api/endpoints/blocking/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -55,9 +60,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/blocking/list.ts b/packages/backend/src/server/api/endpoints/blocking/list.ts index d61bb0d214..40534cb57f 100644 --- a/packages/backend/src/server/api/endpoints/blocking/list.ts +++ b/packages/backend/src/server/api/endpoints/blocking/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { BlockingsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.blockingsRepository) private blockingsRepository: BlockingsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/create.ts b/packages/backend/src/server/api/endpoints/channels/create.ts index 69e2f2504c..95d9b07c26 100644 --- a/packages/backend/src/server/api/endpoints/channels/create.ts +++ b/packages/backend/src/server/api/endpoints/channels/create.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelsRepository, DriveFilesRepository } from '@/models/index.js'; -import type { Channel } from '@/models/entities/Channel.js'; +import type { MiChannel } from '@/models/entities/Channel.js'; import { IdService } from '@/core/IdService.js'; import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -44,13 +49,13 @@ export const paramDef = { description: { type: 'string', nullable: true, minLength: 1, maxLength: 2048 }, bannerId: { type: 'string', format: 'misskey:id', nullable: true }, color: { type: 'string', minLength: 1, maxLength: 16 }, + isSensitive: { type: 'boolean', nullable: true }, }, required: ['name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -81,8 +86,9 @@ export default class extends Endpoint { name: ps.name, description: ps.description ?? null, bannerId: banner ? banner.id : null, + isSensitive: ps.isSensitive ?? false, ...(ps.color !== undefined ? { color: ps.color } : {}), - } as Channel).then(x => this.channelsRepository.findOneByOrFail(x.identifiers[0])); + } as MiChannel).then(x => this.channelsRepository.findOneByOrFail(x.identifiers[0])); return await this.channelEntityService.pack(channel, me); }); diff --git a/packages/backend/src/server/api/endpoints/channels/favorite.ts b/packages/backend/src/server/api/endpoints/channels/favorite.ts index c8544273a1..4baadac048 100644 --- a/packages/backend/src/server/api/endpoints/channels/favorite.ts +++ b/packages/backend/src/server/api/endpoints/channels/favorite.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelFavoritesRepository, ChannelsRepository } from '@/models/index.js'; @@ -31,9 +36,8 @@ export const paramDef = { required: ['channelId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/featured.ts b/packages/backend/src/server/api/endpoints/channels/featured.ts index 953f027aa2..b608ae7cc4 100644 --- a/packages/backend/src/server/api/endpoints/channels/featured.ts +++ b/packages/backend/src/server/api/endpoints/channels/featured.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelsRepository } from '@/models/index.js'; @@ -26,9 +31,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/follow.ts b/packages/backend/src/server/api/endpoints/channels/follow.ts index f3ca66cfd2..83a612a49e 100644 --- a/packages/backend/src/server/api/endpoints/channels/follow.ts +++ b/packages/backend/src/server/api/endpoints/channels/follow.ts @@ -1,8 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelFollowingsRepository, ChannelsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; @@ -32,9 +36,8 @@ export const paramDef = { required: ['channelId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/followed.ts b/packages/backend/src/server/api/endpoints/channels/followed.ts index a1656903aa..60279f74e7 100644 --- a/packages/backend/src/server/api/endpoints/channels/followed.ts +++ b/packages/backend/src/server/api/endpoints/channels/followed.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelFollowingsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelFollowingsRepository) private channelFollowingsRepository: ChannelFollowingsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/my-favorites.ts b/packages/backend/src/server/api/endpoints/channels/my-favorites.ts index 60525ed060..2ef3420dc6 100644 --- a/packages/backend/src/server/api/endpoints/channels/my-favorites.ts +++ b/packages/backend/src/server/api/endpoints/channels/my-favorites.ts @@ -1,7 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelFavoritesRepository } from '@/models/index.js'; -import { QueryService } from '@/core/QueryService.js'; import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -30,15 +34,13 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelFavoritesRepository) private channelFavoritesRepository: ChannelFavoritesRepository, private channelEntityService: ChannelEntityService, - private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { const query = this.channelFavoritesRepository.createQueryBuilder('favorite') diff --git a/packages/backend/src/server/api/endpoints/channels/owned.ts b/packages/backend/src/server/api/endpoints/channels/owned.ts index 4561bb2e94..878d834f3a 100644 --- a/packages/backend/src/server/api/endpoints/channels/owned.ts +++ b/packages/backend/src/server/api/endpoints/channels/owned.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/search.ts b/packages/backend/src/server/api/endpoints/channels/search.ts index dfb6937964..ab25e2b9ce 100644 --- a/packages/backend/src/server/api/endpoints/channels/search.ts +++ b/packages/backend/src/server/api/endpoints/channels/search.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Brackets } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['query'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/show.ts b/packages/backend/src/server/api/endpoints/channels/show.ts index 070d14631e..c7ed443e25 100644 --- a/packages/backend/src/server/api/endpoints/channels/show.ts +++ b/packages/backend/src/server/api/endpoints/channels/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: ['channelId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index e3119cc40f..dd0db515bc 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { ChannelsRepository, Note, NotesRepository } from '@/models/index.js'; +import type { ChannelsRepository, MiNote, NotesRepository } from '@/models/index.js'; import { QueryService } from '@/core/QueryService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; @@ -46,9 +51,8 @@ export const paramDef = { required: ['channelId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.redis) private redisClient: Redis.Redis, @@ -73,7 +77,7 @@ export default class extends Endpoint { throw new ApiError(meta.errors.noSuchChannel); } - let timeline: Note[] = []; + let timeline: MiNote[] = []; const limit = ps.limit + (ps.untilId ? 1 : 0); // untilIdに指定したものも含まれるため+1 let noteIdsRes: [string, string[]][] = []; diff --git a/packages/backend/src/server/api/endpoints/channels/unfavorite.ts b/packages/backend/src/server/api/endpoints/channels/unfavorite.ts index 67fb1ea03e..8c2ffda986 100644 --- a/packages/backend/src/server/api/endpoints/channels/unfavorite.ts +++ b/packages/backend/src/server/api/endpoints/channels/unfavorite.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelFavoritesRepository, ChannelsRepository } from '@/models/index.js'; @@ -30,9 +35,8 @@ export const paramDef = { required: ['channelId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/unfollow.ts b/packages/backend/src/server/api/endpoints/channels/unfollow.ts index f46ff9f286..774baa0686 100644 --- a/packages/backend/src/server/api/endpoints/channels/unfollow.ts +++ b/packages/backend/src/server/api/endpoints/channels/unfollow.ts @@ -1,7 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ChannelFollowingsRepository, ChannelsRepository } from '@/models/index.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; @@ -31,9 +35,8 @@ export const paramDef = { required: ['channelId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, diff --git a/packages/backend/src/server/api/endpoints/channels/update.ts b/packages/backend/src/server/api/endpoints/channels/update.ts index 30d7f8b244..f5d64bd536 100644 --- a/packages/backend/src/server/api/endpoints/channels/update.ts +++ b/packages/backend/src/server/api/endpoints/channels/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository, ChannelsRepository } from '@/models/index.js'; @@ -55,13 +60,13 @@ export const paramDef = { }, }, color: { type: 'string', minLength: 1, maxLength: 16 }, + isSensitive: { type: 'boolean', nullable: true }, }, required: ['channelId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, @@ -109,6 +114,7 @@ export default class extends Endpoint { ...(ps.color !== undefined ? { color: ps.color } : {}), ...(typeof ps.isArchived === 'boolean' ? { isArchived: ps.isArchived } : {}), ...(banner ? { bannerId: banner.id } : {}), + ...(typeof ps.isSensitive === 'boolean' ? { isSensitive: ps.isSensitive } : {}), }); return await this.channelEntityService.pack(channel.id, me); diff --git a/packages/backend/src/server/api/endpoints/charts/active-users.ts b/packages/backend/src/server/api/endpoints/charts/active-users.ts index 2ab58e4309..e768923ce1 100644 --- a/packages/backend/src/server/api/endpoints/charts/active-users.ts +++ b/packages/backend/src/server/api/endpoints/charts/active-users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['span'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private activeUsersChart: ActiveUsersChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/ap-request.ts b/packages/backend/src/server/api/endpoints/charts/ap-request.ts index e40a53d82e..f518ae41ca 100644 --- a/packages/backend/src/server/api/endpoints/charts/ap-request.ts +++ b/packages/backend/src/server/api/endpoints/charts/ap-request.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['span'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private apRequestChart: ApRequestChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/drive.ts b/packages/backend/src/server/api/endpoints/charts/drive.ts index 9a5aff4af9..94afab113e 100644 --- a/packages/backend/src/server/api/endpoints/charts/drive.ts +++ b/packages/backend/src/server/api/endpoints/charts/drive.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['span'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private driveChart: DriveChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/federation.ts b/packages/backend/src/server/api/endpoints/charts/federation.ts index ed3a968681..bc33930ca4 100644 --- a/packages/backend/src/server/api/endpoints/charts/federation.ts +++ b/packages/backend/src/server/api/endpoints/charts/federation.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['span'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private federationChart: FederationChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/instance.ts b/packages/backend/src/server/api/endpoints/charts/instance.ts index c992d525c9..a432845b38 100644 --- a/packages/backend/src/server/api/endpoints/charts/instance.ts +++ b/packages/backend/src/server/api/endpoints/charts/instance.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['span', 'host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private instanceChart: InstanceChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/notes.ts b/packages/backend/src/server/api/endpoints/charts/notes.ts index 5750cd5b78..e1e9d06311 100644 --- a/packages/backend/src/server/api/endpoints/charts/notes.ts +++ b/packages/backend/src/server/api/endpoints/charts/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['span'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private notesChart: NotesChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/user/drive.ts b/packages/backend/src/server/api/endpoints/charts/user/drive.ts index 5e372294b7..b4a58c9872 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/drive.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/drive.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['span', 'userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private perUserDriveChart: PerUserDriveChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/user/following.ts b/packages/backend/src/server/api/endpoints/charts/user/following.ts index 3f50918fa7..c609c5a7fe 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/following.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { getJsonSchema } from '@/core/chart/core.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['span', 'userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private perUserFollowingChart: PerUserFollowingChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/user/notes.ts b/packages/backend/src/server/api/endpoints/charts/user/notes.ts index 0517b3283f..ad6a342fb7 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/notes.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['span', 'userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private perUserNotesChart: PerUserNotesChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/user/pv.ts b/packages/backend/src/server/api/endpoints/charts/user/pv.ts index 8d1a9aee10..635a403d12 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/pv.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/pv.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['span', 'userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private perUserPvChart: PerUserPvChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts index f2ff413195..92bc7028ad 100644 --- a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts +++ b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['span', 'userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private perUserReactionsChart: PerUserReactionsChart, ) { diff --git a/packages/backend/src/server/api/endpoints/charts/users.ts b/packages/backend/src/server/api/endpoints/charts/users.ts index 1374f02046..3be3721e3a 100644 --- a/packages/backend/src/server/api/endpoints/charts/users.ts +++ b/packages/backend/src/server/api/endpoints/charts/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { getJsonSchema } from '@/core/chart/core.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['span'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private usersChart: UsersChart, ) { diff --git a/packages/backend/src/server/api/endpoints/clips/add-note.ts b/packages/backend/src/server/api/endpoints/clips/add-note.ts index 2837f2cf81..40bbad4e6f 100644 --- a/packages/backend/src/server/api/endpoints/clips/add-note.ts +++ b/packages/backend/src/server/api/endpoints/clips/add-note.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -58,9 +63,8 @@ export const paramDef = { required: ['clipId', 'noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/create.ts b/packages/backend/src/server/api/endpoints/clips/create.ts index 5395a5c373..29eaf05778 100644 --- a/packages/backend/src/server/api/endpoints/clips/create.ts +++ b/packages/backend/src/server/api/endpoints/clips/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { IdService } from '@/core/IdService.js'; @@ -41,9 +46,8 @@ export const paramDef = { required: ['name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/delete.ts b/packages/backend/src/server/api/endpoints/clips/delete.ts index 077a9ec40f..cfad66f6ea 100644 --- a/packages/backend/src/server/api/endpoints/clips/delete.ts +++ b/packages/backend/src/server/api/endpoints/clips/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ClipsRepository } from '@/models/index.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: ['clipId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/favorite.ts b/packages/backend/src/server/api/endpoints/clips/favorite.ts index ce09855531..668a374c0b 100644 --- a/packages/backend/src/server/api/endpoints/clips/favorite.ts +++ b/packages/backend/src/server/api/endpoints/clips/favorite.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { ClipsRepository, ClipFavoritesRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; @@ -37,9 +42,8 @@ export const paramDef = { required: ['clipId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/list.ts b/packages/backend/src/server/api/endpoints/clips/list.ts index 3b8deab709..45f38c7bb3 100644 --- a/packages/backend/src/server/api/endpoints/clips/list.ts +++ b/packages/backend/src/server/api/endpoints/clips/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ClipsRepository } from '@/models/index.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/my-favorites.ts b/packages/backend/src/server/api/endpoints/clips/my-favorites.ts index fc727e93bd..8272179746 100644 --- a/packages/backend/src/server/api/endpoints/clips/my-favorites.ts +++ b/packages/backend/src/server/api/endpoints/clips/my-favorites.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ClipFavoritesRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipFavoritesRepository) private clipFavoritesRepository: ClipFavoritesRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/notes.ts b/packages/backend/src/server/api/endpoints/clips/notes.ts index 49607babee..4efd170514 100644 --- a/packages/backend/src/server/api/endpoints/clips/notes.ts +++ b/packages/backend/src/server/api/endpoints/clips/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { NotesRepository, ClipsRepository, ClipNotesRepository } from '@/models/index.js'; @@ -43,9 +48,8 @@ export const paramDef = { required: ['clipId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/remove-note.ts b/packages/backend/src/server/api/endpoints/clips/remove-note.ts index d0ef795819..ef3c32a1f8 100644 --- a/packages/backend/src/server/api/endpoints/clips/remove-note.ts +++ b/packages/backend/src/server/api/endpoints/clips/remove-note.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js'; @@ -38,9 +43,8 @@ export const paramDef = { required: ['clipId', 'noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/show.ts b/packages/backend/src/server/api/endpoints/clips/show.ts index 99d630a9b5..2132ceb7de 100644 --- a/packages/backend/src/server/api/endpoints/clips/show.ts +++ b/packages/backend/src/server/api/endpoints/clips/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ClipsRepository } from '@/models/index.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['clipId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/unfavorite.ts b/packages/backend/src/server/api/endpoints/clips/unfavorite.ts index 3da252a226..139fbab963 100644 --- a/packages/backend/src/server/api/endpoints/clips/unfavorite.ts +++ b/packages/backend/src/server/api/endpoints/clips/unfavorite.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { ClipsRepository, ClipFavoritesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -36,9 +41,8 @@ export const paramDef = { required: ['clipId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/clips/update.ts b/packages/backend/src/server/api/endpoints/clips/update.ts index 70f1959353..58609b01e5 100644 --- a/packages/backend/src/server/api/endpoints/clips/update.ts +++ b/packages/backend/src/server/api/endpoints/clips/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { ClipsRepository } from '@/models/index.js'; @@ -40,9 +45,8 @@ export const paramDef = { required: ['clipId', 'name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/drive.ts b/packages/backend/src/server/api/endpoints/drive.ts index a6ece0311b..71d3ca5f14 100644 --- a/packages/backend/src/server/api/endpoints/drive.ts +++ b/packages/backend/src/server/api/endpoints/drive.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { MetaService } from '@/core/MetaService.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private metaService: MetaService, private driveFileEntityService: DriveFileEntityService, diff --git a/packages/backend/src/server/api/endpoints/drive/files.ts b/packages/backend/src/server/api/endpoints/drive/files.ts index f4343248b8..81db4b9745 100644 --- a/packages/backend/src/server/api/endpoints/drive/files.ts +++ b/packages/backend/src/server/api/endpoints/drive/files.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/index.js'; @@ -36,9 +41,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts b/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts index 328d0e4643..49f79a1abe 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { NotesRepository, DriveFilesRepository } from '@/models/index.js'; @@ -41,9 +46,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts index cdcdde7e8a..9bb0b12f5c 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/index.js'; @@ -26,9 +31,8 @@ export const paramDef = { required: ['md5'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts index a1c1f9325e..5e97588c99 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/create.ts @@ -1,13 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; -import { Inject, Injectable } from '@nestjs/common'; -import type { DriveFilesRepository } from '@/models/index.js'; +import { Injectable } from '@nestjs/common'; import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/const.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { MetaService } from '@/core/MetaService.js'; import { DriveService } from '@/core/DriveService.js'; -import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; export const meta = { @@ -67,13 +70,9 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - private driveFileEntityService: DriveFileEntityService, private metaService: MetaService, private driveService: DriveService, diff --git a/packages/backend/src/server/api/endpoints/drive/files/delete.ts b/packages/backend/src/server/api/endpoints/drive/files/delete.ts index 2ced97ee02..49fc2d0a8a 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/delete.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/index.js'; @@ -39,9 +44,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts b/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts index d6d85f4e77..4eede4e342 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { DriveFilesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['md5'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/files/find.ts b/packages/backend/src/server/api/endpoints/drive/files/find.ts index 858063eb4b..ecd7f7934c 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/find.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/find.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: ['name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/files/show.ts b/packages/backend/src/server/api/endpoints/drive/files/show.ts index 271b33ef4b..941be20790 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/show.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/show.ts @@ -1,5 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import type { DriveFilesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; @@ -49,9 +54,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -60,7 +64,7 @@ export default class extends Endpoint { private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { - let file: DriveFile | null = null; + let file: MiDriveFile | null = null; if (ps.fileId) { file = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); diff --git a/packages/backend/src/server/api/endpoints/drive/files/update.ts b/packages/backend/src/server/api/endpoints/drive/files/update.ts index c43f812e2f..902570016b 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/update.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { DriveFilesRepository, DriveFoldersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -66,9 +71,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts b/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts index c835587c4a..bbe62063cf 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts @@ -1,11 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; -import { Inject, Injectable } from '@nestjs/common'; -import type { DriveFilesRepository } from '@/models/index.js'; +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { DriveService } from '@/core/DriveService.js'; -import { DI } from '@/di-symbols.js'; export const meta = { tags: ['drive'], @@ -37,13 +40,9 @@ export const paramDef = { required: ['url'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - private driveFileEntityService: DriveFileEntityService, private driveService: DriveService, private globalEventService: GlobalEventService, diff --git a/packages/backend/src/server/api/endpoints/drive/folders.ts b/packages/backend/src/server/api/endpoints/drive/folders.ts index eb674f3e15..fd65df46f5 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFoldersRepository } from '@/models/index.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFoldersRepository) private driveFoldersRepository: DriveFoldersRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/folders/create.ts b/packages/backend/src/server/api/endpoints/drive/folders/create.ts index 39c9c6bc58..6e5e711943 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -44,9 +49,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFoldersRepository) private driveFoldersRepository: DriveFoldersRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/folders/delete.ts b/packages/backend/src/server/api/endpoints/drive/folders/delete.ts index d921bc1b17..e6832b29b4 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/delete.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFoldersRepository, DriveFilesRepository } from '@/models/index.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['folderId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/folders/find.ts b/packages/backend/src/server/api/endpoints/drive/folders/find.ts index ee24db11f2..3625e6882c 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/find.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/find.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFoldersRepository) private driveFoldersRepository: DriveFoldersRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/folders/show.ts b/packages/backend/src/server/api/endpoints/drive/folders/show.ts index c06263b902..5fffd25523 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/show.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFoldersRepository } from '@/models/index.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['folderId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFoldersRepository) private driveFoldersRepository: DriveFoldersRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/folders/update.ts b/packages/backend/src/server/api/endpoints/drive/folders/update.ts index ff0a78b929..4035e3c0d2 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders/update.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFoldersRepository } from '@/models/index.js'; @@ -50,9 +55,8 @@ export const paramDef = { required: ['folderId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFoldersRepository) private driveFoldersRepository: DriveFoldersRepository, diff --git a/packages/backend/src/server/api/endpoints/drive/stream.ts b/packages/backend/src/server/api/endpoints/drive/stream.ts index a1c14a8e3f..264163eccd 100644 --- a/packages/backend/src/server/api/endpoints/drive/stream.ts +++ b/packages/backend/src/server/api/endpoints/drive/stream.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository } from '@/models/index.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/email-address/available.ts b/packages/backend/src/server/api/endpoints/email-address/available.ts index 0f13b14d01..787009f13c 100644 --- a/packages/backend/src/server/api/endpoints/email-address/available.ts +++ b/packages/backend/src/server/api/endpoints/email-address/available.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { EmailService } from '@/core/EmailService.js'; @@ -31,9 +36,8 @@ export const paramDef = { required: ['emailAddress'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private emailService: EmailService, ) { diff --git a/packages/backend/src/server/api/endpoints/emoji.ts b/packages/backend/src/server/api/endpoints/emoji.ts index 51027f35c0..5509e60379 100644 --- a/packages/backend/src/server/api/endpoints/emoji.ts +++ b/packages/backend/src/server/api/endpoints/emoji.ts @@ -1,9 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { EmojisRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; -import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; export const meta = { @@ -30,13 +34,9 @@ export const paramDef = { required: ['name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.emojisRepository) private emojisRepository: EmojisRepository, diff --git a/packages/backend/src/server/api/endpoints/emojis.ts b/packages/backend/src/server/api/endpoints/emojis.ts index 3c2d0ce4a4..9b014eb57d 100644 --- a/packages/backend/src/server/api/endpoints/emojis.ts +++ b/packages/backend/src/server/api/endpoints/emojis.ts @@ -1,9 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { EmojisRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; -import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; export const meta = { @@ -37,13 +41,9 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.emojisRepository) private emojisRepository: EmojisRepository, diff --git a/packages/backend/src/server/api/endpoints/endpoint.ts b/packages/backend/src/server/api/endpoints/endpoint.ts index b38c97f60a..cecaded20a 100644 --- a/packages/backend/src/server/api/endpoints/endpoint.ts +++ b/packages/backend/src/server/api/endpoints/endpoint.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import endpoints from '../endpoints.js'; @@ -16,9 +21,8 @@ export const paramDef = { required: ['endpoint'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( ) { super(meta, paramDef, async (ps) => { diff --git a/packages/backend/src/server/api/endpoints/endpoints.ts b/packages/backend/src/server/api/endpoints/endpoints.ts index 9e706db747..86def04aca 100644 --- a/packages/backend/src/server/api/endpoints/endpoints.ts +++ b/packages/backend/src/server/api/endpoints/endpoints.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import endpoints from '../endpoints.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( ) { super(meta, paramDef, async () => { diff --git a/packages/backend/src/server/api/endpoints/export-custom-emojis.ts b/packages/backend/src/server/api/endpoints/export-custom-emojis.ts index 6b6079ad51..7380c593e3 100644 --- a/packages/backend/src/server/api/endpoints/export-custom-emojis.ts +++ b/packages/backend/src/server/api/endpoints/export-custom-emojis.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/federation/followers.ts b/packages/backend/src/server/api/endpoints/federation/followers.ts index 1b2f9446f8..52ca485860 100644 --- a/packages/backend/src/server/api/endpoints/federation/followers.ts +++ b/packages/backend/src/server/api/endpoints/federation/followers.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { FollowingsRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, diff --git a/packages/backend/src/server/api/endpoints/federation/following.ts b/packages/backend/src/server/api/endpoints/federation/following.ts index c5aa1ec60b..28fa5ca842 100644 --- a/packages/backend/src/server/api/endpoints/federation/following.ts +++ b/packages/backend/src/server/api/endpoints/federation/following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { FollowingsRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, diff --git a/packages/backend/src/server/api/endpoints/federation/instances.ts b/packages/backend/src/server/api/endpoints/federation/instances.ts index b140321f44..35f1f5164f 100644 --- a/packages/backend/src/server/api/endpoints/federation/instances.ts +++ b/packages/backend/src/server/api/endpoints/federation/instances.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { InstancesRepository } from '@/models/index.js'; @@ -41,9 +46,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, diff --git a/packages/backend/src/server/api/endpoints/federation/show-instance.ts b/packages/backend/src/server/api/endpoints/federation/show-instance.ts index 66502748b3..fb55a2e44d 100644 --- a/packages/backend/src/server/api/endpoints/federation/show-instance.ts +++ b/packages/backend/src/server/api/endpoints/federation/show-instance.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { InstancesRepository } from '@/models/index.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: ['host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, diff --git a/packages/backend/src/server/api/endpoints/federation/stats.ts b/packages/backend/src/server/api/endpoints/federation/stats.ts index 19418e698c..ba7f2807bb 100644 --- a/packages/backend/src/server/api/endpoints/federation/stats.ts +++ b/packages/backend/src/server/api/endpoints/federation/stats.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull, MoreThan, Not } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { FollowingsRepository, InstancesRepository } from '@/models/index.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, diff --git a/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts b/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts index 4596e0c0b5..c0aa882088 100644 --- a/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts +++ b/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js'; @@ -17,9 +22,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private getterService: GetterService, private apPersonService: ApPersonService, diff --git a/packages/backend/src/server/api/endpoints/federation/users.ts b/packages/backend/src/server/api/endpoints/federation/users.ts index 06f252005b..5b414e12fa 100644 --- a/packages/backend/src/server/api/endpoints/federation/users.ts +++ b/packages/backend/src/server/api/endpoints/federation/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['host'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/fetch-rss.ts b/packages/backend/src/server/api/endpoints/fetch-rss.ts index 5849d3111f..37859d8330 100644 --- a/packages/backend/src/server/api/endpoints/fetch-rss.ts +++ b/packages/backend/src/server/api/endpoints/fetch-rss.ts @@ -1,8 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Parser from 'rss-parser'; -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { Config } from '@/config.js'; -import { DI } from '@/di-symbols.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; const rssParser = new Parser(); @@ -23,13 +26,9 @@ export const paramDef = { required: ['url'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.config) - private config: Config, - private httpRequestService: HttpRequestService, ) { super(meta, paramDef, async (ps, me) => { diff --git a/packages/backend/src/server/api/endpoints/flash/create.ts b/packages/backend/src/server/api/endpoints/flash/create.ts index 3172bdbfda..8727be2014 100644 --- a/packages/backend/src/server/api/endpoints/flash/create.ts +++ b/packages/backend/src/server/api/endpoints/flash/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import type { FlashsRepository } from '@/models/index.js'; @@ -37,9 +42,8 @@ export const paramDef = { required: ['title', 'summary', 'script', 'permissions'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/delete.ts b/packages/backend/src/server/api/endpoints/flash/delete.ts index e94ede9f68..86cdd72811 100644 --- a/packages/backend/src/server/api/endpoints/flash/delete.ts +++ b/packages/backend/src/server/api/endpoints/flash/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { FlashsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: ['flashId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/featured.ts b/packages/backend/src/server/api/endpoints/flash/featured.ts index 99c8763b11..3be7ddebb2 100644 --- a/packages/backend/src/server/api/endpoints/flash/featured.ts +++ b/packages/backend/src/server/api/endpoints/flash/featured.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { FlashsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -26,9 +31,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/like.ts b/packages/backend/src/server/api/endpoints/flash/like.ts index 57245f9f41..16818c53ab 100644 --- a/packages/backend/src/server/api/endpoints/flash/like.ts +++ b/packages/backend/src/server/api/endpoints/flash/like.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { FlashsRepository, FlashLikesRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; @@ -43,9 +48,8 @@ export const paramDef = { required: ['flashId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/my-likes.ts b/packages/backend/src/server/api/endpoints/flash/my-likes.ts index 7d1149ada9..48897ea74d 100644 --- a/packages/backend/src/server/api/endpoints/flash/my-likes.ts +++ b/packages/backend/src/server/api/endpoints/flash/my-likes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { FlashLikesRepository } from '@/models/index.js'; @@ -43,9 +48,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashLikesRepository) private flashLikesRepository: FlashLikesRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/my.ts b/packages/backend/src/server/api/endpoints/flash/my.ts index 45a3b50e08..1d74bfe635 100644 --- a/packages/backend/src/server/api/endpoints/flash/my.ts +++ b/packages/backend/src/server/api/endpoints/flash/my.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { FlashsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/show.ts b/packages/backend/src/server/api/endpoints/flash/show.ts index 14720a8c8d..d655203306 100644 --- a/packages/backend/src/server/api/endpoints/flash/show.ts +++ b/packages/backend/src/server/api/endpoints/flash/show.ts @@ -1,5 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { UsersRepository, FlashsRepository } from '@/models/index.js'; +import type { FlashsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { FlashEntityService } from '@/core/entities/FlashEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -33,13 +38,9 @@ export const paramDef = { required: ['flashId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/unlike.ts b/packages/backend/src/server/api/endpoints/flash/unlike.ts index 696512b06c..6e723c5a17 100644 --- a/packages/backend/src/server/api/endpoints/flash/unlike.ts +++ b/packages/backend/src/server/api/endpoints/flash/unlike.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { FlashsRepository, FlashLikesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -36,9 +41,8 @@ export const paramDef = { required: ['flashId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, diff --git a/packages/backend/src/server/api/endpoints/flash/update.ts b/packages/backend/src/server/api/endpoints/flash/update.ts index 78dfd4a06a..9da29b50ea 100644 --- a/packages/backend/src/server/api/endpoints/flash/update.ts +++ b/packages/backend/src/server/api/endpoints/flash/update.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; -import type { FlashsRepository, DriveFilesRepository } from '@/models/index.js'; +import type { FlashsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../error.js'; @@ -44,19 +49,16 @@ export const paramDef = { permissions: { type: 'array', items: { type: 'string', } }, + visibility: { type: 'string', enum: ['public', 'private'] }, }, required: ['flashId', 'title', 'summary', 'script', 'permissions'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.flashsRepository) private flashsRepository: FlashsRepository, - - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, ) { super(meta, paramDef, async (ps, me) => { const flash = await this.flashsRepository.findOneBy({ id: ps.flashId }); diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts index 009fc96f64..3f90c29b2c 100644 --- a/packages/backend/src/server/api/endpoints/following/create.ts +++ b/packages/backend/src/server/api/endpoints/following/create.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; +import type { FollowingsRepository } from '@/models/index.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; @@ -70,13 +75,9 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, diff --git a/packages/backend/src/server/api/endpoints/following/delete.ts b/packages/backend/src/server/api/endpoints/following/delete.ts index 77ef263169..87a21a95e1 100644 --- a/packages/backend/src/server/api/endpoints/following/delete.ts +++ b/packages/backend/src/server/api/endpoints/following/delete.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; +import type { FollowingsRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; import { DI } from '@/di-symbols.js'; @@ -55,13 +60,9 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, diff --git a/packages/backend/src/server/api/endpoints/following/invalidate.ts b/packages/backend/src/server/api/endpoints/following/invalidate.ts index 0e57f6328f..e786ccd097 100644 --- a/packages/backend/src/server/api/endpoints/following/invalidate.ts +++ b/packages/backend/src/server/api/endpoints/following/invalidate.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; +import type { FollowingsRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; import { DI } from '@/di-symbols.js'; @@ -55,13 +60,9 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, diff --git a/packages/backend/src/server/api/endpoints/following/requests/accept.ts b/packages/backend/src/server/api/endpoints/following/requests/accept.ts index cca3e60614..91fe922200 100644 --- a/packages/backend/src/server/api/endpoints/following/requests/accept.ts +++ b/packages/backend/src/server/api/endpoints/following/requests/accept.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GetterService } from '@/server/api/GetterService.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private getterService: GetterService, private userFollowingService: UserFollowingService, diff --git a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts index 7325e73cac..d9d5c7041b 100644 --- a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts +++ b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts @@ -1,11 +1,14 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { FollowingsRepository } from '@/models/index.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { GetterService } from '@/server/api/GetterService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; -import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; export const meta = { @@ -44,13 +47,9 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.followingsRepository) - private followingsRepository: FollowingsRepository, - private userEntityService: UserEntityService, private getterService: GetterService, private userFollowingService: UserFollowingService, diff --git a/packages/backend/src/server/api/endpoints/following/requests/list.ts b/packages/backend/src/server/api/endpoints/following/requests/list.ts index 29588e8731..6214bce7a4 100644 --- a/packages/backend/src/server/api/endpoints/following/requests/list.ts +++ b/packages/backend/src/server/api/endpoints/following/requests/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; @@ -49,9 +54,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.followRequestsRepository) private followRequestsRepository: FollowRequestsRepository, diff --git a/packages/backend/src/server/api/endpoints/following/requests/reject.ts b/packages/backend/src/server/api/endpoints/following/requests/reject.ts index a8fdc44876..35f047bcef 100644 --- a/packages/backend/src/server/api/endpoints/following/requests/reject.ts +++ b/packages/backend/src/server/api/endpoints/following/requests/reject.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GetterService } from '@/server/api/GetterService.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private getterService: GetterService, private userFollowingService: UserFollowingService, diff --git a/packages/backend/src/server/api/endpoints/gallery/featured.ts b/packages/backend/src/server/api/endpoints/gallery/featured.ts index 46347247f0..512be6111d 100644 --- a/packages/backend/src/server/api/endpoints/gallery/featured.ts +++ b/packages/backend/src/server/api/endpoints/gallery/featured.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository } from '@/models/index.js'; @@ -26,9 +31,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/gallery/popular.ts b/packages/backend/src/server/api/endpoints/gallery/popular.ts index 4ee3d68a92..e1f3b8a149 100644 --- a/packages/backend/src/server/api/endpoints/gallery/popular.ts +++ b/packages/backend/src/server/api/endpoints/gallery/popular.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository } from '@/models/index.js'; @@ -26,9 +31,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts.ts b/packages/backend/src/server/api/endpoints/gallery/posts.ts index b9aac3fb34..7299041179 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts index ca6bfa7e0f..25def8451e 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts @@ -1,9 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository, GalleryPostsRepository } from '@/models/index.js'; -import { GalleryPost } from '@/models/entities/GalleryPost.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import { MiGalleryPost } from '@/models/entities/GalleryPost.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { IdService } from '@/core/IdService.js'; import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -46,9 +51,8 @@ export const paramDef = { required: ['title', 'fileIds'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, @@ -65,13 +69,13 @@ export default class extends Endpoint { id: fileId, userId: me.id, }), - ))).filter((file): file is DriveFile => file != null); + ))).filter((file): file is MiDriveFile => file != null); if (files.length === 0) { throw new Error(); } - const post = await this.galleryPostsRepository.insert(new GalleryPost({ + const post = await this.galleryPostsRepository.insert(new MiGalleryPost({ id: this.idService.genId(), createdAt: new Date(), updatedAt: new Date(), diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts b/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts index 6cdcc17b39..43713dd1f4 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository } from '@/models/index.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: ['postId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts index c0bb55f640..172f59a65a 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryLikesRepository, GalleryPostsRepository } from '@/models/index.js'; @@ -43,9 +48,8 @@ export const paramDef = { required: ['postId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/show.ts b/packages/backend/src/server/api/endpoints/gallery/posts/show.ts index f7e828142b..04ceb07f35 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/show.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: ['postId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts b/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts index 513089217d..6929e5e697 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository, GalleryLikesRepository } from '@/models/index.js'; @@ -36,9 +41,8 @@ export const paramDef = { required: ['postId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts index a2a10d8400..bc7e8b0a6d 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { DriveFilesRepository, GalleryPostsRepository } from '@/models/index.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -45,9 +50,8 @@ export const paramDef = { required: ['postId', 'title', 'fileIds'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, @@ -63,7 +67,7 @@ export default class extends Endpoint { id: fileId, userId: me.id, }), - ))).filter((file): file is DriveFile => file != null); + ))).filter((file): file is MiDriveFile => file != null); if (files.length === 0) { throw new Error(); diff --git a/packages/backend/src/server/api/endpoints/get-online-users-count.ts b/packages/backend/src/server/api/endpoints/get-online-users-count.ts index 810bde03e8..4e6a68d503 100644 --- a/packages/backend/src/server/api/endpoints/get-online-users-count.ts +++ b/packages/backend/src/server/api/endpoints/get-online-users-count.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { MoreThan } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import { USER_ONLINE_THRESHOLD } from '@/const.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/hashtags/list.ts b/packages/backend/src/server/api/endpoints/hashtags/list.ts index 693d938bf0..f4f230a42d 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/list.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { HashtagsRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['sort'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.hashtagsRepository) private hashtagsRepository: HashtagsRepository, diff --git a/packages/backend/src/server/api/endpoints/hashtags/search.ts b/packages/backend/src/server/api/endpoints/hashtags/search.ts index 81a790316b..a4ec9a51d7 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/search.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/search.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { HashtagsRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: ['query'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.hashtagsRepository) private hashtagsRepository: HashtagsRepository, diff --git a/packages/backend/src/server/api/endpoints/hashtags/show.ts b/packages/backend/src/server/api/endpoints/hashtags/show.ts index 06b0d6e9b2..88ce4c5fef 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/show.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { HashtagsRepository } from '@/models/index.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: ['tag'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.hashtagsRepository) private hashtagsRepository: HashtagsRepository, diff --git a/packages/backend/src/server/api/endpoints/hashtags/trend.ts b/packages/backend/src/server/api/endpoints/hashtags/trend.ts index ce1cd9f01f..4137562de6 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/trend.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/trend.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { NotesRepository } from '@/models/index.js'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import { safeForSql } from '@/misc/safe-for-sql.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { MetaService } from '@/core/MetaService.js'; @@ -63,9 +68,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -96,7 +100,7 @@ export default class extends Endpoint { const tags: { name: string; - users: Note['userId'][]; + users: MiNote['userId'][]; }[] = []; for (const note of tagNotes) { diff --git a/packages/backend/src/server/api/endpoints/hashtags/users.ts b/packages/backend/src/server/api/endpoints/hashtags/users.ts index b00b005add..9918ddab06 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/users.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: ['tag', 'sort'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/i.ts b/packages/backend/src/server/api/endpoints/i.ts index 4d593542db..56c770761a 100644 --- a/packages/backend/src/server/api/endpoints/i.ts +++ b/packages/backend/src/server/api/endpoints/i.ts @@ -1,5 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { UserProfilesRepository, UsersRepository } from '@/models/index.js'; +import type { UserProfilesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -32,13 +37,9 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/done.ts b/packages/backend/src/server/api/endpoints/i/2fa/done.ts index 6c31075e05..e508a28cc0 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/done.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/done.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as OTPAuth from 'otpauth'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import type { UserProfilesRepository } from '@/models/index.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; -import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; export const meta = { @@ -21,13 +25,9 @@ export const paramDef = { required: ['token'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.config) - private config: Config, - @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts index a7e39fc028..cff51245c7 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { promisify } from 'node:util'; import bcrypt from 'bcryptjs'; import cbor from 'cbor'; @@ -30,9 +35,8 @@ export const paramDef = { required: ['clientDataJSON', 'attestationObject', 'password', 'challengeId', 'name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts b/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts index 0ee9f556a8..41277de596 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: ['value'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts index 19c77365c6..65ae66d01e 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { promisify } from 'node:util'; import * as crypto from 'node:crypto'; import bcrypt from 'bcryptjs'; @@ -24,9 +29,8 @@ export const paramDef = { required: ['password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register.ts b/packages/backend/src/server/api/endpoints/i/2fa/register.ts index eb4d7f9c14..5ab1635e48 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/register.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/register.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import * as OTPAuth from 'otpauth'; import * as QRCode from 'qrcode'; @@ -21,9 +26,8 @@ export const paramDef = { required: ['password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts index 4b726aed80..9cd0898d48 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: ['password', 'credentialId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userSecurityKeysRepository) private userSecurityKeysRepository: UserSecurityKeysRepository, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts b/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts index e0e7ba6658..ee58fb2af4 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -20,9 +25,8 @@ export const paramDef = { required: ['password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts index 2ef5e5a279..cc837ca9f0 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/update-key.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UserProfilesRepository, UserSecurityKeysRepository } from '@/models/index.js'; +import type { UserSecurityKeysRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; @@ -36,16 +41,12 @@ export const paramDef = { required: ['name', 'credentialId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userSecurityKeysRepository) private userSecurityKeysRepository: UserSecurityKeysRepository, - @Inject(DI.userProfilesRepository) - private userProfilesRepository: UserProfilesRepository, - private userEntityService: UserEntityService, private globalEventService: GlobalEventService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/apps.ts b/packages/backend/src/server/api/endpoints/i/apps.ts index 48fb03a8af..1318535a02 100644 --- a/packages/backend/src/server/api/endpoints/i/apps.ts +++ b/packages/backend/src/server/api/endpoints/i/apps.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AccessTokensRepository } from '@/models/index.js'; @@ -17,9 +22,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.accessTokensRepository) private accessTokensRepository: AccessTokensRepository, diff --git a/packages/backend/src/server/api/endpoints/i/authorized-apps.ts b/packages/backend/src/server/api/endpoints/i/authorized-apps.ts index f5a946eb91..91f75d2a21 100644 --- a/packages/backend/src/server/api/endpoints/i/authorized-apps.ts +++ b/packages/backend/src/server/api/endpoints/i/authorized-apps.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IsNull, Not } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.accessTokensRepository) private accessTokensRepository: AccessTokensRepository, diff --git a/packages/backend/src/server/api/endpoints/i/change-password.ts b/packages/backend/src/server/api/endpoints/i/change-password.ts index 873835a36c..93168b0038 100644 --- a/packages/backend/src/server/api/endpoints/i/change-password.ts +++ b/packages/backend/src/server/api/endpoints/i/change-password.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['currentPassword', 'newPassword'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/claim-achievement.ts b/packages/backend/src/server/api/endpoints/i/claim-achievement.ts index 4eef496385..b24b3438dc 100644 --- a/packages/backend/src/server/api/endpoints/i/claim-achievement.ts +++ b/packages/backend/src/server/api/endpoints/i/claim-achievement.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { AchievementService, ACHIEVEMENT_TYPES } from '@/core/AchievementService.js'; @@ -15,9 +20,8 @@ export const paramDef = { required: ['name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private achievementService: AchievementService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/delete-account.ts b/packages/backend/src/server/api/endpoints/i/delete-account.ts index 77a03d9811..7609353acf 100644 --- a/packages/backend/src/server/api/endpoints/i/delete-account.ts +++ b/packages/backend/src/server/api/endpoints/i/delete-account.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, UserProfilesRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/i/export-antennas.ts b/packages/backend/src/server/api/endpoints/i/export-antennas.ts index 4182c1b247..23b2f6b4ce 100644 --- a/packages/backend/src/server/api/endpoints/i/export-antennas.ts +++ b/packages/backend/src/server/api/endpoints/i/export-antennas.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; diff --git a/packages/backend/src/server/api/endpoints/i/export-blocking.ts b/packages/backend/src/server/api/endpoints/i/export-blocking.ts index 4be88cbc2b..8068a3b305 100644 --- a/packages/backend/src/server/api/endpoints/i/export-blocking.ts +++ b/packages/backend/src/server/api/endpoints/i/export-blocking.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/export-favorites.ts b/packages/backend/src/server/api/endpoints/i/export-favorites.ts index f522d4c409..c22905bc67 100644 --- a/packages/backend/src/server/api/endpoints/i/export-favorites.ts +++ b/packages/backend/src/server/api/endpoints/i/export-favorites.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/export-following.ts b/packages/backend/src/server/api/endpoints/i/export-following.ts index 1741781c0f..880833ab76 100644 --- a/packages/backend/src/server/api/endpoints/i/export-following.ts +++ b/packages/backend/src/server/api/endpoints/i/export-following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/export-mute.ts b/packages/backend/src/server/api/endpoints/i/export-mute.ts index 8e8042b1f9..8eb70a387a 100644 --- a/packages/backend/src/server/api/endpoints/i/export-mute.ts +++ b/packages/backend/src/server/api/endpoints/i/export-mute.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/export-notes.ts b/packages/backend/src/server/api/endpoints/i/export-notes.ts index ed54c9991c..791f637790 100644 --- a/packages/backend/src/server/api/endpoints/i/export-notes.ts +++ b/packages/backend/src/server/api/endpoints/i/export-notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/export-user-lists.ts b/packages/backend/src/server/api/endpoints/i/export-user-lists.ts index 5c2be38b71..f387f6d016 100644 --- a/packages/backend/src/server/api/endpoints/i/export-user-lists.ts +++ b/packages/backend/src/server/api/endpoints/i/export-user-lists.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private queueService: QueueService, ) { diff --git a/packages/backend/src/server/api/endpoints/i/favorites.ts b/packages/backend/src/server/api/endpoints/i/favorites.ts index bdfb63974a..dd59683f06 100644 --- a/packages/backend/src/server/api/endpoints/i/favorites.ts +++ b/packages/backend/src/server/api/endpoints/i/favorites.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { NoteFavoritesRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.noteFavoritesRepository) private noteFavoritesRepository: NoteFavoritesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts index 915639e5f7..c01aeb2d11 100644 --- a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts +++ b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryLikesRepository } from '@/models/index.js'; @@ -44,9 +49,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryLikesRepository) private galleryLikesRepository: GalleryLikesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/gallery/posts.ts b/packages/backend/src/server/api/endpoints/i/gallery/posts.ts index 5ba9afd4a8..0309d93a7e 100644 --- a/packages/backend/src/server/api/endpoints/i/gallery/posts.ts +++ b/packages/backend/src/server/api/endpoints/i/gallery/posts.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts b/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts index 3179457817..b889cfda6e 100644 --- a/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts +++ b/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { MutedNotesRepository } from '@/models/index.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.mutedNotesRepository) private mutedNotesRepository: MutedNotesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/import-antennas.ts b/packages/backend/src/server/api/endpoints/i/import-antennas.ts index 8582e98f76..8feb0007a0 100644 --- a/packages/backend/src/server/api/endpoints/i/import-antennas.ts +++ b/packages/backend/src/server/api/endpoints/i/import-antennas.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueueService } from '@/core/QueueService.js'; -import type { AntennasRepository, DriveFilesRepository, UsersRepository, Antenna as _Antenna } from '@/models/index.js'; +import type { AntennasRepository, DriveFilesRepository, UsersRepository, MiAntenna as _Antenna } from '@/models/index.js'; import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; import { DownloadService } from '@/core/DownloadService.js'; diff --git a/packages/backend/src/server/api/endpoints/i/import-blocking.ts b/packages/backend/src/server/api/endpoints/i/import-blocking.ts index 32c16300fb..27bbc9cd33 100644 --- a/packages/backend/src/server/api/endpoints/i/import-blocking.ts +++ b/packages/backend/src/server/api/endpoints/i/import-blocking.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -52,9 +57,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/import-following.ts b/packages/backend/src/server/api/endpoints/i/import-following.ts index 1926a1f503..30cf116fba 100644 --- a/packages/backend/src/server/api/endpoints/i/import-following.ts +++ b/packages/backend/src/server/api/endpoints/i/import-following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -51,9 +56,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/import-muting.ts b/packages/backend/src/server/api/endpoints/i/import-muting.ts index 34f2627563..227d32ecec 100644 --- a/packages/backend/src/server/api/endpoints/i/import-muting.ts +++ b/packages/backend/src/server/api/endpoints/i/import-muting.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -52,9 +57,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/import-user-lists.ts b/packages/backend/src/server/api/endpoints/i/import-user-lists.ts index 1b3cb5359d..288b5eee70 100644 --- a/packages/backend/src/server/api/endpoints/i/import-user-lists.ts +++ b/packages/backend/src/server/api/endpoints/i/import-user-lists.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -51,9 +56,8 @@ export const paramDef = { required: ['fileId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/move.ts b/packages/backend/src/server/api/endpoints/i/move.ts index 261dd527c0..eb67e171fe 100644 --- a/packages/backend/src/server/api/endpoints/i/move.ts +++ b/packages/backend/src/server/api/endpoints/i/move.ts @@ -1,13 +1,15 @@ -import { Inject, Injectable } from '@nestjs/common'; -import ms from 'ms'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ -import type { Config } from '@/config.js'; -import { DI } from '@/di-symbols.js'; +import { Injectable } from '@nestjs/common'; +import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { ApiError } from '@/server/api/error.js'; -import { LocalUser, RemoteUser } from '@/models/entities/User.js'; +import { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js'; import { AccountMoveService } from '@/core/AccountMoveService.js'; import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js'; @@ -72,13 +74,9 @@ export const paramDef = { required: ['moveToAccount'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.config) - private config: Config, - private remoteUserResolveService: RemoteUserResolveService, private apiLoggerService: ApiLoggerService, private accountMoveService: AccountMoveService, @@ -101,7 +99,7 @@ export default class extends Endpoint { this.apiLoggerService.logger.warn(`failed to resolve remote user: ${e}`); throw new ApiError(meta.errors.noSuchUser); }); - const destination = await this.getterService.getUser(moveTo.id) as LocalUser | RemoteUser; + const destination = await this.getterService.getUser(moveTo.id) as MiLocalUser | MiRemoteUser; const newUri = this.userEntityService.getUserUri(destination); // update local db diff --git a/packages/backend/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts index f5662f4a0e..efc37a6268 100644 --- a/packages/backend/src/server/api/endpoints/i/notifications.ts +++ b/packages/backend/src/server/api/endpoints/i/notifications.ts @@ -1,16 +1,20 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets, In } from 'typeorm'; import * as Redis from 'ioredis'; import { Inject, Injectable } from '@nestjs/common'; -import type { UsersRepository, FollowingsRepository, MutingsRepository, UserProfilesRepository, NotesRepository } from '@/models/index.js'; +import type { NotesRepository } from '@/models/index.js'; import { obsoleteNotificationTypes, notificationTypes } from '@/types.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { QueryService } from '@/core/QueryService.js'; import { NoteReadService } from '@/core/NoteReadService.js'; import { NotificationEntityService } from '@/core/entities/NotificationEntityService.js'; import { NotificationService } from '@/core/NotificationService.js'; import { DI } from '@/di-symbols.js'; import { IdService } from '@/core/IdService.js'; -import { Notification } from '@/models/entities/Notification.js'; +import { MiNotification } from '@/models/entities/Notification.js'; export const meta = { tags: ['account', 'notifications'], @@ -53,29 +57,18 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.redis) private redisClient: Redis.Redis, - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.mutingsRepository) - private mutingsRepository: MutingsRepository, - - @Inject(DI.userProfilesRepository) - private userProfilesRepository: UserProfilesRepository, - @Inject(DI.notesRepository) private notesRepository: NotesRepository, private idService: IdService, private notificationEntityService: NotificationEntityService, private notificationService: NotificationService, - private queryService: QueryService, private noteReadService: NoteReadService, ) { super(meta, paramDef, async (ps, me) => { @@ -102,7 +95,7 @@ export default class extends Endpoint { return []; } - let notifications = notificationsRes.map(x => JSON.parse(x[1][1])).filter(x => x.id !== ps.untilId && x !== ps.sinceId) as Notification[]; + let notifications = notificationsRes.map(x => JSON.parse(x[1][1])).filter(x => x.id !== ps.untilId && x !== ps.sinceId) as MiNotification[]; if (includeTypes && includeTypes.length > 0) { notifications = notifications.filter(notification => includeTypes.includes(notification.type)); diff --git a/packages/backend/src/server/api/endpoints/i/page-likes.ts b/packages/backend/src/server/api/endpoints/i/page-likes.ts index 9f073ba596..36f42c9f94 100644 --- a/packages/backend/src/server/api/endpoints/i/page-likes.ts +++ b/packages/backend/src/server/api/endpoints/i/page-likes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { PageLikesRepository } from '@/models/index.js'; @@ -43,9 +48,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pageLikesRepository) private pageLikesRepository: PageLikesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/pages.ts b/packages/backend/src/server/api/endpoints/i/pages.ts index 772486befc..cc56041f67 100644 --- a/packages/backend/src/server/api/endpoints/i/pages.ts +++ b/packages/backend/src/server/api/endpoints/i/pages.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { PagesRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/pin.ts b/packages/backend/src/server/api/endpoints/i/pin.ts index 2293500945..c89cdfa3a4 100644 --- a/packages/backend/src/server/api/endpoints/i/pin.ts +++ b/packages/backend/src/server/api/endpoints/i/pin.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -47,9 +52,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private userEntityService: UserEntityService, private notePiningService: NotePiningService, diff --git a/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts b/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts index b92de4b739..9a29d5c9e6 100644 --- a/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts +++ b/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { NoteUnreadsRepository } from '@/models/index.js'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.noteUnreadsRepository) private noteUnreadsRepository: NoteUnreadsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/read-announcement.ts b/packages/backend/src/server/api/endpoints/i/read-announcement.ts index 352fe54c5d..ba7859d0d4 100644 --- a/packages/backend/src/server/api/endpoints/i/read-announcement.ts +++ b/packages/backend/src/server/api/endpoints/i/read-announcement.ts @@ -1,11 +1,11 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { IdService } from '@/core/IdService.js'; -import type { AnnouncementReadsRepository, AnnouncementsRepository } from '@/models/index.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { DI } from '@/di-symbols.js'; -import { ApiError } from '../../error.js'; +import { AnnouncementService } from '@/core/AnnouncementService.js'; export const meta = { tags: ['account'], @@ -15,11 +15,6 @@ export const meta = { kind: 'write:account', errors: { - noSuchAnnouncement: { - message: 'No such announcement.', - code: 'NO_SUCH_ANNOUNCEMENT', - id: '184663db-df88-4bc2-8b52-fb85f0681939', - }, }, } as const; @@ -31,51 +26,13 @@ export const paramDef = { required: ['announcementId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.announcementsRepository) - private announcementsRepository: AnnouncementsRepository, - - @Inject(DI.announcementReadsRepository) - private announcementReadsRepository: AnnouncementReadsRepository, - - private userEntityService: UserEntityService, - private idService: IdService, - private globalEventService: GlobalEventService, + private announcementService: AnnouncementService, ) { super(meta, paramDef, async (ps, me) => { - // Check if announcement exists - const announcementExist = await this.announcementsRepository.exist({ where: { id: ps.announcementId } }); - - if (!announcementExist) { - throw new ApiError(meta.errors.noSuchAnnouncement); - } - - // Check if already read - const alreadyRead = await this.announcementReadsRepository.exist({ - where: { - announcementId: ps.announcementId, - userId: me.id, - }, - }); - - if (alreadyRead) { - return; - } - - // Create read - await this.announcementReadsRepository.insert({ - id: this.idService.genId(), - createdAt: new Date(), - announcementId: ps.announcementId, - userId: me.id, - }); - - if (!await this.userEntityService.getHasUnreadAnnouncement(me.id)) { - this.globalEventService.publishMainStream(me.id, 'readAllAnnouncements'); - } + await this.announcementService.read(me, ps.announcementId); }); } } diff --git a/packages/backend/src/server/api/endpoints/i/regenerate-token.ts b/packages/backend/src/server/api/endpoints/i/regenerate-token.ts index 23ff63f5e9..ad63369a21 100644 --- a/packages/backend/src/server/api/endpoints/i/regenerate-token.ts +++ b/packages/backend/src/server/api/endpoints/i/regenerate-token.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -20,9 +25,8 @@ export const paramDef = { required: ['password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/get-all.ts b/packages/backend/src/server/api/endpoints/i/registry/get-all.ts index 17154c1f76..926bdeee19 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/get-all.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/get-all.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts b/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts index 233686dbe1..8e93b3a7c9 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: ['key'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/get.ts b/packages/backend/src/server/api/endpoints/i/registry/get.ts index 99cdf95bad..229e3b346b 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/get.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/get.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: ['key'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts b/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts index 362a5e89f4..4e8d01ff84 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/keys.ts b/packages/backend/src/server/api/endpoints/i/registry/keys.ts index 99f69d8bed..4aa2bd4b5e 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/keys.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/keys.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/remove.ts b/packages/backend/src/server/api/endpoints/i/registry/remove.ts index 78a641f5e2..d1e999945b 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/remove.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/remove.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: ['key'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/scopes.ts b/packages/backend/src/server/api/endpoints/i/registry/scopes.ts index 0a4ecb9c51..45ff063217 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/scopes.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/scopes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -15,9 +20,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/registry/set.ts b/packages/backend/src/server/api/endpoints/i/registry/set.ts index c8e72203c4..663cfe9f1d 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/set.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/set.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistryItemsRepository } from '@/models/index.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['key', 'value'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registryItemsRepository) private registryItemsRepository: RegistryItemsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/revoke-token.ts b/packages/backend/src/server/api/endpoints/i/revoke-token.ts index 415a60147b..256a3ff7f8 100644 --- a/packages/backend/src/server/api/endpoints/i/revoke-token.ts +++ b/packages/backend/src/server/api/endpoints/i/revoke-token.ts @@ -1,7 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AccessTokensRepository } from '@/models/index.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; export const meta = { @@ -18,14 +22,11 @@ export const paramDef = { required: ['tokenId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.accessTokensRepository) private accessTokensRepository: AccessTokensRepository, - - private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { const tokenExist = await this.accessTokensRepository.exist({ where: { id: ps.tokenId } }); diff --git a/packages/backend/src/server/api/endpoints/i/signin-history.ts b/packages/backend/src/server/api/endpoints/i/signin-history.ts index aa8cb5cf42..5543a844ba 100644 --- a/packages/backend/src/server/api/endpoints/i/signin-history.ts +++ b/packages/backend/src/server/api/endpoints/i/signin-history.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { SigninsRepository } from '@/models/index.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.signinsRepository) private signinsRepository: SigninsRepository, diff --git a/packages/backend/src/server/api/endpoints/i/unpin.ts b/packages/backend/src/server/api/endpoints/i/unpin.ts index db239dc284..b59c0e954f 100644 --- a/packages/backend/src/server/api/endpoints/i/unpin.ts +++ b/packages/backend/src/server/api/endpoints/i/unpin.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private userEntityService: UserEntityService, private notePiningService: NotePiningService, diff --git a/packages/backend/src/server/api/endpoints/i/update-email.ts b/packages/backend/src/server/api/endpoints/i/update-email.ts index 58e056bd37..37996db9b7 100644 --- a/packages/backend/src/server/api/endpoints/i/update-email.ts +++ b/packages/backend/src/server/api/endpoints/i/update-email.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import bcrypt from 'bcryptjs'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, UserProfilesRepository } from '@/models/index.js'; +import type { UserProfilesRepository } from '@/models/index.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { EmailService } from '@/core/EmailService.js'; import type { Config } from '@/config.js'; @@ -45,16 +50,12 @@ export const paramDef = { required: ['password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 8f5e6177c2..89125392d6 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import RE2 from 're2'; import * as mfm from 'mfm-js'; import { Inject, Injectable } from '@nestjs/common'; @@ -5,9 +10,9 @@ import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mf import { extractHashtags } from '@/misc/extract-hashtags.js'; import * as Acct from '@/misc/acct.js'; import type { UsersRepository, DriveFilesRepository, UserProfilesRepository, PagesRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { birthdaySchema, descriptionSchema, locationSchema, nameSchema } from '@/models/entities/User.js'; -import type { UserProfile } from '@/models/entities/UserProfile.js'; +import type { MiUserProfile } from '@/models/entities/UserProfile.js'; import { notificationTypes } from '@/types.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { langmap } from '@/misc/langmap.js'; @@ -20,7 +25,6 @@ import { HashtagService } from '@/core/HashtagService.js'; import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; import { CacheService } from '@/core/CacheService.js'; -import { AccountMoveService } from '@/core/AccountMoveService.js'; import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { ApiLoggerService } from '../../ApiLoggerService.js'; @@ -166,9 +170,8 @@ export const paramDef = { }, } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -187,7 +190,6 @@ export default class extends Endpoint { private globalEventService: GlobalEventService, private userFollowingService: UserFollowingService, private accountUpdateService: AccountUpdateService, - private accountMoveService: AccountMoveService, private remoteUserResolveService: RemoteUserResolveService, private apiLoggerService: ApiLoggerService, private hashtagService: HashtagService, @@ -198,8 +200,8 @@ export default class extends Endpoint { const user = await this.usersRepository.findOneByOrFail({ id: _user.id }); const isSecure = token == null; - const updates = {} as Partial; - const profileUpdates = {} as Partial; + const updates = {} as Partial; + const profileUpdates = {} as Partial; const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts index 51fcce6cf0..d13af482b1 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { IdService } from '@/core/IdService.js'; @@ -39,9 +44,8 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.webhooksRepository) private webhooksRepository: WebhooksRepository, diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/delete.ts b/packages/backend/src/server/api/endpoints/i/webhooks/delete.ts index 7bdad136aa..da0002858d 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/delete.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { WebhooksRepository } from '@/models/index.js'; @@ -31,9 +36,8 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.webhooksRepository) private webhooksRepository: WebhooksRepository, diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/list.ts b/packages/backend/src/server/api/endpoints/i/webhooks/list.ts index 58c84938cc..478b34296c 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/list.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { WebhooksRepository } from '@/models/index.js'; @@ -17,9 +22,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.webhooksRepository) private webhooksRepository: WebhooksRepository, diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/show.ts b/packages/backend/src/server/api/endpoints/i/webhooks/show.ts index d15ca0050d..f774840e9f 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/show.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { WebhooksRepository } from '@/models/index.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: ['webhookId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.webhooksRepository) private webhooksRepository: WebhooksRepository, diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/update.ts b/packages/backend/src/server/api/endpoints/i/webhooks/update.ts index 8ec308eda7..8f2dcceaa9 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/update.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { WebhooksRepository } from '@/models/index.js'; @@ -40,9 +45,8 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.webhooksRepository) private webhooksRepository: WebhooksRepository, diff --git a/packages/backend/src/server/api/endpoints/invite/create.ts b/packages/backend/src/server/api/endpoints/invite/create.ts index a64184be10..8532becebe 100644 --- a/packages/backend/src/server/api/endpoints/invite/create.ts +++ b/packages/backend/src/server/api/endpoints/invite/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { MoreThan } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -42,9 +47,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registrationTicketsRepository) private registrationTicketsRepository: RegistrationTicketsRepository, diff --git a/packages/backend/src/server/api/endpoints/invite/delete.ts b/packages/backend/src/server/api/endpoints/invite/delete.ts index afca44954d..8991bfef25 100644 --- a/packages/backend/src/server/api/endpoints/invite/delete.ts +++ b/packages/backend/src/server/api/endpoints/invite/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistrationTicketsRepository } from '@/models/index.js'; @@ -40,9 +45,8 @@ export const paramDef = { required: ['inviteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registrationTicketsRepository) private registrationTicketsRepository: RegistrationTicketsRepository, diff --git a/packages/backend/src/server/api/endpoints/invite/limit.ts b/packages/backend/src/server/api/endpoints/invite/limit.ts index 9a213b7b25..386fd676b9 100644 --- a/packages/backend/src/server/api/endpoints/invite/limit.ts +++ b/packages/backend/src/server/api/endpoints/invite/limit.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { MoreThan } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registrationTicketsRepository) private registrationTicketsRepository: RegistrationTicketsRepository, diff --git a/packages/backend/src/server/api/endpoints/invite/list.ts b/packages/backend/src/server/api/endpoints/invite/list.ts index e047790261..dcd1017589 100644 --- a/packages/backend/src/server/api/endpoints/invite/list.ts +++ b/packages/backend/src/server/api/endpoints/invite/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RegistrationTicketsRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.registrationTicketsRepository) private registrationTicketsRepository: RegistrationTicketsRepository, diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index adfa579558..fbcb8dc34d 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull, LessThanOrEqual, MoreThan, Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import JSON5 from 'json5'; @@ -248,9 +253,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, diff --git a/packages/backend/src/server/api/endpoints/miauth/gen-token.ts b/packages/backend/src/server/api/endpoints/miauth/gen-token.ts index 0ea29f04dc..7f14342d90 100644 --- a/packages/backend/src/server/api/endpoints/miauth/gen-token.ts +++ b/packages/backend/src/server/api/endpoints/miauth/gen-token.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AccessTokensRepository } from '@/models/index.js'; @@ -38,9 +43,8 @@ export const paramDef = { required: ['session', 'permission'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.accessTokensRepository) private accessTokensRepository: AccessTokensRepository, diff --git a/packages/backend/src/server/api/endpoints/mute/create.ts b/packages/backend/src/server/api/endpoints/mute/create.ts index ef53f9ef41..d896a41d61 100644 --- a/packages/backend/src/server/api/endpoints/mute/create.ts +++ b/packages/backend/src/server/api/endpoints/mute/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -54,9 +59,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.mutingsRepository) private mutingsRepository: MutingsRepository, diff --git a/packages/backend/src/server/api/endpoints/mute/delete.ts b/packages/backend/src/server/api/endpoints/mute/delete.ts index 90b74590be..51005206b8 100644 --- a/packages/backend/src/server/api/endpoints/mute/delete.ts +++ b/packages/backend/src/server/api/endpoints/mute/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { MutingsRepository } from '@/models/index.js'; @@ -42,9 +47,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.mutingsRepository) private mutingsRepository: MutingsRepository, diff --git a/packages/backend/src/server/api/endpoints/mute/list.ts b/packages/backend/src/server/api/endpoints/mute/list.ts index 4711e86d6b..710d59c25d 100644 --- a/packages/backend/src/server/api/endpoints/mute/list.ts +++ b/packages/backend/src/server/api/endpoints/mute/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { MutingsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.mutingsRepository) private mutingsRepository: MutingsRepository, diff --git a/packages/backend/src/server/api/endpoints/my/apps.ts b/packages/backend/src/server/api/endpoints/my/apps.ts index 4b7ed80123..e35920e2e3 100644 --- a/packages/backend/src/server/api/endpoints/my/apps.ts +++ b/packages/backend/src/server/api/endpoints/my/apps.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AppsRepository } from '@/models/index.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.appsRepository) private appsRepository: AppsRepository, diff --git a/packages/backend/src/server/api/endpoints/notes.ts b/packages/backend/src/server/api/endpoints/notes.ts index 9013b300e7..4e451b04e2 100644 --- a/packages/backend/src/server/api/endpoints/notes.ts +++ b/packages/backend/src/server/api/endpoints/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/children.ts b/packages/backend/src/server/api/endpoints/notes/children.ts index 5f03fd4b74..93bfe964bb 100644 --- a/packages/backend/src/server/api/endpoints/notes/children.ts +++ b/packages/backend/src/server/api/endpoints/notes/children.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/clips.ts b/packages/backend/src/server/api/endpoints/notes/clips.ts index 0a5542f497..ea43043d4a 100644 --- a/packages/backend/src/server/api/endpoints/notes/clips.ts +++ b/packages/backend/src/server/api/endpoints/notes/clips.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { In } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { ClipNotesRepository, ClipsRepository } from '@/models/index.js'; @@ -39,9 +44,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/conversation.ts b/packages/backend/src/server/api/endpoints/notes/conversation.ts index 10f43b04c0..0a919c217e 100644 --- a/packages/backend/src/server/api/endpoints/notes/conversation.ts +++ b/packages/backend/src/server/api/endpoints/notes/conversation.ts @@ -1,5 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { Note } from '@/models/entities/Note.js'; +import type { MiNote } from '@/models/entities/Note.js'; import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; @@ -41,9 +46,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -57,7 +61,7 @@ export default class extends Endpoint { throw err; }); - const conversation: Note[] = []; + const conversation: MiNote[] = []; let i = 0; const get = async (id: any) => { diff --git a/packages/backend/src/server/api/endpoints/notes/create.test.ts b/packages/backend/src/server/api/endpoints/notes/create.test.ts index 6bff7fc0c9..6d34aaccf3 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.test.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.test.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import { readFile } from 'node:fs/promises'; diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 739316997a..22e772d1ab 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -1,11 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { In } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import type { UsersRepository, NotesRepository, BlockingsRepository, DriveFilesRepository, ChannelsRepository } from '@/models/index.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { Channel } from '@/models/entities/Channel.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiChannel } from '@/models/entities/Channel.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; @@ -157,9 +162,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -180,15 +184,15 @@ export default class extends Endpoint { private noteCreateService: NoteCreateService, ) { super(meta, paramDef, async (ps, me) => { - let visibleUsers: User[] = []; + let visibleUsers: MiUser[] = []; if (ps.visibleUserIds) { visibleUsers = await this.usersRepository.findBy({ id: In(ps.visibleUserIds), }); } - let files: DriveFile[] = []; - const fileIds = ps.fileIds != null ? ps.fileIds : ps.mediaIds != null ? ps.mediaIds : null; + let files: MiDriveFile[] = []; + const fileIds = ps.fileIds ?? ps.mediaIds ?? null; if (fileIds != null) { files = await this.driveFilesRepository.createQueryBuilder('file') .where('file.userId = :userId AND file.id IN (:...fileIds)', { @@ -204,7 +208,7 @@ export default class extends Endpoint { } } - let renote: Note | null = null; + let renote: MiNote | null = null; if (ps.renoteId != null) { // Fetch renote to note renote = await this.notesRepository.findOneBy({ id: ps.renoteId }); @@ -229,7 +233,7 @@ export default class extends Endpoint { } } - let reply: Note | null = null; + let reply: MiNote | null = null; if (ps.replyId != null) { // Fetch reply reply = await this.notesRepository.findOneBy({ id: ps.replyId }); @@ -264,7 +268,7 @@ export default class extends Endpoint { } } - let channel: Channel | null = null; + let channel: MiChannel | null = null; if (ps.channelId != null) { channel = await this.channelsRepository.findOneBy({ id: ps.channelId, isArchived: false }); diff --git a/packages/backend/src/server/api/endpoints/notes/delete.ts b/packages/backend/src/server/api/endpoints/notes/delete.ts index 16c4c01387..33bea250c0 100644 --- a/packages/backend/src/server/api/endpoints/notes/delete.ts +++ b/packages/backend/src/server/api/endpoints/notes/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; @@ -44,9 +49,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts index 9299d66039..7207404ff9 100644 --- a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import type { NoteFavoritesRepository } from '@/models/index.js'; @@ -44,9 +49,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.noteFavoritesRepository) private noteFavoritesRepository: NoteFavoritesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts b/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts index bb3a7c501a..1be51d02d2 100644 --- a/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts +++ b/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GetterService } from '@/server/api/GetterService.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.noteFavoritesRepository) private noteFavoritesRepository: NoteFavoritesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/featured.ts b/packages/backend/src/server/api/endpoints/notes/featured.ts index 3a3cb0739b..b65a7ed7b9 100644 --- a/packages/backend/src/server/api/endpoints/notes/featured.ts +++ b/packages/backend/src/server/api/endpoints/notes/featured.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts index 4ce2fdaec7..9e2dcc532d 100644 --- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts @@ -1,9 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; -import { MetaService } from '@/core/MetaService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; @@ -45,16 +49,14 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, private noteEntityService: NoteEntityService, private queryService: QueryService, - private metaService: MetaService, private roleService: RoleService, private activeUsersChart: ActiveUsersChart, ) { diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index af94cf6087..69e0f218e8 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository, FollowingsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; -import { MetaService } from '@/core/MetaService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; @@ -52,9 +56,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -64,7 +67,6 @@ export default class extends Endpoint { private noteEntityService: NoteEntityService, private queryService: QueryService, - private metaService: MetaService, private roleService: RoleService, private activeUsersChart: ActiveUsersChart, private idService: IdService, diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index fe7407f48a..3fea8eb3ca 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; -import { MetaService } from '@/core/MetaService.js'; import ActiveUsersChart from '@/core/chart/charts/active-users.js'; import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; @@ -51,16 +55,14 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, private noteEntityService: NoteEntityService, private queryService: QueryService, - private metaService: MetaService, private roleService: RoleService, private activeUsersChart: ActiveUsersChart, private idService: IdService, diff --git a/packages/backend/src/server/api/endpoints/notes/mentions.ts b/packages/backend/src/server/api/endpoints/notes/mentions.ts index 6ee9de1e23..0d5cb1130a 100644 --- a/packages/backend/src/server/api/endpoints/notes/mentions.ts +++ b/packages/backend/src/server/api/endpoints/notes/mentions.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository, FollowingsRepository } from '@/models/index.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts b/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts index 889f644643..744f275a55 100644 --- a/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts +++ b/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets, In } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository, MutingsRepository, PollsRepository, PollVotesRepository } from '@/models/index.js'; @@ -30,9 +35,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/polls/vote.ts b/packages/backend/src/server/api/endpoints/notes/polls/vote.ts index 3a33b037f8..53ceeb5a20 100644 --- a/packages/backend/src/server/api/endpoints/notes/polls/vote.ts +++ b/packages/backend/src/server/api/endpoints/notes/polls/vote.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, PollsRepository, PollVotesRepository } from '@/models/index.js'; -import type { RemoteUser } from '@/models/entities/User.js'; +import type { MiRemoteUser } from '@/models/entities/User.js'; import { IdService } from '@/core/IdService.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GetterService } from '@/server/api/GetterService.js'; @@ -71,9 +76,8 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -159,7 +163,7 @@ export default class extends Endpoint { // リモート投票の場合リプライ送信 if (note.userHost != null) { - const pollOwner = await this.usersRepository.findOneByOrFail({ id: note.userId }) as RemoteUser; + const pollOwner = await this.usersRepository.findOneByOrFail({ id: note.userId }) as MiRemoteUser; this.queueService.deliver(me, this.apRendererService.addContext(await this.apRendererService.renderVote(me, vote, note, poll, pollOwner)), pollOwner.inbox, false); } diff --git a/packages/backend/src/server/api/endpoints/notes/reactions.ts b/packages/backend/src/server/api/endpoints/notes/reactions.ts index 4772c4f809..6957601187 100644 --- a/packages/backend/src/server/api/endpoints/notes/reactions.ts +++ b/packages/backend/src/server/api/endpoints/notes/reactions.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NoteReactionsRepository } from '@/models/index.js'; -import type { NoteReaction } from '@/models/entities/NoteReaction.js'; +import type { MiNoteReaction } from '@/models/entities/NoteReaction.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteReactionEntityService } from '@/core/entities/NoteReactionEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -46,9 +51,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.noteReactionsRepository) private noteReactionsRepository: NoteReactionsRepository, @@ -58,7 +62,7 @@ export default class extends Endpoint { super(meta, paramDef, async (ps, me) => { const query = { noteId: ps.noteId, - } as FindOptionsWhere; + } as FindOptionsWhere; if (ps.type) { // ローカルリアクションはホスト名が . とされているが diff --git a/packages/backend/src/server/api/endpoints/notes/reactions/create.ts b/packages/backend/src/server/api/endpoints/notes/reactions/create.ts index 97cb026779..ff22ef1322 100644 --- a/packages/backend/src/server/api/endpoints/notes/reactions/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/reactions/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GetterService } from '@/server/api/GetterService.js'; @@ -43,9 +48,8 @@ export const paramDef = { required: ['noteId', 'reaction'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private getterService: GetterService, private reactionService: ReactionService, diff --git a/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts b/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts index 207f0b4cf2..b43ab044fa 100644 --- a/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts +++ b/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -41,9 +46,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private getterService: GetterService, private reactionService: ReactionService, diff --git a/packages/backend/src/server/api/endpoints/notes/renotes.ts b/packages/backend/src/server/api/endpoints/notes/renotes.ts index 4ee12b3353..a7bd47df85 100644 --- a/packages/backend/src/server/api/endpoints/notes/renotes.ts +++ b/packages/backend/src/server/api/endpoints/notes/renotes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -42,9 +47,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/replies.ts b/packages/backend/src/server/api/endpoints/notes/replies.ts index 900c40d32a..ea5d557763 100644 --- a/packages/backend/src/server/api/endpoints/notes/replies.ts +++ b/packages/backend/src/server/api/endpoints/notes/replies.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts index dc0a5dceee..786282c64e 100644 --- a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts +++ b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; @@ -58,9 +63,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts index cd0e351e45..4425d4593c 100644 --- a/packages/backend/src/server/api/endpoints/notes/search.ts +++ b/packages/backend/src/server/api/endpoints/notes/search.ts @@ -1,10 +1,12 @@ -import { Inject, Injectable } from '@nestjs/common'; -import type { NotesRepository } from '@/models/index.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { SearchService } from '@/core/SearchService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; -import type { Config } from '@/config.js'; -import { DI } from '@/di-symbols.js'; import { RoleService } from '@/core/RoleService.js'; import { ApiError } from '../../error.js'; @@ -52,13 +54,9 @@ export const paramDef = { // TODO: ロジックをサービスに切り出す -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.config) - private config: Config, - private noteEntityService: NoteEntityService, private searchService: SearchService, private roleService: RoleService, diff --git a/packages/backend/src/server/api/endpoints/notes/show.ts b/packages/backend/src/server/api/endpoints/notes/show.ts index 2aec7d64dd..5bb8196543 100644 --- a/packages/backend/src/server/api/endpoints/notes/show.ts +++ b/packages/backend/src/server/api/endpoints/notes/show.ts @@ -1,8 +1,11 @@ -import { Inject, Injectable } from '@nestjs/common'; -import type { NotesRepository } from '@/models/index.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; -import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; import { ApiError } from '../../error.js'; @@ -34,13 +37,9 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - private noteEntityService: NoteEntityService, private getterService: GetterService, ) { diff --git a/packages/backend/src/server/api/endpoints/notes/state.ts b/packages/backend/src/server/api/endpoints/notes/state.ts index 93517ab10c..ac05c747da 100644 --- a/packages/backend/src/server/api/endpoints/notes/state.ts +++ b/packages/backend/src/server/api/endpoints/notes/state.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository, NoteThreadMutingsRepository, NoteFavoritesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts b/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts index abea069da8..afd8276d96 100644 --- a/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import type { NotesRepository, NoteThreadMutingsRepository } from '@/models/index.js'; @@ -37,9 +42,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts b/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts index 30016d48bc..8ef573e988 100644 --- a/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts +++ b/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { NoteThreadMutingsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.noteThreadMutingsRepository) private noteThreadMutingsRepository: NoteThreadMutingsRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index 7e9bf85d88..0aba310882 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository, FollowingsRepository } from '@/models/index.js'; @@ -41,9 +46,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/translate.ts b/packages/backend/src/server/api/endpoints/notes/translate.ts index b91bc7b5ec..00cb9a0a28 100644 --- a/packages/backend/src/server/api/endpoints/notes/translate.ts +++ b/packages/backend/src/server/api/endpoints/notes/translate.ts @@ -1,9 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { URLSearchParams } from 'node:url'; -import { Inject, Injectable } from '@nestjs/common'; -import type { NotesRepository } from '@/models/index.js'; +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { Config } from '@/config.js'; -import { DI } from '@/di-symbols.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { MetaService } from '@/core/MetaService.js'; import { HttpRequestService } from '@/core/HttpRequestService.js'; @@ -38,16 +40,9 @@ export const paramDef = { required: ['noteId', 'targetLang'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.config) - private config: Config, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - private noteEntityService: NoteEntityService, private getterService: GetterService, private metaService: MetaService, diff --git a/packages/backend/src/server/api/endpoints/notes/unrenote.ts b/packages/backend/src/server/api/endpoints/notes/unrenote.ts index e9581beedc..a6e4eb01ab 100644 --- a/packages/backend/src/server/api/endpoints/notes/unrenote.ts +++ b/packages/backend/src/server/api/endpoints/notes/unrenote.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, NotesRepository } from '@/models/index.js'; @@ -37,9 +42,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts index 4c19e1a553..8b8d24e725 100644 --- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository, UserListsRepository, UserListJoiningsRepository } from '@/models/index.js'; @@ -53,9 +58,8 @@ export const paramDef = { required: ['listId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -91,6 +95,10 @@ export default class extends Endpoint { .andWhere('userListJoining.userListId = :userListId', { userListId: list.id }); this.queryService.generateVisibilityQuery(query, me); + this.queryService.generateMutedUserQuery(query, me); + this.queryService.generateMutedNoteQuery(query, me); + this.queryService.generateBlockedUserQuery(query, me); + this.queryService.generateMutedUserRenotesQueryForNotes(query, me); if (ps.includeMyRenotes === false) { query.andWhere(new Brackets(qb => { diff --git a/packages/backend/src/server/api/endpoints/notifications/create.ts b/packages/backend/src/server/api/endpoints/notifications/create.ts index 4102a924ad..020fc2d3df 100644 --- a/packages/backend/src/server/api/endpoints/notifications/create.ts +++ b/packages/backend/src/server/api/endpoints/notifications/create.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NotificationService } from '@/core/NotificationService.js'; @@ -23,9 +28,8 @@ export const paramDef = { required: ['body'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private notificationService: NotificationService, ) { diff --git a/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts b/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts index e601bf9d5b..dc092c1f3a 100644 --- a/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts +++ b/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts @@ -1,6 +1,10 @@ -import { Inject, Injectable } from '@nestjs/common'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { DI } from '@/di-symbols.js'; import { NotificationService } from '@/core/NotificationService.js'; export const meta = { @@ -17,9 +21,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private notificationService: NotificationService, ) { diff --git a/packages/backend/src/server/api/endpoints/page-push.ts b/packages/backend/src/server/api/endpoints/page-push.ts index 1d6fb567f0..8fff9a926f 100644 --- a/packages/backend/src/server/api/endpoints/page-push.ts +++ b/packages/backend/src/server/api/endpoints/page-push.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { PagesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -29,9 +34,8 @@ export const paramDef = { required: ['pageId', 'event'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts index e08ab399f8..1b6ba40755 100644 --- a/packages/backend/src/server/api/endpoints/pages/create.ts +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import type { DriveFilesRepository, PagesRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; -import { Page } from '@/models/entities/Page.js'; +import { MiPage } from '@/models/entities/Page.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { PageEntityService } from '@/core/entities/PageEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -63,9 +68,8 @@ export const paramDef = { required: ['title', 'name', 'content', 'variables', 'script'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, @@ -98,7 +102,7 @@ export default class extends Endpoint { } }); - const page = await this.pagesRepository.insert(new Page({ + const page = await this.pagesRepository.insert(new MiPage({ id: this.idService.genId(), createdAt: new Date(), updatedAt: new Date(), diff --git a/packages/backend/src/server/api/endpoints/pages/delete.ts b/packages/backend/src/server/api/endpoints/pages/delete.ts index e64733131c..ac55abffb0 100644 --- a/packages/backend/src/server/api/endpoints/pages/delete.ts +++ b/packages/backend/src/server/api/endpoints/pages/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { PagesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -34,9 +39,8 @@ export const paramDef = { required: ['pageId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, diff --git a/packages/backend/src/server/api/endpoints/pages/featured.ts b/packages/backend/src/server/api/endpoints/pages/featured.ts index b1c056124e..68c06adb7f 100644 --- a/packages/backend/src/server/api/endpoints/pages/featured.ts +++ b/packages/backend/src/server/api/endpoints/pages/featured.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { PagesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -26,9 +31,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, diff --git a/packages/backend/src/server/api/endpoints/pages/like.ts b/packages/backend/src/server/api/endpoints/pages/like.ts index bc66488103..155f6db559 100644 --- a/packages/backend/src/server/api/endpoints/pages/like.ts +++ b/packages/backend/src/server/api/endpoints/pages/like.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { PagesRepository, PageLikesRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; @@ -43,9 +48,8 @@ export const paramDef = { required: ['pageId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, diff --git a/packages/backend/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts index bf2b2a431e..f74b67a627 100644 --- a/packages/backend/src/server/api/endpoints/pages/show.ts +++ b/packages/backend/src/server/api/endpoints/pages/show.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, PagesRepository } from '@/models/index.js'; -import type { Page } from '@/models/entities/Page.js'; +import type { MiPage } from '@/models/entities/Page.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { PageEntityService } from '@/core/entities/PageEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -40,9 +45,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -53,7 +57,7 @@ export default class extends Endpoint { private pageEntityService: PageEntityService, ) { super(meta, paramDef, async (ps, me) => { - let page: Page | null = null; + let page: MiPage | null = null; if (ps.pageId) { page = await this.pagesRepository.findOneBy({ id: ps.pageId }); diff --git a/packages/backend/src/server/api/endpoints/pages/unlike.ts b/packages/backend/src/server/api/endpoints/pages/unlike.ts index f0c0198460..143cb6965b 100644 --- a/packages/backend/src/server/api/endpoints/pages/unlike.ts +++ b/packages/backend/src/server/api/endpoints/pages/unlike.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { PagesRepository, PageLikesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -36,9 +41,8 @@ export const paramDef = { required: ['pageId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts index 751274067e..4d54d82b74 100644 --- a/packages/backend/src/server/api/endpoints/pages/update.ts +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Not } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; @@ -68,9 +73,8 @@ export const paramDef = { required: ['pageId', 'title', 'name', 'content', 'variables', 'script'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, @@ -112,13 +116,17 @@ export default class extends Endpoint { await this.pagesRepository.update(page.id, { updatedAt: new Date(), title: ps.title, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing name: ps.name === undefined ? page.name : ps.name, summary: ps.summary === undefined ? page.summary : ps.summary, content: ps.content, variables: ps.variables, script: ps.script, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing font: ps.font === undefined ? page.font : ps.font, eyeCatchingImageId: ps.eyeCatchingImageId === null ? null diff --git a/packages/backend/src/server/api/endpoints/ping.ts b/packages/backend/src/server/api/endpoints/ping.ts index 5807bf101e..ee2fe48834 100644 --- a/packages/backend/src/server/api/endpoints/ping.ts +++ b/packages/backend/src/server/api/endpoints/ping.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -24,9 +29,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( ) { super(meta, paramDef, async () => { diff --git a/packages/backend/src/server/api/endpoints/pinned-users.ts b/packages/backend/src/server/api/endpoints/pinned-users.ts index f2c6e798ef..78c65e0201 100644 --- a/packages/backend/src/server/api/endpoints/pinned-users.ts +++ b/packages/backend/src/server/api/endpoints/pinned-users.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; import * as Acct from '@/misc/acct.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { MetaService } from '@/core/MetaService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -30,9 +35,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -48,7 +52,7 @@ export default class extends Endpoint { host: acct.host ?? IsNull(), }))); - return await this.userEntityService.packMany(users.filter(x => x !== null) as User[], me, { detail: true }); + return await this.userEntityService.packMany(users.filter(x => x !== null) as MiUser[], me, { detail: true }); }); } } diff --git a/packages/backend/src/server/api/endpoints/promo/read.ts b/packages/backend/src/server/api/endpoints/promo/read.ts index a76866fe14..2e11be4dc6 100644 --- a/packages/backend/src/server/api/endpoints/promo/read.ts +++ b/packages/backend/src/server/api/endpoints/promo/read.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { PromoReadsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; @@ -28,9 +33,8 @@ export const paramDef = { required: ['noteId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.promoReadsRepository) private promoReadsRepository: PromoReadsRepository, diff --git a/packages/backend/src/server/api/endpoints/renote-mute/create.ts b/packages/backend/src/server/api/endpoints/renote-mute/create.ts index beb5850d78..a1e9c7055a 100644 --- a/packages/backend/src/server/api/endpoints/renote-mute/create.ts +++ b/packages/backend/src/server/api/endpoints/renote-mute/create.ts @@ -1,10 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { IdService } from '@/core/IdService.js'; import type { RenoteMutingsRepository } from '@/models/index.js'; -import type { RenoteMuting } from '@/models/entities/RenoteMuting.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; +import type { MiRenoteMuting } from '@/models/entities/RenoteMuting.js'; import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; import { ApiError } from '../../error.js'; @@ -51,14 +55,12 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.renoteMutingsRepository) private renoteMutingsRepository: RenoteMutingsRepository, - private globalEventService: GlobalEventService, private getterService: GetterService, private idService: IdService, ) { @@ -92,7 +94,7 @@ export default class extends Endpoint { createdAt: new Date(), muterId: muter.id, muteeId: mutee.id, - } as RenoteMuting); + } as MiRenoteMuting); }); } } diff --git a/packages/backend/src/server/api/endpoints/renote-mute/delete.ts b/packages/backend/src/server/api/endpoints/renote-mute/delete.ts index 70901a1406..b390380e4e 100644 --- a/packages/backend/src/server/api/endpoints/renote-mute/delete.ts +++ b/packages/backend/src/server/api/endpoints/renote-mute/delete.ts @@ -1,7 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RenoteMutingsRepository } from '@/models/index.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; import { ApiError } from '../../error.js'; @@ -42,14 +46,12 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.renoteMutingsRepository) private renoteMutingsRepository: RenoteMutingsRepository, - private globalEventService: GlobalEventService, private getterService: GetterService, ) { super(meta, paramDef, async (ps, me) => { diff --git a/packages/backend/src/server/api/endpoints/renote-mute/list.ts b/packages/backend/src/server/api/endpoints/renote-mute/list.ts index cb4e1feba4..f6fae38bc8 100644 --- a/packages/backend/src/server/api/endpoints/renote-mute/list.ts +++ b/packages/backend/src/server/api/endpoints/renote-mute/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RenoteMutingsRepository } from '@/models/index.js'; @@ -33,9 +38,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.renoteMutingsRepository) private renoteMutingsRepository: RenoteMutingsRepository, diff --git a/packages/backend/src/server/api/endpoints/request-reset-password.ts b/packages/backend/src/server/api/endpoints/request-reset-password.ts index 284ed8410d..117eac6871 100644 --- a/packages/backend/src/server/api/endpoints/request-reset-password.ts +++ b/packages/backend/src/server/api/endpoints/request-reset-password.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['username', 'email'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, diff --git a/packages/backend/src/server/api/endpoints/reset-db.ts b/packages/backend/src/server/api/endpoints/reset-db.ts index 1d4825f812..0eeee81580 100644 --- a/packages/backend/src/server/api/endpoints/reset-db.ts +++ b/packages/backend/src/server/api/endpoints/reset-db.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { DataSource } from 'typeorm'; import * as Redis from 'ioredis'; @@ -23,9 +28,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.db) private db: DataSource, diff --git a/packages/backend/src/server/api/endpoints/reset-password.ts b/packages/backend/src/server/api/endpoints/reset-password.ts index e6f1af7b22..41b6e5e652 100644 --- a/packages/backend/src/server/api/endpoints/reset-password.ts +++ b/packages/backend/src/server/api/endpoints/reset-password.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import bcrypt from 'bcryptjs'; import { Inject, Injectable } from '@nestjs/common'; import type { UserProfilesRepository, PasswordResetRequestsRepository } from '@/models/index.js'; @@ -25,9 +30,8 @@ export const paramDef = { required: ['token', 'password'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.passwordResetRequestsRepository) private passwordResetRequestsRepository: PasswordResetRequestsRepository, diff --git a/packages/backend/src/server/api/endpoints/retention.ts b/packages/backend/src/server/api/endpoints/retention.ts index e9c0fd4dcd..7689c2a1de 100644 --- a/packages/backend/src/server/api/endpoints/retention.ts +++ b/packages/backend/src/server/api/endpoints/retention.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { RetentionAggregationsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.retentionAggregationsRepository) private retentionAggregationsRepository: RetentionAggregationsRepository, diff --git a/packages/backend/src/server/api/endpoints/roles/list.ts b/packages/backend/src/server/api/endpoints/roles/list.ts index 5ad29839c2..225736bd74 100644 --- a/packages/backend/src/server/api/endpoints/roles/list.ts +++ b/packages/backend/src/server/api/endpoints/roles/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { RolesRepository } from '@/models/index.js'; @@ -18,9 +23,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/roles/notes.ts b/packages/backend/src/server/api/endpoints/roles/notes.ts index a30c31b727..8a5f41267a 100644 --- a/packages/backend/src/server/api/endpoints/roles/notes.ts +++ b/packages/backend/src/server/api/endpoints/roles/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import * as Redis from 'ioredis'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -45,9 +50,8 @@ export const paramDef = { required: ['roleId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.redis) private redisClient: Redis.Redis, diff --git a/packages/backend/src/server/api/endpoints/roles/show.ts b/packages/backend/src/server/api/endpoints/roles/show.ts index cc755dcc76..a28d65ec38 100644 --- a/packages/backend/src/server/api/endpoints/roles/show.ts +++ b/packages/backend/src/server/api/endpoints/roles/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { RolesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -27,9 +32,8 @@ export const paramDef = { required: ['roleId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/roles/users.ts b/packages/backend/src/server/api/endpoints/roles/users.ts index cc27201886..56d17211bc 100644 --- a/packages/backend/src/server/api/endpoints/roles/users.ts +++ b/packages/backend/src/server/api/endpoints/roles/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Brackets } from 'typeorm'; import type { RoleAssignmentsRepository, RolesRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['roleId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.rolesRepository) private rolesRepository: RolesRepository, diff --git a/packages/backend/src/server/api/endpoints/server-info.ts b/packages/backend/src/server/api/endpoints/server-info.ts index 552441e430..c8cb63e6b3 100644 --- a/packages/backend/src/server/api/endpoints/server-info.ts +++ b/packages/backend/src/server/api/endpoints/server-info.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as os from 'node:os'; import si from 'systeminformation'; import { Injectable } from '@nestjs/common'; @@ -18,9 +23,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( private metaService: MetaService, ) { diff --git a/packages/backend/src/server/api/endpoints/stats.ts b/packages/backend/src/server/api/endpoints/stats.ts index 48a85758a0..464ba5011e 100644 --- a/packages/backend/src/server/api/endpoints/stats.ts +++ b/packages/backend/src/server/api/endpoints/stats.ts @@ -1,5 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; -import type { InstancesRepository, NoteReactionsRepository, NotesRepository, UsersRepository } from '@/models/index.js'; +import type { InstancesRepository, NoteReactionsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { DI } from '@/di-symbols.js'; import NotesChart from '@/core/chart/charts/notes.js'; @@ -52,16 +57,9 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, diff --git a/packages/backend/src/server/api/endpoints/sw/register.ts b/packages/backend/src/server/api/endpoints/sw/register.ts index bfd5de7b00..d32b36bf99 100644 --- a/packages/backend/src/server/api/endpoints/sw/register.ts +++ b/packages/backend/src/server/api/endpoints/sw/register.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { IdService } from '@/core/IdService.js'; import type { SwSubscriptionsRepository } from '@/models/index.js'; @@ -52,9 +57,8 @@ export const paramDef = { required: ['endpoint', 'auth', 'publickey'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.swSubscriptionsRepository) private swSubscriptionsRepository: SwSubscriptionsRepository, diff --git a/packages/backend/src/server/api/endpoints/sw/show-registration.ts b/packages/backend/src/server/api/endpoints/sw/show-registration.ts index bede10be5c..396e5824d6 100644 --- a/packages/backend/src/server/api/endpoints/sw/show-registration.ts +++ b/packages/backend/src/server/api/endpoints/sw/show-registration.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { SwSubscriptionsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -38,9 +43,8 @@ export const paramDef = { required: ['endpoint'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.swSubscriptionsRepository) private swSubscriptionsRepository: SwSubscriptionsRepository, diff --git a/packages/backend/src/server/api/endpoints/sw/unregister.ts b/packages/backend/src/server/api/endpoints/sw/unregister.ts index f12b98617d..2704a02345 100644 --- a/packages/backend/src/server/api/endpoints/sw/unregister.ts +++ b/packages/backend/src/server/api/endpoints/sw/unregister.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { SwSubscriptionsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -19,9 +24,8 @@ export const paramDef = { required: ['endpoint'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.swSubscriptionsRepository) private swSubscriptionsRepository: SwSubscriptionsRepository, diff --git a/packages/backend/src/server/api/endpoints/sw/update-registration.ts b/packages/backend/src/server/api/endpoints/sw/update-registration.ts index b82c4bf49d..d91771233e 100644 --- a/packages/backend/src/server/api/endpoints/sw/update-registration.ts +++ b/packages/backend/src/server/api/endpoints/sw/update-registration.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { SwSubscriptionsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -47,9 +52,8 @@ export const paramDef = { required: ['endpoint'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.swSubscriptionsRepository) private swSubscriptionsRepository: SwSubscriptionsRepository, diff --git a/packages/backend/src/server/api/endpoints/test.ts b/packages/backend/src/server/api/endpoints/test.ts index c88f7f2daf..6d6d44f752 100644 --- a/packages/backend/src/server/api/endpoints/test.ts +++ b/packages/backend/src/server/api/endpoints/test.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -21,9 +26,8 @@ export const paramDef = { required: ['required'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( ) { super(meta, paramDef, async (ps, me) => { diff --git a/packages/backend/src/server/api/endpoints/username/available.ts b/packages/backend/src/server/api/endpoints/username/available.ts index 6293c5cb50..56e096f10f 100644 --- a/packages/backend/src/server/api/endpoints/username/available.ts +++ b/packages/backend/src/server/api/endpoints/username/available.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsedUsernamesRepository, UsersRepository } from '@/models/index.js'; @@ -31,9 +36,8 @@ export const paramDef = { required: ['username'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/users.ts b/packages/backend/src/server/api/endpoints/users.ts index 47d0a81552..daad3ce474 100644 --- a/packages/backend/src/server/api/endpoints/users.ts +++ b/packages/backend/src/server/api/endpoints/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -39,9 +44,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/users/achievements.ts b/packages/backend/src/server/api/endpoints/users/achievements.ts index 2a095d83ea..f1ddc98ea0 100644 --- a/packages/backend/src/server/api/endpoints/users/achievements.ts +++ b/packages/backend/src/server/api/endpoints/users/achievements.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UserProfilesRepository } from '@/models/index.js'; @@ -15,9 +20,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/users/clips.ts b/packages/backend/src/server/api/endpoints/users/clips.ts index c2ad420cb5..eb752fb9df 100644 --- a/packages/backend/src/server/api/endpoints/users/clips.ts +++ b/packages/backend/src/server/api/endpoints/users/clips.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { ClipsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, diff --git a/packages/backend/src/server/api/endpoints/users/flashs.ts b/packages/backend/src/server/api/endpoints/users/flashs.ts new file mode 100644 index 0000000000..4e267f9003 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/users/flashs.ts @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { QueryService } from '@/core/QueryService.js'; +import { FlashEntityService } from '@/core/entities/FlashEntityService.js'; +import type { FlashsRepository } from '@/models/index.js'; +import { DI } from '@/di-symbols.js'; + +export const meta = { + tags: ['users', 'flashs'], + + description: 'Show all flashs this user created.', + + res: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + ref: 'Flash', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + userId: { type: 'string', format: 'misskey:id' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + }, + required: ['userId'], +} as const; + +// eslint-disable-next-line import/no-default-export +@Injectable() +export default class extends Endpoint { + constructor( + @Inject(DI.flashsRepository) + private flashsRepository: FlashsRepository, + + private flashEntityService: FlashEntityService, + private queryService: QueryService, + ) { + super(meta, paramDef, async (ps, me) => { + const query = this.queryService.makePaginationQuery(this.flashsRepository.createQueryBuilder('flash'), ps.sinceId, ps.untilId) + .andWhere('flash.userId = :userId', { userId: ps.userId }) + .andWhere('flash.visibility = \'public\''); + + const flashs = await query + .limit(ps.limit) + .getMany(); + + return await this.flashEntityService.packMany(flashs); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts index 18d66500ab..f3b7ec66e9 100644 --- a/packages/backend/src/server/api/endpoints/users/followers.ts +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, FollowingsRepository, UserProfilesRepository } from '@/models/index.js'; @@ -61,9 +66,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts index 6ea7b923d6..43adcad45a 100644 --- a/packages/backend/src/server/api/endpoints/users/following.ts +++ b/packages/backend/src/server/api/endpoints/users/following.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, FollowingsRepository, UserProfilesRepository } from '@/models/index.js'; @@ -61,9 +66,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/users/gallery/posts.ts b/packages/backend/src/server/api/endpoints/users/gallery/posts.ts index 3ee01953d4..f92788c1cc 100644 --- a/packages/backend/src/server/api/endpoints/users/gallery/posts.ts +++ b/packages/backend/src/server/api/endpoints/users/gallery/posts.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { GalleryPostsRepository } from '@/models/index.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.galleryPostsRepository) private galleryPostsRepository: GalleryPostsRepository, diff --git a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts index b4c1e2ec87..30f0059c04 100644 --- a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts +++ b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Not, In, IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import { maximum } from '@/misc/prelude/array.js'; -import type { NotesRepository, UsersRepository } from '@/models/index.js'; +import type { NotesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -53,13 +58,9 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts index beb0ba85ff..fd4fff0e5b 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListsRepository, UserListJoiningsRepository, BlockingsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; -import type { UserList } from '@/models/entities/UserList.js'; +import type { MiUserList } from '@/models/entities/UserList.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GetterService } from '@/server/api/GetterService.js'; import { UserListEntityService } from '@/core/entities/UserListEntityService.js'; @@ -66,7 +71,7 @@ export const paramDef = { } as const; @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userListsRepository) private userListsRepository: UserListsRepository, @@ -103,7 +108,7 @@ export default class extends Endpoint { createdAt: new Date(), userId: me.id, name: ps.name, - } as UserList).then(x => this.userListsRepository.findOneByOrFail(x.identifiers[0])); + } as MiUserList).then(x => this.userListsRepository.findOneByOrFail(x.identifiers[0])); const users = (await this.userListJoiningsRepository.findBy({ userListId: ps.listId, diff --git a/packages/backend/src/server/api/endpoints/users/lists/create.ts b/packages/backend/src/server/api/endpoints/users/lists/create.ts index 7510889526..f8ad88c2ae 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; -import type { UserList } from '@/models/entities/UserList.js'; +import type { MiUserList } from '@/models/entities/UserList.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserListEntityService } from '@/core/entities/UserListEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -42,9 +47,8 @@ export const paramDef = { required: ['name'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userListsRepository) private userListsRepository: UserListsRepository, @@ -66,7 +70,7 @@ export default class extends Endpoint { createdAt: new Date(), userId: me.id, name: ps.name, - } as UserList).then(x => this.userListsRepository.findOneByOrFail(x.identifiers[0])); + } as MiUserList).then(x => this.userListsRepository.findOneByOrFail(x.identifiers[0])); return await this.userListEntityService.pack(userList); }); diff --git a/packages/backend/src/server/api/endpoints/users/lists/delete.ts b/packages/backend/src/server/api/endpoints/users/lists/delete.ts index 237cb075ab..46349eedf2 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/delete.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/delete.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -30,9 +35,8 @@ export const paramDef = { required: ['listId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userListsRepository) private userListsRepository: UserListsRepository, diff --git a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts index 2c09a47fef..0c4a965605 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UserListFavoritesRepository, UserListsRepository } from '@/models/index.js'; diff --git a/packages/backend/src/server/api/endpoints/users/lists/list.ts b/packages/backend/src/server/api/endpoints/users/lists/list.ts index eab29944b2..db481fc2e4 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/list.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/list.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListsRepository, UsersRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; diff --git a/packages/backend/src/server/api/endpoints/users/lists/pull.ts b/packages/backend/src/server/api/endpoints/users/lists/pull.ts index d50b70efc2..8b63a35cf0 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/pull.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/pull.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListsRepository, UserListJoiningsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -42,9 +47,8 @@ export const paramDef = { required: ['listId', 'userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userListsRepository) private userListsRepository: UserListsRepository, diff --git a/packages/backend/src/server/api/endpoints/users/lists/push.ts b/packages/backend/src/server/api/endpoints/users/lists/push.ts index 6e1f6b2c62..f70c15a95b 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/push.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/push.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import ms from 'ms'; import type { UserListsRepository, UserListJoiningsRepository, BlockingsRepository } from '@/models/index.js'; @@ -65,9 +70,8 @@ export const paramDef = { required: ['listId', 'userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userListsRepository) private userListsRepository: UserListsRepository, diff --git a/packages/backend/src/server/api/endpoints/users/lists/show.ts b/packages/backend/src/server/api/endpoints/users/lists/show.ts index 3fd418d04e..cb86e25d92 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/show.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/show.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListsRepository, UserListFavoritesRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; diff --git a/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts b/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts index a7c3b58947..280a062855 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UserListFavoritesRepository, UserListsRepository } from '@/models/index.js'; diff --git a/packages/backend/src/server/api/endpoints/users/lists/update.ts b/packages/backend/src/server/api/endpoints/users/lists/update.ts index b0a95a2f28..e9a022bf3c 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/update.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/update.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -39,9 +44,8 @@ export const paramDef = { required: ['listId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userListsRepository) private userListsRepository: UserListsRepository, diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts index f42f84e6a7..ace50a54f2 100644 --- a/packages/backend/src/server/api/endpoints/users/notes.ts +++ b/packages/backend/src/server/api/endpoints/users/notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { NotesRepository } from '@/models/index.js'; @@ -52,9 +57,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.notesRepository) private notesRepository: NotesRepository, diff --git a/packages/backend/src/server/api/endpoints/users/pages.ts b/packages/backend/src/server/api/endpoints/users/pages.ts index e9d13ba00f..963340e2ea 100644 --- a/packages/backend/src/server/api/endpoints/users/pages.ts +++ b/packages/backend/src/server/api/endpoints/users/pages.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; @@ -32,9 +37,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.pagesRepository) private pagesRepository: PagesRepository, diff --git a/packages/backend/src/server/api/endpoints/users/reactions.ts b/packages/backend/src/server/api/endpoints/users/reactions.ts index 37fc854c33..57f16d11c9 100644 --- a/packages/backend/src/server/api/endpoints/users/reactions.ts +++ b/packages/backend/src/server/api/endpoints/users/reactions.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserProfilesRepository, NoteReactionsRepository } from '@/models/index.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; @@ -45,9 +50,8 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, diff --git a/packages/backend/src/server/api/endpoints/users/recommendation.ts b/packages/backend/src/server/api/endpoints/users/recommendation.ts index eebc5d14d5..d7794ad1af 100644 --- a/packages/backend/src/server/api/endpoints/users/recommendation.ts +++ b/packages/backend/src/server/api/endpoints/users/recommendation.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: [], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, diff --git a/packages/backend/src/server/api/endpoints/users/relation.ts b/packages/backend/src/server/api/endpoints/users/relation.ts index 3267c18846..326042ed3d 100644 --- a/packages/backend/src/server/api/endpoints/users/relation.ts +++ b/packages/backend/src/server/api/endpoints/users/relation.ts @@ -1,8 +1,11 @@ -import { Inject, Injectable } from '@nestjs/common'; -import type { UsersRepository } from '@/models/index.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { DI } from '@/di-symbols.js'; export const meta = { tags: ['users'], @@ -122,13 +125,9 @@ export const paramDef = { required: ['userId'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - private userEntityService: UserEntityService, ) { super(meta, paramDef, async (ps, me) => { diff --git a/packages/backend/src/server/api/endpoints/users/report-abuse.ts b/packages/backend/src/server/api/endpoints/users/report-abuse.ts index be361e02c4..ea77d1796d 100644 --- a/packages/backend/src/server/api/endpoints/users/report-abuse.ts +++ b/packages/backend/src/server/api/endpoints/users/report-abuse.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import sanitizeHtml from 'sanitize-html'; import { Inject, Injectable } from '@nestjs/common'; -import type { UsersRepository, AbuseUserReportsRepository } from '@/models/index.js'; +import type { AbuseUserReportsRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; @@ -48,13 +53,9 @@ export const paramDef = { required: ['userId', 'comment'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.abuseUserReportsRepository) private abuseUserReportsRepository: AbuseUserReportsRepository, diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts index 1d0c7d0c1d..8ab1a122cf 100644 --- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, FollowingsRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -41,9 +46,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.config) private config: Config, @@ -77,7 +81,7 @@ export default class extends Endpoint { const activeThreshold = new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)); // 30日 - let users: User[] = []; + let users: MiUser[] = []; if (me) { const followingQuery = this.followingsRepository.createQueryBuilder('following') diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts index 836218ccd9..5a738a893a 100644 --- a/packages/backend/src/server/api/endpoints/users/search.ts +++ b/packages/backend/src/server/api/endpoints/users/search.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, UserProfilesRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -37,9 +42,8 @@ export const paramDef = { required: ['query'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -55,7 +59,7 @@ export default class extends Endpoint { ps.query = ps.query.trim(); const isUsername = ps.query.startsWith('@'); - let users: User[] = []; + let users: MiUser[] = []; if (isUsername) { const usernameQuery = this.usersRepository.createQueryBuilder('user') diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index 8e25af64fe..4b215ffd10 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { In, IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js'; @@ -74,9 +79,8 @@ export const paramDef = { ], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -106,7 +110,7 @@ export default class extends Endpoint { }); // リクエストされた通りに並べ替え - const _users: User[] = []; + const _users: MiUser[] = []; for (const id of ps.userIds) { _users.push(users.find(x => x.id === id)!); } @@ -122,7 +126,7 @@ export default class extends Endpoint { throw new ApiError(meta.errors.failedToResolveRemoteUser); }); } else { - const q: FindOptionsWhere = ps.userId != null + const q: FindOptionsWhere = ps.userId != null ? { id: ps.userId } : { usernameLower: ps.username!.toLowerCase(), host: IsNull() }; diff --git a/packages/backend/src/server/api/endpoints/users/update-memo.ts b/packages/backend/src/server/api/endpoints/users/update-memo.ts index ca7756ef75..39d02443ad 100644 --- a/packages/backend/src/server/api/endpoints/users/update-memo.ts +++ b/packages/backend/src/server/api/endpoints/users/update-memo.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { IdService } from '@/core/IdService.js'; @@ -35,9 +40,8 @@ export const paramDef = { required: ['userId', 'memo'], } as const; -// eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( @Inject(DI.userMemosRepository) private userMemosRepository: UserMemoRepository, diff --git a/packages/backend/src/server/api/error.ts b/packages/backend/src/server/api/error.ts index 34f4521606..6506565a0d 100644 --- a/packages/backend/src/server/api/error.ts +++ b/packages/backend/src/server/api/error.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + type E = { message: string, code: string, id: string, kind?: 'client' | 'server' | 'permission', httpStatusCode?: number }; export class ApiError extends Error { diff --git a/packages/backend/src/server/api/openapi/OpenApiServerService.ts b/packages/backend/src/server/api/openapi/OpenApiServerService.ts index e804ba276c..cb22d0f7c9 100644 --- a/packages/backend/src/server/api/openapi/OpenApiServerService.ts +++ b/packages/backend/src/server/api/openapi/OpenApiServerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { fileURLToPath } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; import type { Config } from '@/config.js'; diff --git a/packages/backend/src/server/api/openapi/errors.ts b/packages/backend/src/server/api/openapi/errors.ts index d7f791c6da..84c3c638fa 100644 --- a/packages/backend/src/server/api/openapi/errors.ts +++ b/packages/backend/src/server/api/openapi/errors.ts @@ -1,3 +1,7 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ export const errors = { '400': { diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index fa62480c02..4f972d3f7e 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { Config } from '@/config.js'; import endpoints from '../endpoints.js'; import { errors as basicErrors } from './errors.js'; diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts index 0cef361caf..0b9eb4fe24 100644 --- a/packages/backend/src/server/api/openapi/schemas.ts +++ b/packages/backend/src/server/api/openapi/schemas.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { Schema } from '@/misc/json-schema.js'; import { refs } from '@/misc/json-schema.js'; diff --git a/packages/backend/src/server/api/stream/ChannelsService.ts b/packages/backend/src/server/api/stream/ChannelsService.ts index 4a544fadfe..8fd106c10c 100644 --- a/packages/backend/src/server/api/stream/ChannelsService.ts +++ b/packages/backend/src/server/api/stream/ChannelsService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import { HybridTimelineChannelService } from './channels/hybrid-timeline.js'; diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts index 94b92e02ef..93c673838f 100644 --- a/packages/backend/src/server/api/stream/channel.ts +++ b/packages/backend/src/server/api/stream/channel.ts @@ -1,9 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { bindThis } from '@/decorators.js'; import type Connection from './index.js'; /** * Stream channel */ +// eslint-disable-next-line import/no-default-export export default abstract class Channel { protected connection: Connection; public id: string; diff --git a/packages/backend/src/server/api/stream/channels/admin.ts b/packages/backend/src/server/api/stream/channels/admin.ts index 157fcd6aa3..bfb36d9cb8 100644 --- a/packages/backend/src/server/api/stream/channels/admin.ts +++ b/packages/backend/src/server/api/stream/channels/admin.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import Channel from '../channel.js'; diff --git a/packages/backend/src/server/api/stream/channels/antenna.ts b/packages/backend/src/server/api/stream/channels/antenna.ts index d48dea7258..87648a3a77 100644 --- a/packages/backend/src/server/api/stream/channels/antenna.ts +++ b/packages/backend/src/server/api/stream/channels/antenna.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { isUserRelated } from '@/misc/is-user-related.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts index 9e5b40997b..a01714e76d 100644 --- a/packages/backend/src/server/api/stream/channels/channel.ts +++ b/packages/backend/src/server/api/stream/channels/channel.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { isUserRelated } from '@/misc/is-user-related.js'; import type { Packed } from '@/misc/json-schema.js'; diff --git a/packages/backend/src/server/api/stream/channels/drive.ts b/packages/backend/src/server/api/stream/channels/drive.ts index 52bb29fabe..83f53c1836 100644 --- a/packages/backend/src/server/api/stream/channels/drive.ts +++ b/packages/backend/src/server/api/stream/channels/drive.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; import Channel from '../channel.js'; diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index d3339072c1..a33f1a956a 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { checkWordMute } from '@/misc/check-word-mute.js'; import { isInstanceMuted } from '@/misc/is-instance-muted.js'; diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts index 94ebf86418..3945b1a1eb 100644 --- a/packages/backend/src/server/api/stream/channels/hashtag.ts +++ b/packages/backend/src/server/api/stream/channels/hashtag.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import { isUserRelated } from '@/misc/is-user-related.js'; diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index fe0cc37b6b..bd8888f679 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { checkWordMute } from '@/misc/check-word-mute.js'; import { isUserRelated } from '@/misc/is-user-related.js'; diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index 5a33e13cf5..760fb8d19f 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { checkWordMute } from '@/misc/check-word-mute.js'; import { isUserRelated } from '@/misc/is-user-related.js'; diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts index 9ca4db8ced..f32f8c5cec 100644 --- a/packages/backend/src/server/api/stream/channels/local-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { checkWordMute } from '@/misc/check-word-mute.js'; import { isUserRelated } from '@/misc/is-user-related.js'; diff --git a/packages/backend/src/server/api/stream/channels/main.ts b/packages/backend/src/server/api/stream/channels/main.ts index 139320ce35..f969d02337 100644 --- a/packages/backend/src/server/api/stream/channels/main.ts +++ b/packages/backend/src/server/api/stream/channels/main.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { isInstanceMuted, isUserFromMutedInstance } from '@/misc/is-instance-muted.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; diff --git a/packages/backend/src/server/api/stream/channels/queue-stats.ts b/packages/backend/src/server/api/stream/channels/queue-stats.ts index 7f48c54999..f0dc472303 100644 --- a/packages/backend/src/server/api/stream/channels/queue-stats.ts +++ b/packages/backend/src/server/api/stream/channels/queue-stats.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Xev from 'xev'; import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; diff --git a/packages/backend/src/server/api/stream/channels/role-timeline.ts b/packages/backend/src/server/api/stream/channels/role-timeline.ts index 6218fada97..76b5875343 100644 --- a/packages/backend/src/server/api/stream/channels/role-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/role-timeline.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import { isUserRelated } from '@/misc/is-user-related.js'; import type { Packed } from '@/misc/json-schema.js'; diff --git a/packages/backend/src/server/api/stream/channels/server-stats.ts b/packages/backend/src/server/api/stream/channels/server-stats.ts index 9eae0cf2d3..cacae275a8 100644 --- a/packages/backend/src/server/api/stream/channels/server-stats.ts +++ b/packages/backend/src/server/api/stream/channels/server-stats.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Xev from 'xev'; import { Injectable } from '@nestjs/common'; import { bindThis } from '@/decorators.js'; diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index ea4cff0bc0..557b934722 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -1,6 +1,11 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import type { UserListJoiningsRepository, UserListsRepository } from '@/models/index.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { isUserRelated } from '@/misc/is-user-related.js'; import type { Packed } from '@/misc/json-schema.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; @@ -13,7 +18,7 @@ class UserListChannel extends Channel { public static shouldShare = false; public static requireCredential = false; private listId: string; - public listUsers: User['id'][] = []; + public listUsers: MiUser['id'][] = []; private listUsersClock: NodeJS.Timer; constructor( diff --git a/packages/backend/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts index 8b1c2c09c9..181aa5e2a3 100644 --- a/packages/backend/src/server/api/stream/index.ts +++ b/packages/backend/src/server/api/stream/index.ts @@ -1,12 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as WebSocket from 'ws'; -import type { User } from '@/models/entities/User.js'; -import type { AccessToken } from '@/models/entities/AccessToken.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiAccessToken } from '@/models/entities/AccessToken.js'; import type { Packed } from '@/misc/json-schema.js'; import type { NoteReadService } from '@/core/NoteReadService.js'; import type { NotificationService } from '@/core/NotificationService.js'; import { bindThis } from '@/decorators.js'; import { CacheService } from '@/core/CacheService.js'; -import { UserProfile } from '@/models/index.js'; +import { MiUserProfile } from '@/models/index.js'; import type { ChannelsService } from './ChannelsService.js'; import type { EventEmitter } from 'events'; import type Channel from './channel.js'; @@ -15,15 +20,16 @@ import type { StreamEventEmitter, StreamMessages } from './types.js'; /** * Main stream connection */ +// eslint-disable-next-line import/no-default-export export default class Connection { - public user?: User; - public token?: AccessToken; + public user?: MiUser; + public token?: MiAccessToken; private wsConnection: WebSocket.WebSocket; public subscriber: StreamEventEmitter; private channels: Channel[] = []; private subscribingNotes: any = {}; private cachedNotes: Packed<'Note'>[] = []; - public userProfile: UserProfile | null = null; + public userProfile: MiUserProfile | null = null; public following: Set = new Set(); public followingChannels: Set = new Set(); public userIdsWhoMeMuting: Set = new Set(); @@ -37,8 +43,8 @@ export default class Connection { private notificationService: NotificationService, private cacheService: CacheService, - user: User | null | undefined, - token: AccessToken | null | undefined, + user: MiUser | null | undefined, + token: MiAccessToken | null | undefined, ) { if (user) this.user = user; if (token) this.token = token; diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index f239b06637..531c00bdf6 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -1,48 +1,53 @@ -import type { Channel } from '@/models/entities/Channel.js'; -import type { User } from '@/models/entities/User.js'; -import type { UserProfile } from '@/models/entities/UserProfile.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { Antenna } from '@/models/entities/Antenna.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { DriveFolder } from '@/models/entities/DriveFolder.js'; -import type { UserList } from '@/models/entities/UserList.js'; -import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js'; -import type { Signin } from '@/models/entities/Signin.js'; -import type { Page } from '@/models/entities/Page.js'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import type { MiChannel } from '@/models/entities/Channel.js'; +import type { MiUser } from '@/models/entities/User.js'; +import type { MiUserProfile } from '@/models/entities/UserProfile.js'; +import type { MiNote } from '@/models/entities/Note.js'; +import type { MiAntenna } from '@/models/entities/Antenna.js'; +import type { MiDriveFile } from '@/models/entities/DriveFile.js'; +import type { MiDriveFolder } from '@/models/entities/DriveFolder.js'; +import type { MiUserList } from '@/models/entities/UserList.js'; +import type { MiAbuseUserReport } from '@/models/entities/AbuseUserReport.js'; +import type { MiSignin } from '@/models/entities/Signin.js'; +import type { MiPage } from '@/models/entities/Page.js'; import type { Packed } from '@/misc/json-schema.js'; -import type { Webhook } from '@/models/entities/Webhook.js'; -import type { Meta } from '@/models/entities/Meta.js'; -import { Role, RoleAssignment } from '@/models/index.js'; +import type { MiWebhook } from '@/models/entities/Webhook.js'; +import type { MiMeta } from '@/models/entities/Meta.js'; +import { MiRole, MiRoleAssignment } from '@/models/index.js'; import type Emitter from 'strict-event-emitter-types'; import type { EventEmitter } from 'events'; //#region Stream type-body definitions export interface InternalStreamTypes { - userChangeSuspendedState: { id: User['id']; isSuspended: User['isSuspended']; }; - userTokenRegenerated: { id: User['id']; oldToken: string; newToken: string; }; - remoteUserUpdated: { id: User['id']; }; - follow: { followerId: User['id']; followeeId: User['id']; }; - unfollow: { followerId: User['id']; followeeId: User['id']; }; - blockingCreated: { blockerId: User['id']; blockeeId: User['id']; }; - blockingDeleted: { blockerId: User['id']; blockeeId: User['id']; }; - policiesUpdated: Role['policies']; - roleCreated: Role; - roleDeleted: Role; - roleUpdated: Role; - userRoleAssigned: RoleAssignment; - userRoleUnassigned: RoleAssignment; - webhookCreated: Webhook; - webhookDeleted: Webhook; - webhookUpdated: Webhook; - antennaCreated: Antenna; - antennaDeleted: Antenna; - antennaUpdated: Antenna; - metaUpdated: Meta; - followChannel: { userId: User['id']; channelId: Channel['id']; }; - unfollowChannel: { userId: User['id']; channelId: Channel['id']; }; - updateUserProfile: UserProfile; - mute: { muterId: User['id']; muteeId: User['id']; }; - unmute: { muterId: User['id']; muteeId: User['id']; }; + userChangeSuspendedState: { id: MiUser['id']; isSuspended: MiUser['isSuspended']; }; + userTokenRegenerated: { id: MiUser['id']; oldToken: string; newToken: string; }; + remoteUserUpdated: { id: MiUser['id']; }; + follow: { followerId: MiUser['id']; followeeId: MiUser['id']; }; + unfollow: { followerId: MiUser['id']; followeeId: MiUser['id']; }; + blockingCreated: { blockerId: MiUser['id']; blockeeId: MiUser['id']; }; + blockingDeleted: { blockerId: MiUser['id']; blockeeId: MiUser['id']; }; + policiesUpdated: MiRole['policies']; + roleCreated: MiRole; + roleDeleted: MiRole; + roleUpdated: MiRole; + userRoleAssigned: MiRoleAssignment; + userRoleUnassigned: MiRoleAssignment; + webhookCreated: MiWebhook; + webhookDeleted: MiWebhook; + webhookUpdated: MiWebhook; + antennaCreated: MiAntenna; + antennaDeleted: MiAntenna; + antennaUpdated: MiAntenna; + metaUpdated: MiMeta; + followChannel: { userId: MiUser['id']; channelId: MiChannel['id']; }; + unfollowChannel: { userId: MiUser['id']; channelId: MiChannel['id']; }; + updateUserProfile: MiUserProfile; + mute: { muterId: MiUser['id']; muteeId: MiUser['id']; }; + unmute: { muterId: MiUser['id']; muteeId: MiUser['id']; }; } export interface BroadcastTypes { @@ -59,6 +64,9 @@ export interface BroadcastTypes { [other: string]: any; }[]; }; + announcementCreated: { + announcement: Packed<'Announcement'>; + }; } export interface MainStreamTypes { @@ -71,10 +79,10 @@ export interface MainStreamTypes { unfollow: Packed<'User'>; meUpdated: Packed<'User'>; pageEvent: { - pageId: Page['id']; + pageId: MiPage['id']; event: string; var: any; - userId: User['id']; + userId: MiUser['id']; user: Packed<'User'>; }; urlUploadFinished: { @@ -83,38 +91,41 @@ export interface MainStreamTypes { }; readAllNotifications: undefined; unreadNotification: Packed<'Notification'>; - unreadMention: Note['id']; + unreadMention: MiNote['id']; readAllUnreadMentions: undefined; - unreadSpecifiedNote: Note['id']; + unreadSpecifiedNote: MiNote['id']; readAllUnreadSpecifiedNotes: undefined; readAllAntennas: undefined; - unreadAntenna: Antenna; + unreadAntenna: MiAntenna; readAllAnnouncements: undefined; myTokenRegenerated: undefined; - signin: Signin; + signin: MiSignin; registryUpdated: { scope?: string[]; key: string; value: any | null; }; driveFileCreated: Packed<'DriveFile'>; - readAntenna: Antenna; + readAntenna: MiAntenna; receiveFollowRequest: Packed<'User'>; + announcementCreated: { + announcement: Packed<'Announcement'>; + }; } export interface DriveStreamTypes { fileCreated: Packed<'DriveFile'>; - fileDeleted: DriveFile['id']; + fileDeleted: MiDriveFile['id']; fileUpdated: Packed<'DriveFile'>; folderCreated: Packed<'DriveFolder'>; - folderDeleted: DriveFolder['id']; + folderDeleted: MiDriveFolder['id']; folderUpdated: Packed<'DriveFolder'>; } export interface NoteStreamTypes { pollVoted: { choice: number; - userId: User['id']; + userId: MiUser['id']; }; deleted: { deletedAt: Date; @@ -125,16 +136,16 @@ export interface NoteStreamTypes { name: string; url: string; } | null; - userId: User['id']; + userId: MiUser['id']; }; unreacted: { reaction: string; - userId: User['id']; + userId: MiUser['id']; }; } type NoteStreamEventTypes = { [key in keyof NoteStreamTypes]: { - id: Note['id']; + id: MiNote['id']; body: NoteStreamTypes[key]; }; }; @@ -145,7 +156,7 @@ export interface UserListStreamTypes { } export interface AntennaStreamTypes { - note: Note; + note: MiNote; } export interface RoleTimelineStreamTypes { @@ -154,9 +165,9 @@ export interface RoleTimelineStreamTypes { export interface AdminStreamTypes { newAbuseUserReport: { - id: AbuseUserReport['id']; - targetUserId: User['id'], - reporterId: User['id'], + id: MiAbuseUserReport['id']; + targetUserId: MiUser['id'], + reporterId: MiUser['id'], comment: string; }; } @@ -198,31 +209,31 @@ export type StreamMessages = { payload: EventUnionFromDictionary>; }; main: { - name: `mainStream:${User['id']}`; + name: `mainStream:${MiUser['id']}`; payload: EventUnionFromDictionary>; }; drive: { - name: `driveStream:${User['id']}`; + name: `driveStream:${MiUser['id']}`; payload: EventUnionFromDictionary>; }; note: { - name: `noteStream:${Note['id']}`; + name: `noteStream:${MiNote['id']}`; payload: EventUnionFromDictionary>; }; userList: { - name: `userListStream:${UserList['id']}`; + name: `userListStream:${MiUserList['id']}`; payload: EventUnionFromDictionary>; }; roleTimeline: { - name: `roleTimelineStream:${Role['id']}`; + name: `roleTimelineStream:${MiRole['id']}`; payload: EventUnionFromDictionary>; }; antenna: { - name: `antennaStream:${Antenna['id']}`; + name: `antennaStream:${MiAntenna['id']}`; payload: EventUnionFromDictionary>; }; admin: { - name: `adminStream:${User['id']}`; + name: `adminStream:${MiUser['id']}`; payload: EventUnionFromDictionary>; }; notes: { diff --git a/packages/backend/src/server/oauth/OAuth2ProviderService.ts b/packages/backend/src/server/oauth/OAuth2ProviderService.ts new file mode 100644 index 0000000000..6ad8da0ced --- /dev/null +++ b/packages/backend/src/server/oauth/OAuth2ProviderService.ts @@ -0,0 +1,487 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import dns from 'node:dns/promises'; +import { fileURLToPath } from 'node:url'; +import { Inject, Injectable } from '@nestjs/common'; +import { JSDOM } from 'jsdom'; +import httpLinkHeader from 'http-link-header'; +import ipaddr from 'ipaddr.js'; +import oauth2orize, { type OAuth2, AuthorizationError, ValidateFunctionArity2, OAuth2Req, MiddlewareRequest } from 'oauth2orize'; +import oauth2Pkce from 'oauth2orize-pkce'; +import fastifyView from '@fastify/view'; +import pug from 'pug'; +import bodyParser from 'body-parser'; +import fastifyExpress from '@fastify/express'; +import { verifyChallenge } from 'pkce-challenge'; +import { mf2 } from 'microformats-parser'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; +import { HttpRequestService } from '@/core/HttpRequestService.js'; +import { kinds } from '@/misc/api-permissions.js'; +import type { Config } from '@/config.js'; +import { DI } from '@/di-symbols.js'; +import { bindThis } from '@/decorators.js'; +import type { AccessTokensRepository, UsersRepository } from '@/models/index.js'; +import { IdService } from '@/core/IdService.js'; +import { CacheService } from '@/core/CacheService.js'; +import type { MiLocalUser } from '@/models/entities/User.js'; +import { MemoryKVCache } from '@/misc/cache.js'; +import { LoggerService } from '@/core/LoggerService.js'; +import Logger from '@/logger.js'; +import { StatusError } from '@/misc/status-error.js'; +import type { ServerResponse } from 'node:http'; +import type { FastifyInstance } from 'fastify'; + +// TODO: Consider migrating to @node-oauth/oauth2-server once +// https://github.com/node-oauth/node-oauth2-server/issues/180 is figured out. +// Upstream the various validations and RFC9207 implementation in that case. + +// Follows https://indieauth.spec.indieweb.org/#client-identifier +// This is also mostly similar to https://developers.google.com/identity/protocols/oauth2/web-server#uri-validation +// although Google has stricter rule. +function validateClientId(raw: string): URL { + // "Clients are identified by a [URL]." + const url = ((): URL => { + try { + return new URL(raw); + } catch { throw new AuthorizationError('client_id must be a valid URL', 'invalid_request'); } + })(); + + // "Client identifier URLs MUST have either an https or http scheme" + // But then again: + // https://datatracker.ietf.org/doc/html/rfc6749.html#section-3.1.2.1 + // 'The redirection endpoint SHOULD require the use of TLS as described + // in Section 1.6 when the requested response type is "code" or "token"' + const allowedProtocols = process.env.NODE_ENV === 'test' ? ['http:', 'https:'] : ['https:']; + if (!allowedProtocols.includes(url.protocol)) { + throw new AuthorizationError('client_id must be a valid HTTPS URL', 'invalid_request'); + } + + // "MUST contain a path component (new URL() implicitly adds one)" + + // "MUST NOT contain single-dot or double-dot path segments," + const segments = url.pathname.split('/'); + if (segments.includes('.') || segments.includes('..')) { + throw new AuthorizationError('client_id must not contain dot path segments', 'invalid_request'); + } + + // ("MAY contain a query string component") + + // "MUST NOT contain a fragment component" + if (url.hash) { + throw new AuthorizationError('client_id must not contain a fragment component', 'invalid_request'); + } + + // "MUST NOT contain a username or password component" + if (url.username || url.password) { + throw new AuthorizationError('client_id must not contain a username or a password', 'invalid_request'); + } + + // ("MAY contain a port") + + // "host names MUST be domain names or a loopback interface and MUST NOT be + // IPv4 or IPv6 addresses except for IPv4 127.0.0.1 or IPv6 [::1]." + if (!url.hostname.match(/\.\w+$/) && !['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)) { + throw new AuthorizationError('client_id must have a domain name as a host name', 'invalid_request'); + } + + return url; +} + +interface ClientInformation { + id: string; + redirectUris: string[]; + name: string; +} + +// https://indieauth.spec.indieweb.org/#client-information-discovery +// "Authorization servers SHOULD support parsing the [h-app] Microformat from the client_id, +// and if there is an [h-app] with a url property matching the client_id URL, +// then it should use the name and icon and display them on the authorization prompt." +// (But we don't display any icon for now) +// https://indieauth.spec.indieweb.org/#redirect-url +// "The client SHOULD publish one or more tags or Link HTTP headers with a rel attribute +// of redirect_uri at the client_id URL. +// Authorization endpoints verifying that a redirect_uri is allowed for use by a client MUST +// look for an exact match of the given redirect_uri in the request against the list of +// redirect_uris discovered after resolving any relative URLs." +async function discoverClientInformation(logger: Logger, httpRequestService: HttpRequestService, id: string): Promise { + try { + const res = await httpRequestService.send(id); + const redirectUris: string[] = []; + + const linkHeader = res.headers.get('link'); + if (linkHeader) { + redirectUris.push(...httpLinkHeader.parse(linkHeader).get('rel', 'redirect_uri').map(r => r.uri)); + } + + const text = await res.text(); + const fragment = JSDOM.fragment(text); + + redirectUris.push(...[...fragment.querySelectorAll('link[rel=redirect_uri][href]')].map(el => el.href)); + + let name = id; + if (text) { + const microformats = mf2(text, { baseUrl: res.url }); + const nameProperty = microformats.items.find(item => item.type?.includes('h-app') && item.properties.url?.includes(id))?.properties.name[0]; + if (typeof nameProperty === 'string') { + name = nameProperty; + } + } + + return { + id, + redirectUris: redirectUris.map(uri => new URL(uri, res.url).toString()), + name: typeof name === 'string' ? name : id, + }; + } catch (err) { + console.error(err); + logger.error('Error while fetching client information', { err }); + if (err instanceof StatusError) { + throw new AuthorizationError('Failed to fetch client information', 'invalid_request'); + } else { + throw new AuthorizationError('Failed to parse client information', 'server_error'); + } + } +} + +type OmitFirstElement = T extends [unknown, ...(infer R)] + ? R + : []; + +interface OAuthParsedRequest extends OAuth2Req { + codeChallenge: string; + codeChallengeMethod: string; +} + +interface OAuthHttpResponse extends ServerResponse { + redirect(location: string): void; +} + +interface OAuth2DecisionRequest extends MiddlewareRequest { + body: { + transaction_id: string; + cancel: boolean; + login_token: string; + } +} + +function getQueryMode(issuerUrl: string): oauth2orize.grant.Options['modes'] { + return { + query: (txn, res, params): void => { + // https://datatracker.ietf.org/doc/html/rfc9207#name-response-parameter-iss + // "In authorization responses to the client, including error responses, + // an authorization server supporting this specification MUST indicate its + // identity by including the iss parameter in the response." + params.iss = issuerUrl; + + const parsed = new URL(txn.redirectURI); + for (const [key, value] of Object.entries(params)) { + parsed.searchParams.append(key, value as string); + } + + return (res as OAuthHttpResponse).redirect(parsed.toString()); + }, + }; +} + +/** + * Maps the transaction ID and the oauth/authorize parameters. + * + * Flow: + * 1. oauth/authorize endpoint will call store() to store the parameters + * and puts the generated transaction ID to the dialog page + * 2. oauth/decision will call load() to retrieve the parameters and then remove() + */ +class OAuth2Store { + #cache = new MemoryKVCache(1000 * 60 * 5); // expires after 5min + + load(req: OAuth2DecisionRequest, cb: (err: Error | null, txn?: OAuth2) => void): void { + const { transaction_id } = req.body; + if (!transaction_id) { + cb(new AuthorizationError('Missing transaction ID', 'invalid_request')); + return; + } + const loaded = this.#cache.get(transaction_id); + if (!loaded) { + cb(new AuthorizationError('Invalid or expired transaction ID', 'access_denied')); + return; + } + cb(null, loaded); + } + + store(req: OAuth2DecisionRequest, oauth2: OAuth2, cb: (err: Error | null, transactionID?: string) => void): void { + const transactionId = secureRndstr(128); + this.#cache.set(transactionId, oauth2); + cb(null, transactionId); + } + + remove(req: OAuth2DecisionRequest, tid: string, cb: () => void): void { + this.#cache.delete(tid); + cb(); + } +} + +@Injectable() +export class OAuth2ProviderService { + #server = oauth2orize.createServer({ + store: new OAuth2Store(), + }); + #logger: Logger; + + constructor( + @Inject(DI.config) + private config: Config, + private httpRequestService: HttpRequestService, + @Inject(DI.accessTokensRepository) + accessTokensRepository: AccessTokensRepository, + idService: IdService, + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + private cacheService: CacheService, + loggerService: LoggerService, + ) { + this.#logger = loggerService.getLogger('oauth'); + + const grantCodeCache = new MemoryKVCache<{ + clientId: string, + userId: string, + redirectUri: string, + codeChallenge: string, + scopes: string[], + + // fields to prevent multiple code use + grantedToken?: string, + revoked?: boolean, + used?: boolean, + }>(1000 * 60 * 5); // expires after 5m + + // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics + // "Authorization servers MUST support PKCE [RFC7636]." + this.#server.grant(oauth2Pkce.extensions()); + this.#server.grant(oauth2orize.grant.code({ + modes: getQueryMode(config.url), + }, (client, redirectUri, token, ares, areq, locals, done) => { + (async (): Promise>> => { + this.#logger.info(`Checking the user before sending authorization code to ${client.id}`); + + if (!token) { + throw new AuthorizationError('No user', 'invalid_request'); + } + const user = await this.cacheService.localUserByNativeTokenCache.fetch(token, + () => this.usersRepository.findOneBy({ token }) as Promise); + if (!user) { + throw new AuthorizationError('No such user', 'invalid_request'); + } + + this.#logger.info(`Sending authorization code on behalf of user ${user.id} to ${client.id} through ${redirectUri}, with scope: [${areq.scope}]`); + + const code = secureRndstr(128); + grantCodeCache.set(code, { + clientId: client.id, + userId: user.id, + redirectUri, + codeChallenge: (areq as OAuthParsedRequest).codeChallenge, + scopes: areq.scope, + }); + return [code]; + })().then(args => done(null, ...args), err => done(err)); + })); + this.#server.exchange(oauth2orize.exchange.authorizationCode((client, code, redirectUri, body, authInfo, done) => { + (async (): Promise> | undefined> => { + this.#logger.info('Checking the received authorization code for the exchange'); + const granted = grantCodeCache.get(code); + if (!granted) { + return; + } + + // https://datatracker.ietf.org/doc/html/rfc6749.html#section-4.1.2 + // "If an authorization code is used more than once, the authorization server + // MUST deny the request and SHOULD revoke (when possible) all tokens + // previously issued based on that authorization code." + if (granted.used) { + this.#logger.info(`Detected multiple code use from ${granted.clientId} for user ${granted.userId}. Revoking the code.`); + grantCodeCache.delete(code); + granted.revoked = true; + if (granted.grantedToken) { + await accessTokensRepository.delete({ token: granted.grantedToken }); + } + return; + } + granted.used = true; + + // https://datatracker.ietf.org/doc/html/rfc6749.html#section-4.1.3 + if (body.client_id !== granted.clientId) return; + if (redirectUri !== granted.redirectUri) return; + + // https://datatracker.ietf.org/doc/html/rfc7636.html#section-4.6 + if (!body.code_verifier) return; + if (!(await verifyChallenge(body.code_verifier as string, granted.codeChallenge))) return; + + const accessToken = secureRndstr(128); + const now = new Date(); + + // NOTE: we don't have a setup for automatic token expiration + await accessTokensRepository.insert({ + id: idService.genId(), + createdAt: now, + lastUsedAt: now, + userId: granted.userId, + token: accessToken, + hash: accessToken, + name: granted.clientId, + permission: granted.scopes, + }); + + if (granted.revoked) { + this.#logger.info('Canceling the token as the authorization code was revoked in parallel during the process.'); + await accessTokensRepository.delete({ token: accessToken }); + return; + } + + granted.grantedToken = accessToken; + this.#logger.info(`Generated access token for ${granted.clientId} for user ${granted.userId}, with scope: [${granted.scopes}]`); + + return [accessToken, undefined, { scope: granted.scopes.join(' ') }]; + })().then(args => done(null, ...args ?? []), err => done(err)); + })); + } + + @bindThis + public async createServer(fastify: FastifyInstance): Promise { + // https://datatracker.ietf.org/doc/html/rfc8414.html + // https://indieauth.spec.indieweb.org/#indieauth-server-metadata + fastify.get('/.well-known/oauth-authorization-server', async (_request, reply) => { + reply.send({ + issuer: this.config.url, + authorization_endpoint: new URL('/oauth/authorize', this.config.url), + token_endpoint: new URL('/oauth/token', this.config.url), + scopes_supported: kinds, + response_types_supported: ['code'], + grant_types_supported: ['authorization_code'], + service_documentation: 'https://misskey-hub.net', + code_challenge_methods_supported: ['S256'], + authorization_response_iss_parameter_supported: true, + }); + }); + + fastify.get('/oauth/authorize', async (request, reply) => { + const oauth2 = (request.raw as MiddlewareRequest).oauth2; + if (!oauth2) { + throw new Error('Unexpected lack of authorization information'); + } + + this.#logger.info(`Rendering authorization page for "${oauth2.client.name}"`); + + reply.header('Cache-Control', 'no-store'); + return await reply.view('oauth', { + transactionId: oauth2.transactionID, + clientName: oauth2.client.name, + scope: oauth2.req.scope.join(' '), + }); + }); + fastify.post('/oauth/decision', async () => { }); + fastify.post('/oauth/token', async () => { }); + + fastify.register(fastifyView, { + root: fileURLToPath(new URL('../web/views', import.meta.url)), + engine: { pug }, + defaultContext: { + version: this.config.version, + config: this.config, + }, + }); + + await fastify.register(fastifyExpress); + fastify.use('/oauth/authorize', this.#server.authorize(((areq, done) => { + (async (): Promise> => { + // This should return client/redirectURI AND the error, or + // the handler can't send error to the redirection URI + + const { codeChallenge, codeChallengeMethod, clientID, redirectURI, scope } = areq as OAuthParsedRequest; + + this.#logger.info(`Validating authorization parameters, with client_id: ${clientID}, redirect_uri: ${redirectURI}, scope: ${scope}`); + + const clientUrl = validateClientId(clientID); + + // https://indieauth.spec.indieweb.org/#client-information-discovery + // "the server may want to resolve the domain name first and avoid fetching the document + // if the IP address is within the loopback range defined by [RFC5735] + // or any other implementation-specific internal IP address." + if (process.env.NODE_ENV !== 'test' || process.env.MISSKEY_TEST_CHECK_IP_RANGE === '1') { + const lookup = await dns.lookup(clientUrl.hostname); + if (ipaddr.parse(lookup.address).range() !== 'unicast') { + throw new AuthorizationError('client_id resolves to disallowed IP range.', 'invalid_request'); + } + } + + // Find client information from the remote. + const clientInfo = await discoverClientInformation(this.#logger, this.httpRequestService, clientUrl.href); + + // Require the redirect URI to be included in an explicit list, per + // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.1.3 + if (!clientInfo.redirectUris.includes(redirectURI)) { + throw new AuthorizationError('Invalid redirect_uri', 'invalid_request'); + } + + try { + const scopes = [...new Set(scope)].filter(s => kinds.includes(s)); + if (!scopes.length) { + throw new AuthorizationError('`scope` parameter has no known scope', 'invalid_scope'); + } + areq.scope = scopes; + + // Require PKCE parameters. + // Recommended by https://indieauth.spec.indieweb.org/#authorization-request, but also prevents downgrade attack: + // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-pkce-downgrade-attack + if (typeof codeChallenge !== 'string') { + throw new AuthorizationError('`code_challenge` parameter is required', 'invalid_request'); + } + if (codeChallengeMethod !== 'S256') { + throw new AuthorizationError('`code_challenge_method` parameter must be set as S256', 'invalid_request'); + } + } catch (err) { + return [err as Error, clientInfo, redirectURI]; + } + + return [null, clientInfo, redirectURI]; + })().then(args => done(...args), err => done(err)); + }) as ValidateFunctionArity2)); + fastify.use('/oauth/authorize', this.#server.errorHandler({ + mode: 'indirect', + modes: getQueryMode(this.config.url), + })); + fastify.use('/oauth/authorize', this.#server.errorHandler()); + + fastify.use('/oauth/decision', bodyParser.urlencoded({ extended: false })); + fastify.use('/oauth/decision', this.#server.decision((req, done) => { + const { body } = req as OAuth2DecisionRequest; + this.#logger.info(`Received the decision. Cancel: ${!!body.cancel}`); + req.user = body.login_token; + done(null, undefined); + })); + fastify.use('/oauth/decision', this.#server.errorHandler()); + + // Clients may use JSON or urlencoded + fastify.use('/oauth/token', bodyParser.urlencoded({ extended: false })); + fastify.use('/oauth/token', bodyParser.json({ strict: true })); + fastify.use('/oauth/token', this.#server.token()); + fastify.use('/oauth/token', this.#server.errorHandler()); + + // Return 404 for any unknown paths under /oauth so that clients can know + // whether a certain endpoint is supported or not. + fastify.all('/oauth/*', async (_request, reply) => { + reply.code(404); + reply.send({ + error: { + message: 'Unknown OAuth endpoint.', + code: 'UNKNOWN_OAUTH_ENDPOINT', + id: 'aa49e620-26cb-4e28-aad6-8cbcb58db147', + kind: 'client', + }, + }); + }); + } +} diff --git a/packages/backend/src/server/web/ClientLoggerService.ts b/packages/backend/src/server/web/ClientLoggerService.ts index 6a882aa766..213266f59c 100644 --- a/packages/backend/src/server/web/ClientLoggerService.ts +++ b/packages/backend/src/server/web/ClientLoggerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Injectable } from '@nestjs/common'; import type Logger from '@/logger.js'; import { LoggerService } from '@/core/LoggerService.js'; diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index 363cca8feb..56aa343632 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { randomUUID } from 'node:crypto'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -26,7 +31,7 @@ import { PageEntityService } from '@/core/entities/PageEntityService.js'; import { GalleryPostEntityService } from '@/core/entities/GalleryPostEntityService.js'; import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; import { ChannelEntityService } from '@/core/entities/ChannelEntityService.js'; -import type { ChannelsRepository, ClipsRepository, FlashsRepository, GalleryPostsRepository, Meta, NotesRepository, PagesRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js'; +import type { ChannelsRepository, ClipsRepository, FlashsRepository, GalleryPostsRepository, MiMeta, NotesRepository, PagesRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js'; import type Logger from '@/logger.js'; import { deepClone } from '@/misc/clone.js'; import { bindThis } from '@/decorators.js'; @@ -118,7 +123,7 @@ export class ClientServerService { } @bindThis - private generateCommonPugData(meta: Meta) { + private generateCommonPugData(meta: MiMeta) { return { instanceName: meta.name ?? 'Misskey', icon: meta.iconUrl, @@ -138,21 +143,23 @@ export class ClientServerService { // Authenticate fastify.addHook('onRequest', async (request, reply) => { - if (request.url === bullBoardPath || request.url.startsWith(bullBoardPath + '/')) { + // %71ueueとかでリクエストされたら困るため + const url = decodeURI(request.url); + if (url === bullBoardPath || url.startsWith(bullBoardPath + '/')) { const token = request.cookies.token; if (token == null) { - reply.code(401); - throw new Error('login required'); + reply.code(401).send('Login required'); + return; } const user = await this.usersRepository.findOneBy({ token }); if (user == null) { - reply.code(403); - throw new Error('no such user'); + reply.code(403).send('No such user'); + return; } const isAdministrator = await this.roleService.isAdministrator(user); if (!isAdministrator) { - reply.code(403); - throw new Error('access denied'); + reply.code(403).send('Access denied'); + return; } } }); @@ -677,7 +684,7 @@ export class ClientServerService { fastify.setErrorHandler(async (error, request, reply) => { const errId = randomUUID(); - this.clientLoggerService.logger.error(`Internal error occured in ${request.routerPath}: ${error.message}`, { + this.clientLoggerService.logger.error(`Internal error occurred in ${request.routerPath}: ${error.message}`, { path: request.routerPath, params: request.params, query: request.query, diff --git a/packages/backend/src/server/web/FeedService.ts b/packages/backend/src/server/web/FeedService.ts index 0bd0d3c692..27e8431839 100644 --- a/packages/backend/src/server/web/FeedService.ts +++ b/packages/backend/src/server/web/FeedService.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { In, IsNull } from 'typeorm'; import { Feed } from 'feed'; import { DI } from '@/di-symbols.js'; -import type { DriveFilesRepository, NotesRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js'; +import type { DriveFilesRepository, NotesRepository, UserProfilesRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; -import type { User } from '@/models/entities/User.js'; +import type { MiUser } from '@/models/entities/User.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import { bindThis } from '@/decorators.js'; @@ -15,9 +20,6 @@ export class FeedService { @Inject(DI.config) private config: Config, - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.userProfilesRepository) private userProfilesRepository: UserProfilesRepository, @@ -33,7 +35,7 @@ export class FeedService { } @bindThis - public async packFeed(user: User) { + public async packFeed(user: MiUser) { const author = { link: `${this.config.url}/@${user.username}`, name: user.name ?? user.username, diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index e61e92c623..d590244e34 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { Inject, Injectable } from '@nestjs/common'; import { summaly } from 'summaly'; import { DI } from '@/di-symbols.js'; diff --git a/packages/backend/src/server/web/bios.css b/packages/backend/src/server/web/bios.css index b0da3ee39b..c934a55fa9 100644 --- a/packages/backend/src/server/web/bios.css +++ b/packages/backend/src/server/web/bios.css @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + * { font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace; } diff --git a/packages/backend/src/server/web/bios.js b/packages/backend/src/server/web/bios.js index 51899dd3a3..029eb92aad 100644 --- a/packages/backend/src/server/web/bios.js +++ b/packages/backend/src/server/web/bios.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + 'use strict'; window.onload = async () => { diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index 38ae8ad2e5..48939ef7a0 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /** * BOOT LOADER * サーバーからレスポンスされるHTMLに埋め込まれるスクリプトで、以下の役割を持ちます。 diff --git a/packages/backend/src/server/web/cli.css b/packages/backend/src/server/web/cli.css index 07cd27830b..b7737c3f21 100644 --- a/packages/backend/src/server/web/cli.css +++ b/packages/backend/src/server/web/cli.css @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + * { font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace; } diff --git a/packages/backend/src/server/web/cli.js b/packages/backend/src/server/web/cli.js index 5bb576a27b..e63a80327c 100644 --- a/packages/backend/src/server/web/cli.js +++ b/packages/backend/src/server/web/cli.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + 'use strict'; window.onload = async () => { diff --git a/packages/backend/src/server/web/error.css b/packages/backend/src/server/web/error.css index ab913f7a9f..ea3056bdaf 100644 --- a/packages/backend/src/server/web/error.css +++ b/packages/backend/src/server/web/error.css @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + * { font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif; } diff --git a/packages/backend/src/server/web/style.css b/packages/backend/src/server/web/style.css index d59f00fe16..952be9bf0b 100644 --- a/packages/backend/src/server/web/style.css +++ b/packages/backend/src/server/web/style.css @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + html { background-color: var(--bg); color: var(--fg); diff --git a/packages/backend/src/server/web/views/oauth.pug b/packages/backend/src/server/web/views/oauth.pug new file mode 100644 index 0000000000..1470dbfbdf --- /dev/null +++ b/packages/backend/src/server/web/views/oauth.pug @@ -0,0 +1,9 @@ +extends ./base + +block meta + //- Should be removed by the page when it loads, so that it won't needlessly + //- stay when user navigates away via the navigation bar + //- XXX: Remove navigation bar in auth page? + meta(name='misskey:oauth:transaction-id' content=transactionId) + meta(name='misskey:oauth:client-name' content=clientName) + meta(name='misskey:oauth:scope' content=scope) diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 7c6a1e5199..a3a8e77cd0 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] as const; export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const; diff --git a/packages/backend/test/e2e/2fa.ts b/packages/backend/test/e2e/2fa.ts index 04be97ad9d..387249871e 100644 --- a/packages/backend/test/e2e/2fa.ts +++ b/packages/backend/test/e2e/2fa.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/antennas.ts b/packages/backend/test/e2e/antennas.ts index cb526669f5..7e2beab1ab 100644 --- a/packages/backend/test/e2e/antennas.ts +++ b/packages/backend/test/e2e/antennas.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/api-visibility.ts b/packages/backend/test/e2e/api-visibility.ts index f781559d50..33c8d03fdb 100644 --- a/packages/backend/test/e2e/api-visibility.ts +++ b/packages/backend/test/e2e/api-visibility.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/api.ts b/packages/backend/test/e2e/api.ts index c6beec4f88..15da74931d 100644 --- a/packages/backend/test/e2e/api.ts +++ b/packages/backend/test/e2e/api.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; -import { signup, api, startServer, successfulApiCall, failedApiCall, uploadFile, waitFire, connectStream } from '../utils.js'; +import { IncomingMessage } from 'http'; +import { signup, api, startServer, successfulApiCall, failedApiCall, uploadFile, waitFire, connectStream, relativeFetch } from '../utils.js'; import type { INestApplicationContext } from '@nestjs/common'; import type * as misskey from 'misskey-js'; -import { IncomingMessage } from 'http'; describe('API', () => { let app: INestApplicationContext; @@ -218,6 +223,42 @@ describe('API', () => { assert.ok(result.headers.get('WWW-Authenticate')?.startsWith('Bearer realm="Misskey", error="invalid_request", error_description')); }); - // TODO: insufficient_scope test (authテストが全然なくて書けない) + describe('invalid bearer format', () => { + test('No preceding bearer', async () => { + const result = await relativeFetch('api/notes/create', { + method: 'POST', + headers: { + Authorization: alice.token, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ text: 'test' }), + }); + assert.strictEqual(result.status, 401); + }); + + test('Lowercase bearer', async () => { + const result = await relativeFetch('api/notes/create', { + method: 'POST', + headers: { + Authorization: `bearer ${alice.token}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ text: 'test' }), + }); + assert.strictEqual(result.status, 401); + }); + + test('No space after bearer', async () => { + const result = await relativeFetch('api/notes/create', { + method: 'POST', + headers: { + Authorization: `Bearer${alice.token}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ text: 'test' }), + }); + assert.strictEqual(result.status, 401); + }); + }); }); }); diff --git a/packages/backend/test/e2e/block.ts b/packages/backend/test/e2e/block.ts index 8357884092..4445d9036c 100644 --- a/packages/backend/test/e2e/block.ts +++ b/packages/backend/test/e2e/block.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/clips.ts b/packages/backend/test/e2e/clips.ts index 175f2cac97..833b48f731 100644 --- a/packages/backend/test/e2e/clips.ts +++ b/packages/backend/test/e2e/clips.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/endpoints.ts b/packages/backend/test/e2e/endpoints.ts index a1e89d4833..6e91786413 100644 --- a/packages/backend/test/e2e/endpoints.ts +++ b/packages/backend/test/e2e/endpoints.ts @@ -1,10 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; // node-fetch only supports it's own Blob yet // https://github.com/node-fetch/node-fetch/pull/1664 import { Blob } from 'node-fetch'; -import { User } from '@/models/index.js'; +import { MiUser } from '@/models/index.js'; import { startServer, signup, post, api, uploadFile, simpleGet, initTestDb } from '../utils.js'; import type { INestApplicationContext } from '@nestjs/common'; import type * as misskey from 'misskey-js'; @@ -293,7 +298,7 @@ describe('Endpoints', () => { assert.strictEqual(res.status, 200); const connection = await initTestDb(true); - const Users = connection.getRepository(User); + const Users = connection.getRepository(MiUser); const newBob = await Users.findOneByOrFail({ id: bob.id }); assert.strictEqual(newBob.followersCount, 0); assert.strictEqual(newBob.followingCount, 1); @@ -355,7 +360,7 @@ describe('Endpoints', () => { assert.strictEqual(res.status, 200); const connection = await initTestDb(true); - const Users = connection.getRepository(User); + const Users = connection.getRepository(MiUser); const newBob = await Users.findOneByOrFail({ id: bob.id }); assert.strictEqual(newBob.followersCount, 0); assert.strictEqual(newBob.followingCount, 0); diff --git a/packages/backend/test/e2e/fetch-resource.ts b/packages/backend/test/e2e/fetch-resource.ts index 115945dd3d..1cbfec3e5f 100644 --- a/packages/backend/test/e2e/fetch-resource.ts +++ b/packages/backend/test/e2e/fetch-resource.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; @@ -29,6 +34,8 @@ describe('Webリソース', () => { let aliceGalleryPost: any; let aliceChannel: any; + let bob: misskey.entities.MeSignup; + type Request = { path: string, accept?: string, @@ -85,6 +92,8 @@ describe('Webリソース', () => { fileIds: [aliceUploadedFile.body.id], }); aliceChannel = await channel(alice, {}); + + bob = await signup({ username: 'alice' }); }, 1000 * 60 * 2); afterAll(async () => { @@ -158,9 +167,15 @@ describe('Webリソース', () => { }); describe.each([{ path: '/queue' }])('$path', ({ path }) => { + test('はログインしないとGETできない。', async () => await notOk({ + path, + status: 401, + })); + test('はadminでなければGETできない。', async () => await notOk({ path, - status: 500, // FIXME? 403ではない。 + cookie: cookie(bob), + status: 403, })); test('はadminならGETできる。', async () => await ok({ diff --git a/packages/backend/test/e2e/ff-visibility.ts b/packages/backend/test/e2e/ff-visibility.ts index 9082c77f07..7841e057bf 100644 --- a/packages/backend/test/e2e/ff-visibility.ts +++ b/packages/backend/test/e2e/ff-visibility.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/move.ts b/packages/backend/test/e2e/move.ts index 2fefcd0f0e..24c9473ae8 100644 --- a/packages/backend/test/e2e/move.ts +++ b/packages/backend/test/e2e/move.ts @@ -1,8 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; import { loadConfig } from '@/config.js'; -import { User, UsersRepository } from '@/models/index.js'; +import { MiUser, UsersRepository } from '@/models/index.js'; import { jobQueue } from '@/boot/common.js'; import { secureRndstr } from '@/misc/secure-rndstr.js'; import { uploadFile, signup, startServer, initTestDb, api, sleep, successfulApiCall } from '../utils.js'; @@ -37,7 +42,7 @@ describe('Account Move', () => { dave = await signup({ username: 'dave' }); eve = await signup({ username: 'eve' }); frank = await signup({ username: 'frank' }); - Users = connection.getRepository(User); + Users = connection.getRepository(MiUser); }, 1000 * 60 * 2); afterAll(async () => { diff --git a/packages/backend/test/e2e/mute.ts b/packages/backend/test/e2e/mute.ts index 79e2c90f64..a4b57a1eba 100644 --- a/packages/backend/test/e2e/mute.ts +++ b/packages/backend/test/e2e/mute.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index 33da811a26..20208c4571 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -1,7 +1,13 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; -import { Note } from '@/models/entities/Note.js'; +import { MiNote } from '@/models/entities/Note.js'; +import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { signup, post, uploadUrl, startServer, initTestDb, api, uploadFile } from '../utils.js'; import type { INestApplicationContext } from '@nestjs/common'; import type * as misskey from 'misskey-js'; @@ -16,7 +22,7 @@ describe('Note', () => { beforeAll(async () => { app = await startServer(); const connection = await initTestDb(true); - Notes = connection.getRepository(Note); + Notes = connection.getRepository(MiNote); alice = await signup({ username: 'alice' }); bob = await signup({ username: 'bob' }); }, 1000 * 60 * 2); @@ -164,7 +170,7 @@ describe('Note', () => { test('文字数ぎりぎりで怒られない', async () => { const post = { - text: '!'.repeat(3000), + text: '!'.repeat(MAX_NOTE_TEXT_LENGTH), // 3000文字 }; const res = await api('/notes/create', post, alice); assert.strictEqual(res.status, 200); @@ -172,7 +178,7 @@ describe('Note', () => { test('文字数オーバーで怒られる', async () => { const post = { - text: '!'.repeat(3001), + text: '!'.repeat(MAX_NOTE_TEXT_LENGTH + 1), // 3001文字 }; const res = await api('/notes/create', post, alice); assert.strictEqual(res.status, 400); @@ -546,8 +552,8 @@ describe('Note', () => { test('センシティブな投稿はhomeになる (単語指定)', async () => { const sensitive = await api('admin/update-meta', { sensitiveWords: [ - "test", - ] + 'test', + ], }, alice); assert.strictEqual(sensitive.status, 204); @@ -560,14 +566,13 @@ describe('Note', () => { assert.strictEqual(note1.status, 200); assert.strictEqual(note1.body.createdNote.visibility, 'home'); - }); test('センシティブな投稿はhomeになる (正規表現)', async () => { const sensitive = await api('admin/update-meta', { sensitiveWords: [ - "/Test/i", - ] + '/Test/i', + ], }, alice); assert.strictEqual(sensitive.status, 204); @@ -583,8 +588,8 @@ describe('Note', () => { test('センシティブな投稿はhomeになる (スペースアンド)', async () => { const sensitive = await api('admin/update-meta', { sensitiveWords: [ - "Test hoge" - ] + 'Test hoge', + ], }, alice); assert.strictEqual(sensitive.status, 204); @@ -595,7 +600,6 @@ describe('Note', () => { assert.strictEqual(note2.status, 200); assert.strictEqual(note2.body.createdNote.visibility, 'home'); - }); }); diff --git a/packages/backend/test/e2e/oauth.ts b/packages/backend/test/e2e/oauth.ts new file mode 100644 index 0000000000..a029a0d4be --- /dev/null +++ b/packages/backend/test/e2e/oauth.ts @@ -0,0 +1,944 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +/** + * Basic OAuth tests to make sure the library is correctly integrated to Misskey + * and not regressed by version updates or potential migration to another library. + */ + +process.env.NODE_ENV = 'test'; + +import * as assert from 'assert'; +import { AuthorizationCode, ResourceOwnerPassword, type AuthorizationTokenConfig, ClientCredentials, ModuleOptions } from 'simple-oauth2'; +import pkceChallenge from 'pkce-challenge'; +import { JSDOM } from 'jsdom'; +import Fastify, { type FastifyReply, type FastifyInstance } from 'fastify'; +import { api, port, signup, startServer } from '../utils.js'; +import type * as misskey from 'misskey-js'; +import type { INestApplicationContext } from '@nestjs/common'; + +const host = `http://127.0.0.1:${port}`; + +const clientPort = port + 1; +const redirect_uri = `http://127.0.0.1:${clientPort}/redirect`; + +const basicAuthParams: AuthorizationParamsExtended = { + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', +}; + +interface AuthorizationParamsExtended { + redirect_uri: string; + scope: string | string[]; + state: string; + code_challenge?: string; + code_challenge_method?: string; +} + +interface AuthorizationTokenConfigExtended extends AuthorizationTokenConfig { + code_verifier: string | undefined; +} + +interface GetTokenError { + data: { + payload: { + error: string; + } + } +} + +const clientConfig: ModuleOptions<'client_id'> = { + client: { + id: `http://127.0.0.1:${clientPort}/`, + secret: '', + }, + auth: { + tokenHost: host, + tokenPath: '/oauth/token', + authorizePath: '/oauth/authorize', + }, + options: { + authorizationMethod: 'body', + }, +}; + +function getMeta(html: string): { transactionId: string | undefined, clientName: string | undefined } { + const fragment = JSDOM.fragment(html); + return { + transactionId: fragment.querySelector('meta[name="misskey:oauth:transaction-id"]')?.content, + clientName: fragment.querySelector('meta[name="misskey:oauth:client-name"]')?.content, + }; +} + +function fetchDecision(transactionId: string, user: misskey.entities.MeSignup, { cancel }: { cancel?: boolean } = {}): Promise { + return fetch(new URL('/oauth/decision', host), { + method: 'post', + body: new URLSearchParams({ + transaction_id: transactionId, + login_token: user.token, + cancel: cancel ? 'cancel' : '', + }), + redirect: 'manual', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }); +} + +async function fetchDecisionFromResponse(response: Response, user: misskey.entities.MeSignup, { cancel }: { cancel?: boolean } = {}): Promise { + const { transactionId } = getMeta(await response.text()); + assert.ok(transactionId); + + return await fetchDecision(transactionId, user, { cancel }); +} + +async function fetchAuthorizationCode(user: misskey.entities.MeSignup, scope: string, code_challenge: string): Promise<{ client: AuthorizationCode, code: string }> { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope, + state: 'state', + code_challenge, + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(response.status, 200); + + const decisionResponse = await fetchDecisionFromResponse(response, user); + assert.strictEqual(decisionResponse.status, 302); + + const locationHeader = decisionResponse.headers.get('location'); + assert.ok(locationHeader); + + const location = new URL(locationHeader); + assert.ok(location.searchParams.has('code')); + + const code = new URL(location).searchParams.get('code'); + assert.ok(code); + + return { client, code }; +} + +function assertIndirectError(response: Response, error: string): void { + assert.strictEqual(response.status, 302); + + const locationHeader = response.headers.get('location'); + assert.ok(locationHeader); + + const location = new URL(locationHeader); + assert.strictEqual(location.searchParams.get('error'), error); + + // https://datatracker.ietf.org/doc/html/rfc9207#name-response-parameter-iss + assert.strictEqual(location.searchParams.get('iss'), 'http://misskey.local'); + // https://datatracker.ietf.org/doc/html/rfc6749.html#section-4.1.2.1 + assert.ok(location.searchParams.has('state')); +} + +async function assertDirectError(response: Response, status: number, error: string): Promise { + assert.strictEqual(response.status, status); + + const data = await response.json(); + assert.strictEqual(data.error, error); +} + +describe('OAuth', () => { + let app: INestApplicationContext; + let fastify: FastifyInstance; + + let alice: misskey.entities.MeSignup; + let bob: misskey.entities.MeSignup; + + let sender: (reply: FastifyReply) => void; + + beforeAll(async () => { + app = await startServer(); + alice = await signup({ username: 'alice' }); + bob = await signup({ username: 'bob' }); + + fastify = Fastify(); + fastify.get('/', async (request, reply) => { + sender(reply); + }); + await fastify.listen({ port: clientPort }); + }, 1000 * 60 * 2); + + beforeEach(async () => { + process.env.MISSKEY_TEST_CHECK_IP_RANGE = ''; + sender = (reply): void => { + reply.send(` + + +
Misklient + `); + }; + }); + + afterAll(async () => { + await fastify.close(); + await app.close(); + }); + + test('Full flow', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge, + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(response.status, 200); + + const meta = getMeta(await response.text()); + assert.strictEqual(typeof meta.transactionId, 'string'); + assert.ok(meta.transactionId); + assert.strictEqual(meta.clientName, 'Misklient'); + + const decisionResponse = await fetchDecision(meta.transactionId, alice); + assert.strictEqual(decisionResponse.status, 302); + assert.ok(decisionResponse.headers.has('location')); + + const locationHeader = decisionResponse.headers.get('location'); + assert.ok(locationHeader); + + const location = new URL(locationHeader); + assert.strictEqual(location.origin + location.pathname, redirect_uri); + assert.ok(location.searchParams.has('code')); + assert.strictEqual(location.searchParams.get('state'), 'state'); + // https://datatracker.ietf.org/doc/html/rfc9207#name-response-parameter-iss + assert.strictEqual(location.searchParams.get('iss'), 'http://misskey.local'); + + const code = new URL(location).searchParams.get('code'); + assert.ok(code); + + const token = await client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended); + assert.strictEqual(typeof token.token.access_token, 'string'); + assert.strictEqual(token.token.token_type, 'Bearer'); + assert.strictEqual(token.token.scope, 'write:notes'); + + const createResult = await api('notes/create', { text: 'test' }, { + token: token.token.access_token as string, + bearer: true, + }); + assert.strictEqual(createResult.status, 200); + + const createResultBody = createResult.body as misskey.Endpoints['notes/create']['res']; + assert.strictEqual(createResultBody.createdNote.text, 'test'); + }); + + test('Two concurrent flows', async () => { + const client = new AuthorizationCode(clientConfig); + + const pkceAlice = await pkceChallenge(128); + const pkceBob = await pkceChallenge(128); + + const responseAlice = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: pkceAlice.code_challenge, + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(responseAlice.status, 200); + + const responseBob = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: pkceBob.code_challenge, + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(responseBob.status, 200); + + const decisionResponseAlice = await fetchDecisionFromResponse(responseAlice, alice); + assert.strictEqual(decisionResponseAlice.status, 302); + + const decisionResponseBob = await fetchDecisionFromResponse(responseBob, bob); + assert.strictEqual(decisionResponseBob.status, 302); + + const locationHeaderAlice = decisionResponseAlice.headers.get('location'); + assert.ok(locationHeaderAlice); + const locationAlice = new URL(locationHeaderAlice); + + const locationHeaderBob = decisionResponseBob.headers.get('location'); + assert.ok(locationHeaderBob); + const locationBob = new URL(locationHeaderBob); + + const codeAlice = locationAlice.searchParams.get('code'); + assert.ok(codeAlice); + const codeBob = locationBob.searchParams.get('code'); + assert.ok(codeBob); + + const tokenAlice = await client.getToken({ + code: codeAlice, + redirect_uri, + code_verifier: pkceAlice.code_verifier, + } as AuthorizationTokenConfigExtended); + + const tokenBob = await client.getToken({ + code: codeBob, + redirect_uri, + code_verifier: pkceBob.code_verifier, + } as AuthorizationTokenConfigExtended); + + const createResultAlice = await api('notes/create', { text: 'test' }, { + token: tokenAlice.token.access_token as string, + bearer: true, + }); + assert.strictEqual(createResultAlice.status, 200); + + const createResultBob = await api('notes/create', { text: 'test' }, { + token: tokenBob.token.access_token as string, + bearer: true, + }); + assert.strictEqual(createResultAlice.status, 200); + + const createResultBodyAlice = await createResultAlice.body as misskey.Endpoints['notes/create']['res']; + assert.strictEqual(createResultBodyAlice.createdNote.user.username, 'alice'); + + const createResultBodyBob = await createResultBob.body as misskey.Endpoints['notes/create']['res']; + assert.strictEqual(createResultBodyBob.createdNote.user.username, 'bob'); + }); + + // https://datatracker.ietf.org/doc/html/rfc7636.html + describe('PKCE', () => { + // https://datatracker.ietf.org/doc/html/rfc7636.html#section-4.4.1 + // '... the authorization endpoint MUST return the authorization + // error response with the "error" value set to "invalid_request".' + test('Require PKCE', async () => { + const client = new AuthorizationCode(clientConfig); + + // Pattern 1: No PKCE fields at all + let response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + }), { redirect: 'manual' }); + assertIndirectError(response, 'invalid_request'); + + // Pattern 2: Only code_challenge + response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + } as AuthorizationParamsExtended), { redirect: 'manual' }); + assertIndirectError(response, 'invalid_request'); + + // Pattern 3: Only code_challenge_method + response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended), { redirect: 'manual' }); + assertIndirectError(response, 'invalid_request'); + + // Pattern 4: Unsupported code_challenge_method + response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'SSSS', + } as AuthorizationParamsExtended), { redirect: 'manual' }); + assertIndirectError(response, 'invalid_request'); + }); + + // Use precomputed challenge/verifier set here for deterministic test + const code_challenge = '4w2GDuvaxXlw2l46k5PFIoIcTGHdzw2i3hrn-C_Q6f7u0-nTYKd-beVEYy9XinYsGtAix.Nnvr.GByD3lAii2ibPRsSDrZgIN0YQb.kfevcfR9aDKoTLyOUm4hW4ABhs'; + const code_verifier = 'Ew8VSBiH59JirLlg7ocFpLQ6NXuFC1W_rn8gmRzBKc8'; + + const tests: Record = { + 'Code followed by some junk code': code_verifier + 'x', + 'Clipped code': code_verifier.slice(0, 80), + 'Some part of code is replaced': code_verifier.slice(0, -10) + 'x'.repeat(10), + 'No verifier': undefined, + }; + + describe('Verify PKCE', () => { + for (const [title, wrong_verifier] of Object.entries(tests)) { + test(title, async () => { + const { client, code } = await fetchAuthorizationCode(alice, 'write:notes', code_challenge); + + await assert.rejects(client.getToken({ + code, + redirect_uri, + code_verifier: wrong_verifier, + } as AuthorizationTokenConfigExtended), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + }); + } + }); + }); + + // https://datatracker.ietf.org/doc/html/rfc6749.html#section-4.1.2 + // "If an authorization code is used more than once, the authorization server + // MUST deny the request and SHOULD revoke (when possible) all tokens + // previously issued based on that authorization code." + describe('Revoking authorization code', () => { + test('On success', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + const { client, code } = await fetchAuthorizationCode(alice, 'write:notes', code_challenge); + + await client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended); + + await assert.rejects(client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + }); + + test('On failure', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + const { client, code } = await fetchAuthorizationCode(alice, 'write:notes', code_challenge); + + await assert.rejects(client.getToken({ code, redirect_uri }), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + + await assert.rejects(client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + }); + + test('Revoke the already granted access token', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + const { client, code } = await fetchAuthorizationCode(alice, 'write:notes', code_challenge); + + const token = await client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended); + + const createResult = await api('notes/create', { text: 'test' }, { + token: token.token.access_token as string, + bearer: true, + }); + assert.strictEqual(createResult.status, 200); + + await assert.rejects(client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + + const createResult2 = await api('notes/create', { text: 'test' }, { + token: token.token.access_token as string, + bearer: true, + }); + assert.strictEqual(createResult2.status, 401); + }); + }); + + test('Cancellation', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(response.status, 200); + + const decisionResponse = await fetchDecisionFromResponse(response, alice, { cancel: true }); + assert.strictEqual(decisionResponse.status, 302); + + const locationHeader = decisionResponse.headers.get('location'); + assert.ok(locationHeader); + + const location = new URL(locationHeader); + assert.ok(!location.searchParams.has('code')); + assert.ok(location.searchParams.has('error')); + }); + + // https://datatracker.ietf.org/doc/html/rfc6749.html#section-3.3 + describe('Scope', () => { + // "If the client omits the scope parameter when requesting + // authorization, the authorization server MUST either process the + // request using a pre-defined default value or fail the request + // indicating an invalid scope." + // (And Misskey does the latter) + test('Missing scope', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended), { redirect: 'manual' }); + assertIndirectError(response, 'invalid_scope'); + }); + + test('Empty scope', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: '', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended), { redirect: 'manual' }); + assertIndirectError(response, 'invalid_scope'); + }); + + test('Unknown scopes', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'test:unknown test:unknown2', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended), { redirect: 'manual' }); + assertIndirectError(response, 'invalid_scope'); + }); + + // "If the issued access token scope + // is different from the one requested by the client, the authorization + // server MUST include the "scope" response parameter to inform the + // client of the actual scope granted." + // (Although Misskey always return scope, which is also fine) + test('Partially known scopes', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + + // Just get the known scope for this case for backward compatibility + const { client, code } = await fetchAuthorizationCode( + alice, + 'write:notes test:unknown test:unknown2', + code_challenge, + ); + + const token = await client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended); + + assert.strictEqual(token.token.scope, 'write:notes'); + }); + + test('Known scopes', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes read:account', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + + assert.strictEqual(response.status, 200); + }); + + test('Duplicated scopes', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + + const { client, code } = await fetchAuthorizationCode( + alice, + 'write:notes write:notes read:account read:account', + code_challenge, + ); + + const token = await client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended); + assert.strictEqual(token.token.scope, 'write:notes read:account'); + }); + + test('Scope check by API', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + + const { client, code } = await fetchAuthorizationCode(alice, 'read:account', code_challenge); + + const token = await client.getToken({ + code, + redirect_uri, + code_verifier, + } as AuthorizationTokenConfigExtended); + assert.strictEqual(typeof token.token.access_token, 'string'); + + const createResult = await api('notes/create', { text: 'test' }, { + token: token.token.access_token as string, + bearer: true, + }); + assert.strictEqual(createResult.status, 403); + assert.ok(createResult.headers.get('WWW-Authenticate')?.startsWith('Bearer realm="Misskey", error="insufficient_scope", error_description')); + }); + }); + + // https://datatracker.ietf.org/doc/html/rfc6749.html#section-3.1.2.4 + // "If an authorization request fails validation due to a missing, + // invalid, or mismatching redirection URI, the authorization server + // SHOULD inform the resource owner of the error and MUST NOT + // automatically redirect the user-agent to the invalid redirection URI." + describe('Redirection', () => { + test('Invalid redirect_uri at authorization endpoint', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri: 'http://127.0.0.2/', + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + await assertDirectError(response, 400, 'invalid_request'); + }); + + test('Invalid redirect_uri including the valid one at authorization endpoint', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri: 'http://127.0.0.1/redirection', + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + await assertDirectError(response, 400, 'invalid_request'); + }); + + test('No redirect_uri at authorization endpoint', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + await assertDirectError(response, 400, 'invalid_request'); + }); + + test('Invalid redirect_uri at token endpoint', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + + const { client, code } = await fetchAuthorizationCode(alice, 'write:notes', code_challenge); + + await assert.rejects(client.getToken({ + code, + redirect_uri: 'http://127.0.0.2/', + code_verifier, + } as AuthorizationTokenConfigExtended), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + }); + + test('Invalid redirect_uri including the valid one at token endpoint', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + + const { client, code } = await fetchAuthorizationCode(alice, 'write:notes', code_challenge); + + await assert.rejects(client.getToken({ + code, + redirect_uri: 'http://127.0.0.1/redirection', + code_verifier, + } as AuthorizationTokenConfigExtended), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + }); + + test('No redirect_uri at token endpoint', async () => { + const { code_challenge, code_verifier } = await pkceChallenge(128); + + const { client, code } = await fetchAuthorizationCode(alice, 'write:notes', code_challenge); + + await assert.rejects(client.getToken({ + code, + code_verifier, + } as AuthorizationTokenConfigExtended), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'invalid_grant'); + return true; + }); + }); + }); + + // https://datatracker.ietf.org/doc/html/rfc8414 + test('Server metadata', async () => { + const response = await fetch(new URL('.well-known/oauth-authorization-server', host)); + assert.strictEqual(response.status, 200); + + const body = await response.json(); + assert.strictEqual(body.issuer, 'http://misskey.local'); + assert.ok(body.scopes_supported.includes('write:notes')); + }); + + // Any error on decision endpoint is solely on Misskey side and nothing to do with the client. + // Do not use indirect error here. + describe('Decision endpoint', () => { + test('No login token', async () => { + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL(basicAuthParams)); + assert.strictEqual(response.status, 200); + + const { transactionId } = getMeta(await response.text()); + assert.ok(transactionId); + + const decisionResponse = await fetch(new URL('/oauth/decision', host), { + method: 'post', + body: new URLSearchParams({ + transaction_id: transactionId, + }), + redirect: 'manual', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }); + await assertDirectError(decisionResponse, 400, 'invalid_request'); + }); + + test('No transaction ID', async () => { + const decisionResponse = await fetch(new URL('/oauth/decision', host), { + method: 'post', + body: new URLSearchParams({ + login_token: alice.token, + }), + redirect: 'manual', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }); + await assertDirectError(decisionResponse, 400, 'invalid_request'); + }); + + test('Invalid transaction ID', async () => { + const decisionResponse = await fetch(new URL('/oauth/decision', host), { + method: 'post', + body: new URLSearchParams({ + login_token: alice.token, + transaction_id: 'invalid_id', + }), + redirect: 'manual', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }); + await assertDirectError(decisionResponse, 403, 'access_denied'); + }); + }); + + // Only authorization code grant is supported + describe('Grant type', () => { + test('Implicit grant is not supported', async () => { + const url = new URL('/oauth/authorize', host); + url.searchParams.append('response_type', 'token'); + const response = await fetch(url); + assertDirectError(response, 501, 'unsupported_response_type'); + }); + + test('Resource owner grant is not supported', async () => { + const client = new ResourceOwnerPassword({ + ...clientConfig, + auth: { + tokenHost: host, + tokenPath: '/oauth/token', + }, + }); + + await assert.rejects(client.getToken({ + username: 'alice', + password: 'test', + }), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'unsupported_grant_type'); + return true; + }); + }); + + test('Client credential grant is not supported', async () => { + const client = new ClientCredentials({ + ...clientConfig, + auth: { + tokenHost: host, + tokenPath: '/oauth/token', + }, + }); + + await assert.rejects(client.getToken({}), (err: GetTokenError) => { + assert.strictEqual(err.data.payload.error, 'unsupported_grant_type'); + return true; + }); + }); + }); + + // https://indieauth.spec.indieweb.org/#client-information-discovery + describe('Client Information Discovery', () => { + describe('Redirection', () => { + const tests: Record void> = { + 'Read HTTP header': reply => { + reply.header('Link', '; rel="redirect_uri"'); + reply.send(` + +
Misklient + `); + }, + 'Mixed links': reply => { + reply.header('Link', '; rel="redirect_uri"'); + reply.send(` + + +
Misklient + `); + }, + 'Multiple items in Link header': reply => { + reply.header('Link', '; rel="redirect_uri",; rel="redirect_uri"'); + reply.send(` + +
Misklient + `); + }, + 'Multiple items in HTML': reply => { + reply.send(` + + + +
Misklient + `); + }, + }; + + for (const [title, replyFunc] of Object.entries(tests)) { + test(title, async () => { + sender = replyFunc; + + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(response.status, 200); + }); + } + + test('No item', async () => { + sender = (reply): void => { + reply.send(` + +
Misklient + `); + }; + + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + + // direct error because there's no redirect URI to ping + await assertDirectError(response, 400, 'invalid_request'); + }); + }); + + test('Disallow loopback', async () => { + process.env.MISSKEY_TEST_CHECK_IP_RANGE = '1'; + + const client = new AuthorizationCode(clientConfig); + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + await assertDirectError(response, 400, 'invalid_request'); + }); + + test('Missing name', async () => { + sender = (reply): void => { + reply.header('Link', '; rel="redirect_uri"'); + reply.send(); + }; + + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(response.status, 200); + assert.strictEqual(getMeta(await response.text()).clientName, `http://127.0.0.1:${clientPort}/`); + }); + + test('Mismatching URL in h-app', async () => { + sender = (reply): void => { + reply.header('Link', '; rel="redirect_uri"'); + reply.send(` + +
Misklient + `); + reply.send(); + }; + + const client = new AuthorizationCode(clientConfig); + + const response = await fetch(client.authorizeURL({ + redirect_uri, + scope: 'write:notes', + state: 'state', + code_challenge: 'code', + code_challenge_method: 'S256', + } as AuthorizationParamsExtended)); + assert.strictEqual(response.status, 200); + assert.strictEqual(getMeta(await response.text()).clientName, `http://127.0.0.1:${clientPort}/`); + }); + }); + + test('Unknown OAuth endpoint', async () => { + const response = await fetch(new URL('/oauth/foo', host)); + assert.strictEqual(response.status, 404); + }); +}); diff --git a/packages/backend/test/e2e/renote-mute.ts b/packages/backend/test/e2e/renote-mute.ts index 72fc599aaf..c9e1ccc304 100644 --- a/packages/backend/test/e2e/renote-mute.ts +++ b/packages/backend/test/e2e/renote-mute.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/streaming.ts b/packages/backend/test/e2e/streaming.ts index 2cddafed2e..0dd97069a0 100644 --- a/packages/backend/test/e2e/streaming.ts +++ b/packages/backend/test/e2e/streaming.ts @@ -1,7 +1,12 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; -import { Following } from '@/models/entities/Following.js'; +import { MiFollowing } from '@/models/entities/Following.js'; import { connectStream, signup, api, post, startServer, initTestDb, waitFire } from '../utils.js'; import type { INestApplicationContext } from '@nestjs/common'; import type * as misskey from 'misskey-js'; @@ -41,7 +46,7 @@ describe('Streaming', () => { beforeAll(async () => { app = await startServer(); const connection = await initTestDb(true); - Followings = connection.getRepository(Following); + Followings = connection.getRepository(MiFollowing); ayano = await signup({ username: 'ayano' }); kyoko = await signup({ username: 'kyoko' }); diff --git a/packages/backend/test/e2e/thread-mute.ts b/packages/backend/test/e2e/thread-mute.ts index e01ea90fe0..0e487976dc 100644 --- a/packages/backend/test/e2e/thread-mute.ts +++ b/packages/backend/test/e2e/thread-mute.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/user-notes.ts b/packages/backend/test/e2e/user-notes.ts index 3681456c7e..121070787d 100644 --- a/packages/backend/test/e2e/user-notes.ts +++ b/packages/backend/test/e2e/user-notes.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts index 64efaa57cc..8afbcbe322 100644 --- a/packages/backend/test/e2e/users.ts +++ b/packages/backend/test/e2e/users.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; @@ -155,6 +160,7 @@ describe('ユーザー', () => { hasUnreadChannel: user.hasUnreadChannel, hasUnreadNotification: user.hasUnreadNotification, hasPendingReceivedFollowRequest: user.hasPendingReceivedFollowRequest, + unreadAnnouncements: user.unreadAnnouncements, mutedWords: user.mutedWords, mutedInstances: user.mutedInstances, mutingNotificationTypes: user.mutingNotificationTypes, @@ -400,6 +406,7 @@ describe('ユーザー', () => { assert.strictEqual(response.hasUnreadChannel, false); assert.strictEqual(response.hasUnreadNotification, false); assert.strictEqual(response.hasPendingReceivedFollowRequest, false); + assert.deepStrictEqual(response.unreadAnnouncements, []); assert.deepStrictEqual(response.mutedWords, []); assert.deepStrictEqual(response.mutedInstances, []); assert.deepStrictEqual(response.mutingNotificationTypes, []); diff --git a/packages/backend/test/misc/mock-resolver.ts b/packages/backend/test/misc/mock-resolver.ts index 9dbe77a7c4..257a9c859f 100644 --- a/packages/backend/test/misc/mock-resolver.ts +++ b/packages/backend/test/misc/mock-resolver.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import type { Config } from '@/config.js'; import type { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js'; import type { ApRendererService } from '@/core/activitypub/ApRendererService.js'; diff --git a/packages/backend/test/prelude/get-api-validator.ts b/packages/backend/test/prelude/get-api-validator.ts index f095774760..cccd63299a 100644 --- a/packages/backend/test/prelude/get-api-validator.ts +++ b/packages/backend/test/prelude/get-api-validator.ts @@ -1,11 +1,16 @@ -import { Schema } from '@/misc/schema'; +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import Ajv from 'ajv'; +import { Schema } from '@/misc/schema'; export const getValidator = (paramDef: Schema) => { - const ajv = new Ajv({ - useDefaults: true, - }); - ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/); + const ajv = new Ajv({ + useDefaults: true, + }); + ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/); - return ajv.compile(paramDef); -} + return ajv.compile(paramDef); +}; diff --git a/packages/backend/test/prelude/maybe.ts b/packages/backend/test/prelude/maybe.ts index b8679c1071..37ccfbf7fe 100644 --- a/packages/backend/test/prelude/maybe.ts +++ b/packages/backend/test/prelude/maybe.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as assert from 'assert'; import { just, nothing } from '../../src/misc/prelude/maybe.js'; diff --git a/packages/backend/test/prelude/url.ts b/packages/backend/test/prelude/url.ts index 23b6b22bb0..340c6451ce 100644 --- a/packages/backend/test/prelude/url.ts +++ b/packages/backend/test/prelude/url.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as assert from 'assert'; import { query } from '../../src/misc/prelude/url.js'; diff --git a/packages/backend/test/unit/AnnouncementService.ts b/packages/backend/test/unit/AnnouncementService.ts new file mode 100644 index 0000000000..c97e081ba5 --- /dev/null +++ b/packages/backend/test/unit/AnnouncementService.ts @@ -0,0 +1,194 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +process.env.NODE_ENV = 'test'; + +import { jest } from '@jest/globals'; +import { ModuleMocker } from 'jest-mock'; +import { Test } from '@nestjs/testing'; +import { GlobalModule } from '@/GlobalModule.js'; +import { AnnouncementService } from '@/core/AnnouncementService.js'; +import type { Announcement, AnnouncementsRepository, AnnouncementReadsRepository, UsersRepository, User } from '@/models/index.js'; +import { DI } from '@/di-symbols.js'; +import { genAid } from '@/misc/id/aid.js'; +import { CacheService } from '@/core/CacheService.js'; +import { IdService } from '@/core/IdService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; +import type { TestingModule } from '@nestjs/testing'; +import type { MockFunctionMetadata } from 'jest-mock'; + +const moduleMocker = new ModuleMocker(global); + +describe('AnnouncementService', () => { + let app: TestingModule; + let announcementService: AnnouncementService; + let usersRepository: UsersRepository; + let announcementsRepository: AnnouncementsRepository; + let announcementReadsRepository: AnnouncementReadsRepository; + let globalEventService: jest.Mocked; + + function createUser(data: Partial = {}) { + const un = secureRndstr(16); + return usersRepository.insert({ + id: genAid(new Date()), + createdAt: new Date(), + username: un, + usernameLower: un, + ...data, + }) + .then(x => usersRepository.findOneByOrFail(x.identifiers[0])); + } + + function createAnnouncement(data: Partial = {}) { + return announcementsRepository.insert({ + id: genAid(new Date()), + createdAt: new Date(), + updatedAt: null, + title: 'Title', + text: 'Text', + ...data, + }) + .then(x => announcementsRepository.findOneByOrFail(x.identifiers[0])); + } + + beforeEach(async () => { + app = await Test.createTestingModule({ + imports: [ + GlobalModule, + ], + providers: [ + AnnouncementService, + CacheService, + IdService, + ], + }) + .useMocker((token) => { + if (token === GlobalEventService) { + return { + publishMainStream: jest.fn(), + publishBroadcastStream: jest.fn(), + }; + } + if (typeof token === 'function') { + const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata; + const Mock = moduleMocker.generateFromMetadata(mockMetadata); + return new Mock(); + } + }) + .compile(); + + app.enableShutdownHooks(); + + announcementService = app.get(AnnouncementService); + usersRepository = app.get(DI.usersRepository); + announcementsRepository = app.get(DI.announcementsRepository); + announcementReadsRepository = app.get(DI.announcementReadsRepository); + globalEventService = app.get(GlobalEventService) as jest.Mocked; + }); + + afterEach(async () => { + await Promise.all([ + app.get(DI.metasRepository).delete({}), + usersRepository.delete({}), + announcementsRepository.delete({}), + announcementReadsRepository.delete({}), + ]); + + await app.close(); + }); + + describe('getUnreadAnnouncements', () => { + test('通常', async () => { + const user = await createUser(); + const announcement = await createAnnouncement({ + title: '1', + }); + + const result = await announcementService.getUnreadAnnouncements(user); + + expect(result.length).toBe(1); + expect(result[0].title).toBe(announcement.title); + }); + + test('isActiveがfalseは除外', async () => { + const user = await createUser(); + await createAnnouncement({ + isActive: false, + }); + + const result = await announcementService.getUnreadAnnouncements(user); + + expect(result.length).toBe(0); + }); + + test('forExistingUsers', async () => { + const user = await createUser(); + const [announcementAfter, announcementBefore, announcementBefore2] = await Promise.all([ + createAnnouncement({ + title: 'after', + createdAt: new Date(), + forExistingUsers: true, + }), + createAnnouncement({ + title: 'before', + createdAt: new Date(Date.now() - 1000), + forExistingUsers: true, + }), + createAnnouncement({ + title: 'before2', + createdAt: new Date(Date.now() - 1000), + forExistingUsers: false, + }), + ]); + + const result = await announcementService.getUnreadAnnouncements(user); + + expect(result.length).toBe(2); + expect(result.some(a => a.title === announcementAfter.title)).toBe(true); + expect(result.some(a => a.title === announcementBefore.title)).toBe(false); + expect(result.some(a => a.title === announcementBefore2.title)).toBe(true); + }); + }); + + describe('create', () => { + test('通常', async () => { + const result = await announcementService.create({ + title: 'Title', + text: 'Text', + }); + + expect(result.raw.title).toBe('Title'); + expect(result.packed.title).toBe('Title'); + + expect(globalEventService.publishBroadcastStream).toHaveBeenCalled(); + expect(globalEventService.publishBroadcastStream.mock.lastCall![0]).toBe('announcementCreated'); + expect((globalEventService.publishBroadcastStream.mock.lastCall![1] as any).announcement).toBe(result.packed); + }); + + test('ユーザー指定', async () => { + const user = await createUser(); + const result = await announcementService.create({ + title: 'Title', + text: 'Text', + userId: user.id, + }); + + expect(result.raw.title).toBe('Title'); + expect(result.packed.title).toBe('Title'); + + expect(globalEventService.publishBroadcastStream).not.toHaveBeenCalled(); + expect(globalEventService.publishMainStream).toHaveBeenCalled(); + expect(globalEventService.publishMainStream.mock.lastCall![0]).toBe(user.id); + expect(globalEventService.publishMainStream.mock.lastCall![1]).toBe('announcementCreated'); + expect((globalEventService.publishMainStream.mock.lastCall![2] as any).announcement).toBe(result.packed); + }); + }); + + describe('read', () => { + // TODO + }); +}); + diff --git a/packages/backend/test/unit/DriveService.ts b/packages/backend/test/unit/DriveService.ts index 9ee6d4bcfb..7234da2e36 100644 --- a/packages/backend/test/unit/DriveService.ts +++ b/packages/backend/test/unit/DriveService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import { Test } from '@nestjs/testing'; diff --git a/packages/backend/test/unit/FetchInstanceMetadataService.ts b/packages/backend/test/unit/FetchInstanceMetadataService.ts index 1ee2939829..22ce023216 100644 --- a/packages/backend/test/unit/FetchInstanceMetadataService.ts +++ b/packages/backend/test/unit/FetchInstanceMetadataService.ts @@ -1,8 +1,14 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; import { ModuleMocker } from 'jest-mock'; import { Test } from '@nestjs/testing'; +import { Redis } from 'ioredis'; import { GlobalModule } from '@/GlobalModule.js'; import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; @@ -13,15 +19,14 @@ import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; import type { TestingModule } from '@nestjs/testing'; import type { MockFunctionMetadata } from 'jest-mock'; -import { Redis } from 'ioredis' function mockRedis() { const hash = {}; const set = jest.fn((key, value) => { - const ret = hash[key]; - hash[key] = value; - return ret; - }); + const ret = hash[key]; + hash[key] = value; + return ret; + }); return set; } @@ -47,7 +52,7 @@ describe('FetchInstanceMetadataService', () => { }) .useMocker((token) => { if (token === HttpRequestService) { - return { getJson: jest.fn(), getHtml: jest.fn(), send: jest.fn(), }; + return { getJson: jest.fn(), getHtml: jest.fn(), send: jest.fn() }; } else if (token === FederatedInstanceService) { return { fetch: jest.fn() }; } else if (token === DI.redis) { @@ -74,20 +79,20 @@ describe('FetchInstanceMetadataService', () => { httpRequestService.getJson.mockImplementation(() => { throw Error(); }); const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock'); const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock'); - await fetchInstanceMetadataService.fetchInstanceMetadata({ host: "example.com" }); + await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' }); expect(tryLockSpy).toHaveBeenCalledTimes(1); expect(unlockSpy).toHaveBeenCalledTimes(1); expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1); expect(httpRequestService.getJson).toHaveBeenCalled(); }); - test("Lock and don't update", async () => { + test('Lock and don\'t update', async () => { redisClient.set = mockRedis(); const now = Date.now(); federatedInstanceService.fetch.mockReturnValue({ infoUpdatedAt: { getTime: () => now } }); httpRequestService.getJson.mockImplementation(() => { throw Error(); }); const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock'); const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock'); - await fetchInstanceMetadataService.fetchInstanceMetadata({ host: "example.com" }); + await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' }); expect(tryLockSpy).toHaveBeenCalledTimes(1); expect(unlockSpy).toHaveBeenCalledTimes(1); expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1); @@ -99,8 +104,8 @@ describe('FetchInstanceMetadataService', () => { httpRequestService.getJson.mockImplementation(() => { throw Error(); }); const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock'); const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock'); - await fetchInstanceMetadataService.tryLock("example.com"); - await fetchInstanceMetadataService.fetchInstanceMetadata({ host: "example.com" }); + await fetchInstanceMetadataService.tryLock('example.com'); + await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' }); expect(tryLockSpy).toHaveBeenCalledTimes(2); expect(unlockSpy).toHaveBeenCalledTimes(0); expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0); diff --git a/packages/backend/test/unit/FileInfoService.ts b/packages/backend/test/unit/FileInfoService.ts index efb9bdacc3..de0b31488c 100644 --- a/packages/backend/test/unit/FileInfoService.ts +++ b/packages/backend/test/unit/FileInfoService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; @@ -5,12 +10,12 @@ import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; import { ModuleMocker } from 'jest-mock'; import { Test } from '@nestjs/testing'; +import { describe, beforeAll, afterAll, test } from '@jest/globals'; import { GlobalModule } from '@/GlobalModule.js'; import { FileInfoService } from '@/core/FileInfoService.js'; //import { DI } from '@/di-symbols.js'; import { AiService } from '@/core/AiService.js'; import type { TestingModule } from '@nestjs/testing'; -import { describe, beforeAll, afterAll, test } from '@jest/globals'; import type { MockFunctionMetadata } from 'jest-mock'; const _filename = fileURLToPath(import.meta.url); diff --git a/packages/backend/test/unit/MetaService.ts b/packages/backend/test/unit/MetaService.ts index 9efd8bbe70..2b6e52914e 100644 --- a/packages/backend/test/unit/MetaService.ts +++ b/packages/backend/test/unit/MetaService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts index 5496738778..bb8e6981d5 100644 --- a/packages/backend/test/unit/MfmService.ts +++ b/packages/backend/test/unit/MfmService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as assert from 'assert'; import * as mfm from 'mfm-js'; import { Test } from '@nestjs/testing'; diff --git a/packages/backend/test/unit/ReactionService.ts b/packages/backend/test/unit/ReactionService.ts index aa68f4117d..7b5bf7d0a0 100644 --- a/packages/backend/test/unit/ReactionService.ts +++ b/packages/backend/test/unit/ReactionService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as assert from 'assert'; import { Test } from '@nestjs/testing'; diff --git a/packages/backend/test/unit/RelayService.ts b/packages/backend/test/unit/RelayService.ts index 6bf08f5091..ae20acd060 100644 --- a/packages/backend/test/unit/RelayService.ts +++ b/packages/backend/test/unit/RelayService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts index 6979f23e0c..fc6e23382b 100644 --- a/packages/backend/test/unit/RoleService.ts +++ b/packages/backend/test/unit/RoleService.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; diff --git a/packages/backend/test/unit/S3Service.ts b/packages/backend/test/unit/S3Service.ts index 1dfa22afd2..eec8494322 100644 --- a/packages/backend/test/unit/S3Service.ts +++ b/packages/backend/test/unit/S3Service.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import { Test } from '@nestjs/testing'; diff --git a/packages/backend/test/unit/activitypub.ts b/packages/backend/test/unit/activitypub.ts index 78b916c112..73209523b5 100644 --- a/packages/backend/test/unit/activitypub.ts +++ b/packages/backend/test/unit/activitypub.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; @@ -254,6 +259,21 @@ describe('ActivityPub', () => { assert.strictEqual(note.text, 'test test foo'); assert.strictEqual(note.uri, actor2Note.id); }); + + test('Fetch a note that is a featured note of the attributed actor', async () => { + const actor = createRandomActor(); + actor.featured = `${actor.id}/collections/featured`; + + const featured = createRandomFeaturedCollection(actor, 5); + const firstNote = (featured.items as NonTransientIPost[])[0]; + + resolver.register(actor.id, actor); + resolver.register(actor.featured, featured); + resolver.register(firstNote.id, firstNote); + + const note = await noteService.createNote(firstNote.id as string, resolver); + assert.strictEqual(note?.uri, firstNote.id); + }); }); describe('Images', () => { diff --git a/packages/backend/test/unit/ap-request.ts b/packages/backend/test/unit/ap-request.ts index 98f352e1c6..9edd53d274 100644 --- a/packages/backend/test/unit/ap-request.ts +++ b/packages/backend/test/unit/ap-request.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as assert from 'assert'; import httpSignature from '@peertube/http-signature'; diff --git a/packages/backend/test/unit/chart.ts b/packages/backend/test/unit/chart.ts index 40554d3a47..a419083e7d 100644 --- a/packages/backend/test/unit/chart.ts +++ b/packages/backend/test/unit/chart.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + process.env.NODE_ENV = 'test'; import * as assert from 'assert'; diff --git a/packages/backend/test/unit/extract-mentions.ts b/packages/backend/test/unit/extract-mentions.ts index 66d32be1c5..5901f33fdc 100644 --- a/packages/backend/test/unit/extract-mentions.ts +++ b/packages/backend/test/unit/extract-mentions.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as assert from 'assert'; import { parse } from 'mfm-js'; diff --git a/packages/backend/test/unit/misc/check-word-mute.ts b/packages/backend/test/unit/misc/check-word-mute.ts index 7ab838bdee..12bfca8bd7 100644 --- a/packages/backend/test/unit/misc/check-word-mute.ts +++ b/packages/backend/test/unit/misc/check-word-mute.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { checkWordMute } from '@/misc/check-word-mute.js'; describe(checkWordMute, () => { diff --git a/packages/backend/test/unit/misc/correct-filename.ts b/packages/backend/test/unit/misc/correct-filename.ts new file mode 100644 index 0000000000..8138b2361f --- /dev/null +++ b/packages/backend/test/unit/misc/correct-filename.ts @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { correctFilename } from '@/misc/correct-filename.js'; + +describe(correctFilename, () => { + it('no ext to null', () => { + expect(correctFilename('test', null)).toBe('test.unknown'); + }); + it('no ext to jpg', () => { + expect(correctFilename('test', 'jpg')).toBe('test.jpg'); + }); + it('jpg to webp', () => { + expect(correctFilename('test.jpg', 'webp')).toBe('test.jpg.webp'); + }); + it('jpg to .webp', () => { + expect(correctFilename('test.jpg', '.webp')).toBe('test.jpg.webp'); + }); + it('jpeg to jpg', () => { + expect(correctFilename('test.jpeg', 'jpg')).toBe('test.jpeg'); + }); + it('JPEG to jpg', () => { + expect(correctFilename('test.JPEG', 'jpg')).toBe('test.JPEG'); + }); + it('jpg to jpg', () => { + expect(correctFilename('test.jpg', 'jpg')).toBe('test.jpg'); + }); + it('JPG to jpg', () => { + expect(correctFilename('test.JPG', 'jpg')).toBe('test.JPG'); + }); + it('tiff to tif', () => { + expect(correctFilename('test.tiff', 'tif')).toBe('test.tiff'); + }); + it('skip gz', () => { + expect(correctFilename('test.unitypackage', 'gz')).toBe('test.unitypackage'); + }); + it('skip text file', () => { + expect(correctFilename('test.txt', null)).toBe('test.txt'); + }); + it('unknown', () => { + expect(correctFilename('test.hoge', null)).toBe('test.hoge'); + }); + test('non ascii with space', () => { + expect(correctFilename('ファイル 名前', 'jpg')).toBe('ファイル 名前.jpg'); + }); +}); diff --git a/packages/backend/test/unit/misc/id.ts b/packages/backend/test/unit/misc/id.ts index ecd0e60a31..8cc2ea425f 100644 --- a/packages/backend/test/unit/misc/id.ts +++ b/packages/backend/test/unit/misc/id.ts @@ -1,44 +1,49 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ulid } from 'ulid'; +import { describe, test, expect } from '@jest/globals'; import { aidRegExp, genAid, parseAid } from '@/misc/id/aid.js'; import { genMeid, meidRegExp, parseMeid } from '@/misc/id/meid.js'; import { genMeidg, meidgRegExp, parseMeidg } from '@/misc/id/meidg.js'; import { genObjectId, objectIdRegExp, parseObjectId } from '@/misc/id/object-id.js'; import { ulidRegExp, parseUlid } from '@/misc/id/ulid.js'; -import { ulid } from 'ulid'; -import { describe, test, expect } from '@jest/globals'; describe('misc:id', () => { - test('aid', () => { - const date = new Date(); - const gotAid = genAid(date); - expect(gotAid).toMatch(aidRegExp); - expect(parseAid(gotAid).date.getTime()).toBe(date.getTime()); - }); + test('aid', () => { + const date = new Date(); + const gotAid = genAid(date); + expect(gotAid).toMatch(aidRegExp); + expect(parseAid(gotAid).date.getTime()).toBe(date.getTime()); + }); - test('meid', () => { - const date = new Date(); - const gotMeid = genMeid(date); - expect(gotMeid).toMatch(meidRegExp); - expect(parseMeid(gotMeid).date.getTime()).toBe(date.getTime()); - }); + test('meid', () => { + const date = new Date(); + const gotMeid = genMeid(date); + expect(gotMeid).toMatch(meidRegExp); + expect(parseMeid(gotMeid).date.getTime()).toBe(date.getTime()); + }); - test('meidg', () => { - const date = new Date(); - const gotMeidg = genMeidg(date); - expect(gotMeidg).toMatch(meidgRegExp); - expect(parseMeidg(gotMeidg).date.getTime()).toBe(date.getTime()); - }); + test('meidg', () => { + const date = new Date(); + const gotMeidg = genMeidg(date); + expect(gotMeidg).toMatch(meidgRegExp); + expect(parseMeidg(gotMeidg).date.getTime()).toBe(date.getTime()); + }); - test('objectid', () => { - const date = new Date(); - const gotObjectId = genObjectId(date); - expect(gotObjectId).toMatch(objectIdRegExp); - expect(Math.floor(parseObjectId(gotObjectId).date.getTime() / 1000)).toBe(Math.floor(date.getTime() / 1000)); - }); + test('objectid', () => { + const date = new Date(); + const gotObjectId = genObjectId(date); + expect(gotObjectId).toMatch(objectIdRegExp); + expect(Math.floor(parseObjectId(gotObjectId).date.getTime() / 1000)).toBe(Math.floor(date.getTime() / 1000)); + }); - test('ulid', () => { - const date = new Date(); - const gotUlid = ulid(date.getTime()); - expect(gotUlid).toMatch(ulidRegExp); - expect(parseUlid(gotUlid).date.getTime()).toBe(date.getTime()); - }); + test('ulid', () => { + const date = new Date(); + const gotUlid = ulid(date.getTime()); + expect(gotUlid).toMatch(ulidRegExp); + expect(parseUlid(gotUlid).date.getTime()).toBe(date.getTime()); + }); }); diff --git a/packages/backend/test/unit/misc/others.ts b/packages/backend/test/unit/misc/others.ts index c476aef33b..b16d26d866 100644 --- a/packages/backend/test/unit/misc/others.ts +++ b/packages/backend/test/unit/misc/others.ts @@ -1,42 +1,19 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { describe, test, expect } from '@jest/globals'; import { contentDisposition } from '@/misc/content-disposition.js'; -import { correctFilename } from '@/misc/correct-filename.js'; describe('misc:content-disposition', () => { - test('inline', () => { - expect(contentDisposition('inline', 'foo bar')).toBe('inline; filename=\"foo_bar\"; filename*=UTF-8\'\'foo%20bar'); - }); - test('attachment', () => { - expect(contentDisposition('attachment', 'foo bar')).toBe('attachment; filename=\"foo_bar\"; filename*=UTF-8\'\'foo%20bar'); - }); - test('non ascii', () => { - expect(contentDisposition('attachment', 'ファイル名')).toBe('attachment; filename=\"_____\"; filename*=UTF-8\'\'%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D'); - }); -}); - -describe('misc:correct-filename', () => { - test('simple', () => { - expect(correctFilename('filename', 'jpg')).toBe('filename.jpg'); - }); - test('with same ext', () => { - expect(correctFilename('filename.jpg', 'jpg')).toBe('filename.jpg'); - }); - test('.ext', () => { - expect(correctFilename('filename.jpg', '.jpg')).toBe('filename.jpg'); - }); - test('with different ext', () => { - expect(correctFilename('filename.webp', 'jpg')).toBe('filename.webp.jpg'); - }); - test('non ascii with space', () => { - expect(correctFilename('ファイル 名前', 'jpg')).toBe('ファイル 名前.jpg'); - }); - test('jpeg', () => { - expect(correctFilename('filename.jpeg', 'jpg')).toBe('filename.jpeg'); - }); - test('tiff', () => { - expect(correctFilename('filename.tiff', 'tif')).toBe('filename.tiff'); - }); - test('null ext', () => { - expect(correctFilename('filename', null)).toBe('filename.unknown'); - }); + test('inline', () => { + expect(contentDisposition('inline', 'foo bar')).toBe('inline; filename=\"foo_bar\"; filename*=UTF-8\'\'foo%20bar'); + }); + test('attachment', () => { + expect(contentDisposition('attachment', 'foo bar')).toBe('attachment; filename=\"foo_bar\"; filename*=UTF-8\'\'foo%20bar'); + }); + test('non ascii', () => { + expect(contentDisposition('attachment', 'ファイル名')).toBe('attachment; filename=\"_____\"; filename*=UTF-8\'\'%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D'); + }); }); diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index 31ea3e5ab8..0a24a47066 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import { isAbsolute, basename } from 'node:path'; @@ -90,7 +95,7 @@ const request = async (path: string, params: any, me?: UserToken): Promise<{ sta }; }; -const relativeFetch = async (path: string, init?: RequestInit | undefined) => { +export const relativeFetch = async (path: string, init?: RequestInit | undefined) => { return await fetch(new URL(path, `http://127.0.0.1:${port}/`).toString(), init); }; diff --git a/packages/backend/watch.mjs b/packages/backend/watch.mjs index 9c9d2dbd86..81c23a0f50 100644 --- a/packages/backend/watch.mjs +++ b/packages/backend/watch.mjs @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { execa } from 'execa'; (async () => { diff --git a/packages/frontend/.eslintrc.js b/packages/frontend/.eslintrc.js index 24c3ad4b83..77038f0dfa 100644 --- a/packages/frontend/.eslintrc.js +++ b/packages/frontend/.eslintrc.js @@ -21,9 +21,6 @@ module.exports = { 'allowSingleExtends': true, }, ], - '@typescript-eslint/prefer-nullish-coalescing': [ - 'error', - ], // window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため // e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため 'id-denylist': ['error', 'window', 'e'], diff --git a/packages/frontend/@types/global.d.ts b/packages/frontend/@types/global.d.ts index c757482900..390f63990b 100644 --- a/packages/frontend/@types/global.d.ts +++ b/packages/frontend/@types/global.d.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + type FIXME = any; declare const _LANGS_: string[][]; diff --git a/packages/frontend/@types/theme.d.ts b/packages/frontend/@types/theme.d.ts index 67f724a9aa..f4ba42b89d 100644 --- a/packages/frontend/@types/theme.d.ts +++ b/packages/frontend/@types/theme.d.ts @@ -1,5 +1,10 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + declare module '@/themes/*.json5' { - import { Theme } from "@/scripts/theme"; + import { Theme } from '@/scripts/theme'; const theme: Theme; diff --git a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts index 3929bf0608..a7b8cbb037 100644 --- a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts +++ b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { parse } from 'acorn'; import { generate } from 'astring'; import { describe, expect, it } from 'vitest'; diff --git a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.ts b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.ts index a18f0d9049..18c817e0f5 100644 --- a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.ts +++ b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { generate } from 'astring'; import * as estree from 'estree'; import { walk } from '../node_modules/estree-walker/src/index.js'; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 2819f858c1..7d3c8b9767 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -21,9 +21,9 @@ "@rollup/plugin-replace": "5.0.2", "@rollup/pluginutils": "5.0.2", "@syuilo/aiscript": "0.15.0", - "@tabler/icons-webfont": "2.25.0", + "@tabler/icons-webfont": "2.30.0", "@vitejs/plugin-vue": "4.2.3", - "@vue-macros/reactivity-transform": "0.3.15", + "@vue-macros/reactivity-transform": "0.3.16", "@vue/compiler-sfc": "3.3.4", "astring": "1.8.6", "autosize": "6.0.1", @@ -31,13 +31,13 @@ "browser-image-resizer": "github:misskey-dev/browser-image-resizer#v2.2.1-misskey.3", "buraha": "0.0.1", "canvas-confetti": "1.6.0", - "chart.js": "4.3.0", + "chart.js": "4.3.2", "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": "6.19.9", - "compare-versions": "5.0.3", + "compare-versions": "6.0.0", "cropperjs": "2.0.0-beta.3", "date-fns": "2.30.0", "escape-regexp": "0.0.1", @@ -55,14 +55,14 @@ "prismjs": "1.29.0", "punycode": "2.3.0", "querystring": "0.2.1", - "rollup": "3.26.3", + "rollup": "3.27.0", "s-age": "1.1.2", "sanitize-html": "2.11.0", - "sass": "1.63.6", + "sass": "1.64.1", "strict-event-emitter-types": "2.0.0", "syuilo-password-strength": "0.0.1", "textarea-caret": "3.1.0", - "three": "0.154.0", + "three": "0.155.0", "throttle-debounce": "5.0.0", "tinycolor2": "1.6.0", "tsc-alias": "1.8.7", @@ -71,7 +71,7 @@ "typescript": "5.1.6", "uuid": "9.0.0", "vanilla-tilt": "1.8.0", - "vite": "4.4.4", + "vite": "4.4.7", "vue": "3.3.4", "vue-prism-editor": "2.0.0-alpha.2", "vuedraggable": "next" @@ -103,29 +103,29 @@ "@types/gulp-rename": "2.0.2", "@types/matter-js": "0.18.5", "@types/micromatch": "4.0.2", - "@types/node": "20.4.2", + "@types/node": "20.4.5", "@types/punycode": "2.1.0", "@types/sanitize-html": "2.9.0", - "@types/testing-library__jest-dom": "5.14.8", + "@types/testing-library__jest-dom": "5.14.9", "@types/throttle-debounce": "5.0.0", "@types/tinycolor2": "1.4.3", "@types/uuid": "9.0.2", "@types/websocket": "1.0.5", "@types/ws": "8.5.5", - "@typescript-eslint/eslint-plugin": "5.61.0", - "@typescript-eslint/parser": "5.61.0", + "@typescript-eslint/eslint-plugin": "6.2.0", + "@typescript-eslint/parser": "6.2.0", "@vitest/coverage-v8": "0.33.0", "@vue/runtime-core": "3.3.4", "acorn": "8.10.0", "cross-env": "7.0.3", - "cypress": "12.17.1", - "eslint": "8.45.0", - "eslint-plugin-import": "2.27.5", - "eslint-plugin-vue": "9.15.1", - "fast-glob": "3.3.0", + "cypress": "12.17.2", + "eslint": "8.46.0", + "eslint-plugin-import": "2.28.0", + "eslint-plugin-vue": "9.16.1", + "fast-glob": "3.3.1", "happy-dom": "10.0.3", "micromatch": "4.0.5", - "msw": "1.2.2", + "msw": "1.2.3", "msw-storybook-addon": "1.8.0", "nodemon": "3.0.1", "prettier": "3.0.0", @@ -139,6 +139,6 @@ "vitest": "0.33.0", "vitest-fetch-mock": "0.2.2", "vue-eslint-parser": "9.3.1", - "vue-tsc": "1.8.5" + "vue-tsc": "1.8.8" } } diff --git a/packages/frontend/public/mockServiceWorker.js b/packages/frontend/public/mockServiceWorker.js index e915a1eb08..5384ce6b94 100644 --- a/packages/frontend/public/mockServiceWorker.js +++ b/packages/frontend/public/mockServiceWorker.js @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /* eslint-disable */ /* tslint:disable */ diff --git a/packages/frontend/src/_boot_.ts b/packages/frontend/src/_boot_.ts index 921c161765..a397e57ad3 100644 --- a/packages/frontend/src/_boot_.ts +++ b/packages/frontend/src/_boot_.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + // https://vitejs.dev/config/build-options.html#build-modulepreload import 'vite/modulepreload-polyfill'; diff --git a/packages/frontend/src/account.ts b/packages/frontend/src/account.ts index 4770f616ac..634084c750 100644 --- a/packages/frontend/src/account.ts +++ b/packages/frontend/src/account.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { defineAsyncComponent, reactive, ref } from 'vue'; import * as misskey from 'misskey-js'; import { showSuspendedDialog } from './scripts/show-suspended-dialog'; @@ -91,7 +96,6 @@ export async function removeAccount(idOrToken: Account['id']) { function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Promise { return new Promise((done, fail) => { - // Fetch user window.fetch(`${apiUrl}/i`, { method: 'POST', body: JSON.stringify({ @@ -103,8 +107,8 @@ function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Pr }) .then(res => new Promise }>((done2, fail2) => { if (res.status >= 500 && res.status < 600) { - // サーバーエラー(5xx)の場合をrejectとする - // (認証エラーなど4xxはresolve) + // サーバーエラー(5xx)の場合をrejectとする + // (認証エラーなど4xxはresolve) return fail2(res); } res.json().then(done2, fail2); @@ -112,13 +116,13 @@ function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Pr .then(async res => { if (res.error) { if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') { - // SUSPENDED + // SUSPENDED if (forceShowDialog || $i && (token === $i.token || id === $i.id)) { await showSuspendedDialog(); } } else if (res.error.id === 'e5b3b9f0-2b8f-4b9f-9c1f-8c5c1b2e1b1a') { - // USER_IS_DELETED - // アカウントが削除されている + // USER_IS_DELETED + // アカウントが削除されている if (forceShowDialog || $i && (token === $i.token || id === $i.id)) { await alert({ type: 'error', @@ -127,8 +131,8 @@ function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Pr }); } } else if (res.error.id === 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14') { - // AUTHENTICATION_FAILED - // トークンが無効化されていたりアカウントが削除されたりしている + // AUTHENTICATION_FAILED + // トークンが無効化されていたりアカウントが削除されたりしている if (forceShowDialog || $i && (token === $i.token || id === $i.id)) { await alert({ type: 'error', diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index e1b12fe7d6..8f5de88ccd 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { computed, createApp, watch, markRaw, version as vueVersion, defineAsyncComponent, App } from 'vue'; import { compareVersions } from 'compare-versions'; import widgets from '@/widgets'; diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts index 0a351cd6e3..9ab1f6e14c 100644 --- a/packages/frontend/src/boot/main-boot.ts +++ b/packages/frontend/src/boot/main-boot.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { computed, createApp, watch, markRaw, version as vueVersion, defineAsyncComponent } from 'vue'; import { common } from './common'; import { version, ui, lang, updateLocale } from '@/config'; @@ -78,6 +83,21 @@ export async function mainBoot() { } }); + for (const announcement of ($i.unreadAnnouncements ?? []).filter(x => x.display === 'dialog')) { + popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), { + announcement, + }, {}, 'closed'); + } + + stream.on('announcementCreated', (ev) => { + const announcement = ev.announcement; + if (announcement.display === 'dialog') { + popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), { + announcement, + }, {}, 'closed'); + } + }); + if ($i.isDeleted) { alert({ type: 'warning', diff --git a/packages/frontend/src/boot/sub-boot.ts b/packages/frontend/src/boot/sub-boot.ts index c2664f6c1d..2cc19f2df3 100644 --- a/packages/frontend/src/boot/sub-boot.ts +++ b/packages/frontend/src/boot/sub-boot.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { computed, createApp, watch, markRaw, version as vueVersion, defineAsyncComponent } from 'vue'; import { common } from './common'; diff --git a/packages/frontend/src/cache.ts b/packages/frontend/src/cache.ts index cb315c8ff7..7e5eaf09ad 100644 --- a/packages/frontend/src/cache.ts +++ b/packages/frontend/src/cache.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import * as misskey from 'misskey-js'; import { Cache } from '@/scripts/cache'; diff --git a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts index 7d27adeb04..3b64529620 100644 --- a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts +++ b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { action } from '@storybook/addon-actions'; import { StoryObj } from '@storybook/vue3'; diff --git a/packages/frontend/src/components/MkAbuseReport.vue b/packages/frontend/src/components/MkAbuseReport.vue index dee80378e6..cb97875bcd 100644 --- a/packages/frontend/src/components/MkAbuseReport.vue +++ b/packages/frontend/src/components/MkAbuseReport.vue @@ -1,7 +1,12 @@ + +