Revert "fix: 添付ファイルのあるリクエストを受けたときの初動を改善 (#15896)" (#15927)

* Revert "fix: 添付ファイルのあるリクエストを受けたときの初動を改善 (#15896)"

This reverts commit 7e8cc4d7c0.

* fix CHANGELOG.md
This commit is contained in:
おさむのひと 2025-05-03 16:23:06 +09:00 committed by GitHub
parent c13aa0c224
commit 526057cc61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 96 additions and 362 deletions

View File

@ -17,6 +17,7 @@
- ただし、このオプションを有効にする場合、インデックスの作成にかかる時間が倍~3倍以上になることがあります。 - ただし、このオプションを有効にする場合、インデックスの作成にかかる時間が倍~3倍以上になることがあります。
- また、大きなインスタンスである場合にはインデックスの作成に失敗し、複数回再試行する必要がある可能性があります。 - また、大きなインスタンスである場合にはインデックスの作成に失敗し、複数回再試行する必要がある可能性があります。
- Fix: チャンネルのフォロー一覧の結果が一部正しくないのを修正 (#12175) - Fix: チャンネルのフォロー一覧の結果が一部正しくないのを修正 (#12175)
- Fix: #15895 の取り消し
## 2025.4.1 ## 2025.4.1

View File

@ -223,7 +223,6 @@
"@types/semver": "7.7.0", "@types/semver": "7.7.0",
"@types/simple-oauth2": "5.0.7", "@types/simple-oauth2": "5.0.7",
"@types/sinonjs__fake-timers": "8.1.5", "@types/sinonjs__fake-timers": "8.1.5",
"@types/supertest": "6.0.3",
"@types/tinycolor2": "1.4.6", "@types/tinycolor2": "1.4.6",
"@types/tmp": "0.2.6", "@types/tmp": "0.2.6",
"@types/vary": "1.1.3", "@types/vary": "1.1.3",
@ -240,7 +239,6 @@
"jest-mock": "29.7.0", "jest-mock": "29.7.0",
"nodemon": "3.1.10", "nodemon": "3.1.10",
"pid-port": "1.0.2", "pid-port": "1.0.2",
"simple-oauth2": "5.1.0", "simple-oauth2": "5.1.0"
"supertest": "7.1.0"
} }
} }

View File

@ -73,7 +73,7 @@ export class ServerService implements OnApplicationShutdown {
} }
@bindThis @bindThis
public async launch() { public async launch(): Promise<void> {
const fastify = Fastify({ const fastify = Fastify({
trustProxy: true, trustProxy: true,
logger: false, logger: false,
@ -133,8 +133,8 @@ export class ServerService implements OnApplicationShutdown {
reply.header('content-type', 'text/plain; charset=utf-8'); reply.header('content-type', 'text/plain; charset=utf-8');
reply.header('link', `<${encodeURI(location)}>; rel="canonical"`); reply.header('link', `<${encodeURI(location)}>; rel="canonical"`);
done(null, [ done(null, [
'Refusing to relay remote ActivityPub object lookup.', "Refusing to relay remote ActivityPub object lookup.",
'', "",
`Please remove 'application/activity+json' and 'application/ld+json' from the Accept header or fetch using the authoritative URL at ${location}.`, `Please remove 'application/activity+json' and 'application/ld+json' from the Accept header or fetch using the authoritative URL at ${location}.`,
].join('\n')); ].join('\n'));
}); });
@ -301,7 +301,6 @@ export class ServerService implements OnApplicationShutdown {
} }
await fastify.ready(); await fastify.ready();
return fastify;
} }
@bindThis @bindThis

View File

@ -6,11 +6,8 @@
import { randomUUID } from 'node:crypto'; import { randomUUID } from 'node:crypto';
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import * as stream from 'node:stream/promises'; import * as stream from 'node:stream/promises';
import { Transform } from 'node:stream';
import { type MultipartFile } from '@fastify/multipart';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import * as Sentry from '@sentry/node'; import * as Sentry from '@sentry/node';
import { AttachmentFile } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { getIpHash } from '@/misc/get-ip-hash.js'; import { getIpHash } from '@/misc/get-ip-hash.js';
import type { MiLocalUser, MiUser } from '@/models/User.js'; import type { MiLocalUser, MiUser } from '@/models/User.js';
@ -19,7 +16,7 @@ import type Logger from '@/logger.js';
import type { MiMeta, UserIpsRepository } from '@/models/_.js'; import type { MiMeta, UserIpsRepository } from '@/models/_.js';
import { createTemp } from '@/misc/create-temp.js'; import { createTemp } from '@/misc/create-temp.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { type RolePolicies, RoleService } from '@/core/RoleService.js'; import { RoleService } from '@/core/RoleService.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import { ApiError } from './error.js'; import { ApiError } from './error.js';
import { RateLimiterService } from './RateLimiterService.js'; import { RateLimiterService } from './RateLimiterService.js';
@ -203,6 +200,18 @@ export class ApiCallService implements OnApplicationShutdown {
return; return;
} }
const [path, cleanup] = await createTemp();
await stream.pipeline(multipartData.file, fs.createWriteStream(path));
// ファイルサイズが制限を超えていた場合
// なお truncated はストリームを読み切ってからでないと機能しないため、stream.pipeline より後にある必要がある
if (multipartData.file.truncated) {
cleanup();
reply.code(413);
reply.send();
return;
}
const fields = {} as Record<string, unknown>; const fields = {} as Record<string, unknown>;
for (const [k, v] of Object.entries(multipartData.fields)) { for (const [k, v] of Object.entries(multipartData.fields)) {
fields[k] = typeof v === 'object' && 'value' in v ? v.value : undefined; fields[k] = typeof v === 'object' && 'value' in v ? v.value : undefined;
@ -217,7 +226,10 @@ export class ApiCallService implements OnApplicationShutdown {
return; return;
} }
this.authenticateService.authenticate(token).then(([user, app]) => { this.authenticateService.authenticate(token).then(([user, app]) => {
this.call(endpoint, user, app, fields, multipartData, request).then((res) => { this.call(endpoint, user, app, fields, {
name: multipartData.filename,
path: path,
}, request).then((res) => {
this.send(reply, res); this.send(reply, res);
}).catch((err: ApiError) => { }).catch((err: ApiError) => {
this.#sendApiError(reply, err); this.#sendApiError(reply, err);
@ -282,7 +294,10 @@ export class ApiCallService implements OnApplicationShutdown {
user: MiLocalUser | null | undefined, user: MiLocalUser | null | undefined,
token: MiAccessToken | null | undefined, token: MiAccessToken | null | undefined,
data: any, data: any,
multipartFile: MultipartFile | null, file: {
name: string;
path: string;
} | null,
request: FastifyRequest<{ Body: Record<string, unknown> | undefined, Querystring: Record<string, unknown> }>, request: FastifyRequest<{ Body: Record<string, unknown> | undefined, Querystring: Record<string, unknown> }>,
) { ) {
const isSecure = user != null && token == null; const isSecure = user != null && token == null;
@ -356,37 +371,6 @@ export class ApiCallService implements OnApplicationShutdown {
} }
} }
// Cast non JSON input
if ((ep.meta.requireFile || request.method === 'GET') && ep.params.properties) {
for (const k of Object.keys(ep.params.properties)) {
const param = ep.params.properties![k];
if (['boolean', 'number', 'integer'].includes(param.type ?? '') && typeof data[k] === 'string') {
try {
data[k] = JSON.parse(data[k]);
} catch (e) {
throw new ApiError({
message: 'Invalid param.',
code: 'INVALID_PARAM',
id: '0b5f1631-7c1a-41a6-b399-cce335f34d85',
}, {
param: k,
reason: `cannot cast to ${param.type}`,
});
}
}
}
}
if (token && ((ep.meta.kind && !token.permission.some(p => p === ep.meta.kind))
|| (!ep.meta.kind && (ep.meta.requireCredential || ep.meta.requireModerator || ep.meta.requireAdmin)))) {
throw new ApiError({
message: 'Your app does not have the necessary permissions to use this endpoint.',
code: 'PERMISSION_DENIED',
kind: 'permission',
id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838',
});
}
if ((ep.meta.requireModerator || ep.meta.requireAdmin) && (this.meta.rootUserId !== user!.id)) { if ((ep.meta.requireModerator || ep.meta.requireAdmin) && (this.meta.rootUserId !== user!.id)) {
const myRoles = await this.roleService.getUserRoles(user!.id); const myRoles = await this.roleService.getUserRoles(user!.id);
if (ep.meta.requireModerator && !myRoles.some(r => r.isModerator || r.isAdministrator)) { if (ep.meta.requireModerator && !myRoles.some(r => r.isModerator || r.isAdministrator)) {
@ -420,91 +404,49 @@ export class ApiCallService implements OnApplicationShutdown {
} }
} }
let attachmentFile: AttachmentFile | null = null; if (token && ((ep.meta.kind && !token.permission.some(p => p === ep.meta.kind))
let cleanup = () => {}; || (!ep.meta.kind && (ep.meta.requireCredential || ep.meta.requireModerator || ep.meta.requireAdmin)))) {
if (ep.meta.requireFile && request.method === 'POST' && multipartFile) { throw new ApiError({
const policies = await this.roleService.getUserPolicies(user!.id); message: 'Your app does not have the necessary permissions to use this endpoint.',
const result = await this.handleAttachmentFile( code: 'PERMISSION_DENIED',
Math.min((policies.maxFileSizeMb * 1024 * 1024), this.config.maxFileSize), kind: 'permission',
multipartFile, id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838',
); });
attachmentFile = result.attachmentFile; }
cleanup = result.cleanup;
// Cast non JSON input
if ((ep.meta.requireFile || request.method === 'GET') && ep.params.properties) {
for (const k of Object.keys(ep.params.properties)) {
const param = ep.params.properties![k];
if (['boolean', 'number', 'integer'].includes(param.type ?? '') && typeof data[k] === 'string') {
try {
data[k] = JSON.parse(data[k]);
} catch (e) {
throw new ApiError({
message: 'Invalid param.',
code: 'INVALID_PARAM',
id: '0b5f1631-7c1a-41a6-b399-cce335f34d85',
}, {
param: k,
reason: `cannot cast to ${param.type}`,
});
}
}
}
} }
// API invoking // API invoking
if (this.config.sentryForBackend) { if (this.config.sentryForBackend) {
return await Sentry.startSpan({ return await Sentry.startSpan({
name: 'API: ' + ep.name, name: 'API: ' + ep.name,
}, () => { }, () => ep.exec(data, user, token, file, request.ip, request.headers)
return ep.exec(data, user, token, attachmentFile, request.ip, request.headers) .catch((err: Error) => this.#onExecError(ep, data, err, user?.id)));
.catch((err: Error) => this.#onExecError(ep, data, err, user?.id))
.finally(() => cleanup());
});
} else { } else {
return await ep.exec(data, user, token, attachmentFile, request.ip, request.headers) return await ep.exec(data, user, token, file, request.ip, request.headers)
.catch((err: Error) => this.#onExecError(ep, data, err, user?.id)) .catch((err: Error) => this.#onExecError(ep, data, err, user?.id));
.finally(() => cleanup());
} }
} }
@bindThis
private async handleAttachmentFile(
fileSizeLimit: number,
multipartFile: MultipartFile,
) {
function createTooLongError() {
return new ApiError({
httpStatusCode: 413,
kind: 'client',
message: 'File size is too large.',
code: 'FILE_SIZE_TOO_LARGE',
id: 'ff827ce8-9b4b-4808-8511-422222a3362f',
});
}
function createLimitStream(limit: number) {
let total = 0;
return new Transform({
transform(chunk, _, callback) {
total += chunk.length;
if (total > limit) {
callback(createTooLongError());
} else {
callback(null, chunk);
}
},
});
}
const [path, cleanup] = await createTemp();
try {
await stream.pipeline(
multipartFile.file,
createLimitStream(fileSizeLimit),
fs.createWriteStream(path),
);
// ファイルサイズが制限を超えていた場合
// なお truncated はストリームを読み切ってからでないと機能しないため、stream.pipeline より後にある必要がある
if (multipartFile.file.truncated) {
throw createTooLongError();
}
} catch (err) {
cleanup();
throw err;
}
return {
attachmentFile: {
name: multipartFile.filename,
path,
},
cleanup,
};
}
@bindThis @bindThis
public dispose(): void { public dispose(): void {
clearInterval(this.userIpHistoriesClearIntervalId); clearInterval(this.userIpHistoriesClearIntervalId);

View File

@ -21,23 +21,23 @@ ajv.addFormat('misskey:id', /^[a-zA-Z0-9]+$/);
export type Response = Record<string, any> | void; export type Response = Record<string, any> | void;
export type AttachmentFile = { type File = {
name: string | null; name: string | null;
path: string; path: string;
}; };
// TODO: paramsの型をT['params']のスキーマ定義から推論する // TODO: paramsの型をT['params']のスキーマ定義から推論する
type Executor<T extends IEndpointMeta, Ps extends Schema> = type Executor<T extends IEndpointMeta, Ps extends Schema> =
(params: SchemaType<Ps>, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: AttachmentFile, cleanup?: () => any, ip?: string | null, headers?: Record<string, string> | null) => (params: SchemaType<Ps>, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record<string, string> | null) =>
Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>; Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>;
export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> { export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
public exec: (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: AttachmentFile, ip?: string | null, headers?: Record<string, string> | null) => Promise<any>; public exec: (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => Promise<any>;
constructor(meta: T, paramDef: Ps, cb: Executor<T, Ps>) { constructor(meta: T, paramDef: Ps, cb: Executor<T, Ps>) {
const validate = ajv.compile(paramDef); const validate = ajv.compile(paramDef);
this.exec = (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: AttachmentFile, ip?: string | null, headers?: Record<string, string> | null) => { this.exec = (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => {
let cleanup: undefined | (() => void) = undefined; let cleanup: undefined | (() => void) = undefined;
if (meta.requireFile) { if (meta.requireFile) {

View File

@ -159,8 +159,8 @@ describe('API', () => {
user: { token: application3 }, user: { token: application3 },
}, { }, {
status: 403, status: 403,
code: 'PERMISSION_DENIED', code: 'ROLE_PERMISSION_DENIED',
id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838', id: 'c3d38592-54c0-429d-be96-5636b0431a61',
}); });
await failedApiCall({ await failedApiCall({

View File

@ -1,108 +0,0 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { S3Client } from '@aws-sdk/client-s3';
import { Test, TestingModule } from '@nestjs/testing';
import { mockClient } from 'aws-sdk-client-mock';
import { FastifyInstance } from 'fastify';
import request from 'supertest';
import { CoreModule } from '@/core/CoreModule.js';
import { RoleService } from '@/core/RoleService.js';
import { DI } from '@/di-symbols.js';
import { GlobalModule } from '@/GlobalModule.js';
import { MiRole, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import { MiUser } from '@/models/User.js';
import { ServerModule } from '@/server/ServerModule.js';
import { ServerService } from '@/server/ServerService.js';
describe('/drive/files/create', () => {
let module: TestingModule;
let server: FastifyInstance;
const s3Mock = mockClient(S3Client);
let roleService: RoleService;
let root: MiUser;
let role_tinyAttachment: MiRole;
beforeAll(async () => {
module = await Test.createTestingModule({
imports: [GlobalModule, CoreModule, ServerModule],
}).compile();
module.enableShutdownHooks();
const serverService = module.get<ServerService>(ServerService);
server = await serverService.launch();
const usersRepository = module.get<UsersRepository>(DI.usersRepository);
root = await usersRepository.insert({
id: 'root',
username: 'root',
usernameLower: 'root',
token: '1234567890123456',
}).then(x => usersRepository.findOneByOrFail(x.identifiers[0]));
const userProfilesRepository = module.get<UserProfilesRepository>(DI.userProfilesRepository);
await userProfilesRepository.insert({
userId: root.id,
});
roleService = module.get<RoleService>(RoleService);
role_tinyAttachment = await roleService.create({
name: 'test-role001',
description: 'Test role001 description',
target: 'manual',
policies: {
maxFileSizeMb: {
useDefault: false,
priority: 1,
// 10byte
value: 10 / 1024 / 1024,
},
},
});
});
beforeEach(async () => {
s3Mock.reset();
await roleService.unassign(root.id, role_tinyAttachment.id).catch(() => {});
});
afterAll(async () => {
await server.close();
await module.close();
});
test('200 ok', async () => {
const result = await request(server.server)
.post('/api/drive/files/create')
.set('Content-Type', 'multipart/form-data')
.set('Authorization', `Bearer ${root.token}`)
.attach('file', Buffer.from('a'.repeat(1024 * 1024)));
expect(result.statusCode).toBe(200);
});
test('200 ok(with role)', async () => {
await roleService.assign(root.id, role_tinyAttachment.id);
const result = await request(server.server)
.post('/api/drive/files/create')
.set('Content-Type', 'multipart/form-data')
.set('Authorization', `Bearer ${root.token}`)
.attach('file', Buffer.from('a'.repeat(10)));
expect(result.statusCode).toBe(200);
});
test('413 too large', async () => {
await roleService.assign(root.id, role_tinyAttachment.id);
const result = await request(server.server)
.post('/api/drive/files/create')
.set('Content-Type', 'multipart/form-data')
.set('Authorization', `Bearer ${root.token}`)
.attach('file', Buffer.from('a'.repeat(11)));
expect(result.statusCode).toBe(413);
expect(result.body.error.code).toBe('FILE_SIZE_TOO_LARGE');
});
});

View File

@ -550,9 +550,6 @@ importers:
'@types/sinonjs__fake-timers': '@types/sinonjs__fake-timers':
specifier: 8.1.5 specifier: 8.1.5
version: 8.1.5 version: 8.1.5
'@types/supertest':
specifier: 6.0.3
version: 6.0.3
'@types/tinycolor2': '@types/tinycolor2':
specifier: 1.4.6 specifier: 1.4.6
version: 1.4.6 version: 1.4.6
@ -604,9 +601,6 @@ importers:
simple-oauth2: simple-oauth2:
specifier: 5.1.0 specifier: 5.1.0
version: 5.1.0 version: 5.1.0
supertest:
specifier: 7.1.0
version: 7.1.0
optionalDependencies: optionalDependencies:
'@swc/core-android-arm64': '@swc/core-android-arm64':
specifier: 1.3.11 specifier: 1.3.11
@ -3148,9 +3142,6 @@ packages:
peerDependencies: peerDependencies:
'@opentelemetry/api': ^1.1.0 '@opentelemetry/api': ^1.1.0
'@paralleldrive/cuid2@2.2.2':
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
'@parcel/watcher-android-arm64@2.5.0': '@parcel/watcher-android-arm64@2.5.0':
resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==} resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
@ -4294,9 +4285,6 @@ packages:
'@types/cookie@0.6.0': '@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
'@types/cookiejar@2.1.5':
resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==}
'@types/debug@4.1.12': '@types/debug@4.1.12':
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
@ -4384,9 +4372,6 @@ packages:
'@types/mdx@2.0.3': '@types/mdx@2.0.3':
resolution: {integrity: sha512-IgHxcT3RC8LzFLhKwP3gbMPeaK7BM9eBH46OdapPA7yvuIUJ8H6zHZV53J8hGZcTSnt95jANt+rTBNUUc22ACQ==} resolution: {integrity: sha512-IgHxcT3RC8LzFLhKwP3gbMPeaK7BM9eBH46OdapPA7yvuIUJ8H6zHZV53J8hGZcTSnt95jANt+rTBNUUc22ACQ==}
'@types/methods@1.1.4':
resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==}
'@types/micromatch@4.0.9': '@types/micromatch@4.0.9':
resolution: {integrity: sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg==} resolution: {integrity: sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg==}
@ -4525,12 +4510,6 @@ packages:
'@types/statuses@2.0.4': '@types/statuses@2.0.4':
resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==} resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==}
'@types/superagent@8.1.9':
resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==}
'@types/supertest@6.0.3':
resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==}
'@types/tedious@4.0.14': '@types/tedious@4.0.14':
resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==}
@ -5596,9 +5575,6 @@ packages:
compare-versions@6.1.1: compare-versions@6.1.1:
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
component-emitter@1.3.1:
resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
compress-commons@6.0.2: compress-commons@6.0.2:
resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
@ -5656,9 +5632,6 @@ packages:
resolution: {integrity: sha512-Xd8lFX4LM9QEEwxQpF9J9NTUh8pmdJO0cyRJhFiDoLTk2eH8FXlRv2IFGYVadZpqI3j8fhNrSdKCeYPxiAhLXw==} resolution: {integrity: sha512-Xd8lFX4LM9QEEwxQpF9J9NTUh8pmdJO0cyRJhFiDoLTk2eH8FXlRv2IFGYVadZpqI3j8fhNrSdKCeYPxiAhLXw==}
engines: {node: '>=18'} engines: {node: '>=18'}
cookiejar@2.1.4:
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
core-js@3.29.1: core-js@3.29.1:
resolution: {integrity: sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==} resolution: {integrity: sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==}
@ -5968,9 +5941,6 @@ packages:
devlop@1.1.0: devlop@1.1.0:
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
dezalgo@1.0.4:
resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
diff-match-patch@1.0.5: diff-match-patch@1.0.5:
resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==}
@ -6632,10 +6602,6 @@ packages:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'} engines: {node: '>=12.20.0'}
formidable@3.5.4:
resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==}
engines: {node: '>=14.0.0'}
forwarded-parse@2.1.2: forwarded-parse@2.1.2:
resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==}
@ -10049,14 +10015,6 @@ packages:
peerDependencies: peerDependencies:
postcss: ^8.4.31 postcss: ^8.4.31
superagent@9.0.2:
resolution: {integrity: sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==}
engines: {node: '>=14.18.0'}
supertest@7.1.0:
resolution: {integrity: sha512-5QeSO8hSrKghtcWEoPiO036fxH0Ii2wVQfFZSP0oqQhmjk8bOLhDFXr4JrvaFmPuEWUoq4znY3uSi8UzLKxGqw==}
engines: {node: '>=14.18.0'}
supports-color@5.5.0: supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -11570,7 +11528,7 @@ snapshots:
'@babel/traverse': 7.24.7 '@babel/traverse': 7.24.7
'@babel/types': 7.25.6 '@babel/types': 7.25.6
convert-source-map: 2.0.0 convert-source-map: 2.0.0
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
gensync: 1.0.0-beta.2 gensync: 1.0.0-beta.2
json5: 2.2.3 json5: 2.2.3
semver: 6.3.1 semver: 6.3.1
@ -11590,7 +11548,7 @@ snapshots:
'@babel/traverse': 7.24.7 '@babel/traverse': 7.24.7
'@babel/types': 7.25.6 '@babel/types': 7.25.6
convert-source-map: 2.0.0 convert-source-map: 2.0.0
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
gensync: 1.0.0-beta.2 gensync: 1.0.0-beta.2
json5: 2.2.3 json5: 2.2.3
semver: 6.3.1 semver: 6.3.1
@ -11812,7 +11770,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.24.7 '@babel/helper-split-export-declaration': 7.24.7
'@babel/parser': 7.25.6 '@babel/parser': 7.25.6
'@babel/types': 7.25.6 '@babel/types': 7.25.6
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
globals: 11.12.0 globals: 11.12.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -12148,7 +12106,7 @@ snapshots:
'@eslint/config-array@0.20.0': '@eslint/config-array@0.20.0':
dependencies: dependencies:
'@eslint/object-schema': 2.1.6 '@eslint/object-schema': 2.1.6
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
minimatch: 3.1.2 minimatch: 3.1.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -12162,7 +12120,7 @@ snapshots:
'@eslint/eslintrc@3.3.1': '@eslint/eslintrc@3.3.1':
dependencies: dependencies:
ajv: 6.12.6 ajv: 6.12.6
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
espree: 10.3.0 espree: 10.3.0
globals: 14.0.0 globals: 14.0.0
ignore: 5.3.1 ignore: 5.3.1
@ -13201,10 +13159,6 @@ snapshots:
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0)
'@paralleldrive/cuid2@2.2.2':
dependencies:
'@noble/hashes': 1.7.1
'@parcel/watcher-android-arm64@2.5.0': '@parcel/watcher-android-arm64@2.5.0':
optional: true optional: true
@ -14552,7 +14506,7 @@ snapshots:
'@tokenizer/inflate@0.2.7': '@tokenizer/inflate@0.2.7':
dependencies: dependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
fflate: 0.8.2 fflate: 0.8.2
token-types: 6.0.0 token-types: 6.0.0
transitivePeerDependencies: transitivePeerDependencies:
@ -14632,8 +14586,6 @@ snapshots:
'@types/cookie@0.6.0': {} '@types/cookie@0.6.0': {}
'@types/cookiejar@2.1.5': {}
'@types/debug@4.1.12': '@types/debug@4.1.12':
dependencies: dependencies:
'@types/ms': 0.7.34 '@types/ms': 0.7.34
@ -14727,8 +14679,6 @@ snapshots:
'@types/mdx@2.0.3': {} '@types/mdx@2.0.3': {}
'@types/methods@1.1.4': {}
'@types/micromatch@4.0.9': '@types/micromatch@4.0.9':
dependencies: dependencies:
'@types/braces': 3.0.1 '@types/braces': 3.0.1
@ -14864,18 +14814,6 @@ snapshots:
'@types/statuses@2.0.4': {} '@types/statuses@2.0.4': {}
'@types/superagent@8.1.9':
dependencies:
'@types/cookiejar': 2.1.5
'@types/methods': 1.1.4
'@types/node': 22.15.2
form-data: 4.0.2
'@types/supertest@6.0.3':
dependencies:
'@types/methods': 1.1.4
'@types/superagent': 8.1.9
'@types/tedious@4.0.14': '@types/tedious@4.0.14':
dependencies: dependencies:
'@types/node': 22.15.2 '@types/node': 22.15.2
@ -14940,7 +14878,7 @@ snapshots:
'@typescript-eslint/types': 8.31.0 '@typescript-eslint/types': 8.31.0
'@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3) '@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3)
'@typescript-eslint/visitor-keys': 8.31.0 '@typescript-eslint/visitor-keys': 8.31.0
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
eslint: 9.25.1 eslint: 9.25.1
typescript: 5.8.3 typescript: 5.8.3
transitivePeerDependencies: transitivePeerDependencies:
@ -14955,7 +14893,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3) '@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3)
'@typescript-eslint/utils': 8.31.0(eslint@9.25.1)(typescript@5.8.3) '@typescript-eslint/utils': 8.31.0(eslint@9.25.1)(typescript@5.8.3)
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
eslint: 9.25.1 eslint: 9.25.1
ts-api-utils: 2.1.0(typescript@5.8.3) ts-api-utils: 2.1.0(typescript@5.8.3)
typescript: 5.8.3 typescript: 5.8.3
@ -14968,7 +14906,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/types': 8.31.0 '@typescript-eslint/types': 8.31.0
'@typescript-eslint/visitor-keys': 8.31.0 '@typescript-eslint/visitor-keys': 8.31.0
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
fast-glob: 3.3.3 fast-glob: 3.3.3
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.5 minimatch: 9.0.5
@ -15005,7 +14943,7 @@ snapshots:
dependencies: dependencies:
'@ampproject/remapping': 2.3.0 '@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 1.0.2 '@bcoe/v8-coverage': 1.0.2
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2 istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1 istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 5.0.6 istanbul-lib-source-maps: 5.0.6
@ -15316,14 +15254,14 @@ snapshots:
agent-base@6.0.2: agent-base@6.0.2:
dependencies: dependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
optional: true optional: true
agent-base@7.1.0: agent-base@7.1.0:
dependencies: dependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -16160,8 +16098,6 @@ snapshots:
compare-versions@6.1.1: {} compare-versions@6.1.1: {}
component-emitter@1.3.1: {}
compress-commons@6.0.2: compress-commons@6.0.2:
dependencies: dependencies:
crc-32: 1.2.2 crc-32: 1.2.2
@ -16214,8 +16150,6 @@ snapshots:
cookie@1.0.1: {} cookie@1.0.1: {}
cookiejar@2.1.4: {}
core-js@3.29.1: {} core-js@3.29.1: {}
core-util-is@1.0.2: {} core-util-is@1.0.2: {}
@ -16598,11 +16532,6 @@ snapshots:
dependencies: dependencies:
dequal: 2.0.3 dequal: 2.0.3
dezalgo@1.0.4:
dependencies:
asap: 2.0.6
wrappy: 1.0.2
diff-match-patch@1.0.5: {} diff-match-patch@1.0.5: {}
diff-sequences@29.6.3: {} diff-sequences@29.6.3: {}
@ -16905,7 +16834,7 @@ snapshots:
esbuild-register@3.5.0(esbuild@0.25.3): esbuild-register@3.5.0(esbuild@0.25.3):
dependencies: dependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
esbuild: 0.25.3 esbuild: 0.25.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -17082,7 +17011,7 @@ snapshots:
ajv: 6.12.6 ajv: 6.12.6
chalk: 4.1.2 chalk: 4.1.2
cross-spawn: 7.0.6 cross-spawn: 7.0.6
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
escape-string-regexp: 4.0.0 escape-string-regexp: 4.0.0
eslint-scope: 8.3.0 eslint-scope: 8.3.0
eslint-visitor-keys: 4.2.0 eslint-visitor-keys: 4.2.0
@ -17533,7 +17462,7 @@ snapshots:
follow-redirects@1.15.9(debug@4.4.0): follow-redirects@1.15.9(debug@4.4.0):
optionalDependencies: optionalDependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
for-each@0.3.3: for-each@0.3.3:
dependencies: dependencies:
@ -17561,12 +17490,6 @@ snapshots:
dependencies: dependencies:
fetch-blob: 3.2.0 fetch-blob: 3.2.0
formidable@3.5.4:
dependencies:
'@paralleldrive/cuid2': 2.2.2
dezalgo: 1.0.4
once: 1.4.0
forwarded-parse@2.1.2: {} forwarded-parse@2.1.2: {}
forwarded@0.2.0: {} forwarded@0.2.0: {}
@ -17981,7 +17904,7 @@ snapshots:
http-proxy-agent@7.0.2: http-proxy-agent@7.0.2:
dependencies: dependencies:
agent-base: 7.1.3 agent-base: 7.1.3
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -18009,7 +17932,7 @@ snapshots:
https-proxy-agent@5.0.1: https-proxy-agent@5.0.1:
dependencies: dependencies:
agent-base: 6.0.2 agent-base: 6.0.2
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
optional: true optional: true
@ -18017,14 +17940,14 @@ snapshots:
https-proxy-agent@7.0.2: https-proxy-agent@7.0.2:
dependencies: dependencies:
agent-base: 7.1.0 agent-base: 7.1.0
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
https-proxy-agent@7.0.6: https-proxy-agent@7.0.6:
dependencies: dependencies:
agent-base: 7.1.3 agent-base: 7.1.3
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -18122,7 +18045,7 @@ snapshots:
dependencies: dependencies:
'@ioredis/commands': 1.2.0 '@ioredis/commands': 1.2.0
cluster-key-slot: 1.1.2 cluster-key-slot: 1.1.2
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
denque: 2.1.0 denque: 2.1.0
lodash.defaults: 4.2.0 lodash.defaults: 4.2.0
lodash.isarguments: 3.1.0 lodash.isarguments: 3.1.0
@ -18356,7 +18279,7 @@ snapshots:
istanbul-lib-source-maps@4.0.1: istanbul-lib-source-maps@4.0.1:
dependencies: dependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2 istanbul-lib-coverage: 3.2.2
source-map: 0.6.1 source-map: 0.6.1
transitivePeerDependencies: transitivePeerDependencies:
@ -18365,7 +18288,7 @@ snapshots:
istanbul-lib-source-maps@5.0.6: istanbul-lib-source-maps@5.0.6:
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.25 '@jridgewell/trace-mapping': 0.3.25
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2 istanbul-lib-coverage: 3.2.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -19389,7 +19312,7 @@ snapshots:
micromark@4.0.0: micromark@4.0.0:
dependencies: dependencies:
'@types/debug': 4.1.12 '@types/debug': 4.1.12
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
decode-named-character-reference: 1.0.2 decode-named-character-reference: 1.0.2
devlop: 1.1.0 devlop: 1.1.0
micromark-core-commonmark: 2.0.0 micromark-core-commonmark: 2.0.0
@ -20794,7 +20717,7 @@ snapshots:
require-in-the-middle@7.3.0: require-in-the-middle@7.3.0:
dependencies: dependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
module-details-from-path: 1.0.3 module-details-from-path: 1.0.3
resolve: 1.22.8 resolve: 1.22.8
transitivePeerDependencies: transitivePeerDependencies:
@ -21244,7 +21167,7 @@ snapshots:
socks-proxy-agent@8.0.2: socks-proxy-agent@8.0.2:
dependencies: dependencies:
agent-base: 7.1.3 agent-base: 7.1.3
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
socks: 2.7.1 socks: 2.7.1
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -21353,7 +21276,7 @@ snapshots:
arg: 5.0.2 arg: 5.0.2
bluebird: 3.7.2 bluebird: 3.7.2
check-more-types: 2.24.0 check-more-types: 2.24.0
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
execa: 5.1.1 execa: 5.1.1
lazy-ass: 1.6.0 lazy-ass: 1.6.0
ps-tree: 1.2.0 ps-tree: 1.2.0
@ -21545,27 +21468,6 @@ snapshots:
postcss: 8.5.3 postcss: 8.5.3
postcss-selector-parser: 6.1.2 postcss-selector-parser: 6.1.2
superagent@9.0.2:
dependencies:
component-emitter: 1.3.1
cookiejar: 2.1.4
debug: 4.4.0(supports-color@8.1.1)
fast-safe-stringify: 2.1.1
form-data: 4.0.2
formidable: 3.5.4
methods: 1.1.2
mime: 2.6.0
qs: 6.14.0
transitivePeerDependencies:
- supports-color
supertest@7.1.0:
dependencies:
methods: 1.1.2
superagent: 9.0.2
transitivePeerDependencies:
- supports-color
supports-color@5.5.0: supports-color@5.5.0:
dependencies: dependencies:
has-flag: 3.0.0 has-flag: 3.0.0
@ -21923,7 +21825,7 @@ snapshots:
app-root-path: 3.1.0 app-root-path: 3.1.0
buffer: 6.0.3 buffer: 6.0.3
dayjs: 1.11.13 dayjs: 1.11.13
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
dotenv: 16.4.7 dotenv: 16.4.7
glob: 10.4.5 glob: 10.4.5
reflect-metadata: 0.2.2 reflect-metadata: 0.2.2
@ -22117,7 +22019,7 @@ snapshots:
vite-node@3.1.2(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3): vite-node@3.1.2(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3):
dependencies: dependencies:
cac: 6.7.14 cac: 6.7.14
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
es-module-lexer: 1.6.0 es-module-lexer: 1.6.0
pathe: 2.0.3 pathe: 2.0.3
vite: 6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) vite: 6.3.3(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)
@ -22166,7 +22068,7 @@ snapshots:
'@vitest/spy': 3.1.2 '@vitest/spy': 3.1.2
'@vitest/utils': 3.1.2 '@vitest/utils': 3.1.2
chai: 5.2.0 chai: 5.2.0
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
expect-type: 1.2.1 expect-type: 1.2.1
magic-string: 0.30.17 magic-string: 0.30.17
pathe: 2.0.3 pathe: 2.0.3
@ -22253,7 +22155,7 @@ snapshots:
vue-eslint-parser@10.1.3(eslint@9.25.1): vue-eslint-parser@10.1.3(eslint@9.25.1):
dependencies: dependencies:
debug: 4.4.0(supports-color@8.1.1) debug: 4.4.0(supports-color@5.5.0)
eslint: 9.25.1 eslint: 9.25.1
eslint-scope: 8.3.0 eslint-scope: 8.3.0
eslint-visitor-keys: 4.2.0 eslint-visitor-keys: 4.2.0