@constructive-io/express-context 0.12.1 → 0.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/context.js CHANGED
@@ -64,9 +64,9 @@ function buildContext(req, opts = {}) {
64
64
  // Build loader context (if registry provided and databaseId known)
65
65
  let loaderCtx = null;
66
66
  if (opts.loaders && api.databaseId) {
67
- const servicesPool = (0, pg_cache_1.getPgPool)(opts.pg);
67
+ const routingPool = (0, pg_cache_1.getPgPool)(opts.pg);
68
68
  loaderCtx = {
69
- servicesPool,
69
+ routingPool,
70
70
  tenantPool,
71
71
  databaseId: api.databaseId,
72
72
  apiId: api.apiId,
package/esm/context.js CHANGED
@@ -60,9 +60,9 @@ export function buildContext(req, opts = {}) {
60
60
  // Build loader context (if registry provided and databaseId known)
61
61
  let loaderCtx = null;
62
62
  if (opts.loaders && api.databaseId) {
63
- const servicesPool = getPgPool(opts.pg);
63
+ const routingPool = getPgPool(opts.pg);
64
64
  loaderCtx = {
65
- servicesPool,
65
+ routingPool,
66
66
  tenantPool,
67
67
  databaseId: api.databaseId,
68
68
  apiId: api.apiId,
@@ -7,7 +7,7 @@
7
7
  * 2. Query the discovered <schema>.<table> in the tenant DB
8
8
  *
9
9
  * This is the pattern for any module whose config lives in the tenant
10
- * database rather than the services database.
10
+ * database rather than the routing database.
11
11
  */
12
12
  import { createModuleLoader } from './create-loader';
13
13
  // ─── SQL ────────────────────────────────────────────────────────────────────
@@ -56,7 +56,7 @@ export const authSettingsLoader = createModuleLoader({
56
56
  cookiePath: row.cookie_path,
57
57
  rememberMeDuration: row.remember_me_duration,
58
58
  enableCaptcha: row.enable_captcha,
59
- captchaSiteKey: row.captcha_site_key,
59
+ captchaSiteKey: row.captcha_site_key
60
60
  };
61
- },
61
+ }
62
62
  });
@@ -1,27 +1,27 @@
1
1
  /**
2
2
  * CORS Origins Loader
3
3
  *
4
- * Resolves allowed CORS origins for a database+API combination.
5
- * Checks per-API settings first, falls back to database-level default,
6
- * then to the legacy api_modules approach.
4
+ * Resolves allowed CORS origins for a database+API combination from the
5
+ * scoped routing plane. Checks per-API settings first, falls back to
6
+ * database-level default, then to the api_modules approach.
7
7
  */
8
8
  import { createModuleLoader } from './create-loader';
9
9
  // ─── SQL ────────────────────────────────────────────────────────────────────
10
10
  const CORS_SETTINGS_SQL = `
11
11
  SELECT allowed_origins
12
- FROM services_public.cors_settings
12
+ FROM constructive_routing_public.cors_settings
13
13
  WHERE database_id = $1 AND api_id = $2
14
14
  LIMIT 1
15
15
  `;
16
16
  const CORS_SETTINGS_DB_DEFAULT_SQL = `
17
17
  SELECT allowed_origins
18
- FROM services_public.cors_settings
18
+ FROM constructive_routing_public.cors_settings
19
19
  WHERE database_id = $1 AND api_id IS NULL
20
20
  LIMIT 1
21
21
  `;
22
22
  const CORS_MODULE_SQL = `
23
23
  SELECT data
24
- FROM services_public.api_modules
24
+ FROM constructive_routing_public.api_modules
25
25
  WHERE api_id = $1 AND name = 'cors'
26
26
  LIMIT 1
27
27
  `;
@@ -30,26 +30,26 @@ export const corsLoader = createModuleLoader({
30
30
  name: 'corsOrigins',
31
31
  ttlMs: 5 * 60_000,
32
32
  async resolve(ctx) {
33
- const { servicesPool, databaseId, apiId } = ctx;
33
+ const { routingPool, databaseId, apiId } = ctx;
34
34
  // Try per-API cors_settings first
35
35
  try {
36
36
  if (apiId) {
37
- const perApi = await servicesPool.query(CORS_SETTINGS_SQL, [databaseId, apiId]);
37
+ const perApi = await routingPool.query(CORS_SETTINGS_SQL, [databaseId, apiId]);
38
38
  if (perApi.rows[0])
39
39
  return perApi.rows[0].allowed_origins;
40
40
  }
41
- const dbDefault = await servicesPool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
41
+ const dbDefault = await routingPool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
42
42
  if (dbDefault.rows[0])
43
43
  return dbDefault.rows[0].allowed_origins;
44
44
  }
45
45
  catch {
46
46
  // Table may not exist yet
47
47
  }
48
- // Fall back to legacy api_modules
48
+ // Fall back to api_modules
49
49
  if (apiId) {
50
- const result = await servicesPool.query(CORS_MODULE_SQL, [apiId]);
50
+ const result = await routingPool.query(CORS_MODULE_SQL, [apiId]);
51
51
  return result.rows[0]?.data?.urls;
52
52
  }
53
53
  return undefined;
54
- },
54
+ }
55
55
  });
@@ -21,8 +21,8 @@ const DATABASE_SETTINGS_SQL = `
21
21
  COALESCE(aps.enable_realtime, ds.enable_realtime) AS resolved_enable_realtime,
22
22
  COALESCE(aps.enable_bulk, ds.enable_bulk) AS resolved_enable_bulk,
23
23
  COALESCE(aps.enable_i18n, ds.enable_i18n) AS resolved_enable_i18n
24
- FROM services_public.database_settings ds
25
- LEFT JOIN services_public.api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
24
+ FROM constructive_routing_public.database_settings ds
25
+ LEFT JOIN constructive_routing_public.api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
26
26
  WHERE ds.database_id = $1
27
27
  LIMIT 1
28
28
  `;
@@ -31,8 +31,8 @@ export const databaseSettingsLoader = createModuleLoader({
31
31
  name: 'databaseSettings',
32
32
  ttlMs: 5 * 60_000,
33
33
  async resolve(ctx) {
34
- const { servicesPool, databaseId, apiId } = ctx;
35
- const result = await servicesPool.query(DATABASE_SETTINGS_SQL, [databaseId, apiId ?? null]);
34
+ const { routingPool, databaseId, apiId } = ctx;
35
+ const result = await routingPool.query(DATABASE_SETTINGS_SQL, [databaseId, apiId ?? null]);
36
36
  const row = result.rows[0];
37
37
  if (!row)
38
38
  return undefined;
@@ -48,7 +48,7 @@ export const databaseSettingsLoader = createModuleLoader({
48
48
  enableLlm: row.resolved_enable_llm,
49
49
  enableRealtime: row.resolved_enable_realtime,
50
50
  enableBulk: row.resolved_enable_bulk,
51
- enableI18n: row.resolved_enable_i18n,
51
+ enableI18n: row.resolved_enable_i18n
52
52
  };
53
- },
53
+ }
54
54
  });
@@ -6,11 +6,11 @@
6
6
  * a LoaderRegistry and pass it to createContextMiddleware().
7
7
  *
8
8
  * Built-in loaders cover the standard Constructive modules:
9
- * - rlsModule (services_public.rls_settings)
10
- * - corsOrigins (services_public.cors_settings)
11
- * - databaseSettings(services_public.database_settings)
12
- * - pubkeyChallengeSettings (services_public.pubkey_settings)
13
- * - webauthnSettings(services_public.webauthn_settings)
9
+ * - rlsModule (constructive_routing_public.rls_settings)
10
+ * - corsOrigins (constructive_routing_public.cors_settings)
11
+ * - databaseSettings(constructive_routing_public.database_settings)
12
+ * - pubkeyChallengeSettings (constructive_routing_public.pubkey_settings)
13
+ * - webauthnSettings(constructive_routing_public.webauthn_settings)
14
14
  * - authSettings (metaschema_modules_public.sessions_module → tenant DB)
15
15
  *
16
16
  * To add a new per-db lookup, implement a ModuleLoader and register it:
@@ -28,32 +28,32 @@
28
28
  export { createModuleLoader } from './create-loader';
29
29
  export { createLoaderRegistry } from './registry';
30
30
  // Built-in loaders
31
- export { rlsLoader } from './rls';
32
- export { corsLoader } from './cors';
33
- export { databaseSettingsLoader } from './database-settings';
34
- export { pubkeyLoader } from './pubkey';
35
- export { webauthnLoader } from './webauthn';
31
+ export { agentChatLoader } from './agent-chat';
36
32
  export { authSettingsLoader } from './auth-settings';
37
33
  export { billingLoader } from './billing';
34
+ export { computeLoader } from './compute';
35
+ export { corsLoader } from './cors';
36
+ export { databaseSettingsLoader } from './database-settings';
38
37
  export { inferenceLogLoader } from './inference-log';
39
- export { agentChatLoader } from './agent-chat';
40
38
  export { llmLoader } from './llm';
41
- export { computeLoader } from './compute';
39
+ export { pubkeyLoader } from './pubkey';
40
+ export { rlsLoader } from './rls';
41
+ export { webauthnLoader } from './webauthn';
42
42
  /**
43
43
  * Convenience: create a registry pre-loaded with all built-in loaders.
44
44
  */
45
- import { createLoaderRegistry } from './registry';
46
- import { rlsLoader } from './rls';
47
- import { corsLoader } from './cors';
48
- import { databaseSettingsLoader } from './database-settings';
49
- import { pubkeyLoader } from './pubkey';
50
- import { webauthnLoader } from './webauthn';
45
+ import { agentChatLoader } from './agent-chat';
51
46
  import { authSettingsLoader } from './auth-settings';
52
47
  import { billingLoader } from './billing';
48
+ import { computeLoader } from './compute';
49
+ import { corsLoader } from './cors';
50
+ import { databaseSettingsLoader } from './database-settings';
53
51
  import { inferenceLogLoader } from './inference-log';
54
- import { agentChatLoader } from './agent-chat';
55
52
  import { llmLoader } from './llm';
56
- import { computeLoader } from './compute';
53
+ import { pubkeyLoader } from './pubkey';
54
+ import { createLoaderRegistry } from './registry';
55
+ import { rlsLoader } from './rls';
56
+ import { webauthnLoader } from './webauthn';
57
57
  export function createDefaultRegistry() {
58
58
  const registry = createLoaderRegistry();
59
59
  registry.register(rlsLoader);
@@ -2,8 +2,8 @@
2
2
  * Pubkey Challenge Settings Loader
3
3
  *
4
4
  * Resolves public-key challenge auth config (crypto network, sign-in/sign-up
5
- * function names). Tries the new pubkey_settings table first, falls back
6
- * to the legacy api_modules approach.
5
+ * function names) from the scoped routing plane. Tries the pubkey_settings
6
+ * table first, falls back to the api_modules approach.
7
7
  */
8
8
  import { createModuleLoader } from './create-loader';
9
9
  // ─── SQL ────────────────────────────────────────────────────────────────────
@@ -15,7 +15,7 @@ const PUBKEY_SETTINGS_SQL = `
15
15
  sign_in_req_fn.name AS sign_in_request_challenge,
16
16
  sign_in_fail_fn.name AS sign_in_record_failure,
17
17
  sign_in_fn.name AS sign_in_with_challenge
18
- FROM services_public.pubkey_settings ps
18
+ FROM constructive_routing_public.pubkey_settings ps
19
19
  LEFT JOIN metaschema_public.schema s ON ps.schema_id = s.id
20
20
  LEFT JOIN metaschema_public.function sign_up_fn ON ps.sign_up_with_key_function_id = sign_up_fn.id
21
21
  LEFT JOIN metaschema_public.function sign_in_req_fn ON ps.sign_in_request_challenge_function_id = sign_in_req_fn.id
@@ -26,7 +26,7 @@ const PUBKEY_SETTINGS_SQL = `
26
26
  `;
27
27
  const PUBKEY_MODULE_SQL = `
28
28
  SELECT data
29
- FROM services_public.api_modules
29
+ FROM constructive_routing_public.api_modules
30
30
  WHERE api_id = $1 AND name = 'pubkey_challenge'
31
31
  LIMIT 1
32
32
  `;
@@ -40,7 +40,7 @@ function fromRow(row) {
40
40
  signUpWithKey: row.sign_up_with_key,
41
41
  signInRequestChallenge: row.sign_in_request_challenge,
42
42
  signInRecordFailure: row.sign_in_record_failure,
43
- signInWithChallenge: row.sign_in_with_challenge,
43
+ signInWithChallenge: row.sign_in_with_challenge
44
44
  };
45
45
  }
46
46
  // ─── Loader ─────────────────────────────────────────────────────────────────
@@ -48,10 +48,10 @@ export const pubkeyLoader = createModuleLoader({
48
48
  name: 'pubkeyChallengeSettings',
49
49
  ttlMs: 5 * 60_000,
50
50
  async resolve(ctx) {
51
- const { servicesPool, databaseId, apiId } = ctx;
51
+ const { routingPool, databaseId, apiId } = ctx;
52
52
  // Try new pubkey_settings table first
53
53
  try {
54
- const result = await servicesPool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
54
+ const result = await routingPool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
55
55
  const resolved = fromRow(result.rows[0] ?? null);
56
56
  if (resolved)
57
57
  return resolved;
@@ -59,11 +59,11 @@ export const pubkeyLoader = createModuleLoader({
59
59
  catch {
60
60
  // Table may not exist yet
61
61
  }
62
- // Fall back to legacy api_modules
62
+ // Fall back to api_modules
63
63
  if (apiId) {
64
- const result = await servicesPool.query(PUBKEY_MODULE_SQL, [apiId]);
64
+ const result = await routingPool.query(PUBKEY_MODULE_SQL, [apiId]);
65
65
  return fromRow(result.rows[0]?.data ?? null);
66
66
  }
67
67
  return undefined;
68
- },
68
+ }
69
69
  });
@@ -2,8 +2,8 @@
2
2
  * RLS Module Loader
3
3
  *
4
4
  * Resolves RLS authentication function names and schema references for
5
- * a given database. Tries the new rls_settings table first, falls back
6
- * to the legacy api_modules approach.
5
+ * a given database from the scoped routing plane. Tries the rls_settings
6
+ * table first, falls back to the api_modules approach.
7
7
  */
8
8
  import { createModuleLoader } from './create-loader';
9
9
  // ─── SQL ────────────────────────────────────────────────────────────────────
@@ -17,7 +17,7 @@ const RLS_SETTINGS_SQL = `
17
17
  role_id_fn.name AS current_role_id,
18
18
  ua_fn.name AS current_user_agent,
19
19
  ip_fn.name AS current_ip_address
20
- FROM services_public.rls_settings rs
20
+ FROM constructive_routing_public.rls_settings rs
21
21
  LEFT JOIN metaschema_public.schema auth_schema ON rs.authenticate_schema_id = auth_schema.id
22
22
  LEFT JOIN metaschema_public.schema role_schema ON rs.role_schema_id = role_schema.id
23
23
  LEFT JOIN metaschema_public.function auth_fn ON rs.authenticate_function_id = auth_fn.id
@@ -31,7 +31,7 @@ const RLS_SETTINGS_SQL = `
31
31
  `;
32
32
  const RLS_MODULE_SQL = `
33
33
  SELECT data
34
- FROM services_public.api_modules
34
+ FROM constructive_routing_public.api_modules
35
35
  WHERE api_id = $1 AND name = 'rls_module'
36
36
  LIMIT 1
37
37
  `;
@@ -49,7 +49,7 @@ function fromSettings(row) {
49
49
  currentRole: row.current_role,
50
50
  currentRoleId: row.current_role_id,
51
51
  currentIpAddress: row.current_ip_address,
52
- currentUserAgent: row.current_user_agent,
52
+ currentUserAgent: row.current_user_agent
53
53
  };
54
54
  }
55
55
  function fromModule(row) {
@@ -64,7 +64,7 @@ function fromModule(row) {
64
64
  currentRole: d.current_role,
65
65
  currentRoleId: d.current_role_id,
66
66
  currentIpAddress: d.current_ip_address,
67
- currentUserAgent: d.current_user_agent,
67
+ currentUserAgent: d.current_user_agent
68
68
  };
69
69
  }
70
70
  // ─── Loader ─────────────────────────────────────────────────────────────────
@@ -72,10 +72,10 @@ export const rlsLoader = createModuleLoader({
72
72
  name: 'rlsModule',
73
73
  ttlMs: 5 * 60_000,
74
74
  async resolve(ctx) {
75
- const { servicesPool, databaseId, apiId } = ctx;
75
+ const { routingPool, databaseId, apiId } = ctx;
76
76
  // Try new rls_settings table first
77
77
  try {
78
- const result = await servicesPool.query(RLS_SETTINGS_SQL, [databaseId]);
78
+ const result = await routingPool.query(RLS_SETTINGS_SQL, [databaseId]);
79
79
  const resolved = fromSettings(result.rows[0] ?? null);
80
80
  if (resolved)
81
81
  return resolved;
@@ -83,11 +83,11 @@ export const rlsLoader = createModuleLoader({
83
83
  catch {
84
84
  // Table may not exist yet
85
85
  }
86
- // Fall back to legacy api_modules
86
+ // Fall back to api_modules
87
87
  if (apiId) {
88
- const result = await servicesPool.query(RLS_MODULE_SQL, [apiId]);
88
+ const result = await routingPool.query(RLS_MODULE_SQL, [apiId]);
89
89
  return fromModule(result.rows[0] ?? null);
90
90
  }
91
91
  return undefined;
92
- },
92
+ }
93
93
  });
@@ -2,7 +2,7 @@
2
2
  * Module Loader Types
3
3
  *
4
4
  * A ModuleLoader is a per-database cached lookup that resolves config
5
- * from the services DB or tenant DB. Each loader owns its own LRU cache
5
+ * from the routing DB or tenant DB. Each loader owns its own LRU cache
6
6
  * keyed by databaseId, with independent TTL and eviction.
7
7
  *
8
8
  * Loaders are registered in a LoaderRegistry and resolved in parallel
@@ -19,7 +19,7 @@ const WEBAUTHN_SETTINGS_SQL = `
19
19
  ws.require_user_verification,
20
20
  ws.resident_key,
21
21
  ws.challenge_expiry_seconds
22
- FROM services_public.webauthn_settings ws
22
+ FROM constructive_routing_public.webauthn_settings ws
23
23
  LEFT JOIN metaschema_public.schema s ON ws.schema_id = s.id
24
24
  LEFT JOIN metaschema_public.schema cred_s ON ws.credentials_schema_id = cred_s.id
25
25
  LEFT JOIN metaschema_public.schema sess_s ON ws.sessions_schema_id = sess_s.id
@@ -32,8 +32,8 @@ export const webauthnLoader = createModuleLoader({
32
32
  name: 'webauthnSettings',
33
33
  ttlMs: 5 * 60_000,
34
34
  async resolve(ctx) {
35
- const { servicesPool, databaseId } = ctx;
36
- const result = await servicesPool.query(WEBAUTHN_SETTINGS_SQL, [databaseId]);
35
+ const { routingPool, databaseId } = ctx;
36
+ const result = await routingPool.query(WEBAUTHN_SETTINGS_SQL, [databaseId]);
37
37
  const row = result.rows[0];
38
38
  if (!row?.schema)
39
39
  return undefined;
@@ -48,7 +48,7 @@ export const webauthnLoader = createModuleLoader({
48
48
  attestationType: row.attestation_type,
49
49
  requireUserVerification: row.require_user_verification,
50
50
  residentKey: row.resident_key,
51
- challengeExpirySeconds: row.challenge_expiry_seconds,
51
+ challengeExpirySeconds: row.challenge_expiry_seconds
52
52
  };
53
- },
53
+ }
54
54
  });
@@ -39,8 +39,9 @@ export function buildPgSettings(input) {
39
39
  settings['jwt.claims.database_id'] = api.databaseId;
40
40
  }
41
41
  // API provenance — which API surface this request arrived through.
42
- // Derived server-side from hostname -> services_public.domains -> api_id;
43
- // never taken from client-supplied headers, body, or token payload.
42
+ // Derived server-side by resolving the hostname through the scoped routing
43
+ // plane (resolve_route -> api_id); never taken from client-supplied headers,
44
+ // body, or token payload.
44
45
  if (api.apiId) {
45
46
  settings['jwt.claims.api_id'] = api.apiId;
46
47
  }
@@ -7,7 +7,7 @@
7
7
  * 2. Query the discovered <schema>.<table> in the tenant DB
8
8
  *
9
9
  * This is the pattern for any module whose config lives in the tenant
10
- * database rather than the services database.
10
+ * database rather than the routing database.
11
11
  */
12
12
  import type { AuthSettings } from '../types';
13
13
  import type { ModuleLoader } from './types';
@@ -8,7 +8,7 @@
8
8
  * 2. Query the discovered <schema>.<table> in the tenant DB
9
9
  *
10
10
  * This is the pattern for any module whose config lives in the tenant
11
- * database rather than the services database.
11
+ * database rather than the routing database.
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.authSettingsLoader = void 0;
@@ -59,7 +59,7 @@ exports.authSettingsLoader = (0, create_loader_1.createModuleLoader)({
59
59
  cookiePath: row.cookie_path,
60
60
  rememberMeDuration: row.remember_me_duration,
61
61
  enableCaptcha: row.enable_captcha,
62
- captchaSiteKey: row.captcha_site_key,
62
+ captchaSiteKey: row.captcha_site_key
63
63
  };
64
- },
64
+ }
65
65
  });
package/loaders/cors.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * CORS Origins Loader
3
3
  *
4
- * Resolves allowed CORS origins for a database+API combination.
5
- * Checks per-API settings first, falls back to database-level default,
6
- * then to the legacy api_modules approach.
4
+ * Resolves allowed CORS origins for a database+API combination from the
5
+ * scoped routing plane. Checks per-API settings first, falls back to
6
+ * database-level default, then to the api_modules approach.
7
7
  */
8
8
  import type { ModuleLoader } from './types';
9
9
  export declare const corsLoader: ModuleLoader<string[]>;
package/loaders/cors.js CHANGED
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * CORS Origins Loader
4
4
  *
5
- * Resolves allowed CORS origins for a database+API combination.
6
- * Checks per-API settings first, falls back to database-level default,
7
- * then to the legacy api_modules approach.
5
+ * Resolves allowed CORS origins for a database+API combination from the
6
+ * scoped routing plane. Checks per-API settings first, falls back to
7
+ * database-level default, then to the api_modules approach.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.corsLoader = void 0;
@@ -12,19 +12,19 @@ const create_loader_1 = require("./create-loader");
12
12
  // ─── SQL ────────────────────────────────────────────────────────────────────
13
13
  const CORS_SETTINGS_SQL = `
14
14
  SELECT allowed_origins
15
- FROM services_public.cors_settings
15
+ FROM constructive_routing_public.cors_settings
16
16
  WHERE database_id = $1 AND api_id = $2
17
17
  LIMIT 1
18
18
  `;
19
19
  const CORS_SETTINGS_DB_DEFAULT_SQL = `
20
20
  SELECT allowed_origins
21
- FROM services_public.cors_settings
21
+ FROM constructive_routing_public.cors_settings
22
22
  WHERE database_id = $1 AND api_id IS NULL
23
23
  LIMIT 1
24
24
  `;
25
25
  const CORS_MODULE_SQL = `
26
26
  SELECT data
27
- FROM services_public.api_modules
27
+ FROM constructive_routing_public.api_modules
28
28
  WHERE api_id = $1 AND name = 'cors'
29
29
  LIMIT 1
30
30
  `;
@@ -33,26 +33,26 @@ exports.corsLoader = (0, create_loader_1.createModuleLoader)({
33
33
  name: 'corsOrigins',
34
34
  ttlMs: 5 * 60_000,
35
35
  async resolve(ctx) {
36
- const { servicesPool, databaseId, apiId } = ctx;
36
+ const { routingPool, databaseId, apiId } = ctx;
37
37
  // Try per-API cors_settings first
38
38
  try {
39
39
  if (apiId) {
40
- const perApi = await servicesPool.query(CORS_SETTINGS_SQL, [databaseId, apiId]);
40
+ const perApi = await routingPool.query(CORS_SETTINGS_SQL, [databaseId, apiId]);
41
41
  if (perApi.rows[0])
42
42
  return perApi.rows[0].allowed_origins;
43
43
  }
44
- const dbDefault = await servicesPool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
44
+ const dbDefault = await routingPool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
45
45
  if (dbDefault.rows[0])
46
46
  return dbDefault.rows[0].allowed_origins;
47
47
  }
48
48
  catch {
49
49
  // Table may not exist yet
50
50
  }
51
- // Fall back to legacy api_modules
51
+ // Fall back to api_modules
52
52
  if (apiId) {
53
- const result = await servicesPool.query(CORS_MODULE_SQL, [apiId]);
53
+ const result = await routingPool.query(CORS_MODULE_SQL, [apiId]);
54
54
  return result.rows[0]?.data?.urls;
55
55
  }
56
56
  return undefined;
57
- },
57
+ }
58
58
  });
@@ -24,8 +24,8 @@ const DATABASE_SETTINGS_SQL = `
24
24
  COALESCE(aps.enable_realtime, ds.enable_realtime) AS resolved_enable_realtime,
25
25
  COALESCE(aps.enable_bulk, ds.enable_bulk) AS resolved_enable_bulk,
26
26
  COALESCE(aps.enable_i18n, ds.enable_i18n) AS resolved_enable_i18n
27
- FROM services_public.database_settings ds
28
- LEFT JOIN services_public.api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
27
+ FROM constructive_routing_public.database_settings ds
28
+ LEFT JOIN constructive_routing_public.api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
29
29
  WHERE ds.database_id = $1
30
30
  LIMIT 1
31
31
  `;
@@ -34,8 +34,8 @@ exports.databaseSettingsLoader = (0, create_loader_1.createModuleLoader)({
34
34
  name: 'databaseSettings',
35
35
  ttlMs: 5 * 60_000,
36
36
  async resolve(ctx) {
37
- const { servicesPool, databaseId, apiId } = ctx;
38
- const result = await servicesPool.query(DATABASE_SETTINGS_SQL, [databaseId, apiId ?? null]);
37
+ const { routingPool, databaseId, apiId } = ctx;
38
+ const result = await routingPool.query(DATABASE_SETTINGS_SQL, [databaseId, apiId ?? null]);
39
39
  const row = result.rows[0];
40
40
  if (!row)
41
41
  return undefined;
@@ -51,7 +51,7 @@ exports.databaseSettingsLoader = (0, create_loader_1.createModuleLoader)({
51
51
  enableLlm: row.resolved_enable_llm,
52
52
  enableRealtime: row.resolved_enable_realtime,
53
53
  enableBulk: row.resolved_enable_bulk,
54
- enableI18n: row.resolved_enable_i18n,
54
+ enableI18n: row.resolved_enable_i18n
55
55
  };
56
- },
56
+ }
57
57
  });
@@ -6,11 +6,11 @@
6
6
  * a LoaderRegistry and pass it to createContextMiddleware().
7
7
  *
8
8
  * Built-in loaders cover the standard Constructive modules:
9
- * - rlsModule (services_public.rls_settings)
10
- * - corsOrigins (services_public.cors_settings)
11
- * - databaseSettings(services_public.database_settings)
12
- * - pubkeyChallengeSettings (services_public.pubkey_settings)
13
- * - webauthnSettings(services_public.webauthn_settings)
9
+ * - rlsModule (constructive_routing_public.rls_settings)
10
+ * - corsOrigins (constructive_routing_public.cors_settings)
11
+ * - databaseSettings(constructive_routing_public.database_settings)
12
+ * - pubkeyChallengeSettings (constructive_routing_public.pubkey_settings)
13
+ * - webauthnSettings(constructive_routing_public.webauthn_settings)
14
14
  * - authSettings (metaschema_modules_public.sessions_module → tenant DB)
15
15
  *
16
16
  * To add a new per-db lookup, implement a ModuleLoader and register it:
@@ -30,15 +30,15 @@ export type { CreateLoaderOptions } from './create-loader';
30
30
  export { createModuleLoader } from './create-loader';
31
31
  export type { LoaderRegistry } from './registry';
32
32
  export { createLoaderRegistry } from './registry';
33
- export { rlsLoader } from './rls';
34
- export { corsLoader } from './cors';
35
- export { databaseSettingsLoader } from './database-settings';
36
- export { pubkeyLoader } from './pubkey';
37
- export { webauthnLoader } from './webauthn';
33
+ export { agentChatLoader } from './agent-chat';
38
34
  export { authSettingsLoader } from './auth-settings';
39
35
  export { billingLoader } from './billing';
36
+ export { computeLoader } from './compute';
37
+ export { corsLoader } from './cors';
38
+ export { databaseSettingsLoader } from './database-settings';
40
39
  export { inferenceLogLoader } from './inference-log';
41
- export { agentChatLoader } from './agent-chat';
42
40
  export { llmLoader } from './llm';
43
- export { computeLoader } from './compute';
41
+ export { pubkeyLoader } from './pubkey';
42
+ export { rlsLoader } from './rls';
43
+ export { webauthnLoader } from './webauthn';
44
44
  export declare function createDefaultRegistry(): import("./registry").LoaderRegistry;
package/loaders/index.js CHANGED
@@ -7,11 +7,11 @@
7
7
  * a LoaderRegistry and pass it to createContextMiddleware().
8
8
  *
9
9
  * Built-in loaders cover the standard Constructive modules:
10
- * - rlsModule (services_public.rls_settings)
11
- * - corsOrigins (services_public.cors_settings)
12
- * - databaseSettings(services_public.database_settings)
13
- * - pubkeyChallengeSettings (services_public.pubkey_settings)
14
- * - webauthnSettings(services_public.webauthn_settings)
10
+ * - rlsModule (constructive_routing_public.rls_settings)
11
+ * - corsOrigins (constructive_routing_public.cors_settings)
12
+ * - databaseSettings(constructive_routing_public.database_settings)
13
+ * - pubkeyChallengeSettings (constructive_routing_public.pubkey_settings)
14
+ * - webauthnSettings(constructive_routing_public.webauthn_settings)
15
15
  * - authSettings (metaschema_modules_public.sessions_module → tenant DB)
16
16
  *
17
17
  * To add a new per-db lookup, implement a ModuleLoader and register it:
@@ -27,50 +27,50 @@
27
27
  * registry.register(myLoader);
28
28
  */
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.computeLoader = exports.llmLoader = exports.agentChatLoader = exports.inferenceLogLoader = exports.billingLoader = exports.authSettingsLoader = exports.webauthnLoader = exports.pubkeyLoader = exports.databaseSettingsLoader = exports.corsLoader = exports.rlsLoader = exports.createLoaderRegistry = exports.createModuleLoader = void 0;
30
+ exports.webauthnLoader = exports.rlsLoader = exports.pubkeyLoader = exports.llmLoader = exports.inferenceLogLoader = exports.databaseSettingsLoader = exports.corsLoader = exports.computeLoader = exports.billingLoader = exports.authSettingsLoader = exports.agentChatLoader = exports.createLoaderRegistry = exports.createModuleLoader = void 0;
31
31
  exports.createDefaultRegistry = createDefaultRegistry;
32
32
  var create_loader_1 = require("./create-loader");
33
33
  Object.defineProperty(exports, "createModuleLoader", { enumerable: true, get: function () { return create_loader_1.createModuleLoader; } });
34
34
  var registry_1 = require("./registry");
35
35
  Object.defineProperty(exports, "createLoaderRegistry", { enumerable: true, get: function () { return registry_1.createLoaderRegistry; } });
36
36
  // Built-in loaders
37
- var rls_1 = require("./rls");
38
- Object.defineProperty(exports, "rlsLoader", { enumerable: true, get: function () { return rls_1.rlsLoader; } });
39
- var cors_1 = require("./cors");
40
- Object.defineProperty(exports, "corsLoader", { enumerable: true, get: function () { return cors_1.corsLoader; } });
41
- var database_settings_1 = require("./database-settings");
42
- Object.defineProperty(exports, "databaseSettingsLoader", { enumerable: true, get: function () { return database_settings_1.databaseSettingsLoader; } });
43
- var pubkey_1 = require("./pubkey");
44
- Object.defineProperty(exports, "pubkeyLoader", { enumerable: true, get: function () { return pubkey_1.pubkeyLoader; } });
45
- var webauthn_1 = require("./webauthn");
46
- Object.defineProperty(exports, "webauthnLoader", { enumerable: true, get: function () { return webauthn_1.webauthnLoader; } });
37
+ var agent_chat_1 = require("./agent-chat");
38
+ Object.defineProperty(exports, "agentChatLoader", { enumerable: true, get: function () { return agent_chat_1.agentChatLoader; } });
47
39
  var auth_settings_1 = require("./auth-settings");
48
40
  Object.defineProperty(exports, "authSettingsLoader", { enumerable: true, get: function () { return auth_settings_1.authSettingsLoader; } });
49
41
  var billing_1 = require("./billing");
50
42
  Object.defineProperty(exports, "billingLoader", { enumerable: true, get: function () { return billing_1.billingLoader; } });
43
+ var compute_1 = require("./compute");
44
+ Object.defineProperty(exports, "computeLoader", { enumerable: true, get: function () { return compute_1.computeLoader; } });
45
+ var cors_1 = require("./cors");
46
+ Object.defineProperty(exports, "corsLoader", { enumerable: true, get: function () { return cors_1.corsLoader; } });
47
+ var database_settings_1 = require("./database-settings");
48
+ Object.defineProperty(exports, "databaseSettingsLoader", { enumerable: true, get: function () { return database_settings_1.databaseSettingsLoader; } });
51
49
  var inference_log_1 = require("./inference-log");
52
50
  Object.defineProperty(exports, "inferenceLogLoader", { enumerable: true, get: function () { return inference_log_1.inferenceLogLoader; } });
53
- var agent_chat_1 = require("./agent-chat");
54
- Object.defineProperty(exports, "agentChatLoader", { enumerable: true, get: function () { return agent_chat_1.agentChatLoader; } });
55
51
  var llm_1 = require("./llm");
56
52
  Object.defineProperty(exports, "llmLoader", { enumerable: true, get: function () { return llm_1.llmLoader; } });
57
- var compute_1 = require("./compute");
58
- Object.defineProperty(exports, "computeLoader", { enumerable: true, get: function () { return compute_1.computeLoader; } });
53
+ var pubkey_1 = require("./pubkey");
54
+ Object.defineProperty(exports, "pubkeyLoader", { enumerable: true, get: function () { return pubkey_1.pubkeyLoader; } });
55
+ var rls_1 = require("./rls");
56
+ Object.defineProperty(exports, "rlsLoader", { enumerable: true, get: function () { return rls_1.rlsLoader; } });
57
+ var webauthn_1 = require("./webauthn");
58
+ Object.defineProperty(exports, "webauthnLoader", { enumerable: true, get: function () { return webauthn_1.webauthnLoader; } });
59
59
  /**
60
60
  * Convenience: create a registry pre-loaded with all built-in loaders.
61
61
  */
62
- const registry_2 = require("./registry");
63
- const rls_2 = require("./rls");
64
- const cors_2 = require("./cors");
65
- const database_settings_2 = require("./database-settings");
66
- const pubkey_2 = require("./pubkey");
67
- const webauthn_2 = require("./webauthn");
62
+ const agent_chat_2 = require("./agent-chat");
68
63
  const auth_settings_2 = require("./auth-settings");
69
64
  const billing_2 = require("./billing");
65
+ const compute_2 = require("./compute");
66
+ const cors_2 = require("./cors");
67
+ const database_settings_2 = require("./database-settings");
70
68
  const inference_log_2 = require("./inference-log");
71
- const agent_chat_2 = require("./agent-chat");
72
69
  const llm_2 = require("./llm");
73
- const compute_2 = require("./compute");
70
+ const pubkey_2 = require("./pubkey");
71
+ const registry_2 = require("./registry");
72
+ const rls_2 = require("./rls");
73
+ const webauthn_2 = require("./webauthn");
74
74
  function createDefaultRegistry() {
75
75
  const registry = (0, registry_2.createLoaderRegistry)();
76
76
  registry.register(rls_2.rlsLoader);
@@ -2,8 +2,8 @@
2
2
  * Pubkey Challenge Settings Loader
3
3
  *
4
4
  * Resolves public-key challenge auth config (crypto network, sign-in/sign-up
5
- * function names). Tries the new pubkey_settings table first, falls back
6
- * to the legacy api_modules approach.
5
+ * function names) from the scoped routing plane. Tries the pubkey_settings
6
+ * table first, falls back to the api_modules approach.
7
7
  */
8
8
  import type { PubkeyChallengeSettings } from '../types';
9
9
  import type { ModuleLoader } from './types';
package/loaders/pubkey.js CHANGED
@@ -3,8 +3,8 @@
3
3
  * Pubkey Challenge Settings Loader
4
4
  *
5
5
  * Resolves public-key challenge auth config (crypto network, sign-in/sign-up
6
- * function names). Tries the new pubkey_settings table first, falls back
7
- * to the legacy api_modules approach.
6
+ * function names) from the scoped routing plane. Tries the pubkey_settings
7
+ * table first, falls back to the api_modules approach.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.pubkeyLoader = void 0;
@@ -18,7 +18,7 @@ const PUBKEY_SETTINGS_SQL = `
18
18
  sign_in_req_fn.name AS sign_in_request_challenge,
19
19
  sign_in_fail_fn.name AS sign_in_record_failure,
20
20
  sign_in_fn.name AS sign_in_with_challenge
21
- FROM services_public.pubkey_settings ps
21
+ FROM constructive_routing_public.pubkey_settings ps
22
22
  LEFT JOIN metaschema_public.schema s ON ps.schema_id = s.id
23
23
  LEFT JOIN metaschema_public.function sign_up_fn ON ps.sign_up_with_key_function_id = sign_up_fn.id
24
24
  LEFT JOIN metaschema_public.function sign_in_req_fn ON ps.sign_in_request_challenge_function_id = sign_in_req_fn.id
@@ -29,7 +29,7 @@ const PUBKEY_SETTINGS_SQL = `
29
29
  `;
30
30
  const PUBKEY_MODULE_SQL = `
31
31
  SELECT data
32
- FROM services_public.api_modules
32
+ FROM constructive_routing_public.api_modules
33
33
  WHERE api_id = $1 AND name = 'pubkey_challenge'
34
34
  LIMIT 1
35
35
  `;
@@ -43,7 +43,7 @@ function fromRow(row) {
43
43
  signUpWithKey: row.sign_up_with_key,
44
44
  signInRequestChallenge: row.sign_in_request_challenge,
45
45
  signInRecordFailure: row.sign_in_record_failure,
46
- signInWithChallenge: row.sign_in_with_challenge,
46
+ signInWithChallenge: row.sign_in_with_challenge
47
47
  };
48
48
  }
49
49
  // ─── Loader ─────────────────────────────────────────────────────────────────
@@ -51,10 +51,10 @@ exports.pubkeyLoader = (0, create_loader_1.createModuleLoader)({
51
51
  name: 'pubkeyChallengeSettings',
52
52
  ttlMs: 5 * 60_000,
53
53
  async resolve(ctx) {
54
- const { servicesPool, databaseId, apiId } = ctx;
54
+ const { routingPool, databaseId, apiId } = ctx;
55
55
  // Try new pubkey_settings table first
56
56
  try {
57
- const result = await servicesPool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
57
+ const result = await routingPool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
58
58
  const resolved = fromRow(result.rows[0] ?? null);
59
59
  if (resolved)
60
60
  return resolved;
@@ -62,11 +62,11 @@ exports.pubkeyLoader = (0, create_loader_1.createModuleLoader)({
62
62
  catch {
63
63
  // Table may not exist yet
64
64
  }
65
- // Fall back to legacy api_modules
65
+ // Fall back to api_modules
66
66
  if (apiId) {
67
- const result = await servicesPool.query(PUBKEY_MODULE_SQL, [apiId]);
67
+ const result = await routingPool.query(PUBKEY_MODULE_SQL, [apiId]);
68
68
  return fromRow(result.rows[0]?.data ?? null);
69
69
  }
70
70
  return undefined;
71
- },
71
+ }
72
72
  });
package/loaders/rls.d.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  * RLS Module Loader
3
3
  *
4
4
  * Resolves RLS authentication function names and schema references for
5
- * a given database. Tries the new rls_settings table first, falls back
6
- * to the legacy api_modules approach.
5
+ * a given database from the scoped routing plane. Tries the rls_settings
6
+ * table first, falls back to the api_modules approach.
7
7
  */
8
8
  import type { RlsModule } from '../types';
9
9
  import type { ModuleLoader } from './types';
package/loaders/rls.js CHANGED
@@ -3,8 +3,8 @@
3
3
  * RLS Module Loader
4
4
  *
5
5
  * Resolves RLS authentication function names and schema references for
6
- * a given database. Tries the new rls_settings table first, falls back
7
- * to the legacy api_modules approach.
6
+ * a given database from the scoped routing plane. Tries the rls_settings
7
+ * table first, falls back to the api_modules approach.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.rlsLoader = void 0;
@@ -20,7 +20,7 @@ const RLS_SETTINGS_SQL = `
20
20
  role_id_fn.name AS current_role_id,
21
21
  ua_fn.name AS current_user_agent,
22
22
  ip_fn.name AS current_ip_address
23
- FROM services_public.rls_settings rs
23
+ FROM constructive_routing_public.rls_settings rs
24
24
  LEFT JOIN metaschema_public.schema auth_schema ON rs.authenticate_schema_id = auth_schema.id
25
25
  LEFT JOIN metaschema_public.schema role_schema ON rs.role_schema_id = role_schema.id
26
26
  LEFT JOIN metaschema_public.function auth_fn ON rs.authenticate_function_id = auth_fn.id
@@ -34,7 +34,7 @@ const RLS_SETTINGS_SQL = `
34
34
  `;
35
35
  const RLS_MODULE_SQL = `
36
36
  SELECT data
37
- FROM services_public.api_modules
37
+ FROM constructive_routing_public.api_modules
38
38
  WHERE api_id = $1 AND name = 'rls_module'
39
39
  LIMIT 1
40
40
  `;
@@ -52,7 +52,7 @@ function fromSettings(row) {
52
52
  currentRole: row.current_role,
53
53
  currentRoleId: row.current_role_id,
54
54
  currentIpAddress: row.current_ip_address,
55
- currentUserAgent: row.current_user_agent,
55
+ currentUserAgent: row.current_user_agent
56
56
  };
57
57
  }
58
58
  function fromModule(row) {
@@ -67,7 +67,7 @@ function fromModule(row) {
67
67
  currentRole: d.current_role,
68
68
  currentRoleId: d.current_role_id,
69
69
  currentIpAddress: d.current_ip_address,
70
- currentUserAgent: d.current_user_agent,
70
+ currentUserAgent: d.current_user_agent
71
71
  };
72
72
  }
73
73
  // ─── Loader ─────────────────────────────────────────────────────────────────
@@ -75,10 +75,10 @@ exports.rlsLoader = (0, create_loader_1.createModuleLoader)({
75
75
  name: 'rlsModule',
76
76
  ttlMs: 5 * 60_000,
77
77
  async resolve(ctx) {
78
- const { servicesPool, databaseId, apiId } = ctx;
78
+ const { routingPool, databaseId, apiId } = ctx;
79
79
  // Try new rls_settings table first
80
80
  try {
81
- const result = await servicesPool.query(RLS_SETTINGS_SQL, [databaseId]);
81
+ const result = await routingPool.query(RLS_SETTINGS_SQL, [databaseId]);
82
82
  const resolved = fromSettings(result.rows[0] ?? null);
83
83
  if (resolved)
84
84
  return resolved;
@@ -86,11 +86,11 @@ exports.rlsLoader = (0, create_loader_1.createModuleLoader)({
86
86
  catch {
87
87
  // Table may not exist yet
88
88
  }
89
- // Fall back to legacy api_modules
89
+ // Fall back to api_modules
90
90
  if (apiId) {
91
- const result = await servicesPool.query(RLS_MODULE_SQL, [apiId]);
91
+ const result = await routingPool.query(RLS_MODULE_SQL, [apiId]);
92
92
  return fromModule(result.rows[0] ?? null);
93
93
  }
94
94
  return undefined;
95
- },
95
+ }
96
96
  });
@@ -2,7 +2,7 @@
2
2
  * Module Loader Types
3
3
  *
4
4
  * A ModuleLoader is a per-database cached lookup that resolves config
5
- * from the services DB or tenant DB. Each loader owns its own LRU cache
5
+ * from the routing DB or tenant DB. Each loader owns its own LRU cache
6
6
  * keyed by databaseId, with independent TTL and eviction.
7
7
  *
8
8
  * Loaders are registered in a LoaderRegistry and resolved in parallel
@@ -16,8 +16,8 @@ import type { Pool } from 'pg';
16
16
  * database tier it needs.
17
17
  */
18
18
  export interface LoaderContext {
19
- /** Services database pool (for services_public.* lookups) */
20
- servicesPool: Pool;
19
+ /** Routing/configuration database pool (for constructive_routing_public.* lookups) */
20
+ routingPool: Pool;
21
21
  /** Tenant database pool (for metaschema_modules_public.* lookups) */
22
22
  tenantPool: Pool;
23
23
  /** UUID of the database being resolved */
package/loaders/types.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Module Loader Types
4
4
  *
5
5
  * A ModuleLoader is a per-database cached lookup that resolves config
6
- * from the services DB or tenant DB. Each loader owns its own LRU cache
6
+ * from the routing DB or tenant DB. Each loader owns its own LRU cache
7
7
  * keyed by databaseId, with independent TTL and eviction.
8
8
  *
9
9
  * Loaders are registered in a LoaderRegistry and resolved in parallel
@@ -22,7 +22,7 @@ const WEBAUTHN_SETTINGS_SQL = `
22
22
  ws.require_user_verification,
23
23
  ws.resident_key,
24
24
  ws.challenge_expiry_seconds
25
- FROM services_public.webauthn_settings ws
25
+ FROM constructive_routing_public.webauthn_settings ws
26
26
  LEFT JOIN metaschema_public.schema s ON ws.schema_id = s.id
27
27
  LEFT JOIN metaschema_public.schema cred_s ON ws.credentials_schema_id = cred_s.id
28
28
  LEFT JOIN metaschema_public.schema sess_s ON ws.sessions_schema_id = sess_s.id
@@ -35,8 +35,8 @@ exports.webauthnLoader = (0, create_loader_1.createModuleLoader)({
35
35
  name: 'webauthnSettings',
36
36
  ttlMs: 5 * 60_000,
37
37
  async resolve(ctx) {
38
- const { servicesPool, databaseId } = ctx;
39
- const result = await servicesPool.query(WEBAUTHN_SETTINGS_SQL, [databaseId]);
38
+ const { routingPool, databaseId } = ctx;
39
+ const result = await routingPool.query(WEBAUTHN_SETTINGS_SQL, [databaseId]);
40
40
  const row = result.rows[0];
41
41
  if (!row?.schema)
42
42
  return undefined;
@@ -51,7 +51,7 @@ exports.webauthnLoader = (0, create_loader_1.createModuleLoader)({
51
51
  attestationType: row.attestation_type,
52
52
  requireUserVerification: row.require_user_verification,
53
53
  residentKey: row.resident_key,
54
- challengeExpirySeconds: row.challenge_expiry_seconds,
54
+ challengeExpirySeconds: row.challenge_expiry_seconds
55
55
  };
56
- },
56
+ }
57
57
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/express-context",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "Extractable Express middleware for Constructive tenant context — domain resolution, JWT auth, pgSettings, and withPgClient",
5
5
  "author": "Constructive <developers@constructive.io>",
6
6
  "homepage": "https://github.com/constructive-io/constructive",
@@ -30,13 +30,13 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@constructive-io/url-domains": "^2.19.0",
33
- "@pgpmjs/env": "^2.28.1",
33
+ "@pgpmjs/env": "^2.29.0",
34
34
  "@pgpmjs/logger": "^2.14.0",
35
- "@pgpmjs/server-utils": "^3.15.2",
36
- "@pgpmjs/types": "^2.35.0",
35
+ "@pgpmjs/server-utils": "^3.15.4",
36
+ "@pgpmjs/types": "^2.36.0",
37
37
  "lru-cache": "^11.2.7",
38
38
  "pg": "^8.21.0",
39
- "pg-cache": "^3.15.1",
39
+ "pg-cache": "^3.15.3",
40
40
  "pg-query-context": "^2.19.0"
41
41
  },
42
42
  "devDependencies": {
@@ -59,5 +59,5 @@
59
59
  "jwt",
60
60
  "pgSettings"
61
61
  ],
62
- "gitHead": "dd2accb683fe20c7278a0d58fd36a04a3b07ac63"
62
+ "gitHead": "39db6d576bce7bc1de8123849f237b1695779d88"
63
63
  }
package/pg-settings.js CHANGED
@@ -42,8 +42,9 @@ function buildPgSettings(input) {
42
42
  settings['jwt.claims.database_id'] = api.databaseId;
43
43
  }
44
44
  // API provenance — which API surface this request arrived through.
45
- // Derived server-side from hostname -> services_public.domains -> api_id;
46
- // never taken from client-supplied headers, body, or token payload.
45
+ // Derived server-side by resolving the hostname through the scoped routing
46
+ // plane (resolve_route -> api_id); never taken from client-supplied headers,
47
+ // body, or token payload.
47
48
  if (api.apiId) {
48
49
  settings['jwt.claims.api_id'] = api.apiId;
49
50
  }