squel 5.12.2 → 6.0.2

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/CHANGELOG.md CHANGED
@@ -1,4 +1,34 @@
1
- # Changelog for [squel](https://github.com/hiddentao/squel)
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
+
5
+ ## [6.0.2](https://github.com/hiddentao/squel/compare/v6.0.1...v6.0.2) (2026-04-14)
6
+
7
+ ## 6.0.1 (2026-04-14)
8
+
9
+ ## 6.0.0
10
+
11
+ This is a modernization release. The public API is unchanged — existing calls to `squel.select()`, `squel.useFlavour("postgres")`, and friends continue to work.
12
+
13
+ ### Breaking Changes
14
+
15
+ * `engines.node` raised to `>=18` (from `>=0.12`).
16
+ * Package shape changed: the `squel.js` / `squel.min.js` / `squel-basic.js` / `squel-basic.min.js` UMD bundles are replaced by `dist/esm/`, `dist/cjs/`, and `dist/browser/squel.min.js` (IIFE for CDN / script tags).
17
+ * The separate "basic" bundle is gone — the main entry contains all flavours. ESM tree-shaking removes unused flavours for bundler users.
18
+
19
+ ### Features
20
+
21
+ * Source rewritten in TypeScript with first-class type declarations generated from source (no more hand-maintained `.d.ts`).
22
+ * Dual CJS + ESM output with conditional `exports` map.
23
+ * Biome for lint + format; Bun as the toolchain; bun:test for tests.
24
+ * GitHub Actions CI and automated releases on `master` via commit-and-tag-version with npm provenance.
25
+ * Conventional Commits enforced via husky + commitlint.
26
+
27
+ ## 28 Jul 2020 (5.13.1)
28
+ * Deprecate in NPM (#384)
29
+
30
+ ## 18 Jun 2019 (5.13.0)
31
+ * Added note to top of README stating that Squel is no longer actively maintained.
2
32
 
3
33
  ## 9 Jul 2018 (5.12.2)
4
34
  * Fix Node.js CVE (update growl dev dependency)
package/README.md CHANGED
@@ -1,53 +1,87 @@
1
- # squel - SQL query string builder
1
+ # squel — SQL query string builder
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/hiddentao/squel.svg?branch=master)](http://travis-ci.org/hiddentao/squel)
4
- [![CDNJS](https://img.shields.io/cdnjs/v/squel.svg)](https://cdnjs.com/libraries/squel)
5
- [![NPM module](https://badge.fury.io/js/squel.svg)](https://badge.fury.io/js/squel)
6
- [![NPM downloads](https://img.shields.io/npm/dm/squel.svg?maxAge=2592000)](https://www.npmjs.com/package/squel)
7
- [![Join the chat at https://discord.gg/PBAR2Bz](https://img.shields.io/badge/discord-join%20chat-738bd7.svg)](https://discord.gg/PBAR2Bz)
8
- [![Follow on Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/hiddentao)
3
+ [![CI](https://github.com/hiddentao/squel/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/hiddentao/squel/actions/workflows/ci.yml)
4
+ [![npm version](https://badge.fury.io/js/squel.svg)](https://www.npmjs.com/package/squel)
5
+ [![NPM downloads](https://img.shields.io/npm/dm/squel.svg)](https://www.npmjs.com/package/squel)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
9
8
 
10
- A flexible and powerful SQL query string builder for Javascript.
9
+ A flexible and powerful SQL query string builder for JavaScript and TypeScript.
11
10
 
12
- Full documentation (guide and API) at [https://hiddentao.com/squel/](https://hiddentao.com/squel/).
11
+ Full guide and API documentation at [https://hiddentao.github.io/squel](https://hiddentao.github.io/squel).
13
12
 
14
13
  ## Features
15
14
 
16
- * Works in node.js and in the browser.
17
- * Supports the standard SQL queries: SELECT, UPDATE, INSERT and DELETE.
18
- * Supports non-standard commands for popular DB engines such as MySQL.
19
- * Supports paramterized queries for safe value escaping.
20
- * Can be customized to build any query or command of your choosing.
21
- * Uses method chaining for ease of use.
22
- * Small: ~7 KB minified and gzipped
23
- * And much more, [see the guide..](https://hiddentao.com/squel/)
15
+ - Written in TypeScript with first-class type definitions.
16
+ - Works in Node.js and the browser.
17
+ - Supports the standard SQL queries: `SELECT`, `UPDATE`, `INSERT`, `DELETE`.
18
+ - Supports non-standard commands for MySQL, PostgreSQL, and Microsoft SQL Server.
19
+ - Supports parameterized queries for safe value escaping.
20
+ - Extensible — build any custom query or command you need.
21
+ - Fluent method-chaining API.
22
+ - Ships as dual ESM + CommonJS with a minified IIFE bundle for CDN use.
24
23
 
25
- **WARNING: Do not ever pass queries generated on the client side to your web server for execution.** Such a configuration would make it trivial for a casual attacker to execute arbitrary queries—as with an SQL-injection vector, but much easier to exploit and practically impossible to protect against.
24
+ > **Warning:** Do not ever pass queries generated on the client side to your web server for execution. Such a configuration would make it trivial for a casual attacker to execute arbitrary queries — as with an SQL-injection vector, but much easier to exploit and practically impossible to protect against.
26
25
 
27
- _Note: Squel is suitable for production use, but you may wish to consider more
28
- actively developed alternatives such as [Knex](http://knexjs.org/)_
26
+ Squel is suitable for production use. If you want richer ORM features you may also want to consider [Knex](https://knexjs.org/).
29
27
 
30
28
  ## Installation
31
29
 
32
- Install using [npm](http://npmjs.org/):
33
-
34
30
  ```bash
35
- $ npm install squel
31
+ # npm
32
+ npm install squel
33
+
34
+ # bun
35
+ bun add squel
36
+
37
+ # yarn
38
+ yarn add squel
39
+
40
+ # pnpm
41
+ pnpm add squel
36
42
  ```
37
43
 
38
- ## Available files
44
+ Squel requires Node.js 18 or newer.
39
45
 
40
- * `squel.js` - unminified version of Squel with the standard commands and all available non-standard commands added
41
- * `squel.min.js` - minified version of `squel.js`
42
- * `squel-basic.js` - unminified version of Squel with only the standard SQL commands
43
- * `squel-basic.min.js` - minified version of `squel-basic.js`
46
+ ## Usage
44
47
 
48
+ ### ESM / TypeScript
45
49
 
46
- ## Examples
50
+ ```typescript
51
+ import squel from "squel"
52
+
53
+ const query = squel.select().from("books").field("title").toString()
54
+ ```
55
+
56
+ ### CommonJS
57
+
58
+ ```javascript
59
+ const squel = require("squel").default
60
+ // or: const { squel } = require("squel")
61
+
62
+ const query = squel.select().from("books").field("title").toString()
63
+ ```
64
+
65
+ ### Browser (CDN)
66
+
67
+ ```html
68
+ <script src="https://unpkg.com/squel/dist/browser/squel.min.js"></script>
69
+ <script>
70
+ // `squel` is available on the global scope
71
+ const query = squel.select().from("books").field("title").toString()
72
+ </script>
73
+ ```
74
+
75
+ ## Package layout
47
76
 
48
- Before running the examples ensure you have `squel` installed and enabled at the top of your script:
77
+ The published package contains:
49
78
 
50
- var squel = require("squel");
79
+ - `dist/esm/` &mdash; ES module build (`import squel from "squel"`).
80
+ - `dist/cjs/` &mdash; CommonJS build (`require("squel")`).
81
+ - `dist/types/` &mdash; TypeScript declaration files.
82
+ - `dist/browser/squel.min.js` &mdash; minified IIFE bundle for `<script>` tags (exposes `window.squel`).
83
+
84
+ ## Examples
51
85
 
52
86
  ### SELECT
53
87
 
@@ -82,10 +116,10 @@ squel.select({ autoQuoteFieldNames: true })
82
116
 
83
117
  You can build parameterized queries:
84
118
 
85
- ```js
119
+ ```javascript
86
120
  /*
87
121
  {
88
- text: "SELECT `t1`.`id`, `t1`.`name` as "My name", `t1`.`started` as "Date" FROM table `t1` WHERE age IN (RANGE(?, ?)) ORDER BY id ASC LIMIT 20",
122
+ text: "SELECT `t1`.`id`, `t1`.`name` as \"My name\", `t1`.`started` as \"Date\" FROM table `t1` WHERE age IN (RANGE(?, ?)) ORDER BY id ASC LIMIT 20",
89
123
  values: [1, 1.2]
90
124
  }
91
125
  */
@@ -100,15 +134,14 @@ squel.select({ autoQuoteFieldNames: true })
100
134
  .toParam()
101
135
  ```
102
136
 
103
-
104
137
  You can use nested queries:
105
138
 
106
139
  ```javascript
107
140
  // SELECT s.id FROM (SELECT * FROM students) `s` INNER JOIN (SELECT id FROM marks) `m` ON (m.id = s.id)
108
141
  squel.select()
109
- .from( squel.select().from('students'), 's' )
110
- .field('id')
111
- .join( squel.select().from('marks').field('id'), 'm', 'm.id = s.id' )
142
+ .from(squel.select().from("students"), "s")
143
+ .field("id")
144
+ .join(squel.select().from("marks").field("id"), "m", "m.id = s.id")
112
145
  .toString()
113
146
  ```
114
147
 
@@ -127,11 +160,11 @@ squel.update()
127
160
  .set("test.id", 1)
128
161
  .table("test2")
129
162
  .set("test2.val", 1.2)
130
- .table("test3","a")
163
+ .table("test3", "a")
131
164
  .setFields({
132
165
  "a.name": "Ram",
133
166
  "a.email": null,
134
- "a.count = a.count + 1": undefined
167
+ "a.count = a.count + 1": undefined,
135
168
  })
136
169
  .toString()
137
170
  ```
@@ -139,59 +172,28 @@ squel.update()
139
172
  ### INSERT
140
173
 
141
174
  ```javascript
142
- // INSERT INTO test (f1) VALUES (1)
175
+ // INSERT INTO test (f1, f2) VALUES (1, 1.2)
143
176
  squel.insert()
144
177
  .into("test")
145
178
  .set("f1", 1)
146
- .toString()
147
-
148
- // INSERT INTO test (name, age) VALUES ('Thomas', 29), ('Jane', 31)
149
- squel.insert()
150
- .into("test")
151
- .setFieldsRows([
152
- { name: "Thomas", age: 29 },
153
- { name: "Jane", age: 31 }
154
- ])
179
+ .set("f2", 1.2)
155
180
  .toString()
156
181
  ```
157
182
 
158
183
  ### DELETE
159
184
 
160
185
  ```javascript
161
- // DELETE FROM test
186
+ // DELETE FROM test WHERE (f1 = 2) ORDER BY f2 LIMIT 1
162
187
  squel.delete()
163
188
  .from("test")
189
+ .where("f1 = 2")
190
+ .order("f2")
191
+ .limit(1)
164
192
  .toString()
165
-
166
- // DELETE FROM table1 WHERE (table1.id = 2) ORDER BY id DESC LIMIT 2
167
- squel.delete()
168
- .from("table1")
169
- .where("table1.id = ?", 2)
170
- .order("id", false)
171
- .limit(2)
172
193
  ```
173
194
 
174
- ### Paramterized queries
175
-
176
- Use the `useParam()` method to obtain a parameterized query with a separate list of formatted parameter values:
177
-
178
- ```javascript
179
- // { text: "INSERT INTO test (f1, f2, f3, f4, f5) VALUES (?, ?, ?, ?, ?)", values: [1, 1.2, "TRUE", "blah", "NULL"] }
180
- squel.insert()
181
- .into("test")
182
- .set("f1", 1)
183
- .set("f2", 1.2)
184
- .set("f3", true)
185
- .set("f4", "blah")
186
- .set("f5", null)
187
- .toParam()
188
- ```
189
-
190
-
191
195
  ### Expression builder
192
196
 
193
- There is also an expression builder which allows you to build complex expressions for `WHERE` and `ON` clauses:
194
-
195
197
  ```javascript
196
198
  // test = 3 OR test = 4
197
199
  squel.expr()
@@ -213,169 +215,141 @@ squel.expr()
213
215
  .and("inner = ?", 4)
214
216
  .or(
215
217
  squel.expr()
216
- .and("inner IN ?", ['str1', 'str2', null])
218
+ .and("inner IN ?", ["str1", "str2", null])
217
219
  )
218
220
  )
219
221
  .toString()
220
222
 
221
223
  // SELECT * FROM test INNER JOIN test2 ON (test.id = test2.id) WHERE (test = 3 OR test = 4)
222
224
  squel.select()
223
- .join( "test2", null, squel.expr().and("test.id = test2.id") )
224
- .where( squel.expr().or("test = 3").or("test = 4") )
225
+ .join("test2", null, squel.expr().and("test.id = test2.id"))
226
+ .where(squel.expr().or("test = 3").or("test = 4"))
227
+ .toString()
225
228
  ```
226
229
 
227
230
  ### Custom value types
228
231
 
229
- By default Squel does not support the use of object instances as field values. Instead it lets you tell it how you want
230
- specific object types to be handled:
232
+ By default Squel does not support the use of object instances as field values. Instead it lets you tell it how you want specific object types to be handled:
231
233
 
232
234
  ```javascript
233
235
  // handler for objects of type Date
234
- squel.registerValueHandler(Date, function(date) {
235
- return date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate();
236
- });
236
+ squel.registerValueHandler(Date, (date) => {
237
+ return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
238
+ })
237
239
 
238
- squel.update().
239
- .table('students')
240
- .set('start_date', new Date(2013, 5, 1))
241
- .toString()
240
+ squel.update()
241
+ .table("students")
242
+ .set("start_date", new Date(2013, 5, 1))
243
+ .toString()
242
244
 
243
245
  // UPDATE students SET start_date = '2013/6/1'
244
246
  ```
245
247
 
246
-
247
- _Note that custom value handlers can be overridden on a per-instance basis (see the [docs](https://hiddentao.com/squel/))_
248
+ Custom value handlers can also be overridden on a per-instance basis (see the [docs](https://hiddentao.github.io/squel)).
248
249
 
249
250
  ### Custom queries
250
251
 
251
- Squel allows you to override the built-in query builders with your own as well as create your own types of queries:
252
+ Squel lets you extend the built-in query builders or create entirely new kinds of queries:
252
253
 
253
254
  ```javascript
254
- // ------------------------------------------------------
255
- // Setup the PRAGMA query builder
256
- // ------------------------------------------------------
257
- var util = require('util'); // to use util.inherits() from node.js
258
-
259
- var CommandBlock = function() {};
260
- util.inherits(CommandBlock, squel.cls.Block);
261
-
262
- // private method - will not get exposed within the query builder
263
- CommandBlock.prototype._command = function(_command) {
264
- this._command = _command;
255
+ class CommandBlock extends squel.cls.Block {
256
+ command(command, arg) {
257
+ this._command = command
258
+ this._arg = arg
259
+ }
260
+ compress(level) {
261
+ this.command("compress", level)
262
+ }
263
+ _toParamString(options) {
264
+ let text = this._command.toUpperCase()
265
+ const values = []
266
+ if (options.buildParameterized) {
267
+ text += " ?"
268
+ values.push(this._arg)
269
+ } else {
270
+ text += ` ${this._arg}`
271
+ }
272
+ return { text, values }
273
+ }
265
274
  }
266
275
 
267
- // public method - will get exposed within the query builder
268
- CommandBlock.prototype.compress = function() {
269
- this._command('compress');
270
- };
271
-
272
- CommandBlock.prototype.buildStr = function() {
273
- return this._command.toUpperCase();
274
- };
275
-
276
-
277
- // generic parameter block
278
- var ParamBlock = function() {};
279
- util.inherits(ParamBlock, squel.cls.Block);
280
-
281
- ParamBlock.prototype.param = function(p) {
282
- this._p = p;
283
- };
284
-
285
- ParamBlock.prototype.buildStr = function() {
286
- return this._p;
287
- };
288
-
289
-
290
- // pragma query builder
291
- var PragmaQuery = function(options) {
292
- squel.cls.QueryBuilder.call(this, options, [
293
- new squel.cls.StringBlock(options, 'PRAGMA'),
294
- new CommandBlock(),
295
- new ParamBlock()
296
- ]);
297
- };
298
- util.inherits(PragmaQuery, squel.cls.QueryBuilder);
299
-
300
-
301
- // convenience method (we can override built-in squel methods this way too)
302
- squel.pragma = function(options) {
303
- return new PragmaQuery(options)
304
- };
305
-
276
+ class PragmaQuery extends squel.cls.QueryBuilder {
277
+ constructor(options) {
278
+ super(options, [
279
+ new squel.cls.StringBlock(options, "PRAGMA"),
280
+ new CommandBlock(options),
281
+ ])
282
+ }
283
+ }
306
284
 
307
- // ------------------------------------------------------
308
- // Build a PRAGMA query
309
- // ------------------------------------------------------
285
+ squel.pragma = (options) => new PragmaQuery(options)
310
286
 
311
- squel.pragma()
312
- .compress()
313
- .param('test')
314
- .toString();
287
+ squel.pragma().compress(9).toString()
288
+ // 'PRAGMA COMPRESS 9'
315
289
 
316
- // 'PRAGMA COMPRESS test'
290
+ squel.pragma().compress(9).toParam()
291
+ // { text: 'PRAGMA COMPRESS ?', values: [9] }
317
292
  ```
318
293
 
319
- Examples of custom queries in the wild:
320
-
321
- * https://github.com/bostrt/squel-top-start-at (blog post about it: http://blog.bostrt.net/extending-squel-js/)
322
-
323
-
324
- ## Non-standard SQL
294
+ ## Non-standard SQL flavours
325
295
 
326
- Squel supports the standard SQL commands and reserved words. However a number of database engines provide their own
327
- non-standard commands. To make things easy Squel allows for different 'flavours' of SQL to be loaded and used.
296
+ Squel supports the standard SQL commands and reserved words. A number of database engines provide their own non-standard commands; Squel makes it easy to load different "flavours" of SQL that augment the core builders with engine-specific features.
328
297
 
329
- At the moment Squel provides `mysql`, `mssql` and `postgres` flavours which augment query builders with additional commands (e.g. `INSERT ... RETURNING`
330
- for use with Postgres).
331
-
332
- To use this in node.js:
298
+ Available flavours: `mysql`, `mssql`, `postgres` (e.g. `INSERT ... RETURNING` for Postgres, `ON DUPLICATE KEY UPDATE` for MySQL).
333
299
 
334
300
  ```javascript
335
- var squel = require('squel').useFlavour('postgres');
301
+ import squel from "squel"
302
+
303
+ const pg = squel.useFlavour("postgres")
304
+ const mysql = squel.useFlavour("mysql")
305
+ const mssql = squel.useFlavour("mssql")
336
306
  ```
337
307
 
338
- For the browser:
308
+ For browser use:
339
309
 
340
310
  ```html
341
- <script type="text/javascript" src="https://rawgithub.com/hiddentao/squel/master/squel.min.js"></script>
342
- <script type="text/javascript">
343
- squel = squel.useFlavour('postgres');
311
+ <script src="https://unpkg.com/squel/dist/browser/squel.min.js"></script>
312
+ <script>
313
+ const pg = squel.useFlavour("postgres")
344
314
  </script>
345
315
  ```
346
316
 
347
- (Internally the flavour setup method simply utilizes the [custom query mechanism](http://hiddentao.github.io/squel/#custom_queries) to effect changes).
348
-
349
- Read the the [API docs](http://hiddentao.github.io/squel/api.html) to find out available commands. Flavours of SQL which get added to
350
- Squel in the future will be usable in the above manner.
351
-
352
- ## Building it
317
+ See the [API docs](http://hiddentao.github.io/squel/api.html) for a full reference.
353
318
 
354
- To build the code and run the tests:
319
+ ## Migrating from v5
355
320
 
356
- $ npm install
357
- $ npm test <-- this will build the code and run the tests
321
+ v6.0.0 is a modernization release. The public API is unchanged &mdash; all your existing `squel.select()`, `squel.useFlavour('postgres')`, and related calls continue to work.
358
322
 
359
- ## Releasing it
323
+ The breaking changes are all about **package shape**:
360
324
 
361
- Instructions for creating a new release of squel are in `RELEASE.md`.
325
+ - **Engines:** `engines.node` is now `>=18`. If you need support for older runtimes, stay on v5.
326
+ - **Output layout:** the `squel.js` / `squel.min.js` / `squel-basic.js` / `squel-basic.min.js` UMD bundles have been replaced. Consumers now import from `dist/esm/`, `dist/cjs/`, or the IIFE at `dist/browser/squel.min.js` (see the [Package layout](#package-layout) section).
327
+ - **No separate "basic" bundle.** The main entry point includes all flavours. ESM users benefit from tree-shaking; script-tag users get the single IIFE.
328
+ - **UMD dropped.** If you loaded `squel.min.js` via `<script>`, switch to `dist/browser/squel.min.js` (same global `window.squel`).
362
329
 
330
+ ## Development
363
331
 
364
- ## Contributing
332
+ ```bash
333
+ bun install # install dependencies
334
+ bun run check # lint & format check (biome)
335
+ bun run typecheck # TypeScript type checking
336
+ bun test # run the test suite
337
+ bun run build # produce dist/esm, dist/cjs, dist/types, dist/browser
338
+ ```
365
339
 
366
- Contributions are welcome! Please see `CONTRIBUTING.md`.
340
+ ## Releasing
367
341
 
368
- ## Older verions
342
+ Releases are automated. Landing a conventional commit on `master` triggers the release workflow, which bumps the version, updates `CHANGELOG.md`, creates a tag, and publishes to npm with provenance. See [`RELEASE.md`](RELEASE.md) for details.
369
343
 
370
- **Note: The latest Squel version only works on Node 0.12 or above. Please use Squel 4.4.1 for Node <0.12. The [old 4.x docs](http://hiddentao.github.io/squel/v4/index.html) are also still available.**
344
+ ## Contributing
371
345
 
346
+ Contributions are welcome! Please see [`CONTRIBUTING.md`](CONTRIBUTING.md).
372
347
 
373
348
  ## Ports to other languages
374
349
 
375
- * .NET - https://github.com/seymourpoler/PetProjects/tree/master/SQUEL
376
- * .NET - https://github.com/seymourpoler/Squel.net
377
- * Crystal - https://github.com/seymourpoler/Squel.crystal
350
+ - .NET &mdash; https://github.com/seymourpoler/Squel.net
351
+ - Crystal &mdash; https://github.com/seymourpoler/Squel.crystal
378
352
 
379
353
  ## License
380
354
 
381
- MIT - see LICENSE.md
355
+ MIT &mdash; see [`LICENSE.md`](LICENSE.md).
@@ -0,0 +1 @@
1
+ (()=>{var{defineProperty:b,getOwnPropertyNames:Q,getOwnPropertyDescriptor:V}=Object,$=Object.prototype.hasOwnProperty;var O=new WeakMap,z=(c)=>{var t=O.get(c),s;if(t)return t;if(t=b({},"__esModule",{value:!0}),c&&typeof c==="object"||typeof c==="function")Q(c).map((i)=>!$.call(t,i)&&b(t,i,{get:()=>c[i],enumerable:!(s=V(c,i))||s.enumerable}));return O.set(c,t),t};var A=(c,t)=>{for(var s in t)b(c,s,{get:t[s],enumerable:!0,configurable:!0,set:(i)=>t[s]=()=>i})};var C={};A(C,{squel:()=>S,default:()=>D});var P={name:"squel",version:"6.0.2",description:"SQL query string builder",keywords:["sql","database","rdbms","query-builder","mysql","postgres","mssql"],author:"Ramesh Nair <ram@hiddentao.com> (http://www.hiddentao.com/)",contributors:["Ramesh Nair <ram@hiddentao.com> (http://www.hiddentao.com/)","Sergej Brjuchanov <serges@seznam.cz>"],license:"MIT",repository:{type:"git",url:"https://github.com/hiddentao/squel.git"},homepage:"https://github.com/hiddentao/squel",bugs:{url:"https://github.com/hiddentao/squel/issues"},type:"module",main:"./dist/cjs/index.js",module:"./dist/esm/index.js",types:"./dist/types/index.d.ts",exports:{".":{types:"./dist/types/index.d.ts",import:"./dist/esm/index.js",require:"./dist/cjs/index.js"},"./browser":"./dist/browser/squel.min.js"},files:["dist","README.md","LICENSE.md","CHANGELOG.md"],engines:{node:">=18.0.0"},publishConfig:{access:"public",provenance:!0},scripts:{build:"bun run scripts/build.ts",test:"bun test","test:coverage":"bun test --coverage --coverage-reporter=lcov","test:watch":"bun test --watch",lint:"biome check --write ./src ./tests ./scripts",format:"biome format --write ./src ./tests ./scripts",check:"biome check ./src ./tests ./scripts",typecheck:"tsc --noEmit",prepare:"husky",prepublishOnly:"bun run build && bun run test"},dependencies:{},devDependencies:{"@biomejs/biome":"^1.9.4","@commitlint/cli":"^19.8.1","@commitlint/config-conventional":"^19.8.1","@types/bun":"latest","@types/node":"^22.0.0","commit-and-tag-version":"^12.6.0",husky:"^9.1.7",typescript:"^5.3.0"}};function p(c,t){return c.length?c+t:c}function f(c,...t){if(c&&t){for(let s of t)if(s&&typeof s==="object")for(let i of Object.getOwnPropertyNames(s))c[i]=s[i]}return c}function x(c){return!!c&&c.constructor.prototype===Object.prototype}function B(c){return!!c&&c.constructor.prototype===Array.prototype}function E(c){if(!c)return c;let t=c;if(typeof t.clone==="function")return t.clone();if(x(c)||B(c)){let s=new t.constructor;for(let i of Object.getOwnPropertyNames(c))if(typeof t[i]!=="function")s[i]=E(t[i]);return s}return JSON.parse(JSON.stringify(c))}function v(c,t,s){let i=typeof t;if(i!=="function"&&i!=="string")throw Error("type must be a class constructor or string");if(typeof s!=="function")throw Error("handler must be a function");for(let e of c)if(e.type===t){e.handler=s;return}c.push({type:t,handler:s})}function T(c,t,s){return F(c,t)||F(c,s)}function F(c,t){for(let s of t)if(typeof c===s.type||typeof s.type!=="string"&&c instanceof s.type)return s.handler;return}function N(c=null){let t={isSquelBuilder(e){return!!e&&!!e._toParamString}},s=(e)=>{return!t.isSquelBuilder(e)||!e.options.rawNesting};t.DefaultQueryBuilderOptions={autoQuoteTableNames:!1,autoQuoteFieldNames:!1,autoQuoteAliasNames:!0,useAsForTableAliasNames:!1,nameQuoteCharacter:"`",tableAliasQuoteCharacter:"`",fieldAliasQuoteCharacter:'"',valueHandlers:[],parameterCharacter:"?",numberedParameters:!1,numberedParametersPrefix:"$",numberedParametersStartAt:1,replaceSingleQuotes:!1,singleQuoteReplacement:"''",separator:" ",stringFormatter:null,rawNesting:!1},t.globalValueHandlers=[],t.registerValueHandler=(e,n)=>{v(t.globalValueHandlers,e,n)},t.Cloneable=class{clone(){let e=new this.constructor;return f(e,E(f({},this)))}},t.BaseBuilder=class extends t.Cloneable{options;constructor(e){super();let n=JSON.parse(JSON.stringify(t.DefaultQueryBuilderOptions));n.stringFormatter=t.DefaultQueryBuilderOptions.stringFormatter,this.options=f(n,e)}registerValueHandler(e,n){return v(this.options.valueHandlers,e,n),this}_sanitizeExpression(e){if(!t.isSquelBuilder(e)){if(typeof e!=="string")throw Error("expression must be a string or builder instance")}return e}_sanitizeName(e,n){if(typeof e!=="string")throw Error(`${n} must be a string`);return e}_sanitizeField(e){if(!t.isSquelBuilder(e))return this._sanitizeName(e,"field name");return e}_sanitizeBaseBuilder(e){if(t.isSquelBuilder(e))return e;throw Error("must be a builder instance")}_sanitizeTable(e,n){if(typeof e!=="string")try{return this._sanitizeBaseBuilder(e)}catch(r){throw Error("table name must be a string or a builder")}return this._sanitizeName(e,"table")}_sanitizeTableAlias(e){return this._sanitizeName(e,"table alias")}_sanitizeFieldAlias(e){return this._sanitizeName(e,"field alias")}_sanitizeLimitOffset(e){let n=Number.parseInt(e,10);if(n<0||Number.isNaN(n))throw Error("limit/offset must be >= 0");return n}_sanitizeValue(e){let n=typeof e;if(e===null);else if(n==="string"||n==="number"||n==="boolean");else if(t.isSquelBuilder(e));else if(!T(e,this.options.valueHandlers,t.globalValueHandlers))throw Error("field value must be a string, number, boolean, null or one of the registered custom value types");return e}_escapeValue(e){return this.options.replaceSingleQuotes&&e?e.replace(/'/g,this.options.singleQuoteReplacement):e}_formatTableName(e){if(this.options.autoQuoteTableNames){let n=this.options.nameQuoteCharacter;e=`${n}${e}${n}`}return e}_formatFieldAlias(e){if(this.options.autoQuoteAliasNames){let n=this.options.fieldAliasQuoteCharacter;e=`${n}${e}${n}`}return e}_formatTableAlias(e){if(this.options.autoQuoteAliasNames){let n=this.options.tableAliasQuoteCharacter;e=`${n}${e}${n}`}return this.options.useAsForTableAliasNames?`AS ${e}`:e}_formatFieldName(e,n={}){if(this.options.autoQuoteFieldNames){let r=this.options.nameQuoteCharacter;if(n.ignorePeriodsForFieldNameQuotes)e=`${r}${e}${r}`;else e=e.split(".").map((a)=>a==="*"?a:`${r}${a}${r}`).join(".")}return e}_formatCustomValue(e,n,r){let a=T(e,this.options.valueHandlers,t.globalValueHandlers);if(a){if(e=a(e,n,r),e&&e.rawNesting)return{formatted:!0,rawNesting:!0,value:e.value}}return{formatted:!!a,value:e}}_formatValueForParamArray(e,n={}){if(B(e))return e.map((r)=>this._formatValueForParamArray(r,n));return this._formatCustomValue(e,!0,n).value}_formatValueForQueryString(e,n={}){let{rawNesting:r,formatted:a,value:o}=this._formatCustomValue(e,!1,n),l=o;if(a){if(r)return l;return this._applyNestingFormatting(l,s(e))}if(B(l))l=l.map((u)=>this._formatValueForQueryString(u)),l=this._applyNestingFormatting(l.join(", "),s(l));else{let u=typeof l;if(l===null)l="NULL";else if(u==="boolean")l=l?"TRUE":"FALSE";else if(t.isSquelBuilder(l))l=this._applyNestingFormatting(l.toString(),s(l));else if(u!=="number"){if(u==="string"&&this.options.stringFormatter)return this.options.stringFormatter(l);if(n.dontQuote)l=`${l}`;else l=`'${this._escapeValue(l)}'`}}return l}_applyNestingFormatting(e,n=!0){if(e&&typeof e==="string"&&n&&!this.options.rawNesting){let r=e.charAt(0)==="("&&e.charAt(e.length-1)===")";if(r){let a=0,o=1;while(e.length-1>++a){let l=e.charAt(a);if(l==="(")o++;else if(l===")"){if(o--,o<1){r=!1;break}}}}if(!r)e=`(${e})`}return e}_buildString(e,n,r={}){let{nested:a,buildParameterized:o,formattingOptions:l}=r;n=n||[],e=e||"";let u="",d=-1,h=[],y=this.options.parameterCharacter,_=0;while(e.length>_)if(e.substring(_,_+y.length)===y){let g=n[++d];if(o)if(t.isSquelBuilder(g)){let w=g._toParamString({buildParameterized:o,nested:!0});u+=w.text,w.values.forEach((k)=>h.push(k))}else if(g=this._formatValueForParamArray(g,l),B(g)){let w=g.map(()=>y).join(", ");u+=`(${w})`,g.forEach((k)=>h.push(k))}else u+=y,h.push(g);else u+=this._formatValueForQueryString(g,l);_+=y.length}else u+=e.charAt(_),_++;return{text:this._applyNestingFormatting(u,!!a),values:h}}_buildManyStrings(e,n,r={}){let a=[],o=[];for(let u=0;e.length>u;++u){let d=e[u],h=n[u],{text:y,values:_}=this._buildString(d,h,{buildParameterized:r.buildParameterized,nested:!1});a.push(y),_.forEach((g)=>o.push(g))}let l=a.join(this.options.separator);return{text:l.length?this._applyNestingFormatting(l,!!r.nested):"",values:o}}_toParamString(e){throw Error("Not yet implemented")}toString(e={}){return this._toParamString(e).text}toParam(e={}){return this._toParamString({...e,buildParameterized:!0})}},t.Expression=class extends t.BaseBuilder{_nodes;constructor(e){super(e);this._nodes=[]}and(e,...n){return e=this._sanitizeExpression(e),this._nodes.push({type:"AND",expr:e,para:n}),this}or(e,...n){return e=this._sanitizeExpression(e),this._nodes.push({type:"OR",expr:e,para:n}),this}_toParamString(e={}){let n=[],r=[];for(let a of this._nodes){let{type:o,expr:l,para:u}=a,{text:d,values:h}=t.isSquelBuilder(l)?l._toParamString({buildParameterized:e.buildParameterized,nested:!0}):this._buildString(l,u,{buildParameterized:e.buildParameterized});if(n.length)n.push(o);n.push(d),h.forEach((y)=>r.push(y))}return n=n.join(" "),{text:this._applyNestingFormatting(n,!!e.nested),values:r}}},t.Case=class extends t.BaseBuilder{_fieldName=null;_cases;_elseValue=null;constructor(e,n={}){super(n);let r=null;if(x(e))n=e;else if(e)r=this._sanitizeField(e);this._fieldName=r,this.options=f(Object.assign({},t.DefaultQueryBuilderOptions),n),this._cases=[]}when(e,...n){return this._cases.unshift({expression:e,values:n||[]}),this}then(e){if(this._cases.length===0)throw Error("when() needs to be called first");return this._cases[0].result=e,this}else(e){return this._elseValue=e,this}_toParamString(e={}){let n="",r=[];for(let{expression:a,values:o,result:l}of this._cases){n=p(n," ");let u=this._buildString(a,o,{buildParameterized:e.buildParameterized,nested:!0});n+=`WHEN ${u.text} THEN ${this._formatValueForQueryString(l)}`,u.values.forEach((d)=>r.push(d))}if(n.length){if(n+=` ELSE ${this._formatValueForQueryString(this._elseValue)} END`,this._fieldName)n=`${this._fieldName} ${n}`;n=`CASE ${n}`}else n=this._formatValueForQueryString(this._elseValue);return{text:n,values:r}}},t.Block=class extends t.BaseBuilder{constructor(e){super(e)}exposedMethods(){let e={},n=this;while(n){for(let r of Object.getOwnPropertyNames(n))if(r!=="constructor"&&typeof n[r]==="function"&&r.charAt(0)!=="_"&&!t.Block.prototype[r])e[r]=n[r];n=Object.getPrototypeOf(n)}return e}},t.StringBlock=class extends t.Block{_str;constructor(e,n){super(e);this._str=n}_toParamString(e={}){return{text:this._str,values:[]}}},t.FunctionBlock=class extends t.Block{_strings;_values;constructor(e){super(e);this._strings=[],this._values=[]}function(e,...n){this._strings.push(e),this._values.push(n)}_toParamString(e={}){return this._buildManyStrings(this._strings,this._values,e)}},t.registerValueHandler(t.FunctionBlock,(e,n=!1)=>{return n?e.toParam():e.toString()}),t.AbstractTableBlock=class extends t.Block{_tables;constructor(e,n){super(e);this._tables=[]}_table(e,n=null){if(n=n?this._sanitizeTableAlias(n):n,e=this._sanitizeTable(e),this.options.singleTable)this._tables=[];this._tables.push({table:e,alias:n})}_hasTable(){return this._tables.length>0}_toParamString(e={}){let n="",r=[];if(this._hasTable()){for(let{table:a,alias:o}of this._tables){n=p(n,", ");let l;if(t.isSquelBuilder(a)){let{text:u,values:d}=a._toParamString({buildParameterized:e.buildParameterized,nested:!0});l=u,d.forEach((h)=>r.push(h))}else l=this._formatTableName(a);if(o)l+=` ${this._formatTableAlias(o)}`;n+=l}if(this.options.prefix)n=`${this.options.prefix} ${n}`}return{text:n,values:r}}},t.TargetTableBlock=class extends t.AbstractTableBlock{target(e){this._table(e)}},t.UpdateTableBlock=class extends t.AbstractTableBlock{table(e,n=null){this._table(e,n)}_toParamString(e={}){if(!this._hasTable())throw Error("table() needs to be called");return super._toParamString(e)}},t.FromTableBlock=class extends t.AbstractTableBlock{constructor(e){super(f({},e,{prefix:"FROM"}))}from(e,n=null){this._table(e,n)}},t.IntoTableBlock=class extends t.AbstractTableBlock{constructor(e){super(f({},e,{prefix:"INTO",singleTable:!0}))}into(e){this._table(e)}_toParamString(e={}){if(!this._hasTable())throw Error("into() needs to be called");return super._toParamString(e)}},t.GetFieldBlock=class extends t.Block{_fields;constructor(e){super(e);this._fields=[]}fields(e,n={}){if(B(e))for(let r of e)this.field(r,null,n);else for(let r in e){let a=e[r];this.field(r,a,n)}}field(e,n=null,r={}){if(n=n?this._sanitizeFieldAlias(n):n,e=this._sanitizeField(e),this._fields.filter((o)=>o.name===e&&o.alias===n).length)return this;this._fields.push({name:e,alias:n,options:r});return}_toParamString(e={}){let{queryBuilder:n,buildParameterized:r}=e,a="",o=[];for(let l of this._fields){a=p(a,", ");let{name:u,alias:d,options:h}=l;if(typeof u==="string")a+=this._formatFieldName(u,h);else{let y=u._toParamString({nested:!0,buildParameterized:r});a+=y.text,y.values.forEach((_)=>o.push(_))}if(d)a+=` AS ${this._formatFieldAlias(d)}`}if(!a.length){let l=n?.getBlock(t.FromTableBlock);if(l&&l._hasTable())a="*"}return{text:a,values:o}}},t.AbstractSetFieldBlock=class extends t.Block{_fields;_values;_valueOptions;constructor(e){super(e);this._fields=[],this._values=[[]],this._valueOptions=[[]]}_reset(){this._fields=[],this._values=[[]],this._valueOptions=[[]]}_set(e,n,r={}){if(this._values.length>1)throw Error("Cannot set multiple rows of fields this way.");if(typeof n<"u")n=this._sanitizeValue(n);e=this._sanitizeField(e);let a=this._fields.indexOf(e);if(a===-1)this._fields.push(e),a=this._fields.length-1;this._values[0][a]=n,this._valueOptions[0][a]=r}_setFields(e,n={}){if(typeof e!=="object")throw Error(`Expected an object but got ${typeof e}`);for(let r in e)this._set(r,e[r],n)}_setFieldsRows(e,n={}){if(!B(e))throw Error(`Expected an array of objects but got ${typeof e}`);this._reset();for(let r=0;e.length>r;++r){let a=e[r];for(let o in a){let l=a[o];o=this._sanitizeField(o),l=this._sanitizeValue(l);let u=this._fields.indexOf(o);if(r>0&&u===-1)throw Error("All fields in subsequent rows must match the fields in the first row");if(u===-1)this._fields.push(o),u=this._fields.length-1;if(!B(this._values[r]))this._values[r]=[],this._valueOptions[r]=[];this._values[r][u]=l,this._valueOptions[r][u]=n}}}},t.SetFieldBlock=class extends t.AbstractSetFieldBlock{set(e,n,r){this._set(e,n,r)}setFields(e,n){this._setFields(e,n)}_toParamString(e={}){let{buildParameterized:n}=e;if(this._fields.length<=0)throw Error("set() needs to be called");let r="",a=[];for(let o=0;o<this._fields.length;++o){r=p(r,", ");let l=this._formatFieldName(this._fields[o]),u=this._values[0][o];if(l.indexOf("=")<0)l=`${l} = ${this.options.parameterCharacter}`;let d=this._buildString(l,[u],{buildParameterized:n,formattingOptions:this._valueOptions[0][o]});r+=d.text,d.values.forEach((h)=>a.push(h))}return{text:`SET ${r}`,values:a}}},t.InsertFieldValueBlock=class extends t.AbstractSetFieldBlock{set(e,n,r={}){this._set(e,n,r)}setFields(e,n){this._setFields(e,n)}setFieldsRows(e,n){this._setFieldsRows(e,n)}_toParamString(e={}){let{buildParameterized:n}=e,r=this._fields.map((l)=>this._formatFieldName(l)).join(", "),a=[],o=[];for(let l=0;l<this._values.length;++l){a[l]="";for(let u=0;u<this._values[l].length;++u){let d=this._buildString(this.options.parameterCharacter,[this._values[l][u]],{buildParameterized:n,formattingOptions:this._valueOptions[l][u]});d.values.forEach((h)=>o.push(h)),a[l]=p(a[l],", "),a[l]+=d.text}}return{text:r.length?`(${r}) VALUES (${a.join("), (")})`:"",values:o}}},t.InsertFieldsFromQueryBlock=class extends t.Block{_fields;_query=null;constructor(e){super(e);this._fields=[]}fromQuery(e,n){this._fields=e.map((r)=>this._sanitizeField(r)),this._query=this._sanitizeBaseBuilder(n)}_toParamString(e={}){let n="",r=[];if(this._fields.length&&this._query){let{text:a,values:o}=this._query._toParamString({buildParameterized:e.buildParameterized,nested:!0});n=`(${this._fields.join(", ")}) ${this._applyNestingFormatting(a)}`,r=o}return{text:n,values:r}}},t.DistinctBlock=class extends t.Block{_useDistinct=!1;distinct(){this._useDistinct=!0}_toParamString(){return{text:this._useDistinct?"DISTINCT":"",values:[]}}},t.GroupByBlock=class extends t.Block{_groups;constructor(e){super(e);this._groups=[]}group(e){this._groups.push(this._sanitizeField(e))}_toParamString(e={}){return{text:this._groups.length?`GROUP BY ${this._groups.join(", ")}`:"",values:[]}}},t.AbstractVerbSingleValueBlock=class extends t.Block{_value=null;constructor(e){super(e)}_setValue(e){this._value=e!==null?this._sanitizeLimitOffset(e):e}_toParamString(e={}){let n=this._value!==null?`${this.options.verb} ${this.options.parameterCharacter}`:"",r=this._value!==null?[this._value]:[];return this._buildString(n,r,e)}},t.OffsetBlock=class extends t.AbstractVerbSingleValueBlock{constructor(e){super(f({},e,{verb:"OFFSET"}))}offset(e){this._setValue(e)}},t.LimitBlock=class extends t.AbstractVerbSingleValueBlock{constructor(e){super(f({},e,{verb:"LIMIT"}))}limit(e){this._setValue(e)}},t.AbstractConditionBlock=class extends t.Block{_conditions;constructor(e){super(e);this._conditions=[]}_condition(e,...n){e=this._sanitizeExpression(e),this._conditions.push({expr:e,values:n||[]})}_toParamString(e={}){let n=[],r=[];for(let{expr:o,values:l}of this._conditions){let u=t.isSquelBuilder(o)?o._toParamString({buildParameterized:e.buildParameterized}):this._buildString(o,l,{buildParameterized:e.buildParameterized});if(u.text.length)n.push(u.text);u.values.forEach((d)=>r.push(d))}let a=n.join(") AND (");return{text:a.length?`${this.options.verb} (${a})`:"",values:r}}},t.WhereBlock=class extends t.AbstractConditionBlock{constructor(e){super(f({},e,{verb:"WHERE"}))}where(e,...n){this._condition(e,...n)}},t.HavingBlock=class extends t.AbstractConditionBlock{constructor(e){super(f({},e,{verb:"HAVING"}))}having(e,...n){this._condition(e,...n)}},t.OrderByBlock=class extends t.Block{_orders;constructor(e){super(e);this._orders=[]}order(e,n,...r){e=this._sanitizeField(e);let a;if(typeof n==="string")a=n;else if(n===void 0)a="ASC";else if(n===null)a=null;else a=n?"ASC":"DESC";this._orders.push({field:e,dir:a,values:r||[]})}_toParamString(e={}){let n="",r=[];for(let{field:a,dir:o,values:l}of this._orders){n=p(n,", ");let u=this._buildString(a,l,{buildParameterized:e.buildParameterized});if(n+=u.text,B(u.values))u.values.forEach((d)=>r.push(d));if(o!==null)n+=` ${o}`}return{text:n.length?`ORDER BY ${n}`:"",values:r}}},t.JoinBlock=class extends t.Block{_joins;constructor(e){super(e);this._joins=[]}join(e,n=null,r=null,a="INNER"){e=this._sanitizeTable(e,!0),n=n?this._sanitizeTableAlias(n):n,r=r?this._sanitizeExpression(r):r,this._joins.push({type:a,table:e,alias:n,condition:r})}left_join(e,n=null,r=null){this.join(e,n,r,"LEFT")}right_join(e,n=null,r=null){this.join(e,n,r,"RIGHT")}outer_join(e,n=null,r=null){this.join(e,n,r,"OUTER")}left_outer_join(e,n=null,r=null){this.join(e,n,r,"LEFT OUTER")}full_join(e,n=null,r=null){this.join(e,n,r,"FULL")}cross_join(e,n=null,r=null){this.join(e,n,r,"CROSS")}_toParamString(e={}){let n="",r=[];for(let{type:a,table:o,alias:l,condition:u}of this._joins){n=p(n,this.options.separator);let d;if(t.isSquelBuilder(o)){let h=o._toParamString({buildParameterized:e.buildParameterized,nested:!0});h.values.forEach((y)=>r.push(y)),d=h.text}else d=this._formatTableName(o);if(n+=`${a} JOIN ${d}`,l)n+=` ${this._formatTableAlias(l)}`;if(u){n+=" ON ";let h;if(t.isSquelBuilder(u))h=u._toParamString({buildParameterized:e.buildParameterized});else h=this._buildString(u,[],{buildParameterized:e.buildParameterized});n+=this._applyNestingFormatting(h.text),h.values.forEach((y)=>r.push(y))}}return{text:n,values:r}}},t.UnionBlock=class extends t.Block{_unions;constructor(e){super(e);this._unions=[]}union(e,n="UNION"){e=this._sanitizeTable(e),this._unions.push({type:n,table:e})}union_all(e){this.union(e,"UNION ALL")}_toParamString(e={}){let n="",r=[];for(let{type:a,table:o}of this._unions){n=p(n,this.options.separator);let l;if(o instanceof t.BaseBuilder){let u=o._toParamString({buildParameterized:e.buildParameterized,nested:!0});l=u.text,u.values.forEach((d)=>r.push(d))}else n=this._formatTableName(o),l="";n+=`${a} ${l}`}return{text:n,values:r}}},t.QueryBuilder=class extends t.BaseBuilder{blocks;constructor(e,n){super(e);this.blocks=n||[];for(let r of this.blocks){let a=r.exposedMethods();for(let o in a){let l=a[o];if(this[o]!==void 0)throw Error(`Builder already has a builder method called: ${o}`);((u,d,h)=>{this[d]=(...y)=>{return h.call(u,...y),this}})(r,o,l)}}}registerValueHandler(e,n){for(let r of this.blocks)r.registerValueHandler(e,n);return super.registerValueHandler(e,n),this}updateOptions(e){this.options=f(this.options,e);for(let n of this.blocks)n.options=f(n.options,e)}_toParamString(e={}){let n=f({},this.options,e),r=this.blocks.map((d)=>d._toParamString({buildParameterized:n.buildParameterized,queryBuilder:this})),a=r.map((d)=>d.text),o=r.map((d)=>d.values),l=a.filter((d)=>d.length>0).join(n.separator),u=[];if(o.forEach((d)=>d.forEach((h)=>u.push(h))),!n.nested){if(n.numberedParameters){let d=n.numberedParametersStartAt!==void 0?n.numberedParametersStartAt:1,h=n.parameterCharacter.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&");l=l.replace(new RegExp(h,"g"),()=>{return`${n.numberedParametersPrefix}${d++}`})}}return{text:this._applyNestingFormatting(l,!!n.nested),values:u}}clone(){let e=this.blocks.map((n)=>n.clone());return new this.constructor(this.options,e)}getBlock(e){return this.blocks.filter((n)=>n instanceof e)[0]}},t.Select=class extends t.QueryBuilder{constructor(e,n=null){n=n||[new t.StringBlock(e,"SELECT"),new t.FunctionBlock(e),new t.DistinctBlock(e),new t.GetFieldBlock(e),new t.FromTableBlock(e),new t.JoinBlock(e),new t.WhereBlock(e),new t.GroupByBlock(e),new t.HavingBlock(e),new t.OrderByBlock(e),new t.LimitBlock(e),new t.OffsetBlock(e),new t.UnionBlock(e)];super(e,n)}},t.Update=class extends t.QueryBuilder{constructor(e,n=null){n=n||[new t.StringBlock(e,"UPDATE"),new t.UpdateTableBlock(e),new t.SetFieldBlock(e),new t.WhereBlock(e),new t.OrderByBlock(e),new t.LimitBlock(e)];super(e,n)}},t.Delete=class extends t.QueryBuilder{constructor(e,n=null){n=n||[new t.StringBlock(e,"DELETE"),new t.TargetTableBlock(e),new t.FromTableBlock(f({},e,{singleTable:!0})),new t.JoinBlock(e),new t.WhereBlock(e),new t.OrderByBlock(e),new t.LimitBlock(e)];super(e,n)}},t.Insert=class extends t.QueryBuilder{constructor(e,n=null){n=n||[new t.StringBlock(e,"INSERT"),new t.IntoTableBlock(e),new t.InsertFieldValueBlock(e),new t.InsertFieldsFromQueryBlock(e)];super(e,n)}};let i={VERSION:P.version,flavour:c,expr:(e)=>new t.Expression(e),case:(e,n)=>new t.Case(e,n),select:(e,n)=>new t.Select(e,n),update:(e,n)=>new t.Update(e,n),insert:(e,n)=>new t.Insert(e,n),delete:(e,n)=>new t.Delete(e,n),str:(...e)=>{let n=new t.FunctionBlock;return n.function(...e),n},rstr:(...e)=>{let n=new t.FunctionBlock({rawNesting:!0});return n.function(...e),n},registerValueHandler:t.registerValueHandler};return i.remove=i.delete,i.cls=t,i}var m=N();m.flavours={};m.useFlavour=function(t=null){if(!t)return m;if(m.flavours[t]instanceof Function){let s=N(t);return m.flavours[t].call(null,s),s.flavours=m.flavours,s.useFlavour=m.useFlavour,s}throw Error(`Flavour not available: ${t}`)};var S=m;m.flavours.mysql=(c)=>{let t=c.cls;t.MysqlOnDuplicateKeyUpdateBlock=class extends t.AbstractSetFieldBlock{onDupUpdate(s,i,e){this._set(s,i,e)}_toParamString(s={}){let i="",e=[];for(let n=0;n<this._fields.length;++n){i=p(i,", ");let r=this._fields[n],a=this._values[0][n],o=this._valueOptions[0][n];if(typeof a>"u")i+=r;else{let l=this._buildString(`${r} = ${this.options.parameterCharacter}`,[a],{buildParameterized:s.buildParameterized,formattingOptions:o});i+=l.text,l.values.forEach((u)=>e.push(u))}}return{text:!i.length?"":`ON DUPLICATE KEY UPDATE ${i}`,values:e}}},t.Insert=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.StringBlock(s,"INSERT"),new t.IntoTableBlock(s),new t.InsertFieldValueBlock(s),new t.InsertFieldsFromQueryBlock(s),new t.MysqlOnDuplicateKeyUpdateBlock(s)];super(s,i)}},t.Replace=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.StringBlock(s,"REPLACE"),new t.IntoTableBlock(s),new t.InsertFieldValueBlock(s),new t.InsertFieldsFromQueryBlock(s)];super(s,i)}},c.replace=(s,i)=>new t.Replace(s,i)};m.flavours.postgres=(c)=>{let t=c.cls;t.DefaultQueryBuilderOptions.numberedParameters=!0,t.DefaultQueryBuilderOptions.numberedParametersStartAt=1,t.DefaultQueryBuilderOptions.autoQuoteAliasNames=!1,t.DefaultQueryBuilderOptions.useAsForTableAliasNames=!0,t.PostgresOnConflictKeyUpdateBlock=class extends t.AbstractSetFieldBlock{_onConflict;_dupFields;constructor(s){super(s);this._onConflict=!1,this._dupFields=[]}onConflict(s,i){if(this._onConflict=!0,!s)return;if(!B(s))s=[s];if(this._dupFields=s.map(this._sanitizeField.bind(this)),i)Object.keys(i).forEach((e)=>{this._set(e,i[e])})}_toParamString(s={}){let i="",e=[];for(let r=0;r<this._fields.length;++r){i=p(i,", ");let a=this._fields[r],o=this._values[0][r],l=this._valueOptions[0][r];if(typeof o>"u")i+=a;else{let u=this._buildString(`${a} = ${this.options.parameterCharacter}`,[o],{buildParameterized:s.buildParameterized,formattingOptions:l});i+=u.text,u.values.forEach((d)=>e.push(d))}}let n={text:"",values:e};if(this._onConflict){let r=this._dupFields.length?`(${this._dupFields.join(", ")}) `:"",a=i.length?`UPDATE SET ${i}`:"NOTHING";n.text=`ON CONFLICT ${r}DO ${a}`}return n}},t.ReturningBlock=class extends t.Block{_fields;constructor(s){super(s);this._fields=[]}returning(s,i=null,e={}){if(i=i?this._sanitizeFieldAlias(i):i,s=this._sanitizeField(s),this._fields.filter((r)=>r.name===s&&r.alias===i).length)return this;this._fields.push({name:s,alias:i,options:e})}_toParamString(s={}){let{buildParameterized:i}=s,e="",n=[];for(let r of this._fields){e=p(e,", ");let{name:a,alias:o,options:l}=r;if(typeof a==="string")e+=this._formatFieldName(a,l);else{let u=a._toParamString({nested:!0,buildParameterized:i});e+=u.text,u.values.forEach((d)=>n.push(d))}if(o)e+=` AS ${this._formatFieldAlias(o)}`}return{text:e.length>0?`RETURNING ${e}`:"",values:n}}},t.WithBlock=class extends t.Block{_tables;constructor(s){super(s);this._tables=[]}with(s,i){this._tables.push({alias:s,table:i})}_toParamString(s={}){let i=[],e=[];for(let{alias:n,table:r}of this._tables){let a=r._toParamString({buildParameterized:s.buildParameterized,nested:!0});i.push(`${n} AS ${a.text}`),a.values.forEach((o)=>e.push(o))}return{text:i.length?`WITH ${i.join(", ")}`:"",values:e}}},t.DistinctOnBlock=class extends t.Block{_useDistinct=!1;_distinctFields;constructor(s){super(s);this._distinctFields=[]}distinct(...s){this._useDistinct=!0,s.forEach((i)=>{this._distinctFields.push(this._sanitizeField(i))})}_toParamString(){let s="";if(this._useDistinct){if(s="DISTINCT",this._distinctFields.length)s+=` ON (${this._distinctFields.join(", ")})`}return{text:s,values:[]}}},t.Select=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.WithBlock(s),new t.StringBlock(s,"SELECT"),new t.FunctionBlock(s),new t.DistinctOnBlock(s),new t.GetFieldBlock(s),new t.FromTableBlock(s),new t.JoinBlock(s),new t.WhereBlock(s),new t.GroupByBlock(s),new t.HavingBlock(s),new t.OrderByBlock(s),new t.LimitBlock(s),new t.OffsetBlock(s),new t.UnionBlock(s)];super(s,i)}},t.Insert=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.WithBlock(s),new t.StringBlock(s,"INSERT"),new t.IntoTableBlock(s),new t.InsertFieldValueBlock(s),new t.InsertFieldsFromQueryBlock(s),new t.PostgresOnConflictKeyUpdateBlock(s),new t.ReturningBlock(s)];super(s,i)}},t.Update=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.WithBlock(s),new t.StringBlock(s,"UPDATE"),new t.UpdateTableBlock(s),new t.SetFieldBlock(s),new t.FromTableBlock(s),new t.WhereBlock(s),new t.OrderByBlock(s),new t.LimitBlock(s),new t.ReturningBlock(s)];super(s,i)}},t.Delete=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.WithBlock(s),new t.StringBlock(s,"DELETE"),new t.TargetTableBlock(s),new t.FromTableBlock({...s,singleTable:!0}),new t.JoinBlock(s),new t.WhereBlock(s),new t.OrderByBlock(s),new t.LimitBlock(s),new t.ReturningBlock(s)];super(s,i)}}};m.flavours.mssql=(c)=>{let t=c.cls;t.DefaultQueryBuilderOptions.replaceSingleQuotes=!0,t.DefaultQueryBuilderOptions.autoQuoteAliasNames=!1,t.DefaultQueryBuilderOptions.numberedParametersPrefix="@",c.registerValueHandler(Date,(s)=>{let i=s;return`'${i.getUTCFullYear()}-${i.getUTCMonth()+1}-${i.getUTCDate()} ${i.getUTCHours()}:${i.getUTCMinutes()}:${i.getUTCSeconds()}'`}),t.MssqlLimitOffsetTopBlock=class extends t.Block{_limits;_offsets;ParentBlock;LimitBlock;TopBlock;OffsetBlock;constructor(s){super(s);this._limits=null,this._offsets=null;let i=function(e){e=this._sanitizeLimitOffset(e),this._parent._limits=e};this.ParentBlock=class extends t.Block{_parent;constructor(e){super(e.options);this._parent=e}},this.LimitBlock=class extends this.ParentBlock{limit;constructor(e){super(e);this.limit=i}_toParamString(){let e="";if(this._parent._limits&&this._parent._offsets)e=`FETCH NEXT ${this._parent._limits} ROWS ONLY`;return{text:e,values:[]}}},this.TopBlock=class extends this.ParentBlock{top;constructor(e){super(e);this.top=i}_toParamString(){let e="";if(this._parent._limits&&!this._parent._offsets)e=`TOP (${this._parent._limits})`;return{text:e,values:[]}}},this.OffsetBlock=class extends this.ParentBlock{offset(e){this._parent._offsets=this._sanitizeLimitOffset(e)}_toParamString(){let e="";if(this._parent._offsets)e=`OFFSET ${this._parent._offsets} ROWS`;return{text:e,values:[]}}}}LIMIT(){return new this.LimitBlock(this)}TOP(){return new this.TopBlock(this)}OFFSET(){return new this.OffsetBlock(this)}},t.MssqlUpdateTopBlock=class extends t.Block{_limits;limit;top;constructor(s){super(s);this._limits=null;let i=(e)=>{this._limits=this._sanitizeLimitOffset(e)};this.limit=i,this.top=i}_toParamString(){return{text:this._limits?`TOP (${this._limits})`:"",values:[]}}},t.MssqlInsertFieldValueBlock=class extends t.InsertFieldValueBlock{_outputs;constructor(s){super(s);this._outputs=[]}output(s){if(typeof s==="string")this._outputs.push(`INSERTED.${this._sanitizeField(s)}`);else s.forEach((i)=>{this._outputs.push(`INSERTED.${this._sanitizeField(i)}`)})}_toParamString(s){let i=super._toParamString(s);if(i.text.length&&this._outputs.length>0){let e=`OUTPUT ${this._outputs.join(", ")} `,n=i.text.indexOf("VALUES");i.text=i.text.substring(0,n)+e+i.text.substring(n)}return i}},t.MssqlUpdateDeleteOutputBlock=class extends t.Block{_outputs;constructor(s){super(s);this._outputs=[]}outputs(s){for(let i in s)this.output(i,s[i])}output(s,i=null){s=this._sanitizeField(s),i=i?this._sanitizeFieldAlias(i):i,this._outputs.push({name:this.options.forDelete?`DELETED.${s}`:`INSERTED.${s}`,alias:i})}_toParamString(s){let i="";if(this._outputs.length){for(let e of this._outputs)if(i=p(i,", "),i+=e.name,e.alias)i+=` AS ${this._formatFieldAlias(e.alias)}`;i=`OUTPUT ${i}`}return{text:i,values:[]}}},t.Select=class extends t.QueryBuilder{constructor(s,i=null){let e=new t.MssqlLimitOffsetTopBlock(s);i=i||[new t.StringBlock(s,"SELECT"),new t.DistinctBlock(s),e.TOP(),new t.GetFieldBlock(s),new t.FromTableBlock(s),new t.JoinBlock(s),new t.WhereBlock(s),new t.GroupByBlock(s),new t.OrderByBlock(s),e.OFFSET(),e.LIMIT(),new t.UnionBlock(s)];super(s,i)}},t.Update=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.StringBlock(s,"UPDATE"),new t.MssqlUpdateTopBlock(s),new t.UpdateTableBlock(s),new t.SetFieldBlock(s),new t.MssqlUpdateDeleteOutputBlock(s),new t.WhereBlock(s)];super(s,i)}},t.Delete=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.StringBlock(s,"DELETE"),new t.TargetTableBlock(s),new t.FromTableBlock(f({},s,{singleTable:!0})),new t.JoinBlock(s),new t.MssqlUpdateDeleteOutputBlock(f({},s,{forDelete:!0})),new t.WhereBlock(s),new t.OrderByBlock(s),new t.LimitBlock(s)];super(s,i)}},t.Insert=class extends t.QueryBuilder{constructor(s,i=null){i=i||[new t.StringBlock(s,"INSERT"),new t.IntoTableBlock(s),new t.MssqlInsertFieldValueBlock(s),new t.InsertFieldsFromQueryBlock(s)];super(s,i)}}};var D=S;})();