Skip to content

Commit ec23bf1

Browse files
committed
re-enable graphile explorer
1 parent fb6d8b2 commit ec23bf1

15 files changed

Lines changed: 183 additions & 504 deletions

File tree

graphile/graphile-cache/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@
3030
},
3131
"dependencies": {
3232
"@pgpmjs/logger": "workspace:^",
33+
"express": "^5.2.1",
34+
"grafserv": "^1.0.0-rc.4",
3335
"lru-cache": "^11.2.4",
3436
"pg-cache": "workspace:^",
35-
"grafserv": "^1.0.0-rc.4",
3637
"postgraphile": "^5.0.0-rc.4"
3738
},
3839
"devDependencies": {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { createServer } from 'node:http';
2+
import express from 'express';
3+
import { postgraphile } from 'postgraphile';
4+
import { grafserv } from 'grafserv/express/v4';
5+
import type { GraphileCacheEntry } from './graphile-cache';
6+
7+
interface GraphileInstanceOptions {
8+
preset: any;
9+
cacheKey: string;
10+
}
11+
12+
/**
13+
* Create a PostGraphile v5 instance backed by grafserv/express.
14+
*
15+
* This is the shared factory used by both graphql/server and graphql/explorer
16+
* to spin up a fully-initialised PostGraphile handler that fits into the
17+
* graphile-cache LRU cache.
18+
*
19+
* Callers are responsible for building the `GraphileConfig.Preset` (including
20+
* pgServices, grafserv options, grafast context, etc.) before passing it here.
21+
*/
22+
export const createGraphileInstance = async (
23+
opts: GraphileInstanceOptions
24+
): Promise<GraphileCacheEntry> => {
25+
const { preset, cacheKey } = opts;
26+
27+
const pgl = postgraphile(preset);
28+
const serv = pgl.createServ(grafserv);
29+
30+
const handler = express();
31+
const httpServer = createServer(handler);
32+
await serv.addTo(handler, httpServer);
33+
await serv.ready();
34+
35+
return {
36+
pgl,
37+
serv,
38+
handler,
39+
httpServer,
40+
cacheKey,
41+
createdAt: Date.now(),
42+
};
43+
};

graphile/graphile-cache/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ export {
2828
// Clear matching entries
2929
clearMatchingEntries
3030
} from './graphile-cache';
31+
32+
// Factory for creating PostGraphile v5 instances
33+
export { createGraphileInstance } from './create-instance';

graphile/graphile-cache/tsconfig.esm.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
"extends": "./tsconfig.json",
33
"compilerOptions": {
44
"outDir": "dist/esm",
5-
"module": "ESNext"
5+
"module": "es2022",
6+
"moduleResolution": "bundler",
7+
"declaration": false
68
}
79
}

graphile/graphile-cache/tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
"extends": "../../tsconfig.json",
33
"compilerOptions": {
44
"outDir": "dist",
5-
"rootDir": "src"
5+
"rootDir": "src",
6+
"module": "nodenext",
7+
"moduleResolution": "nodenext"
68
},
79
"include": ["src/**/*"]
810
}

graphql/explorer/package.json

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
"scripts": {
2626
"clean": "makage clean",
2727
"prepack": "npm run build",
28-
"build": "echo 'SKIPPED: graphql-explorer disabled during v5 migration'",
29-
"build:dev": "echo 'SKIPPED: graphql-explorer disabled during v5 migration'",
28+
"build": "makage build",
29+
"build:dev": "makage build --dev",
3030
"dev": "ts-node src/run.ts",
3131
"dev:watch": "nodemon --watch src --ext ts --exec ts-node src/run.ts",
3232
"lint": "eslint . --fix",
@@ -36,24 +36,20 @@
3636
"dependencies": {
3737
"@constructive-io/graphql-env": "workspace:^",
3838
"@constructive-io/graphql-types": "workspace:^",
39-
"@constructive-io/s3-streamer": "workspace:^",
40-
"@constructive-io/upload-names": "workspace:^",
4139
"@constructive-io/url-domains": "workspace:^",
4240
"@pgpmjs/server-utils": "workspace:^",
43-
"@pgpmjs/types": "workspace:^",
4441
"express": "^5.2.1",
45-
"graphile-build": "^4.14.1",
42+
"grafserv": "^1.0.0-rc.4",
4643
"graphile-cache": "workspace:^",
44+
"graphile-config": "1.0.0-rc.3",
4745
"graphile-settings": "workspace:^",
48-
"graphql": "15.10.1",
49-
"graphql-upload": "^13.0.0",
46+
"graphql": "^16.9.0",
5047
"pg-cache": "workspace:^",
5148
"pg-env": "workspace:^",
52-
"postgraphile": "^4.14.1"
49+
"postgraphile": "^5.0.0-rc.4"
5350
},
5451
"devDependencies": {
5552
"@types/express": "^5.0.6",
56-
"@types/graphql-upload": "^8.0.12",
5753
"makage": "^0.1.10",
5854
"nodemon": "^3.1.10",
5955
"ts-node": "^10.9.2"

graphql/explorer/src/server.ts

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,59 @@ import type { ConstructiveOptions } from '@constructive-io/graphql-types';
33
import { cors, healthz, poweredBy } from '@pgpmjs/server-utils';
44
import { middleware as parseDomains } from '@constructive-io/url-domains';
55
import express, { Express, NextFunction, Request, Response } from 'express';
6-
import { GraphileCache, graphileCache } from 'graphile-cache';
7-
import graphqlUpload from 'graphql-upload';
8-
// Scalar
9-
import { getPgPool } from 'pg-cache';
6+
import { createGraphileInstance, graphileCache, GraphileCacheEntry } from 'graphile-cache';
7+
import { makePgService } from 'graphile-settings';
8+
import type { GraphileConfig } from 'graphile-config';
9+
import { buildConnectionString, getPgPool } from 'pg-cache';
1010
import { getPgEnvOptions } from 'pg-env';
11-
import { postgraphile } from 'postgraphile';
1211

1312
import { printDatabases, printSchemas } from './render';
14-
import { getGraphileSettings } from './settings';
13+
import { getGraphilePreset } from './settings';
1514

1615
export const GraphQLExplorer = (rawOpts: ConstructiveOptions = {}): Express => {
1716
const opts = getEnvOptions(rawOpts);
1817

1918
const { pg, server } = opts;
2019

21-
const getGraphileInstanceObj = (
20+
const getGraphileInstanceObj = async (
2221
dbname: string,
2322
schemaname: string
24-
): GraphileCache => {
23+
): Promise<GraphileCacheEntry> => {
2524
const key = `${dbname}.${schemaname}`;
2625

27-
if (graphileCache.has(key)) {
28-
return graphileCache.get(key);
26+
const cached = graphileCache.get(key);
27+
if (cached) {
28+
return cached;
2929
}
3030

31-
const settings = {
32-
...getGraphileSettings({
33-
...opts,
34-
graphile: { schema: schemaname },
35-
}),
36-
graphqlRoute: '/graphql',
37-
graphiqlRoute: '/graphiql',
38-
};
39-
40-
const pgPool = getPgPool(
41-
getPgEnvOptions({
42-
...opts.pg,
43-
database: dbname,
44-
})
31+
const pgConfig = getPgEnvOptions({
32+
...pg,
33+
database: dbname,
34+
});
35+
const connectionString = buildConnectionString(
36+
pgConfig.user,
37+
pgConfig.password,
38+
pgConfig.host,
39+
pgConfig.port,
40+
pgConfig.database
4541
);
4642

47-
const handler = postgraphile(pgPool, schemaname, settings);
48-
49-
const obj = {
50-
pgPool,
51-
pgPoolKey: dbname,
52-
handler,
43+
const basePreset = getGraphilePreset(opts);
44+
const preset: GraphileConfig.Preset = {
45+
...basePreset,
46+
pgServices: [
47+
makePgService({ connectionString, schemas: [schemaname] }),
48+
],
49+
grafserv: {
50+
graphqlPath: '/graphql',
51+
graphiqlPath: '/graphiql',
52+
graphiql: true,
53+
},
5354
};
5455

55-
graphileCache.set(key, obj);
56-
return obj;
56+
const instance = await createGraphileInstance({ preset, cacheKey: key });
57+
graphileCache.set(key, instance);
58+
return instance;
5759
};
5860

5961
const app = express();
@@ -62,7 +64,6 @@ export const GraphQLExplorer = (rawOpts: ConstructiveOptions = {}): Express => {
6264
cors(app, server.origin);
6365
app.use(parseDomains());
6466
app.use(poweredBy('constructive'));
65-
app.use(graphqlUpload.graphqlUploadExpress());
6667

6768
app.use(async (req: Request, res: Response, next: NextFunction) => {
6869
if (req.urlDomains?.subdomains.length === 1) {
@@ -132,8 +133,8 @@ export const GraphQLExplorer = (rawOpts: ConstructiveOptions = {}): Express => {
132133
if (req.urlDomains?.subdomains.length === 2) {
133134
const [schemaName, dbName] = req.urlDomains.subdomains;
134135
try {
135-
const { handler } = getGraphileInstanceObj(dbName, schemaName);
136-
handler(req, res, next);
136+
const instance = await getGraphileInstanceObj(dbName, schemaName);
137+
instance.handler(req, res, next);
137138
return;
138139
} catch (e: any) {
139140
res.status(500).send(e.message);

graphql/explorer/tsconfig.esm.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"compilerOptions": {
44
"outDir": "dist/esm",
55
"module": "es2022",
6+
"moduleResolution": "bundler",
67
"rootDir": "src/",
78
"declaration": false
89
}

graphql/explorer/tsconfig.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
"extends": "../../tsconfig.json",
33
"compilerOptions": {
44
"outDir": "dist",
5-
"rootDir": "src/"
5+
"rootDir": "src/",
6+
"module": "nodenext",
7+
"moduleResolution": "nodenext"
68
},
79
"include": ["src/**/*.ts"],
8-
"exclude": ["dist", "node_modules", "**/*.spec.*", "**/*.test.*"]
10+
"exclude": ["dist", "node_modules", "**/*.spec.*", "**/*.test.*", "src/resolvers/**/*"]
911
}

0 commit comments

Comments
 (0)