sql-love 1.0.3 → 1.0.5

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.
Files changed (56) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +52 -32
  3. package/dist/index.cjs +1328 -0
  4. package/dist/index.d.ts +732 -9
  5. package/{src/SelectBuilder/SelectBuilder.ts → dist/index.mjs} +650 -277
  6. package/package.json +28 -11
  7. package/.github/workflows/node.js.yml +0 -37
  8. package/.prettierrc.json +0 -13
  9. package/CHANGELOG.md +0 -39
  10. package/CONTRIBUTING.md +0 -85
  11. package/assets/sql-love-logo.png +0 -0
  12. package/codecov.yml +0 -7
  13. package/dist/index.js +0 -9
  14. package/dist/src/Parser/Parser.d.ts +0 -157
  15. package/dist/src/Parser/Parser.js +0 -304
  16. package/dist/src/SelectBuilder/SelectBuilder.d.ts +0 -379
  17. package/dist/src/SelectBuilder/SelectBuilder.js +0 -810
  18. package/dist/src/extractGrouped/extractGrouped.d.ts +0 -17
  19. package/dist/src/extractGrouped/extractGrouped.js +0 -31
  20. package/dist/src/extractIndexed/extractIndexed.d.ts +0 -12
  21. package/dist/src/extractIndexed/extractIndexed.js +0 -23
  22. package/dist/src/extractLookup/extractLookup.d.ts +0 -9
  23. package/dist/src/extractLookup/extractLookup.js +0 -21
  24. package/dist/src/getPagination/getPagination.d.ts +0 -16
  25. package/dist/src/getPagination/getPagination.js +0 -40
  26. package/dist/src/runMysql/runMysql.d.ts +0 -58
  27. package/dist/src/runMysql/runMysql.js +0 -61
  28. package/dist/src/runPrisma/runPrisma.d.ts +0 -41
  29. package/dist/src/runPrisma/runPrisma.js +0 -34
  30. package/dist/src/substrCount/substrCount.d.ts +0 -6
  31. package/dist/src/substrCount/substrCount.js +0 -14
  32. package/dist/src/toSafeJson/toSafeJson.d.ts +0 -25
  33. package/dist/src/toSafeJson/toSafeJson.js +0 -45
  34. package/index.ts +0 -19
  35. package/src/Parser/Parser.spec.ts +0 -226
  36. package/src/Parser/Parser.ts +0 -325
  37. package/src/SelectBuilder/SelectBuilder.spec.ts +0 -785
  38. package/src/extractGrouped/extractGrouped.spec.ts +0 -43
  39. package/src/extractGrouped/extractGrouped.ts +0 -36
  40. package/src/extractIndexed/extractIndexed.spec.ts +0 -40
  41. package/src/extractIndexed/extractIndexed.ts +0 -28
  42. package/src/extractLookup/extractLookup.spec.ts +0 -38
  43. package/src/extractLookup/extractLookup.ts +0 -33
  44. package/src/getPagination/getPagination.spec.ts +0 -75
  45. package/src/getPagination/getPagination.ts +0 -42
  46. package/src/runMysql/runMysql.spec.ts +0 -286
  47. package/src/runMysql/runMysql.ts +0 -106
  48. package/src/runPrisma/runPrisma.spec.ts +0 -99
  49. package/src/runPrisma/runPrisma.ts +0 -75
  50. package/src/substrCount/substrCount.spec.ts +0 -29
  51. package/src/substrCount/substrCount.ts +0 -14
  52. package/src/toSafeJson/toSafeJson.spec.ts +0 -28
  53. package/src/toSafeJson/toSafeJson.ts +0 -56
  54. package/tsconfig.build.json +0 -10
  55. package/tsconfig.json +0 -22
  56. package/vitest.config.ts +0 -11
package/LICENSE.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ISC License (ISC)
2
- Copyright 2023 Ken Snyder
2
+ Copyright 2023-2025 Ken Snyder
3
3
 
4
4
  Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
5
5
 
package/README.md CHANGED
@@ -1,12 +1,15 @@
1
- <img alt="SQL Love Logo" src="https://github.com/kensnyder/sql-love/raw/main/assets/sql-love-logo.png?v=1.0.3" width="250" height="208" />
1
+ <img alt="SQL Love Logo" src="https://github.com/kensnyder/sql-love/raw/main/assets/sql-love-logo.png?v=1.0.5" width="250" height="208" />
2
2
 
3
3
  # sql-love
4
4
 
5
- [![NPM Link](https://badgen.net/npm/v/sql-love?v=1.0.3)](https://npmjs.com/package/sql-love)
6
- [![Dependencies](https://badgen.net/static/dependencies/0/green?v=1.0.3)](https://www.npmjs.com/package/sql-love?activeTab=dependencies)
7
- [![Build Status](https://github.com/kensnyder/sql-love/actions/workflows/node.js.yml/badge.svg?v=1.0.3)](https://github.com/kensnyder/sql-love/actions)
8
- [![Code Coverage](https://codecov.io/gh/kensnyder/sql-love/branch/main/graph/badge.svg?v=1.0.3)](https://codecov.io/gh/kensnyder/sql-love)
9
- [![ISC License](https://badgen.net/static/license/ISC/green?v=1.0.3)](https://opensource.org/licenses/ISC)
5
+ [![NPM Link](https://badgen.net/npm/v/sql-love?v=1.0.5)](https://npmjs.com/package/sql-love)
6
+ [![Language](https://badgen.net/static/language/TS?v=1.0.5)](https://github.com/search?q=repo:kensnyder/sql-love++language:TypeScript&type=code)
7
+ [![Build Status](https://github.com/kensnyder/sql-love/actions/workflows/node.js.yml/badge.svg?v=1.0.5)](https://github.com/kensnyder/sql-love/actions)
8
+ [![Code Coverage](https://codecov.io/gh/kensnyder/sql-love/branch/main/graph/badge.svg?v=1.0.5)](https://codecov.io/gh/kensnyder/sql-love)
9
+ [![Gzipped Size](https://badgen.net/bundlephobia/minzip/sql-love?label=minzipped&v=1.0.5)](https://bundlephobia.com/package/sql-love@1.0.5)
10
+ [![Dependency details](https://badgen.net/bundlephobia/dependency-count/sql-love?v=1.0.5)](https://www.npmjs.com/package/sql-love?activeTab=dependencies)
11
+ [![Tree shakeable](https://badgen.net/bundlephobia/tree-shaking/sql-love?v=1.0.5)](https://www.npmjs.com/package/sql-love)
12
+ [![ISC License](https://badgen.net/static/license/ISC/green?v=1.0.5)](https://opensource.org/licenses/ISC)
10
13
 
11
14
  Classes for parsing and building SQL select queries in Node
12
15
 
@@ -65,11 +68,11 @@ if (areaCode) {
65
68
  query.sort(sortField);
66
69
  query.limit(limitTo);
67
70
  const { sql, bindings } = query.compile();
68
- ```
69
71
 
70
- Then execute the SQL in your preferred client:
72
+ //
73
+ // Then execute the SQL in your preferred client:
74
+ //
71
75
 
72
- ```js
73
76
  // mysql2:
74
77
  connection.query(sql, bindings, (err, results, fields) => {});
75
78
 
@@ -82,11 +85,13 @@ const { results } = await env.DB.prepare(sql)
82
85
  .all();
83
86
  ```
84
87
 
85
- _Note that these are prepared statements so the values in the "bindings"_
86
- _array are safe from SQL injection, with the caveat that you are in charge of_
87
- _quoting any identifiers. For instance, we don't recommend populating `u.email`_
88
- _from user input in the example above. But if you do, be sure to use your_
89
- _client's `quoteIdentifier()` function._
88
+ _Note:_ These are prepared statements so the values in the `bindings` array are
89
+ safe from SQL injection, with the caveat that you are in charge of quoting any
90
+ identifiers. For instance, don't populate `u.email` from user input in the
91
+ example above. But if you need dynamic identifiers for some reason, be sure to
92
+ use your SQL client's `quoteIdentifier()` function.
93
+
94
+ ### Parsing with placeholders
90
95
 
91
96
  It is possible to add placeholders to the base query.
92
97
 
@@ -120,7 +125,12 @@ And "bindings" equals:
120
125
  */
121
126
  ```
122
127
 
123
- You may specify a compiler engine to use. The default is `"mysql"`.
128
+ ### RDBMS engine
129
+
130
+ You may specify a RMDBS engine to compile for. The default is `"mysql"`.
131
+ Supported values are `"mysql" | "sqlite" | "pg" | "mssql" | "oracle"`. Each
132
+ RMDBS engine needs slightly different SQL depending on the syntax for binding
133
+ placeholders and for limit/offset.
124
134
 
125
135
  ```js
126
136
  import { SelectBuilder, setDefaultEngine } from 'sql-love';
@@ -150,13 +160,13 @@ setDefaultEngine('pg');
150
160
  You should use prepared statements to run the sql and bindings returned by
151
161
  `SelectBuilder.compile()`. This will protect you from SQL injection.
152
162
 
153
- Using `mysqlClient.query(sql, bindings)` and
163
+ Using mysql2's `client.query(sql, bindings)` or Prisma's
154
164
  `prisma.$queryRawUnsafe(sql, ...bindings)` are examples of using prepared
155
165
  statements.
156
166
 
157
- Note that even though the name `prisma.$queryRawUnsafe(sql, ...bindings)`
158
- implies that the query is unsafe, it is actually safe because
159
- `prisma.$queryRawUnsafe` uses prepared statements.
167
+ Note that even though the name `prisma.$queryRawUnsafe` implies that the
168
+ operation is unsafe, values are bound to a prepared statement and you would be
169
+ using `prisma.$queryRawUnsafe` as intended.
160
170
 
161
171
  SQL Love also includes utility functions for running queries in mysql and
162
172
  Prisma so you don't have to remember these functions. See documentation for
@@ -166,7 +176,7 @@ Prisma so you don't have to remember these functions. See documentation for
166
176
  ### Building the query
167
177
 
168
178
  Use the following methods to build queries. And see
169
- [more examples below](#where-examples).
179
+ [more examples below](#more-examples).
170
180
 
171
181
  - `query.where(column, operator, value)` - Require column satisfy operator
172
182
  - `query.where(column, value)` - Require column equal a value
@@ -315,7 +325,7 @@ const { sql } = query.compileCount({ countExpr: 'DISTINCT externalId' });
315
325
  // SELECT COUNT(DISTINCT externalId) AS found_rows FROM users
316
326
  ```
317
327
 
318
- With queries that have a "HAVING" clause, the main query will be wrapped in a
328
+ With queries that have a `HAVING` clause, the main query will be wrapped in a
319
329
  count query.
320
330
 
321
331
  ```js
@@ -326,6 +336,10 @@ const query = new SelectBuilder(`
326
336
  HAVING COUNT(*) > 1
327
337
  `);
328
338
 
339
+ // Regular query
340
+ const { sql } = query.compile();
341
+
342
+ // Count query
329
343
  const { sql } = query.compileCount();
330
344
  /*
331
345
  SELECT COUNT(*) AS found_rows FROM (
@@ -343,8 +357,10 @@ SelectBuilder has a few other useful methods.
343
357
 
344
358
  - `query.getClone()` - Get an exact copy of this query object
345
359
  - `query.unjoin(tableName)` - Remove a join expression
346
- - `query.reset(field)` - Reset a single aspect of the query (e.g. 'where' or 'having')
347
- - `query.reset(fields)` - Reset a few particular aspects of the query (e.g. \['where', 'having'\])
360
+ - `query.reset(field)` - Reset a single aspect of the query (e.g. 'where' or '
361
+ having')
362
+ - `query.reset(fields)` - Reset a few particular aspects of the query (e.g.
363
+ `['where', 'having']`)
348
364
  - `query.reset()` - Reset query to an empty state
349
365
 
350
366
  ### Parser limitations
@@ -428,7 +444,8 @@ import { SelectBuilder, getPagination } from 'sql-love';
428
444
  const query = new SelectBuilder('SELECT * FROM users').limit(10).page(1);
429
445
  // ...
430
446
  // run a count query to determine that there are 42 results
431
- const pagination = getPagination(query, 42);
447
+ const count = 42;
448
+ const pagination = getPagination(query, count);
432
449
  expect(pagination).toEqual({
433
450
  page: 1,
434
451
  prevPage: null,
@@ -543,6 +560,7 @@ See [getPagination](#getpagination) for details on the pagination object.
543
560
  ```js
544
561
  import { SelectBuilder, runMysql } from 'sql-love';
545
562
  import { mysql } from 'mysql2';
563
+
546
564
  const client = mysql.createConnection(config);
547
565
 
548
566
  const query = new SelectBuilder('SELECT * FROM users');
@@ -557,6 +575,7 @@ found rows and pagination.
557
575
  ```js
558
576
  import { SelectBuilder, runMysqlWithCount } from 'sql-love';
559
577
  import { mysql } from 'mysql2';
578
+
560
579
  const client = mysql.createConnection(config);
561
580
 
562
581
  const query = new SelectBuilder('SELECT * FROM users')
@@ -572,6 +591,7 @@ You can also use the mysql2 promise api:
572
591
  ```js
573
592
  import { SelectBuilder, runMysqlAsync, runMysqlAsyncWithCount } from 'sql-love';
574
593
  import { mysql } from 'mysql2/promise';
594
+
575
595
  const client = await mysql.createConnection(config);
576
596
 
577
597
  const query = new SelectBuilder('SELECT * FROM users')
@@ -589,23 +609,23 @@ const { records, total, pagination } = await runMysqlAsyncWithCount(
589
609
 
590
610
  ### toSafeJson
591
611
 
592
- With some database clients such as Prisma, your recordsets may contain BigInt
593
- objects. These are not safe to pass to JSON.stringify(). The following are
594
- examples of the toSafeJson\* utility functions.
612
+ With some database clients such as Prisma, your recordsets may contain `BigInt`
613
+ objects. These are not safe to pass to `JSON.stringify()`. The following are
614
+ examples of the `toSafeJson*` utility functions.
595
615
 
596
616
  ```js
597
617
  import { toSafeJsonString, toSafeJsonRecords } from 'sql-love';
598
618
 
599
- const records = [{ count: 12n }, { count: 9007199254740993n }];
619
+ const records = [{ postCount: 12n }, { postCount: 9007199254740993n }];
600
620
 
601
621
  toSafeJsonRecords(records);
602
622
  // [
603
- // { count: 12 },
604
- // { count: "9007199254740993" },
623
+ // { postCount: 12 },
624
+ // { postCount: "9007199254740993" },
605
625
  // ]
606
626
 
607
627
  toSafeJsonString(records);
608
- // '[{"count":12},{"count":"9007199254740993"}]'
628
+ // '[{"postCount":12},{"postCount":"9007199254740993"}]'
609
629
 
610
- // Note that BigInt values too big for Number are converted to strings
630
+ // As you can see, BigInt values too big for Number are converted to strings
611
631
  ```