mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-20 15:57:06 +08:00
fix(server): convert 4xx status HttpError to UserFriendlyError (#10956)
This commit is contained in:
@@ -80,6 +80,7 @@
|
|||||||
"graphql-upload": "^17.0.0",
|
"graphql-upload": "^17.0.0",
|
||||||
"html-validate": "^9.0.0",
|
"html-validate": "^9.0.0",
|
||||||
"htmlrewriter": "^0.0.12",
|
"htmlrewriter": "^0.0.12",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"is-mobile": "^5.0.0",
|
"is-mobile": "^5.0.0",
|
||||||
"keyv": "^5.2.2",
|
"keyv": "^5.2.2",
|
||||||
@@ -120,6 +121,7 @@
|
|||||||
"@types/cookie-parser": "^1.4.8",
|
"@types/cookie-parser": "^1.4.8",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/graphql-upload": "^17.0.0",
|
"@types/graphql-upload": "^17.0.0",
|
||||||
|
"@types/http-errors": "^2.0.4",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/mixpanel": "^2.14.9",
|
"@types/mixpanel": "^2.14.9",
|
||||||
"@types/mustache": "^4.2.5",
|
"@types/mustache": "^4.2.5",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { type Blob } from '@prisma/client';
|
import { type Blob } from '@prisma/client';
|
||||||
|
|
||||||
import { TestingApp } from './testing-app';
|
import { TestingApp } from './testing-app';
|
||||||
|
import { TEST_LOG_LEVEL } from './utils';
|
||||||
|
|
||||||
export async function listBlobs(
|
export async function listBlobs(
|
||||||
app: TestingApp,
|
app: TestingApp,
|
||||||
@@ -73,5 +74,13 @@ export async function setBlob(
|
|||||||
`blob-${Math.random().toString(16).substring(2, 10)}.data`
|
`blob-${Math.random().toString(16).substring(2, 10)}.data`
|
||||||
)
|
)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
|
if (res.body.errors?.length) {
|
||||||
|
if (TEST_LOG_LEVEL !== 'fatal') {
|
||||||
|
// print the error stack when log level is not fatal, for better debugging
|
||||||
|
console.error('%o', res.body);
|
||||||
|
}
|
||||||
|
throw new Error(res.body.errors[0].message);
|
||||||
|
}
|
||||||
return res.body.data.setBlob;
|
return res.body.data.setBlob;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,3 +169,15 @@ test('should accept blob even storage out of quota if workspace has unlimited fe
|
|||||||
await t.notThrowsAsync(setBlob(app, workspace.id, buffer));
|
await t.notThrowsAsync(setBlob(app, workspace.id, buffer));
|
||||||
await t.notThrowsAsync(setBlob(app, workspace.id, buffer));
|
await t.notThrowsAsync(setBlob(app, workspace.id, buffer));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should throw error when blob size large than max file size', async t => {
|
||||||
|
await app.signup();
|
||||||
|
|
||||||
|
const workspace = await createWorkspace(app);
|
||||||
|
|
||||||
|
const buffer = Buffer.from(new Uint8Array(1024 * 1024 * 11));
|
||||||
|
await t.throwsAsync(setBlob(app, workspace.id, buffer), {
|
||||||
|
message:
|
||||||
|
'HTTP request error, message: File truncated as it exceeds the 10485760 byte size limit.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -264,6 +264,11 @@ export const USER_FRIENDLY_ERRORS = {
|
|||||||
message: ({ code, message }) =>
|
message: ({ code, message }) =>
|
||||||
`GraphQL bad request, code: ${code}, ${message}`,
|
`GraphQL bad request, code: ${code}, ${message}`,
|
||||||
},
|
},
|
||||||
|
http_request_error: {
|
||||||
|
type: 'bad_request',
|
||||||
|
args: { message: 'string' },
|
||||||
|
message: ({ message }) => `HTTP request error, message: ${message}`,
|
||||||
|
},
|
||||||
|
|
||||||
// Input errors
|
// Input errors
|
||||||
query_too_long: {
|
query_too_long: {
|
||||||
|
|||||||
@@ -45,6 +45,16 @@ export class GraphqlBadRequest extends UserFriendlyError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
|
class HttpRequestErrorDataType {
|
||||||
|
@Field() message!: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HttpRequestError extends UserFriendlyError {
|
||||||
|
constructor(args: HttpRequestErrorDataType, message?: string | ((args: HttpRequestErrorDataType) => string)) {
|
||||||
|
super('bad_request', 'http_request_error', message, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ObjectType()
|
||||||
class QueryTooLongDataType {
|
class QueryTooLongDataType {
|
||||||
@Field() max!: number
|
@Field() max!: number
|
||||||
}
|
}
|
||||||
@@ -896,6 +906,7 @@ export enum ErrorNames {
|
|||||||
NOT_FOUND,
|
NOT_FOUND,
|
||||||
BAD_REQUEST,
|
BAD_REQUEST,
|
||||||
GRAPHQL_BAD_REQUEST,
|
GRAPHQL_BAD_REQUEST,
|
||||||
|
HTTP_REQUEST_ERROR,
|
||||||
QUERY_TOO_LONG,
|
QUERY_TOO_LONG,
|
||||||
VALIDATION_ERROR,
|
VALIDATION_ERROR,
|
||||||
USER_NOT_FOUND,
|
USER_NOT_FOUND,
|
||||||
@@ -1011,5 +1022,5 @@ registerEnumType(ErrorNames, {
|
|||||||
export const ErrorDataUnionType = createUnionType({
|
export const ErrorDataUnionType = createUnionType({
|
||||||
name: 'ErrorDataUnion',
|
name: 'ErrorDataUnion',
|
||||||
types: () =>
|
types: () =>
|
||||||
[GraphqlBadRequestDataType, QueryTooLongDataType, ValidationErrorDataType, WrongSignInCredentialsDataType, UnknownOauthProviderDataType, InvalidOauthCallbackCodeDataType, MissingOauthQueryParameterDataType, InvalidEmailDataType, InvalidPasswordLengthDataType, WorkspacePermissionNotFoundDataType, SpaceNotFoundDataType, MemberNotFoundInSpaceDataType, NotInSpaceDataType, AlreadyInSpaceDataType, SpaceAccessDeniedDataType, SpaceOwnerNotFoundDataType, SpaceShouldHaveOnlyOneOwnerDataType, DocNotFoundDataType, DocActionDeniedDataType, DocUpdateBlockedDataType, VersionRejectedDataType, InvalidHistoryTimestampDataType, DocHistoryNotFoundDataType, BlobNotFoundDataType, ExpectToGrantDocUserRolesDataType, ExpectToRevokeDocUserRolesDataType, ExpectToUpdateDocUserRoleDataType, UnsupportedSubscriptionPlanDataType, SubscriptionAlreadyExistsDataType, SubscriptionNotExistsDataType, SameSubscriptionRecurringDataType, SubscriptionPlanNotFoundDataType, CopilotDocNotFoundDataType, CopilotMessageNotFoundDataType, CopilotPromptNotFoundDataType, CopilotProviderSideErrorDataType, CopilotInvalidContextDataType, CopilotContextFileNotSupportedDataType, CopilotFailedToModifyContextDataType, CopilotFailedToMatchContextDataType, RuntimeConfigNotFoundDataType, InvalidRuntimeConfigTypeDataType, InvalidLicenseUpdateParamsDataType, WorkspaceMembersExceedLimitToDowngradeDataType, UnsupportedClientVersionDataType, MentionUserDocAccessDeniedDataType] as const,
|
[GraphqlBadRequestDataType, HttpRequestErrorDataType, QueryTooLongDataType, ValidationErrorDataType, WrongSignInCredentialsDataType, UnknownOauthProviderDataType, InvalidOauthCallbackCodeDataType, MissingOauthQueryParameterDataType, InvalidEmailDataType, InvalidPasswordLengthDataType, WorkspacePermissionNotFoundDataType, SpaceNotFoundDataType, MemberNotFoundInSpaceDataType, NotInSpaceDataType, AlreadyInSpaceDataType, SpaceAccessDeniedDataType, SpaceOwnerNotFoundDataType, SpaceShouldHaveOnlyOneOwnerDataType, DocNotFoundDataType, DocActionDeniedDataType, DocUpdateBlockedDataType, VersionRejectedDataType, InvalidHistoryTimestampDataType, DocHistoryNotFoundDataType, BlobNotFoundDataType, ExpectToGrantDocUserRolesDataType, ExpectToRevokeDocUserRolesDataType, ExpectToUpdateDocUserRoleDataType, UnsupportedSubscriptionPlanDataType, SubscriptionAlreadyExistsDataType, SubscriptionNotExistsDataType, SameSubscriptionRecurringDataType, SubscriptionPlanNotFoundDataType, CopilotDocNotFoundDataType, CopilotMessageNotFoundDataType, CopilotPromptNotFoundDataType, CopilotProviderSideErrorDataType, CopilotInvalidContextDataType, CopilotContextFileNotSupportedDataType, CopilotFailedToModifyContextDataType, CopilotFailedToMatchContextDataType, RuntimeConfigNotFoundDataType, InvalidRuntimeConfigTypeDataType, InvalidLicenseUpdateParamsDataType, WorkspaceMembersExceedLimitToDowngradeDataType, UnsupportedClientVersionDataType, MentionUserDocAccessDeniedDataType] as const,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ import { ThrottlerException } from '@nestjs/throttler';
|
|||||||
import { BaseWsExceptionFilter } from '@nestjs/websockets';
|
import { BaseWsExceptionFilter } from '@nestjs/websockets';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { GraphQLError } from 'graphql';
|
import { GraphQLError } from 'graphql';
|
||||||
|
import { HttpError } from 'http-errors';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { Socket } from 'socket.io';
|
import { Socket } from 'socket.io';
|
||||||
import { ZodError } from 'zod';
|
import { ZodError } from 'zod';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GraphqlBadRequest,
|
GraphqlBadRequest,
|
||||||
|
HttpRequestError,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
NotFound,
|
NotFound,
|
||||||
TooManyRequest,
|
TooManyRequest,
|
||||||
@@ -57,6 +59,16 @@ export function mapAnyError(error: any): UserFriendlyError {
|
|||||||
return new ValidationError({
|
return new ValidationError({
|
||||||
errors: error.message,
|
errors: error.message,
|
||||||
});
|
});
|
||||||
|
} else if (
|
||||||
|
error instanceof HttpError &&
|
||||||
|
error.status >= 400 &&
|
||||||
|
error.status < 500
|
||||||
|
) {
|
||||||
|
const e = new HttpRequestError({
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
e.status = error.status;
|
||||||
|
return e;
|
||||||
} else {
|
} else {
|
||||||
const e = new InternalServerError();
|
const e = new InternalServerError();
|
||||||
e.cause = error;
|
e.cause = error;
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ type EditorType {
|
|||||||
name: String!
|
name: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
union ErrorDataUnion = AlreadyInSpaceDataType | BlobNotFoundDataType | CopilotContextFileNotSupportedDataType | CopilotDocNotFoundDataType | CopilotFailedToMatchContextDataType | CopilotFailedToModifyContextDataType | CopilotInvalidContextDataType | CopilotMessageNotFoundDataType | CopilotPromptNotFoundDataType | CopilotProviderSideErrorDataType | DocActionDeniedDataType | DocHistoryNotFoundDataType | DocNotFoundDataType | DocUpdateBlockedDataType | ExpectToGrantDocUserRolesDataType | ExpectToRevokeDocUserRolesDataType | ExpectToUpdateDocUserRoleDataType | GraphqlBadRequestDataType | InvalidEmailDataType | InvalidHistoryTimestampDataType | InvalidLicenseUpdateParamsDataType | InvalidOauthCallbackCodeDataType | InvalidPasswordLengthDataType | InvalidRuntimeConfigTypeDataType | MemberNotFoundInSpaceDataType | MentionUserDocAccessDeniedDataType | MissingOauthQueryParameterDataType | NotInSpaceDataType | QueryTooLongDataType | RuntimeConfigNotFoundDataType | SameSubscriptionRecurringDataType | SpaceAccessDeniedDataType | SpaceNotFoundDataType | SpaceOwnerNotFoundDataType | SpaceShouldHaveOnlyOneOwnerDataType | SubscriptionAlreadyExistsDataType | SubscriptionNotExistsDataType | SubscriptionPlanNotFoundDataType | UnknownOauthProviderDataType | UnsupportedClientVersionDataType | UnsupportedSubscriptionPlanDataType | ValidationErrorDataType | VersionRejectedDataType | WorkspaceMembersExceedLimitToDowngradeDataType | WorkspacePermissionNotFoundDataType | WrongSignInCredentialsDataType
|
union ErrorDataUnion = AlreadyInSpaceDataType | BlobNotFoundDataType | CopilotContextFileNotSupportedDataType | CopilotDocNotFoundDataType | CopilotFailedToMatchContextDataType | CopilotFailedToModifyContextDataType | CopilotInvalidContextDataType | CopilotMessageNotFoundDataType | CopilotPromptNotFoundDataType | CopilotProviderSideErrorDataType | DocActionDeniedDataType | DocHistoryNotFoundDataType | DocNotFoundDataType | DocUpdateBlockedDataType | ExpectToGrantDocUserRolesDataType | ExpectToRevokeDocUserRolesDataType | ExpectToUpdateDocUserRoleDataType | GraphqlBadRequestDataType | HttpRequestErrorDataType | InvalidEmailDataType | InvalidHistoryTimestampDataType | InvalidLicenseUpdateParamsDataType | InvalidOauthCallbackCodeDataType | InvalidPasswordLengthDataType | InvalidRuntimeConfigTypeDataType | MemberNotFoundInSpaceDataType | MentionUserDocAccessDeniedDataType | MissingOauthQueryParameterDataType | NotInSpaceDataType | QueryTooLongDataType | RuntimeConfigNotFoundDataType | SameSubscriptionRecurringDataType | SpaceAccessDeniedDataType | SpaceNotFoundDataType | SpaceOwnerNotFoundDataType | SpaceShouldHaveOnlyOneOwnerDataType | SubscriptionAlreadyExistsDataType | SubscriptionNotExistsDataType | SubscriptionPlanNotFoundDataType | UnknownOauthProviderDataType | UnsupportedClientVersionDataType | UnsupportedSubscriptionPlanDataType | ValidationErrorDataType | VersionRejectedDataType | WorkspaceMembersExceedLimitToDowngradeDataType | WorkspacePermissionNotFoundDataType | WrongSignInCredentialsDataType
|
||||||
|
|
||||||
enum ErrorNames {
|
enum ErrorNames {
|
||||||
ACCESS_DENIED
|
ACCESS_DENIED
|
||||||
@@ -429,6 +429,7 @@ enum ErrorNames {
|
|||||||
FAILED_TO_SAVE_UPDATES
|
FAILED_TO_SAVE_UPDATES
|
||||||
FAILED_TO_UPSERT_SNAPSHOT
|
FAILED_TO_UPSERT_SNAPSHOT
|
||||||
GRAPHQL_BAD_REQUEST
|
GRAPHQL_BAD_REQUEST
|
||||||
|
HTTP_REQUEST_ERROR
|
||||||
INTERNAL_SERVER_ERROR
|
INTERNAL_SERVER_ERROR
|
||||||
INVALID_AUTH_STATE
|
INVALID_AUTH_STATE
|
||||||
INVALID_CHECKOUT_PARAMETERS
|
INVALID_CHECKOUT_PARAMETERS
|
||||||
@@ -554,6 +555,10 @@ type GraphqlBadRequestDataType {
|
|||||||
message: String!
|
message: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HttpRequestErrorDataType {
|
||||||
|
message: String!
|
||||||
|
}
|
||||||
|
|
||||||
input ImportUsersInput {
|
input ImportUsersInput {
|
||||||
users: [CreateUserInput!]!
|
users: [CreateUserInput!]!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,6 +489,7 @@ export type ErrorDataUnion =
|
|||||||
| ExpectToRevokeDocUserRolesDataType
|
| ExpectToRevokeDocUserRolesDataType
|
||||||
| ExpectToUpdateDocUserRoleDataType
|
| ExpectToUpdateDocUserRoleDataType
|
||||||
| GraphqlBadRequestDataType
|
| GraphqlBadRequestDataType
|
||||||
|
| HttpRequestErrorDataType
|
||||||
| InvalidEmailDataType
|
| InvalidEmailDataType
|
||||||
| InvalidHistoryTimestampDataType
|
| InvalidHistoryTimestampDataType
|
||||||
| InvalidLicenseUpdateParamsDataType
|
| InvalidLicenseUpdateParamsDataType
|
||||||
@@ -569,6 +570,7 @@ export enum ErrorNames {
|
|||||||
FAILED_TO_SAVE_UPDATES = 'FAILED_TO_SAVE_UPDATES',
|
FAILED_TO_SAVE_UPDATES = 'FAILED_TO_SAVE_UPDATES',
|
||||||
FAILED_TO_UPSERT_SNAPSHOT = 'FAILED_TO_UPSERT_SNAPSHOT',
|
FAILED_TO_UPSERT_SNAPSHOT = 'FAILED_TO_UPSERT_SNAPSHOT',
|
||||||
GRAPHQL_BAD_REQUEST = 'GRAPHQL_BAD_REQUEST',
|
GRAPHQL_BAD_REQUEST = 'GRAPHQL_BAD_REQUEST',
|
||||||
|
HTTP_REQUEST_ERROR = 'HTTP_REQUEST_ERROR',
|
||||||
INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR',
|
INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR',
|
||||||
INVALID_AUTH_STATE = 'INVALID_AUTH_STATE',
|
INVALID_AUTH_STATE = 'INVALID_AUTH_STATE',
|
||||||
INVALID_CHECKOUT_PARAMETERS = 'INVALID_CHECKOUT_PARAMETERS',
|
INVALID_CHECKOUT_PARAMETERS = 'INVALID_CHECKOUT_PARAMETERS',
|
||||||
@@ -697,6 +699,11 @@ export interface GraphqlBadRequestDataType {
|
|||||||
message: Scalars['String']['output'];
|
message: Scalars['String']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HttpRequestErrorDataType {
|
||||||
|
__typename?: 'HttpRequestErrorDataType';
|
||||||
|
message: Scalars['String']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface ImportUsersInput {
|
export interface ImportUsersInput {
|
||||||
users: Array<CreateUserInput>;
|
users: Array<CreateUserInput>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
"ar": 96,
|
"ar": 96,
|
||||||
"ca": 4,
|
"ca": 4,
|
||||||
"da": 5,
|
"da": 5,
|
||||||
"de": 97,
|
"de": 96,
|
||||||
"el-GR": 96,
|
"el-GR": 96,
|
||||||
"en": 100,
|
"en": 100,
|
||||||
"es-AR": 97,
|
"es-AR": 96,
|
||||||
"es-CL": 98,
|
"es-CL": 98,
|
||||||
"es": 96,
|
"es": 96,
|
||||||
"fa": 96,
|
"fa": 96,
|
||||||
"fr": 96,
|
"fr": 96,
|
||||||
"hi": 2,
|
"hi": 2,
|
||||||
"it-IT": 97,
|
"it-IT": 96,
|
||||||
"it": 1,
|
"it": 1,
|
||||||
"ja": 96,
|
"ja": 96,
|
||||||
"ko": 61,
|
"ko": 61,
|
||||||
|
|||||||
@@ -7282,6 +7282,12 @@ export function useAFFiNEI18N(): {
|
|||||||
code: string;
|
code: string;
|
||||||
message: string;
|
message: string;
|
||||||
}>): string;
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `HTTP request error, message: {{message}}`
|
||||||
|
*/
|
||||||
|
["error.HTTP_REQUEST_ERROR"](options: {
|
||||||
|
readonly message: string;
|
||||||
|
}): string;
|
||||||
/**
|
/**
|
||||||
* `Query is too long, max length is {{max}}.`
|
* `Query is too long, max length is {{max}}.`
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1813,6 +1813,7 @@
|
|||||||
"error.NOT_FOUND": "Resource not found.",
|
"error.NOT_FOUND": "Resource not found.",
|
||||||
"error.BAD_REQUEST": "Bad request.",
|
"error.BAD_REQUEST": "Bad request.",
|
||||||
"error.GRAPHQL_BAD_REQUEST": "GraphQL bad request, code: {{code}}, {{message}}",
|
"error.GRAPHQL_BAD_REQUEST": "GraphQL bad request, code: {{code}}, {{message}}",
|
||||||
|
"error.HTTP_REQUEST_ERROR": "HTTP request error, message: {{message}}",
|
||||||
"error.QUERY_TOO_LONG": "Query is too long, max length is {{max}}.",
|
"error.QUERY_TOO_LONG": "Query is too long, max length is {{max}}.",
|
||||||
"error.VALIDATION_ERROR": "Validation error, errors: {{errors}}",
|
"error.VALIDATION_ERROR": "Validation error, errors: {{errors}}",
|
||||||
"error.USER_NOT_FOUND": "User not found.",
|
"error.USER_NOT_FOUND": "User not found.",
|
||||||
|
|||||||
@@ -892,6 +892,7 @@ __metadata:
|
|||||||
"@types/cookie-parser": "npm:^1.4.8"
|
"@types/cookie-parser": "npm:^1.4.8"
|
||||||
"@types/express": "npm:^4.17.21"
|
"@types/express": "npm:^4.17.21"
|
||||||
"@types/graphql-upload": "npm:^17.0.0"
|
"@types/graphql-upload": "npm:^17.0.0"
|
||||||
|
"@types/http-errors": "npm:^2.0.4"
|
||||||
"@types/lodash-es": "npm:^4.17.12"
|
"@types/lodash-es": "npm:^4.17.12"
|
||||||
"@types/mixpanel": "npm:^2.14.9"
|
"@types/mixpanel": "npm:^2.14.9"
|
||||||
"@types/mustache": "npm:^4.2.5"
|
"@types/mustache": "npm:^4.2.5"
|
||||||
@@ -921,6 +922,7 @@ __metadata:
|
|||||||
graphql-upload: "npm:^17.0.0"
|
graphql-upload: "npm:^17.0.0"
|
||||||
html-validate: "npm:^9.0.0"
|
html-validate: "npm:^9.0.0"
|
||||||
htmlrewriter: "npm:^0.0.12"
|
htmlrewriter: "npm:^0.0.12"
|
||||||
|
http-errors: "npm:^2.0.0"
|
||||||
ioredis: "npm:^5.4.1"
|
ioredis: "npm:^5.4.1"
|
||||||
is-mobile: "npm:^5.0.0"
|
is-mobile: "npm:^5.0.0"
|
||||||
keyv: "npm:^5.2.2"
|
keyv: "npm:^5.2.2"
|
||||||
@@ -14347,7 +14349,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/http-errors@npm:*":
|
"@types/http-errors@npm:*, @types/http-errors@npm:^2.0.4":
|
||||||
version: 2.0.4
|
version: 2.0.4
|
||||||
resolution: "@types/http-errors@npm:2.0.4"
|
resolution: "@types/http-errors@npm:2.0.4"
|
||||||
checksum: 10/1f3d7c3b32c7524811a45690881736b3ef741bf9849ae03d32ad1ab7062608454b150a4e7f1351f83d26a418b2d65af9bdc06198f1c079d75578282884c4e8e3
|
checksum: 10/1f3d7c3b32c7524811a45690881736b3ef741bf9849ae03d32ad1ab7062608454b150a4e7f1351f83d26a418b2d65af9bdc06198f1c079d75578282884c4e8e3
|
||||||
|
|||||||
Reference in New Issue
Block a user