sql-love 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -6
- package/dist/index.cjs +15 -6
- package/dist/index.d.ts +7 -4
- package/dist/index.mjs +15 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<img alt="SQL Love Logo" src="https://github.com/kensnyder/sql-love/raw/main/assets/sql-love-logo.png?v=1.1.
|
|
1
|
+
<img alt="SQL Love Logo" src="https://github.com/kensnyder/sql-love/raw/main/assets/sql-love-logo.png?v=1.1.4" width="250" height="208" />
|
|
2
2
|
|
|
3
3
|
# sql-love
|
|
4
4
|
|
|
5
|
-
[](https://github.com/search?q=repo:kensnyder/sql-love++language:TypeScript&type=code)
|
|
6
|
+
[](https://codecov.io/gh/kensnyder/sql-love)
|
|
7
7
|

|
|
8
8
|

|
|
9
9
|

|
|
10
|
-
[](https://opensource.org/licenses/ISC)
|
|
11
11
|
|
|
12
12
|
Classes for parsing and building SQL select queries in Node/Bun/Deno.
|
|
13
13
|
|
|
@@ -189,7 +189,7 @@ Use the following methods to build queries. And see
|
|
|
189
189
|
- `query.having(columnValueRecord)` - Add multiple conditions
|
|
190
190
|
- `query.orHaving(expressions)` - Multiple `having()`s joined by OR
|
|
191
191
|
- `query.orderBy(column, direction)` - Add ORDER BY clause
|
|
192
|
-
- `query.sortField(
|
|
192
|
+
- `query.sortField(field, mapNames, modifier)` - Add ORDER BY clause for an allowed field in mapNames
|
|
193
193
|
- `query.limit(num)` - Limit by the given number
|
|
194
194
|
- `query.offset(num)` - Specify an offset
|
|
195
195
|
- `query.page(num)` - Automatically calculate offset based on limit and page
|
|
@@ -316,8 +316,11 @@ query.orderBy('modified_at DESC NULLS LAST'); // ORDER BY modified_at DESC NULLS
|
|
|
316
316
|
query.orderBy('modified_at USING >'); // ORDER BY modified_at USING >
|
|
317
317
|
|
|
318
318
|
// Sorting with support for hyphens and mapping
|
|
319
|
-
|
|
319
|
+
// Only fields present in mapNames are allowed, so field names may safely
|
|
320
|
+
// come from user input (e.g. a "?sort=-created" query string param).
|
|
321
|
+
// Unknown fields emit a console.warn and add no ORDER BY clause.
|
|
320
322
|
query.sortField('-created', { created: 'created_at' }); // ORDER BY created_at DESC
|
|
323
|
+
query.sortField('-foo', { created: 'created_at' }); // console.warn; no ORDER BY added
|
|
321
324
|
query.sortField(
|
|
322
325
|
'-created_at',
|
|
323
326
|
{
|
package/dist/index.cjs
CHANGED
|
@@ -859,7 +859,7 @@ UNION
|
|
|
859
859
|
if (numArgs === 1) {
|
|
860
860
|
collection.push(column);
|
|
861
861
|
return this;
|
|
862
|
-
} else if (numArgs === 2 && Array.isArray(operator) &&
|
|
862
|
+
} else if (numArgs === 2 && Array.isArray(operator) && substrCount(column, "?") === operator.length) {
|
|
863
863
|
const values = operator;
|
|
864
864
|
const sql = column.replace(/\?/g, () => {
|
|
865
865
|
this._bindings.push(values.shift());
|
|
@@ -1035,13 +1035,16 @@ UNION
|
|
|
1035
1035
|
return this;
|
|
1036
1036
|
}
|
|
1037
1037
|
/**
|
|
1038
|
-
* Sort by the given
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1038
|
+
* Sort by the given field, with a map of allowed fields to column expressions.
|
|
1039
|
+
* Only field names present in mapNames are allowed; anything else emits a
|
|
1040
|
+
* console.warn and adds no ORDER BY clause. This prevents SQL injection when
|
|
1041
|
+
* fieldName comes from user input.
|
|
1042
|
+
* @param fieldName The field name such as 'created' or '-created' for descending
|
|
1043
|
+
* @param mapNames Allowed field names mapped to column expressions
|
|
1041
1044
|
* @param [modifier] Additional clause to append such as 'NULLS LAST' or 'COLLATE "en_US"'
|
|
1042
1045
|
* @example
|
|
1043
|
-
* query.sortField('-modified_at'); // ORDER BY modified_at DESC
|
|
1044
1046
|
* query.sortField('-created', {'created': 'created_at'}); // ORDER BY created_at DESC
|
|
1047
|
+
* query.sortField('-foo', {'created': 'created_at'}); // console.warn; no ORDER BY added
|
|
1045
1048
|
* query.sortField('-created', {
|
|
1046
1049
|
* 'created': 'created_at NULLS LAST',
|
|
1047
1050
|
* '-created': 'created_at DESC NULLS LAST'
|
|
@@ -1064,7 +1067,13 @@ UNION
|
|
|
1064
1067
|
direction = "DESC";
|
|
1065
1068
|
fieldName = fieldName.slice(1);
|
|
1066
1069
|
}
|
|
1067
|
-
|
|
1070
|
+
if (!Object.prototype.hasOwnProperty.call(mapNames, fieldName)) {
|
|
1071
|
+
console.warn(
|
|
1072
|
+
`SelectBuilder: sortField() ignoring unknown field "${fieldName.slice(0, 100)}"`
|
|
1073
|
+
);
|
|
1074
|
+
return this;
|
|
1075
|
+
}
|
|
1076
|
+
const column = mapNames[fieldName];
|
|
1068
1077
|
if (modifier) {
|
|
1069
1078
|
direction += ` ${modifier}`;
|
|
1070
1079
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -359,13 +359,16 @@ export declare class SelectBuilder {
|
|
|
359
359
|
*/
|
|
360
360
|
orderBy(column: string, direction?: "ASC" | "DESC"): this;
|
|
361
361
|
/**
|
|
362
|
-
* Sort by the given
|
|
363
|
-
*
|
|
364
|
-
*
|
|
362
|
+
* Sort by the given field, with a map of allowed fields to column expressions.
|
|
363
|
+
* Only field names present in mapNames are allowed; anything else emits a
|
|
364
|
+
* console.warn and adds no ORDER BY clause. This prevents SQL injection when
|
|
365
|
+
* fieldName comes from user input.
|
|
366
|
+
* @param fieldName The field name such as 'created' or '-created' for descending
|
|
367
|
+
* @param mapNames Allowed field names mapped to column expressions
|
|
365
368
|
* @param [modifier] Additional clause to append such as 'NULLS LAST' or 'COLLATE "en_US"'
|
|
366
369
|
* @example
|
|
367
|
-
* query.sortField('-modified_at'); // ORDER BY modified_at DESC
|
|
368
370
|
* query.sortField('-created', {'created': 'created_at'}); // ORDER BY created_at DESC
|
|
371
|
+
* query.sortField('-foo', {'created': 'created_at'}); // console.warn; no ORDER BY added
|
|
369
372
|
* query.sortField('-created', {
|
|
370
373
|
* 'created': 'created_at NULLS LAST',
|
|
371
374
|
* '-created': 'created_at DESC NULLS LAST'
|
package/dist/index.mjs
CHANGED
|
@@ -819,7 +819,7 @@ UNION
|
|
|
819
819
|
if (numArgs === 1) {
|
|
820
820
|
collection.push(column);
|
|
821
821
|
return this;
|
|
822
|
-
} else if (numArgs === 2 && Array.isArray(operator) &&
|
|
822
|
+
} else if (numArgs === 2 && Array.isArray(operator) && substrCount(column, "?") === operator.length) {
|
|
823
823
|
const values = operator;
|
|
824
824
|
const sql = column.replace(/\?/g, () => {
|
|
825
825
|
this._bindings.push(values.shift());
|
|
@@ -995,13 +995,16 @@ UNION
|
|
|
995
995
|
return this;
|
|
996
996
|
}
|
|
997
997
|
/**
|
|
998
|
-
* Sort by the given
|
|
999
|
-
*
|
|
1000
|
-
*
|
|
998
|
+
* Sort by the given field, with a map of allowed fields to column expressions.
|
|
999
|
+
* Only field names present in mapNames are allowed; anything else emits a
|
|
1000
|
+
* console.warn and adds no ORDER BY clause. This prevents SQL injection when
|
|
1001
|
+
* fieldName comes from user input.
|
|
1002
|
+
* @param fieldName The field name such as 'created' or '-created' for descending
|
|
1003
|
+
* @param mapNames Allowed field names mapped to column expressions
|
|
1001
1004
|
* @param [modifier] Additional clause to append such as 'NULLS LAST' or 'COLLATE "en_US"'
|
|
1002
1005
|
* @example
|
|
1003
|
-
* query.sortField('-modified_at'); // ORDER BY modified_at DESC
|
|
1004
1006
|
* query.sortField('-created', {'created': 'created_at'}); // ORDER BY created_at DESC
|
|
1007
|
+
* query.sortField('-foo', {'created': 'created_at'}); // console.warn; no ORDER BY added
|
|
1005
1008
|
* query.sortField('-created', {
|
|
1006
1009
|
* 'created': 'created_at NULLS LAST',
|
|
1007
1010
|
* '-created': 'created_at DESC NULLS LAST'
|
|
@@ -1024,7 +1027,13 @@ UNION
|
|
|
1024
1027
|
direction = "DESC";
|
|
1025
1028
|
fieldName = fieldName.slice(1);
|
|
1026
1029
|
}
|
|
1027
|
-
|
|
1030
|
+
if (!Object.prototype.hasOwnProperty.call(mapNames, fieldName)) {
|
|
1031
|
+
console.warn(
|
|
1032
|
+
`SelectBuilder: sortField() ignoring unknown field "${fieldName.slice(0, 100)}"`
|
|
1033
|
+
);
|
|
1034
|
+
return this;
|
|
1035
|
+
}
|
|
1036
|
+
const column = mapNames[fieldName];
|
|
1028
1037
|
if (modifier) {
|
|
1029
1038
|
direction += ` ${modifier}`;
|
|
1030
1039
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sql-love",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Build SQL queries with JavaScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@types/bun": "latest",
|
|
56
56
|
"@types/node": "latest",
|
|
57
57
|
"dts-bundle-generator": "9.5.1",
|
|
58
|
-
"prettier": "3.9.
|
|
58
|
+
"prettier": "3.9.9",
|
|
59
59
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
60
60
|
"typescript": "5.9.3"
|
|
61
61
|
}
|