@budibase/server 1.0.27-alpha.2 → 1.0.27-alpha.20

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 (350) hide show
  1. package/__mocks__/node-fetch.ts +18 -0
  2. package/builder/assets/{index.5522fcd5.css → index.39e01193.css} +1 -1
  3. package/builder/assets/{index.e9e2c4d7.js → index.c5bf8ef6.js} +247 -242
  4. package/builder/assets/{vendor.f9faf6ab.js → vendor.10e2ad1b.js} +12 -12
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +1128 -968
  7. package/coverage/coverage-final.json +70 -70
  8. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +3 -3
  10. package/coverage/lcov-report/api/controllers/application.js.html +73 -64
  11. package/coverage/lcov-report/api/controllers/auth.js.html +2 -2
  12. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/cloud.js.html +13 -4
  15. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/datasource.js.html +150 -48
  17. package/coverage/lcov-report/api/controllers/dev.js.html +3 -3
  18. package/coverage/lcov-report/api/controllers/hosting.js.html +3 -3
  19. package/coverage/lcov-report/api/controllers/index.html +20 -20
  20. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
  24. package/coverage/lcov-report/api/controllers/query/index.html +21 -21
  25. package/coverage/lcov-report/api/controllers/query/index.js.html +102 -120
  26. package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -3
  27. package/coverage/lcov-report/api/controllers/role.js.html +2 -2
  28. package/coverage/lcov-report/api/controllers/routing.js.html +2 -2
  29. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/index.html +11 -11
  31. package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/row/internal.js.html +38 -11
  33. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
  34. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
  36. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  39. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/user.js.html +14 -5
  44. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  45. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  46. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  48. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  49. package/coverage/lcov-report/api/controllers/webhook.js.html +2 -2
  50. package/coverage/lcov-report/api/index.html +1 -1
  51. package/coverage/lcov-report/api/index.js.html +6 -6
  52. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/apikeys.js.html +2 -2
  54. package/coverage/lcov-report/api/routes/application.js.html +2 -2
  55. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/automation.js.html +2 -2
  57. package/coverage/lcov-report/api/routes/backup.js.html +2 -2
  58. package/coverage/lcov-report/api/routes/cloud.js.html +2 -2
  59. package/coverage/lcov-report/api/routes/component.js.html +2 -2
  60. package/coverage/lcov-report/api/routes/datasource.js.html +2 -2
  61. package/coverage/lcov-report/api/routes/deploy.js.html +2 -2
  62. package/coverage/lcov-report/api/routes/dev.js.html +2 -2
  63. package/coverage/lcov-report/api/routes/hosting.js.html +2 -2
  64. package/coverage/lcov-report/api/routes/index.html +1 -1
  65. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/integration.js.html +2 -2
  67. package/coverage/lcov-report/api/routes/layout.js.html +2 -2
  68. package/coverage/lcov-report/api/routes/metadata.js.html +2 -2
  69. package/coverage/lcov-report/api/routes/permission.js.html +12 -3
  70. package/coverage/lcov-report/api/routes/query.js.html +25 -4
  71. package/coverage/lcov-report/api/routes/role.js.html +2 -2
  72. package/coverage/lcov-report/api/routes/routing.js.html +2 -2
  73. package/coverage/lcov-report/api/routes/row.js.html +2 -2
  74. package/coverage/lcov-report/api/routes/screen.js.html +2 -2
  75. package/coverage/lcov-report/api/routes/script.js.html +2 -2
  76. package/coverage/lcov-report/api/routes/static.js.html +2 -2
  77. package/coverage/lcov-report/api/routes/table.js.html +2 -2
  78. package/coverage/lcov-report/api/routes/templates.js.html +2 -2
  79. package/coverage/lcov-report/api/routes/user.js.html +2 -2
  80. package/coverage/lcov-report/api/routes/view.js.html +2 -2
  81. package/coverage/lcov-report/api/routes/webhook.js.html +2 -2
  82. package/coverage/lcov-report/automations/actions.js.html +1 -1
  83. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  84. package/coverage/lcov-report/automations/bullboard.js.html +2 -2
  85. package/coverage/lcov-report/automations/index.html +1 -1
  86. package/coverage/lcov-report/automations/index.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/executeQuery.js.html +32 -8
  93. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/index.html +11 -11
  96. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  99. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  100. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  101. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  103. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  111. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  112. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  113. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  114. package/coverage/lcov-report/automations/utils.js.html +6 -6
  115. package/coverage/lcov-report/constants/index.html +1 -1
  116. package/coverage/lcov-report/constants/index.js.html +4 -4
  117. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  118. package/coverage/lcov-report/constants/screens.js.html +2 -2
  119. package/coverage/lcov-report/db/client.js.html +2 -2
  120. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  121. package/coverage/lcov-report/db/index.html +1 -1
  122. package/coverage/lcov-report/db/index.js.html +1 -1
  123. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  124. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  125. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  126. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  127. package/coverage/lcov-report/db/newid.js.html +2 -2
  128. package/coverage/lcov-report/db/utils.js.html +19 -19
  129. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  130. package/coverage/lcov-report/events/index.html +1 -1
  131. package/coverage/lcov-report/events/index.js.html +1 -1
  132. package/coverage/lcov-report/events/utils.js.html +1 -1
  133. package/coverage/lcov-report/index.html +69 -69
  134. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  135. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  136. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  137. package/coverage/lcov-report/middleware/authorized.js.html +12 -12
  138. package/coverage/lcov-report/middleware/builder.js.html +10 -10
  139. package/coverage/lcov-report/middleware/currentapp.js.html +79 -40
  140. package/coverage/lcov-report/middleware/index.html +10 -10
  141. package/coverage/lcov-report/middleware/joi-validator.js.html +9 -9
  142. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  143. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  144. package/coverage/lcov-report/middleware/usageQuota.js.html +2 -2
  145. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  146. package/coverage/lcov-report/threads/automation.js.html +3 -3
  147. package/coverage/lcov-report/threads/index.html +31 -31
  148. package/coverage/lcov-report/threads/index.js.html +12 -12
  149. package/coverage/lcov-report/threads/query.js.html +531 -87
  150. package/coverage/lcov-report/threads/utils.js.html +210 -15
  151. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  152. package/coverage/lcov-report/utilities/budibaseDir.js.html +2 -2
  153. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  154. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  155. package/coverage/lcov-report/utilities/global.js.html +28 -19
  156. package/coverage/lcov-report/utilities/index.html +4 -4
  157. package/coverage/lcov-report/utilities/index.js.html +13 -13
  158. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
  159. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  160. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  161. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  162. package/coverage/lcov-report/utilities/rowProcessor/index.html +19 -19
  163. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +211 -10
  164. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  165. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  166. package/coverage/lcov-report/utilities/security.js.html +13 -4
  167. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  168. package/coverage/lcov-report/utilities/users.js.html +1 -1
  169. package/coverage/lcov-report/utilities/workerRequests.js.html +22 -22
  170. package/coverage/lcov.info +1921 -1630
  171. package/dist/api/controllers/apikeys.js +2 -2
  172. package/dist/api/controllers/application.js +4 -4
  173. package/dist/api/controllers/auth.js +1 -1
  174. package/dist/api/controllers/cloud.js +2 -2
  175. package/dist/api/controllers/datasource.js +29 -0
  176. package/dist/api/controllers/deploy/index.js +2 -2
  177. package/dist/api/controllers/dev.js +2 -2
  178. package/dist/api/controllers/hosting.js +2 -2
  179. package/dist/api/controllers/permission.js +2 -2
  180. package/dist/api/controllers/query/import/sources/base/index.js +2 -1
  181. package/dist/api/controllers/query/import/sources/curl.js +11 -5
  182. package/dist/api/controllers/query/import/sources/openapi2.js +8 -5
  183. package/dist/api/controllers/query/index.js +46 -47
  184. package/dist/api/controllers/query/validation.js +2 -1
  185. package/dist/api/controllers/role.js +1 -1
  186. package/dist/api/controllers/routing.js +1 -1
  187. package/dist/api/controllers/row/internal.js +14 -6
  188. package/dist/api/controllers/row/internalSearch.js +1 -1
  189. package/dist/api/controllers/screen.js +1 -1
  190. package/dist/api/controllers/user.js +3 -3
  191. package/dist/api/controllers/webhook.js +1 -1
  192. package/dist/api/index.js +1 -1
  193. package/dist/api/routes/apikeys.js +1 -1
  194. package/dist/api/routes/application.js +1 -1
  195. package/dist/api/routes/automation.js +1 -1
  196. package/dist/api/routes/backup.js +1 -1
  197. package/dist/api/routes/cloud.js +1 -1
  198. package/dist/api/routes/component.js +1 -1
  199. package/dist/api/routes/datasource.js +1 -1
  200. package/dist/api/routes/deploy.js +1 -1
  201. package/dist/api/routes/dev.js +1 -1
  202. package/dist/api/routes/hosting.js +1 -1
  203. package/dist/api/routes/integration.js +1 -1
  204. package/dist/api/routes/layout.js +1 -1
  205. package/dist/api/routes/metadata.js +1 -1
  206. package/dist/api/routes/permission.js +1 -1
  207. package/dist/api/routes/query.js +4 -2
  208. package/dist/api/routes/role.js +1 -1
  209. package/dist/api/routes/routing.js +1 -1
  210. package/dist/api/routes/row.js +1 -1
  211. package/dist/api/routes/screen.js +1 -1
  212. package/dist/api/routes/script.js +1 -1
  213. package/dist/api/routes/static.js +1 -1
  214. package/dist/api/routes/table.js +1 -1
  215. package/dist/api/routes/templates.js +1 -1
  216. package/dist/api/routes/tests/utilities/TestFunctions.js +1 -1
  217. package/dist/api/routes/user.js +1 -1
  218. package/dist/api/routes/view.js +1 -1
  219. package/dist/api/routes/webhook.js +1 -1
  220. package/dist/app.js +1 -1
  221. package/dist/automations/bullboard.js +1 -1
  222. package/dist/automations/steps/executeQuery.js +9 -2
  223. package/dist/automations/utils.js +1 -1
  224. package/dist/constants/index.js +3 -3
  225. package/dist/constants/screens.js +1 -1
  226. package/dist/db/client.js +1 -1
  227. package/dist/db/utils.js +1 -1
  228. package/dist/environment.js +1 -0
  229. package/dist/integrations/base/sqlTable.js +1 -1
  230. package/dist/integrations/dynamodb.js +19 -0
  231. package/dist/integrations/rest.js +71 -22
  232. package/dist/integrations/s3.js +17 -8
  233. package/dist/integrations/utils.js +40 -37
  234. package/dist/middleware/authorized.js +2 -2
  235. package/dist/middleware/builder.js +2 -2
  236. package/dist/middleware/currentapp.js +15 -6
  237. package/dist/middleware/usageQuota.js +1 -1
  238. package/dist/package.json +5 -4
  239. package/dist/tests/utilities/TestConfiguration.js +55 -8
  240. package/dist/tests/utilities/structures.js +2 -2
  241. package/dist/threads/automation.js +2 -2
  242. package/dist/threads/query.js +195 -50
  243. package/dist/threads/utils.js +62 -1
  244. package/dist/tsconfig.tsbuildinfo +1 -1
  245. package/dist/utilities/budibaseDir.js +1 -1
  246. package/dist/utilities/fileSystem/utilities.js +2 -1
  247. package/dist/utilities/global.js +5 -5
  248. package/dist/utilities/index.js +2 -2
  249. package/dist/utilities/redis.js +1 -1
  250. package/dist/utilities/rowProcessor/index.js +63 -0
  251. package/dist/utilities/security.js +2 -2
  252. package/dist/utilities/usageQuota.js +2 -2
  253. package/dist/utilities/workerRequests.js +3 -3
  254. package/package.json +6 -5
  255. package/scripts/replicateApp.js +1 -1
  256. package/src/api/controllers/apikeys.js +2 -2
  257. package/src/api/controllers/application.js +7 -4
  258. package/src/api/controllers/auth.js +1 -1
  259. package/src/api/controllers/cloud.js +5 -2
  260. package/src/api/controllers/datasource.js +34 -0
  261. package/src/api/controllers/deploy/index.js +2 -2
  262. package/src/api/controllers/dev.js +2 -2
  263. package/src/api/controllers/hosting.js +2 -2
  264. package/src/api/controllers/permission.js +2 -2
  265. package/src/api/controllers/query/import/sources/base/index.ts +3 -1
  266. package/src/api/controllers/query/import/sources/curl.ts +12 -4
  267. package/src/api/controllers/query/import/sources/openapi2.ts +9 -5
  268. package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +2 -3
  269. package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +6 -7
  270. package/src/api/controllers/query/import/tests/index.spec.js +0 -6
  271. package/src/api/controllers/query/index.js +49 -55
  272. package/src/api/controllers/query/validation.js +2 -1
  273. package/src/api/controllers/role.js +1 -1
  274. package/src/api/controllers/routing.js +1 -1
  275. package/src/api/controllers/row/internal.js +14 -5
  276. package/src/api/controllers/row/internalSearch.js +1 -1
  277. package/src/api/controllers/screen.js +1 -1
  278. package/src/api/controllers/user.js +6 -3
  279. package/src/api/controllers/webhook.js +1 -1
  280. package/src/api/index.js +1 -1
  281. package/src/api/routes/apikeys.js +1 -1
  282. package/src/api/routes/application.js +1 -1
  283. package/src/api/routes/automation.js +1 -1
  284. package/src/api/routes/backup.js +1 -1
  285. package/src/api/routes/cloud.js +1 -1
  286. package/src/api/routes/component.js +1 -1
  287. package/src/api/routes/datasource.js +1 -1
  288. package/src/api/routes/deploy.js +1 -1
  289. package/src/api/routes/dev.js +1 -1
  290. package/src/api/routes/hosting.js +1 -1
  291. package/src/api/routes/integration.js +1 -1
  292. package/src/api/routes/layout.js +1 -1
  293. package/src/api/routes/metadata.js +1 -1
  294. package/src/api/routes/permission.js +4 -1
  295. package/src/api/routes/query.js +9 -2
  296. package/src/api/routes/role.js +1 -1
  297. package/src/api/routes/routing.js +1 -1
  298. package/src/api/routes/row.js +1 -1
  299. package/src/api/routes/screen.js +1 -1
  300. package/src/api/routes/script.js +1 -1
  301. package/src/api/routes/static.js +1 -1
  302. package/src/api/routes/table.js +1 -1
  303. package/src/api/routes/templates.js +1 -1
  304. package/src/api/routes/tests/datasource.spec.js +45 -0
  305. package/src/api/routes/tests/permissions.spec.js +1 -1
  306. package/src/api/routes/tests/query.spec.js +70 -1
  307. package/src/api/routes/tests/role.spec.js +2 -2
  308. package/src/api/routes/tests/routing.spec.js +1 -1
  309. package/src/api/routes/tests/user.spec.js +1 -1
  310. package/src/api/routes/tests/utilities/TestFunctions.js +1 -1
  311. package/src/api/routes/user.js +1 -1
  312. package/src/api/routes/view.js +1 -1
  313. package/src/api/routes/webhook.js +1 -1
  314. package/src/app.ts +1 -1
  315. package/src/automations/bullboard.js +1 -1
  316. package/src/automations/steps/executeQuery.js +10 -2
  317. package/src/automations/utils.js +1 -1
  318. package/src/constants/index.js +3 -3
  319. package/src/constants/screens.js +1 -1
  320. package/src/db/client.js +1 -1
  321. package/src/db/utils.js +1 -1
  322. package/src/definitions/datasource.ts +25 -0
  323. package/src/environment.js +1 -0
  324. package/src/integrations/base/sqlTable.ts +1 -1
  325. package/src/integrations/dynamodb.ts +18 -0
  326. package/src/integrations/rest.ts +103 -20
  327. package/src/integrations/s3.ts +18 -7
  328. package/src/integrations/tests/rest.spec.js +287 -24
  329. package/src/integrations/utils.ts +8 -7
  330. package/src/middleware/authorized.js +2 -2
  331. package/src/middleware/builder.js +2 -2
  332. package/src/middleware/currentapp.js +20 -7
  333. package/src/middleware/tests/authorized.spec.js +2 -2
  334. package/src/middleware/tests/currentapp.spec.js +35 -41
  335. package/src/middleware/tests/usageQuota.spec.js +1 -1
  336. package/src/middleware/usageQuota.js +1 -1
  337. package/src/tests/utilities/TestConfiguration.js +65 -8
  338. package/src/tests/utilities/structures.js +2 -2
  339. package/src/threads/automation.js +2 -2
  340. package/src/threads/query.js +203 -55
  341. package/src/threads/utils.js +66 -1
  342. package/src/utilities/budibaseDir.js +1 -1
  343. package/src/utilities/fileSystem/utilities.js +3 -1
  344. package/src/utilities/global.js +8 -5
  345. package/src/utilities/index.js +2 -2
  346. package/src/utilities/redis.js +1 -1
  347. package/src/utilities/rowProcessor/index.js +67 -0
  348. package/src/utilities/security.js +5 -2
  349. package/src/utilities/usageQuota.js +2 -2
  350. package/src/utilities/workerRequests.js +3 -3
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">68.42% </span>
26
+ <span class="strong">87.06% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>26/38</span>
28
+ <span class='fraction'>101/116</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">55.55% </span>
33
+ <span class="strong">68.96% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>10/18</span>
35
+ <span class='fraction'>40/58</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">87.5% </span>
40
+ <span class="strong">92.3% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>7/8</span>
42
+ <span class='fraction'>12/13</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">69.44% </span>
47
+ <span class="strong">87.5% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>25/36</span>
49
+ <span class='fraction'>98/112</span>
50
50
  </div>
51
51
 
52
52
 
@@ -55,7 +55,7 @@
55
55
  Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
56
  </p>
57
57
  </div>
58
- <div class='status-line medium'></div>
58
+ <div class='status-line high'></div>
59
59
  <pre><table class="coverage">
60
60
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
61
61
  <a name='L2'></a><a href='#L2'>2</a>
@@ -138,161 +138,605 @@
138
138
  <a name='L79'></a><a href='#L79'>79</a>
139
139
  <a name='L80'></a><a href='#L80'>80</a>
140
140
  <a name='L81'></a><a href='#L81'>81</a>
141
- <a name='L82'></a><a href='#L82'>82</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
142
- <span class="cline-any cline-yes">1x</span>
143
- <span class="cline-any cline-yes">1x</span>
144
- <span class="cline-any cline-neutral">&nbsp;</span>
141
+ <a name='L82'></a><a href='#L82'>82</a>
142
+ <a name='L83'></a><a href='#L83'>83</a>
143
+ <a name='L84'></a><a href='#L84'>84</a>
144
+ <a name='L85'></a><a href='#L85'>85</a>
145
+ <a name='L86'></a><a href='#L86'>86</a>
146
+ <a name='L87'></a><a href='#L87'>87</a>
147
+ <a name='L88'></a><a href='#L88'>88</a>
148
+ <a name='L89'></a><a href='#L89'>89</a>
149
+ <a name='L90'></a><a href='#L90'>90</a>
150
+ <a name='L91'></a><a href='#L91'>91</a>
151
+ <a name='L92'></a><a href='#L92'>92</a>
152
+ <a name='L93'></a><a href='#L93'>93</a>
153
+ <a name='L94'></a><a href='#L94'>94</a>
154
+ <a name='L95'></a><a href='#L95'>95</a>
155
+ <a name='L96'></a><a href='#L96'>96</a>
156
+ <a name='L97'></a><a href='#L97'>97</a>
157
+ <a name='L98'></a><a href='#L98'>98</a>
158
+ <a name='L99'></a><a href='#L99'>99</a>
159
+ <a name='L100'></a><a href='#L100'>100</a>
160
+ <a name='L101'></a><a href='#L101'>101</a>
161
+ <a name='L102'></a><a href='#L102'>102</a>
162
+ <a name='L103'></a><a href='#L103'>103</a>
163
+ <a name='L104'></a><a href='#L104'>104</a>
164
+ <a name='L105'></a><a href='#L105'>105</a>
165
+ <a name='L106'></a><a href='#L106'>106</a>
166
+ <a name='L107'></a><a href='#L107'>107</a>
167
+ <a name='L108'></a><a href='#L108'>108</a>
168
+ <a name='L109'></a><a href='#L109'>109</a>
169
+ <a name='L110'></a><a href='#L110'>110</a>
170
+ <a name='L111'></a><a href='#L111'>111</a>
171
+ <a name='L112'></a><a href='#L112'>112</a>
172
+ <a name='L113'></a><a href='#L113'>113</a>
173
+ <a name='L114'></a><a href='#L114'>114</a>
174
+ <a name='L115'></a><a href='#L115'>115</a>
175
+ <a name='L116'></a><a href='#L116'>116</a>
176
+ <a name='L117'></a><a href='#L117'>117</a>
177
+ <a name='L118'></a><a href='#L118'>118</a>
178
+ <a name='L119'></a><a href='#L119'>119</a>
179
+ <a name='L120'></a><a href='#L120'>120</a>
180
+ <a name='L121'></a><a href='#L121'>121</a>
181
+ <a name='L122'></a><a href='#L122'>122</a>
182
+ <a name='L123'></a><a href='#L123'>123</a>
183
+ <a name='L124'></a><a href='#L124'>124</a>
184
+ <a name='L125'></a><a href='#L125'>125</a>
185
+ <a name='L126'></a><a href='#L126'>126</a>
186
+ <a name='L127'></a><a href='#L127'>127</a>
187
+ <a name='L128'></a><a href='#L128'>128</a>
188
+ <a name='L129'></a><a href='#L129'>129</a>
189
+ <a name='L130'></a><a href='#L130'>130</a>
190
+ <a name='L131'></a><a href='#L131'>131</a>
191
+ <a name='L132'></a><a href='#L132'>132</a>
192
+ <a name='L133'></a><a href='#L133'>133</a>
193
+ <a name='L134'></a><a href='#L134'>134</a>
194
+ <a name='L135'></a><a href='#L135'>135</a>
195
+ <a name='L136'></a><a href='#L136'>136</a>
196
+ <a name='L137'></a><a href='#L137'>137</a>
197
+ <a name='L138'></a><a href='#L138'>138</a>
198
+ <a name='L139'></a><a href='#L139'>139</a>
199
+ <a name='L140'></a><a href='#L140'>140</a>
200
+ <a name='L141'></a><a href='#L141'>141</a>
201
+ <a name='L142'></a><a href='#L142'>142</a>
202
+ <a name='L143'></a><a href='#L143'>143</a>
203
+ <a name='L144'></a><a href='#L144'>144</a>
204
+ <a name='L145'></a><a href='#L145'>145</a>
205
+ <a name='L146'></a><a href='#L146'>146</a>
206
+ <a name='L147'></a><a href='#L147'>147</a>
207
+ <a name='L148'></a><a href='#L148'>148</a>
208
+ <a name='L149'></a><a href='#L149'>149</a>
209
+ <a name='L150'></a><a href='#L150'>150</a>
210
+ <a name='L151'></a><a href='#L151'>151</a>
211
+ <a name='L152'></a><a href='#L152'>152</a>
212
+ <a name='L153'></a><a href='#L153'>153</a>
213
+ <a name='L154'></a><a href='#L154'>154</a>
214
+ <a name='L155'></a><a href='#L155'>155</a>
215
+ <a name='L156'></a><a href='#L156'>156</a>
216
+ <a name='L157'></a><a href='#L157'>157</a>
217
+ <a name='L158'></a><a href='#L158'>158</a>
218
+ <a name='L159'></a><a href='#L159'>159</a>
219
+ <a name='L160'></a><a href='#L160'>160</a>
220
+ <a name='L161'></a><a href='#L161'>161</a>
221
+ <a name='L162'></a><a href='#L162'>162</a>
222
+ <a name='L163'></a><a href='#L163'>163</a>
223
+ <a name='L164'></a><a href='#L164'>164</a>
224
+ <a name='L165'></a><a href='#L165'>165</a>
225
+ <a name='L166'></a><a href='#L166'>166</a>
226
+ <a name='L167'></a><a href='#L167'>167</a>
227
+ <a name='L168'></a><a href='#L168'>168</a>
228
+ <a name='L169'></a><a href='#L169'>169</a>
229
+ <a name='L170'></a><a href='#L170'>170</a>
230
+ <a name='L171'></a><a href='#L171'>171</a>
231
+ <a name='L172'></a><a href='#L172'>172</a>
232
+ <a name='L173'></a><a href='#L173'>173</a>
233
+ <a name='L174'></a><a href='#L174'>174</a>
234
+ <a name='L175'></a><a href='#L175'>175</a>
235
+ <a name='L176'></a><a href='#L176'>176</a>
236
+ <a name='L177'></a><a href='#L177'>177</a>
237
+ <a name='L178'></a><a href='#L178'>178</a>
238
+ <a name='L179'></a><a href='#L179'>179</a>
239
+ <a name='L180'></a><a href='#L180'>180</a>
240
+ <a name='L181'></a><a href='#L181'>181</a>
241
+ <a name='L182'></a><a href='#L182'>182</a>
242
+ <a name='L183'></a><a href='#L183'>183</a>
243
+ <a name='L184'></a><a href='#L184'>184</a>
244
+ <a name='L185'></a><a href='#L185'>185</a>
245
+ <a name='L186'></a><a href='#L186'>186</a>
246
+ <a name='L187'></a><a href='#L187'>187</a>
247
+ <a name='L188'></a><a href='#L188'>188</a>
248
+ <a name='L189'></a><a href='#L189'>189</a>
249
+ <a name='L190'></a><a href='#L190'>190</a>
250
+ <a name='L191'></a><a href='#L191'>191</a>
251
+ <a name='L192'></a><a href='#L192'>192</a>
252
+ <a name='L193'></a><a href='#L193'>193</a>
253
+ <a name='L194'></a><a href='#L194'>194</a>
254
+ <a name='L195'></a><a href='#L195'>195</a>
255
+ <a name='L196'></a><a href='#L196'>196</a>
256
+ <a name='L197'></a><a href='#L197'>197</a>
257
+ <a name='L198'></a><a href='#L198'>198</a>
258
+ <a name='L199'></a><a href='#L199'>199</a>
259
+ <a name='L200'></a><a href='#L200'>200</a>
260
+ <a name='L201'></a><a href='#L201'>201</a>
261
+ <a name='L202'></a><a href='#L202'>202</a>
262
+ <a name='L203'></a><a href='#L203'>203</a>
263
+ <a name='L204'></a><a href='#L204'>204</a>
264
+ <a name='L205'></a><a href='#L205'>205</a>
265
+ <a name='L206'></a><a href='#L206'>206</a>
266
+ <a name='L207'></a><a href='#L207'>207</a>
267
+ <a name='L208'></a><a href='#L208'>208</a>
268
+ <a name='L209'></a><a href='#L209'>209</a>
269
+ <a name='L210'></a><a href='#L210'>210</a>
270
+ <a name='L211'></a><a href='#L211'>211</a>
271
+ <a name='L212'></a><a href='#L212'>212</a>
272
+ <a name='L213'></a><a href='#L213'>213</a>
273
+ <a name='L214'></a><a href='#L214'>214</a>
274
+ <a name='L215'></a><a href='#L215'>215</a>
275
+ <a name='L216'></a><a href='#L216'>216</a>
276
+ <a name='L217'></a><a href='#L217'>217</a>
277
+ <a name='L218'></a><a href='#L218'>218</a>
278
+ <a name='L219'></a><a href='#L219'>219</a>
279
+ <a name='L220'></a><a href='#L220'>220</a>
280
+ <a name='L221'></a><a href='#L221'>221</a>
281
+ <a name='L222'></a><a href='#L222'>222</a>
282
+ <a name='L223'></a><a href='#L223'>223</a>
283
+ <a name='L224'></a><a href='#L224'>224</a>
284
+ <a name='L225'></a><a href='#L225'>225</a>
285
+ <a name='L226'></a><a href='#L226'>226</a>
286
+ <a name='L227'></a><a href='#L227'>227</a>
287
+ <a name='L228'></a><a href='#L228'>228</a>
288
+ <a name='L229'></a><a href='#L229'>229</a>
289
+ <a name='L230'></a><a href='#L230'>230</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">2x</span>
290
+ <span class="cline-any cline-yes">2x</span>
291
+ <span class="cline-any cline-yes">2x</span>
292
+ <span class="cline-any cline-yes">2x</span>
293
+ <span class="cline-any cline-yes">2x</span>
294
+ <span class="cline-any cline-yes">2x</span>
145
295
  <span class="cline-any cline-neutral">&nbsp;</span>
146
296
  <span class="cline-any cline-yes">2x</span>
297
+ <span class="cline-any cline-yes">2x</span>
298
+ <span class="cline-any cline-neutral">&nbsp;</span>
299
+ <span class="cline-any cline-neutral">&nbsp;</span>
300
+ <span class="cline-any cline-neutral">&nbsp;</span>
301
+ <span class="cline-any cline-yes">15x</span>
302
+ <span class="cline-any cline-yes">15x</span>
303
+ <span class="cline-any cline-yes">15x</span>
304
+ <span class="cline-any cline-yes">15x</span>
305
+ <span class="cline-any cline-yes">15x</span>
306
+ <span class="cline-any cline-yes">15x</span>
307
+ <span class="cline-any cline-yes">15x</span>
308
+ <span class="cline-any cline-yes">15x</span>
309
+ <span class="cline-any cline-yes">15x</span>
310
+ <span class="cline-any cline-yes">15x</span>
311
+ <span class="cline-any cline-neutral">&nbsp;</span>
312
+ <span class="cline-any cline-neutral">&nbsp;</span>
313
+ <span class="cline-any cline-neutral">&nbsp;</span>
314
+ <span class="cline-any cline-yes">15x</span>
315
+ <span class="cline-any cline-yes">15x</span>
316
+ <span class="cline-any cline-neutral">&nbsp;</span>
317
+ <span class="cline-any cline-neutral">&nbsp;</span>
318
+ <span class="cline-any cline-neutral">&nbsp;</span>
319
+ <span class="cline-any cline-yes">16x</span>
320
+ <span class="cline-any cline-neutral">&nbsp;</span>
321
+ <span class="cline-any cline-yes">16x</span>
322
+ <span class="cline-any cline-yes">16x</span>
323
+ <span class="cline-any cline-neutral">&nbsp;</span>
324
+ <span class="cline-any cline-neutral">&nbsp;</span>
325
+ <span class="cline-any cline-yes">16x</span>
147
326
  <span class="cline-any cline-no">&nbsp;</span>
327
+ <span class="cline-any cline-neutral">&nbsp;</span>
328
+ <span class="cline-any cline-neutral">&nbsp;</span>
329
+ <span class="cline-any cline-yes">16x</span>
330
+ <span class="cline-any cline-yes">16x</span>
331
+ <span class="cline-any cline-yes">2x</span>
332
+ <span class="cline-any cline-neutral">&nbsp;</span>
333
+ <span class="cline-any cline-yes">14x</span>
334
+ <span class="cline-any cline-neutral">&nbsp;</span>
335
+ <span class="cline-any cline-yes">14x</span>
336
+ <span class="cline-any cline-yes">14x</span>
337
+ <span class="cline-any cline-yes">14x</span>
338
+ <span class="cline-any cline-yes">14x</span>
339
+ <span class="cline-any cline-yes">14x</span>
340
+ <span class="cline-any cline-yes">14x</span>
341
+ <span class="cline-any cline-yes">12x</span>
342
+ <span class="cline-any cline-yes">12x</span>
343
+ <span class="cline-any cline-yes">12x</span>
344
+ <span class="cline-any cline-yes">12x</span>
345
+ <span class="cline-any cline-neutral">&nbsp;</span>
346
+ <span class="cline-any cline-neutral">&nbsp;</span>
347
+ <span class="cline-any cline-neutral">&nbsp;</span>
348
+ <span class="cline-any cline-yes">14x</span>
148
349
  <span class="cline-any cline-no">&nbsp;</span>
149
350
  <span class="cline-any cline-neutral">&nbsp;</span>
351
+ <span class="cline-any cline-neutral">&nbsp;</span>
352
+ <span class="cline-any cline-neutral">&nbsp;</span>
150
353
  <span class="cline-any cline-no">&nbsp;</span>
151
354
  <span class="cline-any cline-neutral">&nbsp;</span>
152
355
  <span class="cline-any cline-neutral">&nbsp;</span>
153
- <span class="cline-any cline-yes">2x</span>
154
356
  <span class="cline-any cline-neutral">&nbsp;</span>
357
+ <span class="cline-any cline-yes">14x</span>
155
358
  <span class="cline-any cline-neutral">&nbsp;</span>
156
359
  <span class="cline-any cline-neutral">&nbsp;</span>
157
- <span class="cline-any cline-yes">2x</span>
158
360
  <span class="cline-any cline-neutral">&nbsp;</span>
159
361
  <span class="cline-any cline-neutral">&nbsp;</span>
160
362
  <span class="cline-any cline-neutral">&nbsp;</span>
363
+ <span class="cline-any cline-yes">1x</span>
161
364
  <span class="cline-any cline-neutral">&nbsp;</span>
365
+ <span class="cline-any cline-yes">1x</span>
366
+ <span class="cline-any cline-yes">1x</span>
162
367
  <span class="cline-any cline-neutral">&nbsp;</span>
163
368
  <span class="cline-any cline-neutral">&nbsp;</span>
164
369
  <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-yes">13x</span>
371
+ <span class="cline-any cline-yes">11x</span>
165
372
  <span class="cline-any cline-neutral">&nbsp;</span>
166
- <span class="cline-any cline-yes">4x</span>
167
- <span class="cline-any cline-yes">4x</span>
168
- <span class="cline-any cline-yes">2x</span>
169
373
  <span class="cline-any cline-neutral">&nbsp;</span>
170
- <span class="cline-any cline-yes">2x</span>
171
374
  <span class="cline-any cline-neutral">&nbsp;</span>
172
- <span class="cline-any cline-yes">2x</span>
173
- <span class="cline-any cline-yes">2x</span>
174
- <span class="cline-any cline-yes">2x</span>
175
- <span class="cline-any cline-yes">2x</span>
176
- <span class="cline-any cline-yes">2x</span>
177
- <span class="cline-any cline-no">&nbsp;</span>
375
+ <span class="cline-any cline-yes">13x</span>
178
376
  <span class="cline-any cline-no">&nbsp;</span>
377
+ <span class="cline-any cline-neutral">&nbsp;</span>
378
+ <span class="cline-any cline-neutral">&nbsp;</span>
379
+ <span class="cline-any cline-neutral">&nbsp;</span>
380
+ <span class="cline-any cline-yes">13x</span>
381
+ <span class="cline-any cline-neutral">&nbsp;</span>
382
+ <span class="cline-any cline-yes">13x</span>
179
383
  <span class="cline-any cline-no">&nbsp;</span>
180
384
  <span class="cline-any cline-neutral">&nbsp;</span>
181
385
  <span class="cline-any cline-neutral">&nbsp;</span>
386
+ <span class="cline-any cline-yes">13x</span>
387
+ <span class="cline-any cline-neutral">&nbsp;</span>
388
+ <span class="cline-any cline-neutral">&nbsp;</span>
389
+ <span class="cline-any cline-neutral">&nbsp;</span>
390
+ <span class="cline-any cline-yes">5x</span>
391
+ <span class="cline-any cline-yes">5x</span>
392
+ <span class="cline-any cline-yes">5x</span>
393
+ <span class="cline-any cline-yes">5x</span>
394
+ <span class="cline-any cline-neutral">&nbsp;</span>
395
+ <span class="cline-any cline-neutral">&nbsp;</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</span>
397
+ <span class="cline-any cline-neutral">&nbsp;</span>
398
+ <span class="cline-any cline-neutral">&nbsp;</span>
399
+ <span class="cline-any cline-neutral">&nbsp;</span>
400
+ <span class="cline-any cline-neutral">&nbsp;</span>
401
+ <span class="cline-any cline-neutral">&nbsp;</span>
402
+ <span class="cline-any cline-neutral">&nbsp;</span>
403
+ <span class="cline-any cline-neutral">&nbsp;</span>
404
+ <span class="cline-any cline-neutral">&nbsp;</span>
405
+ <span class="cline-any cline-neutral">&nbsp;</span>
406
+ <span class="cline-any cline-neutral">&nbsp;</span>
407
+ <span class="cline-any cline-yes">6x</span>
408
+ <span class="cline-any cline-yes">6x</span>
409
+ <span class="cline-any cline-yes">6x</span>
410
+ <span class="cline-any cline-yes">6x</span>
411
+ <span class="cline-any cline-yes">6x</span>
412
+ <span class="cline-any cline-yes">5x</span>
413
+ <span class="cline-any cline-neutral">&nbsp;</span>
414
+ <span class="cline-any cline-neutral">&nbsp;</span>
415
+ <span class="cline-any cline-neutral">&nbsp;</span>
416
+ <span class="cline-any cline-yes">5x</span>
417
+ <span class="cline-any cline-yes">5x</span>
418
+ <span class="cline-any cline-neutral">&nbsp;</span>
419
+ <span class="cline-any cline-yes">1x</span>
420
+ <span class="cline-any cline-neutral">&nbsp;</span>
421
+ <span class="cline-any cline-yes">6x</span>
422
+ <span class="cline-any cline-neutral">&nbsp;</span>
182
423
  <span class="cline-any cline-neutral">&nbsp;</span>
424
+ <span class="cline-any cline-neutral">&nbsp;</span>
425
+ <span class="cline-any cline-yes">16x</span>
426
+ <span class="cline-any cline-yes">16x</span>
427
+ <span class="cline-any cline-no">&nbsp;</span>
428
+ <span class="cline-any cline-neutral">&nbsp;</span>
429
+ <span class="cline-any cline-yes">16x</span>
430
+ <span class="cline-any cline-yes">16x</span>
431
+ <span class="cline-any cline-yes">16x</span>
432
+ <span class="cline-any cline-yes">2x</span>
183
433
  <span class="cline-any cline-yes">2x</span>
434
+ <span class="cline-any cline-neutral">&nbsp;</span>
435
+ <span class="cline-any cline-neutral">&nbsp;</span>
436
+ <span class="cline-any cline-yes">16x</span>
437
+ <span class="cline-any cline-neutral">&nbsp;</span>
438
+ <span class="cline-any cline-yes">11x</span>
439
+ <span class="cline-any cline-yes">11x</span>
440
+ <span class="cline-any cline-neutral">&nbsp;</span>
441
+ <span class="cline-any cline-yes">6x</span>
184
442
  <span class="cline-any cline-no">&nbsp;</span>
443
+ <span class="cline-any cline-neutral">&nbsp;</span>
444
+ <span class="cline-any cline-neutral">&nbsp;</span>
445
+ <span class="cline-any cline-yes">6x</span>
446
+ <span class="cline-any cline-yes">6x</span>
447
+ <span class="cline-any cline-neutral">&nbsp;</span>
448
+ <span class="cline-any cline-yes">11x</span>
449
+ <span class="cline-any cline-yes">11x</span>
450
+ <span class="cline-any cline-yes">11x</span>
451
+ <span class="cline-any cline-yes">6x</span>
452
+ <span class="cline-any cline-yes">6x</span>
453
+ <span class="cline-any cline-neutral">&nbsp;</span>
454
+ <span class="cline-any cline-neutral">&nbsp;</span>
455
+ <span class="cline-any cline-neutral">&nbsp;</span>
456
+ <span class="cline-any cline-neutral">&nbsp;</span>
457
+ <span class="cline-any cline-yes">6x</span>
458
+ <span class="cline-any cline-neutral">&nbsp;</span>
459
+ <span class="cline-any cline-neutral">&nbsp;</span>
460
+ <span class="cline-any cline-yes">16x</span>
461
+ <span class="cline-any cline-neutral">&nbsp;</span>
462
+ <span class="cline-any cline-neutral">&nbsp;</span>
463
+ <span class="cline-any cline-neutral">&nbsp;</span>
464
+ <span class="cline-any cline-yes">16x</span>
465
+ <span class="cline-any cline-neutral">&nbsp;</span>
466
+ <span class="cline-any cline-neutral">&nbsp;</span>
467
+ <span class="cline-any cline-yes">16x</span>
468
+ <span class="cline-any cline-yes">19x</span>
185
469
  <span class="cline-any cline-no">&nbsp;</span>
186
470
  <span class="cline-any cline-neutral">&nbsp;</span>
471
+ <span class="cline-any cline-yes">19x</span>
187
472
  <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-no">&nbsp;</span>
474
+ <span class="cline-any cline-yes">19x</span>
188
475
  <span class="cline-any cline-neutral">&nbsp;</span>
189
- <span class="cline-any cline-yes">2x</span>
476
+ <span class="cline-any cline-yes">19x</span>
477
+ <span class="cline-any cline-neutral">&nbsp;</span>
478
+ <span class="cline-any cline-yes">19x</span>
190
479
  <span class="cline-any cline-no">&nbsp;</span>
191
480
  <span class="cline-any cline-neutral">&nbsp;</span>
481
+ <span class="cline-any cline-yes">19x</span>
482
+ <span class="cline-any cline-neutral">&nbsp;</span>
192
483
  <span class="cline-any cline-neutral">&nbsp;</span>
193
484
  <span class="cline-any cline-neutral">&nbsp;</span>
194
- <span class="cline-any cline-yes">2x</span>
195
485
  <span class="cline-any cline-no">&nbsp;</span>
196
486
  <span class="cline-any cline-neutral">&nbsp;</span>
197
487
  <span class="cline-any cline-neutral">&nbsp;</span>
488
+ <span class="cline-any cline-yes">16x</span>
198
489
  <span class="cline-any cline-neutral">&nbsp;</span>
199
- <span class="cline-any cline-yes">2x</span>
200
490
  <span class="cline-any cline-neutral">&nbsp;</span>
201
- <span class="cline-any cline-yes">2x</span>
491
+ <span class="cline-any cline-neutral">&nbsp;</span>
492
+ <span class="cline-any cline-neutral">&nbsp;</span>
493
+ <span class="cline-any cline-no">&nbsp;</span>
202
494
  <span class="cline-any cline-no">&nbsp;</span>
203
495
  <span class="cline-any cline-neutral">&nbsp;</span>
204
496
  <span class="cline-any cline-neutral">&nbsp;</span>
205
- <span class="cline-any cline-yes">2x</span>
206
497
  <span class="cline-any cline-neutral">&nbsp;</span>
207
498
  <span class="cline-any cline-neutral">&nbsp;</span>
208
- <span class="cline-any cline-yes">1x</span>
209
- <span class="cline-any cline-yes">4x</span>
210
499
  <span class="cline-any cline-neutral">&nbsp;</span>
211
500
  <span class="cline-any cline-neutral">&nbsp;</span>
212
501
  <span class="cline-any cline-neutral">&nbsp;</span>
502
+ <span class="cline-any cline-no">&nbsp;</span>
503
+ <span class="cline-any cline-neutral">&nbsp;</span>
504
+ <span class="cline-any cline-yes">16x</span>
213
505
  <span class="cline-any cline-neutral">&nbsp;</span>
214
506
  <span class="cline-any cline-neutral">&nbsp;</span>
215
507
  <span class="cline-any cline-neutral">&nbsp;</span>
216
508
  <span class="cline-any cline-yes">2x</span>
509
+ <span class="cline-any cline-yes">10x</span>
510
+ <span class="cline-any cline-yes">10x</span>
511
+ <span class="cline-any cline-neutral">&nbsp;</span>
512
+ <span class="cline-any cline-yes">8x</span>
217
513
  <span class="cline-any cline-neutral">&nbsp;</span>
218
514
  <span class="cline-any cline-neutral">&nbsp;</span>
219
515
  <span class="cline-any cline-yes">2x</span>
220
516
  <span class="cline-any cline-neutral">&nbsp;</span>
221
517
  <span class="cline-any cline-neutral">&nbsp;</span>
222
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">require("./utils").threadSetup()
518
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const threadUtils = require("./utils")
519
+ threadUtils.threadSetup()
223
520
  const ScriptRunner = require("../utilities/scriptRunner")
224
521
  const { integrations } = require("../integrations")
522
+ const { processStringSync } = require("@budibase/string-templates")
523
+ const CouchDB = require("../db")
225
524
  &nbsp;
226
- function formatResponse(resp) {
227
- <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof resp === "string") {
228
- <span class="cstat-no" title="statement not covered" > try {</span>
229
- <span class="cstat-no" title="statement not covered" > resp = JSON.parse(resp)</span>
230
- } catch (err) {
231
- <span class="cstat-no" title="statement not covered" > resp = { response: resp }</span>
232
- }
525
+ const IS_TRIPLE_BRACE = new RegExp(/^{{3}.*}{3}$/)
526
+ const IS_HANDLEBARS = new RegExp(/^{{2}.*}{2}$/)
527
+ &nbsp;
528
+ class QueryRunner {
529
+ constructor(input, flags = { noRecursiveQuery: false }) {
530
+ this.appId = input.appId
531
+ this.datasource = input.datasource
532
+ this.queryVerb = input.queryVerb
533
+ this.fields = input.fields
534
+ this.parameters = input.parameters
535
+ this.pagination = input.pagination
536
+ this.transformer = input.transformer
537
+ this.queryId = input.queryId
538
+ this.noRecursiveQuery = flags.noRecursiveQuery
539
+ this.cachedVariables = []
540
+ // allows the response from a query to be stored throughout this
541
+ // execution so that if it needs to be re-used for another variable
542
+ // it can be
543
+ this.queryResponse = {}
544
+ this.hasRerun = false
233
545
  }
234
- return resp
235
- }
236
546
  &nbsp;
237
- function hasExtraData(response) {
238
- return (
239
- typeof response === "object" &amp;&amp;
240
- !Array.isArray(response) &amp;&amp;
241
- <span class="branch-2 cbranch-no" title="branch not covered" > response.data != null </span>&amp;&amp;
242
- <span class="branch-3 cbranch-no" title="branch not covered" > response.info != null</span>
243
- )
244
- }
547
+ async execute() {
548
+ let { datasource, fields, queryVerb, transformer } = this
549
+ // pre-query, make sure datasource variables are added to parameters
550
+ const parameters = await this.addDatasourceVariables()
551
+ let query = this.enrichQueryFields(fields, parameters)
245
552
  &nbsp;
246
- async function runAndTransform(datasource, queryVerb, query, transformer) {
247
- const Integration = integrations[datasource.source]
248
- if (!Integration) {
249
- throw "Integration type does not exist."
250
- }
251
- const integration = new Integration(datasource.config)
553
+ // Add pagination values for REST queries
554
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (this.pagination) {
555
+ <span class="cstat-no" title="statement not covered" > query.paginationValues = this.pagination</span>
556
+ }
252
557
  &nbsp;
253
- let output = formatResponse(await integration[queryVerb](query))
254
- let rows = output,
255
- info = undefined,
256
- extra = undefined
257
- <span class="missing-if-branch" title="if path not taken" >I</span>if (hasExtraData(output)) {
258
- <span class="cstat-no" title="statement not covered" > rows = output.data</span>
259
- <span class="cstat-no" title="statement not covered" > info = output.info</span>
260
- <span class="cstat-no" title="statement not covered" > extra = output.extra</span>
558
+ const Integration = integrations[datasource.source]
559
+ if (!Integration) {
560
+ throw "Integration type does not exist."
561
+ }
562
+ const integration = new Integration(datasource.config)
563
+ &nbsp;
564
+ let output = threadUtils.formatResponse(await integration[queryVerb](query))
565
+ let rows = output,
566
+ info = undefined,
567
+ extra = undefined,
568
+ pagination = undefined
569
+ if (threadUtils.hasExtraData(output)) {
570
+ rows = output.data
571
+ info = output.info
572
+ extra = output.extra
573
+ pagination = output.pagination
574
+ }
575
+ &nbsp;
576
+ // transform as required
577
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (transformer) {
578
+ const runner = <span class="cstat-no" title="statement not covered" >new ScriptRunner(transformer, {</span>
579
+ data: rows,
580
+ params: parameters,
581
+ })
582
+ <span class="cstat-no" title="statement not covered" > rows = runner.execute()</span>
583
+ }
584
+ &nbsp;
585
+ // if the request fails we retry once, invalidating the cached value
586
+ if (
587
+ info &amp;&amp;
588
+ info.code &gt;= 400 &amp;&amp;
589
+ this.cachedVariables.length &gt; 0 &amp;&amp;
590
+ !this.hasRerun
591
+ ) {
592
+ this.hasRerun = true
593
+ // invalidate the cache value
594
+ await threadUtils.invalidateDynamicVariables(this.cachedVariables)
595
+ return this.execute()
596
+ }
597
+ &nbsp;
598
+ // needs to an array for next step
599
+ if (!Array.isArray(rows)) {
600
+ rows = [rows]
601
+ }
602
+ &nbsp;
603
+ // map into JSON if just raw primitive here
604
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (rows.find(row =&gt; typeof row !== "object")) {
605
+ <span class="cstat-no" title="statement not covered" > rows = rows.map(<span class="fstat-no" title="function not covered" >va</span>lue =&gt; (<span class="cstat-no" title="statement not covered" >{ value })</span>)</span>
606
+ }
607
+ &nbsp;
608
+ // get all the potential fields in the schema
609
+ let keys = rows.flatMap(Object.keys)
610
+ &nbsp;
611
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (integration.end) {
612
+ <span class="cstat-no" title="statement not covered" > integration.end()</span>
613
+ }
614
+ &nbsp;
615
+ return { rows, keys, info, extra, pagination }
261
616
  }
262
617
  &nbsp;
263
- // transform as required
264
- <span class="missing-if-branch" title="if path not taken" >I</span>if (transformer) {
265
- const runner = <span class="cstat-no" title="statement not covered" >new ScriptRunner(transformer, { data: rows })</span>
266
- <span class="cstat-no" title="statement not covered" > rows = runner.execute()</span>
618
+ async runAnotherQuery(queryId, parameters) {
619
+ const db = new CouchDB(this.appId)
620
+ const query = await db.get(queryId)
621
+ const datasource = await db.get(query.datasourceId)
622
+ return new QueryRunner(
623
+ {
624
+ appId: this.appId,
625
+ datasource,
626
+ queryVerb: query.queryVerb,
627
+ fields: query.fields,
628
+ parameters,
629
+ transformer: query.transformer,
630
+ },
631
+ { noRecursiveQuery: true }
632
+ ).execute()
267
633
  }
268
634
  &nbsp;
269
- // needs to an array for next step
270
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!Array.isArray(rows)) {
271
- <span class="cstat-no" title="statement not covered" > rows = [rows]</span>
635
+ async getDynamicVariable(variable) {
636
+ let { parameters } = this
637
+ const queryId = variable.queryId,
638
+ name = variable.name
639
+ let value = await threadUtils.checkCacheForDynamicVariable(queryId, name)
640
+ if (!value) {
641
+ value = this.queryResponse[queryId]
642
+ ? <span class="branch-0 cbranch-no" title="branch not covered" >this.queryResponse[queryId]</span>
643
+ : await this.runAnotherQuery(queryId, parameters)
644
+ // store incase this query is to be called again
645
+ this.queryResponse[queryId] = value
646
+ await threadUtils.storeDynamicVariable(queryId, name, value)
647
+ } else {
648
+ this.cachedVariables.push({ queryId, name })
649
+ }
650
+ return value
272
651
  }
273
652
  &nbsp;
274
- // map into JSON if just raw primitive here
275
- <span class="missing-if-branch" title="if path not taken" >I</span>if (rows.find(row =&gt; typeof row !== "object")) {
276
- <span class="cstat-no" title="statement not covered" > rows = rows.map(<span class="fstat-no" title="function not covered" >va</span>lue =&gt; (<span class="cstat-no" title="statement not covered" >{ value })</span>)</span>
653
+ async addDatasourceVariables() {
654
+ let { datasource, parameters, fields } = this
655
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!datasource || !datasource.config) {
656
+ <span class="cstat-no" title="statement not covered" > return parameters</span>
657
+ }
658
+ const staticVars = datasource.config.staticVariables || {}
659
+ const dynamicVars = datasource.config.dynamicVariables || []
660
+ for (let [key, value] of Object.entries(staticVars)) {
661
+ if (!parameters[key]) {
662
+ parameters[key] = value
663
+ }
664
+ }
665
+ if (!this.noRecursiveQuery) {
666
+ // need to see if this uses any variables
667
+ const stringFields = JSON.stringify(fields)
668
+ const foundVars = dynamicVars.filter(variable =&gt; {
669
+ // don't allow a query to use its own dynamic variable (loop)
670
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (variable.queryId === this.queryId) {
671
+ <span class="cstat-no" title="statement not covered" > return false</span>
672
+ }
673
+ // look for {{ variable }} but allow spaces between handlebars
674
+ const regex = new RegExp(`{{[ ]*${variable.name}[ ]*}}`)
675
+ return regex.test(stringFields)
676
+ })
677
+ const dynamics = foundVars.map(dynVar =&gt; this.getDynamicVariable(dynVar))
678
+ const responses = await Promise.all(dynamics)
679
+ for (let i = 0; i &lt; foundVars.length; i++) {
680
+ const variable = foundVars[i]
681
+ parameters[variable.name] = processStringSync(variable.value, {
682
+ data: responses[i].rows,
683
+ info: responses[i].extra,
684
+ })
685
+ // make sure its known that this uses dynamic variables in case it fails
686
+ this.hasDynamicVariables = true
687
+ }
688
+ }
689
+ return parameters
277
690
  }
278
691
  &nbsp;
279
- // get all the potential fields in the schema
280
- let keys = rows.flatMap(Object.keys)
692
+ enrichQueryFields(fields, parameters = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span> {
693
+ const enrichedQuery = {}
281
694
  &nbsp;
282
- <span class="missing-if-branch" title="if path not taken" >I</span>if (integration.end) {
283
- <span class="cstat-no" title="statement not covered" > integration.end()</span>
695
+ // enrich the fields with dynamic parameters
696
+ for (let key of Object.keys(fields)) {
697
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (fields[key] == null) {
698
+ <span class="cstat-no" title="statement not covered" > continue</span>
699
+ }
700
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof fields[key] === "object") {
701
+ // enrich nested fields object
702
+ <span class="cstat-no" title="statement not covered" > enrichedQuery[key] = this.enrichQueryFields(fields[key], parameters)</span>
703
+ } else if (typeof fields[key] === "string") {
704
+ // enrich string value as normal
705
+ let value = fields[key]
706
+ // add triple brace to avoid escaping e.g. '=' in cookie header
707
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (IS_HANDLEBARS.test(value) &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >!IS_TRIPLE_BRACE.test(value))</span> {
708
+ <span class="cstat-no" title="statement not covered" > value = `{${value}}`</span>
709
+ }
710
+ enrichedQuery[key] = processStringSync(value, parameters, {
711
+ noHelpers: true,
712
+ })
713
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
714
+ <span class="cstat-no" title="statement not covered" > enrichedQuery[key] = fields[key]</span>
715
+ }
716
+ }
717
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (
718
+ enrichedQuery.json ||
719
+ enrichedQuery.customData ||
720
+ enrichedQuery.requestBody
721
+ ) {
722
+ <span class="cstat-no" title="statement not covered" > try {</span>
723
+ <span class="cstat-no" title="statement not covered" > enrichedQuery.json = JSON.parse(</span>
724
+ enrichedQuery.json ||
725
+ enrichedQuery.customData ||
726
+ enrichedQuery.requestBody
727
+ )
728
+ } catch (err) {
729
+ // no json found, ignore
730
+ }
731
+ <span class="cstat-no" title="statement not covered" > delete enrichedQuery.customData</span>
732
+ }
733
+ return enrichedQuery
284
734
  }
285
- &nbsp;
286
- return { rows, keys, info, extra }
287
735
  }
288
736
  &nbsp;
289
737
  module.exports = (input, callback) =&gt; {
290
- runAndTransform(
291
- input.datasource,
292
- input.queryVerb,
293
- input.query,
294
- input.transformer
295
- )
738
+ const Runner = new QueryRunner(input)
739
+ Runner.execute()
296
740
  .then(response =&gt; {
297
741
  callback(null, response)
298
742
  })
@@ -307,7 +751,7 @@ module.exports = (input, callback) =&gt; {
307
751
  <div class='footer quiet pad2 space-top1 center small'>
308
752
  Code coverage generated by
309
753
  <a href="https://istanbul.js.org/" target="_blank">istanbul</a>
310
- at Tue Jan 04 2022 11:51:46 GMT+0000 (Coordinated Universal Time)
754
+ at Mon Jan 17 2022 10:15:07 GMT+0000 (Coordinated Universal Time)
311
755
  </div>
312
756
  </div>
313
757
  <script src="../prettify.js"></script>