Merge branch 'develop' into test-aeasfgtsghdgh
This commit is contained in:
commit
247a09f498
|
|
@ -5,7 +5,7 @@
|
||||||
"workspaceFolder": "/workspace",
|
"workspaceFolder": "/workspace",
|
||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
"version": "24.10.0"
|
"version": "22.15.0"
|
||||||
},
|
},
|
||||||
"ghcr.io/devcontainers-extra/features/pnpm:2": {
|
"ghcr.io/devcontainers-extra/features/pnpm:2": {
|
||||||
"version": "10.10.0"
|
"version": "10.10.0"
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ jobs:
|
||||||
- name: Copy Configure
|
- name: Copy Configure
|
||||||
run: cp .github/misskey/test.yml .config/default.yml
|
run: cp .github/misskey/test.yml .config/default.yml
|
||||||
- name: Compile Configure
|
- name: Compile Configure
|
||||||
run: pnpm convert:config
|
run: pnpm compile-config
|
||||||
- name: Build
|
- name: Build
|
||||||
run: pnpm build
|
run: pnpm build
|
||||||
- name: Run migrations
|
- name: Run migrations
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
24.10.0
|
22.15.0
|
||||||
|
|
|
||||||
16
CHANGELOG.md
16
CHANGELOG.md
|
|
@ -1,4 +1,4 @@
|
||||||
## 2025.12.0
|
## Unreleased
|
||||||
|
|
||||||
### General
|
### General
|
||||||
-
|
-
|
||||||
|
|
@ -6,11 +6,23 @@
|
||||||
### Client
|
### Client
|
||||||
-
|
-
|
||||||
|
|
||||||
|
### Server
|
||||||
|
-
|
||||||
|
|
||||||
|
|
||||||
|
## 2025.12.0
|
||||||
|
|
||||||
|
### Note
|
||||||
|
- configの`trustProxy`のデフォルト値を`false`に変更しました。アップデート前に現在のconfigをご確認の上、必要に応じて値を変更してください。
|
||||||
|
|
||||||
|
### Client
|
||||||
|
- Fix: stacking router viewで連続して戻る操作を行うと何も表示されなくなる問題を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- Enhance: メモリ使用量を削減しました
|
- Enhance: メモリ使用量を削減しました
|
||||||
- Enhance: ActivityPubアクティビティを送信する際のパフォーマンス向上
|
- Enhance: ActivityPubアクティビティを送信する際のパフォーマンス向上
|
||||||
- Enhance: 依存関係の更新
|
- Enhance: 依存関係の更新
|
||||||
|
- Fix: セキュリティに関する修正
|
||||||
|
|
||||||
## 2025.11.1
|
## 2025.11.1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# syntax = docker/dockerfile:1.4
|
# syntax = docker/dockerfile:1.4
|
||||||
|
|
||||||
ARG NODE_VERSION=24.10.0-bookworm
|
ARG NODE_VERSION=22.15.0-bookworm
|
||||||
|
|
||||||
# build assets & compile TypeScript
|
# build assets & compile TypeScript
|
||||||
|
|
||||||
|
|
|
||||||
14
package.json
14
package.json
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "2025.12.0-alpha.1",
|
"version": "2025.12.0",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/misskey-dev/misskey.git"
|
"url": "https://github.com/misskey-dev/misskey.git"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.23.0",
|
"packageManager": "pnpm@10.24.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/misskey-js",
|
"packages/misskey-js",
|
||||||
"packages/i18n",
|
"packages/i18n",
|
||||||
|
|
@ -22,15 +22,15 @@
|
||||||
],
|
],
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"convert:config": "cd packages/backend && pnpm convert:config",
|
"compile-config": "cd packages/backend && pnpm compile-config",
|
||||||
"build-pre": "node ./scripts/build-pre.js",
|
"build-pre": "node ./scripts/build-pre.js",
|
||||||
"build-assets": "node ./scripts/build-assets.mjs",
|
"build-assets": "node ./scripts/build-assets.mjs",
|
||||||
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
|
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
|
||||||
"build-storybook": "pnpm --filter frontend build-storybook",
|
"build-storybook": "pnpm --filter frontend build-storybook",
|
||||||
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
|
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
|
||||||
"start": "pnpm check:connect && cd packages/backend && pnpm convert:config && node ./built/boot/entry.js",
|
"start": "pnpm check:connect && cd packages/backend && pnpm compile-config && node ./built/boot/entry.js",
|
||||||
"start:inspect": "cd packages/backend && pnpm convert:config && node --inspect ./built/boot/entry.js",
|
"start:inspect": "cd packages/backend && pnpm compile-config && node --inspect ./built/boot/entry.js",
|
||||||
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && pnpm convert:config && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
||||||
"cli": "cd packages/backend && pnpm cli",
|
"cli": "cd packages/backend && pnpm cli",
|
||||||
"init": "pnpm migrate",
|
"init": "pnpm migrate",
|
||||||
"migrate": "cd packages/backend && pnpm migrate",
|
"migrate": "cd packages/backend && pnpm migrate",
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
"eslint": "9.39.1",
|
"eslint": "9.39.1",
|
||||||
"globals": "16.5.0",
|
"globals": "16.5.0",
|
||||||
"ncp": "2.0.0",
|
"ncp": "2.0.0",
|
||||||
"pnpm": "10.23.0",
|
"pnpm": "10.24.0",
|
||||||
"start-server-and-test": "2.1.3"
|
"start-server-and-test": "2.1.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,14 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isConcurrentIndexMigrationEnabled } from "./js/migration-config.js";
|
const isConcurrentIndexMigrationEnabled = process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
|
||||||
|
|
||||||
export class CompositeNoteIndex1745378064470 {
|
export class CompositeNoteIndex1745378064470 {
|
||||||
name = 'CompositeNoteIndex1745378064470';
|
name = 'CompositeNoteIndex1745378064470';
|
||||||
transaction = isConcurrentIndexMigrationEnabled() ? false : undefined;
|
transaction = isConcurrentIndexMigrationEnabled ? false : undefined;
|
||||||
|
|
||||||
async up(queryRunner) {
|
async up(queryRunner) {
|
||||||
const concurrently = isConcurrentIndexMigrationEnabled();
|
const concurrently = isConcurrentIndexMigrationEnabled;
|
||||||
|
|
||||||
if (concurrently) {
|
if (concurrently) {
|
||||||
const hasValidIndex = await queryRunner.query(`SELECT indisvalid FROM pg_index INNER JOIN pg_class ON pg_index.indexrelid = pg_class.oid WHERE pg_class.relname = 'IDX_724b311e6f883751f261ebe378'`);
|
const hasValidIndex = await queryRunner.query(`SELECT indisvalid FROM pg_index INNER JOIN pg_class ON pg_index.indexrelid = pg_class.oid WHERE pg_class.relname = 'IDX_724b311e6f883751f261ebe378'`);
|
||||||
|
|
@ -29,7 +29,7 @@ export class CompositeNoteIndex1745378064470 {
|
||||||
}
|
}
|
||||||
|
|
||||||
async down(queryRunner) {
|
async down(queryRunner) {
|
||||||
const mayConcurrently = isConcurrentIndexMigrationEnabled() ? 'CONCURRENTLY' : '';
|
const mayConcurrently = isConcurrentIndexMigrationEnabled ? 'CONCURRENTLY' : '';
|
||||||
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_724b311e6f883751f261ebe378"`);
|
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_724b311e6f883751f261ebe378"`);
|
||||||
await queryRunner.query(`CREATE INDEX ${mayConcurrently} "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId")`);
|
await queryRunner.query(`CREATE INDEX ${mayConcurrently} "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId")`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,15 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {loadConfig} from "./js/migration-config.js";
|
|
||||||
|
|
||||||
export class MigrateSomeConfigFileSettingsToMeta1746949539915 {
|
export class MigrateSomeConfigFileSettingsToMeta1746949539915 {
|
||||||
name = 'MigrateSomeConfigFileSettingsToMeta1746949539915'
|
name = 'MigrateSomeConfigFileSettingsToMeta1746949539915'
|
||||||
|
|
||||||
async up(queryRunner) {
|
async up(queryRunner) {
|
||||||
const config = loadConfig();
|
|
||||||
// $1 cannot be used in ALTER TABLE queries
|
// $1 cannot be used in ALTER TABLE queries
|
||||||
await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT ${config.proxyRemoteFiles}`);
|
await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT TRUE`);
|
||||||
await queryRunner.query(`ALTER TABLE "meta" ADD "signToActivityPubGet" boolean NOT NULL DEFAULT ${config.signToActivityPubGet}`);
|
await queryRunner.query(`ALTER TABLE "meta" ADD "signToActivityPubGet" boolean NOT NULL DEFAULT TRUE`);
|
||||||
await queryRunner.query(`ALTER TABLE "meta" ADD "allowExternalApRedirect" boolean NOT NULL DEFAULT ${!config.disallowExternalApRedirect}`);
|
await queryRunner.query(`ALTER TABLE "meta" ADD "allowExternalApRedirect" boolean NOT NULL DEFAULT TRUE`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async down(queryRunner) {
|
async down(queryRunner) {
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { path as configYamlPath } from '../../built/config.js';
|
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
import fs from "node:fs";
|
|
||||||
|
|
||||||
export function isConcurrentIndexMigrationEnabled() {
|
|
||||||
return process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
|
|
||||||
}
|
|
||||||
|
|
||||||
let loadedConfigCache = undefined;
|
|
||||||
|
|
||||||
function loadConfigInternal() {
|
|
||||||
const config = yaml.load(fs.readFileSync(configYamlPath, 'utf-8'));
|
|
||||||
|
|
||||||
return {
|
|
||||||
disallowExternalApRedirect: Boolean(config.disallowExternalApRedirect ?? false),
|
|
||||||
proxyRemoteFiles: Boolean(config.proxyRemoteFiles ?? false),
|
|
||||||
signToActivityPubGet: Boolean(config.signToActivityPubGet ?? true),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function loadConfig() {
|
|
||||||
if (loadedConfigCache === undefined) {
|
|
||||||
loadedConfigCache = loadConfigInternal();
|
|
||||||
}
|
|
||||||
return loadedConfigCache;
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
import { loadConfig } from './built/config.js';
|
import { loadConfig } from './built/config.js';
|
||||||
import { entities } from './built/postgres.js';
|
import { entities } from './built/postgres.js';
|
||||||
import { isConcurrentIndexMigrationEnabled } from "./migration/js/migration-config.js";
|
|
||||||
|
const isConcurrentIndexMigrationEnabled = process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
|
||||||
|
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
|
|
||||||
|
|
@ -15,5 +16,5 @@ export default new DataSource({
|
||||||
extra: config.db.extra,
|
extra: config.db.extra,
|
||||||
entities: entities,
|
entities: entities,
|
||||||
migrations: ['migration/*.js'],
|
migrations: ['migration/*.js'],
|
||||||
migrationsTransactionMode: isConcurrentIndexMigrationEnabled() ? 'each' : 'all',
|
migrationsTransactionMode: isConcurrentIndexMigrationEnabled ? 'each' : 'all',
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,37 +7,37 @@
|
||||||
"node": "^22.15.0 || ^24.10.0"
|
"node": "^22.15.0 || ^24.10.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "pnpm convert:config && node ./built/boot/entry.js",
|
"start": "pnpm compile-config && node ./built/boot/entry.js",
|
||||||
"start:inspect": "pnpm convert:config && node --inspect ./built/boot/entry.js",
|
"start:inspect": "pnpm compile-config && node --inspect ./built/boot/entry.js",
|
||||||
"start:test": "pnpm convert:config && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
"start:test": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/boot/entry.js",
|
||||||
"migrate": "pnpm convert:config && pnpm typeorm migration:run -d ormconfig.js",
|
"migrate": "pnpm compile-config && pnpm typeorm migration:run -d ormconfig.js",
|
||||||
"revert": "pnpm convert:config && pnpm typeorm migration:revert -d ormconfig.js",
|
"revert": "pnpm compile-config && pnpm typeorm migration:revert -d ormconfig.js",
|
||||||
"cli": "pnpm convert:config && node ./built/boot/cli.js",
|
"cli": "pnpm compile-config && node ./built/boot/cli.js",
|
||||||
"check:connect": "pnpm convert:config && node ./scripts/check_connect.js",
|
"check:connect": "pnpm compile-config && node ./scripts/check_connect.js",
|
||||||
"convert:config": "node ./scripts/convert_config.js",
|
"compile-config": "node ./scripts/compile_config.js",
|
||||||
"build": "swc src -d built -D --strip-leading-paths",
|
"build": "swc src -d built -D --strip-leading-paths",
|
||||||
"build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths",
|
"build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths",
|
||||||
"watch:swc": "swc src -d built -D -w --strip-leading-paths",
|
"watch:swc": "swc src -d built -D -w --strip-leading-paths",
|
||||||
"build:tsc": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
"build:tsc": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
||||||
"watch": "pnpm convert:config && node ./scripts/watch.mjs",
|
"watch": "pnpm compile-config && node ./scripts/watch.mjs",
|
||||||
"restart": "pnpm build && pnpm start",
|
"restart": "pnpm build && pnpm start",
|
||||||
"dev": "pnpm convert:config && node ./scripts/dev.mjs",
|
"dev": "pnpm compile-config && node ./scripts/dev.mjs",
|
||||||
"typecheck": "tsc --noEmit && tsc -p test --noEmit && tsc -p test-federation --noEmit",
|
"typecheck": "tsc --noEmit && tsc -p test --noEmit && tsc -p test-federation --noEmit",
|
||||||
"eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"",
|
"eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"",
|
||||||
"lint": "pnpm typecheck && pnpm eslint",
|
"lint": "pnpm typecheck && pnpm eslint",
|
||||||
"jest": "pnpm convert:config && cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.unit.cjs",
|
"jest": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.unit.cjs",
|
||||||
"jest:e2e": "pnpm convert:config && cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.e2e.cjs",
|
"jest:e2e": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.e2e.cjs",
|
||||||
"jest:fed": "pnpm convert:config && node ./jest.js --forceExit --config jest.config.fed.cjs",
|
"jest:fed": "pnpm compile-config && node ./jest.js --forceExit --config jest.config.fed.cjs",
|
||||||
"jest-and-coverage": "pnpm convert:config && cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.unit.cjs",
|
"jest-and-coverage": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.unit.cjs",
|
||||||
"jest-and-coverage:e2e": "pnpm convert:config && cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.e2e.cjs",
|
"jest-and-coverage:e2e": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.e2e.cjs",
|
||||||
"jest-clear": "pnpm convert:config && cross-env NODE_ENV=test node ./jest.js --clearCache",
|
"jest-clear": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./jest.js --clearCache",
|
||||||
"test": "pnpm jest",
|
"test": "pnpm jest",
|
||||||
"test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e",
|
"test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e",
|
||||||
"test:fed": "pnpm jest:fed",
|
"test:fed": "pnpm jest:fed",
|
||||||
"test-and-coverage": "pnpm jest-and-coverage",
|
"test-and-coverage": "pnpm jest-and-coverage",
|
||||||
"test-and-coverage:e2e": "pnpm build && pnpm build:test && pnpm jest-and-coverage:e2e",
|
"test-and-coverage:e2e": "pnpm build && pnpm build:test && pnpm jest-and-coverage:e2e",
|
||||||
"check-migrations": "node scripts/check_migrations_clean.js",
|
"check-migrations": "node scripts/check_migrations_clean.js",
|
||||||
"generate-api-json": "pnpm convert:config && node ./scripts/generate_api_json.js"
|
"generate-api-json": "pnpm compile-config && node ./scripts/generate_api_json.js"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@swc/core-android-arm64": "1.3.11",
|
"@swc/core-android-arm64": "1.3.11",
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
"utf-8-validate": "6.0.5"
|
"utf-8-validate": "6.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "3.937.0",
|
"@aws-sdk/client-s3": "3.940.0",
|
||||||
"@aws-sdk/lib-storage": "3.937.0",
|
"@aws-sdk/lib-storage": "3.940.0",
|
||||||
"@discordapp/twemoji": "16.0.1",
|
"@discordapp/twemoji": "16.0.1",
|
||||||
"@fastify/accepts": "5.0.3",
|
"@fastify/accepts": "5.0.3",
|
||||||
"@fastify/cookie": "11.0.2",
|
"@fastify/cookie": "11.0.2",
|
||||||
|
|
@ -84,13 +84,13 @@
|
||||||
"@kitajs/html": "4.2.11",
|
"@kitajs/html": "4.2.11",
|
||||||
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
"@misskey-dev/sharp-read-bmp": "1.2.0",
|
||||||
"@misskey-dev/summaly": "5.2.5",
|
"@misskey-dev/summaly": "5.2.5",
|
||||||
"@napi-rs/canvas": "0.1.82",
|
"@napi-rs/canvas": "0.1.83",
|
||||||
"@nestjs/common": "11.1.9",
|
"@nestjs/common": "11.1.9",
|
||||||
"@nestjs/core": "11.1.9",
|
"@nestjs/core": "11.1.9",
|
||||||
"@nestjs/testing": "11.1.9",
|
"@nestjs/testing": "11.1.9",
|
||||||
"@peertube/http-signature": "1.7.0",
|
"@peertube/http-signature": "1.7.0",
|
||||||
"@sentry/node": "10.26.0",
|
"@sentry/node": "10.27.0",
|
||||||
"@sentry/profiling-node": "10.26.0",
|
"@sentry/profiling-node": "10.27.0",
|
||||||
"@simplewebauthn/server": "13.2.2",
|
"@simplewebauthn/server": "13.2.2",
|
||||||
"@sinonjs/fake-timers": "15.0.0",
|
"@sinonjs/fake-timers": "15.0.0",
|
||||||
"@smithy/node-http-handler": "4.4.5",
|
"@smithy/node-http-handler": "4.4.5",
|
||||||
|
|
@ -104,8 +104,8 @@
|
||||||
"async-mutex": "0.5.0",
|
"async-mutex": "0.5.0",
|
||||||
"bcryptjs": "3.0.3",
|
"bcryptjs": "3.0.3",
|
||||||
"blurhash": "2.0.5",
|
"blurhash": "2.0.5",
|
||||||
"body-parser": "2.2.0",
|
"body-parser": "2.2.1",
|
||||||
"bullmq": "5.64.1",
|
"bullmq": "5.65.0",
|
||||||
"cacheable-lookup": "7.0.0",
|
"cacheable-lookup": "7.0.0",
|
||||||
"cbor": "10.0.11",
|
"cbor": "10.0.11",
|
||||||
"chalk": "5.6.2",
|
"chalk": "5.6.2",
|
||||||
|
|
@ -121,13 +121,13 @@
|
||||||
"file-type": "21.1.1",
|
"file-type": "21.1.1",
|
||||||
"fluent-ffmpeg": "2.1.3",
|
"fluent-ffmpeg": "2.1.3",
|
||||||
"form-data": "4.0.5",
|
"form-data": "4.0.5",
|
||||||
"got": "14.6.4",
|
"got": "14.6.5",
|
||||||
"hpagent": "1.2.0",
|
"hpagent": "1.2.0",
|
||||||
"http-link-header": "1.1.3",
|
"http-link-header": "1.1.3",
|
||||||
"i18n": "workspace:*",
|
"i18n": "workspace:*",
|
||||||
"ioredis": "5.8.2",
|
"ioredis": "5.8.2",
|
||||||
"ip-cidr": "4.0.2",
|
"ip-cidr": "4.0.2",
|
||||||
"ipaddr.js": "2.2.0",
|
"ipaddr.js": "2.3.0",
|
||||||
"is-svg": "6.1.0",
|
"is-svg": "6.1.0",
|
||||||
"json5": "2.2.3",
|
"json5": "2.2.3",
|
||||||
"jsonld": "9.0.0",
|
"jsonld": "9.0.0",
|
||||||
|
|
@ -143,7 +143,7 @@
|
||||||
"nested-property": "4.0.0",
|
"nested-property": "4.0.0",
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
"node-html-parser": "7.0.1",
|
"node-html-parser": "7.0.1",
|
||||||
"nodemailer": "7.0.10",
|
"nodemailer": "7.0.11",
|
||||||
"nsfwjs": "4.2.0",
|
"nsfwjs": "4.2.0",
|
||||||
"oauth": "0.10.2",
|
"oauth": "0.10.2",
|
||||||
"oauth2orize": "1.12.0",
|
"oauth2orize": "1.12.0",
|
||||||
|
|
@ -151,7 +151,7 @@
|
||||||
"os-utils": "0.0.14",
|
"os-utils": "0.0.14",
|
||||||
"otpauth": "9.4.1",
|
"otpauth": "9.4.1",
|
||||||
"pg": "8.16.3",
|
"pg": "8.16.3",
|
||||||
"pkce-challenge": "5.0.0",
|
"pkce-challenge": "5.0.1",
|
||||||
"probe-image-size": "7.2.3",
|
"probe-image-size": "7.2.3",
|
||||||
"promise-limit": "2.7.0",
|
"promise-limit": "2.7.0",
|
||||||
"qrcode": "1.5.4",
|
"qrcode": "1.5.4",
|
||||||
|
|
@ -187,7 +187,7 @@
|
||||||
"@jest/globals": "29.7.0",
|
"@jest/globals": "29.7.0",
|
||||||
"@kitajs/ts-html-plugin": "4.1.3",
|
"@kitajs/ts-html-plugin": "4.1.3",
|
||||||
"@nestjs/platform-express": "11.1.9",
|
"@nestjs/platform-express": "11.1.9",
|
||||||
"@sentry/vue": "10.26.0",
|
"@sentry/vue": "10.27.0",
|
||||||
"@simplewebauthn/types": "12.0.0",
|
"@simplewebauthn/types": "12.0.0",
|
||||||
"@swc/jest": "0.2.39",
|
"@swc/jest": "0.2.39",
|
||||||
"@types/accepts": "1.3.7",
|
"@types/accepts": "1.3.7",
|
||||||
|
|
@ -222,8 +222,8 @@
|
||||||
"@types/vary": "1.1.3",
|
"@types/vary": "1.1.3",
|
||||||
"@types/web-push": "3.6.4",
|
"@types/web-push": "3.6.4",
|
||||||
"@types/ws": "8.18.1",
|
"@types/ws": "8.18.1",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"aws-sdk-client-mock": "4.1.0",
|
"aws-sdk-client-mock": "4.1.0",
|
||||||
"cross-env": "10.1.0",
|
"cross-env": "10.1.0",
|
||||||
"eslint-plugin-import": "2.32.0",
|
"eslint-plugin-import": "2.32.0",
|
||||||
|
|
|
||||||
|
|
@ -17,43 +17,38 @@ const _filename = fileURLToPath(import.meta.url);
|
||||||
const _dirname = dirname(_filename);
|
const _dirname = dirname(_filename);
|
||||||
|
|
||||||
const configDir = resolve(_dirname, '../../../.config');
|
const configDir = resolve(_dirname, '../../../.config');
|
||||||
|
const OUTPUT_PATH = resolve(_dirname, '../../../built/.config.json');
|
||||||
|
|
||||||
|
// TODO: yamlのパースに失敗したときのエラーハンドリング
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YAMLファイルをJSONファイルに変換
|
* YAMLファイルをJSONファイルに変換
|
||||||
* @param {string} ymlPath - YAMLファイルのパス
|
* @param {string} ymlPath - YAMLファイルのパス
|
||||||
* @param {string} jsonPath - JSONファイルの出力パス
|
|
||||||
*/
|
*/
|
||||||
function convertYamlToJson(ymlPath, jsonPath) {
|
function yamlToJson(ymlPath) {
|
||||||
if (!fs.existsSync(ymlPath)) {
|
if (!fs.existsSync(ymlPath)) {
|
||||||
console.log(`skipped: ${ymlPath} is not found`);
|
console.warn(`YAML file not found: ${ymlPath}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`${ymlPath} → ${OUTPUT_PATH}`);
|
||||||
|
|
||||||
const yamlContent = fs.readFileSync(ymlPath, 'utf-8');
|
const yamlContent = fs.readFileSync(ymlPath, 'utf-8');
|
||||||
const jsonContent = yaml.load(yamlContent);
|
const jsonContent = yaml.load(yamlContent);
|
||||||
fs.writeFileSync(jsonPath, JSON.stringify({
|
if (!fs.existsSync(dirname(OUTPUT_PATH))) {
|
||||||
|
fs.mkdirSync(dirname(OUTPUT_PATH), { recursive: true });
|
||||||
|
}
|
||||||
|
fs.writeFileSync(OUTPUT_PATH, JSON.stringify({
|
||||||
'_NOTE_': 'This file is auto-generated from YAML file. DO NOT EDIT.',
|
'_NOTE_': 'This file is auto-generated from YAML file. DO NOT EDIT.',
|
||||||
...jsonContent,
|
...jsonContent,
|
||||||
}), 'utf-8');
|
}), 'utf-8');
|
||||||
console.log(`✓ ${ymlPath} → ${jsonPath}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// default.yml と test.yml を変換
|
|
||||||
convertYamlToJson(
|
|
||||||
resolve(configDir, 'default.yml'),
|
|
||||||
resolve(configDir, 'default.json'),
|
|
||||||
);
|
|
||||||
|
|
||||||
convertYamlToJson(
|
|
||||||
resolve(configDir, 'test.yml'),
|
|
||||||
resolve(configDir, 'test.json'),
|
|
||||||
);
|
|
||||||
|
|
||||||
// MISSKEY_CONFIG_YML 環境変数が指定されている場合も変換
|
|
||||||
if (process.env.MISSKEY_CONFIG_YML) {
|
if (process.env.MISSKEY_CONFIG_YML) {
|
||||||
const customYmlPath = resolve(configDir, process.env.MISSKEY_CONFIG_YML);
|
const customYmlPath = resolve(configDir, process.env.MISSKEY_CONFIG_YML);
|
||||||
const customJsonPath = customYmlPath.replace(/\.ya?ml$/i, '.json');
|
yamlToJson(customYmlPath);
|
||||||
convertYamlToJson(customYmlPath, customJsonPath);
|
} else {
|
||||||
|
yamlToJson(resolve(configDir, process.env.NODE_ENV === 'test' ? 'test.yml' : 'default.yml'));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Configuration compiled');
|
console.log('Configuration compiled ✓');
|
||||||
|
|
@ -217,21 +217,15 @@ export type FulltextSearchProvider = 'sqlLike' | 'sqlPgroonga' | 'meilisearch';
|
||||||
const _filename = fileURLToPath(import.meta.url);
|
const _filename = fileURLToPath(import.meta.url);
|
||||||
const _dirname = dirname(_filename);
|
const _dirname = dirname(_filename);
|
||||||
|
|
||||||
/**
|
const compiledConfigFilePathForTest = resolve(_dirname, '../../../built/._config_.json');
|
||||||
* Path of configuration directory
|
|
||||||
*/
|
|
||||||
const dir = `${_dirname}/../../../.config`;
|
|
||||||
|
|
||||||
/**
|
export const compiledConfigFilePath = fs.existsSync(compiledConfigFilePathForTest) ? compiledConfigFilePathForTest : resolve(_dirname, '../../../built/.config.json');
|
||||||
* Path of configuration file
|
|
||||||
*/
|
|
||||||
export const path = process.env.MISSKEY_CONFIG_YML
|
|
||||||
? resolve(dir, process.env.MISSKEY_CONFIG_YML).replace(/\.ya?ml$/i, '.json')
|
|
||||||
: process.env.NODE_ENV === 'test'
|
|
||||||
? resolve(dir, 'test.json')
|
|
||||||
: resolve(dir, 'default.json');
|
|
||||||
|
|
||||||
export function loadConfig(): Config {
|
export function loadConfig(): Config {
|
||||||
|
if (!fs.existsSync(compiledConfigFilePath)) {
|
||||||
|
throw new Error('Compiled configuration file not found. Try running \'pnpm compile-config\'.');
|
||||||
|
}
|
||||||
|
|
||||||
const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../built/meta.json`, 'utf-8'));
|
const meta = JSON.parse(fs.readFileSync(`${_dirname}/../../../built/meta.json`, 'utf-8'));
|
||||||
|
|
||||||
const frontendManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_vite_/manifest.json');
|
const frontendManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_vite_/manifest.json');
|
||||||
|
|
@ -243,7 +237,7 @@ export function loadConfig(): Config {
|
||||||
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
|
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
|
||||||
: { 'src/boot.ts': { file: null } };
|
: { 'src/boot.ts': { file: null } };
|
||||||
|
|
||||||
const config = JSON.parse(fs.readFileSync(path, 'utf-8')) as Source;
|
const config = JSON.parse(fs.readFileSync(compiledConfigFilePath, 'utf-8')) as Source;
|
||||||
|
|
||||||
const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? '');
|
const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? '');
|
||||||
const version = meta.version;
|
const version = meta.version;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepos
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { DebounceLoader } from '@/misc/loader.js';
|
import { DebounceLoader } from '@/misc/loader.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
|
import { shouldHideNoteByTime } from '@/misc/should-hide-note-by-time.js';
|
||||||
import { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js';
|
import { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js';
|
||||||
import type { OnModuleInit } from '@nestjs/common';
|
import type { OnModuleInit } from '@nestjs/common';
|
||||||
import type { CustomEmojiService } from '../CustomEmojiService.js';
|
import type { CustomEmojiService } from '../CustomEmojiService.js';
|
||||||
|
|
@ -116,12 +117,7 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
private treatVisibility(packedNote: Packed<'Note'>): Packed<'Note'>['visibility'] {
|
private treatVisibility(packedNote: Packed<'Note'>): Packed<'Note'>['visibility'] {
|
||||||
if (packedNote.visibility === 'public' || packedNote.visibility === 'home') {
|
if (packedNote.visibility === 'public' || packedNote.visibility === 'home') {
|
||||||
const followersOnlyBefore = packedNote.user.makeNotesFollowersOnlyBefore;
|
const followersOnlyBefore = packedNote.user.makeNotesFollowersOnlyBefore;
|
||||||
if ((followersOnlyBefore != null)
|
if (shouldHideNoteByTime(followersOnlyBefore, packedNote.createdAt)) {
|
||||||
&& (
|
|
||||||
(followersOnlyBefore <= 0 && (Date.now() - new Date(packedNote.createdAt).getTime() > 0 - (followersOnlyBefore * 1000)))
|
|
||||||
|| (followersOnlyBefore > 0 && (new Date(packedNote.createdAt).getTime() < followersOnlyBefore * 1000))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
packedNote.visibility = 'followers';
|
packedNote.visibility = 'followers';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,12 +137,7 @@ export class NoteEntityService implements OnModuleInit {
|
||||||
|
|
||||||
if (!hide) {
|
if (!hide) {
|
||||||
const hiddenBefore = packedNote.user.makeNotesHiddenBefore;
|
const hiddenBefore = packedNote.user.makeNotesHiddenBefore;
|
||||||
if ((hiddenBefore != null)
|
if (shouldHideNoteByTime(hiddenBefore, packedNote.createdAt)) {
|
||||||
&& (
|
|
||||||
(hiddenBefore <= 0 && (Date.now() - new Date(packedNote.createdAt).getTime() > 0 - (hiddenBefore * 1000)))
|
|
||||||
|| (hiddenBefore > 0 && (new Date(packedNote.createdAt).getTime() < hiddenBefore * 1000))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
hide = true;
|
hide = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ノートが指定された時間条件に基づいて非表示対象かどうかを判定する
|
||||||
|
* @param hiddenBefore 非表示条件(負の値: 作成からの経過秒数、正の値: UNIXタイムスタンプ秒、null: 判定しない)
|
||||||
|
* @param createdAt ノートの作成日時(ISO 8601形式の文字列 または Date オブジェクト)
|
||||||
|
* @returns 非表示にすべき場合は true
|
||||||
|
*/
|
||||||
|
export function shouldHideNoteByTime(hiddenBefore: number | null | undefined, createdAt: string | Date): boolean {
|
||||||
|
if (hiddenBefore == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdAtTime = typeof createdAt === 'string' ? new Date(createdAt).getTime() : createdAt.getTime();
|
||||||
|
|
||||||
|
if (hiddenBefore <= 0) {
|
||||||
|
// 負の値: 作成からの経過時間(秒)で判定
|
||||||
|
const elapsedSeconds = (Date.now() - createdAtTime) / 1000;
|
||||||
|
const hideAfterSeconds = Math.abs(hiddenBefore);
|
||||||
|
return elapsedSeconds >= hideAfterSeconds;
|
||||||
|
} else {
|
||||||
|
// 正の値: 絶対的なタイムスタンプ(秒)で判定
|
||||||
|
const createdAtSeconds = createdAtTime / 1000;
|
||||||
|
return createdAtSeconds <= hiddenBefore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,21 +5,20 @@
|
||||||
|
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import { Writable } from 'node:stream';
|
import { Writable } from 'node:stream';
|
||||||
import { Inject, Injectable, StreamableFile } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { MoreThan } from 'typeorm';
|
|
||||||
import { format as dateFormat } from 'date-fns';
|
import { format as dateFormat } from 'date-fns';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { ClipNotesRepository, ClipsRepository, MiClip, MiClipNote, MiUser, NotesRepository, PollsRepository, UsersRepository } from '@/models/_.js';
|
import type { ClipNotesRepository, ClipsRepository, MiClip, MiClipNote, MiUser, PollsRepository, UsersRepository } from '@/models/_.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { createTemp } from '@/misc/create-temp.js';
|
import { createTemp } from '@/misc/create-temp.js';
|
||||||
import type { MiPoll } from '@/models/Poll.js';
|
import type { MiPoll } from '@/models/Poll.js';
|
||||||
import type { MiNote } from '@/models/Note.js';
|
import type { MiNote } from '@/models/Note.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
|
||||||
import { Packed } from '@/misc/json-schema.js';
|
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { NotificationService } from '@/core/NotificationService.js';
|
import { NotificationService } from '@/core/NotificationService.js';
|
||||||
|
import { QueryService } from '@/core/QueryService.js';
|
||||||
|
import { shouldHideNoteByTime } from '@/misc/should-hide-note-by-time.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
|
@ -43,6 +42,7 @@ export class ExportClipsProcessorService {
|
||||||
|
|
||||||
private driveService: DriveService,
|
private driveService: DriveService,
|
||||||
private queueLoggerService: QueueLoggerService,
|
private queueLoggerService: QueueLoggerService,
|
||||||
|
private queryService: QueryService,
|
||||||
private idService: IdService,
|
private idService: IdService,
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
) {
|
) {
|
||||||
|
|
@ -100,16 +100,16 @@ export class ExportClipsProcessorService {
|
||||||
});
|
});
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const clips = await this.clipsRepository.find({
|
const query = this.clipsRepository.createQueryBuilder('clip')
|
||||||
where: {
|
.where('clip.userId = :userId', { userId: user.id })
|
||||||
userId: user.id,
|
.orderBy('clip.id', 'ASC')
|
||||||
...(cursor ? { id: MoreThan(cursor) } : {}),
|
.take(100);
|
||||||
},
|
|
||||||
take: 100,
|
if (cursor) {
|
||||||
order: {
|
query.andWhere('clip.id > :cursor', { cursor });
|
||||||
id: 1,
|
}
|
||||||
},
|
|
||||||
});
|
const clips = await query.getMany();
|
||||||
|
|
||||||
if (clips.length === 0) {
|
if (clips.length === 0) {
|
||||||
job.updateProgress(100);
|
job.updateProgress(100);
|
||||||
|
|
@ -124,7 +124,7 @@ export class ExportClipsProcessorService {
|
||||||
const isFirst = exportedClipsCount === 0;
|
const isFirst = exportedClipsCount === 0;
|
||||||
await writer.write(isFirst ? content : ',\n' + content);
|
await writer.write(isFirst ? content : ',\n' + content);
|
||||||
|
|
||||||
await this.processClipNotes(writer, clip.id);
|
await this.processClipNotes(writer, clip.id, user.id);
|
||||||
|
|
||||||
await writer.write(']}');
|
await writer.write(']}');
|
||||||
exportedClipsCount++;
|
exportedClipsCount++;
|
||||||
|
|
@ -134,22 +134,25 @@ export class ExportClipsProcessorService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async processClipNotes(writer: WritableStreamDefaultWriter, clipId: string): Promise<void> {
|
async processClipNotes(writer: WritableStreamDefaultWriter, clipId: string, userId: string): Promise<void> {
|
||||||
let exportedClipNotesCount = 0;
|
let exportedClipNotesCount = 0;
|
||||||
let cursor: MiClipNote['id'] | null = null;
|
let cursor: MiClipNote['id'] | null = null;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const clipNotes = await this.clipNotesRepository.find({
|
const query = this.clipNotesRepository.createQueryBuilder('clipNote')
|
||||||
where: {
|
.leftJoinAndSelect('clipNote.note', 'note')
|
||||||
clipId,
|
.leftJoinAndSelect('note.user', 'user')
|
||||||
...(cursor ? { id: MoreThan(cursor) } : {}),
|
.where('clipNote.clipId = :clipId', { clipId })
|
||||||
},
|
.orderBy('clipNote.id', 'ASC')
|
||||||
take: 100,
|
.take(100);
|
||||||
order: {
|
|
||||||
id: 1,
|
if (cursor) {
|
||||||
},
|
query.andWhere('clipNote.id > :cursor', { cursor });
|
||||||
relations: ['note', 'note.user'],
|
}
|
||||||
}) as (MiClipNote & { note: MiNote & { user: MiUser } })[];
|
|
||||||
|
this.queryService.generateVisibilityQuery(query, { id: userId });
|
||||||
|
|
||||||
|
const clipNotes = await query.getMany() as (MiClipNote & { note: MiNote & { user: MiUser } })[];
|
||||||
|
|
||||||
if (clipNotes.length === 0) {
|
if (clipNotes.length === 0) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -158,6 +161,11 @@ export class ExportClipsProcessorService {
|
||||||
cursor = clipNotes.at(-1)?.id ?? null;
|
cursor = clipNotes.at(-1)?.id ?? null;
|
||||||
|
|
||||||
for (const clipNote of clipNotes) {
|
for (const clipNote of clipNotes) {
|
||||||
|
const noteCreatedAt = this.idService.parse(clipNote.note.id).date;
|
||||||
|
if (shouldHideNoteByTime(clipNote.note.user.makeNotesHiddenBefore, noteCreatedAt)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let poll: MiPoll | undefined;
|
let poll: MiPoll | undefined;
|
||||||
if (clipNote.note.hasPoll) {
|
if (clipNote.note.hasPoll) {
|
||||||
poll = await this.pollsRepository.findOneByOrFail({ noteId: clipNote.note.id });
|
poll = await this.pollsRepository.findOneByOrFail({ noteId: clipNote.note.id });
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { MoreThan } from 'typeorm';
|
|
||||||
import { format as dateFormat } from 'date-fns';
|
import { format as dateFormat } from 'date-fns';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { MiNoteFavorite, NoteFavoritesRepository, PollsRepository, MiUser, UsersRepository } from '@/models/_.js';
|
import type { MiNoteFavorite, NoteFavoritesRepository, PollsRepository, MiUser, UsersRepository } from '@/models/_.js';
|
||||||
|
|
@ -17,6 +16,8 @@ import type { MiNote } from '@/models/Note.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { NotificationService } from '@/core/NotificationService.js';
|
import { NotificationService } from '@/core/NotificationService.js';
|
||||||
|
import { QueryService } from '@/core/QueryService.js';
|
||||||
|
import { shouldHideNoteByTime } from '@/misc/should-hide-note-by-time.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
|
@ -37,6 +38,7 @@ export class ExportFavoritesProcessorService {
|
||||||
|
|
||||||
private driveService: DriveService,
|
private driveService: DriveService,
|
||||||
private queueLoggerService: QueueLoggerService,
|
private queueLoggerService: QueueLoggerService,
|
||||||
|
private queryService: QueryService,
|
||||||
private idService: IdService,
|
private idService: IdService,
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
) {
|
) {
|
||||||
|
|
@ -83,17 +85,20 @@ export class ExportFavoritesProcessorService {
|
||||||
});
|
});
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const favorites = await this.noteFavoritesRepository.find({
|
const query = this.noteFavoritesRepository.createQueryBuilder('favorite')
|
||||||
where: {
|
.leftJoinAndSelect('favorite.note', 'note')
|
||||||
userId: user.id,
|
.leftJoinAndSelect('note.user', 'user')
|
||||||
...(cursor ? { id: MoreThan(cursor) } : {}),
|
.where('favorite.userId = :userId', { userId: user.id })
|
||||||
},
|
.orderBy('favorite.id', 'ASC')
|
||||||
take: 100,
|
.take(100);
|
||||||
order: {
|
|
||||||
id: 1,
|
if (cursor) {
|
||||||
},
|
query.andWhere('favorite.id > :cursor', { cursor });
|
||||||
relations: ['note', 'note.user'],
|
}
|
||||||
}) as (MiNoteFavorite & { note: MiNote & { user: MiUser } })[];
|
|
||||||
|
this.queryService.generateVisibilityQuery(query, { id: user.id });
|
||||||
|
|
||||||
|
const favorites = await query.getMany() as (MiNoteFavorite & { note: MiNote & { user: MiUser } })[];
|
||||||
|
|
||||||
if (favorites.length === 0) {
|
if (favorites.length === 0) {
|
||||||
job.updateProgress(100);
|
job.updateProgress(100);
|
||||||
|
|
@ -103,6 +108,11 @@ export class ExportFavoritesProcessorService {
|
||||||
cursor = favorites.at(-1)?.id ?? null;
|
cursor = favorites.at(-1)?.id ?? null;
|
||||||
|
|
||||||
for (const favorite of favorites) {
|
for (const favorite of favorites) {
|
||||||
|
const noteCreatedAt = this.idService.parse(favorite.note.id).date;
|
||||||
|
if (shouldHideNoteByTime(favorite.note.user.makeNotesHiddenBefore, noteCreatedAt)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let poll: MiPoll | undefined;
|
let poll: MiPoll | undefined;
|
||||||
if (favorite.note.hasPoll) {
|
if (favorite.note.hasPoll) {
|
||||||
poll = await this.pollsRepository.findOneByOrFail({ noteId: favorite.note.id });
|
poll = await this.pollsRepository.findOneByOrFail({ noteId: favorite.note.id });
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
url: https://example.com/
|
||||||
|
port: 3000
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"url": "https://${HOST}/",
|
||||||
|
"port": 3000,
|
||||||
|
"db": {
|
||||||
|
"host": "db.${HOST}",
|
||||||
|
"port": 5432,
|
||||||
|
"db": "misskey",
|
||||||
|
"user": "postgres",
|
||||||
|
"pass": "postgres"
|
||||||
|
},
|
||||||
|
"dbReplications": false,
|
||||||
|
"trustProxy": true,
|
||||||
|
"redis": {
|
||||||
|
"host": "redis.test",
|
||||||
|
"port": 6379
|
||||||
|
},
|
||||||
|
"id": "aidx",
|
||||||
|
"proxyBypassHosts": [
|
||||||
|
"api.deepl.com",
|
||||||
|
"api-free.deepl.com",
|
||||||
|
"www.recaptcha.net",
|
||||||
|
"hcaptcha.com",
|
||||||
|
"challenges.cloudflare.com"
|
||||||
|
],
|
||||||
|
"allowedPrivateNetworks": [
|
||||||
|
"127.0.0.1/32",
|
||||||
|
"172.20.0.0/16"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
url: https://${HOST}/
|
|
||||||
port: 3000
|
|
||||||
db:
|
|
||||||
host: db.${HOST}
|
|
||||||
port: 5432
|
|
||||||
db: misskey
|
|
||||||
user: postgres
|
|
||||||
pass: postgres
|
|
||||||
dbReplications: false
|
|
||||||
redis:
|
|
||||||
host: redis.test
|
|
||||||
port: 6379
|
|
||||||
id: 'aidx'
|
|
||||||
proxyBypassHosts:
|
|
||||||
- api.deepl.com
|
|
||||||
- api-free.deepl.com
|
|
||||||
- www.recaptcha.net
|
|
||||||
- hcaptcha.com
|
|
||||||
- challenges.cloudflare.com
|
|
||||||
allowedPrivateNetworks:
|
|
||||||
- 127.0.0.1/32
|
|
||||||
- 172.20.0.0/16
|
|
||||||
|
|
@ -37,12 +37,8 @@ services:
|
||||||
- internal_network_a
|
- internal_network_a
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ./.config/a.test.default.yml
|
source: ./.config/a.test.config.json
|
||||||
target: /misskey/.config/default.yml
|
target: /misskey/built/._config_.json
|
||||||
read_only: true
|
|
||||||
- type: bind
|
|
||||||
source: ../scripts/convert_config.js
|
|
||||||
target: /misskey/packages/backend/scripts/convert_config.js
|
|
||||||
read_only: true
|
read_only: true
|
||||||
|
|
||||||
db.a.test:
|
db.a.test:
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,8 @@ services:
|
||||||
- internal_network_b
|
- internal_network_b
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ./.config/b.test.default.yml
|
source: ./.config/b.test.config.json
|
||||||
target: /misskey/.config/default.yml
|
target: /misskey/built/._config_.json
|
||||||
read_only: true
|
|
||||||
- type: bind
|
|
||||||
source: ../scripts/convert_config.js
|
|
||||||
target: /misskey/packages/backend/scripts/convert_config.js
|
|
||||||
read_only: true
|
read_only: true
|
||||||
|
|
||||||
db.b.test:
|
db.b.test:
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@ services:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ../../../built
|
source: ../../../built
|
||||||
target: /misskey/built
|
target: /misskey/built
|
||||||
|
read_only: false
|
||||||
|
- type: bind
|
||||||
|
source: ./.config/dummy.yml
|
||||||
|
target: /misskey/.config/default.yml
|
||||||
read_only: true
|
read_only: true
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ../assets
|
source: ../assets
|
||||||
|
|
@ -43,8 +47,8 @@ services:
|
||||||
target: /misskey/packages/backend/package.json
|
target: /misskey/packages/backend/package.json
|
||||||
read_only: true
|
read_only: true
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ../scripts/convert_config.js
|
source: ../scripts/compile_config.js
|
||||||
target: /misskey/packages/backend/scripts/convert_config.js
|
target: /misskey/packages/backend/scripts/compile_config.js
|
||||||
read_only: true
|
read_only: true
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ../../misskey-js/built
|
source: ../../misskey-js/built
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ services:
|
||||||
target: /misskey/packages/backend/jest.js
|
target: /misskey/packages/backend/jest.js
|
||||||
read_only: true
|
read_only: true
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ../scripts/convert_config.js
|
source: ../scripts/compile_config.js
|
||||||
target: /misskey/packages/backend/scripts/convert_config.js
|
target: /misskey/packages/backend/scripts/compile_config.js
|
||||||
read_only: true
|
read_only: true
|
||||||
- type: bind
|
- type: bind
|
||||||
source: ../../misskey-js/built
|
source: ../../misskey-js/built
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ function generate {
|
||||||
-days 500
|
-days 500
|
||||||
if [ ! -f .config/docker.env ]; then cp .config/example.docker.env .config/docker.env; fi
|
if [ ! -f .config/docker.env ]; then cp .config/example.docker.env .config/docker.env; fi
|
||||||
if [ ! -f .config/$1.conf ]; then sed "s/\${HOST}/$1/g" .config/example.conf > .config/$1.conf; fi
|
if [ ! -f .config/$1.conf ]; then sed "s/\${HOST}/$1/g" .config/example.conf > .config/$1.conf; fi
|
||||||
if [ ! -f .config/$1.default.yml ]; then sed "s/\${HOST}/$1/g" .config/example.default.yml > .config/$1.default.yml; fi
|
if [ ! -f .config/$1.default.yml ]; then sed "s/\${HOST}/$1/g" .config/example.config.json > .config/$1.config.json; fi
|
||||||
}
|
}
|
||||||
|
|
||||||
generate a.test
|
generate a.test
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,36 @@ describe('export-clips', () => {
|
||||||
assert.strictEqual(exported[1].clipNotes[0].note.text, 'baz2');
|
assert.strictEqual(exported[1].clipNotes[0].note.text, 'baz2');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Clipping other user\'s note', async () => {
|
test('Clipping other user\'s note (followers only notes are excluded when not following)', async () => {
|
||||||
|
const res = await api('clips/create', {
|
||||||
|
name: 'kawaii',
|
||||||
|
description: 'kawaii',
|
||||||
|
}, alice);
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const clip = res.body;
|
||||||
|
|
||||||
|
const note = await post(bob, {
|
||||||
|
text: 'baz',
|
||||||
|
visibility: 'followers',
|
||||||
|
});
|
||||||
|
|
||||||
|
const res2 = await api('clips/add-note', {
|
||||||
|
clipId: clip.id,
|
||||||
|
noteId: note.id,
|
||||||
|
}, alice);
|
||||||
|
assert.strictEqual(res2.status, 204);
|
||||||
|
|
||||||
|
const res3 = await api('i/export-clips', {}, alice);
|
||||||
|
assert.strictEqual(res3.status, 204);
|
||||||
|
|
||||||
|
const exported = await pollFirstDriveFile();
|
||||||
|
assert.strictEqual(exported[0].clipNotes.length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Clipping other user\'s note (followers only notes are included when following)', async () => {
|
||||||
|
// Alice follows Bob
|
||||||
|
await api('following/create', { userId: bob.id }, alice);
|
||||||
|
|
||||||
const res = await api('clips/create', {
|
const res = await api('clips/create', {
|
||||||
name: 'kawaii',
|
name: 'kawaii',
|
||||||
description: 'kawaii',
|
description: 'kawaii',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, expect, test, beforeEach, afterEach } from '@jest/globals';
|
||||||
|
import * as lolex from '@sinonjs/fake-timers';
|
||||||
|
import { shouldHideNoteByTime } from '@/misc/should-hide-note-by-time.js';
|
||||||
|
|
||||||
|
describe('misc:should-hide-note-by-time', () => {
|
||||||
|
let clock: lolex.InstalledClock;
|
||||||
|
const epoch = Date.UTC(2000, 0, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
clock = lolex.install({
|
||||||
|
// https://github.com/sinonjs/sinon/issues/2620
|
||||||
|
toFake: Object.keys(lolex.timers).filter((key) => !['nextTick', 'queueMicrotask'].includes(key)) as lolex.FakeMethod[],
|
||||||
|
now: new Date(epoch),
|
||||||
|
shouldClearNativeTimers: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
clock.uninstall();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hiddenBefore が null または undefined の場合', () => {
|
||||||
|
test('hiddenBefore が null のときは false を返す(非表示機能が有効でない)', () => {
|
||||||
|
const createdAt = new Date(epoch - 86400000); // 1 day ago
|
||||||
|
expect(shouldHideNoteByTime(null, createdAt)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('hiddenBefore が undefined のときは false を返す(非表示機能が有効でない)', () => {
|
||||||
|
const createdAt = new Date(epoch - 86400000); // 1 day ago
|
||||||
|
expect(shouldHideNoteByTime(undefined, createdAt)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('相対時間モード (hiddenBefore <= 0)', () => {
|
||||||
|
test('閾値内に作成されたノートは false を返す(作成からの経過時間がまだ短い→表示)', () => {
|
||||||
|
const hiddenBefore = -86400; // 1 day in seconds
|
||||||
|
const createdAt = new Date(epoch - 3600000); // 1 hour ago
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAt)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('閾値を超えて作成されたノートは true を返す(指定期間以上経過している→非表示)', () => {
|
||||||
|
const hiddenBefore = -86400; // 1 day in seconds
|
||||||
|
const createdAt = new Date(epoch - 172800000); // 2 days ago
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ちょうど閾値で作成されたノートは true を返す(閾値に達したら非表示)', () => {
|
||||||
|
const hiddenBefore = -86400; // 1 day in seconds
|
||||||
|
const createdAt = new Date(epoch - 86400000); // exactly 1 day ago
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('異なる相対時間値で判定できる(1時間設定と3時間設定の異なる結果)', () => {
|
||||||
|
const createdAt = new Date(epoch - 7200000); // 2 hours ago
|
||||||
|
expect(shouldHideNoteByTime(-3600, createdAt)).toBe(true); // 1時間経過→非表示
|
||||||
|
expect(shouldHideNoteByTime(-10800, createdAt)).toBe(false); // 3時間未経過→表示
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ISO 8601 形式の文字列の createdAt に対応できる(文字列でも正しく判定)', () => {
|
||||||
|
const createdAtString = new Date(epoch - 86400000).toISOString();
|
||||||
|
const hiddenBefore = -86400; // 1 day in seconds
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAtString)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('hiddenBefore が 0 の場合に対応できる(0秒以上経過で非表示→ほぼ全て非表示)', () => {
|
||||||
|
const hiddenBefore = 0;
|
||||||
|
const createdAt = new Date(epoch - 1); // 1ms ago
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('絶対時間モード (hiddenBefore > 0)', () => {
|
||||||
|
test('閾値タイムスタンプより後に作成されたノートは false を返す(指定日時より後→表示)', () => {
|
||||||
|
const thresholdSeconds = Math.floor(epoch / 1000);
|
||||||
|
const createdAt = new Date(epoch + 3600000); // 1 hour from epoch
|
||||||
|
expect(shouldHideNoteByTime(thresholdSeconds, createdAt)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('閾値タイムスタンプより前に作成されたノートは true を返す(指定日時より前→非表示)', () => {
|
||||||
|
const thresholdSeconds = Math.floor(epoch / 1000);
|
||||||
|
const createdAt = new Date(epoch - 3600000); // 1 hour ago
|
||||||
|
expect(shouldHideNoteByTime(thresholdSeconds, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ちょうど閾値タイムスタンプで作成されたノートは true を返す(指定日時に達したら非表示)', () => {
|
||||||
|
const thresholdSeconds = Math.floor(epoch / 1000);
|
||||||
|
const createdAt = new Date(epoch); // exactly epoch
|
||||||
|
expect(shouldHideNoteByTime(thresholdSeconds, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ISO 8601 形式の文字列の createdAt に対応できる(文字列でも正しく判定)', () => {
|
||||||
|
const thresholdSeconds = Math.floor(epoch / 1000);
|
||||||
|
const createdAtString = new Date(epoch - 3600000).toISOString();
|
||||||
|
expect(shouldHideNoteByTime(thresholdSeconds, createdAtString)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('異なる閾値タイムスタンプで判定できる(2021年設定と現在より1時間前設定の異なる結果)', () => {
|
||||||
|
const thresholdSeconds = Math.floor((epoch - 86400000) / 1000); // 1 day ago
|
||||||
|
const createdAtBefore = new Date(epoch - 172800000); // 2 days ago
|
||||||
|
const createdAtAfter = new Date(epoch - 3600000); // 1 hour ago
|
||||||
|
expect(shouldHideNoteByTime(thresholdSeconds, createdAtBefore)).toBe(true); // 閾値より前→非表示
|
||||||
|
expect(shouldHideNoteByTime(thresholdSeconds, createdAtAfter)).toBe(false); // 閾値より後→表示
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('エッジケース', () => {
|
||||||
|
test('相対時間モードで非常に古いノートに対応できる(非常に古い→閾値超→非表示)', () => {
|
||||||
|
const hiddenBefore = -1; // hide notes older than 1 second
|
||||||
|
const createdAt = new Date(epoch - 1000000); // very old
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('相対時間モードで非常に新しいノートに対応できる(非常に新しい→閾値未満→表示)', () => {
|
||||||
|
const hiddenBefore = -86400; // 1 day
|
||||||
|
const createdAt = new Date(epoch - 1); // 1ms ago
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAt)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('大きなタイムスタンプ値に対応できる(未来の日時を指定→現在のノートは全て非表示)', () => {
|
||||||
|
const thresholdSeconds = Math.floor(epoch / 1000) + 86400; // 1 day from epoch
|
||||||
|
const createdAt = new Date(epoch); // created epoch
|
||||||
|
expect(shouldHideNoteByTime(thresholdSeconds, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('小さな相対時間値に対応できる(1秒設定で2秒前→非表示)', () => {
|
||||||
|
const hiddenBefore = -1; // 1 second
|
||||||
|
const createdAt = new Date(epoch - 2000); // 2 seconds ago
|
||||||
|
expect(shouldHideNoteByTime(hiddenBefore, createdAt)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -12,8 +12,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/estree": "1.0.8",
|
"@types/estree": "1.0.8",
|
||||||
"@types/node": "24.10.1",
|
"@types/node": "24.10.1",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"rollup": "4.53.3",
|
"rollup": "4.53.3",
|
||||||
"typescript": "5.9.3"
|
"typescript": "5.9.3"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"@rollup/pluginutils": "5.3.0",
|
"@rollup/pluginutils": "5.3.0",
|
||||||
"@twemoji/parser": "16.0.0",
|
"@twemoji/parser": "16.0.0",
|
||||||
"@vitejs/plugin-vue": "6.0.2",
|
"@vitejs/plugin-vue": "6.0.2",
|
||||||
"@vue/compiler-sfc": "3.5.24",
|
"@vue/compiler-sfc": "3.5.25",
|
||||||
"astring": "1.9.0",
|
"astring": "1.9.0",
|
||||||
"buraha": "0.0.1",
|
"buraha": "0.0.1",
|
||||||
"estree-walker": "3.0.3",
|
"estree-walker": "3.0.3",
|
||||||
|
|
@ -29,14 +29,14 @@
|
||||||
"punycode.js": "2.3.1",
|
"punycode.js": "2.3.1",
|
||||||
"rollup": "4.53.3",
|
"rollup": "4.53.3",
|
||||||
"sass": "1.94.2",
|
"sass": "1.94.2",
|
||||||
"shiki": "3.15.0",
|
"shiki": "3.17.0",
|
||||||
"tinycolor2": "1.6.0",
|
"tinycolor2": "1.6.0",
|
||||||
"tsc-alias": "1.8.16",
|
"tsc-alias": "1.8.16",
|
||||||
"tsconfig-paths": "4.2.0",
|
"tsconfig-paths": "4.2.0",
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"uuid": "13.0.0",
|
"uuid": "13.0.0",
|
||||||
"vite": "7.2.4",
|
"vite": "7.2.4",
|
||||||
"vue": "3.5.24"
|
"vue": "3.5.25"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@misskey-dev/summaly": "5.2.5",
|
"@misskey-dev/summaly": "5.2.5",
|
||||||
|
|
@ -48,21 +48,21 @@
|
||||||
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
||||||
"@types/tinycolor2": "1.4.6",
|
"@types/tinycolor2": "1.4.6",
|
||||||
"@types/ws": "8.18.1",
|
"@types/ws": "8.18.1",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"@vitest/coverage-v8": "4.0.13",
|
"@vitest/coverage-v8": "4.0.14",
|
||||||
"@vue/runtime-core": "3.5.24",
|
"@vue/runtime-core": "3.5.25",
|
||||||
"acorn": "8.15.0",
|
"acorn": "8.15.0",
|
||||||
"cross-env": "10.1.0",
|
"cross-env": "10.1.0",
|
||||||
"eslint-plugin-import": "2.32.0",
|
"eslint-plugin-import": "2.32.0",
|
||||||
"eslint-plugin-vue": "10.6.0",
|
"eslint-plugin-vue": "10.6.2",
|
||||||
"fast-glob": "3.3.3",
|
"fast-glob": "3.3.3",
|
||||||
"happy-dom": "20.0.10",
|
"happy-dom": "20.0.11",
|
||||||
"intersection-observer": "0.12.2",
|
"intersection-observer": "0.12.2",
|
||||||
"micromatch": "4.0.8",
|
"micromatch": "4.0.8",
|
||||||
"msw": "2.12.2",
|
"msw": "2.12.3",
|
||||||
"nodemon": "3.1.11",
|
"nodemon": "3.1.11",
|
||||||
"prettier": "3.6.2",
|
"prettier": "3.7.1",
|
||||||
"start-server-and-test": "2.1.3",
|
"start-server-and-test": "2.1.3",
|
||||||
"tsx": "4.20.6",
|
"tsx": "4.20.6",
|
||||||
"vite-plugin-turbosnap": "1.0.3",
|
"vite-plugin-turbosnap": "1.0.3",
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "24.10.1",
|
"@types/node": "24.10.1",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"esbuild": "0.27.0",
|
"esbuild": "0.27.0",
|
||||||
"eslint-plugin-vue": "10.6.0",
|
"eslint-plugin-vue": "10.6.2",
|
||||||
"nodemon": "3.1.11",
|
"nodemon": "3.1.11",
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"vue-eslint-parser": "10.2.0"
|
"vue-eslint-parser": "10.2.0"
|
||||||
|
|
@ -36,6 +36,6 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"i18n": "workspace:*",
|
"i18n": "workspace:*",
|
||||||
"misskey-js": "workspace:*",
|
"misskey-js": "workspace:*",
|
||||||
"vue": "3.5.24"
|
"vue": "3.5.25"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@
|
||||||
"@rollup/plugin-json": "6.1.0",
|
"@rollup/plugin-json": "6.1.0",
|
||||||
"@rollup/plugin-replace": "6.0.3",
|
"@rollup/plugin-replace": "6.0.3",
|
||||||
"@rollup/pluginutils": "5.3.0",
|
"@rollup/pluginutils": "5.3.0",
|
||||||
"@sentry/vue": "10.26.0",
|
"@sentry/vue": "10.27.0",
|
||||||
"@syuilo/aiscript": "1.2.0",
|
"@syuilo/aiscript": "1.2.0",
|
||||||
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
|
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
|
||||||
"@twemoji/parser": "16.0.0",
|
"@twemoji/parser": "16.0.0",
|
||||||
"@vitejs/plugin-vue": "6.0.2",
|
"@vitejs/plugin-vue": "6.0.2",
|
||||||
"@vue/compiler-sfc": "3.5.24",
|
"@vue/compiler-sfc": "3.5.25",
|
||||||
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15",
|
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.15",
|
||||||
"analytics": "0.8.19",
|
"analytics": "0.8.19",
|
||||||
"astring": "1.9.0",
|
"astring": "1.9.0",
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
"json5": "2.2.3",
|
"json5": "2.2.3",
|
||||||
"magic-string": "0.30.21",
|
"magic-string": "0.30.21",
|
||||||
"matter-js": "0.20.0",
|
"matter-js": "0.20.0",
|
||||||
"mediabunny": "1.25.1",
|
"mediabunny": "1.25.3",
|
||||||
"mfm-js": "0.25.0",
|
"mfm-js": "0.25.0",
|
||||||
"misskey-bubble-game": "workspace:*",
|
"misskey-bubble-game": "workspace:*",
|
||||||
"misskey-js": "workspace:*",
|
"misskey-js": "workspace:*",
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
"rollup": "4.53.3",
|
"rollup": "4.53.3",
|
||||||
"sanitize-html": "2.17.0",
|
"sanitize-html": "2.17.0",
|
||||||
"sass": "1.94.2",
|
"sass": "1.94.2",
|
||||||
"shiki": "3.15.0",
|
"shiki": "3.17.0",
|
||||||
"strict-event-emitter-types": "2.0.0",
|
"strict-event-emitter-types": "2.0.0",
|
||||||
"textarea-caret": "3.1.0",
|
"textarea-caret": "3.1.0",
|
||||||
"three": "0.181.2",
|
"three": "0.181.2",
|
||||||
|
|
@ -82,7 +82,7 @@
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"v-code-diff": "1.13.1",
|
"v-code-diff": "1.13.1",
|
||||||
"vite": "7.2.4",
|
"vite": "7.2.4",
|
||||||
"vue": "3.5.24",
|
"vue": "3.5.25",
|
||||||
"vuedraggable": "next",
|
"vuedraggable": "next",
|
||||||
"wanakana": "5.3.1"
|
"wanakana": "5.3.1"
|
||||||
},
|
},
|
||||||
|
|
@ -90,7 +90,7 @@
|
||||||
"@misskey-dev/summaly": "5.2.5",
|
"@misskey-dev/summaly": "5.2.5",
|
||||||
"@storybook/addon-essentials": "8.6.14",
|
"@storybook/addon-essentials": "8.6.14",
|
||||||
"@storybook/addon-interactions": "8.6.14",
|
"@storybook/addon-interactions": "8.6.14",
|
||||||
"@storybook/addon-links": "10.0.8",
|
"@storybook/addon-links": "10.1.0",
|
||||||
"@storybook/addon-mdx-gfm": "8.6.14",
|
"@storybook/addon-mdx-gfm": "8.6.14",
|
||||||
"@storybook/addon-storysource": "8.6.14",
|
"@storybook/addon-storysource": "8.6.14",
|
||||||
"@storybook/blocks": "8.6.14",
|
"@storybook/blocks": "8.6.14",
|
||||||
|
|
@ -98,13 +98,13 @@
|
||||||
"@storybook/core-events": "8.6.14",
|
"@storybook/core-events": "8.6.14",
|
||||||
"@storybook/manager-api": "8.6.14",
|
"@storybook/manager-api": "8.6.14",
|
||||||
"@storybook/preview-api": "8.6.14",
|
"@storybook/preview-api": "8.6.14",
|
||||||
"@storybook/react": "10.0.8",
|
"@storybook/react": "10.1.0",
|
||||||
"@storybook/react-vite": "10.0.8",
|
"@storybook/react-vite": "10.1.0",
|
||||||
"@storybook/test": "8.6.14",
|
"@storybook/test": "8.6.14",
|
||||||
"@storybook/theming": "8.6.14",
|
"@storybook/theming": "8.6.14",
|
||||||
"@storybook/types": "8.6.14",
|
"@storybook/types": "8.6.14",
|
||||||
"@storybook/vue3": "10.0.8",
|
"@storybook/vue3": "10.1.0",
|
||||||
"@storybook/vue3-vite": "10.0.8",
|
"@storybook/vue3-vite": "10.1.0",
|
||||||
"@tabler/icons-webfont": "3.35.0",
|
"@tabler/icons-webfont": "3.35.0",
|
||||||
"@testing-library/vue": "8.1.0",
|
"@testing-library/vue": "8.1.0",
|
||||||
"@types/canvas-confetti": "1.9.0",
|
"@types/canvas-confetti": "1.9.0",
|
||||||
|
|
@ -118,35 +118,35 @@
|
||||||
"@types/throttle-debounce": "5.0.2",
|
"@types/throttle-debounce": "5.0.2",
|
||||||
"@types/tinycolor2": "1.4.6",
|
"@types/tinycolor2": "1.4.6",
|
||||||
"@types/ws": "8.18.1",
|
"@types/ws": "8.18.1",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"@vitest/coverage-v8": "4.0.13",
|
"@vitest/coverage-v8": "4.0.14",
|
||||||
"@vue/compiler-core": "3.5.24",
|
"@vue/compiler-core": "3.5.25",
|
||||||
"@vue/runtime-core": "3.5.24",
|
"@vue/runtime-core": "3.5.25",
|
||||||
"acorn": "8.15.0",
|
"acorn": "8.15.0",
|
||||||
"cross-env": "10.1.0",
|
"cross-env": "10.1.0",
|
||||||
"cypress": "15.7.0",
|
"cypress": "15.7.0",
|
||||||
"eslint-plugin-import": "2.32.0",
|
"eslint-plugin-import": "2.32.0",
|
||||||
"eslint-plugin-vue": "10.6.0",
|
"eslint-plugin-vue": "10.6.2",
|
||||||
"fast-glob": "3.3.3",
|
"fast-glob": "3.3.3",
|
||||||
"happy-dom": "20.0.10",
|
"happy-dom": "20.0.11",
|
||||||
"intersection-observer": "0.12.2",
|
"intersection-observer": "0.12.2",
|
||||||
"micromatch": "4.0.8",
|
"micromatch": "4.0.8",
|
||||||
"minimatch": "10.1.1",
|
"minimatch": "10.1.1",
|
||||||
"msw": "2.12.2",
|
"msw": "2.12.3",
|
||||||
"msw-storybook-addon": "2.0.6",
|
"msw-storybook-addon": "2.0.6",
|
||||||
"nodemon": "3.1.11",
|
"nodemon": "3.1.11",
|
||||||
"prettier": "3.6.2",
|
"prettier": "3.7.1",
|
||||||
"react": "19.2.0",
|
"react": "19.2.0",
|
||||||
"react-dom": "19.2.0",
|
"react-dom": "19.2.0",
|
||||||
"seedrandom": "3.0.5",
|
"seedrandom": "3.0.5",
|
||||||
"start-server-and-test": "2.1.3",
|
"start-server-and-test": "2.1.3",
|
||||||
"storybook": "10.0.8",
|
"storybook": "10.1.0",
|
||||||
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
||||||
"tsx": "4.20.6",
|
"tsx": "4.20.6",
|
||||||
"vite-plugin-glsl": "1.5.4",
|
"vite-plugin-glsl": "1.5.4",
|
||||||
"vite-plugin-turbosnap": "1.0.3",
|
"vite-plugin-turbosnap": "1.0.3",
|
||||||
"vitest": "4.0.13",
|
"vitest": "4.0.14",
|
||||||
"vitest-fetch-mock": "0.4.5",
|
"vitest-fetch-mock": "0.4.5",
|
||||||
"vue-component-type-helpers": "3.1.5",
|
"vue-component-type-helpers": "3.1.5",
|
||||||
"vue-eslint-parser": "10.2.0",
|
"vue-eslint-parser": "10.2.0",
|
||||||
|
|
|
||||||
|
|
@ -233,16 +233,18 @@ function showMenu(ev: MouseEvent) {
|
||||||
.hide {
|
.hide {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 6px;
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
background-color: var(--MI_THEME-fg);
|
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
|
backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
|
border-radius: 0 0 0 9px;
|
||||||
|
color: #fff;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
padding: 5px 8px;
|
padding: 5px 8px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
top: 12px;
|
top: 0;
|
||||||
right: 12px;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hiddenTextWrapper {
|
.hiddenTextWrapper {
|
||||||
|
|
@ -272,17 +274,17 @@ html[data-color-scheme=light] .visible {
|
||||||
.menu {
|
.menu {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 999px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.3);
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
|
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
backdrop-filter: var(--MI-blur, blur(15px));
|
backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
|
border-radius: 9px 0 0 0;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
bottom: 10px;
|
bottom: 0;
|
||||||
right: 10px;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.imageContainer {
|
.imageContainer {
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ function mount() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function back() {
|
function back() {
|
||||||
|
if (tabs.value.length <= 1) return; // transitionの関係でタブが1つの状態でbackが呼ばれることがある
|
||||||
const prev = tabs.value[tabs.value.length - 2];
|
const prev = tabs.value[tabs.value.length - 2];
|
||||||
tabs.value = [...tabs.value.slice(0, tabs.value.length - 1)];
|
tabs.value = [...tabs.value.slice(0, tabs.value.length - 1)];
|
||||||
router?.replaceByPath(prev.fullPath);
|
router?.replaceByPath(prev.fullPath);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "24.10.1",
|
"@types/node": "24.10.1",
|
||||||
"@types/wawoff2": "1.0.2",
|
"@types/wawoff2": "1.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0"
|
"@typescript-eslint/parser": "8.48.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tabler/icons-webfont": "3.35.0",
|
"@tabler/icons-webfont": "3.35.0",
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@
|
||||||
"@types/matter-js": "0.20.2",
|
"@types/matter-js": "0.20.2",
|
||||||
"@types/node": "24.10.1",
|
"@types/node": "24.10.1",
|
||||||
"@types/seedrandom": "3.0.8",
|
"@types/seedrandom": "3.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"esbuild": "0.27.0",
|
"esbuild": "0.27.0",
|
||||||
"execa": "9.6.0",
|
"execa": "9.6.0",
|
||||||
"glob": "11.1.0",
|
"glob": "11.1.0",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"name": "misskey-js",
|
"name": "misskey-js",
|
||||||
"version": "2025.12.0-alpha.1",
|
"version": "2025.12.0",
|
||||||
"description": "Misskey SDK for JavaScript",
|
"description": "Misskey SDK for JavaScript",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "24.10.1",
|
"@types/node": "24.10.1",
|
||||||
"@typescript-eslint/eslint-plugin": "8.47.0",
|
"@typescript-eslint/eslint-plugin": "8.48.0",
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"esbuild": "0.27.0",
|
"esbuild": "0.27.0",
|
||||||
"execa": "9.6.0",
|
"execa": "9.6.0",
|
||||||
"glob": "11.1.0",
|
"glob": "11.1.0",
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
"misskey-js": "workspace:*"
|
"misskey-js": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/parser": "8.47.0",
|
"@typescript-eslint/parser": "8.48.0",
|
||||||
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.74",
|
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.74",
|
||||||
"eslint-plugin-import": "2.32.0",
|
"eslint-plugin-import": "2.32.0",
|
||||||
"nodemon": "3.1.11",
|
"nodemon": "3.1.11",
|
||||||
|
|
|
||||||
2226
pnpm-lock.yaml
2226
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -10,7 +10,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mdast": "4.0.4",
|
"@types/mdast": "4.0.4",
|
||||||
"@types/node": "24.10.1",
|
"@types/node": "24.10.1",
|
||||||
"@vitest/coverage-v8": "4.0.13",
|
"@vitest/coverage-v8": "4.0.14",
|
||||||
"mdast-util-to-string": "4.0.0",
|
"mdast-util-to-string": "4.0.0",
|
||||||
"remark": "15.0.1",
|
"remark": "15.0.1",
|
||||||
"remark-parse": "11.0.0",
|
"remark-parse": "11.0.0",
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
"unified": "11.0.5",
|
"unified": "11.0.5",
|
||||||
"vite": "7.2.4",
|
"vite": "7.2.4",
|
||||||
"vite-node": "5.2.0",
|
"vite-node": "5.2.0",
|
||||||
"vitest": "4.0.13"
|
"vitest": "4.0.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-string-parser": {
|
"node_modules/@babel/helper-string-parser": {
|
||||||
|
|
@ -915,21 +915,21 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/coverage-v8": {
|
"node_modules/@vitest/coverage-v8": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.14.tgz",
|
||||||
"integrity": "sha512-w77N6bmtJ3CFnL/YHiYotwW/JI3oDlR3K38WEIqegRfdMSScaYxwYKB/0jSNpOTZzUjQkG8HHEz4sdWQMWpQ5g==",
|
"integrity": "sha512-EYHLqN/BY6b47qHH7gtMxAg++saoGmsjWmAq9MlXxAz4M0NcHh9iOyKhBZyU4yxZqOd8Xnqp80/5saeitz4Cng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bcoe/v8-coverage": "^1.0.2",
|
"@bcoe/v8-coverage": "^1.0.2",
|
||||||
"@vitest/utils": "4.0.13",
|
"@vitest/utils": "4.0.14",
|
||||||
"ast-v8-to-istanbul": "^0.3.8",
|
"ast-v8-to-istanbul": "^0.3.8",
|
||||||
"debug": "^4.4.3",
|
|
||||||
"istanbul-lib-coverage": "^3.2.2",
|
"istanbul-lib-coverage": "^3.2.2",
|
||||||
"istanbul-lib-report": "^3.0.1",
|
"istanbul-lib-report": "^3.0.1",
|
||||||
"istanbul-lib-source-maps": "^5.0.6",
|
"istanbul-lib-source-maps": "^5.0.6",
|
||||||
"istanbul-reports": "^3.2.0",
|
"istanbul-reports": "^3.2.0",
|
||||||
"magicast": "^0.5.1",
|
"magicast": "^0.5.1",
|
||||||
|
"obug": "^2.1.1",
|
||||||
"std-env": "^3.10.0",
|
"std-env": "^3.10.0",
|
||||||
"tinyrainbow": "^3.0.3"
|
"tinyrainbow": "^3.0.3"
|
||||||
},
|
},
|
||||||
|
|
@ -937,8 +937,8 @@
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@vitest/browser": "4.0.13",
|
"@vitest/browser": "4.0.14",
|
||||||
"vitest": "4.0.13"
|
"vitest": "4.0.14"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@vitest/browser": {
|
"@vitest/browser": {
|
||||||
|
|
@ -947,16 +947,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/expect": {
|
"node_modules/@vitest/expect": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.14.tgz",
|
||||||
"integrity": "sha512-zYtcnNIBm6yS7Gpr7nFTmq8ncowlMdOJkWLqYvhr/zweY6tFbDkDi8BPPOeHxEtK1rSI69H7Fd4+1sqvEGli6w==",
|
"integrity": "sha512-RHk63V3zvRiYOWAV0rGEBRO820ce17hz7cI2kDmEdfQsBjT2luEKB5tCOc91u1oSQoUOZkSv3ZyzkdkSLD7lKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standard-schema/spec": "^1.0.0",
|
"@standard-schema/spec": "^1.0.0",
|
||||||
"@types/chai": "^5.2.2",
|
"@types/chai": "^5.2.2",
|
||||||
"@vitest/spy": "4.0.13",
|
"@vitest/spy": "4.0.14",
|
||||||
"@vitest/utils": "4.0.13",
|
"@vitest/utils": "4.0.14",
|
||||||
"chai": "^6.2.1",
|
"chai": "^6.2.1",
|
||||||
"tinyrainbow": "^3.0.3"
|
"tinyrainbow": "^3.0.3"
|
||||||
},
|
},
|
||||||
|
|
@ -965,13 +965,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/mocker": {
|
"node_modules/@vitest/mocker": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.14.tgz",
|
||||||
"integrity": "sha512-eNCwzrI5djoauklwP1fuslHBjrbR8rqIVbvNlAnkq1OTa6XT+lX68mrtPirNM9TnR69XUPt4puBCx2Wexseylg==",
|
"integrity": "sha512-RzS5NujlCzeRPF1MK7MXLiEFpkIXeMdQ+rN3Kk3tDI9j0mtbr7Nmuq67tpkOJQpgyClbOltCXMjLZicJHsH5Cg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/spy": "4.0.13",
|
"@vitest/spy": "4.0.14",
|
||||||
"estree-walker": "^3.0.3",
|
"estree-walker": "^3.0.3",
|
||||||
"magic-string": "^0.30.21"
|
"magic-string": "^0.30.21"
|
||||||
},
|
},
|
||||||
|
|
@ -992,9 +992,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/pretty-format": {
|
"node_modules/@vitest/pretty-format": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.14.tgz",
|
||||||
"integrity": "sha512-ooqfze8URWbI2ozOeLDMh8YZxWDpGXoeY3VOgcDnsUxN0jPyPWSUvjPQWqDGCBks+opWlN1E4oP1UYl3C/2EQA==",
|
"integrity": "sha512-SOYPgujB6TITcJxgd3wmsLl+wZv+fy3av2PpiPpsWPZ6J1ySUYfScfpIt2Yv56ShJXR2MOA6q2KjKHN4EpdyRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -1005,13 +1005,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/runner": {
|
"node_modules/@vitest/runner": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.14.tgz",
|
||||||
"integrity": "sha512-9IKlAru58wcVaWy7hz6qWPb2QzJTKt+IOVKjAx5vb5rzEFPTL6H4/R9BMvjZ2ppkxKgTrFONEJFtzvnyEpiT+A==",
|
"integrity": "sha512-BsAIk3FAqxICqREbX8SetIteT8PiaUL/tgJjmhxJhCsigmzzH8xeadtp7LRnTpCVzvf0ib9BgAfKJHuhNllKLw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/utils": "4.0.13",
|
"@vitest/utils": "4.0.14",
|
||||||
"pathe": "^2.0.3"
|
"pathe": "^2.0.3"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
|
|
@ -1019,13 +1019,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/snapshot": {
|
"node_modules/@vitest/snapshot": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.14.tgz",
|
||||||
"integrity": "sha512-hb7Usvyika1huG6G6l191qu1urNPsq1iFc2hmdzQY3F5/rTgqQnwwplyf8zoYHkpt7H6rw5UfIw6i/3qf9oSxQ==",
|
"integrity": "sha512-aQVBfT1PMzDSA16Y3Fp45a0q8nKexx6N5Amw3MX55BeTeZpoC08fGqEZqVmPcqN0ueZsuUQ9rriPMhZ3Mu19Ag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "4.0.13",
|
"@vitest/pretty-format": "4.0.14",
|
||||||
"magic-string": "^0.30.21",
|
"magic-string": "^0.30.21",
|
||||||
"pathe": "^2.0.3"
|
"pathe": "^2.0.3"
|
||||||
},
|
},
|
||||||
|
|
@ -1034,9 +1034,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/spy": {
|
"node_modules/@vitest/spy": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.14.tgz",
|
||||||
"integrity": "sha512-hSu+m4se0lDV5yVIcNWqjuncrmBgwaXa2utFLIrBkQCQkt+pSwyZTPFQAZiiF/63j8jYa8uAeUZ3RSfcdWaYWw==",
|
"integrity": "sha512-JmAZT1UtZooO0tpY3GRyiC/8W7dCs05UOq9rfsUUgEZEdq+DuHLmWhPsrTt0TiW7WYeL/hXpaE07AZ2RCk44hg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
|
|
@ -1044,13 +1044,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/utils": {
|
"node_modules/@vitest/utils": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.14.tgz",
|
||||||
"integrity": "sha512-ydozWyQ4LZuu8rLp47xFUWis5VOKMdHjXCWhs1LuJsTNKww+pTHQNK4e0assIB9K80TxFyskENL6vCu3j34EYA==",
|
"integrity": "sha512-hLqXZKAWNg8pI+SQXyXxWCTOpA3MvsqcbVeNgSi8x/CSN2wi26dSzn1wrOhmCmFjEvN9p8/kLFRHa6PI8jHazw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "4.0.13",
|
"@vitest/pretty-format": "4.0.14",
|
||||||
"tinyrainbow": "^3.0.3"
|
"tinyrainbow": "^3.0.3"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
|
|
@ -2439,24 +2439,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitest": {
|
"node_modules/vitest": {
|
||||||
"version": "4.0.13",
|
"version": "4.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.14.tgz",
|
||||||
"integrity": "sha512-QSD4I0fN6uZQfftryIXuqvqgBxTvJ3ZNkF6RWECd82YGAYAfhcppBLFXzXJHQAAhVFyYEuFTrq6h0hQqjB7jIQ==",
|
"integrity": "sha512-d9B2J9Cm9dN9+6nxMnnNJKJCtcyKfnHj15N6YNJfaFHRLua/d3sRKU9RuKmO9mB0XdFtUizlxfz/VPbd3OxGhw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/expect": "4.0.13",
|
"@vitest/expect": "4.0.14",
|
||||||
"@vitest/mocker": "4.0.13",
|
"@vitest/mocker": "4.0.14",
|
||||||
"@vitest/pretty-format": "4.0.13",
|
"@vitest/pretty-format": "4.0.14",
|
||||||
"@vitest/runner": "4.0.13",
|
"@vitest/runner": "4.0.14",
|
||||||
"@vitest/snapshot": "4.0.13",
|
"@vitest/snapshot": "4.0.14",
|
||||||
"@vitest/spy": "4.0.13",
|
"@vitest/spy": "4.0.14",
|
||||||
"@vitest/utils": "4.0.13",
|
"@vitest/utils": "4.0.14",
|
||||||
"debug": "^4.4.3",
|
|
||||||
"es-module-lexer": "^1.7.0",
|
"es-module-lexer": "^1.7.0",
|
||||||
"expect-type": "^1.2.2",
|
"expect-type": "^1.2.2",
|
||||||
"magic-string": "^0.30.21",
|
"magic-string": "^0.30.21",
|
||||||
|
"obug": "^2.1.1",
|
||||||
"pathe": "^2.0.3",
|
"pathe": "^2.0.3",
|
||||||
"picomatch": "^4.0.3",
|
"picomatch": "^4.0.3",
|
||||||
"std-env": "^3.10.0",
|
"std-env": "^3.10.0",
|
||||||
|
|
@ -2479,12 +2479,11 @@
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@edge-runtime/vm": "*",
|
"@edge-runtime/vm": "*",
|
||||||
"@opentelemetry/api": "^1.9.0",
|
"@opentelemetry/api": "^1.9.0",
|
||||||
"@types/debug": "^4.1.12",
|
|
||||||
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
|
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
|
||||||
"@vitest/browser-playwright": "4.0.13",
|
"@vitest/browser-playwright": "4.0.14",
|
||||||
"@vitest/browser-preview": "4.0.13",
|
"@vitest/browser-preview": "4.0.14",
|
||||||
"@vitest/browser-webdriverio": "4.0.13",
|
"@vitest/browser-webdriverio": "4.0.14",
|
||||||
"@vitest/ui": "4.0.13",
|
"@vitest/ui": "4.0.14",
|
||||||
"happy-dom": "*",
|
"happy-dom": "*",
|
||||||
"jsdom": "*"
|
"jsdom": "*"
|
||||||
},
|
},
|
||||||
|
|
@ -2495,9 +2494,6 @@
|
||||||
"@opentelemetry/api": {
|
"@opentelemetry/api": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@types/debug": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mdast": "4.0.4",
|
"@types/mdast": "4.0.4",
|
||||||
"@types/node": "24.10.1",
|
"@types/node": "24.10.1",
|
||||||
"@vitest/coverage-v8": "4.0.13",
|
"@vitest/coverage-v8": "4.0.14",
|
||||||
"mdast-util-to-string": "4.0.0",
|
"mdast-util-to-string": "4.0.0",
|
||||||
"remark": "15.0.1",
|
"remark": "15.0.1",
|
||||||
"remark-parse": "11.0.0",
|
"remark-parse": "11.0.0",
|
||||||
|
|
@ -19,6 +19,6 @@
|
||||||
"unified": "11.0.5",
|
"unified": "11.0.5",
|
||||||
"vite": "7.2.4",
|
"vite": "7.2.4",
|
||||||
"vite-node": "5.2.0",
|
"vite-node": "5.2.0",
|
||||||
"vitest": "4.0.13"
|
"vitest": "4.0.14"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue