From 26f5051a8ebc429e7b19ae231798a4dd4734caa1 Mon Sep 17 00:00:00 2001 From: NotNite Date: Sat, 29 Apr 2023 01:19:06 +0000 Subject: [PATCH] Extremely hacky Nix support --- .gitignore | 3 + .prettierignore | 1 + README.md | 37 +- codegen.ts | 26 +- flake.lock | 61 ++ flake.nix | 178 ++++ introspection.json | 2123 ++++++++++++++++++++++++++++++++++++++++++ next.config.js | 3 +- package-lock.json | 26 + package.json | 1 + prisma/schema.prisma | 2 +- 11 files changed, 2446 insertions(+), 15 deletions(-) create mode 100644 .prettierignore create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 introspection.json diff --git a/.gitignore b/.gitignore index b298746..00c9049 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ database.db* # graphql-codegen src/__generated__ + +# NixOS +result diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..ce50af8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +src/graphql.ts diff --git a/README.md b/README.md index 4bca939..2535fca 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ After cloning, create an `.env.local` with the following contents (in `key=value - `LDAP_BIND_PASSWORD`: the password of the bind user - `BASE_DOMAIN`: the domain gluestick is deployed on, with a protocol and trailing slash - This domain will be used for OAuth redirects - if you are testing locally, set it to `http://localhost:3000/` +- `DATABASE_URL`: a Prisma-like path to your database Example config: @@ -69,6 +70,7 @@ GITHUB_TOKEN=redacted GITHUB_ORG=n2pm BASE_DOMAIN=https://gluestick.n2.pm/ +DATABASE_URL=file:./database.db ``` ### Generating code @@ -93,7 +95,7 @@ export GRAPHQL_CODEDGEN_AUTH=... Then, generate the GraphQL and database code: ```shell -npm run graphql-codegen +GRAPHQL_USE_INTROSPECTION=true npm run graphql-codegen npm run prisma-generate ``` @@ -108,7 +110,36 @@ npm run start ## Developing -You'll want to run these two commands at the same time: +### Generating GraphQL code + +Because the LLDAP GraphQL API is locked behind authentication, and of a quirk with `graphl-codegen` configuration files, we need to set a temporary environment variable to generate GraphQL code. If not using introspection, you will need a running LLDAP server. + +Run the `get-token.js` helper script and set the environment variable from its output: + +```shell +node get-token.js +export GRAPHQL_CODEDGEN_AUTH=... +``` + +Then, generate the GraphQL code: + +```shell +npm run graphql-codegen +``` + +If you want to use introspection, set `GRAPHQL_USE_INTROSPECTION=true` before generating the code. You won't need to set the auth environment variable in this case. + +### Working with Prisma + +gluestick uses [Prisma](https://www.prisma.io/) for accessing the database. If you will be modifying the database schema, you will need to work with it. Consider taking some time to familiarize yourself with the [Prisma CLI](https://www.prisma.io/docs/reference/api-reference/command-reference) first. + +When first cloning, generate the Prisma client: + +```shell +npm run prisma-generate +``` + +### Running the server ```shell # Next.js hot reload @@ -119,5 +150,3 @@ npm run dev | pino-pretty # Only required if working on GraphQL code npm run graphql-codegen -- -w ``` - -If you're interacting with the database, take some time to familiarize yourself with the [Prisma CLI](https://www.prisma.io/docs/reference/api-reference/command-reference). diff --git a/codegen.ts b/codegen.ts index af73e09..dfac337 100644 --- a/codegen.ts +++ b/codegen.ts @@ -4,24 +4,32 @@ import { CodegenConfig } from "@graphql-codegen/cli"; import * as dotenv from "dotenv"; dotenv.config({ path: ".env.local" }); +const useIntrospection = ["1", "true"].includes( + process.env.GRAPHQL_USE_INTROSPECTION?.toLowerCase() ?? "" +); + const config: CodegenConfig = { - schema: { - [`http://${process.env.LDAP_HOST}:17170/api/graphql`]: { - headers: { - // can't make the request automatically (await on top level) - Authorization: `Bearer ${process.env.GRAPHQL_CODEGEN_AUTH}` - } - } - }, + schema: useIntrospection + ? "introspection.json" + : { + [`http://${process.env.LDAP_HOST}:17170/api/graphql`]: { + headers: { + // can't make the request automatically (await on top level) + Authorization: `Bearer ${process.env.GRAPHQL_CODEGEN_AUTH}` + } + } + }, documents: ["src/**/*.ts", "src/**/*.tsx"], generates: { "./src/__generated__/": { preset: "client", - plugins: [], presetConfig: { gqlTagName: "gql" } + }, + "introspection.json": { + plugins: ["introspection"] } }, ignoreNoDocuments: true diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..e40fbe9 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1682656005, + "narHash": "sha256-fYplYo7so1O+rSQ2/aS+SbTPwLTeoUXk4ekKNtSl4P8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6806b63e824f84b0f0e60b6d660d4ae753de0477", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..772f8af --- /dev/null +++ b/flake.nix @@ -0,0 +1,178 @@ +{ + description = + "NotNet's one stop shop for authentication and account onboarding"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + let + packages = flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages."${system}"; + + # I really cannot be assed to pick this apart + inputs = with pkgs; [ vips pkg-config python3 ]; + + # https://github.com/prisma/prisma/issues/3026#issuecomment-927258138 + prismaHook = with pkgs; '' + export PRISMA_MIGRATION_ENGINE_BINARY="${prisma-engines}/bin/migration-engine" + export PRISMA_QUERY_ENGINE_BINARY="${prisma-engines}/bin/query-engine" + export PRISMA_QUERY_ENGINE_LIBRARY="${prisma-engines}/lib/libquery_engine.node" + export PRISMA_INTROSPECTION_ENGINE_BINARY="${prisma-engines}/bin/introspection-engine" + export PRISMA_FMT_BINARY="${prisma-engines}/bin/prisma-fmt" + ''; + in rec { + packages.gluestick = pkgs.buildNpmPackage { + pname = "gluestick"; + version = "0.1.0"; + src = ./.; + npmDepsHash = "sha256-keOreamXKunlJzU2AKJo0J02ZxQrjLdoCIMCaiwEU4Y="; + + nativeBuildInputs = inputs; + buildInputs = inputs; + + preBuild = '' + ${prismaHook} + + # Use the introspection.json, because we can't connect to the API at build time + GRAPHQL_USE_INTROSPECTION=true npm run graphql-codegen + npm run prisma-generate + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out + cp -r .next/standalone $out/server + cp -r .next/static $out/server/.next/static + cp -r public $out/server/public + cp -r prisma $out/prisma + + mkdir -p $out/bin + cat > $out/bin/gluestick < $out/bin/prisma <