fix: lint & test

This commit is contained in:
DarkSky
2026-02-03 18:11:43 +08:00
parent ae26418281
commit 18b8c7831f
21 changed files with 108 additions and 198 deletions

View File

@@ -832,8 +832,8 @@
},
"versionControl.requiredVersion": {
"type": "string",
"description": "Allowed version range of the app that allowed to access the server. Requires 'client/versionControl.enabled' to be true to take effect.\n@default \">=0.20.0\"",
"default": ">=0.20.0"
"description": "Allowed version range of the app that allowed to access the server. Requires 'client/versionControl.enabled' to be true to take effect.\n@default \">=0.25.0\"",
"default": ">=0.25.0"
}
}
},

View File

@@ -32,6 +32,16 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 4
{
code: 'Bad Request',
message: 'Invalid header',
name: 'BAD_REQUEST',
status: 400,
type: 'BAD_REQUEST',
}
> Snapshot 5
Buffer @Uint8Array [
66616b65 20696d61 6765
]
@@ -56,7 +66,7 @@ Generated by [AVA](https://avajs.dev).
{
code: 'Bad Request',
message: 'Invalid URL',
message: 'Invalid header',
name: 'BAD_REQUEST',
status: 400,
type: 'BAD_REQUEST',
@@ -64,6 +74,16 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 4
{
code: 'Bad Request',
message: 'Invalid URL',
name: 'BAD_REQUEST',
status: 400,
type: 'BAD_REQUEST',
}
> Snapshot 5
{
description: 'Test Description',
favicons: [
@@ -77,7 +97,7 @@ Generated by [AVA](https://avajs.dev).
videos: [],
}
> Snapshot 5
> Snapshot 6
{
charset: 'gbk',
@@ -90,7 +110,7 @@ Generated by [AVA](https://avajs.dev).
videos: [],
}
> Snapshot 6
> Snapshot 7
{
charset: 'shift_jis',
@@ -103,7 +123,7 @@ Generated by [AVA](https://avajs.dev).
videos: [],
}
> Snapshot 7
> Snapshot 8
{
charset: 'big5',
@@ -116,7 +136,7 @@ Generated by [AVA](https://avajs.dev).
videos: [],
}
> Snapshot 8
> Snapshot 9
{
charset: 'euc-kr',

View File

@@ -922,7 +922,6 @@ test('should be able to manage context', async t => {
const { id: fileId } = await addContextFile(
app,
contextId,
'fileId1',
'sample.pdf',
buffer
);

View File

@@ -39,31 +39,7 @@ Generated by [AVA](https://avajs.dev).
},
}
## should not return apple oauth provider when client version is not specified
> Snapshot 1
{
serverConfig: {
oauthProviders: [
'Google',
],
},
}
## should not return apple oauth provider in version < 0.22.0
> Snapshot 1
{
serverConfig: {
oauthProviders: [
'Google',
],
},
}
## should not return apple oauth provider when client version format is not correct
## should return apple oauth provider when client version is not specified
> Snapshot 1
@@ -71,6 +47,7 @@ Generated by [AVA](https://avajs.dev).
serverConfig: {
oauthProviders: [
'Google',
'Apple',
],
},
}

View File

@@ -71,7 +71,7 @@ e2e('should return apple oauth provider in version >= 0.22.0', async t => {
});
e2e(
'should not return apple oauth provider when client version is not specified',
'should return apple oauth provider when client version is not specified',
async t => {
const res = await app.gql({
query: oauthProvidersQuery,
@@ -80,32 +80,3 @@ e2e(
t.snapshot(res);
}
);
e2e('should not return apple oauth provider in version < 0.22.0', async t => {
const res = await app.gql({
query: oauthProvidersQuery,
context: {
headers: {
'x-affine-version': '0.21.0',
},
},
});
t.snapshot(res);
});
e2e(
'should not return apple oauth provider when client version format is not correct',
async t => {
const res = await app.gql({
query: oauthProvidersQuery,
context: {
headers: {
'x-affine-version': 'mock-invalid-version',
},
},
});
t.snapshot(res);
}
);

View File

@@ -194,7 +194,7 @@ test('should throw if provider is invalid', async t => {
await app
.POST('/api/oauth/preflight')
.send({ provider: 'Invalid' })
.send({ provider: 'Invalid', client_nonce: 'test-nonce' })
.expect(HttpStatus.BAD_REQUEST)
.expect({
status: 400,

View File

@@ -250,7 +250,6 @@ export async function listContext(
export async function addContextFile(
app: TestingApp,
contextId: string,
blobId: string,
fileName: string,
content: Buffer
): Promise<{ id: string }> {
@@ -269,7 +268,7 @@ export async function addContextFile(
`,
variables: {
content: null,
options: { contextId, blobId },
options: { contextId },
},
})
)

View File

@@ -1,10 +1,14 @@
import * as dns from 'node:dns/promises';
import type { ExecutionContext, TestFn } from 'ava';
import ava from 'ava';
import { LookupAddress } from 'dns';
import Sinon from 'sinon';
import type { Response } from 'supertest';
import {
__resetDnsLookupForTests,
__setDnsLookupForTests,
type DnsLookup,
} from '../base/utils/ssrf';
import { createTestingApp, TestingApp } from './utils';
type TestContext = {
@@ -13,24 +17,21 @@ type TestContext = {
const test = ava as TestFn<TestContext>;
const LookupAddressStub = (async (_hostname, options) => {
const result = [{ address: '76.76.21.21', family: 4 }] as LookupAddress[];
const isOptions = options && typeof options === 'object';
if (isOptions && 'all' in options && options.all) {
return result;
}
return result[0];
}) as DnsLookup;
test.before(async t => {
// @ts-expect-error test
env.DEPLOYMENT_TYPE = 'selfhosted';
// Avoid relying on real DNS during tests. SSRF protection uses dns.lookup().
Sinon.stub(dns, 'lookup').callsFake(async (...args: any[]) => {
const options = args[1];
const result = [{ address: '93.184.216.34', family: 4 }];
if (
options &&
typeof options === 'object' &&
'all' in options &&
options.all
) {
return result as any;
}
return result[0] as any;
});
__setDnsLookupForTests(LookupAddressStub);
const app = await createTestingApp();
@@ -39,6 +40,7 @@ test.before(async t => {
test.after.always(async t => {
Sinon.restore();
__resetDnsLookupForTests();
await t.context.app.close();
});
@@ -57,7 +59,7 @@ const assertAndSnapshotRaw = async (
) => {
const {
status = 200,
origin = 'http://localhost',
origin = 'http://localhost:3010',
referer,
method = 'GET',
checker = () => {},

View File

@@ -9,6 +9,17 @@ const DEFAULT_ALLOWED_PROTOCOLS = new Set(['http:', 'https:']);
const BLOCKED_IPS = new BlockList();
const ALLOWED_IPV6 = new BlockList();
export type DnsLookup = typeof dns.lookup;
let dnsLookup: DnsLookup = dns.lookup;
export function __setDnsLookupForTests(lookup: DnsLookup) {
dnsLookup = lookup;
}
export function __resetDnsLookupForTests() {
dnsLookup = dns.lookup;
}
export type SSRFBlockReason =
| 'invalid_url'
| 'disallowed_protocol'
@@ -112,7 +123,7 @@ async function resolveHostAddresses(hostname: string): Promise<string[]> {
return ['127.0.0.1', '::1'];
}
const results = await dns.lookup(hostname, {
const results = await dnsLookup(hostname, {
all: true,
verbatim: true,
});

View File

@@ -63,7 +63,6 @@ export interface AddContextDocInput {
}
export interface AddContextFileInput {
blobId?: InputMaybe<Scalars['String']['input']>;
contextId: Scalars['String']['input'];
}
@@ -978,12 +977,14 @@ export type ErrorDataUnion =
| NoMoreSeatDataType
| NotInSpaceDataType
| QueryTooLongDataType
| ResponseTooLargeErrorDataType
| RuntimeConfigNotFoundDataType
| SameSubscriptionRecurringDataType
| SpaceAccessDeniedDataType
| SpaceNotFoundDataType
| SpaceOwnerNotFoundDataType
| SpaceShouldHaveOnlyOneOwnerDataType
| SsrfBlockedErrorDataType
| SubscriptionAlreadyExistsDataType
| SubscriptionNotExistsDataType
| SubscriptionPlanNotFoundDataType
@@ -1107,6 +1108,7 @@ export enum ErrorNames {
PASSWORD_REQUIRED = 'PASSWORD_REQUIRED',
QUERY_TOO_LONG = 'QUERY_TOO_LONG',
REPLY_NOT_FOUND = 'REPLY_NOT_FOUND',
RESPONSE_TOO_LARGE_ERROR = 'RESPONSE_TOO_LARGE_ERROR',
RUNTIME_CONFIG_NOT_FOUND = 'RUNTIME_CONFIG_NOT_FOUND',
SAME_EMAIL_PROVIDED = 'SAME_EMAIL_PROVIDED',
SAME_SUBSCRIPTION_RECURRING = 'SAME_SUBSCRIPTION_RECURRING',
@@ -1116,6 +1118,7 @@ export enum ErrorNames {
SPACE_NOT_FOUND = 'SPACE_NOT_FOUND',
SPACE_OWNER_NOT_FOUND = 'SPACE_OWNER_NOT_FOUND',
SPACE_SHOULD_HAVE_ONLY_ONE_OWNER = 'SPACE_SHOULD_HAVE_ONLY_ONE_OWNER',
SSRF_BLOCKED_ERROR = 'SSRF_BLOCKED_ERROR',
STORAGE_QUOTA_EXCEEDED = 'STORAGE_QUOTA_EXCEEDED',
SUBSCRIPTION_ALREADY_EXISTS = 'SUBSCRIPTION_ALREADY_EXISTS',
SUBSCRIPTION_EXPIRED = 'SUBSCRIPTION_EXPIRED',
@@ -1622,23 +1625,17 @@ export interface Mutation {
forkCopilotSession: Scalars['String']['output'];
generateLicenseKey: Scalars['String']['output'];
generateUserAccessToken: RevealedAccessToken;
/** @deprecated use WorkspaceType.blobUploadPartUrl */
getBlobUploadPartUrl: BlobUploadPart;
grantDocUserRoles: Scalars['Boolean']['output'];
grantMember: Scalars['Boolean']['output'];
/** import users */
importUsers: Array<UserImportResultType>;
installLicense: License;
/** @deprecated use [inviteMembers] instead */
inviteBatch: Array<InviteResult>;
inviteMembers: Array<InviteResult>;
leaveWorkspace: Scalars['Boolean']['output'];
linkCalendarAccount: Scalars['String']['output'];
/** mention user in a doc */
mentionUser: Scalars['ID']['output'];
publishDoc: DocType;
/** @deprecated use publishDoc instead */
publishPage: DocType;
/** queue workspace doc embedding */
queueWorkspaceEmbedding: Scalars['Boolean']['output'];
/** mark all notifications as read */
@@ -1668,14 +1665,10 @@ export interface Mutation {
resolveComment: Scalars['Boolean']['output'];
resumeSubscription: SubscriptionType;
retryAudioTranscription: Maybe<TranscriptionResultType>;
/** @deprecated use [revokeMember] instead */
revoke: Scalars['Boolean']['output'];
revokeDocUserRoles: Scalars['Boolean']['output'];
revokeInviteLink: Scalars['Boolean']['output'];
revokeMember: Scalars['Boolean']['output'];
revokePublicDoc: DocType;
/** @deprecated use revokePublicDoc instead */
revokePublicPage: DocType;
revokeUserAccessToken: Scalars['Boolean']['output'];
sendChangeEmail: Scalars['Boolean']['output'];
sendChangePasswordEmail: Scalars['Boolean']['output'];
@@ -1720,11 +1713,6 @@ export interface Mutation {
uploadAvatar: UserType;
/** Upload a comment attachment and return the access url */
uploadCommentAttachment: Scalars['String']['output'];
/**
* validate app configuration
* @deprecated use Query.validateAppConfig
*/
validateAppConfig: Array<AppConfigValidateResult>;
verifyEmail: Scalars['Boolean']['output'];
}
@@ -1925,13 +1913,6 @@ export interface MutationGenerateUserAccessTokenArgs {
input: GenerateAccessTokenInput;
}
export interface MutationGetBlobUploadPartUrlArgs {
key: Scalars['String']['input'];
partNumber: Scalars['Int']['input'];
uploadId: Scalars['String']['input'];
workspaceId: Scalars['String']['input'];
}
export interface MutationGrantDocUserRolesArgs {
input: GrantDocUserRolesInput;
}
@@ -1951,12 +1932,6 @@ export interface MutationInstallLicenseArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationInviteBatchArgs {
emails: Array<Scalars['String']['input']>;
sendInviteMail?: InputMaybe<Scalars['Boolean']['input']>;
workspaceId: Scalars['String']['input'];
}
export interface MutationInviteMembersArgs {
emails: Array<Scalars['String']['input']>;
workspaceId: Scalars['String']['input'];
@@ -1982,12 +1957,6 @@ export interface MutationPublishDocArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationPublishPageArgs {
mode?: InputMaybe<PublicDocMode>;
pageId: Scalars['String']['input'];
workspaceId: Scalars['String']['input'];
}
export interface MutationQueueWorkspaceEmbeddingArgs {
docId: Array<Scalars['String']['input']>;
workspaceId: Scalars['String']['input'];
@@ -2052,11 +2021,6 @@ export interface MutationRetryAudioTranscriptionArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationRevokeArgs {
userId: Scalars['String']['input'];
workspaceId: Scalars['String']['input'];
}
export interface MutationRevokeDocUserRolesArgs {
input: RevokeDocUserRoleInput;
}
@@ -2075,11 +2039,6 @@ export interface MutationRevokePublicDocArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationRevokePublicPageArgs {
docId: Scalars['String']['input'];
workspaceId: Scalars['String']['input'];
}
export interface MutationRevokeUserAccessTokenArgs {
id: Scalars['String']['input'];
}
@@ -2212,10 +2171,6 @@ export interface MutationUploadCommentAttachmentArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationValidateAppConfigArgs {
updates: Array<UpdateAppConfigInput>;
}
export interface MutationVerifyEmailArgs {
token: Scalars['String']['input'];
}
@@ -2401,8 +2356,6 @@ export interface PublicUserType {
export interface Query {
__typename?: 'Query';
/** @deprecated use currentUser.accessTokens */
accessTokens: Array<AccessToken>;
/** Get workspace detail for admin */
adminWorkspace: Maybe<AdminWorkspace>;
/** List workspaces for admin */
@@ -2416,23 +2369,11 @@ export interface Query {
* @deprecated use Mutation.applyDocUpdates
*/
applyDocUpdates: Scalars['String']['output'];
/** @deprecated use `user.quotaUsage` instead */
collectAllBlobSizes: WorkspaceBlobSizes;
/** Get current user */
currentUser: Maybe<UserType>;
error: ErrorDataUnion;
/** get workspace invitation info */
getInviteInfo: InvitationType;
/**
* Get is admin of workspace
* @deprecated use WorkspaceType[role] instead
*/
isAdmin: Scalars['Boolean']['output'];
/**
* Get is owner of workspace
* @deprecated use WorkspaceType[role] instead
*/
isOwner: Scalars['Boolean']['output'];
/** List all copilot prompts */
listCopilotPrompts: Array<CopilotPromptType>;
prices: Array<SubscriptionPrice>;
@@ -2494,14 +2435,6 @@ export interface QueryGetInviteInfoArgs {
inviteId: Scalars['String']['input'];
}
export interface QueryIsAdminArgs {
workspaceId: Scalars['String']['input'];
}
export interface QueryIsOwnerArgs {
workspaceId: Scalars['String']['input'];
}
export interface QueryPublicUserByIdArgs {
id: Scalars['String']['input'];
}
@@ -2630,6 +2563,12 @@ export interface ReplyUpdateInput {
id: Scalars['ID']['input'];
}
export interface ResponseTooLargeErrorDataType {
__typename?: 'ResponseTooLargeErrorDataType';
limitBytes: Scalars['Int']['output'];
receivedBytes: Scalars['Int']['output'];
}
export interface RevealedAccessToken {
__typename?: 'RevealedAccessToken';
createdAt: Scalars['DateTime']['output'];
@@ -2812,6 +2751,11 @@ export interface SpaceShouldHaveOnlyOneOwnerDataType {
spaceId: Scalars['String']['output'];
}
export interface SsrfBlockedErrorDataType {
__typename?: 'SsrfBlockedErrorDataType';
reason: Scalars['String']['output'];
}
export interface StreamObject {
__typename?: 'StreamObject';
args: Maybe<Scalars['JSON']['output']>;
@@ -3126,11 +3070,6 @@ export interface VersionRejectedDataType {
version: Scalars['String']['output'];
}
export interface WorkspaceBlobSizes {
__typename?: 'WorkspaceBlobSizes';
size: Scalars['SafeInt']['output'];
}
export interface WorkspaceCalendarItemInput {
colorOverride?: InputMaybe<Scalars['String']['input']>;
sortOrder?: InputMaybe<Scalars['Int']['input']>;
@@ -3308,11 +3247,6 @@ export interface WorkspaceType {
public: Scalars['Boolean']['output'];
/** Get public docs of a workspace */
publicDocs: Array<DocType>;
/**
* Get public page of a workspace by page id.
* @deprecated use [WorkspaceType.doc] instead
*/
publicPage: Maybe<DocType>;
/** quota of workspace */
quota: WorkspaceQuotaType;
/** Get recently updated docs of a workspace */
@@ -3378,10 +3312,6 @@ export interface WorkspaceTypePageMetaArgs {
pageId: Scalars['String']['input'];
}
export interface WorkspaceTypePublicPageArgs {
pageId: Scalars['String']['input'];
}
export interface WorkspaceTypeRecentlyUpdatedDocsArgs {
pagination: PaginationInput;
}

View File

@@ -26,7 +26,7 @@
"lodash-es": "^4.17.21",
"nanoid": "^5.1.6",
"rxjs": "^7.8.2",
"uuid": "^11.1.0",
"uuid": "^13.0.0",
"y-protocols": "^1.0.6",
"yjs": "^13.6.27"
},
@@ -36,7 +36,7 @@
"@blocksuite/affine": "workspace:*",
"fake-indexeddb": "^6.0.0",
"idb": "^8.0.0",
"socket.io-client": "^4.8.1",
"socket.io-client": "^4.8.3",
"vitest": "^3.2.4"
},
"peerDependencies": {
@@ -44,6 +44,6 @@
"@affine/graphql": "workspace:*",
"@blocksuite/affine": "workspace:*",
"idb": "^8.0.0",
"socket.io-client": "^4.7.5"
"socket.io-client": "^4.8.3"
}
}

View File

@@ -26,7 +26,7 @@
"react": "^19.2.1",
"react-dom": "^19.2.1",
"react-router-dom": "^6.30.3",
"uuid": "^11.1.0",
"uuid": "^13.0.0",
"webm-muxer": "^5.0.3"
},
"devDependencies": {

View File

@@ -73,7 +73,7 @@
"semver": "^7.7.3",
"tree-kill": "^1.2.2",
"ts-node": "^10.9.2",
"uuid": "^11.1.0",
"uuid": "^13.0.0",
"vitest": "^3.2.4",
"zod": "^3.25.76"
},

View File

@@ -91,7 +91,7 @@
"semver": "^7.7.3",
"ses": "^1.14.0",
"shiki": "^3.19.0",
"socket.io-client": "^4.8.1",
"socket.io-client": "^4.8.3",
"swr": "^2.3.7",
"tinykeys": "patch:tinykeys@npm%3A2.1.0#~/.yarn/patches/tinykeys-npm-2.1.0-819feeaed0.patch",
"y-protocols": "^1.0.6",

View File

@@ -9,16 +9,16 @@
"es-CL": 99,
"es": 98,
"fa": 98,
"fr": 100,
"fr": 99,
"hi": 2,
"it-IT": 100,
"it-IT": 99,
"it": 1,
"ja": 98,
"ko": 99,
"nb-NO": 48,
"pl": 100,
"pt-BR": 98,
"ru": 100,
"ru": 99,
"sv-SE": 98,
"uk": 98,
"ur": 2,

View File

@@ -8504,6 +8504,17 @@ export function useAFFiNEI18N(): {
["error.HTTP_REQUEST_ERROR"](options: {
readonly message: string;
}): string;
/**
* `Invalid URL`
*/
["error.SSRF_BLOCKED_ERROR"](): string;
/**
* `Response too large ({{receivedBytes}} bytes), limit is {{limitBytes}} bytes`
*/
["error.RESPONSE_TOO_LARGE_ERROR"](options: Readonly<{
receivedBytes: string;
limitBytes: string;
}>): string;
/**
* `Email service is not configured.`
*/

View File

@@ -2131,6 +2131,8 @@
"error.BAD_REQUEST": "Bad request.",
"error.GRAPHQL_BAD_REQUEST": "GraphQL bad request, code: {{code}}, {{message}}",
"error.HTTP_REQUEST_ERROR": "HTTP request error, message: {{message}}",
"error.SSRF_BLOCKED_ERROR": "Invalid URL",
"error.RESPONSE_TOO_LARGE_ERROR": "Response too large ({{receivedBytes}} bytes), limit is {{limitBytes}} bytes",
"error.EMAIL_SERVICE_NOT_CONFIGURED": "Email service is not configured.",
"error.QUERY_TOO_LONG": "Query is too long, max length is {{max}}.",
"error.VALIDATION_ERROR": "Validation error, errors: {{errors}}",

View File

@@ -27,7 +27,7 @@
"react-dom": "^19.2.1",
"react-markdown": "^10.1.0",
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.4",
"socket.io-client": "^4.8.3",
"swr": "^2.3.7",
"tailwindcss": "^4.1.17",
"tsx": "^4.19.2",

View File

@@ -485,7 +485,7 @@ __metadata:
semver: "npm:^7.7.3"
ses: "npm:^1.14.0"
shiki: "npm:^3.19.0"
socket.io-client: "npm:^4.8.1"
socket.io-client: "npm:^4.8.3"
swr: "npm:^2.3.7"
tinykeys: "patch:tinykeys@npm%3A2.1.0#~/.yarn/patches/tinykeys-npm-2.1.0-819feeaed0.patch"
vitest: "npm:^3.2.4"
@@ -562,7 +562,7 @@ __metadata:
react-dom: "npm:^19.2.1"
react-router-dom: "npm:^6.30.3"
typescript: "npm:^5.7.2"
uuid: "npm:^11.1.0"
uuid: "npm:^13.0.0"
webm-muxer: "npm:^5.0.3"
languageName: unknown
linkType: soft
@@ -617,7 +617,7 @@ __metadata:
set-cookie-parser: "npm:^2.7.1"
tree-kill: "npm:^1.2.2"
ts-node: "npm:^10.9.2"
uuid: "npm:^11.1.0"
uuid: "npm:^13.0.0"
vitest: "npm:^3.2.4"
yjs: "npm:^13.6.27"
zod: "npm:^3.25.76"
@@ -750,7 +750,7 @@ __metadata:
react-dom: "npm:^19.2.1"
react-markdown: "npm:^10.1.0"
socket.io: "npm:^4.7.4"
socket.io-client: "npm:^4.7.4"
socket.io-client: "npm:^4.8.3"
swr: "npm:^2.3.7"
tailwindcss: "npm:^4.1.17"
tsx: "npm:^4.19.2"
@@ -861,8 +861,8 @@ __metadata:
lodash-es: "npm:^4.17.21"
nanoid: "npm:^5.1.6"
rxjs: "npm:^7.8.2"
socket.io-client: "npm:^4.8.1"
uuid: "npm:^11.1.0"
socket.io-client: "npm:^4.8.3"
uuid: "npm:^13.0.0"
vitest: "npm:^3.2.4"
y-protocols: "npm:^1.0.6"
yjs: "npm:^13.6.27"
@@ -871,7 +871,7 @@ __metadata:
"@affine/graphql": "workspace:*"
"@blocksuite/affine": "workspace:*"
idb: ^8.0.0
socket.io-client: ^4.7.5
socket.io-client: ^4.8.3
languageName: unknown
linkType: soft
@@ -34564,18 +34564,6 @@ __metadata:
languageName: node
linkType: hard
"socket.io-client@npm:^4.7.4, socket.io-client@npm:^4.8.1":
version: 4.8.1
resolution: "socket.io-client@npm:4.8.1"
dependencies:
"@socket.io/component-emitter": "npm:~3.1.0"
debug: "npm:~4.3.2"
engine.io-client: "npm:~6.6.1"
socket.io-parser: "npm:~4.2.4"
checksum: 10/7480cf1ab30eba371a96dd1ce2ce9018dcbeaf81035a066fb89d99df0d0a6388b05840c92d970317c739956b68b28b0f4833f3b18e460a24eef557b9bca127c1
languageName: node
linkType: hard
"socket.io-client@npm:^4.8.3":
version: 4.8.3
resolution: "socket.io-client@npm:4.8.3"
@@ -36866,7 +36854,7 @@ __metadata:
languageName: node
linkType: hard
"uuid@npm:*":
"uuid@npm:*, uuid@npm:^13.0.0":
version: 13.0.0
resolution: "uuid@npm:13.0.0"
bin: