velocious 1.0.431 → 1.0.433

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 (794) hide show
  1. package/build/application.js +229 -0
  2. package/build/authorization/ability.js +329 -0
  3. package/build/authorization/base-resource.js +143 -0
  4. package/build/background-jobs/client.js +50 -0
  5. package/build/background-jobs/cron-expression.js +277 -0
  6. package/build/background-jobs/forked-runner-child.js +86 -0
  7. package/build/background-jobs/job-record.js +13 -0
  8. package/build/background-jobs/job-registry.js +92 -0
  9. package/build/background-jobs/job-runner.js +107 -0
  10. package/build/background-jobs/job.js +77 -0
  11. package/build/background-jobs/json-socket.js +78 -0
  12. package/build/background-jobs/main.js +926 -0
  13. package/build/background-jobs/normalize-error.js +26 -0
  14. package/build/background-jobs/scheduler.js +274 -0
  15. package/build/background-jobs/socket-request.js +68 -0
  16. package/build/background-jobs/status-reporter.js +101 -0
  17. package/build/background-jobs/store.js +994 -0
  18. package/build/background-jobs/types.js +70 -0
  19. package/build/background-jobs/web/authorization.js +89 -0
  20. package/build/background-jobs/web/controller.js +280 -0
  21. package/build/background-jobs/web/index.js +57 -0
  22. package/build/background-jobs/web/path-matcher.js +74 -0
  23. package/build/background-jobs/web/registry.js +49 -0
  24. package/build/background-jobs/worker.js +683 -0
  25. package/build/beacon/client.js +330 -0
  26. package/build/beacon/in-process-broker.js +71 -0
  27. package/build/beacon/in-process-client.js +139 -0
  28. package/build/beacon/server.js +148 -0
  29. package/build/beacon/types.js +55 -0
  30. package/build/cli/base-command.js +67 -0
  31. package/build/cli/browser-cli.js +45 -0
  32. package/build/cli/commands/background-jobs-main.js +7 -0
  33. package/build/cli/commands/background-jobs-runner.js +7 -0
  34. package/build/cli/commands/background-jobs-worker.js +7 -0
  35. package/build/cli/commands/beacon.js +7 -0
  36. package/build/cli/commands/console.js +12 -0
  37. package/build/cli/commands/db/base-command.js +82 -0
  38. package/build/cli/commands/db/create.js +64 -0
  39. package/build/cli/commands/db/drop.js +75 -0
  40. package/build/cli/commands/db/migrate.js +17 -0
  41. package/build/cli/commands/db/reset.js +22 -0
  42. package/build/cli/commands/db/rollback.js +15 -0
  43. package/build/cli/commands/db/schema/dump.js +12 -0
  44. package/build/cli/commands/db/schema/load.js +12 -0
  45. package/build/cli/commands/db/seed.js +12 -0
  46. package/build/cli/commands/db/tenants/check.js +38 -0
  47. package/build/cli/commands/db/tenants/create.js +33 -0
  48. package/build/cli/commands/db/tenants/migrate.js +49 -0
  49. package/build/cli/commands/destroy/migration.js +7 -0
  50. package/build/cli/commands/generate/base-models.js +7 -0
  51. package/build/cli/commands/generate/frontend-models.js +12 -0
  52. package/build/cli/commands/generate/migration.js +7 -0
  53. package/build/cli/commands/generate/model.js +7 -0
  54. package/build/cli/commands/init.js +11 -0
  55. package/build/cli/commands/routes.js +7 -0
  56. package/build/cli/commands/run-script.js +12 -0
  57. package/build/cli/commands/runner.js +12 -0
  58. package/build/cli/commands/server.js +7 -0
  59. package/build/cli/commands/test.js +9 -0
  60. package/build/cli/index.js +152 -0
  61. package/build/cli/tenant-database-command-helper.js +198 -0
  62. package/build/cli/use-browser-cli.js +30 -0
  63. package/build/configuration-resolver.js +65 -0
  64. package/build/configuration-types.js +429 -0
  65. package/build/configuration.js +2590 -0
  66. package/build/controller.js +421 -0
  67. package/build/current-configuration.js +31 -0
  68. package/build/current.js +80 -0
  69. package/build/database/annotations-async-hooks.js +47 -0
  70. package/build/database/annotations.js +40 -0
  71. package/build/database/drivers/base-column.js +182 -0
  72. package/build/database/drivers/base-columns-index.js +81 -0
  73. package/build/database/drivers/base-foreign-key.js +104 -0
  74. package/build/database/drivers/base-table.js +156 -0
  75. package/build/database/drivers/base.js +1609 -0
  76. package/build/database/drivers/mssql/column.js +74 -0
  77. package/build/database/drivers/mssql/columns-index.js +6 -0
  78. package/build/database/drivers/mssql/connect-connection.js +16 -0
  79. package/build/database/drivers/mssql/foreign-key.js +12 -0
  80. package/build/database/drivers/mssql/index.js +590 -0
  81. package/build/database/drivers/mssql/options.js +79 -0
  82. package/build/database/drivers/mssql/query-parser.js +6 -0
  83. package/build/database/drivers/mssql/sql/alter-table.js +4 -0
  84. package/build/database/drivers/mssql/sql/create-database.js +36 -0
  85. package/build/database/drivers/mssql/sql/create-index.js +4 -0
  86. package/build/database/drivers/mssql/sql/create-table.js +4 -0
  87. package/build/database/drivers/mssql/sql/delete.js +19 -0
  88. package/build/database/drivers/mssql/sql/drop-database.js +36 -0
  89. package/build/database/drivers/mssql/sql/drop-table.js +4 -0
  90. package/build/database/drivers/mssql/sql/insert.js +4 -0
  91. package/build/database/drivers/mssql/sql/update.js +31 -0
  92. package/build/database/drivers/mssql/sql/upsert.js +23 -0
  93. package/build/database/drivers/mssql/structure-sql.js +120 -0
  94. package/build/database/drivers/mssql/table.js +145 -0
  95. package/build/database/drivers/mysql/column.js +112 -0
  96. package/build/database/drivers/mysql/columns-index.js +22 -0
  97. package/build/database/drivers/mysql/foreign-key.js +12 -0
  98. package/build/database/drivers/mysql/index.js +473 -0
  99. package/build/database/drivers/mysql/options.js +34 -0
  100. package/build/database/drivers/mysql/query-parser.js +6 -0
  101. package/build/database/drivers/mysql/query.js +37 -0
  102. package/build/database/drivers/mysql/sql/alter-table.js +6 -0
  103. package/build/database/drivers/mysql/sql/create-database.js +39 -0
  104. package/build/database/drivers/mysql/sql/create-index.js +6 -0
  105. package/build/database/drivers/mysql/sql/create-table.js +6 -0
  106. package/build/database/drivers/mysql/sql/delete.js +21 -0
  107. package/build/database/drivers/mysql/sql/drop-database.js +6 -0
  108. package/build/database/drivers/mysql/sql/drop-table.js +6 -0
  109. package/build/database/drivers/mysql/sql/insert.js +6 -0
  110. package/build/database/drivers/mysql/sql/update.js +33 -0
  111. package/build/database/drivers/mysql/sql/upsert.js +13 -0
  112. package/build/database/drivers/mysql/structure-sql.js +93 -0
  113. package/build/database/drivers/mysql/table.js +121 -0
  114. package/build/database/drivers/pgsql/column.js +90 -0
  115. package/build/database/drivers/pgsql/columns-index.js +6 -0
  116. package/build/database/drivers/pgsql/foreign-key.js +12 -0
  117. package/build/database/drivers/pgsql/index.js +441 -0
  118. package/build/database/drivers/pgsql/options.js +32 -0
  119. package/build/database/drivers/pgsql/query-parser.js +6 -0
  120. package/build/database/drivers/pgsql/sql/alter-table.js +6 -0
  121. package/build/database/drivers/pgsql/sql/create-database.js +38 -0
  122. package/build/database/drivers/pgsql/sql/create-index.js +6 -0
  123. package/build/database/drivers/pgsql/sql/create-table.js +6 -0
  124. package/build/database/drivers/pgsql/sql/delete.js +21 -0
  125. package/build/database/drivers/pgsql/sql/drop-database.js +6 -0
  126. package/build/database/drivers/pgsql/sql/drop-table.js +6 -0
  127. package/build/database/drivers/pgsql/sql/insert.js +6 -0
  128. package/build/database/drivers/pgsql/sql/update.js +33 -0
  129. package/build/database/drivers/pgsql/sql/upsert.js +14 -0
  130. package/build/database/drivers/pgsql/structure-sql.js +126 -0
  131. package/build/database/drivers/pgsql/table.js +135 -0
  132. package/build/database/drivers/sqlite/base.js +509 -0
  133. package/build/database/drivers/sqlite/column.js +75 -0
  134. package/build/database/drivers/sqlite/columns-index.js +30 -0
  135. package/build/database/drivers/sqlite/connection-sql-js.js +46 -0
  136. package/build/database/drivers/sqlite/foreign-key.js +24 -0
  137. package/build/database/drivers/sqlite/index.js +394 -0
  138. package/build/database/drivers/sqlite/index.native.js +72 -0
  139. package/build/database/drivers/sqlite/index.web.js +99 -0
  140. package/build/database/drivers/sqlite/options.js +32 -0
  141. package/build/database/drivers/sqlite/query-parser.js +6 -0
  142. package/build/database/drivers/sqlite/query.js +35 -0
  143. package/build/database/drivers/sqlite/query.native.js +35 -0
  144. package/build/database/drivers/sqlite/query.web.js +49 -0
  145. package/build/database/drivers/sqlite/sql/alter-table.js +187 -0
  146. package/build/database/drivers/sqlite/sql/create-index.js +6 -0
  147. package/build/database/drivers/sqlite/sql/create-table.js +6 -0
  148. package/build/database/drivers/sqlite/sql/delete.js +26 -0
  149. package/build/database/drivers/sqlite/sql/drop-table.js +6 -0
  150. package/build/database/drivers/sqlite/sql/insert.js +6 -0
  151. package/build/database/drivers/sqlite/sql/update.js +33 -0
  152. package/build/database/drivers/sqlite/sql/upsert.js +14 -0
  153. package/build/database/drivers/sqlite/structure-sql.js +56 -0
  154. package/build/database/drivers/sqlite/table-rebuilder.js +96 -0
  155. package/build/database/drivers/sqlite/table.js +131 -0
  156. package/build/database/drivers/structure-sql/utils.js +35 -0
  157. package/build/database/handler.js +13 -0
  158. package/build/database/initializer-from-require-context.js +101 -0
  159. package/build/database/migration/index.js +438 -0
  160. package/build/database/migrator/files-finder.js +55 -0
  161. package/build/database/migrator/types.js +31 -0
  162. package/build/database/migrator.js +557 -0
  163. package/build/database/pool/async-tracked-multi-connection.js +1164 -0
  164. package/build/database/pool/base-methods-forward.js +52 -0
  165. package/build/database/pool/base.js +380 -0
  166. package/build/database/pool/single-multi-use.js +118 -0
  167. package/build/database/query/alter-table-base.js +104 -0
  168. package/build/database/query/base.js +49 -0
  169. package/build/database/query/create-database-base.js +42 -0
  170. package/build/database/query/create-index-base.js +117 -0
  171. package/build/database/query/create-table-base.js +205 -0
  172. package/build/database/query/delete-base.js +19 -0
  173. package/build/database/query/drop-database-base.js +38 -0
  174. package/build/database/query/drop-table-base.js +58 -0
  175. package/build/database/query/from-base.js +36 -0
  176. package/build/database/query/from-plain.js +16 -0
  177. package/build/database/query/from-table.js +18 -0
  178. package/build/database/query/index.js +533 -0
  179. package/build/database/query/insert-base.js +172 -0
  180. package/build/database/query/join-base.js +43 -0
  181. package/build/database/query/join-object.js +167 -0
  182. package/build/database/query/join-plain.js +18 -0
  183. package/build/database/query/join-tracker.js +93 -0
  184. package/build/database/query/model-class-query.js +1577 -0
  185. package/build/database/query/order-base.js +33 -0
  186. package/build/database/query/order-column.js +77 -0
  187. package/build/database/query/order-plain.js +28 -0
  188. package/build/database/query/preloader/belongs-to.js +267 -0
  189. package/build/database/query/preloader/ensure-model-class-initialized.js +18 -0
  190. package/build/database/query/preloader/has-many.js +316 -0
  191. package/build/database/query/preloader/has-one.js +123 -0
  192. package/build/database/query/preloader/selection.js +152 -0
  193. package/build/database/query/preloader.js +201 -0
  194. package/build/database/query/query-data.js +305 -0
  195. package/build/database/query/select-base.js +30 -0
  196. package/build/database/query/select-plain.js +18 -0
  197. package/build/database/query/select-table-and-column.js +28 -0
  198. package/build/database/query/update-base.js +41 -0
  199. package/build/database/query/upsert-base.js +103 -0
  200. package/build/database/query/where-base.js +38 -0
  201. package/build/database/query/where-combinator.js +31 -0
  202. package/build/database/query/where-hash.js +77 -0
  203. package/build/database/query/where-model-class-hash.js +505 -0
  204. package/build/database/query/where-not.js +23 -0
  205. package/build/database/query/where-plain.js +20 -0
  206. package/build/database/query/with-count.js +219 -0
  207. package/build/database/query-parser/base-query-parser.js +40 -0
  208. package/build/database/query-parser/from-parser.js +49 -0
  209. package/build/database/query-parser/group-parser.js +55 -0
  210. package/build/database/query-parser/joins-parser.js +37 -0
  211. package/build/database/query-parser/limit-parser.js +77 -0
  212. package/build/database/query-parser/options.js +94 -0
  213. package/build/database/query-parser/order-parser.js +45 -0
  214. package/build/database/query-parser/select-parser.js +67 -0
  215. package/build/database/query-parser/where-parser.js +46 -0
  216. package/build/database/record/acts-as-list.js +374 -0
  217. package/build/database/record/attachments/download.js +49 -0
  218. package/build/database/record/attachments/handle.js +188 -0
  219. package/build/database/record/attachments/normalize-input.js +213 -0
  220. package/build/database/record/attachments/storage-drivers/filesystem.js +114 -0
  221. package/build/database/record/attachments/storage-drivers/native.js +146 -0
  222. package/build/database/record/attachments/storage-drivers/s3.js +245 -0
  223. package/build/database/record/attachments/store.js +591 -0
  224. package/build/database/record/index.js +4119 -0
  225. package/build/database/record/instance-relationships/base.js +289 -0
  226. package/build/database/record/instance-relationships/belongs-to.js +84 -0
  227. package/build/database/record/instance-relationships/has-many.js +284 -0
  228. package/build/database/record/instance-relationships/has-one.js +117 -0
  229. package/build/database/record/record-not-found-error.js +3 -0
  230. package/build/database/record/relationships/base.js +195 -0
  231. package/build/database/record/relationships/belongs-to.js +57 -0
  232. package/build/database/record/relationships/has-many.js +46 -0
  233. package/build/database/record/relationships/has-one.js +46 -0
  234. package/build/database/record/state-machine.js +278 -0
  235. package/build/database/record/user-module.js +43 -0
  236. package/build/database/record/validators/base.js +27 -0
  237. package/build/database/record/validators/format.js +50 -0
  238. package/build/database/record/validators/presence.js +24 -0
  239. package/build/database/record/validators/uniqueness.js +124 -0
  240. package/build/database/table-data/index.js +241 -0
  241. package/build/database/table-data/table-column.js +416 -0
  242. package/build/database/table-data/table-foreign-key.js +69 -0
  243. package/build/database/table-data/table-index.js +46 -0
  244. package/build/database/table-data/table-reference.js +13 -0
  245. package/build/database/use-database.js +48 -0
  246. package/build/environment-handlers/base.js +561 -0
  247. package/build/environment-handlers/browser.js +338 -0
  248. package/build/environment-handlers/node/cli/commands/background-jobs-main.js +21 -0
  249. package/build/environment-handlers/node/cli/commands/background-jobs-runner.js +24 -0
  250. package/build/environment-handlers/node/cli/commands/background-jobs-worker.js +47 -0
  251. package/build/environment-handlers/node/cli/commands/beacon.js +21 -0
  252. package/build/environment-handlers/node/cli/commands/cli-command-context.js +31 -0
  253. package/build/environment-handlers/node/cli/commands/console.js +149 -0
  254. package/build/environment-handlers/node/cli/commands/db/schema/dump.js +43 -0
  255. package/build/environment-handlers/node/cli/commands/db/schema/load.js +69 -0
  256. package/build/environment-handlers/node/cli/commands/db/seed.js +79 -0
  257. package/build/environment-handlers/node/cli/commands/destroy/migration.js +47 -0
  258. package/build/environment-handlers/node/cli/commands/generate/base-models.js +396 -0
  259. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +872 -0
  260. package/build/environment-handlers/node/cli/commands/generate/migration.js +45 -0
  261. package/build/environment-handlers/node/cli/commands/generate/model.js +45 -0
  262. package/build/environment-handlers/node/cli/commands/init.js +68 -0
  263. package/build/environment-handlers/node/cli/commands/routes.js +63 -0
  264. package/build/environment-handlers/node/cli/commands/run-script.js +85 -0
  265. package/build/environment-handlers/node/cli/commands/runner.js +84 -0
  266. package/build/environment-handlers/node/cli/commands/server.js +151 -0
  267. package/build/environment-handlers/node/cli/commands/test.js +118 -0
  268. package/build/environment-handlers/node.js +887 -0
  269. package/build/error-logger.js +30 -0
  270. package/build/frontend-model-controller.js +3491 -0
  271. package/build/frontend-model-resource/base-resource.js +939 -0
  272. package/build/frontend-models/base.js +4004 -0
  273. package/build/frontend-models/clear-pending-debounced-callback.js +16 -0
  274. package/build/frontend-models/event-hook-models.js +49 -0
  275. package/build/frontend-models/model-registry.js +28 -0
  276. package/build/frontend-models/outgoing-event-buffer.js +51 -0
  277. package/build/frontend-models/preloader.js +169 -0
  278. package/build/frontend-models/query.js +2245 -0
  279. package/build/frontend-models/resource-config-validation.js +56 -0
  280. package/build/frontend-models/resource-definition.js +399 -0
  281. package/build/frontend-models/transport-serialization.js +369 -0
  282. package/build/frontend-models/use-created-event.js +21 -0
  283. package/build/frontend-models/use-destroyed-event.js +148 -0
  284. package/build/frontend-models/use-model-class-event.js +164 -0
  285. package/build/frontend-models/use-updated-event.js +152 -0
  286. package/build/frontend-models/websocket-channel.js +494 -0
  287. package/build/frontend-models/websocket-publishers.js +224 -0
  288. package/build/http-client/header.js +17 -0
  289. package/build/http-client/index.js +139 -0
  290. package/build/http-client/request.js +94 -0
  291. package/build/http-client/response.js +151 -0
  292. package/build/http-client/websocket-client.js +27 -0
  293. package/build/http-server/client/index.js +507 -0
  294. package/build/http-server/client/params-to-object.js +152 -0
  295. package/build/http-server/client/request-buffer/form-data-part.js +139 -0
  296. package/build/http-server/client/request-buffer/header.js +19 -0
  297. package/build/http-server/client/request-buffer/index.js +535 -0
  298. package/build/http-server/client/request-parser.js +195 -0
  299. package/build/http-server/client/request-runner.js +321 -0
  300. package/build/http-server/client/request-timing.js +171 -0
  301. package/build/http-server/client/request.js +114 -0
  302. package/build/http-server/client/response.js +251 -0
  303. package/build/http-server/client/uploaded-file/memory-uploaded-file.js +32 -0
  304. package/build/http-server/client/uploaded-file/temporary-uploaded-file.js +32 -0
  305. package/build/http-server/client/uploaded-file/uploaded-file.js +36 -0
  306. package/build/http-server/client/websocket-request.js +147 -0
  307. package/build/http-server/client/websocket-session.js +1755 -0
  308. package/build/http-server/cookie.js +245 -0
  309. package/build/http-server/development-reloader.js +240 -0
  310. package/build/http-server/index.js +561 -0
  311. package/build/http-server/remote-address.js +77 -0
  312. package/build/http-server/server-client.js +222 -0
  313. package/build/http-server/server-lock.js +178 -0
  314. package/build/http-server/websocket-channel-subscribers.js +110 -0
  315. package/build/http-server/websocket-channel.js +137 -0
  316. package/build/http-server/websocket-connection.js +118 -0
  317. package/build/http-server/websocket-event-log-store.js +433 -0
  318. package/build/http-server/websocket-events-host.js +170 -0
  319. package/build/http-server/websocket-events.js +50 -0
  320. package/build/http-server/worker-handler/channel-subscriber-dispatch.js +28 -0
  321. package/build/http-server/worker-handler/in-process.js +155 -0
  322. package/build/http-server/worker-handler/index.js +370 -0
  323. package/build/http-server/worker-handler/worker-script.js +6 -0
  324. package/build/http-server/worker-handler/worker-thread.js +286 -0
  325. package/build/initializer.js +39 -0
  326. package/build/jobs/mail-delivery.js +22 -0
  327. package/build/logger/base-logger.js +34 -0
  328. package/build/logger/console-logger.js +28 -0
  329. package/build/logger/file-logger.js +36 -0
  330. package/build/logger/outputs/array-output.js +50 -0
  331. package/build/logger/outputs/console-output.js +32 -0
  332. package/build/logger/outputs/file-output.js +55 -0
  333. package/build/logger/outputs/stdout-output.js +64 -0
  334. package/build/logger.js +507 -0
  335. package/build/mailer/backends/smtp.js +197 -0
  336. package/build/mailer/base.js +337 -0
  337. package/build/mailer/delivery.js +70 -0
  338. package/build/mailer/index.js +24 -0
  339. package/build/mailer.js +15 -0
  340. package/build/plugins/sqljs-wasm-route-controller.js +70 -0
  341. package/build/plugins/sqljs-wasm-route.js +71 -0
  342. package/build/record-payload-values.js +83 -0
  343. package/build/routes/app-routes.js +17 -0
  344. package/build/routes/base-route.js +133 -0
  345. package/build/routes/basic-route.js +109 -0
  346. package/build/routes/built-in/debug/controller.js +12 -0
  347. package/build/routes/built-in/errors/controller.js +7 -0
  348. package/build/routes/get-route.js +75 -0
  349. package/build/routes/hooks/frontend-model-command-route-hook.js +100 -0
  350. package/build/routes/index.js +50 -0
  351. package/build/routes/namespace-route.js +51 -0
  352. package/build/routes/plugin-routes.js +141 -0
  353. package/build/routes/post-route.js +74 -0
  354. package/build/routes/resolver.js +535 -0
  355. package/build/routes/resource-route.js +154 -0
  356. package/build/routes/root-route.js +11 -0
  357. package/build/src/application.js +187 -214
  358. package/build/src/authorization/ability.js +250 -297
  359. package/build/src/authorization/base-resource.js +120 -136
  360. package/build/src/background-jobs/client.js +43 -47
  361. package/build/src/background-jobs/cron-expression.js +127 -166
  362. package/build/src/background-jobs/forked-runner-child.js +37 -47
  363. package/build/src/background-jobs/job-record.js +8 -10
  364. package/build/src/background-jobs/job-registry.js +72 -84
  365. package/build/src/background-jobs/job-runner.js +74 -81
  366. package/build/src/background-jobs/job.js +62 -72
  367. package/build/src/background-jobs/json-socket.js +65 -70
  368. package/build/src/background-jobs/main.js +841 -900
  369. package/build/src/background-jobs/normalize-error.js +12 -11
  370. package/build/src/background-jobs/scheduler.js +205 -247
  371. package/build/src/background-jobs/socket-request.js +60 -65
  372. package/build/src/background-jobs/status-reporter.js +86 -96
  373. package/build/src/background-jobs/store.js +862 -980
  374. package/build/src/background-jobs/types.js +2 -3
  375. package/build/src/background-jobs/web/authorization.js +38 -50
  376. package/build/src/background-jobs/web/controller.js +232 -268
  377. package/build/src/background-jobs/web/index.js +36 -40
  378. package/build/src/background-jobs/web/path-matcher.js +45 -48
  379. package/build/src/background-jobs/web/registry.js +9 -14
  380. package/build/src/background-jobs/worker.js +585 -639
  381. package/build/src/beacon/client.js +264 -293
  382. package/build/src/beacon/in-process-broker.js +20 -25
  383. package/build/src/beacon/in-process-client.js +104 -116
  384. package/build/src/beacon/server.js +110 -126
  385. package/build/src/beacon/types.js +2 -8
  386. package/build/src/cli/base-command.js +49 -57
  387. package/build/src/cli/browser-cli.js +37 -42
  388. package/build/src/cli/commands/background-jobs-main.js +5 -5
  389. package/build/src/cli/commands/background-jobs-runner.js +5 -5
  390. package/build/src/cli/commands/background-jobs-worker.js +5 -5
  391. package/build/src/cli/commands/beacon.js +5 -5
  392. package/build/src/cli/commands/console.js +10 -10
  393. package/build/src/cli/commands/db/base-command.js +71 -76
  394. package/build/src/cli/commands/db/create.js +53 -61
  395. package/build/src/cli/commands/db/drop.js +62 -71
  396. package/build/src/cli/commands/db/migrate.js +13 -15
  397. package/build/src/cli/commands/db/reset.js +16 -19
  398. package/build/src/cli/commands/db/rollback.js +12 -13
  399. package/build/src/cli/commands/db/schema/dump.js +9 -9
  400. package/build/src/cli/commands/db/schema/load.js +9 -9
  401. package/build/src/cli/commands/db/seed.js +9 -9
  402. package/build/src/cli/commands/db/tenants/check.js +32 -35
  403. package/build/src/cli/commands/db/tenants/create.js +26 -29
  404. package/build/src/cli/commands/db/tenants/migrate.js +40 -44
  405. package/build/src/cli/commands/destroy/migration.js +5 -5
  406. package/build/src/cli/commands/generate/base-models.js +5 -5
  407. package/build/src/cli/commands/generate/frontend-models.js +9 -9
  408. package/build/src/cli/commands/generate/migration.js +5 -5
  409. package/build/src/cli/commands/generate/model.js +5 -5
  410. package/build/src/cli/commands/init.js +7 -9
  411. package/build/src/cli/commands/routes.js +6 -6
  412. package/build/src/cli/commands/run-script.js +9 -9
  413. package/build/src/cli/commands/runner.js +9 -9
  414. package/build/src/cli/commands/server.js +6 -6
  415. package/build/src/cli/commands/test.js +6 -7
  416. package/build/src/cli/index.js +127 -141
  417. package/build/src/cli/tenant-database-command-helper.js +154 -185
  418. package/build/src/cli/use-browser-cli.js +15 -20
  419. package/build/src/configuration-resolver.js +47 -54
  420. package/build/src/configuration-types.d.ts +5 -3
  421. package/build/src/configuration-types.d.ts.map +1 -1
  422. package/build/src/configuration-types.js +3 -54
  423. package/build/src/configuration.js +2240 -2547
  424. package/build/src/controller.js +363 -407
  425. package/build/src/current-configuration.js +9 -12
  426. package/build/src/current.js +70 -75
  427. package/build/src/database/annotations-async-hooks.js +16 -22
  428. package/build/src/database/annotations.js +12 -18
  429. package/build/src/database/drivers/base-column.js +155 -179
  430. package/build/src/database/drivers/base-columns-index.js +69 -78
  431. package/build/src/database/drivers/base-foreign-key.js +89 -101
  432. package/build/src/database/drivers/base-table.js +124 -149
  433. package/build/src/database/drivers/base.js +1306 -1489
  434. package/build/src/database/drivers/mssql/column.js +39 -50
  435. package/build/src/database/drivers/mssql/columns-index.js +2 -3
  436. package/build/src/database/drivers/mssql/connect-connection.js +11 -9
  437. package/build/src/database/drivers/mssql/foreign-key.js +8 -9
  438. package/build/src/database/drivers/mssql/index.js +507 -587
  439. package/build/src/database/drivers/mssql/options.js +68 -75
  440. package/build/src/database/drivers/mssql/query-parser.js +2 -3
  441. package/build/src/database/drivers/mssql/sql/alter-table.js +2 -2
  442. package/build/src/database/drivers/mssql/sql/create-database.js +24 -31
  443. package/build/src/database/drivers/mssql/sql/create-index.js +2 -2
  444. package/build/src/database/drivers/mssql/sql/create-table.js +2 -2
  445. package/build/src/database/drivers/mssql/sql/delete.js +14 -16
  446. package/build/src/database/drivers/mssql/sql/drop-database.js +24 -31
  447. package/build/src/database/drivers/mssql/sql/drop-table.js +2 -2
  448. package/build/src/database/drivers/mssql/sql/insert.js +2 -2
  449. package/build/src/database/drivers/mssql/sql/update.js +24 -28
  450. package/build/src/database/drivers/mssql/sql/upsert.js +18 -20
  451. package/build/src/database/drivers/mssql/structure-sql.js +102 -114
  452. package/build/src/database/drivers/mssql/table.js +81 -96
  453. package/build/src/database/drivers/mysql/column.js +75 -92
  454. package/build/src/database/drivers/mysql/columns-index.js +16 -19
  455. package/build/src/database/drivers/mysql/foreign-key.js +8 -9
  456. package/build/src/database/drivers/mysql/index.js +396 -457
  457. package/build/src/database/drivers/mysql/options.js +26 -30
  458. package/build/src/database/drivers/mysql/query-parser.js +2 -3
  459. package/build/src/database/drivers/mysql/query.js +26 -29
  460. package/build/src/database/drivers/mysql/sql/alter-table.js +2 -3
  461. package/build/src/database/drivers/mysql/sql/create-database.js +23 -28
  462. package/build/src/database/drivers/mysql/sql/create-index.js +2 -3
  463. package/build/src/database/drivers/mysql/sql/create-table.js +2 -3
  464. package/build/src/database/drivers/mysql/sql/delete.js +14 -17
  465. package/build/src/database/drivers/mysql/sql/drop-database.js +2 -3
  466. package/build/src/database/drivers/mysql/sql/drop-table.js +2 -3
  467. package/build/src/database/drivers/mysql/sql/insert.js +2 -3
  468. package/build/src/database/drivers/mysql/sql/update.js +24 -29
  469. package/build/src/database/drivers/mysql/sql/upsert.js +8 -10
  470. package/build/src/database/drivers/mysql/structure-sql.js +79 -88
  471. package/build/src/database/drivers/mysql/table.js +83 -98
  472. package/build/src/database/drivers/pgsql/column.js +56 -72
  473. package/build/src/database/drivers/pgsql/columns-index.js +2 -3
  474. package/build/src/database/drivers/pgsql/foreign-key.js +8 -9
  475. package/build/src/database/drivers/pgsql/index.js +377 -438
  476. package/build/src/database/drivers/pgsql/options.js +25 -28
  477. package/build/src/database/drivers/pgsql/query-parser.js +2 -3
  478. package/build/src/database/drivers/pgsql/sql/alter-table.js +2 -3
  479. package/build/src/database/drivers/pgsql/sql/create-database.js +19 -23
  480. package/build/src/database/drivers/pgsql/sql/create-index.js +2 -3
  481. package/build/src/database/drivers/pgsql/sql/create-table.js +2 -3
  482. package/build/src/database/drivers/pgsql/sql/delete.js +14 -17
  483. package/build/src/database/drivers/pgsql/sql/drop-database.js +2 -3
  484. package/build/src/database/drivers/pgsql/sql/drop-table.js +2 -3
  485. package/build/src/database/drivers/pgsql/sql/insert.js +2 -3
  486. package/build/src/database/drivers/pgsql/sql/update.js +24 -29
  487. package/build/src/database/drivers/pgsql/sql/upsert.js +9 -11
  488. package/build/src/database/drivers/pgsql/structure-sql.js +108 -120
  489. package/build/src/database/drivers/pgsql/table.js +60 -77
  490. package/build/src/database/drivers/sqlite/base.js +405 -478
  491. package/build/src/database/drivers/sqlite/column.js +54 -69
  492. package/build/src/database/drivers/sqlite/columns-index.js +22 -27
  493. package/build/src/database/drivers/sqlite/connection-sql-js.js +35 -42
  494. package/build/src/database/drivers/sqlite/foreign-key.js +18 -21
  495. package/build/src/database/drivers/sqlite/index.js +330 -373
  496. package/build/src/database/drivers/sqlite/index.native.js +55 -64
  497. package/build/src/database/drivers/sqlite/index.web.js +69 -87
  498. package/build/src/database/drivers/sqlite/options.js +25 -28
  499. package/build/src/database/drivers/sqlite/query-parser.js +2 -3
  500. package/build/src/database/drivers/sqlite/query.js +21 -24
  501. package/build/src/database/drivers/sqlite/query.native.js +20 -25
  502. package/build/src/database/drivers/sqlite/query.web.js +30 -37
  503. package/build/src/database/drivers/sqlite/sql/alter-table.js +159 -179
  504. package/build/src/database/drivers/sqlite/sql/create-index.js +2 -3
  505. package/build/src/database/drivers/sqlite/sql/create-table.js +2 -3
  506. package/build/src/database/drivers/sqlite/sql/delete.js +17 -22
  507. package/build/src/database/drivers/sqlite/sql/drop-table.js +2 -3
  508. package/build/src/database/drivers/sqlite/sql/insert.js +2 -3
  509. package/build/src/database/drivers/sqlite/sql/update.js +24 -29
  510. package/build/src/database/drivers/sqlite/sql/upsert.js +9 -11
  511. package/build/src/database/drivers/sqlite/structure-sql.js +49 -52
  512. package/build/src/database/drivers/sqlite/table-rebuilder.js +62 -75
  513. package/build/src/database/drivers/sqlite/table.js +102 -125
  514. package/build/src/database/drivers/structure-sql/utils.js +14 -17
  515. package/build/src/database/handler.js +9 -10
  516. package/build/src/database/initializer-from-require-context.js +76 -87
  517. package/build/src/database/migration/index.js +332 -395
  518. package/build/src/database/migrator/files-finder.js +40 -50
  519. package/build/src/database/migrator/types.js +2 -30
  520. package/build/src/database/migrator.js +454 -526
  521. package/build/src/database/pool/async-tracked-multi-connection.js +997 -1147
  522. package/build/src/database/pool/base-methods-forward.js +40 -43
  523. package/build/src/database/pool/base.js +298 -343
  524. package/build/src/database/pool/single-multi-use.js +93 -110
  525. package/build/src/database/query/alter-table-base.js +84 -99
  526. package/build/src/database/query/base.js +39 -46
  527. package/build/src/database/query/create-database-base.js +25 -30
  528. package/build/src/database/query/create-index-base.js +75 -94
  529. package/build/src/database/query/create-table-base.js +151 -193
  530. package/build/src/database/query/delete-base.js +14 -16
  531. package/build/src/database/query/drop-database-base.js +23 -28
  532. package/build/src/database/query/drop-table-base.js +42 -53
  533. package/build/src/database/query/from-base.js +30 -33
  534. package/build/src/database/query/from-plain.js +11 -13
  535. package/build/src/database/query/from-table.js +13 -15
  536. package/build/src/database/query/index.js +410 -472
  537. package/build/src/database/query/insert-base.js +143 -164
  538. package/build/src/database/query/join-base.js +35 -40
  539. package/build/src/database/query/join-object.js +128 -153
  540. package/build/src/database/query/join-plain.js +13 -15
  541. package/build/src/database/query/join-tracker.js +76 -90
  542. package/build/src/database/query/model-class-query.js +1134 -1370
  543. package/build/src/database/query/order-base.js +27 -30
  544. package/build/src/database/query/order-column.js +44 -53
  545. package/build/src/database/query/order-plain.js +20 -24
  546. package/build/src/database/query/preloader/belongs-to.js +210 -258
  547. package/build/src/database/query/preloader/ensure-model-class-initialized.js +8 -9
  548. package/build/src/database/query/preloader/has-many.js +240 -301
  549. package/build/src/database/query/preloader/has-one.js +91 -117
  550. package/build/src/database/query/preloader/selection.js +117 -129
  551. package/build/src/database/query/preloader.js +160 -185
  552. package/build/src/database/query/query-data.js +157 -201
  553. package/build/src/database/query/select-base.js +25 -27
  554. package/build/src/database/query/select-plain.js +13 -15
  555. package/build/src/database/query/select-table-and-column.js +21 -25
  556. package/build/src/database/query/update-base.js +35 -38
  557. package/build/src/database/query/upsert-base.js +93 -100
  558. package/build/src/database/query/where-base.js +32 -35
  559. package/build/src/database/query/where-combinator.js +25 -28
  560. package/build/src/database/query/where-hash.js +61 -68
  561. package/build/src/database/query/where-model-class-hash.js +414 -469
  562. package/build/src/database/query/where-not.js +18 -20
  563. package/build/src/database/query/where-plain.js +15 -17
  564. package/build/src/database/query/with-count.js +125 -159
  565. package/build/src/database/query-parser/base-query-parser.js +32 -37
  566. package/build/src/database/query-parser/from-parser.js +36 -45
  567. package/build/src/database/query-parser/group-parser.js +42 -50
  568. package/build/src/database/query-parser/joins-parser.js +28 -33
  569. package/build/src/database/query-parser/limit-parser.js +67 -70
  570. package/build/src/database/query-parser/options.js +75 -82
  571. package/build/src/database/query-parser/order-parser.js +36 -40
  572. package/build/src/database/query-parser/select-parser.js +49 -60
  573. package/build/src/database/query-parser/where-parser.js +36 -41
  574. package/build/src/database/record/acts-as-list.js +235 -273
  575. package/build/src/database/record/attachments/download.js +44 -45
  576. package/build/src/database/record/attachments/handle.js +141 -161
  577. package/build/src/database/record/attachments/normalize-input.js +128 -138
  578. package/build/src/database/record/attachments/storage-drivers/filesystem.js +77 -91
  579. package/build/src/database/record/attachments/storage-drivers/native.js +112 -121
  580. package/build/src/database/record/attachments/storage-drivers/s3.js +177 -208
  581. package/build/src/database/record/attachments/store.js +467 -539
  582. package/build/src/database/record/index.d.ts +109 -25
  583. package/build/src/database/record/index.d.ts.map +1 -1
  584. package/build/src/database/record/index.js +3502 -3898
  585. package/build/src/database/record/instance-relationships/base.js +234 -268
  586. package/build/src/database/record/instance-relationships/belongs-to.js +58 -73
  587. package/build/src/database/record/instance-relationships/has-many.js +225 -264
  588. package/build/src/database/record/instance-relationships/has-one.js +85 -105
  589. package/build/src/database/record/record-not-found-error.js +3 -2
  590. package/build/src/database/record/relationships/base.js +144 -166
  591. package/build/src/database/record/relationships/belongs-to.js +44 -51
  592. package/build/src/database/record/relationships/has-many.js +32 -40
  593. package/build/src/database/record/relationships/has-one.js +32 -40
  594. package/build/src/database/record/state-machine.js +156 -208
  595. package/build/src/database/record/user-module.js +32 -38
  596. package/build/src/database/record/validators/base.js +22 -24
  597. package/build/src/database/record/validators/format.js +36 -46
  598. package/build/src/database/record/validators/presence.js +18 -20
  599. package/build/src/database/record/validators/uniqueness.js +99 -117
  600. package/build/src/database/table-data/index.js +199 -231
  601. package/build/src/database/table-data/table-column.js +338 -382
  602. package/build/src/database/table-data/table-foreign-key.js +57 -66
  603. package/build/src/database/table-data/table-index.js +29 -36
  604. package/build/src/database/table-data/table-reference.js +10 -10
  605. package/build/src/database/use-database.js +32 -40
  606. package/build/src/environment-handlers/base.js +484 -544
  607. package/build/src/environment-handlers/browser.js +241 -294
  608. package/build/src/environment-handlers/node/cli/commands/background-jobs-main.js +16 -19
  609. package/build/src/environment-handlers/node/cli/commands/background-jobs-runner.js +18 -21
  610. package/build/src/environment-handlers/node/cli/commands/background-jobs-worker.js +22 -29
  611. package/build/src/environment-handlers/node/cli/commands/beacon.js +16 -19
  612. package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +14 -15
  613. package/build/src/environment-handlers/node/cli/commands/console.js +99 -120
  614. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +34 -39
  615. package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +57 -63
  616. package/build/src/environment-handlers/node/cli/commands/db/seed.js +51 -63
  617. package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +32 -40
  618. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +4 -2
  619. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  620. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +326 -358
  621. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +10 -10
  622. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  623. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +729 -844
  624. package/build/src/environment-handlers/node/cli/commands/generate/migration.js +34 -38
  625. package/build/src/environment-handlers/node/cli/commands/generate/model.js +34 -38
  626. package/build/src/environment-handlers/node/cli/commands/init.js +56 -61
  627. package/build/src/environment-handlers/node/cli/commands/routes.js +51 -59
  628. package/build/src/environment-handlers/node/cli/commands/run-script.js +54 -68
  629. package/build/src/environment-handlers/node/cli/commands/runner.js +56 -74
  630. package/build/src/environment-handlers/node/cli/commands/server.js +93 -106
  631. package/build/src/environment-handlers/node/cli/commands/test.js +97 -113
  632. package/build/src/environment-handlers/node.js +753 -874
  633. package/build/src/error-logger.js +22 -21
  634. package/build/src/frontend-model-controller.js +2791 -3291
  635. package/build/src/frontend-model-resource/base-resource.d.ts +8 -3
  636. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  637. package/build/src/frontend-model-resource/base-resource.js +770 -865
  638. package/build/src/frontend-models/base.js +3136 -3593
  639. package/build/src/frontend-models/clear-pending-debounced-callback.js +7 -8
  640. package/build/src/frontend-models/event-hook-models.js +16 -21
  641. package/build/src/frontend-models/model-registry.js +9 -11
  642. package/build/src/frontend-models/outgoing-event-buffer.js +10 -17
  643. package/build/src/frontend-models/preloader.js +131 -149
  644. package/build/src/frontend-models/query.js +1557 -1855
  645. package/build/src/frontend-models/resource-config-validation.js +27 -37
  646. package/build/src/frontend-models/resource-definition.d.ts +6 -7
  647. package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
  648. package/build/src/frontend-models/resource-definition.js +237 -291
  649. package/build/src/frontend-models/transport-serialization.js +203 -266
  650. package/build/src/frontend-models/use-created-event.js +5 -7
  651. package/build/src/frontend-models/use-destroyed-event.js +80 -93
  652. package/build/src/frontend-models/use-model-class-event.js +79 -91
  653. package/build/src/frontend-models/use-updated-event.js +84 -97
  654. package/build/src/frontend-models/websocket-channel.js +381 -441
  655. package/build/src/frontend-models/websocket-publishers.js +142 -175
  656. package/build/src/http-client/header.js +13 -14
  657. package/build/src/http-client/index.js +116 -132
  658. package/build/src/http-client/request.js +71 -87
  659. package/build/src/http-client/response.js +122 -140
  660. package/build/src/http-client/websocket-client.js +15 -17
  661. package/build/src/http-server/client/index.js +409 -465
  662. package/build/src/http-server/client/params-to-object.js +124 -135
  663. package/build/src/http-server/client/request-buffer/form-data-part.js +111 -132
  664. package/build/src/http-server/client/request-buffer/header.js +15 -16
  665. package/build/src/http-server/client/request-buffer/index.js +446 -506
  666. package/build/src/http-server/client/request-parser.js +163 -186
  667. package/build/src/http-server/client/request-runner.js +226 -259
  668. package/build/src/http-server/client/request-timing.js +132 -151
  669. package/build/src/http-server/client/request.js +96 -108
  670. package/build/src/http-server/client/response.js +213 -235
  671. package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +25 -29
  672. package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +25 -29
  673. package/build/src/http-server/client/uploaded-file/uploaded-file.js +33 -33
  674. package/build/src/http-server/client/websocket-request.js +114 -137
  675. package/build/src/http-server/client/websocket-session.js +1452 -1657
  676. package/build/src/http-server/cookie.js +216 -236
  677. package/build/src/http-server/development-reloader.js +190 -221
  678. package/build/src/http-server/index.js +451 -525
  679. package/build/src/http-server/remote-address.js +38 -50
  680. package/build/src/http-server/server-client.js +181 -208
  681. package/build/src/http-server/server-lock.js +153 -167
  682. package/build/src/http-server/websocket-channel-subscribers.js +81 -93
  683. package/build/src/http-server/websocket-channel.js +104 -117
  684. package/build/src/http-server/websocket-connection.js +96 -104
  685. package/build/src/http-server/websocket-event-log-store.js +350 -404
  686. package/build/src/http-server/websocket-events-host.js +145 -164
  687. package/build/src/http-server/websocket-events.js +47 -47
  688. package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +13 -14
  689. package/build/src/http-server/worker-handler/in-process.js +123 -141
  690. package/build/src/http-server/worker-handler/index.js +313 -349
  691. package/build/src/http-server/worker-handler/worker-script.js +4 -5
  692. package/build/src/http-server/worker-handler/worker-thread.js +240 -269
  693. package/build/src/initializer.js +31 -36
  694. package/build/src/jobs/mail-delivery.js +13 -15
  695. package/build/src/logger/base-logger.js +24 -26
  696. package/build/src/logger/console-logger.js +21 -23
  697. package/build/src/logger/file-logger.js +29 -31
  698. package/build/src/logger/outputs/array-output.js +37 -42
  699. package/build/src/logger/outputs/console-output.js +20 -24
  700. package/build/src/logger/outputs/file-output.js +43 -48
  701. package/build/src/logger/outputs/stdout-output.js +39 -48
  702. package/build/src/logger.js +338 -394
  703. package/build/src/mailer/backends/smtp.js +134 -163
  704. package/build/src/mailer/base.js +211 -251
  705. package/build/src/mailer/delivery.js +56 -64
  706. package/build/src/mailer/index.js +4 -22
  707. package/build/src/mailer.js +4 -13
  708. package/build/src/plugins/sqljs-wasm-route-controller.js +42 -52
  709. package/build/src/plugins/sqljs-wasm-route.js +28 -38
  710. package/build/src/record-payload-values.js +25 -28
  711. package/build/src/routes/app-routes.js +12 -14
  712. package/build/src/routes/base-route.js +112 -130
  713. package/build/src/routes/basic-route.js +83 -102
  714. package/build/src/routes/built-in/debug/controller.js +10 -10
  715. package/build/src/routes/built-in/errors/controller.js +5 -5
  716. package/build/src/routes/get-route.js +50 -63
  717. package/build/src/routes/hooks/frontend-model-command-route-hook.js +66 -80
  718. package/build/src/routes/index.js +36 -43
  719. package/build/src/routes/namespace-route.js +38 -47
  720. package/build/src/routes/plugin-routes.js +107 -124
  721. package/build/src/routes/post-route.js +51 -62
  722. package/build/src/routes/resolver.js +422 -494
  723. package/build/src/routes/resource-route.js +124 -143
  724. package/build/src/routes/root-route.js +7 -8
  725. package/build/src/testing/base-expect.js +13 -14
  726. package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +329 -405
  727. package/build/src/testing/browser-test-app.js +23 -29
  728. package/build/src/testing/expect-to-change.js +41 -50
  729. package/build/src/testing/expect-utils.js +139 -184
  730. package/build/src/testing/expect.js +638 -731
  731. package/build/src/testing/request-client.js +70 -85
  732. package/build/src/testing/test-files-finder.js +285 -339
  733. package/build/src/testing/test-filter-parser.js +124 -155
  734. package/build/src/testing/test-runner.js +883 -1020
  735. package/build/src/testing/test-suite-splitter.js +114 -142
  736. package/build/src/testing/test.js +216 -256
  737. package/build/src/utils/backtrace-cleaner-node.js +62 -69
  738. package/build/src/utils/backtrace-cleaner.js +188 -216
  739. package/build/src/utils/ensure-error.js +7 -7
  740. package/build/src/utils/event-emitter.js +4 -6
  741. package/build/src/utils/file-exists.js +9 -10
  742. package/build/src/utils/format-value.js +67 -76
  743. package/build/src/utils/model-scope.js +27 -31
  744. package/build/src/utils/nest-callbacks.js +10 -13
  745. package/build/src/utils/plain-object.js +5 -6
  746. package/build/src/utils/ransack.js +448 -563
  747. package/build/src/utils/rest-args-error.js +5 -6
  748. package/build/src/utils/singularize-model-name.js +9 -11
  749. package/build/src/utils/split-sql-statements.js +68 -79
  750. package/build/src/utils/to-import-specifier.js +24 -30
  751. package/build/src/utils/with-tracked-stack-async-hooks.js +60 -74
  752. package/build/src/utils/with-tracked-stack.js +14 -18
  753. package/build/src/velocious-error.js +27 -30
  754. package/build/templates/configuration.js +61 -0
  755. package/build/templates/generate-migration.js +11 -0
  756. package/build/templates/generate-model.js +6 -0
  757. package/build/templates/routes.js +11 -0
  758. package/build/testing/base-expect.js +17 -0
  759. package/build/testing/browser-frontend-model-event-hook-scenarios.js +520 -0
  760. package/build/testing/browser-test-app.js +32 -0
  761. package/build/testing/expect-to-change.js +55 -0
  762. package/build/testing/expect-utils.js +269 -0
  763. package/build/testing/expect.js +763 -0
  764. package/build/testing/request-client.js +90 -0
  765. package/build/testing/test-files-finder.js +364 -0
  766. package/build/testing/test-filter-parser.js +198 -0
  767. package/build/testing/test-runner.js +1168 -0
  768. package/build/testing/test-suite-splitter.js +177 -0
  769. package/build/testing/test.js +370 -0
  770. package/build/utils/backtrace-cleaner-node.js +87 -0
  771. package/build/utils/backtrace-cleaner.js +266 -0
  772. package/build/utils/ensure-error.js +15 -0
  773. package/build/utils/event-emitter.js +8 -0
  774. package/build/utils/file-exists.js +18 -0
  775. package/build/utils/format-value.js +101 -0
  776. package/build/utils/model-scope.js +56 -0
  777. package/build/utils/nest-callbacks.js +22 -0
  778. package/build/utils/plain-object.js +14 -0
  779. package/build/utils/ransack.js +859 -0
  780. package/build/utils/rest-args-error.js +14 -0
  781. package/build/utils/singularize-model-name.js +18 -0
  782. package/build/utils/split-sql-statements.js +88 -0
  783. package/build/utils/to-import-specifier.js +53 -0
  784. package/build/utils/with-tracked-stack-async-hooks.js +103 -0
  785. package/build/utils/with-tracked-stack.js +38 -0
  786. package/build/velocious-error.js +34 -0
  787. package/package.json +3 -3
  788. package/src/configuration-types.js +1 -1
  789. package/src/database/record/index.js +174 -25
  790. package/src/environment-handlers/node/cli/commands/generate/base-models.js +50 -21
  791. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +5 -5
  792. package/src/frontend-model-resource/base-resource.js +6 -2
  793. package/src/frontend-models/resource-definition.js +3 -3
  794. package/src/frontend-models/websocket-publishers.js +6 -6
@@ -1,763 +1,670 @@
1
1
  // @ts-check
2
-
3
- import {formatValue, minifiedStringify} from "../utils/format-value.js"
4
- import {anythingDifferent} from "set-state-compare/build/diff-utils.js"
5
- import BaseExpect from "./base-expect.js"
6
- import ExpectToChange from "./expect-to-change.js"
7
- import {
8
- isArrayContaining,
9
- isObjectContaining,
10
- matchArrayContaining,
11
- matchObject
12
- } from "./expect-utils.js"
13
-
2
+ import { formatValue, minifiedStringify } from "../utils/format-value.js";
3
+ import { anythingDifferent } from "set-state-compare/build/diff-utils.js";
4
+ import BaseExpect from "./base-expect.js";
5
+ import ExpectToChange from "./expect-to-change.js";
6
+ import { isArrayContaining, isObjectContaining, matchArrayContaining, matchObject } from "./expect-utils.js";
14
7
  export default class Expect extends BaseExpect {
15
- /**
16
- * Runs constructor.
17
- * @param {?} object - Object.
18
- */
19
- constructor(object) {
20
- super()
21
- this._object = object
22
-
23
8
  /**
24
- * Narrows the runtime value to the documented type.
25
- @type {Array<Expect | ExpectToChange>} */
26
- this.expectations = []
27
- }
28
-
29
- /**
30
- * Runs and change.
31
- * @param {function(): Promise<number>} changeCallback - Change callback.
32
- * @returns {ExpectToChange} - The and change.
33
- */
34
- andChange(changeCallback) {
35
- return this.toChange(changeCallback)
36
- }
37
-
38
- /**
39
- * Returns not.
40
- * @returns {this} - A value.
41
- */
42
- get not() {
43
- this._not = true
44
-
45
- return this
46
- }
47
-
48
- /**
49
- * Runs to be.
50
- * @param {?} result - Result.
51
- * @returns {void} - No return value.
52
- */
53
- toBe(result) {
54
- if (this._not) {
55
- if (this._object === result) {
56
- const objectPrint = formatValue(this._object)
57
- const resultPrint = formatValue(result)
58
-
59
- throw new Error(`${objectPrint} was unexpected not to be ${resultPrint}`)
60
- }
61
- } else {
62
- if (this._object !== result) {
63
- const objectPrint = formatValue(this._object)
64
- const resultPrint = formatValue(result)
65
-
66
- throw new Error(`${objectPrint} wasn't expected be ${resultPrint}`)
67
- }
9
+ * Runs constructor.
10
+ * @param {?} object - Object.
11
+ */
12
+ constructor(object) {
13
+ super();
14
+ this._object = object;
15
+ /**
16
+ * Narrows the runtime value to the documented type.
17
+ @type {Array<Expect | ExpectToChange>} */
18
+ this.expectations = [];
68
19
  }
69
- }
70
-
71
- /**
72
- * Runs to be less than.
73
- * @param {number} result - Result.
74
- * @returns {void} - No return value.
75
- */
76
- toBeLessThan(result) {
77
- if (typeof this._object !== "number" || typeof result !== "number") {
78
- throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`)
79
- }
80
-
81
- if (this._not) {
82
- if (this._object < result) {
83
- const objectPrint = formatValue(this._object)
84
- const resultPrint = formatValue(result)
85
-
86
- throw new Error(`${objectPrint} was unexpected to be less than ${resultPrint}`)
87
- }
88
- } else {
89
- if (this._object >= result) {
90
- const objectPrint = formatValue(this._object)
91
- const resultPrint = formatValue(result)
92
-
93
- throw new Error(`${objectPrint} wasn't expected to be greater than or equal to ${resultPrint}`)
94
- }
95
- }
96
- }
97
-
98
- /**
99
- * Runs to be less than or equal.
100
- * @param {number} result - Result.
101
- * @returns {void} - No return value.
102
- */
103
- toBeLessThanOrEqual(result) {
104
- if (typeof this._object !== "number" || typeof result !== "number") {
105
- throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`)
106
- }
107
-
108
- if (this._not) {
109
- if (this._object <= result) {
110
- const objectPrint = formatValue(this._object)
111
- const resultPrint = formatValue(result)
112
-
113
- throw new Error(`${objectPrint} was unexpected to be less than or equal to ${resultPrint}`)
114
- }
115
- } else {
116
- if (this._object > result) {
117
- const objectPrint = formatValue(this._object)
118
- const resultPrint = formatValue(result)
119
-
120
- throw new Error(`${objectPrint} wasn't expected to be greater than ${resultPrint}`)
121
- }
122
- }
123
- }
124
-
125
- /**
126
- * Runs to be greater than.
127
- * @param {number} result - Result.
128
- * @returns {void} - No return value.
129
- */
130
- toBeGreaterThan(result) {
131
- if (typeof this._object !== "number" || typeof result !== "number") {
132
- throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`)
133
- }
134
-
135
- if (this._not) {
136
- if (this._object > result) {
137
- const objectPrint = formatValue(this._object)
138
- const resultPrint = formatValue(result)
139
-
140
- throw new Error(`${objectPrint} was unexpected to be greater than ${resultPrint}`)
141
- }
142
- } else {
143
- if (this._object <= result) {
144
- const objectPrint = formatValue(this._object)
145
- const resultPrint = formatValue(result)
146
-
147
- throw new Error(`${objectPrint} wasn't expected to be less than or equal to ${resultPrint}`)
148
- }
149
- }
150
- }
151
-
152
- /**
153
- * Runs to be greater than or equal.
154
- * @param {number} result - Result.
155
- * @returns {void} - No return value.
156
- */
157
- toBeGreaterThanOrEqual(result) {
158
- if (typeof this._object !== "number" || typeof result !== "number") {
159
- throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`)
160
- }
161
-
162
- if (this._not) {
163
- if (this._object >= result) {
164
- const objectPrint = formatValue(this._object)
165
- const resultPrint = formatValue(result)
166
-
167
- throw new Error(`${objectPrint} was unexpected to be greater than or equal to ${resultPrint}`)
168
- }
169
- } else {
170
- if (this._object < result) {
171
- const objectPrint = formatValue(this._object)
172
- const resultPrint = formatValue(result)
173
-
174
- throw new Error(`${objectPrint} wasn't expected to be less than ${resultPrint}`)
175
- }
176
- }
177
- }
178
-
179
- /**
180
- * Runs to be close to.
181
- * @param {number} result - Result.
182
- * @param {number} [precision] - Decimal precision.
183
- * @returns {void} - No return value.
184
- */
185
- toBeCloseTo(result, precision = 2) {
186
- if (typeof this._object !== "number" || typeof result !== "number") {
187
- throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`)
188
- }
189
-
190
- if (typeof precision !== "number" || !Number.isFinite(precision)) {
191
- throw new Error(`Expected precision to be a number but got ${typeof precision}`)
192
- }
193
-
194
- const tolerance = 0.5 * Math.pow(10, -precision)
195
- const diff = Math.abs(this._object - result)
196
- const isClose = diff <= tolerance
197
-
198
- if (this._not) {
199
- if (isClose) {
200
- const objectPrint = formatValue(this._object)
201
- const resultPrint = formatValue(result)
202
-
203
- throw new Error(`${objectPrint} was unexpected to be close to ${resultPrint}`)
204
- }
205
- } else {
206
- if (!isClose) {
207
- const objectPrint = formatValue(this._object)
208
- const resultPrint = formatValue(result)
209
-
210
- throw new Error(`${objectPrint} wasn't expected to be close to ${resultPrint}`)
211
- }
212
- }
213
- }
214
-
215
- /**
216
- * Runs to have length.
217
- * @param {number} result - Expected length.
218
- * @returns {void} - No return value.
219
- */
220
- toHaveLength(result) {
221
- if (typeof result !== "number") {
222
- throw new Error(`Expected length number but got ${typeof result}`)
223
- }
224
-
225
- if (this._object === null || this._object === undefined || typeof this._object.length !== "number") {
226
- throw new Error(`Expected value with length but got ${typeof this._object}`)
227
- }
228
-
229
- const objectPrint = formatValue(this._object)
230
- const resultPrint = formatValue(result)
231
- const lengthValue = this._object.length
232
-
233
- if (this._not) {
234
- if (lengthValue === result) {
235
- throw new Error(`${objectPrint} was unexpected to have length ${resultPrint}`)
236
- }
237
- } else if (lengthValue !== result) {
238
- throw new Error(`${objectPrint} wasn't expected to have length ${resultPrint}`)
239
- }
240
- }
241
-
242
- /**
243
- * Runs to be defined.
244
- * @returns {void} - No return value.
245
- */
246
- toBeDefined() {
247
- if (this._not) {
248
- if (this._object !== undefined) {
249
- const objectPrint = formatValue(this._object)
250
-
251
- throw new Error(`${objectPrint} wasn´t expected to be defined`)
252
- }
253
- } else {
254
- if (this._object === undefined) {
255
- const objectPrint = formatValue(this._object)
256
-
257
- throw new Error(`${objectPrint} wasn't expected be undefined`)
258
- }
259
- }
260
- }
261
-
262
- /**
263
- * Runs to be instance of.
264
- * @param {new (...args: Array<?>) => ?} klass - Class constructor to check against (e.g. a built-in like Error).
265
- * @returns {void} - No return value.
266
- */
267
- toBeInstanceOf(klass) {
268
- if (!(this._object instanceof klass)) {
269
- const objectPrint = formatValue(this._object)
270
-
271
- throw new Error(`Expected ${objectPrint} to be a ${klass.name} but it wasn't`)
272
- }
273
- }
274
-
275
- /**
276
- * Runs to be false.
277
- * @returns {void} - No return value.
278
- */
279
- toBeFalse() {
280
- this.toBe(false)
281
- }
282
-
283
- /**
284
- * Runs to be null.
285
- * @returns {void} - No return value.
286
- */
287
- toBeNull() {
288
- this.toBe(null)
289
- }
290
-
291
- /**
292
- * Runs to be undefined.
293
- * @returns {void} - No return value.
294
- */
295
- toBeUndefined() {
296
- this.toBe(undefined)
297
- }
298
-
299
- /**
300
- * Runs to be true.
301
- * @returns {void} - No return value.
302
- */
303
- toBeTrue() {
304
- this.toBe(true)
305
- }
306
-
307
- /**
308
- * Runs to be truthy.
309
- * @returns {void} - No return value.
310
- */
311
- toBeTruthy() {
312
- const objectPrint = formatValue(this._object)
313
-
314
- if (this._not) {
315
- if (this._object) {
316
- throw new Error(`${objectPrint} was unexpected to be truthy`)
317
- }
318
- } else {
319
- if (!this._object) {
320
- throw new Error(`${objectPrint} wasn't expected to be truthy`)
321
- }
322
- }
323
- }
324
-
325
- /**
326
- * Runs to change.
327
- * @param {function(): Promise<number>} changeCallback - Change callback.
328
- * @returns {ExpectToChange} - The change.
329
- */
330
- toChange(changeCallback) {
331
- if (this._not) throw new Error("not stub")
332
-
333
- const expectToChange = new ExpectToChange({changeCallback, expect: this})
334
-
335
- this.expectations.push(expectToChange)
336
-
337
- return expectToChange
338
- }
339
-
340
- /**
341
- * Runs to contain.
342
- * @param {?} valueToContain - Value to contain.
343
- * @returns {void} - No return value.
344
- */
345
- toContain(valueToContain) {
346
- if (typeof this._object == "string") {
347
- const matches = this._object.includes(String(valueToContain))
348
- const objectPrint = minifiedStringify(this._object)
349
- const valuePrint = typeof valueToContain == "string"
350
- ? minifiedStringify(valueToContain)
351
- : formatValue(valueToContain)
352
-
353
- if (this._not) {
354
- if (matches) {
355
- throw new Error(`${objectPrint} was unexpected to contain ${valuePrint}`)
356
- }
357
- } else if (!matches) {
358
- throw new Error(`${objectPrint} doesn't contain ${valuePrint}`)
359
- }
360
-
361
- return
362
- }
363
-
364
- if (!Array.isArray(this._object)) {
365
- throw new Error(`Expected array or string but got ${typeof this._object}`)
366
- }
367
-
368
- const matches = this._object.includes(valueToContain)
369
- const objectPrint = formatValue(this._object)
370
- const valuePrint = typeof valueToContain == "string"
371
- ? minifiedStringify(valueToContain)
372
- : formatValue(valueToContain)
373
-
374
- if (this._not) {
375
- if (matches) {
376
- throw new Error(`${objectPrint} was unexpected to contain ${valuePrint}`)
377
- }
378
- } else if (!matches) {
379
- throw new Error(`${objectPrint} doesn't contain ${valuePrint}`)
380
- }
381
- }
382
-
383
- /**
384
- * Runs to contain equal.
385
- * @param {?} valueToContain - Value to contain.
386
- * @returns {void} - No return value.
387
- */
388
- toContainEqual(valueToContain) {
389
- if (!Array.isArray(this._object)) {
390
- throw new Error(`Expected array but got ${typeof this._object}`)
391
- }
392
-
393
- const matches = this._object.some((item) => !anythingDifferent(item, valueToContain))
394
- const objectPrint = formatValue(this._object)
395
- const valuePrint = typeof valueToContain == "string"
396
- ? minifiedStringify(valueToContain)
397
- : formatValue(valueToContain)
398
-
399
- if (this._not) {
400
- if (matches) {
401
- throw new Error(`${objectPrint} was unexpected to contain ${valuePrint}`)
402
- }
403
- } else if (!matches) {
404
- throw new Error(`${objectPrint} doesn't contain ${valuePrint}`)
20
+ /**
21
+ * Runs and change.
22
+ * @param {function(): Promise<number>} changeCallback - Change callback.
23
+ * @returns {ExpectToChange} - The and change.
24
+ */
25
+ andChange(changeCallback) {
26
+ return this.toChange(changeCallback);
405
27
  }
406
- }
407
-
408
- /**
409
- * Runs to equal.
410
- * @param {?} result - Result.
411
- * @returns {void} - No return value.
412
- */
413
- toEqual(result) {
414
- if (this._object instanceof Set && result instanceof Set) {
415
- const objectPrint = formatValue(this._object)
416
- const resultPrint = formatValue(result)
417
- const actualItems = Array.from(this._object)
418
- const expectedItems = Array.from(result)
419
- const missingItems = expectedItems.filter((expectedItem) => {
420
- return !actualItems.some((actualItem) => !anythingDifferent(actualItem, expectedItem))
421
- })
422
- const unexpectedItems = actualItems.filter((actualItem) => {
423
- return !expectedItems.some((expectedItem) => !anythingDifferent(actualItem, expectedItem))
424
- })
425
- const isEqual = missingItems.length === 0 && unexpectedItems.length === 0
426
-
427
- if (this._not) {
428
- if (isEqual) {
429
- throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`)
430
- }
431
- } else if (!isEqual) {
432
- const missingStrings = missingItems.map((item) => minifiedStringify(item))
433
- const unexpectedStrings = unexpectedItems.map((item) => minifiedStringify(item))
434
- const diffParts = []
435
-
436
- if (missingStrings.length > 0) diffParts.push(`missing ${missingStrings.join(", ")}`)
437
- if (unexpectedStrings.length > 0) diffParts.push(`unexpected ${unexpectedStrings.join(", ")}`)
438
-
439
- const diffMessage = diffParts.length > 0 ? ` (diff: ${diffParts.join("; ")})` : ""
440
-
441
- throw new Error(`${objectPrint} wasn't equal to ${resultPrint}${diffMessage}`)
442
- }
443
-
444
- return
28
+ /**
29
+ * Returns not.
30
+ * @returns {this} - A value.
31
+ */
32
+ get not() {
33
+ this._not = true;
34
+ return this;
445
35
  }
446
-
447
- if (isObjectContaining(result)) {
448
- const expectedValue = /**
449
- * Narrows the runtime value to the documented type.
450
- @type {?} */ (result).value
451
- const {matches, differences} = matchObject(this._object, expectedValue)
452
- const objectPrint = formatValue(this._object)
453
- const expectedPrint = formatValue(expectedValue)
454
-
455
- if (this._not) {
456
- if (matches) {
457
- throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`)
458
- }
459
- } else if (!matches) {
460
- const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : ""
461
-
462
- throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`)
463
- }
464
-
465
- return
36
+ /**
37
+ * Runs to be.
38
+ * @param {?} result - Result.
39
+ * @returns {void} - No return value.
40
+ */
41
+ toBe(result) {
42
+ if (this._not) {
43
+ if (this._object === result) {
44
+ const objectPrint = formatValue(this._object);
45
+ const resultPrint = formatValue(result);
46
+ throw new Error(`${objectPrint} was unexpected not to be ${resultPrint}`);
47
+ }
48
+ }
49
+ else {
50
+ if (this._object !== result) {
51
+ const objectPrint = formatValue(this._object);
52
+ const resultPrint = formatValue(result);
53
+ throw new Error(`${objectPrint} wasn't expected be ${resultPrint}`);
54
+ }
55
+ }
466
56
  }
467
-
468
- if (isArrayContaining(result)) {
469
- const expectedValue = /**
470
- * Narrows the runtime value to the documented type.
471
- @type {Array<?>} */ (/**
472
- * Narrows the runtime value to the documented type.
473
- @type {?} */ (result).value)
474
- const {matches, differences} = matchArrayContaining(this._object, expectedValue)
475
- const objectPrint = formatValue(this._object)
476
- const expectedPrint = formatValue(expectedValue)
477
-
478
- if (this._not) {
479
- if (matches) {
480
- throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`)
481
- }
482
- } else if (!matches) {
483
- const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : ""
484
-
485
- throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`)
486
- }
487
-
488
- return
57
+ /**
58
+ * Runs to be less than.
59
+ * @param {number} result - Result.
60
+ * @returns {void} - No return value.
61
+ */
62
+ toBeLessThan(result) {
63
+ if (typeof this._object !== "number" || typeof result !== "number") {
64
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
65
+ }
66
+ if (this._not) {
67
+ if (this._object < result) {
68
+ const objectPrint = formatValue(this._object);
69
+ const resultPrint = formatValue(result);
70
+ throw new Error(`${objectPrint} was unexpected to be less than ${resultPrint}`);
71
+ }
72
+ }
73
+ else {
74
+ if (this._object >= result) {
75
+ const objectPrint = formatValue(this._object);
76
+ const resultPrint = formatValue(result);
77
+ throw new Error(`${objectPrint} wasn't expected to be greater than or equal to ${resultPrint}`);
78
+ }
79
+ }
489
80
  }
490
-
491
- if (this._not) {
492
- if (typeof this._object == "object" && typeof result == "object") {
493
- if (!anythingDifferent(this._object, result)) {
494
- const objectPrint = formatValue(this._object)
495
- const resultPrint = formatValue(result)
496
-
497
- throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`)
498
- }
499
- } else {
500
- if (this._object == result) {
501
- const objectPrint = formatValue(this._object)
502
- const resultPrint = formatValue(result)
503
-
504
- throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`)
505
- }
506
- }
507
- } else {
508
- if (typeof this._object == "object" && typeof result == "object") {
509
- if (anythingDifferent(this._object, result)) {
510
- const objectPrint = formatValue(this._object)
511
- const resultPrint = formatValue(result)
512
-
513
- if (Array.isArray(this._object) && Array.isArray(result)) {
514
- const actualStrings = this._object.map((item) => minifiedStringify(item))
515
- const expectedStrings = result.map((item) => minifiedStringify(item))
516
-
517
- const missingItems = expectedStrings.filter((item) => !actualStrings.includes(item))
518
- const unexpectedItems = actualStrings.filter((item) => !expectedStrings.includes(item))
519
-
520
- const diffParts = []
521
-
522
- if (missingItems.length > 0) diffParts.push(`missing ${missingItems.join(", ")}`)
523
- if (unexpectedItems.length > 0) diffParts.push(`unexpected ${unexpectedItems.join(", ")}`)
524
-
525
- const diffMessage = diffParts.length > 0 ? ` (diff: ${diffParts.join("; ")})` : ""
526
-
527
- throw new Error(`${objectPrint} wasn't equal to ${resultPrint}${diffMessage}`)
528
- }
529
-
530
- throw new Error(`${objectPrint} wasn't equal to ${resultPrint}`)
531
- }
532
- } else {
533
- if (this._object != result) {
534
- const objectPrint = formatValue(this._object)
535
- const resultPrint = formatValue(result)
536
-
537
- throw new Error(`${objectPrint} wasn't equal to ${resultPrint}`)
538
- }
539
- }
81
+ /**
82
+ * Runs to be less than or equal.
83
+ * @param {number} result - Result.
84
+ * @returns {void} - No return value.
85
+ */
86
+ toBeLessThanOrEqual(result) {
87
+ if (typeof this._object !== "number" || typeof result !== "number") {
88
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
89
+ }
90
+ if (this._not) {
91
+ if (this._object <= result) {
92
+ const objectPrint = formatValue(this._object);
93
+ const resultPrint = formatValue(result);
94
+ throw new Error(`${objectPrint} was unexpected to be less than or equal to ${resultPrint}`);
95
+ }
96
+ }
97
+ else {
98
+ if (this._object > result) {
99
+ const objectPrint = formatValue(this._object);
100
+ const resultPrint = formatValue(result);
101
+ throw new Error(`${objectPrint} wasn't expected to be greater than ${resultPrint}`);
102
+ }
103
+ }
540
104
  }
541
- }
542
-
543
- /**
544
- * Runs to match.
545
- * @param {RegExp} regex - Regex.
546
- * @returns {void} - No return value.
547
- */
548
- toMatch(regex) {
549
- if (typeof this._object !== "string") {
550
- throw new Error(`Expected string but got ${typeof this._object}`)
105
+ /**
106
+ * Runs to be greater than.
107
+ * @param {number} result - Result.
108
+ * @returns {void} - No return value.
109
+ */
110
+ toBeGreaterThan(result) {
111
+ if (typeof this._object !== "number" || typeof result !== "number") {
112
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
113
+ }
114
+ if (this._not) {
115
+ if (this._object > result) {
116
+ const objectPrint = formatValue(this._object);
117
+ const resultPrint = formatValue(result);
118
+ throw new Error(`${objectPrint} was unexpected to be greater than ${resultPrint}`);
119
+ }
120
+ }
121
+ else {
122
+ if (this._object <= result) {
123
+ const objectPrint = formatValue(this._object);
124
+ const resultPrint = formatValue(result);
125
+ throw new Error(`${objectPrint} wasn't expected to be less than or equal to ${resultPrint}`);
126
+ }
127
+ }
551
128
  }
552
-
553
- const match = this._object.match(regex)
554
- const objectPrint = minifiedStringify(this._object)
555
-
556
- if (this._not) {
557
- if (match) {
558
- throw new Error(`${objectPrint} shouldn't match ${regex}`)
559
- }
560
- } else {
561
- if (!match) {
562
- throw new Error(`${objectPrint} didn't match ${regex}`)
563
- }
129
+ /**
130
+ * Runs to be greater than or equal.
131
+ * @param {number} result - Result.
132
+ * @returns {void} - No return value.
133
+ */
134
+ toBeGreaterThanOrEqual(result) {
135
+ if (typeof this._object !== "number" || typeof result !== "number") {
136
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
137
+ }
138
+ if (this._not) {
139
+ if (this._object >= result) {
140
+ const objectPrint = formatValue(this._object);
141
+ const resultPrint = formatValue(result);
142
+ throw new Error(`${objectPrint} was unexpected to be greater than or equal to ${resultPrint}`);
143
+ }
144
+ }
145
+ else {
146
+ if (this._object < result) {
147
+ const objectPrint = formatValue(this._object);
148
+ const resultPrint = formatValue(result);
149
+ throw new Error(`${objectPrint} wasn't expected to be less than ${resultPrint}`);
150
+ }
151
+ }
564
152
  }
565
- }
566
-
567
- /**
568
- * Runs to match object.
569
- * @param {Record<string, ?> | Array<?>} expected - Expected partial object.
570
- * @returns {void} - No return value.
571
- */
572
- toMatchObject(expected) {
573
- if (expected === null || typeof expected !== "object") {
574
- throw new Error(`Expected object but got ${typeof expected}`)
153
+ /**
154
+ * Runs to be close to.
155
+ * @param {number} result - Result.
156
+ * @param {number} [precision] - Decimal precision.
157
+ * @returns {void} - No return value.
158
+ */
159
+ toBeCloseTo(result, precision = 2) {
160
+ if (typeof this._object !== "number" || typeof result !== "number") {
161
+ throw new Error(`Expected numbers but got ${typeof this._object} and ${typeof result}`);
162
+ }
163
+ if (typeof precision !== "number" || !Number.isFinite(precision)) {
164
+ throw new Error(`Expected precision to be a number but got ${typeof precision}`);
165
+ }
166
+ const tolerance = 0.5 * Math.pow(10, -precision);
167
+ const diff = Math.abs(this._object - result);
168
+ const isClose = diff <= tolerance;
169
+ if (this._not) {
170
+ if (isClose) {
171
+ const objectPrint = formatValue(this._object);
172
+ const resultPrint = formatValue(result);
173
+ throw new Error(`${objectPrint} was unexpected to be close to ${resultPrint}`);
174
+ }
175
+ }
176
+ else {
177
+ if (!isClose) {
178
+ const objectPrint = formatValue(this._object);
179
+ const resultPrint = formatValue(result);
180
+ throw new Error(`${objectPrint} wasn't expected to be close to ${resultPrint}`);
181
+ }
182
+ }
575
183
  }
576
-
577
- const {matches, differences} = matchObject(this._object, expected)
578
- const objectPrint = formatValue(this._object)
579
- const expectedPrint = formatValue(expected)
580
-
581
- if (this._not) {
582
- if (matches) {
583
- throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`)
584
- }
585
- } else if (!matches) {
586
- const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : ""
587
-
588
- throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`)
184
+ /**
185
+ * Runs to have length.
186
+ * @param {number} result - Expected length.
187
+ * @returns {void} - No return value.
188
+ */
189
+ toHaveLength(result) {
190
+ if (typeof result !== "number") {
191
+ throw new Error(`Expected length number but got ${typeof result}`);
192
+ }
193
+ if (this._object === null || this._object === undefined || typeof this._object.length !== "number") {
194
+ throw new Error(`Expected value with length but got ${typeof this._object}`);
195
+ }
196
+ const objectPrint = formatValue(this._object);
197
+ const resultPrint = formatValue(result);
198
+ const lengthValue = this._object.length;
199
+ if (this._not) {
200
+ if (lengthValue === result) {
201
+ throw new Error(`${objectPrint} was unexpected to have length ${resultPrint}`);
202
+ }
203
+ }
204
+ else if (lengthValue !== result) {
205
+ throw new Error(`${objectPrint} wasn't expected to have length ${resultPrint}`);
206
+ }
589
207
  }
590
- }
591
-
592
- /**
593
- * Runs to throw error.
594
- * @template T extends Error
595
- * @param {string|T} expectedError - Expected error.
596
- * @returns {Promise<void>} - Resolves when complete.
597
- */
598
- async toThrowError(expectedError) {
599
- if (this._not) throw new Error("not stub")
600
-
601
- let failedError
602
-
603
- try {
604
- if (typeof this._object !== "function") {
605
- throw new Error(`Expected function but got ${typeof this._object}`)
606
- }
607
-
608
- await this._object()
609
- } catch (error) {
610
- failedError = error
208
+ /**
209
+ * Runs to be defined.
210
+ * @returns {void} - No return value.
211
+ */
212
+ toBeDefined() {
213
+ if (this._not) {
214
+ if (this._object !== undefined) {
215
+ const objectPrint = formatValue(this._object);
216
+ throw new Error(`${objectPrint} wasn´t expected to be defined`);
217
+ }
218
+ }
219
+ else {
220
+ if (this._object === undefined) {
221
+ const objectPrint = formatValue(this._object);
222
+ throw new Error(`${objectPrint} wasn't expected be undefined`);
223
+ }
224
+ }
611
225
  }
612
-
613
- if (!failedError) throw new Error("Expected to fail but didn't")
614
-
615
- let expectedErrorMessage, failedErrorMessage
616
-
617
- if (typeof failedError == "string") {
618
- failedErrorMessage = failedError
619
- } else if (failedError instanceof Error) {
620
- failedErrorMessage = failedError.message
621
- } else {
622
- failedErrorMessage = String(failedError)
226
+ /**
227
+ * Runs to be instance of.
228
+ * @param {new (...args: Array<?>) => ?} klass - Class constructor to check against (e.g. a built-in like Error).
229
+ * @returns {void} - No return value.
230
+ */
231
+ toBeInstanceOf(klass) {
232
+ if (!(this._object instanceof klass)) {
233
+ const objectPrint = formatValue(this._object);
234
+ throw new Error(`Expected ${objectPrint} to be a ${klass.name} but it wasn't`);
235
+ }
623
236
  }
624
-
625
- if (typeof expectedError == "string") {
626
- expectedErrorMessage = expectedError
627
- } else if (expectedError instanceof Error) {
628
- expectedErrorMessage = expectedError.message
629
- } else {
630
- expectedErrorMessage = String(expectedError)
237
+ /**
238
+ * Runs to be false.
239
+ * @returns {void} - No return value.
240
+ */
241
+ toBeFalse() {
242
+ this.toBe(false);
631
243
  }
632
-
633
- if (failedErrorMessage != expectedErrorMessage) {
634
- throw new Error(`Expected to fail with '${expectedErrorMessage}' but failed with '${failedErrorMessage}'`)
244
+ /**
245
+ * Runs to be null.
246
+ * @returns {void} - No return value.
247
+ */
248
+ toBeNull() {
249
+ this.toBe(null);
635
250
  }
636
- }
637
-
638
- /**
639
- * Runs to throw.
640
- * @param {string|RegExp|Error|((new (...args: Array<?>) => Error))} [expected] - Expected error.
641
- * @returns {Promise<void>} - Resolves when complete.
642
- */
643
- async toThrow(expected) {
644
- if (typeof this._object !== "function") {
645
- throw new Error(`Expected function but got ${typeof this._object}`)
251
+ /**
252
+ * Runs to be undefined.
253
+ * @returns {void} - No return value.
254
+ */
255
+ toBeUndefined() {
256
+ this.toBe(undefined);
646
257
  }
647
-
648
- let failedError
649
-
650
- try {
651
- await this._object()
652
- } catch (error) {
653
- failedError = error
258
+ /**
259
+ * Runs to be true.
260
+ * @returns {void} - No return value.
261
+ */
262
+ toBeTrue() {
263
+ this.toBe(true);
654
264
  }
655
-
656
- const objectPrint = formatValue(this._object)
657
-
658
- if (this._not) {
659
- if (failedError) {
660
- throw new Error(`${objectPrint} was unexpected to throw`)
661
- }
662
-
663
- return
265
+ /**
266
+ * Runs to be truthy.
267
+ * @returns {void} - No return value.
268
+ */
269
+ toBeTruthy() {
270
+ const objectPrint = formatValue(this._object);
271
+ if (this._not) {
272
+ if (this._object) {
273
+ throw new Error(`${objectPrint} was unexpected to be truthy`);
274
+ }
275
+ }
276
+ else {
277
+ if (!this._object) {
278
+ throw new Error(`${objectPrint} wasn't expected to be truthy`);
279
+ }
280
+ }
664
281
  }
665
-
666
- if (!failedError) throw new Error("Expected to fail but didn't")
667
- if (expected === undefined) return
668
-
669
- const failedErrorMessage = failedError instanceof Error ? failedError.message : String(failedError)
670
- const failedErrorName = failedError instanceof Error ? failedError.name : typeof failedError
671
-
672
- if (expected instanceof RegExp) {
673
- if (!expected.test(failedErrorMessage)) {
674
- throw new Error(`Expected to fail with message matching ${expected} but failed with '${failedErrorMessage}'`)
675
- }
676
-
677
- return
282
+ /**
283
+ * Runs to change.
284
+ * @param {function(): Promise<number>} changeCallback - Change callback.
285
+ * @returns {ExpectToChange} - The change.
286
+ */
287
+ toChange(changeCallback) {
288
+ if (this._not)
289
+ throw new Error("not stub");
290
+ const expectToChange = new ExpectToChange({ changeCallback, expect: this });
291
+ this.expectations.push(expectToChange);
292
+ return expectToChange;
678
293
  }
679
-
680
- if (typeof expected === "function" && (expected.prototype instanceof Error || expected === Error)) {
681
- if (!(failedError instanceof expected)) {
682
- throw new Error(`Expected to throw ${expected.name} but threw ${failedErrorName}`)
683
- }
684
-
685
- return
294
+ /**
295
+ * Runs to contain.
296
+ * @param {?} valueToContain - Value to contain.
297
+ * @returns {void} - No return value.
298
+ */
299
+ toContain(valueToContain) {
300
+ if (typeof this._object == "string") {
301
+ const matches = this._object.includes(String(valueToContain));
302
+ const objectPrint = minifiedStringify(this._object);
303
+ const valuePrint = typeof valueToContain == "string"
304
+ ? minifiedStringify(valueToContain)
305
+ : formatValue(valueToContain);
306
+ if (this._not) {
307
+ if (matches) {
308
+ throw new Error(`${objectPrint} was unexpected to contain ${valuePrint}`);
309
+ }
310
+ }
311
+ else if (!matches) {
312
+ throw new Error(`${objectPrint} doesn't contain ${valuePrint}`);
313
+ }
314
+ return;
315
+ }
316
+ if (!Array.isArray(this._object)) {
317
+ throw new Error(`Expected array or string but got ${typeof this._object}`);
318
+ }
319
+ const matches = this._object.includes(valueToContain);
320
+ const objectPrint = formatValue(this._object);
321
+ const valuePrint = typeof valueToContain == "string"
322
+ ? minifiedStringify(valueToContain)
323
+ : formatValue(valueToContain);
324
+ if (this._not) {
325
+ if (matches) {
326
+ throw new Error(`${objectPrint} was unexpected to contain ${valuePrint}`);
327
+ }
328
+ }
329
+ else if (!matches) {
330
+ throw new Error(`${objectPrint} doesn't contain ${valuePrint}`);
331
+ }
686
332
  }
687
-
688
- let expectedMessage
689
-
690
- if (typeof expected === "string") {
691
- expectedMessage = expected
692
- } else if (expected instanceof Error) {
693
- expectedMessage = expected.message
694
- } else {
695
- expectedMessage = String(expected)
333
+ /**
334
+ * Runs to contain equal.
335
+ * @param {?} valueToContain - Value to contain.
336
+ * @returns {void} - No return value.
337
+ */
338
+ toContainEqual(valueToContain) {
339
+ if (!Array.isArray(this._object)) {
340
+ throw new Error(`Expected array but got ${typeof this._object}`);
341
+ }
342
+ const matches = this._object.some((item) => !anythingDifferent(item, valueToContain));
343
+ const objectPrint = formatValue(this._object);
344
+ const valuePrint = typeof valueToContain == "string"
345
+ ? minifiedStringify(valueToContain)
346
+ : formatValue(valueToContain);
347
+ if (this._not) {
348
+ if (matches) {
349
+ throw new Error(`${objectPrint} was unexpected to contain ${valuePrint}`);
350
+ }
351
+ }
352
+ else if (!matches) {
353
+ throw new Error(`${objectPrint} doesn't contain ${valuePrint}`);
354
+ }
696
355
  }
697
-
698
- if (failedErrorMessage != expectedMessage) {
699
- throw new Error(`Expected to fail with '${expectedMessage}' but failed with '${failedErrorMessage}'`)
356
+ /**
357
+ * Runs to equal.
358
+ * @param {?} result - Result.
359
+ * @returns {void} - No return value.
360
+ */
361
+ toEqual(result) {
362
+ if (this._object instanceof Set && result instanceof Set) {
363
+ const objectPrint = formatValue(this._object);
364
+ const resultPrint = formatValue(result);
365
+ const actualItems = Array.from(this._object);
366
+ const expectedItems = Array.from(result);
367
+ const missingItems = expectedItems.filter((expectedItem) => {
368
+ return !actualItems.some((actualItem) => !anythingDifferent(actualItem, expectedItem));
369
+ });
370
+ const unexpectedItems = actualItems.filter((actualItem) => {
371
+ return !expectedItems.some((expectedItem) => !anythingDifferent(actualItem, expectedItem));
372
+ });
373
+ const isEqual = missingItems.length === 0 && unexpectedItems.length === 0;
374
+ if (this._not) {
375
+ if (isEqual) {
376
+ throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`);
377
+ }
378
+ }
379
+ else if (!isEqual) {
380
+ const missingStrings = missingItems.map((item) => minifiedStringify(item));
381
+ const unexpectedStrings = unexpectedItems.map((item) => minifiedStringify(item));
382
+ const diffParts = [];
383
+ if (missingStrings.length > 0)
384
+ diffParts.push(`missing ${missingStrings.join(", ")}`);
385
+ if (unexpectedStrings.length > 0)
386
+ diffParts.push(`unexpected ${unexpectedStrings.join(", ")}`);
387
+ const diffMessage = diffParts.length > 0 ? ` (diff: ${diffParts.join("; ")})` : "";
388
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}${diffMessage}`);
389
+ }
390
+ return;
391
+ }
392
+ if (isObjectContaining(result)) {
393
+ const expectedValue = /**
394
+ * Narrows the runtime value to the documented type.
395
+ @type {?} */ (result).value;
396
+ const { matches, differences } = matchObject(this._object, expectedValue);
397
+ const objectPrint = formatValue(this._object);
398
+ const expectedPrint = formatValue(expectedValue);
399
+ if (this._not) {
400
+ if (matches) {
401
+ throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`);
402
+ }
403
+ }
404
+ else if (!matches) {
405
+ const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : "";
406
+ throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`);
407
+ }
408
+ return;
409
+ }
410
+ if (isArrayContaining(result)) {
411
+ const expectedValue = /**
412
+ * Narrows the runtime value to the documented type.
413
+ @type {Array<?>} */ ( /**
414
+ * Narrows the runtime value to the documented type.
415
+ @type {?} */(result).value);
416
+ const { matches, differences } = matchArrayContaining(this._object, expectedValue);
417
+ const objectPrint = formatValue(this._object);
418
+ const expectedPrint = formatValue(expectedValue);
419
+ if (this._not) {
420
+ if (matches) {
421
+ throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`);
422
+ }
423
+ }
424
+ else if (!matches) {
425
+ const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : "";
426
+ throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`);
427
+ }
428
+ return;
429
+ }
430
+ if (this._not) {
431
+ if (typeof this._object == "object" && typeof result == "object") {
432
+ if (!anythingDifferent(this._object, result)) {
433
+ const objectPrint = formatValue(this._object);
434
+ const resultPrint = formatValue(result);
435
+ throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`);
436
+ }
437
+ }
438
+ else {
439
+ if (this._object == result) {
440
+ const objectPrint = formatValue(this._object);
441
+ const resultPrint = formatValue(result);
442
+ throw new Error(`${objectPrint} was unexpected equal to ${resultPrint}`);
443
+ }
444
+ }
445
+ }
446
+ else {
447
+ if (typeof this._object == "object" && typeof result == "object") {
448
+ if (anythingDifferent(this._object, result)) {
449
+ const objectPrint = formatValue(this._object);
450
+ const resultPrint = formatValue(result);
451
+ if (Array.isArray(this._object) && Array.isArray(result)) {
452
+ const actualStrings = this._object.map((item) => minifiedStringify(item));
453
+ const expectedStrings = result.map((item) => minifiedStringify(item));
454
+ const missingItems = expectedStrings.filter((item) => !actualStrings.includes(item));
455
+ const unexpectedItems = actualStrings.filter((item) => !expectedStrings.includes(item));
456
+ const diffParts = [];
457
+ if (missingItems.length > 0)
458
+ diffParts.push(`missing ${missingItems.join(", ")}`);
459
+ if (unexpectedItems.length > 0)
460
+ diffParts.push(`unexpected ${unexpectedItems.join(", ")}`);
461
+ const diffMessage = diffParts.length > 0 ? ` (diff: ${diffParts.join("; ")})` : "";
462
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}${diffMessage}`);
463
+ }
464
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}`);
465
+ }
466
+ }
467
+ else {
468
+ if (this._object != result) {
469
+ const objectPrint = formatValue(this._object);
470
+ const resultPrint = formatValue(result);
471
+ throw new Error(`${objectPrint} wasn't equal to ${resultPrint}`);
472
+ }
473
+ }
474
+ }
700
475
  }
701
- }
702
-
703
- /**
704
- * Runs execute.
705
- * @returns {Promise<?>} - Resolves with the execute.
706
- */
707
- async execute() {
708
- for (const expectation of this.expectations) {
709
- await expectation.runBefore()
476
+ /**
477
+ * Runs to match.
478
+ * @param {RegExp} regex - Regex.
479
+ * @returns {void} - No return value.
480
+ */
481
+ toMatch(regex) {
482
+ if (typeof this._object !== "string") {
483
+ throw new Error(`Expected string but got ${typeof this._object}`);
484
+ }
485
+ const match = this._object.match(regex);
486
+ const objectPrint = minifiedStringify(this._object);
487
+ if (this._not) {
488
+ if (match) {
489
+ throw new Error(`${objectPrint} shouldn't match ${regex}`);
490
+ }
491
+ }
492
+ else {
493
+ if (!match) {
494
+ throw new Error(`${objectPrint} didn't match ${regex}`);
495
+ }
496
+ }
710
497
  }
711
-
712
- if (typeof this._object !== "function") {
713
- throw new Error(`Expected function but got ${typeof this._object}`)
498
+ /**
499
+ * Runs to match object.
500
+ * @param {Record<string, ?> | Array<?>} expected - Expected partial object.
501
+ * @returns {void} - No return value.
502
+ */
503
+ toMatchObject(expected) {
504
+ if (expected === null || typeof expected !== "object") {
505
+ throw new Error(`Expected object but got ${typeof expected}`);
506
+ }
507
+ const { matches, differences } = matchObject(this._object, expected);
508
+ const objectPrint = formatValue(this._object);
509
+ const expectedPrint = formatValue(expected);
510
+ if (this._not) {
511
+ if (matches) {
512
+ throw new Error(`Expected ${objectPrint} not to match ${expectedPrint}`);
513
+ }
514
+ }
515
+ else if (!matches) {
516
+ const diffPrint = Object.keys(differences).length > 0 ? ` (diff: ${minifiedStringify(differences)})` : "";
517
+ throw new Error(`Expected ${objectPrint} to match ${expectedPrint}${diffPrint}`);
518
+ }
714
519
  }
715
-
716
- const result = await this._object()
717
-
718
- for (const expectation of this.expectations) {
719
- await expectation.runAfter()
520
+ /**
521
+ * Runs to throw error.
522
+ * @template T extends Error
523
+ * @param {string|T} expectedError - Expected error.
524
+ * @returns {Promise<void>} - Resolves when complete.
525
+ */
526
+ async toThrowError(expectedError) {
527
+ if (this._not)
528
+ throw new Error("not stub");
529
+ let failedError;
530
+ try {
531
+ if (typeof this._object !== "function") {
532
+ throw new Error(`Expected function but got ${typeof this._object}`);
533
+ }
534
+ await this._object();
535
+ }
536
+ catch (error) {
537
+ failedError = error;
538
+ }
539
+ if (!failedError)
540
+ throw new Error("Expected to fail but didn't");
541
+ let expectedErrorMessage, failedErrorMessage;
542
+ if (typeof failedError == "string") {
543
+ failedErrorMessage = failedError;
544
+ }
545
+ else if (failedError instanceof Error) {
546
+ failedErrorMessage = failedError.message;
547
+ }
548
+ else {
549
+ failedErrorMessage = String(failedError);
550
+ }
551
+ if (typeof expectedError == "string") {
552
+ expectedErrorMessage = expectedError;
553
+ }
554
+ else if (expectedError instanceof Error) {
555
+ expectedErrorMessage = expectedError.message;
556
+ }
557
+ else {
558
+ expectedErrorMessage = String(expectedError);
559
+ }
560
+ if (failedErrorMessage != expectedErrorMessage) {
561
+ throw new Error(`Expected to fail with '${expectedErrorMessage}' but failed with '${failedErrorMessage}'`);
562
+ }
720
563
  }
721
-
722
- for (const expectation of this.expectations) {
723
- await expectation.execute()
564
+ /**
565
+ * Runs to throw.
566
+ * @param {string|RegExp|Error|((new (...args: Array<?>) => Error))} [expected] - Expected error.
567
+ * @returns {Promise<void>} - Resolves when complete.
568
+ */
569
+ async toThrow(expected) {
570
+ if (typeof this._object !== "function") {
571
+ throw new Error(`Expected function but got ${typeof this._object}`);
572
+ }
573
+ let failedError;
574
+ try {
575
+ await this._object();
576
+ }
577
+ catch (error) {
578
+ failedError = error;
579
+ }
580
+ const objectPrint = formatValue(this._object);
581
+ if (this._not) {
582
+ if (failedError) {
583
+ throw new Error(`${objectPrint} was unexpected to throw`);
584
+ }
585
+ return;
586
+ }
587
+ if (!failedError)
588
+ throw new Error("Expected to fail but didn't");
589
+ if (expected === undefined)
590
+ return;
591
+ const failedErrorMessage = failedError instanceof Error ? failedError.message : String(failedError);
592
+ const failedErrorName = failedError instanceof Error ? failedError.name : typeof failedError;
593
+ if (expected instanceof RegExp) {
594
+ if (!expected.test(failedErrorMessage)) {
595
+ throw new Error(`Expected to fail with message matching ${expected} but failed with '${failedErrorMessage}'`);
596
+ }
597
+ return;
598
+ }
599
+ if (typeof expected === "function" && (expected.prototype instanceof Error || expected === Error)) {
600
+ if (!(failedError instanceof expected)) {
601
+ throw new Error(`Expected to throw ${expected.name} but threw ${failedErrorName}`);
602
+ }
603
+ return;
604
+ }
605
+ let expectedMessage;
606
+ if (typeof expected === "string") {
607
+ expectedMessage = expected;
608
+ }
609
+ else if (expected instanceof Error) {
610
+ expectedMessage = expected.message;
611
+ }
612
+ else {
613
+ expectedMessage = String(expected);
614
+ }
615
+ if (failedErrorMessage != expectedMessage) {
616
+ throw new Error(`Expected to fail with '${expectedMessage}' but failed with '${failedErrorMessage}'`);
617
+ }
724
618
  }
725
-
726
- return result
727
- }
728
-
729
- /**
730
- * Runs to have attributes.
731
- * @param {Record<string, ?>} result - Result.
732
- * @returns {void} - No return value.
733
- */
734
- toHaveAttributes(result) {
735
- if (this._not) throw new Error("not stub")
736
-
737
619
  /**
738
- * Differences.
739
- @type {Record<string, Array<?>>} */
740
- const differences = {}
741
- const objectAsRecord = /**
742
- * Narrows the runtime value to the documented type.
743
- @type {Record<string, ?>} */ (this._object)
744
-
745
- for (const key in result) {
746
- const value = result[key]
747
-
748
- if (!(key in objectAsRecord)) throw new Error(`${this._object.constructor.name} doesn't respond to ${key}`)
749
-
750
- const objectValue = /**
751
- * Narrows the runtime value to the documented type.
752
- @type {() => ?} */ (objectAsRecord[key])()
753
-
754
- if (value != objectValue) {
755
- differences[key] = [value, objectValue]
756
- }
620
+ * Runs execute.
621
+ * @returns {Promise<?>} - Resolves with the execute.
622
+ */
623
+ async execute() {
624
+ for (const expectation of this.expectations) {
625
+ await expectation.runBefore();
626
+ }
627
+ if (typeof this._object !== "function") {
628
+ throw new Error(`Expected function but got ${typeof this._object}`);
629
+ }
630
+ const result = await this._object();
631
+ for (const expectation of this.expectations) {
632
+ await expectation.runAfter();
633
+ }
634
+ for (const expectation of this.expectations) {
635
+ await expectation.execute();
636
+ }
637
+ return result;
757
638
  }
758
-
759
- if (Object.keys(differences).length > 0) {
760
- throw new Error(`Object had differet values: ${minifiedStringify(differences)}`)
639
+ /**
640
+ * Runs to have attributes.
641
+ * @param {Record<string, ?>} result - Result.
642
+ * @returns {void} - No return value.
643
+ */
644
+ toHaveAttributes(result) {
645
+ if (this._not)
646
+ throw new Error("not stub");
647
+ /**
648
+ * Differences.
649
+ @type {Record<string, Array<?>>} */
650
+ const differences = {};
651
+ const objectAsRecord = /**
652
+ * Narrows the runtime value to the documented type.
653
+ @type {Record<string, ?>} */ (this._object);
654
+ for (const key in result) {
655
+ const value = result[key];
656
+ if (!(key in objectAsRecord))
657
+ throw new Error(`${this._object.constructor.name} doesn't respond to ${key}`);
658
+ const objectValue = /**
659
+ * Narrows the runtime value to the documented type.
660
+ @type {() => ?} */ (objectAsRecord[key])();
661
+ if (value != objectValue) {
662
+ differences[key] = [value, objectValue];
663
+ }
664
+ }
665
+ if (Object.keys(differences).length > 0) {
666
+ throw new Error(`Object had differet values: ${minifiedStringify(differences)}`);
667
+ }
761
668
  }
762
- }
763
669
  }
670
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Rlc3RpbmcvZXhwZWN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsV0FBVyxFQUFFLGlCQUFpQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDdkUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sdUNBQXVDLENBQUE7QUFDdkUsT0FBTyxVQUFVLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxjQUFjLE1BQU0sdUJBQXVCLENBQUE7QUFDbEQsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixrQkFBa0IsRUFDbEIsb0JBQW9CLEVBQ3BCLFdBQVcsRUFDWixNQUFNLG1CQUFtQixDQUFBO0FBRTFCLE1BQU0sQ0FBQyxPQUFPLE9BQU8sTUFBTyxTQUFRLFVBQVU7SUFDNUM7OztPQUdHO0lBQ0gsWUFBWSxNQUFNO1FBQ2hCLEtBQUssRUFBRSxDQUFBO1FBQ1AsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUE7UUFFckI7O21EQUUyQztRQUMzQyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQTtJQUN4QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFNBQVMsQ0FBQyxjQUFjO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUN0QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBSSxHQUFHO1FBQ0wsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7UUFFaEIsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQUksQ0FBQyxNQUFNO1FBQ1QsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDZCxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssTUFBTSxFQUFFLENBQUM7Z0JBQzVCLE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FB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QUMsQ0FBQTtZQUV6QixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksY0FBYyxDQUFDO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLHVCQUF1QixHQUFHLEVBQUUsQ0FBQyxDQUFBO1lBRTNHLE1BQU0sV0FBVyxHQUFHOztvREFFb0IsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUE7WUFFaEUsSUFBSSxLQUFLLElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQ3pCLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQTtZQUN6QyxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsaUJBQWlCLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2xGLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtmb3JtYXRWYWx1ZSwgbWluaWZpZWRTdHJpbmdpZnl9IGZyb20gXCIuLi91dGlscy9mb3JtYXQtdmFsdWUuanNcIlxuaW1wb3J0IHthbnl0aGluZ0RpZmZlcmVudH0gZnJvbSBcInNldC1zdGF0ZS1jb21wYXJlL2J1aWxkL2RpZmYtdXRpbHMuanNcIlxuaW1wb3J0IEJhc2VFeHBlY3QgZnJvbSBcIi4vYmFzZS1leHBlY3QuanNcIlxuaW1wb3J0IEV4cGVjdFRvQ2hhbmdlIGZyb20gXCIuL2V4cGVjdC10by1jaGFuZ2UuanNcIlxuaW1wb3J0IHtcbiAgaXNBcnJheUNvbnRhaW5pbmcsXG4gIGlzT2JqZWN0Q29udGFpbmluZyxcbiAgbWF0Y2hBcnJheUNvbnRhaW5pbmcsXG4gIG1hdGNoT2JqZWN0XG59IGZyb20gXCIuL2V4cGVjdC11dGlscy5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV4cGVjdCBleHRlbmRzIEJhc2VFeHBlY3Qge1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHs/fSBvYmplY3QgLSBPYmplY3QuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvYmplY3QpIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5fb2JqZWN0ID0gb2JqZWN0XG5cbiAgICAvKipcbiAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICBAdHlwZSB7QXJyYXk8RXhwZWN0IHwgRXhwZWN0VG9DaGFuZ2U+fSAqL1xuICAgIHRoaXMuZXhwZWN0YXRpb25zID0gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFuZCBjaGFuZ2UuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oKTogUHJvbWlzZTxudW1iZXI+fSBjaGFuZ2VDYWxsYmFjayAtIENoYW5nZSBjYWxsYmFjay5cbiAgICogQHJldHVybnMge0V4cGVjdFRvQ2hhbmdlfSAtIFRoZSBhbmQgY2hhbmdlLlxuICAgKi9cbiAgYW5kQ2hhbmdlKGNoYW5nZUNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMudG9DaGFuZ2UoY2hhbmdlQ2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBub3QuXG4gICAqIEByZXR1cm5zIHt0aGlzfSAtIEEgdmFsdWUuXG4gICAqL1xuICBnZXQgbm90KCkge1xuICAgIHRoaXMuX25vdCA9IHRydWVcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBiZS5cbiAgICogQHBhcmFtIHs/fSByZXN1bHQgLSBSZXN1bHQuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQmUocmVzdWx0KSB7XG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA9PT0gcmVzdWx0KSB7XG4gICAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgICAgICBjb25zdCByZXN1bHRQcmludCA9IGZvcm1hdFZhbHVlKHJlc3VsdClcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhcyB1bmV4cGVjdGVkIG5vdCB0byBiZSAke3Jlc3VsdFByaW50fWApXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QgIT09IHJlc3VsdCkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXhwZWN0ZWQgYmUgJHtyZXN1bHRQcmludH1gKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRvIGJlIGxlc3MgdGhhbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc3VsdCAtIFJlc3VsdC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZUxlc3NUaGFuKHJlc3VsdCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcIm51bWJlclwiIHx8IHR5cGVvZiByZXN1bHQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgbnVtYmVycyBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH0gYW5kICR7dHlwZW9mIHJlc3VsdH1gKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QgPCByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgbGVzcyB0aGFuICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA+PSByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAke3Jlc3VsdFByaW50fWApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzdWx0IC0gUmVzdWx0LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlTGVzc1RoYW5PckVxdWFsKHJlc3VsdCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcIm51bWJlclwiIHx8IHR5cGVvZiByZXN1bHQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgbnVtYmVycyBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH0gYW5kICR7dHlwZW9mIHJlc3VsdH1gKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QgPD0gcmVzdWx0KSB7XG4gICAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgICAgICBjb25zdCByZXN1bHRQcmludCA9IGZvcm1hdFZhbHVlKHJlc3VsdClcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhcyB1bmV4cGVjdGVkIHRvIGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAke3Jlc3VsdFByaW50fWApXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QgPiByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGJlIGdyZWF0ZXIgdGhhbiAke3Jlc3VsdFByaW50fWApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdG8gYmUgZ3JlYXRlciB0aGFuLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzdWx0IC0gUmVzdWx0LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlR3JlYXRlclRoYW4ocmVzdWx0KSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgIT09IFwibnVtYmVyXCIgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBudW1iZXJzIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fSBhbmQgJHt0eXBlb2YgcmVzdWx0fWApXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA+IHJlc3VsdCkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCB0byBiZSBncmVhdGVyIHRoYW4gJHtyZXN1bHRQcmludH1gKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5fb2JqZWN0IDw9IHJlc3VsdCkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXhwZWN0ZWQgdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXN1bHQgLSBSZXN1bHQuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQmVHcmVhdGVyVGhhbk9yRXF1YWwocmVzdWx0KSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgIT09IFwibnVtYmVyXCIgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBudW1iZXJzIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fSBhbmQgJHt0eXBlb2YgcmVzdWx0fWApXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA+PSByZXN1bHQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX29iamVjdCA8IHJlc3VsdCkge1xuICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXhwZWN0ZWQgdG8gYmUgbGVzcyB0aGFuICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBiZSBjbG9zZSB0by5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc3VsdCAtIFJlc3VsdC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtwcmVjaXNpb25dIC0gRGVjaW1hbCBwcmVjaXNpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQmVDbG9zZVRvKHJlc3VsdCwgcHJlY2lzaW9uID0gMikge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcIm51bWJlclwiIHx8IHR5cGVvZiByZXN1bHQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgbnVtYmVycyBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH0gYW5kICR7dHlwZW9mIHJlc3VsdH1gKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcHJlY2lzaW9uICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNGaW5pdGUocHJlY2lzaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBwcmVjaXNpb24gdG8gYmUgYSBudW1iZXIgYnV0IGdvdCAke3R5cGVvZiBwcmVjaXNpb259YClcbiAgICB9XG5cbiAgICBjb25zdCB0b2xlcmFuY2UgPSAwLjUgKiBNYXRoLnBvdygxMCwgLXByZWNpc2lvbilcbiAgICBjb25zdCBkaWZmID0gTWF0aC5hYnModGhpcy5fb2JqZWN0IC0gcmVzdWx0KVxuICAgIGNvbnN0IGlzQ2xvc2UgPSBkaWZmIDw9IHRvbGVyYW5jZVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKGlzQ2xvc2UpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gYmUgY2xvc2UgdG8gJHtyZXN1bHRQcmludH1gKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWlzQ2xvc2UpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGJlIGNsb3NlIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBoYXZlIGxlbmd0aC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc3VsdCAtIEV4cGVjdGVkIGxlbmd0aC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9IYXZlTGVuZ3RoKHJlc3VsdCkge1xuICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGxlbmd0aCBudW1iZXIgYnV0IGdvdCAke3R5cGVvZiByZXN1bHR9YClcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fb2JqZWN0ID09PSBudWxsIHx8IHRoaXMuX29iamVjdCA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0aGlzLl9vYmplY3QubGVuZ3RoICE9PSBcIm51bWJlclwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHZhbHVlIHdpdGggbGVuZ3RoIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fWApXG4gICAgfVxuXG4gICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG4gICAgY29uc3QgbGVuZ3RoVmFsdWUgPSB0aGlzLl9vYmplY3QubGVuZ3RoXG5cbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAobGVuZ3RoVmFsdWUgPT09IHJlc3VsdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhcyB1bmV4cGVjdGVkIHRvIGhhdmUgbGVuZ3RoICR7cmVzdWx0UHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxlbmd0aFZhbHVlICE9PSByZXN1bHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGV4cGVjdGVkIHRvIGhhdmUgbGVuZ3RoICR7cmVzdWx0UHJpbnR9YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBiZSBkZWZpbmVkLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlRGVmaW5lZCgpIHtcbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAodGhpcy5fb2JqZWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuwrR0IGV4cGVjdGVkIHRvIGJlIGRlZmluZWRgKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5fb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXhwZWN0ZWQgYmUgdW5kZWZpbmVkYClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBiZSBpbnN0YW5jZSBvZi5cbiAgICogQHBhcmFtIHtuZXcgKC4uLmFyZ3M6IEFycmF5PD8+KSA9PiA/fSBrbGFzcyAtIENsYXNzIGNvbnN0cnVjdG9yIHRvIGNoZWNrIGFnYWluc3QgKGUuZy4gYSBidWlsdC1pbiBsaWtlIEVycm9yKS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZUluc3RhbmNlT2Yoa2xhc3MpIHtcbiAgICBpZiAoISh0aGlzLl9vYmplY3QgaW5zdGFuY2VvZiBrbGFzcykpIHtcbiAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7b2JqZWN0UHJpbnR9IHRvIGJlIGEgJHtrbGFzcy5uYW1lfSBidXQgaXQgd2Fzbid0YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBiZSBmYWxzZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZUZhbHNlKCkge1xuICAgIHRoaXMudG9CZShmYWxzZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRvIGJlIG51bGwuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQmVOdWxsKCkge1xuICAgIHRoaXMudG9CZShudWxsKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdG8gYmUgdW5kZWZpbmVkLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlVW5kZWZpbmVkKCkge1xuICAgIHRoaXMudG9CZSh1bmRlZmluZWQpXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBiZSB0cnVlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0JlVHJ1ZSgpIHtcbiAgICB0aGlzLnRvQmUodHJ1ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRvIGJlIHRydXRoeS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9CZVRydXRoeSgpIHtcbiAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCB0byBiZSB0cnV0aHlgKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuX29iamVjdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhc24ndCBleHBlY3RlZCB0byBiZSB0cnV0aHlgKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRvIGNoYW5nZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbigpOiBQcm9taXNlPG51bWJlcj59IGNoYW5nZUNhbGxiYWNrIC0gQ2hhbmdlIGNhbGxiYWNrLlxuICAgKiBAcmV0dXJucyB7RXhwZWN0VG9DaGFuZ2V9IC0gVGhlIGNoYW5nZS5cbiAgICovXG4gIHRvQ2hhbmdlKGNoYW5nZUNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX25vdCkgdGhyb3cgbmV3IEVycm9yKFwibm90IHN0dWJcIilcblxuICAgIGNvbnN0IGV4cGVjdFRvQ2hhbmdlID0gbmV3IEV4cGVjdFRvQ2hhbmdlKHtjaGFuZ2VDYWxsYmFjaywgZXhwZWN0OiB0aGlzfSlcblxuICAgIHRoaXMuZXhwZWN0YXRpb25zLnB1c2goZXhwZWN0VG9DaGFuZ2UpXG5cbiAgICByZXR1cm4gZXhwZWN0VG9DaGFuZ2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRvIGNvbnRhaW4uXG4gICAqIEBwYXJhbSB7P30gdmFsdWVUb0NvbnRhaW4gLSBWYWx1ZSB0byBjb250YWluLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0NvbnRhaW4odmFsdWVUb0NvbnRhaW4pIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuX29iamVjdCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb25zdCBtYXRjaGVzID0gdGhpcy5fb2JqZWN0LmluY2x1ZGVzKFN0cmluZyh2YWx1ZVRvQ29udGFpbikpXG4gICAgICBjb25zdCBvYmplY3RQcmludCA9IG1pbmlmaWVkU3RyaW5naWZ5KHRoaXMuX29iamVjdClcbiAgICAgIGNvbnN0IHZhbHVlUHJpbnQgPSB0eXBlb2YgdmFsdWVUb0NvbnRhaW4gPT0gXCJzdHJpbmdcIlxuICAgICAgICA/IG1pbmlmaWVkU3RyaW5naWZ5KHZhbHVlVG9Db250YWluKVxuICAgICAgICA6IGZvcm1hdFZhbHVlKHZhbHVlVG9Db250YWluKVxuXG4gICAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCB0byBjb250YWluICR7dmFsdWVQcmludH1gKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFtYXRjaGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gZG9lc24ndCBjb250YWluICR7dmFsdWVQcmludH1gKVxuICAgICAgfVxuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5fb2JqZWN0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhcnJheSBvciBzdHJpbmcgYnV0IGdvdCAke3R5cGVvZiB0aGlzLl9vYmplY3R9YClcbiAgICB9XG5cbiAgICBjb25zdCBtYXRjaGVzID0gdGhpcy5fb2JqZWN0LmluY2x1ZGVzKHZhbHVlVG9Db250YWluKVxuICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgIGNvbnN0IHZhbHVlUHJpbnQgPSB0eXBlb2YgdmFsdWVUb0NvbnRhaW4gPT0gXCJzdHJpbmdcIlxuICAgICAgPyBtaW5pZmllZFN0cmluZ2lmeSh2YWx1ZVRvQ29udGFpbilcbiAgICAgIDogZm9ybWF0VmFsdWUodmFsdWVUb0NvbnRhaW4pXG5cbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhcyB1bmV4cGVjdGVkIHRvIGNvbnRhaW4gJHt2YWx1ZVByaW50fWApXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghbWF0Y2hlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSBkb2Vzbid0IGNvbnRhaW4gJHt2YWx1ZVByaW50fWApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdG8gY29udGFpbiBlcXVhbC5cbiAgICogQHBhcmFtIHs/fSB2YWx1ZVRvQ29udGFpbiAtIFZhbHVlIHRvIGNvbnRhaW4uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvQ29udGFpbkVxdWFsKHZhbHVlVG9Db250YWluKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMuX29iamVjdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYXJyYXkgYnV0IGdvdCAke3R5cGVvZiB0aGlzLl9vYmplY3R9YClcbiAgICB9XG5cbiAgICBjb25zdCBtYXRjaGVzID0gdGhpcy5fb2JqZWN0LnNvbWUoKGl0ZW0pID0+ICFhbnl0aGluZ0RpZmZlcmVudChpdGVtLCB2YWx1ZVRvQ29udGFpbikpXG4gICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgY29uc3QgdmFsdWVQcmludCA9IHR5cGVvZiB2YWx1ZVRvQ29udGFpbiA9PSBcInN0cmluZ1wiXG4gICAgICA/IG1pbmlmaWVkU3RyaW5naWZ5KHZhbHVlVG9Db250YWluKVxuICAgICAgOiBmb3JtYXRWYWx1ZSh2YWx1ZVRvQ29udGFpbilcblxuICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgdG8gY29udGFpbiAke3ZhbHVlUHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFtYXRjaGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IGRvZXNuJ3QgY29udGFpbiAke3ZhbHVlUHJpbnR9YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBlcXVhbC5cbiAgICogQHBhcmFtIHs/fSByZXN1bHQgLSBSZXN1bHQuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHRvRXF1YWwocmVzdWx0KSB7XG4gICAgaWYgKHRoaXMuX29iamVjdCBpbnN0YW5jZW9mIFNldCAmJiByZXN1bHQgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgICAgY29uc3QgcmVzdWx0UHJpbnQgPSBmb3JtYXRWYWx1ZShyZXN1bHQpXG4gICAgICBjb25zdCBhY3R1YWxJdGVtcyA9IEFycmF5LmZyb20odGhpcy5fb2JqZWN0KVxuICAgICAgY29uc3QgZXhwZWN0ZWRJdGVtcyA9IEFycmF5LmZyb20ocmVzdWx0KVxuICAgICAgY29uc3QgbWlzc2luZ0l0ZW1zID0gZXhwZWN0ZWRJdGVtcy5maWx0ZXIoKGV4cGVjdGVkSXRlbSkgPT4ge1xuICAgICAgICByZXR1cm4gIWFjdHVhbEl0ZW1zLnNvbWUoKGFjdHVhbEl0ZW0pID0+ICFhbnl0aGluZ0RpZmZlcmVudChhY3R1YWxJdGVtLCBleHBlY3RlZEl0ZW0pKVxuICAgICAgfSlcbiAgICAgIGNvbnN0IHVuZXhwZWN0ZWRJdGVtcyA9IGFjdHVhbEl0ZW1zLmZpbHRlcigoYWN0dWFsSXRlbSkgPT4ge1xuICAgICAgICByZXR1cm4gIWV4cGVjdGVkSXRlbXMuc29tZSgoZXhwZWN0ZWRJdGVtKSA9PiAhYW55dGhpbmdEaWZmZXJlbnQoYWN0dWFsSXRlbSwgZXhwZWN0ZWRJdGVtKSlcbiAgICAgIH0pXG4gICAgICBjb25zdCBpc0VxdWFsID0gbWlzc2luZ0l0ZW1zLmxlbmd0aCA9PT0gMCAmJiB1bmV4cGVjdGVkSXRlbXMubGVuZ3RoID09PSAwXG5cbiAgICAgIGlmICh0aGlzLl9ub3QpIHtcbiAgICAgICAgaWYgKGlzRXF1YWwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b2JqZWN0UHJpbnR9IHdhcyB1bmV4cGVjdGVkIGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9YClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghaXNFcXVhbCkge1xuICAgICAgICBjb25zdCBtaXNzaW5nU3RyaW5ncyA9IG1pc3NpbmdJdGVtcy5tYXAoKGl0ZW0pID0+IG1pbmlmaWVkU3RyaW5naWZ5KGl0ZW0pKVxuICAgICAgICBjb25zdCB1bmV4cGVjdGVkU3RyaW5ncyA9IHVuZXhwZWN0ZWRJdGVtcy5tYXAoKGl0ZW0pID0+IG1pbmlmaWVkU3RyaW5naWZ5KGl0ZW0pKVxuICAgICAgICBjb25zdCBkaWZmUGFydHMgPSBbXVxuXG4gICAgICAgIGlmIChtaXNzaW5nU3RyaW5ncy5sZW5ndGggPiAwKSBkaWZmUGFydHMucHVzaChgbWlzc2luZyAke21pc3NpbmdTdHJpbmdzLmpvaW4oXCIsIFwiKX1gKVxuICAgICAgICBpZiAodW5leHBlY3RlZFN0cmluZ3MubGVuZ3RoID4gMCkgZGlmZlBhcnRzLnB1c2goYHVuZXhwZWN0ZWQgJHt1bmV4cGVjdGVkU3RyaW5ncy5qb2luKFwiLCBcIil9YClcblxuICAgICAgICBjb25zdCBkaWZmTWVzc2FnZSA9IGRpZmZQYXJ0cy5sZW5ndGggPiAwID8gYCAoZGlmZjogJHtkaWZmUGFydHMuam9pbihcIjsgXCIpfSlgIDogXCJcIlxuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2Fzbid0IGVxdWFsIHRvICR7cmVzdWx0UHJpbnR9JHtkaWZmTWVzc2FnZX1gKVxuICAgICAgfVxuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoaXNPYmplY3RDb250YWluaW5nKHJlc3VsdCkpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWUgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHJlc3VsdCkudmFsdWVcbiAgICAgIGNvbnN0IHttYXRjaGVzLCBkaWZmZXJlbmNlc30gPSBtYXRjaE9iamVjdCh0aGlzLl9vYmplY3QsIGV4cGVjdGVkVmFsdWUpXG4gICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgIGNvbnN0IGV4cGVjdGVkUHJpbnQgPSBmb3JtYXRWYWx1ZShleHBlY3RlZFZhbHVlKVxuXG4gICAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke29iamVjdFByaW50fSBub3QgdG8gbWF0Y2ggJHtleHBlY3RlZFByaW50fWApXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIW1hdGNoZXMpIHtcbiAgICAgICAgY29uc3QgZGlmZlByaW50ID0gT2JqZWN0LmtleXMoZGlmZmVyZW5jZXMpLmxlbmd0aCA+IDAgPyBgIChkaWZmOiAke21pbmlmaWVkU3RyaW5naWZ5KGRpZmZlcmVuY2VzKX0pYCA6IFwiXCJcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7b2JqZWN0UHJpbnR9IHRvIG1hdGNoICR7ZXhwZWN0ZWRQcmludH0ke2RpZmZQcmludH1gKVxuICAgICAgfVxuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheUNvbnRhaW5pbmcocmVzdWx0KSkge1xuICAgICAgY29uc3QgZXhwZWN0ZWRWYWx1ZSA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtBcnJheTw/Pn0gKi8gKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHJlc3VsdCkudmFsdWUpXG4gICAgICBjb25zdCB7bWF0Y2hlcywgZGlmZmVyZW5jZXN9ID0gbWF0Y2hBcnJheUNvbnRhaW5pbmcodGhpcy5fb2JqZWN0LCBleHBlY3RlZFZhbHVlKVxuICAgICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG4gICAgICBjb25zdCBleHBlY3RlZFByaW50ID0gZm9ybWF0VmFsdWUoZXhwZWN0ZWRWYWx1ZSlcblxuICAgICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtvYmplY3RQcmludH0gbm90IHRvIG1hdGNoICR7ZXhwZWN0ZWRQcmludH1gKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFtYXRjaGVzKSB7XG4gICAgICAgIGNvbnN0IGRpZmZQcmludCA9IE9iamVjdC5rZXlzKGRpZmZlcmVuY2VzKS5sZW5ndGggPiAwID8gYCAoZGlmZjogJHttaW5pZmllZFN0cmluZ2lmeShkaWZmZXJlbmNlcyl9KWAgOiBcIlwiXG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke29iamVjdFByaW50fSB0byBtYXRjaCAke2V4cGVjdGVkUHJpbnR9JHtkaWZmUHJpbnR9YClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX25vdCkge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVzdWx0ID09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgaWYgKCFhbnl0aGluZ0RpZmZlcmVudCh0aGlzLl9vYmplY3QsIHJlc3VsdCkpIHtcbiAgICAgICAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICAgICAgICBjb25zdCByZXN1bHRQcmludCA9IGZvcm1hdFZhbHVlKHJlc3VsdClcblxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gd2FzIHVuZXhwZWN0ZWQgZXF1YWwgdG8gJHtyZXN1bHRQcmludH1gKVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5fb2JqZWN0ID09IHJlc3VsdCkge1xuICAgICAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCBlcXVhbCB0byAke3Jlc3VsdFByaW50fWApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVzdWx0ID09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgaWYgKGFueXRoaW5nRGlmZmVyZW50KHRoaXMuX29iamVjdCwgcmVzdWx0KSkge1xuICAgICAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5fb2JqZWN0KSAmJiBBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGFjdHVhbFN0cmluZ3MgPSB0aGlzLl9vYmplY3QubWFwKChpdGVtKSA9PiBtaW5pZmllZFN0cmluZ2lmeShpdGVtKSlcbiAgICAgICAgICAgIGNvbnN0IGV4cGVjdGVkU3RyaW5ncyA9IHJlc3VsdC5tYXAoKGl0ZW0pID0+IG1pbmlmaWVkU3RyaW5naWZ5KGl0ZW0pKVxuXG4gICAgICAgICAgICBjb25zdCBtaXNzaW5nSXRlbXMgPSBleHBlY3RlZFN0cmluZ3MuZmlsdGVyKChpdGVtKSA9PiAhYWN0dWFsU3RyaW5ncy5pbmNsdWRlcyhpdGVtKSlcbiAgICAgICAgICAgIGNvbnN0IHVuZXhwZWN0ZWRJdGVtcyA9IGFjdHVhbFN0cmluZ3MuZmlsdGVyKChpdGVtKSA9PiAhZXhwZWN0ZWRTdHJpbmdzLmluY2x1ZGVzKGl0ZW0pKVxuXG4gICAgICAgICAgICBjb25zdCBkaWZmUGFydHMgPSBbXVxuXG4gICAgICAgICAgICBpZiAobWlzc2luZ0l0ZW1zLmxlbmd0aCA+IDApIGRpZmZQYXJ0cy5wdXNoKGBtaXNzaW5nICR7bWlzc2luZ0l0ZW1zLmpvaW4oXCIsIFwiKX1gKVxuICAgICAgICAgICAgaWYgKHVuZXhwZWN0ZWRJdGVtcy5sZW5ndGggPiAwKSBkaWZmUGFydHMucHVzaChgdW5leHBlY3RlZCAke3VuZXhwZWN0ZWRJdGVtcy5qb2luKFwiLCBcIil9YClcblxuICAgICAgICAgICAgY29uc3QgZGlmZk1lc3NhZ2UgPSBkaWZmUGFydHMubGVuZ3RoID4gMCA/IGAgKGRpZmY6ICR7ZGlmZlBhcnRzLmpvaW4oXCI7IFwiKX0pYCA6IFwiXCJcblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXF1YWwgdG8gJHtyZXN1bHRQcmludH0ke2RpZmZNZXNzYWdlfWApXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXF1YWwgdG8gJHtyZXN1bHRQcmludH1gKVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5fb2JqZWN0ICE9IHJlc3VsdCkge1xuICAgICAgICAgIGNvbnN0IG9iamVjdFByaW50ID0gZm9ybWF0VmFsdWUodGhpcy5fb2JqZWN0KVxuICAgICAgICAgIGNvbnN0IHJlc3VsdFByaW50ID0gZm9ybWF0VmFsdWUocmVzdWx0KVxuXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXNuJ3QgZXF1YWwgdG8gJHtyZXN1bHRQcmludH1gKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdG8gbWF0Y2guXG4gICAqIEBwYXJhbSB7UmVnRXhwfSByZWdleCAtIFJlZ2V4LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b01hdGNoKHJlZ2V4KSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9vYmplY3QgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgc3RyaW5nIGJ1dCBnb3QgJHt0eXBlb2YgdGhpcy5fb2JqZWN0fWApXG4gICAgfVxuXG4gICAgY29uc3QgbWF0Y2ggPSB0aGlzLl9vYmplY3QubWF0Y2gocmVnZXgpXG4gICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBtaW5pZmllZFN0cmluZ2lmeSh0aGlzLl9vYmplY3QpXG5cbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSBzaG91bGRuJ3QgbWF0Y2ggJHtyZWdleH1gKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvYmplY3RQcmludH0gZGlkbid0IG1hdGNoICR7cmVnZXh9YClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byBtYXRjaCBvYmplY3QuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz4gfCBBcnJheTw/Pn0gZXhwZWN0ZWQgLSBFeHBlY3RlZCBwYXJ0aWFsIG9iamVjdC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgdG9NYXRjaE9iamVjdChleHBlY3RlZCkge1xuICAgIGlmIChleHBlY3RlZCA9PT0gbnVsbCB8fCB0eXBlb2YgZXhwZWN0ZWQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgb2JqZWN0IGJ1dCBnb3QgJHt0eXBlb2YgZXhwZWN0ZWR9YClcbiAgICB9XG5cbiAgICBjb25zdCB7bWF0Y2hlcywgZGlmZmVyZW5jZXN9ID0gbWF0Y2hPYmplY3QodGhpcy5fb2JqZWN0LCBleHBlY3RlZClcbiAgICBjb25zdCBvYmplY3RQcmludCA9IGZvcm1hdFZhbHVlKHRoaXMuX29iamVjdClcbiAgICBjb25zdCBleHBlY3RlZFByaW50ID0gZm9ybWF0VmFsdWUoZXhwZWN0ZWQpXG5cbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7b2JqZWN0UHJpbnR9IG5vdCB0byBtYXRjaCAke2V4cGVjdGVkUHJpbnR9YClcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFtYXRjaGVzKSB7XG4gICAgICBjb25zdCBkaWZmUHJpbnQgPSBPYmplY3Qua2V5cyhkaWZmZXJlbmNlcykubGVuZ3RoID4gMCA/IGAgKGRpZmY6ICR7bWluaWZpZWRTdHJpbmdpZnkoZGlmZmVyZW5jZXMpfSlgIDogXCJcIlxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7b2JqZWN0UHJpbnR9IHRvIG1hdGNoICR7ZXhwZWN0ZWRQcmludH0ke2RpZmZQcmludH1gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRvIHRocm93IGVycm9yLlxuICAgKiBAdGVtcGxhdGUgVCBleHRlbmRzIEVycm9yXG4gICAqIEBwYXJhbSB7c3RyaW5nfFR9IGV4cGVjdGVkRXJyb3IgLSBFeHBlY3RlZCBlcnJvci5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHRvVGhyb3dFcnJvcihleHBlY3RlZEVycm9yKSB7XG4gICAgaWYgKHRoaXMuX25vdCkgdGhyb3cgbmV3IEVycm9yKFwibm90IHN0dWJcIilcblxuICAgIGxldCBmYWlsZWRFcnJvclxuXG4gICAgdHJ5IHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiBidXQgZ290ICR7dHlwZW9mIHRoaXMuX29iamVjdH1gKVxuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLl9vYmplY3QoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBmYWlsZWRFcnJvciA9IGVycm9yXG4gICAgfVxuXG4gICAgaWYgKCFmYWlsZWRFcnJvcikgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgdG8gZmFpbCBidXQgZGlkbid0XCIpXG5cbiAgICBsZXQgZXhwZWN0ZWRFcnJvck1lc3NhZ2UsIGZhaWxlZEVycm9yTWVzc2FnZVxuXG4gICAgaWYgKHR5cGVvZiBmYWlsZWRFcnJvciA9PSBcInN0cmluZ1wiKSB7XG4gICAgICBmYWlsZWRFcnJvck1lc3NhZ2UgPSBmYWlsZWRFcnJvclxuICAgIH0gZWxzZSBpZiAoZmFpbGVkRXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgZmFpbGVkRXJyb3JNZXNzYWdlID0gZmFpbGVkRXJyb3IubWVzc2FnZVxuICAgIH0gZWxzZSB7XG4gICAgICBmYWlsZWRFcnJvck1lc3NhZ2UgPSBTdHJpbmcoZmFpbGVkRXJyb3IpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBleHBlY3RlZEVycm9yID09IFwic3RyaW5nXCIpIHtcbiAgICAgIGV4cGVjdGVkRXJyb3JNZXNzYWdlID0gZXhwZWN0ZWRFcnJvclxuICAgIH0gZWxzZSBpZiAoZXhwZWN0ZWRFcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBleHBlY3RlZEVycm9yTWVzc2FnZSA9IGV4cGVjdGVkRXJyb3IubWVzc2FnZVxuICAgIH0gZWxzZSB7XG4gICAgICBleHBlY3RlZEVycm9yTWVzc2FnZSA9IFN0cmluZyhleHBlY3RlZEVycm9yKVxuICAgIH1cblxuICAgIGlmIChmYWlsZWRFcnJvck1lc3NhZ2UgIT0gZXhwZWN0ZWRFcnJvck1lc3NhZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgdG8gZmFpbCB3aXRoICcke2V4cGVjdGVkRXJyb3JNZXNzYWdlfScgYnV0IGZhaWxlZCB3aXRoICcke2ZhaWxlZEVycm9yTWVzc2FnZX0nYClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0byB0aHJvdy5cbiAgICogQHBhcmFtIHtzdHJpbmd8UmVnRXhwfEVycm9yfCgobmV3ICguLi5hcmdzOiBBcnJheTw/PikgPT4gRXJyb3IpKX0gW2V4cGVjdGVkXSAtIEV4cGVjdGVkIGVycm9yLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgdG9UaHJvdyhleHBlY3RlZCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgZnVuY3Rpb24gYnV0IGdvdCAke3R5cGVvZiB0aGlzLl9vYmplY3R9YClcbiAgICB9XG5cbiAgICBsZXQgZmFpbGVkRXJyb3JcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9vYmplY3QoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBmYWlsZWRFcnJvciA9IGVycm9yXG4gICAgfVxuXG4gICAgY29uc3Qgb2JqZWN0UHJpbnQgPSBmb3JtYXRWYWx1ZSh0aGlzLl9vYmplY3QpXG5cbiAgICBpZiAodGhpcy5fbm90KSB7XG4gICAgICBpZiAoZmFpbGVkRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29iamVjdFByaW50fSB3YXMgdW5leHBlY3RlZCB0byB0aHJvd2ApXG4gICAgICB9XG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghZmFpbGVkRXJyb3IpIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIHRvIGZhaWwgYnV0IGRpZG4ndFwiKVxuICAgIGlmIChleHBlY3RlZCA9PT0gdW5kZWZpbmVkKSByZXR1cm5cblxuICAgIGNvbnN0IGZhaWxlZEVycm9yTWVzc2FnZSA9IGZhaWxlZEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBmYWlsZWRFcnJvci5tZXNzYWdlIDogU3RyaW5nKGZhaWxlZEVycm9yKVxuICAgIGNvbnN0IGZhaWxlZEVycm9yTmFtZSA9IGZhaWxlZEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBmYWlsZWRFcnJvci5uYW1lIDogdHlwZW9mIGZhaWxlZEVycm9yXG5cbiAgICBpZiAoZXhwZWN0ZWQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIGlmICghZXhwZWN0ZWQudGVzdChmYWlsZWRFcnJvck1lc3NhZ2UpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgdG8gZmFpbCB3aXRoIG1lc3NhZ2UgbWF0Y2hpbmcgJHtleHBlY3RlZH0gYnV0IGZhaWxlZCB3aXRoICcke2ZhaWxlZEVycm9yTWVzc2FnZX0nYClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gXCJmdW5jdGlvblwiICYmIChleHBlY3RlZC5wcm90b3R5cGUgaW5zdGFuY2VvZiBFcnJvciB8fCBleHBlY3RlZCA9PT0gRXJyb3IpKSB7XG4gICAgICBpZiAoIShmYWlsZWRFcnJvciBpbnN0YW5jZW9mIGV4cGVjdGVkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHRvIHRocm93ICR7ZXhwZWN0ZWQubmFtZX0gYnV0IHRocmV3ICR7ZmFpbGVkRXJyb3JOYW1lfWApXG4gICAgICB9XG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGxldCBleHBlY3RlZE1lc3NhZ2VcblxuICAgIGlmICh0eXBlb2YgZXhwZWN0ZWQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGV4cGVjdGVkTWVzc2FnZSA9IGV4cGVjdGVkXG4gICAgfSBlbHNlIGlmIChleHBlY3RlZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBleHBlY3RlZE1lc3NhZ2UgPSBleHBlY3RlZC5tZXNzYWdlXG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGVjdGVkTWVzc2FnZSA9IFN0cmluZyhleHBlY3RlZClcbiAgICB9XG5cbiAgICBpZiAoZmFpbGVkRXJyb3JNZXNzYWdlICE9IGV4cGVjdGVkTWVzc2FnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCB0byBmYWlsIHdpdGggJyR7ZXhwZWN0ZWRNZXNzYWdlfScgYnV0IGZhaWxlZCB3aXRoICcke2ZhaWxlZEVycm9yTWVzc2FnZX0nYClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBleGVjdXRlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBleGVjdXRlLlxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICBmb3IgKGNvbnN0IGV4cGVjdGF0aW9uIG9mIHRoaXMuZXhwZWN0YXRpb25zKSB7XG4gICAgICBhd2FpdCBleHBlY3RhdGlvbi5ydW5CZWZvcmUoKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5fb2JqZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgZnVuY3Rpb24gYnV0IGdvdCAke3R5cGVvZiB0aGlzLl9vYmplY3R9YClcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9vYmplY3QoKVxuXG4gICAgZm9yIChjb25zdCBleHBlY3RhdGlvbiBvZiB0aGlzLmV4cGVjdGF0aW9ucykge1xuICAgICAgYXdhaXQgZXhwZWN0YXRpb24ucnVuQWZ0ZXIoKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZXhwZWN0YXRpb24gb2YgdGhpcy5leHBlY3RhdGlvbnMpIHtcbiAgICAgIGF3YWl0IGV4cGVjdGF0aW9uLmV4ZWN1dGUoKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRvIGhhdmUgYXR0cmlidXRlcy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcmVzdWx0IC0gUmVzdWx0LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICB0b0hhdmVBdHRyaWJ1dGVzKHJlc3VsdCkge1xuICAgIGlmICh0aGlzLl9ub3QpIHRocm93IG5ldyBFcnJvcihcIm5vdCBzdHViXCIpXG5cbiAgICAvKipcbiAgICAgKiBEaWZmZXJlbmNlcy5cbiAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBBcnJheTw/Pj59ICovXG4gICAgY29uc3QgZGlmZmVyZW5jZXMgPSB7fVxuICAgIGNvbnN0IG9iamVjdEFzUmVjb3JkID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHRoaXMuX29iamVjdClcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHJlc3VsdCkge1xuICAgICAgY29uc3QgdmFsdWUgPSByZXN1bHRba2V5XVxuXG4gICAgICBpZiAoIShrZXkgaW4gb2JqZWN0QXNSZWNvcmQpKSB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5fb2JqZWN0LmNvbnN0cnVjdG9yLm5hbWV9IGRvZXNuJ3QgcmVzcG9uZCB0byAke2tleX1gKVxuXG4gICAgICBjb25zdCBvYmplY3RWYWx1ZSA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgeygpID0+ID99ICovIChvYmplY3RBc1JlY29yZFtrZXldKSgpXG5cbiAgICAgIGlmICh2YWx1ZSAhPSBvYmplY3RWYWx1ZSkge1xuICAgICAgICBkaWZmZXJlbmNlc1trZXldID0gW3ZhbHVlLCBvYmplY3RWYWx1ZV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoT2JqZWN0LmtleXMoZGlmZmVyZW5jZXMpLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgT2JqZWN0IGhhZCBkaWZmZXJldCB2YWx1ZXM6ICR7bWluaWZpZWRTdHJpbmdpZnkoZGlmZmVyZW5jZXMpfWApXG4gICAgfVxuICB9XG59XG4iXX0=