Giter Club home page Giter Club logo

graphile / starter Goto Github PK

View Code? Open in Web Editor NEW
1.7K 41.0 215.0 7.34 MB

Opinionated SaaS quick-start with pre-built user account and organization system for full-stack application development in React, Node.js, GraphQL and PostgreSQL. Powered by PostGraphile, TypeScript, Apollo Client, Graphile Worker, Graphile Migrate, GraphQL Code Generator, Ant Design and Next.js

Home Page: https://graphile-starter.herokuapp.com

License: Other

JavaScript 7.32% TypeScript 56.21% PLpgSQL 33.74% Shell 1.68% HTML 0.26% Dockerfile 0.73% Procfile 0.04% CSS 0.04%
starter postgraphile graphql node nodejs apollo-client eslint typescript job-queue postgresql

starter's Introduction

Graphile Starter

Take it for a spin!

We're running the starter at:

https://graphile-starter.herokuapp.com

Feel free to register an account and have a poke around as you see fit.

NOTE: emails are sent from Graphile Starter, so please only enter email addresses you control.

NOTE: every time we merge to master, we ship a new version of Graphile Starter to Heroku and entirely wipe the database, so your data may not persist. If you wish to delete your data before this time you can do so via the delete account feature baked into the starter.

NOT FOR BEGINNERS

We do not advise that you build your own projects on top of this project until you're comfortable with the various tools it uses (Node.js, Express, PostgreSQL, GraphQL, PostGraphile, Graphile Worker, Graphile Migrate, TypeScript, React, Apollo Client for React, GraphQL Code Generator, ESLint, Prettier, Jest, Cypress, etc).

This is an advanced project with deeply integrated tooling across the full stack. The project is called "Starter" because it helps you to start new projects with all these technologies, tools and techniques already in place. If you're not already familiar with these things then you'll probably find the project overwhelming, it is not intended to be your first experience of any of these tools.

If you're just getting started with PostGraphile, before you dive into this project make sure you check out the PostGraphile required knowledge and especially the schema design tutorial. This repository takes a slightly different approach to schema design than the aforementioned tutorial, but it's still an incredibly valuable resource.

Purpose

Graphile Starter is an opinionated quick-start project for full-stack application development in React, Node.js, GraphQL and PostgreSQL. It includes the foundations of a modern web application, with a full user registration system, organizations (e.g. teams/companies/etc), session management, optimized job queue, a significant amount of pre-configured tooling, tests (both end-to-end and more granular) and much more.

It is suitable for building projects both large and small, with a focus on productivity. You might use it:

  • to go from conception to launch of a web app during a hack day
  • as the foundation for client projects at your web agency
  • to build your side-hustle without spending lots of time on boilerplate
  • to build a SaaS project to help fund your open source work ๐Ÿ˜‰

However you use it, the project can be deployed to many platforms, and can be scaled to larger audiences both horizontally and vertically with very few changes.

Please note that this software is not "complete," free of software defects, or free of security issues โ€” it is not a "finished" solution, but rather the seed of a solution which you should review, customize, fix, and develop further.

It is intended that you use a "point in time" version of this software โ”€ it is not intended that you can merge updates to this software into your own derivative in an automated fashion.

Crowd-funded open-source software

PLEASE DONATE.

Take this software and use it as the starting point to build your project. Go make some money, and give something back to support us building more tools and kits for the Node, GraphQL and PostgreSQL ecosystems. We have made this project available under the simple and liberal MIT license to give you to a huge amount of freedom in how you use it, but this isn't possible without the help of our wonderful sponsors.

We need more people to join our sponsors so we can continue to bring about awesome projects like this. We'd love to spend more time on open source, building tools that will save you and others even more time and money โ”€ please sponsor our open source efforts:

And please give some love to our featured sponsors ๐Ÿคฉ:

The Guild
The Guild
*
Dovetail
Dovetail
*
Netflix
Netflix
*
Stellate
Stellate
*
Steelhead
Steelhead
*
Sylvera
Sylvera
*

* Sponsors the entire Graphile suite

Table of contents

Features

Graphile Starter is a full-stack GraphQL and React project, with server-side rendering (SSR) and routing thanks to Next.js. The backend is a beautiful pairing of Node.js and PostgreSQL running on Express.js, enabled by PostGraphile in library mode. The frontend uses the AntD design framework to accelerate development. The entire stack is written in TypeScript, with auto-generated GraphQL types and operations thanks to graphql-code-generator.

There are four tenets to Graphile Starter:

  • Speedy development
  • Batteries included
  • Type safety
  • Best practices

Graphile Starter is easy to start and everything is pre-configured as much as possible.

Speedy development: hot reloading, easy debugging, Graphile's idempotent migration system, job queue and server middleware ready to use; not to mention deep integration with VSCode should you use that editor: plugin recommendations, pre-configured settings, ESLint and Prettier integration and debugging profiles

Batteries included: full user system and OAuth, AntD design framework, Jest and Cypress end-to-end testing, security, email templating and transport, pre-configured linting and code formatting, deployment instructions, and more

Type safety: pre-configured type checking, strongly typed throughout with TypeScript

Best practices: React, GraphQL, PostGraphile, Node, Jest and Cypress best practices

See TECHNICAL_DECISIONS.md for a more detailed list of features included and the technical decisions behind them.

Variants

Since this is a highly opinionated starter; community members may have slightly different opinions and may choose to maintain forks of this project that apply their own opinions. A few of these are listed below; if you maintain a fork of this project please make a note at the top of your own README, and add it to this list:

VARIANTS ARE NOT OFFICIALLY SUPPORTED and may become out of date or unmaintained over time. If you have issues with variants, please submit issues or PRs to the projects in question, not to this project.

Prerequisites

You can either work with this project locally (directly on your machine) or use a pre-configured Docker environment. We'll differentiate this in the README with a table like this one:

Local mode OR Docker mode
command for local development or command for docker-compose development

Be careful not to mix and match Docker-mode vs local-mode for development. You should make a choice and stick to it. (Developing locally but deploying with production.Docker is absolutely fine.)

IMPORTANT: If you choose the Docker mode, be sure to read docker/README.md.

For users of Visual Studio Code (VSCode), a .vscode folder is included with editor settings and debugger settings provided, plus a list of recommended extensions. Should you need it, there is also a .devcontainer folder which enables you to use VSCode's remote containers giving you a local-like development experience whilst still using docker containers.

Local development

Requires:

  • Node.js v16+ must be installed
  • PostgreSQL v10+ server must be available
  • pg_dump command must be available (or you can remove this functionality)
  • VSCode is recommended, but any editor will do

This software has been developed under Mac and Linux, and should work in a bash environment.

Windows users: making a project like Graphile Starter run smoothly on Windows can be a challenge; @JoeSchr and @hips on the Graphile Discord have been working in improving this and they're pretty pleased with the result, but you may still get some teething problems. PRs to fix Windows compatibility issues are welcome (please keep them small!) Failing that, try the Docker mode :)

Docker development

Requires:

  • docker
  • docker-compose
  • Ensure you've allocated Docker at least 4GB of RAM; significantly more recommended
    • (Development only, production is much more efficient)

Has been tested on Windows and Linux (Ubuntu 18.04LTS).

Getting started

This project is designed to work with yarn. If you don't have yarn installed, you can install it with npm install -g yarn. The Docker setup already has yarn & npm installed and configured.

To get started, please run yarn, followed by:

Local mode OR Docker mode
yarn setup or export UID; yarn docker setup

This command will lead you through the necessary steps, and create a .env file for you containing your secrets.

NOTE: export UID is really important on Linux Docker hosts, otherwise the files and folders created by Docker will end up owned by root, which is non-optimal. We recommend adding export UID to your ~/.profile or ~/.bashrc or similar so you don't have to remember it.

Do not commit .env to version control!

Running

You can bring up the stack with:

Local mode OR Docker mode
yarn start or export UID; yarn docker start

After a short period you should be able to load the application at http://localhost:5678

This main command runs a number of tasks:

  • uses graphile-migrate to watch themigrations/current.sql file for changes, and automatically runs it against your database when it changes
  • watches the TypeScript source code of the server, and compiles it from @app/*/src to @app/*/dist so node/graphile-worker/etc. can run the compiled code directly
  • runs the node server (includes PostGraphile and Next.js middleware)
  • runs graphile-worker to execute your tasks (e.g. sending emails)
  • watches your GraphQL files and your PostGraphile schema for changes and generates your TypeScript React hooks for you automatically, leading to strongly typed code with minimal effort
  • runs the jest tests in watch mode, automatically re-running as the database or test files change

NOTE: docker-compose up server also runs the PostgreSQL server that the system connects to.

You may also choose to develop locally, but use the PostgreSQL server via docker-compose up -d db.

Then for development you may need a console; you can open one with:

Local mode OR Docker mode
bash or export UID; yarn docker bash

To shut everything down:

Local mode OR Docker mode
Ctrl-c or export UID; yarn docker down

Making it yours

  1. Download and extract a zip of the latest release from GitHub
  2. In that folder run:
    • git init
    • git add .
    • git commit -m "Graphile Starter base"
  3. Change the project name in package.json
  4. Change the project settings in @app/config/src/index.ts
  5. Replace the README.md file
  6. Add your own copyright notices to the LICENSE.md file
  7. Commit as you usually would
  8. Show your appreciation with sponsorship

Docker development

Be sure to read docker/README.md.

Building the production docker image

To build the production image, use docker build as shown below. You should supply the ROOT_URL build variable (which will be baked into the client code, so cannot be changed as envvars); if you don't then the defaults will apply (which likely will not be suitable).

To build the worker, pass TARGET="worker" instead of the default TARGET="server".

docker build \
  --file production.Dockerfile \
  --build-arg ROOT_URL="http://localhost:5678" \
  --build-arg TARGET="server" \
  .

When you run the image you must pass it the relevant environmental variables, for example:

docker run --rm -it --init -p 5678:5678 \
  -e GRAPHILE_LICENSE="$GRAPHILE_LICENSE" \
  -e SECRET="$SECRET" \
  -e JWT_SECRET="$JWT_SECRET" \
  -e DATABASE_VISITOR="$DATABASE_VISITOR" \
  -e DATABASE_URL="$DATABASE_URL" \
  -e AUTH_DATABASE_URL="$AUTH_DATABASE_URL" \
  -e GITHUB_KEY="$GITHUB_KEY" \
  -e GITHUB_SECRET="$GITHUB_SECRET" \
  docker-image-id-here

Currently if you miss required envvars weird things will happen; we don't currently have environment validation (PRs welcome!).

Note: If you are using the production.Dockerfile to run graphile/starter in a Docker container on eg. Kubernetes, AWS ECS, DigitalOcean App Platform (or similar) and you are trying to connect to Amazon RDS or DigitalOcean databases (or probably other managed databases), make sure to replace /data/amazon-rds-ca-cert.pem with the CA certificate of your own database. This file is copied into your Docker image during build time and can therefore be referenced in your env variables DATABASE_URL and AUTH_DATABASE_URL:
DATABASE_URL="postgres://name:password@host:port/dbname?ssl=true&sslrootcert=/app/data/amazon-rds-ca-cert.pem"

Production build for local mode

Use yarn run build to generate a production build of the project

Deploying to Heroku

Prerequisites:

If you are using graphile-migrate make sure that you have executed graphile-migrate commit to commit all your database changes, since we only run committed migrations in production.

Make sure you have customized @app/config/src/index.ts.

Make sure everything is committed and pushed in git.

Set up a database server; we recommend using Amazon RDS.

Once your database server is running, you can use our heroku-setup script to automate the setup process. This script does the following:

  • Creates the Heroku app
  • Adds the redis extension to this Heroku app
  • Creates the database in the database server
  • Creates the relevant roles, generating random passwords for them
  • Installs some common database extensions
  • Sets the Heroku config variables
  • Adds the Heroku app as a git remote named 'Heroku'
  • Pushes the 'master' branch to Heroku to perform your initial build

Create a copy of heroku-setup.template and rename the copy to heroku-setup, then edit it and customize the settings at the top. We also recommend reading through the script and customizing it as you see fit - particularly if you are using additional extensions that need installing.

Now run the script:

bash heroku-setup

Hopefully all has gone well. If not, step through the remaining tasks in the Heroku-setup script and fix each task as you go. We've designed the script so that if your superuser credentials are wrong, or the Heroku app already exists, you can just edit the settings and try again. All other errors will probably need manual intervention. Verbosity is high so you can track exactly what happened.

The server should be up and running now (be sure to access it over HTTPS otherwise you will not be able to run GraphQL queries), but it is not yet capable of sending emails. To achieve this, you must configure an email transport. We have pre-configured support for Amazon SES. Once SES is set up, your domain is verified, and you've verified any emails you wish to send email to (or have had your sending limits removed), make sure that the fromEmail in @app/config/src/index.ts is correct, and then create an IAM role for your PostGraphile server. Here's an IAM template for sending emails - this is the only permission required for our IAM role currently, but you may wish to add others later.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ses:SendRawEmail",
            "Resource": "*"
        }
    ]
}

Generate an Access Key for this IAM role, and then tell Heroku the access key id and secret:

heroku config:set AWS_ACCESS_KEY_ID="..." AWS_SECRET_ACCESS_KEY="..." -a $APP_NAME

Now you can tell Heroku to run the worker process as well as the currently running 'web' process:

heroku ps:scale worker=1 -a $APP_NAME

When you register an account on the server you should receive a verification email containing a clickable link. When you click the link your email will be verified and thanks to GraphQL subscriptions the previous tab should be updated to reflect that your account is now verified.

You can also configure your application for social login. This works the same as in development except the callback URL will be different, something like https://MY_HEROKU_APP_NAME.herokuapp.com/auth/github/callback. Set the GitHub OAuth secrets on your Heroku app to trigger a restart and enable social login:

heroku config:set GITHUB_KEY="..." GITHUB_SECRET="..." -a $APP_NAME

Cleanup

To delete the Heroku app:

heroku apps:destroy -a $APP_NAME

To delete the database/roles (replace dbname with your database name):

drop database dbname;
drop role dbname_visitor;
drop role dbname_authenticator;
drop role dbname;

Custom packages

When running yarn setup, this command will also invoke yarn workspaces foreach run setup. This allows you to add custom setup hooks necessary for your individual packages.

Add a line like the following to your scripts section in your package.json:

"setup": "npm i -g some-package"

MIT License

This is open source software; you may use, modify and distribute it under the terms of the MIT License, see GRAPHILE_STARTER_LICENSE.md.

starter's People

Contributors

benjie avatar cusxio avatar deden avatar dependabot[bot] avatar eleijonmarck avatar fnimick avatar hcharley avatar hegelstad avatar hos avatar jackbravo avatar jannotti avatar jccr avatar jemgillam avatar jessevelden avatar joeschr avatar jofarnold avatar jonparton avatar justinr1234 avatar lukeramsden avatar macfly avatar makoncline avatar martinov avatar moblimic avatar petrus-jvrensburg avatar purge avatar rcy avatar remcoplasmeyer avatar singingwolfboy avatar thejoeschr avatar xvaara 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

starter's Issues

GitHub auth to get emails uses ?access_token=... which is deprecated

Hi @benjie,

On February 4th, 2020 at 08:51 (UTC) your application (Graphile Starter (Heroku)) used an access token (with the User-Agent passport-github) as part of a query parameter to access an endpoint through the GitHub API:

https://api.github.com/user/emails

Please use the Authorization HTTP header instead as using the access_token query parameter is deprecated.

Depending on your API usage, we'll be sending you this email reminder once every 3 days for each token and User-Agent used in API calls made on your behalf.
Just one URL that was accessed with a token and User-Agent combination will be listed in the email reminder, not all.

Visit https://developer.github.com/changes/2019-11-05-deprecated-passwords-and-authorizations-api/#authenticating-using-query-parameters for more information.

Thanks,
The GitHub Team

Might be sufficient to just upgrade passport-github?

Start script fails without git repo

The instructions say to start by downloading the .zip file.
If yarn start is run on this folder before git init, the process fails with the error

(TEST) [jest] --watch is not supported without git/hg, please use --watchAll
(TEST) [jest] node --inspect=9876 node_modules/.bin/jest -i --watch exited with code 1

The start script should check if it's being run in a git repo, and if not, fail and instruct the user to git init.

GraphQL Relation discovery in sql not working

After uncommenting example commands in current.sql, the following graphql query unexpectedly fails. The reason I expect it to work is in the docs: https://www.graphile.org/postgraphile/relations/

query MyQuery {
  posts {
    edges {
      node {
        userByAuthorId {
          email
        }
        body
        headline
      }
    }
  }
}

On inspection of data/schema.graphql, I notice that authorId is an int, instead of a reference. In other words,

type Post {
  authorId: Int
}

should probably be

type Post {
  author: User!
}

Am I missing something? Pardon my ignorance.

Here is my changeset: https://github.com/bdombro/starter/pull/1

Prevent yarn.lock from being generated when running `yarn docker`

This should do the trick:

docker/package.json

...
"preinstall": "echo $(cat NOOP_MESSAGE.txt); exit 126",
...

docker/NOOP_MESSAGE.txt

Exiting without running `yarn install` because this is a helper package that has no dependencies created by graphile/starter.

This is a noop that prevents a yarn.lock file from being accidentally generated.

Recommendations for disabling default mutations

This project uses PostGraphile's default CRUD mutations, which is perfectly reasonable and expected. However, when a developer takes this codebase and customizes it for their own project, they will probably turn off the default CRUD mutations in favor of custom mutations -- and at that point, things go a bit off the rails.

GraphQL Code Generator is designed to validate that our queries match our schema, but once these mutations are disabled, the queries no longer match, and running yarn build results in a lot of ugly errors. Furthermore, it's not immediately obvious that these errors are due to disabling the default mutations, since they involve code and queries that the developer didn't write and is not familiar with. Even after the developer determines the cause of the errors, it's not clear what is the best way to resolve the issue: delete the code? Disable graphql-codegen? Write custom mutations that match the autogenerated ones that you need? Something else?

To be clear, the problem here is not using autogenerated mutations. That is a very handy feature for PostGraphile, and it makes sense to show it off in this repo. The problem is that there are no clear paths for how to disable this feature without breaking everything. This problem could be solved with documentation, with informative error messages, with a migration file that defines the database functions necessary to recreate these mutations, or some combination of these. (Maybe other ways, too?)

Github Login violates email constraint

When I attempt to log in via GitHub, this error throws after the callback:

error: null value in column "email" violates not-null constraint
    at Connection.parseE (/home/frank/git/starter/node_modules/pg/lib/connection.js:601:11)
    at Connection.parseMessage (/home/frank/git/starter/node_modules/pg/lib/connection.js:398:19)
    at Socket.<anonymous> (/home/frank/git/starter/node_modules/pg/lib/connection.js:120:22)
    at Socket.emit (events.js:193:13)
    at addChunk (_stream_readable.js:295:12)
    at readableAddChunk (_stream_readable.js:276:11)
    at Socket.Readable.push (_stream_readable.js:231:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:154:17)

Not sure, but the authorization screen on Github was only accessing public data, perhaps it needs to request access to Email address?

db never installs on fresh install

I expected to be able to see what the application would look like but didnt get the repo running. :(

Reproducable example

$ git clone https://github.com/graphile/starter
$ cd starter

Reading the readme or the docker readme https://github.com/graphile/starter/blob/master/docker/README.md i run the command:

$ export UID; yarn docker setup
yarn run v1.21.1
$ yarn --cwd ./docker setup
$ node ./scripts/yarn-setup.js
$ yarn compose down --remove-orphans
$ docker-compose -f ../docker-compose.yml down --remove-orphans
Stopping starter_db_1 ... done
Removing starter_server_run_2 ... done
Removing starter_server_run_1 ... done
Removing starter_db_1         ... done
Removing network starter_default
$ yarn compose up -d db
$ docker-compose -f ../docker-compose.yml up -d db
Creating network "starter_default" with the default driver
Creating starter_db_1 ... done
$ docker-compose -f ../docker-compose.yml run server sudo bash -c 'chmod o+rwx /var/run/docker.sock && chown -R node /work/node_modules /work/@app/*/node_modules'
Starting starter_db_1 ... done
$ docker-compose -f ../docker-compose.yml run server yarn setup starter
Starting starter_db_1 ... done
yarn run v1.21.1
$ yarn && node ./scripts/setup.js starter
[1/4] Resolving packages...
success Already up-to-date.
Installing or reinstalling the roles and database...
Database is not ready yet (attempt 1)
Database is not ready yet (attempt 2)
Database is not ready yet (attempt 3)
Database is not ready yet (attempt 4)
Database is not ready yet (attempt 5)
Database is not ready yet (attempt 6)
Database is not ready yet (attempt 7)
Database is not ready yet (attempt 8)
Database is not ready yet (attempt 9)
Database is not ready yet (attempt 10)
Database is not ready yet (attempt 11)
Database is not ready yet (attempt 12)
Database is not ready yet (attempt 13)
Database is not ready yet (attempt 14)
Database is not ready yet (attempt 15)
Database is not ready yet (attempt 16)
Database is not ready yet (attempt 17)
Database is not ready yet (attempt 18)
Database is not ready yet (attempt 19)
Database is not ready yet (attempt 20)
Database is not ready yet (attempt 21)
Database is not ready yet (attempt 22)
Database is not ready yet (attempt 23)
Database is not ready yet (attempt 24)
Database is not ready yet (attempt 25)
Database is not ready yet (attempt 26)
Database is not ready yet (attempt 27)
Database is not ready yet (attempt 28)
Database is not ready yet (attempt 29)
Database is not ready yet (attempt 30)
Database never came up, aborting :(
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Avoid using "psql" in "setup.js"

As privately discussed, it would be super useful for various different setups if we would avoid to use psql in setup.js. @benjie says he could maybe rewrite it to use node-postgres.

Example for setups which would then be possible:

  • using the starter natively on windows OS. where the postgreSQL server is eg. on another machine or started via docker
  • use inside our docker-compose setup.

Explanation about docker-compose

While trying to combine the latest commits about dotenv, js scripts, etc, it turned out the single major hassle is to to call docker-compose run pgtools psql or $PSQL via spawnSync from inside the running webapp/dev container.

For reference:

Since with my current work we wouldn't need a special DOCKER_MODE anymore, they only inside container calls to docker-compose are psql to reset database at setup and further on pg_dump to update schema.sql afaik .

Also it turns out, the current way we are doing pg_dump via pgtools/docker-compose.yml is actually not working, just was not failing. The dump never actually updates schema.sql. I tested this by using a different databasename then graphile-starter

Reason it seems you can't map a volume if you call docker-compose from inside another running container. I'm currently exploring other solutions, maybe via using docker cp and a special Dockerfile.

But it would be really great, if we could just use node-postgresql or any other "native JS" solution so we don't need to support psql tooling on different plattforms.

Use yarn workspaces

Reduce the number of root-level dependencies and commands to make it easier to grok what's going on.

CRA for apps without SSR

Having @app/client-cra for a Create-React-App based version of the @app/client might be a better option for apps that sit behind the login wall and don't need any SSR.

local run windows: password authentification failed

trying to setup locally with Windows10 and WSL but I have this error (coval is my windows user):

`โœ˜ coval@coco-desk ๎‚ฐ ~/winhome/Documents/projects/plants/starter-2.2.0 ๎‚ฐ ๎‚  master ๎‚ฐ yarn setup
yarn run v1.21.1
$ yarn && node ./scripts/setup.js
[1/4] Resolving packages...
success Already up-to-date.
? What would you like to call your database? graphile_starter
? What's the hostname of your database server (include :port if it's not the default :5432)? localhost:6543
? Please enter a superuser connection string to the database server (so we can drop/create the 'graphile_starter' and 'graphile_starter_shadow' databases) - IMPORTANT: it must not be a connection to the 'graphile_starter' database itself, instead try 'template1'. postgres://localhost:6543/template1
? We're going to drop (if necessary):

  • database graphile_starter
  • database graphile_starter_shadow
  • database role graphile_starter_visitor (cascade)
  • database role graphile_starter_authenticator (cascade)
  • database role graphile_starter Yes
    Installing or reinstalling the roles and database...
    error: password authentication failed for user "coval"
    at Connection.parseE (/c/Users/Coco/Documents/projects/plants/starter-2.2.0/node_modules/pg/lib/connection.js:604:13)
    at Connection.parseMessage (/c/Users/Coco/Documents/projects/plants/starter-2.2.0/node_modules/pg/lib/connection.js:403:19)
    at Socket. (/c/Users/Coco/Documents/projects/plants/starter-2.2.0/node_modules/pg/lib/connection.js:123:22)
    at Socket.emit (events.js:203:13)
    at addChunk (_stream_readable.js:295:12)
    at readableAddChunk (_stream_readable.js:276:11)
    at Socket.Readable.push (_stream_readable.js:210:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:166:17) {
    name: 'error',
    length: 101,
    severity: 'FATAL',
    code: '28P01',
    detail: undefined,
    hint: undefined,
    position: undefined,
    internalPosition: undefined,
    internalQuery: undefined,
    where: undefined,
    schema: undefined,
    table: undefined,
    column: undefined,
    dataType: undefined,
    constraint: undefined,
    file: 'auth.c',
    line: '337',
    routine: 'auth_failed'
    }
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.`

I am not sure where to input my password. I have also creating a user coval in the database but still the same error.
I think it is a stupid mistake but can't find solution.

tsc unable to compile imports from other workspaces in certain cases

Problem

tsc is unable to navigate imports from any workspace in a workspace that is tsconfig configured with a rootDir.

Repro: https://github.com/jkantr/starter/tree/repo_import__to_workspace_with_rootdir
Error:

@app/server: error TS6059: File '/mnt/d/src/graphql-starter-repro/@app/graphql/index.tsx' is not under 'rootDir' '/mnt/d/src/graphql-starter-repro/@app/server/src'. 'rootDir' is expected to contain all source files.

This error persists even when added the workspace in question to the local deps. See:
https://github.com/jkantr/starter/blob/repo_import__to_workspace_with_rootdir/%40app/server/package.json#L15

Solution:

Use TS3.0 Project References - example referencer tsconfig:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "noEmit": false,
    "rootDir": "src",
    "outDir": "dist",
    "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo",
    "declarationDir": "dist",
    "lib": ["es2018", "esnext.asynciterable"],
    "target": "es2018",
    "module": "commonjs"
  },
  "include": ["src"],
  "references": [{ "path": "../graphql" }]
}

Example refrencee tsconfig:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "jsx": "react",
    "target": "es2017",
    "module": "commonjs",
    "noEmit": false,
    "composite": true
  },
  "include": ["index.tsx"]
}

(the above with @app/server and @app/graphql fixes the error in the above repo branch)

Possible Resolution:

Either include certain references / reference paths by default in the starter for workspaces with rootDirs or include a section in the README pertaining to this enhancement when needed.

CI for master build failed on --noEmit, here's why

Looking at the last merge to master here, I can see the error for error TS5072: Unknown build option '--noEmit'.

I can see noEmit is set in config throughout:

https://github.com/graphile/starter/search?q=emit&unscoped_q=emit

however, when using tsc --build for project references, many of of your options change, and noEmit is one of the things you can no longer do. you do have the option of doing tsc --build --dry which is effectively the same.

https://www.typescriptlang.org/docs/handbook/project-references.html#tsc--b-commandline

Improve the setup script's wait-for-database functionality

If the error code is 'ENOTFOUND' then it's not likely the attempt to setup the database will succeed. Perhaps change the code to:

  // Wait for PostgreSQL to come up
  let attempts = 0;
  while (true) {
    try {
      await pgPool.query('select true as "Connection test";');
      break;
    } catch (e) {
      if (e.code === 'ENOTFOUND') {
        console.log(
          'Could not find database connection at host:',
          answers.DATABASE_HOST
        );
        process.exit(1);
      }
      attempts++;
      if (attempts <= 60) {
        console.log(`Database is not ready yet (attempt ${attempts})`);
      } else {
        console.log('Database never came up, aborting :(');
        process.exit(1);
      }
      await sleep(2000);
    }
  }

using starter for an existing db - a rough outline

in setting up the starter, i had to comment some lines out from the server index.ts file. this is because they reference the starter's authorization design (User). This could be refactored to be a bit easier, but not so hard to work around manually. in fact, it gives me a roadmap to implement my own stuff on all fronts. some reorganization of this code and comments explaining as much might be good:

  /*
   * Middleware is installed from the /server/middleware directory. These
   * helpers may augment the express app with new settings and/or install
   * express middleware. These helpers may be asynchronous, but they should
   * operate very rapidly to enable quick as possible server startup.
   */
  await middleware.installDatabasePools(app);
  // await middleware.installSession(app);
  // await middleware.installPassport(app);
  await middleware.installLogging(app);
  // These are our assets: images/etc; served out of the /client/public folder
  await middleware.installSharedStatic(app);
  // if (isTest || isDev) {
  //   await middleware.installCypressServerCommand(app);
  // }
  await middleware.installPostGraphile(app);
  // await middleware.installNext(app);

also PassportLoginPlugin and SubscriptionsPlugin had to be commented out of installPostgraphile.ts

for the db migrations, i created a new template database by pg_dump -s my old db, then using psql to run that file on the new template

i added TEMPLATE_DATABASE_NAME to my .env

added preAfterReset to .gmrc

  "afterReset": [
    {
      "_": "command",
      "command": "scripts/preAfterReset"
    },
    "afterReset.sql",
    {
      "_": "command",
      "command": "cd backend/dist/worker && npx --no-install graphile-worker --once"
    }
  ],

in scripts, added preAfterReset

#!/usr/bin/env bash

set -e
export NODE_ENV=development

if [ -x .env ]; then
  . .env

  fail () {
    echo ".env already exists, but it doesn't define $1 - aborting!"
    exit 1;
  }

  if [ "$DATABASE_HOST" = "" ]; then fail DATABASE_HOST; fi;
  if [ "$DATABASE_OWNER" = "" ]; then fail DATABASE_OWNER; fi;
  if [ "$DATABASE_OWNER_PASSWORD" = "" ]; then fail DATABASE_OWNER_PASSWORD; fi;
  if [ "$DATABASE_AUTHENTICATOR" = "" ]; then fail DATABASE_AUTHENTICATOR; fi;
  if [ "$DATABASE_AUTHENTICATOR_PASSWORD" = "" ]; then fail DATABASE_AUTHENTICATOR_PASSWORD; fi;
  if [ "$TEMPLATE_DATABASE_NAME" = "" ]; then fail DATABASE_RESET_TEMPLATE; fi;

  echo "Configuration already exists, using existing secrets."
fi

echo "Rebuilding database from template..."
echo $DATABASE_NAME     $ROOT_DATABASE_URL
PSQL="psql"
$PSQL -X -v ON_ERROR_STOP=1 "${ROOT_DATABASE_URL}" <<SQL
DROP DATABASE IF EXISTS ${DATABASE_NAME};
CREATE DATABASE ${DATABASE_NAME} TEMPLATE ${TEMPLATE_DATABASE_NAME};

DROP DATABASE IF EXISTS ${DATABASE_NAME}_shadow;
CREATE DATABASE ${DATABASE_NAME}_shadow TEMPLATE ${TEMPLATE_DATABASE_NAME};

DROP DATABASE IF EXISTS ${DATABASE_NAME}_test;
CREATE DATABASE ${DATABASE_NAME}_test TEMPLATE ${TEMPLATE_DATABASE_NAME};
SQL

echo "โœ… preAfterReset success"

Possible session signing vulnerability

Problem

The starter properly generates cryptographically secure secrets in the setup script, but has a 'fallback' using a very dubious default:

const { SECRET = String(Math.random()) } = process.env;

If one misconfigures their env vars after setup, or circumvents the setup, this could result in using a very insecure secret for session signing.

Solution

Provide no default here and fail if there is no secret available.

Production worker docker image missing email templates folder

When running the production worker docker image, the following error occurs when an email is sent.

[worker(worker-2405044886759662)] ERROR: Failed task 30 (send_email) with error ENOENT: no such file or directory, open '/app/@app/worker/dist/../templates/verify_email.mjml' (17.34ms):
  Error: ENOENT: no such file or directory, open '/app/@app/worker/dist/../templates/verify_email.mjml'

This is fixed by placing the following on line 51 of production.Dockerfile

COPY --from=builder /app/@app/worker/templates/ /app/@app/worker/templates/

but, is there a way to only include the template folder if the $TARGET is worker?

Handle SSR of timestamptz

Server timezone may differ from client timezone leading to dates being rendered differently on client vs server and causing hydration issues. For example, reload the email management page.

Extract the server code for authentication into a Postgraphile plugin?

First of all, thanks for this starter project. I personally found it very helpful when learning Postgraphile and working on my first project:

  1. it shows how Postgraphile features work together in practice;
  2. it shows the best practices;
  3. it's well documented, up-to-date and complete;
  4. it drastically reduces costs of setting up a new project from scratch, especially for beginners.

Obviously it makes sense that the starter project contains an authentication solution. Most of real world apps require it. But having this solution hardcoded in the project has several drawbacks, IMO. An authentication solution is:

  1. Quite complex when done right, lots of code, features and security requirements;
  2. Critical, must be maintained and bug-free.

With this in mind, it might not match the goals of the starter project for the following reasons:

  1. The project is intended to be used at "point in time". If an issue is discovered and fixed at a later date regarding the authentication, any previous user of the starter project won't get the fix easily;
  2. The project is incredibly useful for beginners, as a tutorial/playground for learning Postgraphile. However the authentication code takes the big part of the spotlight. And it's not the best learning material. As said above, it's rather complex and domain-specific.

So what about extracting this code into a flexible authentication plugin, as an alternative to JWT + external auth solutions?

  • It can evolve over time with security fixes and additional features;
  • It will greatly simplify the starter project code and lower the barrier for beginners. The starter can then showcase a simpler model like a forum or a todo-list;
  • Right now if a developer doesn't want to implement authentication manually, he's required to go with JWT and an external auth service. But I believe many developers would gladly not deal with the complexities of JWT for a simple auth. Coming from Ruby on Rails development, I know libraries like Devise (https://github.com/plataformatec/devise) are very popular and a go-to choice for implementing a simple, in-house auth system;
  • For developers that just want the boilerplate code for auth in order to customize the code internally, cloning the starter project or cloning the auth plugin project is pretty much the same;

Now I understand it's big task to make it as an external plugin, especially to make it flexible and pluggable with the rest of the stack. But most of the work is already done in the starter project and it looks good!

I think it will be a great long-term addition to the Postgraphile ecosystem.
What do you think?

yarn docker setup fails on MacOS

Setup:

  • MacOS Catalaina
  • yarn v1.21.1
  • ZSH & iTerm

Steps to reproduce:

yarn docker setup output

I also tried pruned all containers and images to force rebuild but it did not help.
Found this issue #3 and checked commit history but did not find anything useful in this date range which was very different to the current setup

generated .env file

Question: Are there any guidelines for creating an adjacent React package within @app?

Looking for an easy way to create a generic React package to supply my @app/client package with "dumb" components, but it seems like there is a lot of boilerplate needed that is slightly different from @app/graphql or @app/config, meaning that for newbies to the project, the overhead of creating a new React-specific module is non-trivial, and will probably leave others and myself creating sub-optimal implementations.

Allow eslint to warn on unused vars instead of TS

https://discordapp.com/channels/489127045289476126/498852330754801666/655062567240073219
https://discordapp.com/channels/489127045289476126/498852330754801666/655066636516327454

[10:04 AM] Benjie:IMO things like unused vars should be something ESLint tells you about, not TypeScript. I think TypeScript was overreaching with that rule.

[10:20 AM] Benjie: Oh and add these to tsconfig:

    "noUnusedLocals": false,
    "noUnusedParameters": false,


I'd actually be tempted to add these to the official starter TBH; as I say my opinion is
that's ESLint's responsibility.

.eslintrc.js assumes eslint run from top-level

When run from any subdirectory, say scripts, eslint clean.js says:

Error: Cannot read config file: /Users/jj/src/table-stakes/.eslintrc.js
Error: ENOENT: no such file or directory, open './data/schema.graphql'

That is what my editor does (I suppose others run eslint from the top, and give the path to the file in question). It seems right to allow both. The fix is:

 const { readFileSync } = require("fs");
-const schemaString = readFileSync("./data/schema.graphql", "utf8");
+const schemaString = readFileSync(`${__dirname}/data/schema.graphql`, "utf8");
 
 module.exports = {
   parser: "@typescript-eslint/parser",

cypressServerCommand: won't let testRunner know something went wrong

It seems to me, that this error handling code is never reached

 } catch (e) {
      /*
       * If anything goes wrong, let the test runner know so that it can fail
       * the test.
       */
      res.status(500).json({
        error: {
          message: e.message,
          stack: e.stack,
        },
      });

because it get's handled by /work/@app/server/src/middleware/installErrorHandler.ts before that.

Did I just mess up my configuration or can somebody confirm that?

On my end this is bad for cypress testrunner because it just waits forever until a timeout without any information (there is a error log in the server cli printed by installErrorHandler.ts ofc)

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.