kysely 0.27.5 → 0.28.0

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 (371) hide show
  1. package/CODE_OF_CONDUCT.md +183 -0
  2. package/FUNDING.md +25 -0
  3. package/README.md +182 -3
  4. package/deno.check.d.ts +7 -0
  5. package/dist/cjs/dialect/mssql/mssql-dialect-config.d.ts +26 -16
  6. package/dist/cjs/dialect/mssql/mssql-driver.d.ts +6 -3
  7. package/dist/cjs/dialect/mssql/mssql-driver.js +33 -19
  8. package/dist/cjs/dialect/mssql/mssql-query-compiler.d.ts +2 -0
  9. package/dist/cjs/dialect/mssql/mssql-query-compiler.js +11 -0
  10. package/dist/cjs/dialect/mysql/mysql-driver.d.ts +4 -0
  11. package/dist/cjs/dialect/mysql/mysql-driver.js +27 -12
  12. package/dist/cjs/dialect/postgres/postgres-driver.d.ts +4 -0
  13. package/dist/cjs/dialect/postgres/postgres-driver.js +28 -18
  14. package/dist/cjs/dialect/postgres/postgres-introspector.js +7 -17
  15. package/dist/cjs/dialect/sqlite/sqlite-driver.d.ts +4 -0
  16. package/dist/cjs/dialect/sqlite/sqlite-driver.js +19 -13
  17. package/dist/cjs/dialect/sqlite/sqlite-introspector.js +66 -44
  18. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.d.ts +2 -0
  19. package/dist/cjs/dialect/sqlite/sqlite-query-compiler.js +4 -0
  20. package/dist/cjs/driver/database-connection.d.ts +0 -4
  21. package/dist/cjs/driver/driver.d.ts +17 -0
  22. package/dist/cjs/driver/driver.js +13 -1
  23. package/dist/cjs/driver/dummy-driver.d.ts +3 -0
  24. package/dist/cjs/driver/dummy-driver.js +9 -0
  25. package/dist/cjs/driver/runtime-driver.d.ts +4 -0
  26. package/dist/cjs/driver/runtime-driver.js +43 -3
  27. package/dist/cjs/expression/expression-builder.d.ts +9 -10
  28. package/dist/cjs/helpers/postgres.d.ts +48 -0
  29. package/dist/cjs/helpers/postgres.js +50 -0
  30. package/dist/cjs/index.d.ts +13 -2
  31. package/dist/cjs/index.js +13 -2
  32. package/dist/cjs/kysely.d.ts +339 -2
  33. package/dist/cjs/kysely.js +465 -11
  34. package/dist/cjs/migration/migrator.d.ts +16 -1
  35. package/dist/cjs/migration/migrator.js +14 -4
  36. package/dist/cjs/operation-node/aggregate-function-node.d.ts +2 -1
  37. package/dist/cjs/operation-node/aggregate-function-node.js +4 -3
  38. package/dist/cjs/operation-node/alter-table-node.d.ts +3 -1
  39. package/dist/cjs/operation-node/collate-node.d.ts +13 -0
  40. package/dist/cjs/operation-node/collate-node.js +19 -0
  41. package/dist/cjs/operation-node/constraint-node.d.ts +1 -1
  42. package/dist/cjs/operation-node/create-type-node.d.ts +1 -1
  43. package/dist/cjs/operation-node/create-type-node.js +1 -1
  44. package/dist/cjs/operation-node/delete-query-node.d.ts +8 -2
  45. package/dist/cjs/operation-node/delete-query-node.js +11 -15
  46. package/dist/cjs/operation-node/foreign-key-constraint-node.d.ts +4 -0
  47. package/dist/cjs/operation-node/insert-query-node.d.ts +3 -0
  48. package/dist/cjs/operation-node/join-node.d.ts +1 -1
  49. package/dist/cjs/operation-node/merge-query-node.d.ts +2 -0
  50. package/dist/cjs/operation-node/operation-node-transformer.d.ts +106 -97
  51. package/dist/cjs/operation-node/operation-node-transformer.js +352 -312
  52. package/dist/cjs/operation-node/operation-node-visitor.d.ts +9 -1
  53. package/dist/cjs/operation-node/operation-node-visitor.js +4 -0
  54. package/dist/cjs/operation-node/operation-node.d.ts +1 -1
  55. package/dist/cjs/operation-node/or-action-node.d.ts +12 -0
  56. package/dist/cjs/operation-node/or-action-node.js +18 -0
  57. package/dist/cjs/operation-node/order-by-item-node.d.ts +5 -0
  58. package/dist/cjs/operation-node/order-by-item-node.js +6 -0
  59. package/dist/cjs/operation-node/primary-key-constraint-node.d.ts +29 -0
  60. package/dist/cjs/operation-node/{primary-constraint-node.js → primary-key-constraint-node.js} +11 -2
  61. package/dist/cjs/operation-node/query-node.d.ts +7 -0
  62. package/dist/cjs/operation-node/query-node.js +15 -0
  63. package/dist/cjs/operation-node/refresh-materialized-view-node.d.ts +17 -0
  64. package/dist/cjs/operation-node/refresh-materialized-view-node.js +25 -0
  65. package/dist/cjs/operation-node/rename-constraint-node.d.ts +14 -0
  66. package/dist/cjs/operation-node/rename-constraint-node.js +20 -0
  67. package/dist/cjs/operation-node/select-query-node.d.ts +8 -2
  68. package/dist/cjs/operation-node/select-query-node.js +11 -15
  69. package/dist/cjs/operation-node/unique-constraint-node.d.ts +2 -0
  70. package/dist/cjs/operation-node/update-query-node.d.ts +3 -4
  71. package/dist/cjs/operation-node/update-query-node.js +5 -2
  72. package/dist/cjs/parser/collate-parser.d.ts +1 -0
  73. package/dist/cjs/parser/collate-parser.js +2 -0
  74. package/dist/cjs/parser/delete-from-parser.d.ts +5 -0
  75. package/dist/cjs/parser/delete-from-parser.js +2 -0
  76. package/dist/cjs/parser/insert-values-parser.js +3 -1
  77. package/dist/cjs/parser/join-parser.d.ts +1 -1
  78. package/dist/cjs/parser/join-parser.js +7 -1
  79. package/dist/cjs/parser/merge-into-parser.d.ts +5 -0
  80. package/dist/cjs/parser/merge-into-parser.js +2 -0
  81. package/dist/cjs/parser/order-by-parser.d.ts +18 -5
  82. package/dist/cjs/parser/order-by-parser.js +24 -14
  83. package/dist/cjs/parser/savepoint-parser.d.ts +4 -0
  84. package/dist/cjs/parser/savepoint-parser.js +11 -0
  85. package/dist/cjs/parser/select-from-parser.d.ts +4 -0
  86. package/dist/cjs/parser/select-from-parser.js +2 -0
  87. package/dist/cjs/parser/table-parser.d.ts +2 -5
  88. package/dist/cjs/parser/update-parser.d.ts +5 -0
  89. package/dist/cjs/parser/update-parser.js +2 -0
  90. package/dist/cjs/parser/update-set-parser.d.ts +7 -4
  91. package/dist/cjs/plugin/camel-case/camel-case-plugin.js +1 -1
  92. package/dist/cjs/plugin/camel-case/camel-case-transformer.d.ts +2 -1
  93. package/dist/cjs/plugin/camel-case/camel-case-transformer.js +2 -2
  94. package/dist/cjs/plugin/camel-case/camel-case.js +4 -1
  95. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-plugin.js +1 -1
  96. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +4 -3
  97. package/dist/cjs/plugin/deduplicate-joins/deduplicate-joins-transformer.js +6 -6
  98. package/dist/cjs/plugin/handle-empty-in-lists/handle-empty-in-lists-plugin.d.ts +211 -0
  99. package/dist/cjs/plugin/handle-empty-in-lists/handle-empty-in-lists-plugin.js +162 -0
  100. package/dist/cjs/plugin/handle-empty-in-lists/handle-empty-in-lists-transformer.d.ts +8 -0
  101. package/dist/cjs/plugin/handle-empty-in-lists/handle-empty-in-lists-transformer.js +29 -0
  102. package/dist/cjs/plugin/handle-empty-in-lists/handle-empty-in-lists.d.ts +44 -0
  103. package/dist/cjs/plugin/handle-empty-in-lists/handle-empty-in-lists.js +66 -0
  104. package/dist/cjs/plugin/immediate-value/immediate-value-plugin.js +1 -1
  105. package/dist/cjs/plugin/immediate-value/immediate-value-transformer.d.ts +2 -0
  106. package/dist/cjs/plugin/immediate-value/immediate-value-transformer.js +6 -4
  107. package/dist/cjs/plugin/with-schema/with-schema-plugin.js +1 -1
  108. package/dist/cjs/plugin/with-schema/with-schema-transformer.d.ts +8 -3
  109. package/dist/cjs/plugin/with-schema/with-schema-transformer.js +45 -14
  110. package/dist/cjs/query-builder/aggregate-function-builder.d.ts +83 -5
  111. package/dist/cjs/query-builder/aggregate-function-builder.js +15 -27
  112. package/dist/cjs/query-builder/cte-builder.js +0 -2
  113. package/dist/cjs/query-builder/delete-query-builder.d.ts +36 -47
  114. package/dist/cjs/query-builder/delete-query-builder.js +12 -78
  115. package/dist/cjs/query-builder/function-module.d.ts +31 -4
  116. package/dist/cjs/query-builder/insert-query-builder.d.ts +161 -6
  117. package/dist/cjs/query-builder/insert-query-builder.js +197 -10
  118. package/dist/cjs/query-builder/join-builder.js +0 -2
  119. package/dist/cjs/query-builder/merge-query-builder.d.ts +145 -3
  120. package/dist/cjs/query-builder/merge-query-builder.js +28 -7
  121. package/dist/cjs/query-builder/on-conflict-builder.js +0 -4
  122. package/dist/cjs/query-builder/order-by-interface.d.ts +176 -0
  123. package/dist/cjs/query-builder/order-by-interface.js +2 -0
  124. package/dist/cjs/query-builder/order-by-item-builder.d.ts +43 -0
  125. package/dist/cjs/query-builder/order-by-item-builder.js +75 -0
  126. package/dist/cjs/query-builder/over-builder.d.ts +43 -6
  127. package/dist/cjs/query-builder/over-builder.js +8 -25
  128. package/dist/cjs/query-builder/returning-interface.d.ts +20 -3
  129. package/dist/cjs/query-builder/select-query-builder.d.ts +279 -98
  130. package/dist/cjs/query-builder/select-query-builder.js +26 -26
  131. package/dist/cjs/query-builder/update-query-builder.d.ts +88 -9
  132. package/dist/cjs/query-builder/update-query-builder.js +17 -15
  133. package/dist/cjs/query-compiler/compiled-query.d.ts +2 -0
  134. package/dist/cjs/query-compiler/compiled-query.js +2 -0
  135. package/dist/cjs/query-compiler/default-query-compiler.d.ts +17 -2
  136. package/dist/cjs/query-compiler/default-query-compiler.js +97 -2
  137. package/dist/cjs/query-compiler/query-compiler.d.ts +4 -2
  138. package/dist/cjs/query-creator.d.ts +23 -25
  139. package/dist/cjs/query-creator.js +280 -8
  140. package/dist/cjs/query-executor/default-query-executor.d.ts +2 -1
  141. package/dist/cjs/query-executor/default-query-executor.js +2 -2
  142. package/dist/cjs/query-executor/query-executor-base.js +7 -25
  143. package/dist/cjs/raw-builder/raw-builder.js +0 -3
  144. package/dist/cjs/raw-builder/sql.d.ts +4 -4
  145. package/dist/cjs/raw-builder/sql.js +1 -1
  146. package/dist/cjs/schema/alter-column-builder.js +0 -3
  147. package/dist/cjs/schema/alter-table-add-foreign-key-constraint-builder.d.ts +4 -0
  148. package/dist/cjs/schema/alter-table-add-foreign-key-constraint-builder.js +24 -2
  149. package/dist/cjs/schema/alter-table-add-index-builder.js +0 -2
  150. package/dist/cjs/schema/alter-table-builder.d.ts +7 -3
  151. package/dist/cjs/schema/alter-table-builder.js +21 -10
  152. package/dist/cjs/schema/alter-table-drop-constraint-builder.js +0 -2
  153. package/dist/cjs/schema/alter-table-executor.js +0 -2
  154. package/dist/cjs/schema/check-constraint-builder.d.ts +13 -0
  155. package/dist/cjs/schema/check-constraint-builder.js +20 -0
  156. package/dist/cjs/schema/column-definition-builder.js +0 -2
  157. package/dist/cjs/schema/create-index-builder.js +1 -3
  158. package/dist/cjs/schema/create-schema-builder.js +0 -2
  159. package/dist/cjs/schema/create-table-builder.d.ts +5 -4
  160. package/dist/cjs/schema/create-table-builder.js +9 -7
  161. package/dist/cjs/schema/create-type-builder.d.ts +1 -1
  162. package/dist/cjs/schema/create-type-builder.js +0 -2
  163. package/dist/cjs/schema/create-view-builder.js +0 -2
  164. package/dist/cjs/schema/drop-index-builder.js +0 -2
  165. package/dist/cjs/schema/drop-schema-builder.js +0 -2
  166. package/dist/cjs/schema/drop-table-builder.js +0 -2
  167. package/dist/cjs/schema/drop-type-builder.js +0 -2
  168. package/dist/cjs/schema/drop-view-builder.js +0 -2
  169. package/dist/cjs/schema/foreign-key-constraint-builder.d.ts +9 -0
  170. package/dist/cjs/schema/foreign-key-constraint-builder.js +16 -2
  171. package/dist/cjs/schema/primary-key-constraint-builder.d.ts +17 -0
  172. package/dist/cjs/schema/primary-key-constraint-builder.js +37 -0
  173. package/dist/cjs/schema/refresh-materialized-view-builder.d.ts +47 -0
  174. package/dist/cjs/schema/refresh-materialized-view-builder.js +75 -0
  175. package/dist/cjs/schema/schema.d.ts +14 -0
  176. package/dist/cjs/schema/schema.js +21 -0
  177. package/dist/cjs/schema/unique-constraint-builder.d.ts +10 -1
  178. package/dist/cjs/schema/unique-constraint-builder.js +26 -5
  179. package/dist/cjs/util/infer-result.d.ts +1 -1
  180. package/dist/cjs/util/log.d.ts +1 -0
  181. package/dist/cjs/util/log.js +3 -2
  182. package/dist/cjs/util/provide-controlled-connection.d.ts +7 -0
  183. package/dist/cjs/util/provide-controlled-connection.js +24 -0
  184. package/dist/esm/dialect/mssql/mssql-dialect-config.d.ts +26 -16
  185. package/dist/esm/dialect/mssql/mssql-driver.d.ts +6 -3
  186. package/dist/esm/dialect/mssql/mssql-driver.js +33 -19
  187. package/dist/esm/dialect/mssql/mssql-query-compiler.d.ts +2 -0
  188. package/dist/esm/dialect/mssql/mssql-query-compiler.js +11 -0
  189. package/dist/esm/dialect/mysql/mysql-driver.d.ts +4 -0
  190. package/dist/esm/dialect/mysql/mysql-driver.js +27 -12
  191. package/dist/esm/dialect/postgres/postgres-driver.d.ts +4 -0
  192. package/dist/esm/dialect/postgres/postgres-driver.js +28 -18
  193. package/dist/esm/dialect/postgres/postgres-introspector.js +7 -17
  194. package/dist/esm/dialect/sqlite/sqlite-driver.d.ts +4 -0
  195. package/dist/esm/dialect/sqlite/sqlite-driver.js +19 -13
  196. package/dist/esm/dialect/sqlite/sqlite-introspector.js +66 -44
  197. package/dist/esm/dialect/sqlite/sqlite-query-compiler.d.ts +2 -0
  198. package/dist/esm/dialect/sqlite/sqlite-query-compiler.js +4 -0
  199. package/dist/esm/driver/database-connection.d.ts +0 -4
  200. package/dist/esm/driver/driver.d.ts +17 -0
  201. package/dist/esm/driver/driver.js +11 -0
  202. package/dist/esm/driver/dummy-driver.d.ts +3 -0
  203. package/dist/esm/driver/dummy-driver.js +9 -0
  204. package/dist/esm/driver/runtime-driver.d.ts +4 -0
  205. package/dist/esm/driver/runtime-driver.js +43 -3
  206. package/dist/esm/expression/expression-builder.d.ts +9 -10
  207. package/dist/esm/helpers/postgres.d.ts +48 -0
  208. package/dist/esm/helpers/postgres.js +49 -0
  209. package/dist/esm/index.d.ts +13 -2
  210. package/dist/esm/index.js +11 -1
  211. package/dist/esm/kysely.d.ts +339 -2
  212. package/dist/esm/kysely.js +461 -10
  213. package/dist/esm/migration/migrator.d.ts +16 -1
  214. package/dist/esm/migration/migrator.js +14 -4
  215. package/dist/esm/operation-node/aggregate-function-node.d.ts +2 -1
  216. package/dist/esm/operation-node/aggregate-function-node.js +4 -3
  217. package/dist/esm/operation-node/alter-table-node.d.ts +3 -1
  218. package/dist/esm/operation-node/collate-node.d.ts +13 -0
  219. package/dist/esm/operation-node/collate-node.js +17 -0
  220. package/dist/esm/operation-node/constraint-node.d.ts +1 -1
  221. package/dist/esm/operation-node/create-type-node.d.ts +1 -1
  222. package/dist/esm/operation-node/create-type-node.js +1 -1
  223. package/dist/esm/operation-node/delete-query-node.d.ts +8 -2
  224. package/dist/esm/operation-node/delete-query-node.js +11 -15
  225. package/dist/esm/operation-node/foreign-key-constraint-node.d.ts +4 -0
  226. package/dist/esm/operation-node/insert-query-node.d.ts +3 -0
  227. package/dist/esm/operation-node/join-node.d.ts +1 -1
  228. package/dist/esm/operation-node/merge-query-node.d.ts +2 -0
  229. package/dist/esm/operation-node/operation-node-transformer.d.ts +106 -97
  230. package/dist/esm/operation-node/operation-node-transformer.js +352 -312
  231. package/dist/esm/operation-node/operation-node-visitor.d.ts +9 -1
  232. package/dist/esm/operation-node/operation-node-visitor.js +4 -0
  233. package/dist/esm/operation-node/operation-node.d.ts +1 -1
  234. package/dist/esm/operation-node/or-action-node.d.ts +12 -0
  235. package/dist/esm/operation-node/or-action-node.js +16 -0
  236. package/dist/esm/operation-node/order-by-item-node.d.ts +5 -0
  237. package/dist/esm/operation-node/order-by-item-node.js +6 -0
  238. package/dist/esm/operation-node/primary-key-constraint-node.d.ts +29 -0
  239. package/dist/esm/operation-node/{primary-constraint-node.js → primary-key-constraint-node.js} +11 -2
  240. package/dist/esm/operation-node/query-node.d.ts +7 -0
  241. package/dist/esm/operation-node/query-node.js +15 -0
  242. package/dist/esm/operation-node/refresh-materialized-view-node.d.ts +17 -0
  243. package/dist/esm/operation-node/refresh-materialized-view-node.js +23 -0
  244. package/dist/esm/operation-node/rename-constraint-node.d.ts +14 -0
  245. package/dist/esm/operation-node/rename-constraint-node.js +18 -0
  246. package/dist/esm/operation-node/select-query-node.d.ts +8 -2
  247. package/dist/esm/operation-node/select-query-node.js +11 -15
  248. package/dist/esm/operation-node/unique-constraint-node.d.ts +2 -0
  249. package/dist/esm/operation-node/update-query-node.d.ts +3 -4
  250. package/dist/esm/operation-node/update-query-node.js +5 -2
  251. package/dist/esm/parser/collate-parser.d.ts +1 -0
  252. package/dist/esm/parser/collate-parser.js +2 -0
  253. package/dist/esm/parser/delete-from-parser.d.ts +5 -0
  254. package/dist/esm/parser/delete-from-parser.js +2 -0
  255. package/dist/esm/parser/insert-values-parser.js +3 -1
  256. package/dist/esm/parser/join-parser.d.ts +1 -1
  257. package/dist/esm/parser/join-parser.js +7 -1
  258. package/dist/esm/parser/merge-into-parser.d.ts +5 -0
  259. package/dist/esm/parser/merge-into-parser.js +2 -0
  260. package/dist/esm/parser/order-by-parser.d.ts +18 -5
  261. package/dist/esm/parser/order-by-parser.js +27 -17
  262. package/dist/esm/parser/savepoint-parser.d.ts +4 -0
  263. package/dist/esm/parser/savepoint-parser.js +9 -0
  264. package/dist/esm/parser/select-from-parser.d.ts +4 -0
  265. package/dist/esm/parser/select-from-parser.js +2 -0
  266. package/dist/esm/parser/table-parser.d.ts +2 -5
  267. package/dist/esm/parser/update-parser.d.ts +5 -0
  268. package/dist/esm/parser/update-parser.js +2 -0
  269. package/dist/esm/parser/update-set-parser.d.ts +7 -4
  270. package/dist/esm/plugin/camel-case/camel-case-plugin.js +1 -1
  271. package/dist/esm/plugin/camel-case/camel-case-transformer.d.ts +2 -1
  272. package/dist/esm/plugin/camel-case/camel-case-transformer.js +2 -2
  273. package/dist/esm/plugin/camel-case/camel-case.js +4 -1
  274. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js +1 -1
  275. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.d.ts +4 -3
  276. package/dist/esm/plugin/deduplicate-joins/deduplicate-joins-transformer.js +6 -6
  277. package/dist/esm/plugin/handle-empty-in-lists/handle-empty-in-lists-plugin.d.ts +211 -0
  278. package/dist/esm/plugin/handle-empty-in-lists/handle-empty-in-lists-plugin.js +159 -0
  279. package/dist/esm/plugin/handle-empty-in-lists/handle-empty-in-lists-transformer.d.ts +8 -0
  280. package/dist/esm/plugin/handle-empty-in-lists/handle-empty-in-lists-transformer.js +26 -0
  281. package/dist/esm/plugin/handle-empty-in-lists/handle-empty-in-lists.d.ts +44 -0
  282. package/dist/esm/plugin/handle-empty-in-lists/handle-empty-in-lists.js +63 -0
  283. package/dist/esm/plugin/immediate-value/immediate-value-plugin.js +1 -1
  284. package/dist/esm/plugin/immediate-value/immediate-value-transformer.d.ts +2 -0
  285. package/dist/esm/plugin/immediate-value/immediate-value-transformer.js +6 -4
  286. package/dist/esm/plugin/with-schema/with-schema-plugin.js +1 -1
  287. package/dist/esm/plugin/with-schema/with-schema-transformer.d.ts +8 -3
  288. package/dist/esm/plugin/with-schema/with-schema-transformer.js +45 -14
  289. package/dist/esm/query-builder/aggregate-function-builder.d.ts +83 -5
  290. package/dist/esm/query-builder/aggregate-function-builder.js +15 -27
  291. package/dist/esm/query-builder/cte-builder.js +0 -2
  292. package/dist/esm/query-builder/delete-query-builder.d.ts +36 -47
  293. package/dist/esm/query-builder/delete-query-builder.js +12 -78
  294. package/dist/esm/query-builder/function-module.d.ts +31 -4
  295. package/dist/esm/query-builder/insert-query-builder.d.ts +161 -6
  296. package/dist/esm/query-builder/insert-query-builder.js +197 -10
  297. package/dist/esm/query-builder/join-builder.js +0 -2
  298. package/dist/esm/query-builder/merge-query-builder.d.ts +145 -3
  299. package/dist/esm/query-builder/merge-query-builder.js +29 -8
  300. package/dist/esm/query-builder/on-conflict-builder.js +0 -4
  301. package/dist/esm/query-builder/order-by-interface.d.ts +176 -0
  302. package/dist/esm/query-builder/order-by-interface.js +2 -0
  303. package/dist/esm/query-builder/order-by-item-builder.d.ts +43 -0
  304. package/dist/esm/query-builder/order-by-item-builder.js +72 -0
  305. package/dist/esm/query-builder/over-builder.d.ts +43 -6
  306. package/dist/esm/query-builder/over-builder.js +8 -25
  307. package/dist/esm/query-builder/returning-interface.d.ts +20 -3
  308. package/dist/esm/query-builder/select-query-builder.d.ts +279 -98
  309. package/dist/esm/query-builder/select-query-builder.js +26 -26
  310. package/dist/esm/query-builder/update-query-builder.d.ts +88 -9
  311. package/dist/esm/query-builder/update-query-builder.js +17 -15
  312. package/dist/esm/query-compiler/compiled-query.d.ts +2 -0
  313. package/dist/esm/query-compiler/compiled-query.js +2 -0
  314. package/dist/esm/query-compiler/default-query-compiler.d.ts +17 -2
  315. package/dist/esm/query-compiler/default-query-compiler.js +97 -2
  316. package/dist/esm/query-compiler/query-compiler.d.ts +4 -2
  317. package/dist/esm/query-creator.d.ts +23 -25
  318. package/dist/esm/query-creator.js +281 -9
  319. package/dist/esm/query-executor/default-query-executor.d.ts +2 -1
  320. package/dist/esm/query-executor/default-query-executor.js +2 -2
  321. package/dist/esm/query-executor/query-executor-base.js +7 -25
  322. package/dist/esm/raw-builder/raw-builder.js +0 -3
  323. package/dist/esm/raw-builder/sql.d.ts +4 -4
  324. package/dist/esm/raw-builder/sql.js +1 -1
  325. package/dist/esm/schema/alter-column-builder.js +0 -3
  326. package/dist/esm/schema/alter-table-add-foreign-key-constraint-builder.d.ts +4 -0
  327. package/dist/esm/schema/alter-table-add-foreign-key-constraint-builder.js +24 -2
  328. package/dist/esm/schema/alter-table-add-index-builder.js +0 -2
  329. package/dist/esm/schema/alter-table-builder.d.ts +7 -3
  330. package/dist/esm/schema/alter-table-builder.js +22 -11
  331. package/dist/esm/schema/alter-table-drop-constraint-builder.js +0 -2
  332. package/dist/esm/schema/alter-table-executor.js +0 -2
  333. package/dist/esm/schema/check-constraint-builder.d.ts +13 -0
  334. package/dist/esm/schema/check-constraint-builder.js +17 -0
  335. package/dist/esm/schema/column-definition-builder.js +0 -2
  336. package/dist/esm/schema/create-index-builder.js +1 -3
  337. package/dist/esm/schema/create-schema-builder.js +0 -2
  338. package/dist/esm/schema/create-table-builder.d.ts +5 -4
  339. package/dist/esm/schema/create-table-builder.js +10 -8
  340. package/dist/esm/schema/create-type-builder.d.ts +1 -1
  341. package/dist/esm/schema/create-type-builder.js +0 -2
  342. package/dist/esm/schema/create-view-builder.js +0 -2
  343. package/dist/esm/schema/drop-index-builder.js +0 -2
  344. package/dist/esm/schema/drop-schema-builder.js +0 -2
  345. package/dist/esm/schema/drop-table-builder.js +0 -2
  346. package/dist/esm/schema/drop-type-builder.js +0 -2
  347. package/dist/esm/schema/drop-view-builder.js +0 -2
  348. package/dist/esm/schema/foreign-key-constraint-builder.d.ts +9 -0
  349. package/dist/esm/schema/foreign-key-constraint-builder.js +16 -2
  350. package/dist/esm/schema/primary-key-constraint-builder.d.ts +17 -0
  351. package/dist/esm/schema/primary-key-constraint-builder.js +34 -0
  352. package/dist/esm/schema/refresh-materialized-view-builder.d.ts +47 -0
  353. package/dist/esm/schema/refresh-materialized-view-builder.js +72 -0
  354. package/dist/esm/schema/schema.d.ts +14 -0
  355. package/dist/esm/schema/schema.js +21 -0
  356. package/dist/esm/schema/unique-constraint-builder.d.ts +10 -1
  357. package/dist/esm/schema/unique-constraint-builder.js +26 -5
  358. package/dist/esm/util/infer-result.d.ts +1 -1
  359. package/dist/esm/util/log.d.ts +1 -0
  360. package/dist/esm/util/log.js +3 -2
  361. package/dist/esm/util/provide-controlled-connection.d.ts +7 -0
  362. package/dist/esm/util/provide-controlled-connection.js +22 -0
  363. package/outdated-typescript.d.ts +5 -0
  364. package/package.json +16 -2
  365. package/CONTRIBUTING.md +0 -70
  366. package/dist/cjs/operation-node/primary-constraint-node.d.ts +0 -15
  367. package/dist/cjs/util/prevent-await.d.ts +0 -1
  368. package/dist/cjs/util/prevent-await.js +0 -13
  369. package/dist/esm/operation-node/primary-constraint-node.d.ts +0 -15
  370. package/dist/esm/util/prevent-await.d.ts +0 -1
  371. package/dist/esm/util/prevent-await.js +0 -11
@@ -4,8 +4,11 @@ exports.isOrderByDirection = isOrderByDirection;
4
4
  exports.parseOrderBy = parseOrderBy;
5
5
  exports.parseOrderByItem = parseOrderByItem;
6
6
  const dynamic_reference_builder_js_1 = require("../dynamic/dynamic-reference-builder.js");
7
+ const expression_js_1 = require("../expression/expression.js");
7
8
  const order_by_item_node_js_1 = require("../operation-node/order-by-item-node.js");
8
9
  const raw_node_js_1 = require("../operation-node/raw-node.js");
10
+ const order_by_item_builder_js_1 = require("../query-builder/order-by-item-builder.js");
11
+ const log_once_js_1 = require("../util/log-once.js");
9
12
  const expression_parser_js_1 = require("./expression-parser.js");
10
13
  const reference_parser_js_1 = require("./reference-parser.js");
11
14
  function isOrderByDirection(thing) {
@@ -18,21 +21,22 @@ function parseOrderBy(args) {
18
21
  if (args.length === 1) {
19
22
  const [orderBy] = args;
20
23
  if (Array.isArray(orderBy)) {
24
+ (0, log_once_js_1.logOnce)('orderBy(array) is deprecated, use multiple orderBy calls instead.');
21
25
  return orderBy.map((item) => parseOrderByItem(item));
22
26
  }
23
27
  return [parseOrderByItem(orderBy)];
24
28
  }
25
29
  throw new Error(`Invalid number of arguments at order by! expected 1-2, received ${args.length}`);
26
30
  }
27
- function parseOrderByItem(ref, direction) {
28
- const parsedRef = parseOrderByExpression(ref);
31
+ function parseOrderByItem(expr, modifiers) {
32
+ const parsedRef = parseOrderByExpression(expr);
29
33
  if (order_by_item_node_js_1.OrderByItemNode.is(parsedRef)) {
30
- if (direction) {
34
+ if (modifiers) {
31
35
  throw new Error('Cannot specify direction twice!');
32
36
  }
33
37
  return parsedRef;
34
38
  }
35
- return order_by_item_node_js_1.OrderByItemNode.create(parsedRef, parseOrderByDirectionExpression(direction));
39
+ return parseOrderByWithModifiers(parsedRef, modifiers);
36
40
  }
37
41
  function parseOrderByExpression(expr) {
38
42
  if ((0, expression_parser_js_1.isExpressionOrFactory)(expr)) {
@@ -43,19 +47,25 @@ function parseOrderByExpression(expr) {
43
47
  }
44
48
  const [ref, direction] = expr.split(' ');
45
49
  if (direction) {
46
- if (!isOrderByDirection(direction)) {
47
- throw new Error(`Invalid order by direction: ${direction}`);
48
- }
49
- return order_by_item_node_js_1.OrderByItemNode.create((0, reference_parser_js_1.parseStringReference)(ref), parseOrderByDirectionExpression(direction));
50
+ (0, log_once_js_1.logOnce)("`orderBy('column asc')` is deprecated. Use `orderBy('column', 'asc')` instead.");
51
+ return parseOrderByWithModifiers((0, reference_parser_js_1.parseStringReference)(ref), direction);
50
52
  }
51
53
  return (0, reference_parser_js_1.parseStringReference)(expr);
52
54
  }
53
- function parseOrderByDirectionExpression(expr) {
54
- if (!expr) {
55
- return undefined;
55
+ function parseOrderByWithModifiers(expr, modifiers) {
56
+ if (typeof modifiers === 'string') {
57
+ if (!isOrderByDirection(modifiers)) {
58
+ throw new Error(`Invalid order by direction: ${modifiers}`);
59
+ }
60
+ return order_by_item_node_js_1.OrderByItemNode.create(expr, raw_node_js_1.RawNode.createWithSql(modifiers));
61
+ }
62
+ if ((0, expression_js_1.isExpression)(modifiers)) {
63
+ (0, log_once_js_1.logOnce)("`orderBy(..., expr)` is deprecated. Use `orderBy(..., 'asc')` or `orderBy(..., (ob) => ...)` instead.");
64
+ return order_by_item_node_js_1.OrderByItemNode.create(expr, modifiers.toOperationNode());
56
65
  }
57
- if (expr === 'asc' || expr === 'desc') {
58
- return raw_node_js_1.RawNode.createWithSql(expr);
66
+ const node = order_by_item_node_js_1.OrderByItemNode.create(expr);
67
+ if (!modifiers) {
68
+ return node;
59
69
  }
60
- return expr.toOperationNode();
70
+ return modifiers(new order_by_item_builder_js_1.OrderByItemBuilder({ node })).toOperationNode();
61
71
  }
@@ -0,0 +1,4 @@
1
+ import { RawNode } from '../operation-node/raw-node.js';
2
+ export type RollbackToSavepoint<S extends string[], SN extends S[number]> = S extends [...infer L, infer R] ? R extends SN ? S : RollbackToSavepoint<L extends string[] ? L : never, SN> : never;
3
+ export type ReleaseSavepoint<S extends string[], SN extends S[number]> = S extends [...infer L, infer R] ? R extends SN ? L : ReleaseSavepoint<L extends string[] ? L : never, SN> : never;
4
+ export declare function parseSavepointCommand(command: string, savepointName: string): RawNode;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSavepointCommand = parseSavepointCommand;
4
+ const identifier_node_js_1 = require("../operation-node/identifier-node.js");
5
+ const raw_node_js_1 = require("../operation-node/raw-node.js");
6
+ function parseSavepointCommand(command, savepointName) {
7
+ return raw_node_js_1.RawNode.createWithChildren([
8
+ raw_node_js_1.RawNode.createWithSql(`${command} `),
9
+ identifier_node_js_1.IdentifierNode.create(savepointName), // ensures savepointName gets sanitized
10
+ ]);
11
+ }
@@ -0,0 +1,4 @@
1
+ import type { SelectQueryBuilder } from '../query-builder/select-query-builder.js';
2
+ import type { ShallowRecord } from '../util/type-utils.js';
3
+ import type { ExtractTableAlias, From, FromTables, TableExpressionOrList } from './table-parser.js';
4
+ export type SelectFrom<DB, TB extends keyof DB, TE extends TableExpressionOrList<DB, TB>> = TE extends keyof DB & string ? SelectQueryBuilder<DB, TB | ExtractTableAlias<DB, TE>, {}> : TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? SelectQueryBuilder<DB & ShallowRecord<A, DB[T]>, TB | A, {}> : never : TE extends ReadonlyArray<infer T> ? SelectQueryBuilder<From<DB, T>, FromTables<DB, TB, T>, {}> : SelectQueryBuilder<From<DB, TE>, FromTables<DB, TB, TE>, {}>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -3,22 +3,19 @@ import { TableNode } from '../operation-node/table-node.js';
3
3
  import { AliasedExpressionOrFactory } from './expression-parser.js';
4
4
  import { OperationNode } from '../operation-node/operation-node.js';
5
5
  import { AliasedExpression } from '../expression/expression.js';
6
- import { DrainOuterGeneric, ShallowRecord } from '../util/type-utils.js';
6
+ import { DrainOuterGeneric } from '../util/type-utils.js';
7
7
  export type TableExpression<DB, TB extends keyof DB> = AnyAliasedTable<DB> | AnyTable<DB> | AliasedExpressionOrFactory<DB, TB>;
8
8
  export type TableExpressionOrList<DB, TB extends keyof DB> = TableExpression<DB, TB> | ReadonlyArray<TableExpression<DB, TB>>;
9
- export type TableReference<DB> = SimpleTableReference<DB> | AliasedExpression<any, any>;
10
9
  export type SimpleTableReference<DB> = AnyAliasedTable<DB> | AnyTable<DB>;
11
10
  export type AnyAliasedTable<DB> = `${AnyTable<DB>} as ${string}`;
12
- export type TableReferenceOrList<DB> = TableReference<DB> | ReadonlyArray<TableReference<DB>>;
11
+ export type AnyTable<DB> = keyof DB & string;
13
12
  export type From<DB, TE> = DrainOuterGeneric<{
14
13
  [C in keyof DB | ExtractAliasFromTableExpression<DB, TE>]: C extends ExtractAliasFromTableExpression<DB, TE> ? ExtractRowTypeFromTableExpression<DB, TE, C> : C extends keyof DB ? DB[C] : never;
15
14
  }>;
16
15
  export type FromTables<DB, TB extends keyof DB, TE> = DrainOuterGeneric<TB | ExtractAliasFromTableExpression<DB, TE>>;
17
16
  export type ExtractTableAlias<DB, TE> = TE extends `${string} as ${infer TA}` ? TA extends keyof DB ? TA : never : TE extends keyof DB ? TE : never;
18
- export type PickTableWithAlias<DB, T extends AnyAliasedTable<DB>> = T extends `${infer TB} as ${infer A}` ? TB extends keyof DB ? ShallowRecord<A, DB[TB]> : never : never;
19
17
  type ExtractAliasFromTableExpression<DB, TE> = TE extends string ? TE extends `${string} as ${infer TA}` ? TA : TE extends keyof DB ? TE : never : TE extends AliasedExpression<any, infer QA> ? QA : TE extends (qb: any) => AliasedExpression<any, infer QA> ? QA : never;
20
18
  type ExtractRowTypeFromTableExpression<DB, TE, A extends keyof any> = TE extends `${infer T} as ${infer TA}` ? TA extends A ? T extends keyof DB ? DB[T] : never : never : TE extends A ? TE extends keyof DB ? DB[TE] : never : TE extends AliasedExpression<infer O, infer QA> ? QA extends A ? O : never : TE extends (qb: any) => AliasedExpression<infer O, infer QA> ? QA extends A ? O : never : never;
21
- type AnyTable<DB> = keyof DB & string;
22
19
  export declare function parseTableExpressionOrList(table: TableExpressionOrList<any, any>): OperationNode[];
23
20
  export declare function parseTableExpression(table: TableExpression<any, any>): OperationNode;
24
21
  export declare function parseAliasedTable(from: string): TableNode | AliasNode;
@@ -0,0 +1,5 @@
1
+ import type { UpdateQueryBuilder } from '../query-builder/update-query-builder.js';
2
+ import type { UpdateResult } from '../query-builder/update-result.js';
3
+ import type { ShallowRecord } from '../util/type-utils.js';
4
+ import type { ExtractTableAlias, From, FromTables, TableExpressionOrList } from './table-parser.js';
5
+ export type UpdateTable<DB, TE extends TableExpressionOrList<DB, never>> = TE extends ReadonlyArray<infer T> ? UpdateQueryBuilder<From<DB, T>, FromTables<DB, never, T>, FromTables<DB, never, T>, UpdateResult> : TE extends keyof DB & string ? UpdateQueryBuilder<DB, ExtractTableAlias<DB, TE>, ExtractTableAlias<DB, TE>, UpdateResult> : TE extends `${infer T} as ${infer A}` ? T extends keyof DB ? UpdateQueryBuilder<DB & ShallowRecord<A, DB[T]>, A, A, UpdateResult> : never : UpdateQueryBuilder<From<DB, TE>, FromTables<DB, never, TE>, FromTables<DB, never, TE>, UpdateResult>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,11 +1,14 @@
1
1
  import { ColumnUpdateNode } from '../operation-node/column-update-node.js';
2
2
  import { ExpressionBuilder } from '../expression/expression-builder.js';
3
- import { UpdateKeys, UpdateType } from '../util/column-type.js';
3
+ import { UpdateType } from '../util/column-type.js';
4
4
  import { ValueExpression } from './value-parser.js';
5
5
  import { ExtractRawTypeFromReferenceExpression, ReferenceExpression } from './reference-parser.js';
6
- export type UpdateObject<DB, TB extends keyof DB, UT extends keyof DB = TB> = {
7
- [C in UpdateKeys<DB[UT]>]?: ValueExpression<DB, TB, UpdateType<DB[UT][C]>> | undefined;
8
- };
6
+ import { AnyColumn, DrainOuterGeneric } from '../util/type-utils.js';
7
+ export type UpdateObject<DB, TB extends keyof DB, UT extends keyof DB = TB> = DrainOuterGeneric<{
8
+ [C in AnyColumn<DB, UT>]?: {
9
+ [T in UT]: C extends keyof DB[T] ? ValueExpression<DB, TB, UpdateType<DB[T][C]>> | undefined : never;
10
+ }[UT];
11
+ }>;
9
12
  export type UpdateObjectFactory<DB, TB extends keyof DB, UT extends keyof DB> = (eb: ExpressionBuilder<DB, TB>) => UpdateObject<DB, TB, UT>;
10
13
  export type UpdateObjectExpression<DB, TB extends keyof DB, UT extends keyof DB = TB> = UpdateObject<DB, TB, UT> | UpdateObjectFactory<DB, TB, UT>;
11
14
  export type ExtractUpdateTypeFromReferenceExpression<DB, TB extends keyof DB, RE, DV = unknown> = UpdateType<ExtractRawTypeFromReferenceExpression<DB, TB, RE, DV>>;
@@ -85,7 +85,7 @@ class CamelCasePlugin {
85
85
  this.#snakeCaseTransformer = new camel_case_transformer_js_1.SnakeCaseTransformer(this.snakeCase.bind(this));
86
86
  }
87
87
  transformQuery(args) {
88
- return this.#snakeCaseTransformer.transformNode(args.node);
88
+ return this.#snakeCaseTransformer.transformNode(args.node, args.queryId);
89
89
  }
90
90
  async transformResult(args) {
91
91
  if (args.result.rows && Array.isArray(args.result.rows)) {
@@ -1,8 +1,9 @@
1
1
  import { IdentifierNode } from '../../operation-node/identifier-node.js';
2
2
  import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
+ import { QueryId } from '../../util/query-id.js';
3
4
  import { StringMapper } from './camel-case.js';
4
5
  export declare class SnakeCaseTransformer extends OperationNodeTransformer {
5
6
  #private;
6
7
  constructor(snakeCase: StringMapper);
7
- protected transformIdentifier(node: IdentifierNode): IdentifierNode;
8
+ protected transformIdentifier(node: IdentifierNode, queryId: QueryId): IdentifierNode;
8
9
  }
@@ -8,8 +8,8 @@ class SnakeCaseTransformer extends operation_node_transformer_js_1.OperationNode
8
8
  super();
9
9
  this.#snakeCase = snakeCase;
10
10
  }
11
- transformIdentifier(node) {
12
- node = super.transformIdentifier(node);
11
+ transformIdentifier(node, queryId) {
12
+ node = super.transformIdentifier(node, queryId);
13
13
  return {
14
14
  ...node,
15
15
  name: this.#snakeCase(node.name),
@@ -23,7 +23,10 @@ function createSnakeCaseMapper({ upperCase = false, underscoreBeforeDigits = fal
23
23
  // If underScoreBeforeDigits is true then, well, insert an underscore
24
24
  // before digits :). Only the first digit gets an underscore if
25
25
  // there are multiple.
26
- if (underscoreBeforeDigits && isDigit(char) && !isDigit(prevChar)) {
26
+ if (underscoreBeforeDigits &&
27
+ isDigit(char) &&
28
+ !isDigit(prevChar) &&
29
+ !out.endsWith('_')) {
27
30
  out += '_' + char;
28
31
  continue;
29
32
  }
@@ -10,7 +10,7 @@ const deduplicate_joins_transformer_js_1 = require("./deduplicate-joins-transfor
10
10
  class DeduplicateJoinsPlugin {
11
11
  #transformer = new deduplicate_joins_transformer_js_1.DeduplicateJoinsTransformer();
12
12
  transformQuery(args) {
13
- return this.#transformer.transformNode(args.node);
13
+ return this.#transformer.transformNode(args.node, args.queryId);
14
14
  }
15
15
  transformResult(args) {
16
16
  return Promise.resolve(args.result);
@@ -2,9 +2,10 @@ import { DeleteQueryNode } from '../../operation-node/delete-query-node.js';
2
2
  import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
3
  import { SelectQueryNode } from '../../operation-node/select-query-node.js';
4
4
  import { UpdateQueryNode } from '../../operation-node/update-query-node.js';
5
+ import { QueryId } from '../../util/query-id.js';
5
6
  export declare class DeduplicateJoinsTransformer extends OperationNodeTransformer {
6
7
  #private;
7
- protected transformSelectQuery(node: SelectQueryNode): SelectQueryNode;
8
- protected transformUpdateQuery(node: UpdateQueryNode): UpdateQueryNode;
9
- protected transformDeleteQuery(node: DeleteQueryNode): DeleteQueryNode;
8
+ protected transformSelectQuery(node: SelectQueryNode, queryId: QueryId): SelectQueryNode;
9
+ protected transformUpdateQuery(node: UpdateQueryNode, queryId: QueryId): UpdateQueryNode;
10
+ protected transformDeleteQuery(node: DeleteQueryNode, queryId: QueryId): DeleteQueryNode;
10
11
  }
@@ -4,14 +4,14 @@ exports.DeduplicateJoinsTransformer = void 0;
4
4
  const operation_node_transformer_js_1 = require("../../operation-node/operation-node-transformer.js");
5
5
  const object_utils_js_1 = require("../../util/object-utils.js");
6
6
  class DeduplicateJoinsTransformer extends operation_node_transformer_js_1.OperationNodeTransformer {
7
- transformSelectQuery(node) {
8
- return this.#transformQuery(super.transformSelectQuery(node));
7
+ transformSelectQuery(node, queryId) {
8
+ return this.#transformQuery(super.transformSelectQuery(node, queryId));
9
9
  }
10
- transformUpdateQuery(node) {
11
- return this.#transformQuery(super.transformUpdateQuery(node));
10
+ transformUpdateQuery(node, queryId) {
11
+ return this.#transformQuery(super.transformUpdateQuery(node, queryId));
12
12
  }
13
- transformDeleteQuery(node) {
14
- return this.#transformQuery(super.transformDeleteQuery(node));
13
+ transformDeleteQuery(node, queryId) {
14
+ return this.#transformQuery(super.transformDeleteQuery(node, queryId));
15
15
  }
16
16
  #transformQuery(node) {
17
17
  if (!node.joins || node.joins.length === 0) {
@@ -0,0 +1,211 @@
1
+ import { QueryResult } from '../../driver/database-connection.js';
2
+ import { RootOperationNode } from '../../query-compiler/query-compiler.js';
3
+ import { KyselyPlugin, PluginTransformQueryArgs, PluginTransformResultArgs } from '../kysely-plugin.js';
4
+ import { UnknownRow } from '../../util/type-utils.js';
5
+ import { HandleEmptyInListsOptions } from './handle-empty-in-lists.js';
6
+ /**
7
+ * A plugin that allows handling `in ()` and `not in ()` expressions.
8
+ *
9
+ * These expressions are invalid SQL syntax for many databases, and result in runtime
10
+ * database errors.
11
+ *
12
+ * The workarounds used by other libraries always involve modifying the query under
13
+ * the hood, which is not aligned with Kysely's philosophy of WYSIWYG. We recommend manually checking
14
+ * for empty arrays before passing them as arguments to `in` and `not in` expressions
15
+ * instead, but understand that this can be cumbersome. Hence we're going with an
16
+ * opt-in approach where you can choose if and how to handle these cases. We do
17
+ * not want to make this the default behavior, as it can lead to unexpected behavior.
18
+ * Use it at your own risk. Test it. Make sure it works as expected for you.
19
+ *
20
+ * Using this plugin also allows you to throw an error (thus avoiding unnecessary
21
+ * requests to the database) or print a warning in these cases.
22
+ *
23
+ * ### Examples
24
+ *
25
+ * The following strategy replaces the `in`/`not in` expression with a noncontingent
26
+ * expression. A contradiction (falsy) `1 = 0` for `in`, and a tautology (truthy) `1 = 1` for `not in`),
27
+ * similarily to how {@link https://github.com/knex/knex/blob/176151d8048b2a7feeb89a3d649a5580786d4f4e/docs/src/guide/query-builder.md#L1763 | Knex.js},
28
+ * {@link https://github.com/prisma/prisma-engines/blob/99168c54187178484dae45d9478aa40cfd1866d2/quaint/src/visitor.rs#L804-L823 | PrismaORM},
29
+ * {@link https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Query/Grammars/Grammar.php#L284-L291 | Laravel},
30
+ * {@link https://docs.sqlalchemy.org/en/13/core/engines.html#sqlalchemy.create_engine.params.empty_in_strategy | SQLAlchemy}
31
+ * handle this.
32
+ *
33
+ * ```ts
34
+ * import Sqlite from 'better-sqlite3'
35
+ * import {
36
+ * HandleEmptyInListsPlugin,
37
+ * Kysely,
38
+ * replaceWithNoncontingentExpression,
39
+ * SqliteDialect,
40
+ * } from 'kysely'
41
+ * import type { Database } from 'type-editor' // imaginary module
42
+ *
43
+ * const db = new Kysely<Database>({
44
+ * dialect: new SqliteDialect({
45
+ * database: new Sqlite(':memory:'),
46
+ * }),
47
+ * plugins: [
48
+ * new HandleEmptyInListsPlugin({
49
+ * strategy: replaceWithNoncontingentExpression
50
+ * })
51
+ * ],
52
+ * })
53
+ *
54
+ * const results = await db
55
+ * .selectFrom('person')
56
+ * .where('id', 'in', [])
57
+ * .where('first_name', 'not in', [])
58
+ * .selectAll()
59
+ * .execute()
60
+ * ```
61
+ *
62
+ * The generated SQL (SQLite):
63
+ *
64
+ * ```sql
65
+ * select * from "person" where 1 = 0 and 1 = 1
66
+ * ```
67
+ *
68
+ * The following strategy does the following:
69
+ *
70
+ * When `in`, pushes a `null` value into the empty list resulting in `in (null)`,
71
+ * similiarly to how {@link https://github.com/typeorm/typeorm/blob/0280cdc451c35ef73c830eb1191c95d34f6ce06e/src/query-builder/QueryBuilder.ts#L919-L922 | TypeORM}
72
+ * and {@link https://github.com/sequelize/sequelize/blob/0f2891c6897e12bf9bf56df344aae5b698f58c7d/packages/core/src/abstract-dialect/where-sql-builder.ts#L368-L379 | Sequelize}
73
+ * handle `in ()`. `in (null)` is logically the equivalent of `= null`, which returns
74
+ * `null`, which is a falsy expression in most SQL databases. We recommend NOT
75
+ * using this strategy if you plan to use `in` in `select`, `returning`, or `output`
76
+ * clauses, as the return type differs from the `SqlBool` default type for comparisons.
77
+ *
78
+ * When `not in`, casts the left operand as `char` and pushes a unique value into
79
+ * the empty list resulting in `cast({{lhs}} as char) not in ({{VALUE}})`. Casting
80
+ * is required to avoid database errors with non-string values.
81
+ *
82
+ * ```ts
83
+ * import Sqlite from 'better-sqlite3'
84
+ * import {
85
+ * HandleEmptyInListsPlugin,
86
+ * Kysely,
87
+ * pushValueIntoList,
88
+ * SqliteDialect
89
+ * } from 'kysely'
90
+ * import type { Database } from 'type-editor' // imaginary module
91
+ *
92
+ * const db = new Kysely<Database>({
93
+ * dialect: new SqliteDialect({
94
+ * database: new Sqlite(':memory:'),
95
+ * }),
96
+ * plugins: [
97
+ * new HandleEmptyInListsPlugin({
98
+ * strategy: pushValueIntoList('__kysely_no_values_were_provided__') // choose a unique value for not in. has to be something with zero chance being in the data.
99
+ * })
100
+ * ],
101
+ * })
102
+ *
103
+ * const results = await db
104
+ * .selectFrom('person')
105
+ * .where('id', 'in', [])
106
+ * .where('first_name', 'not in', [])
107
+ * .selectAll()
108
+ * .execute()
109
+ * ```
110
+ *
111
+ * The generated SQL (SQLite):
112
+ *
113
+ * ```sql
114
+ * select * from "person" where "id" in (null) and cast("first_name" as char) not in ('__kysely_no_values_were_provided__')
115
+ * ```
116
+ *
117
+ * The following custom strategy throws an error when an empty list is encountered
118
+ * to avoid unnecessary requests to the database:
119
+ *
120
+ * ```ts
121
+ * import Sqlite from 'better-sqlite3'
122
+ * import {
123
+ * HandleEmptyInListsPlugin,
124
+ * Kysely,
125
+ * SqliteDialect
126
+ * } from 'kysely'
127
+ * import type { Database } from 'type-editor' // imaginary module
128
+ *
129
+ * const db = new Kysely<Database>({
130
+ * dialect: new SqliteDialect({
131
+ * database: new Sqlite(':memory:'),
132
+ * }),
133
+ * plugins: [
134
+ * new HandleEmptyInListsPlugin({
135
+ * strategy: () => {
136
+ * throw new Error('Empty in/not-in is not allowed')
137
+ * }
138
+ * })
139
+ * ],
140
+ * })
141
+ *
142
+ * const results = await db
143
+ * .selectFrom('person')
144
+ * .where('id', 'in', [])
145
+ * .selectAll()
146
+ * .execute() // throws an error with 'Empty in/not-in is not allowed' message!
147
+ * ```
148
+ */
149
+ export declare class HandleEmptyInListsPlugin implements KyselyPlugin {
150
+ #private;
151
+ readonly opt: HandleEmptyInListsOptions;
152
+ constructor(opt: HandleEmptyInListsOptions);
153
+ /**
154
+ * This is called for each query before it is executed. You can modify the query by
155
+ * transforming its {@link OperationNode} tree provided in {@link PluginTransformQueryArgs.node | args.node}
156
+ * and returning the transformed tree. You'd usually want to use an {@link OperationNodeTransformer}
157
+ * for this.
158
+ *
159
+ * If you need to pass some query-related data between this method and `transformResult` you
160
+ * can use a `WeakMap` with {@link PluginTransformQueryArgs.queryId | args.queryId} as the key:
161
+ *
162
+ * ```ts
163
+ * import type {
164
+ * KyselyPlugin,
165
+ * QueryResult,
166
+ * RootOperationNode,
167
+ * UnknownRow
168
+ * } from 'kysely'
169
+ *
170
+ * interface MyData {
171
+ * // ...
172
+ * }
173
+ * const data = new WeakMap<any, MyData>()
174
+ *
175
+ * const plugin = {
176
+ * transformQuery(args: PluginTransformQueryArgs): RootOperationNode {
177
+ * const something: MyData = {}
178
+ *
179
+ * // ...
180
+ *
181
+ * data.set(args.queryId, something)
182
+ *
183
+ * // ...
184
+ *
185
+ * return args.node
186
+ * },
187
+ *
188
+ * async transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>> {
189
+ * // ...
190
+ *
191
+ * const something = data.get(args.queryId)
192
+ *
193
+ * // ...
194
+ *
195
+ * return args.result
196
+ * }
197
+ * } satisfies KyselyPlugin
198
+ * ```
199
+ *
200
+ * You should use a `WeakMap` instead of a `Map` or some other strong references because `transformQuery`
201
+ * is not always matched by a call to `transformResult` which would leave orphaned items in the map
202
+ * and cause a memory leak.
203
+ */
204
+ transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
205
+ /**
206
+ * This method is called for each query after it has been executed. The result
207
+ * of the query can be accessed through {@link PluginTransformResultArgs.result | args.result}.
208
+ * You can modify the result and return the modifier result.
209
+ */
210
+ transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
211
+ }
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HandleEmptyInListsPlugin = void 0;
4
+ const handle_empty_in_lists_transformer_js_1 = require("./handle-empty-in-lists-transformer.js");
5
+ /**
6
+ * A plugin that allows handling `in ()` and `not in ()` expressions.
7
+ *
8
+ * These expressions are invalid SQL syntax for many databases, and result in runtime
9
+ * database errors.
10
+ *
11
+ * The workarounds used by other libraries always involve modifying the query under
12
+ * the hood, which is not aligned with Kysely's philosophy of WYSIWYG. We recommend manually checking
13
+ * for empty arrays before passing them as arguments to `in` and `not in` expressions
14
+ * instead, but understand that this can be cumbersome. Hence we're going with an
15
+ * opt-in approach where you can choose if and how to handle these cases. We do
16
+ * not want to make this the default behavior, as it can lead to unexpected behavior.
17
+ * Use it at your own risk. Test it. Make sure it works as expected for you.
18
+ *
19
+ * Using this plugin also allows you to throw an error (thus avoiding unnecessary
20
+ * requests to the database) or print a warning in these cases.
21
+ *
22
+ * ### Examples
23
+ *
24
+ * The following strategy replaces the `in`/`not in` expression with a noncontingent
25
+ * expression. A contradiction (falsy) `1 = 0` for `in`, and a tautology (truthy) `1 = 1` for `not in`),
26
+ * similarily to how {@link https://github.com/knex/knex/blob/176151d8048b2a7feeb89a3d649a5580786d4f4e/docs/src/guide/query-builder.md#L1763 | Knex.js},
27
+ * {@link https://github.com/prisma/prisma-engines/blob/99168c54187178484dae45d9478aa40cfd1866d2/quaint/src/visitor.rs#L804-L823 | PrismaORM},
28
+ * {@link https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Query/Grammars/Grammar.php#L284-L291 | Laravel},
29
+ * {@link https://docs.sqlalchemy.org/en/13/core/engines.html#sqlalchemy.create_engine.params.empty_in_strategy | SQLAlchemy}
30
+ * handle this.
31
+ *
32
+ * ```ts
33
+ * import Sqlite from 'better-sqlite3'
34
+ * import {
35
+ * HandleEmptyInListsPlugin,
36
+ * Kysely,
37
+ * replaceWithNoncontingentExpression,
38
+ * SqliteDialect,
39
+ * } from 'kysely'
40
+ * import type { Database } from 'type-editor' // imaginary module
41
+ *
42
+ * const db = new Kysely<Database>({
43
+ * dialect: new SqliteDialect({
44
+ * database: new Sqlite(':memory:'),
45
+ * }),
46
+ * plugins: [
47
+ * new HandleEmptyInListsPlugin({
48
+ * strategy: replaceWithNoncontingentExpression
49
+ * })
50
+ * ],
51
+ * })
52
+ *
53
+ * const results = await db
54
+ * .selectFrom('person')
55
+ * .where('id', 'in', [])
56
+ * .where('first_name', 'not in', [])
57
+ * .selectAll()
58
+ * .execute()
59
+ * ```
60
+ *
61
+ * The generated SQL (SQLite):
62
+ *
63
+ * ```sql
64
+ * select * from "person" where 1 = 0 and 1 = 1
65
+ * ```
66
+ *
67
+ * The following strategy does the following:
68
+ *
69
+ * When `in`, pushes a `null` value into the empty list resulting in `in (null)`,
70
+ * similiarly to how {@link https://github.com/typeorm/typeorm/blob/0280cdc451c35ef73c830eb1191c95d34f6ce06e/src/query-builder/QueryBuilder.ts#L919-L922 | TypeORM}
71
+ * and {@link https://github.com/sequelize/sequelize/blob/0f2891c6897e12bf9bf56df344aae5b698f58c7d/packages/core/src/abstract-dialect/where-sql-builder.ts#L368-L379 | Sequelize}
72
+ * handle `in ()`. `in (null)` is logically the equivalent of `= null`, which returns
73
+ * `null`, which is a falsy expression in most SQL databases. We recommend NOT
74
+ * using this strategy if you plan to use `in` in `select`, `returning`, or `output`
75
+ * clauses, as the return type differs from the `SqlBool` default type for comparisons.
76
+ *
77
+ * When `not in`, casts the left operand as `char` and pushes a unique value into
78
+ * the empty list resulting in `cast({{lhs}} as char) not in ({{VALUE}})`. Casting
79
+ * is required to avoid database errors with non-string values.
80
+ *
81
+ * ```ts
82
+ * import Sqlite from 'better-sqlite3'
83
+ * import {
84
+ * HandleEmptyInListsPlugin,
85
+ * Kysely,
86
+ * pushValueIntoList,
87
+ * SqliteDialect
88
+ * } from 'kysely'
89
+ * import type { Database } from 'type-editor' // imaginary module
90
+ *
91
+ * const db = new Kysely<Database>({
92
+ * dialect: new SqliteDialect({
93
+ * database: new Sqlite(':memory:'),
94
+ * }),
95
+ * plugins: [
96
+ * new HandleEmptyInListsPlugin({
97
+ * strategy: pushValueIntoList('__kysely_no_values_were_provided__') // choose a unique value for not in. has to be something with zero chance being in the data.
98
+ * })
99
+ * ],
100
+ * })
101
+ *
102
+ * const results = await db
103
+ * .selectFrom('person')
104
+ * .where('id', 'in', [])
105
+ * .where('first_name', 'not in', [])
106
+ * .selectAll()
107
+ * .execute()
108
+ * ```
109
+ *
110
+ * The generated SQL (SQLite):
111
+ *
112
+ * ```sql
113
+ * select * from "person" where "id" in (null) and cast("first_name" as char) not in ('__kysely_no_values_were_provided__')
114
+ * ```
115
+ *
116
+ * The following custom strategy throws an error when an empty list is encountered
117
+ * to avoid unnecessary requests to the database:
118
+ *
119
+ * ```ts
120
+ * import Sqlite from 'better-sqlite3'
121
+ * import {
122
+ * HandleEmptyInListsPlugin,
123
+ * Kysely,
124
+ * SqliteDialect
125
+ * } from 'kysely'
126
+ * import type { Database } from 'type-editor' // imaginary module
127
+ *
128
+ * const db = new Kysely<Database>({
129
+ * dialect: new SqliteDialect({
130
+ * database: new Sqlite(':memory:'),
131
+ * }),
132
+ * plugins: [
133
+ * new HandleEmptyInListsPlugin({
134
+ * strategy: () => {
135
+ * throw new Error('Empty in/not-in is not allowed')
136
+ * }
137
+ * })
138
+ * ],
139
+ * })
140
+ *
141
+ * const results = await db
142
+ * .selectFrom('person')
143
+ * .where('id', 'in', [])
144
+ * .selectAll()
145
+ * .execute() // throws an error with 'Empty in/not-in is not allowed' message!
146
+ * ```
147
+ */
148
+ class HandleEmptyInListsPlugin {
149
+ opt;
150
+ #transformer;
151
+ constructor(opt) {
152
+ this.opt = opt;
153
+ this.#transformer = new handle_empty_in_lists_transformer_js_1.HandleEmptyInListsTransformer(opt.strategy);
154
+ }
155
+ transformQuery(args) {
156
+ return this.#transformer.transformNode(args.node, args.queryId);
157
+ }
158
+ async transformResult(args) {
159
+ return args.result;
160
+ }
161
+ }
162
+ exports.HandleEmptyInListsPlugin = HandleEmptyInListsPlugin;
@@ -0,0 +1,8 @@
1
+ import { BinaryOperationNode } from '../../operation-node/binary-operation-node.js';
2
+ import { OperationNodeTransformer } from '../../operation-node/operation-node-transformer.js';
3
+ import { EmptyInListsStrategy } from './handle-empty-in-lists.js';
4
+ export declare class HandleEmptyInListsTransformer extends OperationNodeTransformer {
5
+ #private;
6
+ constructor(strategy: EmptyInListsStrategy);
7
+ protected transformBinaryOperation(node: BinaryOperationNode): BinaryOperationNode;
8
+ }