@pineliner/odb-client 1.0.6 → 1.0.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/core/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAmB,WAAW,EAAE,MAAM,aAAa,CAAA;AAG9E;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,aAAa;IAajC;;OAEG;IACG,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,GAAG,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAoD9E;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAqB9B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC;IAqBrC;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;YACW,WAAW;IAgDzB;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,UAAU;IAOtD;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC;CAGrC"}
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/core/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAmB,WAAW,EAAE,MAAM,aAAa,CAAA;AAG9E;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,aAAa;IAajC;;OAEG;IACG,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,GAAG,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAqD9E;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAqB9B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC;IAqBrC;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;YACW,WAAW;IAgDzB;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,UAAU;IAOtD;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC;CAGrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"bun-sqlite.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/bun-sqlite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAGV,eAAe,EAChB,MAAM,UAAU,CAAA;AAEjB;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,QAAQ,CAAC,IAAI,EAAG,YAAY,CAAS;IACrC,OAAO,CAAC,MAAM,CAAiB;gBAEnB,MAAM,EAAE,eAAe;IAI7B,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IASrD,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAapC"}
1
+ {"version":3,"file":"bun-sqlite.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/bun-sqlite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAGV,eAAe,EAChB,MAAM,UAAU,CAAA;AAYjB;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,QAAQ,CAAC,IAAI,EAAG,YAAY,CAAS;IACrC,OAAO,CAAC,MAAM,CAAiB;gBAEnB,MAAM,EAAE,eAAe;IAI7B,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IASrD,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAapC"}
@@ -1 +1 @@
1
- {"version":3,"file":"libsql.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/libsql.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAGV,YAAY,EACb,MAAM,UAAU,CAAA;AAEjB;;;GAGG;AACH,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAS;IACjC,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,EAAE,YAAY;IAI1B,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IAUlD,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAYpC"}
1
+ {"version":3,"file":"libsql.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/libsql.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAGV,YAAY,EACb,MAAM,UAAU,CAAA;AAYjB;;;GAGG;AACH,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAS;IACjC,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,EAAE,YAAY;IAI1B,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IAUlD,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAYpC"}
@@ -1,3 +1,4 @@
1
+ import { ServiceClient } from '../../service/service-client';
1
2
  import type { DatabaseAdapter, Connection, ODBLiteConfig } from '../types';
2
3
  /**
3
4
  * ODB-Lite adapter for DatabaseManager
@@ -6,7 +7,7 @@ import type { DatabaseAdapter, Connection, ODBLiteConfig } from '../types';
6
7
  export declare class ODBLiteAdapter implements DatabaseAdapter {
7
8
  readonly type: "odblite";
8
9
  private config;
9
- private serviceClient;
10
+ serviceClient: ServiceClient;
10
11
  constructor(config: ODBLiteConfig);
11
12
  connect(config: any): Promise<Connection>;
12
13
  disconnect(tenantId?: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"odblite.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/odblite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAGV,aAAa,EACd,MAAM,UAAU,CAAA;AAEjB;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAS;IAClC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAe;gBAExB,MAAM,EAAE,aAAa;IAQ3B,OAAO,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC;IA2BzC,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"}
1
+ {"version":3,"file":"odblite.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/odblite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAE5D,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAGV,aAAa,EACd,MAAM,UAAU,CAAA;AAYjB;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAS;IAClC,OAAO,CAAC,MAAM,CAAe;IACtB,aAAa,EAAE,aAAa,CAAA;gBAEvB,MAAM,EAAE,aAAa;IAQ3B,OAAO,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC;IAgCzC,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAQpC"}
@@ -1,6 +1,8 @@
1
1
  export { DatabaseManager } from './manager';
2
2
  export { parseSQL, splitSQLStatements } from './sql-parser';
3
3
  export type { ParsedStatements, SQLParserOptions } from './sql-parser';
4
+ export { sql, raw, empty, fragment, join, set, where, convertTemplateToQuery } from './sql-template';
5
+ export type { SqlQuery, SqlFragment } from './sql-template';
4
6
  export { BunSQLiteAdapter } from './adapters/bun-sqlite';
5
7
  export { LibSQLAdapter } from './adapters/libsql';
6
8
  export { ODBLiteAdapter } from './adapters/odblite';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAG3C,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC3D,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGnD,YAAY,EAEV,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,iBAAiB,EAGjB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,aAAa,EAGb,UAAU,GACX,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAG3C,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC3D,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGtE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACpG,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGnD,YAAY,EAEV,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,iBAAiB,EAGjB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,aAAa,EAGb,UAAU,GACX,MAAM,SAAS,CAAA"}
@@ -0,0 +1,432 @@
1
+ /**
2
+ * SQL Template Tag Converter - postgres.js Compatible
3
+ *
4
+ * Provides postgres.js-style SQL template literals and helper methods
5
+ * for safe, composable SQL query building.
6
+ *
7
+ * ## Basic Usage
8
+ *
9
+ * ```typescript
10
+ * import { getConnection, sql } from '@pineliner/odb-client'
11
+ *
12
+ * const db = await getConnection('tenant-id')
13
+ *
14
+ * // Simple query with parameters
15
+ * const users = await db`SELECT * FROM users WHERE id = ${userId}`
16
+ *
17
+ * // Use sql() helper for dynamic parts
18
+ * const columns = ['name', 'email', 'age']
19
+ * const result = await db`SELECT ${sql(columns)} FROM users`
20
+ * ```
21
+ *
22
+ * ## Supported Patterns (postgres.js Compatible)
23
+ *
24
+ * ### 1. Query Parameters (Basic Template Literals)
25
+ * ```typescript
26
+ * // Parameters are automatically escaped
27
+ * await db`SELECT * FROM users WHERE name = ${name} AND age > ${age}`
28
+ * // → SELECT * FROM users WHERE name = ? AND age = ? [name, age]
29
+ * ```
30
+ *
31
+ * ### 2. Dynamic Column Selection
32
+ * ```typescript
33
+ * const columns = ['name', 'age']
34
+ *
35
+ * await db`
36
+ * SELECT ${sql(columns)}
37
+ * FROM users
38
+ * `
39
+ * // → SELECT name, age FROM users
40
+ * ```
41
+ *
42
+ * ### 3. Dynamic Inserts (Single Object)
43
+ * ```typescript
44
+ * const user = {
45
+ * name: 'Murray',
46
+ * age: 68
47
+ * }
48
+ *
49
+ * await db`INSERT INTO users ${sql(user, 'name', 'age')}`
50
+ * // → INSERT INTO users (name, age) VALUES (?, ?)
51
+ * // ["Murray", 68]
52
+ *
53
+ * // Columns can also be given with an array
54
+ * const columns = ['name', 'age']
55
+ * await db`INSERT INTO users ${sql(user, columns)}`
56
+ * ```
57
+ *
58
+ * ### 4. Bulk Inserts (Array of Objects)
59
+ * ```typescript
60
+ * const users = [
61
+ * { name: 'Murray', age: 68, garbage: 'ignore' },
62
+ * { name: 'Walter', age: 80 }
63
+ * ]
64
+ *
65
+ * await db`INSERT INTO users ${sql(users, 'name', 'age')}`
66
+ * // → INSERT INTO users (name, age) VALUES (?, ?), (?, ?)
67
+ * // ["Murray", 68, "Walter", 80]
68
+ *
69
+ * // Omit column names to use all object keys
70
+ * await db`INSERT INTO users ${sql(users)}`
71
+ * // → INSERT INTO users (name, age, garbage) VALUES (?, ?, ?), (?, ?, ?)
72
+ * ```
73
+ *
74
+ * ### 5. Dynamic Column Updates
75
+ * ```typescript
76
+ * const user = {
77
+ * id: 1,
78
+ * name: 'Murray',
79
+ * age: 68
80
+ * }
81
+ *
82
+ * await db`
83
+ * UPDATE users
84
+ * SET ${set(user, 'name', 'age')}
85
+ * WHERE user_id = ${user.id}
86
+ * `
87
+ * // → UPDATE users SET name = ?, age = ? WHERE user_id = ?
88
+ * // ["Murray", 68, 1]
89
+ *
90
+ * // Or using set() helper
91
+ * await db`
92
+ * UPDATE users
93
+ * SET ${set({ name: user.name, age: user.age })}
94
+ * WHERE user_id = ${user.id}
95
+ * `
96
+ * ```
97
+ *
98
+ * ### 6. Multiple Updates in One Query
99
+ * ```typescript
100
+ * const users = [
101
+ * [1, 'John', 34],
102
+ * [2, 'Jane', 27],
103
+ * ]
104
+ *
105
+ * await db`
106
+ * UPDATE users
107
+ * SET name = update_data.name, age = (update_data.age)::int
108
+ * FROM (VALUES ${sql(users)}) AS update_data (id, name, age)
109
+ * WHERE users.id = (update_data.id)::int
110
+ * RETURNING users.id, users.name, users.age
111
+ * `
112
+ * // → UPDATE users SET ... FROM (VALUES (?, ?, ?), (?, ?, ?)) AS update_data ...
113
+ * // [1, "John", 34, 2, "Jane", 27]
114
+ * ```
115
+ *
116
+ * ### 7. Dynamic WHERE IN Clause
117
+ * ```typescript
118
+ * const users = await db`
119
+ * SELECT *
120
+ * FROM users
121
+ * WHERE age IN ${sql([68, 75, 23])}
122
+ * `
123
+ * // → SELECT * FROM users WHERE age IN (?, ?, ?)
124
+ * // [68, 75, 23]
125
+ *
126
+ * // Or use array directly in template
127
+ * await db`SELECT * FROM users WHERE age IN ${[68, 75, 23]}`
128
+ * ```
129
+ *
130
+ * ### 8. Dynamic Values in SELECT
131
+ * ```typescript
132
+ * const [{ a, b, c }] = await db`
133
+ * SELECT *
134
+ * FROM (VALUES ${sql(['a', 'b', 'c'])}) AS x(a, b, c)
135
+ * `
136
+ * // Note: For VALUES with string literals, use the array directly or wrap in sql()
137
+ * ```
138
+ *
139
+ * ### 9. Conditional Fragments
140
+ * ```typescript
141
+ * const isAdmin = true
142
+ * const minAge = 25
143
+ *
144
+ * await db`
145
+ * SELECT * FROM users
146
+ * WHERE is_active = 1
147
+ * ${isAdmin ? fragment`AND role = 'admin'` : empty()}
148
+ * ${minAge ? fragment`AND age >= ${minAge}` : empty()}
149
+ * `
150
+ * // → SELECT * FROM users WHERE is_active = 1 AND role = 'admin' AND age >= ?
151
+ * // [25]
152
+ * ```
153
+ *
154
+ * ### 10. Transactions
155
+ * ```typescript
156
+ * await db.begin(async tx => {
157
+ * await tx`INSERT INTO users ${sql(user, 'name', 'email')}`
158
+ * await tx`UPDATE accounts SET balance = balance - ${amount} WHERE user_id = ${userId}`
159
+ * })
160
+ * // Automatically commits on success, rolls back on error
161
+ * ```
162
+ *
163
+ * ### 11. Raw SQL (use with caution)
164
+ * ```typescript
165
+ * const tableName = 'users' // From trusted source only!
166
+ * await db`SELECT * FROM ${raw(tableName)} WHERE id = ${userId}`
167
+ * // → SELECT * FROM users WHERE id = ?
168
+ * // [userId]
169
+ * ```
170
+ *
171
+ * ### 12. Reusable Fragments
172
+ * ```typescript
173
+ * const activeUsers = fragment`is_active = 1 AND is_deleted = 0`
174
+ * const olderThan = (age: number) => fragment`age > ${age}`
175
+ *
176
+ * await db`
177
+ * SELECT * FROM users
178
+ * WHERE ${activeUsers}
179
+ * AND ${olderThan(25)}
180
+ * `
181
+ * ```
182
+ *
183
+ * ## API Reference
184
+ *
185
+ * - `sql(columns: string[])` - Dynamic column list for SELECT
186
+ * - `sql(object, ...keys)` - INSERT format from single object
187
+ * - `sql(objects[], ...keys)` - Bulk INSERT from array of objects
188
+ * - `sql(array[][])` - Bulk insert values (2D array)
189
+ * - `fragment` `` ` - Template tag for reusable query fragments
190
+ * - `raw(string)` - Unescaped SQL fragment (dangerous!)
191
+ * - `empty()` - Empty SQL fragment for conditionals
192
+ * - `set(object)` - Generate SET clause for UPDATE
193
+ * - `where(object)` - Generate WHERE clause with AND conditions
194
+ * - `join(fragments[], separator)` - Combine multiple fragments
195
+ */
196
+ export interface SqlQuery {
197
+ sql: string;
198
+ args: any[];
199
+ }
200
+ export interface SqlFragment {
201
+ _isSqlFragment: true;
202
+ sql: string;
203
+ args: any[];
204
+ }
205
+ /**
206
+ * Convert template literal to parameterized query
207
+ *
208
+ * @param strings - Template literal strings
209
+ * @param values - Template literal values
210
+ * @returns Object with sql string and args array
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * const query = convertTemplateToQuery(
215
+ * ['SELECT * FROM users WHERE id = ', ' AND name = ', ''],
216
+ * [userId, userName]
217
+ * )
218
+ * // → { sql: "SELECT * FROM users WHERE id = ? AND name = ?", args: [userId, userName] }
219
+ * ```
220
+ */
221
+ export declare function convertTemplateToQuery(strings: TemplateStringsArray, values: any[]): SqlQuery;
222
+ /**
223
+ * sql() helper - postgres.js compatible
224
+ *
225
+ * Multi-purpose SQL helper that adapts based on arguments.
226
+ *
227
+ * @param value - Array, object, array of objects, or 2D array
228
+ * @param keys - Optional keys (string[] or ...string)
229
+ * @returns SQL fragment
230
+ *
231
+ * @example Dynamic column selection
232
+ * ```typescript
233
+ * sql(['name', 'email', 'age'])
234
+ * // → "name, email, age"
235
+ * ```
236
+ *
237
+ * @example Single object INSERT
238
+ * ```typescript
239
+ * sql({ name: 'John', age: 30 }, 'name', 'age')
240
+ * // → "(name, age) VALUES (?, ?)" with args ["John", 30]
241
+ * ```
242
+ *
243
+ * @example Single object UPDATE
244
+ * ```typescript
245
+ * sql({ name: 'John', age: 30 }, 'name', 'age')
246
+ * // Context determines if INSERT or UPDATE format
247
+ * // For UPDATE: "name" = ?, "age" = ? with args ["John", 30]
248
+ * // For INSERT: (name, age) VALUES (?, ?) with args ["John", 30]
249
+ * ```
250
+ *
251
+ * @example Array of objects (bulk insert)
252
+ * ```typescript
253
+ * sql([{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }], 'name', 'age')
254
+ * // → "(name, age) VALUES (?, ?), (?, ?)" with args ["John", 30, "Jane", 25]
255
+ * ```
256
+ *
257
+ * @example 2D array (bulk insert values)
258
+ * ```typescript
259
+ * sql([[1, 'John'], [2, 'Jane']])
260
+ * // → "(?, ?), (?, ?)" with args [1, "John", 2, "Jane"]
261
+ * ```
262
+ *
263
+ * @example VALUES clause
264
+ * ```typescript
265
+ * sql(['a', 'b', 'c'])
266
+ * // In SELECT context: "a, b, c"
267
+ * // In VALUES context: You'd use the array directly in template
268
+ * ```
269
+ */
270
+ export declare function sql(value: any, ...keys: (string | string[])[]): SqlFragment;
271
+ /**
272
+ * Create an empty SQL fragment
273
+ *
274
+ * Useful for conditional queries where you want to add nothing.
275
+ *
276
+ * @returns Empty SQL fragment
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * const isFiltered = false
281
+ * await db`
282
+ * SELECT * FROM users
283
+ * WHERE is_active = 1
284
+ * ${isFiltered ? sql`AND age > 25` : empty()}
285
+ * `
286
+ * ```
287
+ */
288
+ export declare function empty(): SqlFragment;
289
+ /**
290
+ * Create a raw SQL fragment (use with extreme caution!)
291
+ *
292
+ * This bypasses parameterization and inserts the string directly into SQL.
293
+ * **WARNING**: Can lead to SQL injection if used with untrusted input!
294
+ *
295
+ * Only use for:
296
+ * - Table/column names from trusted sources
297
+ * - SQL keywords or operators
298
+ * - Pre-validated identifiers
299
+ *
300
+ * @param value - Raw SQL string (must be from trusted source)
301
+ * @returns SQL fragment with no parameters
302
+ *
303
+ * @example Safe usage (trusted table name)
304
+ * ```typescript
305
+ * const tableName = 'users' // From config, not user input!
306
+ * await db`SELECT * FROM ${raw(tableName)} WHERE id = ${userId}`
307
+ * ```
308
+ *
309
+ * @example UNSAFE - Never do this!
310
+ * ```typescript
311
+ * // ❌ DANGEROUS - SQL injection vulnerability!
312
+ * const userInput = req.query.table // From user!
313
+ * await db`SELECT * FROM ${raw(userInput)}` // Don't do this!
314
+ * ```
315
+ */
316
+ export declare function raw(value: string): SqlFragment;
317
+ /**
318
+ * Create a reusable SQL fragment from template literal
319
+ *
320
+ * Useful for building composable query parts that can be reused.
321
+ *
322
+ * @param strings - Template literal strings
323
+ * @param values - Template literal values
324
+ * @returns SQL fragment that can be embedded in other queries
325
+ *
326
+ * @example Basic fragment
327
+ * ```typescript
328
+ * const activeUsers = fragment`is_active = 1 AND is_deleted = 0`
329
+ *
330
+ * await db`SELECT * FROM users WHERE ${activeUsers}`
331
+ * await db`SELECT COUNT(*) FROM users WHERE ${activeUsers}`
332
+ * ```
333
+ *
334
+ * @example Parameterized fragment
335
+ * ```typescript
336
+ * const olderThan = (age: number) => fragment`age > ${age}`
337
+ * const youngerThan = (age: number) => fragment`age < ${age}`
338
+ *
339
+ * await db`
340
+ * SELECT * FROM users
341
+ * WHERE ${olderThan(25)} AND ${youngerThan(65)}
342
+ * `
343
+ * ```
344
+ *
345
+ * @example Complex reusable conditions
346
+ * ```typescript
347
+ * const validUser = fragment`
348
+ * is_active = 1
349
+ * AND is_deleted = 0
350
+ * AND is_verified = 1
351
+ * AND banned_at IS NULL
352
+ * `
353
+ *
354
+ * const adminUser = fragment`${validUser} AND role = 'admin'`
355
+ *
356
+ * await db`SELECT * FROM users WHERE ${adminUser}`
357
+ * ```
358
+ */
359
+ export declare function fragment(strings: TemplateStringsArray, ...values: any[]): SqlFragment;
360
+ /**
361
+ * Combine multiple SQL fragments
362
+ *
363
+ * @param fragments - Array of SQL fragments
364
+ * @param separator - Optional separator (default: ', ')
365
+ * @returns Combined SQL fragment
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * const conditions = [
370
+ * sql`age > ${25}`,
371
+ * sql`country = ${'US'}`,
372
+ * sql`is_active = 1`
373
+ * ]
374
+ *
375
+ * await db`
376
+ * SELECT * FROM users
377
+ * WHERE ${join(conditions, ' AND ')}
378
+ * `
379
+ * ```
380
+ */
381
+ export declare function join(fragments: SqlFragment[], separator?: string): SqlFragment;
382
+ /**
383
+ * Create SET clause for UPDATE queries
384
+ *
385
+ * @param data - Object with column: value pairs
386
+ * @param keys - Optional array of keys to include (filters the object)
387
+ * @returns SQL fragment for SET clause
388
+ *
389
+ * @example All keys
390
+ * ```typescript
391
+ * const updates = { name: 'John Doe', age: 31, updated_at: new Date() }
392
+ *
393
+ * await db`
394
+ * UPDATE users
395
+ * SET ${set(updates)}
396
+ * WHERE id = ${userId}
397
+ * `
398
+ * // → UPDATE users SET name = ?, age = ?, updated_at = ? WHERE id = ?
399
+ * ```
400
+ *
401
+ * @example Specific keys only
402
+ * ```typescript
403
+ * const user = { id: 1, name: 'Murray', age: 68 }
404
+ *
405
+ * await db`
406
+ * UPDATE users
407
+ * SET ${set(user, 'name', 'age')}
408
+ * WHERE user_id = ${user.id}
409
+ * `
410
+ * // → UPDATE users SET name = ?, age = ? WHERE user_id = ?
411
+ * ```
412
+ */
413
+ export declare function set(data: Record<string, any>, ...keys: string[]): SqlFragment;
414
+ /**
415
+ * Create WHERE clause from object (AND conditions)
416
+ *
417
+ * @param conditions - Object with column: value pairs
418
+ * @returns SQL fragment for WHERE clause
419
+ *
420
+ * @example
421
+ * ```typescript
422
+ * const filters = { is_active: 1, role: 'admin', age: 30 }
423
+ *
424
+ * await db`
425
+ * SELECT * FROM users
426
+ * WHERE ${where(filters)}
427
+ * `
428
+ * // → SELECT * FROM users WHERE is_active = ? AND role = ? AND age = ?
429
+ * ```
430
+ */
431
+ export declare function where(conditions: Record<string, any>): SqlFragment;
432
+ //# sourceMappingURL=sql-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-template.d.ts","sourceRoot":"","sources":["../../src/database/sql-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkMG;AAEH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,GAAG,EAAE,CAAA;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,IAAI,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,GAAG,EAAE,CAAA;CACZ;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,MAAM,EAAE,GAAG,EAAE,GACZ,QAAQ,CAyCV;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,GAAG,CACjB,KAAK,EAAE,GAAG,EACV,GAAG,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAC7B,WAAW,CA2Fb;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,IAAI,WAAW,CAMnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAM9C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,GAAG,EAAE,GACf,WAAW,CAMb;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,SAAS,GAAE,MAAa,GAAG,WAAW,CAapF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,GAAG,CACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,GAAG,IAAI,EAAE,MAAM,EAAE,GAChB,WAAW,CAuBb;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,WAAW,CAclE"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * SQL Template Examples - postgres.js Compatible Usage
3
+ *
4
+ * This file demonstrates all supported postgres.js patterns with our sql-template implementation.
5
+ * These examples show the exact usage from postgres.js documentation.
6
+ *
7
+ * NOTE: This file is for documentation only - not included in build
8
+ * @file sql-template.examples.ts
9
+ */
10
+ export {};
11
+ /**
12
+ * All examples demonstrate postgres.js-compatible patterns:
13
+ *
14
+ * ✅ Template literals with automatic parameterization
15
+ * ✅ sql(columns[]) for dynamic column selection
16
+ * ✅ sql(object, ...keys) for INSERT statements
17
+ * ✅ sql(objects[], ...keys) for bulk INSERT
18
+ * ✅ sql(array[][]) for VALUES clause
19
+ * ✅ Array values for IN clauses
20
+ * ✅ set(object, ...keys) for UPDATE SET clauses
21
+ * ✅ where(object) for WHERE conditions
22
+ * ✅ fragment`` for reusable query parts
23
+ * ✅ empty() for conditional fragments
24
+ * ✅ raw() for unescaped SQL (use carefully!)
25
+ * ✅ join(fragments[], separator) for combining fragments
26
+ * ✅ Transactions with begin()
27
+ */
28
+ //# sourceMappingURL=sql-template.examples.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-template.examples.d.ts","sourceRoot":"","sources":["../../src/database/sql-template.examples.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;AAkVH;;;;;;;;;;;;;;;;GAgBG"}
@@ -17,9 +17,15 @@ export interface QueryResult<T = any> {
17
17
  /**
18
18
  * Unified database connection interface
19
19
  * All backends implement this through adapters
20
+ *
21
+ * postgres.js-compatible API:
22
+ * - sql`...` returns rows array directly (not QueryResult)
23
+ * - sql() can be called as helper function for fragments
24
+ * - sql.empty(), sql.raw(), etc. are available as helper methods
20
25
  */
21
26
  export interface Connection {
22
- sql<T = any>(strings: TemplateStringsArray, ...values: any[]): Promise<QueryResult<T>>;
27
+ sql<T = any>(strings: TemplateStringsArray, ...values: any[]): Promise<T[]>;
28
+ sql(value: any, ...keys: string[]): any;
23
29
  query<T = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
24
30
  execute(sql: string | {
25
31
  sql: string;
@@ -29,6 +35,7 @@ export interface Connection {
29
35
  transaction<T>(fn: (tx: Connection) => Promise<T>): Promise<T>;
30
36
  begin<T>(fn: (tx: Connection) => Promise<T>): Promise<T>;
31
37
  close(): Promise<void>;
38
+ createORM?(): any;
32
39
  databaseHash?: string;
33
40
  databaseName?: string;
34
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"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"}