@constructive-io/graphql-server 4.0.1 → 4.1.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 +0 -4
- package/esm/index.js +0 -1
- package/index.d.ts +0 -1
- package/index.js +0 -1
- package/package.json +8 -12
- package/esm/schema.js +0 -99
- package/schema.d.ts +0 -12
- package/schema.js +0 -136
package/README.md
CHANGED
|
@@ -118,10 +118,6 @@ Configuration is merged from defaults, config files, and env vars via `@construc
|
|
|
118
118
|
|
|
119
119
|
Use `supertest` or your HTTP client of choice against `/graphql`. For RLS-aware tests, provide a `Bearer` token and ensure the API's auth function is available.
|
|
120
120
|
|
|
121
|
-
## Codegen
|
|
122
|
-
|
|
123
|
-
For local codegen test, use `PORT=5555 API_ENABLE_META=true PGDATABASE=launchql pnpm dev`
|
|
124
|
-
|
|
125
121
|
## Related Packages
|
|
126
122
|
|
|
127
123
|
- `@constructive-io/graphql-env` - env parsing + defaults for GraphQL
|
package/esm/index.js
CHANGED
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -16,7 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.flushService = exports.flush = exports.graphile = exports.cors = exports.createAuthenticateMiddleware = exports.getApiConfig = exports.getSubdomain = exports.createApiMiddleware = void 0;
|
|
18
18
|
__exportStar(require("./server"), exports);
|
|
19
|
-
__exportStar(require("./schema"), exports);
|
|
20
19
|
// Export options module - types, defaults, type guards, and utility functions
|
|
21
20
|
__exportStar(require("./options"), exports);
|
|
22
21
|
// Export middleware for use in testing packages
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-server",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Constructive GraphQL Server",
|
|
6
6
|
"main": "index.js",
|
|
@@ -29,10 +29,7 @@
|
|
|
29
29
|
"lint": "eslint . --fix",
|
|
30
30
|
"test": "jest --passWithNoTests",
|
|
31
31
|
"test:watch": "jest --watch",
|
|
32
|
-
"bucket:create": "ts-node src/scripts/create-bucket.ts"
|
|
33
|
-
"codegen:schema": "ts-node src/scripts/codegen-schema.ts",
|
|
34
|
-
"codegen:clean": "rimraf src/codegen/orm codegen/schema.graphql",
|
|
35
|
-
"codegen": "npm run codegen:clean && npm run codegen:schema && graphql-codegen generate-orm --schema codegen/schema.graphql --output src/codegen/orm"
|
|
32
|
+
"bucket:create": "ts-node src/scripts/create-bucket.ts"
|
|
36
33
|
},
|
|
37
34
|
"keywords": [
|
|
38
35
|
"server",
|
|
@@ -42,11 +39,11 @@
|
|
|
42
39
|
"backend"
|
|
43
40
|
],
|
|
44
41
|
"dependencies": {
|
|
45
|
-
"@constructive-io/graphql-env": "^3.
|
|
42
|
+
"@constructive-io/graphql-env": "^3.1.0",
|
|
46
43
|
"@constructive-io/graphql-types": "^3.0.0",
|
|
47
44
|
"@constructive-io/s3-utils": "^2.6.0",
|
|
48
|
-
"@constructive-io/upload-names": "^2.
|
|
49
|
-
"@constructive-io/url-domains": "^2.
|
|
45
|
+
"@constructive-io/upload-names": "^2.6.0",
|
|
46
|
+
"@constructive-io/url-domains": "^2.6.0",
|
|
50
47
|
"@graphile-contrib/pg-many-to-many": "2.0.0-rc.1",
|
|
51
48
|
"@graphile/simplify-inflection": "8.0.0-rc.3",
|
|
52
49
|
"@pgpmjs/logger": "^2.1.0",
|
|
@@ -62,7 +59,7 @@
|
|
|
62
59
|
"graphile-build-pg": "^5.0.0-rc.3",
|
|
63
60
|
"graphile-cache": "^3.0.0",
|
|
64
61
|
"graphile-config": "1.0.0-rc.3",
|
|
65
|
-
"graphile-settings": "^4.0
|
|
62
|
+
"graphile-settings": "^4.1.0",
|
|
66
63
|
"graphql": "^16.9.0",
|
|
67
64
|
"graphql-upload": "^13.0.0",
|
|
68
65
|
"lru-cache": "^11.2.4",
|
|
@@ -82,11 +79,10 @@
|
|
|
82
79
|
"@types/graphql-upload": "^8.0.12",
|
|
83
80
|
"@types/pg": "^8.16.0",
|
|
84
81
|
"@types/request-ip": "^0.0.41",
|
|
85
|
-
"graphile-test": "4.
|
|
82
|
+
"graphile-test": "4.1.0",
|
|
86
83
|
"makage": "^0.1.10",
|
|
87
84
|
"nodemon": "^3.1.10",
|
|
88
|
-
"rimraf": "^6.1.2",
|
|
89
85
|
"ts-node": "^10.9.2"
|
|
90
86
|
},
|
|
91
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "6dac0247c675de94b41038ac1e5095dc5df0c753"
|
|
92
88
|
}
|
package/esm/schema.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { printSchema, getIntrospectionQuery, buildClientSchema } from 'graphql';
|
|
2
|
-
import { ConstructivePreset, makePgService } from 'graphile-settings';
|
|
3
|
-
import { makeSchema } from 'graphile-build';
|
|
4
|
-
import { getPgPool } from 'pg-cache';
|
|
5
|
-
import * as http from 'node:http';
|
|
6
|
-
import * as https from 'node:https';
|
|
7
|
-
// Build GraphQL Schema SDL directly from Postgres using PostGraphile v5, without HTTP.
|
|
8
|
-
export async function buildSchemaSDL(opts) {
|
|
9
|
-
const database = opts.database ?? 'constructive';
|
|
10
|
-
const schemas = Array.isArray(opts.schemas) ? opts.schemas : [];
|
|
11
|
-
// Get pool config for connection string
|
|
12
|
-
const pool = getPgPool({ database });
|
|
13
|
-
const poolConfig = pool.options || {};
|
|
14
|
-
const connectionString = `postgres://${poolConfig.user || 'postgres'}:${poolConfig.password || ''}@${poolConfig.host || 'localhost'}:${poolConfig.port || 5432}/${database}`;
|
|
15
|
-
// Build v5 preset
|
|
16
|
-
const preset = {
|
|
17
|
-
extends: [
|
|
18
|
-
ConstructivePreset,
|
|
19
|
-
...(opts.graphile?.extends ?? []),
|
|
20
|
-
],
|
|
21
|
-
...(opts.graphile?.disablePlugins && { disablePlugins: opts.graphile.disablePlugins }),
|
|
22
|
-
...(opts.graphile?.plugins && { plugins: opts.graphile.plugins }),
|
|
23
|
-
...(opts.graphile?.schema && { schema: opts.graphile.schema }),
|
|
24
|
-
pgServices: [
|
|
25
|
-
makePgService({
|
|
26
|
-
connectionString,
|
|
27
|
-
schemas,
|
|
28
|
-
}),
|
|
29
|
-
],
|
|
30
|
-
};
|
|
31
|
-
const { schema } = await makeSchema(preset);
|
|
32
|
-
return printSchema(schema);
|
|
33
|
-
}
|
|
34
|
-
// Fetch GraphQL Schema SDL from a running GraphQL endpoint via introspection.
|
|
35
|
-
// This centralizes GraphQL client usage in the server package to avoid duplicating deps in the CLI.
|
|
36
|
-
export async function fetchEndpointSchemaSDL(endpoint, opts) {
|
|
37
|
-
const url = new URL(endpoint);
|
|
38
|
-
const requestUrl = url;
|
|
39
|
-
const introspectionQuery = getIntrospectionQuery({ descriptions: true });
|
|
40
|
-
const postData = JSON.stringify({
|
|
41
|
-
query: introspectionQuery,
|
|
42
|
-
variables: null,
|
|
43
|
-
operationName: 'IntrospectionQuery',
|
|
44
|
-
});
|
|
45
|
-
const headers = {
|
|
46
|
-
'Content-Type': 'application/json',
|
|
47
|
-
'Content-Length': String(Buffer.byteLength(postData)),
|
|
48
|
-
};
|
|
49
|
-
if (opts?.headerHost) {
|
|
50
|
-
headers['Host'] = opts.headerHost;
|
|
51
|
-
}
|
|
52
|
-
if (opts?.auth) {
|
|
53
|
-
headers['Authorization'] = opts.auth;
|
|
54
|
-
}
|
|
55
|
-
if (opts?.headers) {
|
|
56
|
-
for (const [key, value] of Object.entries(opts.headers)) {
|
|
57
|
-
headers[key] = value;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const isHttps = requestUrl.protocol === 'https:';
|
|
61
|
-
const lib = isHttps ? https : http;
|
|
62
|
-
const responseData = await new Promise((resolve, reject) => {
|
|
63
|
-
const req = lib.request({
|
|
64
|
-
hostname: requestUrl.hostname,
|
|
65
|
-
port: (requestUrl.port ? Number(requestUrl.port) : (isHttps ? 443 : 80)),
|
|
66
|
-
path: requestUrl.pathname,
|
|
67
|
-
method: 'POST',
|
|
68
|
-
headers,
|
|
69
|
-
}, (res) => {
|
|
70
|
-
let data = '';
|
|
71
|
-
res.on('data', (chunk) => { data += chunk; });
|
|
72
|
-
res.on('end', () => {
|
|
73
|
-
if (res.statusCode && res.statusCode >= 400) {
|
|
74
|
-
reject(new Error(`HTTP ${res.statusCode} – ${data}`));
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
resolve(data);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
req.on('error', (err) => reject(err));
|
|
81
|
-
req.write(postData);
|
|
82
|
-
req.end();
|
|
83
|
-
});
|
|
84
|
-
let json;
|
|
85
|
-
try {
|
|
86
|
-
json = JSON.parse(responseData);
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
throw new Error(`Failed to parse response: ${responseData}`);
|
|
90
|
-
}
|
|
91
|
-
if (json.errors) {
|
|
92
|
-
throw new Error('Introspection returned errors');
|
|
93
|
-
}
|
|
94
|
-
if (!json.data) {
|
|
95
|
-
throw new Error('No data in introspection response');
|
|
96
|
-
}
|
|
97
|
-
const schema = buildClientSchema(json.data);
|
|
98
|
-
return printSchema(schema);
|
|
99
|
-
}
|
package/schema.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { GraphileConfig } from 'graphile-config';
|
|
2
|
-
export type BuildSchemaOptions = {
|
|
3
|
-
database?: string;
|
|
4
|
-
schemas: string[];
|
|
5
|
-
graphile?: Partial<GraphileConfig.Preset>;
|
|
6
|
-
};
|
|
7
|
-
export declare function buildSchemaSDL(opts: BuildSchemaOptions): Promise<string>;
|
|
8
|
-
export declare function fetchEndpointSchemaSDL(endpoint: string, opts?: {
|
|
9
|
-
headerHost?: string;
|
|
10
|
-
headers?: Record<string, string>;
|
|
11
|
-
auth?: string;
|
|
12
|
-
}): Promise<string>;
|
package/schema.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.buildSchemaSDL = buildSchemaSDL;
|
|
37
|
-
exports.fetchEndpointSchemaSDL = fetchEndpointSchemaSDL;
|
|
38
|
-
const graphql_1 = require("graphql");
|
|
39
|
-
const graphile_settings_1 = require("graphile-settings");
|
|
40
|
-
const graphile_build_1 = require("graphile-build");
|
|
41
|
-
const pg_cache_1 = require("pg-cache");
|
|
42
|
-
const http = __importStar(require("node:http"));
|
|
43
|
-
const https = __importStar(require("node:https"));
|
|
44
|
-
// Build GraphQL Schema SDL directly from Postgres using PostGraphile v5, without HTTP.
|
|
45
|
-
async function buildSchemaSDL(opts) {
|
|
46
|
-
const database = opts.database ?? 'constructive';
|
|
47
|
-
const schemas = Array.isArray(opts.schemas) ? opts.schemas : [];
|
|
48
|
-
// Get pool config for connection string
|
|
49
|
-
const pool = (0, pg_cache_1.getPgPool)({ database });
|
|
50
|
-
const poolConfig = pool.options || {};
|
|
51
|
-
const connectionString = `postgres://${poolConfig.user || 'postgres'}:${poolConfig.password || ''}@${poolConfig.host || 'localhost'}:${poolConfig.port || 5432}/${database}`;
|
|
52
|
-
// Build v5 preset
|
|
53
|
-
const preset = {
|
|
54
|
-
extends: [
|
|
55
|
-
graphile_settings_1.ConstructivePreset,
|
|
56
|
-
...(opts.graphile?.extends ?? []),
|
|
57
|
-
],
|
|
58
|
-
...(opts.graphile?.disablePlugins && { disablePlugins: opts.graphile.disablePlugins }),
|
|
59
|
-
...(opts.graphile?.plugins && { plugins: opts.graphile.plugins }),
|
|
60
|
-
...(opts.graphile?.schema && { schema: opts.graphile.schema }),
|
|
61
|
-
pgServices: [
|
|
62
|
-
(0, graphile_settings_1.makePgService)({
|
|
63
|
-
connectionString,
|
|
64
|
-
schemas,
|
|
65
|
-
}),
|
|
66
|
-
],
|
|
67
|
-
};
|
|
68
|
-
const { schema } = await (0, graphile_build_1.makeSchema)(preset);
|
|
69
|
-
return (0, graphql_1.printSchema)(schema);
|
|
70
|
-
}
|
|
71
|
-
// Fetch GraphQL Schema SDL from a running GraphQL endpoint via introspection.
|
|
72
|
-
// This centralizes GraphQL client usage in the server package to avoid duplicating deps in the CLI.
|
|
73
|
-
async function fetchEndpointSchemaSDL(endpoint, opts) {
|
|
74
|
-
const url = new URL(endpoint);
|
|
75
|
-
const requestUrl = url;
|
|
76
|
-
const introspectionQuery = (0, graphql_1.getIntrospectionQuery)({ descriptions: true });
|
|
77
|
-
const postData = JSON.stringify({
|
|
78
|
-
query: introspectionQuery,
|
|
79
|
-
variables: null,
|
|
80
|
-
operationName: 'IntrospectionQuery',
|
|
81
|
-
});
|
|
82
|
-
const headers = {
|
|
83
|
-
'Content-Type': 'application/json',
|
|
84
|
-
'Content-Length': String(Buffer.byteLength(postData)),
|
|
85
|
-
};
|
|
86
|
-
if (opts?.headerHost) {
|
|
87
|
-
headers['Host'] = opts.headerHost;
|
|
88
|
-
}
|
|
89
|
-
if (opts?.auth) {
|
|
90
|
-
headers['Authorization'] = opts.auth;
|
|
91
|
-
}
|
|
92
|
-
if (opts?.headers) {
|
|
93
|
-
for (const [key, value] of Object.entries(opts.headers)) {
|
|
94
|
-
headers[key] = value;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const isHttps = requestUrl.protocol === 'https:';
|
|
98
|
-
const lib = isHttps ? https : http;
|
|
99
|
-
const responseData = await new Promise((resolve, reject) => {
|
|
100
|
-
const req = lib.request({
|
|
101
|
-
hostname: requestUrl.hostname,
|
|
102
|
-
port: (requestUrl.port ? Number(requestUrl.port) : (isHttps ? 443 : 80)),
|
|
103
|
-
path: requestUrl.pathname,
|
|
104
|
-
method: 'POST',
|
|
105
|
-
headers,
|
|
106
|
-
}, (res) => {
|
|
107
|
-
let data = '';
|
|
108
|
-
res.on('data', (chunk) => { data += chunk; });
|
|
109
|
-
res.on('end', () => {
|
|
110
|
-
if (res.statusCode && res.statusCode >= 400) {
|
|
111
|
-
reject(new Error(`HTTP ${res.statusCode} – ${data}`));
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
resolve(data);
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
req.on('error', (err) => reject(err));
|
|
118
|
-
req.write(postData);
|
|
119
|
-
req.end();
|
|
120
|
-
});
|
|
121
|
-
let json;
|
|
122
|
-
try {
|
|
123
|
-
json = JSON.parse(responseData);
|
|
124
|
-
}
|
|
125
|
-
catch (e) {
|
|
126
|
-
throw new Error(`Failed to parse response: ${responseData}`);
|
|
127
|
-
}
|
|
128
|
-
if (json.errors) {
|
|
129
|
-
throw new Error('Introspection returned errors');
|
|
130
|
-
}
|
|
131
|
-
if (!json.data) {
|
|
132
|
-
throw new Error('No data in introspection response');
|
|
133
|
-
}
|
|
134
|
-
const schema = (0, graphql_1.buildClientSchema)(json.data);
|
|
135
|
-
return (0, graphql_1.printSchema)(schema);
|
|
136
|
-
}
|