enhance(backend): テストの高速化 (#12939)
* enhance(backend): テストの高速化 * add ls * 自動的にマージされるようなので不要 * 起動方法を揃える * fix test
This commit is contained in:
		
							parent
							
								
									618e2ba1d2
								
							
						
					
					
						commit
						35ec41fc1e
					
				
					 45 changed files with 563 additions and 283 deletions
				
			
		
							
								
								
									
										56
									
								
								.github/workflows/test-backend.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								.github/workflows/test-backend.yml
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -8,7 +8,7 @@ on:
 | 
				
			||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  jest:
 | 
					  unit:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
| 
						 | 
					@ -51,9 +51,59 @@ jobs:
 | 
				
			||||||
    - name: Build
 | 
					    - name: Build
 | 
				
			||||||
      run: pnpm build
 | 
					      run: pnpm build
 | 
				
			||||||
    - name: Test
 | 
					    - name: Test
 | 
				
			||||||
      run: pnpm jest-and-coverage
 | 
					      run: pnpm --filter backend test-and-coverage
 | 
				
			||||||
    - name: Upload Coverage
 | 
					    - name: Upload to Codecov
 | 
				
			||||||
      uses: codecov/codecov-action@v3
 | 
					      uses: codecov/codecov-action@v3
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        token: ${{ secrets.CODECOV_TOKEN }}
 | 
					        token: ${{ secrets.CODECOV_TOKEN }}
 | 
				
			||||||
        files: ./packages/backend/coverage/coverage-final.json
 | 
					        files: ./packages/backend/coverage/coverage-final.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  e2e:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    strategy:
 | 
				
			||||||
 | 
					      matrix:
 | 
				
			||||||
 | 
					        node-version: [20.10.0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    services:
 | 
				
			||||||
 | 
					      postgres:
 | 
				
			||||||
 | 
					        image: postgres:15
 | 
				
			||||||
 | 
					        ports:
 | 
				
			||||||
 | 
					          - 54312:5432
 | 
				
			||||||
 | 
					        env:
 | 
				
			||||||
 | 
					          POSTGRES_DB: test-misskey
 | 
				
			||||||
 | 
					          POSTGRES_HOST_AUTH_METHOD: trust
 | 
				
			||||||
 | 
					      redis:
 | 
				
			||||||
 | 
					        image: redis:7
 | 
				
			||||||
 | 
					        ports:
 | 
				
			||||||
 | 
					          - 56312:6379
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - uses: actions/checkout@v4.1.1
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          submodules: true
 | 
				
			||||||
 | 
					      - name: Install pnpm
 | 
				
			||||||
 | 
					        uses: pnpm/action-setup@v2
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          version: 8
 | 
				
			||||||
 | 
					          run_install: false
 | 
				
			||||||
 | 
					      - name: Use Node.js ${{ matrix.node-version }}
 | 
				
			||||||
 | 
					        uses: actions/setup-node@v4.0.1
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          node-version: ${{ matrix.node-version }}
 | 
				
			||||||
 | 
					          cache: 'pnpm'
 | 
				
			||||||
 | 
					      - run: corepack enable
 | 
				
			||||||
 | 
					      - run: pnpm i --frozen-lockfile
 | 
				
			||||||
 | 
					      - name: Check pnpm-lock.yaml
 | 
				
			||||||
 | 
					        run: git diff --exit-code pnpm-lock.yaml
 | 
				
			||||||
 | 
					      - name: Copy Configure
 | 
				
			||||||
 | 
					        run: cp .github/misskey/test.yml .config
 | 
				
			||||||
 | 
					      - name: Build
 | 
				
			||||||
 | 
					        run: pnpm build
 | 
				
			||||||
 | 
					      - name: Test
 | 
				
			||||||
 | 
					        run: pnpm --filter backend test-and-coverage:e2e
 | 
				
			||||||
 | 
					      - name: Upload to Codecov
 | 
				
			||||||
 | 
					        uses: codecov/codecov-action@v3
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          token: ${{ secrets.CODECOV_TOKEN }}
 | 
				
			||||||
 | 
					          files: ./packages/backend/coverage/coverage-final.json
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -41,6 +41,7 @@ docker-compose.yml
 | 
				
			||||||
# misskey
 | 
					# misskey
 | 
				
			||||||
/build
 | 
					/build
 | 
				
			||||||
built
 | 
					built
 | 
				
			||||||
 | 
					built-test
 | 
				
			||||||
/data
 | 
					/data
 | 
				
			||||||
/.cache-loader
 | 
					/.cache-loader
 | 
				
			||||||
/db
 | 
					/db
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,7 +160,6 @@ module.exports = {
 | 
				
			||||||
	testMatch: [
 | 
						testMatch: [
 | 
				
			||||||
		"<rootDir>/test/unit/**/*.ts",
 | 
							"<rootDir>/test/unit/**/*.ts",
 | 
				
			||||||
		"<rootDir>/src/**/*.test.ts",
 | 
							"<rootDir>/src/**/*.test.ts",
 | 
				
			||||||
		"<rootDir>/test/e2e/**/*.ts",
 | 
					 | 
				
			||||||
	],
 | 
						],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
 | 
						// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								packages/backend/jest.config.e2e.cjs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								packages/backend/jest.config.e2e.cjs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* For a detailed explanation regarding each configuration property and type check, visit:
 | 
				
			||||||
 | 
					* https://jestjs.io/docs/en/configuration.html
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const base = require('./jest.config.cjs')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
						...base,
 | 
				
			||||||
 | 
						globalSetup: "<rootDir>/built-test/entry.js",
 | 
				
			||||||
 | 
						setupFilesAfterEnv: ["<rootDir>/test/jest.setup.ts"],
 | 
				
			||||||
 | 
						testMatch: [
 | 
				
			||||||
 | 
							"<rootDir>/test/e2e/**/*.ts",
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										14
									
								
								packages/backend/jest.config.unit.cjs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								packages/backend/jest.config.unit.cjs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* For a detailed explanation regarding each configuration property and type check, visit:
 | 
				
			||||||
 | 
					* https://jestjs.io/docs/en/configuration.html
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const base = require('./jest.config.cjs')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
						...base,
 | 
				
			||||||
 | 
						testMatch: [
 | 
				
			||||||
 | 
							"<rootDir>/test/unit/**/*.ts",
 | 
				
			||||||
 | 
							"<rootDir>/src/**/*.test.ts",
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
		"revert": "pnpm typeorm migration:revert -d ormconfig.js",
 | 
							"revert": "pnpm typeorm migration:revert -d ormconfig.js",
 | 
				
			||||||
		"check:connect": "node ./check_connect.js",
 | 
							"check:connect": "node ./check_connect.js",
 | 
				
			||||||
		"build": "swc src -d built -D",
 | 
							"build": "swc src -d built -D",
 | 
				
			||||||
 | 
							"build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc",
 | 
				
			||||||
		"watch:swc": "swc src -d built -D -w",
 | 
							"watch:swc": "swc src -d built -D -w",
 | 
				
			||||||
		"build:tsc": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
 | 
							"build:tsc": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
 | 
				
			||||||
		"watch": "node watch.mjs",
 | 
							"watch": "node watch.mjs",
 | 
				
			||||||
| 
						 | 
					@ -21,11 +22,15 @@
 | 
				
			||||||
		"typecheck": "tsc --noEmit",
 | 
							"typecheck": "tsc --noEmit",
 | 
				
			||||||
		"eslint": "eslint --quiet \"src/**/*.ts\"",
 | 
							"eslint": "eslint --quiet \"src/**/*.ts\"",
 | 
				
			||||||
		"lint": "pnpm typecheck && pnpm eslint",
 | 
							"lint": "pnpm typecheck && pnpm eslint",
 | 
				
			||||||
		"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit",
 | 
							"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.unit.cjs",
 | 
				
			||||||
		"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit",
 | 
							"jest:e2e": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.e2e.cjs",
 | 
				
			||||||
 | 
							"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --config jest.config.unit.cjs",
 | 
				
			||||||
 | 
							"jest-and-coverage:e2e": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --config jest.config.e2e.cjs",
 | 
				
			||||||
		"jest-clear": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --clearCache",
 | 
							"jest-clear": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --clearCache",
 | 
				
			||||||
		"test": "pnpm jest",
 | 
							"test": "pnpm jest",
 | 
				
			||||||
 | 
							"test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e",
 | 
				
			||||||
		"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",
 | 
				
			||||||
		"generate-api-json": "node ./generate_api_json.js"
 | 
							"generate-api-json": "node ./generate_api_json.js"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"optionalDependencies": {
 | 
						"optionalDependencies": {
 | 
				
			||||||
| 
						 | 
					@ -178,6 +183,7 @@
 | 
				
			||||||
	"devDependencies": {
 | 
						"devDependencies": {
 | 
				
			||||||
		"@jest/globals": "29.7.0",
 | 
							"@jest/globals": "29.7.0",
 | 
				
			||||||
		"@misskey-dev/eslint-plugin": "^1.0.0",
 | 
							"@misskey-dev/eslint-plugin": "^1.0.0",
 | 
				
			||||||
 | 
							"@nestjs/platform-express": "^10.3.0",
 | 
				
			||||||
		"@simplewebauthn/typescript-types": "8.3.4",
 | 
							"@simplewebauthn/typescript-types": "8.3.4",
 | 
				
			||||||
		"@swc/jest": "0.2.29",
 | 
							"@swc/jest": "0.2.29",
 | 
				
			||||||
		"@types/accepts": "1.3.7",
 | 
							"@types/accepts": "1.3.7",
 | 
				
			||||||
| 
						 | 
					@ -226,9 +232,11 @@
 | 
				
			||||||
		"eslint": "8.56.0",
 | 
							"eslint": "8.56.0",
 | 
				
			||||||
		"eslint-plugin-import": "2.29.1",
 | 
							"eslint-plugin-import": "2.29.1",
 | 
				
			||||||
		"execa": "8.0.1",
 | 
							"execa": "8.0.1",
 | 
				
			||||||
 | 
							"fkill": "^9.0.0",
 | 
				
			||||||
		"jest": "29.7.0",
 | 
							"jest": "29.7.0",
 | 
				
			||||||
		"jest-mock": "29.7.0",
 | 
							"jest-mock": "29.7.0",
 | 
				
			||||||
		"nodemon": "3.0.2",
 | 
							"nodemon": "3.0.2",
 | 
				
			||||||
 | 
							"pid-port": "^1.0.0",
 | 
				
			||||||
		"simple-oauth2": "5.0.0"
 | 
							"simple-oauth2": "5.0.0"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										32
									
								
								packages/backend/test-server/.eslintrc.cjs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/backend/test-server/.eslintrc.cjs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
						parserOptions: {
 | 
				
			||||||
 | 
							tsconfigRootDir: __dirname,
 | 
				
			||||||
 | 
							project: ['./tsconfig.json'],
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						extends: [
 | 
				
			||||||
 | 
							'../../shared/.eslintrc.js',
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						rules: {
 | 
				
			||||||
 | 
							'import/order': ['warn', {
 | 
				
			||||||
 | 
								'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
 | 
				
			||||||
 | 
								'pathGroups': [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										'pattern': '@/**',
 | 
				
			||||||
 | 
										'group': 'external',
 | 
				
			||||||
 | 
										'position': 'after'
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
							}],
 | 
				
			||||||
 | 
							'no-restricted-globals': [
 | 
				
			||||||
 | 
								'error',
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									'name': '__dirname',
 | 
				
			||||||
 | 
									'message': 'Not in ESModule. Use `import.meta.url` instead.'
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									'name': '__filename',
 | 
				
			||||||
 | 
									'message': 'Not in ESModule. Use `import.meta.url` instead.'
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										23
									
								
								packages/backend/test-server/.swcrc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/backend/test-server/.swcrc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"$schema": "https://json.schemastore.org/swcrc",
 | 
				
			||||||
 | 
						"jsc": {
 | 
				
			||||||
 | 
							"parser": {
 | 
				
			||||||
 | 
								"syntax": "typescript",
 | 
				
			||||||
 | 
								"dynamicImport": true,
 | 
				
			||||||
 | 
								"decorators": true
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"transform": {
 | 
				
			||||||
 | 
								"legacyDecorator": true,
 | 
				
			||||||
 | 
								"decoratorMetadata": true
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"experimental": {
 | 
				
			||||||
 | 
								"keepImportAssertions": true
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"baseUrl": "../built",
 | 
				
			||||||
 | 
							"paths": {
 | 
				
			||||||
 | 
								"@/*": ["*"]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"target": "es2022"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"minify": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										80
									
								
								packages/backend/test-server/entry.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								packages/backend/test-server/entry.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,80 @@
 | 
				
			||||||
 | 
					import { portToPid } from 'pid-port';
 | 
				
			||||||
 | 
					import fkill from 'fkill';
 | 
				
			||||||
 | 
					import Fastify from 'fastify';
 | 
				
			||||||
 | 
					import { NestFactory } from '@nestjs/core';
 | 
				
			||||||
 | 
					import { MainModule } from '@/MainModule.js';
 | 
				
			||||||
 | 
					import { ServerService } from '@/server/ServerService.js';
 | 
				
			||||||
 | 
					import { loadConfig } from '@/config.js';
 | 
				
			||||||
 | 
					import { NestLogger } from '@/NestLogger.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const config = loadConfig();
 | 
				
			||||||
 | 
					const originEnv = JSON.stringify(process.env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * テスト用のサーバインスタンスを起動する
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async function launch() {
 | 
				
			||||||
 | 
						await killTestServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						console.log('starting application...');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const app = await NestFactory.createApplicationContext(MainModule, {
 | 
				
			||||||
 | 
							logger: new NestLogger(),
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						const serverService = app.get(ServerService);
 | 
				
			||||||
 | 
						await serverService.launch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						await startControllerEndpoints();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ジョブキューは必要な時にテストコード側で起動する
 | 
				
			||||||
 | 
						// ジョブキューが動くとテスト結果の確認に支障が出ることがあるので意図的に動かさないでいる
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						console.log('application initialized.');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 既に重複したポートで待ち受けしているサーバがある場合はkillする
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async function killTestServer() {
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
							const pid = await portToPid(config.port);
 | 
				
			||||||
 | 
							if (pid) {
 | 
				
			||||||
 | 
								await fkill(pid, { force: true });
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} catch {
 | 
				
			||||||
 | 
							// NOP;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 別プロセスに切り離してしまったが故に出来なくなった環境変数の書き換え等を実現するためのエンドポイントを作る
 | 
				
			||||||
 | 
					 * @param port
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async function startControllerEndpoints(port = config.port + 1000) {
 | 
				
			||||||
 | 
						const fastify = Fastify();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fastify.post<{ Body: { key?: string, value?: string } }>('/env', async (req, res) => {
 | 
				
			||||||
 | 
							console.log(req.body);
 | 
				
			||||||
 | 
							const key = req.body['key'];
 | 
				
			||||||
 | 
							if (!key) {
 | 
				
			||||||
 | 
								res.code(400).send({ success: false });
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							process.env[key] = req.body['value'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							res.code(200).send({ success: true });
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fastify.post<{ Body: { key?: string, value?: string } }>('/env-reset', async (req, res) => {
 | 
				
			||||||
 | 
							process.env = JSON.parse(originEnv);
 | 
				
			||||||
 | 
							res.code(200).send({ success: true });
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						await fastify.listen({ port: port, host: 'localhost' });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default launch;
 | 
				
			||||||
							
								
								
									
										52
									
								
								packages/backend/test-server/tsconfig.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								packages/backend/test-server/tsconfig.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"compilerOptions": {
 | 
				
			||||||
 | 
							"allowJs": true,
 | 
				
			||||||
 | 
							"noEmitOnError": true,
 | 
				
			||||||
 | 
							"noImplicitAny": true,
 | 
				
			||||||
 | 
							"noImplicitReturns": true,
 | 
				
			||||||
 | 
							"noUnusedParameters": false,
 | 
				
			||||||
 | 
							"noUnusedLocals": false,
 | 
				
			||||||
 | 
							"noFallthroughCasesInSwitch": true,
 | 
				
			||||||
 | 
							"declaration": false,
 | 
				
			||||||
 | 
							"sourceMap": true,
 | 
				
			||||||
 | 
							"target": "ES2022",
 | 
				
			||||||
 | 
							"module": "nodenext",
 | 
				
			||||||
 | 
							"moduleResolution": "nodenext",
 | 
				
			||||||
 | 
							"allowSyntheticDefaultImports": true,
 | 
				
			||||||
 | 
							"removeComments": false,
 | 
				
			||||||
 | 
							"noLib": false,
 | 
				
			||||||
 | 
							"strict": true,
 | 
				
			||||||
 | 
							"strictNullChecks": true,
 | 
				
			||||||
 | 
							"strictPropertyInitialization": false,
 | 
				
			||||||
 | 
							"skipLibCheck": true,
 | 
				
			||||||
 | 
							"experimentalDecorators": true,
 | 
				
			||||||
 | 
							"emitDecoratorMetadata": true,
 | 
				
			||||||
 | 
							"resolveJsonModule": true,
 | 
				
			||||||
 | 
							"isolatedModules": true,
 | 
				
			||||||
 | 
							"rootDir": "../src",
 | 
				
			||||||
 | 
							"baseUrl": "./",
 | 
				
			||||||
 | 
							"paths": {
 | 
				
			||||||
 | 
								"@/*": ["../src/*"]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"outDir": "../built-test",
 | 
				
			||||||
 | 
							"types": [
 | 
				
			||||||
 | 
								"node"
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							"typeRoots": [
 | 
				
			||||||
 | 
								"../src/@types",
 | 
				
			||||||
 | 
								"../node_modules/@types",
 | 
				
			||||||
 | 
								"../node_modules"
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							"lib": [
 | 
				
			||||||
 | 
								"esnext"
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"compileOnSave": false,
 | 
				
			||||||
 | 
						"include": [
 | 
				
			||||||
 | 
							"./**/*.ts",
 | 
				
			||||||
 | 
							"../src/**/*.ts"
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"exclude": [
 | 
				
			||||||
 | 
							"../src/**/*.test.ts"
 | 
				
			||||||
 | 
						]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import * as crypto from 'node:crypto';
 | 
				
			||||||
import cbor from 'cbor';
 | 
					import cbor from 'cbor';
 | 
				
			||||||
import * as OTPAuth from 'otpauth';
 | 
					import * as OTPAuth from 'otpauth';
 | 
				
			||||||
import { loadConfig } from '@/config.js';
 | 
					import { loadConfig } from '@/config.js';
 | 
				
			||||||
import { api, signup, startServer } from '../utils.js';
 | 
					import { api, signup } from '../utils.js';
 | 
				
			||||||
import type {
 | 
					import type {
 | 
				
			||||||
	AuthenticationResponseJSON,
 | 
						AuthenticationResponseJSON,
 | 
				
			||||||
	AuthenticatorAssertionResponseJSON,
 | 
						AuthenticatorAssertionResponseJSON,
 | 
				
			||||||
| 
						 | 
					@ -19,11 +19,9 @@ import type {
 | 
				
			||||||
	PublicKeyCredentialRequestOptionsJSON,
 | 
						PublicKeyCredentialRequestOptionsJSON,
 | 
				
			||||||
	RegistrationResponseJSON,
 | 
						RegistrationResponseJSON,
 | 
				
			||||||
} from '@simplewebauthn/typescript-types';
 | 
					} from '@simplewebauthn/typescript-types';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('2要素認証', () => {
 | 
					describe('2要素認証', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const config = loadConfig();
 | 
						const config = loadConfig();
 | 
				
			||||||
| 
						 | 
					@ -185,14 +183,9 @@ describe('2要素認証', () => {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username, password });
 | 
							alice = await signup({ username, password });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('が設定でき、OTPでログインできる。', async () => {
 | 
						test('が設定でき、OTPでログインできる。', async () => {
 | 
				
			||||||
		const registerResponse = await api('/i/2fa/register', {
 | 
							const registerResponse = await api('/i/2fa/register', {
 | 
				
			||||||
			password,
 | 
								password,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,24 +6,20 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { inspect } from 'node:util';
 | 
					 | 
				
			||||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
 | 
					import { DEFAULT_POLICIES } from '@/core/RoleService.js';
 | 
				
			||||||
import type { Packed } from '@/misc/json-schema.js';
 | 
					import type { Packed } from '@/misc/json-schema.js';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
	signup,
 | 
					 | 
				
			||||||
	post,
 | 
					 | 
				
			||||||
	userList,
 | 
					 | 
				
			||||||
	page,
 | 
					 | 
				
			||||||
	role,
 | 
					 | 
				
			||||||
	startServer,
 | 
					 | 
				
			||||||
	api,
 | 
						api,
 | 
				
			||||||
	successfulApiCall,
 | 
					 | 
				
			||||||
	failedApiCall,
 | 
						failedApiCall,
 | 
				
			||||||
	uploadFile,
 | 
						post,
 | 
				
			||||||
 | 
						role,
 | 
				
			||||||
 | 
						signup,
 | 
				
			||||||
 | 
						successfulApiCall,
 | 
				
			||||||
	testPaginationConsistency,
 | 
						testPaginationConsistency,
 | 
				
			||||||
 | 
						uploadFile,
 | 
				
			||||||
 | 
						userList,
 | 
				
			||||||
} from '../utils.js';
 | 
					} from '../utils.js';
 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const compareBy = <T extends { id: string }>(selector: (s: T) => string = (s: T): string => s.id) => (a: T, b: T): number => {
 | 
					const compareBy = <T extends { id: string }>(selector: (s: T) => string = (s: T): string => s.id) => (a: T, b: T): number => {
 | 
				
			||||||
	return selector(a).localeCompare(selector(b));
 | 
						return selector(a).localeCompare(selector(b));
 | 
				
			||||||
| 
						 | 
					@ -54,8 +50,6 @@ describe('アンテナ', () => {
 | 
				
			||||||
		withReplies: false,
 | 
							withReplies: false,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let root: User;
 | 
						let root: User;
 | 
				
			||||||
	let alice: User;
 | 
						let alice: User;
 | 
				
			||||||
	let bob: User;
 | 
						let bob: User;
 | 
				
			||||||
| 
						 | 
					@ -79,10 +73,6 @@ describe('アンテナ', () => {
 | 
				
			||||||
	let userMutingAlice: User;
 | 
						let userMutingAlice: User;
 | 
				
			||||||
	let userMutedByAlice: User;
 | 
						let userMutedByAlice: User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
					 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		root = await signup({ username: 'root' });
 | 
							root = await signup({ username: 'root' });
 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
| 
						 | 
					@ -136,10 +126,6 @@ describe('アンテナ', () => {
 | 
				
			||||||
		await api('mute/create', { userId: userMutedByAlice.id }, alice);
 | 
							await api('mute/create', { userId: userMutedByAlice.id }, alice);
 | 
				
			||||||
	}, 1000 * 60 * 10);
 | 
						}, 1000 * 60 * 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	beforeEach(async () => {
 | 
						beforeEach(async () => {
 | 
				
			||||||
		// テスト間で影響し合わないように毎回全部消す。
 | 
							// テスト間で影響し合わないように毎回全部消す。
 | 
				
			||||||
		for (const user of [alice, bob]) {
 | 
							for (const user of [alice, bob]) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,21 +6,10 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, post, startServer } from '../utils.js';
 | 
					import { api, post, signup } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('API visibility', () => {
 | 
					describe('API visibility', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	beforeAll(async () => {
 | 
					 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	describe('Note visibility', () => {
 | 
						describe('Note visibility', () => {
 | 
				
			||||||
		//#region vars
 | 
							//#region vars
 | 
				
			||||||
		/** ヒロイン */
 | 
							/** ヒロイン */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,27 +7,30 @@ process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { IncomingMessage } from 'http';
 | 
					import { IncomingMessage } from 'http';
 | 
				
			||||||
import { signup, api, startServer, successfulApiCall, failedApiCall, uploadFile, waitFire, connectStream, relativeFetch, createAppToken } from '../utils.js';
 | 
					import {
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
						api,
 | 
				
			||||||
 | 
						connectStream,
 | 
				
			||||||
 | 
						createAppToken,
 | 
				
			||||||
 | 
						failedApiCall,
 | 
				
			||||||
 | 
						relativeFetch,
 | 
				
			||||||
 | 
						signup,
 | 
				
			||||||
 | 
						successfulApiCall,
 | 
				
			||||||
 | 
						uploadFile,
 | 
				
			||||||
 | 
						waitFire,
 | 
				
			||||||
 | 
					} from '../utils.js';
 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('API', () => {
 | 
					describe('API', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
	let carol: misskey.entities.SignupResponse;
 | 
						let carol: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
		carol = await signup({ username: 'carol' });
 | 
							carol = await signup({ username: 'carol' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	describe('General validation', () => {
 | 
						describe('General validation', () => {
 | 
				
			||||||
		test('wrong type', async () => {
 | 
							test('wrong type', async () => {
 | 
				
			||||||
			const res = await api('/test', {
 | 
								const res = await api('/test', {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,29 +6,21 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, post, startServer } from '../utils.js';
 | 
					import { api, post, signup } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Block', () => {
 | 
					describe('Block', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// alice blocks bob
 | 
						// alice blocks bob
 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
	let carol: misskey.entities.SignupResponse;
 | 
						let carol: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
		carol = await signup({ username: 'carol' });
 | 
							carol = await signup({ username: 'carol' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('Block作成', async () => {
 | 
						test('Block作成', async () => {
 | 
				
			||||||
		const res = await api('/blocking/create', {
 | 
							const res = await api('/blocking/create', {
 | 
				
			||||||
			userId: bob.id,
 | 
								userId: bob.id,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,25 +18,13 @@ import { paramDef as UnfavoriteParamDef } from '@/server/api/endpoints/clips/unf
 | 
				
			||||||
import { paramDef as AddNoteParamDef } from '@/server/api/endpoints/clips/add-note.js';
 | 
					import { paramDef as AddNoteParamDef } from '@/server/api/endpoints/clips/add-note.js';
 | 
				
			||||||
import { paramDef as RemoveNoteParamDef } from '@/server/api/endpoints/clips/remove-note.js';
 | 
					import { paramDef as RemoveNoteParamDef } from '@/server/api/endpoints/clips/remove-note.js';
 | 
				
			||||||
import { paramDef as NotesParamDef } from '@/server/api/endpoints/clips/notes.js';
 | 
					import { paramDef as NotesParamDef } from '@/server/api/endpoints/clips/notes.js';
 | 
				
			||||||
import {
 | 
					import { api, ApiRequest, failedApiCall, hiddenNote, post, signup, successfulApiCall } from '../utils.js';
 | 
				
			||||||
	signup,
 | 
					 | 
				
			||||||
	post,
 | 
					 | 
				
			||||||
	startServer,
 | 
					 | 
				
			||||||
	api,
 | 
					 | 
				
			||||||
	successfulApiCall,
 | 
					 | 
				
			||||||
	failedApiCall,
 | 
					 | 
				
			||||||
	ApiRequest,
 | 
					 | 
				
			||||||
	hiddenNote,
 | 
					 | 
				
			||||||
} from '../utils.js';
 | 
					 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('クリップ', () => {
 | 
					describe('クリップ', () => {
 | 
				
			||||||
	type User = Packed<'User'>;
 | 
						type User = Packed<'User'>;
 | 
				
			||||||
	type Note = Packed<'Note'>;
 | 
						type Note = Packed<'Note'>;
 | 
				
			||||||
	type Clip = Packed<'Clip'>;
 | 
						type Clip = Packed<'Clip'>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let alice: User;
 | 
						let alice: User;
 | 
				
			||||||
	let bob: User;
 | 
						let bob: User;
 | 
				
			||||||
	let aliceNote: Note;
 | 
						let aliceNote: Note;
 | 
				
			||||||
| 
						 | 
					@ -145,7 +133,6 @@ describe('クリップ', () => {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,10 +147,6 @@ describe('クリップ', () => {
 | 
				
			||||||
		bobSpecifiedNote = await post(bob, { text: 'specified only', visibility: 'specified' }) as any;
 | 
							bobSpecifiedNote = await post(bob, { text: 'specified only', visibility: 'specified' }) as any;
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	afterEach(async () => {
 | 
						afterEach(async () => {
 | 
				
			||||||
		// テスト間で影響し合わないように毎回全部消す。
 | 
							// テスト間で影響し合わないように毎回全部消す。
 | 
				
			||||||
		for (const user of [alice, bob]) {
 | 
							for (const user of [alice, bob]) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,30 +10,22 @@ import * as assert from 'assert';
 | 
				
			||||||
// https://github.com/node-fetch/node-fetch/pull/1664
 | 
					// https://github.com/node-fetch/node-fetch/pull/1664
 | 
				
			||||||
import { Blob } from 'node-fetch';
 | 
					import { Blob } from 'node-fetch';
 | 
				
			||||||
import { MiUser } from '@/models/_.js';
 | 
					import { MiUser } from '@/models/_.js';
 | 
				
			||||||
import { startServer, signup, post, api, uploadFile, simpleGet, initTestDb } from '../utils.js';
 | 
					import { api, initTestDb, post, signup, simpleGet, uploadFile } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Endpoints', () => {
 | 
					describe('Endpoints', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
	let carol: misskey.entities.SignupResponse;
 | 
						let carol: misskey.entities.SignupResponse;
 | 
				
			||||||
	let dave: misskey.entities.SignupResponse;
 | 
						let dave: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
		carol = await signup({ username: 'carol' });
 | 
							carol = await signup({ username: 'carol' });
 | 
				
			||||||
		dave = await signup({ username: 'dave' });
 | 
							dave = await signup({ username: 'dave' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	describe('signup', () => {
 | 
						describe('signup', () => {
 | 
				
			||||||
		test('不正なユーザー名でアカウントが作成できない', async () => {
 | 
							test('不正なユーザー名でアカウントが作成できない', async () => {
 | 
				
			||||||
			const res = await api('signup', {
 | 
								const res = await api('signup', {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,12 +6,12 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, startServer, startJobQueue, port, post } from '../utils.js';
 | 
					import { api, port, post, signup, startJobQueue } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					import type { INestApplicationContext } from '@nestjs/common';
 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('export-clips', () => {
 | 
					describe('export-clips', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
						let queue: INestApplicationContext;
 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,14 +33,13 @@ describe('export-clips', () => {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
							queue = await startJobQueue();
 | 
				
			||||||
		await startJobQueue();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
						afterAll(async () => {
 | 
				
			||||||
		await app.close();
 | 
							await queue.close();
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeEach(async () => {
 | 
						beforeEach(async () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,9 +6,8 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { startServer, channel, clip, cookie, galleryPost, signup, page, play, post, simpleGet, uploadFile } from '../utils.js';
 | 
					import { channel, clip, cookie, galleryPost, page, play, post, signup, simpleGet, uploadFile } from '../utils.js';
 | 
				
			||||||
import type { SimpleGetResponse } from '../utils.js';
 | 
					import type { SimpleGetResponse } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Request Accept
 | 
					// Request Accept
 | 
				
			||||||
| 
						 | 
					@ -23,8 +22,6 @@ const HTML = 'text/html; charset=utf-8';
 | 
				
			||||||
const JSON_UTF8 = 'application/json; charset=utf-8';
 | 
					const JSON_UTF8 = 'application/json; charset=utf-8';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Webリソース', () => {
 | 
					describe('Webリソース', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let aliceUploadedFile: any;
 | 
						let aliceUploadedFile: any;
 | 
				
			||||||
	let alicesPost: any;
 | 
						let alicesPost: any;
 | 
				
			||||||
| 
						 | 
					@ -79,7 +76,6 @@ describe('Webリソース', () => {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		aliceUploadedFile = await uploadFile(alice);
 | 
							aliceUploadedFile = await uploadFile(alice);
 | 
				
			||||||
		alicesPost = await post(alice, {
 | 
							alicesPost = await post(alice, {
 | 
				
			||||||
| 
						 | 
					@ -96,10 +92,6 @@ describe('Webリソース', () => {
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	describe.each([
 | 
						describe.each([
 | 
				
			||||||
		{ path: '/', type: HTML },
 | 
							{ path: '/', type: HTML },
 | 
				
			||||||
		{ path: '/docs/ja-JP/about', type: HTML }, // "指定されたURLに該当するページはありませんでした。"
 | 
							{ path: '/docs/ja-JP/about', type: HTML }, // "指定されたURLに該当するページはありませんでした。"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,26 +6,18 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, startServer, simpleGet } from '../utils.js';
 | 
					import { api, signup, simpleGet } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('FF visibility', () => {
 | 
					describe('FF visibility', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('followingVisibility, followersVisibility がともに public なユーザーのフォロー/フォロワーを誰でも見れる', async () => {
 | 
						test('followingVisibility, followersVisibility がともに public なユーザーのフォロー/フォロワーを誰でも見れる', async () => {
 | 
				
			||||||
		await api('/i/update', {
 | 
							await api('/i/update', {
 | 
				
			||||||
			followingVisibility: 'public',
 | 
								followingVisibility: 'public',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,19 +3,19 @@
 | 
				
			||||||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { INestApplicationContext } from '@nestjs/common';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { loadConfig } from '@/config.js';
 | 
					import { loadConfig } from '@/config.js';
 | 
				
			||||||
import { MiUser, UsersRepository } from '@/models/_.js';
 | 
					import { MiUser, UsersRepository } from '@/models/_.js';
 | 
				
			||||||
import { jobQueue } from '@/boot/common.js';
 | 
					 | 
				
			||||||
import { secureRndstr } from '@/misc/secure-rndstr.js';
 | 
					import { secureRndstr } from '@/misc/secure-rndstr.js';
 | 
				
			||||||
import { uploadFile, signup, startServer, initTestDb, api, sleep, successfulApiCall } from '../utils.js';
 | 
					import { jobQueue } from '@/boot/common.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					import { api, initTestDb, signup, sleep, successfulApiCall, uploadFile } from '../utils.js';
 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Account Move', () => {
 | 
					describe('Account Move', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
	let jq: INestApplicationContext;
 | 
						let jq: INestApplicationContext;
 | 
				
			||||||
	let url: URL;
 | 
						let url: URL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,8 +30,8 @@ describe('Account Move', () => {
 | 
				
			||||||
	let Users: UsersRepository;
 | 
						let Users: UsersRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		jq = await jobQueue();
 | 
							jq = await jobQueue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const config = loadConfig();
 | 
							const config = loadConfig();
 | 
				
			||||||
		url = new URL(config.url);
 | 
							url = new URL(config.url);
 | 
				
			||||||
		const connection = await initTestDb(false);
 | 
							const connection = await initTestDb(false);
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ describe('Account Move', () => {
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
						afterAll(async () => {
 | 
				
			||||||
		await Promise.all([app.close(), jq.close()]);
 | 
							await jq.close();
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	describe('Create Alias', () => {
 | 
						describe('Create Alias', () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,29 +6,21 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, post, react, startServer, waitFire } from '../utils.js';
 | 
					import { api, post, react, signup, waitFire } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Mute', () => {
 | 
					describe('Mute', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// alice mutes carol
 | 
						// alice mutes carol
 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
	let carol: misskey.entities.SignupResponse;
 | 
						let carol: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
		carol = await signup({ username: 'carol' });
 | 
							carol = await signup({ username: 'carol' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('ミュート作成', async () => {
 | 
						test('ミュート作成', async () => {
 | 
				
			||||||
		const res = await api('/mute/create', {
 | 
							const res = await api('/mute/create', {
 | 
				
			||||||
			userId: carol.id,
 | 
								userId: carol.id,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,20 +6,9 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { relativeFetch, startServer } from '../utils.js';
 | 
					import { relativeFetch } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('nodeinfo', () => {
 | 
					describe('nodeinfo', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	beforeAll(async () => {
 | 
					 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('nodeinfo 2.1', async () => {
 | 
						test('nodeinfo 2.1', async () => {
 | 
				
			||||||
		const res = await relativeFetch('nodeinfo/2.1');
 | 
							const res = await relativeFetch('nodeinfo/2.1');
 | 
				
			||||||
		assert.ok(res.ok);
 | 
							assert.ok(res.ok);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,29 +8,22 @@ process.env.NODE_ENV = 'test';
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { MiNote } from '@/models/Note.js';
 | 
					import { MiNote } from '@/models/Note.js';
 | 
				
			||||||
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
 | 
					import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
 | 
				
			||||||
import { signup, post, uploadUrl, startServer, initTestDb, api, uploadFile } from '../utils.js';
 | 
					import { api, initTestDb, post, signup, uploadFile, uploadUrl } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Note', () => {
 | 
					describe('Note', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
	let Notes: any;
 | 
						let Notes: any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		const connection = await initTestDb(true);
 | 
							const connection = await initTestDb(true);
 | 
				
			||||||
		Notes = connection.getRepository(MiNote);
 | 
							Notes = connection.getRepository(MiNote);
 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('投稿できる', async () => {
 | 
						test('投稿できる', async () => {
 | 
				
			||||||
		const post = {
 | 
							const post = {
 | 
				
			||||||
			text: 'test',
 | 
								text: 'test',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,13 +11,18 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { AuthorizationCode, ResourceOwnerPassword, type AuthorizationTokenConfig, ClientCredentials, ModuleOptions } from 'simple-oauth2';
 | 
					import {
 | 
				
			||||||
 | 
						AuthorizationCode,
 | 
				
			||||||
 | 
						type AuthorizationTokenConfig,
 | 
				
			||||||
 | 
						ClientCredentials,
 | 
				
			||||||
 | 
						ModuleOptions,
 | 
				
			||||||
 | 
						ResourceOwnerPassword,
 | 
				
			||||||
 | 
					} from 'simple-oauth2';
 | 
				
			||||||
import pkceChallenge from 'pkce-challenge';
 | 
					import pkceChallenge from 'pkce-challenge';
 | 
				
			||||||
import { JSDOM } from 'jsdom';
 | 
					import { JSDOM } from 'jsdom';
 | 
				
			||||||
import Fastify, { type FastifyReply, type FastifyInstance } from 'fastify';
 | 
					import Fastify, { type FastifyInstance, type FastifyReply } from 'fastify';
 | 
				
			||||||
import { api, port, signup, startServer } from '../utils.js';
 | 
					import { api, port, sendEnvUpdateRequest, signup } from '../utils.js';
 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const host = `http://127.0.0.1:${port}`;
 | 
					const host = `http://127.0.0.1:${port}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -147,7 +152,6 @@ async function assertDirectError(response: Response, status: number, error: stri
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('OAuth', () => {
 | 
					describe('OAuth', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
	let fastify: FastifyInstance;
 | 
						let fastify: FastifyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
| 
						 | 
					@ -156,7 +160,6 @@ describe('OAuth', () => {
 | 
				
			||||||
	let sender: (reply: FastifyReply) => void;
 | 
						let sender: (reply: FastifyReply) => void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,7 +171,7 @@ describe('OAuth', () => {
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeEach(async () => {
 | 
						beforeEach(async () => {
 | 
				
			||||||
		process.env.MISSKEY_TEST_CHECK_IP_RANGE = '';
 | 
							await sendEnvUpdateRequest({ key: 'MISSKEY_TEST_CHECK_IP_RANGE', value: '' });
 | 
				
			||||||
		sender = (reply): void => {
 | 
							sender = (reply): void => {
 | 
				
			||||||
			reply.send(`
 | 
								reply.send(`
 | 
				
			||||||
				<!DOCTYPE html>
 | 
									<!DOCTYPE html>
 | 
				
			||||||
| 
						 | 
					@ -180,7 +183,6 @@ describe('OAuth', () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
						afterAll(async () => {
 | 
				
			||||||
		await fastify.close();
 | 
							await fastify.close();
 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test('Full flow', async () => {
 | 
						test('Full flow', async () => {
 | 
				
			||||||
| 
						 | 
					@ -881,7 +883,7 @@ describe('OAuth', () => {
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		test('Disallow loopback', async () => {
 | 
							test('Disallow loopback', async () => {
 | 
				
			||||||
			process.env.MISSKEY_TEST_CHECK_IP_RANGE = '1';
 | 
								await sendEnvUpdateRequest({ key: 'MISSKEY_TEST_CHECK_IP_RANGE', value: '1' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const client = new AuthorizationCode(clientConfig);
 | 
								const client = new AuthorizationCode(clientConfig);
 | 
				
			||||||
			const response = await fetch(client.authorizeURL({
 | 
								const response = await fetch(client.authorizeURL({
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,29 +6,21 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, post, react, startServer, waitFire, sleep } from '../utils.js';
 | 
					import { api, post, signup, sleep, waitFire } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Renote Mute', () => {
 | 
					describe('Renote Mute', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// alice mutes carol
 | 
						// alice mutes carol
 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
	let carol: misskey.entities.SignupResponse;
 | 
						let carol: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
		carol = await signup({ username: 'carol' });
 | 
							carol = await signup({ username: 'carol' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('ミュート作成', async () => {
 | 
						test('ミュート作成', async () => {
 | 
				
			||||||
		const res = await api('/renote-mute/create', {
 | 
							const res = await api('/renote-mute/create', {
 | 
				
			||||||
			userId: carol.id,
 | 
								userId: carol.id,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,12 +8,10 @@ process.env.NODE_ENV = 'test';
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { WebSocket } from 'ws';
 | 
					import { WebSocket } from 'ws';
 | 
				
			||||||
import { MiFollowing } from '@/models/Following.js';
 | 
					import { MiFollowing } from '@/models/Following.js';
 | 
				
			||||||
import { signup, api, post, startServer, initTestDb, waitFire, createAppToken, port } from '../utils.js';
 | 
					import { api, createAppToken, initTestDb, port, post, signup, waitFire } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Streaming', () => {
 | 
					describe('Streaming', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
	let Followings: any;
 | 
						let Followings: any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const follow = async (follower: any, followee: any) => {
 | 
						const follow = async (follower: any, followee: any) => {
 | 
				
			||||||
| 
						 | 
					@ -48,7 +46,6 @@ describe('Streaming', () => {
 | 
				
			||||||
		let list: any;
 | 
							let list: any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		beforeAll(async () => {
 | 
							beforeAll(async () => {
 | 
				
			||||||
			app = await startServer();
 | 
					 | 
				
			||||||
			const connection = await initTestDb(true);
 | 
								const connection = await initTestDb(true);
 | 
				
			||||||
			Followings = connection.getRepository(MiFollowing);
 | 
								Followings = connection.getRepository(MiFollowing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,10 +92,6 @@ describe('Streaming', () => {
 | 
				
			||||||
			}, chitose);
 | 
								}, chitose);
 | 
				
			||||||
		}, 1000 * 60 * 2);
 | 
							}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		afterAll(async () => {
 | 
					 | 
				
			||||||
			await app.close();
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		describe('Events', () => {
 | 
							describe('Events', () => {
 | 
				
			||||||
			test('mention event', async () => {
 | 
								test('mention event', async () => {
 | 
				
			||||||
				const fired = await waitFire(
 | 
									const fired = await waitFire(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,28 +6,20 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, post, connectStream, startServer } from '../utils.js';
 | 
					import { api, connectStream, post, signup } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Note thread mute', () => {
 | 
					describe('Note thread mute', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let bob: misskey.entities.SignupResponse;
 | 
						let bob: misskey.entities.SignupResponse;
 | 
				
			||||||
	let carol: misskey.entities.SignupResponse;
 | 
						let carol: misskey.entities.SignupResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		bob = await signup({ username: 'bob' });
 | 
							bob = await signup({ username: 'bob' });
 | 
				
			||||||
		carol = await signup({ username: 'carol' });
 | 
							carol = await signup({ username: 'carol' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('notes/mentions にミュートしているスレッドの投稿が含まれない', async () => {
 | 
						test('notes/mentions にミュートしているスレッドの投稿が含まれない', async () => {
 | 
				
			||||||
		const bobNote = await post(bob, { text: '@alice @carol root note' });
 | 
							const bobNote = await post(bob, { text: '@alice @carol root note' });
 | 
				
			||||||
		const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' });
 | 
							const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' });
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,12 +6,8 @@
 | 
				
			||||||
// How to run:
 | 
					// How to run:
 | 
				
			||||||
// pnpm jest -- e2e/timelines.ts
 | 
					// pnpm jest -- e2e/timelines.ts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					 | 
				
			||||||
process.env.FORCE_FOLLOW_REMOTE_USER_FOR_TESTING = 'true';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { api, post, randomString, signup, sleep, startServer, uploadUrl } from '../utils.js';
 | 
					import { api, post, randomString, sendEnvUpdateRequest, signup, sleep, uploadUrl } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function genHost() {
 | 
					function genHost() {
 | 
				
			||||||
	return randomString() + '.example.com';
 | 
						return randomString() + '.example.com';
 | 
				
			||||||
| 
						 | 
					@ -21,16 +17,6 @@ function waitForPushToTl() {
 | 
				
			||||||
	return sleep(500);
 | 
						return sleep(500);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
beforeAll(async () => {
 | 
					 | 
				
			||||||
	app = await startServer();
 | 
					 | 
				
			||||||
}, 1000 * 60 * 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
afterAll(async () => {
 | 
					 | 
				
			||||||
	await app.close();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('Timelines', () => {
 | 
					describe('Timelines', () => {
 | 
				
			||||||
	describe('Home TL', () => {
 | 
						describe('Home TL', () => {
 | 
				
			||||||
		test.concurrent('自分の visibility: followers なノートが含まれる', async () => {
 | 
							test.concurrent('自分の visibility: followers なノートが含まれる', async () => {
 | 
				
			||||||
| 
						 | 
					@ -334,8 +320,9 @@ describe('Timelines', () => {
 | 
				
			||||||
		test.concurrent('フォローしているリモートユーザーのノートが含まれる', async () => {
 | 
							test.concurrent('フォローしているリモートユーザーのノートが含まれる', async () => {
 | 
				
			||||||
			const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
								const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
 | 
				
			||||||
			await api('/following/create', { userId: bob.id }, alice);
 | 
								await api('/following/create', { userId: bob.id }, alice);
 | 
				
			||||||
			await sleep(1000);
 | 
					
 | 
				
			||||||
			const bobNote = await post(bob, { text: 'hi' });
 | 
								const bobNote = await post(bob, { text: 'hi' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			await waitForPushToTl();
 | 
								await waitForPushToTl();
 | 
				
			||||||
| 
						 | 
					@ -348,8 +335,9 @@ describe('Timelines', () => {
 | 
				
			||||||
		test.concurrent('フォローしているリモートユーザーの visibility: home なノートが含まれる', async () => {
 | 
							test.concurrent('フォローしているリモートユーザーの visibility: home なノートが含まれる', async () => {
 | 
				
			||||||
			const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
								const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
 | 
				
			||||||
			await api('/following/create', { userId: bob.id }, alice);
 | 
								await api('/following/create', { userId: bob.id }, alice);
 | 
				
			||||||
			await sleep(1000);
 | 
					
 | 
				
			||||||
			const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
 | 
								const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			await waitForPushToTl();
 | 
								await waitForPushToTl();
 | 
				
			||||||
| 
						 | 
					@ -762,8 +750,9 @@ describe('Timelines', () => {
 | 
				
			||||||
		test.concurrent('フォローしているリモートユーザーのノートが含まれる', async () => {
 | 
							test.concurrent('フォローしているリモートユーザーのノートが含まれる', async () => {
 | 
				
			||||||
			const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
								const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
 | 
				
			||||||
			await api('/following/create', { userId: bob.id }, alice);
 | 
								await api('/following/create', { userId: bob.id }, alice);
 | 
				
			||||||
			await sleep(1000);
 | 
					
 | 
				
			||||||
			const bobNote = await post(bob, { text: 'hi' });
 | 
								const bobNote = await post(bob, { text: 'hi' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			await waitForPushToTl();
 | 
								await waitForPushToTl();
 | 
				
			||||||
| 
						 | 
					@ -776,8 +765,9 @@ describe('Timelines', () => {
 | 
				
			||||||
		test.concurrent('フォローしているリモートユーザーの visibility: home なノートが含まれる', async () => {
 | 
							test.concurrent('フォローしているリモートユーザーの visibility: home なノートが含まれる', async () => {
 | 
				
			||||||
			const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
								const [alice, bob] = await Promise.all([signup(), signup({ host: genHost() })]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								await sendEnvUpdateRequest({ key: 'FORCE_FOLLOW_REMOTE_USER_FOR_TESTING', value: 'true' });
 | 
				
			||||||
			await api('/following/create', { userId: bob.id }, alice);
 | 
								await api('/following/create', { userId: bob.id }, alice);
 | 
				
			||||||
			await sleep(1000);
 | 
					
 | 
				
			||||||
			const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
 | 
								const bobNote = await post(bob, { text: 'hi', visibility: 'home' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			await waitForPushToTl();
 | 
								await waitForPushToTl();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,20 +6,16 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { signup, api, post, uploadUrl, startServer } from '../utils.js';
 | 
					import { api, post, signup, uploadUrl } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('users/notes', () => {
 | 
					describe('users/notes', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let alice: misskey.entities.SignupResponse;
 | 
						let alice: misskey.entities.SignupResponse;
 | 
				
			||||||
	let jpgNote: any;
 | 
						let jpgNote: any;
 | 
				
			||||||
	let pngNote: any;
 | 
						let pngNote: any;
 | 
				
			||||||
	let jpgPngNote: any;
 | 
						let jpgPngNote: any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
		const jpg = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg');
 | 
							const jpg = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg');
 | 
				
			||||||
		const png = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.png');
 | 
							const png = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.png');
 | 
				
			||||||
| 
						 | 
					@ -34,10 +30,6 @@ describe('users/notes', () => {
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async() => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('withFiles', async () => {
 | 
						test('withFiles', async () => {
 | 
				
			||||||
		const res = await api('/users/notes', {
 | 
							const res = await api('/users/notes', {
 | 
				
			||||||
			userId: alice.id,
 | 
								userId: alice.id,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,20 +8,8 @@ process.env.NODE_ENV = 'test';
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { inspect } from 'node:util';
 | 
					import { inspect } from 'node:util';
 | 
				
			||||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
 | 
					import { DEFAULT_POLICIES } from '@/core/RoleService.js';
 | 
				
			||||||
import type { Packed } from '@/misc/json-schema.js';
 | 
					import { api, page, post, role, signup, successfulApiCall, uploadFile } from '../utils.js';
 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
	signup,
 | 
					 | 
				
			||||||
	post,
 | 
					 | 
				
			||||||
	page,
 | 
					 | 
				
			||||||
	role,
 | 
					 | 
				
			||||||
	startServer,
 | 
					 | 
				
			||||||
	api,
 | 
					 | 
				
			||||||
	successfulApiCall,
 | 
					 | 
				
			||||||
	failedApiCall,
 | 
					 | 
				
			||||||
	uploadFile,
 | 
					 | 
				
			||||||
} from '../utils.js';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('ユーザー', () => {
 | 
					describe('ユーザー', () => {
 | 
				
			||||||
	// エンティティとしてのユーザーを主眼においたテストを記述する
 | 
						// エンティティとしてのユーザーを主眼においたテストを記述する
 | 
				
			||||||
| 
						 | 
					@ -185,8 +173,6 @@ describe('ユーザー', () => {
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	let root: User;
 | 
						let root: User;
 | 
				
			||||||
	let alice: User;
 | 
						let alice: User;
 | 
				
			||||||
	let aliceNote: misskey.entities.Note;
 | 
						let aliceNote: misskey.entities.Note;
 | 
				
			||||||
| 
						 | 
					@ -230,10 +216,6 @@ describe('ユーザー', () => {
 | 
				
			||||||
	let userFollowRequesting: User;
 | 
						let userFollowRequesting: User;
 | 
				
			||||||
	let userFollowRequested: User;
 | 
						let userFollowRequested: User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
					 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		root = await signup({ username: 'root' });
 | 
							root = await signup({ username: 'root' });
 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
| 
						 | 
					@ -321,10 +303,6 @@ describe('ユーザー', () => {
 | 
				
			||||||
		await api('following/create', { userId: userFollowRequested.id }, userFollowRequesting);
 | 
							await api('following/create', { userId: userFollowRequested.id }, userFollowRequesting);
 | 
				
			||||||
	}, 1000 * 60 * 10);
 | 
						}, 1000 * 60 * 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	beforeEach(async () => {
 | 
						beforeEach(async () => {
 | 
				
			||||||
		alice = {
 | 
							alice = {
 | 
				
			||||||
			...alice,
 | 
								...alice,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,24 +6,16 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'assert';
 | 
					import * as assert from 'assert';
 | 
				
			||||||
import { host, origin, relativeFetch, signup, startServer } from '../utils.js';
 | 
					import { host, origin, relativeFetch, signup } from '../utils.js';
 | 
				
			||||||
import type { INestApplicationContext } from '@nestjs/common';
 | 
					 | 
				
			||||||
import type * as misskey from 'misskey-js';
 | 
					import type * as misskey from 'misskey-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('.well-known', () => {
 | 
					describe('.well-known', () => {
 | 
				
			||||||
	let app: INestApplicationContext;
 | 
					 | 
				
			||||||
	let alice: misskey.entities.User;
 | 
						let alice: misskey.entities.User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeAll(async () => {
 | 
						beforeAll(async () => {
 | 
				
			||||||
		app = await startServer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		alice = await signup({ username: 'alice' });
 | 
							alice = await signup({ username: 'alice' });
 | 
				
			||||||
	}, 1000 * 60 * 2);
 | 
						}, 1000 * 60 * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afterAll(async () => {
 | 
					 | 
				
			||||||
		await app.close();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	test('nodeinfo', async () => {
 | 
						test('nodeinfo', async () => {
 | 
				
			||||||
		const res = await relativeFetch('.well-known/nodeinfo');
 | 
							const res = await relativeFetch('.well-known/nodeinfo');
 | 
				
			||||||
		assert.ok(res.ok);
 | 
							assert.ok(res.ok);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								packages/backend/test/jest.setup.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/backend/test/jest.setup.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					import { initTestDb, sendEnvResetRequest } from './utils.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					beforeAll(async () => {
 | 
				
			||||||
 | 
						await Promise.all([
 | 
				
			||||||
 | 
							initTestDb(false),
 | 
				
			||||||
 | 
							sendEnvResetRequest(),
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,13 @@ import type { LoggerService } from '@/core/LoggerService.js';
 | 
				
			||||||
import type { MetaService } from '@/core/MetaService.js';
 | 
					import type { MetaService } from '@/core/MetaService.js';
 | 
				
			||||||
import type { UtilityService } from '@/core/UtilityService.js';
 | 
					import type { UtilityService } from '@/core/UtilityService.js';
 | 
				
			||||||
import { bindThis } from '@/decorators.js';
 | 
					import { bindThis } from '@/decorators.js';
 | 
				
			||||||
import type { NoteReactionsRepository, NotesRepository, PollsRepository, UsersRepository, FollowRequestsRepository } from '@/models/_.js';
 | 
					import type {
 | 
				
			||||||
 | 
						FollowRequestsRepository,
 | 
				
			||||||
 | 
						NoteReactionsRepository,
 | 
				
			||||||
 | 
						NotesRepository,
 | 
				
			||||||
 | 
						PollsRepository,
 | 
				
			||||||
 | 
						UsersRepository,
 | 
				
			||||||
 | 
					} from '@/models/_.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MockResponse = {
 | 
					type MockResponse = {
 | 
				
			||||||
	type: string;
 | 
						type: string;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,13 @@ import { ModuleMocker } from 'jest-mock';
 | 
				
			||||||
import { Test } from '@nestjs/testing';
 | 
					import { Test } from '@nestjs/testing';
 | 
				
			||||||
import { GlobalModule } from '@/GlobalModule.js';
 | 
					import { GlobalModule } from '@/GlobalModule.js';
 | 
				
			||||||
import { AnnouncementService } from '@/core/AnnouncementService.js';
 | 
					import { AnnouncementService } from '@/core/AnnouncementService.js';
 | 
				
			||||||
import type { MiAnnouncement, AnnouncementsRepository, AnnouncementReadsRepository, UsersRepository, MiUser } from '@/models/_.js';
 | 
					import type {
 | 
				
			||||||
 | 
						AnnouncementReadsRepository,
 | 
				
			||||||
 | 
						AnnouncementsRepository,
 | 
				
			||||||
 | 
						MiAnnouncement,
 | 
				
			||||||
 | 
						MiUser,
 | 
				
			||||||
 | 
						UsersRepository,
 | 
				
			||||||
 | 
					} from '@/models/_.js';
 | 
				
			||||||
import { DI } from '@/di-symbols.js';
 | 
					import { DI } from '@/di-symbols.js';
 | 
				
			||||||
import { genAidx } from '@/misc/id/aidx.js';
 | 
					import { genAidx } from '@/misc/id/aidx.js';
 | 
				
			||||||
import { CacheService } from '@/core/CacheService.js';
 | 
					import { CacheService } from '@/core/CacheService.js';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,13 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Test } from '@nestjs/testing';
 | 
					import { Test } from '@nestjs/testing';
 | 
				
			||||||
import { DeleteObjectCommandOutput, DeleteObjectCommand, NoSuchKey, InvalidObjectState, S3Client } from '@aws-sdk/client-s3';
 | 
					import {
 | 
				
			||||||
 | 
						DeleteObjectCommand,
 | 
				
			||||||
 | 
						DeleteObjectCommandOutput,
 | 
				
			||||||
 | 
						InvalidObjectState,
 | 
				
			||||||
 | 
						NoSuchKey,
 | 
				
			||||||
 | 
						S3Client,
 | 
				
			||||||
 | 
					} from '@aws-sdk/client-s3';
 | 
				
			||||||
import { mockClient } from 'aws-sdk-client-mock';
 | 
					import { mockClient } from 'aws-sdk-client-mock';
 | 
				
			||||||
import { GlobalModule } from '@/GlobalModule.js';
 | 
					import { GlobalModule } from '@/GlobalModule.js';
 | 
				
			||||||
import { DriveService } from '@/core/DriveService.js';
 | 
					import { DriveService } from '@/core/DriveService.js';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,8 @@ describe('FetchInstanceMetadataService', () => {
 | 
				
			||||||
					return { fetch: jest.fn() };
 | 
										return { fetch: jest.fn() };
 | 
				
			||||||
				} else if (token === DI.redis) {
 | 
									} else if (token === DI.redis) {
 | 
				
			||||||
					return mockRedis;
 | 
										return mockRedis;
 | 
				
			||||||
				}})
 | 
									}
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
			.compile();
 | 
								.compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		app.enableShutdownHooks();
 | 
							app.enableShutdownHooks();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import { fileURLToPath } from 'node:url';
 | 
				
			||||||
import { dirname } from 'node:path';
 | 
					import { dirname } from 'node:path';
 | 
				
			||||||
import { ModuleMocker } from 'jest-mock';
 | 
					import { ModuleMocker } from 'jest-mock';
 | 
				
			||||||
import { Test } from '@nestjs/testing';
 | 
					import { Test } from '@nestjs/testing';
 | 
				
			||||||
import { describe, beforeAll, afterAll, test } from '@jest/globals';
 | 
					import { afterAll, beforeAll, describe, test } from '@jest/globals';
 | 
				
			||||||
import { GlobalModule } from '@/GlobalModule.js';
 | 
					import { GlobalModule } from '@/GlobalModule.js';
 | 
				
			||||||
import { FileInfoService } from '@/core/FileInfoService.js';
 | 
					import { FileInfoService } from '@/core/FileInfoService.js';
 | 
				
			||||||
//import { DI } from '@/di-symbols.js';
 | 
					//import { DI } from '@/di-symbols.js';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,15 +6,13 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { jest } from '@jest/globals';
 | 
					import { jest } from '@jest/globals';
 | 
				
			||||||
import { ModuleMocker } from 'jest-mock';
 | 
					 | 
				
			||||||
import { Test } from '@nestjs/testing';
 | 
					import { Test } from '@nestjs/testing';
 | 
				
			||||||
import { GlobalModule } from '@/GlobalModule.js';
 | 
					import { GlobalModule } from '@/GlobalModule.js';
 | 
				
			||||||
import type { MetasRepository } from '@/models/_.js';
 | 
					 | 
				
			||||||
import { DI } from '@/di-symbols.js';
 | 
					import { DI } from '@/di-symbols.js';
 | 
				
			||||||
import { MetaService } from '@/core/MetaService.js';
 | 
					import { MetaService } from '@/core/MetaService.js';
 | 
				
			||||||
import { CoreModule } from '@/core/CoreModule.js';
 | 
					import { CoreModule } from '@/core/CoreModule.js';
 | 
				
			||||||
import type { DataSource } from 'typeorm';
 | 
					 | 
				
			||||||
import type { TestingModule } from '@nestjs/testing';
 | 
					import type { TestingModule } from '@nestjs/testing';
 | 
				
			||||||
 | 
					import type { DataSource } from 'typeorm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('MetaService', () => {
 | 
					describe('MetaService', () => {
 | 
				
			||||||
	let app: TestingModule;
 | 
						let app: TestingModule;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ import { Test } from '@nestjs/testing';
 | 
				
			||||||
import * as lolex from '@sinonjs/fake-timers';
 | 
					import * as lolex from '@sinonjs/fake-timers';
 | 
				
			||||||
import { GlobalModule } from '@/GlobalModule.js';
 | 
					import { GlobalModule } from '@/GlobalModule.js';
 | 
				
			||||||
import { RoleService } from '@/core/RoleService.js';
 | 
					import { RoleService } from '@/core/RoleService.js';
 | 
				
			||||||
import type { MiRole, RolesRepository, RoleAssignmentsRepository, UsersRepository, MiUser } from '@/models/_.js';
 | 
					import type { MiRole, MiUser, RoleAssignmentsRepository, RolesRepository, UsersRepository } from '@/models/_.js';
 | 
				
			||||||
import { DI } from '@/di-symbols.js';
 | 
					import { DI } from '@/di-symbols.js';
 | 
				
			||||||
import { MetaService } from '@/core/MetaService.js';
 | 
					import { MetaService } from '@/core/MetaService.js';
 | 
				
			||||||
import { genAidx } from '@/misc/id/aidx.js';
 | 
					import { genAidx } from '@/misc/id/aidx.js';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,13 @@
 | 
				
			||||||
process.env.NODE_ENV = 'test';
 | 
					process.env.NODE_ENV = 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Test } from '@nestjs/testing';
 | 
					import { Test } from '@nestjs/testing';
 | 
				
			||||||
import { UploadPartCommand, CompleteMultipartUploadCommand, CreateMultipartUploadCommand, S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
 | 
					import {
 | 
				
			||||||
 | 
						CompleteMultipartUploadCommand,
 | 
				
			||||||
 | 
						CreateMultipartUploadCommand,
 | 
				
			||||||
 | 
						PutObjectCommand,
 | 
				
			||||||
 | 
						S3Client,
 | 
				
			||||||
 | 
						UploadPartCommand,
 | 
				
			||||||
 | 
					} from '@aws-sdk/client-s3';
 | 
				
			||||||
import { mockClient } from 'aws-sdk-client-mock';
 | 
					import { mockClient } from 'aws-sdk-client-mock';
 | 
				
			||||||
import { GlobalModule } from '@/GlobalModule.js';
 | 
					import { GlobalModule } from '@/GlobalModule.js';
 | 
				
			||||||
import { CoreModule } from '@/core/CoreModule.js';
 | 
					import { CoreModule } from '@/core/CoreModule.js';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,13 +4,13 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { ulid } from 'ulid';
 | 
					import { ulid } from 'ulid';
 | 
				
			||||||
import { describe, test, expect } from '@jest/globals';
 | 
					import { describe, expect, test } from '@jest/globals';
 | 
				
			||||||
import { aidRegExp, genAid, parseAid } from '@/misc/id/aid.js';
 | 
					import { aidRegExp, genAid, parseAid } from '@/misc/id/aid.js';
 | 
				
			||||||
import { aidxRegExp, genAidx, parseAidx } from '@/misc/id/aidx.js';
 | 
					import { aidxRegExp, genAidx, parseAidx } from '@/misc/id/aidx.js';
 | 
				
			||||||
import { genMeid, meidRegExp, parseMeid } from '@/misc/id/meid.js';
 | 
					import { genMeid, meidRegExp, parseMeid } from '@/misc/id/meid.js';
 | 
				
			||||||
import { genMeidg, meidgRegExp, parseMeidg } from '@/misc/id/meidg.js';
 | 
					import { genMeidg, meidgRegExp, parseMeidg } from '@/misc/id/meidg.js';
 | 
				
			||||||
import { genObjectId, objectIdRegExp, parseObjectId } from '@/misc/id/object-id.js';
 | 
					import { genObjectId, objectIdRegExp, parseObjectId } from '@/misc/id/object-id.js';
 | 
				
			||||||
import { ulidRegExp, parseUlid } from '@/misc/id/ulid.js';
 | 
					import { parseUlid, ulidRegExp } from '@/misc/id/ulid.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('misc:id', () => {
 | 
					describe('misc:id', () => {
 | 
				
			||||||
	test('aid', () => {
 | 
						test('aid', () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@
 | 
				
			||||||
 * SPDX-License-Identifier: AGPL-3.0-only
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { describe, test, expect } from '@jest/globals';
 | 
					import { describe, expect, test } from '@jest/globals';
 | 
				
			||||||
import { contentDisposition } from '@/misc/content-disposition.js';
 | 
					import { contentDisposition } from '@/misc/content-disposition.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('misc:content-disposition', () => {
 | 
					describe('misc:content-disposition', () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as assert from 'node:assert';
 | 
					import * as assert from 'node:assert';
 | 
				
			||||||
import { readFile } from 'node:fs/promises';
 | 
					import { readFile } from 'node:fs/promises';
 | 
				
			||||||
import { isAbsolute, basename } from 'node:path';
 | 
					import { basename, isAbsolute } from 'node:path';
 | 
				
			||||||
import { randomUUID } from 'node:crypto';
 | 
					import { randomUUID } from 'node:crypto';
 | 
				
			||||||
import { inspect } from 'node:util';
 | 
					import { inspect } from 'node:util';
 | 
				
			||||||
import WebSocket, { ClientOptions } from 'ws';
 | 
					import WebSocket, { ClientOptions } from 'ws';
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,11 @@ export const failedApiCall = async <T, >(request: ApiRequest, assertion: {
 | 
				
			||||||
	return res.body;
 | 
						return res.body;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const request = async (path: string, params: any, me?: UserToken): Promise<{ status: number, headers: Headers, body: any }> => {
 | 
					const request = async (path: string, params: any, me?: UserToken): Promise<{
 | 
				
			||||||
 | 
						status: number,
 | 
				
			||||||
 | 
						headers: Headers,
 | 
				
			||||||
 | 
						body: any
 | 
				
			||||||
 | 
					}> => {
 | 
				
			||||||
	const bodyAuth: Record<string, string> = {};
 | 
						const bodyAuth: Record<string, string> = {};
 | 
				
			||||||
	const headers: Record<string, string> = {
 | 
						const headers: Record<string, string> = {
 | 
				
			||||||
		'Content-Type': 'application/json',
 | 
							'Content-Type': 'application/json',
 | 
				
			||||||
| 
						 | 
					@ -275,7 +279,11 @@ interface UploadOptions {
 | 
				
			||||||
 * Upload file
 | 
					 * Upload file
 | 
				
			||||||
 * @param user User
 | 
					 * @param user User
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export const uploadFile = async (user?: UserToken, { path, name, blob }: UploadOptions = {}): Promise<{ status: number, headers: Headers, body: misskey.Endpoints['drive/files/create']['res'] | null }> => {
 | 
					export const uploadFile = async (user?: UserToken, { path, name, blob }: UploadOptions = {}): Promise<{
 | 
				
			||||||
 | 
						status: number,
 | 
				
			||||||
 | 
						headers: Headers,
 | 
				
			||||||
 | 
						body: misskey.Endpoints['drive/files/create']['res'] | null
 | 
				
			||||||
 | 
					}> => {
 | 
				
			||||||
	const absPath = path == null
 | 
						const absPath = path == null
 | 
				
			||||||
		? new URL('resources/Lenna.jpg', import.meta.url)
 | 
							? new URL('resources/Lenna.jpg', import.meta.url)
 | 
				
			||||||
		: isAbsolute(path.toString())
 | 
							: isAbsolute(path.toString())
 | 
				
			||||||
| 
						 | 
					@ -426,8 +434,8 @@ export const simpleGet = async (path: string, accept = '*/*', cookie: any = unde
 | 
				
			||||||
	];
 | 
						];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const body =
 | 
						const body =
 | 
				
			||||||
		jsonTypes.includes(res.headers.get('content-type') ?? '')	? await res.json() :
 | 
							jsonTypes.includes(res.headers.get('content-type') ?? '') ? await res.json() :
 | 
				
			||||||
		htmlTypes.includes(res.headers.get('content-type') ?? '')	? new JSDOM(await res.text()) :
 | 
							htmlTypes.includes(res.headers.get('content-type') ?? '') ? new JSDOM(await res.text()) :
 | 
				
			||||||
		null;
 | 
							null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
| 
						 | 
					@ -557,3 +565,34 @@ export function sleep(msec: number) {
 | 
				
			||||||
		}, msec);
 | 
							}, msec);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function sendEnvUpdateRequest(params: { key: string, value?: string }) {
 | 
				
			||||||
 | 
						const res = await fetch(
 | 
				
			||||||
 | 
							`http://localhost:${port + 1000}/env`,
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								method: 'POST',
 | 
				
			||||||
 | 
								headers: {
 | 
				
			||||||
 | 
									'Content-Type': 'application/json',
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								body: JSON.stringify(params),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (res.status !== 200) {
 | 
				
			||||||
 | 
							throw new Error('server env update failed.');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function sendEnvResetRequest() {
 | 
				
			||||||
 | 
						const res = await fetch(
 | 
				
			||||||
 | 
							`http://localhost:${port + 1000}/env-reset`,
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								method: 'POST',
 | 
				
			||||||
 | 
								body: JSON.stringify({}),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (res.status !== 200) {
 | 
				
			||||||
 | 
							throw new Error('server env update failed.');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										154
									
								
								pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										154
									
								
								pnpm-lock.yaml
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -112,10 +112,10 @@ importers:
 | 
				
			||||||
        version: 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
					        version: 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
				
			||||||
      '@nestjs/core':
 | 
					      '@nestjs/core':
 | 
				
			||||||
        specifier: 10.2.10
 | 
					        specifier: 10.2.10
 | 
				
			||||||
        version: 10.2.10(@nestjs/common@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
					        version: 10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.0)(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
				
			||||||
      '@nestjs/testing':
 | 
					      '@nestjs/testing':
 | 
				
			||||||
        specifier: 10.2.10
 | 
					        specifier: 10.2.10
 | 
				
			||||||
        version: 10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)
 | 
					        version: 10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(@nestjs/platform-express@10.3.0)
 | 
				
			||||||
      '@peertube/http-signature':
 | 
					      '@peertube/http-signature':
 | 
				
			||||||
        specifier: 1.7.0
 | 
					        specifier: 1.7.0
 | 
				
			||||||
        version: 1.7.0
 | 
					        version: 1.7.0
 | 
				
			||||||
| 
						 | 
					@ -496,6 +496,9 @@ importers:
 | 
				
			||||||
      '@misskey-dev/eslint-plugin':
 | 
					      '@misskey-dev/eslint-plugin':
 | 
				
			||||||
        specifier: ^1.0.0
 | 
					        specifier: ^1.0.0
 | 
				
			||||||
        version: 1.0.0(@typescript-eslint/eslint-plugin@6.14.0)(@typescript-eslint/parser@6.14.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
 | 
					        version: 1.0.0(@typescript-eslint/eslint-plugin@6.14.0)(@typescript-eslint/parser@6.14.0)(eslint-plugin-import@2.29.1)(eslint@8.56.0)
 | 
				
			||||||
 | 
					      '@nestjs/platform-express':
 | 
				
			||||||
 | 
					        specifier: ^10.3.0
 | 
				
			||||||
 | 
					        version: 10.3.0(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)
 | 
				
			||||||
      '@simplewebauthn/typescript-types':
 | 
					      '@simplewebauthn/typescript-types':
 | 
				
			||||||
        specifier: 8.3.4
 | 
					        specifier: 8.3.4
 | 
				
			||||||
        version: 8.3.4
 | 
					        version: 8.3.4
 | 
				
			||||||
| 
						 | 
					@ -640,6 +643,9 @@ importers:
 | 
				
			||||||
      execa:
 | 
					      execa:
 | 
				
			||||||
        specifier: 8.0.1
 | 
					        specifier: 8.0.1
 | 
				
			||||||
        version: 8.0.1
 | 
					        version: 8.0.1
 | 
				
			||||||
 | 
					      fkill:
 | 
				
			||||||
 | 
					        specifier: ^9.0.0
 | 
				
			||||||
 | 
					        version: 9.0.0
 | 
				
			||||||
      jest:
 | 
					      jest:
 | 
				
			||||||
        specifier: 29.7.0
 | 
					        specifier: 29.7.0
 | 
				
			||||||
        version: 29.7.0(@types/node@20.10.5)
 | 
					        version: 29.7.0(@types/node@20.10.5)
 | 
				
			||||||
| 
						 | 
					@ -649,6 +655,9 @@ importers:
 | 
				
			||||||
      nodemon:
 | 
					      nodemon:
 | 
				
			||||||
        specifier: 3.0.2
 | 
					        specifier: 3.0.2
 | 
				
			||||||
        version: 3.0.2
 | 
					        version: 3.0.2
 | 
				
			||||||
 | 
					      pid-port:
 | 
				
			||||||
 | 
					        specifier: ^1.0.0
 | 
				
			||||||
 | 
					        version: 1.0.0
 | 
				
			||||||
      simple-oauth2:
 | 
					      simple-oauth2:
 | 
				
			||||||
        specifier: 5.0.0
 | 
					        specifier: 5.0.0
 | 
				
			||||||
        version: 5.0.0
 | 
					        version: 5.0.0
 | 
				
			||||||
| 
						 | 
					@ -4878,7 +4887,6 @@ packages:
 | 
				
			||||||
  /@lukeed/csprng@1.0.1:
 | 
					  /@lukeed/csprng@1.0.1:
 | 
				
			||||||
    resolution: {integrity: sha512-uSvJdwQU5nK+Vdf6zxcWAY2A8r7uqe+gePwLWzJ+fsQehq18pc0I2hJKwypZ2aLM90+Er9u1xn4iLJPZ+xlL4g==}
 | 
					    resolution: {integrity: sha512-uSvJdwQU5nK+Vdf6zxcWAY2A8r7uqe+gePwLWzJ+fsQehq18pc0I2hJKwypZ2aLM90+Er9u1xn4iLJPZ+xlL4g==}
 | 
				
			||||||
    engines: {node: '>=8'}
 | 
					    engines: {node: '>=8'}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /@lukeed/ms@2.0.1:
 | 
					  /@lukeed/ms@2.0.1:
 | 
				
			||||||
    resolution: {integrity: sha512-Xs/4RZltsAL7pkvaNStUQt7netTkyxrS0K+RILcVr3TRMS/ToOg4I6uNfhB9SlGsnWBym4U+EaXq0f0cEMNkHA==}
 | 
					    resolution: {integrity: sha512-Xs/4RZltsAL7pkvaNStUQt7netTkyxrS0K+RILcVr3TRMS/ToOg4I6uNfhB9SlGsnWBym4U+EaXq0f0cEMNkHA==}
 | 
				
			||||||
| 
						 | 
					@ -5132,9 +5140,8 @@ packages:
 | 
				
			||||||
      rxjs: 7.8.1
 | 
					      rxjs: 7.8.1
 | 
				
			||||||
      tslib: 2.6.2
 | 
					      tslib: 2.6.2
 | 
				
			||||||
      uid: 2.0.2
 | 
					      uid: 2.0.2
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /@nestjs/core@10.2.10(@nestjs/common@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1):
 | 
					  /@nestjs/core@10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.0)(reflect-metadata@0.1.14)(rxjs@7.8.1):
 | 
				
			||||||
    resolution: {integrity: sha512-+ckOI6BPi2ZMHikT9MCG4ctHDc4OnjhoIytrn7f2AYMMXI4bnutJhqyQKc30VDka5x3Wq6QAD57pgSP7y+JjJg==}
 | 
					    resolution: {integrity: sha512-+ckOI6BPi2ZMHikT9MCG4ctHDc4OnjhoIytrn7f2AYMMXI4bnutJhqyQKc30VDka5x3Wq6QAD57pgSP7y+JjJg==}
 | 
				
			||||||
    requiresBuild: true
 | 
					    requiresBuild: true
 | 
				
			||||||
    peerDependencies:
 | 
					    peerDependencies:
 | 
				
			||||||
| 
						 | 
					@ -5153,6 +5160,7 @@ packages:
 | 
				
			||||||
        optional: true
 | 
					        optional: true
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
      '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
					      '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
				
			||||||
 | 
					      '@nestjs/platform-express': 10.3.0(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)
 | 
				
			||||||
      '@nuxtjs/opencollective': 0.3.2
 | 
					      '@nuxtjs/opencollective': 0.3.2
 | 
				
			||||||
      fast-safe-stringify: 2.1.1
 | 
					      fast-safe-stringify: 2.1.1
 | 
				
			||||||
      iterare: 1.2.1
 | 
					      iterare: 1.2.1
 | 
				
			||||||
| 
						 | 
					@ -5163,9 +5171,24 @@ packages:
 | 
				
			||||||
      uid: 2.0.2
 | 
					      uid: 2.0.2
 | 
				
			||||||
    transitivePeerDependencies:
 | 
					    transitivePeerDependencies:
 | 
				
			||||||
      - encoding
 | 
					      - encoding
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /@nestjs/testing@10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10):
 | 
					  /@nestjs/platform-express@10.3.0(@nestjs/common@10.2.10)(@nestjs/core@10.2.10):
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-E4hUW48bYv8OHbP9XQg6deefmXb0pDSSuE38SdhA0mJ37zGY7C5EqqBUdlQk4ttfD+OdnbIgJ1zOokT6dd2d7A==}
 | 
				
			||||||
 | 
					    peerDependencies:
 | 
				
			||||||
 | 
					      '@nestjs/common': ^10.0.0
 | 
				
			||||||
 | 
					      '@nestjs/core': ^10.0.0
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
				
			||||||
 | 
					      '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.0)(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
				
			||||||
 | 
					      body-parser: 1.20.2
 | 
				
			||||||
 | 
					      cors: 2.8.5
 | 
				
			||||||
 | 
					      express: 4.18.2
 | 
				
			||||||
 | 
					      multer: 1.4.4-lts.1
 | 
				
			||||||
 | 
					      tslib: 2.6.2
 | 
				
			||||||
 | 
					    transitivePeerDependencies:
 | 
				
			||||||
 | 
					      - supports-color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /@nestjs/testing@10.2.10(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)(@nestjs/platform-express@10.3.0):
 | 
				
			||||||
    resolution: {integrity: sha512-IVLUnPz/+fkBtPATYfqTIP+phN9yjkXejmj+JyhmcfPJZpxBmD1i9VSMqa4u54l37j0xkGPscQ0IXpbhqMYUKw==}
 | 
					    resolution: {integrity: sha512-IVLUnPz/+fkBtPATYfqTIP+phN9yjkXejmj+JyhmcfPJZpxBmD1i9VSMqa4u54l37j0xkGPscQ0IXpbhqMYUKw==}
 | 
				
			||||||
    peerDependencies:
 | 
					    peerDependencies:
 | 
				
			||||||
      '@nestjs/common': ^10.0.0
 | 
					      '@nestjs/common': ^10.0.0
 | 
				
			||||||
| 
						 | 
					@ -5179,7 +5202,8 @@ packages:
 | 
				
			||||||
        optional: true
 | 
					        optional: true
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
      '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
					      '@nestjs/common': 10.2.10(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
				
			||||||
      '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
					      '@nestjs/core': 10.2.10(@nestjs/common@10.2.10)(@nestjs/platform-express@10.3.0)(reflect-metadata@0.1.14)(rxjs@7.8.1)
 | 
				
			||||||
 | 
					      '@nestjs/platform-express': 10.3.0(@nestjs/common@10.2.10)(@nestjs/core@10.2.10)
 | 
				
			||||||
      tslib: 2.6.2
 | 
					      tslib: 2.6.2
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5249,7 +5273,6 @@ packages:
 | 
				
			||||||
      node-fetch: 2.7.0
 | 
					      node-fetch: 2.7.0
 | 
				
			||||||
    transitivePeerDependencies:
 | 
					    transitivePeerDependencies:
 | 
				
			||||||
      - encoding
 | 
					      - encoding
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /@one-ini/wasm@0.1.1:
 | 
					  /@one-ini/wasm@0.1.1:
 | 
				
			||||||
    resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
 | 
					    resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
 | 
				
			||||||
| 
						 | 
					@ -9164,6 +9187,14 @@ packages:
 | 
				
			||||||
      clean-stack: 2.2.0
 | 
					      clean-stack: 2.2.0
 | 
				
			||||||
      indent-string: 4.0.0
 | 
					      indent-string: 4.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /aggregate-error@5.0.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==}
 | 
				
			||||||
 | 
					    engines: {node: '>=18'}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      clean-stack: 5.2.0
 | 
				
			||||||
 | 
					      indent-string: 5.0.0
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /ajv-draft-04@1.0.0(ajv@8.12.0):
 | 
					  /ajv-draft-04@1.0.0(ajv@8.12.0):
 | 
				
			||||||
    resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
 | 
					    resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
 | 
				
			||||||
    peerDependencies:
 | 
					    peerDependencies:
 | 
				
			||||||
| 
						 | 
					@ -9268,6 +9299,9 @@ packages:
 | 
				
			||||||
    engines: {node: '>= 6.0.0'}
 | 
					    engines: {node: '>= 6.0.0'}
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /append-field@1.0.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /aproba@2.0.0:
 | 
					  /aproba@2.0.0:
 | 
				
			||||||
    resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
 | 
					    resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
 | 
				
			||||||
    requiresBuild: true
 | 
					    requiresBuild: true
 | 
				
			||||||
| 
						 | 
					@ -9806,7 +9840,6 @@ packages:
 | 
				
			||||||
      unpipe: 1.0.0
 | 
					      unpipe: 1.0.0
 | 
				
			||||||
    transitivePeerDependencies:
 | 
					    transitivePeerDependencies:
 | 
				
			||||||
      - supports-color
 | 
					      - supports-color
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /boolbase@1.0.0:
 | 
					  /boolbase@1.0.0:
 | 
				
			||||||
    resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
 | 
					    resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
 | 
				
			||||||
| 
						 | 
					@ -9952,7 +9985,6 @@ packages:
 | 
				
			||||||
    engines: {node: '>=10.16.0'}
 | 
					    engines: {node: '>=10.16.0'}
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
      streamsearch: 1.1.0
 | 
					      streamsearch: 1.1.0
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /bytes@3.0.0:
 | 
					  /bytes@3.0.0:
 | 
				
			||||||
    resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
 | 
					    resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
 | 
				
			||||||
| 
						 | 
					@ -10290,6 +10322,13 @@ packages:
 | 
				
			||||||
    resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
 | 
					    resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
 | 
				
			||||||
    engines: {node: '>=6'}
 | 
					    engines: {node: '>=6'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /clean-stack@5.2.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==}
 | 
				
			||||||
 | 
					    engines: {node: '>=14.16'}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      escape-string-regexp: 5.0.0
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /cli-cursor@3.1.0:
 | 
					  /cli-cursor@3.1.0:
 | 
				
			||||||
    resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
 | 
					    resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
 | 
				
			||||||
    engines: {node: '>=8'}
 | 
					    engines: {node: '>=8'}
 | 
				
			||||||
| 
						 | 
					@ -10534,7 +10573,6 @@ packages:
 | 
				
			||||||
      inherits: 2.0.4
 | 
					      inherits: 2.0.4
 | 
				
			||||||
      readable-stream: 2.3.7
 | 
					      readable-stream: 2.3.7
 | 
				
			||||||
      typedarray: 0.0.6
 | 
					      typedarray: 0.0.6
 | 
				
			||||||
    dev: true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /config-chain@1.1.13:
 | 
					  /config-chain@1.1.13:
 | 
				
			||||||
    resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
 | 
					    resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
 | 
				
			||||||
| 
						 | 
					@ -10545,7 +10583,6 @@ packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /consola@2.15.3:
 | 
					  /consola@2.15.3:
 | 
				
			||||||
    resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
 | 
					    resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /console-control-strings@1.1.0:
 | 
					  /console-control-strings@1.1.0:
 | 
				
			||||||
    resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
 | 
					    resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
 | 
				
			||||||
| 
						 | 
					@ -10611,6 +10648,13 @@ packages:
 | 
				
			||||||
  /core-util-is@1.0.3:
 | 
					  /core-util-is@1.0.3:
 | 
				
			||||||
    resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
 | 
					    resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /cors@2.8.5:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
 | 
				
			||||||
 | 
					    engines: {node: '>= 0.10'}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      object-assign: 4.1.1
 | 
				
			||||||
 | 
					      vary: 1.1.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /crc-32@1.2.2:
 | 
					  /crc-32@1.2.2:
 | 
				
			||||||
    resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
 | 
					    resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
 | 
				
			||||||
    engines: {node: '>=0.8'}
 | 
					    engines: {node: '>=0.8'}
 | 
				
			||||||
| 
						 | 
					@ -11636,7 +11680,6 @@ packages:
 | 
				
			||||||
  /escape-string-regexp@5.0.0:
 | 
					  /escape-string-regexp@5.0.0:
 | 
				
			||||||
    resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
 | 
					    resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
 | 
				
			||||||
    engines: {node: '>=12'}
 | 
					    engines: {node: '>=12'}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /escodegen@2.1.0:
 | 
					  /escodegen@2.1.0:
 | 
				
			||||||
    resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
 | 
					    resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
 | 
				
			||||||
| 
						 | 
					@ -12058,6 +12101,21 @@ packages:
 | 
				
			||||||
      signal-exit: 3.0.7
 | 
					      signal-exit: 3.0.7
 | 
				
			||||||
      strip-final-newline: 2.0.0
 | 
					      strip-final-newline: 2.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /execa@6.1.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==}
 | 
				
			||||||
 | 
					    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      cross-spawn: 7.0.3
 | 
				
			||||||
 | 
					      get-stream: 6.0.1
 | 
				
			||||||
 | 
					      human-signals: 3.0.1
 | 
				
			||||||
 | 
					      is-stream: 3.0.0
 | 
				
			||||||
 | 
					      merge-stream: 2.0.0
 | 
				
			||||||
 | 
					      npm-run-path: 5.1.0
 | 
				
			||||||
 | 
					      onetime: 6.0.0
 | 
				
			||||||
 | 
					      signal-exit: 3.0.7
 | 
				
			||||||
 | 
					      strip-final-newline: 3.0.0
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /execa@8.0.1:
 | 
					  /execa@8.0.1:
 | 
				
			||||||
    resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
 | 
					    resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
 | 
				
			||||||
    engines: {node: '>=16.17'}
 | 
					    engines: {node: '>=16.17'}
 | 
				
			||||||
| 
						 | 
					@ -12252,7 +12310,6 @@ packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /fast-safe-stringify@2.1.1:
 | 
					  /fast-safe-stringify@2.1.1:
 | 
				
			||||||
    resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
 | 
					    resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /fast-uri@2.2.0:
 | 
					  /fast-uri@2.2.0:
 | 
				
			||||||
    resolution: {integrity: sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==}
 | 
					    resolution: {integrity: sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==}
 | 
				
			||||||
| 
						 | 
					@ -12470,6 +12527,18 @@ packages:
 | 
				
			||||||
      semver-regex: 4.0.5
 | 
					      semver-regex: 4.0.5
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /fkill@9.0.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-MdYSsbdCaIRjzo5edthZtWmEZVMfr1qrtYZUHIdO3swCE+CoZA8S5l0s4jDsYlTa9ZiXv0pTgpzE7s4N8NeUOA==}
 | 
				
			||||||
 | 
					    engines: {node: '>=18'}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      aggregate-error: 5.0.0
 | 
				
			||||||
 | 
					      execa: 8.0.1
 | 
				
			||||||
 | 
					      pid-port: 1.0.0
 | 
				
			||||||
 | 
					      process-exists: 5.0.0
 | 
				
			||||||
 | 
					      ps-list: 8.1.1
 | 
				
			||||||
 | 
					      taskkill: 5.0.0
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /flat-cache@3.0.4:
 | 
					  /flat-cache@3.0.4:
 | 
				
			||||||
    resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
 | 
					    resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
 | 
				
			||||||
    engines: {node: ^10.12.0 || >=12.0.0}
 | 
					    engines: {node: ^10.12.0 || >=12.0.0}
 | 
				
			||||||
| 
						 | 
					@ -13298,6 +13367,11 @@ packages:
 | 
				
			||||||
    resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
 | 
					    resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
 | 
				
			||||||
    engines: {node: '>=10.17.0'}
 | 
					    engines: {node: '>=10.17.0'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /human-signals@3.0.1:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==}
 | 
				
			||||||
 | 
					    engines: {node: '>=12.20.0'}
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /human-signals@5.0.0:
 | 
					  /human-signals@5.0.0:
 | 
				
			||||||
    resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
 | 
					    resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
 | 
				
			||||||
    engines: {node: '>=16.17.0'}
 | 
					    engines: {node: '>=16.17.0'}
 | 
				
			||||||
| 
						 | 
					@ -13362,6 +13436,11 @@ packages:
 | 
				
			||||||
    resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
 | 
					    resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
 | 
				
			||||||
    engines: {node: '>=8'}
 | 
					    engines: {node: '>=8'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /indent-string@5.0.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
 | 
				
			||||||
 | 
					    engines: {node: '>=12'}
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /inflight@1.0.6:
 | 
					  /inflight@1.0.6:
 | 
				
			||||||
    resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
 | 
					    resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
| 
						 | 
					@ -13893,7 +13972,6 @@ packages:
 | 
				
			||||||
  /iterare@1.2.1:
 | 
					  /iterare@1.2.1:
 | 
				
			||||||
    resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==}
 | 
					    resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==}
 | 
				
			||||||
    engines: {node: '>=6'}
 | 
					    engines: {node: '>=6'}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /jackspeak@2.3.6:
 | 
					  /jackspeak@2.3.6:
 | 
				
			||||||
    resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
 | 
					    resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
 | 
				
			||||||
| 
						 | 
					@ -15437,6 +15515,18 @@ packages:
 | 
				
			||||||
    resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
 | 
					    resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /multer@1.4.4-lts.1:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==}
 | 
				
			||||||
 | 
					    engines: {node: '>= 6.0.0'}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      append-field: 1.0.0
 | 
				
			||||||
 | 
					      busboy: 1.6.0
 | 
				
			||||||
 | 
					      concat-stream: 1.6.2
 | 
				
			||||||
 | 
					      mkdirp: 0.5.6
 | 
				
			||||||
 | 
					      object-assign: 4.1.1
 | 
				
			||||||
 | 
					      type-is: 1.6.18
 | 
				
			||||||
 | 
					      xtend: 4.0.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /multi-integer-range@3.0.0:
 | 
					  /multi-integer-range@3.0.0:
 | 
				
			||||||
    resolution: {integrity: sha512-uQzynjVJ8F7x5wjaK0g4Ybhy2TvO/pk96+YHyS5g1W4GuUEV6HMebZ8HcRwWgKIRCUT2MLbM5uCKwYcAqkS+8Q==}
 | 
					    resolution: {integrity: sha512-uQzynjVJ8F7x5wjaK0g4Ybhy2TvO/pk96+YHyS5g1W4GuUEV6HMebZ8HcRwWgKIRCUT2MLbM5uCKwYcAqkS+8Q==}
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
| 
						 | 
					@ -16230,7 +16320,6 @@ packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /path-to-regexp@3.2.0:
 | 
					  /path-to-regexp@3.2.0:
 | 
				
			||||||
    resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==}
 | 
					    resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /path-to-regexp@6.2.1:
 | 
					  /path-to-regexp@6.2.1:
 | 
				
			||||||
    resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
 | 
					    resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
 | 
				
			||||||
| 
						 | 
					@ -16366,6 +16455,13 @@ packages:
 | 
				
			||||||
    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
 | 
					    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
 | 
				
			||||||
    engines: {node: '>=8.6'}
 | 
					    engines: {node: '>=8.6'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /pid-port@1.0.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-LSNBeKChRPA4Xlrs6+zV588G1hSrFvANtPV5rt/5MPfSPK3V9XPWxx1d29svsrOjngT9ifLisXWCLS7DvO9ZhQ==}
 | 
				
			||||||
 | 
					    engines: {node: '>=18'}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      execa: 8.0.1
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /pify@2.3.0:
 | 
					  /pify@2.3.0:
 | 
				
			||||||
    resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
 | 
					    resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
 | 
				
			||||||
    engines: {node: '>=0.10.0'}
 | 
					    engines: {node: '>=0.10.0'}
 | 
				
			||||||
| 
						 | 
					@ -16922,6 +17018,13 @@ packages:
 | 
				
			||||||
    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 | 
					    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /process-exists@5.0.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-6QPRh5fyHD8MaXr4GYML8K/YY0Sq5dKHGIOrAKS3cYpHQdmygFCcijIu1dVoNKAZ0TWAMoeh8KDK9dF8auBkJA==}
 | 
				
			||||||
 | 
					    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      ps-list: 8.1.1
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /process-nextick-args@2.0.1:
 | 
					  /process-nextick-args@2.0.1:
 | 
				
			||||||
    resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
 | 
					    resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16993,6 +17096,11 @@ packages:
 | 
				
			||||||
    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
 | 
					    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /ps-list@8.1.1:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-OPS9kEJYVmiO48u/B9qneqhkMvgCxT+Tm28VCEJpheTpl8cJ0ffZRRNgS5mrQRTrX5yRTpaJ+hRDeefXYmmorQ==}
 | 
				
			||||||
 | 
					    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /ps-tree@1.2.0:
 | 
					  /ps-tree@1.2.0:
 | 
				
			||||||
    resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
 | 
					    resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
 | 
				
			||||||
    engines: {node: '>= 0.10'}
 | 
					    engines: {node: '>= 0.10'}
 | 
				
			||||||
| 
						 | 
					@ -17258,7 +17366,6 @@ packages:
 | 
				
			||||||
      http-errors: 2.0.0
 | 
					      http-errors: 2.0.0
 | 
				
			||||||
      iconv-lite: 0.4.24
 | 
					      iconv-lite: 0.4.24
 | 
				
			||||||
      unpipe: 1.0.0
 | 
					      unpipe: 1.0.0
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /rc@1.2.8:
 | 
					  /rc@1.2.8:
 | 
				
			||||||
    resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
 | 
					    resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
 | 
				
			||||||
| 
						 | 
					@ -17563,7 +17670,6 @@ packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /reflect-metadata@0.1.14:
 | 
					  /reflect-metadata@0.1.14:
 | 
				
			||||||
    resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==}
 | 
					    resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /regenerate-unicode-properties@10.1.0:
 | 
					  /regenerate-unicode-properties@10.1.0:
 | 
				
			||||||
    resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==}
 | 
					    resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==}
 | 
				
			||||||
| 
						 | 
					@ -18546,7 +18652,6 @@ packages:
 | 
				
			||||||
  /streamsearch@1.1.0:
 | 
					  /streamsearch@1.1.0:
 | 
				
			||||||
    resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
 | 
					    resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
 | 
				
			||||||
    engines: {node: '>=10.0.0'}
 | 
					    engines: {node: '>=10.0.0'}
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /streamx@2.15.0:
 | 
					  /streamx@2.15.0:
 | 
				
			||||||
    resolution: {integrity: sha512-HcxY6ncGjjklGs1xsP1aR71INYcsXFJet5CU1CHqihQ2J5nOsbd4OjgjHO42w/4QNv9gZb3BueV+Vxok5pLEXg==}
 | 
					    resolution: {integrity: sha512-HcxY6ncGjjklGs1xsP1aR71INYcsXFJet5CU1CHqihQ2J5nOsbd4OjgjHO42w/4QNv9gZb3BueV+Vxok5pLEXg==}
 | 
				
			||||||
| 
						 | 
					@ -18855,6 +18960,13 @@ packages:
 | 
				
			||||||
      mkdirp: 1.0.4
 | 
					      mkdirp: 1.0.4
 | 
				
			||||||
      yallist: 4.0.0
 | 
					      yallist: 4.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /taskkill@5.0.0:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-+HRtZ40Vc+6YfCDWCeAsixwxJgMbPY4HHuTgzPYH3JXvqHWUlsCfy+ylXlAKhFNcuLp4xVeWeFBUhDk+7KYUvQ==}
 | 
				
			||||||
 | 
					    engines: {node: '>=14.16'}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      execa: 6.1.0
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /telejson@7.2.0:
 | 
					  /telejson@7.2.0:
 | 
				
			||||||
    resolution: {integrity: sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==}
 | 
					    resolution: {integrity: sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==}
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
| 
						 | 
					@ -19288,7 +19400,6 @@ packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /typedarray@0.0.6:
 | 
					  /typedarray@0.0.6:
 | 
				
			||||||
    resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
 | 
					    resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
 | 
				
			||||||
    dev: true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /typeorm@0.3.17(ioredis@5.3.2)(pg@8.11.3):
 | 
					  /typeorm@0.3.17(ioredis@5.3.2)(pg@8.11.3):
 | 
				
			||||||
    resolution: {integrity: sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==}
 | 
					    resolution: {integrity: sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==}
 | 
				
			||||||
| 
						 | 
					@ -19401,7 +19512,6 @@ packages:
 | 
				
			||||||
    engines: {node: '>=8'}
 | 
					    engines: {node: '>=8'}
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
      '@lukeed/csprng': 1.0.1
 | 
					      '@lukeed/csprng': 1.0.1
 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /ulid@2.3.0:
 | 
					  /ulid@2.3.0:
 | 
				
			||||||
    resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==}
 | 
					    resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue