kysely 0.28.15 → 0.28.17

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 (34) hide show
  1. package/README.md +1 -0
  2. package/dist/cjs/dialect/mysql/mysql-query-compiler.d.ts +6 -0
  3. package/dist/cjs/dialect/mysql/mysql-query-compiler.js +10 -1
  4. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.d.ts +1 -0
  5. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.js +4 -0
  6. package/dist/cjs/expression/expression-builder.d.ts +1 -1
  7. package/dist/cjs/index.d.ts +4 -0
  8. package/dist/cjs/index.js +4 -0
  9. package/dist/cjs/parser/binary-operation-parser.d.ts +3 -1
  10. package/dist/cjs/query-builder/delete-query-builder.d.ts +4 -8
  11. package/dist/cjs/query-builder/insert-query-builder.d.ts +0 -4
  12. package/dist/cjs/query-builder/json-path-builder.js +8 -0
  13. package/dist/cjs/query-builder/merge-query-builder.d.ts +0 -8
  14. package/dist/cjs/query-builder/returning-interface.d.ts +0 -4
  15. package/dist/cjs/query-builder/update-query-builder.d.ts +4 -8
  16. package/dist/cjs/query-compiler/default-query-compiler.d.ts +1 -0
  17. package/dist/cjs/query-compiler/default-query-compiler.js +12 -4
  18. package/dist/esm/dialect/mysql/mysql-query-compiler.d.ts +6 -0
  19. package/dist/esm/dialect/mysql/mysql-query-compiler.js +10 -1
  20. package/dist/esm/dialect/sqlite/sqlite-query-compiler.d.ts +1 -0
  21. package/dist/esm/dialect/sqlite/sqlite-query-compiler.js +4 -0
  22. package/dist/esm/expression/expression-builder.d.ts +1 -1
  23. package/dist/esm/index.d.ts +4 -0
  24. package/dist/esm/index.js +4 -0
  25. package/dist/esm/parser/binary-operation-parser.d.ts +3 -1
  26. package/dist/esm/query-builder/delete-query-builder.d.ts +4 -8
  27. package/dist/esm/query-builder/insert-query-builder.d.ts +0 -4
  28. package/dist/esm/query-builder/json-path-builder.js +8 -0
  29. package/dist/esm/query-builder/merge-query-builder.d.ts +0 -8
  30. package/dist/esm/query-builder/returning-interface.d.ts +0 -4
  31. package/dist/esm/query-builder/update-query-builder.d.ts +4 -8
  32. package/dist/esm/query-compiler/default-query-compiler.d.ts +1 -0
  33. package/dist/esm/query-compiler/default-query-compiler.js +12 -4
  34. package/package.json +34 -34
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://stand-with-ukraine.pp.ua)
2
2
 
3
3
  [![NPM Version](https://img.shields.io/npm/v/kysely?style=flat&label=latest)](https://github.com/kysely-org/kysely/releases/latest)
4
+ [![Socket Badge](https://badge.socket.dev/npm/package/kysely/0.28.17)](https://socket.dev/npm/package/kysely/overview/0.28.17)
4
5
  [![Tests](https://github.com/kysely-org/kysely/actions/workflows/test.yml/badge.svg)](https://github.com/kysely-org/kysely)
5
6
  [![License](https://img.shields.io/github/license/kysely-org/kysely?style=flat)](https://github.com/kysely-org/kysely/blob/master/LICENSE)
6
7
  [![Issues](https://img.shields.io/github/issues-closed/kysely-org/kysely?logo=github)](https://github.com/kysely-org/kysely/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc)
@@ -17,5 +17,11 @@ export declare class MysqlQueryCompiler extends DefaultQueryCompiler {
17
17
  * @see https://dev.mysql.com/doc/refman/9.6/en/string-literals.html
18
18
  */
19
19
  protected sanitizeStringLiteral(value: string): string;
20
+ /**
21
+ * Member values appear inside `"..."` in the JSON path, which itself sits
22
+ * inside a SQL string literal. They must therefore be escaped twice — once
23
+ * for the JSON path grammar, then again for MySQL's string literal parser.
24
+ */
25
+ protected sanitizeJSONPathMemberValue(value: string): string;
20
26
  protected visitCreateIndex(node: CreateIndexNode): void;
21
27
  }
@@ -2,8 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MysqlQueryCompiler = void 0;
4
4
  const default_query_compiler_js_1 = require("../../query-compiler/default-query-compiler.js");
5
- const LITERAL_ESCAPE_REGEX = /\\|'/g;
5
+ const LITERAL_ESCAPE_REGEX = /[\\']/g;
6
6
  const ID_WRAP_REGEX = /`/g;
7
+ const JSON_PATH_MEMBER_ESCAPE_REGEX = /[\\'"]/g;
7
8
  class MysqlQueryCompiler extends default_query_compiler_js_1.DefaultQueryCompiler {
8
9
  getCurrentParameterPlaceholder() {
9
10
  return '?';
@@ -39,6 +40,14 @@ class MysqlQueryCompiler extends default_query_compiler_js_1.DefaultQueryCompile
39
40
  sanitizeStringLiteral(value) {
40
41
  return value.replace(LITERAL_ESCAPE_REGEX, (char) => char === '\\' ? '\\\\' : "''");
41
42
  }
43
+ /**
44
+ * Member values appear inside `"..."` in the JSON path, which itself sits
45
+ * inside a SQL string literal. They must therefore be escaped twice — once
46
+ * for the JSON path grammar, then again for MySQL's string literal parser.
47
+ */
48
+ sanitizeJSONPathMemberValue(value) {
49
+ return value.replace(JSON_PATH_MEMBER_ESCAPE_REGEX, (char) => char === '\\' ? '\\\\\\\\' : char === "'" ? "''" : '\\\\"');
50
+ }
42
51
  visitCreateIndex(node) {
43
52
  this.append('create ');
44
53
  if (node.unique) {
@@ -10,5 +10,6 @@ export declare class SqliteQueryCompiler extends DefaultQueryCompiler {
10
10
  protected getRightIdentifierWrapper(): string;
11
11
  protected getAutoIncrement(): string;
12
12
  protected sanitizeIdentifier(identifier: string): string;
13
+ protected sanitizeJSONPathMemberValue(value: string): string;
13
14
  protected visitDefaultInsertValue(_: DefaultInsertValueNode): void;
14
15
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqliteQueryCompiler = void 0;
4
4
  const default_query_compiler_js_1 = require("../../query-compiler/default-query-compiler.js");
5
5
  const ID_WRAP_REGEX = /"/g;
6
+ const JSON_PATH_MEMBER_ESCAPE_REGEX = /[\\'"]/g;
6
7
  class SqliteQueryCompiler extends default_query_compiler_js_1.DefaultQueryCompiler {
7
8
  visitOrAction(node) {
8
9
  this.append('or ');
@@ -29,6 +30,9 @@ class SqliteQueryCompiler extends default_query_compiler_js_1.DefaultQueryCompil
29
30
  sanitizeIdentifier(identifier) {
30
31
  return identifier.replace(ID_WRAP_REGEX, '""');
31
32
  }
33
+ sanitizeJSONPathMemberValue(value) {
34
+ return value.replace(JSON_PATH_MEMBER_ESCAPE_REGEX, (char) => char === '\\' ? '\\\\' : char === "'" ? "''" : '\\"');
35
+ }
32
36
  visitDefaultInsertValue(_) {
33
37
  // sqlite doesn't support the `default` keyword in inserts.
34
38
  this.append('null');
@@ -524,7 +524,7 @@ export interface ExpressionBuilder<DB, TB extends keyof DB> {
524
524
  * ```
525
525
  *
526
526
  * In the next example a reference tuple is compared to a subquery. Note that
527
- * in this case you need to use the {@link @SelectQueryBuilder.$asTuple | $asTuple}
527
+ * in this case you need to use the {@link SelectQueryBuilder.$asTuple | $asTuple}
528
528
  * function:
529
529
  *
530
530
  * ```ts
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @module
3
+ * @mergeModuleWith <project>
4
+ */
1
5
  export * from './kysely.js';
2
6
  export * from './query-creator.js';
3
7
  export * from './expression/expression.js';
package/dist/cjs/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  "use strict";
2
+ /**
3
+ * @module
4
+ * @mergeModuleWith <project>
5
+ */
2
6
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
7
  if (k2 === undefined) k2 = k;
4
8
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -6,12 +6,14 @@ import { type ValueExpression, type ValueExpressionOrList } from './value-parser
6
6
  import type { OperationNode } from '../operation-node/operation-node.js';
7
7
  import type { Expression } from '../expression/expression.js';
8
8
  import type { SelectType } from '../util/column-type.js';
9
+ import type { IsNever } from '../util/type-utils.js';
10
+ import type { KyselyTypeError } from '../util/type-error.js';
9
11
  export type OperandValueExpression<DB, TB extends keyof DB, RE> = ValueExpression<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE>>;
10
12
  export type OperandValueExpressionOrList<DB, TB extends keyof DB, RE> = ValueExpressionOrList<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE> | null>;
11
13
  export type OperatorExpression = Operator | Expression<unknown>;
12
14
  export type BinaryOperatorExpression = BinaryOperator | Expression<unknown>;
13
15
  export type ComparisonOperatorExpression = ComparisonOperator | Expression<unknown>;
14
- export type FilterObject<DB, TB extends keyof DB> = {
16
+ export type FilterObject<DB, TB extends keyof DB> = IsNever<TB> extends true ? KyselyTypeError<'there are no tables in query context, so a filter object cannot be defined. try passing an array instead.'> : {
15
17
  [R in StringReference<DB, TB>]?: ValueExpressionOrList<DB, TB, SelectType<ExtractTypeFromStringReference<DB, TB, R>>>;
16
18
  };
17
19
  export declare function parseValueBinaryOperationOrExpression(args: any[]): OperationNode;
@@ -653,10 +653,6 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
653
653
  * On supported databases like PostgreSQL, this method can be chained to
654
654
  * `insert`, `update`, `delete` and `merge` queries to return data.
655
655
  *
656
- * Note that on SQLite you need to give aliases for the expressions to avoid
657
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
658
- * For example `.returning('id as id')`.
659
- *
660
656
  * Also see the {@link returningAll} method.
661
657
  *
662
658
  * ### Examples
@@ -976,21 +972,21 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
976
972
  */
977
973
  clearLimit(): DeleteQueryBuilder<DB, TB, O>;
978
974
  /**
979
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
975
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
980
976
  */
981
977
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers?: OrderByModifiers): DeleteQueryBuilder<DB, TB, O>;
982
978
  /**
983
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
979
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
984
980
  * @deprecated It does ~2-2.6x more compile-time instantiations compared to multiple chained `orderBy(expr, modifiers?)` calls (in `order by` clauses with reasonable item counts), and has broken autocompletion.
985
981
  */
986
982
  orderBy<OE extends OrderByExpression<DB, TB, {}> | DirectedOrderByStringReference<DB, TB, {}>>(exprs: ReadonlyArray<OE>): DeleteQueryBuilder<DB, TB, O>;
987
983
  /**
988
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
984
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
989
985
  * @deprecated It does ~2.9x more compile-time instantiations compared to a `orderBy(expr, direction)` call.
990
986
  */
991
987
  orderBy<OE extends DirectedOrderByStringReference<DB, TB, {}>>(expr: OE): DeleteQueryBuilder<DB, TB, O>;
992
988
  /**
993
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
989
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
994
990
  * @deprecated Use `orderBy(expr, (ob) => ...)` instead.
995
991
  */
996
992
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers: Expression<any>): DeleteQueryBuilder<DB, TB, O>;
@@ -752,10 +752,6 @@ export declare class InsertQueryBuilder<DB, TB extends keyof DB, O> implements R
752
752
  * On supported databases like PostgreSQL, this method can be chained to
753
753
  * `insert`, `update`, `delete` and `merge` queries to return data.
754
754
  *
755
- * Note that on SQLite you need to give aliases for the expressions to avoid
756
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
757
- * For example `.returning('id as id')`.
758
- *
759
755
  * Also see the {@link returningAll} method.
760
756
  *
761
757
  * ### Examples
@@ -9,6 +9,7 @@ const json_path_node_js_1 = require("../operation-node/json-path-node.js");
9
9
  const json_reference_node_js_1 = require("../operation-node/json-reference-node.js");
10
10
  const operation_node_source_js_1 = require("../operation-node/operation-node-source.js");
11
11
  const value_node_js_1 = require("../operation-node/value-node.js");
12
+ const HASH_NEGATIVE_INDEX_REGEX = /^#-\d+$/;
12
13
  class JSONPathBuilder {
13
14
  #node;
14
15
  constructor(node) {
@@ -82,6 +83,13 @@ class JSONPathBuilder {
82
83
  * ```
83
84
  */
84
85
  at(index) {
86
+ if ((typeof index !== 'number' && typeof index !== 'string') ||
87
+ (typeof index === 'number' && !Number.isInteger(index)) ||
88
+ (typeof index === 'string' &&
89
+ index !== 'last' &&
90
+ !HASH_NEGATIVE_INDEX_REGEX.test(index))) {
91
+ throw new Error(`Unexpected index value in .at(...): ${index}`);
92
+ }
85
93
  return this.#createBuilderWithPathLeg('ArrayLocation', index);
86
94
  }
87
95
  /**
@@ -130,10 +130,6 @@ export declare class MergeQueryBuilder<DB, TT extends keyof DB, O> implements Mu
130
130
  * On supported databases like PostgreSQL, this method can be chained to
131
131
  * `insert`, `update`, `delete` and `merge` queries to return data.
132
132
  *
133
- * Note that on SQLite you need to give aliases for the expressions to avoid
134
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
135
- * For example `.returning('id as id')`.
136
- *
137
133
  * Also see the {@link returningAll} method.
138
134
  *
139
135
  * ### Examples
@@ -527,10 +523,6 @@ export declare class WheneableMergeQueryBuilder<DB, TT extends keyof DB, ST exte
527
523
  * On supported databases like PostgreSQL, this method can be chained to
528
524
  * `insert`, `update`, `delete` and `merge` queries to return data.
529
525
  *
530
- * Note that on SQLite you need to give aliases for the expressions to avoid
531
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
532
- * For example `.returning('id as id')`.
533
- *
534
526
  * Also see the {@link returningAll} method.
535
527
  *
536
528
  * ### Examples
@@ -8,10 +8,6 @@ export interface ReturningInterface<DB, TB extends keyof DB, O> {
8
8
  * On supported databases like PostgreSQL, this method can be chained to
9
9
  * `insert`, `update`, `delete` and `merge` queries to return data.
10
10
  *
11
- * Note that on SQLite you need to give aliases for the expressions to avoid
12
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
13
- * For example `.returning('id as id')`.
14
- *
15
11
  * Also see the {@link returningAll} method.
16
12
  *
17
13
  * ### Examples
@@ -602,21 +602,21 @@ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyo
602
602
  fullJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2): UpdateQueryBuilderWithFullJoin<DB, UT, TB, O, TE>;
603
603
  fullJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN): UpdateQueryBuilderWithFullJoin<DB, UT, TB, O, TE>;
604
604
  /**
605
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
605
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
606
606
  */
607
607
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers?: OrderByModifiers): UpdateQueryBuilder<DB, UT, TB, O>;
608
608
  /**
609
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
609
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
610
610
  * @deprecated It does ~2-2.6x more compile-time instantiations compared to multiple chained `orderBy(expr, modifiers?)` calls (in `order by` clauses with reasonable item counts), and has broken autocompletion.
611
611
  */
612
612
  orderBy<OE extends OrderByExpression<DB, TB, {}> | DirectedOrderByStringReference<DB, TB, {}>>(exprs: ReadonlyArray<OE>): UpdateQueryBuilder<DB, UT, TB, O>;
613
613
  /**
614
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
614
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
615
615
  * @deprecated It does ~2.9x more compile-time instantiations compared to a `orderBy(expr, direction)` call.
616
616
  */
617
617
  orderBy<OE extends DirectedOrderByStringReference<DB, TB, {}>>(expr: OE): UpdateQueryBuilder<DB, UT, TB, O>;
618
618
  /**
619
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
619
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
620
620
  * @deprecated Use `orderBy(expr, (ob) => ...)` instead.
621
621
  */
622
622
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers: Expression<any>): UpdateQueryBuilder<DB, UT, TB, O>;
@@ -850,10 +850,6 @@ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyo
850
850
  * On supported databases like PostgreSQL, this method can be chained to
851
851
  * `insert`, `update`, `delete` and `merge` queries to return data.
852
852
  *
853
- * Note that on SQLite you need to give aliases for the expressions to avoid
854
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
855
- * For example `.returning('id as id')`.
856
- *
857
853
  * Also see the {@link returningAll} method.
858
854
  *
859
855
  * ### Examples
@@ -222,6 +222,7 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
222
222
  protected getRightExplainOptionsWrapper(): string;
223
223
  protected sanitizeIdentifier(identifier: string): string;
224
224
  protected sanitizeStringLiteral(value: string): string;
225
+ protected sanitizeJSONPathMemberValue(value: string): string;
225
226
  protected addParameter(parameter: unknown): void;
226
227
  protected appendImmediateValue(value: unknown): void;
227
228
  protected appendStringLiteral(value: string): void;
@@ -13,6 +13,7 @@ const set_operation_node_js_1 = require("../operation-node/set-operation-node.js
13
13
  const when_node_js_1 = require("../operation-node/when-node.js");
14
14
  const log_once_js_1 = require("../util/log-once.js");
15
15
  const LIT_WRAP_REGEX = /'/g;
16
+ const JSON_PATH_MEMBER_WRAP_REGEX = /['"]/g;
16
17
  class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisitor {
17
18
  #sql = '';
18
19
  #parameters = [];
@@ -1168,13 +1169,17 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
1168
1169
  }
1169
1170
  visitJSONPathLeg(node) {
1170
1171
  const isArrayLocation = node.type === 'ArrayLocation';
1171
- this.append(isArrayLocation ? '[' : '.');
1172
- this.append(typeof node.value === 'string'
1173
- ? this.sanitizeStringLiteral(node.value)
1174
- : String(node.value));
1172
+ const value = String(node.value);
1175
1173
  if (isArrayLocation) {
1174
+ this.append('[');
1175
+ this.append(this.sanitizeStringLiteral(value));
1176
1176
  this.append(']');
1177
1177
  }
1178
+ else {
1179
+ this.append('."');
1180
+ this.append(this.sanitizeJSONPathMemberValue(value));
1181
+ this.append('"');
1182
+ }
1178
1183
  }
1179
1184
  visitJSONOperatorChain(node) {
1180
1185
  for (let i = 0, len = node.values.length; i < len; i++) {
@@ -1321,6 +1326,9 @@ class DefaultQueryCompiler extends operation_node_visitor_js_1.OperationNodeVisi
1321
1326
  sanitizeStringLiteral(value) {
1322
1327
  return value.replace(LIT_WRAP_REGEX, "''");
1323
1328
  }
1329
+ sanitizeJSONPathMemberValue(value) {
1330
+ return value.replace(JSON_PATH_MEMBER_WRAP_REGEX, (char) => char === "'" ? "''" : '\\"');
1331
+ }
1324
1332
  addParameter(parameter) {
1325
1333
  this.#parameters.push(parameter);
1326
1334
  }
@@ -17,5 +17,11 @@ export declare class MysqlQueryCompiler extends DefaultQueryCompiler {
17
17
  * @see https://dev.mysql.com/doc/refman/9.6/en/string-literals.html
18
18
  */
19
19
  protected sanitizeStringLiteral(value: string): string;
20
+ /**
21
+ * Member values appear inside `"..."` in the JSON path, which itself sits
22
+ * inside a SQL string literal. They must therefore be escaped twice — once
23
+ * for the JSON path grammar, then again for MySQL's string literal parser.
24
+ */
25
+ protected sanitizeJSONPathMemberValue(value: string): string;
20
26
  protected visitCreateIndex(node: CreateIndexNode): void;
21
27
  }
@@ -1,7 +1,8 @@
1
1
  /// <reference types="./mysql-query-compiler.d.ts" />
2
2
  import { DefaultQueryCompiler } from '../../query-compiler/default-query-compiler.js';
3
- const LITERAL_ESCAPE_REGEX = /\\|'/g;
3
+ const LITERAL_ESCAPE_REGEX = /[\\']/g;
4
4
  const ID_WRAP_REGEX = /`/g;
5
+ const JSON_PATH_MEMBER_ESCAPE_REGEX = /[\\'"]/g;
5
6
  export class MysqlQueryCompiler extends DefaultQueryCompiler {
6
7
  getCurrentParameterPlaceholder() {
7
8
  return '?';
@@ -37,6 +38,14 @@ export class MysqlQueryCompiler extends DefaultQueryCompiler {
37
38
  sanitizeStringLiteral(value) {
38
39
  return value.replace(LITERAL_ESCAPE_REGEX, (char) => char === '\\' ? '\\\\' : "''");
39
40
  }
41
+ /**
42
+ * Member values appear inside `"..."` in the JSON path, which itself sits
43
+ * inside a SQL string literal. They must therefore be escaped twice — once
44
+ * for the JSON path grammar, then again for MySQL's string literal parser.
45
+ */
46
+ sanitizeJSONPathMemberValue(value) {
47
+ return value.replace(JSON_PATH_MEMBER_ESCAPE_REGEX, (char) => char === '\\' ? '\\\\\\\\' : char === "'" ? "''" : '\\\\"');
48
+ }
40
49
  visitCreateIndex(node) {
41
50
  this.append('create ');
42
51
  if (node.unique) {
@@ -10,5 +10,6 @@ export declare class SqliteQueryCompiler extends DefaultQueryCompiler {
10
10
  protected getRightIdentifierWrapper(): string;
11
11
  protected getAutoIncrement(): string;
12
12
  protected sanitizeIdentifier(identifier: string): string;
13
+ protected sanitizeJSONPathMemberValue(value: string): string;
13
14
  protected visitDefaultInsertValue(_: DefaultInsertValueNode): void;
14
15
  }
@@ -1,6 +1,7 @@
1
1
  /// <reference types="./sqlite-query-compiler.d.ts" />
2
2
  import { DefaultQueryCompiler } from '../../query-compiler/default-query-compiler.js';
3
3
  const ID_WRAP_REGEX = /"/g;
4
+ const JSON_PATH_MEMBER_ESCAPE_REGEX = /[\\'"]/g;
4
5
  export class SqliteQueryCompiler extends DefaultQueryCompiler {
5
6
  visitOrAction(node) {
6
7
  this.append('or ');
@@ -27,6 +28,9 @@ export class SqliteQueryCompiler extends DefaultQueryCompiler {
27
28
  sanitizeIdentifier(identifier) {
28
29
  return identifier.replace(ID_WRAP_REGEX, '""');
29
30
  }
31
+ sanitizeJSONPathMemberValue(value) {
32
+ return value.replace(JSON_PATH_MEMBER_ESCAPE_REGEX, (char) => char === '\\' ? '\\\\' : char === "'" ? "''" : '\\"');
33
+ }
30
34
  visitDefaultInsertValue(_) {
31
35
  // sqlite doesn't support the `default` keyword in inserts.
32
36
  this.append('null');
@@ -524,7 +524,7 @@ export interface ExpressionBuilder<DB, TB extends keyof DB> {
524
524
  * ```
525
525
  *
526
526
  * In the next example a reference tuple is compared to a subquery. Note that
527
- * in this case you need to use the {@link @SelectQueryBuilder.$asTuple | $asTuple}
527
+ * in this case you need to use the {@link SelectQueryBuilder.$asTuple | $asTuple}
528
528
  * function:
529
529
  *
530
530
  * ```ts
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @module
3
+ * @mergeModuleWith <project>
4
+ */
1
5
  export * from './kysely.js';
2
6
  export * from './query-creator.js';
3
7
  export * from './expression/expression.js';
package/dist/esm/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  /// <reference types="./index.d.ts" />
2
+ /**
3
+ * @module
4
+ * @mergeModuleWith <project>
5
+ */
2
6
  export * from './kysely.js';
3
7
  export * from './query-creator.js';
4
8
  export * from './expression/expression.js';
@@ -6,12 +6,14 @@ import { type ValueExpression, type ValueExpressionOrList } from './value-parser
6
6
  import type { OperationNode } from '../operation-node/operation-node.js';
7
7
  import type { Expression } from '../expression/expression.js';
8
8
  import type { SelectType } from '../util/column-type.js';
9
+ import type { IsNever } from '../util/type-utils.js';
10
+ import type { KyselyTypeError } from '../util/type-error.js';
9
11
  export type OperandValueExpression<DB, TB extends keyof DB, RE> = ValueExpression<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE>>;
10
12
  export type OperandValueExpressionOrList<DB, TB extends keyof DB, RE> = ValueExpressionOrList<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE> | null>;
11
13
  export type OperatorExpression = Operator | Expression<unknown>;
12
14
  export type BinaryOperatorExpression = BinaryOperator | Expression<unknown>;
13
15
  export type ComparisonOperatorExpression = ComparisonOperator | Expression<unknown>;
14
- export type FilterObject<DB, TB extends keyof DB> = {
16
+ export type FilterObject<DB, TB extends keyof DB> = IsNever<TB> extends true ? KyselyTypeError<'there are no tables in query context, so a filter object cannot be defined. try passing an array instead.'> : {
15
17
  [R in StringReference<DB, TB>]?: ValueExpressionOrList<DB, TB, SelectType<ExtractTypeFromStringReference<DB, TB, R>>>;
16
18
  };
17
19
  export declare function parseValueBinaryOperationOrExpression(args: any[]): OperationNode;
@@ -653,10 +653,6 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
653
653
  * On supported databases like PostgreSQL, this method can be chained to
654
654
  * `insert`, `update`, `delete` and `merge` queries to return data.
655
655
  *
656
- * Note that on SQLite you need to give aliases for the expressions to avoid
657
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
658
- * For example `.returning('id as id')`.
659
- *
660
656
  * Also see the {@link returningAll} method.
661
657
  *
662
658
  * ### Examples
@@ -976,21 +972,21 @@ export declare class DeleteQueryBuilder<DB, TB extends keyof DB, O> implements W
976
972
  */
977
973
  clearLimit(): DeleteQueryBuilder<DB, TB, O>;
978
974
  /**
979
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
975
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
980
976
  */
981
977
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers?: OrderByModifiers): DeleteQueryBuilder<DB, TB, O>;
982
978
  /**
983
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
979
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
984
980
  * @deprecated It does ~2-2.6x more compile-time instantiations compared to multiple chained `orderBy(expr, modifiers?)` calls (in `order by` clauses with reasonable item counts), and has broken autocompletion.
985
981
  */
986
982
  orderBy<OE extends OrderByExpression<DB, TB, {}> | DirectedOrderByStringReference<DB, TB, {}>>(exprs: ReadonlyArray<OE>): DeleteQueryBuilder<DB, TB, O>;
987
983
  /**
988
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
984
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
989
985
  * @deprecated It does ~2.9x more compile-time instantiations compared to a `orderBy(expr, direction)` call.
990
986
  */
991
987
  orderBy<OE extends DirectedOrderByStringReference<DB, TB, {}>>(expr: OE): DeleteQueryBuilder<DB, TB, O>;
992
988
  /**
993
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
989
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
994
990
  * @deprecated Use `orderBy(expr, (ob) => ...)` instead.
995
991
  */
996
992
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers: Expression<any>): DeleteQueryBuilder<DB, TB, O>;
@@ -752,10 +752,6 @@ export declare class InsertQueryBuilder<DB, TB extends keyof DB, O> implements R
752
752
  * On supported databases like PostgreSQL, this method can be chained to
753
753
  * `insert`, `update`, `delete` and `merge` queries to return data.
754
754
  *
755
- * Note that on SQLite you need to give aliases for the expressions to avoid
756
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
757
- * For example `.returning('id as id')`.
758
- *
759
755
  * Also see the {@link returningAll} method.
760
756
  *
761
757
  * ### Examples
@@ -7,6 +7,7 @@ import { JSONPathNode } from '../operation-node/json-path-node.js';
7
7
  import { JSONReferenceNode } from '../operation-node/json-reference-node.js';
8
8
  import { isOperationNodeSource } from '../operation-node/operation-node-source.js';
9
9
  import { ValueNode } from '../operation-node/value-node.js';
10
+ const HASH_NEGATIVE_INDEX_REGEX = /^#-\d+$/;
10
11
  export class JSONPathBuilder {
11
12
  #node;
12
13
  constructor(node) {
@@ -80,6 +81,13 @@ export class JSONPathBuilder {
80
81
  * ```
81
82
  */
82
83
  at(index) {
84
+ if ((typeof index !== 'number' && typeof index !== 'string') ||
85
+ (typeof index === 'number' && !Number.isInteger(index)) ||
86
+ (typeof index === 'string' &&
87
+ index !== 'last' &&
88
+ !HASH_NEGATIVE_INDEX_REGEX.test(index))) {
89
+ throw new Error(`Unexpected index value in .at(...): ${index}`);
90
+ }
83
91
  return this.#createBuilderWithPathLeg('ArrayLocation', index);
84
92
  }
85
93
  /**
@@ -130,10 +130,6 @@ export declare class MergeQueryBuilder<DB, TT extends keyof DB, O> implements Mu
130
130
  * On supported databases like PostgreSQL, this method can be chained to
131
131
  * `insert`, `update`, `delete` and `merge` queries to return data.
132
132
  *
133
- * Note that on SQLite you need to give aliases for the expressions to avoid
134
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
135
- * For example `.returning('id as id')`.
136
- *
137
133
  * Also see the {@link returningAll} method.
138
134
  *
139
135
  * ### Examples
@@ -527,10 +523,6 @@ export declare class WheneableMergeQueryBuilder<DB, TT extends keyof DB, ST exte
527
523
  * On supported databases like PostgreSQL, this method can be chained to
528
524
  * `insert`, `update`, `delete` and `merge` queries to return data.
529
525
  *
530
- * Note that on SQLite you need to give aliases for the expressions to avoid
531
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
532
- * For example `.returning('id as id')`.
533
- *
534
526
  * Also see the {@link returningAll} method.
535
527
  *
536
528
  * ### Examples
@@ -8,10 +8,6 @@ export interface ReturningInterface<DB, TB extends keyof DB, O> {
8
8
  * On supported databases like PostgreSQL, this method can be chained to
9
9
  * `insert`, `update`, `delete` and `merge` queries to return data.
10
10
  *
11
- * Note that on SQLite you need to give aliases for the expressions to avoid
12
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
13
- * For example `.returning('id as id')`.
14
- *
15
11
  * Also see the {@link returningAll} method.
16
12
  *
17
13
  * ### Examples
@@ -602,21 +602,21 @@ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyo
602
602
  fullJoin<TE extends TableExpression<DB, TB>, K1 extends JoinReferenceExpression<DB, TB, TE>, K2 extends JoinReferenceExpression<DB, TB, TE>>(table: TE, k1: K1, k2: K2): UpdateQueryBuilderWithFullJoin<DB, UT, TB, O, TE>;
603
603
  fullJoin<TE extends TableExpression<DB, TB>, FN extends JoinCallbackExpression<DB, TB, TE>>(table: TE, callback: FN): UpdateQueryBuilderWithFullJoin<DB, UT, TB, O, TE>;
604
604
  /**
605
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
605
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
606
606
  */
607
607
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers?: OrderByModifiers): UpdateQueryBuilder<DB, UT, TB, O>;
608
608
  /**
609
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
609
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
610
610
  * @deprecated It does ~2-2.6x more compile-time instantiations compared to multiple chained `orderBy(expr, modifiers?)` calls (in `order by` clauses with reasonable item counts), and has broken autocompletion.
611
611
  */
612
612
  orderBy<OE extends OrderByExpression<DB, TB, {}> | DirectedOrderByStringReference<DB, TB, {}>>(exprs: ReadonlyArray<OE>): UpdateQueryBuilder<DB, UT, TB, O>;
613
613
  /**
614
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
614
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
615
615
  * @deprecated It does ~2.9x more compile-time instantiations compared to a `orderBy(expr, direction)` call.
616
616
  */
617
617
  orderBy<OE extends DirectedOrderByStringReference<DB, TB, {}>>(expr: OE): UpdateQueryBuilder<DB, UT, TB, O>;
618
618
  /**
619
- * @description This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
619
+ * @remarks This is only supported by some dialects like MySQL or SQLite with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.
620
620
  * @deprecated Use `orderBy(expr, (ob) => ...)` instead.
621
621
  */
622
622
  orderBy<OE extends OrderByExpression<DB, TB, {}>>(expr: OE, modifiers: Expression<any>): UpdateQueryBuilder<DB, UT, TB, O>;
@@ -850,10 +850,6 @@ export declare class UpdateQueryBuilder<DB, UT extends keyof DB, TB extends keyo
850
850
  * On supported databases like PostgreSQL, this method can be chained to
851
851
  * `insert`, `update`, `delete` and `merge` queries to return data.
852
852
  *
853
- * Note that on SQLite you need to give aliases for the expressions to avoid
854
- * [this bug](https://sqlite.org/forum/forumpost/033daf0b32) in SQLite.
855
- * For example `.returning('id as id')`.
856
- *
857
853
  * Also see the {@link returningAll} method.
858
854
  *
859
855
  * ### Examples
@@ -222,6 +222,7 @@ export declare class DefaultQueryCompiler extends OperationNodeVisitor implement
222
222
  protected getRightExplainOptionsWrapper(): string;
223
223
  protected sanitizeIdentifier(identifier: string): string;
224
224
  protected sanitizeStringLiteral(value: string): string;
225
+ protected sanitizeJSONPathMemberValue(value: string): string;
225
226
  protected addParameter(parameter: unknown): void;
226
227
  protected appendImmediateValue(value: unknown): void;
227
228
  protected appendStringLiteral(value: string): void;
@@ -11,6 +11,7 @@ import { SetOperationNode } from '../operation-node/set-operation-node.js';
11
11
  import { WhenNode } from '../operation-node/when-node.js';
12
12
  import { logOnce } from '../util/log-once.js';
13
13
  const LIT_WRAP_REGEX = /'/g;
14
+ const JSON_PATH_MEMBER_WRAP_REGEX = /['"]/g;
14
15
  export class DefaultQueryCompiler extends OperationNodeVisitor {
15
16
  #sql = '';
16
17
  #parameters = [];
@@ -1166,13 +1167,17 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
1166
1167
  }
1167
1168
  visitJSONPathLeg(node) {
1168
1169
  const isArrayLocation = node.type === 'ArrayLocation';
1169
- this.append(isArrayLocation ? '[' : '.');
1170
- this.append(typeof node.value === 'string'
1171
- ? this.sanitizeStringLiteral(node.value)
1172
- : String(node.value));
1170
+ const value = String(node.value);
1173
1171
  if (isArrayLocation) {
1172
+ this.append('[');
1173
+ this.append(this.sanitizeStringLiteral(value));
1174
1174
  this.append(']');
1175
1175
  }
1176
+ else {
1177
+ this.append('."');
1178
+ this.append(this.sanitizeJSONPathMemberValue(value));
1179
+ this.append('"');
1180
+ }
1176
1181
  }
1177
1182
  visitJSONOperatorChain(node) {
1178
1183
  for (let i = 0, len = node.values.length; i < len; i++) {
@@ -1319,6 +1324,9 @@ export class DefaultQueryCompiler extends OperationNodeVisitor {
1319
1324
  sanitizeStringLiteral(value) {
1320
1325
  return value.replace(LIT_WRAP_REGEX, "''");
1321
1326
  }
1327
+ sanitizeJSONPathMemberValue(value) {
1328
+ return value.replace(JSON_PATH_MEMBER_WRAP_REGEX, (char) => char === "'" ? "''" : '\\"');
1329
+ }
1322
1330
  addParameter(parameter) {
1323
1331
  this.#parameters.push(parameter);
1324
1332
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kysely",
3
- "version": "0.28.15",
3
+ "version": "0.28.17",
4
4
  "description": "Type safe SQL query builder",
5
5
  "repository": {
6
6
  "type": "git",
@@ -77,38 +77,38 @@
77
77
  "Igal Klebanov <igalklebanov@gmail.com>"
78
78
  ],
79
79
  "devDependencies": {
80
- "@arethetypeswrong/cli": "^0.18.2",
81
- "@ark/attest": "^0.56.0",
82
- "@types/better-sqlite3": "^7.6.13",
83
- "@types/chai": "^5.2.3",
84
- "@types/chai-as-promised": "^8.0.2",
85
- "@types/mocha": "^10.0.10",
86
- "@types/node": "^25.5.0",
87
- "@types/pg": "^8.20.0",
88
- "@types/pg-cursor": "^2.7.2",
89
- "@types/semver": "^7.7.1",
90
- "@types/sinon": "^21.0.0",
91
- "better-sqlite3": "^12.8.0",
92
- "chai": "^6.2.2",
93
- "chai-as-promised": "^8.0.2",
94
- "esbuild": "^0.27.4",
95
- "jsr": "^0.14.3",
96
- "lodash": "^4.17.23",
97
- "mocha": "^11.7.5",
98
- "mysql2": "^3.20.0",
99
- "pathe": "^2.0.3",
100
- "pg": "^8.20.0",
101
- "pg-cursor": "^2.19.0",
102
- "pkg-types": "^2.3.0",
103
- "playwright": "^1.58.2",
104
- "prettier": "^3.8.1",
105
- "semver": "^7.7.4",
106
- "sinon": "^21.0.3",
107
- "std-env": "^4.0.0",
108
- "tarn": "^3.0.2",
109
- "tedious": "^19.2.1",
110
- "tsd": "^0.33.0",
111
- "typescript": "~6.0.2"
80
+ "@arethetypeswrong/cli": "0.18.2",
81
+ "@ark/attest": "0.56.0",
82
+ "@types/better-sqlite3": "7.6.13",
83
+ "@types/chai": "5.2.3",
84
+ "@types/chai-as-promised": "8.0.2",
85
+ "@types/mocha": "10.0.10",
86
+ "@types/node": "25.5.2",
87
+ "@types/pg": "8.20.0",
88
+ "@types/pg-cursor": "2.7.2",
89
+ "@types/semver": "7.7.1",
90
+ "@types/sinon": "21.0.1",
91
+ "better-sqlite3": "12.8.0",
92
+ "chai": "6.2.2",
93
+ "chai-as-promised": "8.0.2",
94
+ "esbuild": "0.28.0",
95
+ "jsr": "0.14.3",
96
+ "lodash": "4.18.1",
97
+ "mocha": "11.7.5",
98
+ "mysql2": "3.21.0",
99
+ "pathe": "2.0.3",
100
+ "pg": "8.20.0",
101
+ "pg-cursor": "2.19.0",
102
+ "pkg-types": "2.3.0",
103
+ "playwright": "1.59.1",
104
+ "prettier": "3.8.1",
105
+ "semver": "7.7.4",
106
+ "sinon": "21.0.3",
107
+ "std-env": "4.0.0",
108
+ "tarn": "3.0.2",
109
+ "tedious": "19.2.1",
110
+ "tsd": "0.33.0",
111
+ "typescript": "6.0.2"
112
112
  },
113
113
  "scripts": {
114
114
  "clean": "rm -rf dist & rm -rf test/node/dist & rm -rf test/browser/bundle.js & rm -rf helpers",
@@ -121,7 +121,7 @@
121
121
  "test:browser": "pnpm build && pnpm test:browser:build && node test/browser/test.js",
122
122
  "test:bun": "pnpm build && bun link && cd test/bun && bun install && bun run test",
123
123
  "test:cloudflare-workers": "pnpm build && pnpm -r test --filter kysely-cloudflare-workers-test",
124
- "test:deno": "deno run --allow-env --allow-read --allow-net --no-lock test/deno/local.test.ts && deno run --allow-env --allow-read --allow-net --no-lock test/deno/cdn.test.ts",
124
+ "test:deno": "deno run --allow-env --allow-read --allow-net --no-lock test/deno/test.ts",
125
125
  "test:typings": "tsd test/typings",
126
126
  "test:esmimports": "node scripts/check-esm-imports.cjs",
127
127
  "test:esbuild": "esbuild --bundle --platform=node --external:pg-native dist/esm/index.js --outfile=/dev/null",