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,31 +1,25 @@
1
1
  // @ts-check
2
-
3
- import * as inflection from "inflection"
4
- import {isPlainObject} from "is-plain-object"
5
- import {resolveFrontendModelClass} from "../frontend-models/model-registry.js"
6
-
2
+ import * as inflection from "inflection";
3
+ import { isPlainObject } from "is-plain-object";
4
+ import { resolveFrontendModelClass } from "../frontend-models/model-registry.js";
7
5
  /**
8
6
  * RansackPredicate type.
9
7
  * @typedef {"cont" | "end" | "eq" | "gt" | "gteq" | "in" | "lt" | "lteq" | "not_eq" | "not_in" | "null" | "start"} RansackPredicate
10
8
  */
11
-
12
9
  /**
13
10
  * RansackCombinator type.
14
11
  * @typedef {"and" | "or"} RansackCombinator
15
12
  */
16
-
17
13
  /**
18
14
  * RansackModelClass type.
19
15
  * @typedef {typeof import("../database/record/index.js").default | typeof import("../frontend-models/base.js").default} RansackModelClass
20
16
  */
21
-
22
17
  /**
23
18
  * RansackAttribute type.
24
19
  * @typedef {object} RansackAttribute
25
20
  * @property {string} attributeName - Resolved attribute name.
26
21
  * @property {string[]} path - Resolved relationship path.
27
22
  */
28
-
29
23
  /**
30
24
  * RansackCondition type.
31
25
  * @typedef {object} RansackCondition
@@ -34,7 +28,6 @@ import {resolveFrontendModelClass} from "../frontend-models/model-registry.js"
34
28
  * @property {RansackPredicate} predicate - Parsed Ransack predicate.
35
29
  * @property {?} value - Normalized value.
36
30
  */
37
-
38
31
  /**
39
32
  * RansackGroup type.
40
33
  * @typedef {object} RansackGroup
@@ -42,22 +35,20 @@ import {resolveFrontendModelClass} from "../frontend-models/model-registry.js"
42
35
  * @property {RansackCondition[]} conditions - Conditions in this group.
43
36
  * @property {RansackGroup[]} groupings - Nested groups.
44
37
  */
45
-
46
38
  const supportedPredicates = [
47
- "not_in",
48
- "not_eq",
49
- "gteq",
50
- "lteq",
51
- "start",
52
- "cont",
53
- "null",
54
- "end",
55
- "eq",
56
- "gt",
57
- "lt",
58
- "in"
59
- ]
60
-
39
+ "not_in",
40
+ "not_eq",
41
+ "gteq",
42
+ "lteq",
43
+ "start",
44
+ "cont",
45
+ "null",
46
+ "end",
47
+ "eq",
48
+ "gt",
49
+ "lt",
50
+ "in"
51
+ ];
61
52
  /**
62
53
  * Runs the normalizeRansackParams helper.
63
54
  * @param {RansackModelClass} modelClass - Model class.
@@ -65,9 +56,8 @@ const supportedPredicates = [
65
56
  * @returns {RansackCondition[]} - Normalized conditions.
66
57
  */
67
58
  export function normalizeRansackParams(modelClass, params) {
68
- return normalizeRansackGroup(modelClass, params).conditions
59
+ return normalizeRansackGroup(modelClass, params).conditions;
69
60
  }
70
-
71
61
  /**
72
62
  * Runs the normalizeRansackGroup helper.
73
63
  * @param {RansackModelClass} modelClass - Model class.
@@ -75,43 +65,36 @@ export function normalizeRansackParams(modelClass, params) {
75
65
  * @returns {RansackGroup} - Normalized group.
76
66
  */
77
67
  export function normalizeRansackGroup(modelClass, params) {
78
- if (!isPlainObject(params)) {
79
- throw new Error(`ransack params must be a plain object, got: ${typeof params}`)
80
- }
81
-
82
- /**
83
- * Normalized.
84
- @type {RansackGroup} */
85
- const normalized = {
86
- combinator: normalizeRansackCombinator(params.m, "and"),
87
- conditions: [],
88
- groupings: []
89
- }
90
-
91
- for (const [key, rawValue] of Object.entries(params)) {
92
- if (key === "m") {
93
- continue
94
- }
95
-
96
- if (key === "c") {
97
- normalized.conditions.push(...normalizeAdvancedRansackConditions({modelClass, value: rawValue}))
98
- continue
99
- }
100
-
101
- if (key === "g") {
102
- normalized.groupings.push(...normalizeAdvancedRansackGroups({modelClass, value: rawValue}))
103
- continue
104
- }
105
-
106
- const condition = normalizeSimpleRansackCondition({key, modelClass, rawValue})
107
- if (condition) normalized.conditions.push(condition)
108
- }
109
-
110
- return normalized
111
- }
112
-
113
- const SKIP_RANSACK_CONDITION = Symbol("skip-ransack-condition")
114
-
68
+ if (!isPlainObject(params)) {
69
+ throw new Error(`ransack params must be a plain object, got: ${typeof params}`);
70
+ }
71
+ /**
72
+ * Normalized.
73
+ @type {RansackGroup} */
74
+ const normalized = {
75
+ combinator: normalizeRansackCombinator(params.m, "and"),
76
+ conditions: [],
77
+ groupings: []
78
+ };
79
+ for (const [key, rawValue] of Object.entries(params)) {
80
+ if (key === "m") {
81
+ continue;
82
+ }
83
+ if (key === "c") {
84
+ normalized.conditions.push(...normalizeAdvancedRansackConditions({ modelClass, value: rawValue }));
85
+ continue;
86
+ }
87
+ if (key === "g") {
88
+ normalized.groupings.push(...normalizeAdvancedRansackGroups({ modelClass, value: rawValue }));
89
+ continue;
90
+ }
91
+ const condition = normalizeSimpleRansackCondition({ key, modelClass, rawValue });
92
+ if (condition)
93
+ normalized.conditions.push(condition);
94
+ }
95
+ return normalized;
96
+ }
97
+ const SKIP_RANSACK_CONDITION = Symbol("skip-ransack-condition");
115
98
  /**
116
99
  * Runs normalize simple ransack condition.
117
100
  * @param {object} args - Options.
@@ -120,30 +103,25 @@ const SKIP_RANSACK_CONDITION = Symbol("skip-ransack-condition")
120
103
  * @param {?} args.rawValue - Raw condition value.
121
104
  * @returns {RansackCondition | null} - Normalized condition, or null when skipped.
122
105
  */
123
- function normalizeSimpleRansackCondition({key, modelClass, rawValue}) {
124
- const parsedKey = parseRansackKey(key)
125
-
126
- if (!parsedKey) {
127
- throw new Error(`Unsupported ransack predicate in key: ${key}`)
128
- }
129
-
130
- const value = normalizeRansackValue({
131
- predicate: parsedKey.predicate,
132
- value: rawValue
133
- })
134
-
135
- if (value === SKIP_RANSACK_CONDITION) return null
136
-
137
- const attributes = resolveRansackAttributes({modelClass, value: parsedKey.pathValue})
138
-
139
- return {
140
- attributes,
141
- combinator: attributes.length > 1 ? "or" : "and",
142
- predicate: parsedKey.predicate,
143
- value
144
- }
145
- }
146
-
106
+ function normalizeSimpleRansackCondition({ key, modelClass, rawValue }) {
107
+ const parsedKey = parseRansackKey(key);
108
+ if (!parsedKey) {
109
+ throw new Error(`Unsupported ransack predicate in key: ${key}`);
110
+ }
111
+ const value = normalizeRansackValue({
112
+ predicate: parsedKey.predicate,
113
+ value: rawValue
114
+ });
115
+ if (value === SKIP_RANSACK_CONDITION)
116
+ return null;
117
+ const attributes = resolveRansackAttributes({ modelClass, value: parsedKey.pathValue });
118
+ return {
119
+ attributes,
120
+ combinator: attributes.length > 1 ? "or" : "and",
121
+ predicate: parsedKey.predicate,
122
+ value
123
+ };
124
+ }
147
125
  /**
148
126
  * Runs normalize advanced ransack conditions.
149
127
  * @param {object} args - Options.
@@ -151,48 +129,39 @@ function normalizeSimpleRansackCondition({key, modelClass, rawValue}) {
151
129
  * @param {?} args.value - Advanced conditions collection.
152
130
  * @returns {RansackCondition[]} - Normalized conditions.
153
131
  */
154
- function normalizeAdvancedRansackConditions({modelClass, value}) {
155
- /**
156
- * Conditions.
157
- @type {RansackCondition[]} */
158
- const conditions = []
159
-
160
- for (const entry of normalizeRansackCollection(value, "conditions")) {
161
- if (!isPlainObject(entry)) {
162
- throw new Error(`Ransack condition entries must be plain objects, got: ${typeof entry}`)
163
- }
164
-
165
- const predicateValue = entry.p
166
-
167
- if (typeof predicateValue !== "string") {
168
- throw new Error("Ransack condition predicate must be a string")
169
- }
170
-
171
- if (!supportedPredicates.includes(predicateValue)) {
172
- throw new Error(`Unsupported ransack predicate in condition: ${predicateValue}`)
173
- }
174
-
175
- const predicate = /**
176
- * Narrows the runtime value to the documented type.
177
- @type {RansackPredicate} */ (predicateValue)
178
- const rawValue = advancedRansackConditionValue({predicate, value: entry.v})
179
- const normalizedValue = normalizeRansackValue({predicate, value: rawValue})
180
-
181
- if (normalizedValue === SKIP_RANSACK_CONDITION) continue
182
-
183
- const attributes = resolveRansackAttributesFromAdvancedValue({modelClass, value: entry.a})
184
-
185
- conditions.push({
186
- attributes,
187
- combinator: normalizeRansackCombinator(entry.m, attributes.length > 1 ? "or" : "and"),
188
- predicate,
189
- value: normalizedValue
190
- })
191
- }
192
-
193
- return conditions
194
- }
195
-
132
+ function normalizeAdvancedRansackConditions({ modelClass, value }) {
133
+ /**
134
+ * Conditions.
135
+ @type {RansackCondition[]} */
136
+ const conditions = [];
137
+ for (const entry of normalizeRansackCollection(value, "conditions")) {
138
+ if (!isPlainObject(entry)) {
139
+ throw new Error(`Ransack condition entries must be plain objects, got: ${typeof entry}`);
140
+ }
141
+ const predicateValue = entry.p;
142
+ if (typeof predicateValue !== "string") {
143
+ throw new Error("Ransack condition predicate must be a string");
144
+ }
145
+ if (!supportedPredicates.includes(predicateValue)) {
146
+ throw new Error(`Unsupported ransack predicate in condition: ${predicateValue}`);
147
+ }
148
+ const predicate = /**
149
+ * Narrows the runtime value to the documented type.
150
+ @type {RansackPredicate} */ (predicateValue);
151
+ const rawValue = advancedRansackConditionValue({ predicate, value: entry.v });
152
+ const normalizedValue = normalizeRansackValue({ predicate, value: rawValue });
153
+ if (normalizedValue === SKIP_RANSACK_CONDITION)
154
+ continue;
155
+ const attributes = resolveRansackAttributesFromAdvancedValue({ modelClass, value: entry.a });
156
+ conditions.push({
157
+ attributes,
158
+ combinator: normalizeRansackCombinator(entry.m, attributes.length > 1 ? "or" : "and"),
159
+ predicate,
160
+ value: normalizedValue
161
+ });
162
+ }
163
+ return conditions;
164
+ }
196
165
  /**
197
166
  * Runs normalize advanced ransack groups.
198
167
  * @param {object} args - Options.
@@ -200,23 +169,19 @@ function normalizeAdvancedRansackConditions({modelClass, value}) {
200
169
  * @param {?} args.value - Advanced groups collection.
201
170
  * @returns {RansackGroup[]} - Normalized groups.
202
171
  */
203
- function normalizeAdvancedRansackGroups({modelClass, value}) {
204
- /**
205
- * Groupings.
206
- @type {RansackGroup[]} */
207
- const groupings = []
208
-
209
- for (const entry of normalizeRansackCollection(value, "groupings")) {
210
- if (!isPlainObject(entry)) {
211
- throw new Error(`Ransack grouping entries must be plain objects, got: ${typeof entry}`)
172
+ function normalizeAdvancedRansackGroups({ modelClass, value }) {
173
+ /**
174
+ * Groupings.
175
+ @type {RansackGroup[]} */
176
+ const groupings = [];
177
+ for (const entry of normalizeRansackCollection(value, "groupings")) {
178
+ if (!isPlainObject(entry)) {
179
+ throw new Error(`Ransack grouping entries must be plain objects, got: ${typeof entry}`);
180
+ }
181
+ groupings.push(normalizeRansackGroup(modelClass, entry));
212
182
  }
213
-
214
- groupings.push(normalizeRansackGroup(modelClass, entry))
215
- }
216
-
217
- return groupings
183
+ return groupings;
218
184
  }
219
-
220
185
  /**
221
186
  * Runs normalize ransack combinator.
222
187
  * @param {?} value - Candidate combinator.
@@ -224,12 +189,12 @@ function normalizeAdvancedRansackGroups({modelClass, value}) {
224
189
  * @returns {RansackCombinator} - Normalized combinator.
225
190
  */
226
191
  function normalizeRansackCombinator(value, defaultValue) {
227
- if (value === undefined || value === null || value === "") return defaultValue
228
- if (value === "and" || value === "or") return value
229
-
230
- throw new Error(`Invalid ransack combinator: ${String(value)}`)
192
+ if (value === undefined || value === null || value === "")
193
+ return defaultValue;
194
+ if (value === "and" || value === "or")
195
+ return value;
196
+ throw new Error(`Invalid ransack combinator: ${String(value)}`);
231
197
  }
232
-
233
198
  /**
234
199
  * Runs normalize ransack collection.
235
200
  * @param {?} value - Candidate collection.
@@ -237,27 +202,24 @@ function normalizeRansackCombinator(value, defaultValue) {
237
202
  * @returns {Array<?>} - Collection values in stable order.
238
203
  */
239
204
  function normalizeRansackCollection(value, name) {
240
- if (value === undefined || value === null || value === "") return []
241
- if (Array.isArray(value)) return value
242
-
243
- if (isPlainObject(value)) {
244
- return Object.keys(value)
245
- .sort((left, right) => {
246
- const leftNumber = Number(left)
247
- const rightNumber = Number(right)
248
-
249
- if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) {
250
- return leftNumber - rightNumber
251
- }
252
-
253
- return left.localeCompare(right)
254
- })
255
- .map((key) => value[key])
256
- }
257
-
258
- throw new Error(`Ransack ${name} must be an array or object, got: ${typeof value}`)
205
+ if (value === undefined || value === null || value === "")
206
+ return [];
207
+ if (Array.isArray(value))
208
+ return value;
209
+ if (isPlainObject(value)) {
210
+ return Object.keys(value)
211
+ .sort((left, right) => {
212
+ const leftNumber = Number(left);
213
+ const rightNumber = Number(right);
214
+ if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) {
215
+ return leftNumber - rightNumber;
216
+ }
217
+ return left.localeCompare(right);
218
+ })
219
+ .map((key) => value[key]);
220
+ }
221
+ throw new Error(`Ransack ${name} must be an array or object, got: ${typeof value}`);
259
222
  }
260
-
261
223
  /**
262
224
  * Runs advanced ransack condition value.
263
225
  * @param {object} args - Options.
@@ -265,16 +227,14 @@ function normalizeRansackCollection(value, name) {
265
227
  * @param {?} args.value - Advanced condition value.
266
228
  * @returns {?} - Value passed to predicate normalization.
267
229
  */
268
- function advancedRansackConditionValue({predicate, value}) {
269
- if (predicate === "in" || predicate === "not_in") return value
270
-
271
- if (Array.isArray(value)) {
272
- return value.find((entry) => entry !== undefined && entry !== null && entry !== "")
273
- }
274
-
275
- return value
230
+ function advancedRansackConditionValue({ predicate, value }) {
231
+ if (predicate === "in" || predicate === "not_in")
232
+ return value;
233
+ if (Array.isArray(value)) {
234
+ return value.find((entry) => entry !== undefined && entry !== null && entry !== "");
235
+ }
236
+ return value;
276
237
  }
277
-
278
238
  /**
279
239
  * Runs resolve ransack attributes from advanced value.
280
240
  * @param {object} args - Options.
@@ -282,58 +242,49 @@ function advancedRansackConditionValue({predicate, value}) {
282
242
  * @param {?} args.value - Advanced attribute value.
283
243
  * @returns {RansackAttribute[]} - Resolved attributes.
284
244
  */
285
- function resolveRansackAttributesFromAdvancedValue({modelClass, value}) {
286
- const values = normalizeAdvancedAttributeValues(value)
287
- /**
288
- * Attributes.
289
- @type {RansackAttribute[]} */
290
- const attributes = []
291
-
292
- for (const attributeValue of values) {
293
- attributes.push(...resolveRansackAttributes({modelClass, value: attributeValue}))
294
- }
295
-
296
- if (attributes.length < 1) {
297
- throw new Error("Ransack condition must include at least one attribute")
298
- }
299
-
300
- return attributes
301
- }
302
-
245
+ function resolveRansackAttributesFromAdvancedValue({ modelClass, value }) {
246
+ const values = normalizeAdvancedAttributeValues(value);
247
+ /**
248
+ * Attributes.
249
+ @type {RansackAttribute[]} */
250
+ const attributes = [];
251
+ for (const attributeValue of values) {
252
+ attributes.push(...resolveRansackAttributes({ modelClass, value: attributeValue }));
253
+ }
254
+ if (attributes.length < 1) {
255
+ throw new Error("Ransack condition must include at least one attribute");
256
+ }
257
+ return attributes;
258
+ }
303
259
  /**
304
260
  * Runs normalize advanced attribute values.
305
261
  * @param {?} value - Advanced attribute value.
306
262
  * @returns {string[]} - Attribute path strings.
307
263
  */
308
264
  function normalizeAdvancedAttributeValues(value) {
309
- if (typeof value === "string") return [value]
310
-
311
- if (Array.isArray(value)) {
312
- return value.map((entry) => normalizeAdvancedAttributeValue(entry))
313
- }
314
-
315
- if (isPlainObject(value)) {
316
- return normalizeRansackCollection(value, "attributes").map((entry) => normalizeAdvancedAttributeValue(entry))
317
- }
318
-
319
- throw new Error(`Ransack condition attributes must be strings, arrays, or objects, got: ${typeof value}`)
320
- }
321
-
265
+ if (typeof value === "string")
266
+ return [value];
267
+ if (Array.isArray(value)) {
268
+ return value.map((entry) => normalizeAdvancedAttributeValue(entry));
269
+ }
270
+ if (isPlainObject(value)) {
271
+ return normalizeRansackCollection(value, "attributes").map((entry) => normalizeAdvancedAttributeValue(entry));
272
+ }
273
+ throw new Error(`Ransack condition attributes must be strings, arrays, or objects, got: ${typeof value}`);
274
+ }
322
275
  /**
323
276
  * Runs normalize advanced attribute value.
324
277
  * @param {?} value - Advanced attribute entry.
325
278
  * @returns {string} - Attribute path string.
326
279
  */
327
280
  function normalizeAdvancedAttributeValue(value) {
328
- if (typeof value === "string") return value
329
-
330
- if (isPlainObject(value) && typeof value.name === "string") {
331
- return value.name
332
- }
333
-
334
- throw new Error(`Ransack condition attribute entries must be strings or {name}, got: ${typeof value}`)
281
+ if (typeof value === "string")
282
+ return value;
283
+ if (isPlainObject(value) && typeof value.name === "string") {
284
+ return value.name;
285
+ }
286
+ throw new Error(`Ransack condition attribute entries must be strings or {name}, got: ${typeof value}`);
335
287
  }
336
-
337
288
  /**
338
289
  * Runs resolve ransack attributes.
339
290
  * @param {object} args - Options.
@@ -341,23 +292,20 @@ function normalizeAdvancedAttributeValue(value) {
341
292
  * @param {string} args.value - Attribute path value.
342
293
  * @returns {RansackAttribute[]} - Resolved attributes.
343
294
  */
344
- function resolveRansackAttributes({modelClass, value}) {
345
- return value.split("_or_").map((attributeValue) => {
346
- const resolvedPath = resolveRansackPath({modelClass, value: attributeValue})
347
- const targetModelClass = modelClassAtPath({modelClass, path: resolvedPath.path})
348
- const attributeName = resolveAttributeName({modelClass: targetModelClass, value: resolvedPath.attributeValue})
349
-
350
- if (!attributeName) {
351
- throw new Error(`Unknown ransack attribute "${resolvedPath.attributeValue}" for ${targetModelClass.name}`)
352
- }
353
-
354
- return {
355
- attributeName,
356
- path: resolvedPath.path
357
- }
358
- })
295
+ function resolveRansackAttributes({ modelClass, value }) {
296
+ return value.split("_or_").map((attributeValue) => {
297
+ const resolvedPath = resolveRansackPath({ modelClass, value: attributeValue });
298
+ const targetModelClass = modelClassAtPath({ modelClass, path: resolvedPath.path });
299
+ const attributeName = resolveAttributeName({ modelClass: targetModelClass, value: resolvedPath.attributeValue });
300
+ if (!attributeName) {
301
+ throw new Error(`Unknown ransack attribute "${resolvedPath.attributeValue}" for ${targetModelClass.name}`);
302
+ }
303
+ return {
304
+ attributeName,
305
+ path: resolvedPath.path
306
+ };
307
+ });
359
308
  }
360
-
361
309
  /**
362
310
  * Runs model class at path.
363
311
  * @param {object} args - Options.
@@ -365,22 +313,17 @@ function resolveRansackAttributes({modelClass, value}) {
365
313
  * @param {string[]} args.path - Relationship path.
366
314
  * @returns {RansackModelClass} - Target model class.
367
315
  */
368
- function modelClassAtPath({modelClass, path}) {
369
- let currentModelClass = modelClass
370
-
371
- for (const relationshipName of path) {
372
- const relationship = relationshipEntries(currentModelClass)[relationshipName]
373
-
374
- if (!relationship) {
375
- throw new Error(`Unknown ransack relationship "${relationshipName}" for ${currentModelClass.name}`)
316
+ function modelClassAtPath({ modelClass, path }) {
317
+ let currentModelClass = modelClass;
318
+ for (const relationshipName of path) {
319
+ const relationship = relationshipEntries(currentModelClass)[relationshipName];
320
+ if (!relationship) {
321
+ throw new Error(`Unknown ransack relationship "${relationshipName}" for ${currentModelClass.name}`);
322
+ }
323
+ currentModelClass = relationship.targetModelClass;
376
324
  }
377
-
378
- currentModelClass = relationship.targetModelClass
379
- }
380
-
381
- return currentModelClass
325
+ return currentModelClass;
382
326
  }
383
-
384
327
  /**
385
328
  * Runs resolve ransack path.
386
329
  * @param {object} args - Options.
@@ -388,41 +331,35 @@ function modelClassAtPath({modelClass, path}) {
388
331
  * @param {string} args.value - Remaining path value.
389
332
  * @returns {{attributeValue: string, path: string[]}} - Resolved relationship path and remaining attribute value.
390
333
  */
391
- function resolveRansackPath({modelClass, value}) {
392
- /**
393
- * Path.
394
- @type {string[]} */
395
- const path = []
396
- let currentModelClass = modelClass
397
- let remainingValue = value
398
-
399
- while (true) {
400
- if (resolveAttributeName({modelClass: currentModelClass, value: remainingValue})) {
401
- break
402
- }
403
-
404
- const match = findRelationshipPrefix({
405
- modelClass: currentModelClass,
406
- value: remainingValue
407
- })
408
-
409
- if (!match) break
410
-
411
- path.push(match.relationshipName)
412
- currentModelClass = match.targetModelClass
413
- remainingValue = match.remainingValue
414
- }
415
-
416
- if (remainingValue.length < 1) {
417
- throw new Error(`Invalid ransack key path: ${value}`)
418
- }
419
-
420
- return {
421
- attributeValue: remainingValue,
422
- path
423
- }
424
- }
425
-
334
+ function resolveRansackPath({ modelClass, value }) {
335
+ /**
336
+ * Path.
337
+ @type {string[]} */
338
+ const path = [];
339
+ let currentModelClass = modelClass;
340
+ let remainingValue = value;
341
+ while (true) {
342
+ if (resolveAttributeName({ modelClass: currentModelClass, value: remainingValue })) {
343
+ break;
344
+ }
345
+ const match = findRelationshipPrefix({
346
+ modelClass: currentModelClass,
347
+ value: remainingValue
348
+ });
349
+ if (!match)
350
+ break;
351
+ path.push(match.relationshipName);
352
+ currentModelClass = match.targetModelClass;
353
+ remainingValue = match.remainingValue;
354
+ }
355
+ if (remainingValue.length < 1) {
356
+ throw new Error(`Invalid ransack key path: ${value}`);
357
+ }
358
+ return {
359
+ attributeValue: remainingValue,
360
+ path
361
+ };
362
+ }
426
363
  /**
427
364
  * Runs find relationship prefix.
428
365
  * @param {object} args - Options.
@@ -430,37 +367,34 @@ function resolveRansackPath({modelClass, value}) {
430
367
  * @param {string} args.value - Remaining value to match.
431
368
  * @returns {{relationshipName: string, remainingValue: string, targetModelClass: RansackModelClass} | null} - Matching relationship prefix.
432
369
  */
433
- function findRelationshipPrefix({modelClass, value}) {
434
- let bestMatch = null
435
-
436
- for (const relationshipName of Object.keys(relationshipEntries(modelClass))) {
437
- const relationship = relationshipEntries(modelClass)[relationshipName]
438
-
439
- for (const candidate of relationshipCandidates(relationshipName)) {
440
- const remainingValue = stripRelationshipCandidate(value, candidate)
441
-
442
- if (remainingValue === null) continue
443
- if (remainingValue.length < 1) continue
444
- if (bestMatch && candidate.length <= bestMatch.candidateLength) continue
445
-
446
- bestMatch = {
447
- candidateLength: candidate.length,
448
- relationshipName,
449
- remainingValue,
450
- targetModelClass: relationship.targetModelClass
451
- }
452
- }
453
- }
454
-
455
- if (!bestMatch) return null
456
-
457
- return {
458
- relationshipName: bestMatch.relationshipName,
459
- remainingValue: bestMatch.remainingValue,
460
- targetModelClass: bestMatch.targetModelClass
461
- }
462
- }
463
-
370
+ function findRelationshipPrefix({ modelClass, value }) {
371
+ let bestMatch = null;
372
+ for (const relationshipName of Object.keys(relationshipEntries(modelClass))) {
373
+ const relationship = relationshipEntries(modelClass)[relationshipName];
374
+ for (const candidate of relationshipCandidates(relationshipName)) {
375
+ const remainingValue = stripRelationshipCandidate(value, candidate);
376
+ if (remainingValue === null)
377
+ continue;
378
+ if (remainingValue.length < 1)
379
+ continue;
380
+ if (bestMatch && candidate.length <= bestMatch.candidateLength)
381
+ continue;
382
+ bestMatch = {
383
+ candidateLength: candidate.length,
384
+ relationshipName,
385
+ remainingValue,
386
+ targetModelClass: relationship.targetModelClass
387
+ };
388
+ }
389
+ }
390
+ if (!bestMatch)
391
+ return null;
392
+ return {
393
+ relationshipName: bestMatch.relationshipName,
394
+ remainingValue: bestMatch.remainingValue,
395
+ targetModelClass: bestMatch.targetModelClass
396
+ };
397
+ }
464
398
  /**
465
399
  * Returns the portion of `value` after `candidate` when `candidate`
466
400
  * sits at a relationship-path boundary, or null when there's no
@@ -477,29 +411,26 @@ function findRelationshipPrefix({modelClass, value}) {
477
411
  * @returns {string | null} - Remainder after the candidate, or null.
478
412
  */
479
413
  function stripRelationshipCandidate(value, candidate) {
480
- if (value.startsWith(`${candidate}_`)) {
481
- return value.slice(candidate.length + 1)
482
- }
483
-
484
- if (value.length <= candidate.length) return null
485
- if (!value.startsWith(candidate)) return null
486
-
487
- const nextChar = value.charAt(candidate.length)
488
-
489
- if (nextChar < "A" || nextChar > "Z") return null
490
-
491
- return nextChar.toLowerCase() + value.slice(candidate.length + 1)
492
- }
493
-
414
+ if (value.startsWith(`${candidate}_`)) {
415
+ return value.slice(candidate.length + 1);
416
+ }
417
+ if (value.length <= candidate.length)
418
+ return null;
419
+ if (!value.startsWith(candidate))
420
+ return null;
421
+ const nextChar = value.charAt(candidate.length);
422
+ if (nextChar < "A" || nextChar > "Z")
423
+ return null;
424
+ return nextChar.toLowerCase() + value.slice(candidate.length + 1);
425
+ }
494
426
  /**
495
427
  * Runs relationship candidates.
496
428
  * @param {string} relationshipName - Relationship name.
497
429
  * @returns {string[]} - Candidate tokens for matching.
498
430
  */
499
431
  function relationshipCandidates(relationshipName) {
500
- return uniqunize([relationshipName, inflection.underscore(relationshipName)])
432
+ return uniqunize([relationshipName, inflection.underscore(relationshipName)]);
501
433
  }
502
-
503
434
  /**
504
435
  * Runs resolve attribute name.
505
436
  * @param {object} args - Options.
@@ -507,139 +438,123 @@ function relationshipCandidates(relationshipName) {
507
438
  * @param {string} args.value - Attribute candidate.
508
439
  * @returns {string | undefined} - Resolved attribute name.
509
440
  */
510
- function resolveAttributeName({modelClass, value}) {
511
- for (const [attributeName, columnName] of Object.entries(attributeEntries(modelClass))) {
512
- if (matchesAttributeValue({attributeName, columnName, value})) {
513
- return attributeName
441
+ function resolveAttributeName({ modelClass, value }) {
442
+ for (const [attributeName, columnName] of Object.entries(attributeEntries(modelClass))) {
443
+ if (matchesAttributeValue({ attributeName, columnName, value })) {
444
+ return attributeName;
445
+ }
514
446
  }
515
- }
516
-
517
- return undefined
447
+ return undefined;
518
448
  }
519
-
520
449
  /**
521
450
  * Runs relationship entries.
522
451
  * @param {RansackModelClass} modelClass - Model class.
523
452
  * @returns {Record<string, {targetModelClass: RansackModelClass}>} - Relationship entries keyed by name.
524
453
  */
525
454
  function relationshipEntries(modelClass) {
526
- if (typeof /**
527
- * Narrows the runtime value to the documented type.
528
- @type {?} */ (modelClass).getRelationshipsMap === "function") {
529
- return backendRelationshipEntries(modelClass)
530
- }
531
-
532
- if (typeof /**
533
- * Narrows the runtime value to the documented type.
534
- @type {?} */ (modelClass).relationshipDefinitions === "function" &&
535
- typeof /**
536
- * Narrows the runtime value to the documented type.
537
- @type {?} */ (modelClass).relationshipModelClasses === "function") {
538
- return frontendRelationshipEntries(modelClass)
539
- }
540
-
541
- return {}
542
- }
543
-
455
+ if (typeof /**
456
+ * Narrows the runtime value to the documented type.
457
+ @type {?} */ (modelClass).getRelationshipsMap === "function") {
458
+ return backendRelationshipEntries(modelClass);
459
+ }
460
+ if (typeof /**
461
+ * Narrows the runtime value to the documented type.
462
+ @type {?} */ (modelClass).relationshipDefinitions === "function" &&
463
+ typeof /**
464
+ * Narrows the runtime value to the documented type.
465
+ @type {?} */ (modelClass).relationshipModelClasses === "function") {
466
+ return frontendRelationshipEntries(modelClass);
467
+ }
468
+ return {};
469
+ }
544
470
  /**
545
471
  * Runs backend relationship entries.
546
472
  * @param {RansackModelClass} modelClass - Backend model class.
547
473
  * @returns {Record<string, {targetModelClass: RansackModelClass}>} - Relationship entries keyed by name.
548
474
  */
549
475
  function backendRelationshipEntries(modelClass) {
550
- /**
551
- * Entries.
552
- @type {Record<string, {targetModelClass: RansackModelClass}>} */
553
- const entries = {}
554
- const relationshipsMap = /**
555
- * Narrows the runtime value to the documented type.
556
- @type {?} */ (modelClass).getRelationshipsMap()
557
-
558
- for (const relationshipName of Object.keys(relationshipsMap)) {
559
- const relationship = relationshipsMap[relationshipName]
560
-
561
- if (typeof relationship.isPolymorphic === "function" && relationship.isPolymorphic()) continue
562
-
563
- const targetModelClass = relationship.getTargetModelClass()
564
-
565
- if (!targetModelClass) continue
566
-
567
- entries[relationshipName] = {targetModelClass}
568
- }
569
-
570
- return entries
571
- }
572
-
476
+ /**
477
+ * Entries.
478
+ @type {Record<string, {targetModelClass: RansackModelClass}>} */
479
+ const entries = {};
480
+ const relationshipsMap = /**
481
+ * Narrows the runtime value to the documented type.
482
+ @type {?} */ (modelClass).getRelationshipsMap();
483
+ for (const relationshipName of Object.keys(relationshipsMap)) {
484
+ const relationship = relationshipsMap[relationshipName];
485
+ if (typeof relationship.isPolymorphic === "function" && relationship.isPolymorphic())
486
+ continue;
487
+ const targetModelClass = relationship.getTargetModelClass();
488
+ if (!targetModelClass)
489
+ continue;
490
+ entries[relationshipName] = { targetModelClass };
491
+ }
492
+ return entries;
493
+ }
573
494
  /**
574
495
  * Runs frontend relationship entries.
575
496
  * @param {RansackModelClass} modelClass - Frontend model class.
576
497
  * @returns {Record<string, {targetModelClass: RansackModelClass}>} - Relationship entries keyed by name.
577
498
  */
578
499
  function frontendRelationshipEntries(modelClass) {
579
- /**
580
- * Entries.
581
- @type {Record<string, {targetModelClass: RansackModelClass}>} */
582
- const entries = {}
583
- const definitions = /**
584
- * Narrows the runtime value to the documented type.
585
- @type {?} */ (modelClass).relationshipDefinitions()
586
- const relationshipModelClasses = /**
587
- * Narrows the runtime value to the documented type.
588
- @type {?} */ (modelClass).relationshipModelClasses()
589
-
590
- for (const relationshipName of Object.keys(definitions)) {
591
- const targetModelClass = resolveFrontendModelClass(relationshipModelClasses[relationshipName])
592
-
593
- if (!targetModelClass) continue
594
-
595
- entries[relationshipName] = {targetModelClass}
596
- }
597
-
598
- return entries
599
- }
600
-
500
+ /**
501
+ * Entries.
502
+ @type {Record<string, {targetModelClass: RansackModelClass}>} */
503
+ const entries = {};
504
+ const definitions = /**
505
+ * Narrows the runtime value to the documented type.
506
+ @type {?} */ (modelClass).relationshipDefinitions();
507
+ const relationshipModelClasses = /**
508
+ * Narrows the runtime value to the documented type.
509
+ @type {?} */ (modelClass).relationshipModelClasses();
510
+ for (const relationshipName of Object.keys(definitions)) {
511
+ const targetModelClass = resolveFrontendModelClass(relationshipModelClasses[relationshipName]);
512
+ if (!targetModelClass)
513
+ continue;
514
+ entries[relationshipName] = { targetModelClass };
515
+ }
516
+ return entries;
517
+ }
601
518
  /**
602
519
  * Runs attribute entries.
603
520
  * @param {RansackModelClass} modelClass - Model class.
604
521
  * @returns {Record<string, string>} - Attribute-to-column entries keyed by attribute name.
605
522
  */
606
523
  function attributeEntries(modelClass) {
607
- if (typeof /**
608
- * Narrows the runtime value to the documented type.
609
- @type {?} */ (modelClass).getAttributeNameToColumnNameMap === "function") {
610
- return /** Narrows the runtime value to the documented type. @type {Record<string, string>} */ ((/**
611
- * Narrows the runtime value to the documented type.
612
- @type {?} */ (modelClass).getAttributeNameToColumnNameMap()))
613
- }
614
-
615
- const resourceConfig = typeof /**
616
- * Narrows the runtime value to the documented type.
617
- @type {?} */ (modelClass).resourceConfig === "function"
618
- ? /**
619
- * Narrows the runtime value to the documented type.
620
- @type {?} */ (modelClass).resourceConfig()
621
- : {}
622
- const attributes = resourceConfig.attributes
623
- /**
624
- * Entries.
625
- @type {Record<string, string>} */
626
- const entries = {}
627
-
628
- if (Array.isArray(attributes)) {
629
- for (const attributeName of attributes) {
630
- if (typeof attributeName !== "string") continue
631
-
632
- entries[attributeName] = attributeName
633
- }
634
- } else if (isPlainObject(attributes)) {
635
- for (const attributeName of Object.keys(attributes)) {
636
- entries[attributeName] = attributeName
637
- }
638
- }
639
-
640
- return entries
641
- }
642
-
524
+ if (typeof /**
525
+ * Narrows the runtime value to the documented type.
526
+ @type {?} */ (modelClass).getAttributeNameToColumnNameMap === "function") {
527
+ return /** Narrows the runtime value to the documented type. @type {Record<string, string>} */ (( /**
528
+ * Narrows the runtime value to the documented type.
529
+ @type {?} */(modelClass).getAttributeNameToColumnNameMap()));
530
+ }
531
+ const resourceConfig = typeof /**
532
+ * Narrows the runtime value to the documented type.
533
+ @type {?} */ (modelClass).resourceConfig === "function"
534
+ ? /**
535
+ * Narrows the runtime value to the documented type.
536
+ @type {?} */
537
+ (modelClass).resourceConfig()
538
+ : {};
539
+ const attributes = resourceConfig.attributes;
540
+ /**
541
+ * Entries.
542
+ @type {Record<string, string>} */
543
+ const entries = {};
544
+ if (Array.isArray(attributes)) {
545
+ for (const attributeName of attributes) {
546
+ if (typeof attributeName !== "string")
547
+ continue;
548
+ entries[attributeName] = attributeName;
549
+ }
550
+ }
551
+ else if (isPlainObject(attributes)) {
552
+ for (const attributeName of Object.keys(attributes)) {
553
+ entries[attributeName] = attributeName;
554
+ }
555
+ }
556
+ return entries;
557
+ }
643
558
  /**
644
559
  * Runs matches attribute value.
645
560
  * @param {object} args - Options.
@@ -648,72 +563,61 @@ function attributeEntries(modelClass) {
648
563
  * @param {string} args.value - Candidate value.
649
564
  * @returns {boolean} - Whether the candidate resolves to the attribute.
650
565
  */
651
- function matchesAttributeValue({attributeName, columnName, value}) {
652
- return uniqunize([
653
- attributeName,
654
- columnName,
655
- inflection.underscore(attributeName),
656
- inflection.underscore(columnName)
657
- ]).includes(value)
566
+ function matchesAttributeValue({ attributeName, columnName, value }) {
567
+ return uniqunize([
568
+ attributeName,
569
+ columnName,
570
+ inflection.underscore(attributeName),
571
+ inflection.underscore(columnName)
572
+ ]).includes(value);
658
573
  }
659
-
660
574
  /**
661
575
  * Runs parse ransack key.
662
576
  * @param {string} key - Ransack key.
663
577
  * @returns {{pathValue: string, predicate: RansackPredicate} | null} - Parsed key.
664
578
  */
665
579
  function parseRansackKey(key) {
666
- for (const predicate of supportedPredicates) {
667
- const suffix = `_${predicate}`
668
- if (!key.endsWith(suffix)) continue
669
-
670
- const pathValue = key.slice(0, key.length - suffix.length)
671
-
672
- if (pathValue.length < 1) {
673
- throw new Error(`Invalid ransack key: ${key}`)
674
- }
675
-
676
- return {
677
- pathValue,
678
- predicate: /**
679
- * Narrows the runtime value to the documented type.
680
- @type {RansackPredicate} */ (predicate)
681
- }
682
- }
683
-
684
- for (const predicate of supportedPredicates) {
685
- const camelSuffix = snakeToCamelSuffix(predicate)
686
-
687
- if (!key.endsWith(camelSuffix)) continue
688
-
689
- const pathValue = key.slice(0, key.length - camelSuffix.length)
690
-
691
- if (pathValue.length < 1) {
692
- throw new Error(`Invalid ransack key: ${key}`)
693
- }
694
-
695
- return {
696
- pathValue,
697
- predicate: /**
698
- * Narrows the runtime value to the documented type.
699
- @type {RansackPredicate} */ (predicate)
580
+ for (const predicate of supportedPredicates) {
581
+ const suffix = `_${predicate}`;
582
+ if (!key.endsWith(suffix))
583
+ continue;
584
+ const pathValue = key.slice(0, key.length - suffix.length);
585
+ if (pathValue.length < 1) {
586
+ throw new Error(`Invalid ransack key: ${key}`);
587
+ }
588
+ return {
589
+ pathValue,
590
+ predicate: /**
591
+ * Narrows the runtime value to the documented type.
592
+ @type {RansackPredicate} */ (predicate)
593
+ };
700
594
  }
701
- }
702
-
703
- return null
595
+ for (const predicate of supportedPredicates) {
596
+ const camelSuffix = snakeToCamelSuffix(predicate);
597
+ if (!key.endsWith(camelSuffix))
598
+ continue;
599
+ const pathValue = key.slice(0, key.length - camelSuffix.length);
600
+ if (pathValue.length < 1) {
601
+ throw new Error(`Invalid ransack key: ${key}`);
602
+ }
603
+ return {
604
+ pathValue,
605
+ predicate: /**
606
+ * Narrows the runtime value to the documented type.
607
+ @type {RansackPredicate} */ (predicate)
608
+ };
609
+ }
610
+ return null;
704
611
  }
705
-
706
612
  /**
707
613
  * Runs snake to camel suffix.
708
614
  * @param {string} value - Snake-case predicate.
709
615
  * @returns {string} - CamelCase predicate suffix used in ransack keys.
710
616
  */
711
617
  function snakeToCamelSuffix(value) {
712
- const segments = value.split("_")
713
-
714
- return segments.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("")
618
+ const segments = value.split("_");
619
+ return segments.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
715
620
  }
716
-
717
621
  /**
718
622
  * Runs normalize ransack value.
719
623
  * @param {object} args - Options.
@@ -721,99 +625,87 @@ function snakeToCamelSuffix(value) {
721
625
  * @param {?} args.value - Raw value.
722
626
  * @returns {?} - Normalized value.
723
627
  */
724
- function normalizeRansackValue({predicate, value}) {
725
- if (predicate === "null") {
726
- return normalizeRansackNullValue(value)
727
- }
728
-
729
- if (predicate === "in" || predicate === "not_in") {
730
- return normalizeRansackListValue(value)
731
- }
732
-
733
- if (ransackValueIsBlank(value)) return SKIP_RANSACK_CONDITION
734
-
735
- return value
736
- }
737
-
628
+ function normalizeRansackValue({ predicate, value }) {
629
+ if (predicate === "null") {
630
+ return normalizeRansackNullValue(value);
631
+ }
632
+ if (predicate === "in" || predicate === "not_in") {
633
+ return normalizeRansackListValue(value);
634
+ }
635
+ if (ransackValueIsBlank(value))
636
+ return SKIP_RANSACK_CONDITION;
637
+ return value;
638
+ }
738
639
  /**
739
640
  * Runs normalize ransack null value.
740
641
  * @param {?} value - Candidate null predicate value.
741
642
  * @returns {boolean | typeof SKIP_RANSACK_CONDITION} - Normalized value.
742
643
  */
743
644
  function normalizeRansackNullValue(value) {
744
- const booleanValue = normalizeRansackBoolean(value)
745
-
746
- return booleanValue === null ? SKIP_RANSACK_CONDITION : booleanValue
645
+ const booleanValue = normalizeRansackBoolean(value);
646
+ return booleanValue === null ? SKIP_RANSACK_CONDITION : booleanValue;
747
647
  }
748
-
749
648
  /**
750
649
  * Runs normalize ransack list value.
751
650
  * @param {?} value - Candidate list predicate value.
752
651
  * @returns {Array<?> | typeof SKIP_RANSACK_CONDITION} - Normalized value.
753
652
  */
754
653
  function normalizeRansackListValue(value) {
755
- const normalizedArray = normalizeRansackArray(value)
756
-
757
- return normalizedArray.length < 1 ? SKIP_RANSACK_CONDITION : normalizedArray
654
+ const normalizedArray = normalizeRansackArray(value);
655
+ return normalizedArray.length < 1 ? SKIP_RANSACK_CONDITION : normalizedArray;
758
656
  }
759
-
760
657
  /**
761
658
  * Ransack true values.
762
659
  @type {Set<?>} */
763
- const ransackTrueValues = new Set([true, 1, "1", "true"])
660
+ const ransackTrueValues = new Set([true, 1, "1", "true"]);
764
661
  /**
765
662
  * Ransack false values.
766
663
  @type {Set<?>} */
767
- const ransackFalseValues = new Set([false, 0, "0", "false"])
768
-
664
+ const ransackFalseValues = new Set([false, 0, "0", "false"]);
769
665
  /**
770
666
  * Runs normalize ransack boolean.
771
667
  * @param {?} value - Candidate boolean.
772
668
  * @returns {boolean | null} - Normalized boolean or null when blank.
773
669
  */
774
670
  function normalizeRansackBoolean(value) {
775
- if (ransackTrueValues.has(value)) return true
776
- if (ransackFalseValues.has(value)) return false
777
- if (ransackValueIsBlank(value)) return null
778
-
779
- throw new Error(`Invalid ransack boolean value: ${String(value)}`)
671
+ if (ransackTrueValues.has(value))
672
+ return true;
673
+ if (ransackFalseValues.has(value))
674
+ return false;
675
+ if (ransackValueIsBlank(value))
676
+ return null;
677
+ throw new Error(`Invalid ransack boolean value: ${String(value)}`);
780
678
  }
781
-
782
679
  /**
783
680
  * Runs ransack value is blank.
784
681
  * @param {?} value - Candidate value.
785
682
  * @returns {boolean} - Whether value should be ignored as blank.
786
683
  */
787
684
  function ransackValueIsBlank(value) {
788
- return value === undefined || value === null || value === ""
685
+ return value === undefined || value === null || value === "";
789
686
  }
790
-
791
687
  /**
792
688
  * Runs normalize ransack array.
793
689
  * @param {?} value - Candidate array-ish value.
794
690
  * @returns {Array<?>} - Normalized array values.
795
691
  */
796
692
  function normalizeRansackArray(value) {
797
- if (Array.isArray(value)) {
798
- return value.filter((entry) => entry !== undefined && entry !== null && entry !== "")
799
- }
800
-
801
- if (typeof value === "string") {
802
- return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0)
803
- }
804
-
805
- if (value === undefined || value === null || value === "") return []
806
-
807
- return [value]
808
- }
809
-
693
+ if (Array.isArray(value)) {
694
+ return value.filter((entry) => entry !== undefined && entry !== null && entry !== "");
695
+ }
696
+ if (typeof value === "string") {
697
+ return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
698
+ }
699
+ if (value === undefined || value === null || value === "")
700
+ return [];
701
+ return [value];
702
+ }
810
703
  /**
811
704
  * RansackSort type.
812
705
  * @typedef {object} RansackSort
813
706
  * @property {string} attribute - Resolved attribute name.
814
707
  * @property {"asc" | "desc"} direction - Sort direction.
815
708
  */
816
-
817
709
  /**
818
710
  * Parses and validates a ransack `s` sort string against model attributes.
819
711
  * @param {RansackModelClass} modelClass - Model class for attribute validation.
@@ -821,39 +713,32 @@ function normalizeRansackArray(value) {
821
713
  * @returns {RansackSort[]} - Validated sort definitions.
822
714
  */
823
715
  export function parseRansackSort(modelClass, sortString) {
824
- const segments = sortString.split(",").map((segment) => segment.trim()).filter((segment) => segment.length > 0)
825
-
826
- /**
827
- * Sorts.
828
- @type {RansackSort[]} */
829
- const sorts = []
830
-
831
- for (const segment of segments) {
832
- const parts = segment.split(/\s+/)
833
- const columnCandidate = parts[0]
834
- const directionCandidate = parts.length > 1 ? parts[1].toLowerCase() : "asc"
835
-
836
- if (directionCandidate !== "asc" && directionCandidate !== "desc") {
837
- throw new Error(`Invalid ransack sort direction "${directionCandidate}" in: ${segment}`)
838
- }
839
-
840
- const resolvedAttribute = resolveAttributeName({modelClass, value: columnCandidate})
841
-
842
- if (!resolvedAttribute) {
843
- throw new Error(`Unknown ransack sort attribute "${columnCandidate}" for ${modelClass.name}`)
844
- }
845
-
846
- sorts.push({attribute: resolvedAttribute, direction: directionCandidate})
847
- }
848
-
849
- return sorts
850
- }
851
-
716
+ const segments = sortString.split(",").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
717
+ /**
718
+ * Sorts.
719
+ @type {RansackSort[]} */
720
+ const sorts = [];
721
+ for (const segment of segments) {
722
+ const parts = segment.split(/\s+/);
723
+ const columnCandidate = parts[0];
724
+ const directionCandidate = parts.length > 1 ? parts[1].toLowerCase() : "asc";
725
+ if (directionCandidate !== "asc" && directionCandidate !== "desc") {
726
+ throw new Error(`Invalid ransack sort direction "${directionCandidate}" in: ${segment}`);
727
+ }
728
+ const resolvedAttribute = resolveAttributeName({ modelClass, value: columnCandidate });
729
+ if (!resolvedAttribute) {
730
+ throw new Error(`Unknown ransack sort attribute "${columnCandidate}" for ${modelClass.name}`);
731
+ }
732
+ sorts.push({ attribute: resolvedAttribute, direction: directionCandidate });
733
+ }
734
+ return sorts;
735
+ }
852
736
  /**
853
737
  * Runs uniqunize.
854
738
  * @param {string[]} values - Input values.
855
739
  * @returns {string[]} - Unique values in original order.
856
740
  */
857
741
  function uniqunize(values) {
858
- return Array.from(new Set(values))
742
+ return Array.from(new Set(values));
859
743
  }
744
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuc2Fjay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9yYW5zYWNrLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEtBQUssVUFBVSxNQUFNLFlBQVksQ0FBQTtBQUN4QyxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0saUJBQWlCLENBQUE7QUFDN0MsT0FBTyxFQUFDLHlCQUF5QixFQUFDLE1BQU0sc0NBQXNDLENBQUE7QUFFOUU7OztHQUdHO0FBRUg7OztHQUdHO0FBRUg7OztHQUdHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7OztHQU9HO0FBRUg7Ozs7OztHQU1HO0FBRUgsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixRQUFRO0lBQ1IsUUFBUTtJQUNSLE1BQU07SUFDTixNQUFNO0lBQ04sT0FBTztJQUNQLE1BQU07SUFDTixNQUFNO0lBQ04sS0FBSztJQUNMLElBQUk7SUFDSixJQUFJO0lBQ0osSUFBSTtJQUNKLElBQUk7Q0FDTCxDQUFBO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsVUFBVSxFQUFFLE1BQU07SUFDdkQsT0FBTyxxQkFBcUIsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUMsVUFBVSxDQUFBO0FBQzdELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxVQUFVLEVBQUUsTUFBTTtJQUN0RCxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsT0FBTyxNQUFNLEVBQUUsQ0FBQyxDQUFBO0lBQ2pGLENBQUM7SUFFRDs7NkJBRXlCO0lBQ3pCLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLFVBQVUsRUFBRSwwQkFBMEIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQztRQUN2RCxVQUFVLEVBQUUsRUFBRTtRQUNkLFNB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SyxDQUFDLG1DQUFtQyxrQkFBa0IsU0FBUyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1FBQzFGLENBQUM7UUFFRCxNQUFNLGlCQUFpQixHQUFHLG9CQUFvQixDQUFDLEVBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUMsQ0FBQyxDQUFBO1FBRXBGLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLGVBQWUsU0FBUyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUMvRixDQUFDO1FBRUQsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFDLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUMsQ0FBQyxDQUFBO0lBQzNFLENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxTQUFTLENBQUMsTUFBTTtJQUN2QixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtBQUNwQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCAqIGFzIGluZmxlY3Rpb24gZnJvbSBcImluZmxlY3Rpb25cIlxuaW1wb3J0IHtpc1BsYWluT2JqZWN0fSBmcm9tIFwiaXMtcGxhaW4tb2JqZWN0XCJcbmltcG9ydCB7cmVzb2x2ZUZyb250ZW5kTW9kZWxDbGFzc30gZnJvbSBcIi4uL2Zyb250ZW5kLW1vZGVscy9tb2RlbC1yZWdpc3RyeS5qc1wiXG5cbi8qKlxuICogUmFuc2Fja1ByZWRpY2F0ZSB0eXBlLlxuICogQHR5cGVkZWYge1wiY29udFwiIHwgXCJlbmRcIiB8IFwiZXFcIiB8IFwiZ3RcIiB8IFwiZ3RlcVwiIHwgXCJpblwiIHwgXCJsdFwiIHwgXCJsdGVxXCIgfCBcIm5vdF9lcVwiIHwgXCJub3RfaW5cIiB8IFwibnVsbFwiIHwgXCJzdGFydFwifSBSYW5zYWNrUHJlZGljYXRlXG4gKi9cblxuLyoqXG4gKiBSYW5zYWNrQ29tYmluYXRvciB0eXBlLlxuICogQHR5cGVkZWYge1wiYW5kXCIgfCBcIm9yXCJ9IFJhbnNhY2tDb21iaW5hdG9yXG4gKi9cblxuLyoqXG4gKiBSYW5zYWNrTW9kZWxDbGFzcyB0eXBlLlxuICogQHR5cGVkZWYge3R5cGVvZiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IHR5cGVvZiBpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbHMvYmFzZS5qc1wiKS5kZWZhdWx0fSBSYW5zYWNrTW9kZWxDbGFzc1xuICovXG5cbi8qKlxuICogUmFuc2Fja0F0dHJpYnV0ZSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gUmFuc2Fja0F0dHJpYnV0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGF0dHJpYnV0ZU5hbWUgLSBSZXNvbHZlZCBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IHBhdGggLSBSZXNvbHZlZCByZWxhdGlvbnNoaXAgcGF0aC5cbiAqL1xuXG4vKipcbiAqIFJhbnNhY2tDb25kaXRpb24gdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFJhbnNhY2tDb25kaXRpb25cbiAqIEBwcm9wZXJ0eSB7UmFuc2Fja0F0dHJpYnV0ZVtdfSBhdHRyaWJ1dGVzIC0gUmVzb2x2ZWQgYXR0cmlidXRlcyB0byB0ZXN0LlxuICogQHByb3BlcnR5IHtSYW5zYWNrQ29tYmluYXRvcn0gY29tYmluYXRvciAtIEhvdyBtdWx0aXBsZSBhdHRyaWJ1dGVzIGFyZSBjb21iaW5lZC5cbiAqIEBwcm9wZXJ0eSB7UmFuc2Fja1ByZWRpY2F0ZX0gcHJlZGljYXRlIC0gUGFyc2VkIFJhbnNhY2sgcHJlZGljYXRlLlxuICogQHByb3BlcnR5IHs/fSB2YWx1ZSAtIE5vcm1hbGl6ZWQgdmFsdWUuXG4gKi9cblxuLyoqXG4gKiBSYW5zYWNrR3JvdXAgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFJhbnNhY2tHcm91cFxuICogQHByb3BlcnR5IHtSYW5zYWNrQ29tYmluYXRvcn0gY29tYmluYXRvciAtIEhvdyBlbnRyaWVzIGluc2lkZSB0aGlzIGdyb3VwIGFyZSBjb21iaW5lZC5cbiAqIEBwcm9wZXJ0eSB7UmFuc2Fja0NvbmRpdGlvbltdfSBjb25kaXRpb25zIC0gQ29uZGl0aW9ucyBpbiB0aGlzIGdyb3VwLlxuICogQHByb3BlcnR5IHtSYW5zYWNrR3JvdXBbXX0gZ3JvdXBpbmdzIC0gTmVzdGVkIGdyb3Vwcy5cbiAqL1xuXG5jb25zdCBzdXBwb3J0ZWRQcmVkaWNhdGVzID0gW1xuICBcIm5vdF9pblwiLFxuICBcIm5vdF9lcVwiLFxuICBcImd0ZXFcIixcbiAgXCJsdGVxXCIsXG4gIFwic3RhcnRcIixcbiAgXCJjb250XCIsXG4gIFwibnVsbFwiLFxuICBcImVuZFwiLFxuICBcImVxXCIsXG4gIFwiZ3RcIixcbiAgXCJsdFwiLFxuICBcImluXCJcbl1cblxuLyoqXG4gKiBSdW5zIHRoZSBub3JtYWxpemVSYW5zYWNrUGFyYW1zIGhlbHBlci5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IG1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHBhcmFtcyAtIFJhbnNhY2stc3R5bGUgcGFyYW1zIGhhc2guXG4gKiBAcmV0dXJucyB7UmFuc2Fja0NvbmRpdGlvbltdfSAtIE5vcm1hbGl6ZWQgY29uZGl0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVJhbnNhY2tQYXJhbXMobW9kZWxDbGFzcywgcGFyYW1zKSB7XG4gIHJldHVybiBub3JtYWxpemVSYW5zYWNrR3JvdXAobW9kZWxDbGFzcywgcGFyYW1zKS5jb25kaXRpb25zXG59XG5cbi8qKlxuICogUnVucyB0aGUgbm9ybWFsaXplUmFuc2Fja0dyb3VwIGhlbHBlci5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IG1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHBhcmFtcyAtIFJhbnNhY2stc3R5bGUgcGFyYW1zIGhhc2guXG4gKiBAcmV0dXJucyB7UmFuc2Fja0dyb3VwfSAtIE5vcm1hbGl6ZWQgZ3JvdXAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrR3JvdXAobW9kZWxDbGFzcywgcGFyYW1zKSB7XG4gIGlmICghaXNQbGFpbk9iamVjdChwYXJhbXMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGByYW5zYWNrIHBhcmFtcyBtdXN0IGJlIGEgcGxhaW4gb2JqZWN0LCBnb3Q6ICR7dHlwZW9mIHBhcmFtc31gKVxuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZWQuXG4gICAgQHR5cGUge1JhbnNhY2tHcm91cH0gKi9cbiAgY29uc3Qgbm9ybWFsaXplZCA9IHtcbiAgICBjb21iaW5hdG9yOiBub3JtYWxpemVSYW5zYWNrQ29tYmluYXRvcihwYXJhbXMubSwgXCJhbmRcIiksXG4gICAgY29uZGl0aW9uczogW10sXG4gICAgZ3JvdXBpbmdzOiBbXVxuICB9XG5cbiAgZm9yIChjb25zdCBba2V5LCByYXdWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMocGFyYW1zKSkge1xuICAgIGlmIChrZXkgPT09IFwibVwiKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChrZXkgPT09IFwiY1wiKSB7XG4gICAgICBub3JtYWxpemVkLmNvbmRpdGlvbnMucHVzaCguLi5ub3JtYWxpemVBZHZhbmNlZFJhbnNhY2tDb25kaXRpb25zKHttb2RlbENsYXNzLCB2YWx1ZTogcmF3VmFsdWV9KSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKGtleSA9PT0gXCJnXCIpIHtcbiAgICAgIG5vcm1hbGl6ZWQuZ3JvdXBpbmdzLnB1c2goLi4ubm9ybWFsaXplQWR2YW5jZWRSYW5zYWNrR3JvdXBzKHttb2RlbENsYXNzLCB2YWx1ZTogcmF3VmFsdWV9KSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgY29uc3QgY29uZGl0aW9uID0gbm9ybWFsaXplU2ltcGxlUmFuc2Fja0NvbmRpdGlvbih7a2V5LCBtb2RlbENsYXNzLCByYXdWYWx1ZX0pXG4gICAgaWYgKGNvbmRpdGlvbikgbm9ybWFsaXplZC5jb25kaXRpb25zLnB1c2goY29uZGl0aW9uKVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRcbn1cblxuY29uc3QgU0tJUF9SQU5TQUNLX0NPTkRJVElPTiA9IFN5bWJvbChcInNraXAtcmFuc2Fjay1jb25kaXRpb25cIilcblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSBzaW1wbGUgcmFuc2FjayBjb25kaXRpb24uXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJncy5rZXkgLSBTaW1wbGUgUmFuc2FjayBrZXkuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7P30gYXJncy5yYXdWYWx1ZSAtIFJhdyBjb25kaXRpb24gdmFsdWUuXG4gKiBAcmV0dXJucyB7UmFuc2Fja0NvbmRpdGlvbiB8IG51bGx9IC0gTm9ybWFsaXplZCBjb25kaXRpb24sIG9yIG51bGwgd2hlbiBza2lwcGVkLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVTaW1wbGVSYW5zYWNrQ29uZGl0aW9uKHtrZXksIG1vZGVsQ2xhc3MsIHJhd1ZhbHVlfSkge1xuICBjb25zdCBwYXJzZWRLZXkgPSBwYXJzZVJhbnNhY2tLZXkoa2V5KVxuXG4gIGlmICghcGFyc2VkS2V5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCByYW5zYWNrIHByZWRpY2F0ZSBpbiBrZXk6ICR7a2V5fWApXG4gIH1cblxuICBjb25zdCB2YWx1ZSA9IG5vcm1hbGl6ZVJhbnNhY2tWYWx1ZSh7XG4gICAgcHJlZGljYXRlOiBwYXJzZWRLZXkucHJlZGljYXRlLFxuICAgIHZhbHVlOiByYXdWYWx1ZVxuICB9KVxuXG4gIGlmICh2YWx1ZSA9PT0gU0tJUF9SQU5TQUNLX0NPTkRJVElPTikgcmV0dXJuIG51bGxcblxuICBjb25zdCBhdHRyaWJ1dGVzID0gcmVzb2x2ZVJhbnNhY2tBdHRyaWJ1dGVzKHttb2RlbENsYXNzLCB2YWx1ZTogcGFyc2VkS2V5LnBhdGhWYWx1ZX0pXG5cbiAgcmV0dXJuIHtcbiAgICBhdHRyaWJ1dGVzLFxuICAgIGNvbWJpbmF0b3I6IGF0dHJpYnV0ZXMubGVuZ3RoID4gMSA/IFwib3JcIiA6IFwiYW5kXCIsXG4gICAgcHJlZGljYXRlOiBwYXJzZWRLZXkucHJlZGljYXRlLFxuICAgIHZhbHVlXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSBhZHZhbmNlZCByYW5zYWNrIGNvbmRpdGlvbnMuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7P30gYXJncy52YWx1ZSAtIEFkdmFuY2VkIGNvbmRpdGlvbnMgY29sbGVjdGlvbi5cbiAqIEByZXR1cm5zIHtSYW5zYWNrQ29uZGl0aW9uW119IC0gTm9ybWFsaXplZCBjb25kaXRpb25zLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVBZHZhbmNlZFJhbnNhY2tDb25kaXRpb25zKHttb2RlbENsYXNzLCB2YWx1ZX0pIHtcbiAgLyoqXG4gICAqIENvbmRpdGlvbnMuXG4gICAgQHR5cGUge1JhbnNhY2tDb25kaXRpb25bXX0gKi9cbiAgY29uc3QgY29uZGl0aW9ucyA9IFtdXG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBub3JtYWxpemVSYW5zYWNrQ29sbGVjdGlvbih2YWx1ZSwgXCJjb25kaXRpb25zXCIpKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KGVudHJ5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSYW5zYWNrIGNvbmRpdGlvbiBlbnRyaWVzIG11c3QgYmUgcGxhaW4gb2JqZWN0cywgZ290OiAke3R5cGVvZiBlbnRyeX1gKVxuICAgIH1cblxuICAgIGNvbnN0IHByZWRpY2F0ZVZhbHVlID0gZW50cnkucFxuXG4gICAgaWYgKHR5cGVvZiBwcmVkaWNhdGVWYWx1ZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmFuc2FjayBjb25kaXRpb24gcHJlZGljYXRlIG11c3QgYmUgYSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICBpZiAoIXN1cHBvcnRlZFByZWRpY2F0ZXMuaW5jbHVkZXMocHJlZGljYXRlVmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHJhbnNhY2sgcHJlZGljYXRlIGluIGNvbmRpdGlvbjogJHtwcmVkaWNhdGVWYWx1ZX1gKVxuICAgIH1cblxuICAgIGNvbnN0IHByZWRpY2F0ZSA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSYW5zYWNrUHJlZGljYXRlfSAqLyAocHJlZGljYXRlVmFsdWUpXG4gICAgY29uc3QgcmF3VmFsdWUgPSBhZHZhbmNlZFJhbnNhY2tDb25kaXRpb25WYWx1ZSh7cHJlZGljYXRlLCB2YWx1ZTogZW50cnkudn0pXG4gICAgY29uc3Qgbm9ybWFsaXplZFZhbHVlID0gbm9ybWFsaXplUmFuc2Fja1ZhbHVlKHtwcmVkaWNhdGUsIHZhbHVlOiByYXdWYWx1ZX0pXG5cbiAgICBpZiAobm9ybWFsaXplZFZhbHVlID09PSBTS0lQX1JBTlNBQ0tfQ09ORElUSU9OKSBjb250aW51ZVxuXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IHJlc29sdmVSYW5zYWNrQXR0cmlidXRlc0Zyb21BZHZhbmNlZFZhbHVlKHttb2RlbENsYXNzLCB2YWx1ZTogZW50cnkuYX0pXG5cbiAgICBjb25kaXRpb25zLnB1c2goe1xuICAgICAgYXR0cmlidXRlcyxcbiAgICAgIGNvbWJpbmF0b3I6IG5vcm1hbGl6ZVJhbnNhY2tDb21iaW5hdG9yKGVudHJ5Lm0sIGF0dHJpYnV0ZXMubGVuZ3RoID4gMSA/IFwib3JcIiA6IFwiYW5kXCIpLFxuICAgICAgcHJlZGljYXRlLFxuICAgICAgdmFsdWU6IG5vcm1hbGl6ZWRWYWx1ZVxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gY29uZGl0aW9uc1xufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIGFkdmFuY2VkIHJhbnNhY2sgZ3JvdXBzLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0gez99IGFyZ3MudmFsdWUgLSBBZHZhbmNlZCBncm91cHMgY29sbGVjdGlvbi5cbiAqIEByZXR1cm5zIHtSYW5zYWNrR3JvdXBbXX0gLSBOb3JtYWxpemVkIGdyb3Vwcy5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplQWR2YW5jZWRSYW5zYWNrR3JvdXBzKHttb2RlbENsYXNzLCB2YWx1ZX0pIHtcbiAgLyoqXG4gICAqIEdyb3VwaW5ncy5cbiAgICBAdHlwZSB7UmFuc2Fja0dyb3VwW119ICovXG4gIGNvbnN0IGdyb3VwaW5ncyA9IFtdXG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBub3JtYWxpemVSYW5zYWNrQ29sbGVjdGlvbih2YWx1ZSwgXCJncm91cGluZ3NcIikpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QoZW50cnkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJhbnNhY2sgZ3JvdXBpbmcgZW50cmllcyBtdXN0IGJlIHBsYWluIG9iamVjdHMsIGdvdDogJHt0eXBlb2YgZW50cnl9YClcbiAgICB9XG5cbiAgICBncm91cGluZ3MucHVzaChub3JtYWxpemVSYW5zYWNrR3JvdXAobW9kZWxDbGFzcywgZW50cnkpKVxuICB9XG5cbiAgcmV0dXJuIGdyb3VwaW5nc1xufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIHJhbnNhY2sgY29tYmluYXRvci5cbiAqIEBwYXJhbSB7P30gdmFsdWUgLSBDYW5kaWRhdGUgY29tYmluYXRvci5cbiAqIEBwYXJhbSB7UmFuc2Fja0NvbWJpbmF0b3J9IGRlZmF1bHRWYWx1ZSAtIERlZmF1bHQgY29tYmluYXRvci5cbiAqIEByZXR1cm5zIHtSYW5zYWNrQ29tYmluYXRvcn0gLSBOb3JtYWxpemVkIGNvbWJpbmF0b3IuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJhbnNhY2tDb21iaW5hdG9yKHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCIpIHJldHVybiBkZWZhdWx0VmFsdWVcbiAgaWYgKHZhbHVlID09PSBcImFuZFwiIHx8IHZhbHVlID09PSBcIm9yXCIpIHJldHVybiB2YWx1ZVxuXG4gIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5zYWNrIGNvbWJpbmF0b3I6ICR7U3RyaW5nKHZhbHVlKX1gKVxufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIHJhbnNhY2sgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7P30gdmFsdWUgLSBDYW5kaWRhdGUgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQ29sbGVjdGlvbiBuYW1lIGZvciBlcnJvcnMuXG4gKiBAcmV0dXJucyB7QXJyYXk8Pz59IC0gQ29sbGVjdGlvbiB2YWx1ZXMgaW4gc3RhYmxlIG9yZGVyLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrQ29sbGVjdGlvbih2YWx1ZSwgbmFtZSkge1xuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikgcmV0dXJuIFtdXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIHZhbHVlXG5cbiAgaWYgKGlzUGxhaW5PYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHZhbHVlKVxuICAgICAgLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiB7XG4gICAgICAgIGNvbnN0IGxlZnROdW1iZXIgPSBOdW1iZXIobGVmdClcbiAgICAgICAgY29uc3QgcmlnaHROdW1iZXIgPSBOdW1iZXIocmlnaHQpXG5cbiAgICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZShsZWZ0TnVtYmVyKSAmJiBOdW1iZXIuaXNGaW5pdGUocmlnaHROdW1iZXIpKSB7XG4gICAgICAgICAgcmV0dXJuIGxlZnROdW1iZXIgLSByaWdodE51bWJlclxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGxlZnQubG9jYWxlQ29tcGFyZShyaWdodClcbiAgICAgIH0pXG4gICAgICAubWFwKChrZXkpID0+IHZhbHVlW2tleV0pXG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoYFJhbnNhY2sgJHtuYW1lfSBtdXN0IGJlIGFuIGFycmF5IG9yIG9iamVjdCwgZ290OiAke3R5cGVvZiB2YWx1ZX1gKVxufVxuXG4vKipcbiAqIFJ1bnMgYWR2YW5jZWQgcmFuc2FjayBjb25kaXRpb24gdmFsdWUuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1JhbnNhY2tQcmVkaWNhdGV9IGFyZ3MucHJlZGljYXRlIC0gUGFyc2VkIHByZWRpY2F0ZS5cbiAqIEBwYXJhbSB7P30gYXJncy52YWx1ZSAtIEFkdmFuY2VkIGNvbmRpdGlvbiB2YWx1ZS5cbiAqIEByZXR1cm5zIHs/fSAtIFZhbHVlIHBhc3NlZCB0byBwcmVkaWNhdGUgbm9ybWFsaXphdGlvbi5cbiAqL1xuZnVuY3Rpb24gYWR2YW5jZWRSYW5zYWNrQ29uZGl0aW9uVmFsdWUoe3ByZWRpY2F0ZSwgdmFsdWV9KSB7XG4gIGlmIChwcmVkaWNhdGUgPT09IFwiaW5cIiB8fCBwcmVkaWNhdGUgPT09IFwibm90X2luXCIpIHJldHVybiB2YWx1ZVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5maW5kKChlbnRyeSkgPT4gZW50cnkgIT09IHVuZGVmaW5lZCAmJiBlbnRyeSAhPT0gbnVsbCAmJiBlbnRyeSAhPT0gXCJcIilcbiAgfVxuXG4gIHJldHVybiB2YWx1ZVxufVxuXG4vKipcbiAqIFJ1bnMgcmVzb2x2ZSByYW5zYWNrIGF0dHJpYnV0ZXMgZnJvbSBhZHZhbmNlZCB2YWx1ZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IGFyZ3MubW9kZWxDbGFzcyAtIE1vZGVsIGNsYXNzLlxuICogQHBhcmFtIHs/fSBhcmdzLnZhbHVlIC0gQWR2YW5jZWQgYXR0cmlidXRlIHZhbHVlLlxuICogQHJldHVybnMge1JhbnNhY2tBdHRyaWJ1dGVbXX0gLSBSZXNvbHZlZCBhdHRyaWJ1dGVzLlxuICovXG5mdW5jdGlvbiByZXNvbHZlUmFuc2Fja0F0dHJpYnV0ZXNGcm9tQWR2YW5jZWRWYWx1ZSh7bW9kZWxDbGFzcywgdmFsdWV9KSB7XG4gIGNvbnN0IHZhbHVlcyA9IG5vcm1hbGl6ZUFkdmFuY2VkQXR0cmlidXRlVmFsdWVzKHZhbHVlKVxuICAvKipcbiAgICogQXR0cmlidXRlcy5cbiAgICBAdHlwZSB7UmFuc2Fja0F0dHJpYnV0ZVtdfSAqL1xuICBjb25zdCBhdHRyaWJ1dGVzID0gW11cblxuICBmb3IgKGNvbnN0IGF0dHJpYnV0ZVZhbHVlIG9mIHZhbHVlcykge1xuICAgIGF0dHJpYnV0ZXMucHVzaCguLi5yZXNvbHZlUmFuc2Fja0F0dHJpYnV0ZXMoe21vZGVsQ2xhc3MsIHZhbHVlOiBhdHRyaWJ1dGVWYWx1ZX0pKVxuICB9XG5cbiAgaWYgKGF0dHJpYnV0ZXMubGVuZ3RoIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlJhbnNhY2sgY29uZGl0aW9uIG11c3QgaW5jbHVkZSBhdCBsZWFzdCBvbmUgYXR0cmlidXRlXCIpXG4gIH1cblxuICByZXR1cm4gYXR0cmlidXRlc1xufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIGFkdmFuY2VkIGF0dHJpYnV0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gQWR2YW5jZWQgYXR0cmlidXRlIHZhbHVlLlxuICogQHJldHVybnMge3N0cmluZ1tdfSAtIEF0dHJpYnV0ZSBwYXRoIHN0cmluZ3MuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUFkdmFuY2VkQXR0cmlidXRlVmFsdWVzKHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiBbdmFsdWVdXG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLm1hcCgoZW50cnkpID0+IG5vcm1hbGl6ZUFkdmFuY2VkQXR0cmlidXRlVmFsdWUoZW50cnkpKVxuICB9XG5cbiAgaWYgKGlzUGxhaW5PYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZVJhbnNhY2tDb2xsZWN0aW9uKHZhbHVlLCBcImF0dHJpYnV0ZXNcIikubWFwKChlbnRyeSkgPT4gbm9ybWFsaXplQWR2YW5jZWRBdHRyaWJ1dGVWYWx1ZShlbnRyeSkpXG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoYFJhbnNhY2sgY29uZGl0aW9uIGF0dHJpYnV0ZXMgbXVzdCBiZSBzdHJpbmdzLCBhcnJheXMsIG9yIG9iamVjdHMsIGdvdDogJHt0eXBlb2YgdmFsdWV9YClcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSBhZHZhbmNlZCBhdHRyaWJ1dGUgdmFsdWUuXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gQWR2YW5jZWQgYXR0cmlidXRlIGVudHJ5LlxuICogQHJldHVybnMge3N0cmluZ30gLSBBdHRyaWJ1dGUgcGF0aCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUFkdmFuY2VkQXR0cmlidXRlVmFsdWUodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHZhbHVlXG5cbiAgaWYgKGlzUGxhaW5PYmplY3QodmFsdWUpICYmIHR5cGVvZiB2YWx1ZS5uYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIHZhbHVlLm5hbWVcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgUmFuc2FjayBjb25kaXRpb24gYXR0cmlidXRlIGVudHJpZXMgbXVzdCBiZSBzdHJpbmdzIG9yIHtuYW1lfSwgZ290OiAke3R5cGVvZiB2YWx1ZX1gKVxufVxuXG4vKipcbiAqIFJ1bnMgcmVzb2x2ZSByYW5zYWNrIGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBhcmdzLm1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnZhbHVlIC0gQXR0cmlidXRlIHBhdGggdmFsdWUuXG4gKiBAcmV0dXJucyB7UmFuc2Fja0F0dHJpYnV0ZVtdfSAtIFJlc29sdmVkIGF0dHJpYnV0ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVSYW5zYWNrQXR0cmlidXRlcyh7bW9kZWxDbGFzcywgdmFsdWV9KSB7XG4gIHJldHVybiB2YWx1ZS5zcGxpdChcIl9vcl9cIikubWFwKChhdHRyaWJ1dGVWYWx1ZSkgPT4ge1xuICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IHJlc29sdmVSYW5zYWNrUGF0aCh7bW9kZWxDbGFzcywgdmFsdWU6IGF0dHJpYnV0ZVZhbHVlfSlcbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gbW9kZWxDbGFzc0F0UGF0aCh7bW9kZWxDbGFzcywgcGF0aDogcmVzb2x2ZWRQYXRoLnBhdGh9KVxuICAgIGNvbnN0IGF0dHJpYnV0ZU5hbWUgPSByZXNvbHZlQXR0cmlidXRlTmFtZSh7bW9kZWxDbGFzczogdGFyZ2V0TW9kZWxDbGFzcywgdmFsdWU6IHJlc29sdmVkUGF0aC5hdHRyaWJ1dGVWYWx1ZX0pXG5cbiAgICBpZiAoIWF0dHJpYnV0ZU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biByYW5zYWNrIGF0dHJpYnV0ZSBcIiR7cmVzb2x2ZWRQYXRoLmF0dHJpYnV0ZVZhbHVlfVwiIGZvciAke3RhcmdldE1vZGVsQ2xhc3MubmFtZX1gKVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBhdHRyaWJ1dGVOYW1lLFxuICAgICAgcGF0aDogcmVzb2x2ZWRQYXRoLnBhdGhcbiAgICB9XG4gIH0pXG59XG5cbi8qKlxuICogUnVucyBtb2RlbCBjbGFzcyBhdCBwYXRoLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gUm9vdCBtb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MucGF0aCAtIFJlbGF0aW9uc2hpcCBwYXRoLlxuICogQHJldHVybnMge1JhbnNhY2tNb2RlbENsYXNzfSAtIFRhcmdldCBtb2RlbCBjbGFzcy5cbiAqL1xuZnVuY3Rpb24gbW9kZWxDbGFzc0F0UGF0aCh7bW9kZWxDbGFzcywgcGF0aH0pIHtcbiAgbGV0IGN1cnJlbnRNb2RlbENsYXNzID0gbW9kZWxDbGFzc1xuXG4gIGZvciAoY29uc3QgcmVsYXRpb25zaGlwTmFtZSBvZiBwYXRoKSB7XG4gICAgY29uc3QgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwRW50cmllcyhjdXJyZW50TW9kZWxDbGFzcylbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgIGlmICghcmVsYXRpb25zaGlwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcmFuc2FjayByZWxhdGlvbnNoaXAgXCIke3JlbGF0aW9uc2hpcE5hbWV9XCIgZm9yICR7Y3VycmVudE1vZGVsQ2xhc3MubmFtZX1gKVxuICAgIH1cblxuICAgIGN1cnJlbnRNb2RlbENsYXNzID0gcmVsYXRpb25zaGlwLnRhcmdldE1vZGVsQ2xhc3NcbiAgfVxuXG4gIHJldHVybiBjdXJyZW50TW9kZWxDbGFzc1xufVxuXG4vKipcbiAqIFJ1bnMgcmVzb2x2ZSByYW5zYWNrIHBhdGguXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBhcmdzLm1vZGVsQ2xhc3MgLSBDdXJyZW50IG1vZGVsIGNsYXNzLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudmFsdWUgLSBSZW1haW5pbmcgcGF0aCB2YWx1ZS5cbiAqIEByZXR1cm5zIHt7YXR0cmlidXRlVmFsdWU6IHN0cmluZywgcGF0aDogc3RyaW5nW119fSAtIFJlc29sdmVkIHJlbGF0aW9uc2hpcCBwYXRoIGFuZCByZW1haW5pbmcgYXR0cmlidXRlIHZhbHVlLlxuICovXG5mdW5jdGlvbiByZXNvbHZlUmFuc2Fja1BhdGgoe21vZGVsQ2xhc3MsIHZhbHVlfSkge1xuICAvKipcbiAgICogUGF0aC5cbiAgICBAdHlwZSB7c3RyaW5nW119ICovXG4gIGNvbnN0IHBhdGggPSBbXVxuICBsZXQgY3VycmVudE1vZGVsQ2xhc3MgPSBtb2RlbENsYXNzXG4gIGxldCByZW1haW5pbmdWYWx1ZSA9IHZhbHVlXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAocmVzb2x2ZUF0dHJpYnV0ZU5hbWUoe21vZGVsQ2xhc3M6IGN1cnJlbnRNb2RlbENsYXNzLCB2YWx1ZTogcmVtYWluaW5nVmFsdWV9KSkge1xuICAgICAgYnJlYWtcbiAgICB9XG5cbiAgICBjb25zdCBtYXRjaCA9IGZpbmRSZWxhdGlvbnNoaXBQcmVmaXgoe1xuICAgICAgbW9kZWxDbGFzczogY3VycmVudE1vZGVsQ2xhc3MsXG4gICAgICB2YWx1ZTogcmVtYWluaW5nVmFsdWVcbiAgICB9KVxuXG4gICAgaWYgKCFtYXRjaCkgYnJlYWtcblxuICAgIHBhdGgucHVzaChtYXRjaC5yZWxhdGlvbnNoaXBOYW1lKVxuICAgIGN1cnJlbnRNb2RlbENsYXNzID0gbWF0Y2gudGFyZ2V0TW9kZWxDbGFzc1xuICAgIHJlbWFpbmluZ1ZhbHVlID0gbWF0Y2gucmVtYWluaW5nVmFsdWVcbiAgfVxuXG4gIGlmIChyZW1haW5pbmdWYWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHJhbnNhY2sga2V5IHBhdGg6ICR7dmFsdWV9YClcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYXR0cmlidXRlVmFsdWU6IHJlbWFpbmluZ1ZhbHVlLFxuICAgIHBhdGhcbiAgfVxufVxuXG4vKipcbiAqIFJ1bnMgZmluZCByZWxhdGlvbnNoaXAgcHJlZml4LlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gQ3VycmVudCBtb2RlbCBjbGFzcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnZhbHVlIC0gUmVtYWluaW5nIHZhbHVlIHRvIG1hdGNoLlxuICogQHJldHVybnMge3tyZWxhdGlvbnNoaXBOYW1lOiBzdHJpbmcsIHJlbWFpbmluZ1ZhbHVlOiBzdHJpbmcsIHRhcmdldE1vZGVsQ2xhc3M6IFJhbnNhY2tNb2RlbENsYXNzfSB8IG51bGx9IC0gTWF0Y2hpbmcgcmVsYXRpb25zaGlwIHByZWZpeC5cbiAqL1xuZnVuY3Rpb24gZmluZFJlbGF0aW9uc2hpcFByZWZpeCh7bW9kZWxDbGFzcywgdmFsdWV9KSB7XG4gIGxldCBiZXN0TWF0Y2ggPSBudWxsXG5cbiAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIE9iamVjdC5rZXlzKHJlbGF0aW9uc2hpcEVudHJpZXMobW9kZWxDbGFzcykpKSB7XG4gICAgY29uc3QgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwRW50cmllcyhtb2RlbENsYXNzKVtyZWxhdGlvbnNoaXBOYW1lXVxuXG4gICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgcmVsYXRpb25zaGlwQ2FuZGlkYXRlcyhyZWxhdGlvbnNoaXBOYW1lKSkge1xuICAgICAgY29uc3QgcmVtYWluaW5nVmFsdWUgPSBzdHJpcFJlbGF0aW9uc2hpcENhbmRpZGF0ZSh2YWx1ZSwgY2FuZGlkYXRlKVxuXG4gICAgICBpZiAocmVtYWluaW5nVmFsdWUgPT09IG51bGwpIGNvbnRpbnVlXG4gICAgICBpZiAocmVtYWluaW5nVmFsdWUubGVuZ3RoIDwgMSkgY29udGludWVcbiAgICAgIGlmIChiZXN0TWF0Y2ggJiYgY2FuZGlkYXRlLmxlbmd0aCA8PSBiZXN0TWF0Y2guY2FuZGlkYXRlTGVuZ3RoKSBjb250aW51ZVxuXG4gICAgICBiZXN0TWF0Y2ggPSB7XG4gICAgICAgIGNhbmRpZGF0ZUxlbmd0aDogY2FuZGlkYXRlLmxlbmd0aCxcbiAgICAgICAgcmVsYXRpb25zaGlwTmFtZSxcbiAgICAgICAgcmVtYWluaW5nVmFsdWUsXG4gICAgICAgIHRhcmdldE1vZGVsQ2xhc3M6IHJlbGF0aW9uc2hpcC50YXJnZXRNb2RlbENsYXNzXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKCFiZXN0TWF0Y2gpIHJldHVybiBudWxsXG5cbiAgcmV0dXJuIHtcbiAgICByZWxhdGlvbnNoaXBOYW1lOiBiZXN0TWF0Y2gucmVsYXRpb25zaGlwTmFtZSxcbiAgICByZW1haW5pbmdWYWx1ZTogYmVzdE1hdGNoLnJlbWFpbmluZ1ZhbHVlLFxuICAgIHRhcmdldE1vZGVsQ2xhc3M6IGJlc3RNYXRjaC50YXJnZXRNb2RlbENsYXNzXG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBwb3J0aW9uIG9mIGB2YWx1ZWAgYWZ0ZXIgYGNhbmRpZGF0ZWAgd2hlbiBgY2FuZGlkYXRlYFxuICogc2l0cyBhdCBhIHJlbGF0aW9uc2hpcC1wYXRoIGJvdW5kYXJ5LCBvciBudWxsIHdoZW4gdGhlcmUncyBub1xuICogYm91bmRhcnkgbWF0Y2guIFR3byBib3VuZGFyeSBmb3JtcyBhcmUgYWNjZXB0ZWQ6XG4gKiAtIHNuYWtlOiBgPGNhbmRpZGF0ZT5fYCBmb2xsb3dlZCBieSB0aGUgcmVzdCBvZiB0aGUgcGF0aCAoZS5nLlxuICogICBgdGFza19wcm9qZWN0X2lkYCBhZ2FpbnN0IGNhbmRpZGF0ZSBgdGFza2AgcmV0dXJucyBgcHJvamVjdF9pZGApLlxuICogLSBjYW1lbDogYDxjYW5kaWRhdGU+YCBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBhbiB1cHBlcmNhc2UgbGV0dGVyLFxuICogICB3aGljaCBtYXJrcyBhIG5ldyB3b3JkIGluIGNhbWVsQ2FzZSAoZS5nLiBgdGFza1Byb2plY3RJZGAgYWdhaW5zdFxuICogICBjYW5kaWRhdGUgYHRhc2tgIHJldHVybnMgYHByb2plY3RJZGAgd2l0aCB0aGUgbGVhZGluZyBgUGBcbiAqICAgbG93ZXJjYXNlZCBzbyB0aGUgcmVtYWluZGVyIHN0YXlzIGluIGNhbGxlci1mb3JtIGZvciB0aGUgbmV4dFxuICogICBhdHRyaWJ1dGUgLyByZWxhdGlvbnNoaXAgbWF0Y2gpLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gUmVtYWluaW5nIHJhbnNhY2sgcGF0aC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjYW5kaWRhdGUgLSBSZWxhdGlvbnNoaXAgbmFtZSBjYW5kaWRhdGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH0gLSBSZW1haW5kZXIgYWZ0ZXIgdGhlIGNhbmRpZGF0ZSwgb3IgbnVsbC5cbiAqL1xuZnVuY3Rpb24gc3RyaXBSZWxhdGlvbnNoaXBDYW5kaWRhdGUodmFsdWUsIGNhbmRpZGF0ZSkge1xuICBpZiAodmFsdWUuc3RhcnRzV2l0aChgJHtjYW5kaWRhdGV9X2ApKSB7XG4gICAgcmV0dXJuIHZhbHVlLnNsaWNlKGNhbmRpZGF0ZS5sZW5ndGggKyAxKVxuICB9XG5cbiAgaWYgKHZhbHVlLmxlbmd0aCA8PSBjYW5kaWRhdGUubGVuZ3RoKSByZXR1cm4gbnVsbFxuICBpZiAoIXZhbHVlLnN0YXJ0c1dpdGgoY2FuZGlkYXRlKSkgcmV0dXJuIG51bGxcblxuICBjb25zdCBuZXh0Q2hhciA9IHZhbHVlLmNoYXJBdChjYW5kaWRhdGUubGVuZ3RoKVxuXG4gIGlmIChuZXh0Q2hhciA8IFwiQVwiIHx8IG5leHRDaGFyID4gXCJaXCIpIHJldHVybiBudWxsXG5cbiAgcmV0dXJuIG5leHRDaGFyLnRvTG93ZXJDYXNlKCkgKyB2YWx1ZS5zbGljZShjYW5kaWRhdGUubGVuZ3RoICsgMSlcbn1cblxuLyoqXG4gKiBSdW5zIHJlbGF0aW9uc2hpcCBjYW5kaWRhdGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IHJlbGF0aW9uc2hpcE5hbWUgLSBSZWxhdGlvbnNoaXAgbmFtZS5cbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBDYW5kaWRhdGUgdG9rZW5zIGZvciBtYXRjaGluZy5cbiAqL1xuZnVuY3Rpb24gcmVsYXRpb25zaGlwQ2FuZGlkYXRlcyhyZWxhdGlvbnNoaXBOYW1lKSB7XG4gIHJldHVybiB1bmlxdW5pemUoW3JlbGF0aW9uc2hpcE5hbWUsIGluZmxlY3Rpb24udW5kZXJzY29yZShyZWxhdGlvbnNoaXBOYW1lKV0pXG59XG5cbi8qKlxuICogUnVucyByZXNvbHZlIGF0dHJpYnV0ZSBuYW1lLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gYXJncy52YWx1ZSAtIEF0dHJpYnV0ZSBjYW5kaWRhdGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSAtIFJlc29sdmVkIGF0dHJpYnV0ZSBuYW1lLlxuICovXG5mdW5jdGlvbiByZXNvbHZlQXR0cmlidXRlTmFtZSh7bW9kZWxDbGFzcywgdmFsdWV9KSB7XG4gIGZvciAoY29uc3QgW2F0dHJpYnV0ZU5hbWUsIGNvbHVtbk5hbWVdIG9mIE9iamVjdC5lbnRyaWVzKGF0dHJpYnV0ZUVudHJpZXMobW9kZWxDbGFzcykpKSB7XG4gICAgaWYgKG1hdGNoZXNBdHRyaWJ1dGVWYWx1ZSh7YXR0cmlidXRlTmFtZSwgY29sdW1uTmFtZSwgdmFsdWV9KSkge1xuICAgICAgcmV0dXJuIGF0dHJpYnV0ZU5hbWVcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogUnVucyByZWxhdGlvbnNoaXAgZW50cmllcy5cbiAqIEBwYXJhbSB7UmFuc2Fja01vZGVsQ2xhc3N9IG1vZGVsQ2xhc3MgLSBNb2RlbCBjbGFzcy5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB7dGFyZ2V0TW9kZWxDbGFzczogUmFuc2Fja01vZGVsQ2xhc3N9Pn0gLSBSZWxhdGlvbnNoaXAgZW50cmllcyBrZXllZCBieSBuYW1lLlxuICovXG5mdW5jdGlvbiByZWxhdGlvbnNoaXBFbnRyaWVzKG1vZGVsQ2xhc3MpIHtcbiAgaWYgKHR5cGVvZiAvKipcbiAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsQ2xhc3MpLmdldFJlbGF0aW9uc2hpcHNNYXAgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHJldHVybiBiYWNrZW5kUmVsYXRpb25zaGlwRW50cmllcyhtb2RlbENsYXNzKVxuICB9XG5cbiAgaWYgKHR5cGVvZiAvKipcbiAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsQ2xhc3MpLnJlbGF0aW9uc2hpcERlZmluaXRpb25zID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICB0eXBlb2YgLyoqXG4gICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsQ2xhc3MpLnJlbGF0aW9uc2hpcE1vZGVsQ2xhc3NlcyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgcmV0dXJuIGZyb250ZW5kUmVsYXRpb25zaGlwRW50cmllcyhtb2RlbENsYXNzKVxuICB9XG5cbiAgcmV0dXJuIHt9XG59XG5cbi8qKlxuICogUnVucyBiYWNrZW5kIHJlbGF0aW9uc2hpcCBlbnRyaWVzLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gbW9kZWxDbGFzcyAtIEJhY2tlbmQgbW9kZWwgY2xhc3MuXG4gKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywge3RhcmdldE1vZGVsQ2xhc3M6IFJhbnNhY2tNb2RlbENsYXNzfT59IC0gUmVsYXRpb25zaGlwIGVudHJpZXMga2V5ZWQgYnkgbmFtZS5cbiAqL1xuZnVuY3Rpb24gYmFja2VuZFJlbGF0aW9uc2hpcEVudHJpZXMobW9kZWxDbGFzcykge1xuICAvKipcbiAgICogRW50cmllcy5cbiAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywge3RhcmdldE1vZGVsQ2xhc3M6IFJhbnNhY2tNb2RlbENsYXNzfT59ICovXG4gIGNvbnN0IGVudHJpZXMgPSB7fVxuICBjb25zdCByZWxhdGlvbnNoaXBzTWFwID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAobW9kZWxDbGFzcykuZ2V0UmVsYXRpb25zaGlwc01hcCgpXG5cbiAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIE9iamVjdC5rZXlzKHJlbGF0aW9uc2hpcHNNYXApKSB7XG4gICAgY29uc3QgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwc01hcFtyZWxhdGlvbnNoaXBOYW1lXVxuXG4gICAgaWYgKHR5cGVvZiByZWxhdGlvbnNoaXAuaXNQb2x5bW9ycGhpYyA9PT0gXCJmdW5jdGlvblwiICYmIHJlbGF0aW9uc2hpcC5pc1BvbHltb3JwaGljKCkpIGNvbnRpbnVlXG5cbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gcmVsYXRpb25zaGlwLmdldFRhcmdldE1vZGVsQ2xhc3MoKVxuXG4gICAgaWYgKCF0YXJnZXRNb2RlbENsYXNzKSBjb250aW51ZVxuXG4gICAgZW50cmllc1tyZWxhdGlvbnNoaXBOYW1lXSA9IHt0YXJnZXRNb2RlbENsYXNzfVxuICB9XG5cbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuLyoqXG4gKiBSdW5zIGZyb250ZW5kIHJlbGF0aW9uc2hpcCBlbnRyaWVzLlxuICogQHBhcmFtIHtSYW5zYWNrTW9kZWxDbGFzc30gbW9kZWxDbGFzcyAtIEZyb250ZW5kIG1vZGVsIGNsYXNzLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHt0YXJnZXRNb2RlbENsYXNzOiBSYW5zYWNrTW9kZWxDbGFzc30+fSAtIFJlbGF0aW9uc2hpcCBlbnRyaWVzIGtleWVkIGJ5IG5hbWUuXG4gKi9cbmZ1bmN0aW9uIGZyb250ZW5kUmVsYXRpb25zaGlwRW50cmllcyhtb2RlbENsYXNzKSB7XG4gIC8qKlxuICAgKiBFbnRyaWVzLlxuICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB7dGFyZ2V0TW9kZWxDbGFzczogUmFuc2Fja01vZGVsQ2xhc3N9Pn0gKi9cbiAgY29uc3QgZW50cmllcyA9IHt9XG4gIGNvbnN0IGRlZmluaXRpb25zID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5yZWxhdGlvbnNoaXBEZWZpbml0aW9ucygpXG4gIGNvbnN0IHJlbGF0aW9uc2hpcE1vZGVsQ2xhc3NlcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5yZWxhdGlvbnNoaXBNb2RlbENsYXNzZXMoKVxuXG4gIGZvciAoY29uc3QgcmVsYXRpb25zaGlwTmFtZSBvZiBPYmplY3Qua2V5cyhkZWZpbml0aW9ucykpIHtcbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gcmVzb2x2ZUZyb250ZW5kTW9kZWxDbGFzcyhyZWxhdGlvbnNoaXBNb2RlbENsYXNzZXNbcmVsYXRpb25zaGlwTmFtZV0pXG5cbiAgICBpZiAoIXRhcmdldE1vZGVsQ2xhc3MpIGNvbnRpbnVlXG5cbiAgICBlbnRyaWVzW3JlbGF0aW9uc2hpcE5hbWVdID0ge3RhcmdldE1vZGVsQ2xhc3N9XG4gIH1cblxuICByZXR1cm4gZW50cmllc1xufVxuXG4vKipcbiAqIFJ1bnMgYXR0cmlidXRlIGVudHJpZXMuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MuXG4gKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgc3RyaW5nPn0gLSBBdHRyaWJ1dGUtdG8tY29sdW1uIGVudHJpZXMga2V5ZWQgYnkgYXR0cmlidXRlIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIGF0dHJpYnV0ZUVudHJpZXMobW9kZWxDbGFzcykge1xuICBpZiAodHlwZW9mIC8qKlxuICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAobW9kZWxDbGFzcykuZ2V0QXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgcmV0dXJuIC8qKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+fSAqLyAoKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUgez99ICovIChtb2RlbENsYXNzKS5nZXRBdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwKCkpKVxuICB9XG5cbiAgY29uc3QgcmVzb3VyY2VDb25maWcgPSB0eXBlb2YgLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsQ2xhc3MpLnJlc291cmNlQ29uZmlnID09PSBcImZ1bmN0aW9uXCJcbiAgICA/IC8qKlxuICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsQ2xhc3MpLnJlc291cmNlQ29uZmlnKClcbiAgICA6IHt9XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSByZXNvdXJjZUNvbmZpZy5hdHRyaWJ1dGVzXG4gIC8qKlxuICAgKiBFbnRyaWVzLlxuICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+fSAqL1xuICBjb25zdCBlbnRyaWVzID0ge31cblxuICBpZiAoQXJyYXkuaXNBcnJheShhdHRyaWJ1dGVzKSkge1xuICAgIGZvciAoY29uc3QgYXR0cmlidXRlTmFtZSBvZiBhdHRyaWJ1dGVzKSB7XG4gICAgICBpZiAodHlwZW9mIGF0dHJpYnV0ZU5hbWUgIT09IFwic3RyaW5nXCIpIGNvbnRpbnVlXG5cbiAgICAgIGVudHJpZXNbYXR0cmlidXRlTmFtZV0gPSBhdHRyaWJ1dGVOYW1lXG4gICAgfVxuICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3QoYXR0cmlidXRlcykpIHtcbiAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZU5hbWUgb2YgT2JqZWN0LmtleXMoYXR0cmlidXRlcykpIHtcbiAgICAgIGVudHJpZXNbYXR0cmlidXRlTmFtZV0gPSBhdHRyaWJ1dGVOYW1lXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuLyoqXG4gKiBSdW5zIG1hdGNoZXMgYXR0cmlidXRlIHZhbHVlLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY29sdW1uTmFtZSAtIENvbHVtbiBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudmFsdWUgLSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBjYW5kaWRhdGUgcmVzb2x2ZXMgdG8gdGhlIGF0dHJpYnV0ZS5cbiAqL1xuZnVuY3Rpb24gbWF0Y2hlc0F0dHJpYnV0ZVZhbHVlKHthdHRyaWJ1dGVOYW1lLCBjb2x1bW5OYW1lLCB2YWx1ZX0pIHtcbiAgcmV0dXJuIHVuaXF1bml6ZShbXG4gICAgYXR0cmlidXRlTmFtZSxcbiAgICBjb2x1bW5OYW1lLFxuICAgIGluZmxlY3Rpb24udW5kZXJzY29yZShhdHRyaWJ1dGVOYW1lKSxcbiAgICBpbmZsZWN0aW9uLnVuZGVyc2NvcmUoY29sdW1uTmFtZSlcbiAgXSkuaW5jbHVkZXModmFsdWUpXG59XG5cbi8qKlxuICogUnVucyBwYXJzZSByYW5zYWNrIGtleS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBSYW5zYWNrIGtleS5cbiAqIEByZXR1cm5zIHt7cGF0aFZhbHVlOiBzdHJpbmcsIHByZWRpY2F0ZTogUmFuc2Fja1ByZWRpY2F0ZX0gfCBudWxsfSAtIFBhcnNlZCBrZXkuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUmFuc2Fja0tleShrZXkpIHtcbiAgZm9yIChjb25zdCBwcmVkaWNhdGUgb2Ygc3VwcG9ydGVkUHJlZGljYXRlcykge1xuICAgIGNvbnN0IHN1ZmZpeCA9IGBfJHtwcmVkaWNhdGV9YFxuICAgIGlmICgha2V5LmVuZHNXaXRoKHN1ZmZpeCkpIGNvbnRpbnVlXG5cbiAgICBjb25zdCBwYXRoVmFsdWUgPSBrZXkuc2xpY2UoMCwga2V5Lmxlbmd0aCAtIHN1ZmZpeC5sZW5ndGgpXG5cbiAgICBpZiAocGF0aFZhbHVlLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCByYW5zYWNrIGtleTogJHtrZXl9YClcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGF0aFZhbHVlLFxuICAgICAgcHJlZGljYXRlOiAvKipcbiAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSYW5zYWNrUHJlZGljYXRlfSAqLyAocHJlZGljYXRlKVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgcHJlZGljYXRlIG9mIHN1cHBvcnRlZFByZWRpY2F0ZXMpIHtcbiAgICBjb25zdCBjYW1lbFN1ZmZpeCA9IHNuYWtlVG9DYW1lbFN1ZmZpeChwcmVkaWNhdGUpXG5cbiAgICBpZiAoIWtleS5lbmRzV2l0aChjYW1lbFN1ZmZpeCkpIGNvbnRpbnVlXG5cbiAgICBjb25zdCBwYXRoVmFsdWUgPSBrZXkuc2xpY2UoMCwga2V5Lmxlbmd0aCAtIGNhbWVsU3VmZml4Lmxlbmd0aClcblxuICAgIGlmIChwYXRoVmFsdWUubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHJhbnNhY2sga2V5OiAke2tleX1gKVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwYXRoVmFsdWUsXG4gICAgICBwcmVkaWNhdGU6IC8qKlxuICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgQHR5cGUge1JhbnNhY2tQcmVkaWNhdGV9ICovIChwcmVkaWNhdGUpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cblxuLyoqXG4gKiBSdW5zIHNuYWtlIHRvIGNhbWVsIHN1ZmZpeC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFNuYWtlLWNhc2UgcHJlZGljYXRlLlxuICogQHJldHVybnMge3N0cmluZ30gLSBDYW1lbENhc2UgcHJlZGljYXRlIHN1ZmZpeCB1c2VkIGluIHJhbnNhY2sga2V5cy5cbiAqL1xuZnVuY3Rpb24gc25ha2VUb0NhbWVsU3VmZml4KHZhbHVlKSB7XG4gIGNvbnN0IHNlZ21lbnRzID0gdmFsdWUuc3BsaXQoXCJfXCIpXG5cbiAgcmV0dXJuIHNlZ21lbnRzLm1hcCgoc2VnbWVudCkgPT4gc2VnbWVudC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHNlZ21lbnQuc2xpY2UoMSkpLmpvaW4oXCJcIilcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSByYW5zYWNrIHZhbHVlLlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICogQHBhcmFtIHtSYW5zYWNrUHJlZGljYXRlfSBhcmdzLnByZWRpY2F0ZSAtIFBhcnNlZCBwcmVkaWNhdGUuXG4gKiBAcGFyYW0gez99IGFyZ3MudmFsdWUgLSBSYXcgdmFsdWUuXG4gKiBAcmV0dXJucyB7P30gLSBOb3JtYWxpemVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrVmFsdWUoe3ByZWRpY2F0ZSwgdmFsdWV9KSB7XG4gIGlmIChwcmVkaWNhdGUgPT09IFwibnVsbFwiKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZVJhbnNhY2tOdWxsVmFsdWUodmFsdWUpXG4gIH1cblxuICBpZiAocHJlZGljYXRlID09PSBcImluXCIgfHwgcHJlZGljYXRlID09PSBcIm5vdF9pblwiKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZVJhbnNhY2tMaXN0VmFsdWUodmFsdWUpXG4gIH1cblxuICBpZiAocmFuc2Fja1ZhbHVlSXNCbGFuayh2YWx1ZSkpIHJldHVybiBTS0lQX1JBTlNBQ0tfQ09ORElUSU9OXG5cbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgcmFuc2FjayBudWxsIHZhbHVlLlxuICogQHBhcmFtIHs/fSB2YWx1ZSAtIENhbmRpZGF0ZSBudWxsIHByZWRpY2F0ZSB2YWx1ZS5cbiAqIEByZXR1cm5zIHtib29sZWFuIHwgdHlwZW9mIFNLSVBfUkFOU0FDS19DT05ESVRJT059IC0gTm9ybWFsaXplZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplUmFuc2Fja051bGxWYWx1ZSh2YWx1ZSkge1xuICBjb25zdCBib29sZWFuVmFsdWUgPSBub3JtYWxpemVSYW5zYWNrQm9vbGVhbih2YWx1ZSlcblxuICByZXR1cm4gYm9vbGVhblZhbHVlID09PSBudWxsID8gU0tJUF9SQU5TQUNLX0NPTkRJVElPTiA6IGJvb2xlYW5WYWx1ZVxufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIHJhbnNhY2sgbGlzdCB2YWx1ZS5cbiAqIEBwYXJhbSB7P30gdmFsdWUgLSBDYW5kaWRhdGUgbGlzdCBwcmVkaWNhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyB7QXJyYXk8Pz4gfCB0eXBlb2YgU0tJUF9SQU5TQUNLX0NPTkRJVElPTn0gLSBOb3JtYWxpemVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSYW5zYWNrTGlzdFZhbHVlKHZhbHVlKSB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRBcnJheSA9IG5vcm1hbGl6ZVJhbnNhY2tBcnJheSh2YWx1ZSlcblxuICByZXR1cm4gbm9ybWFsaXplZEFycmF5Lmxlbmd0aCA8IDEgPyBTS0lQX1JBTlNBQ0tfQ09ORElUSU9OIDogbm9ybWFsaXplZEFycmF5XG59XG5cbi8qKlxuICogUmFuc2FjayB0cnVlIHZhbHVlcy5cbiAgQHR5cGUge1NldDw/Pn0gKi9cbmNvbnN0IHJhbnNhY2tUcnVlVmFsdWVzID0gbmV3IFNldChbdHJ1ZSwgMSwgXCIxXCIsIFwidHJ1ZVwiXSlcbi8qKlxuICogUmFuc2FjayBmYWxzZSB2YWx1ZXMuXG4gIEB0eXBlIHtTZXQ8Pz59ICovXG5jb25zdCByYW5zYWNrRmFsc2VWYWx1ZXMgPSBuZXcgU2V0KFtmYWxzZSwgMCwgXCIwXCIsIFwiZmFsc2VcIl0pXG5cbi8qKlxuICogUnVucyBub3JtYWxpemUgcmFuc2FjayBib29sZWFuLlxuICogQHBhcmFtIHs/fSB2YWx1ZSAtIENhbmRpZGF0ZSBib29sZWFuLlxuICogQHJldHVybnMge2Jvb2xlYW4gfCBudWxsfSAtIE5vcm1hbGl6ZWQgYm9vbGVhbiBvciBudWxsIHdoZW4gYmxhbmsuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJhbnNhY2tCb29sZWFuKHZhbHVlKSB7XG4gIGlmIChyYW5zYWNrVHJ1ZVZhbHVlcy5oYXModmFsdWUpKSByZXR1cm4gdHJ1ZVxuICBpZiAocmFuc2Fja0ZhbHNlVmFsdWVzLmhhcyh2YWx1ZSkpIHJldHVybiBmYWxzZVxuICBpZiAocmFuc2Fja1ZhbHVlSXNCbGFuayh2YWx1ZSkpIHJldHVybiBudWxsXG5cbiAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHJhbnNhY2sgYm9vbGVhbiB2YWx1ZTogJHtTdHJpbmcodmFsdWUpfWApXG59XG5cbi8qKlxuICogUnVucyByYW5zYWNrIHZhbHVlIGlzIGJsYW5rLlxuICogQHBhcmFtIHs/fSB2YWx1ZSAtIENhbmRpZGF0ZSB2YWx1ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdmFsdWUgc2hvdWxkIGJlIGlnbm9yZWQgYXMgYmxhbmsuXG4gKi9cbmZ1bmN0aW9uIHJhbnNhY2tWYWx1ZUlzQmxhbmsodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCJcbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSByYW5zYWNrIGFycmF5LlxuICogQHBhcmFtIHs/fSB2YWx1ZSAtIENhbmRpZGF0ZSBhcnJheS1pc2ggdmFsdWUuXG4gKiBAcmV0dXJucyB7QXJyYXk8Pz59IC0gTm9ybWFsaXplZCBhcnJheSB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJhbnNhY2tBcnJheSh2YWx1ZSkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWUuZmlsdGVyKChlbnRyeSkgPT4gZW50cnkgIT09IHVuZGVmaW5lZCAmJiBlbnRyeSAhPT0gbnVsbCAmJiBlbnRyeSAhPT0gXCJcIilcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gdmFsdWUuc3BsaXQoXCIsXCIpLm1hcCgoZW50cnkpID0+IGVudHJ5LnRyaW0oKSkuZmlsdGVyKChlbnRyeSkgPT4gZW50cnkubGVuZ3RoID4gMClcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSBcIlwiKSByZXR1cm4gW11cblxuICByZXR1cm4gW3ZhbHVlXVxufVxuXG4vKipcbiAqIFJhbnNhY2tTb3J0IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBSYW5zYWNrU29ydFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGF0dHJpYnV0ZSAtIFJlc29sdmVkIGF0dHJpYnV0ZSBuYW1lLlxuICogQHByb3BlcnR5IHtcImFzY1wiIHwgXCJkZXNjXCJ9IGRpcmVjdGlvbiAtIFNvcnQgZGlyZWN0aW9uLlxuICovXG5cbi8qKlxuICogUGFyc2VzIGFuZCB2YWxpZGF0ZXMgYSByYW5zYWNrIGBzYCBzb3J0IHN0cmluZyBhZ2FpbnN0IG1vZGVsIGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0ge1JhbnNhY2tNb2RlbENsYXNzfSBtb2RlbENsYXNzIC0gTW9kZWwgY2xhc3MgZm9yIGF0dHJpYnV0ZSB2YWxpZGF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvcnRTdHJpbmcgLSBSYW5zYWNrIHNvcnQgc3RyaW5nIChlLmcuLCBcIm5hbWUgYXNjXCIgb3IgXCJuYW1lIGFzYywgY3JlYXRlZEF0IGRlc2NcIikuXG4gKiBAcmV0dXJucyB7UmFuc2Fja1NvcnRbXX0gLSBWYWxpZGF0ZWQgc29ydCBkZWZpbml0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmFuc2Fja1NvcnQobW9kZWxDbGFzcywgc29ydFN0cmluZykge1xuICBjb25zdCBzZWdtZW50cyA9IHNvcnRTdHJpbmcuc3BsaXQoXCIsXCIpLm1hcCgoc2VnbWVudCkgPT4gc2VnbWVudC50cmltKCkpLmZpbHRlcigoc2VnbWVudCkgPT4gc2VnbWVudC5sZW5ndGggPiAwKVxuXG4gIC8qKlxuICAgKiBTb3J0cy5cbiAgICBAdHlwZSB7UmFuc2Fja1NvcnRbXX0gKi9cbiAgY29uc3Qgc29ydHMgPSBbXVxuXG4gIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cykge1xuICAgIGNvbnN0IHBhcnRzID0gc2VnbWVudC5zcGxpdCgvXFxzKy8pXG4gICAgY29uc3QgY29sdW1uQ2FuZGlkYXRlID0gcGFydHNbMF1cbiAgICBjb25zdCBkaXJlY3Rpb25DYW5kaWRhdGUgPSBwYXJ0cy5sZW5ndGggPiAxID8gcGFydHNbMV0udG9Mb3dlckNhc2UoKSA6IFwiYXNjXCJcblxuICAgIGlmIChkaXJlY3Rpb25DYW5kaWRhdGUgIT09IFwiYXNjXCIgJiYgZGlyZWN0aW9uQ2FuZGlkYXRlICE9PSBcImRlc2NcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHJhbnNhY2sgc29ydCBkaXJlY3Rpb24gXCIke2RpcmVjdGlvbkNhbmRpZGF0ZX1cIiBpbjogJHtzZWdtZW50fWApXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRBdHRyaWJ1dGUgPSByZXNvbHZlQXR0cmlidXRlTmFtZSh7bW9kZWxDbGFzcywgdmFsdWU6IGNvbHVtbkNhbmRpZGF0ZX0pXG5cbiAgICBpZiAoIXJlc29sdmVkQXR0cmlidXRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcmFuc2FjayBzb3J0IGF0dHJpYnV0ZSBcIiR7Y29sdW1uQ2FuZGlkYXRlfVwiIGZvciAke21vZGVsQ2xhc3MubmFtZX1gKVxuICAgIH1cblxuICAgIHNvcnRzLnB1c2goe2F0dHJpYnV0ZTogcmVzb2x2ZWRBdHRyaWJ1dGUsIGRpcmVjdGlvbjogZGlyZWN0aW9uQ2FuZGlkYXRlfSlcbiAgfVxuXG4gIHJldHVybiBzb3J0c1xufVxuXG4vKipcbiAqIFJ1bnMgdW5pcXVuaXplLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gdmFsdWVzIC0gSW5wdXQgdmFsdWVzLlxuICogQHJldHVybnMge3N0cmluZ1tdfSAtIFVuaXF1ZSB2YWx1ZXMgaW4gb3JpZ2luYWwgb3JkZXIuXG4gKi9cbmZ1bmN0aW9uIHVuaXF1bml6ZSh2YWx1ZXMpIHtcbiAgcmV0dXJuIEFycmF5LmZyb20obmV3IFNldCh2YWx1ZXMpKVxufVxuIl19