@venturekit/data 0.0.0-dev.20260312012510 → 0.0.0-dev.20260329102450

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.
@@ -2,6 +2,47 @@
2
2
  * Query Module
3
3
  *
4
4
  * Provides database querying, result mapping, and transaction support.
5
+ *
6
+ * ## Result Mapping
7
+ *
8
+ * All queries automatically run through `mapResults()` which converts
9
+ * dot-notation column aliases into nested objects. For example:
10
+ *
11
+ * ```sql
12
+ * SELECT p.id, p.title, u.id AS "author.id", u.name AS "author.name"
13
+ * FROM posts p JOIN users u ON u.id = p.author_id
14
+ * ```
15
+ *
16
+ * Returns: `[{ id: '1', title: 'Hello', author: { id: '5', name: 'Alice' } }]`
17
+ *
18
+ * ## Custom Result Mappers
19
+ *
20
+ * The optional third argument to `query()` lets you transform the mapped rows
21
+ * into any shape. The mapper receives the already-nested rows (after dot-notation
22
+ * expansion) and must return the final value:
23
+ *
24
+ * ```typescript
25
+ * // Extract a single column
26
+ * const titles = await query<string[]>(
27
+ * 'SELECT title FROM posts',
28
+ * [],
29
+ * (rows) => rows.map(r => r.title as string),
30
+ * );
31
+ *
32
+ * // Return a single row or null
33
+ * const post = await query<Post | null>(
34
+ * 'SELECT * FROM posts WHERE id = $1',
35
+ * [id],
36
+ * (rows) => (rows[0] as Post) ?? null,
37
+ * );
38
+ * ```
39
+ *
40
+ * ## Error Handling
41
+ *
42
+ * - Throws the underlying `pg` driver error on connection/query failures.
43
+ * - If `resultsMapper` throws, that error propagates unchanged.
44
+ * - An empty result set is **not** an error — it returns `[]` (or whatever
45
+ * your mapper produces for an empty array).
5
46
  */
6
47
  import type { ResultsMapper } from './transaction.js';
7
48
  export { getPool } from './pool.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,GAC/B,OAAO,CAAC,CAAC,CAAC,CAKZ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,GAC/B,OAAO,CAAC,CAAC,CAAC,CAKZ"}
@@ -2,6 +2,47 @@
2
2
  * Query Module
3
3
  *
4
4
  * Provides database querying, result mapping, and transaction support.
5
+ *
6
+ * ## Result Mapping
7
+ *
8
+ * All queries automatically run through `mapResults()` which converts
9
+ * dot-notation column aliases into nested objects. For example:
10
+ *
11
+ * ```sql
12
+ * SELECT p.id, p.title, u.id AS "author.id", u.name AS "author.name"
13
+ * FROM posts p JOIN users u ON u.id = p.author_id
14
+ * ```
15
+ *
16
+ * Returns: `[{ id: '1', title: 'Hello', author: { id: '5', name: 'Alice' } }]`
17
+ *
18
+ * ## Custom Result Mappers
19
+ *
20
+ * The optional third argument to `query()` lets you transform the mapped rows
21
+ * into any shape. The mapper receives the already-nested rows (after dot-notation
22
+ * expansion) and must return the final value:
23
+ *
24
+ * ```typescript
25
+ * // Extract a single column
26
+ * const titles = await query<string[]>(
27
+ * 'SELECT title FROM posts',
28
+ * [],
29
+ * (rows) => rows.map(r => r.title as string),
30
+ * );
31
+ *
32
+ * // Return a single row or null
33
+ * const post = await query<Post | null>(
34
+ * 'SELECT * FROM posts WHERE id = $1',
35
+ * [id],
36
+ * (rows) => (rows[0] as Post) ?? null,
37
+ * );
38
+ * ```
39
+ *
40
+ * ## Error Handling
41
+ *
42
+ * - Throws the underlying `pg` driver error on connection/query failures.
43
+ * - If `resultsMapper` throws, that error propagates unchanged.
44
+ * - An empty result set is **not** an error — it returns `[]` (or whatever
45
+ * your mapper produces for an empty array).
5
46
  */
6
47
  import { getPool } from './pool.js';
7
48
  import { mapResults } from './mapper.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAU,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjD,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;IAEhC,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,CAAC,CAAC;IACpC,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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAU,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjD,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;IAEhC,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,CAAC,CAAC;IACpC,OAAO,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAsB,CAAC;AACxE,CAAC"}
@@ -2,13 +2,61 @@
2
2
  * Result Mapper
3
3
  *
4
4
  * Maps flat database rows with dot-notation column aliases
5
- * into nested objects.
5
+ * into nested objects. This is applied automatically by `query()`.
6
6
  *
7
- * Example:
8
- * { "id": 1, "author.id": 5, "author.name": "Alice" }
9
- * becomes
10
- * { id: 1, author: { id: 5, name: "Alice" } }
7
+ * ## How it works
8
+ *
9
+ * Column aliases containing dots are split and turned into nested objects:
10
+ *
11
+ * ```
12
+ * { "id": 1, "author.id": 5, "author.name": "Alice" }
13
+ * // becomes
14
+ * { id: 1, author: { id: 5, name: "Alice" } }
15
+ * ```
16
+ *
17
+ * Deeper nesting is also supported:
18
+ *
19
+ * ```
20
+ * { "author.address.city": "Paris" }
21
+ * // becomes
22
+ * { author: { address: { city: "Paris" } } }
23
+ * ```
24
+ *
25
+ * Columns **without** dots are passed through unchanged.
26
+ *
27
+ * ## Important notes
28
+ *
29
+ * - `mapResults([])` returns `[]` (empty array is a no-op).
30
+ * - `null` / `undefined` column values are preserved as-is in the output.
31
+ * - If a dot-notation key conflicts with a plain key (e.g. both `author`
32
+ * and `author.id` exist), the nested object wins and the plain value
33
+ * is overwritten. Use unambiguous aliases to avoid this.
34
+ */
35
+ /**
36
+ * Map a single flat row with dot-notation keys into a nested object.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * mapRow({ id: 1, 'author.id': 5, 'author.name': 'Alice' });
41
+ * // => { id: 1, author: { id: 5, name: 'Alice' } }
42
+ * ```
11
43
  */
12
44
  export declare function mapRow(row: Record<string, unknown>): Record<string, unknown>;
45
+ /**
46
+ * Map an array of flat database rows into nested objects.
47
+ *
48
+ * Returns an empty array when given `null`, `undefined`, or `[]`.
49
+ * This is called automatically by `query()` — you only need to call
50
+ * it directly if you are processing raw `pg` results yourself.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * import { mapResults } from '@venturekit/data';
55
+ *
56
+ * const raw = await pool.query('SELECT p.id, u.name AS "author.name" FROM ...');
57
+ * const nested = mapResults(raw.rows);
58
+ * // => [{ id: 1, author: { name: 'Alice' } }, ...]
59
+ * ```
60
+ */
13
61
  export declare function mapResults(rows: Record<string, unknown>[]): Record<string, unknown>[];
14
62
  //# sourceMappingURL=mapper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../src/query/mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwB5E;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAGrF"}
1
+ {"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../src/query/mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwB5E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAGrF"}
@@ -2,12 +2,44 @@
2
2
  * Result Mapper
3
3
  *
4
4
  * Maps flat database rows with dot-notation column aliases
5
- * into nested objects.
5
+ * into nested objects. This is applied automatically by `query()`.
6
6
  *
7
- * Example:
8
- * { "id": 1, "author.id": 5, "author.name": "Alice" }
9
- * becomes
10
- * { id: 1, author: { id: 5, name: "Alice" } }
7
+ * ## How it works
8
+ *
9
+ * Column aliases containing dots are split and turned into nested objects:
10
+ *
11
+ * ```
12
+ * { "id": 1, "author.id": 5, "author.name": "Alice" }
13
+ * // becomes
14
+ * { id: 1, author: { id: 5, name: "Alice" } }
15
+ * ```
16
+ *
17
+ * Deeper nesting is also supported:
18
+ *
19
+ * ```
20
+ * { "author.address.city": "Paris" }
21
+ * // becomes
22
+ * { author: { address: { city: "Paris" } } }
23
+ * ```
24
+ *
25
+ * Columns **without** dots are passed through unchanged.
26
+ *
27
+ * ## Important notes
28
+ *
29
+ * - `mapResults([])` returns `[]` (empty array is a no-op).
30
+ * - `null` / `undefined` column values are preserved as-is in the output.
31
+ * - If a dot-notation key conflicts with a plain key (e.g. both `author`
32
+ * and `author.id` exist), the nested object wins and the plain value
33
+ * is overwritten. Use unambiguous aliases to avoid this.
34
+ */
35
+ /**
36
+ * Map a single flat row with dot-notation keys into a nested object.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * mapRow({ id: 1, 'author.id': 5, 'author.name': 'Alice' });
41
+ * // => { id: 1, author: { id: 5, name: 'Alice' } }
42
+ * ```
11
43
  */
12
44
  export function mapRow(row) {
13
45
  const mapped = {};
@@ -31,6 +63,22 @@ export function mapRow(row) {
31
63
  }
32
64
  return mapped;
33
65
  }
66
+ /**
67
+ * Map an array of flat database rows into nested objects.
68
+ *
69
+ * Returns an empty array when given `null`, `undefined`, or `[]`.
70
+ * This is called automatically by `query()` — you only need to call
71
+ * it directly if you are processing raw `pg` results yourself.
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * import { mapResults } from '@venturekit/data';
76
+ *
77
+ * const raw = await pool.query('SELECT p.id, u.name AS "author.name" FROM ...');
78
+ * const nested = mapResults(raw.rows);
79
+ * // => [{ id: 1, author: { name: 'Alice' } }, ...]
80
+ * ```
81
+ */
34
82
  export function mapResults(rows) {
35
83
  if (!rows || rows.length === 0)
36
84
  return [];
@@ -1 +1 @@
1
- {"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../src/query/mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,UAAU,MAAM,CAAC,GAA4B;IACjD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,OAAO,GAA4B,MAAM,CAAC;YAC9C,IAAI,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;YAE1B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACrB,CAAC;gBACD,OAAO,GAAG,OAAO,CAAC,IAAI,CAA4B,CAAC;gBACnD,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;YACxB,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAA+B;IACxD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../src/query/mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,MAAM,CAAC,GAA4B;IACjD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,OAAO,GAA4B,MAAM,CAAC;YAC9C,IAAI,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;YAE1B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACrB,CAAC;gBACD,OAAO,GAAG,OAAO,CAAC,IAAI,CAA4B,CAAC;gBACnD,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;YACxB,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CAAC,IAA+B;IACxD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venturekit/data",
3
- "version": "0.0.0-dev.20260312012510",
3
+ "version": "0.0.0-dev.20260329102450",
4
4
  "description": "Database and data layer for VentureKit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,7 +25,7 @@
25
25
  }
26
26
  },
27
27
  "dependencies": {
28
- "@venturekit/core": "0.0.0-dev.20260312012510",
28
+ "@venturekit/core": "0.0.0-dev.20260329102450",
29
29
  "pg": "^8.12.0"
30
30
  },
31
31
  "devDependencies": {