@constructive-io/graphql-server 2.11.5 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -23
- package/esm/middleware/api.js +16 -4
- package/esm/middleware/auth.js +11 -1
- package/esm/middleware/flush.js +1 -1
- package/esm/server.js +7 -1
- package/middleware/api.js +16 -4
- package/middleware/auth.js +11 -1
- package/middleware/flush.js +1 -1
- package/package.json +12 -12
- package/server.js +6 -0
package/README.md
CHANGED
|
@@ -33,13 +33,13 @@ import { GraphQLServer } from '@constructive-io/graphql-server';
|
|
|
33
33
|
GraphQLServer(
|
|
34
34
|
getEnvOptions({
|
|
35
35
|
pg: { database: 'constructive_db' },
|
|
36
|
-
server: { host: '0.0.0.0', port: 3000 }
|
|
36
|
+
server: { host: '0.0.0.0', port: 3000 },
|
|
37
37
|
})
|
|
38
38
|
);
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
> **Tip:** Set `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE` to control DB connectivity.
|
|
42
|
-
See [Configuration](#configuration) for the full list of supported env vars and defaults.
|
|
42
|
+
> See [Configuration](#configuration) for the full list of supported env vars and defaults.
|
|
43
43
|
|
|
44
44
|
### Local Development (this repo)
|
|
45
45
|
|
|
@@ -50,9 +50,9 @@ pnpm dev
|
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
This starts the server with env defaults from `@constructive-io/graphql-env`.
|
|
53
|
-
> **Tip:** Set `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE` to control DB connectivity.
|
|
54
|
-
See [Configuration](#configuration) for the full list of supported env vars and defaults.
|
|
55
53
|
|
|
54
|
+
> **Tip:** Set `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE` to control DB connectivity.
|
|
55
|
+
> See [Configuration](#configuration) for the full list of supported env vars and defaults.
|
|
56
56
|
|
|
57
57
|
## What it does
|
|
58
58
|
|
|
@@ -79,7 +79,7 @@ Runs an Express server that wires CORS, uploads, domain parsing, auth, and PostG
|
|
|
79
79
|
|
|
80
80
|
When `API_ENABLE_META=true` (default):
|
|
81
81
|
|
|
82
|
-
- The server resolves APIs from `
|
|
82
|
+
- The server resolves APIs from `services_public.domains` using the request host.
|
|
83
83
|
- Only APIs where `api.is_public` matches `API_IS_PUBLIC` are served.
|
|
84
84
|
- In private mode (`API_IS_PUBLIC=false`), you can override with headers:
|
|
85
85
|
- `X-Api-Name` + `X-Database-Id`
|
|
@@ -95,24 +95,24 @@ When `API_ENABLE_META=false`:
|
|
|
95
95
|
|
|
96
96
|
Configuration is merged from defaults, config files, and env vars via `@constructive-io/graphql-env`. See `graphql/env/README.md` for the full list and examples.
|
|
97
97
|
|
|
98
|
-
| Env var
|
|
99
|
-
|
|
|
100
|
-
| `PGHOST`
|
|
101
|
-
| `PGPORT`
|
|
102
|
-
| `PGUSER`
|
|
103
|
-
| `PGPASSWORD`
|
|
104
|
-
| `PGDATABASE`
|
|
105
|
-
| `GRAPHILE_SCHEMA`
|
|
106
|
-
| `FEATURES_SIMPLE_INFLECTION`
|
|
107
|
-
| `FEATURES_OPPOSITE_BASE_NAMES` | Enable opposite base names
|
|
108
|
-
| `FEATURES_POSTGIS`
|
|
109
|
-
| `API_ENABLE_META`
|
|
110
|
-
| `API_IS_PUBLIC`
|
|
111
|
-
| `API_EXPOSED_SCHEMAS`
|
|
112
|
-
| `API_META_SCHEMAS`
|
|
113
|
-
| `API_ANON_ROLE`
|
|
114
|
-
| `API_ROLE_NAME`
|
|
115
|
-
| `API_DEFAULT_DATABASE_ID`
|
|
98
|
+
| Env var | Purpose | Default |
|
|
99
|
+
| ------------------------------ | ------------------------------------- | ------------------------------------------------------------- |
|
|
100
|
+
| `PGHOST` | Postgres host | `localhost` |
|
|
101
|
+
| `PGPORT` | Postgres port | `5432` |
|
|
102
|
+
| `PGUSER` | Postgres user | `postgres` |
|
|
103
|
+
| `PGPASSWORD` | Postgres password | `password` |
|
|
104
|
+
| `PGDATABASE` | Postgres database | `postgres` |
|
|
105
|
+
| `GRAPHILE_SCHEMA` | Comma-separated schemas to expose | empty |
|
|
106
|
+
| `FEATURES_SIMPLE_INFLECTION` | Enable simple inflection | `true` |
|
|
107
|
+
| `FEATURES_OPPOSITE_BASE_NAMES` | Enable opposite base names | `true` |
|
|
108
|
+
| `FEATURES_POSTGIS` | Enable PostGIS support | `true` |
|
|
109
|
+
| `API_ENABLE_META` | Enable meta API routing | `true` |
|
|
110
|
+
| `API_IS_PUBLIC` | Serve public APIs only | `true` |
|
|
111
|
+
| `API_EXPOSED_SCHEMAS` | Schemas when meta routing is disabled | empty |
|
|
112
|
+
| `API_META_SCHEMAS` | Meta schemas to query | `services_public,metaschema_public,metaschema_modules_public` |
|
|
113
|
+
| `API_ANON_ROLE` | Anonymous role name | `administrator` |
|
|
114
|
+
| `API_ROLE_NAME` | Authenticated role name | `administrator` |
|
|
115
|
+
| `API_DEFAULT_DATABASE_ID` | Default database ID | `hard-coded` |
|
|
116
116
|
|
|
117
117
|
## Testing
|
|
118
118
|
|
package/esm/middleware/api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getNodeEnv } from '@constructive-io/graphql-env';
|
|
2
|
+
import { Logger } from '@pgpmjs/logger';
|
|
2
3
|
import { svcCache } from '@pgpmjs/server-utils';
|
|
3
4
|
import { getSchema, GraphileQuery } from 'graphile-query';
|
|
4
5
|
import { getGraphileSettings } from 'graphile-settings';
|
|
@@ -7,6 +8,8 @@ import errorPage50x from '../errors/50x';
|
|
|
7
8
|
import errorPage404Message from '../errors/404-message';
|
|
8
9
|
import { ApiByNameQuery, ApiQuery, ListOfAllDomainsOfDb } from './gql';
|
|
9
10
|
import './types'; // for Request type
|
|
11
|
+
const log = new Logger('api');
|
|
12
|
+
const isDev = () => getNodeEnv() === 'development';
|
|
10
13
|
const transformServiceToApi = (svc) => {
|
|
11
14
|
const api = svc.data.api;
|
|
12
15
|
const schemaNames = api.schemaNamesFromExt?.nodes?.map((n) => n.schemaName) || [];
|
|
@@ -92,6 +95,8 @@ export const createApiMiddleware = (opts) => {
|
|
|
92
95
|
const api = transformServiceToApi(svc);
|
|
93
96
|
req.api = api;
|
|
94
97
|
req.databaseId = api.databaseId;
|
|
98
|
+
if (isDev())
|
|
99
|
+
log.debug(`Resolved API: db=${api.dbname}, schemas=[${api.schema?.join(', ')}]`);
|
|
95
100
|
next();
|
|
96
101
|
}
|
|
97
102
|
catch (e) {
|
|
@@ -104,7 +109,7 @@ export const createApiMiddleware = (opts) => {
|
|
|
104
109
|
.send(errorPage404Message("The resource you're looking for does not exist."));
|
|
105
110
|
}
|
|
106
111
|
else {
|
|
107
|
-
|
|
112
|
+
log.error('API middleware error:', e);
|
|
108
113
|
res.status(500).send(errorPage50x);
|
|
109
114
|
}
|
|
110
115
|
}
|
|
@@ -162,7 +167,7 @@ const queryServiceByDomainAndSubdomain = async ({ opts, key, client, domain, sub
|
|
|
162
167
|
variables: { domain, subdomain },
|
|
163
168
|
});
|
|
164
169
|
if (result.errors?.length) {
|
|
165
|
-
|
|
170
|
+
log.error('GraphQL query errors:', result.errors);
|
|
166
171
|
return null;
|
|
167
172
|
}
|
|
168
173
|
const nodes = result?.data?.domains?.nodes;
|
|
@@ -184,7 +189,7 @@ const queryServiceByApiName = async ({ opts, key, client, databaseId, name, }) =
|
|
|
184
189
|
variables: { databaseId, name },
|
|
185
190
|
});
|
|
186
191
|
if (result.errors?.length) {
|
|
187
|
-
|
|
192
|
+
log.error('GraphQL query errors:', result.errors);
|
|
188
193
|
return null;
|
|
189
194
|
}
|
|
190
195
|
const data = result?.data;
|
|
@@ -229,14 +234,21 @@ export const getApiConfig = async (opts, req) => {
|
|
|
229
234
|
req.svc_key = key;
|
|
230
235
|
let svc;
|
|
231
236
|
if (svcCache.has(key)) {
|
|
237
|
+
if (isDev())
|
|
238
|
+
log.debug(`Cache HIT for key=${key}`);
|
|
232
239
|
svc = svcCache.get(key);
|
|
233
240
|
}
|
|
234
241
|
else {
|
|
242
|
+
if (isDev())
|
|
243
|
+
log.debug(`Cache MISS for key=${key}, looking up API`);
|
|
235
244
|
const apiOpts = opts.api || {};
|
|
236
245
|
const allSchemata = apiOpts.metaSchemas || [];
|
|
237
246
|
const validatedSchemata = await validateSchemata(rootPgPool, allSchemata);
|
|
238
247
|
if (validatedSchemata.length === 0) {
|
|
239
|
-
const
|
|
248
|
+
const apiOpts2 = opts.api || {};
|
|
249
|
+
const message = `No valid schemas found. Configured metaSchemas: [${(apiOpts2.metaSchemas || []).join(', ')}]`;
|
|
250
|
+
if (isDev())
|
|
251
|
+
log.debug(message);
|
|
240
252
|
const error = new Error(message);
|
|
241
253
|
error.code = 'NO_VALID_SCHEMAS';
|
|
242
254
|
throw error;
|
package/esm/middleware/auth.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { getNodeEnv } from '@constructive-io/graphql-env';
|
|
2
|
+
import { Logger } from '@pgpmjs/logger';
|
|
1
3
|
import { getPgPool } from 'pg-cache';
|
|
2
4
|
import pgQueryContext from 'pg-query-context';
|
|
3
5
|
import './types'; // for Request type
|
|
6
|
+
const log = new Logger('auth');
|
|
7
|
+
const isDev = () => getNodeEnv() === 'development';
|
|
4
8
|
export const createAuthenticateMiddleware = (opts) => {
|
|
5
9
|
return async (req, res, next) => {
|
|
6
10
|
const api = req.api;
|
|
@@ -13,8 +17,11 @@ export const createAuthenticateMiddleware = (opts) => {
|
|
|
13
17
|
database: api.dbname,
|
|
14
18
|
});
|
|
15
19
|
const rlsModule = api.rlsModule;
|
|
16
|
-
if (!rlsModule)
|
|
20
|
+
if (!rlsModule) {
|
|
21
|
+
if (isDev())
|
|
22
|
+
log.debug('No RLS module configured, skipping auth');
|
|
17
23
|
return next();
|
|
24
|
+
}
|
|
18
25
|
const authFn = opts.server.strictAuth
|
|
19
26
|
? rlsModule.authenticateStrict
|
|
20
27
|
: rlsModule.authenticate;
|
|
@@ -46,8 +53,11 @@ export const createAuthenticateMiddleware = (opts) => {
|
|
|
46
53
|
return;
|
|
47
54
|
}
|
|
48
55
|
token = result.rows[0];
|
|
56
|
+
if (isDev())
|
|
57
|
+
log.debug(`Auth success: role=${token.role}`);
|
|
49
58
|
}
|
|
50
59
|
catch (e) {
|
|
60
|
+
log.error('Auth error:', e.message);
|
|
51
61
|
res.status(200).json({
|
|
52
62
|
errors: [
|
|
53
63
|
{
|
package/esm/middleware/flush.js
CHANGED
package/esm/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getEnvOptions } from '@constructive-io/graphql-env';
|
|
1
|
+
import { getEnvOptions, getNodeEnv } from '@constructive-io/graphql-env';
|
|
2
2
|
import { Logger } from '@pgpmjs/logger';
|
|
3
3
|
import { healthz, poweredBy, trustProxy } from '@pgpmjs/server-utils';
|
|
4
4
|
import { middleware as parseDomains } from '@constructive-io/url-domains';
|
|
@@ -13,6 +13,7 @@ import { cors } from './middleware/cors';
|
|
|
13
13
|
import { flush, flushService } from './middleware/flush';
|
|
14
14
|
import { graphile } from './middleware/graphile';
|
|
15
15
|
const log = new Logger('server');
|
|
16
|
+
const isDev = () => getNodeEnv() === 'development';
|
|
16
17
|
export const GraphQLServer = (rawOpts = {}) => {
|
|
17
18
|
const envOptions = getEnvOptions(rawOpts);
|
|
18
19
|
const app = new Server(envOptions);
|
|
@@ -27,6 +28,11 @@ class Server {
|
|
|
27
28
|
const app = express();
|
|
28
29
|
const api = createApiMiddleware(opts);
|
|
29
30
|
const authenticate = createAuthenticateMiddleware(opts);
|
|
31
|
+
// Log startup config in dev mode
|
|
32
|
+
if (isDev()) {
|
|
33
|
+
log.debug(`Database: ${opts.pg?.database}@${opts.pg?.host}:${opts.pg?.port}`);
|
|
34
|
+
log.debug(`Meta schemas: ${opts.api?.metaSchemas?.join(', ') || 'default'}`);
|
|
35
|
+
}
|
|
30
36
|
healthz(app);
|
|
31
37
|
trustProxy(app, opts.server.trustProxy);
|
|
32
38
|
// Warn if a global CORS override is set in production
|
package/middleware/api.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getApiConfig = exports.createApiMiddleware = exports.getSubdomain = void 0;
|
|
7
7
|
const graphql_env_1 = require("@constructive-io/graphql-env");
|
|
8
|
+
const logger_1 = require("@pgpmjs/logger");
|
|
8
9
|
const server_utils_1 = require("@pgpmjs/server-utils");
|
|
9
10
|
const graphile_query_1 = require("graphile-query");
|
|
10
11
|
const graphile_settings_1 = require("graphile-settings");
|
|
@@ -13,6 +14,8 @@ const _50x_1 = __importDefault(require("../errors/50x"));
|
|
|
13
14
|
const _404_message_1 = __importDefault(require("../errors/404-message"));
|
|
14
15
|
const gql_1 = require("./gql");
|
|
15
16
|
require("./types"); // for Request type
|
|
17
|
+
const log = new logger_1.Logger('api');
|
|
18
|
+
const isDev = () => (0, graphql_env_1.getNodeEnv)() === 'development';
|
|
16
19
|
const transformServiceToApi = (svc) => {
|
|
17
20
|
const api = svc.data.api;
|
|
18
21
|
const schemaNames = api.schemaNamesFromExt?.nodes?.map((n) => n.schemaName) || [];
|
|
@@ -99,6 +102,8 @@ const createApiMiddleware = (opts) => {
|
|
|
99
102
|
const api = transformServiceToApi(svc);
|
|
100
103
|
req.api = api;
|
|
101
104
|
req.databaseId = api.databaseId;
|
|
105
|
+
if (isDev())
|
|
106
|
+
log.debug(`Resolved API: db=${api.dbname}, schemas=[${api.schema?.join(', ')}]`);
|
|
102
107
|
next();
|
|
103
108
|
}
|
|
104
109
|
catch (e) {
|
|
@@ -111,7 +116,7 @@ const createApiMiddleware = (opts) => {
|
|
|
111
116
|
.send((0, _404_message_1.default)("The resource you're looking for does not exist."));
|
|
112
117
|
}
|
|
113
118
|
else {
|
|
114
|
-
|
|
119
|
+
log.error('API middleware error:', e);
|
|
115
120
|
res.status(500).send(_50x_1.default);
|
|
116
121
|
}
|
|
117
122
|
}
|
|
@@ -170,7 +175,7 @@ const queryServiceByDomainAndSubdomain = async ({ opts, key, client, domain, sub
|
|
|
170
175
|
variables: { domain, subdomain },
|
|
171
176
|
});
|
|
172
177
|
if (result.errors?.length) {
|
|
173
|
-
|
|
178
|
+
log.error('GraphQL query errors:', result.errors);
|
|
174
179
|
return null;
|
|
175
180
|
}
|
|
176
181
|
const nodes = result?.data?.domains?.nodes;
|
|
@@ -192,7 +197,7 @@ const queryServiceByApiName = async ({ opts, key, client, databaseId, name, }) =
|
|
|
192
197
|
variables: { databaseId, name },
|
|
193
198
|
});
|
|
194
199
|
if (result.errors?.length) {
|
|
195
|
-
|
|
200
|
+
log.error('GraphQL query errors:', result.errors);
|
|
196
201
|
return null;
|
|
197
202
|
}
|
|
198
203
|
const data = result?.data;
|
|
@@ -237,14 +242,21 @@ const getApiConfig = async (opts, req) => {
|
|
|
237
242
|
req.svc_key = key;
|
|
238
243
|
let svc;
|
|
239
244
|
if (server_utils_1.svcCache.has(key)) {
|
|
245
|
+
if (isDev())
|
|
246
|
+
log.debug(`Cache HIT for key=${key}`);
|
|
240
247
|
svc = server_utils_1.svcCache.get(key);
|
|
241
248
|
}
|
|
242
249
|
else {
|
|
250
|
+
if (isDev())
|
|
251
|
+
log.debug(`Cache MISS for key=${key}, looking up API`);
|
|
243
252
|
const apiOpts = opts.api || {};
|
|
244
253
|
const allSchemata = apiOpts.metaSchemas || [];
|
|
245
254
|
const validatedSchemata = await validateSchemata(rootPgPool, allSchemata);
|
|
246
255
|
if (validatedSchemata.length === 0) {
|
|
247
|
-
const
|
|
256
|
+
const apiOpts2 = opts.api || {};
|
|
257
|
+
const message = `No valid schemas found. Configured metaSchemas: [${(apiOpts2.metaSchemas || []).join(', ')}]`;
|
|
258
|
+
if (isDev())
|
|
259
|
+
log.debug(message);
|
|
248
260
|
const error = new Error(message);
|
|
249
261
|
error.code = 'NO_VALID_SCHEMAS';
|
|
250
262
|
throw error;
|
package/middleware/auth.js
CHANGED
|
@@ -4,9 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createAuthenticateMiddleware = void 0;
|
|
7
|
+
const graphql_env_1 = require("@constructive-io/graphql-env");
|
|
8
|
+
const logger_1 = require("@pgpmjs/logger");
|
|
7
9
|
const pg_cache_1 = require("pg-cache");
|
|
8
10
|
const pg_query_context_1 = __importDefault(require("pg-query-context"));
|
|
9
11
|
require("./types"); // for Request type
|
|
12
|
+
const log = new logger_1.Logger('auth');
|
|
13
|
+
const isDev = () => (0, graphql_env_1.getNodeEnv)() === 'development';
|
|
10
14
|
const createAuthenticateMiddleware = (opts) => {
|
|
11
15
|
return async (req, res, next) => {
|
|
12
16
|
const api = req.api;
|
|
@@ -19,8 +23,11 @@ const createAuthenticateMiddleware = (opts) => {
|
|
|
19
23
|
database: api.dbname,
|
|
20
24
|
});
|
|
21
25
|
const rlsModule = api.rlsModule;
|
|
22
|
-
if (!rlsModule)
|
|
26
|
+
if (!rlsModule) {
|
|
27
|
+
if (isDev())
|
|
28
|
+
log.debug('No RLS module configured, skipping auth');
|
|
23
29
|
return next();
|
|
30
|
+
}
|
|
24
31
|
const authFn = opts.server.strictAuth
|
|
25
32
|
? rlsModule.authenticateStrict
|
|
26
33
|
: rlsModule.authenticate;
|
|
@@ -52,8 +59,11 @@ const createAuthenticateMiddleware = (opts) => {
|
|
|
52
59
|
return;
|
|
53
60
|
}
|
|
54
61
|
token = result.rows[0];
|
|
62
|
+
if (isDev())
|
|
63
|
+
log.debug(`Auth success: role=${token.role}`);
|
|
55
64
|
}
|
|
56
65
|
catch (e) {
|
|
66
|
+
log.error('Auth error:', e.message);
|
|
57
67
|
res.status(200).json({
|
|
58
68
|
errors: [
|
|
59
69
|
{
|
package/middleware/flush.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Constructive GraphQL Server",
|
|
6
6
|
"main": "index.js",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"backend"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@constructive-io/graphql-env": "^2.8.
|
|
43
|
-
"@constructive-io/graphql-types": "^2.12.
|
|
42
|
+
"@constructive-io/graphql-env": "^2.8.15",
|
|
43
|
+
"@constructive-io/graphql-types": "^2.12.11",
|
|
44
44
|
"@constructive-io/s3-utils": "^2.4.1",
|
|
45
45
|
"@constructive-io/upload-names": "^2.3.6",
|
|
46
46
|
"@constructive-io/url-domains": "^2.3.7",
|
|
@@ -52,15 +52,15 @@
|
|
|
52
52
|
"express": "^5.2.1",
|
|
53
53
|
"graphile-build": "^4.14.1",
|
|
54
54
|
"graphile-cache": "^1.6.14",
|
|
55
|
-
"graphile-i18n": "^0.
|
|
56
|
-
"graphile-meta-schema": "^0.
|
|
57
|
-
"graphile-plugin-connection-filter": "^2.
|
|
58
|
-
"graphile-plugin-connection-filter-postgis": "^1.
|
|
59
|
-
"graphile-plugin-fulltext-filter": "^2.
|
|
55
|
+
"graphile-i18n": "^0.3.0",
|
|
56
|
+
"graphile-meta-schema": "^0.4.0",
|
|
57
|
+
"graphile-plugin-connection-filter": "^2.5.0",
|
|
58
|
+
"graphile-plugin-connection-filter-postgis": "^1.2.0",
|
|
59
|
+
"graphile-plugin-fulltext-filter": "^2.2.0",
|
|
60
60
|
"graphile-query": "^2.4.7",
|
|
61
|
-
"graphile-search-plugin": "^0.
|
|
62
|
-
"graphile-settings": "^2.
|
|
63
|
-
"graphile-simple-inflector": "^0.
|
|
61
|
+
"graphile-search-plugin": "^0.3.0",
|
|
62
|
+
"graphile-settings": "^2.11.0",
|
|
63
|
+
"graphile-simple-inflector": "^0.3.0",
|
|
64
64
|
"graphile-utils": "^4.14.1",
|
|
65
65
|
"graphql": "15.10.1",
|
|
66
66
|
"graphql-tag": "2.12.6",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"nodemon": "^3.1.10",
|
|
84
84
|
"ts-node": "^10.9.2"
|
|
85
85
|
},
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "97528ad4eb2f60c16785ffb84af7b61c52cb5ad8"
|
|
87
87
|
}
|
package/server.js
CHANGED
|
@@ -19,6 +19,7 @@ const cors_1 = require("./middleware/cors");
|
|
|
19
19
|
const flush_1 = require("./middleware/flush");
|
|
20
20
|
const graphile_1 = require("./middleware/graphile");
|
|
21
21
|
const log = new logger_1.Logger('server');
|
|
22
|
+
const isDev = () => (0, graphql_env_1.getNodeEnv)() === 'development';
|
|
22
23
|
const GraphQLServer = (rawOpts = {}) => {
|
|
23
24
|
const envOptions = (0, graphql_env_1.getEnvOptions)(rawOpts);
|
|
24
25
|
const app = new Server(envOptions);
|
|
@@ -34,6 +35,11 @@ class Server {
|
|
|
34
35
|
const app = (0, express_1.default)();
|
|
35
36
|
const api = (0, api_1.createApiMiddleware)(opts);
|
|
36
37
|
const authenticate = (0, auth_1.createAuthenticateMiddleware)(opts);
|
|
38
|
+
// Log startup config in dev mode
|
|
39
|
+
if (isDev()) {
|
|
40
|
+
log.debug(`Database: ${opts.pg?.database}@${opts.pg?.host}:${opts.pg?.port}`);
|
|
41
|
+
log.debug(`Meta schemas: ${opts.api?.metaSchemas?.join(', ') || 'default'}`);
|
|
42
|
+
}
|
|
37
43
|
(0, server_utils_1.healthz)(app);
|
|
38
44
|
(0, server_utils_1.trustProxy)(app, opts.server.trustProxy);
|
|
39
45
|
// Warn if a global CORS override is set in production
|