@budibase/backend-core 3.2.26 → 3.2.27

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 (466) hide show
  1. package/dist/index.js +62 -23
  2. package/dist/index.js.map +4 -4
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +7 -7
  5. package/dist/plugins.js.map +2 -2
  6. package/dist/plugins.js.meta.json +1 -1
  7. package/dist/src/events/processors/types.d.ts +1 -1
  8. package/dist/src/events/publishers/index.d.ts +1 -0
  9. package/dist/src/events/publishers/rowAction.d.ts +6 -0
  10. package/dist/src/events/publishers/table.d.ts +2 -2
  11. package/dist/src/events/publishers/view.d.ts +17 -6
  12. package/dist/src/index.d.ts +11 -11
  13. package/dist/src/platform/platformDb.d.ts +1 -1
  14. package/dist/src/queue/queue.d.ts +1 -1
  15. package/dist/src/tenancy/db.d.ts +1 -1
  16. package/package.json +7 -7
  17. package/dist/jest.config.js +0 -25
  18. package/dist/jest.config.js.map +0 -1
  19. package/dist/src/accounts/accounts.js +0 -83
  20. package/dist/src/accounts/accounts.js.map +0 -1
  21. package/dist/src/accounts/api.js +0 -102
  22. package/dist/src/accounts/api.js.map +0 -1
  23. package/dist/src/accounts/index.js +0 -18
  24. package/dist/src/accounts/index.js.map +0 -1
  25. package/dist/src/auth/auth.js +0 -198
  26. package/dist/src/auth/auth.js.map +0 -1
  27. package/dist/src/auth/index.js +0 -18
  28. package/dist/src/auth/index.js.map +0 -1
  29. package/dist/src/blacklist/blacklist.js +0 -75
  30. package/dist/src/blacklist/blacklist.js.map +0 -1
  31. package/dist/src/blacklist/index.js +0 -18
  32. package/dist/src/blacklist/index.js.map +0 -1
  33. package/dist/src/cache/appMetadata.js +0 -96
  34. package/dist/src/cache/appMetadata.js.map +0 -1
  35. package/dist/src/cache/base/index.js +0 -189
  36. package/dist/src/cache/base/index.js.map +0 -1
  37. package/dist/src/cache/docWritethrough.js +0 -123
  38. package/dist/src/cache/docWritethrough.js.map +0 -1
  39. package/dist/src/cache/generic.js +0 -37
  40. package/dist/src/cache/generic.js.map +0 -1
  41. package/dist/src/cache/index.js +0 -48
  42. package/dist/src/cache/index.js.map +0 -1
  43. package/dist/src/cache/invite.js +0 -128
  44. package/dist/src/cache/invite.js.map +0 -1
  45. package/dist/src/cache/passwordReset.js +0 -92
  46. package/dist/src/cache/passwordReset.js.map +0 -1
  47. package/dist/src/cache/user.js +0 -183
  48. package/dist/src/cache/user.js.map +0 -1
  49. package/dist/src/cache/writethrough.js +0 -170
  50. package/dist/src/cache/writethrough.js.map +0 -1
  51. package/dist/src/configs/configs.js +0 -294
  52. package/dist/src/configs/configs.js.map +0 -1
  53. package/dist/src/configs/index.js +0 -18
  54. package/dist/src/configs/index.js.map +0 -1
  55. package/dist/src/constants/db.js +0 -75
  56. package/dist/src/constants/db.js.map +0 -1
  57. package/dist/src/constants/index.js +0 -19
  58. package/dist/src/constants/index.js.map +0 -1
  59. package/dist/src/constants/misc.js +0 -40
  60. package/dist/src/constants/misc.js.map +0 -1
  61. package/dist/src/context/Context.js +0 -14
  62. package/dist/src/context/Context.js.map +0 -1
  63. package/dist/src/context/identity.js +0 -81
  64. package/dist/src/context/identity.js.map +0 -1
  65. package/dist/src/context/index.js +0 -44
  66. package/dist/src/context/index.js.map +0 -1
  67. package/dist/src/context/mainContext.js +0 -446
  68. package/dist/src/context/mainContext.js.map +0 -1
  69. package/dist/src/context/types.js +0 -3
  70. package/dist/src/context/types.js.map +0 -1
  71. package/dist/src/db/Replication.js +0 -90
  72. package/dist/src/db/Replication.js.map +0 -1
  73. package/dist/src/db/couch/DatabaseImpl.js +0 -475
  74. package/dist/src/db/couch/DatabaseImpl.js.map +0 -1
  75. package/dist/src/db/couch/connections.js +0 -101
  76. package/dist/src/db/couch/connections.js.map +0 -1
  77. package/dist/src/db/couch/index.js +0 -26
  78. package/dist/src/db/couch/index.js.map +0 -1
  79. package/dist/src/db/couch/pouchDB.js +0 -108
  80. package/dist/src/db/couch/pouchDB.js.map +0 -1
  81. package/dist/src/db/couch/pouchDump.js +0 -2
  82. package/dist/src/db/couch/pouchDump.js.map +0 -1
  83. package/dist/src/db/couch/utils.js +0 -60
  84. package/dist/src/db/couch/utils.js.map +0 -1
  85. package/dist/src/db/db.js +0 -47
  86. package/dist/src/db/db.js.map +0 -1
  87. package/dist/src/db/errors.js +0 -21
  88. package/dist/src/db/errors.js.map +0 -1
  89. package/dist/src/db/index.js +0 -58
  90. package/dist/src/db/index.js.map +0 -1
  91. package/dist/src/db/instrumentation.js +0 -202
  92. package/dist/src/db/instrumentation.js.map +0 -1
  93. package/dist/src/db/lucene.js +0 -638
  94. package/dist/src/db/lucene.js.map +0 -1
  95. package/dist/src/db/searchIndexes/index.js +0 -18
  96. package/dist/src/db/searchIndexes/index.js.map +0 -1
  97. package/dist/src/db/searchIndexes/searchIndexes.js +0 -76
  98. package/dist/src/db/searchIndexes/searchIndexes.js.map +0 -1
  99. package/dist/src/db/utils.js +0 -212
  100. package/dist/src/db/utils.js.map +0 -1
  101. package/dist/src/db/views.js +0 -224
  102. package/dist/src/db/views.js.map +0 -1
  103. package/dist/src/docIds/conversions.js +0 -62
  104. package/dist/src/docIds/conversions.js.map +0 -1
  105. package/dist/src/docIds/ids.js +0 -125
  106. package/dist/src/docIds/ids.js.map +0 -1
  107. package/dist/src/docIds/index.js +0 -19
  108. package/dist/src/docIds/index.js.map +0 -1
  109. package/dist/src/docIds/newid.js +0 -8
  110. package/dist/src/docIds/newid.js.map +0 -1
  111. package/dist/src/docIds/params.js +0 -141
  112. package/dist/src/docIds/params.js.map +0 -1
  113. package/dist/src/docUpdates/index.js +0 -35
  114. package/dist/src/docUpdates/index.js.map +0 -1
  115. package/dist/src/environment.js +0 -182
  116. package/dist/src/environment.js.map +0 -1
  117. package/dist/src/errors/errors.js +0 -97
  118. package/dist/src/errors/errors.js.map +0 -1
  119. package/dist/src/errors/index.js +0 -18
  120. package/dist/src/errors/index.js.map +0 -1
  121. package/dist/src/events/analytics.js +0 -52
  122. package/dist/src/events/analytics.js.map +0 -1
  123. package/dist/src/events/asyncEvents/index.js +0 -19
  124. package/dist/src/events/asyncEvents/index.js.map +0 -1
  125. package/dist/src/events/asyncEvents/publisher.js +0 -26
  126. package/dist/src/events/asyncEvents/publisher.js.map +0 -1
  127. package/dist/src/events/asyncEvents/queue.js +0 -26
  128. package/dist/src/events/asyncEvents/queue.js.map +0 -1
  129. package/dist/src/events/backfill.js +0 -189
  130. package/dist/src/events/backfill.js.map +0 -1
  131. package/dist/src/events/documentId.js +0 -27
  132. package/dist/src/events/documentId.js.map +0 -1
  133. package/dist/src/events/events.js +0 -87
  134. package/dist/src/events/events.js.map +0 -1
  135. package/dist/src/events/identification.js +0 -299
  136. package/dist/src/events/identification.js.map +0 -1
  137. package/dist/src/events/index.js +0 -59
  138. package/dist/src/events/index.js.map +0 -1
  139. package/dist/src/events/processors/AnalyticsProcessor.js +0 -103
  140. package/dist/src/events/processors/AnalyticsProcessor.js.map +0 -1
  141. package/dist/src/events/processors/AuditLogsProcessor.js +0 -86
  142. package/dist/src/events/processors/AuditLogsProcessor.js.map +0 -1
  143. package/dist/src/events/processors/LoggingProcessor.js +0 -47
  144. package/dist/src/events/processors/LoggingProcessor.js.map +0 -1
  145. package/dist/src/events/processors/Processors.js +0 -52
  146. package/dist/src/events/processors/Processors.js.map +0 -1
  147. package/dist/src/events/processors/async/DocumentUpdateProcessor.js +0 -44
  148. package/dist/src/events/processors/async/DocumentUpdateProcessor.js.map +0 -1
  149. package/dist/src/events/processors/index.js +0 -23
  150. package/dist/src/events/processors/index.js.map +0 -1
  151. package/dist/src/events/processors/posthog/PosthogProcessor.js +0 -149
  152. package/dist/src/events/processors/posthog/PosthogProcessor.js.map +0 -1
  153. package/dist/src/events/processors/posthog/index.js +0 -8
  154. package/dist/src/events/processors/posthog/index.js.map +0 -1
  155. package/dist/src/events/processors/posthog/rateLimiting.js +0 -129
  156. package/dist/src/events/processors/posthog/rateLimiting.js.map +0 -1
  157. package/dist/src/events/processors/types.js +0 -3
  158. package/dist/src/events/processors/types.js.map +0 -1
  159. package/dist/src/events/publishers/account.js +0 -43
  160. package/dist/src/events/publishers/account.js.map +0 -1
  161. package/dist/src/events/publishers/ai.js +0 -30
  162. package/dist/src/events/publishers/ai.js.map +0 -1
  163. package/dist/src/events/publishers/app.js +0 -166
  164. package/dist/src/events/publishers/app.js.map +0 -1
  165. package/dist/src/events/publishers/auditLog.js +0 -34
  166. package/dist/src/events/publishers/auditLog.js.map +0 -1
  167. package/dist/src/events/publishers/auth.js +0 -80
  168. package/dist/src/events/publishers/auth.js.map +0 -1
  169. package/dist/src/events/publishers/automation.js +0 -117
  170. package/dist/src/events/publishers/automation.js.map +0 -1
  171. package/dist/src/events/publishers/backfill.js +0 -85
  172. package/dist/src/events/publishers/backfill.js.map +0 -1
  173. package/dist/src/events/publishers/backup.js +0 -41
  174. package/dist/src/events/publishers/backup.js.map +0 -1
  175. package/dist/src/events/publishers/datasource.js +0 -54
  176. package/dist/src/events/publishers/datasource.js.map +0 -1
  177. package/dist/src/events/publishers/email.js +0 -30
  178. package/dist/src/events/publishers/email.js.map +0 -1
  179. package/dist/src/events/publishers/environmentVariable.js +0 -44
  180. package/dist/src/events/publishers/environmentVariable.js.map +0 -1
  181. package/dist/src/events/publishers/group.js +0 -107
  182. package/dist/src/events/publishers/group.js.map +0 -1
  183. package/dist/src/events/publishers/index.js +0 -57
  184. package/dist/src/events/publishers/index.js.map +0 -1
  185. package/dist/src/events/publishers/installation.js +0 -52
  186. package/dist/src/events/publishers/installation.js.map +0 -1
  187. package/dist/src/events/publishers/layout.js +0 -34
  188. package/dist/src/events/publishers/layout.js.map +0 -1
  189. package/dist/src/events/publishers/license.js +0 -77
  190. package/dist/src/events/publishers/license.js.map +0 -1
  191. package/dist/src/events/publishers/org.js +0 -52
  192. package/dist/src/events/publishers/org.js.map +0 -1
  193. package/dist/src/events/publishers/plugin.js +0 -55
  194. package/dist/src/events/publishers/plugin.js.map +0 -1
  195. package/dist/src/events/publishers/query.js +0 -74
  196. package/dist/src/events/publishers/query.js.map +0 -1
  197. package/dist/src/events/publishers/role.js +0 -69
  198. package/dist/src/events/publishers/role.js.map +0 -1
  199. package/dist/src/events/publishers/rows.js +0 -32
  200. package/dist/src/events/publishers/rows.js.map +0 -1
  201. package/dist/src/events/publishers/screen.js +0 -46
  202. package/dist/src/events/publishers/screen.js.map +0 -1
  203. package/dist/src/events/publishers/serve.js +0 -47
  204. package/dist/src/events/publishers/serve.js.map +0 -1
  205. package/dist/src/events/publishers/table.js +0 -77
  206. package/dist/src/events/publishers/table.js.map +0 -1
  207. package/dist/src/events/publishers/user.js +0 -201
  208. package/dist/src/events/publishers/user.js.map +0 -1
  209. package/dist/src/events/publishers/view.js +0 -111
  210. package/dist/src/events/publishers/view.js.map +0 -1
  211. package/dist/src/features/features.js +0 -271
  212. package/dist/src/features/features.js.map +0 -1
  213. package/dist/src/features/index.js +0 -42
  214. package/dist/src/features/index.js.map +0 -1
  215. package/dist/src/features/tests/utils.js +0 -56
  216. package/dist/src/features/tests/utils.js.map +0 -1
  217. package/dist/src/helpers.js +0 -13
  218. package/dist/src/helpers.js.map +0 -1
  219. package/dist/src/index.js +0 -99
  220. package/dist/src/index.js.map +0 -1
  221. package/dist/src/installation.js +0 -159
  222. package/dist/src/installation.js.map +0 -1
  223. package/dist/src/logging/alerts.js +0 -23
  224. package/dist/src/logging/alerts.js.map +0 -1
  225. package/dist/src/logging/correlation/correlation.js +0 -18
  226. package/dist/src/logging/correlation/correlation.js.map +0 -1
  227. package/dist/src/logging/correlation/index.js +0 -18
  228. package/dist/src/logging/correlation/index.js.map +0 -1
  229. package/dist/src/logging/correlation/middleware.js +0 -17
  230. package/dist/src/logging/correlation/middleware.js.map +0 -1
  231. package/dist/src/logging/index.js +0 -45
  232. package/dist/src/logging/index.js.map +0 -1
  233. package/dist/src/logging/pino/logger.js +0 -234
  234. package/dist/src/logging/pino/logger.js.map +0 -1
  235. package/dist/src/logging/pino/middleware.js +0 -46
  236. package/dist/src/logging/pino/middleware.js.map +0 -1
  237. package/dist/src/logging/system.js +0 -110
  238. package/dist/src/logging/system.js.map +0 -1
  239. package/dist/src/middleware/adminOnly.js +0 -19
  240. package/dist/src/middleware/adminOnly.js.map +0 -1
  241. package/dist/src/middleware/auditLog.js +0 -18
  242. package/dist/src/middleware/auditLog.js.map +0 -1
  243. package/dist/src/middleware/authenticated.js +0 -254
  244. package/dist/src/middleware/authenticated.js.map +0 -1
  245. package/dist/src/middleware/builderOnly.js +0 -33
  246. package/dist/src/middleware/builderOnly.js.map +0 -1
  247. package/dist/src/middleware/builderOrAdmin.js +0 -33
  248. package/dist/src/middleware/builderOrAdmin.js.map +0 -1
  249. package/dist/src/middleware/contentSecurityPolicy.js +0 -124
  250. package/dist/src/middleware/contentSecurityPolicy.js.map +0 -1
  251. package/dist/src/middleware/csrf.js +0 -81
  252. package/dist/src/middleware/csrf.js.map +0 -1
  253. package/dist/src/middleware/errorHandling.js +0 -88
  254. package/dist/src/middleware/errorHandling.js.map +0 -1
  255. package/dist/src/middleware/index.js +0 -79
  256. package/dist/src/middleware/index.js.map +0 -1
  257. package/dist/src/middleware/internalApi.js +0 -30
  258. package/dist/src/middleware/internalApi.js.map +0 -1
  259. package/dist/src/middleware/ip.js +0 -23
  260. package/dist/src/middleware/ip.js.map +0 -1
  261. package/dist/src/middleware/joi-validator.js +0 -53
  262. package/dist/src/middleware/joi-validator.js.map +0 -1
  263. package/dist/src/middleware/matchers.js +0 -36
  264. package/dist/src/middleware/matchers.js.map +0 -1
  265. package/dist/src/middleware/passport/datasource/google.js +0 -107
  266. package/dist/src/middleware/passport/datasource/google.js.map +0 -1
  267. package/dist/src/middleware/passport/local.js +0 -91
  268. package/dist/src/middleware/passport/local.js.map +0 -1
  269. package/dist/src/middleware/passport/sso/google.js +0 -98
  270. package/dist/src/middleware/passport/sso/google.js.map +0 -1
  271. package/dist/src/middleware/passport/sso/oidc.js +0 -158
  272. package/dist/src/middleware/passport/sso/oidc.js.map +0 -1
  273. package/dist/src/middleware/passport/sso/sso.js +0 -150
  274. package/dist/src/middleware/passport/sso/sso.js.map +0 -1
  275. package/dist/src/middleware/passport/utils.js +0 -75
  276. package/dist/src/middleware/passport/utils.js.map +0 -1
  277. package/dist/src/middleware/querystringToBody.js +0 -29
  278. package/dist/src/middleware/querystringToBody.js.map +0 -1
  279. package/dist/src/middleware/tenancy.js +0 -37
  280. package/dist/src/middleware/tenancy.js.map +0 -1
  281. package/dist/src/migrations/definitions.js +0 -39
  282. package/dist/src/migrations/definitions.js.map +0 -1
  283. package/dist/src/migrations/index.js +0 -19
  284. package/dist/src/migrations/index.js.map +0 -1
  285. package/dist/src/migrations/migrations.js +0 -203
  286. package/dist/src/migrations/migrations.js.map +0 -1
  287. package/dist/src/objectStore/buckets/app.js +0 -95
  288. package/dist/src/objectStore/buckets/app.js.map +0 -1
  289. package/dist/src/objectStore/buckets/global.js +0 -68
  290. package/dist/src/objectStore/buckets/global.js.map +0 -1
  291. package/dist/src/objectStore/buckets/index.js +0 -20
  292. package/dist/src/objectStore/buckets/index.js.map +0 -1
  293. package/dist/src/objectStore/buckets/plugins.js +0 -104
  294. package/dist/src/objectStore/buckets/plugins.js.map +0 -1
  295. package/dist/src/objectStore/cloudfront.js +0 -73
  296. package/dist/src/objectStore/cloudfront.js.map +0 -1
  297. package/dist/src/objectStore/index.js +0 -20
  298. package/dist/src/objectStore/index.js.map +0 -1
  299. package/dist/src/objectStore/objectStore.js +0 -509
  300. package/dist/src/objectStore/objectStore.js.map +0 -1
  301. package/dist/src/objectStore/utils.js +0 -148
  302. package/dist/src/objectStore/utils.js.map +0 -1
  303. package/dist/src/platform/index.js +0 -43
  304. package/dist/src/platform/index.js.map +0 -1
  305. package/dist/src/platform/platformDb.js +0 -9
  306. package/dist/src/platform/platformDb.js.map +0 -1
  307. package/dist/src/platform/tenants.js +0 -149
  308. package/dist/src/platform/tenants.js.map +0 -1
  309. package/dist/src/platform/users.js +0 -118
  310. package/dist/src/platform/users.js.map +0 -1
  311. package/dist/src/plugin/index.js +0 -18
  312. package/dist/src/plugin/index.js.map +0 -1
  313. package/dist/src/plugin/utils.js +0 -158
  314. package/dist/src/plugin/utils.js.map +0 -1
  315. package/dist/src/queue/constants.js +0 -13
  316. package/dist/src/queue/constants.js.map +0 -1
  317. package/dist/src/queue/inMemoryQueue.js +0 -192
  318. package/dist/src/queue/inMemoryQueue.js.map +0 -1
  319. package/dist/src/queue/index.js +0 -19
  320. package/dist/src/queue/index.js.map +0 -1
  321. package/dist/src/queue/listeners.js +0 -199
  322. package/dist/src/queue/listeners.js.map +0 -1
  323. package/dist/src/queue/queue.js +0 -124
  324. package/dist/src/queue/queue.js.map +0 -1
  325. package/dist/src/redis/index.js +0 -47
  326. package/dist/src/redis/index.js.map +0 -1
  327. package/dist/src/redis/init.js +0 -184
  328. package/dist/src/redis/init.js.map +0 -1
  329. package/dist/src/redis/redis.js +0 -396
  330. package/dist/src/redis/redis.js.map +0 -1
  331. package/dist/src/redis/redlockImpl.js +0 -181
  332. package/dist/src/redis/redlockImpl.js.map +0 -1
  333. package/dist/src/redis/utils.js +0 -131
  334. package/dist/src/redis/utils.js.map +0 -1
  335. package/dist/src/security/auth.js +0 -26
  336. package/dist/src/security/auth.js.map +0 -1
  337. package/dist/src/security/encryption.js +0 -169
  338. package/dist/src/security/encryption.js.map +0 -1
  339. package/dist/src/security/index.js +0 -18
  340. package/dist/src/security/index.js.map +0 -1
  341. package/dist/src/security/permissions.js +0 -147
  342. package/dist/src/security/permissions.js.map +0 -1
  343. package/dist/src/security/roles.js +0 -566
  344. package/dist/src/security/roles.js.map +0 -1
  345. package/dist/src/security/secrets.js +0 -53
  346. package/dist/src/security/secrets.js.map +0 -1
  347. package/dist/src/security/sessions.js +0 -156
  348. package/dist/src/security/sessions.js.map +0 -1
  349. package/dist/src/sql/designDoc.js +0 -19
  350. package/dist/src/sql/designDoc.js.map +0 -1
  351. package/dist/src/sql/index.js +0 -47
  352. package/dist/src/sql/index.js.map +0 -1
  353. package/dist/src/sql/sql.js +0 -1536
  354. package/dist/src/sql/sql.js.map +0 -1
  355. package/dist/src/sql/sqlTable.js +0 -256
  356. package/dist/src/sql/sqlTable.js.map +0 -1
  357. package/dist/src/sql/utils.js +0 -179
  358. package/dist/src/sql/utils.js.map +0 -1
  359. package/dist/src/tenancy/db.js +0 -9
  360. package/dist/src/tenancy/db.js.map +0 -1
  361. package/dist/src/tenancy/index.js +0 -19
  362. package/dist/src/tenancy/index.js.map +0 -1
  363. package/dist/src/tenancy/tenancy.js +0 -125
  364. package/dist/src/tenancy/tenancy.js.map +0 -1
  365. package/dist/src/timers/index.js +0 -18
  366. package/dist/src/timers/index.js.map +0 -1
  367. package/dist/src/timers/timers.js +0 -25
  368. package/dist/src/timers/timers.js.map +0 -1
  369. package/dist/src/users/db.js +0 -489
  370. package/dist/src/users/db.js.map +0 -1
  371. package/dist/src/users/events.js +0 -179
  372. package/dist/src/users/events.js.map +0 -1
  373. package/dist/src/users/index.js +0 -23
  374. package/dist/src/users/index.js.map +0 -1
  375. package/dist/src/users/lookup.js +0 -126
  376. package/dist/src/users/lookup.js.map +0 -1
  377. package/dist/src/users/users.js +0 -376
  378. package/dist/src/users/users.js.map +0 -1
  379. package/dist/src/users/utils.js +0 -127
  380. package/dist/src/users/utils.js.map +0 -1
  381. package/dist/src/utils/Duration.js +0 -54
  382. package/dist/src/utils/Duration.js.map +0 -1
  383. package/dist/src/utils/hashing.js +0 -46
  384. package/dist/src/utils/hashing.js.map +0 -1
  385. package/dist/src/utils/index.js +0 -21
  386. package/dist/src/utils/index.js.map +0 -1
  387. package/dist/src/utils/stringUtils.js +0 -8
  388. package/dist/src/utils/stringUtils.js.map +0 -1
  389. package/dist/src/utils/utils.js +0 -267
  390. package/dist/src/utils/utils.js.map +0 -1
  391. package/dist/tests/core/logging.js +0 -33
  392. package/dist/tests/core/logging.js.map +0 -1
  393. package/dist/tests/core/utilities/index.js +0 -48
  394. package/dist/tests/core/utilities/index.js.map +0 -1
  395. package/dist/tests/core/utilities/jestUtils.js +0 -21
  396. package/dist/tests/core/utilities/jestUtils.js.map +0 -1
  397. package/dist/tests/core/utilities/mocks/alerts.js +0 -40
  398. package/dist/tests/core/utilities/mocks/alerts.js.map +0 -1
  399. package/dist/tests/core/utilities/mocks/date.js +0 -6
  400. package/dist/tests/core/utilities/mocks/date.js.map +0 -1
  401. package/dist/tests/core/utilities/mocks/events.js +0 -154
  402. package/dist/tests/core/utilities/mocks/events.js.map +0 -1
  403. package/dist/tests/core/utilities/mocks/index.js +0 -47
  404. package/dist/tests/core/utilities/mocks/index.js.map +0 -1
  405. package/dist/tests/core/utilities/mocks/licenses.js +0 -109
  406. package/dist/tests/core/utilities/mocks/licenses.js.map +0 -1
  407. package/dist/tests/core/utilities/queue.js +0 -21
  408. package/dist/tests/core/utilities/queue.js.map +0 -1
  409. package/dist/tests/core/utilities/structures/Chance.js +0 -21
  410. package/dist/tests/core/utilities/structures/Chance.js.map +0 -1
  411. package/dist/tests/core/utilities/structures/accounts.js +0 -43
  412. package/dist/tests/core/utilities/structures/accounts.js.map +0 -1
  413. package/dist/tests/core/utilities/structures/apps.js +0 -23
  414. package/dist/tests/core/utilities/structures/apps.js.map +0 -1
  415. package/dist/tests/core/utilities/structures/common.js +0 -11
  416. package/dist/tests/core/utilities/structures/common.js.map +0 -1
  417. package/dist/tests/core/utilities/structures/db.js +0 -15
  418. package/dist/tests/core/utilities/structures/db.js.map +0 -1
  419. package/dist/tests/core/utilities/structures/documents/index.js +0 -18
  420. package/dist/tests/core/utilities/structures/documents/index.js.map +0 -1
  421. package/dist/tests/core/utilities/structures/documents/platform/index.js +0 -38
  422. package/dist/tests/core/utilities/structures/documents/platform/index.js.map +0 -1
  423. package/dist/tests/core/utilities/structures/documents/platform/installation.js +0 -47
  424. package/dist/tests/core/utilities/structures/documents/platform/installation.js.map +0 -1
  425. package/dist/tests/core/utilities/structures/generator.js +0 -9
  426. package/dist/tests/core/utilities/structures/generator.js.map +0 -1
  427. package/dist/tests/core/utilities/structures/index.js +0 -56
  428. package/dist/tests/core/utilities/structures/index.js.map +0 -1
  429. package/dist/tests/core/utilities/structures/koa.js +0 -10
  430. package/dist/tests/core/utilities/structures/koa.js.map +0 -1
  431. package/dist/tests/core/utilities/structures/licenses.js +0 -157
  432. package/dist/tests/core/utilities/structures/licenses.js.map +0 -1
  433. package/dist/tests/core/utilities/structures/plugins.js +0 -22
  434. package/dist/tests/core/utilities/structures/plugins.js.map +0 -1
  435. package/dist/tests/core/utilities/structures/quotas.js +0 -73
  436. package/dist/tests/core/utilities/structures/quotas.js.map +0 -1
  437. package/dist/tests/core/utilities/structures/scim.js +0 -62
  438. package/dist/tests/core/utilities/structures/scim.js.map +0 -1
  439. package/dist/tests/core/utilities/structures/sso.js +0 -140
  440. package/dist/tests/core/utilities/structures/sso.js.map +0 -1
  441. package/dist/tests/core/utilities/structures/tenants.js +0 -8
  442. package/dist/tests/core/utilities/structures/tenants.js.map +0 -1
  443. package/dist/tests/core/utilities/structures/userGroups.js +0 -12
  444. package/dist/tests/core/utilities/structures/userGroups.js.map +0 -1
  445. package/dist/tests/core/utilities/structures/users.js +0 -53
  446. package/dist/tests/core/utilities/structures/users.js.map +0 -1
  447. package/dist/tests/core/utilities/testContainerUtils.js +0 -161
  448. package/dist/tests/core/utilities/testContainerUtils.js.map +0 -1
  449. package/dist/tests/core/utilities/utils/index.js +0 -39
  450. package/dist/tests/core/utilities/utils/index.js.map +0 -1
  451. package/dist/tests/core/utilities/utils/queue.js +0 -37
  452. package/dist/tests/core/utilities/utils/queue.js.map +0 -1
  453. package/dist/tests/core/utilities/utils/time.js +0 -7
  454. package/dist/tests/core/utilities/utils/time.js.map +0 -1
  455. package/dist/tests/extra/DBTestConfiguration.js +0 -65
  456. package/dist/tests/extra/DBTestConfiguration.js.map +0 -1
  457. package/dist/tests/extra/index.js +0 -43
  458. package/dist/tests/extra/index.js.map +0 -1
  459. package/dist/tests/extra/testEnv.js +0 -136
  460. package/dist/tests/extra/testEnv.js.map +0 -1
  461. package/dist/tests/index.js +0 -19
  462. package/dist/tests/index.js.map +0 -1
  463. package/dist/tests/jestEnv.js +0 -12
  464. package/dist/tests/jestEnv.js.map +0 -1
  465. package/dist/tests/jestSetup.js +0 -33
  466. package/dist/tests/jestSetup.js.map +0 -1
@@ -1,1536 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
- var __importDefault = (this && this.__importDefault) || function (mod) {
45
- return (mod && mod.__esModule) ? mod : { "default": mod };
46
- };
47
- Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.COUNT_FIELD_NAME = void 0;
49
- const knex_1 = require("knex");
50
- const dbCore = __importStar(require("../db"));
51
- const utils_1 = require("./utils");
52
- const sqlTable_1 = __importDefault(require("./sqlTable"));
53
- const types_1 = require("@budibase/types");
54
- const environment_1 = __importDefault(require("../environment"));
55
- const shared_core_1 = require("@budibase/shared-core");
56
- const lodash_1 = require("lodash");
57
- exports.COUNT_FIELD_NAME = "__bb_total";
58
- function getBaseLimit() {
59
- const envLimit = environment_1.default.SQL_MAX_ROWS
60
- ? parseInt(environment_1.default.SQL_MAX_ROWS)
61
- : null;
62
- return envLimit || 5000;
63
- }
64
- function getRelationshipLimit() {
65
- const envLimit = environment_1.default.SQL_MAX_RELATED_ROWS
66
- ? parseInt(environment_1.default.SQL_MAX_RELATED_ROWS)
67
- : null;
68
- return envLimit || 500;
69
- }
70
- function prioritisedArraySort(toSort, priorities) {
71
- return toSort.sort((a, b) => {
72
- const aPriority = priorities.find(field => field && a.endsWith(field));
73
- const bPriority = priorities.find(field => field && b.endsWith(field));
74
- if (aPriority && !bPriority) {
75
- return -1;
76
- }
77
- if (!aPriority && bPriority) {
78
- return 1;
79
- }
80
- return a.localeCompare(b);
81
- });
82
- }
83
- function convertBooleans(query) {
84
- if (Array.isArray(query)) {
85
- return query.map((q) => convertBooleans(q));
86
- }
87
- else {
88
- if (query.bindings) {
89
- query.bindings = query.bindings.map(binding => {
90
- if (typeof binding === "boolean") {
91
- return binding ? 1 : 0;
92
- }
93
- return binding;
94
- });
95
- }
96
- }
97
- return query;
98
- }
99
- function isSqs(table) {
100
- return (table.sourceType === types_1.TableSourceType.INTERNAL ||
101
- table.sourceId === types_1.INTERNAL_TABLE_SOURCE_ID);
102
- }
103
- function escapeQuotes(value, quoteChar = '"') {
104
- return value.replace(new RegExp(quoteChar, "g"), `${quoteChar}${quoteChar}`);
105
- }
106
- function wrap(value, quoteChar = '"') {
107
- return `${quoteChar}${escapeQuotes(value, quoteChar)}${quoteChar}`;
108
- }
109
- function stringifyArray(value, quoteStyle = '"') {
110
- for (let i in value) {
111
- if (typeof value[i] === "string") {
112
- value[i] = wrap(value[i], quoteStyle);
113
- }
114
- }
115
- return `[${value.join(",")}]`;
116
- }
117
- const allowEmptyRelationships = {
118
- [types_1.BasicOperator.EQUAL]: false,
119
- [types_1.BasicOperator.NOT_EQUAL]: true,
120
- [types_1.BasicOperator.EMPTY]: false,
121
- [types_1.BasicOperator.NOT_EMPTY]: true,
122
- [types_1.BasicOperator.FUZZY]: false,
123
- [types_1.BasicOperator.STRING]: false,
124
- [types_1.RangeOperator.RANGE]: false,
125
- [types_1.ArrayOperator.CONTAINS]: false,
126
- [types_1.ArrayOperator.NOT_CONTAINS]: true,
127
- [types_1.ArrayOperator.CONTAINS_ANY]: false,
128
- [types_1.ArrayOperator.ONE_OF]: false,
129
- [types_1.LogicalOperator.AND]: false,
130
- [types_1.LogicalOperator.OR]: false,
131
- };
132
- class InternalBuilder {
133
- constructor(client, knex, query) {
134
- var _a;
135
- // states the various situations in which we need a full mapped select statement
136
- this.SPECIAL_SELECT_CASES = {
137
- POSTGRES_MONEY: (field) => {
138
- var _a;
139
- return (this.client === types_1.SqlClient.POSTGRES &&
140
- ((_a = field === null || field === void 0 ? void 0 : field.externalType) === null || _a === void 0 ? void 0 : _a.includes("money")));
141
- },
142
- MSSQL_DATES: (field) => {
143
- return (this.client === types_1.SqlClient.MS_SQL &&
144
- (field === null || field === void 0 ? void 0 : field.type) === types_1.FieldType.DATETIME &&
145
- field.timeOnly);
146
- },
147
- };
148
- this.client = client;
149
- this.query = query;
150
- this.knex = knex;
151
- this.splitter = new shared_core_1.dataFilters.ColumnSplitter([this.table], {
152
- aliases: this.query.tableAliases,
153
- columnPrefix: (_a = this.query.meta) === null || _a === void 0 ? void 0 : _a.columnPrefix,
154
- });
155
- }
156
- get table() {
157
- return this.query.table;
158
- }
159
- get knexClient() {
160
- return this.knex.client;
161
- }
162
- getFieldSchema(key) {
163
- const { column } = this.splitter.run(key);
164
- return this.table.schema[column];
165
- }
166
- quoteChars() {
167
- const wrapped = this.knexClient.wrapIdentifier("foo", {});
168
- return [wrapped[0], wrapped[wrapped.length - 1]];
169
- }
170
- // Takes a string like foo and returns a quoted string like [foo] for SQL
171
- // Server and "foo" for Postgres.
172
- quote(str) {
173
- return this.knexClient.wrapIdentifier(str, {});
174
- }
175
- isQuoted(key) {
176
- const [start, end] = this.quoteChars();
177
- return key.startsWith(start) && key.endsWith(end);
178
- }
179
- // Takes a string like a.b.c or an array like ["a", "b", "c"] and returns a
180
- // quoted identifier like [a].[b].[c] for SQL Server and `a`.`b`.`c` for
181
- // MySQL.
182
- quotedIdentifier(key) {
183
- if (!Array.isArray(key)) {
184
- key = this.splitIdentifier(key);
185
- }
186
- return key.map(part => this.quote(part)).join(".");
187
- }
188
- quotedValue(value) {
189
- const formatter = this.knexClient.formatter(this.knexClient.queryBuilder());
190
- return formatter.wrap(value, false);
191
- }
192
- castIntToString(identifier) {
193
- switch (this.client) {
194
- case types_1.SqlClient.ORACLE: {
195
- return this.knex.raw("to_char(??)", [identifier]);
196
- }
197
- case types_1.SqlClient.POSTGRES: {
198
- return this.knex.raw("??::TEXT", [identifier]);
199
- }
200
- case types_1.SqlClient.MY_SQL:
201
- case types_1.SqlClient.MARIADB: {
202
- return this.knex.raw("CAST(?? AS CHAR)", [identifier]);
203
- }
204
- case types_1.SqlClient.SQL_LITE: {
205
- // Technically sqlite can actually represent numbers larger than a 64bit
206
- // int as a string, but it does it using scientific notation (e.g.
207
- // "1e+20") which is not what we want. Given that the external SQL
208
- // databases are limited to supporting only 64bit ints, we settle for
209
- // that here.
210
- return this.knex.raw("printf('%d', ??)", [identifier]);
211
- }
212
- case types_1.SqlClient.MS_SQL: {
213
- return this.knex.raw("CONVERT(NVARCHAR, ??)", [identifier]);
214
- }
215
- }
216
- }
217
- // Unfortuantely we cannot rely on knex's identifier escaping because it trims
218
- // the identifier string before escaping it, which breaks cases for us where
219
- // columns that start or end with a space aren't referenced correctly anymore.
220
- //
221
- // So whenever you're using an identifier binding in knex, e.g. knex.raw("??
222
- // as ?", ["foo", "bar"]), you need to make sure you call this:
223
- //
224
- // knex.raw("?? as ?", [this.quotedIdentifier("foo"), "bar"])
225
- //
226
- // Issue we filed against knex about this:
227
- // https://github.com/knex/knex/issues/6143
228
- rawQuotedIdentifier(key) {
229
- return this.knex.raw(this.quotedIdentifier(key));
230
- }
231
- // Turns an identifier like a.b.c or `a`.`b`.`c` into ["a", "b", "c"]
232
- splitIdentifier(key) {
233
- const [start, end] = this.quoteChars();
234
- if (this.isQuoted(key)) {
235
- return key.slice(1, -1).split(`${end}.${start}`);
236
- }
237
- return key.split(".");
238
- }
239
- qualifyIdentifier(key) {
240
- const tableName = this.getTableName();
241
- const parts = this.splitIdentifier(key);
242
- if (parts[0] !== tableName) {
243
- parts.unshift(tableName);
244
- }
245
- if (this.isQuoted(key)) {
246
- return this.quotedIdentifier(parts);
247
- }
248
- return parts.join(".");
249
- }
250
- isFullSelectStatementRequired() {
251
- for (let column of Object.values(this.table.schema)) {
252
- if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(column)) {
253
- return true;
254
- }
255
- else if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(column)) {
256
- return true;
257
- }
258
- }
259
- return false;
260
- }
261
- generateSelectStatement() {
262
- const { table, resource } = this.query;
263
- if (!resource || !resource.fields || resource.fields.length === 0) {
264
- return "*";
265
- }
266
- const alias = this.getTableName(table);
267
- const schema = this.table.schema;
268
- if (!this.isFullSelectStatementRequired()) {
269
- return [this.knex.raw("??", [`${alias}.*`])];
270
- }
271
- // get just the fields for this table
272
- return resource.fields
273
- .map(field => {
274
- const parts = field.split(/\./g);
275
- let table = undefined;
276
- let column = parts[0];
277
- // Just a column name, e.g.: "column"
278
- if (parts.length > 1) {
279
- table = parts[0];
280
- column = parts.slice(1).join(".");
281
- }
282
- return { table, column, field };
283
- })
284
- .filter(({ table }) => !table || table === alias)
285
- .map(({ table, column, field }) => {
286
- const columnSchema = schema[column];
287
- if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(columnSchema)) {
288
- return this.knex.raw(`??::money::numeric as ??`, [
289
- this.rawQuotedIdentifier([table, column].join(".")),
290
- this.knex.raw(this.quote(field)),
291
- ]);
292
- }
293
- if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(columnSchema)) {
294
- // Time gets returned as timestamp from mssql, not matching the expected
295
- // HH:mm format
296
- // TODO: figure out how to express this safely without string
297
- // interpolation.
298
- return this.knex.raw(`CONVERT(varchar, ??, 108) as ??`, [
299
- this.rawQuotedIdentifier(field),
300
- this.knex.raw(this.quote(field)),
301
- ]);
302
- }
303
- if (table) {
304
- return this.rawQuotedIdentifier(`${table}.${column}`);
305
- }
306
- else {
307
- return this.rawQuotedIdentifier(field);
308
- }
309
- });
310
- }
311
- // OracleDB can't use character-large-objects (CLOBs) in WHERE clauses,
312
- // so when we use them we need to wrap them in to_char(). This function
313
- // converts a field name to the appropriate identifier.
314
- convertClobs(field, opts) {
315
- if (this.client !== types_1.SqlClient.ORACLE) {
316
- throw new Error("you've called convertClobs on a DB that's not Oracle, this is a mistake");
317
- }
318
- const parts = this.splitIdentifier(field);
319
- const col = parts.pop();
320
- const schema = this.table.schema[col];
321
- let identifier = this.rawQuotedIdentifier(field);
322
- if (schema.type === types_1.FieldType.STRING ||
323
- schema.type === types_1.FieldType.LONGFORM ||
324
- schema.type === types_1.FieldType.BB_REFERENCE_SINGLE ||
325
- schema.type === types_1.FieldType.BB_REFERENCE ||
326
- schema.type === types_1.FieldType.OPTIONS ||
327
- schema.type === types_1.FieldType.BARCODEQR) {
328
- if (opts === null || opts === void 0 ? void 0 : opts.forSelect) {
329
- identifier = this.knex.raw("to_char(??) as ??", [
330
- identifier,
331
- this.rawQuotedIdentifier(col),
332
- ]);
333
- }
334
- else {
335
- identifier = this.knex.raw("to_char(??)", [identifier]);
336
- }
337
- }
338
- return identifier;
339
- }
340
- parse(input, schema) {
341
- if (Array.isArray(input)) {
342
- return JSON.stringify(input);
343
- }
344
- if (input == undefined) {
345
- return null;
346
- }
347
- if (this.client === types_1.SqlClient.ORACLE &&
348
- schema.type === types_1.FieldType.DATETIME &&
349
- schema.timeOnly) {
350
- if (input instanceof Date) {
351
- const hours = input.getHours().toString().padStart(2, "0");
352
- const minutes = input.getMinutes().toString().padStart(2, "0");
353
- const seconds = input.getSeconds().toString().padStart(2, "0");
354
- return `${hours}:${minutes}:${seconds}`;
355
- }
356
- if (typeof input === "string") {
357
- return new Date(`1970-01-01T${input}Z`);
358
- }
359
- }
360
- if (typeof input === "string") {
361
- if ((0, utils_1.isInvalidISODateString)(input)) {
362
- return null;
363
- }
364
- if ((0, utils_1.isValidISODateString)(input)) {
365
- return new Date(input.trim());
366
- }
367
- }
368
- return input;
369
- }
370
- parseBody(body) {
371
- for (let [key, value] of Object.entries(body)) {
372
- const { column } = this.splitter.run(key);
373
- const schema = this.table.schema[column];
374
- if (!schema) {
375
- continue;
376
- }
377
- body[key] = this.parse(value, schema);
378
- }
379
- return body;
380
- }
381
- parseFilters(filters) {
382
- filters = (0, lodash_1.cloneDeep)(filters);
383
- for (const op of Object.values(types_1.BasicOperator)) {
384
- const filter = filters[op];
385
- if (!filter) {
386
- continue;
387
- }
388
- for (const key of Object.keys(filter)) {
389
- if (Array.isArray(filter[key])) {
390
- filter[key] = JSON.stringify(filter[key]);
391
- continue;
392
- }
393
- const { column } = this.splitter.run(key);
394
- const schema = this.table.schema[column];
395
- if (!schema) {
396
- continue;
397
- }
398
- filter[key] = this.parse(filter[key], schema);
399
- }
400
- }
401
- for (const op of Object.values(types_1.ArrayOperator)) {
402
- const filter = filters[op];
403
- if (!filter) {
404
- continue;
405
- }
406
- for (const key of Object.keys(filter)) {
407
- const { column } = this.splitter.run(key);
408
- const schema = this.table.schema[column];
409
- if (!schema) {
410
- continue;
411
- }
412
- filter[key] = filter[key].map(v => this.parse(v, schema));
413
- }
414
- }
415
- for (const op of Object.values(types_1.RangeOperator)) {
416
- const filter = filters[op];
417
- if (!filter) {
418
- continue;
419
- }
420
- for (const key of Object.keys(filter)) {
421
- const { column } = this.splitter.run(key);
422
- const schema = this.table.schema[column];
423
- if (!schema) {
424
- continue;
425
- }
426
- const value = filter[key];
427
- if ("low" in value) {
428
- value.low = this.parse(value.low, schema);
429
- }
430
- if ("high" in value) {
431
- value.high = this.parse(value.high, schema);
432
- }
433
- }
434
- }
435
- return filters;
436
- }
437
- addJoinFieldCheck(query, relationship) {
438
- var _a;
439
- const document = ((_a = relationship.from) === null || _a === void 0 ? void 0 : _a.split(".")[0]) || "";
440
- return query.andWhere(`${document}.fieldName`, "=", relationship.column);
441
- }
442
- addRelationshipForFilter(query, allowEmptyRelationships, filterKey, whereCb) {
443
- const { relationships, schema, tableAliases: aliases, table } = this.query;
444
- const fromAlias = (aliases === null || aliases === void 0 ? void 0 : aliases[table.name]) || table.name;
445
- const matches = (value) => filterKey.match(new RegExp(`^${value}\\.`));
446
- if (!relationships) {
447
- return query;
448
- }
449
- for (const relationship of relationships) {
450
- const relatedTableName = relationship.tableName;
451
- const toAlias = (aliases === null || aliases === void 0 ? void 0 : aliases[relatedTableName]) || relatedTableName;
452
- const matchesTableName = matches(relatedTableName) || matches(toAlias);
453
- const matchesRelationName = matches(relationship.column);
454
- // this is the relationship which is being filtered
455
- if ((matchesTableName || matchesRelationName) &&
456
- relationship.to &&
457
- relationship.tableName) {
458
- const joinTable = this.knex
459
- .select(this.knex.raw(1))
460
- .from({ [toAlias]: relatedTableName });
461
- let subQuery = joinTable.clone();
462
- const manyToMany = (0, utils_1.validateManyToMany)(relationship);
463
- let updatedKey;
464
- if (!matchesTableName) {
465
- updatedKey = filterKey.replace(new RegExp(`^${relationship.column}.`), `${(aliases === null || aliases === void 0 ? void 0 : aliases[relationship.tableName]) || relationship.tableName}.`);
466
- }
467
- else {
468
- updatedKey = filterKey;
469
- }
470
- if (manyToMany) {
471
- const throughAlias = (aliases === null || aliases === void 0 ? void 0 : aliases[manyToMany.through]) || relationship.through;
472
- let throughTable = this.tableNameWithSchema(manyToMany.through, {
473
- alias: throughAlias,
474
- schema,
475
- });
476
- subQuery = subQuery
477
- // add a join through the junction table
478
- .innerJoin(throughTable, function () {
479
- this.on(`${toAlias}.${manyToMany.toPrimary}`, "=", `${throughAlias}.${manyToMany.to}`);
480
- })
481
- // check the document in the junction table points to the main table
482
- .where(`${throughAlias}.${manyToMany.from}`, "=", this.rawQuotedIdentifier(`${fromAlias}.${manyToMany.fromPrimary}`));
483
- // in SQS the same junction table is used for different many-to-many relationships between the
484
- // two same tables, this is needed to avoid rows ending up in all columns
485
- if (this.client === types_1.SqlClient.SQL_LITE) {
486
- subQuery = this.addJoinFieldCheck(subQuery, manyToMany);
487
- }
488
- query = query.where(q => {
489
- q.whereExists(whereCb(updatedKey, subQuery));
490
- if (allowEmptyRelationships) {
491
- q.orWhereNotExists(joinTable.clone().innerJoin(throughTable, function () {
492
- this.on(`${fromAlias}.${manyToMany.fromPrimary}`, "=", `${throughAlias}.${manyToMany.from}`);
493
- }));
494
- }
495
- });
496
- }
497
- else {
498
- const toKey = `${toAlias}.${relationship.to}`;
499
- const foreignKey = `${fromAlias}.${relationship.from}`;
500
- // "join" to the main table, making sure the ID matches that of the main
501
- subQuery = subQuery.where(toKey, "=", this.rawQuotedIdentifier(foreignKey));
502
- query = query.where(q => {
503
- q.whereExists(whereCb(updatedKey, subQuery.clone()));
504
- if (allowEmptyRelationships) {
505
- q.orWhereNotExists(subQuery);
506
- }
507
- });
508
- }
509
- }
510
- }
511
- return query;
512
- }
513
- // right now we only do filters on the specific table being queried
514
- addFilters(query, filters, opts) {
515
- if (!filters) {
516
- return query;
517
- }
518
- const builder = this;
519
- filters = this.parseFilters(Object.assign({}, filters));
520
- const aliases = this.query.tableAliases;
521
- // if all or specified in filters, then everything is an or
522
- const shouldOr = filters.allOr;
523
- const isSqlite = this.client === types_1.SqlClient.SQL_LITE;
524
- const tableName = isSqlite ? this.table._id : this.table.name;
525
- function getTableAlias(name) {
526
- const alias = aliases === null || aliases === void 0 ? void 0 : aliases[name];
527
- return alias || name;
528
- }
529
- function iterate(structure, operation, fn, complexKeyFn) {
530
- const handleRelationship = (q, key, value) => {
531
- const [filterTableName, ...otherProperties] = key.split(".");
532
- const property = otherProperties.join(".");
533
- const alias = getTableAlias(filterTableName);
534
- return q.andWhere(subquery => fn(subquery, alias ? `${alias}.${property}` : property, value));
535
- };
536
- for (const key in structure) {
537
- const value = structure[key];
538
- const updatedKey = dbCore.removeKeyNumbering(key);
539
- const isRelationshipField = updatedKey.includes(".");
540
- const shouldProcessRelationship = (opts === null || opts === void 0 ? void 0 : opts.relationship) && isRelationshipField;
541
- let castedTypeValue;
542
- if (key === types_1.InternalSearchFilterOperator.COMPLEX_ID_OPERATOR &&
543
- (castedTypeValue = structure[key]) &&
544
- complexKeyFn) {
545
- const alias = getTableAlias(tableName);
546
- query = complexKeyFn(query, castedTypeValue.id.map((x) => alias ? `${alias}.${x}` : x), castedTypeValue.values);
547
- }
548
- else if (!isRelationshipField) {
549
- const alias = getTableAlias(tableName);
550
- query = fn(query, alias ? `${alias}.${updatedKey}` : updatedKey, value);
551
- }
552
- else if (shouldProcessRelationship) {
553
- if (shouldOr) {
554
- query = query.or;
555
- }
556
- query = builder.addRelationshipForFilter(query, allowEmptyRelationships[operation], updatedKey, (updatedKey, q) => {
557
- return handleRelationship(q, updatedKey, value);
558
- });
559
- }
560
- }
561
- }
562
- const like = (q, key, value) => {
563
- if ((filters === null || filters === void 0 ? void 0 : filters.fuzzyOr) || shouldOr) {
564
- q = q.or;
565
- }
566
- if (this.client === types_1.SqlClient.ORACLE ||
567
- this.client === types_1.SqlClient.SQL_LITE) {
568
- return q.whereRaw(`LOWER(??) LIKE ?`, [
569
- this.rawQuotedIdentifier(key),
570
- `%${value.toLowerCase()}%`,
571
- ]);
572
- }
573
- return q.whereILike(
574
- // @ts-expect-error knex types are wrong, raw is fine here
575
- this.rawQuotedIdentifier(key), this.knex.raw("?", [`%${value}%`]));
576
- };
577
- const contains = (mode, any = false) => {
578
- function addModifiers(q) {
579
- if (shouldOr || mode === (filters === null || filters === void 0 ? void 0 : filters.containsAny)) {
580
- q = q.or;
581
- }
582
- if (mode === (filters === null || filters === void 0 ? void 0 : filters.notContains)) {
583
- q = q.not;
584
- }
585
- return q;
586
- }
587
- if (this.client === types_1.SqlClient.POSTGRES) {
588
- iterate(mode, types_1.ArrayOperator.CONTAINS, (q, key, value) => {
589
- q = addModifiers(q);
590
- if (any) {
591
- return q.whereRaw(`COALESCE(??::jsonb \\?| array??, FALSE)`, [
592
- this.rawQuotedIdentifier(key),
593
- this.knex.raw(stringifyArray(value, "'")),
594
- ]);
595
- }
596
- else {
597
- return q.whereRaw(`COALESCE(??::jsonb @> '??', FALSE)`, [
598
- this.rawQuotedIdentifier(key),
599
- this.knex.raw(stringifyArray(value)),
600
- ]);
601
- }
602
- });
603
- }
604
- else if (this.client === types_1.SqlClient.MY_SQL ||
605
- this.client === types_1.SqlClient.MARIADB) {
606
- iterate(mode, types_1.ArrayOperator.CONTAINS, (q, key, value) => {
607
- return addModifiers(q).whereRaw(`COALESCE(?(??, ?), FALSE)`, [
608
- this.knex.raw(any ? "JSON_OVERLAPS" : "JSON_CONTAINS"),
609
- this.rawQuotedIdentifier(key),
610
- this.knex.raw(wrap(stringifyArray(value))),
611
- ]);
612
- });
613
- }
614
- else {
615
- iterate(mode, types_1.ArrayOperator.CONTAINS, (q, key, value) => {
616
- if (value.length === 0) {
617
- return q;
618
- }
619
- q = q.where(subQuery => {
620
- if (mode === (filters === null || filters === void 0 ? void 0 : filters.notContains)) {
621
- subQuery = subQuery.not;
622
- }
623
- subQuery = subQuery.where(subSubQuery => {
624
- for (const elem of value) {
625
- if (mode === (filters === null || filters === void 0 ? void 0 : filters.containsAny)) {
626
- subSubQuery = subSubQuery.or;
627
- }
628
- else {
629
- subSubQuery = subSubQuery.and;
630
- }
631
- const lower = typeof elem === "string" ? `"${elem.toLowerCase()}"` : elem;
632
- subSubQuery = subSubQuery.whereLike(
633
- // @ts-expect-error knex types are wrong, raw is fine here
634
- this.knex.raw(`COALESCE(LOWER(??), '')`, [
635
- this.rawQuotedIdentifier(key),
636
- ]), `%${lower}%`);
637
- }
638
- });
639
- if (mode === (filters === null || filters === void 0 ? void 0 : filters.notContains)) {
640
- subQuery = subQuery.or.whereNull(
641
- // @ts-expect-error knex types are wrong, raw is fine here
642
- this.rawQuotedIdentifier(key));
643
- }
644
- return subQuery;
645
- });
646
- return q;
647
- });
648
- }
649
- };
650
- if (filters.$and) {
651
- const { $and } = filters;
652
- for (const condition of $and.conditions) {
653
- query = query.where(b => {
654
- this.addFilters(b, condition, opts);
655
- });
656
- }
657
- }
658
- if (filters.$or) {
659
- const { $or } = filters;
660
- query = query.where(b => {
661
- for (const condition of $or.conditions) {
662
- b.orWhere(c => this.addFilters(c, Object.assign(Object.assign({}, condition), { allOr: true }), opts));
663
- }
664
- });
665
- }
666
- if (filters.oneOf) {
667
- iterate(filters.oneOf, types_1.ArrayOperator.ONE_OF, (q, key, array) => {
668
- if (shouldOr) {
669
- q = q.or;
670
- }
671
- if (this.client === types_1.SqlClient.ORACLE) {
672
- // @ts-ignore
673
- key = this.convertClobs(key);
674
- }
675
- return q.whereIn(key, Array.isArray(array) ? array : [array]);
676
- }, (q, key, array) => {
677
- if (shouldOr) {
678
- q = q.or;
679
- }
680
- if (this.client === types_1.SqlClient.ORACLE) {
681
- // @ts-ignore
682
- key = key.map(k => this.convertClobs(k));
683
- }
684
- return q.whereIn(key, Array.isArray(array) ? array : [array]);
685
- });
686
- }
687
- if (filters.string) {
688
- iterate(filters.string, types_1.BasicOperator.STRING, (q, key, value) => {
689
- if (shouldOr) {
690
- q = q.or;
691
- }
692
- if (this.client === types_1.SqlClient.ORACLE ||
693
- this.client === types_1.SqlClient.SQL_LITE) {
694
- return q.whereRaw(`LOWER(??) LIKE ?`, [
695
- this.rawQuotedIdentifier(key),
696
- `${value.toLowerCase()}%`,
697
- ]);
698
- }
699
- else {
700
- return q.whereILike(key, `${value}%`);
701
- }
702
- });
703
- }
704
- if (filters.fuzzy) {
705
- iterate(filters.fuzzy, types_1.BasicOperator.FUZZY, like);
706
- }
707
- if (filters.range) {
708
- iterate(filters.range, types_1.RangeOperator.RANGE, (q, key, value) => {
709
- const isEmptyObject = (val) => {
710
- return (val &&
711
- Object.keys(val).length === 0 &&
712
- Object.getPrototypeOf(val) === Object.prototype);
713
- };
714
- if (isEmptyObject(value.low)) {
715
- value.low = "";
716
- }
717
- if (isEmptyObject(value.high)) {
718
- value.high = "";
719
- }
720
- const lowValid = (0, utils_1.isValidFilter)(value.low), highValid = (0, utils_1.isValidFilter)(value.high);
721
- const schema = this.getFieldSchema(key);
722
- let rawKey = key;
723
- let high = value.high;
724
- let low = value.low;
725
- if (this.client === types_1.SqlClient.ORACLE) {
726
- rawKey = this.convertClobs(key);
727
- }
728
- else if (this.client === types_1.SqlClient.SQL_LITE &&
729
- (schema === null || schema === void 0 ? void 0 : schema.type) === types_1.FieldType.BIGINT) {
730
- rawKey = this.knex.raw("CAST(?? AS INTEGER)", [
731
- this.rawQuotedIdentifier(key),
732
- ]);
733
- high = this.knex.raw("CAST(? AS INTEGER)", [value.high]);
734
- low = this.knex.raw("CAST(? AS INTEGER)", [value.low]);
735
- }
736
- if (shouldOr) {
737
- q = q.or;
738
- }
739
- if (lowValid && highValid) {
740
- // @ts-expect-error knex types are wrong, raw is fine here
741
- return q.whereBetween(rawKey, [low, high]);
742
- }
743
- else if (lowValid) {
744
- // @ts-expect-error knex types are wrong, raw is fine here
745
- return q.where(rawKey, ">=", low);
746
- }
747
- else if (highValid) {
748
- // @ts-expect-error knex types are wrong, raw is fine here
749
- return q.where(rawKey, "<=", high);
750
- }
751
- return q;
752
- });
753
- }
754
- if (filters.equal) {
755
- iterate(filters.equal, types_1.BasicOperator.EQUAL, (q, key, value) => {
756
- if (shouldOr) {
757
- q = q.or;
758
- }
759
- if (this.client === types_1.SqlClient.MS_SQL) {
760
- return q.whereRaw(`CASE WHEN ?? = ? THEN 1 ELSE 0 END = 1`, [
761
- this.rawQuotedIdentifier(key),
762
- value,
763
- ]);
764
- }
765
- else if (this.client === types_1.SqlClient.ORACLE) {
766
- const identifier = this.convertClobs(key);
767
- return q.where(subq =>
768
- // @ts-expect-error knex types are wrong, raw is fine here
769
- subq.whereNotNull(identifier).andWhere(identifier, value));
770
- }
771
- else {
772
- return q.whereRaw(`COALESCE(?? = ?, FALSE)`, [
773
- this.rawQuotedIdentifier(key),
774
- value,
775
- ]);
776
- }
777
- });
778
- }
779
- if (filters.notEqual) {
780
- iterate(filters.notEqual, types_1.BasicOperator.NOT_EQUAL, (q, key, value) => {
781
- if (shouldOr) {
782
- q = q.or;
783
- }
784
- if (this.client === types_1.SqlClient.MS_SQL) {
785
- return q.whereRaw(`CASE WHEN ?? = ? THEN 1 ELSE 0 END = 0`, [
786
- this.rawQuotedIdentifier(key),
787
- value,
788
- ]);
789
- }
790
- else if (this.client === types_1.SqlClient.ORACLE) {
791
- const identifier = this.convertClobs(key);
792
- return (q
793
- .where(subq => subq.not
794
- // @ts-expect-error knex types are wrong, raw is fine here
795
- .whereNull(identifier)
796
- .and.where(identifier, "!=", value))
797
- // @ts-expect-error knex types are wrong, raw is fine here
798
- .or.whereNull(identifier));
799
- }
800
- else {
801
- return q.whereRaw(`COALESCE(?? != ?, TRUE)`, [
802
- this.rawQuotedIdentifier(key),
803
- value,
804
- ]);
805
- }
806
- });
807
- }
808
- if (filters.empty) {
809
- iterate(filters.empty, types_1.BasicOperator.EMPTY, (q, key) => {
810
- if (shouldOr) {
811
- q = q.or;
812
- }
813
- return q.whereNull(key);
814
- });
815
- }
816
- if (filters.notEmpty) {
817
- iterate(filters.notEmpty, types_1.BasicOperator.NOT_EMPTY, (q, key) => {
818
- if (shouldOr) {
819
- q = q.or;
820
- }
821
- return q.whereNotNull(key);
822
- });
823
- }
824
- if (filters.contains) {
825
- contains(filters.contains);
826
- }
827
- if (filters.notContains) {
828
- contains(filters.notContains);
829
- }
830
- if (filters.containsAny) {
831
- contains(filters.containsAny, true);
832
- }
833
- const tableRef = (aliases === null || aliases === void 0 ? void 0 : aliases[this.table._id]) || this.table._id;
834
- // when searching internal tables make sure long looking for rows
835
- if (filters.documentType && !(0, utils_1.isExternalTable)(this.table) && tableRef) {
836
- // has to be its own option, must always be AND onto the search
837
- query.andWhereLike(`${tableRef}._id`, `${(0, types_1.prefixed)(filters.documentType)}%`);
838
- }
839
- return query;
840
- }
841
- isSqs() {
842
- return isSqs(this.table);
843
- }
844
- getTableName(table) {
845
- if (!table) {
846
- table = this.table;
847
- }
848
- let name = table.name;
849
- if (isSqs(table) && table._id) {
850
- // SQS uses the table ID rather than the table name
851
- name = table._id;
852
- }
853
- const aliases = this.query.tableAliases || {};
854
- return aliases[name] ? aliases[name] : name;
855
- }
856
- addDistinctCount(query) {
857
- if (!this.table.primary) {
858
- throw new Error("SQL counting requires primary key to be supplied");
859
- }
860
- return query.countDistinct(`${this.getTableName()}.${this.table.primary[0]} as ${exports.COUNT_FIELD_NAME}`);
861
- }
862
- addAggregations(query, aggregations) {
863
- var _a;
864
- const fields = ((_a = this.query.resource) === null || _a === void 0 ? void 0 : _a.fields) || [];
865
- const tableName = this.getTableName();
866
- if (fields.length > 0) {
867
- const qualifiedFields = fields.map(field => this.qualifyIdentifier(field));
868
- if (this.client === types_1.SqlClient.ORACLE) {
869
- const groupByFields = qualifiedFields.map(field => this.convertClobs(field));
870
- const selectFields = qualifiedFields.map(field => this.convertClobs(field, { forSelect: true }));
871
- query = query.groupBy(groupByFields).select(selectFields);
872
- }
873
- else {
874
- query = query.groupBy(qualifiedFields).select(qualifiedFields);
875
- }
876
- }
877
- for (const aggregation of aggregations) {
878
- const op = aggregation.calculationType;
879
- if (op === types_1.CalculationType.COUNT) {
880
- if ("distinct" in aggregation && aggregation.distinct) {
881
- if (this.client === types_1.SqlClient.ORACLE) {
882
- const field = this.convertClobs(`${tableName}.${aggregation.field}`);
883
- query = query.select(this.knex.raw(`COUNT(DISTINCT ??) as ??`, [
884
- field,
885
- aggregation.name,
886
- ]));
887
- }
888
- else {
889
- query = query.countDistinct(`${tableName}.${aggregation.field} as ${aggregation.name}`);
890
- }
891
- }
892
- else {
893
- if (this.client === types_1.SqlClient.ORACLE) {
894
- const field = this.convertClobs(`${tableName}.${aggregation.field}`);
895
- query = query.select(this.knex.raw(`COUNT(??) as ??`, [field, aggregation.name]));
896
- }
897
- else {
898
- query = query.count(`${aggregation.field} as ${aggregation.name}`);
899
- }
900
- }
901
- }
902
- else {
903
- const fieldSchema = this.getFieldSchema(aggregation.field);
904
- if (!fieldSchema) {
905
- // This should not happen in practice.
906
- throw new Error(`field schema missing for aggregation target: ${aggregation.field}`);
907
- }
908
- let aggregate = this.knex.raw("??(??)", [
909
- this.knex.raw(op),
910
- this.rawQuotedIdentifier(`${tableName}.${aggregation.field}`),
911
- ]);
912
- if (fieldSchema.type === types_1.FieldType.BIGINT) {
913
- aggregate = this.castIntToString(aggregate);
914
- }
915
- query = query.select(this.knex.raw("?? as ??", [aggregate, aggregation.name]));
916
- }
917
- }
918
- return query;
919
- }
920
- isAggregateField(field) {
921
- var _a, _b;
922
- const found = (_b = (_a = this.query.resource) === null || _a === void 0 ? void 0 : _a.aggregations) === null || _b === void 0 ? void 0 : _b.find(aggregation => aggregation.name === field);
923
- return !!found;
924
- }
925
- addSorting(query) {
926
- var _a, _b;
927
- let { sort, resource } = this.query;
928
- const primaryKey = this.table.primary;
929
- const aliased = this.getTableName();
930
- if (!Array.isArray(primaryKey)) {
931
- throw new Error("Sorting requires primary key to be specified for table");
932
- }
933
- if (sort && Object.keys(sort || {}).length > 0) {
934
- for (let [key, value] of Object.entries(sort)) {
935
- const direction = value.direction === types_1.SortOrder.ASCENDING ? "asc" : "desc";
936
- // TODO: figure out a way to remove this conditional, not relying on
937
- // the defaults of each datastore.
938
- let nulls = undefined;
939
- if (this.client === types_1.SqlClient.POSTGRES ||
940
- this.client === types_1.SqlClient.ORACLE) {
941
- nulls = value.direction === types_1.SortOrder.ASCENDING ? "first" : "last";
942
- }
943
- if (this.isAggregateField(key)) {
944
- query = query.orderBy(key, direction, nulls);
945
- }
946
- else {
947
- let composite = `${aliased}.${key}`;
948
- if (this.client === types_1.SqlClient.ORACLE) {
949
- query = query.orderByRaw(`?? ?? nulls ??`, [
950
- this.convertClobs(composite),
951
- this.knex.raw(direction),
952
- this.knex.raw(nulls),
953
- ]);
954
- }
955
- else {
956
- query = query.orderBy(composite, direction, nulls);
957
- }
958
- }
959
- }
960
- }
961
- // add sorting by the primary key if the result isn't already sorted by it,
962
- // to make sure result is deterministic
963
- const hasAggregations = ((_b = (_a = resource === null || resource === void 0 ? void 0 : resource.aggregations) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
964
- if (!hasAggregations && (!sort || sort[primaryKey[0]] === undefined)) {
965
- query = query.orderBy(`${aliased}.${primaryKey[0]}`);
966
- }
967
- return query;
968
- }
969
- tableNameWithSchema(tableName, opts) {
970
- let withSchema = (opts === null || opts === void 0 ? void 0 : opts.schema) ? `${opts.schema}.${tableName}` : tableName;
971
- if (opts === null || opts === void 0 ? void 0 : opts.alias) {
972
- withSchema += ` as ${opts.alias}`;
973
- }
974
- return withSchema;
975
- }
976
- buildJsonField(table, field) {
977
- var _a;
978
- const parts = field.split(".");
979
- let baseName = parts[parts.length - 1];
980
- let unaliased;
981
- let tableField;
982
- if (parts.length > 1) {
983
- const alias = parts.shift();
984
- unaliased = parts.join(".");
985
- tableField = `${alias}.${unaliased}`;
986
- }
987
- else {
988
- unaliased = parts.join(".");
989
- tableField = unaliased;
990
- }
991
- if ((_a = this.query.meta) === null || _a === void 0 ? void 0 : _a.columnPrefix) {
992
- baseName = baseName.replace(this.query.meta.columnPrefix, "");
993
- }
994
- let identifier = this.rawQuotedIdentifier(tableField);
995
- // Internal tables have special _id, _rev, createdAt, and updatedAt fields
996
- // that do not appear in the schema, meaning schema could actually be
997
- // undefined.
998
- const schema = table.schema[baseName];
999
- if (schema && schema.type === types_1.FieldType.BIGINT) {
1000
- identifier = this.castIntToString(identifier);
1001
- }
1002
- return [unaliased, identifier];
1003
- }
1004
- maxFunctionParameters() {
1005
- // functions like say json_build_object() in SQL have a limit as to how many can be performed
1006
- // before a limit is met, this limit exists in Postgres/SQLite. This can be very important, such as
1007
- // for JSON column building as part of relationships. We also have a default limit to avoid very complex
1008
- // functions being built - it is likely this is not necessary or the best way to do it.
1009
- switch (this.client) {
1010
- case types_1.SqlClient.SQL_LITE:
1011
- return 127;
1012
- case types_1.SqlClient.POSTGRES:
1013
- return 100;
1014
- // other DBs don't have a limit, but set some sort of limit
1015
- default:
1016
- return 200;
1017
- }
1018
- }
1019
- addJsonRelationships(query, fromTable, relationships) {
1020
- const sqlClient = this.client;
1021
- const knex = this.knex;
1022
- const { resource, tableAliases: aliases, schema, tables } = this.query;
1023
- const fields = (resource === null || resource === void 0 ? void 0 : resource.fields) || [];
1024
- for (let relationship of relationships) {
1025
- const { tableName: toTable, through: throughTable, to: toKey, from: fromKey, fromPrimary, toPrimary, } = relationship;
1026
- // skip invalid relationships
1027
- if (!toTable || !fromTable) {
1028
- continue;
1029
- }
1030
- const relatedTable = tables[toTable];
1031
- if (!relatedTable) {
1032
- throw new Error(`related table "${toTable}" not found in datasource`);
1033
- }
1034
- const toAlias = (aliases === null || aliases === void 0 ? void 0 : aliases[toTable]) || toTable, fromAlias = (aliases === null || aliases === void 0 ? void 0 : aliases[fromTable]) || fromTable, throughAlias = (throughTable && (aliases === null || aliases === void 0 ? void 0 : aliases[throughTable])) || throughTable;
1035
- let toTableWithSchema = this.tableNameWithSchema(toTable, {
1036
- alias: toAlias,
1037
- schema,
1038
- });
1039
- const requiredFields = [
1040
- ...((relatedTable === null || relatedTable === void 0 ? void 0 : relatedTable.primary) || []),
1041
- relatedTable === null || relatedTable === void 0 ? void 0 : relatedTable.primaryDisplay,
1042
- ].filter(field => field);
1043
- // sort the required fields to first in the list, so they don't get sliced out
1044
- let relationshipFields = prioritisedArraySort(fields.filter(field => field.split(".")[0] === toAlias), requiredFields);
1045
- relationshipFields = relationshipFields.slice(0, Math.floor(this.maxFunctionParameters() / 2));
1046
- const fieldList = relationshipFields.map(field => this.buildJsonField(relatedTable, field));
1047
- const fieldListFormatted = fieldList
1048
- .map(f => {
1049
- const separator = this.client === types_1.SqlClient.ORACLE ? " VALUE " : ",";
1050
- return this.knex.raw(`?${separator}??`, [f[0], f[1]]).toString();
1051
- })
1052
- .join(",");
1053
- // SQL Server uses TOP - which performs a little differently to the normal LIMIT syntax
1054
- // it reduces the result set rather than limiting how much data it filters over
1055
- const primaryKey = `${toAlias}.${toPrimary || toKey}`;
1056
- let subQuery = knex
1057
- .from(toTableWithSchema)
1058
- // add sorting to get consistent order
1059
- .orderBy(primaryKey);
1060
- const isManyToMany = throughTable && toPrimary && fromPrimary;
1061
- let correlatedTo = isManyToMany
1062
- ? `${throughAlias}.${fromKey}`
1063
- : `${toAlias}.${toKey}`, correlatedFrom = isManyToMany
1064
- ? `${fromAlias}.${fromPrimary}`
1065
- : `${fromAlias}.${fromKey}`;
1066
- // many-to-many relationship needs junction table join
1067
- if (isManyToMany) {
1068
- let throughTableWithSchema = this.tableNameWithSchema(throughTable, {
1069
- alias: throughAlias,
1070
- schema,
1071
- });
1072
- subQuery = subQuery.join(throughTableWithSchema, function () {
1073
- this.on(`${toAlias}.${toPrimary}`, "=", `${throughAlias}.${toKey}`);
1074
- });
1075
- }
1076
- // add the correlation to the overall query
1077
- subQuery = subQuery.where(correlatedTo, "=", this.rawQuotedIdentifier(correlatedFrom));
1078
- const standardWrap = (select) => {
1079
- subQuery = subQuery.select(`${toAlias}.*`).limit(getRelationshipLimit());
1080
- // @ts-ignore - the from alias syntax isn't in Knex typing
1081
- return knex.select(select).from({
1082
- [toAlias]: subQuery,
1083
- });
1084
- };
1085
- let wrapperQuery;
1086
- switch (sqlClient) {
1087
- case types_1.SqlClient.SQL_LITE:
1088
- // need to check the junction table document is to the right column, this is just for SQS
1089
- subQuery = this.addJoinFieldCheck(subQuery, relationship);
1090
- wrapperQuery = standardWrap(this.knex.raw(`json_group_array(json_object(${fieldListFormatted}))`));
1091
- break;
1092
- case types_1.SqlClient.POSTGRES:
1093
- wrapperQuery = standardWrap(this.knex.raw(`json_agg(json_build_object(${fieldListFormatted}))`));
1094
- break;
1095
- case types_1.SqlClient.MARIADB:
1096
- // can't use the standard wrap due to correlated sub-query limitations in MariaDB
1097
- wrapperQuery = subQuery.select(knex.raw(`json_arrayagg(json_object(${fieldListFormatted}) LIMIT ${getRelationshipLimit()})`));
1098
- break;
1099
- case types_1.SqlClient.MY_SQL:
1100
- case types_1.SqlClient.ORACLE:
1101
- wrapperQuery = standardWrap(this.knex.raw(`json_arrayagg(json_object(${fieldListFormatted}))`));
1102
- break;
1103
- case types_1.SqlClient.MS_SQL: {
1104
- const comparatorQuery = knex
1105
- .select(`*`)
1106
- // @ts-ignore - from alias syntax not TS supported
1107
- .from({
1108
- [fromAlias]: subQuery
1109
- .select(fieldList.map(f => {
1110
- // @ts-expect-error raw is fine here, knex types are wrong
1111
- return knex.ref(f[1]).as(f[0]);
1112
- }))
1113
- .limit(getRelationshipLimit()),
1114
- });
1115
- wrapperQuery = knex.raw(`(SELECT ?? = (${comparatorQuery} FOR JSON PATH))`, [this.rawQuotedIdentifier(toAlias)]);
1116
- break;
1117
- }
1118
- default:
1119
- throw new Error(`JSON relationships not implement for ${sqlClient}`);
1120
- }
1121
- query = query.select({ [relationship.column]: wrapperQuery });
1122
- }
1123
- return query;
1124
- }
1125
- addJoin(query, tables, columns) {
1126
- const { tableAliases: aliases, schema } = this.query;
1127
- const toTable = tables.to, fromTable = tables.from, throughTable = tables.through;
1128
- const toAlias = (aliases === null || aliases === void 0 ? void 0 : aliases[toTable]) || toTable, throughAlias = (throughTable && (aliases === null || aliases === void 0 ? void 0 : aliases[throughTable])) || throughTable, fromAlias = (aliases === null || aliases === void 0 ? void 0 : aliases[fromTable]) || fromTable;
1129
- let toTableWithSchema = this.tableNameWithSchema(toTable, {
1130
- alias: toAlias,
1131
- schema,
1132
- });
1133
- let throughTableWithSchema = throughTable
1134
- ? this.tableNameWithSchema(throughTable, {
1135
- alias: throughAlias,
1136
- schema,
1137
- })
1138
- : undefined;
1139
- if (!throughTable) {
1140
- query = query.leftJoin(toTableWithSchema, function () {
1141
- for (let relationship of columns) {
1142
- const from = relationship.from, to = relationship.to;
1143
- this.orOn(`${fromAlias}.${from}`, "=", `${toAlias}.${to}`);
1144
- }
1145
- });
1146
- }
1147
- else {
1148
- query = query
1149
- // @ts-ignore
1150
- .leftJoin(throughTableWithSchema, function () {
1151
- for (let relationship of columns) {
1152
- const fromPrimary = relationship.fromPrimary;
1153
- const from = relationship.from;
1154
- this.orOn(`${fromAlias}.${fromPrimary}`, "=", `${throughAlias}.${from}`);
1155
- }
1156
- })
1157
- .leftJoin(toTableWithSchema, function () {
1158
- for (let relationship of columns) {
1159
- const toPrimary = relationship.toPrimary;
1160
- const to = relationship.to;
1161
- this.orOn(`${toAlias}.${toPrimary}`, `${throughAlias}.${to}`);
1162
- }
1163
- });
1164
- }
1165
- return query;
1166
- }
1167
- qualifiedKnex(opts) {
1168
- var _a;
1169
- let alias = (_a = this.query.tableAliases) === null || _a === void 0 ? void 0 : _a[this.query.table.name];
1170
- if ((opts === null || opts === void 0 ? void 0 : opts.alias) === false) {
1171
- alias = undefined;
1172
- }
1173
- else if (typeof (opts === null || opts === void 0 ? void 0 : opts.alias) === "string") {
1174
- alias = opts.alias;
1175
- }
1176
- return this.knex(this.tableNameWithSchema(this.query.table.name, {
1177
- alias,
1178
- schema: this.query.schema,
1179
- }));
1180
- }
1181
- create(opts) {
1182
- var _a;
1183
- const { body } = this.query;
1184
- if (!body) {
1185
- throw new Error("Cannot create without row body");
1186
- }
1187
- let query = this.qualifiedKnex({ alias: false });
1188
- const parsedBody = this.parseBody(body);
1189
- if (this.client === types_1.SqlClient.ORACLE) {
1190
- // Oracle doesn't seem to automatically insert nulls
1191
- // if we don't specify them, so we need to do that here
1192
- for (const [column, schema] of Object.entries(this.query.table.schema)) {
1193
- if (((_a = schema.constraints) === null || _a === void 0 ? void 0 : _a.presence) === true ||
1194
- schema.type === types_1.FieldType.FORMULA ||
1195
- schema.type === types_1.FieldType.AUTO ||
1196
- schema.type === types_1.FieldType.LINK ||
1197
- schema.type === types_1.FieldType.AI) {
1198
- continue;
1199
- }
1200
- const value = parsedBody[column];
1201
- if (value == null) {
1202
- parsedBody[column] = null;
1203
- }
1204
- }
1205
- }
1206
- else {
1207
- // make sure no null values in body for creation
1208
- for (let [key, value] of Object.entries(parsedBody)) {
1209
- if (value == null) {
1210
- delete parsedBody[key];
1211
- }
1212
- }
1213
- }
1214
- // mysql can't use returning
1215
- if (opts.disableReturning) {
1216
- return query.insert(parsedBody);
1217
- }
1218
- else {
1219
- return query.insert(parsedBody).returning("*");
1220
- }
1221
- }
1222
- bulkCreate() {
1223
- const { body } = this.query;
1224
- let query = this.qualifiedKnex({ alias: false });
1225
- if (!Array.isArray(body)) {
1226
- return query;
1227
- }
1228
- const parsedBody = body.map(row => this.parseBody(row));
1229
- return query.insert(parsedBody);
1230
- }
1231
- bulkUpsert() {
1232
- const { body } = this.query;
1233
- let query = this.qualifiedKnex({ alias: false });
1234
- if (!Array.isArray(body)) {
1235
- return query;
1236
- }
1237
- const parsedBody = body.map(row => this.parseBody(row));
1238
- if (this.client === types_1.SqlClient.POSTGRES ||
1239
- this.client === types_1.SqlClient.SQL_LITE ||
1240
- this.client === types_1.SqlClient.MY_SQL ||
1241
- this.client === types_1.SqlClient.MARIADB) {
1242
- const primary = this.table.primary;
1243
- if (!primary) {
1244
- throw new Error("Primary key is required for upsert");
1245
- }
1246
- return query.insert(parsedBody).onConflict(primary).merge();
1247
- }
1248
- else if (this.client === types_1.SqlClient.MS_SQL ||
1249
- this.client === types_1.SqlClient.ORACLE) {
1250
- // No upsert or onConflict support in MSSQL/Oracle yet, see:
1251
- // https://github.com/knex/knex/pull/6050
1252
- return query.insert(parsedBody);
1253
- }
1254
- return query.upsert(parsedBody);
1255
- }
1256
- read(opts = {}) {
1257
- var _a, _b;
1258
- let { operation, filters, paginate, relationships, table } = this.query;
1259
- const { limits } = opts;
1260
- // start building the query
1261
- let query = this.qualifiedKnex();
1262
- // handle pagination
1263
- let foundOffset = null;
1264
- let foundLimit = (limits === null || limits === void 0 ? void 0 : limits.query) || (limits === null || limits === void 0 ? void 0 : limits.base);
1265
- if (paginate && paginate.page && paginate.limit) {
1266
- // @ts-ignore
1267
- const page = paginate.page <= 1 ? 0 : paginate.page - 1;
1268
- const offset = page * paginate.limit;
1269
- foundLimit = paginate.limit;
1270
- foundOffset = offset;
1271
- }
1272
- else if (paginate && paginate.offset && paginate.limit) {
1273
- foundLimit = paginate.limit;
1274
- foundOffset = paginate.offset;
1275
- }
1276
- else if (paginate && paginate.limit) {
1277
- foundLimit = paginate.limit;
1278
- }
1279
- // counting should not sort, limit or offset
1280
- if (operation !== types_1.Operation.COUNT) {
1281
- // add the found limit if supplied
1282
- if (foundLimit != null) {
1283
- query = query.limit(foundLimit);
1284
- }
1285
- // add overall pagination
1286
- if (foundOffset != null) {
1287
- query = query.offset(foundOffset);
1288
- }
1289
- }
1290
- const aggregations = ((_a = this.query.resource) === null || _a === void 0 ? void 0 : _a.aggregations) || [];
1291
- if (operation === types_1.Operation.COUNT) {
1292
- query = this.addDistinctCount(query);
1293
- }
1294
- else if (aggregations.length > 0) {
1295
- query = this.addAggregations(query, aggregations);
1296
- }
1297
- else {
1298
- query = query.select(this.generateSelectStatement());
1299
- }
1300
- // have to add after as well (this breaks MS-SQL)
1301
- if (operation !== types_1.Operation.COUNT) {
1302
- query = this.addSorting(query);
1303
- }
1304
- query = this.addFilters(query, filters, { relationship: true });
1305
- // handle relationships with a CTE for all others
1306
- if ((relationships === null || relationships === void 0 ? void 0 : relationships.length) && aggregations.length === 0) {
1307
- const mainTable = ((_b = this.query.tableAliases) === null || _b === void 0 ? void 0 : _b[table.name]) || table.name;
1308
- const cte = this.addSorting(this.knex
1309
- .with("paginated", query)
1310
- .select(this.generateSelectStatement())
1311
- .from({
1312
- [mainTable]: "paginated",
1313
- }));
1314
- // add JSON aggregations attached to the CTE
1315
- return this.addJsonRelationships(cte, table.name, relationships);
1316
- }
1317
- return query;
1318
- }
1319
- update(opts) {
1320
- const { body, filters } = this.query;
1321
- if (!body) {
1322
- throw new Error("Cannot update without row body");
1323
- }
1324
- let query = this.qualifiedKnex();
1325
- const parsedBody = this.parseBody(body);
1326
- query = this.addFilters(query, filters);
1327
- // mysql can't use returning
1328
- if (opts.disableReturning) {
1329
- return query.update(parsedBody);
1330
- }
1331
- else {
1332
- return query.update(parsedBody).returning("*");
1333
- }
1334
- }
1335
- delete(opts) {
1336
- const { filters } = this.query;
1337
- let query = this.qualifiedKnex();
1338
- query = this.addFilters(query, filters);
1339
- // mysql can't use returning
1340
- if (opts.disableReturning) {
1341
- return query.delete();
1342
- }
1343
- else {
1344
- return query.delete().returning(this.generateSelectStatement());
1345
- }
1346
- }
1347
- }
1348
- class SqlQueryBuilder extends sqlTable_1.default {
1349
- // pass through client to get flavour of SQL
1350
- constructor(client, limit = getBaseLimit()) {
1351
- super(client);
1352
- this.limit = limit;
1353
- }
1354
- convertToNative(query, opts = {}) {
1355
- const sqlClient = this.getSqlClient();
1356
- if (opts === null || opts === void 0 ? void 0 : opts.disableBindings) {
1357
- return { sql: query.toString() };
1358
- }
1359
- else {
1360
- let native = (0, utils_1.getNativeSql)(query);
1361
- if (sqlClient === types_1.SqlClient.SQL_LITE) {
1362
- native = convertBooleans(native);
1363
- }
1364
- return native;
1365
- }
1366
- }
1367
- /**
1368
- * @param json The JSON query DSL which is to be converted to SQL.
1369
- * @param opts extra options which are to be passed into the query builder, e.g. disableReturning
1370
- * which for the sake of mySQL stops adding the returning statement to inserts, updates and deletes.
1371
- * @return the query ready to be passed to the driver.
1372
- */
1373
- _query(json, opts = {}) {
1374
- const sqlClient = this.getSqlClient();
1375
- const config = {
1376
- client: this.getBaseSqlClient(),
1377
- };
1378
- if (sqlClient === types_1.SqlClient.SQL_LITE || sqlClient === types_1.SqlClient.ORACLE) {
1379
- config.useNullAsDefault = true;
1380
- }
1381
- const client = (0, knex_1.knex)(config);
1382
- let query;
1383
- const builder = new InternalBuilder(sqlClient, client, json);
1384
- switch (this._operation(json)) {
1385
- case types_1.Operation.CREATE:
1386
- query = builder.create(opts);
1387
- break;
1388
- case types_1.Operation.READ:
1389
- query = builder.read({
1390
- limits: {
1391
- query: this.limit,
1392
- base: getBaseLimit(),
1393
- },
1394
- });
1395
- break;
1396
- case types_1.Operation.COUNT:
1397
- // read without any limits to count
1398
- query = builder.read();
1399
- break;
1400
- case types_1.Operation.UPDATE:
1401
- query = builder.update(opts);
1402
- break;
1403
- case types_1.Operation.DELETE:
1404
- query = builder.delete(opts);
1405
- break;
1406
- case types_1.Operation.BULK_CREATE:
1407
- query = builder.bulkCreate();
1408
- break;
1409
- case types_1.Operation.BULK_UPSERT:
1410
- query = builder.bulkUpsert();
1411
- break;
1412
- case types_1.Operation.CREATE_TABLE:
1413
- case types_1.Operation.UPDATE_TABLE:
1414
- case types_1.Operation.DELETE_TABLE:
1415
- return this._tableQuery(json);
1416
- default:
1417
- throw `Operation type is not supported by SQL query builder`;
1418
- }
1419
- return this.convertToNative(query, opts);
1420
- }
1421
- getReturningRow(queryFn, json) {
1422
- return __awaiter(this, void 0, void 0, function* () {
1423
- var _a;
1424
- if (!json.extra || !json.extra.idFilter) {
1425
- return {};
1426
- }
1427
- const input = this._query({
1428
- operation: types_1.Operation.READ,
1429
- datasource: json.datasource,
1430
- schema: json.schema,
1431
- table: json.table,
1432
- tables: json.tables,
1433
- resource: { fields: [] },
1434
- filters: (_a = json.extra) === null || _a === void 0 ? void 0 : _a.idFilter,
1435
- paginate: { limit: 1 },
1436
- });
1437
- return queryFn(input, types_1.Operation.READ);
1438
- });
1439
- }
1440
- // when creating if an ID has been inserted need to make sure
1441
- // the id filter is enriched with it before trying to retrieve the row
1442
- checkLookupKeys(id, json) {
1443
- if (!id || !json.table.primary) {
1444
- return json;
1445
- }
1446
- const primaryKey = json.table.primary[0];
1447
- json.extra = {
1448
- idFilter: {
1449
- equal: {
1450
- [primaryKey]: id,
1451
- },
1452
- },
1453
- };
1454
- return json;
1455
- }
1456
- // this function recreates the returning functionality of postgres
1457
- queryWithReturning(json_1, queryFn_1) {
1458
- return __awaiter(this, arguments, void 0, function* (json, queryFn, processFn = (result) => result) {
1459
- const sqlClient = this.getSqlClient();
1460
- const operation = this._operation(json);
1461
- const input = this._query(json, { disableReturning: true });
1462
- if (Array.isArray(input)) {
1463
- const responses = [];
1464
- for (let query of input) {
1465
- responses.push(yield queryFn(query, operation));
1466
- }
1467
- return responses;
1468
- }
1469
- let row;
1470
- // need to manage returning, a feature mySQL can't do
1471
- if (operation === types_1.Operation.DELETE) {
1472
- row = processFn(yield this.getReturningRow(queryFn, json));
1473
- }
1474
- const response = yield queryFn(input, operation);
1475
- const results = processFn(response);
1476
- // same as delete, manage returning
1477
- if (operation === types_1.Operation.CREATE || operation === types_1.Operation.UPDATE) {
1478
- let id;
1479
- if (sqlClient === types_1.SqlClient.MS_SQL) {
1480
- id = results === null || results === void 0 ? void 0 : results[0].id;
1481
- }
1482
- else if (sqlClient === types_1.SqlClient.MY_SQL ||
1483
- sqlClient === types_1.SqlClient.MARIADB) {
1484
- id = results === null || results === void 0 ? void 0 : results.insertId;
1485
- }
1486
- row = processFn(yield this.getReturningRow(queryFn, this.checkLookupKeys(id, json)));
1487
- }
1488
- if (operation === types_1.Operation.COUNT) {
1489
- return results;
1490
- }
1491
- if (operation !== types_1.Operation.READ) {
1492
- return row;
1493
- }
1494
- return results.length ? results : [{ [operation.toLowerCase()]: true }];
1495
- });
1496
- }
1497
- getTableName(table, aliases) {
1498
- let name = table.name;
1499
- if (table.sourceType === types_1.TableSourceType.INTERNAL ||
1500
- table.sourceId === types_1.INTERNAL_TABLE_SOURCE_ID) {
1501
- if (!table._id) {
1502
- return;
1503
- }
1504
- // SQS uses the table ID rather than the table name
1505
- name = table._id;
1506
- }
1507
- return (aliases === null || aliases === void 0 ? void 0 : aliases[name]) || name;
1508
- }
1509
- convertJsonStringColumns(table, results, aliases) {
1510
- const tableName = this.getTableName(table, aliases);
1511
- for (const [name, field] of Object.entries(table.schema)) {
1512
- if (!this._isJsonColumn(field)) {
1513
- continue;
1514
- }
1515
- const fullName = `${tableName}.${name}`;
1516
- for (let row of results) {
1517
- if (typeof row[fullName] === "string") {
1518
- row[fullName] = JSON.parse(row[fullName]);
1519
- }
1520
- if (typeof row[name] === "string") {
1521
- row[name] = JSON.parse(row[name]);
1522
- }
1523
- }
1524
- }
1525
- return results;
1526
- }
1527
- _isJsonColumn(field) {
1528
- return (types_1.JsonTypes.includes(field.type) &&
1529
- !shared_core_1.helpers.schema.isDeprecatedSingleUserColumn(field));
1530
- }
1531
- log(query, values) {
1532
- (0, utils_1.sqlLog)(this.getSqlClient(), query, values);
1533
- }
1534
- }
1535
- exports.default = SqlQueryBuilder;
1536
- //# sourceMappingURL=sql.js.map