sql-love 1.1.0 → 1.1.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/dist/index.cjs CHANGED
@@ -1,65 +1,71 @@
1
1
  var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __moduleCache = /* @__PURE__ */ new WeakMap;
6
- var __toCommonJS = (from) => {
7
- var entry = __moduleCache.get(from), desc;
8
- if (entry)
9
- return entry;
10
- entry = __defProp({}, "__esModule", { value: true });
11
- if (from && typeof from === "object" || typeof from === "function")
12
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
- get: () => from[key],
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- }));
16
- __moduleCache.set(from, entry);
17
- return entry;
18
- };
19
5
  var __export = (target, all) => {
20
6
  for (var name in all)
21
- __defProp(target, name, {
22
- get: all[name],
23
- enumerable: true,
24
- configurable: true,
25
- set: (newValue) => all[name] = () => newValue
26
- });
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
27
16
  };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
18
 
29
19
  // index.ts
30
- var exports_sql_love = {};
31
- __export(exports_sql_love, {
32
- toSafeJsonValue: () => toSafeJsonValue,
33
- toSafeJsonString: () => toSafeJsonString,
34
- toSafeJsonRecords: () => toSafeJsonRecords,
35
- toSafeJsonRecord: () => toSafeJsonRecord,
36
- runPrismaWithCount: () => runPrismaWithCount,
37
- runPrisma: () => runPrisma,
38
- runMysqlWithCount: () => runMysqlWithCount,
39
- runMysqlAsyncWithCount: () => runMysqlAsyncWithCount,
40
- runMysqlAsync: () => runMysqlAsync,
41
- runMysql: () => runMysql,
42
- getPagination: () => getPagination,
43
- extractLookup: () => extractLookup,
44
- extractIndexed: () => extractIndexed,
45
- extractGrouped: () => extractGrouped,
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ Parser: () => Parser,
46
23
  SelectBuilder: () => SelectBuilder,
47
- Parser: () => Parser
24
+ extractGrouped: () => extractGrouped,
25
+ extractIndexed: () => extractIndexed,
26
+ extractLookup: () => extractLookup,
27
+ getPagination: () => getPagination,
28
+ runMysql: () => runMysql,
29
+ runMysqlAsync: () => runMysqlAsync,
30
+ runMysqlAsyncWithCount: () => runMysqlAsyncWithCount,
31
+ runMysqlWithCount: () => runMysqlWithCount,
32
+ runPrisma: () => runPrisma,
33
+ runPrismaWithCount: () => runPrismaWithCount,
34
+ toSafeJsonRecord: () => toSafeJsonRecord,
35
+ toSafeJsonRecords: () => toSafeJsonRecords,
36
+ toSafeJsonString: () => toSafeJsonString,
37
+ toSafeJsonValue: () => toSafeJsonValue
48
38
  });
49
- module.exports = __toCommonJS(exports_sql_love);
39
+ module.exports = __toCommonJS(index_exports);
50
40
 
51
41
  // src/Parser/Parser.ts
52
- class Parser {
42
+ var Parser = class {
53
43
  query;
44
+ /**
45
+ * Create a new instance
46
+ * @param query A Select object on which to build parsed conditions
47
+ */
54
48
  constructor(query) {
55
49
  this.query = query;
56
50
  }
51
+ /**
52
+ * Strip single-line and multi-line comment blocks
53
+ * @param sql The SQL string
54
+ * @return The SQL string without comments
55
+ * @private
56
+ */
57
57
  _stripComments(sql) {
58
58
  sql = sql.replace(/\/\*[\s\S]*?\*\//g, "");
59
59
  sql = sql.replace(/--([\r\n]|\s+[^\r\n]+[\r\n])/g, "");
60
60
  sql = sql.replace(/#[^\r\n]+[\r\n]/g, "");
61
61
  return sql;
62
62
  }
63
+ /**
64
+ * Before splitting into SQL clauses, extract some regex-able subQueries
65
+ * @param sql The unparsed sql string
66
+ * @return An array with new sql and subQueries
67
+ * @private
68
+ */
63
69
  _extractSubQueries(sql) {
64
70
  const subQueries = {};
65
71
  let i = 0;
@@ -73,6 +79,11 @@ class Parser {
73
79
  sql = sql.replace(/\bIN\s*\(\s*SELECT\s.+?\)/, extractor);
74
80
  return { sql, subQueries };
75
81
  }
82
+ /**
83
+ * Inject column subQueries back into this object
84
+ * @param subQueries The lookup of extracted subQueries
85
+ * @private
86
+ */
76
87
  _injectSubQueries(subQueries) {
77
88
  const replacer = ($0) => {
78
89
  return subQueries[$0] || $0;
@@ -85,10 +96,21 @@ class Parser {
85
96
  this.query._wheres = this.query._wheres.map(mapper);
86
97
  this.query._havings = this.query._havings.map(mapper);
87
98
  }
99
+ /**
100
+ * Split SQL into clauses (used by parse())
101
+ * @param sql The SQL to split
102
+ * @return
103
+ * @private
104
+ */
88
105
  _split(sql) {
89
106
  const splitter = /(?:^|\s)(SELECT|FROM|(?:INNER|LEFT\s+OUTER|RIGHT\s+OUTER|LEFT|RIGHT|CROSS|FULL|FULL\s+OUTER)\s+JOIN|WHERE|GROUP\s+BY|HAVING|ORDER\s+BY|LIMIT|OFFSET|FETCH\s+NEXT)\b/i;
90
107
  return sql.split(splitter);
91
108
  }
109
+ /**
110
+ * Get a QuickSelect object representing the given SQL SELECT statement
111
+ * @param rawSql The raw SQL for the SELECT statement
112
+ * @return True if the SQL was parsed successfully
113
+ */
92
114
  parse(rawSql) {
93
115
  const stripped = this._stripComments(rawSql);
94
116
  const { sql, subQueries } = this._extractSubQueries(stripped);
@@ -99,11 +121,16 @@ class Parser {
99
121
  const keyword = rawKeyword.toUpperCase().replace(/\s+/g, "_");
100
122
  const clause = expressions[i++].trim();
101
123
  const handler = `_handle${keyword}`;
102
- this[handler](clause);
124
+ this[handler]?.(clause);
103
125
  }
104
126
  this._injectSubQueries(subQueries);
105
127
  return true;
106
128
  }
129
+ /**
130
+ * Handle SQL_CALC_FOUND_ROWS and column names
131
+ * @param clause The clause after the SELECT
132
+ * @private
133
+ */
107
134
  _handleSELECT(clause) {
108
135
  let columns = clause.split(/s*,s*/);
109
136
  let buffer = "";
@@ -131,34 +158,84 @@ class Parser {
131
158
  }
132
159
  });
133
160
  }
161
+ /**
162
+ * Handle table names
163
+ * @param clause The clause after the FROM
164
+ * @private
165
+ */
134
166
  _handleFROM(clause) {
135
167
  const tables = clause.split(/\s*,\s*/);
136
168
  tables.forEach((table) => this.query.table(table));
137
169
  }
170
+ /**
171
+ * Handle INNER JOIN statements
172
+ * @param clause The clause after the INNER JOIN
173
+ * @private
174
+ */
138
175
  _handleINNER_JOIN(clause) {
139
176
  this.query.innerJoin(clause);
140
177
  }
178
+ /**
179
+ * Handle LEFT JOIN statements
180
+ * @param clause The clause after the LEFT JOIN
181
+ * @private
182
+ */
141
183
  _handleLEFT_JOIN(clause) {
142
184
  this.query.leftJoin(clause);
143
185
  }
186
+ /**
187
+ * Handle LEFT OUTER JOIN statements
188
+ * @param clause The clause after the LEFT OUTER JOIN
189
+ * @private
190
+ */
144
191
  _handleLEFT_OUTER_JOIN(clause) {
145
192
  this.query.leftOuterJoin(clause);
146
193
  }
194
+ /**
195
+ * Handle RIGHT JOIN statements
196
+ * @param clause The clause after the RIGHT JOIN
197
+ * @private
198
+ */
147
199
  _handleRIGHT_JOIN(clause) {
148
200
  this.query.rightJoin(clause);
149
201
  }
202
+ /**
203
+ * Handle RIGHT OUTER JOIN statements
204
+ * @param clause The clause after the RIGHT OUTER JOIN
205
+ * @private
206
+ */
150
207
  _handleRIGHT_OUTER_JOIN(clause) {
151
208
  this.query.rightOuterJoin(clause);
152
209
  }
210
+ /**
211
+ * Handle CROSS JOIN statements
212
+ * @param clause The clause after the CROSS JOIN
213
+ * @private
214
+ */
153
215
  _handleCROSS_JOIN(clause) {
154
216
  this.query.crossJoin(clause);
155
217
  }
218
+ /**
219
+ * Handle FULL JOIN statements
220
+ * @param clause The clause after the FULL JOIN
221
+ * @private
222
+ */
156
223
  _handleFULL_JOIN(clause) {
157
224
  this.query.fullJoin(clause);
158
225
  }
226
+ /**
227
+ * Handle FULL OUTER JOIN statements
228
+ * @param clause The clause after the FULL OUTER JOIN
229
+ * @private
230
+ */
159
231
  _handleFULL_OUTER_JOIN(clause) {
160
232
  this.query.fullOuterJoin(clause);
161
233
  }
234
+ /**
235
+ * Handle WHERE conditions
236
+ * @param clause All the conditions after WHERE
237
+ * @private
238
+ */
162
239
  _handleWHERE(clause) {
163
240
  if (/^(1|'1'|true)$/i.test(clause)) {
164
241
  this.query._wheres.push(clause);
@@ -166,9 +243,20 @@ class Parser {
166
243
  this._handleConditions("where", clause);
167
244
  }
168
245
  }
246
+ /**
247
+ * Handle HAVING statements
248
+ * @param clause All the conditions after HAVING
249
+ * @private
250
+ */
169
251
  _handleHAVING(clause) {
170
252
  this._handleConditions("having", clause);
171
253
  }
254
+ /**
255
+ * Build a conditions list
256
+ * @param type Either where or having
257
+ * @param clause The expressions following the type keyword
258
+ * @private
259
+ */
172
260
  _handleConditions(type, clause) {
173
261
  const andGroups = clause.split(/\bAND\b/i);
174
262
  andGroups.forEach((andGroup) => {
@@ -182,14 +270,29 @@ class Parser {
182
270
  }
183
271
  });
184
272
  }
273
+ /**
274
+ * Handle GROUP BY statements
275
+ * @param clause The clauses after the GROUP BY
276
+ * @private
277
+ */
185
278
  _handleGROUP_BY(clause) {
186
279
  const columns = clause.split(/\s*,\s*/);
187
280
  columns.forEach((column) => this.query.groupBy(column));
188
281
  }
282
+ /**
283
+ * Handle ORDER BY statements
284
+ * @param clause The clause after the ORDER BY
285
+ * @private
286
+ */
189
287
  _handleORDER_BY(clause) {
190
288
  const columns = clause.split(/\s*,\s*/);
191
289
  columns.forEach((column) => this.query.orderBy(column));
192
290
  }
291
+ /**
292
+ * Handle LIMIT statements including "LIMIT #" and "LIMIT #, #"
293
+ * @param clause The clause after the LIMIT
294
+ * @private
295
+ */
193
296
  _handleLIMIT(clause) {
194
297
  const offsetLimit = clause.match(/^(\d+|\?|:\w+)\s*,\s*(\d+|\?|:\w+)$/);
195
298
  if (offsetLimit) {
@@ -200,15 +303,26 @@ class Parser {
200
303
  this.query.limit(clause);
201
304
  }
202
305
  }
306
+ /**
307
+ * Handle OFFSET statements
308
+ * @param clause The number after the OFFSET
309
+ * @private
310
+ */
203
311
  _handleOFFSET(clause) {
204
312
  clause = clause.replace(/^(\d+) ROWS$/i, "$1");
205
313
  this.query.offset(clause);
206
314
  }
315
+ /**
316
+ * Handle OFFSET statements
317
+ * @param clause The number after the OFFSET
318
+ * @private
319
+ */
207
320
  _handleFETCH_NEXT(clause) {
208
321
  clause = clause.replace(/^(\d+) ROWS ONLY$/i, "$1");
209
322
  this.query.limit(clause);
210
323
  }
211
- }
324
+ };
325
+
212
326
  // src/substrCount/substrCount.ts
213
327
  function substrCount(haystack, needle) {
214
328
  let count = 0;
@@ -221,23 +335,76 @@ function substrCount(haystack, needle) {
221
335
  }
222
336
 
223
337
  // src/SelectBuilder/SelectBuilder.ts
224
- var isNullish = (v) => v === undefined || v === null || v === false || isNaN(v);
338
+ var isNullish = (v) => v === void 0 || v === null || v === false || Object.is(NaN, v);
225
339
  var defaultEngine = "mysql";
226
-
227
- class SelectBuilder {
340
+ var SelectBuilder = class _SelectBuilder {
341
+ /**
342
+ * The list of values to bind to the query
343
+ * @private
344
+ */
228
345
  _bindings = [];
346
+ /**
347
+ * The list of strings to come immediately after "SELECT"
348
+ * and before column names
349
+ * @private
350
+ */
229
351
  _options = [];
352
+ /**
353
+ * The list of column names to select
354
+ * @private
355
+ */
230
356
  _tables = [];
357
+ /**
358
+ * The list of tables in the FROM clause
359
+ * @private
360
+ */
231
361
  _columns = [];
362
+ /**
363
+ * The list of JOIN strings to add
364
+ * @private
365
+ */
232
366
  _joins = [];
367
+ /**
368
+ * The list of WHERE clauses to join with AND
369
+ * @private
370
+ */
233
371
  _wheres = [];
372
+ /**
373
+ * The list of GROUP BY clauses to join with commas
374
+ * @private
375
+ */
234
376
  _groupBys = [];
377
+ /**
378
+ * The list of HAVING clauses to join with AND
379
+ * @private
380
+ */
235
381
  _havings = [];
382
+ /**
383
+ * The list of ORDER BY clauses to join with commas
384
+ * @private
385
+ */
236
386
  _orderBys = [];
387
+ /**
388
+ * The LIMIT to use
389
+ * @private
390
+ */
237
391
  _limit;
392
+ /**
393
+ * The OFFSET to use
394
+ * @private
395
+ */
238
396
  _offset;
397
+ /**
398
+ * The page used to construct an OFFSET based on the LIMIT
399
+ * @private
400
+ */
239
401
  _page;
240
- constructor(sql = null, bindings = null) {
402
+ /**
403
+ * Select constructor
404
+ * @param [sql] A base SQL query to parse
405
+ * @param [bindings] Placeholders to bind to the query
406
+ */
407
+ constructor(sql, bindings = {}) {
241
408
  if (sql) {
242
409
  if (bindings) {
243
410
  const keys = Object.keys(bindings);
@@ -250,58 +417,58 @@ class SelectBuilder {
250
417
  new Parser(this).parse(sql);
251
418
  }
252
419
  }
420
+ /**
421
+ * Set the default database engine style (mssql, mysql, oracle, pg)
422
+ * @param engine
423
+ */
253
424
  static setDefaultEngine(engine) {
254
425
  defaultEngine = engine;
255
- return SelectBuilder;
426
+ return _SelectBuilder;
256
427
  }
428
+ /**
429
+ * Get the SQL as a pretty-printed string alongside an array of bindings
430
+ * @param engine The database engine style (mssql, mysql, oracle, pg)
431
+ * @return The SQL query as a string
432
+ */
257
433
  compile({
258
434
  engine = defaultEngine,
259
435
  bindingIndex = 1
260
436
  } = {}) {
261
437
  const lines = [
262
438
  "SELECT",
263
- this._options.length ? ` ${this._options.join(`
264
- `)}` : null,
265
- this._columns.length ? ` ${this._columns.join(`,
266
- `)}` : ` *
267
- `,
439
+ this._options.length ? ` ${this._options.join("\n ")}` : null,
440
+ this._columns.length ? ` ${this._columns.join(",\n ")}` : " *\n",
268
441
  `FROM ${this._tables.join(", ")}`,
269
- this._joins.length ? this._joins.join(`
270
- `) : null,
271
- this._wheres.length ? `WHERE ${this._wheres.join(`
272
- AND `)}` : null,
273
- this._groupBys.length ? `GROUP BY ${this._groupBys.join(`,
274
- `)}` : null,
275
- this._havings.length ? `HAVING ${this._havings.join(`
276
- AND `)}` : null,
277
- this._orderBys.length ? `ORDER BY ${this._orderBys.join(`,
278
- `)}` : null
442
+ this._joins.length ? this._joins.join("\n") : null,
443
+ this._wheres.length ? `WHERE ${this._wheres.join("\n AND ")}` : null,
444
+ this._groupBys.length ? `GROUP BY ${this._groupBys.join(",\n ")}` : null,
445
+ this._havings.length ? `HAVING ${this._havings.join("\n AND ")}` : null,
446
+ this._orderBys.length ? `ORDER BY ${this._orderBys.join(",\n ")}` : null
279
447
  ];
280
- if (this._page > 0) {
448
+ if (this._page && this._page > 0 && this._limit) {
281
449
  const offset = (this._page - 1) * this._limit;
282
- lines.push(this._compileOFFSET(engine, offset));
283
- lines.push(this._compileLIMIT(engine, this._limit));
450
+ lines.push(this._compileOFFSET(engine, offset) ?? "");
451
+ lines.push(this._compileLIMIT(engine, this._limit) ?? "");
284
452
  } else {
285
453
  if (this._offset) {
286
- lines.push(this._compileOFFSET(engine, this._offset));
454
+ lines.push(this._compileOFFSET(engine, this._offset) ?? "");
287
455
  }
288
456
  if (this._limit) {
289
- lines.push(this._compileLIMIT(engine, this._limit));
457
+ lines.push(this._compileLIMIT(engine, this._limit) ?? "");
290
458
  }
291
459
  }
292
- const pretty = lines.filter(Boolean).join(`
293
- `).trim();
460
+ const pretty = lines.filter(Boolean).join("\n").trim();
294
461
  let replacer;
295
462
  const bindings = [];
296
463
  if (engine === "pg") {
297
464
  let idx = bindingIndex;
298
465
  replacer = (_, $1) => {
299
- bindings.push(this._bindings[$1]);
466
+ bindings.push(this._bindings[Number($1)]);
300
467
  return "$" + idx++;
301
468
  };
302
469
  } else {
303
470
  replacer = (_, $1) => {
304
- bindings.push(this._bindings[$1]);
471
+ bindings.push(this._bindings[Number($1)]);
305
472
  return "?";
306
473
  };
307
474
  }
@@ -322,6 +489,11 @@ class SelectBuilder {
322
489
  return `OFFSET ${offset} ROWS`;
323
490
  }
324
491
  }
492
+ /**
493
+ * Get SQL needed to return the found rows of this query
494
+ * @param engineStyle The database engine style (mssql, mysql, oracle, pg)
495
+ * @param countExpr The expression to use inside the COUNT()
496
+ */
325
497
  compileCount({
326
498
  countExpr = "*",
327
499
  engine = defaultEngine,
@@ -329,11 +501,10 @@ class SelectBuilder {
329
501
  } = {}) {
330
502
  const query = this.getFoundRowsQuery(countExpr);
331
503
  const { sql, bindings } = query.compile({ engine, bindingIndex });
332
- if (this._havings.length === 0) {
504
+ if (this._havings.length === 0 && this._groupBys.length === 0) {
333
505
  return { sql, bindings };
334
506
  } else {
335
- const subquerySql = sql.replace(/\n/g, `
336
- `);
507
+ const subquerySql = sql.replace(/\n/g, "\n ");
337
508
  return {
338
509
  sql: `SELECT COUNT(*) AS found_rows
339
510
  FROM (
@@ -343,6 +514,11 @@ ${subquerySql}
343
514
  };
344
515
  }
345
516
  }
517
+ /**
518
+ * Get SQL needed to union this query with another
519
+ * @param query The query to union
520
+ * @param engine The database engine style (mssql, mysql, oracle, pg)
521
+ */
346
522
  compileUnion(query, {
347
523
  engine = defaultEngine,
348
524
  bindingIndex = 1
@@ -359,7 +535,12 @@ UNION
359
535
  bindings: [...first.bindings, ...second.bindings]
360
536
  };
361
537
  }
362
- reset(fieldOrFields = null) {
538
+ /**
539
+ * @param [fieldOrFields] If given, reset the given component(s), otherwise reset all query components
540
+ * Valid components: option, column, table, where, orWhere, having, groupBy, orderBy, limit, offset, page
541
+ * @return This object
542
+ */
543
+ reset(fieldOrFields) {
363
544
  if (Array.isArray(fieldOrFields)) {
364
545
  fieldOrFields.forEach((name) => this.reset(name));
365
546
  return this;
@@ -389,15 +570,18 @@ UNION
389
570
  this._groupBys = [];
390
571
  this._havings = [];
391
572
  this._orderBys = [];
392
- this._limit = null;
393
- this._offset = null;
394
- this._page = null;
573
+ this._limit = void 0;
574
+ this._offset = void 0;
575
+ this._page = void 0;
395
576
  this._bindings = [];
396
577
  }
397
578
  return this;
398
579
  }
580
+ /**
581
+ * Clone this builder object
582
+ */
399
583
  getClone() {
400
- const copy = new SelectBuilder;
584
+ const copy = new _SelectBuilder();
401
585
  copy._options = [...this._options];
402
586
  copy._columns = [...this._columns];
403
587
  copy._tables = [...this._tables];
@@ -412,6 +596,10 @@ UNION
412
596
  copy._bindings = [...this._bindings];
413
597
  return copy;
414
598
  }
599
+ /**
600
+ * Build a version of this query that simply returns COUNT(*)
601
+ * @param [countExpr="*"] Use to specify `DISTINCT colname` if needed
602
+ */
415
603
  getFoundRowsQuery(countExpr = "*") {
416
604
  if (this._havings.length === 0) {
417
605
  const clone = this.getClone();
@@ -419,46 +607,86 @@ UNION
419
607
  clone._options = [];
420
608
  clone._groupBys = [];
421
609
  clone._orderBys = [];
422
- clone._limit = null;
423
- clone._offset = null;
424
- clone._page = null;
610
+ clone._limit = void 0;
611
+ clone._offset = void 0;
612
+ clone._page = void 0;
425
613
  return clone;
426
614
  } else {
427
615
  const subquery = this.getClone();
428
- subquery._limit = null;
429
- subquery._offset = null;
430
- subquery._page = null;
616
+ subquery._limit = void 0;
617
+ subquery._offset = void 0;
618
+ subquery._page = void 0;
431
619
  return subquery;
432
620
  }
433
621
  }
622
+ /**
623
+ * Add an array of column names to fetch
624
+ * @param columnNames The names of columns
625
+ */
434
626
  select(columnNames) {
435
627
  this._columns = this._columns.concat(columnNames);
436
628
  return this;
437
629
  }
630
+ /**
631
+ * Add an array of column names to fetch
632
+ * @param columnNames The names of columns
633
+ */
438
634
  columns(columnNames) {
439
635
  this._columns = this._columns.concat(columnNames);
440
636
  return this;
441
637
  }
638
+ /**
639
+ * Add a column name to fetch
640
+ * @param columnName The name of the column
641
+ */
442
642
  column(columnName) {
443
643
  this._columns.push(columnName);
444
644
  return this;
445
645
  }
646
+ /**
647
+ * Add an option expression such as "TOP 10" or "SQL_CALC_FOUND_ROWS"
648
+ * @param optionExpression Expression to go after "SELECT" and before column list
649
+ */
446
650
  option(optionExpression) {
447
651
  this._options.push(optionExpression);
448
652
  return this;
449
653
  }
654
+ /**
655
+ * Add a table to the "FROM" clause (same as .from())
656
+ * @param {String} tableName The name of the table to query
657
+ * @return {Select}
658
+ */
450
659
  table(tableName) {
451
660
  this._tables.push(tableName);
452
661
  return this;
453
662
  }
663
+ /**
664
+ * Add multiple table to the "FROM" clause
665
+ * @param {Array} tableNames The names of the tables to query
666
+ * @return {Select}
667
+ */
454
668
  tables(tableNames) {
455
669
  this._tables.push(...tableNames);
456
670
  return this;
457
671
  }
672
+ /**
673
+ * Add a table to the "FROM" clause (same as .table())
674
+ * @param {String} tableName The name of the table to query
675
+ * @return {Select}
676
+ */
458
677
  from(tableName) {
459
678
  this._tables.push(tableName);
460
679
  return this;
461
680
  }
681
+ /**
682
+ * Add the given join type expression
683
+ * @param joinType The type of join (e.g. "INNER JOIN", "LEFT JOIN", etc.)
684
+ * @param expression The expression following the INNER JOIN keyword
685
+ * @param bindings A list of values to bind to ? placeholders in the expression
686
+ * @example
687
+ * query.join('posts p ON p.id = c.post_id');
688
+ * query.join('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
689
+ */
462
690
  _addJoin(joinType, expression, bindings = []) {
463
691
  if (bindings.length > 0) {
464
692
  expression = expression.replace(/\?/g, () => {
@@ -468,42 +696,118 @@ UNION
468
696
  }
469
697
  this._joins.push(`${joinType} ${expression}`);
470
698
  }
699
+ /**
700
+ * Add a JOIN expression
701
+ * @param expression The expression following the INNER JOIN keyword
702
+ * @param bindings A list of values to bind to ? placeholders in the expression
703
+ * @example
704
+ * query.join('posts p ON p.id = c.post_id');
705
+ * query.join('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
706
+ */
471
707
  join(expression, bindings = []) {
472
708
  this._addJoin("JOIN", expression, bindings);
473
709
  return this;
474
710
  }
711
+ /**
712
+ * Add a LEFT JOIN expression
713
+ * @param expression The expression following the LEFT JOIN keyword
714
+ * @param bindings A list of values to bind to ? placeholders in the expression
715
+ * @example
716
+ * query.leftJoin('posts p ON p.id = c.post_id');
717
+ * query.leftJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
718
+ */
475
719
  leftJoin(expression, bindings = []) {
476
720
  this._addJoin("LEFT JOIN", expression, bindings);
477
721
  return this;
478
722
  }
723
+ /**
724
+ * Add a FULL JOIN expression
725
+ * @param expression The expression following the FULL JOIN keyword
726
+ * @param bindings A list of values to bind to ? placeholders in the expression
727
+ * @example
728
+ * query.fullJoin('posts p ON p.id = c.post_id');
729
+ * query.fullJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
730
+ */
479
731
  fullJoin(expression, bindings = []) {
480
732
  this._addJoin("FULL JOIN", expression, bindings);
481
733
  return this;
482
734
  }
735
+ /**
736
+ * Add a RIGHT JOIN expression
737
+ * @param expression The expression following the RIGHT JOIN keyword
738
+ * @param bindings A list of values to bind to ? placeholders in the expression
739
+ * @example
740
+ * query.rightJoin('posts p ON p.id = c.post_id');
741
+ * query.rightJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
742
+ */
483
743
  rightJoin(expression, bindings = []) {
484
744
  this._addJoin("RIGHT JOIN", expression, bindings);
485
745
  return this;
486
746
  }
747
+ /**
748
+ * Add a CROSS JOIN expression
749
+ * @param expression The expression following the CROSS JOIN keyword
750
+ * @param bindings A list of values to bind to ? placeholders in the expression
751
+ * @example
752
+ * query.crossJoin('posts p ON p.id = c.post_id');
753
+ * query.crossJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
754
+ */
487
755
  crossJoin(expression, bindings = []) {
488
756
  this._addJoin("CROSS JOIN", expression, bindings);
489
757
  return this;
490
758
  }
759
+ /**
760
+ * Add an INNER JOIN expression (same as ->join())
761
+ * @param expression The expression following the INNER JOIN keyword
762
+ * @param bindings A list of values to bind to ? placeholders in the expression
763
+ * @example
764
+ * query.innerJoin('posts p ON p.id = c.post_id');
765
+ * query.innerJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
766
+ */
491
767
  innerJoin(expression, bindings = []) {
492
768
  this._addJoin("INNER JOIN", expression, bindings);
493
769
  return this;
494
770
  }
771
+ /**
772
+ * Add a LEFT OUTER JOIN expression
773
+ * @param expression The expression following the LEFT OUTER JOIN keyword
774
+ * @param bindings A list of values to bind to ? placeholders in the expression
775
+ * @example
776
+ * query.leftOuterJoin('posts p ON p.id = c.post_id');
777
+ * query.leftOuterJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
778
+ */
495
779
  leftOuterJoin(expression, bindings = []) {
496
780
  this._addJoin("LEFT OUTER JOIN", expression, bindings);
497
781
  return this;
498
782
  }
783
+ /**
784
+ * Add a FULL OUTER JOIN expression
785
+ * @param expression The expression following the FULL OUTER JOIN keyword
786
+ * @param bindings A list of values to bind to ? placeholders in the expression
787
+ * @example
788
+ * query.fullOuterJoin('posts p ON p.id = c.post_id');
789
+ * query.fullOuterJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
790
+ */
499
791
  fullOuterJoin(expression, bindings = []) {
500
792
  this._addJoin("FULL OUTER JOIN", expression, bindings);
501
793
  return this;
502
794
  }
795
+ /**
796
+ * Add a RIGHT OUTER JOIN expression
797
+ * @param expression The expression following the RIGHT OUTER JOIN keyword
798
+ * @param bindings A list of values to bind to ? placeholders in the expression
799
+ * @example
800
+ * query.rightOuterJoin('posts p ON p.id = c.post_id');
801
+ * query.rightOuterJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
802
+ */
503
803
  rightOuterJoin(expression, bindings = []) {
504
804
  this._addJoin("RIGHT OUTER JOIN", expression, bindings);
505
805
  return this;
506
806
  }
807
+ /**
808
+ * Remove a join condition with the specified table
809
+ * @param table The name of the table or tables in the first part of the join statement
810
+ */
507
811
  unjoin(table) {
508
812
  if (Array.isArray(table)) {
509
813
  table.forEach((t) => this.unjoin(t));
@@ -515,6 +819,34 @@ UNION
515
819
  });
516
820
  return this;
517
821
  }
822
+ /**
823
+ * Utility function to add conditions for a clause (WHERE, HAVING)
824
+ * @param collection The collection to add the clauses to (e.g. this._wheres or this._havings)
825
+ * @param criteria Criteria adhering to WhereCriteria type
826
+ * @example The following are equivalent
827
+ * this._conditions(this._wheres, ['deleted_at IS NULL']);
828
+ * this._conditions(this._wheres, ['deleted_at', null]);
829
+ * this._conditions(this._wheres, ['deleted_at', '=', null]);
830
+ * @example More examples
831
+ * this._conditions(this._wheres, ['fname', 'LIKE', 'joe']); // `fname` LIKE 'joe'
832
+ * this._conditions(this._wheres, ['fname', 'LIKE ?', 'joe']); // `fname` LIKE 'joe'
833
+ * this._conditions(this._wheres, ['fname LIKE %?%', 'joe']); // `fname` LIKE '%joe%'
834
+ * this._conditions(this._wheres, ['fname LIKE ?%', 'joe']); // `fname` LIKE 'joe%'
835
+ * this._conditions(this._wheres, ['fname', 'LIKE ?%', 'joe']); // `fname` LIKE 'joe%'
836
+ * this._conditions(this._wheres, ['price >', 10]); // `price` > 10
837
+ * this._conditions(this._wheres, ['price', '>', 10]); // `price` > 10
838
+ * this._conditions(this._wheres, ['price =', 10]); // `price` = 10
839
+ * this._conditions(this._wheres, ['price !=', 10]); // `price` != 10
840
+ * this._conditions(this._wheres, ['price', 10]); // `price` = 10
841
+ * this._conditions(this._wheres, ['price', '=', 10]); // `price` = 10
842
+ * this._conditions(this._wheres, ['price', '!=', 10]); // `price` != 10
843
+ * this._conditions(this._wheres, ['price', 'BETWEEN', [10,20]]); // `price` BETWEEN 10 AND 20
844
+ * this._conditions(this._wheres, ['price', 'NOT BETWEEN', [10,20]]); // `price` NOT BETWEEN 10 AND 20
845
+ * this._conditions(this._wheres, ['price', [10,20]]); // `price` IN(10,20)
846
+ * this._conditions(this._wheres, ['price', '=', [10,20]]); // `price` IN(10,20)
847
+ * this._conditions(this._wheres, ['price', 'IN', [10,20]]); // `price` IN(10,20)
848
+ * this._conditions(this._wheres, ['price', 'NOT IN', [10,20]]); // `price` NOT IN(10,20)
849
+ */
518
850
  _conditions(collection, criteria) {
519
851
  const numArgs = criteria.length;
520
852
  let [column, operator, value] = criteria;
@@ -538,18 +870,22 @@ UNION
538
870
  } else if (numArgs === 2) {
539
871
  value = operator;
540
872
  const parts = column.split(" ");
541
- column = parts.shift();
873
+ column = parts.shift() ?? "";
542
874
  operator = parts.join(" ");
543
875
  }
544
876
  if (typeof operator !== "string" || operator === "") {
545
877
  operator = "=";
546
878
  }
547
879
  operator = operator.toLocaleUpperCase();
548
- const likeMatch = operator.match(/^(LIKE|NOT LIKE|ILIKE|NOT ILIKE)(?: (\?|\?%|%\?|%\?%))?$/i);
880
+ const likeMatch = operator.match(
881
+ /^(LIKE|NOT LIKE|ILIKE|NOT ILIKE)(?: (\?|\?%|%\?|%\?%))?$/i
882
+ );
549
883
  if (operator === "NOT BETWEEN" || operator === "BETWEEN") {
550
884
  const one = this._bindings.length;
551
885
  const two = this._bindings.length + 1;
552
- collection.push(`${column} ${operator} __BOUND_${one}__ AND __BOUND_${two}__`);
886
+ collection.push(
887
+ `${column} ${operator} __BOUND_${one}__ AND __BOUND_${two}__`
888
+ );
553
889
  this._bindings.push(value[0], value[1]);
554
890
  } else if (likeMatch) {
555
891
  const like = likeMatch[1].toUpperCase();
@@ -567,32 +903,52 @@ UNION
567
903
  this._bindings.push(infix.replace("?", value || ""));
568
904
  }
569
905
  } else if (value === null) {
570
- collection.push(operator === "=" ? `${column} IS NULL` : `${column} IS NOT NULL`);
906
+ collection.push(
907
+ operator === "=" ? `${column} IS NULL` : `${column} IS NOT NULL`
908
+ );
571
909
  } else if (Array.isArray(value)) {
572
910
  const inVals = [];
573
- for (let i = 0;i < value.length; i++) {
911
+ for (let i = 0; i < value.length; i++) {
574
912
  inVals.push(`__BOUND_${this._bindings.length}__`);
575
913
  this._bindings.push(value[i]);
576
914
  }
577
915
  const joined = inVals.join(", ");
578
- collection.push(operator === "=" || operator === "IN" ? `${column} IN(${joined})` : `${column} NOT IN(${joined})`);
916
+ collection.push(
917
+ operator === "=" || operator === "IN" ? `${column} IN(${joined})` : `${column} NOT IN(${joined})`
918
+ );
579
919
  } else if (operator === "IN" || operator === "NOT IN") {
580
- collection.push(`${column} ${operator}(__BOUND_${this._bindings.length}__)`);
920
+ collection.push(
921
+ `${column} ${operator}(__BOUND_${this._bindings.length}__)`
922
+ );
581
923
  this._bindings.push(value);
582
924
  } else {
583
- collection.push(`${column} ${operator} __BOUND_${this._bindings.length}__`);
925
+ collection.push(
926
+ `${column} ${operator} __BOUND_${this._bindings.length}__`
927
+ );
584
928
  this._bindings.push(value);
585
929
  }
586
930
  return this;
587
931
  }
932
+ /**
933
+ * Add a group by column or expression
934
+ * @param column The name of a column (or expression) to group by
935
+ */
588
936
  groupBy(column) {
589
937
  this._groupBys.push(column);
590
938
  return this;
591
939
  }
940
+ /**
941
+ * Add WHERE clauses to conditions (See _conditions for usage)
942
+ */
592
943
  where(...args) {
593
944
  this._conditions(this._wheres, args);
594
945
  return this;
595
946
  }
947
+ /**
948
+ * Add a WHERE clause with a BETWEEN condition
949
+ * @param column The column name
950
+ * @param twoValueArray The two values to be between. If the first is null, it will use >= instead. If the second is null, it will use <= instead. If both are null, no criteria will be added
951
+ */
596
952
  whereBetween(column, twoValueArray) {
597
953
  if (!isNullish(twoValueArray[0]) && !isNullish(twoValueArray[1])) {
598
954
  this.where(column, "BETWEEN", twoValueArray);
@@ -600,9 +956,14 @@ UNION
600
956
  this.where(column, ">=", twoValueArray[0]);
601
957
  } else if (isNullish(twoValueArray[0]) && !isNullish(twoValueArray[1])) {
602
958
  this.where(column, "<=", twoValueArray[1]);
603
- } else {}
959
+ } else {
960
+ }
604
961
  return this;
605
962
  }
963
+ /**
964
+ * Add a series of WHERE clauses joined by OR (See _conditions for usage)
965
+ * @param conditions
966
+ */
606
967
  _orConditions(conditions) {
607
968
  const items = [];
608
969
  if (Array.isArray(conditions)) {
@@ -627,21 +988,44 @@ UNION
627
988
  return joined;
628
989
  }
629
990
  }
991
+ /**
992
+ * Add WHERE conditions to place inside an OR block (See _conditions for usage)
993
+ * @param conditions A list or object where each item is an array with parameters that would be taken by where()
994
+ */
630
995
  orWhere(conditions) {
631
996
  const joined = this._orConditions(conditions);
632
997
  this.where(`(${joined})`);
633
998
  return this;
634
999
  }
1000
+ /**
1001
+ * Add an OR with conditions under the HAVING clause
1002
+ * @param conditions A list or object where each item is an array with parameters that would be taken by having()
1003
+ */
635
1004
  orHaving(conditions) {
636
1005
  const joined = this._orConditions(conditions);
637
1006
  this.having(`(${joined})`);
638
1007
  return this;
639
1008
  }
1009
+ /**
1010
+ * Add a HAVING condition (See _conditions for usage)
1011
+ */
640
1012
  having(...args) {
641
1013
  this._conditions(this._havings, args);
642
1014
  return this;
643
1015
  }
644
- orderBy(column, direction = null) {
1016
+ /**
1017
+ * Add a column or expression to order by
1018
+ * @param column The column name or expression to sort by. Include DESC or prefix with - to sort descending
1019
+ * @param [direction] The direction to sort by (ASC or DESC)
1020
+ * @example
1021
+ * query.orderBy('modified_at'); // ORDER BY modified_at
1022
+ * query.orderBy('-modified_at'); // ORDER BY modified_at DESC
1023
+ * query.orderBy('COUNT(*)'); // ORDER BY COUNT(*)
1024
+ * query.orderBy('COUNT(*) DESC'); // ORDER BY COUNT(*) DESC
1025
+ * query.orderBy('modified_at DESC NULLS LAST'); // ORDER BY modified_at DESC NULLS LAST
1026
+ * query.orderBy('modified_at USING >'); // ORDER BY modified_at USING >
1027
+ */
1028
+ orderBy(column, direction) {
645
1029
  if (direction) {
646
1030
  this._orderBys.push(`${column} ${direction}`);
647
1031
  } else {
@@ -650,8 +1034,24 @@ UNION
650
1034
  }
651
1035
  return this;
652
1036
  }
1037
+ /**
1038
+ * Sort by the given column, with a map of columns to translate
1039
+ * @param fieldName The file name such as 'created_at' or '-created_at' for descending
1040
+ * @param [mapNames] Column names to translate from field to column expression
1041
+ * @param [modifier] Additional clause to append such as 'NULLS LAST' or 'COLLATE "en_US"'
1042
+ * @example
1043
+ * query.sortField('-modified_at'); // ORDER BY modified_at DESC
1044
+ * query.sortField('-created', {'created': 'created_at'}); // ORDER BY created_at DESC
1045
+ * query.sortField('-created', {
1046
+ * 'created': 'created_at NULLS LAST',
1047
+ * '-created': 'created_at DESC NULLS LAST'
1048
+ * }); // ORDER BY created_at DESC NULLS LAST
1049
+ * query.sortField('-name', {
1050
+ * 'name': 'name COLLATE "jp_JP"'
1051
+ * }); // ORDER BY name COLLATE "jp_JP" DESC
1052
+ */
653
1053
  sortField(fieldName, mapNames = {}, modifier = "") {
654
- if (!fieldName) {
1054
+ if (typeof fieldName !== "string" || fieldName === "") {
655
1055
  return this;
656
1056
  }
657
1057
  let direction = "ASC";
@@ -671,12 +1071,26 @@ UNION
671
1071
  this.orderBy(column, direction);
672
1072
  return this;
673
1073
  }
1074
+ /**
1075
+ * Check to see if the given string is 0 or all digits not starting with 0
1076
+ * @param string The input string
1077
+ * @private
1078
+ */
674
1079
  _isEntirelyDigits(string) {
675
1080
  return /^(0|[1-9]\d*)$/.test(string);
676
1081
  }
1082
+ /**
1083
+ * Check to see if the given string is all digits
1084
+ * @param string The input string
1085
+ * @private
1086
+ */
677
1087
  _isEntirelyDigitsNoZeros(string) {
678
1088
  return /^[1-9]\d*$/.test(string);
679
1089
  }
1090
+ /**
1091
+ * Limit results to the given number
1092
+ * @param max The number to limit by (placeholder string or integer greater than 0)
1093
+ */
680
1094
  limit(max) {
681
1095
  if (typeof max === "string") {
682
1096
  max = max.trim();
@@ -686,38 +1100,55 @@ UNION
686
1100
  } else if (typeof max === "number" && Number.isInteger(max) && max >= 1) {
687
1101
  this._limit = max;
688
1102
  } else {
689
- throw new Error(`SelectBuilder: "limit(n)" must receive a positive integer (got "${max}")`);
1103
+ throw new Error(
1104
+ `SelectBuilder: "limit(n)" must receive a positive integer (got "${max}")`
1105
+ );
690
1106
  }
691
1107
  return this;
692
1108
  }
1109
+ /**
1110
+ * Fetch results from the given offset
1111
+ * @param number The offset (placeholder string or integer greater than or equal to 0)
1112
+ */
693
1113
  offset(number) {
694
1114
  if (typeof number === "string" && this._isEntirelyDigits(number.trim())) {
695
1115
  this._offset = parseInt(number, 10);
696
1116
  } else if (typeof number === "number" && Number.isInteger(number) && number >= 0) {
697
1117
  this._offset = number;
698
1118
  } else {
699
- throw new Error(`SelectBuilder: "offset(n)" must receive a positive integer (got "${number}")`);
1119
+ throw new Error(
1120
+ `SelectBuilder: "offset(n)" must receive a positive integer (got "${number}")`
1121
+ );
700
1122
  }
701
1123
  return this;
702
1124
  }
1125
+ /**
1126
+ * Set the offset based on the limit with the given page number
1127
+ * @param number The page number (integer greater than 0)
1128
+ */
703
1129
  page(number) {
704
1130
  if (typeof number === "string" && this._isEntirelyDigitsNoZeros(number.trim())) {
705
1131
  this._page = parseInt(number, 10);
706
1132
  } else if (typeof number === "number" && Number.isInteger(number) && number >= 1) {
707
1133
  this._page = number;
708
1134
  } else {
709
- throw new Error('SelectBuilder: "page(n)" must receive a positive integer');
1135
+ throw new Error(
1136
+ 'SelectBuilder: "page(n)" must receive a positive integer'
1137
+ );
710
1138
  }
711
1139
  return this;
712
1140
  }
713
- }
1141
+ };
1142
+
714
1143
  // src/extractGrouped/extractGrouped.ts
715
1144
  function extractGrouped(field, records) {
716
1145
  let idx = 0;
717
1146
  const grouped = {};
718
1147
  for (const record of records) {
719
1148
  if (!(field in record)) {
720
- throw new Error(`Column "${String(field)}" is not present in record ${idx}`);
1149
+ throw new Error(
1150
+ `Column "${String(field)}" is not present in record ${idx}`
1151
+ );
721
1152
  }
722
1153
  if (!grouped[record[field]]) {
723
1154
  grouped[record[field]] = [];
@@ -727,35 +1158,44 @@ function extractGrouped(field, records) {
727
1158
  }
728
1159
  return grouped;
729
1160
  }
1161
+
730
1162
  // src/extractIndexed/extractIndexed.ts
731
1163
  function extractIndexed(field, records) {
732
1164
  let idx = 0;
733
1165
  const indexed = {};
734
1166
  for (const record of records) {
735
1167
  if (!(field in record)) {
736
- throw new Error(`Column "${String(field)}" is not present in record ${idx}`);
1168
+ throw new Error(
1169
+ `Column "${String(field)}" is not present in record ${idx}`
1170
+ );
737
1171
  }
738
1172
  indexed[record[field]] = record;
739
1173
  idx++;
740
1174
  }
741
1175
  return indexed;
742
1176
  }
1177
+
743
1178
  // src/extractLookup/extractLookup.ts
744
1179
  function extractLookup(keyField, valueField, records) {
745
1180
  const lookup = {};
746
1181
  let idx = 0;
747
1182
  for (const record of records) {
748
1183
  if (!(keyField in record)) {
749
- throw new Error(`Column "${String(keyField)}" is not present in record ${idx}`);
1184
+ throw new Error(
1185
+ `Column "${String(keyField)}" is not present in record ${idx}`
1186
+ );
750
1187
  }
751
1188
  if (!(valueField in record)) {
752
- throw new Error(`Column "${String(valueField)}" is not present in record ${idx}`);
1189
+ throw new Error(
1190
+ `Column "${String(valueField)}" is not present in record ${idx}`
1191
+ );
753
1192
  }
754
1193
  idx++;
755
- lookup[String(record[keyField])] = record[valueField];
1194
+ lookup[record[keyField]] = record[valueField];
756
1195
  }
757
1196
  return lookup;
758
1197
  }
1198
+
759
1199
  // src/getPagination/getPagination.ts
760
1200
  function getPagination(query, total) {
761
1201
  total = Number(total) || 0;
@@ -775,8 +1215,8 @@ function getPagination(query, total) {
775
1215
  const numPages = total === 0 || perPage === null ? 0 : Math.ceil(total / perPage) || 0;
776
1216
  const isFirst = page === 1;
777
1217
  const isLast = numPages > 0 && page === numPages;
778
- const prevPage = numPages === 0 ? null : page - 1 || null;
779
- const nextPage = numPages > 0 && page + 1 <= numPages ? page + 1 : null;
1218
+ const prevPage = numPages === 0 || page === null ? null : page - 1 || null;
1219
+ const nextPage = numPages > 0 && page !== null && page + 1 <= numPages ? page + 1 : null;
780
1220
  return {
781
1221
  page,
782
1222
  prevPage,
@@ -788,6 +1228,7 @@ function getPagination(query, total) {
788
1228
  isLast
789
1229
  };
790
1230
  }
1231
+
791
1232
  // src/runMysql/runMysql.ts
792
1233
  function _queryToPromise(mysqlClient, sql, bindings) {
793
1234
  return new Promise((resolve, reject) => {
@@ -838,6 +1279,7 @@ async function runMysqlAsyncWithCount(mysqlClient, query, {
838
1279
  return { records, total: 0, pagination: getPagination(query, 0), fields };
839
1280
  }
840
1281
  }
1282
+
841
1283
  // src/toSafeJson/toSafeJson.ts
842
1284
  function toSafeJsonValue(value) {
843
1285
  if (typeof value === "bigint") {
@@ -864,16 +1306,19 @@ function toSafeJsonString(records) {
864
1306
  }
865
1307
 
866
1308
  // src/runPrisma/runPrisma.ts
867
- async function runPrisma(prisma, query, { engine = undefined } = {}) {
1309
+ async function runPrisma(prisma, query, { engine = void 0 } = {}) {
868
1310
  const { sql, bindings } = query.compile({ engine });
869
1311
  return prisma.$queryRawUnsafe(sql, ...bindings);
870
1312
  }
871
1313
  async function runPrismaWithCount(prisma, query, {
872
- engine = undefined,
1314
+ engine = void 0,
873
1315
  countExpr = "*"
874
1316
  } = {}) {
875
1317
  const { sql, bindings } = query.compile({ engine });
876
- const records = await prisma.$queryRawUnsafe(sql, ...bindings);
1318
+ const records = await prisma.$queryRawUnsafe(
1319
+ sql,
1320
+ ...bindings
1321
+ );
877
1322
  if (records.length > 0) {
878
1323
  const { sql: sql2, bindings: bindings2 } = query.compileCount({ engine, countExpr });
879
1324
  const result = await prisma.$queryRawUnsafe(sql2, ...bindings2);
@@ -883,3 +1328,22 @@ async function runPrismaWithCount(prisma, query, {
883
1328
  return { records, total: 0, pagination: getPagination(query, 0) };
884
1329
  }
885
1330
  }
1331
+ // Annotate the CommonJS export names for ESM import in node:
1332
+ 0 && (module.exports = {
1333
+ Parser,
1334
+ SelectBuilder,
1335
+ extractGrouped,
1336
+ extractIndexed,
1337
+ extractLookup,
1338
+ getPagination,
1339
+ runMysql,
1340
+ runMysqlAsync,
1341
+ runMysqlAsyncWithCount,
1342
+ runMysqlWithCount,
1343
+ runPrisma,
1344
+ runPrismaWithCount,
1345
+ toSafeJsonRecord,
1346
+ toSafeJsonRecords,
1347
+ toSafeJsonString,
1348
+ toSafeJsonValue
1349
+ });