@constructive-io/graphql-server 4.28.0 → 4.29.1

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.
@@ -206,7 +206,8 @@ const DATABASE_SETTINGS_SQL = `
206
206
  COALESCE(aps.enable_many_to_many, ds.enable_many_to_many) AS resolved_enable_many_to_many,
207
207
  COALESCE(aps.enable_connection_filter, ds.enable_connection_filter) AS resolved_enable_connection_filter,
208
208
  COALESCE(aps.enable_ltree, ds.enable_ltree) AS resolved_enable_ltree,
209
- COALESCE(aps.enable_llm, ds.enable_llm) AS resolved_enable_llm
209
+ COALESCE(aps.enable_llm, ds.enable_llm) AS resolved_enable_llm,
210
+ COALESCE(aps.enable_realtime, ds.enable_realtime) AS resolved_enable_realtime
210
211
  FROM services_public.database_settings ds
211
212
  LEFT JOIN services_public.api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
212
213
  WHERE ds.database_id = $1
@@ -267,6 +268,11 @@ const toRlsModule = (row) => {
267
268
  const toRlsModuleFromSettings = (row) => {
268
269
  if (!row)
269
270
  return undefined;
271
+ // If metaschema_public.function rows are missing (e.g. trigger was skipped
272
+ // during migration), the LEFT JOINs resolve NULL. Return undefined so the
273
+ // caller falls back to the legacy api_modules lookup.
274
+ if (!row.authenticate || !row.authenticate_schema)
275
+ return undefined;
270
276
  return {
271
277
  authenticate: row.authenticate,
272
278
  authenticateStrict: row.authenticate_strict,
@@ -347,7 +353,8 @@ const queryRlsSettings = async (pool, databaseId) => {
347
353
  const result = await pool.query(RLS_SETTINGS_SQL, [databaseId]);
348
354
  return toRlsModuleFromSettings(result.rows[0] ?? null);
349
355
  }
350
- catch {
356
+ catch (e) {
357
+ log.warn(`[rls-settings] Failed to load RLS settings: ${e.message}`);
351
358
  return undefined;
352
359
  }
353
360
  };
@@ -372,7 +379,8 @@ const queryCorsSettings = async (pool, databaseId, apiId) => {
372
379
  const dbDefault = await pool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
373
380
  return dbDefault.rows[0]?.allowed_origins;
374
381
  }
375
- catch {
382
+ catch (e) {
383
+ log.warn(`[cors-settings] Failed to load CORS settings: ${e.message}`);
376
384
  return undefined;
377
385
  }
378
386
  };
@@ -419,7 +427,8 @@ const queryPubkeySettings = async (pool, databaseId) => {
419
427
  const result = await pool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
420
428
  return toPubkeyChallengeSettings(result.rows[0] ?? null);
421
429
  }
422
- catch {
430
+ catch (e) {
431
+ log.warn(`[pubkey-settings] Failed to load pubkey challenge settings: ${e.message}`);
423
432
  return undefined;
424
433
  }
425
434
  };
@@ -458,7 +467,8 @@ const queryWebauthnSettings = async (pool, databaseId) => {
458
467
  const result = await pool.query(WEBAUTHN_SETTINGS_SQL, [databaseId]);
459
468
  return toWebauthnSettings(result.rows[0] ?? null);
460
469
  }
461
- catch {
470
+ catch (e) {
471
+ log.warn(`[webauthn-settings] Failed to load webauthn settings: ${e.message}`);
462
472
  return undefined;
463
473
  }
464
474
  };
@@ -476,6 +486,7 @@ const toDatabaseSettings = (row) => {
476
486
  enableConnectionFilter: row.resolved_enable_connection_filter,
477
487
  enableLtree: row.resolved_enable_ltree,
478
488
  enableLlm: row.resolved_enable_llm,
489
+ enableRealtime: row.resolved_enable_realtime,
479
490
  };
480
491
  };
481
492
  const queryDatabaseSettings = async (pool, databaseId, apiId) => {
@@ -483,7 +494,8 @@ const queryDatabaseSettings = async (pool, databaseId, apiId) => {
483
494
  const result = await pool.query(DATABASE_SETTINGS_SQL, [databaseId, apiId ?? null]);
484
495
  return toDatabaseSettings(result.rows[0] ?? null);
485
496
  }
486
- catch {
497
+ catch (e) {
498
+ log.warn(`[database-settings] Failed to load database settings: ${e.message}`);
487
499
  return undefined;
488
500
  }
489
501
  };
@@ -324,7 +324,11 @@ export const graphile = (opts) => {
324
324
  cacheKey: key,
325
325
  serviceKey: key,
326
326
  databaseId: api.databaseId ?? null,
327
- }, () => createGraphileInstance({ preset, cacheKey: key }), { enabled: observabilityEnabled });
327
+ }, () => createGraphileInstance({
328
+ preset,
329
+ cacheKey: key,
330
+ enableRealtime: api.databaseSettings?.enableRealtime,
331
+ }), { enabled: observabilityEnabled });
328
332
  creating.set(key, creationPromise);
329
333
  try {
330
334
  const instance = await creationPromise;
package/middleware/api.js CHANGED
@@ -212,7 +212,8 @@ const DATABASE_SETTINGS_SQL = `
212
212
  COALESCE(aps.enable_many_to_many, ds.enable_many_to_many) AS resolved_enable_many_to_many,
213
213
  COALESCE(aps.enable_connection_filter, ds.enable_connection_filter) AS resolved_enable_connection_filter,
214
214
  COALESCE(aps.enable_ltree, ds.enable_ltree) AS resolved_enable_ltree,
215
- COALESCE(aps.enable_llm, ds.enable_llm) AS resolved_enable_llm
215
+ COALESCE(aps.enable_llm, ds.enable_llm) AS resolved_enable_llm,
216
+ COALESCE(aps.enable_realtime, ds.enable_realtime) AS resolved_enable_realtime
216
217
  FROM services_public.database_settings ds
217
218
  LEFT JOIN services_public.api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
218
219
  WHERE ds.database_id = $1
@@ -275,6 +276,11 @@ const toRlsModule = (row) => {
275
276
  const toRlsModuleFromSettings = (row) => {
276
277
  if (!row)
277
278
  return undefined;
279
+ // If metaschema_public.function rows are missing (e.g. trigger was skipped
280
+ // during migration), the LEFT JOINs resolve NULL. Return undefined so the
281
+ // caller falls back to the legacy api_modules lookup.
282
+ if (!row.authenticate || !row.authenticate_schema)
283
+ return undefined;
278
284
  return {
279
285
  authenticate: row.authenticate,
280
286
  authenticateStrict: row.authenticate_strict,
@@ -355,7 +361,8 @@ const queryRlsSettings = async (pool, databaseId) => {
355
361
  const result = await pool.query(RLS_SETTINGS_SQL, [databaseId]);
356
362
  return toRlsModuleFromSettings(result.rows[0] ?? null);
357
363
  }
358
- catch {
364
+ catch (e) {
365
+ log.warn(`[rls-settings] Failed to load RLS settings: ${e.message}`);
359
366
  return undefined;
360
367
  }
361
368
  };
@@ -380,7 +387,8 @@ const queryCorsSettings = async (pool, databaseId, apiId) => {
380
387
  const dbDefault = await pool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
381
388
  return dbDefault.rows[0]?.allowed_origins;
382
389
  }
383
- catch {
390
+ catch (e) {
391
+ log.warn(`[cors-settings] Failed to load CORS settings: ${e.message}`);
384
392
  return undefined;
385
393
  }
386
394
  };
@@ -427,7 +435,8 @@ const queryPubkeySettings = async (pool, databaseId) => {
427
435
  const result = await pool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
428
436
  return toPubkeyChallengeSettings(result.rows[0] ?? null);
429
437
  }
430
- catch {
438
+ catch (e) {
439
+ log.warn(`[pubkey-settings] Failed to load pubkey challenge settings: ${e.message}`);
431
440
  return undefined;
432
441
  }
433
442
  };
@@ -466,7 +475,8 @@ const queryWebauthnSettings = async (pool, databaseId) => {
466
475
  const result = await pool.query(WEBAUTHN_SETTINGS_SQL, [databaseId]);
467
476
  return toWebauthnSettings(result.rows[0] ?? null);
468
477
  }
469
- catch {
478
+ catch (e) {
479
+ log.warn(`[webauthn-settings] Failed to load webauthn settings: ${e.message}`);
470
480
  return undefined;
471
481
  }
472
482
  };
@@ -484,6 +494,7 @@ const toDatabaseSettings = (row) => {
484
494
  enableConnectionFilter: row.resolved_enable_connection_filter,
485
495
  enableLtree: row.resolved_enable_ltree,
486
496
  enableLlm: row.resolved_enable_llm,
497
+ enableRealtime: row.resolved_enable_realtime,
487
498
  };
488
499
  };
489
500
  const queryDatabaseSettings = async (pool, databaseId, apiId) => {
@@ -491,7 +502,8 @@ const queryDatabaseSettings = async (pool, databaseId, apiId) => {
491
502
  const result = await pool.query(DATABASE_SETTINGS_SQL, [databaseId, apiId ?? null]);
492
503
  return toDatabaseSettings(result.rows[0] ?? null);
493
504
  }
494
- catch {
505
+ catch (e) {
506
+ log.warn(`[database-settings] Failed to load database settings: ${e.message}`);
495
507
  return undefined;
496
508
  }
497
509
  };
@@ -333,7 +333,11 @@ const graphile = (opts) => {
333
333
  cacheKey: key,
334
334
  serviceKey: key,
335
335
  databaseId: api.databaseId ?? null,
336
- }, () => (0, graphile_cache_1.createGraphileInstance)({ preset, cacheKey: key }), { enabled: observabilityEnabled });
336
+ }, () => (0, graphile_cache_1.createGraphileInstance)({
337
+ preset,
338
+ cacheKey: key,
339
+ enableRealtime: api.databaseSettings?.enableRealtime,
340
+ }), { enabled: observabilityEnabled });
337
341
  creating.set(key, creationPromise);
338
342
  try {
339
343
  const instance = await creationPromise;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-server",
3
- "version": "4.28.0",
3
+ "version": "4.29.1",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "Constructive GraphQL Server",
6
6
  "main": "index.js",
@@ -41,38 +41,38 @@
41
41
  "backend"
42
42
  ],
43
43
  "dependencies": {
44
- "@constructive-io/graphql-env": "^3.10.0",
45
- "@constructive-io/graphql-types": "^3.9.0",
46
- "@constructive-io/s3-utils": "^2.16.0",
47
- "@constructive-io/upload-names": "^2.15.0",
48
- "@constructive-io/url-domains": "^2.15.0",
44
+ "@constructive-io/graphql-env": "^3.10.1",
45
+ "@constructive-io/graphql-types": "^3.9.1",
46
+ "@constructive-io/s3-utils": "^2.16.1",
47
+ "@constructive-io/upload-names": "^2.15.1",
48
+ "@constructive-io/url-domains": "^2.15.1",
49
49
  "@graphile-contrib/pg-many-to-many": "2.0.0-rc.2",
50
50
  "@graphile/simplify-inflection": "8.0.0",
51
- "@pgpmjs/env": "^2.22.0",
52
- "@pgpmjs/logger": "^2.10.0",
53
- "@pgpmjs/server-utils": "^3.10.0",
54
- "@pgpmjs/types": "^2.26.0",
51
+ "@pgpmjs/env": "^2.22.1",
52
+ "@pgpmjs/logger": "^2.10.1",
53
+ "@pgpmjs/server-utils": "^3.10.1",
54
+ "@pgpmjs/types": "^2.26.1",
55
55
  "@pgsql/quotes": "^17.1.0",
56
56
  "cors": "^2.8.6",
57
57
  "deepmerge": "^4.3.1",
58
58
  "express": "^5.2.1",
59
- "gql-ast": "^3.9.0",
59
+ "gql-ast": "^3.9.1",
60
60
  "grafast": "1.0.0",
61
61
  "grafserv": "1.0.0",
62
62
  "graphile-build": "5.0.0",
63
63
  "graphile-build-pg": "5.0.0",
64
- "graphile-cache": "^3.9.0",
64
+ "graphile-cache": "^3.10.1",
65
65
  "graphile-config": "1.0.0",
66
- "graphile-settings": "^4.32.0",
66
+ "graphile-settings": "^4.33.1",
67
67
  "graphile-utils": "5.0.0",
68
68
  "graphql": "16.13.0",
69
69
  "graphql-upload": "^13.0.0",
70
70
  "lru-cache": "^11.2.7",
71
71
  "multer": "^2.1.1",
72
72
  "pg": "^8.20.0",
73
- "pg-cache": "^3.9.0",
74
- "pg-env": "^1.13.0",
75
- "pg-query-context": "^2.14.0",
73
+ "pg-cache": "^3.9.1",
74
+ "pg-env": "^1.13.1",
75
+ "pg-query-context": "^2.14.1",
76
76
  "pg-sql2": "5.0.0",
77
77
  "postgraphile": "5.0.0",
78
78
  "request-ip": "^3.3.0"
@@ -85,10 +85,10 @@
85
85
  "@types/multer": "^2.1.0",
86
86
  "@types/pg": "^8.18.0",
87
87
  "@types/request-ip": "^0.0.41",
88
- "graphile-test": "4.14.0",
88
+ "graphile-test": "4.14.1",
89
89
  "makage": "^0.3.0",
90
90
  "nodemon": "^3.1.14",
91
91
  "ts-node": "^10.9.2"
92
92
  },
93
- "gitHead": "c665e2443ec98da61e9f372cf663cb9973afef4b"
93
+ "gitHead": "d43f1d7e38cc39a71b4f8d2cafb39f46df12e31a"
94
94
  }
package/types.d.ts CHANGED
@@ -28,6 +28,7 @@ export interface DatabaseSettings {
28
28
  enableConnectionFilter: boolean;
29
29
  enableLtree: boolean;
30
30
  enableLlm: boolean;
31
+ enableRealtime: boolean;
31
32
  }
32
33
  /**
33
34
  * Resolved pubkey challenge config from pubkey_settings typed table.