query-weaver 0.2.0-alpha.2 → 0.2.0-alpha.4

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Query Weaver
2
2
 
3
- Compose SQL statements safely by leveraging template string literals
3
+ Compose SQL statements safely by leveraging template string literals.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,26 +8,18 @@ Compose SQL statements safely by leveraging template string literals
8
8
  $ npm install query-weaver
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## Basic Usage
12
12
 
13
- ### As a SQL Builder
13
+ ### As an SQL Builder
14
14
 
15
15
  <!-- prettier-ignore -->
16
- ```js
16
+ ```ts
17
17
  import { sql } from 'query-weaver';
18
- import pg from 'pg';
19
18
 
20
19
  const foo = 1, bar = 'Bar';
21
20
  const query = sql`SELECT * FROM foobar WHERE foo = ${foo} AND bar = ${bar}`;
22
-
23
- console.log(query.toString());
24
- // SELECT * FROM foobar WHERE foo = '1' AND bar = 'Bar'
25
-
26
- const db = new pg.Pool();
27
- const { rows } = await db.query(query);
28
-
29
- console.log(rows);
30
- // [ { foo: 1, bar: 'Bar' } ]
21
+ console.log(query);
22
+ // QueryFragments { text: [Getter], values: [Getter], embed: [Getter] }
31
23
 
32
24
  console.log(JSON.stringify(query, null, 2));
33
25
  // {
@@ -38,17 +30,14 @@ console.log(JSON.stringify(query, null, 2));
38
30
  // ],
39
31
  // "embed": "SELECT * FROM foobar WHERE foo = '1' AND bar = 'Bar'"
40
32
  // }
41
-
42
- db.end();
43
33
  ```
44
34
 
45
- As you can see, the query is executed using **placeholder** on the database. This makes string-value concatenation safe.
46
- You can also get a string embed version of the query, so that you can debug the query easily.
35
+ The query is executed using **placeholders** in the database, which makes string-value concatenation safe. You can also obtain an embedded string version of the query so that you can easily debug it by copying and pasting.
47
36
 
48
- ### As a Query Helper (with `node-postgres` for example)
37
+ ### Inject a Query Helper
49
38
 
50
39
  <!-- prettier-ignore -->
51
- ```js
40
+ ```ts
52
41
  import { withQueryHelper } from 'query-weaver';
53
42
  import pg from 'pg';
54
43
 
@@ -61,23 +50,23 @@ const { rows } =
61
50
  console.log(rows);
62
51
  // [ { foo: 1, bar: 'Bar' } ]
63
52
 
64
- db.end(); // this call will be proxied to the original pg.Pool() instance
53
+ db.end();
65
54
  ```
66
55
 
67
- Almost the same as above, but you can directly pass the template string to the `query` function.
56
+ The `withQueryHelper` utility wraps the original object with a Query Helper, providing utility functions as if they were built into the original object. Essentially, these are shorthand functions that bridge the original `query` and the Query Weaver functions, with the most notable features being debugging and transaction support.
57
+
58
+ ## Utilities
68
59
 
69
- ### WHERE builder
60
+ ### WHERE Builder
70
61
 
71
62
  `WHERE_AND` / `WHERE_OR` / `AND` / `OR` / `WHERE` (`WHERE_AND` alias)
72
63
 
73
64
  <!-- prettier-ignore -->
74
- ```js
65
+ ```ts
75
66
  import { sql, WHERE, OR } from 'query-weaver';
76
67
 
77
68
  const a = 1, b = 'string', c = null, d = 5, e = false, f = [1, 2, 3, 4, 5];
78
- console.log(
79
- String(sql`SELECT * FROM foobar ${WHERE({ a, b, c }, OR({ d, e }))}`)
80
- );
69
+ console.log(String(sql`SELECT * FROM foobar ${WHERE({ a, b, c }, OR({ d, e }))}`));
81
70
  // SELECT * FROM foobar WHERE ((a = '1') AND (b = 'string') AND (c IS NULL) AND (((d = '5') OR (e = false))))
82
71
 
83
72
  const q = sql`SELECT * FROM foobar ${WHERE(
@@ -97,7 +86,9 @@ console.log(q.embed);
97
86
  // SELECT * FROM foobar WHERE ((a = '10') AND (b = 'string') AND (c IS UNKNOWN) AND (d BETWEEN '1' AND '5') AND (e IS NULL) AND (f = ANY (ARRAY['1','2','3','4','5'])))
98
87
  ```
99
88
 
100
- ### JSON builder
89
+ ### JSON Builder
90
+
91
+ `json`
101
92
 
102
93
  ```js
103
94
  import pg from 'pg';
@@ -109,7 +100,7 @@ const id = 10;
109
100
  const obj = { b: 'string', c: [1, 2, 'X'], d: { e: null, f: undefined } };
110
101
 
111
102
  const row =
112
- await db.getRow`SELECT * FROM jsonb_to_record(${json`{ 'a': ${obj}, 'b': ${id} }`}) AS (a jsonb, b int);`;
103
+ await db.getRow`SELECT * FROM jsonb_to_record(${json`{"a": ${obj}, "b": ${id}}`}) AS (a jsonb, b int);`;
113
104
 
114
105
  console.log(row);
115
106
  // {
@@ -120,92 +111,108 @@ console.log(row);
120
111
  db.end();
121
112
  ```
122
113
 
123
- ### VALUES builder
114
+ ### VALUES Builder
124
115
 
125
116
  `buildValues` / `sql.values`
126
117
 
127
118
  ```js
128
- sql.values([[1, 2, 3], ...]); // => VALUES (1, 2, 3), (...), ...
129
- sql.values([{ a: 1, b: 2, c: 3 }], ...]); // => VALUES (1, 2, 3), (...), ...
119
+ sql.values([[1, 2, 3], ...]); // => VALUES (1, 2, 3), (...), ...
120
+ sql.values([{ a: 1, b: 2, c: 3 }, ...]); // => VALUES (1, 2, 3), (...), ...
130
121
  ```
131
122
 
132
- ### Key builder
123
+ ### Key Builder
133
124
 
134
125
  `buildKeys` / `sql.keys`
135
126
 
136
127
  ```js
137
- sql.keys({ a: 1, b: 2, c: 3 }); // => (a, b, c)
138
- sql.keys([{ a: 1, b: 2, c: 3 }, ...]); // => (a, b, c)
128
+ sql.keys({ a: 1, b: 2, c: 3 }); // => (a, b, c)
129
+ sql.keys([{ a: 1, b: 2, c: 3 }, ...]); // => (a, b, c)
139
130
  ```
140
131
 
141
- ### Raw builder
132
+ ### Raw Builder
142
133
 
143
134
  `raw`
144
135
 
145
- ```js
146
- console.log(sql`SELECT * FROM foobar WHERE ${raw("bar LIKE '%something%'")}`);
136
+ ```ts
137
+ import { sql, raw } from 'query-weaver';
138
+
139
+ console.log(JSON.stringify(sql`SELECT * FROM foobar WHERE ${raw("bar LIKE '%something%'")}`));
140
+ // {"text":"SELECT * FROM foobar WHERE bar LIKE '%something%'","values":[],"embed":"SELECT * FROM foobar WHERE bar LIKE '%something%'"}
147
141
  ```
148
142
 
149
- ### Simple INSERT builder and executor
143
+ ### INSERT Builder and Helper
150
144
 
151
- `buildInsert` / `sql.insert` builder, and `insert` executor
145
+ `buildInsert` / `sql.insert` builder, and `insert` helper
152
146
 
153
147
  ```js
154
- sql.insert(tableName, { ... fieldValuePairs }); // => sql`INSERT INTO ...`
155
- db.insert(tableName, { ... fieldValuePairs }); // => db.query`INSERT INTO ...`
148
+ sql.insert(tableName, { ...fieldValuePairs }); // => sql`INSERT INTO ...`
149
+ db.insert(tableName, { ...fieldValuePairs }); // => db.query`INSERT INTO ...`
156
150
 
157
- // bulk insert
158
- sql.insert(tableName, [{ ... fieldValuePairs }, ... ]); // => sql`INSERT INTO ... VALUES (...), (...), ...`
159
- db.insert(tableName, [{ ... fieldValuePairs }, ... ]); // => db.query`INSERT INTO ... VALUES (...), (...), ...`
151
+ // Bulk insert
152
+ sql.insert(tableName, [{ ...fieldValuePairs }, ...]); // => sql`INSERT INTO ... VALUES (...), (...), ...`
153
+ db.insert(tableName, [{ ...fieldValuePairs }, ...]); // => db.query`INSERT INTO ... VALUES (...), (...), ...`
160
154
  ```
161
155
 
162
- ### Simple UPDATE builder and executor
156
+ ### UPDATE Builder and Helper
163
157
 
164
- `buildUpdate` / `sql.update` builder, and `update` executor
158
+ `buildUpdate` / `sql.update` builder, and `update` helper
165
159
 
166
160
  ```js
167
161
  sql.update(tableName, { ...fieldValuePairs }, { ...whereCondition }); // => sql`UPDATE ...`
168
- db.update(tableName, { ...fieldValuePairs }, { ...whereCondition }); // => db.query`UPDATE ...`
162
+ db.update(tableName, { ...fieldValuePairs }, { ...whereCondition }); // => db.query`UPDATE ...`
169
163
  ```
170
164
 
171
- ### Simple DELETE builder and executor
165
+ ### DELETE Builder and Helper
172
166
 
173
- `buildDelete` / `sql.delete` builder, and `delete` executor
167
+ `buildDelete` / `sql.delete` builder, and `delete` helper
174
168
 
175
169
  ```js
176
170
  sql.delete(tableName, { ...whereCondition }); // => sql`DELETE FROM ...`
177
- db.delete(tableName, { ...whereCondition }); // => db.query`DELETE FROM ...`
171
+ db.delete(tableName, { ...whereCondition }); // => db.query`DELETE FROM ...`
178
172
  ```
179
173
 
180
- ### API
174
+ ### Transaction Helper
181
175
 
182
- As you can see, an object built and constructed by `sql` keyword behave like a simple object with the following properties;
183
- `text`, `values`, and `embed`.
176
+ `begin` helper
184
177
 
185
- Furthermore, the object also comes up with the following APIs;
178
+ ```js
179
+ db.begin(() => {
180
+ db.delete(...);
181
+ db.insert(...);
182
+ });
183
+ ```
184
+
185
+ If an error occurs, the transaction is safely rolled back.
186
+ **NOTE:** Transactions can be nested, but only the outermost transaction is effective.
187
+
188
+ ## Low-level APIs
189
+
190
+ An object created by the `sql` keyword behaves like a simple object with the following properties: `text`, `values`, and `embed`.
191
+
192
+ In addition, the object provides the following APIs:
186
193
 
187
194
  - `append(...)` / `push(...)`
188
- - append a **raw SQL string** or an object created by `sql`, to the query
195
+ - Appends a **raw SQL string** or an object created by `sql` to the query.
189
196
  - `join(glue = ', ')` / `prefix(prefix)` / `suffix(suffix)` / `empty(empty)`
190
- - set glue/prefix/suffix/empty string for toString(), respectively
197
+ - Sets the glue, prefix, suffix, or empty string for `toString()`, respectively.
191
198
  - `setSewingPattern(prefix, glue, suffix, empty)`
192
- - set sewing pattern for toString() at once
199
+ - Sets the sewing pattern for `toString()` all at once.
193
200
  - `toString(opts?)`
194
- - constructs SQL string (by using sewing pattern and `opts` settings)
201
+ - Constructs the SQL string using the sewing pattern and any provided `opts` settings.
195
202
 
196
- To create the object;
203
+ To create a query object, you can use:
197
204
 
198
205
  - `` sql`template string with ${value}` `` / `` json`{"a": "b", "c": ${value}}` ``
199
- - creates a query object with values that will be automatically escaped
206
+ - Creates a query object with values that are automatically escaped.
200
207
  - `sql(value, ...)` / `json(value)`
201
- - creates a query object from only values that will be automatically escaped
208
+ - Creates a query object from values that are automatically escaped.
202
209
 
203
- These APIs can be used, for example, to construct `IN` clause;
210
+ These APIs can be used, for example, to construct an `IN` clause as follows:
204
211
 
205
- ```js
206
- console.log(
207
- sql`SELECT * FROM foobar WHERE foo IN (${sql(1, 2, 3).join()})`.embed,
208
- );
212
+ ```ts
213
+ import { sql } from 'query-weaver';
214
+
215
+ console.log(sql`SELECT * FROM foobar WHERE foo IN (${sql(1, 2, 3).join()})`.embed);
209
216
  // SELECT * FROM foobar WHERE foo IN ('1', '2', '3')
210
217
 
211
218
  const a = [1, 2, 3];
@@ -215,58 +222,38 @@ console.log(sql`SELECT * FROM foobar WHERE foo IN (${sql(...a).join()})`.text);
215
222
 
216
223
  ### Caveats
217
224
 
218
- - Only `sql` and `json` accepts a template string literal.
219
- - The actual SQL statement executed on the database may differ between `[.text, .values]` and `.embed`, due to differences in serialize functions. If you really want to get the exact same statement, you can try this for example:
220
-
221
- ```js
222
- import pgUtil from 'pg/lib/utils.js';
223
- import pgEscape from 'pg-escape';
224
-
225
- console.log(sql`SELECT ${[1, 2, 3, 4, 5]}`.embed);
226
- // SELECT ARRAY['1','2','3','4','5']
227
-
228
- console.log(sql`SELECT ${pgUtil.prepareValue([1, 2, 3, 4, 5])}`.embed);
229
- // SELECT '{"1","2","3","4","5"}'
230
-
231
- // or, pass a custom serialize function
232
- console.log(
233
- sql`SELECT ${[1, 2, 3, 4, 5]}`.toString({
234
- valueFn: (x) => pgEscape.literal(JSON.stringify(x)),
235
- }),
236
- );
237
- // SELECT '[1,2,3,4,5]'
238
- ```
225
+ - Only `sql` and `json` accept a template string literal.
226
+ - The actual SQL statement executed on the database may sometimes differ between `[.text, .values]` and `.embed` due to differences in serialization functions.
239
227
 
240
228
  ### DEBUG
241
229
 
242
- You can get access to the statements and results when using the Query Helper.
243
- I use the following code to record the session;
230
+ You can easily access the statements and results when using the Query Helper. For example, the following code records the session:
244
231
 
245
232
  <!-- prettier-ignore -->
246
233
  ```js
247
234
  import zlib from 'node:zlib'
248
235
 
249
236
  const db = withQueryHelper(new pg.Pool(), {
250
- onError: (ctx, error) => console.error(JSON.stringify({ error: zlib.gzipSync(JSON.stringify({ ... ctx, error })).toString('base64') })),
237
+ onError: (ctx, error) => console.error(JSON.stringify({ error: zlib.gzipSync(JSON.stringify({ ...ctx, error })).toString('base64') })),
251
238
  beforeQuery: (ctx) => console.log(JSON.stringify({ query: zlib.gzipSync(JSON.stringify(ctx)).toString('base64') })),
252
- afterQuery: (ctx, result) => console.log(JSON.stringify({ result: zlib.gzipSync(JSON.stringify({ ... ctx, result })).toString('base64') })),
239
+ afterQuery: (ctx, result) => console.log(JSON.stringify({ result: zlib.gzipSync(JSON.stringify({ ...ctx, result })).toString('base64') })),
253
240
  });
254
241
  ```
255
242
 
256
- After that, you'll see something like this on the console;
243
+ After running this, you will see output similar to the following in the console:
257
244
 
258
245
  <!-- prettier-ignore -->
259
246
  ```json
260
- {"query":"H4sIAAAAAAAAA6tWKkmtKFGyUgp29XF1DlHQUnAL8vdVSMvPT0osUgj3cA1yBXEUbBVUDJV0lMoSc0pTi5Wsog1jdZRSc5NSU4jRqm6oDtRblFpcmlMC1FytlJyfm5uYh9ALks0vd84vzQM6xRDMAVlSrQTUDxYAmghU7AQka2NrawEDVej4tQAAAA=="}
247
+ {"query":"H4sIAAAAAAACA6tWKkmtKFGyUgp29XF1DlHQUnAL8vdVSMvPT0osUgj3cA1yBXEUbBVUDJV0lMoSc0pTi5Wsog1jdZRSc5NSU4jRqm6oDtRblFpcmgO0qlopOT83NzEPoRUkmV/unF+aB5Q2BHNAdlQrAbWDBYAGAhU7Acna2NpaABybVha0AAAA"}
261
248
  ```
262
249
 
263
- Now you can extract the contents by executing the following command;
250
+ You can extract the contents by executing the following command:
264
251
 
265
252
  <!-- prettier-ignore -->
266
253
  ```sh
267
254
  % echo '... base64part' | base64 -d | zcat | jq -r .
268
255
 
269
- # or if you're using X11, select base64 part and then;
256
+ # Or, if you're using X11, select the base64 part and then:
270
257
  % xclip -o | base64 -d | zcat | jq -r .
271
258
  ```
272
259
 
@@ -278,7 +265,7 @@ Now you can extract the contents by executing the following command;
278
265
  1
279
266
  ],
280
267
  "embed": "SELECT * FROM foobar WHERE foo = '1'",
281
- "results": {
268
+ "result": {
282
269
  "command": "SELECT",
283
270
  "rowCount": 1,
284
271
  "rows": [
@@ -291,7 +278,7 @@ Now you can extract the contents by executing the following command;
291
278
  }
292
279
  ```
293
280
 
294
- It is very handy to replay the session like this;
281
+ It is very handy to replay the session as follows:
295
282
 
296
283
  ```sh
297
284
  % xclip -o | base64 -d | zcat | jq -r .embed | psql
@@ -300,16 +287,13 @@ It is very handy to replay the session like this;
300
287
  1 | Bar
301
288
  (1 row)
302
289
 
303
- # Or, you can make a shell-script named `xclip-query` then
290
+ # Or, you can create a shell script named `xclip-query` and then run:
304
291
  % xclip-query .embed | psql
305
292
  ```
306
293
 
307
- ### Query Helper with custom `query` handler
294
+ ### Query Helper with a Custom `query` Function
308
295
 
309
- The final underlying `query` function can be changed by using `query` option.
310
- So you can use Prisma, TypeORM, or whatever you want if you write a query handler for them.
311
-
312
- Here are examples for using it;
296
+ The underlying `query` function, which is used to perform queries, can be replaced by using the `query` option. This allows you to use Prisma, TypeORM, or even raw SQLite object with Query Helper. For example:
313
297
 
314
298
  <!-- prettier-ignore -->
315
299
  ```js
@@ -329,11 +313,24 @@ const db = withQueryHelper(new DataSource({ ... }), {
329
313
  console.log(await db.query`...`);
330
314
  ```
331
315
 
316
+ <!-- prettier-ignore -->
317
+ ```js
318
+ import { DatabaseSync } from 'node:sqlite';
319
+
320
+ const db = withQueryHelper(new DatabaseSync(), {
321
+ query: QueryHelper.sqlite,
322
+ });
323
+
324
+ console.log(await db.query`...`);
325
+ ```
326
+
332
327
  <!-- prettier-ignore -->
333
328
  ```ts
334
- const queryable = async function (this: object, { text, values}: QueryConfig) {
329
+ import { withQueryHelper } from 'query-weaver';
330
+
331
+ const queryable = async function (this: object, { text, values }: QueryConfig) {
335
332
  return {
336
- rows: [this], // `this` would be the object you passed to the constructor
333
+ rows: [this], // `this` will be the object you passed to the constructor
337
334
  rowCount: 1,
338
335
  }
339
336
  }
@@ -347,4 +344,4 @@ console.log(await db.getRow`HELLO QUERY`);
347
344
  ```
348
345
 
349
346
  That's it!
350
- Now you can use Query Weaver interfaces on them.
347
+ Now you can use Query Weaver interfaces on the objects.
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e,t,n){return Math.min(Math.max(e,t),n)}var t=class{#e;#t=0;#n;constructor(e){this.#e=e,this.#n=e.length}get position(){return this.#t}get size(){return this.#n}get remain(){return this.size-this.position}eof(){return this.remain<=0}seek(t){return this.#t=e(t,0,this.size),this}skip(e){return this.seek(this.#t+(e??1))}startsWith(e){if(this.eof())return null;let t=this.#e.slice(this.position);return(typeof e==`string`?t.startsWith(e)&&[e]:t.match(new RegExp(e,e.sticky?e.flags:e.flags+`y`)))||null}match(e,t){let n=this.startsWith(e);return n?(this.skip(n[0].length),t?t(n):n):null}#r(e,t){let n=this.#e.slice(this.position),r=typeof e==`string`?n.indexOf(e):n.search(e);return r<0?null:t(r)}search(e,t){return this.#r(e,n=>{let r=this.read(n),i=this.match(e);if(!i)return null;let a={skipped:r,matched:i};return t?t(a):a})}skipUntil(e){return this.#r(e,e=>this.skip(e))!==null}readUntil(e){return this.#r(e,e=>this.read(e))}read(e){if(this.eof())return``;if(e??=1,e<0)throw RangeError(`read(n): n must be >= 0`);let t=this.#e.slice(this.position,this.position+e);return this.skip(e),t}};const n=`AES128.AES256.ALL.ALLOWOVERWRITE.ANALYSE.ANALYZE.AND.ANY.ARRAY.AS.ASC.AUTHORIZATION.BACKUP.BETWEEN.BINARY.BLANKSASNULL.BOTH.BYTEDICT.CASE.CAST.CHECK.COLLATE.COLUMN.CONSTRAINT.CREATE.CREDENTIALS.CROSS.CURRENT_DATE.CURRENT_TIME.CURRENT_TIMESTAMP.CURRENT_USER.CURRENT_USER_ID.DEFAULT.DEFERRABLE.DEFLATE.DEFRAG.DELTA.DELTA32K.DESC.DISABLE.DISTINCT.DO.ELSE.EMPTYASNULL.ENABLE.ENCODE.ENCRYPT.ENCRYPTION.END.EXCEPT.EXPLICIT.FALSE.FOR.FOREIGN.FREEZE.FROM.FULL.GLOBALDICT256.GLOBALDICT64K.GRANT.GROUP.GZIP.HAVING.IDENTITY.IGNORE.ILIKE.IN.INITIALLY.INNER.INTERSECT.INTO.IS.ISNULL.JOIN.LEADING.LEFT.LIKE.LIMIT.LOCALTIME.LOCALTIMESTAMP.LUN.LUNS.LZO.LZOP.MINUS.MOSTLY13.MOSTLY32.MOSTLY8.NATURAL.NEW.NOT.NOTNULL.NULL.NULLS.OFF.OFFLINE.OFFSET.OLD.ON.ONLY.OPEN.OR.ORDER.OUTER.OVERLAPS.PARALLEL.PARTITION.PERCENT.PLACING.PRIMARY.RAW.READRATIO.RECOVER.REFERENCES.REJECTLOG.RESORT.RESTORE.RIGHT.SELECT.SESSION_USER.SIMILAR.SOME.SYSDATE.SYSTEM.TABLE.TAG.TDES.TEXT255.TEXT32K.THEN.TO.TOP.TRAILING.TRUE.TRUNCATECOLUMNS.UNION.UNIQUE.USER.USING.VERBOSE.WALLET.WHEN.WHERE.WITH.WITHOUT`.split(`.`);function r(e){return e.match(/^[a-zA-Z_][0-9a-zA-Z_$]*$/)&&!n.includes(e.toUpperCase())?e:`"${e.replace(/"/g,`""`)}"`}function i(e){return`${e.includes(`'`)?`E`:``}'${e.replace(/'/g,`''`).replace(/\\/g,`\\\\`)}'`}function a(e,t){return e.split(`.`).map(e=>r(e)).join(`.`)}function o(e,t){return e===null?`NULL`:typeof e==`boolean`?e?`true`:`false`:Array.isArray(e)?`ARRAY[`+e.map(e=>o(e)).join(`,`)+`]`:typeof e==`object`?`toJSON`in e&&typeof e.toJSON==`function`?i(String(e.toJSON())):i(e.toString()):i(String(e))}function s(e,n){let r=new t(n);for(;!r.eof();)if(e.dollarQuoted){if(!r.search(e.dollarQuoted))break;e.dollarQuoted=void 0}else if(e.inEscapedSingleQuote){if(!r.skipUntil(/[\\']/))break;if(r.match(`''`)||r.match(/\\./))continue;if(!r.match(`'`))break;e.inEscapedSingleQuote=!1}else if(e.inSingleQuote){if(!r.skipUntil(`'`))break;if(r.match(`''`))continue;if(!r.match(`'`))break;e.inSingleQuote=!1}else if(e.inBlockComment){if(!r.skipUntil(/\/\*|\*\//))break;if(r.match(`/*`,()=>++e.inBlockComment))continue;if(!r.match(`*/`))break;e.inBlockComment--}else if(e.inLineComment){if(!r.search(/\r\n|\r|\n/))break;e.inLineComment=!1}else{if(!r.skipUntil(/[-$E'/]/))break;if(r.match(/\$[a-zA-Z0-9_]*\$/,t=>e.dollarQuoted=t[0])||r.match(`E'`,()=>e.inEscapedSingleQuote=!0)||r.match(`'`,()=>e.inSingleQuote=!0)||r.match(`--`,()=>e.inLineComment=!0)||r.match(`/*`,()=>e.inBlockComment=1))continue;r.skip()}}function c(e){return e?!!(e.dollarQuoted||e.inLineComment||e.inBlockComment||e.inSingleQuote||e.inEscapedSingleQuote):!1}var l=class{text=``;values=[];sql=``;statement=``;embed=``;#e(e){return this.toString({valueFn:(t,n)=>c(n)?``:e(t),context:{},contextHandler:s})}constructor(){Object.defineProperties(this,{text:{enumerable:!0,get:()=>{let e=1;return this.#e(()=>`$`+ e++)}},values:{enumerable:!0,get:()=>{let e=[];return this.#e(t=>(e.push(t),``)),e}},sql:{enumerable:!1,get:()=>this.#e(()=>`?`)},statement:{enumerable:!1,get:()=>{let e=1;return this.#e(()=>`:`+ e++)}},embed:{enumerable:!0,get:()=>this.#e(e=>o(e))}})}},u=class extends l{#e;constructor(e){super(),this.#e=e}toString(e){return(e?.valueFn??o)(this.#e,e?.context)}},d=class extends l{#e;constructor(e){super(),this.#e=e}toString(e){return(e?.identFn??a)(this.#e,e?.context)}},f=class extends l{#e;constructor(e){super(),this.#e=String(e)}toString(e){return e?.context&&e?.contextHandler&&e.contextHandler(e.context,this.#e),this.#e}};function p(e){return e instanceof l}function m(e){return new d(e)}function h(e){return e===void 0||p(e)?e:new u(e)}function g(e){return e===void 0||p(e)?e:Array.isArray(e)?new b(e.map(g)):new f(e)}function _(e){return e===void 0||p(e)?e:g(JSON.stringify(e))}const v=e=>{if(!Array.isArray(e)||typeof e?.[0]!=`object`||e[0]===null||!(`raw`in e[0])||!Array.isArray(e[0]))return!1;let[t,...n]=e;return t.length-1===n.length};function y(e,t){if(e.length-1!==t.length)throw Error(`Template literal received a mismatched number of values.`);return e.flatMap((e,n)=>n?[t[n-1],e]:[e])}var b=class extends l{#e=[];#t;constructor(...e){if(super(),this.#t={prefix:``,glue:``,suffix:``,empty:``,wrapperFn:e=>e},Array.isArray(e[0])){let[t,n]=e;this.#t={...this.#t,...n},this.push(...t)}else{let[t]=e;this.#t={...this.#t,...t}}}setSewingPattern(e=``,t=``,n=``,r=``){return this.#t={...this.#t,prefix:e,glue:t,suffix:n,empty:r},this}push(...e){return this.#e.push(...e.map(g).filter(e=>e!==void 0)),this}append(...e){return this.push(...e)}join(e=`, `){return this.#t.glue=e,this}prefix(e=` `){return this.#t.prefix=e,this}suffix(e=` `){return this.#t.suffix=e,this}empty(e=``){return this.#t.empty=e,this}toString(e){let t=this.#e.map(t=>t.toString(e)).filter(e=>e).join(this.#t.glue);return t?this.#t.prefix+this.#t.wrapperFn(t,e)+this.#t.suffix:this.#t.empty}};function x(...e){let t;if(v(e)){let[n,...r]=e;t=[new b(y(n.map(g),r.map(h)))]}else t=e.map(h);return new b(t)}const S=m;function C(...e){return new b(e.map(g))}function w(...e){let t,n=(e,t)=>(t?.valueFn||o)(e,t?.context);if(v(e)){let[r,...i]=e;t=[new b(y(r.map(g),i.map(_)),{wrapperFn:n})]}else t=e.map(e=>new b([_(e)],{wrapperFn:n}));return new b(t)}function T(...e){let t=new b,n=e=>{if(e!=null){if(typeof e==`string`){t.push(g(e));return}if(p(e)){t.push(e);return}if(Array.isArray(e)){e.forEach(n);return}if(typeof e==`object`){for(let n in e)if(e[n]!==void 0){if(p(e[n])){t.push(x`${m(n)} ${e[n]}`);continue}if(e[n]===null){t.push(x`${m(n)} IS NULL`);continue}if(Array.isArray(e[n])){let r=e[n];r.length===0?t.push(x`FALSE`):t.push(x`${m(n)} = ANY (${r})`);continue}t.push(x`${m(n)} = ${e[n]}`)}return}}};return n(e),t}function E(...e){return T(e).setSewingPattern(`((`,`) OR (`,`))`,``)}function D(...e){return T(e).setSewingPattern(`((`,`) AND (`,`))`,``)}function O(...e){return T(e).setSewingPattern(`WHERE ((`,`) AND (`,`))`,``)}function k(...e){return T(e).setSewingPattern(`WHERE ((`,`) OR (`,`))`,``)}function A(...e){return C(...e).join(` UNION ALL `)}function j(...e){return C(...e).join(` UNION `)}function M(e){return e==null?x``:(e=Number(e),e>=0?x`LIMIT ${e}`:x``)}function N(e){return e==null?x``:(e=Number(e),e>=0?x`OFFSET ${e}`:x``)}function P(e){let t=Array.isArray(e)?e:[e];if(t.length===0)throw Error(`At least one field value is required.`);let n=t[0],r=n&&Array.isArray(n);if(!n||!r&&typeof n!=`object`)throw Error(`Field values must be arrays or plain objects.`);let i=t.map(e=>{if(Array.isArray(e)!==r)throw Error(`All entries must share the same structure.`);return Object.fromEntries((Array.isArray(e)?e.map((e,t)=>[String(t),e]):Object.entries(e)).filter(([,e])=>e!==void 0))}),a=Object.keys(i[0]),o=i.map(e=>{if(Object.keys(e).length!==a.length)throw Error(`All entries must share the same structure.`);return a.map(t=>{if(!Object.prototype.hasOwnProperty.call(e,t))throw Error(`All entries must share the same structure.`);return e[t]})});return{keys:r?void 0:a,rows:o}}function F(e){let{keys:t,rows:n}=P(e);return{keys:t,fields:t?x(...t.map(m)).setSewingPattern(`(`,`, `,`)`):void 0,VALUES:x`VALUES ${x(...n.map(e=>x(...e).join(`, `))).setSewingPattern(`(`,`), (`,`)`)}`}}function I(e){let{fields:t}=F(e);if(!t)throw Error(`buildKeys requires FieldValues to be objects.`);return t}function L(e){return F(e).VALUES}function R(e,t,n){let{fields:r,VALUES:i}=F(t);if(!r)throw Error(`buildInsert requires FieldValues to be objects.`);return x`INSERT INTO ${m(e)} ${r} ${i}`.append(n).join(` `)}function z(e,t,n,r){let i=new b,a=!1;for(let e in t){let n=t[e];n!==void 0&&(i.push(x`${m(e)} = ${n}`),a=!0)}if(!a)throw Error(`buildUpdate requires at least one field to update.`);return x`UPDATE ${m(e)} SET ${i.join(`, `)} ${O(n)}`.append(r).join(` `)}function B(e,t,n){return x`DELETE FROM ${m(e)} ${O(t)}`.append(n).join(` `)}function V(e,t,n,r){if(!n.length)throw Error(`buildUpsert requires at least one conflict key.`);let{keys:i,fields:a,VALUES:o}=F(t);if(!i||!a)throw Error(`buildUpsert requires FieldValues to be objects.`);let s=x(...n.map(m)).setSewingPattern(`ON CONFLICT (`,`, `,`)`),c=i.filter(e=>!n.includes(e)),l=c.length===0?x`DO NOTHING`:x(...c.map(e=>x`${S(e)} = EXCLUDED.${S(e)}`)).setSewingPattern(`DO UPDATE SET `,`, `);return x`INSERT INTO ${m(e)} ${a} ${o} ${s} ${l}`.append(r).join(` `)}const H=E,U=D,W=O,G=O,K=O,q=k;function J(e,t){return Object.fromEntries(t.map(t=>[t,e[t]]))}var Y=class{#e;#t;#n=0;constructor(e,t={}){if(this.#e=e,this.#t={...t},!this.#t.query){if(!(`query`in e)||typeof e.query!=`function`)throw Error(`No valid query function provided.`);this.#t.query=e.query}}#r(e){if(v(e)){let[t,...n]=e;return x(t,...n)}let[t,n]=e;return typeof t==`object`&&t&&`text`in t?{text:t.text,values:t.values||[],embed:`embed`in t&&typeof t.embed==`string`?t.embed:void 0,sql:`sql`in t&&typeof t.sql==`string`?t.sql:void 0,statement:`statement`in t&&typeof t.statement==`string`?t.statement:void 0}:{text:t,values:n??[]}}#i(e){let t=this.#t.query;if(!t)throw Error(`Query function is not configured.`);return t.call(this.#e,e)}async#a(e){let t=this.#r(e);this.#t?.beforeQuery?.(t);let n=await this.#i(t).catch(e=>{throw this.#t?.onError?.(t,e),e});return typeof n.rowCount!=`number`&&(n.rowCount=n.rows?.length??0),this.#t?.afterQuery?.(t,J(n,[`command`,`rowCount`,`rows`])),n}async insert(e,t,n){let r=R(e,t,n);return await this.#a([r])}async update(e,t,n,r){let i=z(e,t,n,r);return await this.#a([i])}async delete(e,t,n){let r=B(e,t,n);return await this.#a([r])}async upsert(e,t,n,r){let i=V(e,t,n,r);return await this.#a([i])}async query(...e){return this.#a(e)}async getRows(...e){return this.#a(e).then(e=>e.rows)}async getRow(...e){return this.#a(e).then(e=>e.rows?.[0])}async getOne(...e){return this.#a(e).then(e=>Object.values(e.rows?.[0]??{})?.[0])}async getCount(...e){return this.#a(e).then(e=>e.rowCount)}async exec(...e){return this.#a(e).then(e=>e.rowCount)}async begin(e){this.#n===0&&await this.#i({text:`BEGIN`,values:[]}),this.#n+=1;try{let t=await e(this);return this.#n===1&&await this.#i({text:`COMMIT`,values:[]}),t}catch(e){if(this.#n===1)try{await this.#i({text:`ROLLBACK`,values:[]})}catch{throw Error(`Rollback error`,{cause:e})}throw e}finally{--this.#n}}static get prisma(){return async function({text:e,values:t}){if(`$queryRawUnsafe`in this&&typeof this.$queryRawUnsafe==`function`){let n=await this.$queryRawUnsafe(e,...t);return{rows:n,rowCount:n.length}}throw Error(`Prisma adapter requires a $queryRawUnsafe function.`)}}static get typeorm(){return async function({text:e,values:t}){if(`query`in this&&typeof this.query==`function`){let n=await this.query(e,t);return n.length===2&&Array.isArray(n[0])&&typeof n[1]==`number`?{rows:n[0],rowCount:n[1]}:{rows:n,rowCount:n.length}}throw Error(`TypeORM adapter requires a query function.`)}}static get sqlite(){return async function(e){if(`prepare`in this&&typeof this.prepare==`function`){let t=this.prepare(e.sql||e.text).all(...e.values);return{rows:t,rowCount:t.length}}throw Error(`SQLite adapter requires a prepare function.`)}}};function X(e,t){let n=new Y(e,t),r=new Proxy(e,{get(e,t,i){let a=t in n?n:t in e?e:void 0,o=a&&Reflect.get(a,t);return o&&o instanceof Function?function(...t){let n=this===i||this===r||this==null?a:this,s=o.apply(n,t);return s===e?r:s}:o===e?r:o}});return r}exports.AND=D,exports.LIMIT=M,exports.OFFSET=N,exports.OR=E,exports.QueryFragments=b,exports.QueryHelper=Y,exports.UNION=j,exports.UNION_ALL=A,exports.WHERE=O,exports.WHERE_AND=G,exports.WHERE_OR=k,exports.and=U,exports.buildClauses=T,exports.buildDelete=B,exports.buildInsert=R,exports.buildKeys=I,exports.buildUpdate=z,exports.buildUpsert=V,exports.buildValues=L,exports.ident=S,exports.isQueryFragment=p,exports.isQueryTemplateStyle=v,exports.json=w,exports.or=H,exports.pgIdent=a,exports.pgString=o,exports.raw=C,exports.sql=x,exports.where=W,exports.where_and=K,exports.where_or=q,exports.withQueryHelper=X;