From 333dbba393b1be3ef5767104560875264bd29a48 Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Tue, 6 Dec 2022 13:18:02 +0530 Subject: [PATCH 01/14] chore: added docker files for bringing the container up --- packages/hoppscotch-backend/.dockerignore | 1 + packages/hoppscotch-backend/Dockerfile | 30 + .../hoppscotch-backend/docker-compose.yml | 25 + packages/hoppscotch-backend/package.json | 4 + .../hoppscotch-backend/prisma/schema.prisma | 85 +++ packages/hoppscotch-backend/src/app.module.ts | 45 +- .../hoppscotch-backend/src/app.resolver.ts | 12 + packages/hoppscotch-backend/src/errors.ts | 211 +++++++ packages/hoppscotch-backend/src/main.ts | 34 +- pnpm-lock.yaml | 552 +++++++++++++++++- 10 files changed, 980 insertions(+), 19 deletions(-) create mode 100644 packages/hoppscotch-backend/.dockerignore create mode 100644 packages/hoppscotch-backend/Dockerfile create mode 100644 packages/hoppscotch-backend/docker-compose.yml create mode 100644 packages/hoppscotch-backend/prisma/schema.prisma create mode 100644 packages/hoppscotch-backend/src/app.resolver.ts create mode 100644 packages/hoppscotch-backend/src/errors.ts diff --git a/packages/hoppscotch-backend/.dockerignore b/packages/hoppscotch-backend/.dockerignore new file mode 100644 index 000000000..4b904442b --- /dev/null +++ b/packages/hoppscotch-backend/.dockerignore @@ -0,0 +1 @@ +./node_modules diff --git a/packages/hoppscotch-backend/Dockerfile b/packages/hoppscotch-backend/Dockerfile new file mode 100644 index 000000000..0e655336d --- /dev/null +++ b/packages/hoppscotch-backend/Dockerfile @@ -0,0 +1,30 @@ +FROM node:lts + +WORKDIR /usr/src/app + +# Install pnpm +RUN npm i -g pnpm + +# NPM package install +COPY package*.json ./ +RUN pnpm install + + +# Prisma bits +#COPY prisma ./ +#RUN pnpx prisma generate + + +COPY . . + +RUN pnpm run build + +EXPOSE 3170 +EXPOSE 9229 + +ENV APP_PORT=${PORT} +ENV DB_URL=${DATABASE_URL} +ENV PRODUCTION=true +#ENV FB_SERVICE_KEY_PATH="secrets/fb-service-key.json" +CMD ["pnpm", "run", "start:dev"] +#CMD ["./run.sh", "start:dev"] diff --git a/packages/hoppscotch-backend/docker-compose.yml b/packages/hoppscotch-backend/docker-compose.yml new file mode 100644 index 000000000..a5e6d597b --- /dev/null +++ b/packages/hoppscotch-backend/docker-compose.yml @@ -0,0 +1,25 @@ +version: '3.0' +services: + local: + build: ./Dockerfile + environment: + - PRODUCTION=false + - DATABASE_URL=postgresql://postgres:testpass@dev-db:5432/hoppscotch + - PORT=3000 +# volumes: +# - .:/usr/src/app + depends_on: + - dev-db + ports: + - "3170:3000" + - "9229:9229" + + dev-db: + image: postgres + ports: + - "5432:5432" + environment: + POSTGRES_PASSWORD: testpass + POSTGRES_DB: hoppscotch + + diff --git a/packages/hoppscotch-backend/package.json b/packages/hoppscotch-backend/package.json index d21bbeb83..cf458971c 100644 --- a/packages/hoppscotch-backend/package.json +++ b/packages/hoppscotch-backend/package.json @@ -21,9 +21,13 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { + "@nestjs/apollo": "^10.1.6", "@nestjs/common": "^9.2.1", "@nestjs/core": "^9.2.1", + "@nestjs/graphql": "^10.1.6", "@nestjs/platform-express": "^9.2.1", + "apollo-server-express": "^3.11.1", + "graphql": "^15.5.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.6.0" diff --git a/packages/hoppscotch-backend/prisma/schema.prisma b/packages/hoppscotch-backend/prisma/schema.prisma new file mode 100644 index 000000000..fb9f2eb22 --- /dev/null +++ b/packages/hoppscotch-backend/prisma/schema.prisma @@ -0,0 +1,85 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" + binaryTargets = ["native", "debian-openssl-1.1.x"] +} + +model Team { + id String @id @default(cuid()) + name String + members TeamMember[] + TeamInvitation TeamInvitation[] + TeamCollection TeamCollection[] + TeamRequest TeamRequest[] + TeamEnvironment TeamEnvironment[] +} + +model TeamMember { + id String @id @default(uuid()) // Membership ID + role TeamMemberRole + userUid String + teamID String + team Team @relation(fields: [teamID], references: [id], onDelete: Cascade) + + @@unique([teamID, userUid]) +} + +model TeamInvitation { + id String @id @default(cuid()) + teamID String + team Team @relation(fields: [teamID], references: [id], onDelete: Cascade) + creatorUid String + inviteeEmail String + inviteeRole TeamMemberRole + + @@unique([teamID, inviteeEmail]) + @@index([teamID]) +} + +model TeamCollection { + id String @id @default(cuid()) + parentID String? + parent TeamCollection? @relation("TeamCollectionChildParent", fields: [parentID], references: [id]) + children TeamCollection[] @relation("TeamCollectionChildParent") + requests TeamRequest[] + teamID String + team Team @relation(fields: [teamID], references: [id], onDelete: Cascade) + title String +} + +model TeamRequest { + id String @id @default(cuid()) + collectionID String + collection TeamCollection @relation(fields: [collectionID], references: [id], onDelete: Cascade) + teamID String + team Team @relation(fields: [teamID], references: [id], onDelete: Cascade) + title String + request Json +} + +model Shortcode { + id String @id + request Json + creatorUid String? + createdOn DateTime @default(now()) + + @@unique(fields: [id, creatorUid], name: "creator_uid_shortcode_unique") +} + +model TeamEnvironment { + id String @id @default(cuid()) + teamID String + team Team @relation(fields: [teamID], references: [id], onDelete: Cascade) + name String + variables Json +} + +enum TeamMemberRole { + OWNER + VIEWER + EDITOR +} diff --git a/packages/hoppscotch-backend/src/app.module.ts b/packages/hoppscotch-backend/src/app.module.ts index 86628031c..6c3f39d9f 100644 --- a/packages/hoppscotch-backend/src/app.module.ts +++ b/packages/hoppscotch-backend/src/app.module.ts @@ -1,10 +1,51 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { GraphQLModule } from '@nestjs/graphql'; +import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; +import { AppResolver } from './app.resolver'; @Module({ - imports: [], + imports: [ + GraphQLModule.forRoot({ + playground: process.env.PRODUCTION !== 'true', + debug: process.env.PRODUCTION !== 'true', + autoSchemaFile: true, + installSubscriptionHandlers: true, + subscriptions: { + 'subscriptions-transport-ws': { + path: '/graphql', + onConnect: (connectionParams: any) => { + return { + reqHeaders: Object.fromEntries( + Object.entries(connectionParams).map(([k, v]) => [ + k.toLowerCase(), + v, + ]), + ), + }; + }, + }, + }, + context: async ({ req, connection }) => { + if (req) { + return { reqHeaders: req.headers }; + } else { + return { + // Lowercase the keys + reqHeaders: Object.fromEntries( + Object.entries(connection.context).map(([k, v]) => [ + k.toLowerCase(), + v, + ]), + ), + }; + } + }, + driver: ApolloDriver, + }), + ], controllers: [AppController], - providers: [AppService], + providers: [AppService, AppResolver], }) export class AppModule {} diff --git a/packages/hoppscotch-backend/src/app.resolver.ts b/packages/hoppscotch-backend/src/app.resolver.ts new file mode 100644 index 000000000..f16f8b565 --- /dev/null +++ b/packages/hoppscotch-backend/src/app.resolver.ts @@ -0,0 +1,12 @@ +import { Query, Resolver } from '@nestjs/graphql'; +import { AppService } from './app.service'; + +@Resolver((of) => String) +export class AppResolver { + constructor(private appService: AppService) {} + + @Query((returns) => String) + async author() { + return this.appService.getHello(); + } +} diff --git a/packages/hoppscotch-backend/src/errors.ts b/packages/hoppscotch-backend/src/errors.ts new file mode 100644 index 000000000..794a06db5 --- /dev/null +++ b/packages/hoppscotch-backend/src/errors.ts @@ -0,0 +1,211 @@ +export const INVALID_EMAIL = 'invalid/email' as const; + +export const EMAIL_FAILED = 'email/failed' as const; + +/** + * Token Authorization failed (Check 'Authorization' Header) + * (GqlAuthGuard) + */ +export const AUTH_FAIL = 'auth/fail'; + +/** + * Tried to delete an user data document from fb firestore but failed. + * (FirebaseService) + */ +export const USER_FB_DOCUMENT_DELETION_FAILED = + 'fb/firebase_document_deletion_failed' as const; + +/** + * Tried to do an action on a user where user is not found + */ +export const USER_NOT_FOUND = 'user/not_found' as const; + +/** + * User deletion failure + * (UserService) + */ +export const USER_DELETION_FAILED = 'user/deletion_failed' as const; + +/** + * User deletion failure error due to user being a team owner + * (UserService) + */ +export const USER_IS_OWNER = 'user/is_owner' as const; + +/** + * Tried to perform action on a team which they are not a member of + * (GqlTeamMemberGuard) + */ +export const TEAM_MEMBER_NOT_FOUND = 'team/member_not_found' as const; + +/** + * Tried to perform action on a team that doesn't accept their member role level + * (GqlTeamMemberGuard) + */ +export const TEAM_NOT_REQUIRED_ROLE = 'team/not_required_role' as const; + +/** + * Team name validation failure + * (TeamService) + */ +export const TEAM_NAME_INVALID = 'team/name_invalid'; + +/** + * Couldn't find the sync data from the user + * (TeamCollectionService) + */ +export const TEAM_USER_NO_FB_SYNCDATA = 'team/user_no_fb_syncdata'; + +/** + * There was a problem resolving the firebase collection path + * (TeamCollectionService) + */ +export const TEAM_FB_COLL_PATH_RESOLVE_FAIL = 'team/fb_coll_path_resolve_fail'; + +/** + * Tried to update the team to a state it doesn't have any owners + * (TeamService) + */ +export const TEAM_ONLY_ONE_OWNER = 'team/only_one_owner'; + +/** + * Invalid or non-existent Team ID + * (TeamService) + */ +export const TEAM_INVALID_ID = 'team/invalid_id' as const; + +/** + * Invalid or non-existent collection id + * (GqlCollectionTeamMemberGuard) + */ +export const TEAM_INVALID_COLL_ID = 'team/invalid_coll_id' as const; + +/** + * Invalid team id or user id + * (TeamService) + */ +export const TEAM_INVALID_ID_OR_USER = 'team/invalid_id_or_user'; + +/** + * The provided title for the team collection is short (less than 3 characters) + * (TeamCollectionService) + */ +export const TEAM_COLL_SHORT_TITLE = 'team_coll/short_title'; + +/** + * The JSON used is not valid + * (TeamCollectionService) + */ +export const TEAM_COLL_INVALID_JSON = 'team_coll/invalid_json'; + +/** + * Tried to perform action on a request that doesn't accept their member role level + * (GqlRequestTeamMemberGuard) + */ +export const TEAM_REQ_NOT_REQUIRED_ROLE = 'team_req/not_required_role'; + +/** + * Tried to operate on a request which does not exist + * (TeamRequestService) + */ +export const TEAM_REQ_NOT_FOUND = 'team_req/not_found' as const; + +/** + * Invalid or non-existent collection id + * (TeamRequestService) + */ +export const TEAM_REQ_INVALID_TARGET_COLL_ID = + 'team_req/invalid_target_id' as const; + +/** + * Tried to perform action on a request when the user is not even member of the team + * (GqlRequestTeamMemberGuard, GqlCollectionTeamMemberGuard) + */ +export const TEAM_REQ_NOT_MEMBER = 'team_req/not_member'; + +export const TEAM_INVITE_MEMBER_HAS_INVITE = + 'team_invite/member_has_invite' as const; + +export const TEAM_INVITE_NO_INVITE_FOUND = + 'team_invite/no_invite_found' as const; + +export const TEAM_INVITE_ALREADY_MEMBER = 'team_invite/already_member' as const; + +export const TEAM_INVITE_EMAIL_DO_NOT_MATCH = + 'team_invite/email_do_not_match' as const; + +export const TEAM_INVITE_NOT_VALID_VIEWER = + 'team_invite/not_valid_viewer' as const; + +export const SHORTCODE_NOT_FOUND = 'shortcode/not_found' as const; + +export const SHORTCODE_INVALID_JSON = 'shortcode/invalid_json' as const; + +/** + * Invalid or non-existent TEAM ENVIRONMMENT ID + * (TeamEnvironmentsService) + */ +export const TEAM_ENVIRONMMENT_NOT_FOUND = + 'team_environment/not_found' as const; + +/** + * The user is not a member of the team of the given environment + * (GqlTeamEnvTeamGuard) + */ +export const TEAM_ENVIRONMENT_NOT_TEAM_MEMBER = + 'team_environment/not_team_member' as const; + +/* + + |------------------------------------| + |Server errors that are actually bugs| + |------------------------------------| + +*/ + +/** + * Couldn't find user data from the GraphQL context (Check if GqlAuthGuard is applied) + * (GqlTeamMemberGuard, GqlCollectionTeamMemberGuard) + */ +export const BUG_AUTH_NO_USER_CTX = 'bug/auth/auth_no_user_ctx' as const; + +/** + * Couldn't find teamID parameter in the attached GraphQL operation. (Check if teamID is present) + * (GqlTeamMemberGuard, GQLEAAdminGuard, GqlCollectionTeamMemberGuard) + */ +export const BUG_TEAM_NO_TEAM_ID = 'bug/team/no_team_id'; + +/** + * Couldn't find RequireTeamRole decorator. (Check if it is applied) + * (GqlTeamMemberGuard) + */ +export const BUG_TEAM_NO_REQUIRE_TEAM_ROLE = 'bug/team/no_require_team_role'; + +/** + * Couldn't find 'collectionID' param to the attached GQL operation. (Check if exists) + * (GqlCollectionTeamMemberGuard) + */ +export const BUG_TEAM_COLL_NO_COLL_ID = 'bug/team_coll/no_coll_id'; + +/** + * Couldn't find 'requestID' param to the attached GQL operation. (Check if exists) + * (GqlRequestTeamMemberGuard) + */ +export const BUG_TEAM_REQ_NO_REQ_ID = 'bug/team_req/no_req_id'; + +export const BUG_TEAM_INVITE_NO_INVITE_ID = + 'bug/team_invite/no_invite_id' as const; + +/** + * Couldn't find RequireTeamRole decorator. (Check if it is applied) + * (GqlTeamEnvTeamGuard) + */ +export const BUG_TEAM_ENV_GUARD_NO_REQUIRE_ROLES = + 'bug/team_env/guard_no_require_roles' as const; + +/** + * Couldn't find 'id' param to the operation. (Check if it is applied) + * (GqlTeamEnvTeamGuard) + */ +export const BUG_TEAM_ENV_GUARD_NO_ENV_ID = + 'bug/team_env/guard_no_env_id' as const; diff --git a/packages/hoppscotch-backend/src/main.ts b/packages/hoppscotch-backend/src/main.ts index 13cad38cf..5c4786c2a 100644 --- a/packages/hoppscotch-backend/src/main.ts +++ b/packages/hoppscotch-backend/src/main.ts @@ -1,8 +1,40 @@ import { NestFactory } from '@nestjs/core'; +import { json } from 'express'; import { AppModule } from './app.module'; async function bootstrap() { + console.log(`Running in production: ${process.env.PRODUCTION}`); + console.log(`Port: ${process.env.PORT}`); + console.log(`Database: ${process.env.DATABASE_URL}`); + const app = await NestFactory.create(AppModule); - await app.listen(3000); + + // Increase fil upload limit to 50MB + app.use( + json({ + limit: '100mb', + }), + ); + + if (process.env.PRODUCTION === 'false') { + console.log('Enabling CORS with development settings'); + app.enableCors({ + origin: true, + }); + } else { + console.log('Enabling CORS with production settings'); + + // HACK: Temporary fix for Liyas to work on production directly :P + /* + app.enableCors({ + origin: /hoppscotch\.io$/ + }); + */ + + app.enableCors({ + origin: true, + }); + } + await app.listen(process.env.PORT || 3170); } bootstrap(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 709ddc870..48173372f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,9 +44,11 @@ importers: packages/hoppscotch-backend: specifiers: + '@nestjs/apollo': ^10.1.6 '@nestjs/cli': ^9.1.5 '@nestjs/common': ^9.2.1 '@nestjs/core': ^9.2.1 + '@nestjs/graphql': ^10.1.6 '@nestjs/platform-express': ^9.2.1 '@nestjs/schematics': ^9.0.3 '@nestjs/testing': ^9.2.1 @@ -56,9 +58,11 @@ importers: '@types/supertest': ^2.0.12 '@typescript-eslint/eslint-plugin': ^5.45.0 '@typescript-eslint/parser': ^5.45.0 + apollo-server-express: ^3.11.1 eslint: ^8.29.0 eslint-config-prettier: ^8.5.0 eslint-plugin-prettier: ^4.2.1 + graphql: ^15.5.0 jest: 29.3.1 prettier: ^2.8.0 reflect-metadata: ^0.1.13 @@ -72,9 +76,13 @@ importers: tsconfig-paths: 4.1.1 typescript: ^4.9.3 dependencies: + '@nestjs/apollo': 10.1.6_s6pw6ravicthrbuw7ih3vbxenu '@nestjs/common': 9.2.1_whg6pvy6vwu66ypq7idiq2suxq '@nestjs/core': 9.2.1_ajc4cvdydchgvxyi4xnoij5t4i + '@nestjs/graphql': 10.1.6_2khsk5ahlt4vlkrgib4soffmwu '@nestjs/platform-express': 9.2.1_hjcqpoaebdr7gdo5hgc22hthbe + apollo-server-express: 3.11.1_graphql@15.8.0 + graphql: 15.8.0 reflect-metadata: 0.1.13 rimraf: 3.0.2 rxjs: 7.6.0 @@ -724,6 +732,138 @@ packages: openapi-types: 12.0.0 dev: false + /@apollo/protobufjs/1.2.6: + resolution: {integrity: sha512-Wqo1oSHNUj/jxmsVp4iR3I480p6qdqHikn38lKrFhfzcDJ7lwd7Ck7cHRl4JE81tWNArl77xhnG/OkZhxKBYOw==} + hasBin: true + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + '@types/node': 10.17.60 + long: 4.0.0 + dev: false + + /@apollo/protobufjs/1.2.7: + resolution: {integrity: sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==} + hasBin: true + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + long: 4.0.0 + dev: false + + /@apollo/usage-reporting-protobuf/4.0.2: + resolution: {integrity: sha512-GfE8aDqi/lAFut95pjH9IRvH0zGsQ5G/2lYL0ZLZfML7ArX+A4UVHFANQcPCcUYGE6bI6OPhLekg4Vsjf6B1cw==} + dependencies: + '@apollo/protobufjs': 1.2.7 + dev: false + + /@apollo/utils.dropunuseddefinitions/1.1.0_graphql@15.8.0: + resolution: {integrity: sha512-jU1XjMr6ec9pPoL+BFWzEPW7VHHulVdGKMkPAMiCigpVIT11VmCbnij0bWob8uS3ODJ65tZLYKAh/55vLw2rbg==} + engines: {node: '>=12.13.0'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + dependencies: + graphql: 15.8.0 + dev: false + + /@apollo/utils.keyvaluecache/1.0.2: + resolution: {integrity: sha512-p7PVdLPMnPzmXSQVEsy27cYEjVON+SH/Wb7COyW3rQN8+wJgT1nv9jZouYtztWW8ZgTkii5T6tC9qfoDREd4mg==} + dependencies: + '@apollo/utils.logger': 1.0.1 + lru-cache: 7.13.1 + dev: false + + /@apollo/utils.logger/1.0.1: + resolution: {integrity: sha512-XdlzoY7fYNK4OIcvMD2G94RoFZbzTQaNP0jozmqqMudmaGo2I/2Jx71xlDJ801mWA/mbYRihyaw6KJii7k5RVA==} + dev: false + + /@apollo/utils.printwithreducedwhitespace/1.1.0_graphql@15.8.0: + resolution: {integrity: sha512-GfFSkAv3n1toDZ4V6u2d7L4xMwLA+lv+6hqXicMN9KELSJ9yy9RzuEXaX73c/Ry+GzRsBy/fdSUGayGqdHfT2Q==} + engines: {node: '>=12.13.0'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + dependencies: + graphql: 15.8.0 + dev: false + + /@apollo/utils.removealiases/1.0.0_graphql@15.8.0: + resolution: {integrity: sha512-6cM8sEOJW2LaGjL/0vHV0GtRaSekrPQR4DiywaApQlL9EdROASZU5PsQibe2MWeZCOhNrPRuHh4wDMwPsWTn8A==} + engines: {node: '>=12.13.0'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + dependencies: + graphql: 15.8.0 + dev: false + + /@apollo/utils.sortast/1.1.0_graphql@15.8.0: + resolution: {integrity: sha512-VPlTsmUnOwzPK5yGZENN069y6uUHgeiSlpEhRnLFYwYNoJHsuJq2vXVwIaSmts015WTPa2fpz1inkLYByeuRQA==} + engines: {node: '>=12.13.0'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + dependencies: + graphql: 15.8.0 + lodash.sortby: 4.7.0 + dev: false + + /@apollo/utils.stripsensitiveliterals/1.2.0_graphql@15.8.0: + resolution: {integrity: sha512-E41rDUzkz/cdikM5147d8nfCFVKovXxKBcjvLEQ7bjZm/cg9zEcXvS6vFY8ugTubI3fn6zoqo0CyU8zT+BGP9w==} + engines: {node: '>=12.13.0'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + dependencies: + graphql: 15.8.0 + dev: false + + /@apollo/utils.usagereporting/1.0.1_graphql@15.8.0: + resolution: {integrity: sha512-6dk+0hZlnDbahDBB2mP/PZ5ybrtCJdLMbeNJD+TJpKyZmSY6bA3SjI8Cr2EM9QA+AdziywuWg+SgbWUF3/zQqQ==} + engines: {node: '>=12.13.0'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + dependencies: + '@apollo/usage-reporting-protobuf': 4.0.2 + '@apollo/utils.dropunuseddefinitions': 1.1.0_graphql@15.8.0 + '@apollo/utils.printwithreducedwhitespace': 1.1.0_graphql@15.8.0 + '@apollo/utils.removealiases': 1.0.0_graphql@15.8.0 + '@apollo/utils.sortast': 1.1.0_graphql@15.8.0 + '@apollo/utils.stripsensitiveliterals': 1.2.0_graphql@15.8.0 + graphql: 15.8.0 + dev: false + + /@apollographql/apollo-tools/0.5.4_graphql@15.8.0: + resolution: {integrity: sha512-shM3q7rUbNyXVVRkQJQseXv6bnYM3BUma/eZhwXR4xsuM+bqWnJKvW7SAfRjP7LuSCocrexa5AXhjjawNHrIlw==} + engines: {node: '>=8', npm: '>=6'} + peerDependencies: + graphql: ^14.2.1 || ^15.0.0 || ^16.0.0 + dependencies: + graphql: 15.8.0 + dev: false + + /@apollographql/graphql-playground-html/1.6.29: + resolution: {integrity: sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==} + dependencies: + xss: 1.0.14 + dev: false + /@ardatan/relay-compiler/12.0.0_graphql@15.8.0: resolution: {integrity: sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==} hasBin: true @@ -3160,7 +3300,39 @@ packages: dependencies: '@graphql-tools/utils': 8.8.0_graphql@15.8.0 graphql: 15.8.0 - tslib: 2.4.0 + tslib: 2.4.1 + + /@graphql-tools/merge/8.3.11_graphql@15.8.0: + resolution: {integrity: sha512-IpZh8r8e8FycXaUv04xe5HQH9siD1tkS8MvaO8Wb2FaPXv15XSYP+Wsb2MUStpIqGfQxa6xY/+eEuxv+VqwXyg==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/utils': 9.1.0_graphql@15.8.0 + graphql: 15.8.0 + tslib: 2.4.1 + dev: false + + /@graphql-tools/merge/8.3.12_graphql@15.8.0: + resolution: {integrity: sha512-BFL8r4+FrqecPnIW0H8UJCBRQ4Y8Ep60aujw9c/sQuFmQTiqgWgpphswMGfaosP2zUinDE3ojU5wwcS2IJnumA==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/utils': 9.1.1_graphql@15.8.0 + graphql: 15.8.0 + tslib: 2.4.1 + dev: false + + /@graphql-tools/mock/8.7.12_graphql@15.8.0: + resolution: {integrity: sha512-bEjj52T5idjzqFXfDZPFfPZDPFEjVmayYA6RYqMxM3Qdv5JJ8pSMEGDBcXhinbQudPKdRkLmR17usNmRMpUQEg==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/schema': 9.0.10_graphql@15.8.0 + '@graphql-tools/utils': 9.1.1_graphql@15.8.0 + fast-json-stable-stringify: 2.1.0 + graphql: 15.8.0 + tslib: 2.4.1 + dev: false /@graphql-tools/optimize/1.3.0_graphql@15.8.0: resolution: {integrity: sha512-30QOWJoMJEt1De7tAFtWJ6VPrP6SLq+tSQrA3x+WMvCW3q2exq5wPDpvAXOakVKu0y8L2E+YkipC0hcQPBQdLg==} @@ -3227,9 +3399,33 @@ packages: '@graphql-tools/merge': 8.3.0_graphql@15.8.0 '@graphql-tools/utils': 8.8.0_graphql@15.8.0 graphql: 15.8.0 - tslib: 2.4.0 + tslib: 2.4.1 value-or-promise: 1.0.11 + /@graphql-tools/schema/9.0.10_graphql@15.8.0: + resolution: {integrity: sha512-lV0o4df9SpPiaeeDAzgdCJ2o2N9Wvsp0SMHlF2qDbh9aFCFQRsXuksgiDm2yTgT3TG5OtUes/t0D6uPjPZFUbQ==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/merge': 8.3.12_graphql@15.8.0 + '@graphql-tools/utils': 9.1.1_graphql@15.8.0 + graphql: 15.8.0 + tslib: 2.4.1 + value-or-promise: 1.0.11 + dev: false + + /@graphql-tools/schema/9.0.9_graphql@15.8.0: + resolution: {integrity: sha512-hwg8trUytO5ayQ8bzL3+sAyXcu2rhKt5pLXpLO0/TMTN2nXd3DBO4mqx+Ra4Er2mE/msInGQ5EmZbxVBPv+hSg==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/merge': 8.3.11_graphql@15.8.0 + '@graphql-tools/utils': 9.1.0_graphql@15.8.0 + graphql: 15.8.0 + tslib: 2.4.1 + value-or-promise: 1.0.11 + dev: false + /@graphql-tools/url-loader/7.12.1_graphql@15.8.0: resolution: {integrity: sha512-Fd3ZZLEEr9GGFHEbdrcaMHFQu01BLpFnNDBkISupvjokd497O5Uh0xZvsZGC6mxVt0WWQWpgaK2ef+oLuOdLqQ==} peerDependencies: @@ -3263,7 +3459,25 @@ packages: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: graphql: 15.8.0 - tslib: 2.4.0 + tslib: 2.4.1 + + /@graphql-tools/utils/9.1.0_graphql@15.8.0: + resolution: {integrity: sha512-4Ketxo98IwKA/56LP6cI6PgQBwUCujszQcTNkzjq7liJPa2mLjKnmVOJ0bauMwKcEazeYuZagceljb0POmEGvQ==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + graphql: 15.8.0 + tslib: 2.4.1 + dev: false + + /@graphql-tools/utils/9.1.1_graphql@15.8.0: + resolution: {integrity: sha512-DXKLIEDbihK24fktR2hwp/BNIVwULIHaSTNTNhXS+19vgT50eX9wndx1bPxGwHnVBOONcwjXy0roQac49vdt/w==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + graphql: 15.8.0 + tslib: 2.4.1 + dev: false /@graphql-tools/wrap/8.5.0_graphql@15.8.0: resolution: {integrity: sha512-I+x9dBNzC135WWPi04ejqurR/zDmhfeGbCftCaYKF4CvgWd+ZaJx4Uc74n1SBegQtrj+KDrOS4HgKwf9vAVR7A==} @@ -3973,6 +4187,10 @@ packages: chalk: 4.1.2 dev: true + /@josephg/resolvable/1.0.1: + resolution: {integrity: sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==} + dev: false + /@jridgewell/gen-mapping/0.1.1: resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} engines: {node: '>=6.0.0'} @@ -4095,6 +4313,37 @@ packages: dependencies: graphql: 15.8.0 + /@nestjs/apollo/10.1.6_s6pw6ravicthrbuw7ih3vbxenu: + resolution: {integrity: sha512-BQJBBUTjEQ6roCHPC2io/OV+4n/ph1kyN38FFHtTiGHAgWx+YdeMT4LEGcaM1qBOuGC7PyNYTL3Cm2gzsGPSdg==} + peerDependencies: + '@apollo/gateway': ^0.44.1 || ^0.46.0 || ^0.48.0 || ^0.49.0 || ^0.50.0 || ^2.0.0 + '@nestjs/common': ^8.2.3 || ^9.0.0 + '@nestjs/core': ^8.2.3 || ^9.0.0 + '@nestjs/graphql': ^10.0.0 + apollo-server-core: ^3.5.0 + apollo-server-express: ^3.5.0 + apollo-server-fastify: ^3.5.0 + graphql: ^15.8.0 || ^16.0.0 + peerDependenciesMeta: + '@apollo/gateway': + optional: true + apollo-server-core: + optional: true + apollo-server-express: + optional: true + apollo-server-fastify: + optional: true + dependencies: + '@nestjs/common': 9.2.1_whg6pvy6vwu66ypq7idiq2suxq + '@nestjs/core': 9.2.1_ajc4cvdydchgvxyi4xnoij5t4i + '@nestjs/graphql': 10.1.6_2khsk5ahlt4vlkrgib4soffmwu + apollo-server-express: 3.11.1_graphql@15.8.0 + graphql: 15.8.0 + iterall: 1.3.0 + lodash.omit: 4.5.0 + tslib: 2.4.1 + dev: false + /@nestjs/cli/9.1.5: resolution: {integrity: sha512-rSp26+Nv7PFtYrRSP18Gv5ZK8rRSc2SCCF5wh4SdZaVGgkxShpNq9YEfI+ik/uziN3KC5o74ppYRXGj+aHGVsA==} engines: {node: '>= 12.9.0'} @@ -4186,6 +4435,63 @@ packages: - encoding dev: false + /@nestjs/graphql/10.1.6_2khsk5ahlt4vlkrgib4soffmwu: + resolution: {integrity: sha512-RiDTqyBqk+qolcMMKBANuG5zw0q0zbVmkwWydB2F1ObvUyl5t/GOAcR8mbq3gvpfYzylQ5t5/svWUDq/7dcpaQ==} + peerDependencies: + '@apollo/subgraph': ^0.1.5 || ^0.3.0 || ^0.4.0 || ^2.0.0 + '@nestjs/common': ^8.2.3 || ^9.0.0 + '@nestjs/core': ^8.2.3 || ^9.0.0 + graphql: ^15.8.0 || ^16.0.0 + reflect-metadata: ^0.1.13 + ts-morph: ^13.0.2 || ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + '@apollo/subgraph': + optional: true + ts-morph: + optional: true + dependencies: + '@graphql-tools/merge': 8.3.11_graphql@15.8.0 + '@graphql-tools/schema': 9.0.9_graphql@15.8.0 + '@graphql-tools/utils': 9.1.0_graphql@15.8.0 + '@nestjs/common': 9.2.1_whg6pvy6vwu66ypq7idiq2suxq + '@nestjs/core': 9.2.1_ajc4cvdydchgvxyi4xnoij5t4i + '@nestjs/mapped-types': 1.2.0_n3ccvzwmui2f6jwh4xeqysew6i + chokidar: 3.5.3 + fast-glob: 3.2.12 + graphql: 15.8.0 + graphql-tag: 2.12.6_graphql@15.8.0 + graphql-ws: 5.5.5_graphql@15.8.0 + lodash: 4.17.21 + normalize-path: 3.0.0 + reflect-metadata: 0.1.13 + subscriptions-transport-ws: 0.11.0_graphql@15.8.0 + tslib: 2.4.1 + uuid: 9.0.0 + ws: 8.11.0 + transitivePeerDependencies: + - bufferutil + - class-transformer + - class-validator + - utf-8-validate + dev: false + + /@nestjs/mapped-types/1.2.0_n3ccvzwmui2f6jwh4xeqysew6i: + resolution: {integrity: sha512-NTFwPZkQWsArQH8QSyFWGZvJ08gR+R4TofglqZoihn/vU+ktHEJjMqsIsADwb7XD97DhiD+TVv5ac+jG33BHrg==} + peerDependencies: + '@nestjs/common': ^7.0.8 || ^8.0.0 || ^9.0.0 + class-transformer: ^0.2.0 || ^0.3.0 || ^0.4.0 || ^0.5.0 + class-validator: ^0.11.1 || ^0.12.0 || ^0.13.0 + reflect-metadata: ^0.1.12 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + dependencies: + '@nestjs/common': 9.2.1_whg6pvy6vwu66ypq7idiq2suxq + reflect-metadata: 0.1.13 + dev: false + /@nestjs/platform-express/9.2.1_hjcqpoaebdr7gdo5hgc22hthbe: resolution: {integrity: sha512-7PecaXt8lrdS1p6Vb1X/am3GGv+EO1VahyDzaEGOK6C0zwhc0VPfLtwihkjjfhS6BjpRIXXgviwEjONUvxVZnA==} peerDependencies: @@ -4700,6 +5006,12 @@ packages: resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} dev: true + /@types/accepts/1.3.5: + resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} + dependencies: + '@types/node': 18.11.10 + dev: false + /@types/axios/0.14.0: resolution: {integrity: sha512-KqQnQbdYE54D7oa/UmYVMZKq7CO4l8DEENzOKc4aBRwxCXSlJXGz83flFx5L7AWrOQnmuN3kVsRdt+GZPPjiVQ==} deprecated: This is a stub types definition for axios (https://github.com/mzabriskie/axios). axios provides its own type definitions, so you don't need @types/axios installed! @@ -4743,7 +5055,6 @@ packages: dependencies: '@types/connect': 3.4.35 '@types/node': 18.11.10 - dev: true /@types/chalk/2.2.0: resolution: {integrity: sha512-1zzPV9FDe1I/WHhRkf9SNgqtRJWZqrBWgu7JGveuHmmyR9CnAPCie2N/x+iHrgnpYBIcCJWHBoMRv2TRWktsvw==} @@ -4767,12 +5078,15 @@ packages: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: '@types/node': 18.11.10 - dev: true /@types/cookiejar/2.1.2: resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==} dev: true + /@types/cors/2.8.12: + resolution: {integrity: sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==} + dev: false + /@types/debug/4.1.7: resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} dependencies: @@ -4807,7 +5121,6 @@ packages: '@types/node': 18.11.10 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 - dev: true /@types/express/4.17.14: resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==} @@ -4816,7 +5129,6 @@ packages: '@types/express-serve-static-core': 4.17.31 '@types/qs': 6.9.7 '@types/serve-static': 1.15.0 - dev: true /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} @@ -4891,7 +5203,6 @@ packages: /@types/mime/3.0.1: resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} - dev: true /@types/minimist/1.2.2: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} @@ -4901,6 +5212,10 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true + /@types/node/10.17.60: + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + dev: false + /@types/node/16.11.43: resolution: {integrity: sha512-GqWykok+3uocgfAJM8imbozrqLnPyTrpFlrryURQlw1EesPUCx5XxTiucWDSFF9/NUEXDuD4bnvHm8xfVGWTpQ==} dev: true @@ -4910,7 +5225,6 @@ packages: /@types/node/18.11.10: resolution: {integrity: sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==} - dev: true /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -4943,11 +5257,9 @@ packages: /@types/qs/6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} - dev: true /@types/range-parser/1.2.4: resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} - dev: true /@types/resolve/1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} @@ -4968,7 +5280,6 @@ packages: dependencies: '@types/mime': 3.0.1 '@types/node': 18.11.10 - dev: true /@types/splitpanes/2.2.1: resolution: {integrity: sha512-H5BgO6UdJRzz5ddRzuGvLBiPSPEuuHXb5ET+7avLLrEx1uc7f5Ut5oLMDQsfvGtHBBAFczt1QNYuDf27wHbvDQ==} @@ -6335,6 +6646,132 @@ packages: yauzl: 2.10.0 dev: false + /apollo-datasource/3.3.2: + resolution: {integrity: sha512-L5TiS8E2Hn/Yz7SSnWIVbZw0ZfEIXZCa5VUiVxD9P53JvSrf4aStvsFDlGWPvpIdCR+aly2CfoB79B9/JjKFqg==} + engines: {node: '>=12.0'} + deprecated: The `apollo-datasource` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + dependencies: + '@apollo/utils.keyvaluecache': 1.0.2 + apollo-server-env: 4.2.1 + transitivePeerDependencies: + - encoding + dev: false + + /apollo-reporting-protobuf/3.3.3: + resolution: {integrity: sha512-L3+DdClhLMaRZWVmMbBcwl4Ic77CnEBPXLW53F7hkYhkaZD88ivbCVB1w/x5gunO6ZHrdzhjq0FHmTsBvPo7aQ==} + deprecated: The `apollo-reporting-protobuf` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/usage-reporting-protobuf` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + dependencies: + '@apollo/protobufjs': 1.2.6 + dev: false + + /apollo-server-core/3.11.1_graphql@15.8.0: + resolution: {integrity: sha512-t/eCKrRFK1lYZlc5pHD99iG7Np7CEm3SmbDiONA7fckR3EaB/pdsEdIkIwQ5QBBpT5JLp/nwvrZRVwhaWmaRvw==} + engines: {node: '>=12.0'} + deprecated: The `apollo-server-core` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^15.3.0 || ^16.0.0 + dependencies: + '@apollo/utils.keyvaluecache': 1.0.2 + '@apollo/utils.logger': 1.0.1 + '@apollo/utils.usagereporting': 1.0.1_graphql@15.8.0 + '@apollographql/apollo-tools': 0.5.4_graphql@15.8.0 + '@apollographql/graphql-playground-html': 1.6.29 + '@graphql-tools/mock': 8.7.12_graphql@15.8.0 + '@graphql-tools/schema': 8.5.0_graphql@15.8.0 + '@josephg/resolvable': 1.0.1 + apollo-datasource: 3.3.2 + apollo-reporting-protobuf: 3.3.3 + apollo-server-env: 4.2.1 + apollo-server-errors: 3.3.1_graphql@15.8.0 + apollo-server-plugin-base: 3.7.1_graphql@15.8.0 + apollo-server-types: 3.7.1_graphql@15.8.0 + async-retry: 1.3.3 + fast-json-stable-stringify: 2.1.0 + graphql: 15.8.0 + graphql-tag: 2.12.6_graphql@15.8.0 + loglevel: 1.8.1 + lru-cache: 6.0.0 + node-abort-controller: 3.0.1 + sha.js: 2.4.11 + uuid: 9.0.0 + whatwg-mimetype: 3.0.0 + transitivePeerDependencies: + - encoding + dev: false + + /apollo-server-env/4.2.1: + resolution: {integrity: sha512-vm/7c7ld+zFMxibzqZ7SSa5tBENc4B0uye9LTfjJwGoQFY5xsUPH5FpO5j0bMUDZ8YYNbrF9SNtzc5Cngcr90g==} + engines: {node: '>=12.0'} + deprecated: The `apollo-server-env` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/utils.fetcher` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + dependencies: + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: false + + /apollo-server-errors/3.3.1_graphql@15.8.0: + resolution: {integrity: sha512-xnZJ5QWs6FixHICXHxUfm+ZWqqxrNuPlQ+kj5m6RtEgIpekOPssH/SD9gf2B4HuWV0QozorrygwZnux8POvyPA==} + engines: {node: '>=12.0'} + deprecated: The `apollo-server-errors` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^15.3.0 || ^16.0.0 + dependencies: + graphql: 15.8.0 + dev: false + + /apollo-server-express/3.11.1_graphql@15.8.0: + resolution: {integrity: sha512-x9ngcpXbBlt4naCXTwNtBFb/mOd9OU0wtFXvJkObHF26NsRazu3DxDfEuekA6V1NFOocD+A9jmVMQeQWug5MgA==} + engines: {node: '>=12.0'} + deprecated: The `apollo-server-express` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + express: ^4.17.1 + graphql: ^15.3.0 || ^16.0.0 + dependencies: + '@types/accepts': 1.3.5 + '@types/body-parser': 1.19.2 + '@types/cors': 2.8.12 + '@types/express': 4.17.14 + '@types/express-serve-static-core': 4.17.31 + accepts: 1.3.8 + apollo-server-core: 3.11.1_graphql@15.8.0 + apollo-server-types: 3.7.1_graphql@15.8.0 + body-parser: 1.20.1 + cors: 2.8.5 + graphql: 15.8.0 + parseurl: 1.3.3 + transitivePeerDependencies: + - encoding + dev: false + + /apollo-server-plugin-base/3.7.1_graphql@15.8.0: + resolution: {integrity: sha512-g3vJStmQtQvjGI289UkLMfThmOEOddpVgHLHT2bNj0sCD/bbisj4xKbBHETqaURokteqSWyyd4RDTUe0wAUDNQ==} + engines: {node: '>=12.0'} + deprecated: The `apollo-server-plugin-base` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^15.3.0 || ^16.0.0 + dependencies: + apollo-server-types: 3.7.1_graphql@15.8.0 + graphql: 15.8.0 + transitivePeerDependencies: + - encoding + dev: false + + /apollo-server-types/3.7.1_graphql@15.8.0: + resolution: {integrity: sha512-aE9RDVplmkaOj/OduNmGa+0a1B5RIWI0o3zC1zLvBTVWMKTpo0ifVf11TyMkLCY+T7cnZqVqwyShziOyC3FyUw==} + engines: {node: '>=12.0'} + deprecated: The `apollo-server-types` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^15.3.0 || ^16.0.0 + dependencies: + '@apollo/utils.keyvaluecache': 1.0.2 + '@apollo/utils.logger': 1.0.1 + apollo-reporting-protobuf: 3.3.3 + apollo-server-env: 4.2.1 + graphql: 15.8.0 + transitivePeerDependencies: + - encoding + dev: false + /append-field/1.0.0: resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} dev: false @@ -6379,6 +6816,12 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} + /async-retry/1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + dependencies: + retry: 0.13.1 + dev: false + /async/2.6.4: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} dependencies: @@ -7336,6 +7779,10 @@ packages: hasBin: true dev: true + /cssfilter/0.0.10: + resolution: {integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==} + dev: false + /cssom/0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} dev: true @@ -9111,6 +9558,17 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 + dev: true + + /fast-glob/3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 /fast-json-stable-stringify/2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -9580,7 +10038,7 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.11 + fast-glob: 3.2.12 ignore: 5.2.0 merge2: 1.4.1 slash: 3.0.0 @@ -9704,7 +10162,16 @@ packages: graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 dependencies: graphql: 15.8.0 - tslib: 2.4.0 + tslib: 2.4.1 + + /graphql-ws/5.5.5_graphql@15.8.0: + resolution: {integrity: sha512-hvyIS71vs4Tu/yUYHPvGXsTgo0t3arU820+lT5VjZS2go0ewp2LqyCgxEN56CzOG7Iys52eRhHBiD1gGRdiQtw==} + engines: {node: '>=10'} + peerDependencies: + graphql: '>=0.11 <=16' + dependencies: + graphql: 15.8.0 + dev: false /graphql-ws/5.9.1_graphql@15.8.0: resolution: {integrity: sha512-mL/SWGBwIT9Meq0NlfS55yXXTOeWPMbK7bZBEZhFu46bcGk1coTx2Sdtzxdk+9yHWngD+Fk1PZDWaAutQa9tpw==} @@ -11824,6 +12291,10 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.omit/4.5.0: + resolution: {integrity: sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==} + dev: false + /lodash.once/4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} dev: true @@ -11855,6 +12326,11 @@ packages: slice-ansi: 4.0.0 wrap-ansi: 6.2.0 + /loglevel/1.8.1: + resolution: {integrity: sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==} + engines: {node: '>= 0.6.0'} + dev: false + /long/4.0.0: resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} dev: false @@ -11887,6 +12363,11 @@ packages: dependencies: yallist: 4.0.0 + /lru-cache/7.13.1: + resolution: {integrity: sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ==} + engines: {node: '>=12'} + dev: false + /macos-release/2.5.0: resolution: {integrity: sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g==} engines: {node: '>=6'} @@ -12217,7 +12698,6 @@ packages: /node-abort-controller/3.0.1: resolution: {integrity: sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==} - dev: true /node-domexception/1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} @@ -13206,6 +13686,11 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 + /retry/0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + dev: false + /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -13357,7 +13842,7 @@ packages: /rxjs/7.5.5: resolution: {integrity: sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==} dependencies: - tslib: 2.4.0 + tslib: 2.4.1 /rxjs/7.6.0: resolution: {integrity: sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==} @@ -13513,6 +13998,14 @@ packages: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: false + /sha.js/2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + /shebang-command/1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -15826,6 +16319,11 @@ packages: resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} dev: true + /whatwg-mimetype/3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + dev: false + /whatwg-url/5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: @@ -16113,6 +16611,19 @@ packages: utf-8-validate: optional: true + /ws/8.11.0: + resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /ws/8.2.3: resolution: {integrity: sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==} engines: {node: '>=10.0.0'} @@ -16180,6 +16691,15 @@ packages: engines: {node: '>=0.4.0'} dev: false + /xss/1.0.14: + resolution: {integrity: sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==} + engines: {node: '>= 0.10.0'} + hasBin: true + dependencies: + commander: 2.20.3 + cssfilter: 0.0.10 + dev: false + /xtend/4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} From 0f3e36a447c6ae912b602e2aa21e9be158e5f3bb Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Tue, 6 Dec 2022 15:00:51 -0500 Subject: [PATCH 02/14] chore: get functioning server running --- packages/hoppscotch-backend/Dockerfile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/hoppscotch-backend/Dockerfile b/packages/hoppscotch-backend/Dockerfile index 0e655336d..7eb6d8331 100644 --- a/packages/hoppscotch-backend/Dockerfile +++ b/packages/hoppscotch-backend/Dockerfile @@ -2,12 +2,12 @@ FROM node:lts WORKDIR /usr/src/app -# Install pnpm +# # Install pnpm RUN npm i -g pnpm -# NPM package install -COPY package*.json ./ -RUN pnpm install +# # NPM package install +# COPY package*.json ./ +# RUN pnpm install # Prisma bits @@ -16,8 +16,7 @@ RUN pnpm install COPY . . - -RUN pnpm run build +RUN pnpm i EXPOSE 3170 EXPOSE 9229 @@ -25,6 +24,7 @@ EXPOSE 9229 ENV APP_PORT=${PORT} ENV DB_URL=${DATABASE_URL} ENV PRODUCTION=true + #ENV FB_SERVICE_KEY_PATH="secrets/fb-service-key.json" -CMD ["pnpm", "run", "start:dev"] -#CMD ["./run.sh", "start:dev"] +# CMD ["pnpm", "run", "start:dev"] +CMD ["pnpm", "run", "start"] From 9193a1a5d6b2e5ed849fabbd25526141a8e82982 Mon Sep 17 00:00:00 2001 From: Balu Babu Date: Wed, 7 Dec 2022 20:13:42 +0530 Subject: [PATCH 03/14] chore: fixed docker-compose issue with package/hopp-backend --- packages/hoppscotch-backend/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hoppscotch-backend/docker-compose.yml b/packages/hoppscotch-backend/docker-compose.yml index a5e6d597b..eab1e473d 100644 --- a/packages/hoppscotch-backend/docker-compose.yml +++ b/packages/hoppscotch-backend/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.0' services: local: - build: ./Dockerfile + build: . environment: - PRODUCTION=false - DATABASE_URL=postgresql://postgres:testpass@dev-db:5432/hoppscotch From d7afd3157298e35fcea94fa7114f1b6bb729a13c Mon Sep 17 00:00:00 2001 From: Balu Babu Date: Wed, 7 Dec 2022 20:28:46 +0530 Subject: [PATCH 04/14] chore: created pubsub module and added relevant dependencies for it --- packages/hoppscotch-backend/package.json | 3 + pnpm-lock.yaml | 223 ++++++++++------------- 2 files changed, 104 insertions(+), 122 deletions(-) diff --git a/packages/hoppscotch-backend/package.json b/packages/hoppscotch-backend/package.json index cf458971c..c603b4146 100644 --- a/packages/hoppscotch-backend/package.json +++ b/packages/hoppscotch-backend/package.json @@ -28,6 +28,9 @@ "@nestjs/platform-express": "^9.2.1", "apollo-server-express": "^3.11.1", "graphql": "^15.5.0", + "graphql-redis-subscriptions": "^2.5.0", + "graphql-subscriptions": "^2.0.0", + "ioredis": "^5.2.4", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.6.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 48173372f..0f3500dda 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,6 +63,9 @@ importers: eslint-config-prettier: ^8.5.0 eslint-plugin-prettier: ^4.2.1 graphql: ^15.5.0 + graphql-redis-subscriptions: ^2.5.0 + graphql-subscriptions: ^2.0.0 + ioredis: ^5.2.4 jest: 29.3.1 prettier: ^2.8.0 reflect-metadata: ^0.1.13 @@ -83,6 +86,9 @@ importers: '@nestjs/platform-express': 9.2.1_hjcqpoaebdr7gdo5hgc22hthbe apollo-server-express: 3.11.1_graphql@15.8.0 graphql: 15.8.0 + graphql-redis-subscriptions: 2.5.0_nsv4zbviaf54hk5nfhl4slig7i + graphql-subscriptions: 2.0.0_graphql@15.8.0 + ioredis: 5.2.4 reflect-metadata: 0.1.13 rimraf: 3.0.2 rxjs: 7.6.0 @@ -2446,7 +2452,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: true optional: true /@eslint/eslintrc/1.3.0: @@ -3645,14 +3650,12 @@ packages: '@intlify/message-compiler': 9.2.2 '@intlify/shared': 9.2.2 '@intlify/vue-devtools': 9.2.2 - dev: false /@intlify/devtools-if/9.2.2: resolution: {integrity: sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==} engines: {node: '>= 14'} dependencies: '@intlify/shared': 9.2.2 - dev: false /@intlify/message-compiler/9.2.2: resolution: {integrity: sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==} @@ -3660,7 +3663,6 @@ packages: dependencies: '@intlify/shared': 9.2.2 source-map: 0.6.1 - dev: false /@intlify/message-compiler/9.3.0-beta.10: resolution: {integrity: sha512-RoOC6yceOykLRhN0NlbkNOBUx1el6iphx3W8NfOx3jHVNtfT1FYokx14/5sU3F1F0uxeG4sp6q+ppKvaF8o+ww==} @@ -3673,7 +3675,6 @@ packages: /@intlify/shared/9.2.2: resolution: {integrity: sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==} engines: {node: '>= 14'} - dev: false /@intlify/shared/9.3.0-beta.10: resolution: {integrity: sha512-h93uAanbAt/XgjDHclrVB7xix6r7Uz11wx0iGNOCdHP7aA2LCJjUT3uNbekJjjbo+Fl5jzTSJZdm2SexzoqhRA==} @@ -3739,6 +3740,9 @@ packages: dependencies: '@intlify/core-base': 9.2.2 '@intlify/shared': 9.2.2 + + /@ioredis/commands/1.2.0: + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} dev: false /@istanbuljs/load-nyc-config/1.1.0: @@ -4400,7 +4404,6 @@ packages: rxjs: 7.6.0 tslib: 2.4.1 uuid: 9.0.0 - dev: false /@nestjs/core/9.2.1_ajc4cvdydchgvxyi4xnoij5t4i: resolution: {integrity: sha512-a9GkXuu8uXgNgCVW+17iI8kLCltO+HwHpU2IhR+32JKnN2WEQ1YEWU4t3GJ2MNq44YkjIw9zrKvFkjJBlYrNbQ==} @@ -4433,7 +4436,6 @@ packages: uuid: 9.0.0 transitivePeerDependencies: - encoding - dev: false /@nestjs/graphql/10.1.6_2khsk5ahlt4vlkrgib4soffmwu: resolution: {integrity: sha512-RiDTqyBqk+qolcMMKBANuG5zw0q0zbVmkwWydB2F1ObvUyl5t/GOAcR8mbq3gvpfYzylQ5t5/svWUDq/7dcpaQ==} @@ -4505,7 +4507,8 @@ packages: express: 4.18.2 multer: 1.4.4-lts.1 tslib: 2.4.1 - dev: false + transitivePeerDependencies: + - supports-color /@nestjs/schematics/9.0.3_ar2on76c45aosuucycxzxivxgm: resolution: {integrity: sha512-kZrU/lrpVd2cnK8I3ibDb3Wi1ppl3wX3U3lVWoL+DzRRoezWKkh8upEL4q0koKmuXnsmLiu3UPxFeMOrJV7TSA==} @@ -4584,7 +4587,6 @@ packages: node-fetch: 2.6.7 transitivePeerDependencies: - encoding - dev: false /@polka/url/1.0.0-next.21: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} @@ -5775,7 +5777,6 @@ packages: '@graphql-typed-document-node/core': 3.1.1_graphql@15.8.0 graphql: 15.8.0 wonka: 4.0.15 - dev: false /@urql/devtools/2.0.3_orwd6brffn6tmxxcil5zw6uzri: resolution: {integrity: sha512-TktPLiBS9LcBPHD6qcnb8wqOVcg3Bx0iCtvQ80uPpfofwwBGJmqnQTjUdEFU6kwaLOFZULQ9+Uo4831G823mQw==} @@ -5806,7 +5807,6 @@ packages: '@urql/core': 2.5.0_graphql@15.8.0 graphql: 15.8.0 wonka: 4.0.15 - dev: false /@urql/introspection/0.3.3_graphql@15.8.0: resolution: {integrity: sha512-tekSLLqWnusfV6V7xaEnLJQSdXOD/lWy7f8JYQwrX+88Md+voGSCSx5WJXI7KLBN3Tat2OV08tAr8UROykls4Q==} @@ -5945,7 +5945,6 @@ packages: '@vue/shared': 3.2.37 estree-walker: 2.0.2 source-map: 0.6.1 - dev: false /@vue/compiler-core/3.2.39: resolution: {integrity: sha512-mf/36OWXqWn0wsC40nwRRGheR/qoID+lZXbIuLnr4/AngM0ov8Xvv8GHunC0rKRIkh60bTqydlqTeBo49rlbqw==} @@ -5969,7 +5968,6 @@ packages: dependencies: '@vue/compiler-core': 3.2.37 '@vue/shared': 3.2.37 - dev: false /@vue/compiler-dom/3.2.39: resolution: {integrity: sha512-HMFI25Be1C8vLEEv1hgEO1dWwG9QQ8LTTPmCkblVJY/O3OvWx6r1+zsox5mKPMGvqYEZa6l8j+xgOfUspgo7hw==} @@ -6005,7 +6003,6 @@ packages: magic-string: 0.25.9 postcss: 8.4.19 source-map: 0.6.1 - dev: false /@vue/compiler-sfc/3.2.39: resolution: {integrity: sha512-fqAQgFs1/BxTUZkd0Vakn3teKUt//J3c420BgnYgEOoVdTwYpBTSXCMJ88GOBCylmUBbtquGPli9tVs7LzsWIA==} @@ -6041,7 +6038,6 @@ packages: dependencies: '@vue/compiler-dom': 3.2.37 '@vue/shared': 3.2.37 - dev: false /@vue/compiler-ssr/3.2.39: resolution: {integrity: sha512-EoGCJ6lincKOZGW+0Ky4WOKsSmqL7hp1ZYgen8M7u/mlvvEQUaO9tKKOy7K43M9U2aA3tPv0TuYYQFrEbK2eFQ==} @@ -6058,7 +6054,6 @@ packages: /@vue/devtools-api/6.2.1: resolution: {integrity: sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==} - dev: false /@vue/eslint-config-typescript/11.0.1_kpxf5iryryrlim2ejhkirkiuey: resolution: {integrity: sha512-0U+nL0nA7ahnGPk3rTN49x76miUwuQtQPQNWOFvAcjg6nFJkIkA8qbGNtXwsuHtwBwRtWpHhShL3zK07v+632w==} @@ -6110,7 +6105,6 @@ packages: '@vue/shared': 3.2.37 estree-walker: 2.0.2 magic-string: 0.25.9 - dev: false /@vue/reactivity-transform/3.2.39: resolution: {integrity: sha512-HGuWu864zStiWs9wBC6JYOP1E00UjMdDWIG5W+FpUx28hV3uz9ODOKVNm/vdOy/Pvzg8+OcANxAVC85WFBbl3A==} @@ -6135,7 +6129,6 @@ packages: resolution: {integrity: sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==} dependencies: '@vue/shared': 3.2.37 - dev: false /@vue/reactivity/3.2.39: resolution: {integrity: sha512-vlaYX2a3qMhIZfrw3Mtfd+BuU+TZmvDrPMa+6lpfzS9k/LnGxkSuf0fhkP0rMGfiOHPtyKoU9OJJJFGm92beVQ==} @@ -6153,7 +6146,6 @@ packages: dependencies: '@vue/reactivity': 3.2.37 '@vue/shared': 3.2.37 - dev: false /@vue/runtime-core/3.2.39: resolution: {integrity: sha512-xKH5XP57JW5JW+8ZG1khBbuLakINTgPuINKL01hStWLTTGFOrM49UfCFXBcFvWmSbci3gmJyLl2EAzCaZWsx8g==} @@ -6167,7 +6159,6 @@ packages: dependencies: '@vue/reactivity': 3.2.45 '@vue/shared': 3.2.45 - dev: false /@vue/runtime-dom/3.2.37: resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} @@ -6175,7 +6166,6 @@ packages: '@vue/runtime-core': 3.2.37 '@vue/shared': 3.2.37 csstype: 2.6.20 - dev: false /@vue/runtime-dom/3.2.45: resolution: {integrity: sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==} @@ -6183,7 +6173,6 @@ packages: '@vue/runtime-core': 3.2.45 '@vue/shared': 3.2.45 csstype: 2.6.20 - dev: false /@vue/server-renderer/3.2.37_vue@3.2.37: resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} @@ -6193,7 +6182,6 @@ packages: '@vue/compiler-ssr': 3.2.37 '@vue/shared': 3.2.37 vue: 3.2.37 - dev: false /@vue/server-renderer/3.2.45_vue@3.2.45: resolution: {integrity: sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==} @@ -6203,11 +6191,9 @@ packages: '@vue/compiler-ssr': 3.2.45 '@vue/shared': 3.2.45 vue: 3.2.45 - dev: false /@vue/shared/3.2.37: resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} - dev: false /@vue/shared/3.2.39: resolution: {integrity: sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw==} @@ -6428,7 +6414,6 @@ packages: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 - dev: false /acorn-globals/6.0.0: resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} @@ -6741,6 +6726,7 @@ packages: parseurl: 1.3.3 transitivePeerDependencies: - encoding + - supports-color dev: false /apollo-server-plugin-base/3.7.1_graphql@15.8.0: @@ -6774,7 +6760,6 @@ packages: /append-field/1.0.0: resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - dev: false /arg/4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -6789,7 +6774,6 @@ packages: /array-flatten/1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - dev: false /array-ify/1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} @@ -7105,7 +7089,8 @@ packages: raw-body: 2.5.1 type-is: 1.6.18 unpipe: 1.0.0 - dev: false + transitivePeerDependencies: + - supports-color /boolbase/1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -7236,7 +7221,6 @@ packages: /bytes/3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - dev: false /cac/6.7.12: resolution: {integrity: sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA==} @@ -7462,6 +7446,11 @@ packages: engines: {node: '>=0.8'} dev: true + /cluster-key-slot/1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + dev: false + /co/4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -7563,11 +7552,9 @@ packages: inherits: 2.0.4 readable-stream: 2.3.7 typedarray: 0.0.6 - dev: false /consola/2.15.3: resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} - dev: false /constant-case/3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} @@ -7581,12 +7568,10 @@ packages: engines: {node: '>= 0.6'} dependencies: safe-buffer: 5.2.1 - dev: false /content-type/1.0.4: resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} engines: {node: '>= 0.6'} - dev: false /conventional-changelog-angular/5.0.13: resolution: {integrity: sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==} @@ -7610,8 +7595,8 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - is-text-path: 1.0.1 JSONStream: 1.3.5 + is-text-path: 1.0.1 lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 @@ -7630,12 +7615,10 @@ packages: /cookie-signature/1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - dev: false /cookie/0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} - dev: false /cookiejar/2.1.3: resolution: {integrity: sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==} @@ -7660,7 +7643,6 @@ packages: /core-util-is/1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: false /cors/2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} @@ -7668,7 +7650,6 @@ packages: dependencies: object-assign: 4.1.1 vary: 1.1.2 - dev: false /corser/2.0.1: resolution: {integrity: sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==} @@ -7800,7 +7781,6 @@ packages: /csstype/2.6.20: resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} - dev: false /csstype/3.1.0: resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==} @@ -7833,9 +7813,13 @@ packages: /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true dependencies: ms: 2.0.0 - dev: false /debug/3.1.0: resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} @@ -7958,10 +7942,14 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + /denque/2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + dev: false + /depd/2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} - dev: false /dependency-graph/0.11.0: resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} @@ -7971,7 +7959,6 @@ packages: /destroy/1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dev: false /detect-indent/6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} @@ -8072,7 +8059,6 @@ packages: /ee-first/1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - dev: false /ejs/3.1.8: resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} @@ -8106,7 +8092,6 @@ packages: /encodeurl/1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} - dev: false /end-of-stream/1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -8294,7 +8279,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: true optional: true /esbuild-android-arm64/0.14.48: @@ -8320,7 +8304,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /esbuild-darwin-64/0.14.48: @@ -8346,7 +8329,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /esbuild-darwin-arm64/0.14.48: @@ -8372,7 +8354,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /esbuild-freebsd-64/0.14.48: @@ -8398,7 +8379,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: true optional: true /esbuild-freebsd-arm64/0.14.48: @@ -8424,7 +8404,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: true optional: true /esbuild-linux-32/0.14.48: @@ -8450,7 +8429,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-linux-64/0.14.48: @@ -8476,7 +8454,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-linux-arm/0.14.48: @@ -8502,7 +8479,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-linux-arm64/0.14.48: @@ -8528,7 +8504,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-linux-mips64le/0.14.48: @@ -8554,7 +8529,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-linux-ppc64le/0.14.48: @@ -8580,7 +8554,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-linux-riscv64/0.14.48: @@ -8606,7 +8579,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-linux-s390x/0.14.48: @@ -8632,7 +8604,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /esbuild-netbsd-64/0.14.48: @@ -8658,7 +8629,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: true optional: true /esbuild-openbsd-64/0.14.48: @@ -8684,7 +8654,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: true optional: true /esbuild-sunos-64/0.14.48: @@ -8710,7 +8679,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: true optional: true /esbuild-windows-32/0.14.48: @@ -8736,7 +8704,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /esbuild-windows-64/0.14.48: @@ -8762,7 +8729,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /esbuild-windows-arm64/0.14.48: @@ -8788,7 +8754,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /esbuild/0.14.48: @@ -8875,7 +8840,6 @@ packages: esbuild-windows-32: 0.15.7 esbuild-windows-64: 0.15.7 esbuild-windows-arm64: 0.15.7 - dev: true /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} @@ -8883,7 +8847,6 @@ packages: /escape-html/1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - dev: false /escape-string-regexp/1.0.5: resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} @@ -9383,7 +9346,6 @@ packages: /etag/1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - dev: false /event-stream/3.3.4: resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} @@ -9514,7 +9476,8 @@ packages: type-is: 1.6.18 utils-merge: 1.0.1 vary: 1.1.2 - dev: false + transitivePeerDependencies: + - supports-color /external-editor/3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} @@ -9664,7 +9627,8 @@ packages: parseurl: 1.3.3 statuses: 2.0.1 unpipe: 1.0.0 - dev: false + transitivePeerDependencies: + - supports-color /find-up/4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} @@ -9824,7 +9788,6 @@ packages: /forwarded/0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - dev: false /fp-ts/2.12.1: resolution: {integrity: sha512-oxvgqUYR6O9VkKXrxkJ0NOyU0FrE705MeqgBUMEPWyTu6Pwn768cJbHChw2XOBlgFLKfIHxjr2OOBFpv2mUGZw==} @@ -9832,7 +9795,6 @@ packages: /fresh/0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} - dev: false /from/0.1.7: resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} @@ -10142,6 +10104,19 @@ packages: - utf-8-validate dev: false + /graphql-redis-subscriptions/2.5.0_nsv4zbviaf54hk5nfhl4slig7i: + resolution: {integrity: sha512-l7Sc1gXdgNUGFlgWOpqh14ZDm6bM2PPCvMprSt/myZAhTjE2u5Gw5F4ndanS0JqRtO/QhzoZCqio7ewDHa9P3w==} + peerDependencies: + graphql-subscriptions: ^1.0.0 || ^2.0.0 + dependencies: + graphql-subscriptions: 2.0.0_graphql@15.8.0 + iterall: 1.3.0 + optionalDependencies: + ioredis: 5.2.4 + transitivePeerDependencies: + - supports-color + dev: false + /graphql-request/4.3.0_graphql@15.8.0: resolution: {integrity: sha512-2v6hQViJvSsifK606AliqiNiijb1uwWp6Re7o0RTyH+uRTv/u7Uqm2g4Fjq/LgZIzARB38RZEvVBFOQOVdlBow==} peerDependencies: @@ -10155,6 +10130,15 @@ packages: - encoding dev: true + /graphql-subscriptions/2.0.0_graphql@15.8.0: + resolution: {integrity: sha512-s6k2b8mmt9gF9pEfkxsaO1lTxaySfKoEJzEfmwguBbQ//Oq23hIXCfR1hm4kdh5hnR20RdwB+s3BCb+0duHSZA==} + peerDependencies: + graphql: ^15.7.2 || ^16.0.0 + dependencies: + graphql: 15.8.0 + iterall: 1.3.0 + dev: false + /graphql-tag/2.12.6_graphql@15.8.0: resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} engines: {node: '>=10'} @@ -10184,7 +10168,6 @@ packages: /graphql/15.8.0: resolution: {integrity: sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==} engines: {node: '>= 10.x'} - dev: false /growl/1.10.5: resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} @@ -10318,7 +10301,6 @@ packages: setprototypeof: 1.2.0 statuses: 2.0.1 toidentifier: 1.0.1 - dev: false /http-parser-js/0.5.8: resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} @@ -10459,7 +10441,6 @@ packages: /immutable/4.1.0: resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} - dev: true /import-fresh/3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -10595,10 +10576,26 @@ packages: dependencies: fp-ts: 2.12.1 + /ioredis/5.2.4: + resolution: {integrity: sha512-qIpuAEt32lZJQ0XyrloCRdlEdUUNGG9i0UOk6zgzK6igyudNWqEBxfH6OlbnOOoBBvr1WB02mm8fR55CnikRng==} + engines: {node: '>=12.22.0'} + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.2 + debug: 4.3.4 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + /ipaddr.js/1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - dev: false /is-absolute/1.0.0: resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} @@ -10644,7 +10641,6 @@ packages: resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} dependencies: has: 1.0.3 - dev: true /is-date-object/1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -10849,7 +10845,6 @@ packages: /isarray/1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: false /isarray/2.0.1: resolution: {integrity: sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==} @@ -10936,7 +10931,6 @@ packages: /iterare/1.2.1: resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} engines: {node: '>=6'} - dev: false /jake/10.8.5: resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} @@ -12252,6 +12246,10 @@ packages: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} dev: true + /lodash.defaults/4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + dev: false + /lodash.get/4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} @@ -12259,6 +12257,10 @@ packages: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} dev: true + /lodash.isarguments/3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + dev: false + /lodash.isboolean/3.0.3: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} dev: true @@ -12429,7 +12431,6 @@ packages: /media-typer/0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} - dev: false /memfs/3.4.12: resolution: {integrity: sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==} @@ -12469,7 +12470,6 @@ packages: /merge-descriptors/1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - dev: false /merge-stream/2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -12622,7 +12622,6 @@ packages: /ms/2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: false /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -12645,7 +12644,6 @@ packages: object-assign: 4.1.1 type-is: 1.6.18 xtend: 4.0.2 - dev: false /mute-stream/0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} @@ -12680,7 +12678,6 @@ packages: /negotiator/0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - dev: false /neo-async/2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -12803,7 +12800,6 @@ packages: /object-hash/3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} - dev: false /object-inspect/1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} @@ -12839,7 +12835,6 @@ packages: engines: {node: '>= 0.8'} dependencies: ee-first: 1.1.1 - dev: false /once/1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -12871,7 +12866,6 @@ packages: /openapi-types/12.0.0: resolution: {integrity: sha512-6Wd9k8nmGQHgCbehZCP6wwWcfXcvinhybUTBatuhjRsCxUIujuYFZc9QnGeae75CyHASewBtxs0HX/qwREReUw==} - dev: true /opener/1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} @@ -13043,7 +13037,6 @@ packages: /parseurl/1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} - dev: false /pascal-case/3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -13077,7 +13070,6 @@ packages: /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true /path-root-regex/0.1.2: resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} @@ -13093,11 +13085,9 @@ packages: /path-to-regexp/0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - dev: false /path-to-regexp/3.2.0: resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} - dev: false /path-type/3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} @@ -13218,7 +13208,6 @@ packages: nanoid: 3.3.4 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: true /postcss/8.4.19: resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==} @@ -13321,7 +13310,6 @@ packages: /process-nextick-args/2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: false /process/0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} @@ -13372,7 +13360,6 @@ packages: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 - dev: false /prr/1.0.1: resolution: {integrity: sha1-0/wRS6BplaRexok/SEzrHXj19HY=} @@ -13447,7 +13434,6 @@ packages: /range-parser/1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - dev: false /raw-body/2.5.1: resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} @@ -13457,7 +13443,6 @@ packages: http-errors: 2.0.0 iconv-lite: 0.4.24 unpipe: 1.0.0 - dev: false /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -13505,7 +13490,6 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 - dev: false /readable-stream/3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} @@ -13536,9 +13520,20 @@ packages: strip-indent: 3.0.0 dev: true + /redis-errors/1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + dev: false + + /redis-parser/3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + dependencies: + redis-errors: 1.2.0 + dev: false + /reflect-metadata/0.1.13: resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} - dev: false /regenerate-unicode-properties/10.0.1: resolution: {integrity: sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==} @@ -13677,7 +13672,6 @@ packages: is-core-module: 2.9.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /restore-cursor/3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} @@ -13812,7 +13806,6 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.2 - dev: true /rollup/2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} @@ -13848,7 +13841,6 @@ packages: resolution: {integrity: sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==} dependencies: tslib: 2.4.1 - dev: false /safe-buffer/5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -13867,7 +13859,6 @@ packages: chokidar: 3.5.3 immutable: 4.1.0 source-map-js: 1.0.2 - dev: true /sax/1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} @@ -13956,7 +13947,8 @@ packages: on-finished: 2.4.1 range-parser: 1.2.1 statuses: 2.0.1 - dev: false + transitivePeerDependencies: + - supports-color /sentence-case/3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} @@ -13985,7 +13977,8 @@ packages: escape-html: 1.0.3 parseurl: 1.3.3 send: 0.18.0 - dev: false + transitivePeerDependencies: + - supports-color /set-blocking/2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -13996,7 +13989,6 @@ packages: /setprototypeof/1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - dev: false /sha.js/2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} @@ -14278,10 +14270,13 @@ packages: escape-string-regexp: 2.0.0 dev: true + /standard-as-callback/2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + dev: false + /statuses/2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - dev: false /stream-browserify/3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} @@ -14534,7 +14529,6 @@ packages: /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - dev: true /swagger-methods/2.0.2: resolution: {integrity: sha512-/RNqvBZkH8+3S/FqBPejHxJxZenaYq3MrpeXnzi06aDIS39Mqf5YCUNb/ZBjsvFFt8h9FxfKs8EXPtcYdfLiRg==} @@ -14762,7 +14756,6 @@ packages: /toidentifier/1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - dev: false /totalist/3.0.0: resolution: {integrity: sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==} @@ -15158,7 +15151,6 @@ packages: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - dev: false /typedarray-to-buffer/3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} @@ -15168,13 +15160,11 @@ packages: /typedarray/0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - dev: false /typescript/4.7.4: resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} engines: {node: '>=4.2.0'} hasBin: true - dev: true /typescript/4.8.4: resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} @@ -15273,7 +15263,6 @@ packages: /unpipe/1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - dev: false /unplugin-icons/0.14.9_vite@3.2.4: resolution: {integrity: sha512-vPyVfNREH88dP6gszdaoGkAEFPpiScXj1A8eWN905jQgT53A3tsiPEiqJjCHOUVcsUaREt2JSudzumFOsCA78A==} @@ -15559,7 +15548,6 @@ packages: /utils-merge/1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} - dev: false /uuid/8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} @@ -15569,7 +15557,6 @@ packages: /uuid/9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} hasBin: true - dev: false /v8-compile-cache-lib/3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -15616,7 +15603,6 @@ packages: /vary/1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - dev: false /vite-plugin-checker/0.5.1_kjjvnh3jl66vp4phsscdedqila: resolution: {integrity: sha512-NFiO1PyK9yGuaeSnJ7Whw9fnxLc1AlELnZoyFURnauBYhbIkx9n+PmIXxSFUuC9iFyACtbJQUAEuQi6yHs2Adg==} @@ -15926,7 +15912,6 @@ packages: sass: 1.53.0 optionalDependencies: fsevents: 2.3.2 - dev: true /vite/3.2.4: resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} @@ -16073,7 +16058,6 @@ packages: '@intlify/vue-devtools': 9.2.2 '@vue/devtools-api': 6.2.1 vue: 3.2.37 - dev: false /vue-pdf-embed/1.1.4_vue@3.2.37: resolution: {integrity: sha512-d4c7nM3LneWUiL4MssIyPHfGgVMRPh4Z7UgLsXMZ+lbAtH/6SBUFHdzZQLY2BASdh16BM/v6YCbmtQU+KIQdrg==} @@ -16090,7 +16074,6 @@ packages: dependencies: '@vue/devtools-api': 6.2.1 vue: 3.2.37 - dev: false /vue-template-compiler/2.7.14: resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} @@ -16144,7 +16127,6 @@ packages: '@vue/runtime-dom': 3.2.37 '@vue/server-renderer': 3.2.37_vue@3.2.37 '@vue/shared': 3.2.37 - dev: false /vue/3.2.45: resolution: {integrity: sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==} @@ -16154,7 +16136,6 @@ packages: '@vue/runtime-dom': 3.2.45 '@vue/server-renderer': 3.2.45_vue@3.2.45 '@vue/shared': 3.2.45 - dev: false /vuedraggable/4.1.0_vue@3.2.37: resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} @@ -16408,7 +16389,6 @@ packages: /wonka/4.0.15: resolution: {integrity: sha512-U0IUQHKXXn6PFo9nqsHphVCE5m3IntqZNB9Jjn7EB1lrR7YTDY3YWgFvEvwniTzXSvOH/XMzAZaIfJF/LvHYXg==} - dev: false /word-wrap/1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} @@ -16703,7 +16683,6 @@ packages: /xtend/4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - dev: false /y18n/4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} From ab1f8437ea9391f792e9b90f3190acc51538df4a Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Wed, 7 Dec 2022 20:30:02 +0530 Subject: [PATCH 05/14] chore: added existing auth guard and user model --- .../src/guards/gql-auth.guard.ts | 42 +++++++++++++++++++ .../hoppscotch-backend/src/user/user.model.ts | 27 ++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 packages/hoppscotch-backend/src/guards/gql-auth.guard.ts create mode 100644 packages/hoppscotch-backend/src/user/user.model.ts diff --git a/packages/hoppscotch-backend/src/guards/gql-auth.guard.ts b/packages/hoppscotch-backend/src/guards/gql-auth.guard.ts new file mode 100644 index 000000000..aabc77b10 --- /dev/null +++ b/packages/hoppscotch-backend/src/guards/gql-auth.guard.ts @@ -0,0 +1,42 @@ +import { CanActivate, Injectable, ExecutionContext } from '@nestjs/common'; +import { GqlExecutionContext } from '@nestjs/graphql'; +import { User } from '../user/user.model'; +import { IncomingHttpHeaders } from 'http2'; +import { AUTH_FAIL } from 'src/errors'; + +@Injectable() +export class GqlAuthGuard implements CanActivate { + // eslint-disable-next-line @typescript-eslint/no-empty-function + constructor() {} + + async canActivate(context: ExecutionContext): Promise { + try { + const ctx = GqlExecutionContext.create(context).getContext<{ + reqHeaders: IncomingHttpHeaders; + user: User | null; + }>(); + + if ( + ctx.reqHeaders.authorization && + ctx.reqHeaders.authorization.startsWith('Bearer ') + ) { + const idToken = ctx.reqHeaders.authorization.split(' ')[1]; + + const authUser: User = { + uid: 'aabb22ccdd', + displayName: 'exampleUser', + photoURL: 'http://example.com/avatar', + email: 'me@example.com', + }; + + ctx.user = authUser; + + return true; + } else { + return false; + } + } catch (e) { + throw new Error(AUTH_FAIL); + } + } +} diff --git a/packages/hoppscotch-backend/src/user/user.model.ts b/packages/hoppscotch-backend/src/user/user.model.ts new file mode 100644 index 000000000..779dbc4db --- /dev/null +++ b/packages/hoppscotch-backend/src/user/user.model.ts @@ -0,0 +1,27 @@ +import { ObjectType, ID, Field } from '@nestjs/graphql'; + +@ObjectType() +export class User { + @Field(() => ID, { + description: 'Firebase UID of the user', + }) + uid: string; + + @Field({ + nullable: true, + description: 'Displayed name of the user (if given)', + }) + displayName?: string; + + @Field({ + nullable: true, + description: 'Email of the user (if given)', + }) + email?: string; + + @Field({ + nullable: true, + description: 'URL to the profile photo of the user (if given)', + }) + photoURL?: string; +} From 757060b11f7a132e3afe2787e2f6397c9f95d497 Mon Sep 17 00:00:00 2001 From: Balu Babu Date: Wed, 7 Dec 2022 20:31:54 +0530 Subject: [PATCH 06/14] chore: removed comments from pubsub module --- .../src/pubsub/pubsub.module.ts | 8 ++ .../src/pubsub/pubsub.service.ts | 76 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 packages/hoppscotch-backend/src/pubsub/pubsub.module.ts create mode 100644 packages/hoppscotch-backend/src/pubsub/pubsub.service.ts diff --git a/packages/hoppscotch-backend/src/pubsub/pubsub.module.ts b/packages/hoppscotch-backend/src/pubsub/pubsub.module.ts new file mode 100644 index 000000000..b20d887e8 --- /dev/null +++ b/packages/hoppscotch-backend/src/pubsub/pubsub.module.ts @@ -0,0 +1,8 @@ +import { Module } from "@nestjs/common"; +import { PubSubService } from "./pubsub.service"; + +@Module({ + providers: [PubSubService], + exports: [PubSubService] +}) +export class PubSubModule {} diff --git a/packages/hoppscotch-backend/src/pubsub/pubsub.service.ts b/packages/hoppscotch-backend/src/pubsub/pubsub.service.ts new file mode 100644 index 000000000..475768712 --- /dev/null +++ b/packages/hoppscotch-backend/src/pubsub/pubsub.service.ts @@ -0,0 +1,76 @@ +import { OnModuleInit } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; +import { default as Redis, RedisOptions } from 'ioredis'; + +import { RedisPubSub } from 'graphql-redis-subscriptions'; +import { PubSub as LocalPubSub } from 'graphql-subscriptions'; + +/** + * RedisPubSub uses JSON parsing for back and forth conversion, which loses Date objects, hence this reviver brings them back + * This function implementation should function like the JSON.parse reviver function + * @param key The key being parsed + * @param value The value being parsed + * @returns The updated value for the key + */ +const dateReviver = (key: string, value: unknown) => { + const isISO8601Z = + /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/; + + if (typeof value === 'string' && isISO8601Z.test(value)) { + const tempDateNumber = Date.parse(value); + + if (!isNaN(tempDateNumber)) { + return new Date(tempDateNumber); + } + } + + return value; +}; + +/* + * Figure out which PubSub to use (simple/local for dev and Redis for production) + * and expose it + */ + +@Injectable() +export class PubSubService implements OnModuleInit { + private pubsub: RedisPubSub | LocalPubSub; + + onModuleInit() { + if (process.env.PRODUCTION === 'false') { + console.log('Initialize PubSub in development mode'); + + this.pubsub = new LocalPubSub(); + } else { + console.log('Initialize PubSub in production mode'); + console.log( + `REDIS_IP: ${process.env.REDIS_IP}, REDIS_PORT: ${process.env.REDIS_PORT}`, + ); + + const redisOptions: RedisOptions = { + port: parseInt(process.env.REDIS_PORT || '6379'), + host: process.env.REDIS_IP, + retryStrategy: (times: number) => { + return Math.min(times * 50, 2000); + }, + }; + + this.pubsub = new RedisPubSub({ + publisher: new Redis(redisOptions), + subscriber: new Redis(redisOptions), + reviver: dateReviver, + }); + } + } + + asyncIterator( + topic: string | string[], + options?: unknown, + ): AsyncIterator { + return this.pubsub.asyncIterator(topic, options); + } + + async publish(topic: string, payload: any) { + await this.pubsub.publish(topic, payload); + } +} From 06ef17048ae5064202f5a5129363048b061ae086 Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Wed, 7 Dec 2022 20:52:31 +0530 Subject: [PATCH 07/14] chore: added prisma module --- packages/hoppscotch-backend/Dockerfile | 4 ++-- .../hoppscotch-backend/docker-compose.yml | 2 +- packages/hoppscotch-backend/package.json | 2 ++ .../src/prisma/prisma.module.ts | 8 ++++++++ .../src/prisma/prisma.service.ts | 19 +++++++++++++++++++ 5 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 packages/hoppscotch-backend/src/prisma/prisma.module.ts create mode 100644 packages/hoppscotch-backend/src/prisma/prisma.service.ts diff --git a/packages/hoppscotch-backend/Dockerfile b/packages/hoppscotch-backend/Dockerfile index 7eb6d8331..48bc5a2c3 100644 --- a/packages/hoppscotch-backend/Dockerfile +++ b/packages/hoppscotch-backend/Dockerfile @@ -11,8 +11,8 @@ RUN npm i -g pnpm # Prisma bits -#COPY prisma ./ -#RUN pnpx prisma generate +COPY prisma ./ +RUN pnpx prisma generate COPY . . diff --git a/packages/hoppscotch-backend/docker-compose.yml b/packages/hoppscotch-backend/docker-compose.yml index eab1e473d..f4e51f3bd 100644 --- a/packages/hoppscotch-backend/docker-compose.yml +++ b/packages/hoppscotch-backend/docker-compose.yml @@ -4,7 +4,7 @@ services: build: . environment: - PRODUCTION=false - - DATABASE_URL=postgresql://postgres:testpass@dev-db:5432/hoppscotch + - DATABASE_URL=postgresql://postgres:testpass@dev-db:5432/hoppscotch?connect_timeout=300 - PORT=3000 # volumes: # - .:/usr/src/app diff --git a/packages/hoppscotch-backend/package.json b/packages/hoppscotch-backend/package.json index c603b4146..08a9aa4dc 100644 --- a/packages/hoppscotch-backend/package.json +++ b/packages/hoppscotch-backend/package.json @@ -26,11 +26,13 @@ "@nestjs/core": "^9.2.1", "@nestjs/graphql": "^10.1.6", "@nestjs/platform-express": "^9.2.1", + "@prisma/client": "^4.7.1", "apollo-server-express": "^3.11.1", "graphql": "^15.5.0", "graphql-redis-subscriptions": "^2.5.0", "graphql-subscriptions": "^2.0.0", "ioredis": "^5.2.4", + "prisma": "^4.7.1", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.6.0" diff --git a/packages/hoppscotch-backend/src/prisma/prisma.module.ts b/packages/hoppscotch-backend/src/prisma/prisma.module.ts new file mode 100644 index 000000000..953aa89d8 --- /dev/null +++ b/packages/hoppscotch-backend/src/prisma/prisma.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common/decorators'; +import { PrismaService } from './prisma.service'; + +@Module({ + providers: [PrismaService], + exports: [PrismaService], +}) +export class PrismaModule {} diff --git a/packages/hoppscotch-backend/src/prisma/prisma.service.ts b/packages/hoppscotch-backend/src/prisma/prisma.service.ts new file mode 100644 index 000000000..5b962c430 --- /dev/null +++ b/packages/hoppscotch-backend/src/prisma/prisma.service.ts @@ -0,0 +1,19 @@ +import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client/scripts/default-index'; + +@Injectable() +export class PrismaService + extends PrismaClient + implements OnModuleInit, OnModuleDestroy +{ + constructor() { + super(); + } + async onModuleInit() { + await this.$connect(); + } + + async onModuleDestroy() { + await this.$disconnect(); + } +} From ee002df110d9d0c6b7e14d138b4f5bdbe705a42e Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Wed, 7 Dec 2022 23:09:15 +0530 Subject: [PATCH 08/14] chore: added gql decorator and complexity plugin --- .../src/decorators/gql-user.decorator.ts | 17 +++++++ .../src/plugins/GQLComplexityPlugin.ts | 44 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 packages/hoppscotch-backend/src/decorators/gql-user.decorator.ts create mode 100644 packages/hoppscotch-backend/src/plugins/GQLComplexityPlugin.ts diff --git a/packages/hoppscotch-backend/src/decorators/gql-user.decorator.ts b/packages/hoppscotch-backend/src/decorators/gql-user.decorator.ts new file mode 100644 index 000000000..2c4da3b52 --- /dev/null +++ b/packages/hoppscotch-backend/src/decorators/gql-user.decorator.ts @@ -0,0 +1,17 @@ +import { createParamDecorator, ExecutionContext } from '@nestjs/common'; +import { User } from '../user/user.model'; +import { GqlExecutionContext } from '@nestjs/graphql'; + +export const GqlUser = createParamDecorator( + (_data: any, context: ExecutionContext) => { + const { user } = GqlExecutionContext.create(context).getContext<{ + user: User; + }>(); + if (!user) + throw new Error( + '@GqlUser decorator use with null user. Make sure the resolve has the @GqlAuthGuard present.', + ); + + return user; + }, +); diff --git a/packages/hoppscotch-backend/src/plugins/GQLComplexityPlugin.ts b/packages/hoppscotch-backend/src/plugins/GQLComplexityPlugin.ts new file mode 100644 index 000000000..f3b8fca08 --- /dev/null +++ b/packages/hoppscotch-backend/src/plugins/GQLComplexityPlugin.ts @@ -0,0 +1,44 @@ +import { GraphQLSchemaHost } from '@nestjs/graphql'; +import { + ApolloServerPlugin, + GraphQLRequestListener, +} from 'apollo-server-plugin-base'; +import { Plugin } from '@nestjs/apollo'; +import { GraphQLError } from 'graphql'; +import { + fieldExtensionsEstimator, + getComplexity, + simpleEstimator, +} from 'graphql-query-complexity'; + +const COMPLEXITY_LIMIT = 50; + +@Plugin() +export class GQLComplexityPlugin implements ApolloServerPlugin { + constructor(private gqlSchemaHost: GraphQLSchemaHost) {} + + async requestDidStart(): Promise { + const { schema } = this.gqlSchemaHost; + + return { + async didResolveOperation({ request, document }) { + const complexity = getComplexity({ + schema, + operationName: request.operationName, + query: document, + variables: request.variables, + estimators: [ + fieldExtensionsEstimator(), + simpleEstimator({ defaultComplexity: 1 }), + ], + }); + if (complexity > COMPLEXITY_LIMIT) { + throw new GraphQLError( + `Query is too complex: ${complexity}. Maximum allowed complexity: ${COMPLEXITY_LIMIT}`, + ); + } + console.log('Query Complexity:', complexity); + }, + }; + } +} From a173d2c808ba5d1b0190209a2271b0dbe47c24aa Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Wed, 7 Dec 2022 23:11:52 +0530 Subject: [PATCH 09/14] chore: imported existing user module files from old repo --- packages/hoppscotch-backend/src/app.module.ts | 9 ++- .../src/user/user.module.ts | 10 ++++ .../src/user/user.resolver.ts | 57 +++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 packages/hoppscotch-backend/src/user/user.module.ts create mode 100644 packages/hoppscotch-backend/src/user/user.resolver.ts diff --git a/packages/hoppscotch-backend/src/app.module.ts b/packages/hoppscotch-backend/src/app.module.ts index 6c3f39d9f..7614320b9 100644 --- a/packages/hoppscotch-backend/src/app.module.ts +++ b/packages/hoppscotch-backend/src/app.module.ts @@ -1,9 +1,8 @@ import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; -import { AppResolver } from './app.resolver'; +import { UserModule } from './user/user.module'; +import { GQLComplexityPlugin } from './plugins/GQLComplexityPlugin'; @Module({ imports: [ @@ -44,8 +43,8 @@ import { AppResolver } from './app.resolver'; }, driver: ApolloDriver, }), + UserModule, ], - controllers: [AppController], - providers: [AppService, AppResolver], + providers: [GQLComplexityPlugin], }) export class AppModule {} diff --git a/packages/hoppscotch-backend/src/user/user.module.ts b/packages/hoppscotch-backend/src/user/user.module.ts new file mode 100644 index 000000000..3681faad5 --- /dev/null +++ b/packages/hoppscotch-backend/src/user/user.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { UserResolver } from './user.resolver'; +import { PubSubModule } from 'src/pubsub/pubsub.module'; + +@Module({ + imports: [PubSubModule], + providers: [UserResolver], + exports: [], +}) +export class UserModule {} diff --git a/packages/hoppscotch-backend/src/user/user.resolver.ts b/packages/hoppscotch-backend/src/user/user.resolver.ts new file mode 100644 index 000000000..cdbd63f31 --- /dev/null +++ b/packages/hoppscotch-backend/src/user/user.resolver.ts @@ -0,0 +1,57 @@ +import { Resolver, Query } from '@nestjs/graphql'; +import { User } from './user.model'; +import { UseGuards } from '@nestjs/common'; +import { GqlAuthGuard } from '../guards/gql-auth.guard'; +import { GqlUser } from '../decorators/gql-user.decorator'; + +@Resolver(() => User) +export class UserResolver { + // eslint-disable-next-line @typescript-eslint/no-empty-function + constructor() {} + + // Query + // @Query(() => User, { + // nullable: true, + // description: 'Finds a user by their UID or null if no match', + // deprecationReason: + // 'Deprecated due to privacy concerns. Try to get the user from the context-relevant queries', + // }) + // async user(@Args({ name: 'uid', type: () => ID }) uid: string): Promise { + // return this.userService.getUserForUID(uid); + // } + + @Query(() => User, { + description: + "Gives details of the user executing this query (pass Authorization 'Bearer' header)", + }) + @UseGuards(GqlAuthGuard) + me(@GqlUser() user: User): User { + return user; + } + + // // Mutation + // @Mutation(() => Boolean, { + // description: 'Delete an user account', + // }) + // @UseGuards(GqlAuthGuard) + // deleteUser( + // @GqlUser() user:User + // ): Promise { + // return pipe( + // this.userService.deleteUserByUID(user), + // TE.map(() => true), + // TE.mapLeft((message) => message.toString()), + // TE.getOrElse(throwErr) + // )(); + // } + // + // // Subscription + // @Subscription(() => User, { + // description: 'Listen for user deletion', + // resolve: (value) => value, + // }) + // @UseGuards(GqlAuthGuard) + // userDeleted(@GqlUser() user: User): AsyncIterator { + // return this.pubsub.asyncIterator(`user/${user.uid}/deleted`); + // } +} From ef95a8a3057b73b019903b4a34a7b91934d6c7e2 Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Wed, 7 Dec 2022 23:13:13 +0530 Subject: [PATCH 10/14] chore: added fp-ts and gql complexity plugin --- packages/hoppscotch-backend/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/hoppscotch-backend/package.json b/packages/hoppscotch-backend/package.json index 08a9aa4dc..6e3a31005 100644 --- a/packages/hoppscotch-backend/package.json +++ b/packages/hoppscotch-backend/package.json @@ -28,7 +28,10 @@ "@nestjs/platform-express": "^9.2.1", "@prisma/client": "^4.7.1", "apollo-server-express": "^3.11.1", + "apollo-server-plugin-base": "^3.7.1", + "fp-ts": "^2.13.1", "graphql": "^15.5.0", + "graphql-query-complexity": "^0.12.0", "graphql-redis-subscriptions": "^2.5.0", "graphql-subscriptions": "^2.0.0", "ioredis": "^5.2.4", From d4c775a537e397b6d866b9dd200fda17aeaa90f2 Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Wed, 7 Dec 2022 23:14:49 +0530 Subject: [PATCH 11/14] chore: added existing utils from old backend repo --- packages/hoppscotch-backend/src/utils.ts | 112 +++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 packages/hoppscotch-backend/src/utils.ts diff --git a/packages/hoppscotch-backend/src/utils.ts b/packages/hoppscotch-backend/src/utils.ts new file mode 100644 index 000000000..061ddeef1 --- /dev/null +++ b/packages/hoppscotch-backend/src/utils.ts @@ -0,0 +1,112 @@ +import { ExecutionContext } from '@nestjs/common'; +import { GqlExecutionContext } from '@nestjs/graphql'; +import { pipe } from 'fp-ts/lib/function'; +import * as O from 'fp-ts/Option'; +import * as TE from 'fp-ts/TaskEither'; +import * as T from 'fp-ts/Task'; +import { User } from './user/user.model'; +import * as A from 'fp-ts/Array'; +// import { Reflector } from '@nestjs/core'; +// import { TeamMemberRole } from './team/team.model'; + +/** + * A workaround to throw an exception in an expression. + * JS throw keyword creates a statement not an expression. + * This function allows throw to be used as an expression + * @param errMessage Message present in the error message + */ +export function throwErr(errMessage: string): never { + throw new Error(errMessage); +} + +/** + * Prints the given value to log and returns the same value. + * Used for debugging functional pipelines. + * @param val The value to print + * @returns `val` itself + */ +export const trace = (val: T) => { + console.log(val); + return val; +}; + +/** + * Similar to `trace` but allows for labels and also an + * optional transform function. + * @param name The label to given to the trace log (log outputs like this ": ") + * @param transform An optional function to transform the log output value (useful for checking specific aspects or transforms (duh)) + * @returns A function which takes a value, and is traced. + */ +export const namedTrace = + (name: string, transform?: (val: T) => unknown) => + (val: T) => { + console.log(`${name}:`, transform ? transform(val) : val); + + return val; + }; + +/** + * Returns the list of required roles annotated on a GQL Operation + * @param reflector NestJS Reflector instance + * @param context NestJS Execution Context + * @returns An Option which contains the defined roles + */ +// export const getAnnotatedRequiredRoles = ( +// reflector: Reflector, +// context: ExecutionContext, +// ) => +// pipe( +// reflector.get('requiresTeamRole', context.getHandler()), +// O.fromNullable, +// ); + +/** + * Gets the user from the NestJS GQL Execution Context. + * Usually used within guards. + * @param ctx The Execution Context to use to get it + * @returns An Option of the user + */ +export const getUserFromGQLContext = (ctx: ExecutionContext) => + pipe( + ctx, + GqlExecutionContext.create, + (ctx) => ctx.getContext<{ user?: User }>(), + ({ user }) => user, + O.fromNullable, + ); + +/** + * Gets a GQL Argument in the defined operation. + * Usually used in guards. + * @param argName The name of the argument to get + * @param ctx The NestJS Execution Context to use to get it. + * @returns The argument value typed as `unknown` + */ +export const getGqlArg = ( + argName: ArgName, + ctx: ExecutionContext, +) => + pipe( + ctx, + GqlExecutionContext.create, + (ctx) => ctx.getArgs(), + // We are not sure if this thing will even exist + // We pass that worry to the caller + (args) => args[argName as any] as unknown, + ); + +/** + * Sequences an array of TaskEither values while maintaining an array of all the error values + * @param arr Array of TaskEithers + * @returns A TaskEither saying all the errors possible on the left or all the success values on the right + */ +export const taskEitherValidateArraySeq = ( + arr: TE.TaskEither[], +): TE.TaskEither => + pipe( + arr, + A.map(TE.mapLeft(A.of)), + A.sequence( + TE.getApplicativeTaskValidation(T.ApplicativeSeq, A.getMonoid()), + ), + ); From 4da11955f1387dfa0113c4a6f7b4904b31fd22c5 Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Wed, 7 Dec 2022 23:17:56 +0530 Subject: [PATCH 12/14] style: prettier fix for pubsub --- packages/hoppscotch-backend/src/pubsub/pubsub.module.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/hoppscotch-backend/src/pubsub/pubsub.module.ts b/packages/hoppscotch-backend/src/pubsub/pubsub.module.ts index b20d887e8..b12ff3a7d 100644 --- a/packages/hoppscotch-backend/src/pubsub/pubsub.module.ts +++ b/packages/hoppscotch-backend/src/pubsub/pubsub.module.ts @@ -1,8 +1,8 @@ -import { Module } from "@nestjs/common"; -import { PubSubService } from "./pubsub.service"; +import { Module } from '@nestjs/common'; +import { PubSubService } from './pubsub.service'; @Module({ providers: [PubSubService], - exports: [PubSubService] + exports: [PubSubService], }) export class PubSubModule {} From bfc5bfe973ae4bd61f584743ef6ce018ac7b6df3 Mon Sep 17 00:00:00 2001 From: ankitsridhar16 Date: Thu, 8 Dec 2022 20:26:22 +0530 Subject: [PATCH 13/14] chore: added user model in prisma schema --- packages/hoppscotch-backend/prisma/schema.prisma | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/hoppscotch-backend/prisma/schema.prisma b/packages/hoppscotch-backend/prisma/schema.prisma index fb9f2eb22..947d158a8 100644 --- a/packages/hoppscotch-backend/prisma/schema.prisma +++ b/packages/hoppscotch-backend/prisma/schema.prisma @@ -78,6 +78,13 @@ model TeamEnvironment { variables Json } +model User { + uid String @id @default(cuid()) + displayName String? + email String? + photoURL String? +} + enum TeamMemberRole { OWNER VIEWER From c5466edf7191ba6d49b2e64b1163fae982933415 Mon Sep 17 00:00:00 2001 From: Balu Babu Date: Thu, 8 Dec 2022 22:19:14 +0530 Subject: [PATCH 14/14] chore: cleaned up hopp-backend package and modified docker and docker-compose files --- packages/hoppscotch-backend/.eslintrc.js | 2 +- packages/hoppscotch-backend/.prettierrc | 2 +- packages/hoppscotch-backend/Dockerfile | 9 +--- .../hoppscotch-backend/docker-compose.yml | 5 ++- .../src/app.controller.spec.ts | 22 --------- .../hoppscotch-backend/src/app.controller.ts | 12 ----- .../hoppscotch-backend/src/app.resolver.ts | 12 ----- .../hoppscotch-backend/src/app.service.ts | 8 ---- packages/hoppscotch-backend/src/main.ts | 7 --- .../src/user/user.resolver.ts | 45 ++++--------------- packages/hoppscotch-backend/src/utils.ts | 2 - 11 files changed, 15 insertions(+), 111 deletions(-) delete mode 100644 packages/hoppscotch-backend/src/app.controller.spec.ts delete mode 100644 packages/hoppscotch-backend/src/app.controller.ts delete mode 100644 packages/hoppscotch-backend/src/app.resolver.ts delete mode 100644 packages/hoppscotch-backend/src/app.service.ts diff --git a/packages/hoppscotch-backend/.eslintrc.js b/packages/hoppscotch-backend/.eslintrc.js index 8f5aedb71..259de13c7 100644 --- a/packages/hoppscotch-backend/.eslintrc.js +++ b/packages/hoppscotch-backend/.eslintrc.js @@ -2,7 +2,7 @@ module.exports = { parser: '@typescript-eslint/parser', parserOptions: { project: 'tsconfig.json', - tsconfigRootDir : __dirname, + tsconfigRootDir: __dirname, sourceType: 'module', }, plugins: ['@typescript-eslint/eslint-plugin'], diff --git a/packages/hoppscotch-backend/.prettierrc b/packages/hoppscotch-backend/.prettierrc index dcb72794f..a20502b7f 100644 --- a/packages/hoppscotch-backend/.prettierrc +++ b/packages/hoppscotch-backend/.prettierrc @@ -1,4 +1,4 @@ { "singleQuote": true, "trailingComma": "all" -} \ No newline at end of file +} diff --git a/packages/hoppscotch-backend/Dockerfile b/packages/hoppscotch-backend/Dockerfile index 48bc5a2c3..ab0c88f42 100644 --- a/packages/hoppscotch-backend/Dockerfile +++ b/packages/hoppscotch-backend/Dockerfile @@ -5,16 +5,11 @@ WORKDIR /usr/src/app # # Install pnpm RUN npm i -g pnpm -# # NPM package install -# COPY package*.json ./ -# RUN pnpm install - - # Prisma bits COPY prisma ./ RUN pnpx prisma generate - +# # NPM package install COPY . . RUN pnpm i @@ -25,6 +20,4 @@ ENV APP_PORT=${PORT} ENV DB_URL=${DATABASE_URL} ENV PRODUCTION=true -#ENV FB_SERVICE_KEY_PATH="secrets/fb-service-key.json" -# CMD ["pnpm", "run", "start:dev"] CMD ["pnpm", "run", "start"] diff --git a/packages/hoppscotch-backend/docker-compose.yml b/packages/hoppscotch-backend/docker-compose.yml index f4e51f3bd..9b22e6f75 100644 --- a/packages/hoppscotch-backend/docker-compose.yml +++ b/packages/hoppscotch-backend/docker-compose.yml @@ -6,8 +6,9 @@ services: - PRODUCTION=false - DATABASE_URL=postgresql://postgres:testpass@dev-db:5432/hoppscotch?connect_timeout=300 - PORT=3000 -# volumes: -# - .:/usr/src/app + volumes: + - .:/usr/src/app + - /usr/src/app/node_modules/ depends_on: - dev-db ports: diff --git a/packages/hoppscotch-backend/src/app.controller.spec.ts b/packages/hoppscotch-backend/src/app.controller.spec.ts deleted file mode 100644 index d22f3890a..000000000 --- a/packages/hoppscotch-backend/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/packages/hoppscotch-backend/src/app.controller.ts b/packages/hoppscotch-backend/src/app.controller.ts deleted file mode 100644 index cce879ee6..000000000 --- a/packages/hoppscotch-backend/src/app.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { AppService } from './app.service'; - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getHello(): string { - return this.appService.getHello(); - } -} diff --git a/packages/hoppscotch-backend/src/app.resolver.ts b/packages/hoppscotch-backend/src/app.resolver.ts deleted file mode 100644 index f16f8b565..000000000 --- a/packages/hoppscotch-backend/src/app.resolver.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Query, Resolver } from '@nestjs/graphql'; -import { AppService } from './app.service'; - -@Resolver((of) => String) -export class AppResolver { - constructor(private appService: AppService) {} - - @Query((returns) => String) - async author() { - return this.appService.getHello(); - } -} diff --git a/packages/hoppscotch-backend/src/app.service.ts b/packages/hoppscotch-backend/src/app.service.ts deleted file mode 100644 index 927d7cca0..000000000 --- a/packages/hoppscotch-backend/src/app.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AppService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/packages/hoppscotch-backend/src/main.ts b/packages/hoppscotch-backend/src/main.ts index 5c4786c2a..98a2ff179 100644 --- a/packages/hoppscotch-backend/src/main.ts +++ b/packages/hoppscotch-backend/src/main.ts @@ -24,13 +24,6 @@ async function bootstrap() { } else { console.log('Enabling CORS with production settings'); - // HACK: Temporary fix for Liyas to work on production directly :P - /* - app.enableCors({ - origin: /hoppscotch\.io$/ - }); - */ - app.enableCors({ origin: true, }); diff --git a/packages/hoppscotch-backend/src/user/user.resolver.ts b/packages/hoppscotch-backend/src/user/user.resolver.ts index cdbd63f31..d913be01d 100644 --- a/packages/hoppscotch-backend/src/user/user.resolver.ts +++ b/packages/hoppscotch-backend/src/user/user.resolver.ts @@ -6,20 +6,10 @@ import { GqlUser } from '../decorators/gql-user.decorator'; @Resolver(() => User) export class UserResolver { + // TODO: remove the eslint-disable line below once dependencies are added to user.service file // eslint-disable-next-line @typescript-eslint/no-empty-function constructor() {} - // Query - // @Query(() => User, { - // nullable: true, - // description: 'Finds a user by their UID or null if no match', - // deprecationReason: - // 'Deprecated due to privacy concerns. Try to get the user from the context-relevant queries', - // }) - // async user(@Args({ name: 'uid', type: () => ID }) uid: string): Promise { - // return this.userService.getUserForUID(uid); - // } - @Query(() => User, { description: "Gives details of the user executing this query (pass Authorization 'Bearer' header)", @@ -29,29 +19,12 @@ export class UserResolver { return user; } - // // Mutation - // @Mutation(() => Boolean, { - // description: 'Delete an user account', - // }) - // @UseGuards(GqlAuthGuard) - // deleteUser( - // @GqlUser() user:User - // ): Promise { - // return pipe( - // this.userService.deleteUserByUID(user), - // TE.map(() => true), - // TE.mapLeft((message) => message.toString()), - // TE.getOrElse(throwErr) - // )(); - // } - // - // // Subscription - // @Subscription(() => User, { - // description: 'Listen for user deletion', - // resolve: (value) => value, - // }) - // @UseGuards(GqlAuthGuard) - // userDeleted(@GqlUser() user: User): AsyncIterator { - // return this.pubsub.asyncIterator(`user/${user.uid}/deleted`); - // } + @Query(() => User, { + description: + "Gives details of the user executing this query (pass Authorization 'Bearer' header)", + }) + @UseGuards(GqlAuthGuard) + me2(@GqlUser() user: User): User { + return user; + } } diff --git a/packages/hoppscotch-backend/src/utils.ts b/packages/hoppscotch-backend/src/utils.ts index 061ddeef1..a4756f5e6 100644 --- a/packages/hoppscotch-backend/src/utils.ts +++ b/packages/hoppscotch-backend/src/utils.ts @@ -6,8 +6,6 @@ import * as TE from 'fp-ts/TaskEither'; import * as T from 'fp-ts/Task'; import { User } from './user/user.model'; import * as A from 'fp-ts/Array'; -// import { Reflector } from '@nestjs/core'; -// import { TeamMemberRole } from './team/team.model'; /** * A workaround to throw an exception in an expression.