Giter Site home page Giter Site logo

graphql-ts-server-boilerplate's Introduction

graphql-ts-server-boilerplate

A GraphQL Server boilerplate made with Typescript, PostgreSQL, and Redis

Installation

  1. Clone project
git clone https://github.com/benawad/graphql-ts-server-boilerplate.git
  1. cd into folder
cd graphql-ts-server-boilerplate
  1. Download dependencies
yarn
  1. Start PostgreSQL server
  2. Create database called graphql-ts-server-boilerplate
createdb graphql-ts-server-boilerplate
  1. Add a user with the username postgres and and no password. (You can change what these values are in the ormconfig.json)

  2. Install and start Redis

Usage

You can start the server with yarn start then navigate to http://localhost:4000 to use GraphQL Playground.

Features

  • Register - Send confirmation email
  • Login
  • Forgot Password
  • Logout
  • Cookies
  • Authentication middleware
  • Rate limiting
  • Locking accounts
  • Testing (probably Jest)

Watch how it was made

Playlist: https://www.youtube.com/playlist?list=PLN3n1USn4xlky9uj6wOhfsPez7KZOqm2V

graphql-ts-server-boilerplate's People

Contributors

benawad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphql-ts-server-boilerplate's Issues

Session not set in production

I am building server using express and apollo server, when developing locally everything seems to be fine but when in production session is not set to a browser but I can see session keys in redis db when I run keys *. I can't login since my react app keeps receiving 401 status code.

So I am wondering why session keys are stored in redis and session is not actually set. Locally when I inspect element I can see cookie for session id but not in production. I am using apache web server run on ubuntu created by Bitnami. Any help will be appreciated.

Here are my codes

const RedisStore = connectRedis(session);

const bootstrap = async () => {
    //Db connection.
    await createConnection();
    //cron jobs.
    registerCronJobs();
    //Init Firebase
    initFirebase();

    const store = new RedisStore({
        client: redis as any,
        logErrors: true
    });

    const apolloServer = new ApolloServer({
        schema: await createSchema(),
        context: ({req, res}: any) => ({req, res}),
        //introspection: true //turn it on later when other developers can take part.
    });

    const app = express();

    app.use(helmet());

    app.use(cors({
        credentials: process.env.NODE_ENV !== "production",
        origin: ['http://localhost:3000'] //React app.
    }));

    app.set('trust proxy', process.env.NODE_ENV === "production");

    app.use(session({
        store,
        name: COOKIE_NAME,
        secret: config.get('session_secret'),
        resave: false,
        saveUninitialized: false,
        cookie: {
            httpOnly: true,
            secure: process.env.NODE_ENV === "production",
            maxAge: 1000 * 60 * 60 * 24 * 30 // 1 month
        }
    }));

    app.use(bodyParser.urlencoded({extended: false}));
    app.use(bodyParser.json());
    app.use(express.static(path.join(__dirname, '..', 'public/web/build')));
    app.use(bridgeRouter);

    const httpServer = http.createServer(app);
    const PORT = process.env.port || 2000;

    // ref : https://dev.to/tmns/session-handling-in-react-with-redux-express-session-and-apollo-18j8
    apolloServer.applyMiddleware({app, cors: false});
    apolloServer.installSubscriptionHandlers(httpServer);

    app.get('*', function (_req: Request, res: Response) {
        res.sendFile(path.join(__dirname, '..', 'public/web/build', 'index.html'));
    });

    //`listen` on the http server variable, and not on `app`.
    httpServer.listen(PORT, () => {
        console.log(`Server ready at http://localhost:${PORT}${apolloServer.graphqlPath}`);
        console.log(`Subscriptions ready at ws://localhost:${PORT}${apolloServer.subscriptionsPath}`);
    })
};

bootstrap().catch(e => console.log(e));

I asked similar question few weeks ago here on stackoverflow

Any help will be appreciated

Getting '__awaiter' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer Error in setup.js

Hello

When I run the yarn test, I am getting the following error in my terminal.

`Test suite failed to run

TSError: ⨯ Unable to compile TypeScript:
src/testSetup/setup.ts:2:5 - error TS7022: '__awaiter' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

2 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
      ~~~~~~~~~
src/testSetup/setup.ts:2:55 - error TS7006: Parameter 'thisArg' implicitly has an 'any' type.

2 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                                                        ~~~~~~~
src/testSetup/setup.ts:2:64 - error TS7006: Parameter '_arguments' implicitly has an 'any' type.

2 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                                                                 ~~~~~~~~~~
src/testSetup/setup.ts:2:76 - error TS7006: Parameter 'P' implicitly has an 'any' type.

2 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                                                                             ~
src/testSetup/setup.ts:2:79 - error TS7006: Parameter 'generator' implicitly has an 'any' type.

2 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                                                                                ~~~~~~~~~
src/testSetup/setup.ts:3:20 - error TS7006: Parameter 'value' implicitly has an 'any' type.

3     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
                     ~~~~~
src/testSetup/setup.ts:3:81 - error TS7006: Parameter 'resolve' implicitly has an 'any' type.

3     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
                                                                                  ~~~~~~~
src/testSetup/setup.ts:4:47 - error TS7006: Parameter 'resolve' implicitly has an 'any' type.

4     return new (P || (P = Promise))(function (resolve, reject) {
                                                ~~~~~~~
src/testSetup/setup.ts:4:56 - error TS7006: Parameter 'reject' implicitly has an 'any' type.

4     return new (P || (P = Promise))(function (resolve, reject) {
                                                         ~~~~~~
src/testSetup/setup.ts:5:28 - error TS7006: Parameter 'value' implicitly has an 'any' type.

5         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
                             ~~~~~
src/testSetup/setup.ts:6:27 - error TS7006: Parameter 'value' implicitly has an 'any' type.

6         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
                            ~~~~~
src/testSetup/setup.ts:7:23 - error TS7006: Parameter 'result' implicitly has an 'any' type.

7         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }`

It looks like it is throwing error in my setup.js where I have
const app= await startServer();

This is my current setup.js file.
`import { startServer } from "../startServer";

export const setup = async () => {
const app= await startServer();

const addr = app.address();

let port: any = '';

if(typeof addr === 'string') {
port = addr
} else {
port = addr?.port;
}

process.env.TEST_HOST = http://127.0.0.1:${port};
};`

How do you resolve this issue?
Could you please help me with this?

session problems

Hi! I get the following error. Do you have any idea what went wrong?

`
FAIL src/modules/User/me/me.test.ts
● me › return null if no cookie

expect(received).toBeNull()

Expected value to be null, instead received
  {"email": "[email protected]", "id": "70541c8f-ac16-4176-9f3a-ad1b51f69146"}

  40 |     const client = new TestClient(process.env.TEST_HOST as string);
  41 |     const response = await client.me();
> 42 |     expect(response.data.me).toBeNull();
  43 |   });
  44 |
  45 |   test("get current user", async () => {

  at Object.<anonymous> (src/modules/User/me/me.test.ts:42:30)
  at fulfilled (src/modules/User/me/me.test.ts:4:56)

`

Can't get Session

Hello I want to make session with ApolloServer and Express but when i get console log from req.session, it gives me undefined. Whats the problem??

import '@babel/polyfill/noConflict';
import express from 'express';
import { ApolloServer } from 'apollo-server-express';
import mongoose, { mongo } from 'mongoose';
import { existsSync, mkdirSync } from 'fs';
import path from 'path';
import { resolvers } from './resolvers';
import { typeDefs } from './typeDefs';
import session from 'express-session';
import mongoconnect from 'connect-mongo';

const MongoStore = mongoconnect(session);

const app = express();

let dbUrl = 'mongodb://localhost:27017/test';
mongoose.connect(dbUrl);
mongoose.Promise = global.Promise;
let db = mongoose.connection;
db.on('error', console.error.bind(console, "DB connection error"));

const SERVER = new ApolloServer({
    typeDefs,
    resolvers,
    cors: {
        origin: '*',
        credentials: true
    },
    playground: {
        endpoint: `http://localhost:3600/graphql`,
        settings: {
            'editor.theme': 'dark'
        }
    },
    context: ({ req }) => {
        console.log(req.session); //undefined
        return { req }
    }
});

SERVER.applyMiddleware({
    app
});

existsSync(path.join(__dirname, "../images")) || mkdirSync(path.join(__dirname, "../images"));

app.use("/images", express.static(path.join(__dirname, "../images")));

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

app.use(
    session({
        store: new MongoStore({
            mongooseConnection: mongoose.connection,
            url: 'mongodb://localhost:27017/test'
        }),
        secret: "mysecret-ssss",
        resave: false,
        saveUninitialized: false,
        cookie: {
            maxAge: 1000 * 60 * 60 * 2,
            sameSite: true,
            secure: true
        }
    })
);

app.get('/', function (req, res, next) {
});

app.post('/', function (req, res, next) {
    // Handle the post for this route
});

app.listen(3600, () => {
    console.log(`Server ready at port 3600`);
});

ReadMe

Love this and your yourtube series.

Maybe it will be better if you could drop in some ReadMe to let others know how to use this boilerplate.
That way, more people can use this fantastic boilerplate.

Graphql schema files not copied over to dist.

Hey Ben!

When we compile to javascript the schema.graphql is not copied over to the dist folder so genSchema() doesn't work.

I'm not sure if it's intended to work only with ts-node.

By the way, thanks for this nice series!

"Statements are not allowed in ambient contexts."

It seems recently every time I modify my schema and run yarn gen-schema-types the resulting schema.d.ts file contains a couple tslint errors "Statements are not allowed in ambient contexts." due to extra semicolons. It is easy enough to manually fix by hand.

Does this happen to you? Any idea how to fix?

TypeError: Only absolute URLs are supported

When I'm running the command "yarn jest" in the server folder, I'm getting the following error:

TypeError: Only absolute URLs are supported

  11 | const node_fetch_1 = require("node-fetch");
  12 | test("sends invalid back if bad id sent", () => __awaiter(this, void 0, void 0, function* () {
> 13 |     const response = yield node_fetch_1.default(`${process.env.TEST_HOST}/confirm/12083`);
  14 |     const text = yield response.text();
  15 |     expect(text).toEqual("invalid");
  16 | }));

  at getNodeRequestOptions (packages/server/node_modules/node-fetch/lib/index.js:1284:9)
  at packages/server/node_modules/node-fetch/lib/index.js:1370:19
  at Function.fetch [as default] (packages/server/node_modules/node-fetch/lib/index.js:1367:9)
  at Object.<anonymous> (packages/server/dist/server/src/routes/confirmEmail.test.js:13:28)
  at packages/server/dist/server/src/routes/confirmEmail.test.js:7:71
  at Object.<anonymous>.__awaiter (packages/server/dist/server/src/routes/confirmEmail.test.js:3:12)
  at Object.<anonymous> (packages/server/dist/server/src/routes/confirmEmail.test.js:12:49)

I'm not really sure what I'm supposed to do to fix this problem. The url is not being defined correctly apparently. I'm running this on a windows machine.

process.env.TEST_HOST seems to be undefined, so there's something going wrong when defining process.env
unknown

Need to update usage of RateLimit itself and its options (delayMs)

Hi Ben,

I just want to let you know current RateLimit in startServer.ts is obsolete, there is breaking change on express-rate-limit api:

  • v3 changes: Removed delayAfter and delayMs options; they were moved to a new module: express-slow-down.

Also, now RateLimit usage also updated:
Instead of creating RateLimit instance directly, now it should be used as a factory method:

Usage taken from its official npm page:

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
});

And here is the usage of express-slow-down:

const slowDown = require("express-slow-down");
 
app.enable("trust proxy"); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS if you use an ELB, custom Nginx setup, etc)
 
const speedLimiter = slowDown({
  windowMs: 15 * 60 * 1000, // 15 minutes
  delayAfter: 100, // allow 100 requests per 15 minutes, then...
  delayMs: 500 // begin adding 500ms of delay per request above 100:
  // request # 101 is delayed by  500ms
  // request # 102 is delayed by 1000ms
  // request # 103 is delayed by 1500ms
  // etc.
});
 
//  apply to all requests
app.use(speedLimiter);

Update??

Really outdated... would really love it if it was updated

[Typing Error] GraphQL Schema Stitching - Part 6 (YouTube)

Hey Ben, thanks for the project, very helpful!

I'm getting a type error exactly at this point. Probably is some conflict between schema property from GraphQLServer and the type returned by mergeSchemas() from graphql-tools.

Snippet

const schemas: GraphQLSchema[] = []

  const folders = fs.readdirSync(path.join(__dirname, './modules'))

  folders.forEach((folder) => {
    const { resolvers } = require(`./modules/${folder}/resolvers`)
    const typeDefs = importSchema(
      path.join(__dirname, `./modules/${folder}/schema.graphql`)
    )

    schemas.push(makeExecutableSchema({ resolvers, typeDefs }))
  })

  // GETTING ERROR ON THIS NEXT LINE
  const gqlServer = new GraphQLServer({ schema: mergeSchemas({ schemas }) })

Stack Backtrace:

Type 'import("/gql-ts-boilerplate/node_modules/graphql/type/schema").GraphQLSchema' is not assignable to type 'import("/gql-ts-boilerplate/node_modules/apollo-link/node_modules/graphql/type/schema").GraphQLSchema'.
  The types returned by 'getQueryType()' are incompatible between these types.
  Type 'Maybe<GraphQLObjectType<any, any>>' is not assignable to type 'Maybe<GraphQLObjectType<any, any, { [key: string]: any; }>>'.
  Type 'GraphQLObjectType<any, any>' is not assignable to type 'Maybe<GraphQLObjectType<any, any, { [key: string]: any; }>>'.
  Types of property 'isTypeOf' are incompatible.
  Type 'import("/gql-ts-boilerplate/node_modules/graphql/jsutils/Maybe").Maybe<import("/gql-ts-boilerplate/node_modules/graphql/type/definition").GraphQLIsTypeOfFn<any, any>>' is not assignable to type 'import("/gql-ts-boilerplate/node_modules/apollo-link/node_modules/graphql/tsutils/Maybe").default<import("/gql-ts-boilerplate/node_modules/apollo-link/node_modules/graphql/type/definition").GraphQLIsTypeOfFn<any, any>>'.
  Type 'GraphQLIsTypeOfFn<any, any>' is not assignable to type 'Maybe<GraphQLIsTypeOfFn<any, any>>'.
  Types of parameters 'info' and 'info' are incompatible.
  Property 'cacheControl' is missing in type 'import("/gql-ts-boilerplate/node_modules/apollo-link/node_modules/graphql/type/definition").GraphQLResolveInfo' but required in type 'import("/gql-ts-boilerplate/node_modules/graphql/type/definition").GraphQLResolveInfo'.

me returning null

Hi there , sir in my login resolver when i console.log req.session after session.userId = user.id i am able to see userId in my session object but in my me resolver i cannot access session.userId and also i am able to set keys in redis when i used the local express-session store instead of redis the same problem occured . Is there any problem with my express-session i tried it several times but same result Please help.

error: column cnst.consrc does not exist

error: column cnst.consrc does not exist

I guess this error is because there is no schema in postgres.
How to fix this?

yarn start

yarn run v1.22.0
warning package.json: No license field
$ NODE_ENV=development nodemon --exec ts-node src/index.ts
[nodemon] 1.19.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src/index.ts`
query: START TRANSACTION
query: SELECT * FROM current_schema()
query: SELECT * FROM "information_schema"."tables" WHERE ("table_schema" = 'public' AND "table_name" = 'users')
query: SELECT *, "udt_name"::"regtype" AS "regtype" FROM "information_schema"."columns" WHERE ("table_schema" = 'public' AND "table_name" = 'users')
query: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "cnst"."conname" AS "constraint_name", "cnst"."consrc" AS "expression", CASE "cnst"."contype" WHEN 'p' THEN 'PRIMARY' WHEN 'u' THEN 'UNIQUE' WHEN 'c' THEN 'CHECK' END AS "constraint_type", "a"."attname" AS "column_name" FROM "pg_constraint" "cnst" INNER JOIN "pg_class" "t" ON "t"."oid" = "cnst"."conrelid" INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "cnst"."connamespace" INNER JOIN "pg_attribute" "a" ON "a"."attrelid" = "cnst"."conrelid" AND "a"."attnum" = ANY ("cnst"."conkey") WHERE "t"."relkind" = 'r' AND (("ns"."nspname" = 'public' AND "t"."relname" = 'users'))
query: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "i"."relname" AS "constraint_name", "a"."attname" AS "column_name", CASE "ix"."indisunique" WHEN 't' THEN 'TRUE' ELSE'FALSE' END AS "is_unique", pg_get_expr("ix"."indpred", "ix"."indrelid") AS "condition" FROM "pg_class" "t" INNER JOIN "pg_index" "ix" ON "ix"."indrelid" = "t"."oid" INNER JOIN "pg_attribute" "a" ON "a"."attrelid" = "t"."oid"  AND "a"."attnum" = ANY ("ix"."indkey") INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "t"."relnamespace" INNER JOIN "pg_class" "i" ON "i"."oid" = "ix"."indexrelid" LEFT JOIN "pg_constraint" "cnst" ON "cnst"."conname" = "i"."relname" WHERE "t"."relkind" = 'r' AND "cnst"."contype" IS NULL AND (("ns"."nspname" = 'public' AND "t"."relname" = 'users'))
query: SELECT "con"."conname" AS "constraint_name", "con"."nspname" AS "table_schema", "con"."relname" AS "table_name", "att2"."attname" AS "column_name", "ns"."nspname" AS "referenced_table_schema", "cl"."relname" AS "referenced_table_name", "att"."attname" AS "referenced_column_name", "con"."confdeltype" AS "on_delete", "con"."confupdtype" AS "on_update" FROM ( SELECT UNNEST ("con1"."conkey") AS "parent", UNNEST ("con1"."confkey") AS "child", "con1"."confrelid", "con1"."conrelid", "con1"."conname", "con1"."contype", "ns"."nspname", "cl"."relname", CASE "con1"."confdeltype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confdeltype", CASE "con1"."confupdtype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confupdtype" FROM "pg_class" "cl" INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_constraint" "con1" ON "con1"."conrelid" = "cl"."oid" WHERE "con1"."contype" = 'f' AND (("ns"."nspname" = 'public' AND "cl"."relname" = 'users')) ) "con" INNER JOIN "pg_attribute" "att" ON "att"."attrelid" = "con"."confrelid" AND "att"."attnum" = "con"."child" INNER JOIN "pg_class" "cl" ON "cl"."oid" = "con"."confrelid" INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_attribute" "att2" ON "att2"."attrelid" = "con"."conrelid" AND "att2"."attnum" = "con"."parent"
query failed: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "cnst"."conname" AS "constraint_name", "cnst"."consrc" AS "expression", CASE "cnst"."contype" WHEN 'p' THEN 'PRIMARY' WHEN 'u' THEN 'UNIQUE' WHEN 'c' THEN 'CHECK' END AS "constraint_type", "a"."attname" AS "column_name" FROM "pg_constraint" "cnst" INNER JOIN "pg_class" "t" ON "t"."oid" = "cnst"."conrelid" INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "cnst"."connamespace" INNER JOIN "pg_attribute" "a" ON "a"."attrelid" = "cnst"."conrelid" AND "a"."attnum" = ANY ("cnst"."conkey") WHERE "t"."relkind" = 'r' AND (("ns"."nspname" = 'public' AND "t"."relname" = 'users'))
error: error: column cnst.consrc does not exist
    at Connection.parseE (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:614:13)
    at Connection.parseMessage (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:413:19)
    at Socket.<anonymous> (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:129:22)
    at Socket.emit (events.js:321:20)
    at Socket.EventEmitter.emit (domain.js:485:12)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:273:9)
    at Socket.Readable.push (_stream_readable.js:214:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:186:23) {
  name: 'error',
  length: 196,
  severity: 'ERROR',
  code: '42703',
  detail: undefined,
  hint: 'Perhaps you meant to reference the column "cnst.conkey" or the column "cnst.conbin".',
  position: '112',
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'parse_relation.c',
  line: '3377',
  routine: 'errorMissingColumn'
}
query: ROLLBACK
query failed: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "i"."relname" AS "constraint_name", "a"."attname" AS "column_name", CASE "ix"."indisunique" WHEN 't' THEN 'TRUE' ELSE'FALSE' END AS "is_unique", pg_get_expr("ix"."indpred", "ix"."indrelid") AS "condition" FROM "pg_class" "t" INNER JOIN "pg_index" "ix" ON "ix"."indrelid" = "t"."oid" INNER JOIN "pg_attribute" "a" ON "a"."attrelid" = "t"."oid"  AND "a"."attnum" = ANY ("ix"."indkey") INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "t"."relnamespace" INNER JOIN "pg_class" "i" ON "i"."oid" = "ix"."indexrelid" LEFT JOIN "pg_constraint" "cnst" ON "cnst"."conname" = "i"."relname" WHERE "t"."relkind" = 'r' AND "cnst"."contype" IS NULL AND (("ns"."nspname" = 'public' AND "t"."relname" = 'users'))
error: error: current transaction is aborted, commands ignored until end of transaction block
    at Connection.parseE (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:614:13)
    at Connection.parseMessage (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:413:19)
    at Socket.<anonymous> (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:129:22)
    at Socket.emit (events.js:321:20)
    at Socket.EventEmitter.emit (domain.js:485:12)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:273:9)
    at Socket.Readable.push (_stream_readable.js:214:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:186:23) {
  name: 'error',
  length: 144,
  severity: 'ERROR',
  code: '25P02',
  detail: undefined,
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'postgres.c',
  line: '1105',
  routine: 'exec_simple_query'
}
query failed: SELECT "con"."conname" AS "constraint_name", "con"."nspname" AS "table_schema", "con"."relname" AS "table_name", "att2"."attname" AS "column_name", "ns"."nspname" AS "referenced_table_schema", "cl"."relname" AS "referenced_table_name", "att"."attname" AS "referenced_column_name", "con"."confdeltype" AS "on_delete", "con"."confupdtype" AS "on_update" FROM ( SELECT UNNEST ("con1"."conkey") AS "parent", UNNEST ("con1"."confkey") AS "child", "con1"."confrelid", "con1"."conrelid", "con1"."conname", "con1"."contype", "ns"."nspname", "cl"."relname", CASE "con1"."confdeltype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confdeltype", CASE "con1"."confupdtype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confupdtype" FROM "pg_class" "cl" INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_constraint" "con1" ON "con1"."conrelid" = "cl"."oid" WHERE "con1"."contype" = 'f' AND (("ns"."nspname" = 'public' AND "cl"."relname" = 'users')) ) "con" INNER JOIN "pg_attribute" "att" ON "att"."attrelid" = "con"."confrelid" AND "att"."attnum" = "con"."child" INNER JOIN "pg_class" "cl" ON "cl"."oid" = "con"."confrelid" INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_attribute" "att2" ON "att2"."attrelid" = "con"."conrelid" AND "att2"."attnum" = "con"."parent"
error: error: current transaction is aborted, commands ignored until end of transaction block
    at Connection.parseE (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:614:13)
    at Connection.parseMessage (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:413:19)
    at Socket.<anonymous> (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:129:22)
    at Socket.emit (events.js:321:20)
    at Socket.EventEmitter.emit (domain.js:485:12)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:273:9)
    at Socket.Readable.push (_stream_readable.js:214:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:186:23) {
  name: 'error',
  length: 144,
  severity: 'ERROR',
  code: '25P02',
  detail: undefined,
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'postgres.c',
  line: '1105',
  routine: 'exec_simple_query'
}
(node:44672) UnhandledPromiseRejectionWarning: QueryFailedError: column cnst.consrc does not exist
    at new QueryFailedError (/Users/faisal/Desktop/abb/src/error/QueryFailedError.ts:7:9)
    at Query.callback (/Users/faisal/Desktop/abb/src/driver/postgres/PostgresQueryRunner.ts:170:26)
    at Query.handleError (/Users/faisal/Desktop/abb/node_modules/pg/lib/query.js:145:17)
    at Connection.connectedErrorMessageHandler (/Users/faisal/Desktop/abb/node_modules/pg/lib/client.js:214:17)
    at Connection.emit (events.js:321:20)
    at Connection.EventEmitter.emit (domain.js:485:12)
    at Socket.<anonymous> (/Users/faisal/Desktop/abb/node_modules/pg/lib/connection.js:134:12)
    at Socket.emit (events.js:321:20)
    at Socket.EventEmitter.emit (domain.js:485:12)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:273:9)
    at Socket.Readable.push (_stream_readable.js:214:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:186:23)
(node:44672) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:44672) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

trying to create same table twice while running tests with same mock email and password

I was trying from lesson 14. Fixing Connection Error,
while following along with you i found that my test cases were failing when i re run the test with same mock email and password in register.test.ts
I tried logging the queries from postgres and found this line

console.log node_modules/typeorm/platform/PlatformTools.js:214
      query: CREATE TABLE "users" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "email" character varying(255) NOT NULL, "password" text NOT NULL, "confirmed" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))
    console.log node_modules/typeorm/platform/PlatformTools.js:217
      query failed: CREATE TABLE "users" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "email" character varying(255) NOT NULL, "password" text NOT NULL, "confirmed" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))
    console.log node_modules/typeorm/platform/PlatformTools.js:217
      error: { error: duplicate key value violates unique constraint "pg_type_typname_nsp_index"
          at Connection.Object.<anonymous>.Connection.parseE

So I guess it is trying to create the users table twice and throwing error while creating it second time and thereby failing my subsequent tests.

It works if i manually change the email and password before every test but i see you don't change the email every time you test yet it works. Can't figure out why it isn't in my case

Cannot find connection development because its not defined in any orm configuration files

Hey Ben,
So I updated the dependencies and run the boilerplate and am facing the below mentioned issue when I run yarn test and yarn start:

yarn test:
`Test suite failed to run

Jest: Got error running globalSetup - F:\programs\boilerplates\graphql-ts-server-boilerplate\src\testUtils\callSetup.js, reason: Cannot find connection test  because its not defined in any orm configuration files.

  at ConnectionOptionsReader.<anonymous> (node_modules/typeorm/connection/ConnectionOptionsReader.js:56:35)
  at step (node_modules/typeorm/node_modules/tslib/tslib.js:143:27)
  at Object.next (node_modules/typeorm/node_modules/tslib/tslib.js:124:57)
  at fulfilled (node_modules/typeorm/node_modules/tslib/tslib.js:114:62)`

yarn start:
(node:7936) UnhandledPromiseRejectionWarning: Error: Cannot find connection development because its not defined in any orm configuration files. at ConnectionOptionsReader.<anonymous> (F:\programs\boilerplates\graphql-ts-server-boilerplate\src\connection\ConnectionOptionsReader.ts:55:19) at step (F:\programs\boilerplates\graphql-ts-server-boilerplate\node_modules\typeorm\node_modules\tslib\tslib.js:143:27) at Object.next (F:\programs\boilerplates\graphql-ts-server-boilerplate\node_modules\typeorm\node_modules\tslib\tslib.js:124:57) at fulfilled (F:\programs\boilerplates\graphql-ts-server-boilerplate\node_modules\typeorm\node_modules\tslib\tslib.js:114:62) at processTicksAndRejections (internal/process/task_queues.js:93:5) (Use node --trace-warnings ...to show where the warning was created) (node:7936) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag--unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:7936) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This problem is probably that it isn't reading the connections from ormconfig.json, but I don't get the problem here whatsoever. I have referred the documentation as well as your video and everything seems to be the same and logical. Can anyone help me out with this.

Cannot find namespace 'GQL'.

Hi there! I don't know if you know why this happen:

return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
src/resolvers.ts(6,26): error TS2503: Cannot find namespace 'GQL'.
src/resolvers.ts(9,40): error TS2503: Cannot find namespace 'GQL'.

I was following all the steps in your video and well i don't know what happen

/*Greadings from Chile :D thanks for your videos*/

localStorage is not available for opaque origins

I have this error when running yarn test

 FAIL  src/modules/user/logout/logout.test.ts
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (../../node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

 FAIL  src/modules/user/forgotPassword/forgotPassword.test.ts
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (../../node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

 FAIL  src/modules/user/register/createConfirmEmailLink.test.ts
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (../../node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

 FAIL  src/modules/user/register/register.test.ts
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (../../node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

 FAIL  src/routes/confirmEmail.test.ts
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (../../node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

 FAIL  src/modules/user/me/me.test.ts
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (../../node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

 FAIL  src/modules/user/login/login.test.ts
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (../../node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)

Using more type-safe solution

Hi @benawad! I appreciate your work on this project 😉

I would like to suggest using a more TypeScriptish way of creating a GraphQL server, where all your GraphQL types live with your code, not as a separate definitions converted to interfaces by a CLI:
https://19majkel94.github.io/type-graphql

I've experienced the pain of matching and syncing schema, interfaces and resolvers code, that's why I've created this lib:
https://medium.com/@19majkel94/graphql-typescript-typegraphql-ba0225cb4bed

I would be grateful if you share your thoughts on this with me 😃

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.