@venturekit/data 0.0.0-dev.20260505153744 → 0.0.0-dev.20260505164519

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.
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tiny structured logger for `@venturekit/data`.
3
+ *
4
+ * The runtime package wires a pino logger keyed by `requestId`, but
5
+ * `@venturekit/data` is consumed from CLI tooling, queue handlers, and
6
+ * background workers too — none of which can rely on a pino instance
7
+ * being injected. Emitting JSON straight to stdout in the same shape
8
+ * pino uses keeps CloudWatch Logs Insights queries (`fields @timestamp,
9
+ * level, msg, durationMs`) consistent across runtime + data lines, and
10
+ * stays a no-op outside Lambda where stdout still routes somewhere
11
+ * sensible.
12
+ *
13
+ * Filtering is driven by `DB_LOG_LEVEL` (`info` | `warn` | `error`).
14
+ * Default `info`. `error` is the floor — we never silence error lines
15
+ * because they're the ones operators need when diagnosing production
16
+ * incidents.
17
+ */
18
+ /**
19
+ * Internal logger for the data package. Exposed via the package barrel
20
+ * so user code can opt into the same emission format if it wants to;
21
+ * not part of the documented surface yet.
22
+ */
23
+ export declare const dbLog: {
24
+ info(msg: string, fields?: Record<string, unknown>): void;
25
+ warn(msg: string, fields?: Record<string, unknown>): void;
26
+ error(msg: string, fields?: Record<string, unknown>): void;
27
+ };
28
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/internal/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAiCH;;;;GAIG;AACH,eAAO,MAAM,KAAK;cACN,MAAM,WAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAQ,IAAI;cAGnD,MAAM,WAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAQ,IAAI;eAGlD,MAAM,WAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAQ,IAAI;CAG/D,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Tiny structured logger for `@venturekit/data`.
3
+ *
4
+ * The runtime package wires a pino logger keyed by `requestId`, but
5
+ * `@venturekit/data` is consumed from CLI tooling, queue handlers, and
6
+ * background workers too — none of which can rely on a pino instance
7
+ * being injected. Emitting JSON straight to stdout in the same shape
8
+ * pino uses keeps CloudWatch Logs Insights queries (`fields @timestamp,
9
+ * level, msg, durationMs`) consistent across runtime + data lines, and
10
+ * stays a no-op outside Lambda where stdout still routes somewhere
11
+ * sensible.
12
+ *
13
+ * Filtering is driven by `DB_LOG_LEVEL` (`info` | `warn` | `error`).
14
+ * Default `info`. `error` is the floor — we never silence error lines
15
+ * because they're the ones operators need when diagnosing production
16
+ * incidents.
17
+ */
18
+ const LEVEL_PRIORITY = {
19
+ info: 1,
20
+ warn: 2,
21
+ error: 3,
22
+ };
23
+ function envLevel() {
24
+ const raw = (process.env.DB_LOG_LEVEL ?? 'info').toLowerCase();
25
+ if (raw === 'warn' || raw === 'error')
26
+ return raw;
27
+ return 'info';
28
+ }
29
+ function emit(level, msg, fields) {
30
+ if (LEVEL_PRIORITY[level] < LEVEL_PRIORITY[envLevel()])
31
+ return;
32
+ const entry = {
33
+ level,
34
+ time: new Date().toISOString(),
35
+ component: '@venturekit/data',
36
+ ...fields,
37
+ msg,
38
+ };
39
+ // stdout matches pino's default and is captured by Lambda alongside
40
+ // stderr. Using stdout (not stderr) keeps the log line ordered with
41
+ // the runtime's `Request started` / `Request completed` lines emitted
42
+ // by pino in `@venturekit/runtime`.
43
+ // eslint-disable-next-line no-console
44
+ console.log(JSON.stringify(entry));
45
+ }
46
+ /**
47
+ * Internal logger for the data package. Exposed via the package barrel
48
+ * so user code can opt into the same emission format if it wants to;
49
+ * not part of the documented surface yet.
50
+ */
51
+ export const dbLog = {
52
+ info(msg, fields = {}) {
53
+ emit('info', msg, fields);
54
+ },
55
+ warn(msg, fields = {}) {
56
+ emit('warn', msg, fields);
57
+ },
58
+ error(msg, fields = {}) {
59
+ emit('error', msg, fields);
60
+ },
61
+ };
62
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/internal/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,cAAc,GAA0B;IAC5C,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,SAAS,QAAQ;IACf,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,GAAG,CAAC;IAClD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,IAAI,CAAC,KAAY,EAAE,GAAW,EAAE,MAA+B;IACtE,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC;QAAE,OAAO;IAC/D,MAAM,KAAK,GAA4B;QACrC,KAAK;QACL,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC9B,SAAS,EAAE,kBAAkB;QAC7B,GAAG,MAAM;QACT,GAAG;KACJ,CAAC;IACF,oEAAoE;IACpE,oEAAoE;IACpE,sEAAsE;IACtE,oCAAoC;IACpC,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,CAAC,GAAW,EAAE,SAAkC,EAAE;QACpD,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,CAAC,GAAW,EAAE,SAAkC,EAAE;QACpD,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,KAAK,CAAC,GAAW,EAAE,SAAkC,EAAE;QACrD,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;CACF,CAAC"}
@@ -46,6 +46,14 @@
46
46
  */
47
47
  import { type MapperOptions } from './mapper.js';
48
48
  import type { ResultsMapper } from './transaction.js';
49
+ /**
50
+ * Default threshold above which a successful query is logged as slow.
51
+ * Tuned for OLTP workloads (reads in single-digit ms, writes 10–50 ms);
52
+ * 1 s catches obvious offenders without spamming the log on warm cold-
53
+ * start variations or transient RDS read replica blips. Override per
54
+ * environment via `DB_SLOW_QUERY_THRESHOLD_MS`. Set to `0` to disable.
55
+ */
56
+ export declare const DEFAULT_SLOW_QUERY_THRESHOLD_MS = 1000;
49
57
  export { getPool, applyDatabaseUrlToEnv } from './pool.js';
50
58
  export { applyDbSecretToEnv } from './secret.js';
51
59
  export { mapResults, mapRow, configureMapper, getMapperConfig, } from './mapper.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAIH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACvD,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,EAAE,EACvB,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAChC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CAUZ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAIH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,OAAQ,CAAC;AAqBrD,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACvD,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,EAAE,EACvB,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAChC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA6CZ"}
@@ -47,6 +47,33 @@
47
47
  import { getPool } from './pool.js';
48
48
  import { mapResults } from './mapper.js';
49
49
  import { applyDbSecretToEnv } from './secret.js';
50
+ import { dbLog } from '../internal/logger.js';
51
+ /**
52
+ * Default threshold above which a successful query is logged as slow.
53
+ * Tuned for OLTP workloads (reads in single-digit ms, writes 10–50 ms);
54
+ * 1 s catches obvious offenders without spamming the log on warm cold-
55
+ * start variations or transient RDS read replica blips. Override per
56
+ * environment via `DB_SLOW_QUERY_THRESHOLD_MS`. Set to `0` to disable.
57
+ */
58
+ export const DEFAULT_SLOW_QUERY_THRESHOLD_MS = 1_000;
59
+ function resolveSlowQueryThresholdMs() {
60
+ const raw = process.env.DB_SLOW_QUERY_THRESHOLD_MS;
61
+ if (!raw)
62
+ return DEFAULT_SLOW_QUERY_THRESHOLD_MS;
63
+ const n = Number.parseInt(raw, 10);
64
+ return Number.isFinite(n) && n >= 0 ? n : DEFAULT_SLOW_QUERY_THRESHOLD_MS;
65
+ }
66
+ /**
67
+ * Build a short, single-line preview of a SQL string for log fields.
68
+ * Collapses runs of whitespace and clips to 120 chars so log lines
69
+ * stay grep-friendly. Parameter values are never included — the
70
+ * `$1`, `$2` placeholders are passed through verbatim, so PII never
71
+ * leaks into CloudWatch.
72
+ */
73
+ function previewSql(sql) {
74
+ const single = sql.replace(/\s+/g, ' ').trim();
75
+ return single.length > 120 ? `${single.slice(0, 117)}...` : single;
76
+ }
50
77
  export { getPool, applyDatabaseUrlToEnv } from './pool.js';
51
78
  export { applyDbSecretToEnv } from './secret.js';
52
79
  export { mapResults, mapRow, configureMapper, getMapperConfig, } from './mapper.js';
@@ -92,7 +119,40 @@ export async function query(sqlQuery, queryParams, resultsMapper, mapperOptions)
92
119
  // so concurrent first calls share one fetch.
93
120
  await applyDbSecretToEnv();
94
121
  const pool = getPool();
95
- const res = await pool.query(sqlQuery, queryParams);
122
+ const startedAt = Date.now();
123
+ let res;
124
+ try {
125
+ res = await pool.query(sqlQuery, queryParams);
126
+ }
127
+ catch (err) {
128
+ // Capture pg's structured fields when present (`code`, `severity`,
129
+ // `routine`) — the SQLSTATE class is the single best signal for
130
+ // operators triaging a query failure (e.g. `42P01` = relation does
131
+ // not exist, `28P01` = bad password, `08001` = unable to connect).
132
+ const durationMs = Date.now() - startedAt;
133
+ const errAny = err;
134
+ dbLog.error('Postgres query failed', {
135
+ durationMs,
136
+ sqlPreview: previewSql(sqlQuery),
137
+ paramCount: queryParams?.length ?? 0,
138
+ errorName: err instanceof Error ? err.name : undefined,
139
+ errorMessage: err instanceof Error ? err.message : String(err),
140
+ pgCode: errAny.code,
141
+ pgSeverity: errAny.severity,
142
+ pgRoutine: errAny.routine,
143
+ });
144
+ throw err;
145
+ }
146
+ const durationMs = Date.now() - startedAt;
147
+ const slowMs = resolveSlowQueryThresholdMs();
148
+ if (slowMs > 0 && durationMs >= slowMs) {
149
+ dbLog.warn('Slow Postgres query', {
150
+ durationMs,
151
+ thresholdMs: slowMs,
152
+ rowCount: res.rowCount ?? res.rows.length,
153
+ sqlPreview: previewSql(sqlQuery),
154
+ });
155
+ }
96
156
  const mapped = mapResults(res.rows, mapperOptions);
97
157
  return resultsMapper ? resultsMapper(mapped) : mapped;
98
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAA8B,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,QAAgB,EAChB,WAAuB,EACvB,aAAgC,EAChC,aAA6B;IAE7B,sEAAsE;IACtE,0EAA0E;IAC1E,8EAA8E;IAC9E,6CAA6C;IAC7C,MAAM,kBAAkB,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,GAAG,GAAgB,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACnD,OAAO,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAsB,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"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"}
@@ -14,8 +14,23 @@
14
14
  * - DB_SSL_CA (PEM-encoded CA bundle to trust, e.g. the RDS global bundle)
15
15
  * - DB_SSL_INSECURE ("true" to skip certificate verification — NOT recommended)
16
16
  * - DB_POOL_MAX (default 10)
17
+ * - DB_CONNECT_TIMEOUT_MS (default 5000)
18
+ *
19
+ * The connection-timeout default is intentionally well below the 10 s
20
+ * Lambda timeout used by the `nano` / `micro` presets: an unreachable
21
+ * RDS (security-group misconfig, wrong VPC, DB still booting) then
22
+ * surfaces as a clean `pg` error long before the Lambda is killed
23
+ * with no logs.
17
24
  */
18
25
  import { Pool } from 'pg';
26
+ /**
27
+ * Default `pg.Pool#connectionTimeoutMillis`. 5 s strikes the same
28
+ * balance as `DEFAULT_SECRETS_FETCH_TIMEOUT_MS` — fast enough that the
29
+ * Lambda emits a structured error inside its own budget, slow enough
30
+ * that healthy cold-start TCP+TLS handshakes (typically 200–1000 ms
31
+ * to RDS Postgres) don't get false-positive aborts.
32
+ */
33
+ export declare const DEFAULT_CONNECT_TIMEOUT_MS = 5000;
19
34
  /**
20
35
  * Bridge `DATABASE_URL` into the granular `DB_*` slots `getPool()` reads.
21
36
  * Idempotent — only fills slots that aren't already set, so the granular
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/query/pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,IAAI,EAAmB,MAAM,IAAI,CAAC;AAI3C;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAoC5C;AAwBD,wBAAgB,OAAO,IAAI,IAAI,CAc9B"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/query/pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,IAAI,EAAmB,MAAM,IAAI,CAAC;AAK3C;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,OAAQ,CAAC;AAShD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAoC5C;AAwBD,wBAAgB,OAAO,IAAI,IAAI,CAiD9B"}
@@ -14,9 +14,32 @@
14
14
  * - DB_SSL_CA (PEM-encoded CA bundle to trust, e.g. the RDS global bundle)
15
15
  * - DB_SSL_INSECURE ("true" to skip certificate verification — NOT recommended)
16
16
  * - DB_POOL_MAX (default 10)
17
+ * - DB_CONNECT_TIMEOUT_MS (default 5000)
18
+ *
19
+ * The connection-timeout default is intentionally well below the 10 s
20
+ * Lambda timeout used by the `nano` / `micro` presets: an unreachable
21
+ * RDS (security-group misconfig, wrong VPC, DB still booting) then
22
+ * surfaces as a clean `pg` error long before the Lambda is killed
23
+ * with no logs.
17
24
  */
18
25
  import { Pool } from 'pg';
26
+ import { dbLog } from '../internal/logger.js';
19
27
  let pool = null;
28
+ /**
29
+ * Default `pg.Pool#connectionTimeoutMillis`. 5 s strikes the same
30
+ * balance as `DEFAULT_SECRETS_FETCH_TIMEOUT_MS` — fast enough that the
31
+ * Lambda emits a structured error inside its own budget, slow enough
32
+ * that healthy cold-start TCP+TLS handshakes (typically 200–1000 ms
33
+ * to RDS Postgres) don't get false-positive aborts.
34
+ */
35
+ export const DEFAULT_CONNECT_TIMEOUT_MS = 5_000;
36
+ function resolveConnectionTimeoutMs() {
37
+ const raw = process.env.DB_CONNECT_TIMEOUT_MS;
38
+ if (!raw)
39
+ return DEFAULT_CONNECT_TIMEOUT_MS;
40
+ const n = Number.parseInt(raw, 10);
41
+ return Number.isFinite(n) && n >= 0 ? n : DEFAULT_CONNECT_TIMEOUT_MS;
42
+ }
20
43
  /**
21
44
  * Bridge `DATABASE_URL` into the granular `DB_*` slots `getPool()` reads.
22
45
  * Idempotent — only fills slots that aren't already set, so the granular
@@ -84,14 +107,46 @@ function resolveSsl() {
84
107
  export function getPool() {
85
108
  if (!pool) {
86
109
  applyDatabaseUrlToEnv();
110
+ const ssl = resolveSsl();
111
+ const max = Number(process.env.DB_POOL_MAX ?? 10);
112
+ const connectionTimeoutMillis = resolveConnectionTimeoutMs();
113
+ const host = process.env.DB_HOST;
114
+ const port = Number(process.env.DB_PORT ?? 5432);
115
+ const database = process.env.DB_NAME;
116
+ // Log the resolved pool config (sans credentials) once on first
117
+ // `getPool()`. Operators staring at a hung Lambda need this line
118
+ // to confirm DB_HOST / DB_PORT / DB_NAME landed in the expected
119
+ // slots; without it, the only signal that env vars exist at all
120
+ // is a successful query — which is exactly what they don't have.
121
+ dbLog.info('Creating Postgres pool', {
122
+ host,
123
+ port,
124
+ database,
125
+ // Only report whether credentials are present, never their values.
126
+ userPresent: Boolean(process.env.DB_USER),
127
+ passwordPresent: Boolean(process.env.DB_PASSWORD),
128
+ ssl: ssl !== undefined,
129
+ max,
130
+ connectionTimeoutMillis,
131
+ });
87
132
  pool = new Pool({
88
- host: process.env.DB_HOST,
89
- port: Number(process.env.DB_PORT ?? 5432),
90
- database: process.env.DB_NAME,
133
+ host,
134
+ port,
135
+ database,
91
136
  user: process.env.DB_USER,
92
137
  password: process.env.DB_PASSWORD,
93
- ssl: resolveSsl(),
94
- max: Number(process.env.DB_POOL_MAX ?? 10),
138
+ ssl,
139
+ max,
140
+ connectionTimeoutMillis,
141
+ });
142
+ // Async pool errors (e.g. an idle client losing its TCP connection)
143
+ // would otherwise crash the Lambda with no breadcrumb. Capture them
144
+ // in the structured log so CloudWatch shows what blew up.
145
+ pool.on('error', (err) => {
146
+ dbLog.error('Postgres pool emitted error event', {
147
+ errorName: err.name,
148
+ errorMessage: err.message,
149
+ });
95
150
  });
96
151
  }
97
152
  return pool;
@@ -1 +1 @@
1
- {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/query/pool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/query/pool.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,13 @@
19
19
  * concurrent `query()` calls during cold start share one network round
20
20
  * trip rather than racing N of them.
21
21
  *
22
+ * The fetch is bounded by an `AbortController` (default 5 s, override
23
+ * via `DB_SECRET_FETCH_TIMEOUT_MS`). VPC-attached Lambdas without a
24
+ * route to Secrets Manager (no NAT, no `com.amazonaws.<region>.secretsmanager`
25
+ * VPC endpoint) would otherwise hang silently until the Lambda's own
26
+ * timeout fires with zero diagnostic output. The bounded fetch raises
27
+ * an actionable error pointing at the likely network fix instead.
28
+ *
22
29
  * No-op when:
23
30
  * - `DB_SECRET_ARN` is unset (local dev, custom credentials), or
24
31
  * - both `DB_USER` and `DB_PASSWORD` are already set (e.g. the
@@ -30,6 +37,16 @@
30
37
  * environments using a `DATABASE_URL` against a local Postgres) don't
31
38
  * blow up at module load.
32
39
  */
40
+ /**
41
+ * Default timeout for the Secrets Manager `GetSecretValue` call.
42
+ * 5 s is well below the 10 s default Lambda timeout used by the `nano`
43
+ * and `micro` presets, so a hung fetch surfaces as a clear error rather
44
+ * than as a Lambda-level timeout with no logs.
45
+ *
46
+ * Override via `DB_SECRET_FETCH_TIMEOUT_MS` per environment if your
47
+ * Lambda has a longer budget.
48
+ */
49
+ export declare const DEFAULT_SECRETS_FETCH_TIMEOUT_MS = 5000;
33
50
  export declare function applyDbSecretToEnv(): Promise<void>;
34
51
  /**
35
52
  * Reset the memoized resolution. Test-only escape hatch — exposed under
@@ -1 +1 @@
1
- {"version":3,"file":"secret.d.ts","sourceRoot":"","sources":["../../src/query/secret.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAoBH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBxD;AAoDD;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}
1
+ {"version":3,"file":"secret.d.ts","sourceRoot":"","sources":["../../src/query/secret.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAKH;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,OAAQ,CAAC;AAsCtD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBxD;AAoHD;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}
@@ -19,6 +19,13 @@
19
19
  * concurrent `query()` calls during cold start share one network round
20
20
  * trip rather than racing N of them.
21
21
  *
22
+ * The fetch is bounded by an `AbortController` (default 5 s, override
23
+ * via `DB_SECRET_FETCH_TIMEOUT_MS`). VPC-attached Lambdas without a
24
+ * route to Secrets Manager (no NAT, no `com.amazonaws.<region>.secretsmanager`
25
+ * VPC endpoint) would otherwise hang silently until the Lambda's own
26
+ * timeout fires with zero diagnostic output. The bounded fetch raises
27
+ * an actionable error pointing at the likely network fix instead.
28
+ *
22
29
  * No-op when:
23
30
  * - `DB_SECRET_ARN` is unset (local dev, custom credentials), or
24
31
  * - both `DB_USER` and `DB_PASSWORD` are already set (e.g. the
@@ -30,6 +37,34 @@
30
37
  * environments using a `DATABASE_URL` against a local Postgres) don't
31
38
  * blow up at module load.
32
39
  */
40
+ import { dbLog } from '../internal/logger.js';
41
+ /**
42
+ * Default timeout for the Secrets Manager `GetSecretValue` call.
43
+ * 5 s is well below the 10 s default Lambda timeout used by the `nano`
44
+ * and `micro` presets, so a hung fetch surfaces as a clear error rather
45
+ * than as a Lambda-level timeout with no logs.
46
+ *
47
+ * Override via `DB_SECRET_FETCH_TIMEOUT_MS` per environment if your
48
+ * Lambda has a longer budget.
49
+ */
50
+ export const DEFAULT_SECRETS_FETCH_TIMEOUT_MS = 5_000;
51
+ function resolveSecretsFetchTimeoutMs() {
52
+ const raw = process.env.DB_SECRET_FETCH_TIMEOUT_MS;
53
+ if (!raw)
54
+ return DEFAULT_SECRETS_FETCH_TIMEOUT_MS;
55
+ const n = Number.parseInt(raw, 10);
56
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_SECRETS_FETCH_TIMEOUT_MS;
57
+ }
58
+ /**
59
+ * Strip the ARN prefix down to the trailing `secret:<name>` chunk so
60
+ * structured logs don't leak the AWS account number / region in plain
61
+ * text. Returns the input unchanged when it doesn't look like an ARN
62
+ * (e.g. unit tests passing a fake id).
63
+ */
64
+ function redactArn(arn) {
65
+ const idx = arn.lastIndexOf(':');
66
+ return idx === -1 ? arn : arn.slice(idx + 1);
67
+ }
33
68
  let resolution = null;
34
69
  export async function applyDbSecretToEnv() {
35
70
  const arn = process.env.DB_SECRET_ARN;
@@ -57,7 +92,53 @@ async function fetchAndApply(arn) {
57
92
  const sm = await import('@aws-sdk/client-secrets-manager');
58
93
  const region = process.env.AWS_REGION;
59
94
  const client = new sm.SecretsManagerClient(region ? { region } : {});
60
- const result = await client.send(new sm.GetSecretValueCommand({ SecretId: arn }));
95
+ const timeoutMs = resolveSecretsFetchTimeoutMs();
96
+ const controller = new AbortController();
97
+ // `unref()` so the timer never keeps the event loop alive past the
98
+ // SDK call's own resolution — Lambda's freeze/thaw cycle would
99
+ // otherwise stall waiting for it on warm invocations.
100
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
101
+ if (typeof timer.unref === 'function')
102
+ timer.unref();
103
+ const startedAt = Date.now();
104
+ const redactedArn = redactArn(arn);
105
+ dbLog.info('Fetching DB credentials from Secrets Manager', {
106
+ secret: redactedArn,
107
+ region: region ?? 'sdk-default',
108
+ timeoutMs,
109
+ });
110
+ let result;
111
+ try {
112
+ result = await client.send(new sm.GetSecretValueCommand({ SecretId: arn }), { abortSignal: controller.signal });
113
+ }
114
+ catch (err) {
115
+ const durationMs = Date.now() - startedAt;
116
+ const aborted = controller.signal.aborted;
117
+ const errorName = err instanceof Error ? err.name : undefined;
118
+ const errorMessage = err instanceof Error ? err.message : String(err);
119
+ dbLog.error('Failed to fetch DB credentials from Secrets Manager', {
120
+ secret: redactedArn,
121
+ durationMs,
122
+ timedOut: aborted,
123
+ errorName,
124
+ errorMessage,
125
+ });
126
+ if (aborted) {
127
+ // Re-throw with an actionable hint. The most common cause for a
128
+ // VPC-attached Lambda is no route to Secrets Manager — either NAT
129
+ // is unhealthy or there is no SM VPC interface endpoint.
130
+ throw new Error(`[venturekit/data] Timed out (${timeoutMs} ms) fetching DB credentials ` +
131
+ `from Secrets Manager (secret: ${redactedArn}). If the Lambda runs in ` +
132
+ `a VPC, verify it has a route to Secrets Manager: a working NAT gateway/instance, ` +
133
+ `or a com.amazonaws.<region>.secretsmanager VPC interface endpoint. ` +
134
+ `Override the timeout via DB_SECRET_FETCH_TIMEOUT_MS.`);
135
+ }
136
+ throw err;
137
+ }
138
+ finally {
139
+ clearTimeout(timer);
140
+ }
141
+ const fetchDurationMs = Date.now() - startedAt;
61
142
  const raw = result.SecretString;
62
143
  if (!raw) {
63
144
  throw new Error(`[venturekit/data] DB_SECRET_ARN points at a secret with no SecretString: ${arn}`);
@@ -70,23 +151,38 @@ async function fetchAndApply(arn) {
70
151
  throw new Error('[venturekit/data] DB_SECRET_ARN value is not JSON. ' +
71
152
  'Expected an RDS-style secret with at least { username, password } fields.');
72
153
  }
154
+ // Track which env slots we populated so the success log makes it
155
+ // obvious whether host/port/name came from the secret or were already
156
+ // wired in by infra. Operators debugging "why is my DB_HOST empty"
157
+ // can grep for this line and see the answer at a glance.
158
+ const slotsApplied = [];
73
159
  if (!process.env.DB_USER && parsed.username) {
74
160
  process.env.DB_USER = String(parsed.username);
161
+ slotsApplied.push('DB_USER');
75
162
  }
76
163
  if (!process.env.DB_PASSWORD && parsed.password) {
77
164
  process.env.DB_PASSWORD = String(parsed.password);
165
+ slotsApplied.push('DB_PASSWORD');
78
166
  }
79
167
  if (!process.env.DB_HOST && parsed.host) {
80
168
  process.env.DB_HOST = String(parsed.host);
169
+ slotsApplied.push('DB_HOST');
81
170
  }
82
171
  if (!process.env.DB_PORT &&
83
172
  parsed.port !== undefined &&
84
173
  parsed.port !== null) {
85
174
  process.env.DB_PORT = String(parsed.port);
175
+ slotsApplied.push('DB_PORT');
86
176
  }
87
177
  if (!process.env.DB_NAME && parsed.dbname) {
88
178
  process.env.DB_NAME = String(parsed.dbname);
179
+ slotsApplied.push('DB_NAME');
89
180
  }
181
+ dbLog.info('DB credentials applied to env', {
182
+ secret: redactedArn,
183
+ durationMs: fetchDurationMs,
184
+ slotsApplied,
185
+ });
90
186
  }
91
187
  /**
92
188
  * Reset the memoized resolution. Test-only escape hatch — exposed under
@@ -1 +1 @@
1
- {"version":3,"file":"secret.js","sourceRoot":"","sources":["../../src/query/secret.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"secret.js","sourceRoot":"","sources":["../../src/query/secret.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/query/transaction.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,IAAI,CAAC;AAElD,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7D,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACjC,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,EAAE,EACvB,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAChC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CAAC;IACd,6BAA6B;IAC7B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,gCAAgC;IAChC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAUnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAoBzF;AAaD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAAC;AACd,wBAAsB,eAAe,CAAC,CAAC,EACrC,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAAC;AAkDd;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CA6BhE"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/query/transaction.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,IAAI,CAAC;AAElD,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAc7D,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACjC,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,EAAE,EACvB,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAChC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CAAC;IACd,6BAA6B;IAC7B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,gCAAgC;IAChC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAUnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAwCzF;AAaD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAAC;AACd,wBAAsB,eAAe,CAAC,CAAC,EACrC,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAAC;AAkDd;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAkDhE"}
@@ -9,6 +9,16 @@
9
9
  import { getPool } from './pool.js';
10
10
  import { mapResults } from './mapper.js';
11
11
  import { applyDbSecretToEnv } from './secret.js';
12
+ import { dbLog } from '../internal/logger.js';
13
+ /**
14
+ * Same single-line clip used by `query()`'s logger. Duplicated here
15
+ * (rather than imported from `./index.js`) to avoid a cycle between
16
+ * the query barrel and the transaction module.
17
+ */
18
+ function previewSql(sql) {
19
+ const single = sql.replace(/\s+/g, ' ').trim();
20
+ return single.length > 120 ? `${single.slice(0, 117)}...` : single;
21
+ }
12
22
  /**
13
23
  * Default statement timeout (ms) — keeps Lambdas from hanging on rogue queries
14
24
  * while staying generous enough for normal OLTP work. Override per-call via
@@ -49,7 +59,27 @@ export async function beginTransaction(options) {
49
59
  // memoized — see `applyDbSecretToEnv` for details.
50
60
  await applyDbSecretToEnv();
51
61
  const pool = getPool();
52
- const client = await pool.connect();
62
+ // `pool.connect()` is the most likely place a misconfigured network
63
+ // surfaces (security group blocking 5432, RDS in a different VPC,
64
+ // wrong DB_HOST). Wrapping it in start/error logs gives operators a
65
+ // breadcrumb between "Creating Postgres pool" and the eventual
66
+ // Lambda timeout that they otherwise wouldn't have.
67
+ const connectStartedAt = Date.now();
68
+ let client;
69
+ try {
70
+ client = await pool.connect();
71
+ }
72
+ catch (err) {
73
+ const durationMs = Date.now() - connectStartedAt;
74
+ const errAny = err;
75
+ dbLog.error('Postgres pool.connect() failed', {
76
+ durationMs,
77
+ errorName: err instanceof Error ? err.name : undefined,
78
+ errorMessage: err instanceof Error ? err.message : String(err),
79
+ pgCode: errAny.code,
80
+ });
81
+ throw err;
82
+ }
53
83
  await client.query('BEGIN');
54
84
  const timeoutMs = resolveStatementTimeout(options);
55
85
  if (timeoutMs > 0) {
@@ -123,7 +153,29 @@ export async function withTransaction(fnOrOuter, fnOrOptions, maybeOptions) {
123
153
  export function buildTransaction(client) {
124
154
  return {
125
155
  async query(sqlQuery, queryParams, resultsMapper, mapperOptions) {
126
- const res = await client.query(sqlQuery, queryParams);
156
+ const startedAt = Date.now();
157
+ let res;
158
+ try {
159
+ res = await client.query(sqlQuery, queryParams);
160
+ }
161
+ catch (err) {
162
+ // Surface pg's structured error fields just like the top-level
163
+ // `query()` does, so transactional and non-transactional code
164
+ // paths emit identical error breadcrumbs.
165
+ const durationMs = Date.now() - startedAt;
166
+ const errAny = err;
167
+ dbLog.error('Postgres transactional query failed', {
168
+ durationMs,
169
+ sqlPreview: previewSql(sqlQuery),
170
+ paramCount: queryParams?.length ?? 0,
171
+ errorName: err instanceof Error ? err.name : undefined,
172
+ errorMessage: err instanceof Error ? err.message : String(err),
173
+ pgCode: errAny.code,
174
+ pgSeverity: errAny.severity,
175
+ pgRoutine: errAny.routine,
176
+ });
177
+ throw err;
178
+ }
127
179
  const mapped = mapResults(res.rows, mapperOptions);
128
180
  return resultsMapper ? resultsMapper(mapped) : mapped;
129
181
  },
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/query/transaction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/query/transaction.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venturekit/data",
3
- "version": "0.0.0-dev.20260505153744",
3
+ "version": "0.0.0-dev.20260505164519",
4
4
  "description": "Database and data layer for VentureKit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@aws-sdk/client-secrets-manager": "^3.500.0",
29
- "@venturekit/core": "0.0.0-dev.20260505153744",
29
+ "@venturekit/core": "0.0.0-dev.20260505164519",
30
30
  "pg": "^8.12.0"
31
31
  },
32
32
  "devDependencies": {