@constructive-io/graphql-server 2.10.5

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.
Files changed (54) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +89 -0
  3. package/errors/404-message.d.ts +2 -0
  4. package/errors/404-message.js +232 -0
  5. package/errors/404.d.ts +2 -0
  6. package/errors/404.js +218 -0
  7. package/errors/50x.d.ts +2 -0
  8. package/errors/50x.js +216 -0
  9. package/esm/errors/404-message.js +230 -0
  10. package/esm/errors/404.js +216 -0
  11. package/esm/errors/50x.js +214 -0
  12. package/esm/index.js +2 -0
  13. package/esm/middleware/api.js +337 -0
  14. package/esm/middleware/auth.js +68 -0
  15. package/esm/middleware/cors.js +63 -0
  16. package/esm/middleware/flush.js +49 -0
  17. package/esm/middleware/gql.js +125 -0
  18. package/esm/middleware/graphile.js +84 -0
  19. package/esm/middleware/types.js +1 -0
  20. package/esm/plugins/PublicKeySignature.js +114 -0
  21. package/esm/run.js +8 -0
  22. package/esm/schema.js +86 -0
  23. package/esm/scripts/create-bucket.js +32 -0
  24. package/esm/server.js +95 -0
  25. package/esm/types.js +1 -0
  26. package/index.d.ts +2 -0
  27. package/index.js +18 -0
  28. package/middleware/api.d.ts +6 -0
  29. package/middleware/api.js +346 -0
  30. package/middleware/auth.d.ts +4 -0
  31. package/middleware/auth.js +75 -0
  32. package/middleware/cors.d.ts +14 -0
  33. package/middleware/cors.js +70 -0
  34. package/middleware/flush.d.ts +5 -0
  35. package/middleware/flush.js +54 -0
  36. package/middleware/gql.d.ts +6 -0
  37. package/middleware/gql.js +131 -0
  38. package/middleware/graphile.d.ts +4 -0
  39. package/middleware/graphile.js +91 -0
  40. package/middleware/types.d.ts +33 -0
  41. package/middleware/types.js +2 -0
  42. package/package.json +88 -0
  43. package/plugins/PublicKeySignature.d.ts +11 -0
  44. package/plugins/PublicKeySignature.js +121 -0
  45. package/run.d.ts +2 -0
  46. package/run.js +10 -0
  47. package/schema.d.ts +12 -0
  48. package/schema.js +123 -0
  49. package/scripts/create-bucket.d.ts +1 -0
  50. package/scripts/create-bucket.js +34 -0
  51. package/server.d.ts +17 -0
  52. package/server.js +102 -0
  53. package/types.d.ts +85 -0
  54. package/types.js +2 -0
package/server.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import 'dotenv/config';
2
+ import { PgpmOptions } from '@pgpmjs/types';
3
+ import { Pool, PoolClient } from 'pg';
4
+ export declare const GraphQLServer: (rawOpts?: PgpmOptions) => void;
5
+ declare class Server {
6
+ private app;
7
+ private opts;
8
+ constructor(opts: PgpmOptions);
9
+ listen(): void;
10
+ flush(databaseId: string): Promise<void>;
11
+ getPool(): Pool;
12
+ addEventListener(): void;
13
+ listenForChanges(err: Error | null, client: PoolClient, release: () => void): void;
14
+ log(text: string): void;
15
+ error(text: string, err?: unknown): void;
16
+ }
17
+ export { Server };
package/server.js ADDED
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Server = exports.GraphQLServer = void 0;
7
+ require("dotenv/config");
8
+ const graphql_env_1 = require("@constructive-io/graphql-env");
9
+ const logger_1 = require("@pgpmjs/logger");
10
+ const server_utils_1 = require("@pgpmjs/server-utils");
11
+ const url_domains_1 = require("@constructive-io/url-domains");
12
+ const express_1 = __importDefault(require("express"));
13
+ // @ts-ignore
14
+ const graphql_upload_1 = __importDefault(require("graphql-upload"));
15
+ const pg_cache_1 = require("pg-cache");
16
+ const request_ip_1 = __importDefault(require("request-ip"));
17
+ const api_1 = require("./middleware/api");
18
+ const auth_1 = require("./middleware/auth");
19
+ const cors_1 = require("./middleware/cors");
20
+ const flush_1 = require("./middleware/flush");
21
+ const graphile_1 = require("./middleware/graphile");
22
+ const log = new logger_1.Logger('server');
23
+ const GraphQLServer = (rawOpts = {}) => {
24
+ const envOptions = (0, graphql_env_1.getEnvOptions)(rawOpts);
25
+ const app = new Server(envOptions);
26
+ app.addEventListener();
27
+ app.listen();
28
+ };
29
+ exports.GraphQLServer = GraphQLServer;
30
+ class Server {
31
+ app;
32
+ opts;
33
+ constructor(opts) {
34
+ this.opts = (0, graphql_env_1.getEnvOptions)(opts);
35
+ const app = (0, express_1.default)();
36
+ const api = (0, api_1.createApiMiddleware)(opts);
37
+ const authenticate = (0, auth_1.createAuthenticateMiddleware)(opts);
38
+ (0, server_utils_1.healthz)(app);
39
+ (0, server_utils_1.trustProxy)(app, opts.server.trustProxy);
40
+ // Warn if a global CORS override is set in production
41
+ const fallbackOrigin = opts.server?.origin?.trim();
42
+ if (fallbackOrigin && process.env.NODE_ENV === 'production') {
43
+ if (fallbackOrigin === '*') {
44
+ log.warn('CORS wildcard ("*") is enabled in production; this effectively disables CORS and is not recommended. Prefer per-API CORS via meta schema.');
45
+ }
46
+ else {
47
+ log.warn(`CORS override origin set to ${fallbackOrigin} in production. Prefer per-API CORS via meta schema.`);
48
+ }
49
+ }
50
+ app.use((0, server_utils_1.poweredBy)('constructive'));
51
+ app.use((0, cors_1.cors)(fallbackOrigin));
52
+ app.use(graphql_upload_1.default.graphqlUploadExpress());
53
+ app.use((0, url_domains_1.middleware)());
54
+ app.use(request_ip_1.default.mw());
55
+ app.use(api);
56
+ app.use(authenticate);
57
+ app.use((0, graphile_1.graphile)(opts));
58
+ app.use(flush_1.flush);
59
+ this.app = app;
60
+ }
61
+ listen() {
62
+ const { server } = this.opts;
63
+ this.app.listen(server?.port, server?.host, () => log.info(`listening at http://${server?.host}:${server?.port}`));
64
+ }
65
+ async flush(databaseId) {
66
+ await (0, flush_1.flushService)(this.opts, databaseId);
67
+ }
68
+ getPool() {
69
+ return (0, pg_cache_1.getPgPool)(this.opts.pg);
70
+ }
71
+ addEventListener() {
72
+ const pgPool = this.getPool();
73
+ pgPool.connect(this.listenForChanges.bind(this));
74
+ }
75
+ listenForChanges(err, client, release) {
76
+ if (err) {
77
+ this.error('Error connecting with notify listener', err);
78
+ setTimeout(() => this.addEventListener(), 5000);
79
+ return;
80
+ }
81
+ client.on('notification', ({ channel, payload }) => {
82
+ if (channel === 'schema:update' && payload) {
83
+ log.info('schema:update', payload);
84
+ this.flush(payload);
85
+ }
86
+ });
87
+ client.query('LISTEN "schema:update"');
88
+ client.on('error', (e) => {
89
+ this.error('Error with database notify listener', e);
90
+ release();
91
+ this.addEventListener();
92
+ });
93
+ this.log('connected and listening for changes...');
94
+ }
95
+ log(text) {
96
+ log.info(text);
97
+ }
98
+ error(text, err) {
99
+ log.error(text, err);
100
+ }
101
+ }
102
+ exports.Server = Server;
package/types.d.ts ADDED
@@ -0,0 +1,85 @@
1
+ export interface CorsModuleData {
2
+ urls: string[];
3
+ }
4
+ export interface PublicKeyChallengeData {
5
+ schema: string;
6
+ crypto_network: string;
7
+ sign_up_with_key: string;
8
+ sign_in_request_challenge: string;
9
+ sign_in_record_failure: string;
10
+ sign_in_with_challenge: string;
11
+ }
12
+ export interface GenericModuleData {
13
+ [key: string]: any;
14
+ }
15
+ export type ApiModule = {
16
+ name: 'cors';
17
+ data: CorsModuleData;
18
+ } | {
19
+ name: 'pubkey_challenge';
20
+ data: PublicKeyChallengeData;
21
+ } | {
22
+ name: string;
23
+ data?: GenericModuleData;
24
+ };
25
+ export interface RlsModule {
26
+ authenticate?: string;
27
+ authenticateStrict?: string;
28
+ privateSchema: {
29
+ schemaName: string;
30
+ };
31
+ }
32
+ export interface SchemaNode {
33
+ schemaName: string;
34
+ }
35
+ export interface SchemaNodes {
36
+ nodes: SchemaNode[];
37
+ }
38
+ export interface Domain {
39
+ subdomain?: string;
40
+ domain: string;
41
+ }
42
+ export interface DomainNodes {
43
+ nodes: Domain[];
44
+ }
45
+ export interface Site {
46
+ domains: DomainNodes;
47
+ }
48
+ export interface SiteNodes {
49
+ nodes: Site[];
50
+ }
51
+ export interface ApiModuleNodes {
52
+ nodes: ApiModule[];
53
+ }
54
+ export interface Database {
55
+ sites: SiteNodes;
56
+ }
57
+ export interface OldApiStructure {
58
+ dbname: string;
59
+ anonRole: string;
60
+ roleName: string;
61
+ schemaNames: SchemaNodes;
62
+ schemaNamesFromExt: SchemaNodes;
63
+ apiModules: ApiModuleNodes;
64
+ rlsModule?: RlsModule;
65
+ database?: Database;
66
+ databaseId?: string;
67
+ isPublic?: boolean;
68
+ }
69
+ export interface ServiceData {
70
+ api: OldApiStructure;
71
+ }
72
+ export interface Service {
73
+ data: ServiceData;
74
+ }
75
+ export interface ApiStructure {
76
+ dbname: string;
77
+ anonRole: string;
78
+ roleName: string;
79
+ schema: string[];
80
+ apiModules: ApiModule[];
81
+ rlsModule?: RlsModule;
82
+ domains?: string[];
83
+ databaseId?: string;
84
+ isPublic?: boolean;
85
+ }
package/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });