@budibase/server 1.2.58-alpha.6 → 1.2.58

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 (211) hide show
  1. package/__mocks__/mongodb.ts +0 -4
  2. package/__mocks__/node-fetch.ts +1 -8
  3. package/builder/assets/index.08dd0c5e.css +6 -0
  4. package/builder/assets/index.5cf58e77.js +975 -0
  5. package/builder/assets/{vendor.67dbd8fa.js → vendor.6bcafa60.js} +1 -1
  6. package/builder/index.html +3 -3
  7. package/coverage/clover.xml +524 -549
  8. package/coverage/coverage-final.json +20 -20
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/index.html +1 -1
  18. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  24. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/index.html +25 -25
  29. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +191 -317
  31. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/row/utils.js.html +18 -27
  33. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/table/external.js.html +2 -2
  37. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/user.js.html +19 -19
  41. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  45. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  46. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  47. package/coverage/lcov-report/api/index.html +1 -1
  48. package/coverage/lcov-report/api/index.js.html +5 -5
  49. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/index.html +1 -1
  60. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  74. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  77. package/coverage/lcov-report/automations/actions.js.html +1 -1
  78. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  79. package/coverage/lcov-report/automations/bullboard.js.html +6 -9
  80. package/coverage/lcov-report/automations/index.html +11 -11
  81. package/coverage/lcov-report/automations/index.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/index.html +1 -1
  89. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  108. package/coverage/lcov-report/constants/index.html +1 -1
  109. package/coverage/lcov-report/constants/index.js.html +30 -30
  110. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  111. package/coverage/lcov-report/constants/screens.js.html +1 -1
  112. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  113. package/coverage/lcov-report/db/index.html +1 -1
  114. package/coverage/lcov-report/db/index.js.html +1 -1
  115. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  116. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  117. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  118. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  119. package/coverage/lcov-report/db/newid.js.html +4 -4
  120. package/coverage/lcov-report/db/utils.js.html +73 -73
  121. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  122. package/coverage/lcov-report/events/index.html +1 -1
  123. package/coverage/lcov-report/events/index.js.html +1 -1
  124. package/coverage/lcov-report/events/utils.js.html +1 -1
  125. package/coverage/lcov-report/index.html +33 -33
  126. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  127. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  128. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  129. package/coverage/lcov-report/middleware/builder.js.html +12 -12
  130. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  131. package/coverage/lcov-report/middleware/index.html +10 -10
  132. package/coverage/lcov-report/middleware/joi-validator.js.html +9 -18
  133. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  134. package/coverage/lcov-report/middleware/resourceId.js.html +12 -12
  135. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  136. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  137. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  138. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  139. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  140. package/coverage/lcov-report/utilities/global.js.html +31 -31
  141. package/coverage/lcov-report/utilities/index.html +1 -1
  142. package/coverage/lcov-report/utilities/index.js.html +24 -24
  143. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
  144. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  145. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  146. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  147. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  148. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  149. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  150. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  151. package/coverage/lcov-report/utilities/security.js.html +2 -2
  152. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  153. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  154. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +20 -20
  155. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  156. package/coverage/lcov-report/utilities/users.js.html +7 -7
  157. package/coverage/lcov-report/utilities/workerRequests.js.html +13 -13
  158. package/coverage/lcov.info +844 -888
  159. package/dist/api/controllers/application.js +14 -80
  160. package/dist/api/controllers/row/internalSearch.js +4 -39
  161. package/dist/api/controllers/row/utils.js +1 -3
  162. package/dist/api/controllers/static/index.js +2 -26
  163. package/dist/api/controllers/table/external.js +1 -1
  164. package/dist/api/routes/static.js +0 -3
  165. package/dist/app.js +3 -4
  166. package/dist/automations/bullboard.js +0 -1
  167. package/dist/automations/logging/index.js +0 -3
  168. package/dist/integrations/base/sql.js +30 -62
  169. package/dist/integrations/base/utils.js +27 -13
  170. package/dist/integrations/microsoftSqlServer.js +2 -5
  171. package/dist/integrations/mongodb.js +8 -35
  172. package/dist/integrations/mysql.js +2 -2
  173. package/dist/integrations/postgres.js +2 -5
  174. package/dist/middleware/joi-validator.js +4 -7
  175. package/dist/package.json +7 -7
  176. package/dist/threads/index.js +0 -1
  177. package/dist/tsconfig.build.tsbuildinfo +1 -1
  178. package/dist/utilities/fileSystem/index.js +1 -2
  179. package/dist/utilities/redis.js +0 -1
  180. package/package.json +8 -8
  181. package/src/api/controllers/application.ts +15 -96
  182. package/src/api/controllers/row/internalSearch.js +3 -45
  183. package/src/api/controllers/row/utils.js +1 -4
  184. package/src/api/controllers/static/index.ts +1 -21
  185. package/src/api/controllers/table/external.js +1 -1
  186. package/src/api/routes/static.ts +0 -12
  187. package/src/api/routes/tests/application.spec.js +0 -26
  188. package/src/api/routes/tests/static.spec.js +7 -19
  189. package/src/app.ts +3 -5
  190. package/src/automations/bullboard.js +0 -1
  191. package/src/automations/logging/index.ts +0 -3
  192. package/src/integrations/base/sql.ts +30 -67
  193. package/src/integrations/base/utils.ts +18 -9
  194. package/src/integrations/microsoftSqlServer.ts +2 -3
  195. package/src/integrations/mongodb.ts +8 -35
  196. package/src/integrations/mysql.ts +1 -1
  197. package/src/integrations/postgres.ts +1 -2
  198. package/src/integrations/tests/mongo.spec.js +0 -218
  199. package/src/integrations/tests/sql.spec.js +11 -101
  200. package/src/middleware/joi-validator.js +4 -7
  201. package/src/threads/index.ts +0 -1
  202. package/src/utilities/fileSystem/index.js +0 -2
  203. package/src/utilities/redis.js +0 -1
  204. package/builder/assets/index.7ba6d256.js +0 -875
  205. package/builder/assets/index.fdb1647e.css +0 -6
  206. package/dist/api/controllers/static/templates/preview.hbs +0 -103
  207. package/dist/integrations/base/query.js +0 -27
  208. package/src/api/controllers/static/templates/preview.hbs +0 -103
  209. package/src/api/routes/tests/data/old-app.txt +0 -3
  210. package/src/api/routes/tests/internalSearch.spec.js +0 -176
  211. package/src/integrations/base/query.ts +0 -16
@@ -10,7 +10,6 @@ import { QueryOptions } from "../../definitions/datasource"
10
10
  import { isIsoDateString, SqlClient } from "../utils"
11
11
  import SqlTableQueryBuilder from "./sqlTable"
12
12
  import environment from "../../environment"
13
- import { removeKeyNumbering } from "./utils"
14
13
 
15
14
  const envLimit = environment.SQL_MAX_ROWS
16
15
  ? parseInt(environment.SQL_MAX_ROWS)
@@ -134,13 +133,12 @@ class InternalBuilder {
134
133
  fn: (key: string, value: any) => void
135
134
  ) {
136
135
  for (let [key, value] of Object.entries(structure)) {
137
- const updatedKey = removeKeyNumbering(key)
138
- const isRelationshipField = updatedKey.includes(".")
136
+ const isRelationshipField = key.includes(".")
139
137
  if (!opts.relationship && !isRelationshipField) {
140
- fn(`${opts.tableName}.${updatedKey}`, value)
138
+ fn(`${opts.tableName}.${key}`, value)
141
139
  }
142
140
  if (opts.relationship && isRelationshipField) {
143
- fn(updatedKey, value)
141
+ fn(key, value)
144
142
  }
145
143
  }
146
144
  }
@@ -159,61 +157,6 @@ class InternalBuilder {
159
157
  }
160
158
  }
161
159
 
162
- const contains = (mode: object, any: boolean = false) => {
163
- const fnc = allOr ? "orWhere" : "where"
164
- const rawFnc = `${fnc}Raw`
165
- const not = mode === filters?.notContains ? "NOT " : ""
166
- function stringifyArray(value: Array<any>, quoteStyle = '"'): string {
167
- for (let i in value) {
168
- if (typeof value[i] === "string") {
169
- value[i] = `${quoteStyle}${value[i]}${quoteStyle}`
170
- }
171
- }
172
- return `[${value.join(",")}]`
173
- }
174
- if (this.client === SqlClient.POSTGRES) {
175
- iterate(mode, (key: string, value: Array<any>) => {
176
- const wrap = any ? "" : "'"
177
- const containsOp = any ? "\\?| array" : "@>"
178
- const fieldNames = key.split(/\./g)
179
- const tableName = fieldNames[0]
180
- const columnName = fieldNames[1]
181
- // @ts-ignore
182
- query = query[rawFnc](
183
- `${not}"${tableName}"."${columnName}"::jsonb ${containsOp} ${wrap}${stringifyArray(
184
- value,
185
- any ? "'" : '"'
186
- )}${wrap}`
187
- )
188
- })
189
- } else if (this.client === SqlClient.MY_SQL) {
190
- const jsonFnc = any ? "JSON_OVERLAPS" : "JSON_CONTAINS"
191
- iterate(mode, (key: string, value: Array<any>) => {
192
- // @ts-ignore
193
- query = query[rawFnc](
194
- `${not}${jsonFnc}(${key}, '${stringifyArray(value)}')`
195
- )
196
- })
197
- } else {
198
- const andOr = mode === filters?.containsAny ? " OR " : " AND "
199
- iterate(mode, (key: string, value: Array<any>) => {
200
- let statement = ""
201
- for (let i in value) {
202
- if (typeof value[i] === "string") {
203
- value[i] = `%"${value[i]}"%`
204
- } else {
205
- value[i] = `%${value[i]}%`
206
- }
207
- statement +=
208
- (statement ? andOr : "") +
209
- `LOWER(${likeKey(this.client, key)}) LIKE ?`
210
- }
211
- // @ts-ignore
212
- query = query[rawFnc](`${not}(${statement})`, value)
213
- })
214
- }
215
- }
216
-
217
160
  if (!filters) {
218
161
  return query
219
162
  }
@@ -284,13 +227,32 @@ class InternalBuilder {
284
227
  })
285
228
  }
286
229
  if (filters.contains) {
287
- contains(filters.contains)
288
- }
289
- if (filters.notContains) {
290
- contains(filters.notContains)
291
- }
292
- if (filters.containsAny) {
293
- contains(filters.containsAny, true)
230
+ const fnc = allOr ? "orWhere" : "where"
231
+ const rawFnc = `${fnc}Raw`
232
+ if (this.client === SqlClient.POSTGRES) {
233
+ iterate(filters.contains, (key: string, value: any) => {
234
+ const fieldNames = key.split(/\./g)
235
+ const tableName = fieldNames[0]
236
+ const columnName = fieldNames[1]
237
+ if (typeof value === "string") {
238
+ value = `"${value}"`
239
+ }
240
+ // @ts-ignore
241
+ query = query[rawFnc](
242
+ `"${tableName}"."${columnName}"::jsonb @> '[${value}]'`
243
+ )
244
+ })
245
+ } else if (this.client === SqlClient.MY_SQL) {
246
+ iterate(filters.contains, (key: string, value: any) => {
247
+ if (typeof value === "string") {
248
+ value = `"${value}"`
249
+ }
250
+ // @ts-ignore
251
+ query = query[rawFnc](`JSON_CONTAINS(${key}, '${value}')`)
252
+ })
253
+ } else {
254
+ iterate(filters.contains, like)
255
+ }
294
256
  }
295
257
  return query
296
258
  }
@@ -620,3 +582,4 @@ class SqlQueryBuilder extends SqlTableQueryBuilder {
620
582
  }
621
583
 
622
584
  export default SqlQueryBuilder
585
+ module.exports = SqlQueryBuilder
@@ -1,12 +1,21 @@
1
- const QUERY_START_REGEX = /\d[0-9]*:/g
1
+ import { QueryJson, Datasource } from "@budibase/types"
2
2
 
3
- export function removeKeyNumbering(key: any): string {
4
- if (typeof key === "string" && key.match(QUERY_START_REGEX) != null) {
5
- const parts = key.split(":")
6
- // remove the number
7
- parts.shift()
8
- return parts.join(":")
9
- } else {
10
- return key
3
+ module DatasourceUtils {
4
+ const { integrations } = require("../index")
5
+
6
+ export async function makeExternalQuery(
7
+ datasource: Datasource,
8
+ json: QueryJson
9
+ ) {
10
+ const Integration = integrations[datasource.source]
11
+ // query is the opinionated function
12
+ if (Integration.prototype.query) {
13
+ const integration = new Integration(datasource.config)
14
+ return integration.query(json)
15
+ } else {
16
+ throw "Datasource does not support query."
17
+ }
11
18
  }
19
+
20
+ module.exports.makeExternalQuery = makeExternalQuery
12
21
  }
@@ -16,10 +16,10 @@ import {
16
16
  finaliseExternalTables,
17
17
  SqlClient,
18
18
  } from "./utils"
19
- import Sql from "./base/sql"
20
19
 
21
20
  module MSSQLModule {
22
21
  const sqlServer = require("mssql")
22
+ const Sql = require("./base/sql")
23
23
  const DEFAULT_SCHEMA = "dbo"
24
24
 
25
25
  interface MSSQLConfig {
@@ -97,8 +97,7 @@ module MSSQLModule {
97
97
  class SqlServerIntegration extends Sql implements DatasourcePlus {
98
98
  private readonly config: MSSQLConfig
99
99
  private index: number = 0
100
- private readonly pool: any
101
- private client: any
100
+ static pool: any
102
101
  public tables: Record<string, Table> = {}
103
102
  public schemaErrors: Record<string, string> = {}
104
103
 
@@ -92,15 +92,12 @@ module MongoDBModule {
92
92
  if (json[field] instanceof Object) {
93
93
  json[field] = self.createObjectIds(json[field])
94
94
  }
95
- if (
96
- typeof json[field] === "string" &&
97
- json[field].toLowerCase().startsWith("objectid")
98
- ) {
99
- const id = json[field].match(
95
+ if (field === "_id" && typeof json[field] === "string") {
96
+ const id = json["_id"].match(
100
97
  /(?<=objectid\(['"]).*(?=['"]\))/gi
101
98
  )?.[0]
102
99
  if (id) {
103
- json[field] = ObjectID.createFromHexString(id)
100
+ json["_id"] = ObjectID.createFromHexString(id)
104
101
  }
105
102
  }
106
103
  }
@@ -117,31 +114,10 @@ module MongoDBModule {
117
114
  }
118
115
 
119
116
  parseQueryParams(params: string, mode: string) {
120
- let queryParams = []
121
- let openCount = 0
122
- let inQuotes = false
123
- let i = 0
124
- let startIndex = 0
125
- for (let c of params) {
126
- if (c === '"' && i > 0 && params[i - 1] !== "\\") {
127
- inQuotes = !inQuotes
128
- }
129
- if (c === "{" && !inQuotes) {
130
- openCount++
131
- if (openCount === 1) {
132
- startIndex = i
133
- }
134
- } else if (c === "}" && !inQuotes) {
135
- if (openCount === 1) {
136
- queryParams.push(JSON.parse(params.substring(startIndex, i + 1)))
137
- }
138
- openCount--
139
- }
140
- i++
141
- }
142
- let group1 = queryParams[0] ?? {}
143
- let group2 = queryParams[1] ?? {}
144
- let group3 = queryParams[2] ?? {}
117
+ let queryParams = params.split(/(?<=}),[\n\s]*(?={)/g)
118
+ let group1 = queryParams[0] ? JSON.parse(queryParams[0]) : {}
119
+ let group2 = queryParams[1] ? JSON.parse(queryParams[1]) : {}
120
+ let group3 = queryParams[2] ? JSON.parse(queryParams[2]) : {}
145
121
  if (mode === "update") {
146
122
  return {
147
123
  filter: group1,
@@ -200,10 +176,7 @@ module MongoDBModule {
200
176
  return await collection.findOne(json)
201
177
  }
202
178
  case "findOneAndUpdate": {
203
- if (typeof query.json === "string") {
204
- json = this.parseQueryParams(query.json, "update")
205
- }
206
- let findAndUpdateJson = this.createObjectIds(json) as {
179
+ let findAndUpdateJson = json as {
207
180
  filter: FilterQuery<any>
208
181
  update: UpdateQuery<any>
209
182
  options: FindOneAndUpdateOption<any>
@@ -17,10 +17,10 @@ import {
17
17
  } from "./utils"
18
18
  import dayjs from "dayjs"
19
19
  const { NUMBER_REGEX } = require("../utilities")
20
- import Sql from "./base/sql"
21
20
 
22
21
  module MySQLModule {
23
22
  const mysql = require("mysql2/promise")
23
+ const Sql = require("./base/sql")
24
24
 
25
25
  interface MySQLConfig {
26
26
  host: string
@@ -14,10 +14,10 @@ import {
14
14
  finaliseExternalTables,
15
15
  SqlClient,
16
16
  } from "./utils"
17
- import Sql from "./base/sql"
18
17
 
19
18
  module PostgresModule {
20
19
  const { Client, types } = require("pg")
20
+ const Sql = require("./base/sql")
21
21
  const { escapeDangerousCharacters } = require("../utilities")
22
22
 
23
23
  // Return "date" and "timestamp" types as plain strings.
@@ -117,7 +117,6 @@ module PostgresModule {
117
117
  private readonly client: any
118
118
  private readonly config: PostgresConfig
119
119
  private index: number = 1
120
- private open: boolean
121
120
  public tables: Record<string, Table> = {}
122
121
  public schemaErrors: Record<string, string> = {}
123
122
 
@@ -102,222 +102,4 @@ describe("MongoDB Integration", () => {
102
102
  expect(error).toBeDefined()
103
103
  restore()
104
104
  })
105
-
106
- it("creates ObjectIds if the field contains a match on ObjectId", async () => {
107
- const query = {
108
- json: {
109
- filter: {
110
- _id: "ObjectId('ACBD12345678ABCD12345678')",
111
- name: "ObjectId('BBBB12345678ABCD12345678')"
112
- },
113
- update: {
114
- _id: "ObjectId('FFFF12345678ABCD12345678')",
115
- name: "ObjectId('CCCC12345678ABCD12345678')",
116
- },
117
- options: {
118
- upsert: false,
119
- },
120
- },
121
- extra: { collection: "testCollection", actionTypes: "updateOne" },
122
- }
123
- await config.integration.update(query)
124
- expect(config.integration.client.updateOne).toHaveBeenCalled()
125
-
126
- const args = config.integration.client.updateOne.mock.calls[0]
127
- expect(args[0]).toEqual({
128
- _id: mongo.ObjectID.createFromHexString("ACBD12345678ABCD12345678"),
129
- name: mongo.ObjectID.createFromHexString("BBBB12345678ABCD12345678"),
130
- })
131
- expect(args[1]).toEqual({
132
- _id: mongo.ObjectID.createFromHexString("FFFF12345678ABCD12345678"),
133
- name: mongo.ObjectID.createFromHexString("CCCC12345678ABCD12345678"),
134
- })
135
- expect(args[2]).toEqual({
136
- upsert: false
137
- })
138
- })
139
-
140
- it("creates ObjectIds if the $ operator fields contains a match on ObjectId", async () => {
141
- const query = {
142
- json: {
143
- filter: {
144
- _id: {
145
- $eq: "ObjectId('ACBD12345678ABCD12345678')",
146
- }
147
- },
148
- update: {
149
- $set: {
150
- _id: "ObjectId('FFFF12345678ABCD12345678')",
151
- },
152
- },
153
- options: {
154
- upsert: true,
155
- },
156
- },
157
- extra: { collection: "testCollection", actionTypes: "updateOne" },
158
- }
159
- await config.integration.update(query)
160
- expect(config.integration.client.updateOne).toHaveBeenCalled()
161
-
162
- const args = config.integration.client.updateOne.mock.calls[0]
163
- expect(args[0]).toEqual({
164
- _id: {
165
- $eq: mongo.ObjectID.createFromHexString("ACBD12345678ABCD12345678"),
166
- }
167
- })
168
- expect(args[1]).toEqual({
169
- $set: {
170
- _id: mongo.ObjectID.createFromHexString("FFFF12345678ABCD12345678"),
171
- }
172
- })
173
- expect(args[2]).toEqual({
174
- upsert: true
175
- })
176
- })
177
-
178
- it("supports findOneAndUpdate", async () => {
179
- const query = {
180
- json: {
181
- filter: {
182
- _id: {
183
- $eq: "ObjectId('ACBD12345678ABCD12345678')",
184
- }
185
- },
186
- update: {
187
- $set: {
188
- name: "UPDATED",
189
- age: 99
190
- },
191
- },
192
- options: {
193
- upsert: false,
194
- },
195
- },
196
- extra: { collection: "testCollection", actionTypes: "findOneAndUpdate" },
197
- }
198
- await config.integration.read(query)
199
- expect(config.integration.client.findOneAndUpdate).toHaveBeenCalled()
200
-
201
- const args = config.integration.client.findOneAndUpdate.mock.calls[0]
202
- expect(args[0]).toEqual({
203
- _id: {
204
- $eq: mongo.ObjectID.createFromHexString("ACBD12345678ABCD12345678"),
205
- }
206
- })
207
- expect(args[1]).toEqual({
208
- $set: {
209
- name: "UPDATED",
210
- age: 99
211
- }
212
- })
213
- expect(args[2]).toEqual({
214
- upsert: false
215
- })
216
- })
217
-
218
- it("can parse nested objects with arrays", async () => {
219
- const query = {
220
- json: `{
221
- "_id": {
222
- "$eq": "ObjectId('ACBD12345678ABCD12345678')"
223
- }
224
- },
225
- {
226
- "$set": {
227
- "value": {
228
- "data": [
229
- { "cid": 1 },
230
- { "cid": 2 },
231
- { "nested": {
232
- "name": "test"
233
- }}
234
- ]
235
- }
236
- }
237
- },
238
- {
239
- "upsert": true
240
- }`,
241
- extra: { collection: "testCollection", actionTypes: "updateOne" },
242
- }
243
- await config.integration.update(query)
244
- expect(config.integration.client.updateOne).toHaveBeenCalled()
245
-
246
- const args = config.integration.client.updateOne.mock.calls[0]
247
- expect(args[0]).toEqual({
248
- _id: {
249
- $eq: mongo.ObjectID.createFromHexString("ACBD12345678ABCD12345678"),
250
- }
251
- })
252
- expect(args[1]).toEqual({
253
- $set: {
254
- value: {
255
- data: [
256
- { cid: 1 },
257
- { cid: 2 },
258
- { nested: {
259
- name: "test"
260
- }}
261
- ]
262
- },
263
- },
264
- })
265
- expect(args[2]).toEqual({
266
- upsert: true
267
- })
268
- })
269
-
270
- it("ignores braces within strings when parsing nested objects", async () => {
271
- const query = {
272
- json: `{
273
- "_id": {
274
- "$eq": "ObjectId('ACBD12345678ABCD12345678')"
275
- }
276
- },
277
- {
278
- "$set": {
279
- "value": {
280
- "data": [
281
- { "cid": 1 },
282
- { "cid": 2 },
283
- { "nested": {
284
- "name": "te}st"
285
- }}
286
- ]
287
- }
288
- }
289
- },
290
- {
291
- "upsert": true,
292
- "extra": "ad\\"{\\"d"
293
- }`,
294
- extra: { collection: "testCollection", actionTypes: "updateOne" },
295
- }
296
- await config.integration.update(query)
297
- expect(config.integration.client.updateOne).toHaveBeenCalled()
298
-
299
- const args = config.integration.client.updateOne.mock.calls[0]
300
- expect(args[0]).toEqual({
301
- _id: {
302
- $eq: mongo.ObjectID.createFromHexString("ACBD12345678ABCD12345678"),
303
- }
304
- })
305
- expect(args[1]).toEqual({
306
- $set: {
307
- value: {
308
- data: [
309
- { cid: 1 },
310
- { cid: 2 },
311
- { nested: {
312
- name: "te}st"
313
- }}
314
- ]
315
- },
316
- },
317
- })
318
- expect(args[2]).toEqual({
319
- upsert: true,
320
- extra: "ad\"{\"d"
321
- })
322
- })
323
105
  })
@@ -1,4 +1,4 @@
1
- const Sql = require("../base/sql").default
1
+ const Sql = require("../base/sql")
2
2
  const { SqlClient } = require("../utils")
3
3
 
4
4
  const TABLE_NAME = "test"
@@ -240,18 +240,18 @@ describe("SQL query builder", () => {
240
240
  })
241
241
  })
242
242
 
243
- it("should use AND like expression for MS-SQL when filter is contains", () => {
243
+ it("should use like expression for MS-SQL when filter is contains", () => {
244
244
  const query = new Sql(SqlClient.MS_SQL, 10)._query(generateReadJson({
245
245
  filters: {
246
246
  contains: {
247
- age: [20, 25],
248
- name: ["John", "Mary"]
247
+ age: 20,
248
+ name: "John"
249
249
  }
250
250
  }
251
251
  }))
252
252
  expect(query).toEqual({
253
- bindings: [10, "%20%", "%25%", `%"John"%`, `%"Mary"%`],
254
- sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where (LOWER(${TABLE_NAME}.age) LIKE @p1 AND LOWER(${TABLE_NAME}.age) LIKE @p2) and (LOWER(${TABLE_NAME}.name) LIKE @p3 AND LOWER(${TABLE_NAME}.name) LIKE @p4)) as [${TABLE_NAME}]`
253
+ bindings: [10, "%20%", "%John%"],
254
+ sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where LOWER(${TABLE_NAME}.age) LIKE @p1 and LOWER(${TABLE_NAME}.name) LIKE @p2) as [${TABLE_NAME}]`
255
255
  })
256
256
  })
257
257
 
@@ -259,14 +259,14 @@ describe("SQL query builder", () => {
259
259
  const query = new Sql(SqlClient.MY_SQL, 10)._query(generateReadJson({
260
260
  filters: {
261
261
  contains: {
262
- age: [20],
263
- name: ["John"]
262
+ age: 20,
263
+ name: "John"
264
264
  }
265
265
  }
266
266
  }))
267
267
  expect(query).toEqual({
268
268
  bindings: [10],
269
- sql: `select * from (select * from \`${TABLE_NAME}\` where JSON_CONTAINS(${TABLE_NAME}.age, '[20]') and JSON_CONTAINS(${TABLE_NAME}.name, '["John"]') limit ?) as \`${TABLE_NAME}\``
269
+ sql: `select * from (select * from \`${TABLE_NAME}\` where JSON_CONTAINS(${TABLE_NAME}.age, '20') and JSON_CONTAINS(${TABLE_NAME}.name, '"John"') limit ?) as \`${TABLE_NAME}\``
270
270
  })
271
271
  })
272
272
 
@@ -274,8 +274,8 @@ describe("SQL query builder", () => {
274
274
  const query = new Sql(SqlClient.POSTGRES, 10)._query(generateReadJson({
275
275
  filters: {
276
276
  contains: {
277
- age: [20],
278
- name: ["John"]
277
+ age: 20,
278
+ name: "John"
279
279
  }
280
280
  }
281
281
  }))
@@ -284,94 +284,4 @@ describe("SQL query builder", () => {
284
284
  sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb @> '[20]' and \"${TABLE_NAME}\".\"name\"::jsonb @> '["John"]' limit $1) as \"${TABLE_NAME}\"`
285
285
  })
286
286
  })
287
-
288
- it("should use NOT like expression for MS-SQL when filter is notContains", () => {
289
- const query = new Sql(SqlClient.MS_SQL, 10)._query(generateReadJson({
290
- filters: {
291
- notContains: {
292
- age: [20],
293
- name: ["John"]
294
- }
295
- }
296
- }))
297
- expect(query).toEqual({
298
- bindings: [10, "%20%", `%"John"%`],
299
- sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where NOT (LOWER(${TABLE_NAME}.age) LIKE @p1) and NOT (LOWER(${TABLE_NAME}.name) LIKE @p2)) as [${TABLE_NAME}]`
300
- })
301
- })
302
-
303
- it("should use NOT JSON_CONTAINS expression for MySQL when filter is notContains", () => {
304
- const query = new Sql(SqlClient.MY_SQL, 10)._query(generateReadJson({
305
- filters: {
306
- notContains: {
307
- age: [20],
308
- name: ["John"]
309
- }
310
- }
311
- }))
312
- expect(query).toEqual({
313
- bindings: [10],
314
- sql: `select * from (select * from \`${TABLE_NAME}\` where NOT JSON_CONTAINS(${TABLE_NAME}.age, '[20]') and NOT JSON_CONTAINS(${TABLE_NAME}.name, '["John"]') limit ?) as \`${TABLE_NAME}\``
315
- })
316
- })
317
-
318
- it("should use jsonb operator NOT expression for PostgreSQL when filter is notContains", () => {
319
- const query = new Sql(SqlClient.POSTGRES, 10)._query(generateReadJson({
320
- filters: {
321
- notContains: {
322
- age: [20],
323
- name: ["John"]
324
- }
325
- }
326
- }))
327
- expect(query).toEqual({
328
- bindings: [10],
329
- sql: `select * from (select * from \"${TABLE_NAME}\" where NOT \"${TABLE_NAME}\".\"age\"::jsonb @> '[20]' and NOT \"${TABLE_NAME}\".\"name\"::jsonb @> '["John"]' limit $1) as \"${TABLE_NAME}\"`
330
- })
331
- })
332
-
333
- it("should use OR like expression for MS-SQL when filter is containsAny", () => {
334
- const query = new Sql(SqlClient.MS_SQL, 10)._query(generateReadJson({
335
- filters: {
336
- containsAny: {
337
- age: [20, 25],
338
- name: ["John", "Mary"]
339
- }
340
- }
341
- }))
342
- expect(query).toEqual({
343
- bindings: [10, "%20%", "%25%", `%"John"%`, `%"Mary"%`],
344
- sql: `select * from (select top (@p0) * from [${TABLE_NAME}] where (LOWER(${TABLE_NAME}.age) LIKE @p1 OR LOWER(${TABLE_NAME}.age) LIKE @p2) and (LOWER(${TABLE_NAME}.name) LIKE @p3 OR LOWER(${TABLE_NAME}.name) LIKE @p4)) as [${TABLE_NAME}]`
345
- })
346
- })
347
-
348
- it("should use JSON_OVERLAPS expression for MySQL when filter is containsAny", () => {
349
- const query = new Sql(SqlClient.MY_SQL, 10)._query(generateReadJson({
350
- filters: {
351
- containsAny: {
352
- age: [20, 25],
353
- name: ["John", "Mary"]
354
- }
355
- }
356
- }))
357
- expect(query).toEqual({
358
- bindings: [10],
359
- sql: `select * from (select * from \`${TABLE_NAME}\` where JSON_OVERLAPS(${TABLE_NAME}.age, '[20,25]') and JSON_OVERLAPS(${TABLE_NAME}.name, '["John","Mary"]') limit ?) as \`${TABLE_NAME}\``
360
- })
361
- })
362
-
363
- it("should use ?| operator expression for PostgreSQL when filter is containsAny", () => {
364
- const query = new Sql(SqlClient.POSTGRES, 10)._query(generateReadJson({
365
- filters: {
366
- containsAny: {
367
- age: [20, 25],
368
- name: ["John", "Mary"]
369
- }
370
- }
371
- }))
372
- expect(query).toEqual({
373
- bindings: [10],
374
- sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb ?| array [20,25] and \"${TABLE_NAME}\".\"name\"::jsonb ?| array ['John','Mary'] limit $1) as \"${TABLE_NAME}\"`
375
- })
376
- })
377
287
  })
@@ -13,13 +13,10 @@ function validate(schema, property) {
13
13
  params = ctx.request[property]
14
14
  }
15
15
 
16
- // not all schemas have the append property e.g. array schemas
17
- if (schema.append) {
18
- schema = schema.append({
19
- createdAt: Joi.any().optional(),
20
- updatedAt: Joi.any().optional(),
21
- })
22
- }
16
+ schema = schema.append({
17
+ createdAt: Joi.any().optional(),
18
+ updatedAt: Joi.any().optional(),
19
+ })
23
20
 
24
21
  const { error } = schema.validate(params)
25
22
  if (error) {
@@ -106,6 +106,5 @@ export class Thread {
106
106
 
107
107
  static async shutdown() {
108
108
  await Thread.stopThreads()
109
- console.log("Threads shutdown")
110
109
  }
111
110
  }