Compare commits
35 Commits
2024.5.0-b
...
2024.5.0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6078081c33 | ||
![]() |
a59aa20be8 | ||
![]() |
61eec93f4e | ||
![]() |
27d1b7e615 | ||
![]() |
316d192bc0 | ||
![]() |
46164f879b | ||
![]() |
374c8791d7 | ||
![]() |
e8f523f00a | ||
![]() |
030082f756 | ||
![]() |
dc55adbaf7 | ||
![]() |
90ba1ca1f9 | ||
![]() |
514a65e453 | ||
![]() |
a3468fd05b | ||
![]() |
97be1a53ad | ||
![]() |
1e007b63aa | ||
![]() |
a0c596b030 | ||
![]() |
eaa85f5aa3 | ||
![]() |
dfeaa1145b | ||
![]() |
0082747237 | ||
![]() |
5b8f8e7087 | ||
![]() |
be11fd7508 | ||
![]() |
ac4a001e9f | ||
![]() |
24d4124ffc | ||
![]() |
eaadd643eb | ||
![]() |
cf670e8a3d | ||
![]() |
e57ce4fa0f | ||
![]() |
44cafbb9f2 | ||
![]() |
f75e46752e | ||
![]() |
244adef70e | ||
![]() |
e2eb7e8ca9 | ||
![]() |
80f3cb96b0 | ||
![]() |
89b27d8587 | ||
![]() |
1bb1a32986 | ||
![]() |
de9e391e34 | ||
![]() |
934f9f80bd |
@@ -106,7 +106,7 @@ redis:
|
||||
# ┌───────────────────────────┐
|
||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||
|
||||
# You can set scope to local (default value) or global
|
||||
# You can set scope to local (default value) or global
|
||||
# (include notes from remote).
|
||||
|
||||
#meilisearch:
|
||||
@@ -136,6 +136,21 @@ redis:
|
||||
|
||||
id: 'aidx'
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
@@ -185,7 +200,7 @@ proxyRemoteFiles: true
|
||||
signToActivityPubGet: true
|
||||
|
||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
||||
#allowedPrivateNetworks: [
|
||||
# '127.0.0.1/32'
|
||||
|
@@ -205,6 +205,21 @@ redis:
|
||||
|
||||
id: 'aidx'
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
|
@@ -132,6 +132,21 @@ redis:
|
||||
|
||||
id: 'aidx'
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
|
2
.github/workflows/release-edit-with-push.yml
vendored
2
.github/workflows/release-edit-with-push.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
# headがrelease/かつopenのPRを1つ取得
|
||||
- name: Get PR
|
||||
run: |
|
||||
echo "pr_number=$(gh pr list --limit 1 --head "${{ github.ref_name }}" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
||||
echo "pr_number=$(gh pr list --limit 1 --head "$GITHUB_REF_NAME" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
||||
id: get_pr
|
||||
- name: Get target version
|
||||
uses: misskey-dev/release-manager-actions/.github/actions/get-target-version@v1
|
||||
|
4
.github/workflows/release-with-ready.yml
vendored
4
.github/workflows/release-with-ready.yml
vendored
@@ -22,9 +22,11 @@ jobs:
|
||||
# PR情報を取得
|
||||
- name: Get PR
|
||||
run: |
|
||||
pr_json=$(gh pr view ${{ github.event.pull_request.number }} --json isDraft,headRefName)
|
||||
pr_json=$(gh pr view "$PR_NUMBER" --json isDraft,headRefName)
|
||||
echo "ref=$(echo $pr_json | jq -r '.headRefName')" >> $GITHUB_OUTPUT
|
||||
id: get_pr
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
release:
|
||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-prerelease.yml@v1
|
||||
needs: check
|
||||
|
@@ -6,6 +6,7 @@
|
||||
- 管理者向け権限 `read:admin:show-users` は `read:admin:show-user` に統合されました。必要に応じてAPIトークンを再発行してください。
|
||||
|
||||
### General
|
||||
- Feat: エラートラッキングにSentryを使用できるようになりました
|
||||
- Enhance: URLプレビューの有効化・無効化を設定できるように #13569
|
||||
- Enhance: アンテナでBotによるノートを除外できるように
|
||||
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/545)
|
||||
@@ -19,6 +20,7 @@
|
||||
- Enhance: Goneを出さずに終了したサーバーへの配信停止を自動的に行うように
|
||||
- もしそのようなサーバーからから配信が届いた場合には自動的に配信を再開します
|
||||
- Enhance: 配信停止の理由を表示するように
|
||||
- Enhance: サーバーのお問い合わせ先URLを設定できるようになりました
|
||||
- Fix: Play作成時に設定した公開範囲が機能していない問題を修正
|
||||
- Fix: 正規化されていない状態のhashtagが連合されてきたhtmlに含まれているとhashtagが正しくhashtagに復元されない問題を修正
|
||||
- Fix: みつけるのアンケート欄にてチャンネルのアンケートが含まれてしまう問題を修正
|
||||
@@ -26,7 +28,7 @@
|
||||
### Client
|
||||
- Feat: アップロードするファイルの名前をランダム文字列にできるように
|
||||
- Feat: 個別のお知らせにリンクで飛べるように
|
||||
(Cherry-picked from https://github.com/MisskeyIO/misskey)
|
||||
(Based on https://github.com/MisskeyIO/misskey/pull/639)
|
||||
- Enhance: 自分のノートの添付ファイルから直接ファイルの詳細ページに飛べるように
|
||||
- Enhance: 広告がMisskeyと同一ドメインの場合はRouterで遷移するように
|
||||
- Enhance: リアクション・いいねの総数を表示するように
|
||||
@@ -72,6 +74,7 @@
|
||||
- Fix: 通知をグループ化している際に、人数が正常に表示されないことがある問題を修正
|
||||
- Fix: 連合なしの状態の読み書きができない問題を修正
|
||||
- Fix: `/share` で日本語等を含むurlがurlエンコードされない問題を修正
|
||||
- Fix: ファイルを5つ以上添付してもテキストがないとノートが折りたたまれない問題を修正
|
||||
|
||||
### Server
|
||||
- Enhance: エンドポイント`antennas/update`の必須項目を`antennaId`のみに
|
||||
|
@@ -152,6 +152,22 @@ redis:
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: "aidx"
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
|
12
locales/index.d.ts
vendored
12
locales/index.d.ts
vendored
@@ -3364,6 +3364,10 @@ export interface Locale extends ILocale {
|
||||
* 管理者情報が設定されていません。
|
||||
*/
|
||||
"noMaintainerInformationWarning": string;
|
||||
/**
|
||||
* 問い合わせ先URLが設定されていません。
|
||||
*/
|
||||
"noInquiryUrlWarning": string;
|
||||
/**
|
||||
* Botプロテクションが設定されていません。
|
||||
*/
|
||||
@@ -5471,6 +5475,14 @@ export interface Locale extends ILocale {
|
||||
* 有効にすると、タイムラインがキャッシュされていない場合にDBへ追加で問い合わせを行うフォールバック処理を行います。無効にすると、フォールバック処理を行わないことでさらにサーバーの負荷を軽減することができますが、タイムラインが取得できる範囲に制限が生じます。
|
||||
*/
|
||||
"fanoutTimelineDbFallbackDescription": string;
|
||||
/**
|
||||
* 問い合わせ先URL
|
||||
*/
|
||||
"inquiryUrl": string;
|
||||
/**
|
||||
* サーバー運営者へのお問い合わせフォームのURLや、運営者の連絡先等が記載されたWebページのURLを指定します。
|
||||
*/
|
||||
"inquiryUrlDescription": string;
|
||||
};
|
||||
"_accountMigration": {
|
||||
/**
|
||||
|
@@ -837,6 +837,7 @@ administration: "管理"
|
||||
accounts: "アカウント"
|
||||
switch: "切り替え"
|
||||
noMaintainerInformationWarning: "管理者情報が設定されていません。"
|
||||
noInquiryUrlWarning: "問い合わせ先URLが設定されていません。"
|
||||
noBotProtectionWarning: "Botプロテクションが設定されていません。"
|
||||
configure: "設定する"
|
||||
postToGallery: "ギャラリーへ投稿"
|
||||
@@ -1383,6 +1384,8 @@ _serverSettings:
|
||||
fanoutTimelineDescription: "有効にすると、各種タイムラインを取得する際のパフォーマンスが大幅に向上し、データベースへの負荷を軽減することが可能です。ただし、Redisのメモリ使用量は増加します。サーバーのメモリ容量が少ない場合、または動作が不安定な場合は無効にすることができます。"
|
||||
fanoutTimelineDbFallback: "データベースへのフォールバック"
|
||||
fanoutTimelineDbFallbackDescription: "有効にすると、タイムラインがキャッシュされていない場合にDBへ追加で問い合わせを行うフォールバック処理を行います。無効にすると、フォールバック処理を行わないことでさらにサーバーの負荷を軽減することができますが、タイムラインが取得できる範囲に制限が生じます。"
|
||||
inquiryUrl: "問い合わせ先URL"
|
||||
inquiryUrlDescription: "サーバー運営者へのお問い合わせフォームのURLや、運営者の連絡先等が記載されたWebページのURLを指定します。"
|
||||
|
||||
_accountMigration:
|
||||
moveFrom: "別のアカウントからこのアカウントに移行"
|
||||
|
@@ -316,6 +316,7 @@ selectFile: "选择文件"
|
||||
selectFiles: "选择文件"
|
||||
selectFolder: "选择文件夹"
|
||||
selectFolders: "选择多个文件夹"
|
||||
fileNotSelected: "未选择文件"
|
||||
renameFile: "重命名文件"
|
||||
folderName: "文件夹名称"
|
||||
createFolder: "创建文件夹"
|
||||
@@ -2358,6 +2359,7 @@ _deck:
|
||||
alwaysShowMainColumn: "总是显示主列"
|
||||
columnAlign: "列对齐"
|
||||
addColumn: "添加列"
|
||||
newNoteNotificationSettings: "新帖子通知设定"
|
||||
configureColumn: "列设置"
|
||||
swapLeft: "向左移动"
|
||||
swapRight: "向右移动"
|
||||
|
@@ -316,6 +316,7 @@ selectFile: "選擇檔案"
|
||||
selectFiles: "選擇檔案"
|
||||
selectFolder: "選擇資料夾"
|
||||
selectFolders: "選擇資料夾"
|
||||
fileNotSelected: "尚未選擇檔案"
|
||||
renameFile: "重新命名檔案"
|
||||
folderName: "資料夾名稱"
|
||||
createFolder: "新增資料夾"
|
||||
@@ -471,7 +472,7 @@ retype: "重新輸入"
|
||||
noteOf: "{user}的貼文"
|
||||
quoteAttached: "引用"
|
||||
quoteQuestion: "是否要引用?"
|
||||
attachAsFileQuestion: "剪貼簿的文字較長。請問是否要改成附加檔案呢?"
|
||||
attachAsFileQuestion: "剪貼簿的文字較長。請問是否要將其以文字檔的方式附加呢?"
|
||||
noMessagesYet: "沒有訊息"
|
||||
newMessageExists: "有新的訊息"
|
||||
onlyOneFileCanBeAttached: "只能加入一個附件"
|
||||
@@ -1025,6 +1026,7 @@ thisPostMayBeAnnoyingHome: "發佈到首頁"
|
||||
thisPostMayBeAnnoyingCancel: "退出"
|
||||
thisPostMayBeAnnoyingIgnore: "直接發佈貼文"
|
||||
collapseRenotes: "省略顯示已看過的轉發貼文"
|
||||
collapseRenotesDescription: "將已做過反應和轉發的貼文折疊顯示。"
|
||||
internalServerError: "內部伺服器錯誤"
|
||||
internalServerErrorDescription: "內部伺服器出現意外錯誤。"
|
||||
copyErrorInfo: "複製錯誤資訊"
|
||||
@@ -1241,8 +1243,8 @@ alwaysConfirmFollow: "點擊追隨時總是顯示確認訊息"
|
||||
inquiry: "聯絡我們"
|
||||
_delivery:
|
||||
status: "傳送狀態"
|
||||
stop: "已凍結"
|
||||
resume: "繼續傳送"
|
||||
stop: "停止傳送"
|
||||
resume: "恢復傳送"
|
||||
_type:
|
||||
none: "直播中"
|
||||
manuallySuspended: "手動暫停中"
|
||||
@@ -1373,6 +1375,8 @@ _serverSettings:
|
||||
fanoutTimelineDescription: "如果啟用的話,檢索各個時間軸的性能會顯著提昇,資料庫的負荷也會減少。不過,Redis 的記憶體使用量會增加。如果伺服器的記憶體容量比較少或者運行不穩定,可以停用。"
|
||||
fanoutTimelineDbFallback: "資料庫的回退"
|
||||
fanoutTimelineDbFallbackDescription: "若啟用,在時間軸沒有快取的情況下將執行回退處理以額外查詢資料庫。若停用,可以透過不執行回退處理來進一步減少伺服器的負荷,但會限制可取得的時間軸範圍。"
|
||||
inquiryUrl: "聯絡表單網址"
|
||||
inquiryUrlDescription: "指定伺服器運營者的聯絡表單網址或包含運營者聯絡資訊網頁的網址。"
|
||||
_accountMigration:
|
||||
moveFrom: "從其他帳戶遷移到這個帳戶"
|
||||
moveFromSub: "為另一個帳戶建立別名"
|
||||
@@ -2358,6 +2362,7 @@ _deck:
|
||||
alwaysShowMainColumn: "總是顯示主欄"
|
||||
columnAlign: "對齊欄位"
|
||||
addColumn: "新增欄位"
|
||||
newNoteNotificationSettings: "新貼文通知的設定"
|
||||
configureColumn: "欄位的設定"
|
||||
swapLeft: "向左移動"
|
||||
swapRight: "向右移動"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"version": "2024.5.0-beta.5",
|
||||
"version": "2024.5.0",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
16
packages/backend/migration/1717117195275-inquiryUrl.js
Normal file
16
packages/backend/migration/1717117195275-inquiryUrl.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class InquiryUrl1717117195275 {
|
||||
name = 'InquiryUrl1717117195275'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "inquiryUrl" character varying(1024)`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "inquiryUrl"`);
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=20.10.0"
|
||||
"node": "^20.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node ./built/boot/entry.js",
|
||||
@@ -86,6 +86,8 @@
|
||||
"@nestjs/core": "10.3.8",
|
||||
"@nestjs/testing": "10.3.8",
|
||||
"@peertube/http-signature": "1.7.0",
|
||||
"@sentry/node": "^8.5.0",
|
||||
"@sentry/profiling-node": "^8.5.0",
|
||||
"@simplewebauthn/server": "10.0.0",
|
||||
"@sinonjs/fake-timers": "11.2.2",
|
||||
"@smithy/node-http-handler": "2.5.0",
|
||||
|
@@ -10,6 +10,8 @@ import * as os from 'node:os';
|
||||
import cluster from 'node:cluster';
|
||||
import chalk from 'chalk';
|
||||
import chalkTemplate from 'chalk-template';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { nodeProfilingIntegration } from '@sentry/profiling-node';
|
||||
import Logger from '@/logger.js';
|
||||
import { loadConfig } from '@/config.js';
|
||||
import type { Config } from '@/config.js';
|
||||
@@ -71,6 +73,24 @@ export async function masterMain() {
|
||||
|
||||
bootLogger.succ('Misskey initialized');
|
||||
|
||||
if (config.sentryForBackend) {
|
||||
Sentry.init({
|
||||
integrations: [
|
||||
...(config.sentryForBackend.enableNodeProfiling ? [nodeProfilingIntegration()] : []),
|
||||
],
|
||||
|
||||
// Performance Monitoring
|
||||
tracesSampleRate: 1.0, // Capture 100% of the transactions
|
||||
|
||||
// Set sampling rate for profiling - this is relative to tracesSampleRate
|
||||
profilesSampleRate: 1.0,
|
||||
|
||||
maxBreadcrumbs: 0,
|
||||
|
||||
...config.sentryForBackend.options,
|
||||
});
|
||||
}
|
||||
|
||||
if (envOption.disableClustering) {
|
||||
if (envOption.onlyServer) {
|
||||
await server();
|
||||
|
@@ -7,6 +7,7 @@ import * as fs from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import type { RedisOptions } from 'ioredis';
|
||||
|
||||
type RedisOptionsSource = Partial<RedisOptions> & {
|
||||
@@ -56,6 +57,8 @@ type Source = {
|
||||
index: string;
|
||||
scope?: 'local' | 'global' | string[];
|
||||
};
|
||||
sentryForBackend?: { options: Partial<Sentry.NodeOptions>; enableNodeProfiling: boolean; };
|
||||
sentryForFrontend?: { options: Partial<Sentry.NodeOptions> };
|
||||
|
||||
publishTarballInsteadOfProvideRepositoryUrl?: boolean;
|
||||
|
||||
@@ -166,6 +169,8 @@ export type Config = {
|
||||
redisForPubsub: RedisOptions & RedisOptionsSource;
|
||||
redisForJobQueue: RedisOptions & RedisOptionsSource;
|
||||
redisForTimelines: RedisOptions & RedisOptionsSource;
|
||||
sentryForBackend: { options: Partial<Sentry.NodeOptions>; enableNodeProfiling: boolean; } | undefined;
|
||||
sentryForFrontend: { options: Partial<Sentry.NodeOptions> } | undefined;
|
||||
perChannelMaxNoteCacheCount: number;
|
||||
perUserNotificationsMaxCount: number;
|
||||
deactivateAntennaThreshold: number;
|
||||
@@ -234,6 +239,8 @@ export function loadConfig(): Config {
|
||||
redisForPubsub: config.redisForPubsub ? convertRedisOptions(config.redisForPubsub, host) : redis,
|
||||
redisForJobQueue: config.redisForJobQueue ? convertRedisOptions(config.redisForJobQueue, host) : redis,
|
||||
redisForTimelines: config.redisForTimelines ? convertRedisOptions(config.redisForTimelines, host) : redis,
|
||||
sentryForBackend: config.sentryForBackend,
|
||||
sentryForFrontend: config.sentryForFrontend,
|
||||
id: config.id,
|
||||
proxy: config.proxy,
|
||||
proxySmtp: config.proxySmtp,
|
||||
|
@@ -346,10 +346,11 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
||||
@bindThis
|
||||
public async populateEmojis(emojiNames: string[], noteUserHost: string | null): Promise<Record<string, string>> {
|
||||
const emojis = await Promise.all(emojiNames.map(x => this.populateEmoji(x, noteUserHost)));
|
||||
const res = {} as any;
|
||||
const res = {} as Record<string, string>;
|
||||
for (let i = 0; i < emojiNames.length; i++) {
|
||||
if (emojis[i] != null) {
|
||||
res[emojiNames[i]] = emojis[i];
|
||||
const resolvedEmoji = emojis[i];
|
||||
if (resolvedEmoji != null) {
|
||||
res[emojiNames[i]] = resolvedEmoji;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@@ -497,20 +497,20 @@ export class DriveService {
|
||||
|
||||
if (user && !force) {
|
||||
// Check if there is a file with the same hash
|
||||
const much = await this.driveFilesRepository.findOneBy({
|
||||
const matched = await this.driveFilesRepository.findOneBy({
|
||||
md5: info.md5,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (much) {
|
||||
this.registerLogger.info(`file with same hash is found: ${much.id}`);
|
||||
if (sensitive && !much.isSensitive) {
|
||||
if (matched) {
|
||||
this.registerLogger.info(`file with same hash is found: ${matched.id}`);
|
||||
if (sensitive && !matched.isSensitive) {
|
||||
// The file is federated as sensitive for this time, but was federated as non-sensitive before.
|
||||
// Therefore, update the file to sensitive.
|
||||
await this.driveFilesRepository.update({ id: much.id }, { isSensitive: true });
|
||||
much.isSensitive = true;
|
||||
await this.driveFilesRepository.update({ id: matched.id }, { isSensitive: true });
|
||||
matched.isSensitive = true;
|
||||
}
|
||||
return much;
|
||||
return matched;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -154,7 +154,7 @@ export class FetchInstanceMetadataService {
|
||||
throw new Error('No wellknown links');
|
||||
}
|
||||
|
||||
const links = wellknown.links as any[];
|
||||
const links = wellknown.links as ({ rel: string, href: string; })[];
|
||||
|
||||
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');
|
||||
|
@@ -28,6 +28,7 @@ import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserR
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { MiRemoteUser } from '@/models/User.js';
|
||||
import { isNotNull } from '@/misc/is-not-null.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { 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';
|
||||
@@ -36,9 +37,8 @@ import { ApResolverService } from './ApResolverService.js';
|
||||
import { ApAudienceService } from './ApAudienceService.js';
|
||||
import { ApPersonService } from './models/ApPersonService.js';
|
||||
import { ApQuestionService } from './models/ApQuestionService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import type { Resolver } from './ApResolverService.js';
|
||||
import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove } from './type.js';
|
||||
import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IReject, IRemove, IUndo, IUpdate, IMove, IPost } from './type.js';
|
||||
|
||||
@Injectable()
|
||||
export class ApInboxService {
|
||||
@@ -90,13 +90,15 @@ export class ApInboxService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async performActivity(actor: MiRemoteUser, activity: IObject): Promise<void> {
|
||||
public async performActivity(actor: MiRemoteUser, activity: IObject): Promise<string | void> {
|
||||
let result = undefined as string | void;
|
||||
if (isCollectionOrOrderedCollection(activity)) {
|
||||
const results = [] as [string, string | void][];
|
||||
const resolver = this.apResolverService.createResolver();
|
||||
for (const item of toArray(isCollection(activity) ? activity.items : activity.orderedItems)) {
|
||||
const act = await resolver.resolve(item);
|
||||
try {
|
||||
await this.performOneActivity(actor, act);
|
||||
results.push([getApId(item), await this.performOneActivity(actor, act)]);
|
||||
} catch (err) {
|
||||
if (err instanceof Error || typeof err === 'string') {
|
||||
this.logger.error(err);
|
||||
@@ -105,8 +107,13 @@ export class ApInboxService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hasReason = results.some(([, reason]) => (reason != null && !reason.startsWith('ok')));
|
||||
if (hasReason) {
|
||||
result = results.map(([id, reason]) => `${id}: ${reason}`).join('\n');
|
||||
}
|
||||
} else {
|
||||
await this.performOneActivity(actor, activity);
|
||||
result = await this.performOneActivity(actor, activity);
|
||||
}
|
||||
|
||||
// ついでにリモートユーザーの情報が古かったら更新しておく
|
||||
@@ -117,42 +124,43 @@ export class ApInboxService {
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise<void> {
|
||||
public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise<string | void> {
|
||||
if (actor.isSuspended) return;
|
||||
|
||||
if (isCreate(activity)) {
|
||||
await this.create(actor, activity);
|
||||
return await this.create(actor, activity);
|
||||
} else if (isDelete(activity)) {
|
||||
await this.delete(actor, activity);
|
||||
return await this.delete(actor, activity);
|
||||
} else if (isUpdate(activity)) {
|
||||
await this.update(actor, activity);
|
||||
return await this.update(actor, activity);
|
||||
} else if (isFollow(activity)) {
|
||||
await this.follow(actor, activity);
|
||||
return await this.follow(actor, activity);
|
||||
} else if (isAccept(activity)) {
|
||||
await this.accept(actor, activity);
|
||||
return await this.accept(actor, activity);
|
||||
} else if (isReject(activity)) {
|
||||
await this.reject(actor, activity);
|
||||
return await this.reject(actor, activity);
|
||||
} else if (isAdd(activity)) {
|
||||
await this.add(actor, activity).catch(err => this.logger.error(err));
|
||||
return await this.add(actor, activity);
|
||||
} else if (isRemove(activity)) {
|
||||
await this.remove(actor, activity).catch(err => this.logger.error(err));
|
||||
return await this.remove(actor, activity);
|
||||
} else if (isAnnounce(activity)) {
|
||||
await this.announce(actor, activity);
|
||||
return await this.announce(actor, activity);
|
||||
} else if (isLike(activity)) {
|
||||
await this.like(actor, activity);
|
||||
return await this.like(actor, activity);
|
||||
} else if (isUndo(activity)) {
|
||||
await this.undo(actor, activity);
|
||||
return await this.undo(actor, activity);
|
||||
} else if (isBlock(activity)) {
|
||||
await this.block(actor, activity);
|
||||
return await this.block(actor, activity);
|
||||
} else if (isFlag(activity)) {
|
||||
await this.flag(actor, activity);
|
||||
return await this.flag(actor, activity);
|
||||
} else if (isMove(activity)) {
|
||||
await this.move(actor, activity);
|
||||
return await this.move(actor, activity);
|
||||
} else {
|
||||
this.logger.warn(`unrecognized activity type: ${activity.type}`);
|
||||
return `unrecognized activity type: ${activity.type}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,38 +242,49 @@ export class ApInboxService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async add(actor: MiRemoteUser, activity: IAdd): Promise<void> {
|
||||
private async add(actor: MiRemoteUser, activity: IAdd): Promise<string | void> {
|
||||
if (actor.uri !== activity.actor) {
|
||||
throw new Error('invalid actor');
|
||||
return 'invalid actor';
|
||||
}
|
||||
|
||||
if (activity.target == null) {
|
||||
throw new Error('target is null');
|
||||
return 'target is null';
|
||||
}
|
||||
|
||||
if (activity.target === actor.featured) {
|
||||
const note = await this.apNoteService.resolveNote(activity.object);
|
||||
if (note == null) throw new Error('note not found');
|
||||
if (note == null) return 'note not found';
|
||||
await this.notePiningService.addPinned(actor, note.id);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(`unknown target: ${activity.target}`);
|
||||
return `unknown target: ${activity.target}`;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise<void> {
|
||||
private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise<string | void> {
|
||||
const uri = getApId(activity);
|
||||
|
||||
this.logger.info(`Announce: ${uri}`);
|
||||
|
||||
const targetUri = getApId(activity.object);
|
||||
const resolver = this.apResolverService.createResolver();
|
||||
|
||||
await this.announceNote(actor, activity, targetUri);
|
||||
if (!activity.object) return 'skip: activity has no object property';
|
||||
const targetUri = getApId(activity.object);
|
||||
if (targetUri.startsWith('bear:')) return 'skip: bearcaps url not supported.';
|
||||
|
||||
const target = await resolver.resolve(activity.object).catch(e => {
|
||||
this.logger.error(`Resolution failed: ${e}`);
|
||||
return e;
|
||||
});
|
||||
|
||||
if (isPost(target)) return await this.announceNote(actor, activity, target);
|
||||
|
||||
return `skip: unknown object type ${getApType(target)}`;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise<void> {
|
||||
private async announceNote(actor: MiRemoteUser, activity: IAnnounce, target: IPost): Promise<string | void> {
|
||||
const uri = getApId(activity);
|
||||
|
||||
if (actor.isSuspended) {
|
||||
@@ -288,24 +307,21 @@ export class ApInboxService {
|
||||
// Announce対象をresolve
|
||||
let renote;
|
||||
try {
|
||||
renote = await this.apNoteService.resolveNote(targetUri);
|
||||
if (renote == null) throw new Error('announce target is null');
|
||||
renote = await this.apNoteService.resolveNote(target);
|
||||
if (renote == null) return 'announce target is null';
|
||||
} catch (err) {
|
||||
// 対象が4xxならスキップ
|
||||
if (err instanceof StatusError) {
|
||||
if (!err.isRetryable) {
|
||||
this.logger.warn(`Ignored announce target ${targetUri} - ${err.statusCode}`);
|
||||
return;
|
||||
return `Ignored announce target ${target.id} - ${err.statusCode}`;
|
||||
}
|
||||
|
||||
this.logger.warn(`Error in announce target ${targetUri} - ${err.statusCode}`);
|
||||
return `Error in announce target ${target.id} - ${err.statusCode}`;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (!await this.noteEntityService.isVisibleForMe(renote, actor.id)) {
|
||||
this.logger.warn('skip: invalid actor for this activity');
|
||||
return;
|
||||
return 'skip: invalid actor for this activity';
|
||||
}
|
||||
|
||||
this.logger.info(`Creating the (Re)Note: ${uri}`);
|
||||
@@ -314,8 +330,7 @@ export class ApInboxService {
|
||||
const createdAt = activity.published ? new Date(activity.published) : null;
|
||||
|
||||
if (createdAt && createdAt < this.idService.parse(renote.id).date) {
|
||||
this.logger.warn('skip: malformed createdAt');
|
||||
return;
|
||||
return 'skip: malformed createdAt';
|
||||
}
|
||||
|
||||
await this.noteCreateService.create(actor, {
|
||||
@@ -349,11 +364,15 @@ export class ApInboxService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async create(actor: MiRemoteUser, activity: ICreate): Promise<void> {
|
||||
private async create(actor: MiRemoteUser, activity: ICreate): Promise<string | void> {
|
||||
const uri = getApId(activity);
|
||||
|
||||
this.logger.info(`Create: ${uri}`);
|
||||
|
||||
if (!activity.object) return 'skip: activity has no object property';
|
||||
const targetUri = getApId(activity.object);
|
||||
if (targetUri.startsWith('bear:')) return 'skip: bearcaps url not supported.';
|
||||
|
||||
// copy audiences between activity <=> object.
|
||||
if (typeof activity.object === 'object') {
|
||||
const to = unique(concat([toArray(activity.to), toArray(activity.object.to)]));
|
||||
@@ -380,7 +399,7 @@ export class ApInboxService {
|
||||
if (isPost(object)) {
|
||||
await this.createNote(resolver, actor, object, false, activity);
|
||||
} else {
|
||||
this.logger.warn(`Unknown type: ${getApType(object)}`);
|
||||
return `Unknown type: ${getApType(object)}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,7 +441,7 @@ export class ApInboxService {
|
||||
@bindThis
|
||||
private async delete(actor: MiRemoteUser, activity: IDelete): Promise<string> {
|
||||
if (actor.uri !== activity.actor) {
|
||||
throw new Error('invalid actor');
|
||||
return 'invalid actor';
|
||||
}
|
||||
|
||||
// 削除対象objectのtype
|
||||
@@ -581,29 +600,29 @@ export class ApInboxService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async remove(actor: MiRemoteUser, activity: IRemove): Promise<void> {
|
||||
private async remove(actor: MiRemoteUser, activity: IRemove): Promise<string | void> {
|
||||
if (actor.uri !== activity.actor) {
|
||||
throw new Error('invalid actor');
|
||||
return 'invalid actor';
|
||||
}
|
||||
|
||||
if (activity.target == null) {
|
||||
throw new Error('target is null');
|
||||
return 'target is null';
|
||||
}
|
||||
|
||||
if (activity.target === actor.featured) {
|
||||
const note = await this.apNoteService.resolveNote(activity.object);
|
||||
if (note == null) throw new Error('note not found');
|
||||
if (note == null) return 'note not found';
|
||||
await this.notePiningService.removePinned(actor, note.id);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(`unknown target: ${activity.target}`);
|
||||
return `unknown target: ${activity.target}`;
|
||||
}
|
||||
|
||||
@bindThis
|
||||
private async undo(actor: MiRemoteUser, activity: IUndo): Promise<string> {
|
||||
if (actor.uri !== activity.actor) {
|
||||
throw new Error('invalid actor');
|
||||
return 'invalid actor';
|
||||
}
|
||||
|
||||
const uri = activity.id ?? activity;
|
||||
@@ -614,7 +633,7 @@ export class ApInboxService {
|
||||
|
||||
const object = await resolver.resolve(activity.object).catch(e => {
|
||||
this.logger.error(`Resolution failed: ${e}`);
|
||||
throw e;
|
||||
return e;
|
||||
});
|
||||
|
||||
// don't queue because the sender may attempt again when timeout
|
||||
|
@@ -81,20 +81,20 @@ export class ApNoteService {
|
||||
const expectHost = this.utilityService.extractDbHost(uri);
|
||||
|
||||
if (!validPost.includes(getApType(object))) {
|
||||
return new Error(`invalid Note: invalid object type ${getApType(object)}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: invalid object type ${getApType(object)}`);
|
||||
}
|
||||
|
||||
if (object.id && this.utilityService.extractDbHost(object.id) !== expectHost) {
|
||||
return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`);
|
||||
}
|
||||
|
||||
const actualHost = object.attributedTo && this.utilityService.extractDbHost(getOneApId(object.attributedTo));
|
||||
if (object.attributedTo && actualHost !== expectHost) {
|
||||
return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`);
|
||||
}
|
||||
|
||||
if (object.published && !this.idService.isSafeT(new Date(object.published).valueOf())) {
|
||||
return new Error('invalid Note: published timestamp is malformed');
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', 'invalid Note: published timestamp is malformed');
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@@ -328,3 +328,4 @@ export const isAnnounce = (object: IObject): object is IAnnounce => getApType(ob
|
||||
export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block';
|
||||
export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag';
|
||||
export const isMove = (object: IObject): object is IMove => getApType(object) === 'Move';
|
||||
export const isNote = (object: IObject): object is IPost => getApType(object) === 'Note';
|
||||
|
@@ -10,6 +10,8 @@ import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { MiAbuseUserReport } from '@/models/AbuseUserReport.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { isNotNull } from '@/misc/is-not-null.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
@@ -26,6 +28,11 @@ export class AbuseUserReportEntityService {
|
||||
@bindThis
|
||||
public async pack(
|
||||
src: MiAbuseUserReport['id'] | MiAbuseUserReport,
|
||||
hint?: {
|
||||
packedReporter?: Packed<'UserDetailedNotMe'>,
|
||||
packedTargetUser?: Packed<'UserDetailedNotMe'>,
|
||||
packedAssignee?: Packed<'UserDetailedNotMe'>,
|
||||
},
|
||||
) {
|
||||
const report = typeof src === 'object' ? src : await this.abuseUserReportsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
@@ -37,13 +44,13 @@ export class AbuseUserReportEntityService {
|
||||
reporterId: report.reporterId,
|
||||
targetUserId: report.targetUserId,
|
||||
assigneeId: report.assigneeId,
|
||||
reporter: this.userEntityService.pack(report.reporter ?? report.reporterId, null, {
|
||||
reporter: hint?.packedReporter ?? this.userEntityService.pack(report.reporter ?? report.reporterId, null, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}),
|
||||
targetUser: this.userEntityService.pack(report.targetUser ?? report.targetUserId, null, {
|
||||
targetUser: hint?.packedTargetUser ?? this.userEntityService.pack(report.targetUser ?? report.targetUserId, null, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}),
|
||||
assignee: report.assigneeId ? this.userEntityService.pack(report.assignee ?? report.assigneeId, null, {
|
||||
assignee: report.assigneeId ? hint?.packedAssignee ?? this.userEntityService.pack(report.assignee ?? report.assigneeId, null, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}) : null,
|
||||
forwarded: report.forwarded,
|
||||
@@ -51,9 +58,24 @@ export class AbuseUserReportEntityService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
reports: any[],
|
||||
public async packMany(
|
||||
reports: MiAbuseUserReport[],
|
||||
) {
|
||||
return Promise.all(reports.map(x => this.pack(x)));
|
||||
const _reporters = reports.map(({ reporter, reporterId }) => reporter ?? reporterId);
|
||||
const _targetUsers = reports.map(({ targetUser, targetUserId }) => targetUser ?? targetUserId);
|
||||
const _assignees = reports.map(({ assignee, assigneeId }) => assignee ?? assigneeId).filter(isNotNull);
|
||||
const _userMap = await this.userEntityService.packMany(
|
||||
[..._reporters, ..._targetUsers, ..._assignees],
|
||||
null,
|
||||
{ schema: 'UserDetailedNotMe' },
|
||||
).then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(
|
||||
reports.map(report => {
|
||||
const packedReporter = _userMap.get(report.reporterId);
|
||||
const packedTargetUser = _userMap.get(report.targetUserId);
|
||||
const packedAssignee = report.assigneeId != null ? _userMap.get(report.assigneeId) : undefined;
|
||||
return this.pack(report, { packedReporter, packedTargetUser, packedAssignee });
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -43,6 +43,7 @@ export class AntennaEntityService {
|
||||
withFile: antenna.withFile,
|
||||
isActive: antenna.isActive,
|
||||
hasUnreadNote: false, // TODO
|
||||
notify: false, // 後方互換性のため
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -29,6 +29,9 @@ export class BlockingEntityService {
|
||||
public async pack(
|
||||
src: MiBlocking['id'] | MiBlocking,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hint?: {
|
||||
blockee?: Packed<'UserDetailedNotMe'>,
|
||||
},
|
||||
): Promise<Packed<'Blocking'>> {
|
||||
const blocking = typeof src === 'object' ? src : await this.blockingsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
@@ -36,17 +39,20 @@ export class BlockingEntityService {
|
||||
id: blocking.id,
|
||||
createdAt: this.idService.parse(blocking.id).date.toISOString(),
|
||||
blockeeId: blocking.blockeeId,
|
||||
blockee: this.userEntityService.pack(blocking.blockeeId, me, {
|
||||
blockee: hint?.blockee ?? this.userEntityService.pack(blocking.blockeeId, me, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
blockings: any[],
|
||||
public async packMany(
|
||||
blockings: MiBlocking[],
|
||||
me: { id: MiUser['id'] },
|
||||
) {
|
||||
return Promise.all(blockings.map(x => this.pack(x, me)));
|
||||
const _blockees = blockings.map(({ blockee, blockeeId }) => blockee ?? blockeeId);
|
||||
const _userMap = await this.userEntityService.packMany(_blockees, me, { schema: 'UserDetailedNotMe' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(blockings.map(blocking => this.pack(blocking, me, { blockee: _userMap.get(blocking.blockeeId) })));
|
||||
}
|
||||
}
|
||||
|
@@ -35,6 +35,9 @@ export class ClipEntityService {
|
||||
public async pack(
|
||||
src: MiClip['id'] | MiClip,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hint?: {
|
||||
packedUser?: Packed<'UserLite'>
|
||||
},
|
||||
): Promise<Packed<'Clip'>> {
|
||||
const meId = me ? me.id : null;
|
||||
const clip = typeof src === 'object' ? src : await this.clipsRepository.findOneByOrFail({ id: src });
|
||||
@@ -44,7 +47,7 @@ export class ClipEntityService {
|
||||
createdAt: this.idService.parse(clip.id).date.toISOString(),
|
||||
lastClippedAt: clip.lastClippedAt ? clip.lastClippedAt.toISOString() : null,
|
||||
userId: clip.userId,
|
||||
user: this.userEntityService.pack(clip.user ?? clip.userId),
|
||||
user: hint?.packedUser ?? this.userEntityService.pack(clip.user ?? clip.userId),
|
||||
name: clip.name,
|
||||
description: clip.description,
|
||||
isPublic: clip.isPublic,
|
||||
@@ -55,11 +58,14 @@ export class ClipEntityService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
public async packMany(
|
||||
clips: MiClip[],
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
) {
|
||||
return Promise.all(clips.map(x => this.pack(x, me)));
|
||||
const _users = clips.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(clips.map(clip => this.pack(clip, me, { packedUser: _userMap.get(clip.userId) })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -222,6 +222,9 @@ export class DriveFileEntityService {
|
||||
public async packNullable(
|
||||
src: MiDriveFile['id'] | MiDriveFile,
|
||||
options?: PackOptions,
|
||||
hint?: {
|
||||
packedUser?: Packed<'UserLite'>
|
||||
},
|
||||
): Promise<Packed<'DriveFile'> | null> {
|
||||
const opts = Object.assign({
|
||||
detail: false,
|
||||
@@ -249,7 +252,7 @@ export class DriveFileEntityService {
|
||||
detail: true,
|
||||
}) : null,
|
||||
userId: file.userId,
|
||||
user: (opts.withUser && file.userId) ? this.userEntityService.pack(file.userId) : null,
|
||||
user: (opts.withUser && file.userId) ? hint?.packedUser ?? this.userEntityService.pack(file.userId) : null,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -258,7 +261,10 @@ export class DriveFileEntityService {
|
||||
files: MiDriveFile[],
|
||||
options?: PackOptions,
|
||||
): Promise<Packed<'DriveFile'>[]> {
|
||||
const items = await Promise.all(files.map(f => this.packNullable(f, options)));
|
||||
const _user = files.map(({ user, userId }) => user ?? userId).filter(isNotNull);
|
||||
const _userMap = await this.userEntityService.packMany(_user)
|
||||
.then(users => new Map(users.map(user => [user.id, user])));
|
||||
const items = await Promise.all(files.map(f => this.packNullable(f, options, f.userId ? { packedUser: _userMap.get(f.userId) } : {})));
|
||||
return items.filter(isNotNull);
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,9 @@ export class FlashEntityService {
|
||||
public async pack(
|
||||
src: MiFlash['id'] | MiFlash,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hint?: {
|
||||
packedUser?: Packed<'UserLite'>
|
||||
},
|
||||
): Promise<Packed<'Flash'>> {
|
||||
const meId = me ? me.id : null;
|
||||
const flash = typeof src === 'object' ? src : await this.flashsRepository.findOneByOrFail({ id: src });
|
||||
@@ -42,7 +45,7 @@ export class FlashEntityService {
|
||||
createdAt: this.idService.parse(flash.id).date.toISOString(),
|
||||
updatedAt: flash.updatedAt.toISOString(),
|
||||
userId: flash.userId,
|
||||
user: this.userEntityService.pack(flash.user ?? flash.userId, me), // { schema: 'UserDetailed' } すると無限ループするので注意
|
||||
user: hint?.packedUser ?? this.userEntityService.pack(flash.user ?? flash.userId, me), // { schema: 'UserDetailed' } すると無限ループするので注意
|
||||
title: flash.title,
|
||||
summary: flash.summary,
|
||||
script: flash.script,
|
||||
@@ -52,11 +55,14 @@ export class FlashEntityService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
flashs: MiFlash[],
|
||||
public async packMany(
|
||||
flashes: MiFlash[],
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
) {
|
||||
return Promise.all(flashs.map(x => this.pack(x, me)));
|
||||
const _users = flashes.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(flashes.map(flash => this.pack(flash, me, { packedUser: _userMap.get(flash.userId) })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import type { } from '@/models/Blocking.js';
|
||||
import type { MiUser } from '@/models/User.js';
|
||||
import type { MiFollowRequest } from '@/models/FollowRequest.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
@@ -26,14 +27,36 @@ export class FollowRequestEntityService {
|
||||
public async pack(
|
||||
src: MiFollowRequest['id'] | MiFollowRequest,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hint?: {
|
||||
packedFollower?: Packed<'UserLite'>,
|
||||
packedFollowee?: Packed<'UserLite'>,
|
||||
},
|
||||
) {
|
||||
const request = typeof src === 'object' ? src : await this.followRequestsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
return {
|
||||
id: request.id,
|
||||
follower: await this.userEntityService.pack(request.followerId, me),
|
||||
followee: await this.userEntityService.pack(request.followeeId, me),
|
||||
follower: hint?.packedFollower ?? await this.userEntityService.pack(request.followerId, me),
|
||||
followee: hint?.packedFollowee ?? await this.userEntityService.pack(request.followeeId, me),
|
||||
};
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async packMany(
|
||||
requests: MiFollowRequest[],
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
) {
|
||||
const _followers = requests.map(({ follower, followerId }) => follower ?? followerId);
|
||||
const _followees = requests.map(({ followee, followeeId }) => followee ?? followeeId);
|
||||
const _userMap = await this.userEntityService.packMany([..._followers, ..._followees], me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(
|
||||
requests.map(req => {
|
||||
const packedFollower = _userMap.get(req.followerId);
|
||||
const packedFollowee = _userMap.get(req.followeeId);
|
||||
return this.pack(req, me, { packedFollower, packedFollowee });
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -78,6 +78,10 @@ export class FollowingEntityService {
|
||||
populateFollowee?: boolean;
|
||||
populateFollower?: boolean;
|
||||
},
|
||||
hint?: {
|
||||
packedFollowee?: Packed<'UserDetailedNotMe'>,
|
||||
packedFollower?: Packed<'UserDetailedNotMe'>,
|
||||
},
|
||||
): Promise<Packed<'Following'>> {
|
||||
const following = typeof src === 'object' ? src : await this.followingsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
@@ -88,25 +92,35 @@ export class FollowingEntityService {
|
||||
createdAt: this.idService.parse(following.id).date.toISOString(),
|
||||
followeeId: following.followeeId,
|
||||
followerId: following.followerId,
|
||||
followee: opts.populateFollowee ? this.userEntityService.pack(following.followee ?? following.followeeId, me, {
|
||||
followee: opts.populateFollowee ? hint?.packedFollowee ?? this.userEntityService.pack(following.followee ?? following.followeeId, me, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}) : undefined,
|
||||
follower: opts.populateFollower ? this.userEntityService.pack(following.follower ?? following.followerId, me, {
|
||||
follower: opts.populateFollower ? hint?.packedFollower ?? this.userEntityService.pack(following.follower ?? following.followerId, me, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}) : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
followings: any[],
|
||||
public async packMany(
|
||||
followings: MiFollowing[],
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
opts?: {
|
||||
populateFollowee?: boolean;
|
||||
populateFollower?: boolean;
|
||||
},
|
||||
) {
|
||||
return Promise.all(followings.map(x => this.pack(x, me, opts)));
|
||||
const _followees = opts?.populateFollowee ? followings.map(({ followee, followeeId }) => followee ?? followeeId) : [];
|
||||
const _followers = opts?.populateFollower ? followings.map(({ follower, followerId }) => follower ?? followerId) : [];
|
||||
const _userMap = await this.userEntityService.packMany([..._followees, ..._followers], me, { schema: 'UserDetailedNotMe' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(
|
||||
followings.map(following => {
|
||||
const packedFollowee = opts?.populateFollowee ? _userMap.get(following.followeeId) : undefined;
|
||||
const packedFollower = opts?.populateFollower ? _userMap.get(following.followerId) : undefined;
|
||||
return this.pack(following, me, opts, { packedFollowee, packedFollower });
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,9 @@ export class GalleryPostEntityService {
|
||||
public async pack(
|
||||
src: MiGalleryPost['id'] | MiGalleryPost,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hint?: {
|
||||
packedUser?: Packed<'UserLite'>
|
||||
},
|
||||
): Promise<Packed<'GalleryPost'>> {
|
||||
const meId = me ? me.id : null;
|
||||
const post = typeof src === 'object' ? src : await this.galleryPostsRepository.findOneByOrFail({ id: src });
|
||||
@@ -44,7 +47,7 @@ export class GalleryPostEntityService {
|
||||
createdAt: this.idService.parse(post.id).date.toISOString(),
|
||||
updatedAt: post.updatedAt.toISOString(),
|
||||
userId: post.userId,
|
||||
user: this.userEntityService.pack(post.user ?? post.userId, me),
|
||||
user: hint?.packedUser ?? this.userEntityService.pack(post.user ?? post.userId, me),
|
||||
title: post.title,
|
||||
description: post.description,
|
||||
fileIds: post.fileIds,
|
||||
@@ -58,11 +61,14 @@ export class GalleryPostEntityService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
public async packMany(
|
||||
posts: MiGalleryPost[],
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
) {
|
||||
return Promise.all(posts.map(x => this.pack(x, me)));
|
||||
const _users = posts.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(posts.map(post => this.pack(post, me, { packedUser: _userMap.get(post.userId) })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@ import type { MiUser } from '@/models/User.js';
|
||||
import type { MiRegistrationTicket } from '@/models/RegistrationTicket.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { isNotNull } from '@/misc/is-not-null.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
@@ -29,6 +30,10 @@ export class InviteCodeEntityService {
|
||||
public async pack(
|
||||
src: MiRegistrationTicket['id'] | MiRegistrationTicket,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hints?: {
|
||||
packedCreatedBy?: Packed<'UserLite'>,
|
||||
packedUsedBy?: Packed<'UserLite'>,
|
||||
},
|
||||
): Promise<Packed<'InviteCode'>> {
|
||||
const target = typeof src === 'object' ? src : await this.registrationTicketsRepository.findOneOrFail({
|
||||
where: {
|
||||
@@ -42,18 +47,28 @@ export class InviteCodeEntityService {
|
||||
code: target.code,
|
||||
expiresAt: target.expiresAt ? target.expiresAt.toISOString() : null,
|
||||
createdAt: this.idService.parse(target.id).date.toISOString(),
|
||||
createdBy: target.createdBy ? await this.userEntityService.pack(target.createdBy, me) : null,
|
||||
usedBy: target.usedBy ? await this.userEntityService.pack(target.usedBy, me) : null,
|
||||
createdBy: target.createdBy ? hints?.packedCreatedBy ?? await this.userEntityService.pack(target.createdBy, me) : null,
|
||||
usedBy: target.usedBy ? hints?.packedUsedBy ?? await this.userEntityService.pack(target.usedBy, me) : null,
|
||||
usedAt: target.usedAt ? target.usedAt.toISOString() : null,
|
||||
used: !!target.usedAt,
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
targets: any[],
|
||||
public async packMany(
|
||||
tickets: MiRegistrationTicket[],
|
||||
me: { id: MiUser['id'] },
|
||||
) {
|
||||
return Promise.all(targets.map(x => this.pack(x, me)));
|
||||
const _createdBys = tickets.map(({ createdBy, createdById }) => createdBy ?? createdById).filter(isNotNull);
|
||||
const _usedBys = tickets.map(({ usedBy, usedById }) => usedBy ?? usedById).filter(isNotNull);
|
||||
const _userMap = await this.userEntityService.packMany([..._createdBys, ..._usedBys], me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(
|
||||
tickets.map(ticket => {
|
||||
const packedCreatedBy = ticket.createdById != null ? _userMap.get(ticket.createdById) : undefined;
|
||||
const packedUsedBy = ticket.usedById != null ? _userMap.get(ticket.usedById) : undefined;
|
||||
return this.pack(ticket, me, { packedCreatedBy, packedUsedBy });
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -67,6 +67,7 @@ export class MetaEntityService {
|
||||
feedbackUrl: instance.feedbackUrl,
|
||||
impressumUrl: instance.impressumUrl,
|
||||
privacyPolicyUrl: instance.privacyPolicyUrl,
|
||||
inquiryUrl: instance.inquiryUrl,
|
||||
disableRegistration: instance.disableRegistration,
|
||||
emailRequiredForSignup: instance.emailRequiredForSignup,
|
||||
enableHcaptcha: instance.enableHcaptcha,
|
||||
|
@@ -8,9 +8,10 @@ import { DI } from '@/di-symbols.js';
|
||||
import type { ModerationLogsRepository } from '@/models/_.js';
|
||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||
import type { } from '@/models/Blocking.js';
|
||||
import type { MiModerationLog } from '@/models/ModerationLog.js';
|
||||
import { MiModerationLog } from '@/models/ModerationLog.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import type { Packed } from '@/misc/json-schema.js';
|
||||
import { UserEntityService } from './UserEntityService.js';
|
||||
|
||||
@Injectable()
|
||||
@@ -27,6 +28,9 @@ export class ModerationLogEntityService {
|
||||
@bindThis
|
||||
public async pack(
|
||||
src: MiModerationLog['id'] | MiModerationLog,
|
||||
hint?: {
|
||||
packedUser?: Packed<'UserDetailedNotMe'>,
|
||||
},
|
||||
) {
|
||||
const log = typeof src === 'object' ? src : await this.moderationLogsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
@@ -36,17 +40,20 @@ export class ModerationLogEntityService {
|
||||
type: log.type,
|
||||
info: log.info,
|
||||
userId: log.userId,
|
||||
user: this.userEntityService.pack(log.user ?? log.userId, null, {
|
||||
user: hint?.packedUser ?? this.userEntityService.pack(log.user ?? log.userId, null, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
reports: any[],
|
||||
public async packMany(
|
||||
reports: MiModerationLog[],
|
||||
) {
|
||||
return Promise.all(reports.map(x => this.pack(x)));
|
||||
const _users = reports.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, null, { schema: 'UserDetailedNotMe' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(reports.map(report => this.pack(report, { packedUser: _userMap.get(report.userId) })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,9 @@ export class MutingEntityService {
|
||||
public async pack(
|
||||
src: MiMuting['id'] | MiMuting,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hints?: {
|
||||
packedMutee?: Packed<'UserDetailedNotMe'>,
|
||||
},
|
||||
): Promise<Packed<'Muting'>> {
|
||||
const muting = typeof src === 'object' ? src : await this.mutingsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
@@ -38,18 +41,21 @@ export class MutingEntityService {
|
||||
createdAt: this.idService.parse(muting.id).date.toISOString(),
|
||||
expiresAt: muting.expiresAt ? muting.expiresAt.toISOString() : null,
|
||||
muteeId: muting.muteeId,
|
||||
mutee: this.userEntityService.pack(muting.muteeId, me, {
|
||||
mutee: hints?.packedMutee ?? this.userEntityService.pack(muting.muteeId, me, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
mutings: any[],
|
||||
public async packMany(
|
||||
mutings: MiMuting[],
|
||||
me: { id: MiUser['id'] },
|
||||
) {
|
||||
return Promise.all(mutings.map(x => this.pack(x, me)));
|
||||
const _mutees = mutings.map(({ mutee, muteeId }) => mutee ?? muteeId);
|
||||
const _userMap = await this.userEntityService.packMany(_mutees, me, { schema: 'UserDetailedNotMe' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(mutings.map(muting => this.pack(muting, me, { packedMutee: _userMap.get(muting.muteeId) })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -290,6 +290,7 @@ export class NoteEntityService implements OnModuleInit {
|
||||
_hint_?: {
|
||||
myReactions: Map<MiNote['id'], string | null>;
|
||||
packedFiles: Map<MiNote['fileIds'][number], Packed<'DriveFile'> | null>;
|
||||
packedUsers: Map<MiUser['id'], Packed<'UserLite'>>
|
||||
};
|
||||
},
|
||||
): Promise<Packed<'Note'>> {
|
||||
@@ -319,12 +320,13 @@ export class NoteEntityService implements OnModuleInit {
|
||||
.filter(x => x.startsWith(':') && x.includes('@') && !x.includes('@.')) // リモートカスタム絵文字のみ
|
||||
.map(x => this.reactionService.decodeReaction(x).reaction.replaceAll(':', ''));
|
||||
const packedFiles = options?._hint_?.packedFiles;
|
||||
const packedUsers = options?._hint_?.packedUsers;
|
||||
|
||||
const packed: Packed<'Note'> = await awaitAll({
|
||||
id: note.id,
|
||||
createdAt: this.idService.parse(note.id).date.toISOString(),
|
||||
userId: note.userId,
|
||||
user: this.userEntityService.pack(note.user ?? note.userId, me),
|
||||
user: packedUsers?.get(note.userId) ?? this.userEntityService.pack(note.user ?? note.userId, me),
|
||||
text: text,
|
||||
cw: note.cw,
|
||||
visibility: note.visibility,
|
||||
@@ -449,12 +451,20 @@ export class NoteEntityService implements OnModuleInit {
|
||||
// TODO: 本当は renote とか reply がないのに renoteId とか replyId があったらここで解決しておく
|
||||
const fileIds = notes.map(n => [n.fileIds, n.renote?.fileIds, n.reply?.fileIds]).flat(2).filter(isNotNull);
|
||||
const packedFiles = fileIds.length > 0 ? await this.driveFileEntityService.packManyByIdsMap(fileIds) : new Map();
|
||||
const users = [
|
||||
...notes.map(({ user, userId }) => user ?? userId),
|
||||
...notes.map(({ replyUserId }) => replyUserId).filter(isNotNull),
|
||||
...notes.map(({ renoteUserId }) => renoteUserId).filter(isNotNull),
|
||||
];
|
||||
const packedUsers = await this.userEntityService.packMany(users, me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
|
||||
return await Promise.all(notes.map(n => this.pack(n, me, {
|
||||
...options,
|
||||
_hint_: {
|
||||
myReactions: myReactionsMap,
|
||||
packedFiles,
|
||||
packedUsers,
|
||||
},
|
||||
})));
|
||||
}
|
||||
|
@@ -52,6 +52,9 @@ export class NoteReactionEntityService implements OnModuleInit {
|
||||
options?: {
|
||||
withNote: boolean;
|
||||
},
|
||||
hints?: {
|
||||
packedUser?: Packed<'UserLite'>
|
||||
},
|
||||
): Promise<Packed<'NoteReaction'>> {
|
||||
const opts = Object.assign({
|
||||
withNote: false,
|
||||
@@ -62,7 +65,7 @@ export class NoteReactionEntityService implements OnModuleInit {
|
||||
return {
|
||||
id: reaction.id,
|
||||
createdAt: this.idService.parse(reaction.id).date.toISOString(),
|
||||
user: await this.userEntityService.pack(reaction.user ?? reaction.userId, me),
|
||||
user: hints?.packedUser ?? await this.userEntityService.pack(reaction.user ?? reaction.userId, me),
|
||||
type: this.reactionService.convertLegacyReaction(reaction.reaction),
|
||||
...(opts.withNote ? {
|
||||
note: await this.noteEntityService.pack(reaction.note ?? reaction.noteId, me),
|
||||
@@ -81,7 +84,9 @@ export class NoteReactionEntityService implements OnModuleInit {
|
||||
const opts = Object.assign({
|
||||
withNote: false,
|
||||
}, options);
|
||||
|
||||
return Promise.all(reactions.map(reaction => this.pack(reaction, me, opts)));
|
||||
const _users = reactions.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(reactions.map(reaction => this.pack(reaction, me, opts, { packedUser: _userMap.get(reaction.userId) })));
|
||||
}
|
||||
}
|
||||
|
@@ -40,6 +40,9 @@ export class PageEntityService {
|
||||
public async pack(
|
||||
src: MiPage['id'] | MiPage,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hint?: {
|
||||
packedUser?: Packed<'UserLite'>
|
||||
},
|
||||
): Promise<Packed<'Page'>> {
|
||||
const meId = me ? me.id : null;
|
||||
const page = typeof src === 'object' ? src : await this.pagesRepository.findOneByOrFail({ id: src });
|
||||
@@ -91,7 +94,7 @@ export class PageEntityService {
|
||||
createdAt: this.idService.parse(page.id).date.toISOString(),
|
||||
updatedAt: page.updatedAt.toISOString(),
|
||||
userId: page.userId,
|
||||
user: this.userEntityService.pack(page.user ?? page.userId, me), // { schema: 'UserDetailed' } すると無限ループするので注意
|
||||
user: hint?.packedUser ?? this.userEntityService.pack(page.user ?? page.userId, me), // { schema: 'UserDetailed' } すると無限ループするので注意
|
||||
content: page.content,
|
||||
variables: page.variables,
|
||||
title: page.title,
|
||||
@@ -110,11 +113,14 @@ export class PageEntityService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
public async packMany(
|
||||
pages: MiPage[],
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
) {
|
||||
return Promise.all(pages.map(x => this.pack(x, me)));
|
||||
const _users = pages.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(pages.map(page => this.pack(page, me, { packedUser: _userMap.get(page.userId) })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,9 @@ export class RenoteMutingEntityService {
|
||||
public async pack(
|
||||
src: MiRenoteMuting['id'] | MiRenoteMuting,
|
||||
me?: { id: MiUser['id'] } | null | undefined,
|
||||
hints?: {
|
||||
packedMutee?: Packed<'UserDetailedNotMe'>
|
||||
},
|
||||
): Promise<Packed<'RenoteMuting'>> {
|
||||
const muting = typeof src === 'object' ? src : await this.renoteMutingsRepository.findOneByOrFail({ id: src });
|
||||
|
||||
@@ -37,18 +40,21 @@ export class RenoteMutingEntityService {
|
||||
id: muting.id,
|
||||
createdAt: this.idService.parse(muting.id).date.toISOString(),
|
||||
muteeId: muting.muteeId,
|
||||
mutee: this.userEntityService.pack(muting.muteeId, me, {
|
||||
mutee: hints?.packedMutee ?? this.userEntityService.pack(muting.muteeId, me, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packMany(
|
||||
mutings: any[],
|
||||
public async packMany(
|
||||
mutings: MiRenoteMuting[],
|
||||
me: { id: MiUser['id'] },
|
||||
) {
|
||||
return Promise.all(mutings.map(x => this.pack(x, me)));
|
||||
const _users = mutings.map(({ mutee, muteeId }) => mutee ?? muteeId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me, { schema: 'UserDetailedNotMe' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(mutings.map(muting => this.pack(muting, me, { packedMutee: _userMap.get(muting.muteeId) })));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -28,13 +28,15 @@ export class ReversiGameEntityService {
|
||||
@bindThis
|
||||
public async packDetail(
|
||||
src: MiReversiGame['id'] | MiReversiGame,
|
||||
hint?: {
|
||||
packedUser1?: Packed<'UserLite'>,
|
||||
packedUser2?: Packed<'UserLite'>,
|
||||
},
|
||||
): Promise<Packed<'ReversiGameDetailed'>> {
|
||||
const game = typeof src === 'object' ? src : await this.reversiGamesRepository.findOneByOrFail({ id: src });
|
||||
|
||||
const users = await Promise.all([
|
||||
this.userEntityService.pack(game.user1 ?? game.user1Id),
|
||||
this.userEntityService.pack(game.user2 ?? game.user2Id),
|
||||
]);
|
||||
const user1 = hint?.packedUser1 ?? await this.userEntityService.pack(game.user1 ?? game.user1Id);
|
||||
const user2 = hint?.packedUser2 ?? await this.userEntityService.pack(game.user2 ?? game.user2Id);
|
||||
|
||||
return await awaitAll({
|
||||
id: game.id,
|
||||
@@ -49,10 +51,10 @@ export class ReversiGameEntityService {
|
||||
user2Ready: game.user2Ready,
|
||||
user1Id: game.user1Id,
|
||||
user2Id: game.user2Id,
|
||||
user1: users[0],
|
||||
user2: users[1],
|
||||
user1,
|
||||
user2,
|
||||
winnerId: game.winnerId,
|
||||
winner: game.winnerId ? users.find(u => u.id === game.winnerId)! : null,
|
||||
winner: game.winnerId ? [user1, user2].find(u => u.id === game.winnerId)! : null,
|
||||
surrenderedUserId: game.surrenderedUserId,
|
||||
timeoutUserId: game.timeoutUserId,
|
||||
black: game.black,
|
||||
@@ -68,22 +70,35 @@ export class ReversiGameEntityService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packDetailMany(
|
||||
xs: MiReversiGame[],
|
||||
public async packDetailMany(
|
||||
games: MiReversiGame[],
|
||||
) {
|
||||
return Promise.all(xs.map(x => this.packDetail(x)));
|
||||
const _user1s = games.map(({ user1, user1Id }) => user1 ?? user1Id);
|
||||
const _user2s = games.map(({ user2, user2Id }) => user2 ?? user2Id);
|
||||
const _userMap = await this.userEntityService.packMany([..._user1s, ..._user2s])
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(
|
||||
games.map(game => {
|
||||
return this.packDetail(game, {
|
||||
packedUser1: _userMap.get(game.user1Id),
|
||||
packedUser2: _userMap.get(game.user2Id),
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async packLite(
|
||||
src: MiReversiGame['id'] | MiReversiGame,
|
||||
hint?: {
|
||||
packedUser1?: Packed<'UserLite'>,
|
||||
packedUser2?: Packed<'UserLite'>,
|
||||
},
|
||||
): Promise<Packed<'ReversiGameLite'>> {
|
||||
const game = typeof src === 'object' ? src : await this.reversiGamesRepository.findOneByOrFail({ id: src });
|
||||
|
||||
const users = await Promise.all([
|
||||
this.userEntityService.pack(game.user1 ?? game.user1Id),
|
||||
this.userEntityService.pack(game.user2 ?? game.user2Id),
|
||||
]);
|
||||
const user1 = hint?.packedUser1 ?? await this.userEntityService.pack(game.user1 ?? game.user1Id);
|
||||
const user2 = hint?.packedUser2 ?? await this.userEntityService.pack(game.user2 ?? game.user2Id);
|
||||
|
||||
return await awaitAll({
|
||||
id: game.id,
|
||||
@@ -94,10 +109,10 @@ export class ReversiGameEntityService {
|
||||
isEnded: game.isEnded,
|
||||
user1Id: game.user1Id,
|
||||
user2Id: game.user2Id,
|
||||
user1: users[0],
|
||||
user2: users[1],
|
||||
user1,
|
||||
user2,
|
||||
winnerId: game.winnerId,
|
||||
winner: game.winnerId ? users.find(u => u.id === game.winnerId)! : null,
|
||||
winner: game.winnerId ? [user1, user2].find(u => u.id === game.winnerId)! : null,
|
||||
surrenderedUserId: game.surrenderedUserId,
|
||||
timeoutUserId: game.timeoutUserId,
|
||||
black: game.black,
|
||||
@@ -111,10 +126,21 @@ export class ReversiGameEntityService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public packLiteMany(
|
||||
xs: MiReversiGame[],
|
||||
public async packLiteMany(
|
||||
games: MiReversiGame[],
|
||||
) {
|
||||
return Promise.all(xs.map(x => this.packLite(x)));
|
||||
const _user1s = games.map(({ user1, user1Id }) => user1 ?? user1Id);
|
||||
const _user2s = games.map(({ user2, user2Id }) => user2 ?? user2Id);
|
||||
const _userMap = await this.userEntityService.packMany([..._user1s, ..._user2s])
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(
|
||||
games.map(game => {
|
||||
return this.packLite(game, {
|
||||
packedUser1: _userMap.get(game.user1Id),
|
||||
packedUser2: _userMap.get(game.user2Id),
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -50,11 +50,14 @@ export class UserListEntityService {
|
||||
public async packMembershipsMany(
|
||||
memberships: MiUserListMembership[],
|
||||
) {
|
||||
const _users = memberships.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users)
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return Promise.all(memberships.map(async x => ({
|
||||
id: x.id,
|
||||
createdAt: this.idService.parse(x.id).date.toISOString(),
|
||||
userId: x.userId,
|
||||
user: await this.userEntityService.pack(x.userId),
|
||||
user: _userMap.get(x.userId) ?? await this.userEntityService.pack(x.userId),
|
||||
withReplies: x.withReplies,
|
||||
})));
|
||||
}
|
||||
|
@@ -376,6 +376,12 @@ export class MiMeta {
|
||||
})
|
||||
public privacyPolicyUrl: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 1024,
|
||||
nullable: true,
|
||||
})
|
||||
public inquiryUrl: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 8192,
|
||||
nullable: true,
|
||||
|
@@ -95,5 +95,10 @@ export const packedAntennaSchema = {
|
||||
optional: false, nullable: false,
|
||||
default: false,
|
||||
},
|
||||
notify: {
|
||||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
@@ -227,6 +227,10 @@ export const packedMetaLiteSchema = {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
inquiryUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
serverRules: {
|
||||
type: 'array',
|
||||
optional: false, nullable: false,
|
||||
|
@@ -204,13 +204,22 @@ export class InboxProcessorService {
|
||||
|
||||
// アクティビティを処理
|
||||
try {
|
||||
await this.apInboxService.performActivity(authUser.user, activity);
|
||||
const result = await this.apInboxService.performActivity(authUser.user, activity);
|
||||
if (result && !result.startsWith('ok')) {
|
||||
this.logger.warn(`inbox activity ignored (maybe): id=${activity.id} reason=${result}`);
|
||||
return result;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof IdentifiableError) {
|
||||
if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') {
|
||||
return 'blocked notes with prohibited words';
|
||||
}
|
||||
if (e.id === '85ab9bd7-3a41-4530-959d-f07073900109') return 'actor has been suspended';
|
||||
if (e.id === '85ab9bd7-3a41-4530-959d-f07073900109') {
|
||||
return 'actor has been suspended';
|
||||
}
|
||||
if (e.id === 'd450b8a9-48e4-4dab-ae36-f4db763fda7c') { // invalid Note
|
||||
return e.message;
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@@ -37,12 +37,12 @@ export class NodeinfoServerService {
|
||||
@bindThis
|
||||
public getLinks() {
|
||||
return [{
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1',
|
||||
href: this.config.url + nodeinfo2_1path
|
||||
}, {
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0',
|
||||
href: this.config.url + nodeinfo2_0path,
|
||||
}];
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1',
|
||||
href: this.config.url + nodeinfo2_1path,
|
||||
}, {
|
||||
rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0',
|
||||
href: this.config.url + nodeinfo2_0path,
|
||||
}];
|
||||
}
|
||||
|
||||
@bindThis
|
||||
@@ -108,6 +108,7 @@ export class NodeinfoServerService {
|
||||
langs: meta.langs,
|
||||
tosUrl: meta.termsOfServiceUrl,
|
||||
privacyPolicyUrl: meta.privacyPolicyUrl,
|
||||
inquiryUrl: meta.inquiryUrl,
|
||||
impressumUrl: meta.impressumUrl,
|
||||
repositoryUrl: meta.repositoryUrl,
|
||||
feedbackUrl: meta.feedbackUrl,
|
||||
|
@@ -7,6 +7,7 @@ import { randomUUID } from 'node:crypto';
|
||||
import * as fs from 'node:fs';
|
||||
import * as stream from 'node:stream/promises';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { getIpHash } from '@/misc/get-ip-hash.js';
|
||||
import type { MiLocalUser, MiUser } from '@/models/User.js';
|
||||
@@ -17,6 +18,7 @@ import { MetaService } from '@/core/MetaService.js';
|
||||
import { createTemp } from '@/misc/create-temp.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import { ApiError } from './error.js';
|
||||
import { RateLimiterService } from './RateLimiterService.js';
|
||||
import { ApiLoggerService } from './ApiLoggerService.js';
|
||||
@@ -38,6 +40,9 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||
private userIpHistoriesClearIntervalId: NodeJS.Timeout;
|
||||
|
||||
constructor(
|
||||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.userIpsRepository)
|
||||
private userIpsRepository: UserIpsRepository,
|
||||
|
||||
@@ -88,6 +93,48 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||
}
|
||||
}
|
||||
|
||||
#onExecError(ep: IEndpoint, data: any, err: Error): void {
|
||||
if (err instanceof ApiError || err instanceof AuthenticationError) {
|
||||
throw err;
|
||||
} else {
|
||||
const errId = randomUUID();
|
||||
this.logger.error(`Internal error occurred in ${ep.name}: ${err.message}`, {
|
||||
ep: ep.name,
|
||||
ps: data,
|
||||
e: {
|
||||
message: err.message,
|
||||
code: err.name,
|
||||
stack: err.stack,
|
||||
id: errId,
|
||||
},
|
||||
});
|
||||
console.error(err, errId);
|
||||
|
||||
if (this.config.sentryForBackend) {
|
||||
Sentry.captureMessage(`Internal error occurred in ${ep.name}: ${err.message}`, {
|
||||
extra: {
|
||||
ep: ep.name,
|
||||
ps: data,
|
||||
e: {
|
||||
message: err.message,
|
||||
code: err.name,
|
||||
stack: err.stack,
|
||||
id: errId,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
throw new ApiError(null, {
|
||||
e: {
|
||||
message: err.message,
|
||||
code: err.name,
|
||||
id: errId,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public handleRequest(
|
||||
endpoint: IEndpoint & { exec: any },
|
||||
@@ -362,31 +409,11 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||
}
|
||||
|
||||
// API invoking
|
||||
return await ep.exec(data, user, token, file, request.ip, request.headers).catch((err: Error) => {
|
||||
if (err instanceof ApiError || err instanceof AuthenticationError) {
|
||||
throw err;
|
||||
} else {
|
||||
const errId = randomUUID();
|
||||
this.logger.error(`Internal error occurred in ${ep.name}: ${err.message}`, {
|
||||
ep: ep.name,
|
||||
ps: data,
|
||||
e: {
|
||||
message: err.message,
|
||||
code: err.name,
|
||||
stack: err.stack,
|
||||
id: errId,
|
||||
},
|
||||
});
|
||||
console.error(err, errId);
|
||||
throw new ApiError(null, {
|
||||
e: {
|
||||
message: err.message,
|
||||
code: err.name,
|
||||
id: errId,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
if (this.config.sentryForBackend) {
|
||||
return await Sentry.startSpan({ name: 'API: ' + ep.name }, () => ep.exec(data, user, token, file, request.ip, request.headers).catch((err: Error) => this.#onExecError(ep, data, err)));
|
||||
} else {
|
||||
return await ep.exec(data, user, token, file, request.ip, request.headers).catch((err: Error) => this.#onExecError(ep, data, err));
|
||||
}
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
@@ -427,6 +427,10 @@ export const meta = {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
inquiryUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
repositoryUrl: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
@@ -513,6 +517,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
feedbackUrl: instance.feedbackUrl,
|
||||
impressumUrl: instance.impressumUrl,
|
||||
privacyPolicyUrl: instance.privacyPolicyUrl,
|
||||
inquiryUrl: instance.inquiryUrl,
|
||||
disableRegistration: instance.disableRegistration,
|
||||
emailRequiredForSignup: instance.emailRequiredForSignup,
|
||||
enableHcaptcha: instance.enableHcaptcha,
|
||||
|
@@ -89,10 +89,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
.limit(ps.limit)
|
||||
.getMany();
|
||||
|
||||
const _users = assigns.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me, { schema: 'UserDetailed' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return await Promise.all(assigns.map(async assign => ({
|
||||
id: assign.id,
|
||||
createdAt: this.idService.parse(assign.id).date.toISOString(),
|
||||
user: await this.userEntityService.pack(assign.user!, me, { schema: 'UserDetailed' }),
|
||||
user: _userMap.get(assign.userId) ?? await this.userEntityService.pack(assign.user!, me, { schema: 'UserDetailed' }),
|
||||
expiresAt: assign.expiresAt?.toISOString() ?? null,
|
||||
})));
|
||||
});
|
||||
|
@@ -107,6 +107,7 @@ export const paramDef = {
|
||||
feedbackUrl: { type: 'string', nullable: true },
|
||||
impressumUrl: { type: 'string', nullable: true },
|
||||
privacyPolicyUrl: { type: 'string', nullable: true },
|
||||
inquiryUrl: { type: 'string', nullable: true },
|
||||
useObjectStorage: { type: 'boolean' },
|
||||
objectStorageBaseUrl: { type: 'string', nullable: true },
|
||||
objectStorageBucket: { type: 'string', nullable: true },
|
||||
@@ -422,6 +423,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
set.privacyPolicyUrl = ps.privacyPolicyUrl;
|
||||
}
|
||||
|
||||
if (ps.inquiryUrl !== undefined) {
|
||||
set.inquiryUrl = ps.inquiryUrl;
|
||||
}
|
||||
|
||||
if (ps.useObjectStorage !== undefined) {
|
||||
set.useObjectStorage = ps.useObjectStorage;
|
||||
}
|
||||
|
@@ -54,7 +54,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
folderId: ps.folderId ?? IsNull(),
|
||||
});
|
||||
|
||||
return await Promise.all(files.map(file => this.driveFileEntityService.pack(file, { self: true })));
|
||||
return await this.driveFileEntityService.packMany(files, { self: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -71,7 +71,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
.limit(ps.limit)
|
||||
.getMany();
|
||||
|
||||
return await Promise.all(requests.map(req => this.followRequestEntityService.pack(req)));
|
||||
return await this.followRequestEntityService.packMany(requests, me);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
|
||||
const reactions = await query.limit(ps.limit).getMany();
|
||||
|
||||
return await Promise.all(reactions.map(reaction => this.noteReactionEntityService.pack(reaction, me)));
|
||||
return await this.noteReactionEntityService.packMany(reactions, me);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -92,9 +92,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
.limit(ps.limit)
|
||||
.getMany();
|
||||
|
||||
const _users = assigns.map(({ user, userId }) => user ?? userId);
|
||||
const _userMap = await this.userEntityService.packMany(_users, me, { schema: 'UserDetailed' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return await Promise.all(assigns.map(async assign => ({
|
||||
id: assign.id,
|
||||
user: await this.userEntityService.pack(assign.user!, me, { schema: 'UserDetailed' }),
|
||||
user: _userMap.get(assign.userId) ?? await this.userEntityService.pack(assign.user!, me, { schema: 'UserDetailed' }),
|
||||
})));
|
||||
});
|
||||
}
|
||||
|
@@ -118,12 +118,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
const repliedUsersSorted = Object.keys(repliedUsers).sort((a, b) => repliedUsers[b] - repliedUsers[a]);
|
||||
|
||||
// Extract top replied users
|
||||
const topRepliedUsers = repliedUsersSorted.slice(0, ps.limit);
|
||||
const topRepliedUserIds = repliedUsersSorted.slice(0, ps.limit);
|
||||
|
||||
// Make replies object (includes weights)
|
||||
const repliesObj = await Promise.all(topRepliedUsers.map(async (user) => ({
|
||||
user: await this.userEntityService.pack(user, me, { schema: 'UserDetailed' }),
|
||||
weight: repliedUsers[user] / peak,
|
||||
const _userMap = await this.userEntityService.packMany(topRepliedUserIds, me, { schema: 'UserDetailed' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
const repliesObj = await Promise.all(topRepliedUserIds.map(async (userId) => ({
|
||||
user: _userMap.get(userId) ?? await this.userEntityService.pack(userId, me, { schema: 'UserDetailed' }),
|
||||
weight: repliedUsers[userId] / peak,
|
||||
})));
|
||||
|
||||
return repliesObj;
|
||||
|
@@ -117,9 +117,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
if (user != null) _users.push(user);
|
||||
}
|
||||
|
||||
return await Promise.all(_users.map(u => this.userEntityService.pack(u, me, {
|
||||
schema: 'UserDetailed',
|
||||
})));
|
||||
const _userMap = await this.userEntityService.packMany(_users, me, { schema: 'UserDetailed' })
|
||||
.then(users => new Map(users.map(u => [u.id, u])));
|
||||
return _users.map(u => _userMap.get(u.id)!);
|
||||
} else {
|
||||
// Lookup user
|
||||
if (typeof ps.host === 'string' && typeof ps.username === 'string') {
|
||||
|
@@ -157,6 +157,7 @@ describe('アンテナ', () => {
|
||||
withReplies: false,
|
||||
excludeBots: false,
|
||||
localOnly: false,
|
||||
notify: false,
|
||||
};
|
||||
assert.deepStrictEqual(response, expected);
|
||||
});
|
||||
|
@@ -4,77 +4,81 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<MkModalWindow ref="dialogEl" @close="cancel()" @closed="$emit('closed')">
|
||||
<template #header>:{{ emoji.name }}:</template>
|
||||
<template #default>
|
||||
<MkSpacer>
|
||||
<div style="display: flex; flex-direction: column; gap: 1em;">
|
||||
<div :class="$style.emojiImgWrapper">
|
||||
<MkCustomEmoji :name="emoji.name" :normal="true" :useOriginalSize="true" style="height: 100%;"></MkCustomEmoji>
|
||||
</div>
|
||||
<MkKeyValue :copy="`:${emoji.name}:`">
|
||||
<template #key>{{ i18n.ts.name }}</template>
|
||||
<template #value>{{ emoji.name }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.tags }}</template>
|
||||
<template #value>
|
||||
<div v-if="emoji.aliases.length === 0">{{ i18n.ts.none }}</div>
|
||||
<div v-else :class="$style.aliases">
|
||||
<span v-for="alias in emoji.aliases" :key="alias" :class="$style.alias">
|
||||
{{ alias }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.category }}</template>
|
||||
<template #value>{{ emoji.category ?? i18n.ts.none }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.sensitive }}</template>
|
||||
<template #value>{{ emoji.isSensitive ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.localOnly }}</template>
|
||||
<template #value>{{ emoji.localOnly ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.license }}</template>
|
||||
<template #value><Mfm :text="emoji.license ?? i18n.ts.none" /></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue :copy="emoji.url">
|
||||
<template #key>{{ i18n.ts.emojiUrl }}</template>
|
||||
<template #value>
|
||||
<MkLink :url="emoji.url" target="_blank">{{ emoji.url }}</MkLink>
|
||||
</template>
|
||||
</MkKeyValue>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
</MkModalWindow>
|
||||
<MkModalWindow ref="dialogEl" @close="cancel()" @closed="$emit('closed')">
|
||||
<template #header>:{{ emoji.name }}:</template>
|
||||
<template #default>
|
||||
<MkSpacer>
|
||||
<div style="display: flex; flex-direction: column; gap: 1em;">
|
||||
<div :class="$style.emojiImgWrapper">
|
||||
<MkCustomEmoji :name="emoji.name" :normal="true" :useOriginalSize="true" style="height: 100%;"></MkCustomEmoji>
|
||||
</div>
|
||||
<MkKeyValue :copy="`:${emoji.name}:`">
|
||||
<template #key>{{ i18n.ts.name }}</template>
|
||||
<template #value>{{ emoji.name }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.tags }}</template>
|
||||
<template #value>
|
||||
<div v-if="emoji.aliases.length === 0">{{ i18n.ts.none }}</div>
|
||||
<div v-else :class="$style.aliases">
|
||||
<span v-for="alias in emoji.aliases" :key="alias" :class="$style.alias">
|
||||
{{ alias }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.category }}</template>
|
||||
<template #value>{{ emoji.category ?? i18n.ts.none }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.sensitive }}</template>
|
||||
<template #value>{{ emoji.isSensitive ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.localOnly }}</template>
|
||||
<template #value>{{ emoji.localOnly ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.license }}</template>
|
||||
<template #value><Mfm :text="emoji.license ?? i18n.ts.none"/></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue :copy="emoji.url">
|
||||
<template #key>{{ i18n.ts.emojiUrl }}</template>
|
||||
<template #value>
|
||||
<MkLink :url="emoji.url" target="_blank">{{ emoji.url }}</MkLink>
|
||||
</template>
|
||||
</MkKeyValue>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
</MkModalWindow>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { defineProps, shallowRef } from 'vue';
|
||||
import MkLink from '@/components/MkLink.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import MkModalWindow from '@/components/MkModalWindow.vue';
|
||||
import MkKeyValue from '@/components/MkKeyValue.vue';
|
||||
import MkLink from './MkLink.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
emoji: Misskey.entities.EmojiDetailed,
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'ok', cropped: Misskey.entities.DriveFile): void;
|
||||
(ev: 'cancel'): void;
|
||||
(ev: 'closed'): void;
|
||||
}>();
|
||||
|
||||
const dialogEl = shallowRef<InstanceType<typeof MkModalWindow>>();
|
||||
const cancel = () => {
|
||||
|
||||
function cancel() {
|
||||
emit('cancel');
|
||||
dialogEl.value!.close();
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
@@ -12,10 +12,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<img :src="instance.iconUrl || '/favicon.ico'" alt="" class="icon"/>
|
||||
</div>
|
||||
|
||||
<MkInfo v-if="thereIsUnresolvedAbuseReport" warn class="info">{{ i18n.ts.thereIsUnresolvedAbuseReportWarning }} <MkA to="/admin/abuses" class="_link">{{ i18n.ts.check }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noMaintainerInformation" warn class="info">{{ i18n.ts.noMaintainerInformationWarning }} <MkA to="/admin/settings" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noBotProtection" warn class="info">{{ i18n.ts.noBotProtectionWarning }} <MkA to="/admin/security" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noEmailServer" warn class="info">{{ i18n.ts.noEmailServerWarning }} <MkA to="/admin/email-settings" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
|
||||
<div class="_gaps_s">
|
||||
<MkInfo v-if="thereIsUnresolvedAbuseReport" warn>{{ i18n.ts.thereIsUnresolvedAbuseReportWarning }} <MkA to="/admin/abuses" class="_link">{{ i18n.ts.check }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noMaintainerInformation" warn>{{ i18n.ts.noMaintainerInformationWarning }} <MkA to="/admin/settings" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noInquiryUrl" warn>{{ i18n.ts.noInquiryUrlWarning }} <MkA to="/admin/moderation" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noBotProtection" warn>{{ i18n.ts.noBotProtectionWarning }} <MkA to="/admin/security" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noEmailServer" warn>{{ i18n.ts.noEmailServerWarning }} <MkA to="/admin/email-settings" class="_link">{{ i18n.ts.configure }}</MkA></MkInfo>
|
||||
</div>
|
||||
|
||||
<MkSuperMenu :def="menuDef" :grid="narrow"></MkSuperMenu>
|
||||
</div>
|
||||
@@ -61,6 +64,7 @@ const pageProps = ref({});
|
||||
let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail);
|
||||
let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha && !instance.enableTurnstile;
|
||||
let noEmailServer = !instance.enableEmail;
|
||||
let noInquiryUrl = isEmpty(instance.inquiryUrl);
|
||||
const thereIsUnresolvedAbuseReport = ref(false);
|
||||
const currentPage = computed(() => router.currentRef.value.child);
|
||||
|
||||
@@ -348,10 +352,6 @@ defineExpose({
|
||||
|
||||
> .nav {
|
||||
.lxpfedzu {
|
||||
> .info {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
> .banner {
|
||||
margin: 16px;
|
||||
|
||||
|
@@ -30,6 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template #label>{{ i18n.ts.privacyPolicyUrl }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkInput v-model="inquiryUrl" type="url">
|
||||
<template #prefix><i class="ti ti-link"></i></template>
|
||||
<template #label>{{ i18n.ts._serverSettings.inquiryUrl }}</template>
|
||||
<template #caption>{{ i18n.ts._serverSettings.inquiryUrlDescription }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkTextarea v-model="preservedUsernames">
|
||||
<template #label>{{ i18n.ts.preservedUsernames }}</template>
|
||||
<template #caption>{{ i18n.ts.preservedUsernamesDescription }}</template>
|
||||
@@ -86,6 +92,7 @@ const hiddenTags = ref<string>('');
|
||||
const preservedUsernames = ref<string>('');
|
||||
const tosUrl = ref<string | null>(null);
|
||||
const privacyPolicyUrl = ref<string | null>(null);
|
||||
const inquiryUrl = ref<string | null>(null);
|
||||
|
||||
async function init() {
|
||||
const meta = await misskeyApi('admin/meta');
|
||||
@@ -97,6 +104,7 @@ async function init() {
|
||||
preservedUsernames.value = meta.preservedUsernames.join('\n');
|
||||
tosUrl.value = meta.tosUrl;
|
||||
privacyPolicyUrl.value = meta.privacyPolicyUrl;
|
||||
inquiryUrl.value = meta.inquiryUrl;
|
||||
}
|
||||
|
||||
function save() {
|
||||
@@ -105,6 +113,7 @@ function save() {
|
||||
emailRequiredForSignup: emailRequiredForSignup.value,
|
||||
tosUrl: tosUrl.value,
|
||||
privacyPolicyUrl: privacyPolicyUrl.value,
|
||||
inquiryUrl: inquiryUrl.value,
|
||||
sensitiveWords: sensitiveWords.value.split('\n'),
|
||||
prohibitedWords: prohibitedWords.value.split('\n'),
|
||||
hiddenTags: hiddenTags.value.split('\n'),
|
||||
|
@@ -7,7 +7,21 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader/></template>
|
||||
<MkSpacer :contentMax="600" :marginMin="20">
|
||||
<div>{{ instance.maintainerEmail }}</div>
|
||||
<div class="_gaps">
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.inquiry }}</template>
|
||||
<template #value>
|
||||
<MkLink :url="instance.inquiryUrl" target="_blank">{{ instance.inquiryUrl }}</MkLink>
|
||||
</template>
|
||||
</MkKeyValue>
|
||||
|
||||
<MkKeyValue>
|
||||
<template #key>{{ i18n.ts.email }}</template>
|
||||
<template #value>
|
||||
<div>{{ instance.maintainerEmail }}</div>
|
||||
</template>
|
||||
</MkKeyValue>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
@@ -16,6 +30,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
||||
import { instance } from '@/instance.js';
|
||||
import MkKeyValue from '@/components/MkKeyValue.vue';
|
||||
import MkLink from '@/components/MkLink.vue';
|
||||
|
||||
definePageMetadata(() => ({
|
||||
title: i18n.ts.inquiry,
|
||||
|
@@ -6,15 +6,16 @@
|
||||
import * as Misskey from 'misskey-js';
|
||||
|
||||
export function shouldCollapsed(note: Misskey.entities.Note, urls: string[]): boolean {
|
||||
const collapsed = note.cw == null && note.text != null && (
|
||||
(note.text.includes('$[x2')) ||
|
||||
(note.text.includes('$[x3')) ||
|
||||
(note.text.includes('$[x4')) ||
|
||||
(note.text.includes('$[scale')) ||
|
||||
(note.text.split('\n').length > 9) ||
|
||||
(note.text.length > 500) ||
|
||||
(note.files.length >= 5) ||
|
||||
(urls.length >= 4)
|
||||
const collapsed = note.cw == null && (
|
||||
note.text != null && (
|
||||
(note.text.includes('$[x2')) ||
|
||||
(note.text.includes('$[x3')) ||
|
||||
(note.text.includes('$[x4')) ||
|
||||
(note.text.includes('$[scale')) ||
|
||||
(note.text.split('\n').length > 9) ||
|
||||
(note.text.length > 500) ||
|
||||
(urls.length >= 4)
|
||||
) || note.files.length >= 5
|
||||
);
|
||||
|
||||
return collapsed;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"type": "module",
|
||||
"name": "misskey-js",
|
||||
"version": "2024.5.0-beta.5",
|
||||
"version": "2024.5.0",
|
||||
"description": "Misskey SDK for JavaScript",
|
||||
"license": "MIT",
|
||||
"main": "./built/index.js",
|
||||
"types": "./built/index.d.ts",
|
||||
"exports": {
|
||||
@@ -30,7 +31,8 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/misskey-dev/misskey.js.git"
|
||||
"url": "https://github.com/misskey-dev/misskey.git",
|
||||
"directory": "packages/misskey-js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/api-extractor": "7.43.1",
|
||||
|
@@ -4449,6 +4449,8 @@ export type components = {
|
||||
isActive: boolean;
|
||||
/** @default false */
|
||||
hasUnreadNote: boolean;
|
||||
/** @default false */
|
||||
notify: boolean;
|
||||
};
|
||||
Clip: {
|
||||
/**
|
||||
@@ -4831,6 +4833,7 @@ export type components = {
|
||||
impressumUrl: string | null;
|
||||
logoImageUrl: string | null;
|
||||
privacyPolicyUrl: string | null;
|
||||
inquiryUrl: string | null;
|
||||
serverRules: string[];
|
||||
themeColor: string | null;
|
||||
policies: components['schemas']['RolePolicies'];
|
||||
@@ -4978,6 +4981,7 @@ export type operations = {
|
||||
shortName: string | null;
|
||||
objectStorageS3ForcePathStyle: boolean;
|
||||
privacyPolicyUrl: string | null;
|
||||
inquiryUrl: string | null;
|
||||
repositoryUrl: string | null;
|
||||
/**
|
||||
* @deprecated
|
||||
@@ -8906,6 +8910,7 @@ export type operations = {
|
||||
feedbackUrl?: string | null;
|
||||
impressumUrl?: string | null;
|
||||
privacyPolicyUrl?: string | null;
|
||||
inquiryUrl?: string | null;
|
||||
useObjectStorage?: boolean;
|
||||
objectStorageBaseUrl?: string | null;
|
||||
objectStorageBucket?: string | null;
|
||||
|
630
pnpm-lock.yaml
generated
630
pnpm-lock.yaml
generated
@@ -140,6 +140,12 @@ importers:
|
||||
'@peertube/http-signature':
|
||||
specifier: 1.7.0
|
||||
version: 1.7.0
|
||||
'@sentry/node':
|
||||
specifier: ^8.5.0
|
||||
version: 8.5.0
|
||||
'@sentry/profiling-node':
|
||||
specifier: ^8.5.0
|
||||
version: 8.5.0
|
||||
'@simplewebauthn/server':
|
||||
specifier: 10.0.0
|
||||
version: 10.0.0(encoding@0.1.13)
|
||||
@@ -3264,6 +3270,154 @@ packages:
|
||||
'@open-draft/until@2.1.0':
|
||||
resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
|
||||
|
||||
'@opentelemetry/api-logs@0.51.1':
|
||||
resolution: {integrity: sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@opentelemetry/api@1.8.0':
|
||||
resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
'@opentelemetry/context-async-hooks@1.24.1':
|
||||
resolution: {integrity: sha512-R5r6DO4kgEOVBxFXhXjwospLQkv+sYxwCfjvoZBe7Zm6KKXAV9kDSJhi/D1BweowdZmO+sdbENLs374gER8hpQ==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.9.0'
|
||||
|
||||
'@opentelemetry/core@1.24.1':
|
||||
resolution: {integrity: sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.9.0'
|
||||
|
||||
'@opentelemetry/instrumentation-connect@0.36.0':
|
||||
resolution: {integrity: sha512-k9++bmJZ9zDEs3u3DnKTn2l7QTiNFg3gPx7G9rW0TPnP+xZoBSBTrEcGYBaqflQlrFG23Q58+X1sM2ayWPv5Fg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-express@0.39.0':
|
||||
resolution: {integrity: sha512-AG8U7z7D0JcBu/7dDcwb47UMEzj9/FMiJV2iQZqrsZnxR3FjB9J9oIH2iszJYci2eUdp2WbdvtpD9RV/zmME5A==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-fastify@0.36.1':
|
||||
resolution: {integrity: sha512-3Nfm43PI0I+3EX+1YbSy6xbDu276R1Dh1tqAk68yd4yirnIh52Kd5B+nJ8CgHA7o3UKakpBjj6vSzi5vNCzJIA==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-graphql@0.40.0':
|
||||
resolution: {integrity: sha512-LVRdEHWACWOczv2imD+mhUrLMxsEjPPi32vIZJT57zygR5aUiA4em8X3aiGOCycgbMWkIu8xOSGSxdx3JmzN+w==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-hapi@0.38.0':
|
||||
resolution: {integrity: sha512-ZcOqEuwuutTDYIjhDIStix22ECblG/i9pHje23QGs4Q4YS4RMaZ5hKCoQJxW88Z4K7T53rQkdISmoXFKDV8xMg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-http@0.51.1':
|
||||
resolution: {integrity: sha512-6b3nZnFFEz/3xZ6w8bVxctPUWIPWiXuPQ725530JgxnN1cvYFd8CJ75PrHZNjynmzSSnqBkN3ef4R9N+RpMh8Q==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-ioredis@0.40.0':
|
||||
resolution: {integrity: sha512-Jv/fH7KhpWe4KBirsiqeUJIYrsdR2iu2l4nWhfOlRvaZ+zYIiLEzTQR6QhBbyRoAbU4OuYJzjWusOmmpGBnwng==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-koa@0.40.0':
|
||||
resolution: {integrity: sha512-dJc3H/bKMcgUYcQpLF+1IbmUKus0e5Fnn/+ru/3voIRHwMADT3rFSUcGLWSczkg68BCgz0vFWGDTvPtcWIFr7A==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-mongodb@0.43.0':
|
||||
resolution: {integrity: sha512-bMKej7Y76QVUD3l55Q9YqizXybHUzF3pujsBFjqbZrRn2WYqtsDtTUlbCK7fvXNPwFInqZ2KhnTqd0gwo8MzaQ==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-mongoose@0.38.1':
|
||||
resolution: {integrity: sha512-zaeiasdnRjXe6VhYCBMdkmAVh1S5MmXC/0spet+yqoaViGnYst/DOxPvhwg3yT4Yag5crZNWsVXnA538UjP6Ow==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-mysql2@0.38.1':
|
||||
resolution: {integrity: sha512-qkpHMgWSDTYVB1vlZ9sspf7l2wdS5DDq/rbIepDwX5BA0N0068JTQqh0CgAh34tdFqSCnWXIhcyOXC2TtRb0sg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-mysql@0.38.1':
|
||||
resolution: {integrity: sha512-+iBAawUaTfX/HAlvySwozx0C2B6LBfNPXX1W8Z2On1Uva33AGkw2UjL9XgIg1Pj4eLZ9R4EoJ/aFz+Xj4E/7Fw==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-nestjs-core@0.37.1':
|
||||
resolution: {integrity: sha512-ebYQjHZEmGHWEALwwDGhSQVLBaurFnuLIkZD5igPXrt7ohfF4lc5/4al1LO+vKc0NHk8SJWStuRueT86ISA8Vg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation-pg@0.41.0':
|
||||
resolution: {integrity: sha512-BSlhpivzBD77meQNZY9fS4aKgydA8AJBzv2dqvxXFy/Hq64b7HURgw/ztbmwFeYwdF5raZZUifiiNSMLpOJoSA==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation@0.43.0':
|
||||
resolution: {integrity: sha512-S1uHE+sxaepgp+t8lvIDuRgyjJWisAb733198kwQTUc9ZtYQ2V2gmyCtR1x21ePGVLoMiX/NWY7WA290hwkjJQ==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/instrumentation@0.51.1':
|
||||
resolution: {integrity: sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/redis-common@0.36.2':
|
||||
resolution: {integrity: sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@opentelemetry/resources@1.24.1':
|
||||
resolution: {integrity: sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.9.0'
|
||||
|
||||
'@opentelemetry/sdk-metrics@1.24.1':
|
||||
resolution: {integrity: sha512-FrAqCbbGao9iKI+Mgh+OsC9+U2YMoXnlDHe06yH7dvavCKzE3S892dGtX54+WhSFVxHR/TMRVJiK/CV93GR0TQ==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.3.0 <1.9.0'
|
||||
|
||||
'@opentelemetry/sdk-trace-base@1.24.1':
|
||||
resolution: {integrity: sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.9.0'
|
||||
|
||||
'@opentelemetry/semantic-conventions@1.24.1':
|
||||
resolution: {integrity: sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@opentelemetry/sql-common@0.40.1':
|
||||
resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.1.0
|
||||
|
||||
'@peculiar/asn1-android@2.3.10':
|
||||
resolution: {integrity: sha512-z9Rx9cFJv7UUablZISe7uksNbFJCq13hO0yEAOoIpAymALTLlvUOSLnGiQS7okPaM5dP42oTLhezH6XDXRXjGw==}
|
||||
|
||||
@@ -3287,6 +3441,9 @@ packages:
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@prisma/instrumentation@5.14.0':
|
||||
resolution: {integrity: sha512-DeybWvIZzu/mUsOYP9MVd6AyBj+MP7xIMrcuIn25MX8FiQX39QBnET5KhszTAip/ToctUuDwSJ46QkIoyo3RFA==}
|
||||
|
||||
'@radix-ui/react-compose-refs@1.0.1':
|
||||
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
||||
peerDependencies:
|
||||
@@ -3449,6 +3606,37 @@ packages:
|
||||
'@rushstack/ts-command-line@4.19.2':
|
||||
resolution: {integrity: sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==}
|
||||
|
||||
'@sentry/core@8.5.0':
|
||||
resolution: {integrity: sha512-SO3ddBzGdha+Oflp+IKwBxj+7ds1q69OAT3VsypTd+WUFQdI9DIhR92Bjf+QQZCIzUNOi79VWOh3aOi3f6hMnw==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry/node@8.5.0':
|
||||
resolution: {integrity: sha512-t9cHAx/wLJYtdVf2XlzKlRJGvwdAp1wjzG0tC4E1Znx74OuUS1cFNo5WrGuOi0/YcWSxiJaxBvtUcsWK86fIgw==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry/opentelemetry@8.5.0':
|
||||
resolution: {integrity: sha512-AbxFUNjuTKQ9ugZrssmGtPxWkBr4USNoP7GjaaGCNwNzvIVYCa+i8dv7BROJiW2lsxNAremULEbh+nbVmhGxDA==}
|
||||
engines: {node: '>=14.18'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.8.0
|
||||
'@opentelemetry/core': ^1.24.1
|
||||
'@opentelemetry/instrumentation': ^0.51.1
|
||||
'@opentelemetry/sdk-trace-base': ^1.23.0
|
||||
'@opentelemetry/semantic-conventions': ^1.23.0
|
||||
|
||||
'@sentry/profiling-node@8.5.0':
|
||||
resolution: {integrity: sha512-nEXJqVNfZWYi4PakQXBZCJeH59UlnBv+zaYftDNUUXttCmzRXpL1ujNm5mJrJHlWjV7tgIFw02HW3nh2yyKOkw==}
|
||||
engines: {node: '>=14.18'}
|
||||
hasBin: true
|
||||
|
||||
'@sentry/types@8.5.0':
|
||||
resolution: {integrity: sha512-eDgkSmKI4+XL0QZm4H3j/n1RgnrbnjXZmjj+LsfccRZQwbPu9bWlc8q7Y7Ty1gOsoUpX+TecNLp2a8CRID4KHA==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@sentry/utils@8.5.0':
|
||||
resolution: {integrity: sha512-fdrCzo8SAYiw9JBhkJPqYqJkDXZ/wICzN7+zcXIuzKNhE1hdoFjeKcPnpUI3bKZCG6e3hT1PTYQXhVw7GIZV9w==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
'@shikijs/core@1.4.0':
|
||||
resolution: {integrity: sha512-CxpKLntAi64h3j+TwWqVIQObPTED0FyXLHTTh3MKXtqiQNn2JGcMQQ362LftDbc9kYbDtrksNMNoVmVXzKFYUQ==}
|
||||
|
||||
@@ -4254,12 +4442,18 @@ packages:
|
||||
'@types/connect@3.4.35':
|
||||
resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
|
||||
|
||||
'@types/connect@3.4.36':
|
||||
resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==}
|
||||
|
||||
'@types/content-disposition@0.5.8':
|
||||
resolution: {integrity: sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==}
|
||||
|
||||
'@types/cookie@0.6.0':
|
||||
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
||||
|
||||
'@types/cookies@0.9.0':
|
||||
resolution: {integrity: sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==}
|
||||
|
||||
'@types/cross-spawn@6.0.2':
|
||||
resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==}
|
||||
|
||||
@@ -4323,9 +4517,15 @@ packages:
|
||||
'@types/htmlescape@1.1.3':
|
||||
resolution: {integrity: sha512-tuC81YJXGUe0q8WRtBNW+uyx79rkkzWK651ALIXXYq5/u/IxjX4iHneGF2uUqzsNp+F+9J2mFZOv9jiLTtIq0w==}
|
||||
|
||||
'@types/http-assert@1.5.5':
|
||||
resolution: {integrity: sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==}
|
||||
|
||||
'@types/http-cache-semantics@4.0.4':
|
||||
resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==}
|
||||
|
||||
'@types/http-errors@2.0.4':
|
||||
resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
|
||||
|
||||
'@types/http-link-header@1.0.5':
|
||||
resolution: {integrity: sha512-AxhIKR8UbyoqCTNp9rRepkktHuUOw3DjfOfDCaO9kwI8AYzjhxyrvZq4+mRw/2daD3hYDknrtSeV6SsPwmc71w==}
|
||||
|
||||
@@ -4362,9 +4562,21 @@ packages:
|
||||
'@types/jsrsasign@10.5.14':
|
||||
resolution: {integrity: sha512-lppSlfK6etu+cuKs40K4rg8As79PH6hzIB+v55zSqImbSH3SE6Fm8MBHCiI91cWlAP3Z4igtJK1VL3fSN09blQ==}
|
||||
|
||||
'@types/keygrip@1.0.6':
|
||||
resolution: {integrity: sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==}
|
||||
|
||||
'@types/keyv@3.1.4':
|
||||
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
||||
|
||||
'@types/koa-compose@3.2.8':
|
||||
resolution: {integrity: sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==}
|
||||
|
||||
'@types/koa@2.14.0':
|
||||
resolution: {integrity: sha512-DTDUyznHGNHAl+wd1n0z1jxNajduyTh8R53xoewuerdBzGo6Ogj6F2299BFtrexJw4NtgjsI5SMPCmV9gZwGXA==}
|
||||
|
||||
'@types/koa__router@12.0.3':
|
||||
resolution: {integrity: sha512-5YUJVv6NwM1z7m6FuYpKfNLTZ932Z6EF6xy2BbtpJSyn13DKNQEkXVffFVSnJHxvwwWh2SAeumpjAYUELqgjyw==}
|
||||
|
||||
'@types/lodash@4.14.191':
|
||||
resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==}
|
||||
|
||||
@@ -4401,6 +4613,9 @@ packages:
|
||||
'@types/mute-stream@0.0.4':
|
||||
resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==}
|
||||
|
||||
'@types/mysql@2.15.22':
|
||||
resolution: {integrity: sha512-wK1pzsJVVAjYCSZWQoWHziQZbNggXFDUEIGf54g4ZM/ERuP86uGdWeKZWMYlqTPMZfHJJvLPyogXGvCOg87yLQ==}
|
||||
|
||||
'@types/node-fetch@2.6.4':
|
||||
resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
|
||||
|
||||
@@ -4441,9 +4656,15 @@ packages:
|
||||
'@types/offscreencanvas@2019.7.0':
|
||||
resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==}
|
||||
|
||||
'@types/pg-pool@2.0.4':
|
||||
resolution: {integrity: sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==}
|
||||
|
||||
'@types/pg@8.11.5':
|
||||
resolution: {integrity: sha512-2xMjVviMxneZHDHX5p5S6tsRRs7TpDHeeK7kTTMe/kAC/mRRNjWHjZg0rkiY+e17jXSZV3zJYDxXV8Cy72/Vuw==}
|
||||
|
||||
'@types/pg@8.6.1':
|
||||
resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==}
|
||||
|
||||
'@types/pretty-hrtime@1.0.1':
|
||||
resolution: {integrity: sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==}
|
||||
|
||||
@@ -4507,6 +4728,9 @@ packages:
|
||||
'@types/serviceworker@0.0.67':
|
||||
resolution: {integrity: sha512-7TCH7iNsCSNb+aUD9M/36TekrWFSLCjNK8zw/3n5kOtRjbLtDfGYMXTrDnGhSfqXNwpqmt9Vd90w5C/ad1tX6Q==}
|
||||
|
||||
'@types/shimmer@1.0.5':
|
||||
resolution: {integrity: sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==}
|
||||
|
||||
'@types/simple-oauth2@5.0.7':
|
||||
resolution: {integrity: sha512-8JbWVJbiTSBQP/7eiyGKyXWAqp3dKQZpaA+pdW16FCi32ujkzRMG8JfjoAzdWt6W8U591ZNdHcPtP2D7ILTKuA==}
|
||||
|
||||
@@ -4900,6 +5124,16 @@ packages:
|
||||
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
acorn-import-assertions@1.9.0:
|
||||
resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==}
|
||||
peerDependencies:
|
||||
acorn: ^8
|
||||
|
||||
acorn-import-attributes@1.9.5:
|
||||
resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==}
|
||||
peerDependencies:
|
||||
acorn: ^8
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
@@ -7111,6 +7345,12 @@ packages:
|
||||
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
import-in-the-middle@1.4.2:
|
||||
resolution: {integrity: sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==}
|
||||
|
||||
import-in-the-middle@1.7.4:
|
||||
resolution: {integrity: sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==}
|
||||
|
||||
import-lazy@4.0.0:
|
||||
resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -8275,6 +8515,9 @@ packages:
|
||||
resolution: {integrity: sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
module-details-from-path@1.0.3:
|
||||
resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==}
|
||||
|
||||
mri@1.2.0:
|
||||
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -8393,6 +8636,10 @@ packages:
|
||||
nise@5.1.4:
|
||||
resolution: {integrity: sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==}
|
||||
|
||||
node-abi@3.62.0:
|
||||
resolution: {integrity: sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
node-abort-controller@3.1.1:
|
||||
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
|
||||
|
||||
@@ -8626,6 +8873,10 @@ packages:
|
||||
resolution: {integrity: sha512-es3mGcDXV6TKPo6n3aohzHm0qxhLyR39MhF6mkD1FwFGjhxnqMqfSIgM0eCpInZvqatve4CxmXcMZw3jnnsaXw==}
|
||||
hasBin: true
|
||||
|
||||
opentelemetry-instrumentation-fetch-node@1.2.0:
|
||||
resolution: {integrity: sha512-aiSt/4ubOTyb1N5C2ZbGrBvaJOXIZhZvpRPYuUVxQJe27wJZqf/o65iPrqgLcgfeOLaQ8cS2Q+762jrYvniTrA==}
|
||||
engines: {node: '>18.0.0'}
|
||||
|
||||
optionator@0.9.3:
|
||||
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@@ -9570,6 +9821,10 @@ packages:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
require-in-the-middle@7.3.0:
|
||||
resolution: {integrity: sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
||||
require-main-filename@2.0.0:
|
||||
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||
|
||||
@@ -9784,6 +10039,9 @@ packages:
|
||||
shiki@1.4.0:
|
||||
resolution: {integrity: sha512-5WIn0OL8PWm7JhnTwRWXniy6eEDY234mRrERVlFa646V2ErQqwIFd2UML7e0Pq9eqSKLoMa3Ke+xbsF+DAuy+Q==}
|
||||
|
||||
shimmer@1.2.1:
|
||||
resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==}
|
||||
|
||||
side-channel@1.0.4:
|
||||
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
|
||||
|
||||
@@ -13733,6 +13991,203 @@ snapshots:
|
||||
|
||||
'@open-draft/until@2.1.0': {}
|
||||
|
||||
'@opentelemetry/api-logs@0.51.1':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
|
||||
'@opentelemetry/api@1.8.0': {}
|
||||
|
||||
'@opentelemetry/context-async-hooks@1.24.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
|
||||
'@opentelemetry/core@1.24.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
|
||||
'@opentelemetry/instrumentation-connect@0.36.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
'@types/connect': 3.4.36
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-express@0.39.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-fastify@0.36.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-graphql@0.40.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-hapi@0.38.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-http@0.51.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-ioredis@0.40.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/redis-common': 0.36.2
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-koa@0.40.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
'@types/koa': 2.14.0
|
||||
'@types/koa__router': 12.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-mongodb@0.43.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/sdk-metrics': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-mongoose@0.38.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-mysql2@0.38.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
'@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.8.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-mysql@0.38.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
'@types/mysql': 2.15.22
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-nestjs-core@0.37.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation-pg@0.41.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
'@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.8.0)
|
||||
'@types/pg': 8.6.1
|
||||
'@types/pg-pool': 2.0.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/instrumentation@0.43.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@types/shimmer': 1.0.5
|
||||
import-in-the-middle: 1.4.2
|
||||
require-in-the-middle: 7.3.0
|
||||
semver: 7.6.0
|
||||
shimmer: 1.2.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
'@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/api-logs': 0.51.1
|
||||
'@types/shimmer': 1.0.5
|
||||
import-in-the-middle: 1.7.4
|
||||
require-in-the-middle: 7.3.0
|
||||
semver: 7.6.0
|
||||
shimmer: 1.2.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/redis-common@0.36.2': {}
|
||||
|
||||
'@opentelemetry/resources@1.24.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
|
||||
'@opentelemetry/sdk-metrics@1.24.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
lodash.merge: 4.6.2
|
||||
|
||||
'@opentelemetry/sdk-trace-base@1.24.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
|
||||
'@opentelemetry/semantic-conventions@1.24.1': {}
|
||||
|
||||
'@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
|
||||
'@peculiar/asn1-android@2.3.10':
|
||||
dependencies:
|
||||
'@peculiar/asn1-schema': 2.3.8
|
||||
@@ -13776,6 +14231,14 @@ snapshots:
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@prisma/instrumentation@5.14.0':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@radix-ui/react-compose-refs@1.0.1(@types/react@18.0.28)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.4
|
||||
@@ -13922,6 +14385,72 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
'@sentry/core@8.5.0':
|
||||
dependencies:
|
||||
'@sentry/types': 8.5.0
|
||||
'@sentry/utils': 8.5.0
|
||||
|
||||
'@sentry/node@8.5.0':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/context-async-hooks': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-connect': 0.36.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-express': 0.39.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-fastify': 0.36.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-graphql': 0.40.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-hapi': 0.38.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-http': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-ioredis': 0.40.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-koa': 0.40.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-mongodb': 0.43.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-mongoose': 0.38.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-mysql': 0.38.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-mysql2': 0.38.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-nestjs-core': 0.37.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation-pg': 0.41.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
'@prisma/instrumentation': 5.14.0
|
||||
'@sentry/core': 8.5.0
|
||||
'@sentry/opentelemetry': 8.5.0(@opentelemetry/api@1.8.0)(@opentelemetry/core@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0))(@opentelemetry/sdk-trace-base@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/semantic-conventions@1.24.1)
|
||||
'@sentry/types': 8.5.0
|
||||
'@sentry/utils': 8.5.0
|
||||
optionalDependencies:
|
||||
opentelemetry-instrumentation-fetch-node: 1.2.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sentry/opentelemetry@8.5.0(@opentelemetry/api@1.8.0)(@opentelemetry/core@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0))(@opentelemetry/sdk-trace-base@1.24.1(@opentelemetry/api@1.8.0))(@opentelemetry/semantic-conventions@1.24.1)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
'@sentry/core': 8.5.0
|
||||
'@sentry/types': 8.5.0
|
||||
'@sentry/utils': 8.5.0
|
||||
|
||||
'@sentry/profiling-node@8.5.0':
|
||||
dependencies:
|
||||
'@sentry/core': 8.5.0
|
||||
'@sentry/node': 8.5.0
|
||||
'@sentry/types': 8.5.0
|
||||
'@sentry/utils': 8.5.0
|
||||
detect-libc: 2.0.3
|
||||
node-abi: 3.62.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@sentry/types@8.5.0': {}
|
||||
|
||||
'@sentry/utils@8.5.0':
|
||||
dependencies:
|
||||
'@sentry/types': 8.5.0
|
||||
|
||||
'@shikijs/core@1.4.0': {}
|
||||
|
||||
'@sideway/address@4.1.4':
|
||||
@@ -15301,10 +15830,21 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
|
||||
'@types/connect@3.4.36':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
|
||||
'@types/content-disposition@0.5.8': {}
|
||||
|
||||
'@types/cookie@0.6.0': {}
|
||||
|
||||
'@types/cookies@0.9.0':
|
||||
dependencies:
|
||||
'@types/connect': 3.4.35
|
||||
'@types/express': 4.17.17
|
||||
'@types/keygrip': 1.0.6
|
||||
'@types/node': 20.12.7
|
||||
|
||||
'@types/cross-spawn@6.0.2':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
@@ -15372,8 +15912,12 @@ snapshots:
|
||||
|
||||
'@types/htmlescape@1.1.3': {}
|
||||
|
||||
'@types/http-assert@1.5.5': {}
|
||||
|
||||
'@types/http-cache-semantics@4.0.4': {}
|
||||
|
||||
'@types/http-errors@2.0.4': {}
|
||||
|
||||
'@types/http-link-header@1.0.5':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
@@ -15411,10 +15955,31 @@ snapshots:
|
||||
|
||||
'@types/jsrsasign@10.5.14': {}
|
||||
|
||||
'@types/keygrip@1.0.6': {}
|
||||
|
||||
'@types/keyv@3.1.4':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
|
||||
'@types/koa-compose@3.2.8':
|
||||
dependencies:
|
||||
'@types/koa': 2.14.0
|
||||
|
||||
'@types/koa@2.14.0':
|
||||
dependencies:
|
||||
'@types/accepts': 1.3.7
|
||||
'@types/content-disposition': 0.5.8
|
||||
'@types/cookies': 0.9.0
|
||||
'@types/http-assert': 1.5.5
|
||||
'@types/http-errors': 2.0.4
|
||||
'@types/keygrip': 1.0.6
|
||||
'@types/koa-compose': 3.2.8
|
||||
'@types/node': 20.12.7
|
||||
|
||||
'@types/koa__router@12.0.3':
|
||||
dependencies:
|
||||
'@types/koa': 2.14.0
|
||||
|
||||
'@types/lodash@4.14.191': {}
|
||||
|
||||
'@types/long@4.0.2': {}
|
||||
@@ -15445,6 +16010,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
|
||||
'@types/mysql@2.15.22':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
|
||||
'@types/node-fetch@2.6.4':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
@@ -15491,12 +16060,22 @@ snapshots:
|
||||
|
||||
'@types/offscreencanvas@2019.7.0': {}
|
||||
|
||||
'@types/pg-pool@2.0.4':
|
||||
dependencies:
|
||||
'@types/pg': 8.11.5
|
||||
|
||||
'@types/pg@8.11.5':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
pg-protocol: 1.6.0
|
||||
pg-types: 4.0.1
|
||||
|
||||
'@types/pg@8.6.1':
|
||||
dependencies:
|
||||
'@types/node': 20.12.7
|
||||
pg-protocol: 1.6.1
|
||||
pg-types: 2.2.0
|
||||
|
||||
'@types/pretty-hrtime@1.0.1': {}
|
||||
|
||||
'@types/prop-types@15.7.5': {}
|
||||
@@ -15554,6 +16133,8 @@ snapshots:
|
||||
|
||||
'@types/serviceworker@0.0.67': {}
|
||||
|
||||
'@types/shimmer@1.0.5': {}
|
||||
|
||||
'@types/simple-oauth2@5.0.7': {}
|
||||
|
||||
'@types/sinon@10.0.13':
|
||||
@@ -16096,6 +16677,15 @@ snapshots:
|
||||
mime-types: 2.1.35
|
||||
negotiator: 0.6.3
|
||||
|
||||
acorn-import-assertions@1.9.0(acorn@8.11.3):
|
||||
dependencies:
|
||||
acorn: 8.11.3
|
||||
optional: true
|
||||
|
||||
acorn-import-attributes@1.9.5(acorn@8.11.3):
|
||||
dependencies:
|
||||
acorn: 8.11.3
|
||||
|
||||
acorn-jsx@5.3.2(acorn@7.4.1):
|
||||
dependencies:
|
||||
acorn: 7.4.1
|
||||
@@ -19001,6 +19591,21 @@ snapshots:
|
||||
parent-module: 1.0.1
|
||||
resolve-from: 4.0.0
|
||||
|
||||
import-in-the-middle@1.4.2:
|
||||
dependencies:
|
||||
acorn: 8.11.3
|
||||
acorn-import-assertions: 1.9.0(acorn@8.11.3)
|
||||
cjs-module-lexer: 1.2.2
|
||||
module-details-from-path: 1.0.3
|
||||
optional: true
|
||||
|
||||
import-in-the-middle@1.7.4:
|
||||
dependencies:
|
||||
acorn: 8.11.3
|
||||
acorn-import-attributes: 1.9.5(acorn@8.11.3)
|
||||
cjs-module-lexer: 1.2.2
|
||||
module-details-from-path: 1.0.3
|
||||
|
||||
import-lazy@4.0.0: {}
|
||||
|
||||
import-local@3.1.0:
|
||||
@@ -20509,6 +21114,8 @@ snapshots:
|
||||
|
||||
mock-socket@9.3.1: {}
|
||||
|
||||
module-details-from-path@1.0.3: {}
|
||||
|
||||
mri@1.2.0: {}
|
||||
|
||||
ms@2.0.0: {}
|
||||
@@ -20645,6 +21252,10 @@ snapshots:
|
||||
just-extend: 4.2.1
|
||||
path-to-regexp: 1.8.0
|
||||
|
||||
node-abi@3.62.0:
|
||||
dependencies:
|
||||
semver: 7.6.0
|
||||
|
||||
node-abort-controller@3.1.1: {}
|
||||
|
||||
node-addon-api@3.2.1:
|
||||
@@ -20897,6 +21508,15 @@ snapshots:
|
||||
undici: 5.28.2
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
opentelemetry-instrumentation-fetch-node@1.2.0:
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/instrumentation': 0.43.0(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
optionator@0.9.3:
|
||||
dependencies:
|
||||
'@aashutoshrathi/word-wrap': 1.2.6
|
||||
@@ -21910,6 +22530,14 @@ snapshots:
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
require-in-the-middle@7.3.0:
|
||||
dependencies:
|
||||
debug: 4.3.4(supports-color@8.1.1)
|
||||
module-details-from-path: 1.0.3
|
||||
resolve: 1.22.8
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
require-main-filename@2.0.0: {}
|
||||
|
||||
requires-port@1.0.0: {}
|
||||
@@ -22168,6 +22796,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@shikijs/core': 1.4.0
|
||||
|
||||
shimmer@1.2.1: {}
|
||||
|
||||
side-channel@1.0.4:
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
|
Reference in New Issue
Block a user