@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.
- package/dist/core/http-client.d.ts.map +1 -1
- package/dist/database/adapters/bun-sqlite.d.ts.map +1 -1
- package/dist/database/adapters/libsql.d.ts.map +1 -1
- package/dist/database/adapters/odblite.d.ts +2 -1
- package/dist/database/adapters/odblite.d.ts.map +1 -1
- package/dist/database/index.d.ts +2 -0
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/sql-template.d.ts +432 -0
- package/dist/database/sql-template.d.ts.map +1 -0
- package/dist/database/sql-template.examples.d.ts +28 -0
- package/dist/database/sql-template.examples.d.ts.map +1 -0
- package/dist/database/types.d.ts +8 -1
- package/dist/database/types.d.ts.map +1 -1
- package/dist/index.cjs +1861 -1669
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +779 -653
- package/dist/orm/index.d.ts +228 -0
- package/dist/orm/index.d.ts.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/http-client.ts +1 -0
- package/src/database/adapters/bun-sqlite.ts +73 -15
- package/src/database/adapters/libsql.ts +73 -15
- package/src/database/adapters/odblite.ts +87 -23
- package/src/database/index.ts +4 -0
- package/src/database/sql-template.examples.ts +363 -0
- package/src/database/sql-template.ts +660 -0
- package/src/database/types.ts +15 -3
- package/src/index.ts +31 -0
- package/src/orm/index.ts +538 -0
- package/src/types.ts +2 -0
|
@@ -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;
|
|
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;
|
|
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;
|
|
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
|
-
|
|
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":"
|
|
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"}
|
package/dist/database/index.d.ts
CHANGED
|
@@ -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"}
|
package/dist/database/types.d.ts
CHANGED
|
@@ -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<
|
|
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":"AAIA;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,cAAc,GACd,WAAW,GACX,WAAW,CAAA;AAEf;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE7D;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAClC;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,cAAc,GACd,WAAW,GACX,WAAW,CAAA;AAEf;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE7D;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAClC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IAGzB,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;IAG3E,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;IAGvC,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;IACpE,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;KAAE,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC1F,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAA;IAGvC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAC9D,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAGxD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAGtB,SAAS,CAAC,IAAI,GAAG,CAAA;IAGjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7C,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IACnC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAA;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAG1B,OAAO,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACzC,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAG5C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IAEpC,OAAO,EAAE,WAAW,CAAA;IAGpB,YAAY,EAAE,MAAM,CAAA;IAGpB,MAAM,CAAC,EAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,CAAA;IAED,OAAO,CAAC,EAAE;QACR,UAAU,EAAE,MAAM,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IAGD,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,IAAI,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC/B"}
|