From 65879492dfa99238f04b3e0e80c3133df14c94d0 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Fri, 20 Sep 2024 16:13:00 -0500 Subject: [PATCH 1/5] Express -> Fastify --- .eslintrc.cjs | 5 - package.json | 15 +- .../authentication/current-user.provider.ts | 4 +- src/core/exception/exception.filter.ts | 2 +- src/core/graphql/graphql.module.ts | 35 +- src/core/graphql/graphql.options.ts | 25 +- src/core/http/http.adapter.ts | 63 +- src/core/http/types.ts | 15 +- src/core/timeout.interceptor.ts | 2 +- yarn.lock | 1053 +++++++++-------- 10 files changed, 643 insertions(+), 576 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index a877417b82..1078eb4d92 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -37,11 +37,6 @@ const oldRestrictedImports = [ importNames: ['Dictionary', 'SafeDictionary'], message: 'Use a type with strict keys instead', }, - { - name: 'express-serve-static-core', - importNames: ['Dictionary'], - message: 'Use a type with strict keys instead', - }, ]; /** @type {import('@seedcompany/eslint-plugin').ImportRestriction[]} */ diff --git a/package.json b/package.json index d0fcac4a66..27701f5946 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,12 @@ "dependencies": { "@apollo/server": "^4.9.5", "@apollo/subgraph": "^2.5.6", + "@as-integrations/fastify": "^2.1.1", "@aws-sdk/client-s3": "^3.440.0", "@aws-sdk/s3-request-presigner": "^3.440.0", "@faker-js/faker": "^8.2.0", + "@fastify/cookie": "^9.4.0", + "@fastify/cors": "^9.0.1", "@ffprobe-installer/ffprobe": "^2.1.2", "@golevelup/nestjs-discovery": "^4.0.0", "@leeoniya/ufuzzy": "^1.0.11", @@ -43,7 +46,7 @@ "@nestjs/common": "^10.2.7", "@nestjs/core": "^10.2.7", "@nestjs/graphql": "^12.0.9", - "@nestjs/platform-express": "^10.2.7", + "@nestjs/platform-fastify": "^10.4.3", "@patarapolw/prettyprint": "^1.0.3", "@seedcompany/cache": "^2.0.0", "@seedcompany/common": ">=0.13.1 <1", @@ -59,16 +62,15 @@ "cli-table3": "^0.6.3", "clipanion": "^4.0.0-rc.3", "common-tags": "^1.8.2", - "cookie-parser": "^1.4.6", "cypher-query-builder": "patch:cypher-query-builder@npm%3A6.0.4#~/.yarn/patches/cypher-query-builder-npm-6.0.4-e8707a5e8e.patch", "dotenv": "^16.3.1", "dotenv-expand": "^10.0.0", "edgedb": "^1.6.0-canary.20240827T111834", "execa": "^8.0.1", - "express": "^4.18.2", "extensionless": "^1.7.0", "fast-safe-stringify": "^2.1.1", "fastest-levenshtein": "^1.0.16", + "fastify": "^4.28.1", "file-type": "^18.6.0", "glob": "^10.3.10", "got": "^14.3.0", @@ -116,9 +118,6 @@ "@seedcompany/eslint-plugin": "^3.4.1", "@tsconfig/strictest": "^2.0.2", "@types/common-tags": "^1.8.3", - "@types/cookie-parser": "^1.4.5", - "@types/express": "^4.17.20", - "@types/express-serve-static-core": "^4.17.39", "@types/ffprobe": "^1.1.7", "@types/graphql-upload": "^16.0.4", "@types/jest": "^29.5.7", @@ -154,9 +153,13 @@ "neo4j-driver-bolt-connection@npm:5.20.0": "patch:neo4j-driver-bolt-connection@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-bolt-connection-npm-5.20.0-1f7809f435.patch", "neo4j-driver-core@npm:5.20.0": "patch:neo4j-driver-core@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-core-npm-5.20.0-99216f6938.patch", "@apollo/server-plugin-landing-page-graphql-playground": "npm:empty-npm-package@*", + "@apollo/server/express": "npm:empty-npm-package@*", "@nestjs/cli/fork-ts-checker-webpack-plugin": "npm:empty-npm-package@*", "@nestjs/cli/webpack": "npm:empty-npm-package@*", "@nestjs/cli/typescript": "^5.1.6", + "@types/express": "npm:@types/stack-trace@*", + "@types/express-serve-static-core": "npm:@types/stack-trace@*", + "@types/koa": "npm:@types/stack-trace@*", "subscriptions-transport-ws": "npm:empty-npm-package@*" }, "dependenciesMeta": { diff --git a/src/components/authentication/current-user.provider.ts b/src/components/authentication/current-user.provider.ts index 1440533413..fbfb445302 100644 --- a/src/components/authentication/current-user.provider.ts +++ b/src/components/authentication/current-user.provider.ts @@ -47,14 +47,14 @@ export class EdgeDBCurrentUserProvider const { request, session$ } = GqlExecutionContext.create(context).getContext(); if (request) { - const optionsHolder = this.optionsHolderByRequest.get(request)!; + const optionsHolder = this.optionsHolderByRequest.get(request.raw)!; session$.subscribe((session) => { this.applyToOptions(session, optionsHolder); }); } } else if (type === 'http') { const request = context.switchToHttp().getRequest(); - const optionsHolder = this.optionsHolderByRequest.get(request)!; + const optionsHolder = this.optionsHolderByRequest.get(request.raw)!; this.applyToOptions(request.session, optionsHolder); } diff --git a/src/core/exception/exception.filter.ts b/src/core/exception/exception.filter.ts index c1475ec2c2..8b899b9175 100644 --- a/src/core/exception/exception.filter.ts +++ b/src/core/exception/exception.filter.ts @@ -26,7 +26,7 @@ export class ExceptionFilter implements GqlExceptionFilter { const hack = isFromHackAttempt(exception, args); if (hack) { - hack.destroy(); + hack.raw.destroy(); return; } diff --git a/src/core/graphql/graphql.module.ts b/src/core/graphql/graphql.module.ts index ff98a4cac5..d3e8eba52d 100644 --- a/src/core/graphql/graphql.module.ts +++ b/src/core/graphql/graphql.module.ts @@ -2,7 +2,10 @@ import { ApolloDriver } from '@nestjs/apollo'; import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { APP_INTERCEPTOR } from '@nestjs/core'; import { GraphQLModule as NestGraphqlModule } from '@nestjs/graphql'; -import createUploadMiddleware from 'graphql-upload/graphqlUploadExpress.mjs'; +import processUploadRequest, { + UploadOptions, +} from 'graphql-upload/processRequest.mjs'; +import { HttpAdapterHost } from '~/core/http'; import { TracingModule } from '../tracing'; import { GqlContextHost, GqlContextHostImpl } from './gql-context.host'; import { GraphqlErrorFormatter } from './graphql-error-formatter'; @@ -13,6 +16,8 @@ import { GraphqlOptions } from './graphql.options'; import './types'; +const FileUploadOptions: UploadOptions = {}; + @Module({ imports: [TracingModule], providers: [ @@ -42,15 +47,35 @@ export class GraphqlOptionsModule {} exports: [NestGraphqlModule, GqlContextHost], }) export class GraphqlModule implements NestModule { - constructor(private readonly middleware: GqlContextHostImpl) {} + constructor( + private readonly middleware: GqlContextHostImpl, + private readonly app: HttpAdapterHost, + ) {} configure(consumer: MiddlewareConsumer) { // Always attach our GQL Context middleware. // It has its own logic to handle non-gql requests. consumer.apply(this.middleware.use).forRoutes('*'); - // Attach the graphql-upload middleware to the graphql endpoint. - const uploadMiddleware = createUploadMiddleware(); - consumer.apply(uploadMiddleware).forRoutes('/graphql', '/graphql/*'); + // Setup file upload handling + const fastify = this.app.httpAdapter.getInstance(); + const multipartRequests = new WeakSet(); + fastify.addContentTypeParser( + 'multipart/form-data', + (req, payload, done) => { + multipartRequests.add(req); + done(null); + }, + ); + fastify.addHook('preValidation', async (req, reply) => { + if (!multipartRequests.has(req) || !req.url.startsWith('/graphql')) { + return; + } + req.body = await processUploadRequest( + req.raw, + reply.raw, + FileUploadOptions, + ); + }); } } diff --git a/src/core/graphql/graphql.options.ts b/src/core/graphql/graphql.options.ts index 75548e5254..29f1e66d9f 100644 --- a/src/core/graphql/graphql.options.ts +++ b/src/core/graphql/graphql.options.ts @@ -1,10 +1,9 @@ -import { ContextFunction } from '@apollo/server'; -import { ExpressContextFunctionArgument } from '@apollo/server/express4'; import { ApolloServerPluginLandingPageLocalDefault, ApolloServerPluginLandingPageProductionDefault, } from '@apollo/server/plugin/landingPage/default'; -import { ApolloDriverConfig } from '@nestjs/apollo'; +import { ApolloFastifyContextFunctionArgument } from '@as-integrations/fastify'; +import { ApolloDriverConfig as DriverConfig } from '@nestjs/apollo'; import { Injectable } from '@nestjs/common'; import { GqlOptionsFactory } from '@nestjs/graphql'; import { CacheService } from '@seedcompany/cache'; @@ -29,7 +28,7 @@ export class GraphqlOptions implements GqlOptionsFactory { private readonly errorFormatter: GraphqlErrorFormatter, ) {} - async createGqlOptions(): Promise { + async createGqlOptions(): Promise { // Apply git hash to Apollo Studio. // They only look for env, so applying that way. const version = await this.versionService.version; @@ -44,6 +43,7 @@ export class GraphqlOptions implements GqlOptionsFactory { ).asRecord; return { + path: '/graphql/:opName?', autoSchemaFile: 'schema.graphql', context: this.context, playground: false, @@ -80,14 +80,15 @@ export class GraphqlOptions implements GqlOptionsFactory { }; } - context: ContextFunction<[ExpressContextFunctionArgument], GqlContextType> = - async ({ req, res }) => ({ - [isGqlContext.KEY]: true, - request: req, - response: res, - operation: createFakeStubOperation(), - session$: new BehaviorSubject(undefined), - }); + context = ( + ...[request, response]: ApolloFastifyContextFunctionArgument + ): GqlContextType => ({ + [isGqlContext.KEY]: true, + request, + response, + operation: createFakeStubOperation(), + session$: new BehaviorSubject(undefined), + }); } export const createFakeStubOperation = () => { diff --git a/src/core/http/http.adapter.ts b/src/core/http/http.adapter.ts index d07383ae32..c606100d98 100644 --- a/src/core/http/http.adapter.ts +++ b/src/core/http/http.adapter.ts @@ -1,24 +1,30 @@ +import cookieParser from '@fastify/cookie'; +import cors from '@fastify/cors'; // eslint-disable-next-line @seedcompany/no-restricted-imports import { HttpAdapterHost as HttpAdapterHostImpl } from '@nestjs/core'; import { - NestExpressApplication as BaseApplication, - ExpressAdapter, -} from '@nestjs/platform-express'; -import cookieParser from 'cookie-parser'; -import { ConfigService } from '../config/config.service'; -import type { CorsOptions } from './index'; -import { CookieOptions, IResponse } from './types'; - -export type NestHttpApplication = BaseApplication & { - configure: (app: BaseApplication, config: ConfigService) => Promise; + FastifyAdapter, + NestFastifyApplication, +} from '@nestjs/platform-fastify'; +import { ConfigService } from '~/core/config/config.service'; +import type { CookieOptions, CorsOptions, IResponse } from './types'; + +export type NestHttpApplication = NestFastifyApplication & { + configure: ( + app: NestFastifyApplication, + config: ConfigService, + ) => Promise; }; export class HttpAdapterHost extends HttpAdapterHostImpl {} -export class HttpAdapter extends ExpressAdapter { - async configure(app: BaseApplication, config: ConfigService) { - app.enableCors(config.cors as CorsOptions); // typecast to undo deep readonly - app.use(cookieParser()); +export class HttpAdapter extends FastifyAdapter { + async configure(app: NestFastifyApplication, config: ConfigService) { + await app.register(cors, { + // typecast to undo deep readonly + ...(config.cors as CorsOptions), + }); + await app.register(cookieParser); app.setGlobalPrefix(config.hostUrl$.value.pathname.slice(1)); @@ -31,6 +37,33 @@ export class HttpAdapter extends ExpressAdapter { value: string, options: CookieOptions, ) { - response.cookie(name, value, options); + // Avoid linter wanting us to await sending response. + // This method just returns the response instance for fluent interface. + void response.cookie(name, value, options); + } + + // @ts-expect-error we don't need to be compatible with base + reply( + response: IResponse | IResponse['raw'], + body: any, + statusCode?: number, + ) { + // Avoid linter wanting us to await sending response. + // This method just returns the response instance for fluent interface. + void super.reply(response, body, statusCode); + } + + // @ts-expect-error we don't need to be compatible with base + setHeader(response: IResponse, name: string, value: string) { + // Avoid linter wanting us to await sending response. + // This method just returns the response instance for fluent interface. + void super.setHeader(response, name, value); + } + + // @ts-expect-error we don't need to be compatible with base + redirect(response: IResponse, statusCode: number, url: string) { + // Avoid linter wanting us to await sending response. + // This method just returns the response instance for fluent interface. + void super.redirect(response, statusCode, url); } } diff --git a/src/core/http/types.ts b/src/core/http/types.ts index d2980d860b..ee96ee3e63 100644 --- a/src/core/http/types.ts +++ b/src/core/http/types.ts @@ -1,19 +1,22 @@ /* eslint-disable @typescript-eslint/method-signature-style */ // eslint-disable-next-line @seedcompany/no-restricted-imports import type { NestMiddleware } from '@nestjs/common'; -import type { Request, Response } from 'express'; +import type { + FastifyRequest as Request, + FastifyReply as Response, +} from 'fastify'; import type { Session } from '~/common'; // Exporting with I prefix to avoid ambiguity with web global types export type { Request as IRequest, Response as IResponse }; -export type HttpMiddleware = NestMiddleware; +export type HttpMiddleware = NestMiddleware; -export { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface'; -export { CookieOptions } from 'express'; +export { FastifyCorsOptions as CorsOptions } from '@fastify/cors'; +export { SerializeOptions as CookieOptions } from '@fastify/cookie'; -declare module 'express' { - export interface Request { +declare module 'fastify' { + export interface FastifyRequest { session?: Session; } } diff --git a/src/core/timeout.interceptor.ts b/src/core/timeout.interceptor.ts index 4699a7e1b3..f2eb8a79f0 100644 --- a/src/core/timeout.interceptor.ts +++ b/src/core/timeout.interceptor.ts @@ -25,7 +25,7 @@ export class TimeoutInterceptor implements NestInterceptor { return next.handle(); } - const timeout$ = fromEvent(response, 'timeout').pipe( + const timeout$ = fromEvent(response.raw, 'timeout').pipe( map(() => { throw new ServiceUnavailableException( 'Unable to fulfill request in a timely manner', diff --git a/yarn.lock b/yarn.lock index 604b2e4f02..20f7f2b727 100644 --- a/yarn.lock +++ b/yarn.lock @@ -130,7 +130,7 @@ __metadata: languageName: node linkType: hard -"@apollo/server-plugin-landing-page-graphql-playground@npm:empty-npm-package@*, fork-ts-checker-webpack-plugin@npm:empty-npm-package@*, subscriptions-transport-ws@npm:empty-npm-package@*, webpack@npm:empty-npm-package@*": +"@apollo/server-plugin-landing-page-graphql-playground@npm:empty-npm-package@*, express@npm:empty-npm-package@*, fork-ts-checker-webpack-plugin@npm:empty-npm-package@*, subscriptions-transport-ws@npm:empty-npm-package@*, webpack@npm:empty-npm-package@*": version: 1.0.0 resolution: "empty-npm-package@npm:1.0.0" checksum: 10c0/86dc2266288d7e3456205b8fe69ef30a1561d2365783439df0870124e5f4cf64b845ef3fea9b3312107d5a08e8d0b56813392be80a98825b4ad75d22b7e68ce0 @@ -305,6 +305,18 @@ __metadata: languageName: node linkType: hard +"@as-integrations/fastify@npm:^2.1.1": + version: 2.1.1 + resolution: "@as-integrations/fastify@npm:2.1.1" + dependencies: + fastify-plugin: "npm:^4.4.0" + peerDependencies: + "@apollo/server": ^4.0.0 + fastify: ^4.4.0 + checksum: 10c0/c2669ac8b80fc78069fb9bdbc5bda2f6c5eca00e40554005aef05d5933ff5fbe461ff4c02ed4782ee4c139a7cc35392d118e9a937fd2df177884e988f8876b84 + languageName: node + linkType: hard + "@aws-crypto/crc32@npm:5.2.0": version: 5.2.0 resolution: "@aws-crypto/crc32@npm:5.2.0" @@ -1584,6 +1596,84 @@ __metadata: languageName: node linkType: hard +"@fastify/ajv-compiler@npm:^3.5.0": + version: 3.6.0 + resolution: "@fastify/ajv-compiler@npm:3.6.0" + dependencies: + ajv: "npm:^8.11.0" + ajv-formats: "npm:^2.1.1" + fast-uri: "npm:^2.0.0" + checksum: 10c0/f0be2ca1f75833492829c52c5f5ef0ec118bdd010614e002a6366952c27297c0f6a7dafb5917a0f9c4aaa84aa32a39e520c6d837fa251748717d58590cfc8177 + languageName: node + linkType: hard + +"@fastify/cookie@npm:^9.4.0": + version: 9.4.0 + resolution: "@fastify/cookie@npm:9.4.0" + dependencies: + cookie-signature: "npm:^1.1.0" + fastify-plugin: "npm:^4.0.0" + checksum: 10c0/24d2fd4648fc28078c793dc862c53c7f3b356813e5482058b004e6c3733fd2ea432fc5e123ffb77d767b833f8c177501f2c45eda5d5d01bd6ed7040d3e3fd9b6 + languageName: node + linkType: hard + +"@fastify/cors@npm:9.0.1, @fastify/cors@npm:^9.0.1": + version: 9.0.1 + resolution: "@fastify/cors@npm:9.0.1" + dependencies: + fastify-plugin: "npm:^4.0.0" + mnemonist: "npm:0.39.6" + checksum: 10c0/4db9d3d02edbca741c8ed053819bf3b235ecd70e07c640ed91ba0fc1ee2dc8abedbbffeb79ae1a38ccbf59832e414cad90a554ee44227d0811d5a2d062940611 + languageName: node + linkType: hard + +"@fastify/error@npm:^3.2.0, @fastify/error@npm:^3.3.0, @fastify/error@npm:^3.4.0": + version: 3.4.1 + resolution: "@fastify/error@npm:3.4.1" + checksum: 10c0/1f1a0faa8c86639afb6f4bd47a9cdc1f0f20ce0d6944340fbdec8218aaba91dc9cae9ed78e24e61bceb782a867efda2b9a6320091f00dcbb896d9c8a9bdf5f96 + languageName: node + linkType: hard + +"@fastify/fast-json-stringify-compiler@npm:^4.3.0": + version: 4.3.0 + resolution: "@fastify/fast-json-stringify-compiler@npm:4.3.0" + dependencies: + fast-json-stringify: "npm:^5.7.0" + checksum: 10c0/513ef296f5ed682f7a460cfa6c5fb917a32fc540111b873c9937f944558e021492b18f30f9fd8dd20db252381a4428adbcc9f03a077f16c86d02f081eb490c7b + languageName: node + linkType: hard + +"@fastify/formbody@npm:7.4.0": + version: 7.4.0 + resolution: "@fastify/formbody@npm:7.4.0" + dependencies: + fast-querystring: "npm:^1.0.0" + fastify-plugin: "npm:^4.0.0" + checksum: 10c0/128aa7c2a4e975242bf40f18519cb7a26e768478e56754423ba99cbc05946fcb98f53d87c65eafab7ef2ed68e4b95f4d7e1d14e31355e346d9c717dd689e1fa8 + languageName: node + linkType: hard + +"@fastify/merge-json-schemas@npm:^0.1.0": + version: 0.1.1 + resolution: "@fastify/merge-json-schemas@npm:0.1.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + checksum: 10c0/7979ce12724f7b98aea06f0bb9afb20dd869f0ff6fc697517135cbb54e0a36b062cbb38ec176fe43d1fc455576839240df8f33533939ace2d64a6218a6e6b9c1 + languageName: node + linkType: hard + +"@fastify/middie@npm:8.3.3": + version: 8.3.3 + resolution: "@fastify/middie@npm:8.3.3" + dependencies: + "@fastify/error": "npm:^3.2.0" + fastify-plugin: "npm:^4.0.0" + path-to-regexp: "npm:^6.3.0" + reusify: "npm:^1.0.4" + checksum: 10c0/802a1a51d25d2651fcdd223f058530cad8c8b55a9adb764bd47e55e4656d1c4b3ce71a58fe40c8307ddef56750ce0ba93b9df14ead5d01e2a6590b677ec393ab + languageName: node + linkType: hard + "@ffprobe-installer/darwin-arm64@npm:5.0.1": version: 5.0.1 resolution: "@ffprobe-installer/darwin-arm64@npm:5.0.1" @@ -2368,19 +2458,28 @@ __metadata: languageName: node linkType: hard -"@nestjs/platform-express@npm:^10.2.7": - version: 10.3.7 - resolution: "@nestjs/platform-express@npm:10.3.7" +"@nestjs/platform-fastify@npm:^10.4.3": + version: 10.4.4 + resolution: "@nestjs/platform-fastify@npm:10.4.4" dependencies: - body-parser: "npm:1.20.2" - cors: "npm:2.8.5" - express: "npm:4.19.2" - multer: "npm:1.4.4-lts.1" - tslib: "npm:2.6.2" + "@fastify/cors": "npm:9.0.1" + "@fastify/formbody": "npm:7.4.0" + "@fastify/middie": "npm:8.3.3" + fastify: "npm:4.28.1" + light-my-request: "npm:6.0.0" + path-to-regexp: "npm:3.3.0" + tslib: "npm:2.7.0" peerDependencies: + "@fastify/static": ^6.0.0 || ^7.0.0 + "@fastify/view": ^7.0.0 || ^8.0.0 "@nestjs/common": ^10.0.0 "@nestjs/core": ^10.0.0 - checksum: 10c0/281ce6149bb9c7288dda3eabe6d3732d6874c9c47ad923a74022659ec765c1c76d1c05323d6f570faf6f976014b7bc8dabd328e4e86e0db9e4f0f1752c6df7d1 + peerDependenciesMeta: + "@fastify/static": + optional: true + "@fastify/view": + optional: true + checksum: 10c0/fed6c8b8306e7a373dbd67befbc49fe61a3511f12a62a86bec537053d8fb065aa16d3147b544b176b6c4b8591fad8cbd8ac2208df78628b3d6fdf45fcaa66c10 languageName: node linkType: hard @@ -3455,15 +3554,6 @@ __metadata: languageName: node linkType: hard -"@types/accepts@npm:*": - version: 1.3.6 - resolution: "@types/accepts@npm:1.3.6" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/ff2fc4e9384d9edbdba59850f241a1cb92a97565344d1a1193c7ca539ca1037c2931acbeb1f637109b1e5de40fa4ec3f2985e8af747469b19efc0172b69e96af - languageName: node - linkType: hard - "@types/babel__core@npm:^7.1.14": version: 7.20.3 resolution: "@types/babel__core@npm:7.20.3" @@ -3505,16 +3595,6 @@ __metadata: languageName: node linkType: hard -"@types/body-parser@npm:*": - version: 1.19.4 - resolution: "@types/body-parser@npm:1.19.4" - dependencies: - "@types/connect": "npm:*" - "@types/node": "npm:*" - checksum: 10c0/bec2b8a97861a960ee415f7ab3c2aeb7f4d779fd364d27ddee46057897ea571735f1f854f5ee41682964315d4e3699f62427998b9c21851d773398ef535f0612 - languageName: node - linkType: hard - "@types/busboy@npm:^1.5.0": version: 1.5.2 resolution: "@types/busboy@npm:1.5.2" @@ -3540,64 +3620,10 @@ __metadata: languageName: node linkType: hard -"@types/connect@npm:*": - version: 3.4.37 - resolution: "@types/connect@npm:3.4.37" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/79fd5c32a8bb5c9548369e6da3221b6a820f3a8c5396d50f6f642712b9f4c1c881ef86bdf48994a4a279e81998563410b8843c5a10dde5521d5ef6a8ae944c3b - languageName: node - linkType: hard - -"@types/content-disposition@npm:*": - version: 0.5.7 - resolution: "@types/content-disposition@npm:0.5.7" - checksum: 10c0/6be25cb1b5a7f93f6490655901c0c9dadb5d54b853d5e052abd68f6157cfc4c8e6a4fda186a43490f1547066481234bb645d83e4fe07a11bfc4727169d4ddf3b - languageName: node - linkType: hard - -"@types/cookie-parser@npm:^1.4.5": - version: 1.4.5 - resolution: "@types/cookie-parser@npm:1.4.5" - dependencies: - "@types/express": "npm:*" - checksum: 10c0/6828de5179fbe69dab7d5ff16890dc728102941ecdcb7a295bfb0645cdd6abcc8cc17854d57f4001ed778b08d4c51961d1c5c2ea1a4643ae90d3ff22588567c4 - languageName: node - linkType: hard - -"@types/cookies@npm:*": - version: 0.7.9 - resolution: "@types/cookies@npm:0.7.9" - dependencies: - "@types/connect": "npm:*" - "@types/express": "npm:*" - "@types/keygrip": "npm:*" - "@types/node": "npm:*" - checksum: 10c0/0f8a09cf0b420dbe41dab25c3c13bbb27f00ce186a3e154ebe6ac7d6b74d64ffb9f11d11ecca8071dc197bd591255242890974df6baa473f44d746f3173546bf - languageName: node - linkType: hard - -"@types/express-serve-static-core@npm:^4.17.30, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.39": - version: 4.17.39 - resolution: "@types/express-serve-static-core@npm:4.17.39" - dependencies: - "@types/node": "npm:*" - "@types/qs": "npm:*" - "@types/range-parser": "npm:*" - "@types/send": "npm:*" - checksum: 10c0/b23b005fddd2ba3f7142ec9713f06b5582c7712cdf99c3419d3972364903b348a103c3264d9a761d6497140e3b89bd416454684c4bdeff206b4c59b86e96428a - languageName: node - linkType: hard - -"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.20": - version: 4.17.20 - resolution: "@types/express@npm:4.17.20" - dependencies: - "@types/body-parser": "npm:*" - "@types/express-serve-static-core": "npm:^4.17.33" - "@types/qs": "npm:*" - "@types/serve-static": "npm:*" - checksum: 10c0/f73f5f92bd0a0fa4697598be3122c89522caa9e3bcb14c28b5e6d58a8e47f0301027478997153ae9ee4cf3d432576fb3fb0918ea0db521cc1204f8b759828a32 +"@types/express-serve-static-core@npm:@types/stack-trace@*, @types/express@npm:@types/stack-trace@*, @types/koa@npm:@types/stack-trace@*": + version: 0.0.33 + resolution: "@types/stack-trace@npm:0.0.33" + checksum: 10c0/cc8345f042f5de17f960652974d67aac71bf864b748f3efbd10a8c5315c0a7a8a13ab17931c239b9fe6b531a44378347509dc8a97a24dfa1247b93af3f943650 languageName: node linkType: hard @@ -3630,13 +3656,6 @@ __metadata: languageName: node linkType: hard -"@types/http-assert@npm:*": - version: 1.5.4 - resolution: "@types/http-assert@npm:1.5.4" - checksum: 10c0/86db2aa1fae12e68f481937c707887dfc1accb0b8056d363e5d3dd91cecae24de028e9475d3bf95bd3760b4b3eb86e4069bf0901d8221f494f5f279f7e90f1ab - languageName: node - linkType: hard - "@types/http-cache-semantics@npm:^4.0.4": version: 4.0.4 resolution: "@types/http-cache-semantics@npm:4.0.4" @@ -3644,13 +3663,6 @@ __metadata: languageName: node linkType: hard -"@types/http-errors@npm:*": - version: 2.0.3 - resolution: "@types/http-errors@npm:2.0.3" - checksum: 10c0/717ce3e8f49a1facb7130fed934108fa8a51ab02089a1049c782e353e0e08e79bdfaac054c2a94db14ea400302e523276387363aa820eaf0031af8ba5d2941dc - languageName: node - linkType: hard - "@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": version: 2.0.5 resolution: "@types/istanbul-lib-coverage@npm:2.0.5" @@ -3709,38 +3721,6 @@ __metadata: languageName: node linkType: hard -"@types/keygrip@npm:*": - version: 1.0.4 - resolution: "@types/keygrip@npm:1.0.4" - checksum: 10c0/12a706c2902336e0ab23fdc3d3c76230e8e557b57ef639100c4e5ee7119e81d2ba073de337f130e13e6cb576f2de1802380c516eafff2905fb0c90b5104d9666 - languageName: node - linkType: hard - -"@types/koa-compose@npm:*": - version: 3.2.7 - resolution: "@types/koa-compose@npm:3.2.7" - dependencies: - "@types/koa": "npm:*" - checksum: 10c0/9b4e86b5d5a920c19ac73c636acd0a3a8637f9eb11afde65da360d609b4dfe5a70ab8a096a1190c54ae49c8a7a65022e93d3a8ea663eee1d6c8b5379b7859c75 - languageName: node - linkType: hard - -"@types/koa@npm:*": - version: 2.13.10 - resolution: "@types/koa@npm:2.13.10" - dependencies: - "@types/accepts": "npm:*" - "@types/content-disposition": "npm:*" - "@types/cookies": "npm:*" - "@types/http-assert": "npm:*" - "@types/http-errors": "npm:*" - "@types/keygrip": "npm:*" - "@types/koa-compose": "npm:*" - "@types/node": "npm:*" - checksum: 10c0/fc13a614093f2b48a32dea3af8c932d77edb9e571d18faabb6ce8f814222351caead1d2c8e835146d0b9e780e8ac675f9f5a56c03d3b1ad7ea85735174e5f947 - languageName: node - linkType: hard - "@types/lodash@npm:^4.14.136, @types/lodash@npm:^4.14.200": version: 4.14.200 resolution: "@types/lodash@npm:4.14.200" @@ -3762,20 +3742,6 @@ __metadata: languageName: node linkType: hard -"@types/mime@npm:*": - version: 3.0.3 - resolution: "@types/mime@npm:3.0.3" - checksum: 10c0/cef99f8cdc42af9de698027c2a20ba5df12bc9a89dcf5513e70103ebb55e00c5f5c585d02411f4b42fde0e78488342f1b1d3e3546a59a3da42e95fdc616e01eb - languageName: node - linkType: hard - -"@types/mime@npm:^1": - version: 1.3.4 - resolution: "@types/mime@npm:1.3.4" - checksum: 10c0/a0a16d26c0e70a1b133e26e7c46b70b3136b7e894396bdb7de1c642f4ac87fdbbba26bf56cf73f001312289d89de4f1c06ab745d9445850df45a5a802564c4d6 - languageName: node - linkType: hard - "@types/node-fetch@npm:^2.6.1": version: 2.6.8 resolution: "@types/node-fetch@npm:2.6.8" @@ -3837,20 +3803,6 @@ __metadata: languageName: node linkType: hard -"@types/qs@npm:*": - version: 6.9.9 - resolution: "@types/qs@npm:6.9.9" - checksum: 10c0/aede2a4181a49ae8548a1354bac3f8235cb0c5aab066b10875a3e68e88a199e220f4284e7e2bb75a3c18e5d4ff6abe1a6ce0389ef31b63952cc45e0f4d885ba0 - languageName: node - linkType: hard - -"@types/range-parser@npm:*": - version: 1.2.6 - resolution: "@types/range-parser@npm:1.2.6" - checksum: 10c0/46e7fffc54cdacc8fb0cd576f8f9a6436453f0176205d6ec55434a460c7677e78e688673426d5db5e480501b2943ba08a16ececa3a354c222093551c7217fb8f - languageName: node - linkType: hard - "@types/react@npm:^18.2.33": version: 18.2.33 resolution: "@types/react@npm:18.2.33" @@ -3883,27 +3835,6 @@ __metadata: languageName: node linkType: hard -"@types/send@npm:*": - version: 0.17.3 - resolution: "@types/send@npm:0.17.3" - dependencies: - "@types/mime": "npm:^1" - "@types/node": "npm:*" - checksum: 10c0/773a0cb55ea03eefbe9a0e6d42114e0f84968db30954a131aae9ba7e9ab984a4776915447ebdeab4412d7f11750126614b0b75e99413f75810045bdb3196554a - languageName: node - linkType: hard - -"@types/serve-static@npm:*": - version: 1.15.4 - resolution: "@types/serve-static@npm:1.15.4" - dependencies: - "@types/http-errors": "npm:*" - "@types/mime": "npm:*" - "@types/node": "npm:*" - checksum: 10c0/061b38993bf8f2b5033f57147c8ec90e1d1a0d6f734958ceb531ba7cc31192fd272c999cdbc57ede8672787e3aa171ec142dc65a467c04078e43823e7476eb49 - languageName: node - linkType: hard - "@types/stack-trace@npm:^0.0.32": version: 0.0.32 resolution: "@types/stack-trace@npm:0.0.32" @@ -4115,13 +4046,19 @@ __metadata: languageName: node linkType: hard -"accepts@npm:~1.3.8": - version: 1.3.8 - resolution: "accepts@npm:1.3.8" +"abort-controller@npm:^3.0.0": + version: 3.0.0 + resolution: "abort-controller@npm:3.0.0" dependencies: - mime-types: "npm:~2.1.34" - negotiator: "npm:0.6.3" - checksum: 10c0/3a35c5f5586cfb9a21163ca47a5f77ac34fa8ceb5d17d2fa2c0d81f41cbd7f8c6fa52c77e2c039acc0f4d09e71abdc51144246900f6bef5e3c4b333f77d89362 + event-target-shim: "npm:^5.0.0" + checksum: 10c0/90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5 + languageName: node + linkType: hard + +"abstract-logging@npm:^2.0.1": + version: 2.0.1 + resolution: "abstract-logging@npm:2.0.1" + checksum: 10c0/304879d9babcf6772260e5ddde632e6428e1f42f7a7a116d4689e97ad813a20e0ec2dd1e0a122f3617557f40091b9ca85735de4b48c17a2041268cb47b3f8ef1 languageName: node linkType: hard @@ -4178,7 +4115,7 @@ __metadata: languageName: node linkType: hard -"ajv-formats@npm:2.1.1": +"ajv-formats@npm:2.1.1, ajv-formats@npm:^2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" dependencies: @@ -4192,7 +4129,21 @@ __metadata: languageName: node linkType: hard -"ajv@npm:8.12.0, ajv@npm:^8.0.0": +"ajv-formats@npm:^3.0.1": + version: 3.0.1 + resolution: "ajv-formats@npm:3.0.1" + dependencies: + ajv: "npm:^8.0.0" + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 10c0/168d6bca1ea9f163b41c8147bae537e67bd963357a5488a1eaf3abe8baa8eec806d4e45f15b10767e6020679315c7e1e5e6803088dfb84efa2b4e9353b83dd0a + languageName: node + linkType: hard + +"ajv@npm:8.12.0": version: 8.12.0 resolution: "ajv@npm:8.12.0" dependencies: @@ -4216,6 +4167,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + "ansi-colors@npm:4.1.3, ansi-colors@npm:^4.1.1": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" @@ -4297,13 +4260,6 @@ __metadata: languageName: node linkType: hard -"append-field@npm:^1.0.0": - version: 1.0.0 - resolution: "append-field@npm:1.0.0" - checksum: 10c0/1b5abcc227e5179936a9e4f7e2af4769fa1f00eda85bbaed907f7964b0fd1f7d61f0f332b35337f391389ff13dd5310c2546ba670f8e5a743b23ec85185c73ef - languageName: node - linkType: hard - "aproba@npm:^1.0.3 || ^2.0.0": version: 2.0.0 resolution: "aproba@npm:2.0.0" @@ -4374,13 +4330,6 @@ __metadata: languageName: node linkType: hard -"array-flatten@npm:1.1.1": - version: 1.1.1 - resolution: "array-flatten@npm:1.1.1" - checksum: 10c0/806966c8abb2f858b08f5324d9d18d7737480610f3bd5d3498aaae6eb5efdc501a884ba019c9b4a8f02ff67002058749d05548fd42fa8643f02c9c7f22198b91 - languageName: node - linkType: hard - "array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": version: 3.1.7 resolution: "array-includes@npm:3.1.7" @@ -4528,6 +4477,13 @@ __metadata: languageName: node linkType: hard +"atomic-sleep@npm:^1.0.0": + version: 1.0.0 + resolution: "atomic-sleep@npm:1.0.0" + checksum: 10c0/e329a6665512736a9bbb073e1761b4ec102f7926cce35037753146a9db9c8104f5044c1662e4a863576ce544fb8be27cd2be6bc8c1a40147d03f31eb1cfb6e8a + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.5": version: 1.0.5 resolution: "available-typed-arrays@npm:1.0.5" @@ -4535,6 +4491,16 @@ __metadata: languageName: node linkType: hard +"avvio@npm:^8.3.0": + version: 8.4.0 + resolution: "avvio@npm:8.4.0" + dependencies: + "@fastify/error": "npm:^3.3.0" + fastq: "npm:^1.17.1" + checksum: 10c0/bea7f28e38b57755786852226f380ea087d572f8bbcfe14b59d1239551ef89cecc40229a6ac85e17af44c81a481d03280576586385e93d76bb9f2c5bc75c6067 + languageName: node + linkType: hard + "aws-xray-sdk-core@npm:^3.5.3": version: 3.5.3 resolution: "aws-xray-sdk-core@npm:3.5.3" @@ -4673,7 +4639,7 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.2, body-parser@npm:^1.20.0": +"body-parser@npm:^1.20.0": version: 1.20.2 resolution: "body-parser@npm:1.20.2" dependencies: @@ -4810,7 +4776,7 @@ __metadata: languageName: node linkType: hard -"busboy@npm:^1.0.0, busboy@npm:^1.6.0": +"busboy@npm:^1.6.0": version: 1.6.0 resolution: "busboy@npm:1.6.0" dependencies: @@ -5374,18 +5340,6 @@ __metadata: languageName: node linkType: hard -"concat-stream@npm:^1.5.2": - version: 1.6.2 - resolution: "concat-stream@npm:1.6.2" - dependencies: - buffer-from: "npm:^1.0.0" - inherits: "npm:^2.0.3" - readable-stream: "npm:^2.2.2" - typedarray: "npm:^0.0.6" - checksum: 10c0/2e9864e18282946dabbccb212c5c7cec0702745e3671679eb8291812ca7fd12023f7d8cb36493942a62f770ac96a7f90009dc5c82ad69893438371720fa92617 - languageName: node - linkType: hard - "config-chain@npm:^1.1.13": version: 1.1.13 resolution: "config-chain@npm:1.1.13" @@ -5417,16 +5371,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4": - version: 0.5.4 - resolution: "content-disposition@npm:0.5.4" - dependencies: - safe-buffer: "npm:5.2.1" - checksum: 10c0/bac0316ebfeacb8f381b38285dc691c9939bf0a78b0b7c2d5758acadad242d04783cee5337ba7d12a565a19075af1b3c11c728e1e4946de73c6ff7ce45f3f1bb - languageName: node - linkType: hard - -"content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10c0/b76ebed15c000aee4678c3707e0860cb6abd4e680a598c0a26e17f0bfae723ec9cc2802f0ff1bc6e4d80603719010431d2231018373d4dde10f9ccff9dadf5af @@ -5440,31 +5385,14 @@ __metadata: languageName: node linkType: hard -"cookie-parser@npm:^1.4.6": - version: 1.4.6 - resolution: "cookie-parser@npm:1.4.6" - dependencies: - cookie: "npm:0.4.1" - cookie-signature: "npm:1.0.6" - checksum: 10c0/9c2ade5459290802cd472a2d2a6e46fbd7de3e8514e02bfed5edfde892d77733c7f89d9d2015f752a9087680429b416972d7aba748bf6824e21eb680c8556383 - languageName: node - linkType: hard - -"cookie-signature@npm:1.0.6": - version: 1.0.6 - resolution: "cookie-signature@npm:1.0.6" - checksum: 10c0/b36fd0d4e3fef8456915fcf7742e58fbfcc12a17a018e0eb9501c9d5ef6893b596466f03b0564b81af29ff2538fd0aa4b9d54fe5ccbfb4c90ea50ad29fe2d221 - languageName: node - linkType: hard - -"cookie@npm:0.4.1": - version: 0.4.1 - resolution: "cookie@npm:0.4.1" - checksum: 10c0/4d7bc798df3d0f34035977949cd6b7d05bbab47d7dcb868667f460b578a550cd20dec923832b8a3a107ef35aba091a3975e14f79efacf6e39282dc0fed6db4a1 +"cookie-signature@npm:^1.1.0": + version: 1.2.1 + resolution: "cookie-signature@npm:1.2.1" + checksum: 10c0/1f71acf64931d7e7684aa228a0dad70162f6993b65b2957e076833cbd6f9a2f507b8d731b15e3895dce0e7ba4c63551f4686d1a3120199fe28060c41fd493a73 languageName: node linkType: hard -"cookie@npm:0.6.0": +"cookie@npm:^0.6.0": version: 0.6.0 resolution: "cookie@npm:0.6.0" checksum: 10c0/f2318b31af7a31b4ddb4a678d024514df5e705f9be5909a192d7f116cfb6d45cbacf96a473fa733faa95050e7cff26e7832bb3ef94751592f1387b71c8956686 @@ -5477,10 +5405,13 @@ __metadata: dependencies: "@apollo/server": "npm:^4.9.5" "@apollo/subgraph": "npm:^2.5.6" + "@as-integrations/fastify": "npm:^2.1.1" "@aws-sdk/client-s3": "npm:^3.440.0" "@aws-sdk/s3-request-presigner": "npm:^3.440.0" "@edgedb/generate": "github:CarsonF/edgedb-js#workspace=@edgedb/generate&head=temp-host" "@faker-js/faker": "npm:^8.2.0" + "@fastify/cookie": "npm:^9.4.0" + "@fastify/cors": "npm:^9.0.1" "@ffprobe-installer/ffprobe": "npm:^2.1.2" "@golevelup/nestjs-discovery": "npm:^4.0.0" "@leeoniya/ufuzzy": "npm:^1.0.11" @@ -5489,7 +5420,7 @@ __metadata: "@nestjs/common": "npm:^10.2.7" "@nestjs/core": "npm:^10.2.7" "@nestjs/graphql": "npm:^12.0.9" - "@nestjs/platform-express": "npm:^10.2.7" + "@nestjs/platform-fastify": "npm:^10.4.3" "@nestjs/schematics": "npm:^10.0.3" "@nestjs/testing": "npm:^10.2.7" "@patarapolw/prettyprint": "npm:^1.0.3" @@ -5502,9 +5433,6 @@ __metadata: "@seedcompany/scripture": "npm:^0.3.0" "@tsconfig/strictest": "npm:^2.0.2" "@types/common-tags": "npm:^1.8.3" - "@types/cookie-parser": "npm:^1.4.5" - "@types/express": "npm:^4.17.20" - "@types/express-serve-static-core": "npm:^4.17.39" "@types/ffprobe": "npm:^1.1.7" "@types/graphql-upload": "npm:^16.0.4" "@types/jest": "npm:^29.5.7" @@ -5527,7 +5455,6 @@ __metadata: cli-table3: "npm:^0.6.3" clipanion: "npm:^4.0.0-rc.3" common-tags: "npm:^1.8.2" - cookie-parser: "npm:^1.4.6" cypher-query-builder: "patch:cypher-query-builder@npm%3A6.0.4#~/.yarn/patches/cypher-query-builder-npm-6.0.4-e8707a5e8e.patch" debugger-is-attached: "npm:^1.2.0" dotenv: "npm:^16.3.1" @@ -5537,10 +5464,10 @@ __metadata: eslint-plugin-no-only-tests: "npm:^3.1.0" eslint-plugin-typescript-sort-keys: "npm:^2.3.0" execa: "npm:^8.0.1" - express: "npm:^4.18.2" extensionless: "npm:^1.7.0" fast-safe-stringify: "npm:^2.1.1" fastest-levenshtein: "npm:^1.0.16" + fastify: "npm:^4.28.1" file-type: "npm:^18.6.0" glob: "npm:^10.3.10" got: "npm:^14.3.0" @@ -5609,14 +5536,14 @@ __metadata: languageName: node linkType: hard -"core-util-is@npm:^1.0.3, core-util-is@npm:~1.0.0": +"core-util-is@npm:^1.0.3": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 languageName: node linkType: hard -"cors@npm:2.8.5, cors@npm:^2.8.5": +"cors@npm:^2.8.5": version: 2.8.5 resolution: "cors@npm:2.8.5" dependencies: @@ -6208,13 +6135,6 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:~1.0.2": - version: 1.0.2 - resolution: "encodeurl@npm:1.0.2" - checksum: 10c0/f6c2387379a9e7c1156c1c3d4f9cb7bb11cf16dd4c1682e1f6746512564b053df5781029b6061296832b59fb22f459dbe250386d217c2f6e203601abb2ee0bec - languageName: node - linkType: hard - "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -6408,13 +6328,6 @@ __metadata: languageName: node linkType: hard -"escape-html@npm:~1.0.3": - version: 1.0.3 - resolution: "escape-html@npm:1.0.3" - checksum: 10c0/524c739d776b36c3d29fa08a22e03e8824e3b2fd57500e5e44ecf3cc4707c34c60f9ca0781c0e33d191f2991161504c295e98f68c78fe7baa6e57081ec6ac0a3 - languageName: node - linkType: hard - "escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -6739,10 +6652,10 @@ __metadata: languageName: node linkType: hard -"etag@npm:~1.8.1": - version: 1.8.1 - resolution: "etag@npm:1.8.1" - checksum: 10c0/12be11ef62fb9817314d790089a0a49fae4e1b50594135dcb8076312b7d7e470884b5100d249b28c18581b7fd52f8b485689ffae22a11ed9ec17377a33a08f84 +"event-target-shim@npm:^5.0.0": + version: 5.0.1 + resolution: "event-target-shim@npm:5.0.1" + checksum: 10c0/0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b languageName: node linkType: hard @@ -6753,6 +6666,13 @@ __metadata: languageName: node linkType: hard +"events@npm:^3.3.0": + version: 3.3.0 + resolution: "events@npm:3.3.0" + checksum: 10c0/d6b6f2adbccbcda74ddbab52ed07db727ef52e31a61ed26db9feb7dc62af7fc8e060defa65e5f8af9449b86b52cc1a1f6a79f2eafcf4e62add2b7a1fa4a432f6 + languageName: node + linkType: hard + "execa@npm:7.2.0": version: 7.2.0 resolution: "execa@npm:7.2.0" @@ -6848,45 +6768,6 @@ __metadata: languageName: node linkType: hard -"express@npm:4.19.2, express@npm:^4.17.1, express@npm:^4.18.2": - version: 4.19.2 - resolution: "express@npm:4.19.2" - dependencies: - accepts: "npm:~1.3.8" - array-flatten: "npm:1.1.1" - body-parser: "npm:1.20.2" - content-disposition: "npm:0.5.4" - content-type: "npm:~1.0.4" - cookie: "npm:0.6.0" - cookie-signature: "npm:1.0.6" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - finalhandler: "npm:1.2.0" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - merge-descriptors: "npm:1.0.1" - methods: "npm:~1.1.2" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.7" - proxy-addr: "npm:~2.0.7" - qs: "npm:6.11.0" - range-parser: "npm:~1.2.1" - safe-buffer: "npm:5.2.1" - send: "npm:0.18.0" - serve-static: "npm:1.15.0" - setprototypeof: "npm:1.2.0" - statuses: "npm:2.0.1" - type-is: "npm:~1.6.18" - utils-merge: "npm:1.0.1" - vary: "npm:~1.1.2" - checksum: 10c0/e82e2662ea9971c1407aea9fc3c16d6b963e55e3830cd0ef5e00b533feda8b770af4e3be630488ef8a752d7c75c4fcefb15892868eeaafe7353cb9e3e269fdcb - languageName: node - linkType: hard - "extensionless@npm:^1.7.0": version: 1.7.0 resolution: "extensionless@npm:1.7.0" @@ -6905,6 +6786,20 @@ __metadata: languageName: node linkType: hard +"fast-content-type-parse@npm:^1.1.0": + version: 1.1.0 + resolution: "fast-content-type-parse@npm:1.1.0" + checksum: 10c0/882bf990fa5d64be1825ce183818db43900ece0d7ef184cb9409bae8ed1001acbe536a657b1496382cb3e308e71ab39cc399bbdae70cba1745eecaeca4e55384 + languageName: node + linkType: hard + +"fast-decode-uri-component@npm:^1.0.1": + version: 1.0.1 + resolution: "fast-decode-uri-component@npm:1.0.1" + checksum: 10c0/039d50c2e99d64f999c3f2126c23fbf75a04a4117e218a149ca0b1d2aeb8c834b7b19d643b9d35d4eabce357189a6a94085f78cf48869e6e26cc59b036284bc3 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -6939,6 +6834,21 @@ __metadata: languageName: node linkType: hard +"fast-json-stringify@npm:^5.7.0, fast-json-stringify@npm:^5.8.0": + version: 5.16.1 + resolution: "fast-json-stringify@npm:5.16.1" + dependencies: + "@fastify/merge-json-schemas": "npm:^0.1.0" + ajv: "npm:^8.10.0" + ajv-formats: "npm:^3.0.1" + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^2.1.0" + json-schema-ref-resolver: "npm:^1.0.1" + rfdc: "npm:^1.2.0" + checksum: 10c0/bbf955d9912fb827dff0e097fdbff3c11aec540ea8019a19593a16224cac70d49d0cebd98e412843fc72259184f73a78a45e63040d3c44349f4735a492f2f1a4 + languageName: node + linkType: hard + "fast-levenshtein@npm:^2.0.6": version: 2.0.6 resolution: "fast-levenshtein@npm:2.0.6" @@ -6946,6 +6856,22 @@ __metadata: languageName: node linkType: hard +"fast-querystring@npm:^1.0.0": + version: 1.1.2 + resolution: "fast-querystring@npm:1.1.2" + dependencies: + fast-decode-uri-component: "npm:^1.0.1" + checksum: 10c0/e8223273a9b199722f760f5a047a77ad049a14bd444b821502cb8218f5925e3a5fffb56b64389bca73ab2ac6f1aa7aebbe4e203e5f6e53ff5978de97c0fde4e3 + languageName: node + linkType: hard + +"fast-redact@npm:^3.1.1": + version: 3.5.0 + resolution: "fast-redact@npm:3.5.0" + checksum: 10c0/7e2ce4aad6e7535e0775bf12bd3e4f2e53d8051d8b630e0fa9e67f68cb0b0e6070d2f7a94b1d0522ef07e32f7c7cda5755e2b677a6538f1e9070ca053c42343a + languageName: node + linkType: hard + "fast-safe-stringify@npm:2.1.1, fast-safe-stringify@npm:^2.1.1": version: 2.1.1 resolution: "fast-safe-stringify@npm:2.1.1" @@ -6953,6 +6879,20 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^2.0.0, fast-uri@npm:^2.1.0": + version: 2.4.0 + resolution: "fast-uri@npm:2.4.0" + checksum: 10c0/300453cfe2f7d5ec16be0f2c8dc5b280edbaca59440b2deb4ab56ac0f584637179e9ee7539d0b70ef0fce9608245ebfa75307c84fa4829b1065c3b7ef7dcf706 + languageName: node + linkType: hard + +"fast-uri@npm:^3.0.1": + version: 3.0.2 + resolution: "fast-uri@npm:3.0.2" + checksum: 10c0/8cdd3da7b4022a037d348d587d55caff74b7e4f862bbdd2cc35c1e6e3f97d0aedb567894d44c57ee8798d3192cceb97dcf41dbdabfa07dd2842a0474a6c6eeef + languageName: node + linkType: hard + "fast-xml-parser@npm:4.4.1": version: 4.4.1 resolution: "fast-xml-parser@npm:4.4.1" @@ -6971,12 +6911,43 @@ __metadata: languageName: node linkType: hard -"fastq@npm:^1.6.0": - version: 1.15.0 - resolution: "fastq@npm:1.15.0" +"fastify-plugin@npm:^4.0.0, fastify-plugin@npm:^4.4.0": + version: 4.5.1 + resolution: "fastify-plugin@npm:4.5.1" + checksum: 10c0/f58f79cd9d3c88fd7f79a3270276c6339fc57bbe72ef14d20b73779193c404e317ac18e8eae2c5071b3909ebee45d7eb6871da4e65464ac64ed0d9746b4e9b9f + languageName: node + linkType: hard + +"fastify@npm:4.28.1, fastify@npm:^4.28.1": + version: 4.28.1 + resolution: "fastify@npm:4.28.1" + dependencies: + "@fastify/ajv-compiler": "npm:^3.5.0" + "@fastify/error": "npm:^3.4.0" + "@fastify/fast-json-stringify-compiler": "npm:^4.3.0" + abstract-logging: "npm:^2.0.1" + avvio: "npm:^8.3.0" + fast-content-type-parse: "npm:^1.1.0" + fast-json-stringify: "npm:^5.8.0" + find-my-way: "npm:^8.0.0" + light-my-request: "npm:^5.11.0" + pino: "npm:^9.0.0" + process-warning: "npm:^3.0.0" + proxy-addr: "npm:^2.0.7" + rfdc: "npm:^1.3.0" + secure-json-parse: "npm:^2.7.0" + semver: "npm:^7.5.4" + toad-cache: "npm:^3.3.0" + checksum: 10c0/9c212e9a72c42a27ebc9b0bc7fda8f94ff208250158093374942b0e156a3f55fa848c926921f99bdf7f38f6f8103ac28ecc72cc507f33893cd121ce4f3eda069 + languageName: node + linkType: hard + +"fastq@npm:^1.17.1, fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" dependencies: reusify: "npm:^1.0.4" - checksum: 10c0/5ce4f83afa5f88c9379e67906b4d31bc7694a30826d6cc8d0f0473c966929017fda65c2174b0ec89f064ede6ace6c67f8a4fe04cef42119b6a55b0d465554c24 + checksum: 10c0/1095f16cea45fb3beff558bb3afa74ca7a9250f5a670b65db7ed585f92b4b48381445cd328b3d87323da81e43232b5d5978a8201bde84e0cd514310f1ea6da34 languageName: node linkType: hard @@ -7034,18 +7005,14 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" +"find-my-way@npm:^8.0.0": + version: 8.2.2 + resolution: "find-my-way@npm:8.2.2" dependencies: - debug: "npm:2.6.9" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - statuses: "npm:2.0.1" - unpipe: "npm:~1.0.0" - checksum: 10c0/64b7e5ff2ad1fcb14931cd012651631b721ce657da24aedb5650ddde9378bf8e95daa451da43398123f5de161a81e79ff5affe4f9f2a6d2df4a813d6d3e254b7 + fast-deep-equal: "npm:^3.1.3" + fast-querystring: "npm:^1.0.0" + safe-regex2: "npm:^3.1.0" + checksum: 10c0/ce462b2033e08a82fa79b837e4ef9e637d5f3e6763564631ad835b4e50b22e2123c0bf27c4fe6b02bc4006cd7949c0351d2b6b6f32248e839b10bdcbd3a3269f languageName: node linkType: hard @@ -7157,13 +7124,6 @@ __metadata: languageName: node linkType: hard -"fresh@npm:0.5.2": - version: 0.5.2 - resolution: "fresh@npm:0.5.2" - checksum: 10c0/c6d27f3ed86cc5b601404822f31c900dd165ba63fff8152a3ef714e2012e7535027063bc67ded4cb5b3a49fa596495d46cacd9f47d6328459cf570f08b7d9e5a - languageName: node - linkType: hard - "fs-capacitor@npm:^8.0.0": version: 8.0.0 resolution: "fs-capacitor@npm:8.0.0" @@ -8401,13 +8361,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: 10c0/18b5be6669be53425f0b84098732670ed4e727e3af33bc7f948aac01782110eb9a18b3b329c5323bcdd3acdaae547ee077d3951317e7f133bff7105264b3003d - languageName: node - linkType: hard - "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -9059,6 +9012,15 @@ __metadata: languageName: node linkType: hard +"json-schema-ref-resolver@npm:^1.0.1": + version: 1.0.1 + resolution: "json-schema-ref-resolver@npm:1.0.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + checksum: 10c0/aa89d88108c0109ae35b913c89c132fb50c00f3b99fc8a8309b524b9e3a6a77414f19a6a35a1253871462984cbabc74279ebbd9bf103c6629fb7b37c9fb59bcf + languageName: node + linkType: hard + "json-schema-traverse@npm:^0.4.1": version: 0.4.1 resolution: "json-schema-traverse@npm:0.4.1" @@ -9264,6 +9226,28 @@ __metadata: languageName: node linkType: hard +"light-my-request@npm:6.0.0": + version: 6.0.0 + resolution: "light-my-request@npm:6.0.0" + dependencies: + cookie: "npm:^0.6.0" + process-warning: "npm:^4.0.0" + set-cookie-parser: "npm:^2.6.0" + checksum: 10c0/521fde58b0e52d05cc38b23a7ef5b9b7ce35b9a943a4e5a27eb219de2ac08ff566bfaa194b8db3bf99cf0800adc5fe5ed9c0c604c18fce8a0d4554e2237ee89b + languageName: node + linkType: hard + +"light-my-request@npm:^5.11.0": + version: 5.13.0 + resolution: "light-my-request@npm:5.13.0" + dependencies: + cookie: "npm:^0.6.0" + process-warning: "npm:^3.0.0" + set-cookie-parser: "npm:^2.4.1" + checksum: 10c0/460117f30e09c2eec3a62e6ba4264111a28b881fdd0ea79493ed889ebf69a56482d603f0685a0e2930b5ec53205d28c46f3cdf13d7888914852eb7c4dac83285 + languageName: node + linkType: hard + "lilconfig@npm:2.1.0": version: 2.1.0 resolution: "lilconfig@npm:2.1.0" @@ -9652,13 +9636,6 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 10c0/b67d07bd44cfc45cebdec349bb6e1f7b077ee2fd5beb15d1f7af073849208cb6f144fe403e29a36571baf3f4e86469ac39acf13c318381e958e186b2766f54ec - languageName: node - linkType: hard - "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -9673,13 +9650,6 @@ __metadata: languageName: node linkType: hard -"methods@npm:~1.1.2": - version: 1.1.2 - resolution: "methods@npm:1.1.2" - checksum: 10c0/bdf7cc72ff0a33e3eede03708c08983c4d7a173f91348b4b1e4f47d4cdbf734433ad971e7d1e8c77247d9e5cd8adb81ea4c67b0a2db526b758b2233d7814b8b2 - languageName: node - linkType: hard - "micromatch@npm:4.0.5, micromatch@npm:^4.0.4": version: 4.0.5 resolution: "micromatch@npm:4.0.5" @@ -9697,7 +9667,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:~2.1.24": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -9706,15 +9676,6 @@ __metadata: languageName: node linkType: hard -"mime@npm:1.6.0": - version: 1.6.0 - resolution: "mime@npm:1.6.0" - bin: - mime: cli.js - checksum: 10c0/b92cd0adc44888c7135a185bfd0dddc42c32606401c72896a842ae15da71eb88858f17669af41e498b463cd7eb998f7b48939a25b08374c7924a9c8a6f8a81b0 - languageName: node - linkType: hard - "mime@npm:^2.4.6": version: 2.6.0 resolution: "mime@npm:2.6.0" @@ -10316,17 +10277,6 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^0.5.4": - version: 0.5.6 - resolution: "mkdirp@npm:0.5.6" - dependencies: - minimist: "npm:^1.2.6" - bin: - mkdirp: bin/cmd.js - checksum: 10c0/e2e2be789218807b58abced04e7b49851d9e46e88a2f9539242cc8a92c9b5c3a0b9bab360bd3014e02a140fc4fbc58e31176c408b493f8a2a6f4986bd7527b01 - languageName: node - linkType: hard - "mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" @@ -10345,6 +10295,15 @@ __metadata: languageName: node linkType: hard +"mnemonist@npm:0.39.6": + version: 0.39.6 + resolution: "mnemonist@npm:0.39.6" + dependencies: + obliterator: "npm:^2.0.1" + checksum: 10c0/a538945ea547976136ee6e16f224c0a50983143619941f6c4d2c82159e36eb6f8ee93d69d3a1267038fc5b16f88e2d43390023de10dfb145fa15c5e2befa1cdf + languageName: node + linkType: hard + "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" @@ -10359,28 +10318,13 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.3, ms@npm:^2.1.1": +"ms@npm:^2.1.1": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 languageName: node linkType: hard -"multer@npm:1.4.4-lts.1": - version: 1.4.4-lts.1 - resolution: "multer@npm:1.4.4-lts.1" - dependencies: - append-field: "npm:^1.0.0" - busboy: "npm:^1.0.0" - concat-stream: "npm:^1.5.2" - mkdirp: "npm:^0.5.4" - object-assign: "npm:^4.1.1" - type-is: "npm:^1.6.4" - xtend: "npm:^4.0.0" - checksum: 10c0/63277d3483869f424274ef8ce6ab7ff4ce9d2c1cc69e707fc8b5d9b2b348ae6f742809e0b357a591dea885d147594bcd06528d3d6bbe32046115d4a7e126b954 - languageName: node - linkType: hard - "mute-stream@npm:0.0.8": version: 0.0.8 resolution: "mute-stream@npm:0.0.8" @@ -10411,7 +10355,7 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:0.6.3, negotiator@npm:^0.6.3": +"negotiator@npm:^0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 @@ -10735,6 +10679,20 @@ __metadata: languageName: node linkType: hard +"obliterator@npm:^2.0.1": + version: 2.0.4 + resolution: "obliterator@npm:2.0.4" + checksum: 10c0/ff2c10d4de7d62cd1d588b4d18dfc42f246c9e3a259f60d5716f7f88e5b3a3f79856b3207db96ec9a836a01d0958a21c15afa62a3f4e73a1e0b75f2c2f6bab40 + languageName: node + linkType: hard + +"on-exit-leak-free@npm:^2.1.0": + version: 2.1.2 + resolution: "on-exit-leak-free@npm:2.1.2" + checksum: 10c0/faea2e1c9d696ecee919026c32be8d6a633a7ac1240b3b87e944a380e8a11dc9c95c4a1f8fb0568de7ab8db3823e790f12bda45296b1d111e341aad3922a0570 + languageName: node + linkType: hard + "on-finished@npm:2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" @@ -10995,13 +10953,6 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:~1.3.3": - version: 1.3.3 - resolution: "parseurl@npm:1.3.3" - checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 - languageName: node - linkType: hard - "path-browserify@npm:^1.0.1": version: 1.0.1 resolution: "path-browserify@npm:1.0.1" @@ -11061,13 +11012,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 10c0/50a1ddb1af41a9e68bd67ca8e331a705899d16fb720a1ea3a41e310480948387daf603abb14d7b0826c58f10146d49050a1291ba6a82b78a382d1c02c0b8f905 - languageName: node - linkType: hard - "path-to-regexp@npm:3.2.0": version: 3.2.0 resolution: "path-to-regexp@npm:3.2.0" @@ -11075,6 +11019,20 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:3.3.0": + version: 3.3.0 + resolution: "path-to-regexp@npm:3.3.0" + checksum: 10c0/ffa0ebe7088d38d435a8d08b0fe6e8c93ceb2a81a65d4dd1d9a538f52e09d5e3474ed5f553cb3b180d894b0caa10698a68737ab599fd1e56b4663d1a64c9f77b + languageName: node + linkType: hard + +"path-to-regexp@npm:^6.3.0": + version: 6.3.0 + resolution: "path-to-regexp@npm:6.3.0" + checksum: 10c0/73b67f4638b41cde56254e6354e46ae3a2ebc08279583f6af3d96fe4664fc75788f74ed0d18ca44fa4a98491b69434f9eee73b97bb5314bd1b5adb700f5c18d6 + languageName: node + linkType: hard + "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -11119,6 +11077,44 @@ __metadata: languageName: node linkType: hard +"pino-abstract-transport@npm:^1.2.0": + version: 1.2.0 + resolution: "pino-abstract-transport@npm:1.2.0" + dependencies: + readable-stream: "npm:^4.0.0" + split2: "npm:^4.0.0" + checksum: 10c0/b4ab59529b7a91f488440147fc58ee0827a6c1c5ca3627292339354b1381072c1a6bfa9b46d03ad27872589e8477ecf74da12cf286e1e6b665ac64a3b806bf07 + languageName: node + linkType: hard + +"pino-std-serializers@npm:^7.0.0": + version: 7.0.0 + resolution: "pino-std-serializers@npm:7.0.0" + checksum: 10c0/73e694d542e8de94445a03a98396cf383306de41fd75ecc07085d57ed7a57896198508a0dec6eefad8d701044af21eb27253ccc352586a03cf0d4a0bd25b4133 + languageName: node + linkType: hard + +"pino@npm:^9.0.0": + version: 9.4.0 + resolution: "pino@npm:9.4.0" + dependencies: + atomic-sleep: "npm:^1.0.0" + fast-redact: "npm:^3.1.1" + on-exit-leak-free: "npm:^2.1.0" + pino-abstract-transport: "npm:^1.2.0" + pino-std-serializers: "npm:^7.0.0" + process-warning: "npm:^4.0.0" + quick-format-unescaped: "npm:^4.0.3" + real-require: "npm:^0.2.0" + safe-stable-stringify: "npm:^2.3.1" + sonic-boom: "npm:^4.0.1" + thread-stream: "npm:^3.0.0" + bin: + pino: bin.js + checksum: 10c0/12a3d74968964d92b18ca7d6095a3c5b86478dc22264a37486d64e102085ed08820fcbe75e640acc3542fdf2937a34e5050b624f98e6ac62dd10f5e1328058a2 + languageName: node + linkType: hard + "pirates@npm:^4.0.4": version: 4.0.6 resolution: "pirates@npm:4.0.6" @@ -11239,10 +11235,24 @@ __metadata: languageName: node linkType: hard -"process-nextick-args@npm:~2.0.0": - version: 2.0.1 - resolution: "process-nextick-args@npm:2.0.1" - checksum: 10c0/bec089239487833d46b59d80327a1605e1c5287eaad770a291add7f45fda1bb5e28b38e0e061add0a1d0ee0984788ce74fa394d345eed1c420cacf392c554367 +"process-warning@npm:^3.0.0": + version: 3.0.0 + resolution: "process-warning@npm:3.0.0" + checksum: 10c0/60f3c8ddee586f0706c1e6cb5aa9c86df05774b9330d792d7c8851cf0031afd759d665404d07037e0b4901b55c44a423f07bdc465c63de07d8d23196bb403622 + languageName: node + linkType: hard + +"process-warning@npm:^4.0.0": + version: 4.0.0 + resolution: "process-warning@npm:4.0.0" + checksum: 10c0/5312a72b69d37a1b82ad03f3dfa0090dab3804a8fd995d06c28e3c002852bd82f5584217d9f4a3f197892bb2afc22d57e2c662c7e906b5abb48c0380c7b0880d + languageName: node + linkType: hard + +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: 10c0/40c3ce4b7e6d4b8c3355479df77aeed46f81b279818ccdc500124e6a5ab882c0cc81ff7ea16384873a95a74c4570b01b120f287abbdd4c877931460eca6084b3 languageName: node linkType: hard @@ -11284,7 +11294,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": +"proxy-addr@npm:^2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -11352,6 +11362,13 @@ __metadata: languageName: node linkType: hard +"quick-format-unescaped@npm:^4.0.3": + version: 4.0.4 + resolution: "quick-format-unescaped@npm:4.0.4" + checksum: 10c0/fe5acc6f775b172ca5b4373df26f7e4fd347975578199e7d74b2ae4077f0af05baa27d231de1e80e8f72d88275ccc6028568a7a8c9ee5e7368ace0e18eff93a4 + languageName: node + linkType: hard + "quick-lru@npm:^5.1.1": version: 5.1.1 resolution: "quick-lru@npm:5.1.1" @@ -11359,13 +11376,6 @@ __metadata: languageName: node linkType: hard -"range-parser@npm:~1.2.1": - version: 1.2.1 - resolution: "range-parser@npm:1.2.1" - checksum: 10c0/96c032ac2475c8027b7a4e9fe22dc0dfe0f6d90b85e496e0f016fbdb99d6d066de0112e680805075bd989905e2123b3b3d002765149294dce0c1f7f01fcc2ea0 - languageName: node - linkType: hard - "raw-body@npm:2.5.2": version: 2.5.2 resolution: "raw-body@npm:2.5.2" @@ -11413,21 +11423,6 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.2.2": - version: 2.3.8 - resolution: "readable-stream@npm:2.3.8" - dependencies: - core-util-is: "npm:~1.0.0" - inherits: "npm:~2.0.3" - isarray: "npm:~1.0.0" - process-nextick-args: "npm:~2.0.0" - safe-buffer: "npm:~5.1.1" - string_decoder: "npm:~1.1.1" - util-deprecate: "npm:~1.0.1" - checksum: 10c0/7efdb01f3853bc35ac62ea25493567bf588773213f5f4a79f9c365e1ad13bab845ac0dae7bc946270dc40c3929483228415e92a3fc600cc7e4548992f41ee3fa - languageName: node - linkType: hard - "readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" @@ -11439,6 +11434,19 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:^4.0.0": + version: 4.5.2 + resolution: "readable-stream@npm:4.5.2" + dependencies: + abort-controller: "npm:^3.0.0" + buffer: "npm:^6.0.3" + events: "npm:^3.3.0" + process: "npm:^0.11.10" + string_decoder: "npm:^1.3.0" + checksum: 10c0/a2c80e0e53aabd91d7df0330929e32d0a73219f9477dbbb18472f6fdd6a11a699fc5d172a1beff98d50eae4f1496c950ffa85b7cc2c4c196963f289a5f39275d + languageName: node + linkType: hard + "readable-web-to-node-stream@npm:^3.0.2": version: 3.0.2 resolution: "readable-web-to-node-stream@npm:3.0.2" @@ -11457,6 +11465,13 @@ __metadata: languageName: node linkType: hard +"real-require@npm:^0.2.0": + version: 0.2.0 + resolution: "real-require@npm:0.2.0" + checksum: 10c0/23eea5623642f0477412ef8b91acd3969015a1501ed34992ada0e3af521d3c865bb2fe4cdbfec5fe4b505f6d1ef6a03e5c3652520837a8c3b53decff7e74b6a0 + languageName: node + linkType: hard + "rechoir@npm:^0.6.2": version: 0.6.2 resolution: "rechoir@npm:0.6.2" @@ -11667,6 +11682,13 @@ __metadata: languageName: node linkType: hard +"ret@npm:~0.4.0": + version: 0.4.3 + resolution: "ret@npm:0.4.3" + checksum: 10c0/93e4e81cf393ebbafa1a26816e0b22ad0e2539c10e267d46ce8754c3f385b7aa839772ee1f83fdd2487b43d1081f29af41a19160e85456311f6f1778e14ba66b + languageName: node + linkType: hard + "retry@npm:0.13.1, retry@npm:^0.13.1": version: 0.13.1 resolution: "retry@npm:0.13.1" @@ -11688,10 +11710,10 @@ __metadata: languageName: node linkType: hard -"rfdc@npm:^1.3.0": - version: 1.3.0 - resolution: "rfdc@npm:1.3.0" - checksum: 10c0/a17fd7b81f42c7ae4cb932abd7b2f677b04cc462a03619fb46945ae1ccae17c3bc87c020ffdde1751cbfa8549860a2883486fdcabc9b9de3f3108af32b69a667 +"rfdc@npm:^1.2.0, rfdc@npm:^1.3.0": + version: 1.4.1 + resolution: "rfdc@npm:1.4.1" + checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7 languageName: node linkType: hard @@ -11781,20 +11803,13 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 languageName: node linkType: hard -"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": - version: 5.1.2 - resolution: "safe-buffer@npm:5.1.2" - checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 - languageName: node - linkType: hard - "safe-regex-test@npm:^1.0.0": version: 1.0.0 resolution: "safe-regex-test@npm:1.0.0" @@ -11806,6 +11821,15 @@ __metadata: languageName: node linkType: hard +"safe-regex2@npm:^3.1.0": + version: 3.1.0 + resolution: "safe-regex2@npm:3.1.0" + dependencies: + ret: "npm:~0.4.0" + checksum: 10c0/5e5e7f9f116ddfd324b1fdc65ad4470937eebc8883d34669ce8c5afbda64f1954e5e4c2e754ef6281e5f6762e0b8c4e20fb9eec4d47355526f8cc1f6a9764624 + languageName: node + linkType: hard + "safe-stable-stringify@npm:^2.3.1": version: 2.4.3 resolution: "safe-stable-stringify@npm:2.4.3" @@ -11838,6 +11862,13 @@ __metadata: languageName: node linkType: hard +"secure-json-parse@npm:^2.7.0": + version: 2.7.0 + resolution: "secure-json-parse@npm:2.7.0" + checksum: 10c0/f57eb6a44a38a3eeaf3548228585d769d788f59007454214fab9ed7f01fbf2e0f1929111da6db28cf0bcc1a2e89db5219a59e83eeaec3a54e413a0197ce879e4 + languageName: node + linkType: hard + "selderee@npm:^0.11.0": version: 0.11.0 resolution: "selderee@npm:0.11.0" @@ -11888,39 +11919,6 @@ __metadata: languageName: node linkType: hard -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" - dependencies: - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - mime: "npm:1.6.0" - ms: "npm:2.1.3" - on-finished: "npm:2.4.1" - range-parser: "npm:~1.2.1" - statuses: "npm:2.0.1" - checksum: 10c0/0eb134d6a51fc13bbcb976a1f4214ea1e33f242fae046efc311e80aff66c7a43603e26a79d9d06670283a13000e51be6e0a2cb80ff0942eaf9f1cd30b7ae736a - languageName: node - linkType: hard - -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" - dependencies: - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - parseurl: "npm:~1.3.3" - send: "npm:0.18.0" - checksum: 10c0/fa9f0e21a540a28f301258dfe1e57bb4f81cd460d28f0e973860477dd4acef946a1f41748b5bd41c73b621bea2029569c935faa38578fd34cd42a9b4947088ba - languageName: node - linkType: hard - "set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" @@ -11928,6 +11926,13 @@ __metadata: languageName: node linkType: hard +"set-cookie-parser@npm:^2.4.1, set-cookie-parser@npm:^2.6.0": + version: 2.7.0 + resolution: "set-cookie-parser@npm:2.7.0" + checksum: 10c0/5ccb2d0389bda27631d57e44644319f0b77200e7c8bd1515824eb83dbd2d351864a29581f7e7f977a5aeb83c3ec9976e69b706a80ac654152fd26353011ffef4 + languageName: node + linkType: hard + "set-function-length@npm:^1.1.1": version: 1.1.1 resolution: "set-function-length@npm:1.1.1" @@ -12106,6 +12111,15 @@ __metadata: languageName: node linkType: hard +"sonic-boom@npm:^4.0.1": + version: 4.1.0 + resolution: "sonic-boom@npm:4.1.0" + dependencies: + atomic-sleep: "npm:^1.0.0" + checksum: 10c0/4c9e082db296fbfb02e22a1a9b8de8b82f5965697dda3fe7feadc4759bf25d1de0094e3c35f16e015bfdc00fad7b8cf15bef5b0144501a2a5c5b86efb5684096 + languageName: node + linkType: hard + "source-map-support@npm:0.5.13": version: 0.5.13 resolution: "source-map-support@npm:0.5.13" @@ -12140,6 +12154,13 @@ __metadata: languageName: node linkType: hard +"split2@npm:^4.0.0": + version: 4.2.0 + resolution: "split2@npm:4.2.0" + checksum: 10c0/b292beb8ce9215f8c642bb68be6249c5a4c7f332fc8ecadae7be5cbdf1ea95addc95f0459ef2e7ad9d45fd1064698a097e4eb211c83e772b49bc0ee423e91534 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -12307,15 +12328,6 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:~1.1.1": - version: 1.1.1 - resolution: "string_decoder@npm:1.1.1" - dependencies: - safe-buffer: "npm:~5.1.0" - checksum: 10c0/b4f89f3a92fd101b5653ca3c99550e07bdf9e13b35037e9e2a1c7b47cec4e55e06ff3fc468e314a0b5e80bfbaf65c1ca5a84978764884ae9413bec1fc6ca924e - languageName: node - linkType: hard - "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" @@ -12492,6 +12504,15 @@ __metadata: languageName: node linkType: hard +"thread-stream@npm:^3.0.0": + version: 3.1.0 + resolution: "thread-stream@npm:3.1.0" + dependencies: + real-require: "npm:^0.2.0" + checksum: 10c0/c36118379940b77a6ef3e6f4d5dd31e97b8210c3f7b9a54eb8fe6358ab173f6d0acfaf69b9c3db024b948c0c5fd2a7df93e2e49151af02076b35ada3205ec9a6 + languageName: node + linkType: hard + "through@npm:^2.3.6": version: 2.3.8 resolution: "through@npm:2.3.8" @@ -12538,6 +12559,13 @@ __metadata: languageName: node linkType: hard +"toad-cache@npm:^3.3.0": + version: 3.7.0 + resolution: "toad-cache@npm:3.7.0" + checksum: 10c0/7dae2782ee20b22c9798bb8b71dec7ec6a0091021d2ea9dd6e8afccab6b65b358fdba49a02209fac574499702e2c000660721516c87c2538d1b2c0ba03e8c0c3 + languageName: node + linkType: hard + "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" @@ -12747,6 +12775,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:2.7.0, tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.2": + version: 2.7.0 + resolution: "tslib@npm:2.7.0" + checksum: 10c0/469e1d5bf1af585742128827000711efa61010b699cb040ab1800bcd3ccdd37f63ec30642c9e07c4439c1db6e46345582614275daca3e0f4abae29b0083f04a6 + languageName: node + linkType: hard + "tslib@npm:^1.10.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -12754,13 +12789,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.2": - version: 2.7.0 - resolution: "tslib@npm:2.7.0" - checksum: 10c0/469e1d5bf1af585742128827000711efa61010b699cb040ab1800bcd3ccdd37f63ec30642c9e07c4439c1db6e46345582614275daca3e0f4abae29b0083f04a6 - languageName: node - linkType: hard - "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -12830,7 +12858,7 @@ __metadata: languageName: node linkType: hard -"type-is@npm:^1.6.4, type-is@npm:~1.6.18": +"type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" dependencies: @@ -12887,13 +12915,6 @@ __metadata: languageName: node linkType: hard -"typedarray@npm:^0.0.6": - version: 0.0.6 - resolution: "typedarray@npm:0.0.6" - checksum: 10c0/6005cb31df50eef8b1f3c780eb71a17925f3038a100d82f9406ac2ad1de5eb59f8e6decbdc145b3a1f8e5836e17b0c0002fb698b9fe2516b8f9f9ff602d36412 - languageName: node - linkType: hard - "typescript-transform-paths@npm:^3.4.6": version: 3.4.6 resolution: "typescript-transform-paths@npm:3.4.6" @@ -12989,7 +13010,7 @@ __metadata: languageName: node linkType: hard -"unpipe@npm:1.0.0, unpipe@npm:~1.0.0": +"unpipe@npm:1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" checksum: 10c0/193400255bd48968e5c5383730344fbb4fa114cdedfab26e329e50dd2d81b134244bb8a72c6ac1b10ab0281a58b363d06405632c9d49ca9dfd5e90cbd7d0f32c @@ -13033,20 +13054,13 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": +"util-deprecate@npm:^1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 languageName: node linkType: hard -"utils-merge@npm:1.0.1": - version: 1.0.1 - resolution: "utils-merge@npm:1.0.1" - checksum: 10c0/02ba649de1b7ca8854bfe20a82f1dfbdda3fb57a22ab4a8972a63a34553cf7aa51bc9081cf7e001b035b88186d23689d69e71b510e610a09a4c66f68aa95b672 - languageName: node - linkType: hard - "uuid@npm:9.0.1, uuid@npm:^9.0.0, uuid@npm:^9.0.1": version: 9.0.1 resolution: "uuid@npm:9.0.1" @@ -13113,7 +13127,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:~1.1.2": +"vary@npm:^1": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: 10c0/f15d588d79f3675135ba783c91a4083dcd290a2a5be9fcb6514220a1634e23df116847b1cc51f66bfb0644cf9353b2abb7815ae499bab06e46dd33c1a6bf1f4f @@ -13412,13 +13426,6 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.0": - version: 4.0.2 - resolution: "xtend@npm:4.0.2" - checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e - languageName: node - linkType: hard - "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" From d2c736bf9059595d4af4e0dbf36072fe00d95a69 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 23 Sep 2024 17:42:20 -0500 Subject: [PATCH 2/5] Enable compression for HTTP responses --- package.json | 1 + src/core/http/http.adapter.ts | 11 +++ yarn.lock | 158 ++++++++++++++++++++++++++++++++-- 3 files changed, 164 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 27701f5946..3490e26777 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@aws-sdk/client-s3": "^3.440.0", "@aws-sdk/s3-request-presigner": "^3.440.0", "@faker-js/faker": "^8.2.0", + "@fastify/compress": "^7.0.3", "@fastify/cookie": "^9.4.0", "@fastify/cors": "^9.0.1", "@ffprobe-installer/ffprobe": "^2.1.2", diff --git a/src/core/http/http.adapter.ts b/src/core/http/http.adapter.ts index c606100d98..93b91793e5 100644 --- a/src/core/http/http.adapter.ts +++ b/src/core/http/http.adapter.ts @@ -1,3 +1,4 @@ +import compression from '@fastify/compress'; import cookieParser from '@fastify/cookie'; import cors from '@fastify/cors'; // eslint-disable-next-line @seedcompany/no-restricted-imports @@ -6,6 +7,7 @@ import { FastifyAdapter, NestFastifyApplication, } from '@nestjs/platform-fastify'; +import * as zlib from 'node:zlib'; import { ConfigService } from '~/core/config/config.service'; import type { CookieOptions, CorsOptions, IResponse } from './types'; @@ -20,6 +22,15 @@ export class HttpAdapterHost extends HttpAdapterHostImpl {} export class HttpAdapter extends FastifyAdapter { async configure(app: NestFastifyApplication, config: ConfigService) { + await app.register(compression, { + brotliOptions: { + params: { + // This API returns text (JSON), so optimize for that + [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT, + }, + }, + }); + await app.register(cors, { // typecast to undo deep readonly ...(config.cors as CorsOptions), diff --git a/yarn.lock b/yarn.lock index 20f7f2b727..c5c76622d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1596,6 +1596,13 @@ __metadata: languageName: node linkType: hard +"@fastify/accept-negotiator@npm:^1.1.0": + version: 1.1.0 + resolution: "@fastify/accept-negotiator@npm:1.1.0" + checksum: 10c0/1cb9a298c992b812869158ddc6093557a877b30e5f77618a7afea985a0667c50bc7113593bf0f7f9dc9b82b94c16e8ab127a0afc3efde6677fd645539f6d08e5 + languageName: node + linkType: hard + "@fastify/ajv-compiler@npm:^3.5.0": version: 3.6.0 resolution: "@fastify/ajv-compiler@npm:3.6.0" @@ -1607,6 +1614,22 @@ __metadata: languageName: node linkType: hard +"@fastify/compress@npm:^7.0.3": + version: 7.0.3 + resolution: "@fastify/compress@npm:7.0.3" + dependencies: + "@fastify/accept-negotiator": "npm:^1.1.0" + fastify-plugin: "npm:^4.5.0" + mime-db: "npm:^1.52.0" + minipass: "npm:^7.0.2" + peek-stream: "npm:^1.1.3" + pump: "npm:^3.0.0" + pumpify: "npm:^2.0.1" + readable-stream: "npm:^4.5.2" + checksum: 10c0/0c914ca347944d4fb893c5d08503ae7d3f1ecc2ec6812b4b837753587009e0b6a13531c7f9cb86750ed891c8b0b728fc2e98b42a072a0153b4504686e41b6a16 + languageName: node + linkType: hard + "@fastify/cookie@npm:^9.4.0": version: 9.4.0 resolution: "@fastify/cookie@npm:9.4.0" @@ -5410,6 +5433,7 @@ __metadata: "@aws-sdk/s3-request-presigner": "npm:^3.440.0" "@edgedb/generate": "github:CarsonF/edgedb-js#workspace=@edgedb/generate&head=temp-host" "@faker-js/faker": "npm:^8.2.0" + "@fastify/compress": "npm:^7.0.3" "@fastify/cookie": "npm:^9.4.0" "@fastify/cors": "npm:^9.0.1" "@ffprobe-installer/ffprobe": "npm:^2.1.2" @@ -5536,7 +5560,7 @@ __metadata: languageName: node linkType: hard -"core-util-is@npm:^1.0.3": +"core-util-is@npm:^1.0.3, core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 @@ -6027,6 +6051,30 @@ __metadata: languageName: node linkType: hard +"duplexify@npm:^3.5.0": + version: 3.7.1 + resolution: "duplexify@npm:3.7.1" + dependencies: + end-of-stream: "npm:^1.0.0" + inherits: "npm:^2.0.1" + readable-stream: "npm:^2.0.0" + stream-shift: "npm:^1.0.0" + checksum: 10c0/59d1440c1b4e3a4db35ae96933392703ce83518db1828d06b9b6322920d6cbbf0b7159e88be120385fe459e77f1eb0c7622f26e9ec1f47c9ff05c2b35747dbd3 + languageName: node + linkType: hard + +"duplexify@npm:^4.1.1": + version: 4.1.3 + resolution: "duplexify@npm:4.1.3" + dependencies: + end-of-stream: "npm:^1.4.1" + inherits: "npm:^2.0.3" + readable-stream: "npm:^3.1.1" + stream-shift: "npm:^1.0.2" + checksum: 10c0/8a7621ae95c89f3937f982fe36d72ea997836a708471a75bb2a0eecde3330311b1e128a6dad510e0fd64ace0c56bff3484ed2e82af0e465600c82117eadfbda5 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -6144,7 +6192,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0": +"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.4 resolution: "end-of-stream@npm:1.4.4" dependencies: @@ -6911,7 +6959,7 @@ __metadata: languageName: node linkType: hard -"fastify-plugin@npm:^4.0.0, fastify-plugin@npm:^4.4.0": +"fastify-plugin@npm:^4.0.0, fastify-plugin@npm:^4.4.0, fastify-plugin@npm:^4.5.0": version: 4.5.1 resolution: "fastify-plugin@npm:4.5.1" checksum: 10c0/f58f79cd9d3c88fd7f79a3270276c6339fc57bbe72ef14d20b73779193c404e317ac18e8eae2c5071b3909ebee45d7eb6871da4e65464ac64ed0d9746b4e9b9f @@ -8361,6 +8409,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: 10c0/18b5be6669be53425f0b84098732670ed4e727e3af33bc7f948aac01782110eb9a18b3b329c5323bcdd3acdaae547ee077d3951317e7f133bff7105264b3003d + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -9667,6 +9722,13 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:^1.52.0": + version: 1.53.0 + resolution: "mime-db@npm:1.53.0" + checksum: 10c0/1dcc37ba8ed5d1c179f5c6f0837e8db19371d5f2ea3690c3c2f3fa8c3858f976851d3460b172b4dee78ebd606762cbb407aa398545fbacd539e519f858cd7bf4 + languageName: node + linkType: hard + "mime-types@npm:^2.1.12, mime-types@npm:~2.1.24": version: 2.1.35 resolution: "mime-types@npm:2.1.35" @@ -11054,6 +11116,17 @@ __metadata: languageName: node linkType: hard +"peek-stream@npm:^1.1.3": + version: 1.1.3 + resolution: "peek-stream@npm:1.1.3" + dependencies: + buffer-from: "npm:^1.0.0" + duplexify: "npm:^3.5.0" + through2: "npm:^2.0.3" + checksum: 10c0/3c35d1951b8640036f93b1b5628a90f849e49ca4f2e6aba393ff4978413931d9c491c83f71a92f878d5ea4c670af0bba04dfcfb79b310ead22601db7c1420e36 + languageName: node + linkType: hard + "picocolors@npm:^1.0.0": version: 1.0.0 resolution: "picocolors@npm:1.0.0" @@ -11235,6 +11308,13 @@ __metadata: languageName: node linkType: hard +"process-nextick-args@npm:~2.0.0": + version: 2.0.1 + resolution: "process-nextick-args@npm:2.0.1" + checksum: 10c0/bec089239487833d46b59d80327a1605e1c5287eaad770a291add7f45fda1bb5e28b38e0e061add0a1d0ee0984788ce74fa394d345eed1c420cacf392c554367 + languageName: node + linkType: hard + "process-warning@npm:^3.0.0": version: 3.0.0 resolution: "process-warning@npm:3.0.0" @@ -11314,6 +11394,17 @@ __metadata: languageName: node linkType: hard +"pumpify@npm:^2.0.1": + version: 2.0.1 + resolution: "pumpify@npm:2.0.1" + dependencies: + duplexify: "npm:^4.1.1" + inherits: "npm:^2.0.3" + pump: "npm:^3.0.0" + checksum: 10c0/f9c12190dc65f8c347fe82e993708e4d14ce82c96f7cbd24b52f488cfa4dbc2ebbcc49e0f54655f1ca118fea59ddeec6ca5a34ef45558c8bb1de2f1ffa307198 + languageName: node + linkType: hard + "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -11423,7 +11514,22 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": +"readable-stream@npm:^2.0.0, readable-stream@npm:~2.3.6": + version: 2.3.8 + resolution: "readable-stream@npm:2.3.8" + dependencies: + core-util-is: "npm:~1.0.0" + inherits: "npm:~2.0.3" + isarray: "npm:~1.0.0" + process-nextick-args: "npm:~2.0.0" + safe-buffer: "npm:~5.1.1" + string_decoder: "npm:~1.1.1" + util-deprecate: "npm:~1.0.1" + checksum: 10c0/7efdb01f3853bc35ac62ea25493567bf588773213f5f4a79f9c365e1ad13bab845ac0dae7bc946270dc40c3929483228415e92a3fc600cc7e4548992f41ee3fa + languageName: node + linkType: hard + +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -11434,7 +11540,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^4.0.0": +"readable-stream@npm:^4.0.0, readable-stream@npm:^4.5.2": version: 4.5.2 resolution: "readable-stream@npm:4.5.2" dependencies: @@ -11810,6 +11916,13 @@ __metadata: languageName: node linkType: hard +"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": + version: 5.1.2 + resolution: "safe-buffer@npm:5.1.2" + checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 + languageName: node + linkType: hard + "safe-regex-test@npm:^1.0.0": version: 1.0.0 resolution: "safe-regex-test@npm:1.0.0" @@ -12214,6 +12327,13 @@ __metadata: languageName: node linkType: hard +"stream-shift@npm:^1.0.0, stream-shift@npm:^1.0.2": + version: 1.0.3 + resolution: "stream-shift@npm:1.0.3" + checksum: 10c0/939cd1051ca750d240a0625b106a2b988c45fb5a3be0cebe9a9858cb01bc1955e8c7b9fac17a9462976bea4a7b704e317c5c2200c70f0ca715a3363b9aa4fd3b + languageName: node + linkType: hard + "streamsearch@npm:^1.1.0": version: 1.1.0 resolution: "streamsearch@npm:1.1.0" @@ -12328,6 +12448,15 @@ __metadata: languageName: node linkType: hard +"string_decoder@npm:~1.1.1": + version: 1.1.1 + resolution: "string_decoder@npm:1.1.1" + dependencies: + safe-buffer: "npm:~5.1.0" + checksum: 10c0/b4f89f3a92fd101b5653ca3c99550e07bdf9e13b35037e9e2a1c7b47cec4e55e06ff3fc468e314a0b5e80bfbaf65c1ca5a84978764884ae9413bec1fc6ca924e + languageName: node + linkType: hard + "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" @@ -12513,6 +12642,16 @@ __metadata: languageName: node linkType: hard +"through2@npm:^2.0.3": + version: 2.0.5 + resolution: "through2@npm:2.0.5" + dependencies: + readable-stream: "npm:~2.3.6" + xtend: "npm:~4.0.1" + checksum: 10c0/cbfe5b57943fa12b4f8c043658c2a00476216d79c014895cef1ac7a1d9a8b31f6b438d0e53eecbb81054b93128324a82ecd59ec1a4f91f01f7ac113dcb14eade + languageName: node + linkType: hard + "through@npm:^2.3.6": version: 2.3.8 resolution: "through@npm:2.3.8" @@ -13054,7 +13193,7 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1": +"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 @@ -13426,6 +13565,13 @@ __metadata: languageName: node linkType: hard +"xtend@npm:~4.0.1": + version: 4.0.2 + resolution: "xtend@npm:4.0.2" + checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" From a9ba9bec1732e81dbc2bbea590101589dacd89ed Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 30 Sep 2024 10:24:03 -0500 Subject: [PATCH 3/5] Create our own fastify decorators with stricter types --- .eslintrc.cjs | 5 +++++ src/core/http/decorators.ts | 19 +++++++++++++++++++ src/core/http/index.ts | 1 + 3 files changed, 25 insertions(+) create mode 100644 src/core/http/decorators.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 1078eb4d92..9e77cd14b3 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -83,6 +83,11 @@ const restrictedImports = [ path: '@nestjs/common', replacement: { importName: 'HttpMiddleware', path: '~/core/http' }, }, + { + importNames: ['RouteConfig', 'RouteConstraints'], + path: '@nestjs/platform-fastify', + replacement: { path: '~/core/http' }, + }, ]; const namingConvention = [ diff --git a/src/core/http/decorators.ts b/src/core/http/decorators.ts new file mode 100644 index 0000000000..9316d5dbab --- /dev/null +++ b/src/core/http/decorators.ts @@ -0,0 +1,19 @@ +import { + FASTIFY_ROUTE_CONFIG_METADATA, + FASTIFY_ROUTE_CONSTRAINTS_METADATA, +} from '@nestjs/platform-fastify/constants.js'; +import { createMetadataDecorator } from '@seedcompany/nest'; +import { FastifyContextConfig } from 'fastify'; +import type { RouteConstraint } from 'fastify/types/route'; + +export const RouteConstraints = createMetadataDecorator({ + key: FASTIFY_ROUTE_CONSTRAINTS_METADATA, + types: ['class', 'method'], + setter: (config: RouteConstraint) => config, +}); + +export const RouteConfig = createMetadataDecorator({ + key: FASTIFY_ROUTE_CONFIG_METADATA, + types: ['class', 'method'], + setter: (config: FastifyContextConfig) => config, +}); diff --git a/src/core/http/index.ts b/src/core/http/index.ts index 542d05e0a2..60228bbc70 100644 --- a/src/core/http/index.ts +++ b/src/core/http/index.ts @@ -1,3 +1,4 @@ export type * from './types'; export * from './http.adapter'; export * from './http.module'; +export * from './decorators'; From 681c65dcf9a945cdfcbac382b8b7ec5ea4d30c37 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 30 Sep 2024 10:25:06 -0500 Subject: [PATCH 4/5] Configure fastify route injection ourselves This is prep for our own expansion --- src/core/http/http.adapter.ts | 49 ++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/core/http/http.adapter.ts b/src/core/http/http.adapter.ts index 93b91793e5..7aaf8db403 100644 --- a/src/core/http/http.adapter.ts +++ b/src/core/http/http.adapter.ts @@ -1,14 +1,20 @@ import compression from '@fastify/compress'; import cookieParser from '@fastify/cookie'; import cors from '@fastify/cors'; +import { + VERSION_NEUTRAL, + type VersionValue, +} from '@nestjs/common/interfaces/version-options.interface.js'; // eslint-disable-next-line @seedcompany/no-restricted-imports import { HttpAdapterHost as HttpAdapterHostImpl } from '@nestjs/core'; import { FastifyAdapter, NestFastifyApplication, } from '@nestjs/platform-fastify'; +import type { FastifyInstance, HTTPMethods, RouteOptions } from 'fastify'; import * as zlib from 'node:zlib'; import { ConfigService } from '~/core/config/config.service'; +import { RouteConfig, RouteConstraints } from './decorators'; import type { CookieOptions, CorsOptions, IResponse } from './types'; export type NestHttpApplication = NestFastifyApplication & { @@ -20,7 +26,18 @@ export type NestHttpApplication = NestFastifyApplication & { export class HttpAdapterHost extends HttpAdapterHostImpl {} -export class HttpAdapter extends FastifyAdapter { +// @ts-expect-error Convert private methods to protected +class PatchedFastifyAdapter extends FastifyAdapter { + protected injectRouteOptions( + routerMethodKey: Uppercase, + ...args: any[] + ): FastifyInstance { + // @ts-expect-error work around being marked as private + return super.injectRouteOptions(routerMethodKey, ...args); + } +} + +export class HttpAdapter extends PatchedFastifyAdapter { async configure(app: NestFastifyApplication, config: ConfigService) { await app.register(compression, { brotliOptions: { @@ -42,6 +59,36 @@ export class HttpAdapter extends FastifyAdapter { config.applyTimeouts(app.getHttpServer(), config.httpTimeouts); } + protected injectRouteOptions( + method: Uppercase, + urlOrHandler: string | RouteOptions['handler'], + maybeHandler?: RouteOptions['handler'], + ) { + // I don't know why NestJS allows url/path parameter to be omitted. + const url = typeof urlOrHandler === 'function' ? '' : urlOrHandler; + const handler = + typeof urlOrHandler === 'function' ? urlOrHandler : maybeHandler!; + + const config = RouteConfig.get(handler) ?? {}; + const constraints = RouteConstraints.get(handler) ?? {}; + + let version: VersionValue | undefined = (handler as any).version; + version = version === VERSION_NEUTRAL ? undefined : version; + if (version) { + // @ts-expect-error this is what upstream does + constraints.version = version; + } + + const route: RouteOptions = { + method, + url, + handler, + ...(Object.keys(constraints).length > 0 ? { constraints } : {}), + ...(Object.keys(config).length > 0 ? { config } : {}), + }; + return this.instance.route(route); + } + setCookie( response: IResponse, name: string, From 531d326129ddbfd14367652ae3054a7391d471f0 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Fri, 27 Sep 2024 20:21:38 -0500 Subject: [PATCH 5/5] Configure raw body handling at http foundation layer --- package.json | 1 + .../file/local-bucket.controller.ts | 11 +++--- src/core/http/decorators.ts | 37 +++++++++++++++++++ src/core/http/http.adapter.ts | 30 ++++++++++++++- yarn.lock | 16 +++++++- 5 files changed, 86 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 3490e26777..a1743394d2 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "fast-safe-stringify": "^2.1.1", "fastest-levenshtein": "^1.0.16", "fastify": "^4.28.1", + "fastify-raw-body": "^4.3.0", "file-type": "^18.6.0", "glob": "^10.3.10", "got": "^14.3.0", diff --git a/src/components/file/local-bucket.controller.ts b/src/components/file/local-bucket.controller.ts index 3b6a942d9e..2744019596 100644 --- a/src/components/file/local-bucket.controller.ts +++ b/src/components/file/local-bucket.controller.ts @@ -1,4 +1,5 @@ import { + Body, Controller, Get, Headers, @@ -9,9 +10,8 @@ import { } from '@nestjs/common'; import { DateTime } from 'luxon'; import { URL } from 'node:url'; -import rawBody from 'raw-body'; import { InputException } from '~/common'; -import { HttpAdapter, IRequest, IResponse } from '~/core/http'; +import { HttpAdapter, IRequest, IResponse, RawBody } from '~/core/http'; import { FileBucket, InvalidSignedUrlException } from './bucket'; /** @@ -27,14 +27,13 @@ export class LocalBucketController { ) {} @Put() + @RawBody({ passthrough: true }) async upload( @Headers('content-type') contentType: string, @Request() req: IRequest, + @Body() contents: Buffer, ) { - // Chokes on json files because they are parsed with body-parser. - // Need to disable it for this path or create a workaround. - const contents = await rawBody(req); - if (!contents) { + if (!contents || !Buffer.isBuffer(contents)) { throw new InputException(); } diff --git a/src/core/http/decorators.ts b/src/core/http/decorators.ts index 9316d5dbab..5e71193f69 100644 --- a/src/core/http/decorators.ts +++ b/src/core/http/decorators.ts @@ -2,6 +2,7 @@ import { FASTIFY_ROUTE_CONFIG_METADATA, FASTIFY_ROUTE_CONSTRAINTS_METADATA, } from '@nestjs/platform-fastify/constants.js'; +import { Many } from '@seedcompany/common'; import { createMetadataDecorator } from '@seedcompany/nest'; import { FastifyContextConfig } from 'fastify'; import type { RouteConstraint } from 'fastify/types/route'; @@ -17,3 +18,39 @@ export const RouteConfig = createMetadataDecorator({ types: ['class', 'method'], setter: (config: FastifyContextConfig) => config, }); + +/** + * @example + * ```ts + * @RawBody() + * route( + * @Request('rawBody') raw: string, + * @Body() contents: JSON + * ) {} + * ``` + * @example + * ```ts + * @RawBody({ passthrough: true }) + * route( + * @Body() contents: Buffer + * ) {} + * ``` + */ +export const RawBody = createMetadataDecorator({ + types: ['class', 'method'], + setter: ( + config: { + /** + * Pass the raw body through to the handler or + * just to keep the raw body in addition to regular content parsing. + */ + passthrough?: boolean; + /** + * The allowed content types. + * Only applicable if passthrough is true. + * Defaults to '*' + */ + allowContentTypes?: Many | RegExp; + } = {}, + ) => config, +}); diff --git a/src/core/http/http.adapter.ts b/src/core/http/http.adapter.ts index 7aaf8db403..7491d98d93 100644 --- a/src/core/http/http.adapter.ts +++ b/src/core/http/http.adapter.ts @@ -12,9 +12,10 @@ import { NestFastifyApplication, } from '@nestjs/platform-fastify'; import type { FastifyInstance, HTTPMethods, RouteOptions } from 'fastify'; +import rawBody from 'fastify-raw-body'; import * as zlib from 'node:zlib'; import { ConfigService } from '~/core/config/config.service'; -import { RouteConfig, RouteConstraints } from './decorators'; +import { RawBody, RouteConfig, RouteConstraints } from './decorators'; import type { CookieOptions, CorsOptions, IResponse } from './types'; export type NestHttpApplication = NestFastifyApplication & { @@ -54,6 +55,9 @@ export class HttpAdapter extends PatchedFastifyAdapter { }); await app.register(cookieParser); + // Only on routes we've decorated. + await app.register(rawBody, { global: false }); + app.setGlobalPrefix(config.hostUrl$.value.pathname.slice(1)); config.applyTimeouts(app.getHttpServer(), config.httpTimeouts); @@ -71,6 +75,7 @@ export class HttpAdapter extends PatchedFastifyAdapter { const config = RouteConfig.get(handler) ?? {}; const constraints = RouteConstraints.get(handler) ?? {}; + const rawBody = RawBody.get(handler); let version: VersionValue | undefined = (handler as any).version; version = version === VERSION_NEUTRAL ? undefined : version; @@ -79,6 +84,13 @@ export class HttpAdapter extends PatchedFastifyAdapter { constraints.version = version; } + // Plugin configured to just add the rawBody property while continuing + // to parse the content type normally. + // Useful for signed webhook payload validation. + if (rawBody && !rawBody.passthrough) { + config.rawBody = true; + } + const route: RouteOptions = { method, url, @@ -86,6 +98,22 @@ export class HttpAdapter extends PatchedFastifyAdapter { ...(Object.keys(constraints).length > 0 ? { constraints } : {}), ...(Object.keys(config).length > 0 ? { config } : {}), }; + + if (rawBody?.passthrough) { + const { allowContentTypes } = rawBody; + const contentTypes = Array.isArray(allowContentTypes) + ? allowContentTypes.slice() + : ((allowContentTypes ?? '*') as string | RegExp); + return this.instance.register(async (child) => { + child.removeAllContentTypeParsers(); + child.addContentTypeParser( + contentTypes, + { parseAs: 'buffer' }, + (req, payload, done) => done(null, payload), + ); + child.route(route); + }); + } return this.instance.route(route); } diff --git a/yarn.lock b/yarn.lock index c5c76622d1..710b9fae65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5492,6 +5492,7 @@ __metadata: fast-safe-stringify: "npm:^2.1.1" fastest-levenshtein: "npm:^1.0.16" fastify: "npm:^4.28.1" + fastify-raw-body: "npm:^4.3.0" file-type: "npm:^18.6.0" glob: "npm:^10.3.10" got: "npm:^14.3.0" @@ -6966,6 +6967,17 @@ __metadata: languageName: node linkType: hard +"fastify-raw-body@npm:^4.3.0": + version: 4.3.0 + resolution: "fastify-raw-body@npm:4.3.0" + dependencies: + fastify-plugin: "npm:^4.0.0" + raw-body: "npm:^2.5.1" + secure-json-parse: "npm:^2.4.0" + checksum: 10c0/3260ab2fc3483a1668442b0a2b60a3f671948d8fc6e7a811ac782cfc28d31d8f064e7b3835ca21cb542d41c4a2a7bc84dd5c18ef0c38f90d7387dd6bbb83161d + languageName: node + linkType: hard + "fastify@npm:4.28.1, fastify@npm:^4.28.1": version: 4.28.1 resolution: "fastify@npm:4.28.1" @@ -11467,7 +11479,7 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.2": +"raw-body@npm:2.5.2, raw-body@npm:^2.5.1": version: 2.5.2 resolution: "raw-body@npm:2.5.2" dependencies: @@ -11975,7 +11987,7 @@ __metadata: languageName: node linkType: hard -"secure-json-parse@npm:^2.7.0": +"secure-json-parse@npm:^2.4.0, secure-json-parse@npm:^2.7.0": version: 2.7.0 resolution: "secure-json-parse@npm:2.7.0" checksum: 10c0/f57eb6a44a38a3eeaf3548228585d769d788f59007454214fab9ed7f01fbf2e0f1929111da6db28cf0bcc1a2e89db5219a59e83eeaec3a54e413a0197ce879e4