@uql/core 1.0.12 → 3.1.0

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 (464) hide show
  1. package/CHANGELOG.md +254 -0
  2. package/LICENSE.md +2 -2
  3. package/dist/browser/http/bus.d.ts +3 -0
  4. package/dist/browser/http/bus.js +14 -0
  5. package/dist/browser/http/http.d.ts +6 -0
  6. package/dist/browser/http/http.js +45 -0
  7. package/dist/browser/http/index.d.ts +2 -0
  8. package/dist/browser/http/index.js +3 -0
  9. package/dist/browser/index.d.ts +4 -0
  10. package/dist/browser/index.js +5 -0
  11. package/dist/browser/options.d.ts +4 -0
  12. package/dist/browser/options.js +14 -0
  13. package/dist/browser/querier/genericClientRepository.d.ts +17 -0
  14. package/dist/browser/querier/genericClientRepository.js +39 -0
  15. package/dist/browser/querier/httpQuerier.d.ts +20 -0
  16. package/dist/browser/querier/httpQuerier.js +71 -0
  17. package/dist/browser/querier/index.d.ts +3 -0
  18. package/dist/browser/querier/index.js +4 -0
  19. package/dist/browser/querier/querier.util.d.ts +2 -0
  20. package/dist/browser/querier/querier.util.js +17 -0
  21. package/dist/browser/type/clientQuerier.d.ts +16 -0
  22. package/dist/browser/type/clientQuerier.js +2 -0
  23. package/dist/browser/type/clientQuerierPool.d.ts +4 -0
  24. package/dist/browser/type/clientQuerierPool.js +2 -0
  25. package/dist/browser/type/clientRepository.d.ts +13 -0
  26. package/dist/browser/type/clientRepository.js +2 -0
  27. package/dist/browser/type/index.d.ts +4 -0
  28. package/dist/browser/type/index.js +5 -0
  29. package/dist/browser/type/request.d.ts +28 -0
  30. package/dist/browser/type/request.js +2 -0
  31. package/dist/browser/uql-browser.min.js +2150 -0
  32. package/dist/browser/uql-browser.min.js.map +1 -0
  33. package/dist/dialect/abstractDialect.d.ts +16 -0
  34. package/dist/dialect/abstractDialect.js +28 -0
  35. package/dist/dialect/abstractSqlDialect.d.ts +47 -0
  36. package/dist/dialect/abstractSqlDialect.js +650 -0
  37. package/dist/dialect/index.d.ts +3 -0
  38. package/dist/dialect/index.js +4 -0
  39. package/dist/dialect/queryContext.d.ts +48 -0
  40. package/dist/dialect/queryContext.js +65 -0
  41. package/{entity → dist/entity}/decorator/definition.d.ts +3 -3
  42. package/dist/entity/decorator/definition.js +214 -0
  43. package/{entity → dist/entity}/decorator/entity.d.ts +1 -1
  44. package/dist/entity/decorator/entity.js +7 -0
  45. package/{entity → dist/entity}/decorator/field.d.ts +1 -1
  46. package/dist/entity/decorator/field.js +8 -0
  47. package/{entity → dist/entity}/decorator/id.d.ts +1 -1
  48. package/dist/entity/decorator/id.js +8 -0
  49. package/dist/entity/decorator/index.d.ts +5 -0
  50. package/dist/entity/decorator/index.js +6 -0
  51. package/{entity → dist/entity}/decorator/relation.d.ts +1 -1
  52. package/dist/entity/decorator/relation.js +20 -0
  53. package/dist/entity/index.d.ts +1 -0
  54. package/dist/entity/index.js +2 -0
  55. package/dist/express/index.d.ts +2 -0
  56. package/dist/express/index.js +3 -0
  57. package/dist/express/querierMiddleware.d.ts +26 -0
  58. package/dist/express/querierMiddleware.js +190 -0
  59. package/dist/express/query.util.d.ts +2 -0
  60. package/dist/express/query.util.js +19 -0
  61. package/dist/index.d.ts +9 -0
  62. package/dist/index.js +10 -0
  63. package/dist/maria/index.d.ts +3 -0
  64. package/dist/maria/index.js +4 -0
  65. package/dist/maria/mariaDialect.d.ts +8 -0
  66. package/dist/maria/mariaDialect.js +38 -0
  67. package/dist/maria/mariaQuerierPool.test.d.ts +5 -0
  68. package/dist/maria/mariaQuerierPool.test.js +19 -0
  69. package/dist/maria/mariadbQuerier.d.ts +17 -0
  70. package/dist/maria/mariadbQuerier.js +39 -0
  71. package/dist/maria/mariadbQuerier.test.d.ts +4 -0
  72. package/dist/maria/mariadbQuerier.test.js +19 -0
  73. package/dist/maria/mariadbQuerierPool.d.ts +10 -0
  74. package/dist/maria/mariadbQuerierPool.js +17 -0
  75. package/dist/migrate/cli.d.ts +2 -0
  76. package/dist/migrate/cli.js +254 -0
  77. package/dist/migrate/generator/index.d.ts +4 -0
  78. package/dist/migrate/generator/index.js +5 -0
  79. package/dist/migrate/generator/mongoSchemaGenerator.d.ts +12 -0
  80. package/dist/migrate/generator/mongoSchemaGenerator.js +100 -0
  81. package/dist/migrate/generator/mysqlSchemaGenerator.d.ts +14 -0
  82. package/dist/migrate/generator/mysqlSchemaGenerator.js +81 -0
  83. package/dist/migrate/generator/postgresSchemaGenerator.d.ts +18 -0
  84. package/dist/migrate/generator/postgresSchemaGenerator.js +111 -0
  85. package/dist/migrate/generator/sqliteSchemaGenerator.d.ts +14 -0
  86. package/dist/migrate/generator/sqliteSchemaGenerator.js +68 -0
  87. package/dist/migrate/index.d.ts +12 -0
  88. package/dist/migrate/index.js +17 -0
  89. package/dist/migrate/introspection/index.d.ts +4 -0
  90. package/dist/migrate/introspection/index.js +5 -0
  91. package/dist/migrate/introspection/mongoIntrospector.d.ts +8 -0
  92. package/dist/migrate/introspection/mongoIntrospector.js +46 -0
  93. package/dist/migrate/introspection/mysqlIntrospector.d.ts +25 -0
  94. package/dist/migrate/introspection/mysqlIntrospector.js +220 -0
  95. package/dist/migrate/introspection/postgresIntrospector.d.ts +21 -0
  96. package/dist/migrate/introspection/postgresIntrospector.js +269 -0
  97. package/dist/migrate/introspection/sqliteIntrospector.d.ts +23 -0
  98. package/dist/migrate/introspection/sqliteIntrospector.js +212 -0
  99. package/dist/migrate/migrator-mongo.test.d.ts +1 -0
  100. package/dist/migrate/migrator-mongo.test.js +54 -0
  101. package/dist/migrate/migrator.d.ts +133 -0
  102. package/dist/migrate/migrator.js +600 -0
  103. package/dist/migrate/migrator.test.d.ts +1 -0
  104. package/dist/migrate/migrator.test.js +106 -0
  105. package/dist/migrate/schemaGenerator.d.ts +78 -0
  106. package/dist/migrate/schemaGenerator.js +363 -0
  107. package/dist/migrate/storage/databaseStorage.d.ts +24 -0
  108. package/dist/migrate/storage/databaseStorage.js +77 -0
  109. package/dist/migrate/storage/index.d.ts +2 -0
  110. package/dist/migrate/storage/index.js +3 -0
  111. package/dist/migrate/storage/jsonStorage.d.ts +15 -0
  112. package/dist/migrate/storage/jsonStorage.js +51 -0
  113. package/dist/migrate/type.d.ts +1 -0
  114. package/dist/migrate/type.js +2 -0
  115. package/dist/mongo/index.d.ts +3 -0
  116. package/dist/mongo/index.js +4 -0
  117. package/dist/mongo/mongoDialect.d.ts +34 -0
  118. package/dist/mongo/mongoDialect.js +163 -0
  119. package/dist/mongo/mongodbQuerier.d.ts +28 -0
  120. package/dist/mongo/mongodbQuerier.js +204 -0
  121. package/dist/mongo/mongodbQuerier.test.d.ts +1 -0
  122. package/dist/mongo/mongodbQuerier.test.js +36 -0
  123. package/dist/mongo/mongodbQuerierPool.d.ts +10 -0
  124. package/dist/mongo/mongodbQuerierPool.js +20 -0
  125. package/dist/mongo/mongodbQuerierPool.test.d.ts +1 -0
  126. package/dist/mongo/mongodbQuerierPool.test.js +21 -0
  127. package/dist/mysql/index.d.ts +3 -0
  128. package/dist/mysql/index.js +4 -0
  129. package/dist/mysql/mysql2Querier.d.ts +17 -0
  130. package/dist/mysql/mysql2Querier.js +43 -0
  131. package/dist/mysql/mysql2Querier.test.d.ts +4 -0
  132. package/dist/mysql/mysql2Querier.test.js +16 -0
  133. package/dist/mysql/mysql2QuerierPool.d.ts +10 -0
  134. package/dist/mysql/mysql2QuerierPool.js +17 -0
  135. package/dist/mysql/mysql2QuerierPool.test.d.ts +5 -0
  136. package/dist/mysql/mysql2QuerierPool.test.js +16 -0
  137. package/dist/mysql/mysqlDialect.d.ts +5 -0
  138. package/dist/mysql/mysqlDialect.js +15 -0
  139. package/dist/namingStrategy/defaultNamingStrategy.d.ts +9 -0
  140. package/dist/namingStrategy/defaultNamingStrategy.js +15 -0
  141. package/dist/namingStrategy/index.d.ts +2 -0
  142. package/dist/namingStrategy/index.js +3 -0
  143. package/dist/namingStrategy/snakeCaseNamingStrategy.d.ts +8 -0
  144. package/dist/namingStrategy/snakeCaseNamingStrategy.js +14 -0
  145. package/{options.d.ts → dist/options.d.ts} +1 -1
  146. package/dist/options.js +14 -0
  147. package/dist/package.json +131 -0
  148. package/dist/postgres/index.d.ts +3 -0
  149. package/dist/postgres/index.js +4 -0
  150. package/dist/postgres/pgQuerier.d.ts +17 -0
  151. package/dist/postgres/pgQuerier.js +39 -0
  152. package/dist/postgres/pgQuerier.test.d.ts +4 -0
  153. package/dist/postgres/pgQuerier.test.js +20 -0
  154. package/dist/postgres/pgQuerierPool.d.ts +10 -0
  155. package/dist/postgres/pgQuerierPool.js +17 -0
  156. package/dist/postgres/pgQuerierPool.test.d.ts +5 -0
  157. package/dist/postgres/pgQuerierPool.test.js +23 -0
  158. package/dist/postgres/postgresDialect.d.ts +13 -0
  159. package/dist/postgres/postgresDialect.js +110 -0
  160. package/dist/querier/abstractQuerier-test.d.ts +45 -0
  161. package/dist/querier/abstractQuerier-test.js +461 -0
  162. package/dist/querier/abstractQuerier.d.ts +50 -0
  163. package/dist/querier/abstractQuerier.js +278 -0
  164. package/dist/querier/abstractQuerierPool-test.d.ts +9 -0
  165. package/dist/querier/abstractQuerierPool-test.js +18 -0
  166. package/dist/querier/abstractQuerierPool.d.ts +14 -0
  167. package/dist/querier/abstractQuerierPool.js +9 -0
  168. package/dist/querier/abstractSqlQuerier-test.d.ts +9 -0
  169. package/dist/querier/abstractSqlQuerier-test.js +16 -0
  170. package/dist/querier/abstractSqlQuerier.d.ts +28 -0
  171. package/dist/querier/abstractSqlQuerier.js +133 -0
  172. package/dist/querier/decorator/index.d.ts +3 -0
  173. package/dist/querier/decorator/index.js +4 -0
  174. package/dist/querier/decorator/injectQuerier.d.ts +3 -0
  175. package/dist/querier/decorator/injectQuerier.js +33 -0
  176. package/dist/querier/decorator/serialized.d.ts +6 -0
  177. package/dist/querier/decorator/serialized.js +14 -0
  178. package/{querier → dist/querier}/decorator/transactional.d.ts +1 -1
  179. package/dist/querier/decorator/transactional.js +48 -0
  180. package/dist/querier/index.d.ts +4 -0
  181. package/dist/querier/index.js +5 -0
  182. package/dist/repository/genericRepository.d.ts +20 -0
  183. package/dist/repository/genericRepository.js +51 -0
  184. package/dist/repository/index.d.ts +1 -0
  185. package/dist/repository/index.js +2 -0
  186. package/dist/sqlite/index.d.ts +3 -0
  187. package/dist/sqlite/index.js +4 -0
  188. package/dist/sqlite/sqliteDialect.d.ts +10 -0
  189. package/dist/sqlite/sqliteDialect.js +48 -0
  190. package/dist/sqlite/sqliteQuerier.d.ts +15 -0
  191. package/dist/sqlite/sqliteQuerier.js +33 -0
  192. package/dist/sqlite/sqliteQuerier.test.d.ts +5 -0
  193. package/dist/sqlite/sqliteQuerier.test.js +19 -0
  194. package/dist/sqlite/sqliteQuerierPool.d.ts +14 -0
  195. package/dist/sqlite/sqliteQuerierPool.js +34 -0
  196. package/dist/sqlite/sqliteQuerierPool.test.d.ts +5 -0
  197. package/dist/sqlite/sqliteQuerierPool.test.js +10 -0
  198. package/dist/test/entityMock.d.ts +164 -0
  199. package/dist/test/entityMock.js +554 -0
  200. package/dist/test/index.d.ts +3 -0
  201. package/dist/test/index.js +4 -0
  202. package/dist/test/it.util.d.ts +4 -0
  203. package/dist/test/it.util.js +55 -0
  204. package/dist/test/spec.util.d.ts +14 -0
  205. package/dist/test/spec.util.js +50 -0
  206. package/{type → dist/type}/entity.d.ts +97 -4
  207. package/dist/type/entity.js +5 -0
  208. package/dist/type/index.d.ts +9 -0
  209. package/dist/type/index.js +10 -0
  210. package/dist/type/migration.d.ts +213 -0
  211. package/dist/type/migration.js +2 -0
  212. package/dist/type/namingStrategy.d.ts +17 -0
  213. package/dist/type/namingStrategy.js +2 -0
  214. package/dist/type/querier.d.ts +96 -0
  215. package/dist/type/querier.js +11 -0
  216. package/{type → dist/type}/querierPool.d.ts +7 -3
  217. package/dist/type/querierPool.js +2 -0
  218. package/{type → dist/type}/query.d.ts +170 -108
  219. package/dist/type/query.js +9 -0
  220. package/{type → dist/type}/repository.d.ts +42 -35
  221. package/dist/type/repository.js +2 -0
  222. package/{type → dist/type}/universalQuerier.d.ts +50 -28
  223. package/dist/type/universalQuerier.js +2 -0
  224. package/dist/type/utility.d.ts +13 -0
  225. package/dist/type/utility.js +2 -0
  226. package/dist/util/dialect.util.d.ts +12 -0
  227. package/dist/util/dialect.util.js +93 -0
  228. package/dist/util/index.d.ts +5 -0
  229. package/dist/util/index.js +6 -0
  230. package/dist/util/object.util.d.ts +7 -0
  231. package/dist/util/object.util.js +19 -0
  232. package/dist/util/raw.d.ts +8 -0
  233. package/dist/util/raw.js +11 -0
  234. package/dist/util/sql.util.d.ts +13 -0
  235. package/dist/util/sql.util.js +78 -0
  236. package/{util → dist/util}/string.util.d.ts +1 -0
  237. package/dist/util/string.util.js +34 -0
  238. package/package.json +85 -17
  239. package/src/@types/index.d.ts +1 -0
  240. package/src/@types/jest.d.ts +6 -0
  241. package/src/browser/http/bus.spec.ts +22 -0
  242. package/src/browser/http/bus.ts +17 -0
  243. package/src/browser/http/http.spec.ts +70 -0
  244. package/src/browser/http/http.ts +55 -0
  245. package/src/browser/http/index.ts +2 -0
  246. package/src/browser/index.ts +4 -0
  247. package/src/browser/options.spec.ts +37 -0
  248. package/src/browser/options.ts +18 -0
  249. package/src/browser/querier/genericClientRepository.spec.ts +105 -0
  250. package/src/browser/querier/genericClientRepository.ts +49 -0
  251. package/src/browser/querier/httpQuerier.ts +82 -0
  252. package/src/browser/querier/index.ts +3 -0
  253. package/src/browser/querier/querier.util.spec.ts +35 -0
  254. package/src/browser/querier/querier.util.ts +18 -0
  255. package/src/browser/type/clientQuerier.ts +45 -0
  256. package/src/browser/type/clientQuerierPool.ts +5 -0
  257. package/src/browser/type/clientRepository.ts +22 -0
  258. package/src/browser/type/index.ts +4 -0
  259. package/src/browser/type/request.ts +25 -0
  260. package/src/dialect/abstractDialect.ts +28 -0
  261. package/src/dialect/abstractSqlDialect-spec.ts +1309 -0
  262. package/src/dialect/abstractSqlDialect.ts +805 -0
  263. package/src/dialect/index.ts +3 -0
  264. package/src/dialect/namingStrategy.spec.ts +52 -0
  265. package/src/dialect/queryContext.ts +69 -0
  266. package/src/entity/decorator/definition.spec.ts +736 -0
  267. package/src/entity/decorator/definition.ts +265 -0
  268. package/src/entity/decorator/entity.ts +8 -0
  269. package/src/entity/decorator/field.ts +9 -0
  270. package/src/entity/decorator/id.ts +9 -0
  271. package/src/entity/decorator/index.ts +5 -0
  272. package/src/entity/decorator/relation.spec.ts +41 -0
  273. package/src/entity/decorator/relation.ts +34 -0
  274. package/src/entity/index.ts +1 -0
  275. package/src/express/@types/express.d.ts +8 -0
  276. package/src/express/@types/index.d.ts +1 -0
  277. package/src/express/index.ts +2 -0
  278. package/src/express/querierMiddleware.ts +217 -0
  279. package/src/express/query.util.spec.ts +40 -0
  280. package/src/express/query.util.ts +21 -0
  281. package/src/index.ts +9 -0
  282. package/src/maria/index.ts +3 -0
  283. package/src/maria/mariaDialect.spec.ts +207 -0
  284. package/src/maria/mariaDialect.ts +42 -0
  285. package/src/maria/mariaQuerierPool.test.ts +23 -0
  286. package/src/maria/mariadbQuerier.test.ts +23 -0
  287. package/src/maria/mariadbQuerier.ts +45 -0
  288. package/src/maria/mariadbQuerierPool.ts +21 -0
  289. package/src/migrate/cli.ts +301 -0
  290. package/src/migrate/generator/index.ts +4 -0
  291. package/src/migrate/generator/mongoSchemaGenerator.spec.ts +112 -0
  292. package/src/migrate/generator/mongoSchemaGenerator.ts +115 -0
  293. package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +34 -0
  294. package/src/migrate/generator/mysqlSchemaGenerator.ts +92 -0
  295. package/src/migrate/generator/postgresSchemaGenerator.spec.ts +44 -0
  296. package/src/migrate/generator/postgresSchemaGenerator.ts +127 -0
  297. package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +33 -0
  298. package/src/migrate/generator/sqliteSchemaGenerator.ts +81 -0
  299. package/src/migrate/index.ts +41 -0
  300. package/src/migrate/introspection/index.ts +4 -0
  301. package/src/migrate/introspection/mongoIntrospector.spec.ts +75 -0
  302. package/src/migrate/introspection/mongoIntrospector.ts +47 -0
  303. package/src/migrate/introspection/mysqlIntrospector.spec.ts +113 -0
  304. package/src/migrate/introspection/mysqlIntrospector.ts +278 -0
  305. package/src/migrate/introspection/postgresIntrospector.spec.ts +112 -0
  306. package/src/migrate/introspection/postgresIntrospector.ts +329 -0
  307. package/src/migrate/introspection/sqliteIntrospector.spec.ts +112 -0
  308. package/src/migrate/introspection/sqliteIntrospector.ts +296 -0
  309. package/src/migrate/migrator-mongo.test.ts +54 -0
  310. package/src/migrate/migrator.spec.ts +255 -0
  311. package/src/migrate/migrator.test.ts +94 -0
  312. package/src/migrate/migrator.ts +719 -0
  313. package/src/migrate/namingStrategy.spec.ts +22 -0
  314. package/src/migrate/schemaGenerator-advanced.spec.ts +138 -0
  315. package/src/migrate/schemaGenerator.spec.ts +190 -0
  316. package/src/migrate/schemaGenerator.ts +478 -0
  317. package/src/migrate/storage/databaseStorage.spec.ts +69 -0
  318. package/src/migrate/storage/databaseStorage.ts +100 -0
  319. package/src/migrate/storage/index.ts +2 -0
  320. package/src/migrate/storage/jsonStorage.ts +58 -0
  321. package/src/migrate/type.ts +1 -0
  322. package/src/mongo/index.ts +3 -0
  323. package/src/mongo/mongoDialect.spec.ts +251 -0
  324. package/src/mongo/mongoDialect.ts +238 -0
  325. package/src/mongo/mongodbQuerier.test.ts +45 -0
  326. package/src/mongo/mongodbQuerier.ts +256 -0
  327. package/src/mongo/mongodbQuerierPool.test.ts +25 -0
  328. package/src/mongo/mongodbQuerierPool.ts +24 -0
  329. package/src/mysql/index.ts +3 -0
  330. package/src/mysql/mysql2Querier.test.ts +20 -0
  331. package/src/mysql/mysql2Querier.ts +49 -0
  332. package/src/mysql/mysql2QuerierPool.test.ts +20 -0
  333. package/src/mysql/mysql2QuerierPool.ts +21 -0
  334. package/src/mysql/mysqlDialect.spec.ts +20 -0
  335. package/src/mysql/mysqlDialect.ts +16 -0
  336. package/src/namingStrategy/defaultNamingStrategy.ts +18 -0
  337. package/src/namingStrategy/index.spec.ts +36 -0
  338. package/src/namingStrategy/index.ts +2 -0
  339. package/src/namingStrategy/snakeCaseNamingStrategy.ts +15 -0
  340. package/src/options.spec.ts +41 -0
  341. package/src/options.ts +18 -0
  342. package/src/postgres/index.ts +3 -0
  343. package/src/postgres/manual-types.d.ts +4 -0
  344. package/src/postgres/pgQuerier.test.ts +25 -0
  345. package/src/postgres/pgQuerier.ts +45 -0
  346. package/src/postgres/pgQuerierPool.test.ts +28 -0
  347. package/src/postgres/pgQuerierPool.ts +21 -0
  348. package/src/postgres/postgresDialect.spec.ts +428 -0
  349. package/src/postgres/postgresDialect.ts +144 -0
  350. package/src/querier/abstractQuerier-test.ts +584 -0
  351. package/src/querier/abstractQuerier.ts +353 -0
  352. package/src/querier/abstractQuerierPool-test.ts +20 -0
  353. package/src/querier/abstractQuerierPool.ts +18 -0
  354. package/src/querier/abstractSqlQuerier-spec.ts +979 -0
  355. package/src/querier/abstractSqlQuerier-test.ts +21 -0
  356. package/src/querier/abstractSqlQuerier.ts +138 -0
  357. package/src/querier/decorator/index.ts +3 -0
  358. package/src/querier/decorator/injectQuerier.spec.ts +74 -0
  359. package/src/querier/decorator/injectQuerier.ts +45 -0
  360. package/src/querier/decorator/serialized.spec.ts +98 -0
  361. package/src/querier/decorator/serialized.ts +13 -0
  362. package/src/querier/decorator/transactional.spec.ts +240 -0
  363. package/src/querier/decorator/transactional.ts +56 -0
  364. package/src/querier/index.ts +4 -0
  365. package/src/repository/genericRepository.spec.ts +111 -0
  366. package/src/repository/genericRepository.ts +74 -0
  367. package/src/repository/index.ts +1 -0
  368. package/src/sqlite/index.ts +3 -0
  369. package/src/sqlite/manual-types.d.ts +4 -0
  370. package/src/sqlite/sqliteDialect.spec.ts +155 -0
  371. package/src/sqlite/sqliteDialect.ts +76 -0
  372. package/src/sqlite/sqliteQuerier.spec.ts +36 -0
  373. package/src/sqlite/sqliteQuerier.test.ts +21 -0
  374. package/src/sqlite/sqliteQuerier.ts +37 -0
  375. package/src/sqlite/sqliteQuerierPool.test.ts +12 -0
  376. package/src/sqlite/sqliteQuerierPool.ts +38 -0
  377. package/src/test/entityMock.ts +375 -0
  378. package/src/test/index.ts +3 -0
  379. package/src/test/it.util.ts +69 -0
  380. package/src/test/spec.util.ts +57 -0
  381. package/src/type/entity.ts +218 -0
  382. package/src/type/index.ts +9 -0
  383. package/src/type/migration.ts +241 -0
  384. package/src/type/namingStrategy.ts +17 -0
  385. package/src/type/querier.ts +143 -0
  386. package/src/type/querierPool.ts +26 -0
  387. package/src/type/query.ts +506 -0
  388. package/src/type/repository.ts +142 -0
  389. package/src/type/universalQuerier.ts +133 -0
  390. package/src/type/utility.ts +21 -0
  391. package/src/util/dialect.util-extra.spec.ts +96 -0
  392. package/src/util/dialect.util.spec.ts +23 -0
  393. package/src/util/dialect.util.ts +134 -0
  394. package/src/util/index.ts +5 -0
  395. package/src/util/object.util.spec.ts +29 -0
  396. package/src/util/object.util.ts +27 -0
  397. package/src/util/raw.ts +11 -0
  398. package/src/util/sql.util-extra.spec.ts +17 -0
  399. package/src/util/sql.util.spec.ts +208 -0
  400. package/src/util/sql.util.ts +104 -0
  401. package/src/util/string.util.spec.ts +46 -0
  402. package/src/util/string.util.ts +35 -0
  403. package/tsconfig.build.json +5 -0
  404. package/tsconfig.json +8 -0
  405. package/README.md +0 -177
  406. package/dialect/abstractSqlDialect.d.ts +0 -30
  407. package/dialect/abstractSqlDialect.js +0 -365
  408. package/dialect/index.d.ts +0 -4
  409. package/dialect/index.js +0 -8
  410. package/dialect/mysqlDialect.d.ts +0 -6
  411. package/dialect/mysqlDialect.js +0 -21
  412. package/dialect/postgresDialect.d.ts +0 -8
  413. package/dialect/postgresDialect.js +0 -44
  414. package/dialect/sqliteDialect.d.ts +0 -4
  415. package/dialect/sqliteDialect.js +0 -11
  416. package/entity/decorator/definition.js +0 -223
  417. package/entity/decorator/entity.js +0 -11
  418. package/entity/decorator/field.js +0 -12
  419. package/entity/decorator/id.js +0 -12
  420. package/entity/decorator/index.d.ts +0 -5
  421. package/entity/decorator/index.js +0 -12
  422. package/entity/decorator/relation.js +0 -27
  423. package/entity/index.d.ts +0 -1
  424. package/entity/index.js +0 -5
  425. package/index.d.ts +0 -1
  426. package/index.js +0 -5
  427. package/options.js +0 -20
  428. package/querier/abstractQuerier.d.ts +0 -30
  429. package/querier/abstractQuerier.js +0 -230
  430. package/querier/abstractSqlQuerier.d.ts +0 -27
  431. package/querier/abstractSqlQuerier.js +0 -88
  432. package/querier/decorator/index.d.ts +0 -2
  433. package/querier/decorator/index.js +0 -6
  434. package/querier/decorator/injectQuerier.d.ts +0 -3
  435. package/querier/decorator/injectQuerier.js +0 -39
  436. package/querier/decorator/transactional.js +0 -52
  437. package/querier/index.d.ts +0 -3
  438. package/querier/index.js +0 -7
  439. package/repository/genericRepository.d.ts +0 -19
  440. package/repository/genericRepository.js +0 -52
  441. package/repository/index.d.ts +0 -1
  442. package/repository/index.js +0 -5
  443. package/type/entity.js +0 -5
  444. package/type/index.d.ts +0 -7
  445. package/type/index.js +0 -11
  446. package/type/querier.d.ts +0 -53
  447. package/type/querier.js +0 -3
  448. package/type/querierPool.js +0 -3
  449. package/type/query.js +0 -13
  450. package/type/repository.js +0 -3
  451. package/type/universalQuerier.js +0 -3
  452. package/type/utility.d.ts +0 -12
  453. package/type/utility.js +0 -3
  454. package/util/dialect.util.d.ts +0 -17
  455. package/util/dialect.util.js +0 -114
  456. package/util/index.d.ts +0 -5
  457. package/util/index.js +0 -9
  458. package/util/object.util.d.ts +0 -3
  459. package/util/object.util.js +0 -22
  460. package/util/raw.d.ts +0 -2
  461. package/util/raw.js +0 -9
  462. package/util/sql.util.d.ts +0 -2
  463. package/util/sql.util.js +0 -55
  464. package/util/string.util.js +0 -20
@@ -0,0 +1,600 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { basename, extname, join } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { getEntities, getMeta } from '../entity/index.js';
5
+ import { isSqlQuerier } from '../type/index.js';
6
+ import { MariadbSchemaGenerator, MongoSchemaGenerator, MysqlSchemaGenerator, PostgresSchemaGenerator, SqliteSchemaGenerator, } from './generator/index.js';
7
+ import { MariadbSchemaIntrospector, MongoSchemaIntrospector, MysqlSchemaIntrospector, PostgresSchemaIntrospector, SqliteSchemaIntrospector, } from './introspection/index.js';
8
+ import { DatabaseMigrationStorage } from './storage/databaseStorage.js';
9
+ /**
10
+ * Main class for managing database migrations
11
+ */
12
+ export class Migrator {
13
+ querierPool;
14
+ storage;
15
+ migrationsPath;
16
+ logger;
17
+ entities;
18
+ dialect;
19
+ schemaGenerator;
20
+ schemaIntrospector;
21
+ constructor(querierPool, options = {}) {
22
+ this.querierPool = querierPool;
23
+ this.dialect = options.dialect ?? querierPool.dialect ?? 'postgres';
24
+ this.storage =
25
+ options.storage ??
26
+ new DatabaseMigrationStorage(querierPool, {
27
+ tableName: options.tableName,
28
+ });
29
+ this.migrationsPath = options.migrationsPath ?? './migrations';
30
+ this.logger = options.logger ?? (() => { });
31
+ this.entities = options.entities ?? [];
32
+ this.schemaIntrospector = this.createIntrospector();
33
+ this.schemaGenerator = options.schemaGenerator ?? this.createGenerator(options.namingStrategy);
34
+ }
35
+ /**
36
+ * Set the schema generator for DDL operations
37
+ */
38
+ setSchemaGenerator(generator) {
39
+ this.schemaGenerator = generator;
40
+ }
41
+ createIntrospector() {
42
+ switch (this.dialect) {
43
+ case 'postgres':
44
+ return new PostgresSchemaIntrospector(this.querierPool);
45
+ case 'mysql':
46
+ return new MysqlSchemaIntrospector(this.querierPool);
47
+ case 'mariadb':
48
+ return new MariadbSchemaIntrospector(this.querierPool);
49
+ case 'sqlite':
50
+ return new SqliteSchemaIntrospector(this.querierPool);
51
+ case 'mongodb':
52
+ return new MongoSchemaIntrospector(this.querierPool);
53
+ default:
54
+ return undefined;
55
+ }
56
+ }
57
+ createGenerator(namingStrategy) {
58
+ switch (this.dialect) {
59
+ case 'postgres':
60
+ return new PostgresSchemaGenerator(namingStrategy);
61
+ case 'mysql':
62
+ return new MysqlSchemaGenerator(namingStrategy);
63
+ case 'mariadb':
64
+ return new MariadbSchemaGenerator(namingStrategy);
65
+ case 'sqlite':
66
+ return new SqliteSchemaGenerator(namingStrategy);
67
+ case 'mongodb':
68
+ return new MongoSchemaGenerator(namingStrategy);
69
+ default:
70
+ return undefined;
71
+ }
72
+ }
73
+ /**
74
+ * Get the SQL dialect
75
+ */
76
+ getDialect() {
77
+ return this.dialect;
78
+ }
79
+ /**
80
+ * Get all discovered migrations from the migrations directory
81
+ */
82
+ async getMigrations() {
83
+ const files = await this.getMigrationFiles();
84
+ const migrations = [];
85
+ for (const file of files) {
86
+ const migration = await this.loadMigration(file);
87
+ if (migration) {
88
+ migrations.push(migration);
89
+ }
90
+ }
91
+ // Sort by name (which typically includes timestamp)
92
+ return migrations.sort((a, b) => a.name.localeCompare(b.name));
93
+ }
94
+ /**
95
+ * Get list of pending migrations (not yet executed)
96
+ */
97
+ async pending() {
98
+ const [migrations, executed] = await Promise.all([this.getMigrations(), this.storage.executed()]);
99
+ const executedSet = new Set(executed);
100
+ return migrations.filter((m) => !executedSet.has(m.name));
101
+ }
102
+ /**
103
+ * Get list of executed migrations
104
+ */
105
+ async executed() {
106
+ return this.storage.executed();
107
+ }
108
+ /**
109
+ * Run all pending migrations
110
+ */
111
+ async up(options = {}) {
112
+ const pendingMigrations = await this.pending();
113
+ const results = [];
114
+ let migrationsToRun = pendingMigrations;
115
+ if (options.to) {
116
+ const toIndex = migrationsToRun.findIndex((m) => m.name === options.to);
117
+ if (toIndex === -1) {
118
+ throw new Error(`Migration '${options.to}' not found`);
119
+ }
120
+ migrationsToRun = migrationsToRun.slice(0, toIndex + 1);
121
+ }
122
+ if (options.step !== undefined) {
123
+ migrationsToRun = migrationsToRun.slice(0, options.step);
124
+ }
125
+ for (const migration of migrationsToRun) {
126
+ const result = await this.runMigration(migration, 'up');
127
+ results.push(result);
128
+ if (!result.success) {
129
+ break; // Stop on first failure
130
+ }
131
+ }
132
+ return results;
133
+ }
134
+ /**
135
+ * Rollback migrations
136
+ */
137
+ async down(options = {}) {
138
+ const [migrations, executed] = await Promise.all([this.getMigrations(), this.storage.executed()]);
139
+ const executedSet = new Set(executed);
140
+ const executedMigrations = migrations.filter((m) => executedSet.has(m.name)).reverse(); // Rollback in reverse order
141
+ const results = [];
142
+ let migrationsToRun = executedMigrations;
143
+ if (options.to) {
144
+ const toIndex = migrationsToRun.findIndex((m) => m.name === options.to);
145
+ if (toIndex === -1) {
146
+ throw new Error(`Migration '${options.to}' not found`);
147
+ }
148
+ migrationsToRun = migrationsToRun.slice(0, toIndex + 1);
149
+ }
150
+ if (options.step !== undefined) {
151
+ migrationsToRun = migrationsToRun.slice(0, options.step);
152
+ }
153
+ for (const migration of migrationsToRun) {
154
+ const result = await this.runMigration(migration, 'down');
155
+ results.push(result);
156
+ if (!result.success) {
157
+ break; // Stop on first failure
158
+ }
159
+ }
160
+ return results;
161
+ }
162
+ /**
163
+ * Run a single migration within a transaction
164
+ */
165
+ async runMigration(migration, direction) {
166
+ const startTime = Date.now();
167
+ const querier = await this.querierPool.getQuerier();
168
+ if (!isSqlQuerier(querier)) {
169
+ await querier.release();
170
+ throw new Error('Migrator requires a SQL-based querier');
171
+ }
172
+ try {
173
+ this.logger(`${direction === 'up' ? 'Running' : 'Reverting'} migration: ${migration.name}`);
174
+ await querier.beginTransaction();
175
+ if (direction === 'up') {
176
+ await migration.up(querier);
177
+ // Log within the same transaction
178
+ await this.storage.logWithQuerier(querier, migration.name);
179
+ }
180
+ else {
181
+ await migration.down(querier);
182
+ // Unlog within the same transaction
183
+ await this.storage.unlogWithQuerier(querier, migration.name);
184
+ }
185
+ await querier.commitTransaction();
186
+ const duration = Date.now() - startTime;
187
+ this.logger(`Migration ${migration.name} ${direction === 'up' ? 'applied' : 'reverted'} in ${duration}ms`);
188
+ return {
189
+ name: migration.name,
190
+ direction,
191
+ duration,
192
+ success: true,
193
+ };
194
+ }
195
+ catch (error) {
196
+ await querier.rollbackTransaction();
197
+ const duration = Date.now() - startTime;
198
+ this.logger(`Migration ${migration.name} failed: ${error.message}`);
199
+ return {
200
+ name: migration.name,
201
+ direction,
202
+ duration,
203
+ success: false,
204
+ error: error,
205
+ };
206
+ }
207
+ finally {
208
+ await querier.release();
209
+ }
210
+ }
211
+ /**
212
+ * Generate a new migration file
213
+ */
214
+ async generate(name) {
215
+ const timestamp = this.getTimestamp();
216
+ const fileName = `${timestamp}_${this.slugify(name)}.ts`;
217
+ const filePath = join(this.migrationsPath, fileName);
218
+ const content = this.generateMigrationContent(name);
219
+ const { writeFile, mkdir } = await import('node:fs/promises');
220
+ await mkdir(this.migrationsPath, { recursive: true });
221
+ await writeFile(filePath, content, 'utf-8');
222
+ this.logger(`Created migration: ${filePath}`);
223
+ return filePath;
224
+ }
225
+ /**
226
+ * Generate a migration based on entity schema differences
227
+ */
228
+ async generateFromEntities(name) {
229
+ if (!this.schemaGenerator) {
230
+ throw new Error('Schema generator not set. Call setSchemaGenerator() first.');
231
+ }
232
+ const diffs = await this.getDiffs();
233
+ const upStatements = [];
234
+ const downStatements = [];
235
+ for (const diff of diffs) {
236
+ if (diff.type === 'create') {
237
+ const entity = this.findEntityForTable(diff.tableName);
238
+ if (entity) {
239
+ upStatements.push(this.schemaGenerator.generateCreateTable(entity));
240
+ downStatements.push(this.schemaGenerator.generateDropTable(entity));
241
+ }
242
+ }
243
+ else if (diff.type === 'alter') {
244
+ const alterStatements = this.schemaGenerator.generateAlterTable(diff);
245
+ upStatements.push(...alterStatements);
246
+ const alterDownStatements = this.schemaGenerator.generateAlterTableDown(diff);
247
+ downStatements.push(...alterDownStatements);
248
+ }
249
+ }
250
+ if (upStatements.length === 0) {
251
+ this.logger('No schema changes detected.');
252
+ return '';
253
+ }
254
+ const timestamp = this.getTimestamp();
255
+ const fileName = `${timestamp}_${this.slugify(name)}.ts`;
256
+ const filePath = join(this.migrationsPath, fileName);
257
+ const content = this.generateMigrationContentWithStatements(name, upStatements, downStatements.reverse());
258
+ const { writeFile, mkdir } = await import('node:fs/promises');
259
+ await mkdir(this.migrationsPath, { recursive: true });
260
+ await writeFile(filePath, content, 'utf-8');
261
+ this.logger(`Created migration from entities: ${filePath}`);
262
+ return filePath;
263
+ }
264
+ /**
265
+ * Get all schema differences between entities and database
266
+ */
267
+ async getDiffs() {
268
+ if (!this.schemaGenerator || !this.schemaIntrospector) {
269
+ throw new Error('Schema generator and introspector must be set');
270
+ }
271
+ const entities = this.entities.length > 0 ? this.entities : getEntities();
272
+ const diffs = [];
273
+ for (const entity of entities) {
274
+ const meta = getMeta(entity);
275
+ const tableName = this.schemaGenerator.resolveTableName(entity, meta);
276
+ const currentSchema = await this.schemaIntrospector.getTableSchema(tableName);
277
+ const diff = this.schemaGenerator.diffSchema(entity, currentSchema);
278
+ if (diff) {
279
+ diffs.push(diff);
280
+ }
281
+ }
282
+ return diffs;
283
+ }
284
+ findEntityForTable(tableName) {
285
+ const entities = this.entities.length > 0 ? this.entities : getEntities();
286
+ for (const entity of entities) {
287
+ const meta = getMeta(entity);
288
+ const name = this.schemaGenerator.resolveTableName(entity, meta);
289
+ if (name === tableName) {
290
+ return entity;
291
+ }
292
+ }
293
+ return undefined;
294
+ }
295
+ /**
296
+ * Sync schema directly (for development only - not for production!)
297
+ */
298
+ async sync(options = {}) {
299
+ if (options.force) {
300
+ return this.syncForce();
301
+ }
302
+ return this.autoSync({ safe: true });
303
+ }
304
+ /**
305
+ * Drops and recreates all tables (Development only!)
306
+ */
307
+ async syncForce() {
308
+ if (!this.schemaGenerator) {
309
+ throw new Error('Schema generator not set. Call setSchemaGenerator() first.');
310
+ }
311
+ const entities = this.entities.length > 0 ? this.entities : getEntities();
312
+ const querier = await this.querierPool.getQuerier();
313
+ if (!isSqlQuerier(querier)) {
314
+ await querier.release();
315
+ throw new Error('Migrator requires a SQL-based querier');
316
+ }
317
+ try {
318
+ await querier.beginTransaction();
319
+ // Drop all tables first (in reverse order for foreign keys)
320
+ for (const entity of [...entities].reverse()) {
321
+ const dropSql = this.schemaGenerator.generateDropTable(entity);
322
+ this.logger(`Executing: ${dropSql}`);
323
+ await querier.run(dropSql);
324
+ }
325
+ // Create all tables
326
+ for (const entity of entities) {
327
+ const createSql = this.schemaGenerator.generateCreateTable(entity);
328
+ this.logger(`Executing: ${createSql}`);
329
+ await querier.run(createSql);
330
+ }
331
+ await querier.commitTransaction();
332
+ this.logger('Schema sync (force) completed');
333
+ }
334
+ catch (error) {
335
+ await querier.rollbackTransaction();
336
+ throw error;
337
+ }
338
+ finally {
339
+ await querier.release();
340
+ }
341
+ }
342
+ /**
343
+ * Safely synchronizes the schema by only adding missing tables and columns.
344
+ */
345
+ async autoSync(options = {}) {
346
+ if (!this.schemaGenerator || !this.schemaIntrospector) {
347
+ throw new Error('Schema generator and introspector must be set');
348
+ }
349
+ const diffs = await this.getDiffs();
350
+ const statements = [];
351
+ for (const diff of diffs) {
352
+ if (diff.type === 'create') {
353
+ const entity = this.findEntityForTable(diff.tableName);
354
+ if (entity) {
355
+ statements.push(this.schemaGenerator.generateCreateTable(entity));
356
+ }
357
+ }
358
+ else if (diff.type === 'alter') {
359
+ const filteredDiff = this.filterDiff(diff, options);
360
+ const alterStatements = this.schemaGenerator.generateAlterTable(filteredDiff);
361
+ statements.push(...alterStatements);
362
+ }
363
+ }
364
+ if (statements.length === 0) {
365
+ if (options.logging)
366
+ this.logger('Schema is already in sync.');
367
+ return;
368
+ }
369
+ await this.executeSyncStatements(statements, options);
370
+ }
371
+ filterDiff(diff, options) {
372
+ const filteredDiff = { ...diff };
373
+ if (options.safe !== false) {
374
+ // In safe mode, we only allow additions
375
+ delete filteredDiff.columnsToDrop;
376
+ delete filteredDiff.indexesToDrop;
377
+ delete filteredDiff.foreignKeysToDrop;
378
+ }
379
+ if (!options.drop) {
380
+ delete filteredDiff.columnsToDrop;
381
+ }
382
+ return filteredDiff;
383
+ }
384
+ async executeSyncStatements(statements, options) {
385
+ const querier = await this.querierPool.getQuerier();
386
+ try {
387
+ if (this.dialect === 'mongodb') {
388
+ await this.executeMongoSyncStatements(statements, options, querier);
389
+ }
390
+ else {
391
+ await this.executeSqlSyncStatements(statements, options, querier);
392
+ }
393
+ if (options.logging)
394
+ this.logger('Schema synchronization completed');
395
+ }
396
+ catch (error) {
397
+ if (this.dialect !== 'mongodb' && isSqlQuerier(querier)) {
398
+ await querier.rollbackTransaction();
399
+ }
400
+ throw error;
401
+ }
402
+ finally {
403
+ await querier.release();
404
+ }
405
+ }
406
+ async executeMongoSyncStatements(statements, options, querier) {
407
+ const db = querier.db;
408
+ for (const stmt of statements) {
409
+ const cmd = JSON.parse(stmt);
410
+ if (options.logging)
411
+ this.logger(`Executing MongoDB: ${stmt}`);
412
+ const collectionName = cmd.name || cmd.collection;
413
+ if (!collectionName) {
414
+ throw new Error(`MongoDB command missing collection name: ${stmt}`);
415
+ }
416
+ const collection = db.collection(collectionName);
417
+ if (cmd.action === 'createCollection') {
418
+ await db.createCollection(cmd.name);
419
+ if (cmd.indexes?.length) {
420
+ for (const idx of cmd.indexes) {
421
+ const key = Object.fromEntries(idx.columns.map((c) => [c, 1]));
422
+ await collection.createIndex(key, { unique: idx.unique, name: idx.name });
423
+ }
424
+ }
425
+ }
426
+ else if (cmd.action === 'dropCollection') {
427
+ await collection.drop();
428
+ }
429
+ else if (cmd.action === 'createIndex') {
430
+ await collection.createIndex(cmd.key, cmd.options);
431
+ }
432
+ else if (cmd.action === 'dropIndex') {
433
+ await collection.dropIndex(cmd.name);
434
+ }
435
+ }
436
+ }
437
+ async executeSqlSyncStatements(statements, options, querier) {
438
+ if (!isSqlQuerier(querier)) {
439
+ throw new Error('Migrator requires a SQL-based querier for this dialect');
440
+ }
441
+ await querier.beginTransaction();
442
+ for (const sql of statements) {
443
+ if (options.logging)
444
+ this.logger(`Executing: ${sql}`);
445
+ await querier.run(sql);
446
+ }
447
+ await querier.commitTransaction();
448
+ }
449
+ /**
450
+ * Get migration status
451
+ */
452
+ async status() {
453
+ const [pending, executed] = await Promise.all([this.pending().then((m) => m.map((x) => x.name)), this.executed()]);
454
+ return { pending, executed };
455
+ }
456
+ /**
457
+ * Get migration files from the migrations directory
458
+ */
459
+ async getMigrationFiles() {
460
+ try {
461
+ const files = await readdir(this.migrationsPath);
462
+ return files
463
+ .filter((f) => /\.(ts|js|mjs)$/.test(f))
464
+ .filter((f) => !f.endsWith('.d.ts'))
465
+ .sort();
466
+ }
467
+ catch (error) {
468
+ if (error.code === 'ENOENT') {
469
+ return [];
470
+ }
471
+ throw error;
472
+ }
473
+ }
474
+ /**
475
+ * Load a migration from a file
476
+ */
477
+ async loadMigration(fileName) {
478
+ const filePath = join(this.migrationsPath, fileName);
479
+ const fileUrl = pathToFileURL(filePath).href;
480
+ try {
481
+ const module = await import(fileUrl);
482
+ const migration = module.default ?? module;
483
+ if (this.isMigration(migration)) {
484
+ return {
485
+ name: this.getMigrationName(fileName),
486
+ up: migration.up.bind(migration),
487
+ down: migration.down.bind(migration),
488
+ };
489
+ }
490
+ this.logger(`Warning: ${fileName} is not a valid migration`);
491
+ return undefined;
492
+ }
493
+ catch (error) {
494
+ this.logger(`Error loading migration ${fileName}: ${error.message}`);
495
+ return undefined;
496
+ }
497
+ }
498
+ /**
499
+ * Check if an object is a valid migration
500
+ */
501
+ isMigration(obj) {
502
+ return (typeof obj === 'object' &&
503
+ obj !== undefined &&
504
+ obj !== null &&
505
+ typeof obj.up === 'function' &&
506
+ typeof obj.down === 'function');
507
+ }
508
+ /**
509
+ * Extract migration name from filename
510
+ */
511
+ getMigrationName(fileName) {
512
+ return basename(fileName, extname(fileName));
513
+ }
514
+ /**
515
+ * Generate timestamp string for migration names
516
+ */
517
+ getTimestamp() {
518
+ const now = new Date();
519
+ return [
520
+ now.getFullYear(),
521
+ String(now.getMonth() + 1).padStart(2, '0'),
522
+ String(now.getDate()).padStart(2, '0'),
523
+ String(now.getHours()).padStart(2, '0'),
524
+ String(now.getMinutes()).padStart(2, '0'),
525
+ String(now.getSeconds()).padStart(2, '0'),
526
+ ].join('');
527
+ }
528
+ /**
529
+ * Convert a string to a slug for filenames
530
+ */
531
+ slugify(text) {
532
+ return text
533
+ .toLowerCase()
534
+ .replace(/[^a-z0-9]+/g, '_')
535
+ .replace(/^_+|_+$/g, '');
536
+ }
537
+ /**
538
+ * Generate migration file content
539
+ */
540
+ generateMigrationContent(name) {
541
+ return /*ts*/ `import type { SqlQuerier } from '@uql/migrate';
542
+
543
+ /**
544
+ * Migration: ${name}
545
+ * Created: ${new Date().toISOString()}
546
+ */
547
+ export default {
548
+ async up(querier: SqlQuerier): Promise<void> {
549
+ // Add your migration logic here
550
+ // Example:
551
+ // await querier.run(\`
552
+ // CREATE TABLE "users" (
553
+ // "id" SERIAL PRIMARY KEY,
554
+ // "name" VARCHAR(255) NOT NULL,
555
+ // "email" VARCHAR(255) UNIQUE NOT NULL,
556
+ // "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
557
+ // )
558
+ // \`);
559
+ },
560
+
561
+ async down(querier: SqlQuerier): Promise<void> {
562
+ // Add your rollback logic here
563
+ // Example:
564
+ // await querier.run(\`DROP TABLE IF EXISTS "users"\`);
565
+ },
566
+ };
567
+ `;
568
+ }
569
+ /**
570
+ * Generate migration file content with SQL statements
571
+ */
572
+ generateMigrationContentWithStatements(name, upStatements, downStatements) {
573
+ const upSql = upStatements.map((s) => /*ts*/ ` await querier.run(\`${s}\`);`).join('\n');
574
+ const downSql = downStatements.map((s) => /*ts*/ ` await querier.run(\`${s}\`);`).join('\n');
575
+ return /*ts*/ `import type { SqlQuerier } from '@uql/migrate';
576
+
577
+ /**
578
+ * Migration: ${name}
579
+ * Created: ${new Date().toISOString()}
580
+ * Generated from entity definitions
581
+ */
582
+ export default {
583
+ async up(querier: SqlQuerier): Promise<void> {
584
+ ${upSql}
585
+ },
586
+
587
+ async down(querier: SqlQuerier): Promise<void> {
588
+ ${downSql}
589
+ },
590
+ };
591
+ `;
592
+ }
593
+ }
594
+ /**
595
+ * Helper function to define a migration with proper typing
596
+ */
597
+ export function defineMigration(migration) {
598
+ return migration;
599
+ }
600
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlncmF0ZS9taWdyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDekMsT0FBTyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQWlCMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsb0JBQW9CLEVBQ3BCLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIscUJBQXFCLEdBQ3RCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUNMLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsdUJBQXVCLEVBQ3ZCLDBCQUEwQixFQUMxQix3QkFBd0IsR0FDekIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUV4RTs7R0FFRztBQUNILE1BQU0sT0FBTyxRQUFRO0lBVUE7SUFURixPQUFPLENBQW1CO0lBQzFCLGNBQWMsQ0FBUztJQUN2QixNQUFNLENBQTRCO0lBQ2xDLFFBQVEsQ0FBa0I7SUFDMUIsT0FBTyxDQUFVO0lBQzFCLGVBQWUsQ0FBbUI7SUFDbkMsa0JBQWtCLENBQXNCO0lBRS9DLFlBQ21CLFdBQXdCLEVBQ3pDLFVBQTJCLEVBQUU7UUFEWixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUd6QyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksV0FBVyxDQUFDLE9BQU8sSUFBSSxVQUFVLENBQUM7UUFDcEUsSUFB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QUFFLENBQUMsV0FBVyxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBc0JyQyxDQUFDO0lBQ0EsQ0FBQztJQUVEOztPQUVHO0lBQ0ssc0NBQXNDLENBQzVDLElBQVksRUFDWixZQUFzQixFQUN0QixjQUF3QjtRQUV4QixNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVGLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFaEcsT0FBTyxNQUFNLENBQUM7OztnQkFHRixJQUFJO2NBQ04sSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7Ozs7O0VBS3BDLEtBQUs7Ozs7RUFJTCxPQUFPOzs7Q0FHUixDQUFDO0lBQ0EsQ0FBQztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFDLFNBQThCO0lBQzVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWFkZGlyIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBiYXNlbmFtZSwgZXh0bmFtZSwgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBwYXRoVG9GaWxlVVJMIH0gZnJvbSAnbm9kZTp1cmwnO1xuaW1wb3J0IHsgZ2V0RW50aXRpZXMsIGdldE1ldGEgfSBmcm9tICcuLi9lbnRpdHkvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge1xuICBEaWFsZWN0LFxuICBNaWdyYXRpb24sXG4gIE1pZ3JhdGlvbkRlZmluaXRpb24sXG4gIE1pZ3JhdGlvblJlc3VsdCxcbiAgTWlncmF0aW9uU3RvcmFnZSxcbiAgTWlncmF0b3JPcHRpb25zLFxuICBNb25nb1F1ZXJpZXIsXG4gIE5hbWluZ1N0cmF0ZWd5LFxuICBRdWVyaWVyLFxuICBRdWVyaWVyUG9vbCxcbiAgU2NoZW1hRGlmZixcbiAgU2NoZW1hR2VuZXJhdG9yLFxuICBTY2hlbWFJbnRyb3NwZWN0b3IsXG4gIFR5cGUsXG59IGZyb20gJy4uL3R5cGUvaW5kZXguanMnO1xuaW1wb3J0IHsgaXNTcWxRdWVyaWVyIH0gZnJvbSAnLi4vdHlwZS9pbmRleC5qcyc7XG5pbXBvcnQge1xuICBNYXJpYWRiU2NoZW1hR2VuZXJhdG9yLFxuICBNb25nb1NjaGVtYUdlbmVyYXRvcixcbiAgTXlzcWxTY2hlbWFHZW5lcmF0b3IsXG4gIFBvc3RncmVzU2NoZW1hR2VuZXJhdG9yLFxuICBTcWxpdGVTY2hlbWFHZW5lcmF0b3IsXG59IGZyb20gJy4vZ2VuZXJhdG9yL2luZGV4LmpzJztcbmltcG9ydCB7XG4gIE1hcmlhZGJTY2hlbWFJbnRyb3NwZWN0b3IsXG4gIE1vbmdvU2NoZW1hSW50cm9zcGVjdG9yLFxuICBNeXNxbFNjaGVtYUludHJvc3BlY3RvcixcbiAgUG9zdGdyZXNTY2hlbWFJbnRyb3NwZWN0b3IsXG4gIFNxbGl0ZVNjaGVtYUludHJvc3BlY3Rvcixcbn0gZnJvbSAnLi9pbnRyb3NwZWN0aW9uL2luZGV4LmpzJztcbmltcG9ydCB7IERhdGFiYXNlTWlncmF0aW9uU3RvcmFnZSB9IGZyb20gJy4vc3RvcmFnZS9kYXRhYmFzZVN0b3JhZ2UuanMnO1xuXG4vKipcbiAqIE1haW4gY2xhc3MgZm9yIG1hbmFnaW5nIGRhdGFiYXNlIG1pZ3JhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZ3JhdG9yIHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdG9yYWdlOiBNaWdyYXRpb25TdG9yYWdlO1xuICBwcml2YXRlIHJlYWRvbmx5IG1pZ3JhdGlvbnNQYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xuICBwcml2YXRlIHJlYWRvbmx5IGVudGl0aWVzOiBUeXBlPHVua25vd24+W107XG4gIHByaXZhdGUgcmVhZG9ubHkgZGlhbGVjdDogRGlhbGVjdDtcbiAgcHJpdmF0ZSBzY2hlbWFHZW5lcmF0b3I/OiBTY2hlbWFHZW5lcmF0b3I7XG4gIHB1YmxpYyBzY2hlbWFJbnRyb3NwZWN0b3I/OiBTY2hlbWFJbnRyb3NwZWN0b3I7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBxdWVyaWVyUG9vbDogUXVlcmllclBvb2wsXG4gICAgb3B0aW9uczogTWlncmF0b3JPcHRpb25zID0ge30sXG4gICkge1xuICAgIHRoaXMuZGlhbGVjdCA9IG9wdGlvbnMuZGlhbGVjdCA/PyBxdWVyaWVyUG9vbC5kaWFsZWN0ID8/ICdwb3N0Z3Jlcyc7XG4gICAgdGhpcy5zdG9yYWdlID1cbiAgICAgIG9wdGlvbnMuc3RvcmFnZSA/P1xuICAgICAgbmV3IERhdGFiYXNlTWlncmF0aW9uU3RvcmFnZShxdWVyaWVyUG9vbCwge1xuICAgICAgICB0YWJsZU5hbWU6IG9wdGlvbnMudGFibGVOYW1lLFxuICAgICAgfSk7XG4gICAgdGhpcy5taWdyYXRpb25zUGF0aCA9IG9wdGlvbnMubWlncmF0aW9uc1BhdGggPz8gJy4vbWlncmF0aW9ucyc7XG4gICAgdGhpcy5sb2dnZXIgPSBvcHRpb25zLmxvZ2dlciA/PyAoKCkgPT4ge30pO1xuICAgIHRoaXMuZW50aXRpZXMgPSBvcHRpb25zLmVudGl0aWVzID8/IFtdO1xuICAgIHRoaXMuc2NoZW1hSW50cm9zcGVjdG9yID0gdGhpcy5jcmVhdGVJbnRyb3NwZWN0b3IoKTtcbiAgICB0aGlzLnNjaGVtYUdlbmVyYXRvciA9IG9wdGlvbnMuc2NoZW1hR2VuZXJhdG9yID8/IHRoaXMuY3JlYXRlR2VuZXJhdG9yKG9wdGlvbnMubmFtaW5nU3RyYXRlZ3kpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgc2NoZW1hIGdlbmVyYXRvciBmb3IgRERMIG9wZXJhdGlvbnNcbiAgICovXG4gIHNldFNjaGVtYUdlbmVyYXRvcihnZW5lcmF0b3I6IFNjaGVtYUdlbmVyYXRvcik6IHZvaWQge1xuICAgIHRoaXMuc2NoZW1hR2VuZXJhdG9yID0gZ2VuZXJhdG9yO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVJbnRyb3NwZWN0b3IoKTogU2NoZW1hSW50cm9zcGVjdG9yIHwgdW5kZWZpbmVkIHtcbiAgICBzd2l0Y2ggKHRoaXMuZGlhbGVjdCkge1xuICAgICAgY2FzZSAncG9zdGdyZXMnOlxuICAgICAgICByZXR1cm4gbmV3IFBvc3RncmVzU2NoZW1hSW50cm9zcGVjdG9yKHRoaXMucXVlcmllclBvb2wpO1xuICAgICAgY2FzZSAnbXlzcWwnOlxuICAgICAgICByZXR1cm4gbmV3IE15c3FsU2NoZW1hSW50cm9zcGVjdG9yKHRoaXMucXVlcmllclBvb2wpO1xuICAgICAgY2FzZSAnbWFyaWFkYic6XG4gICAgICAgIHJldHVybiBuZXcgTWFyaWFkYlNjaGVtYUludHJvc3BlY3Rvcih0aGlzLnF1ZXJpZXJQb29sKTtcbiAgICAgIGNhc2UgJ3NxbGl0ZSc6XG4gICAgICAgIHJldHVybiBuZXcgU3FsaXRlU2NoZW1hSW50cm9zcGVjdG9yKHRoaXMucXVlcmllclBvb2wpO1xuICAgICAgY2FzZSAnbW9uZ29kYic6XG4gICAgICAgIHJldHVybiBuZXcgTW9uZ29TY2hlbWFJbnRyb3NwZWN0b3IodGhpcy5xdWVyaWVyUG9vbCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR2VuZXJhdG9yKG5hbWluZ1N0cmF0ZWd5PzogTmFtaW5nU3RyYXRlZ3kpOiBTY2hlbWFHZW5lcmF0b3IgfCB1bmRlZmluZWQge1xuICAgIHN3aXRjaCAodGhpcy5kaWFsZWN0KSB7XG4gICAgICBjYXNlICdwb3N0Z3Jlcyc6XG4gICAgICAgIHJldHVybiBuZXcgUG9zdGdyZXNTY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgY2FzZSAnbXlzcWwnOlxuICAgICAgICByZXR1cm4gbmV3IE15c3FsU2NoZW1hR2VuZXJhdG9yKG5hbWluZ1N0cmF0ZWd5KTtcbiAgICAgIGNhc2UgJ21hcmlhZGInOlxuICAgICAgICByZXR1cm4gbmV3IE1hcmlhZGJTY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgY2FzZSAnc3FsaXRlJzpcbiAgICAgICAgcmV0dXJuIG5ldyBTcWxpdGVTY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgY2FzZSAnbW9uZ29kYic6XG4gICAgICAgIHJldHVybiBuZXcgTW9uZ29TY2hlbWFHZW5lcmF0b3IobmFtaW5nU3RyYXRlZ3kpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBTUUwgZGlhbGVjdFxuICAgKi9cbiAgZ2V0RGlhbGVjdCgpOiBEaWFsZWN0IHtcbiAgICByZXR1cm4gdGhpcy5kaWFsZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgZGlzY292ZXJlZCBtaWdyYXRpb25zIGZyb20gdGhlIG1pZ3JhdGlvbnMgZGlyZWN0b3J5XG4gICAqL1xuICBhc3luYyBnZXRNaWdyYXRpb25zKCk6IFByb21pc2U8TWlncmF0aW9uW10+IHtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHRoaXMuZ2V0TWlncmF0aW9uRmlsZXMoKTtcbiAgICBjb25zdCBtaWdyYXRpb25zOiBNaWdyYXRpb25bXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICBjb25zdCBtaWdyYXRpb24gPSBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb24oZmlsZSk7XG4gICAgICBpZiAobWlncmF0aW9uKSB7XG4gICAgICAgIG1pZ3JhdGlvbnMucHVzaChtaWdyYXRpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNvcnQgYnkgbmFtZSAod2hpY2ggdHlwaWNhbGx5IGluY2x1ZGVzIHRpbWVzdGFtcClcbiAgICByZXR1cm4gbWlncmF0aW9ucy5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGxpc3Qgb2YgcGVuZGluZyBtaWdyYXRpb25zIChub3QgeWV0IGV4ZWN1dGVkKVxuICAgKi9cbiAgYXN5bmMgcGVuZGluZygpOiBQcm9taXNlPE1pZ3JhdGlvbltdPiB7XG4gICAgY29uc3QgW21pZ3JhdGlvbnMsIGV4ZWN1dGVkXSA9IGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLmdldE1pZ3JhdGlvbnMoKSwgdGhpcy5zdG9yYWdlLmV4ZWN1dGVkKCldKTtcblxuICAgIGNvbnN0IGV4ZWN1dGVkU2V0ID0gbmV3IFNldChleGVjdXRlZCk7XG4gICAgcmV0dXJuIG1pZ3JhdGlvbnMuZmlsdGVyKChtOiBhbnkpID0+ICFleGVjdXRlZFNldC5oYXMobS5uYW1lKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGxpc3Qgb2YgZXhlY3V0ZWQgbWlncmF0aW9uc1xuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZWQoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZXhlY3V0ZWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYWxsIHBlbmRpbmcgbWlncmF0aW9uc1xuICAgKi9cbiAgYXN5bmMgdXAob3B0aW9uczogeyB0bz86IHN0cmluZzsgc3RlcD86IG51bWJlciB9ID0ge30pOiBQcm9taXNlPE1pZ3JhdGlvblJlc3VsdFtdPiB7XG4gICAgY29uc3QgcGVuZGluZ01pZ3JhdGlvbnMgPSBhd2FpdCB0aGlzLnBlbmRpbmcoKTtcbiAgICBjb25zdCByZXN1bHRzOiBNaWdyYXRpb25SZXN1bHRbXSA9IFtdO1xuXG4gICAgbGV0IG1pZ3JhdGlvbnNUb1J1biA9IHBlbmRpbmdNaWdyYXRpb25zO1xuXG4gICAgaWYgKG9wdGlvbnMudG8pIHtcbiAgICAgIGNvbnN0IHRvSW5kZXggPSBtaWdyYXRpb25zVG9SdW4uZmluZEluZGV4KChtOiBhbnkpID0+IG0ubmFtZSA9PT0gb3B0aW9ucy50byk7XG4gICAgICBpZiAodG9JbmRleCA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb24gJyR7b3B0aW9ucy50b30nIG5vdCBmb3VuZGApO1xuICAgICAgfVxuICAgICAgbWlncmF0aW9uc1RvUnVuID0gbWlncmF0aW9uc1RvUnVuLnNsaWNlKDAsIHRvSW5kZXggKyAxKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5zdGVwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1pZ3JhdGlvbnNUb1J1biA9IG1pZ3JhdGlvbnNUb1J1bi5zbGljZSgwLCBvcHRpb25zLnN0ZXApO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgbWlncmF0aW9uIG9mIG1pZ3JhdGlvbnNUb1J1bikge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ydW5NaWdyYXRpb24obWlncmF0aW9uLCAndXAnKTtcbiAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGJyZWFrOyAvLyBTdG9wIG9uIGZpcnN0IGZhaWx1cmVcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xsYmFjayBtaWdyYXRpb25zXG4gICAqL1xuICBhc3luYyBkb3duKG9wdGlvbnM6IHsgdG8/OiBzdHJpbmc7IHN0ZXA/OiBudW1iZXIgfSA9IHt9KTogUHJvbWlzZTxNaWdyYXRpb25SZXN1bHRbXT4ge1xuICAgIGNvbnN0IFttaWdyYXRpb25zLCBleGVjdXRlZF0gPSBhd2FpdCBQcm9taXNlLmFsbChbdGhpcy5nZXRNaWdyYXRpb25zKCksIHRoaXMuc3RvcmFnZS5leGVjdXRlZCgpXSk7XG5cbiAgICBjb25zdCBleGVjdXRlZFNldCA9IG5ldyBTZXQoZXhlY3V0ZWQpO1xuICAgIGNvbnN0IGV4ZWN1dGVkTWlncmF0aW9ucyA9IG1pZ3JhdGlvbnMuZmlsdGVyKChtOiBhbnkpID0+IGV4ZWN1dGVkU2V0LmhhcyhtLm5hbWUpKS5yZXZlcnNlKCk7IC8vIFJvbGxiYWNrIGluIHJldmVyc2Ugb3JkZXJcblxuICAgIGNvbnN0IHJlc3VsdHM6IE1pZ3JhdGlvblJlc3VsdFtdID0gW107XG4gICAgbGV0IG1pZ3JhdGlvbnNUb1J1biA9IGV4ZWN1dGVkTWlncmF0aW9ucztcblxuICAgIGlmIChvcHRpb25zLnRvKSB7XG4gICAgICBjb25zdCB0b0luZGV4ID0gbWlncmF0aW9uc1RvUnVuLmZpbmRJbmRleCgobTogYW55KSA9PiBtLm5hbWUgPT09IG9wdGlvbnMudG8pO1xuICAgICAgaWYgKHRvSW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uICcke29wdGlvbnMudG99JyBub3QgZm91bmRgKTtcbiAgICAgIH1cbiAgICAgIG1pZ3JhdGlvbnNUb1J1biA9IG1pZ3JhdGlvbnNUb1J1bi5zbGljZSgwLCB0b0luZGV4ICsgMSk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc3RlcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaWdyYXRpb25zVG9SdW4gPSBtaWdyYXRpb25zVG9SdW4uc2xpY2UoMCwgb3B0aW9ucy5zdGVwKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG1pZ3JhdGlvbiBvZiBtaWdyYXRpb25zVG9SdW4pIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucnVuTWlncmF0aW9uKG1pZ3JhdGlvbiwgJ2Rvd24nKTtcbiAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGJyZWFrOyAvLyBTdG9wIG9uIGZpcnN0IGZhaWx1cmVcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYSBzaW5nbGUgbWlncmF0aW9uIHdpdGhpbiBhIHRyYW5zYWN0aW9uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJ1bk1pZ3JhdGlvbihtaWdyYXRpb246IE1pZ3JhdGlvbiwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKTogUHJvbWlzZTxNaWdyYXRpb25SZXN1bHQ+IHtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHF1ZXJpZXIgPSBhd2FpdCB0aGlzLnF1ZXJpZXJQb29sLmdldFF1ZXJpZXIoKTtcblxuICAgIGlmICghaXNTcWxRdWVyaWVyKHF1ZXJpZXIpKSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlncmF0b3IgcmVxdWlyZXMgYSBTUUwtYmFzZWQgcXVlcmllcicpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB0aGlzLmxvZ2dlcihgJHtkaXJlY3Rpb24gPT09ICd1cCcgPyAnUnVubmluZycgOiAnUmV2ZXJ0aW5nJ30gbWlncmF0aW9uOiAke21pZ3JhdGlvbi5uYW1lfWApO1xuXG4gICAgICBhd2FpdCBxdWVyaWVyLmJlZ2luVHJhbnNhY3Rpb24oKTtcblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3VwJykge1xuICAgICAgICBhd2FpdCBtaWdyYXRpb24udXAocXVlcmllcik7XG4gICAgICAgIC8vIExvZyB3aXRoaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb25cbiAgICAgICAgYXdhaXQgdGhpcy5zdG9yYWdlLmxvZ1dpdGhRdWVyaWVyKHF1ZXJpZXIsIG1pZ3JhdGlvbi5uYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IG1pZ3JhdGlvbi5kb3duKHF1ZXJpZXIpO1xuICAgICAgICAvLyBVbmxvZyB3aXRoaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb25cbiAgICAgICAgYXdhaXQgdGhpcy5zdG9yYWdlLnVubG9nV2l0aFF1ZXJpZXIocXVlcmllciwgbWlncmF0aW9uLm5hbWUpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBxdWVyaWVyLmNvbW1pdFRyYW5zYWN0aW9uKCk7XG5cbiAgICAgIGNvbnN0IGR1cmF0aW9uID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICAgIHRoaXMubG9nZ2VyKGBNaWdyYXRpb24gJHttaWdyYXRpb24ubmFtZX0gJHtkaXJlY3Rpb24gPT09ICd1cCcgPyAnYXBwbGllZCcgOiAncmV2ZXJ0ZWQnfSBpbiAke2R1cmF0aW9ufW1zYCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IG1pZ3JhdGlvbi5uYW1lLFxuICAgICAgICBkaXJlY3Rpb24sXG4gICAgICAgIGR1cmF0aW9uLFxuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgcXVlcmllci5yb2xsYmFja1RyYW5zYWN0aW9uKCk7XG5cbiAgICAgIGNvbnN0IGR1cmF0aW9uID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICAgIHRoaXMubG9nZ2VyKGBNaWdyYXRpb24gJHttaWdyYXRpb24ubmFtZX0gZmFpbGVkOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogbWlncmF0aW9uLm5hbWUsXG4gICAgICAgIGRpcmVjdGlvbixcbiAgICAgICAgZHVyYXRpb24sXG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBlcnJvcjogZXJyb3IgYXMgRXJyb3IsXG4gICAgICB9O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgYSBuZXcgbWlncmF0aW9uIGZpbGVcbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlKG5hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgdGltZXN0YW1wID0gdGhpcy5nZXRUaW1lc3RhbXAoKTtcbiAgICBjb25zdCBmaWxlTmFtZSA9IGAke3RpbWVzdGFtcH1fJHt0aGlzLnNsdWdpZnkobmFtZSl9LnRzYDtcbiAgICBjb25zdCBmaWxlUGF0aCA9IGpvaW4odGhpcy5taWdyYXRpb25zUGF0aCwgZmlsZU5hbWUpO1xuXG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuZ2VuZXJhdGVNaWdyYXRpb25Db250ZW50KG5hbWUpO1xuXG4gICAgY29uc3QgeyB3cml0ZUZpbGUsIG1rZGlyIH0gPSBhd2FpdCBpbXBvcnQoJ25vZGU6ZnMvcHJvbWlzZXMnKTtcbiAgICBhd2FpdCBta2Rpcih0aGlzLm1pZ3JhdGlvbnNQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIGNvbnRlbnQsICd1dGYtOCcpO1xuXG4gICAgdGhpcy5sb2dnZXIoYENyZWF0ZWQgbWlncmF0aW9uOiAke2ZpbGVQYXRofWApO1xuICAgIHJldHVybiBmaWxlUGF0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIG1pZ3JhdGlvbiBiYXNlZCBvbiBlbnRpdHkgc2NoZW1hIGRpZmZlcmVuY2VzXG4gICAqL1xuICBhc3luYyBnZW5lcmF0ZUZyb21FbnRpdGllcyhuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGlmICghdGhpcy5zY2hlbWFHZW5lcmF0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2NoZW1hIGdlbmVyYXRvciBub3Qgc2V0LiBDYWxsIHNldFNjaGVtYUdlbmVyYXRvcigpIGZpcnN0LicpO1xuICAgIH1cblxuICAgIGNvbnN0IGRpZmZzID0gYXdhaXQgdGhpcy5nZXREaWZmcygpO1xuICAgIGNvbnN0IHVwU3RhdGVtZW50czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBkb3duU3RhdGVtZW50czogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZGlmZiBvZiBkaWZmcykge1xuICAgICAgaWYgKGRpZmYudHlwZSA9PT0gJ2NyZWF0ZScpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5maW5kRW50aXR5Rm9yVGFibGUoZGlmZi50YWJsZU5hbWUpO1xuICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgdXBTdGF0ZW1lbnRzLnB1c2godGhpcy5zY2hlbWFHZW5lcmF0b3IuZ2VuZXJhdGVDcmVhdGVUYWJsZShlbnRpdHkpKTtcbiAgICAgICAgICBkb3duU3RhdGVtZW50cy5wdXNoKHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlRHJvcFRhYmxlKGVudGl0eSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRpZmYudHlwZSA9PT0gJ2FsdGVyJykge1xuICAgICAgICBjb25zdCBhbHRlclN0YXRlbWVudHMgPSB0aGlzLnNjaGVtYUdlbmVyYXRvci5nZW5lcmF0ZUFsdGVyVGFibGUoZGlmZik7XG4gICAgICAgIHVwU3RhdGVtZW50cy5wdXNoKC4uLmFsdGVyU3RhdGVtZW50cyk7XG5cbiAgICAgICAgY29uc3QgYWx0ZXJEb3duU3RhdGVtZW50cyA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlQWx0ZXJUYWJsZURvd24oZGlmZik7XG4gICAgICAgIGRvd25TdGF0ZW1lbnRzLnB1c2goLi4uYWx0ZXJEb3duU3RhdGVtZW50cyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHVwU3RhdGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMubG9nZ2VyKCdObyBzY2hlbWEgY2hhbmdlcyBkZXRlY3RlZC4nKTtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBjb25zdCB0aW1lc3RhbXAgPSB0aGlzLmdldFRpbWVzdGFtcCgpO1xuICAgIGNvbnN0IGZpbGVOYW1lID0gYCR7dGltZXN0YW1wfV8ke3RoaXMuc2x1Z2lmeShuYW1lKX0udHNgO1xuICAgIGNvbnN0IGZpbGVQYXRoID0gam9pbih0aGlzLm1pZ3JhdGlvbnNQYXRoLCBmaWxlTmFtZSk7XG5cbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy5nZW5lcmF0ZU1pZ3JhdGlvbkNvbnRlbnRXaXRoU3RhdGVtZW50cyhuYW1lLCB1cFN0YXRlbWVudHMsIGRvd25TdGF0ZW1lbnRzLnJldmVyc2UoKSk7XG5cbiAgICBjb25zdCB7IHdyaXRlRmlsZSwgbWtkaXIgfSA9IGF3YWl0IGltcG9ydCgnbm9kZTpmcy9wcm9taXNlcycpO1xuICAgIGF3YWl0IG1rZGlyKHRoaXMubWlncmF0aW9uc1BhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGF3YWl0IHdyaXRlRmlsZShmaWxlUGF0aCwgY29udGVudCwgJ3V0Zi04Jyk7XG5cbiAgICB0aGlzLmxvZ2dlcihgQ3JlYXRlZCBtaWdyYXRpb24gZnJvbSBlbnRpdGllczogJHtmaWxlUGF0aH1gKTtcbiAgICByZXR1cm4gZmlsZVBhdGg7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBzY2hlbWEgZGlmZmVyZW5jZXMgYmV0d2VlbiBlbnRpdGllcyBhbmQgZGF0YWJhc2VcbiAgICovXG4gIGFzeW5jIGdldERpZmZzKCk6IFByb21pc2U8U2NoZW1hRGlmZltdPiB7XG4gICAgaWYgKCF0aGlzLnNjaGVtYUdlbmVyYXRvciB8fCAhdGhpcy5zY2hlbWFJbnRyb3NwZWN0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2NoZW1hIGdlbmVyYXRvciBhbmQgaW50cm9zcGVjdG9yIG11c3QgYmUgc2V0Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmVudGl0aWVzLmxlbmd0aCA+IDAgPyB0aGlzLmVudGl0aWVzIDogZ2V0RW50aXRpZXMoKTtcbiAgICBjb25zdCBkaWZmczogU2NoZW1hRGlmZltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgY29uc3QgbWV0YSA9IGdldE1ldGEoZW50aXR5KTtcbiAgICAgIGNvbnN0IHRhYmxlTmFtZSA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLnJlc29sdmVUYWJsZU5hbWUoZW50aXR5LCBtZXRhKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRTY2hlbWEgPSBhd2FpdCB0aGlzLnNjaGVtYUludHJvc3BlY3Rvci5nZXRUYWJsZVNjaGVtYSh0YWJsZU5hbWUpO1xuICAgICAgY29uc3QgZGlmZiA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmRpZmZTY2hlbWEoZW50aXR5LCBjdXJyZW50U2NoZW1hKTtcbiAgICAgIGlmIChkaWZmKSB7XG4gICAgICAgIGRpZmZzLnB1c2goZGlmZik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGRpZmZzO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kRW50aXR5Rm9yVGFibGUodGFibGVOYW1lOiBzdHJpbmcpOiBUeXBlPHVua25vd24+IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZW50aXRpZXMubGVuZ3RoID4gMCA/IHRoaXMuZW50aXRpZXMgOiBnZXRFbnRpdGllcygpO1xuICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XG4gICAgICBjb25zdCBtZXRhID0gZ2V0TWV0YShlbnRpdHkpO1xuICAgICAgY29uc3QgbmFtZSA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLnJlc29sdmVUYWJsZU5hbWUoZW50aXR5LCBtZXRhKTtcbiAgICAgIGlmIChuYW1lID09PSB0YWJsZU5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jIHNjaGVtYSBkaXJlY3RseSAoZm9yIGRldmVsb3BtZW50IG9ubHkgLSBub3QgZm9yIHByb2R1Y3Rpb24hKVxuICAgKi9cbiAgYXN5bmMgc3luYyhvcHRpb25zOiB7IGZvcmNlPzogYm9vbGVhbiB9ID0ge30pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAob3B0aW9ucy5mb3JjZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc3luY0ZvcmNlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmF1dG9TeW5jKHsgc2FmZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcm9wcyBhbmQgcmVjcmVhdGVzIGFsbCB0YWJsZXMgKERldmVsb3BtZW50IG9ubHkhKVxuICAgKi9cbiAgcHVibGljIGFzeW5jIHN5bmNGb3JjZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuc2NoZW1hR2VuZXJhdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjaGVtYSBnZW5lcmF0b3Igbm90IHNldC4gQ2FsbCBzZXRTY2hlbWFHZW5lcmF0b3IoKSBmaXJzdC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZW50aXRpZXMubGVuZ3RoID4gMCA/IHRoaXMuZW50aXRpZXMgOiBnZXRFbnRpdGllcygpO1xuICAgIGNvbnN0IHF1ZXJpZXIgPSBhd2FpdCB0aGlzLnF1ZXJpZXJQb29sLmdldFF1ZXJpZXIoKTtcblxuICAgIGlmICghaXNTcWxRdWVyaWVyKHF1ZXJpZXIpKSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlncmF0b3IgcmVxdWlyZXMgYSBTUUwtYmFzZWQgcXVlcmllcicpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLmJlZ2luVHJhbnNhY3Rpb24oKTtcblxuICAgICAgLy8gRHJvcCBhbGwgdGFibGVzIGZpcnN0IChpbiByZXZlcnNlIG9yZGVyIGZvciBmb3JlaWduIGtleXMpXG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBbLi4uZW50aXRpZXNdLnJldmVyc2UoKSkge1xuICAgICAgICBjb25zdCBkcm9wU3FsID0gdGhpcy5zY2hlbWFHZW5lcmF0b3IuZ2VuZXJhdGVEcm9wVGFibGUoZW50aXR5KTtcbiAgICAgICAgdGhpcy5sb2dnZXIoYEV4ZWN1dGluZzogJHtkcm9wU3FsfWApO1xuICAgICAgICBhd2FpdCBxdWVyaWVyLnJ1bihkcm9wU3FsKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ3JlYXRlIGFsbCB0YWJsZXNcbiAgICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVNxbCA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlQ3JlYXRlVGFibGUoZW50aXR5KTtcbiAgICAgICAgdGhpcy5sb2dnZXIoYEV4ZWN1dGluZzogJHtjcmVhdGVTcWx9YCk7XG4gICAgICAgIGF3YWl0IHF1ZXJpZXIucnVuKGNyZWF0ZVNxbCk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHF1ZXJpZXIuY29tbWl0VHJhbnNhY3Rpb24oKTtcbiAgICAgIHRoaXMubG9nZ2VyKCdTY2hlbWEgc3luYyAoZm9yY2UpIGNvbXBsZXRlZCcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJvbGxiYWNrVHJhbnNhY3Rpb24oKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2FmZWx5IHN5bmNocm9uaXplcyB0aGUgc2NoZW1hIGJ5IG9ubHkgYWRkaW5nIG1pc3NpbmcgdGFibGVzIGFuZCBjb2x1bW5zLlxuICAgKi9cbiAgYXN5bmMgYXV0b1N5bmMob3B0aW9uczogeyBzYWZlPzogYm9vbGVhbjsgZHJvcD86IGJvb2xlYW47IGxvZ2dpbmc/OiBib29sZWFuIH0gPSB7fSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5zY2hlbWFHZW5lcmF0b3IgfHwgIXRoaXMuc2NoZW1hSW50cm9zcGVjdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjaGVtYSBnZW5lcmF0b3IgYW5kIGludHJvc3BlY3RvciBtdXN0IGJlIHNldCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGRpZmZzID0gYXdhaXQgdGhpcy5nZXREaWZmcygpO1xuICAgIGNvbnN0IHN0YXRlbWVudHM6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGRpZmYgb2YgZGlmZnMpIHtcbiAgICAgIGlmIChkaWZmLnR5cGUgPT09ICdjcmVhdGUnKSB7XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZmluZEVudGl0eUZvclRhYmxlKGRpZmYudGFibGVOYW1lKTtcbiAgICAgICAgaWYgKGVudGl0eSkge1xuICAgICAgICAgIHN0YXRlbWVudHMucHVzaCh0aGlzLnNjaGVtYUdlbmVyYXRvci5nZW5lcmF0ZUNyZWF0ZVRhYmxlKGVudGl0eSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRpZmYudHlwZSA9PT0gJ2FsdGVyJykge1xuICAgICAgICBjb25zdCBmaWx0ZXJlZERpZmYgPSB0aGlzLmZpbHRlckRpZmYoZGlmZiwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGFsdGVyU3RhdGVtZW50cyA9IHRoaXMuc2NoZW1hR2VuZXJhdG9yLmdlbmVyYXRlQWx0ZXJUYWJsZShmaWx0ZXJlZERpZmYpO1xuICAgICAgICBzdGF0ZW1lbnRzLnB1c2goLi4uYWx0ZXJTdGF0ZW1lbnRzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhdGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmIChvcHRpb25zLmxvZ2dpbmcpIHRoaXMubG9nZ2VyKCdTY2hlbWEgaXMgYWxyZWFkeSBpbiBzeW5jLicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZXhlY3V0ZVN5bmNTdGF0ZW1lbnRzKHN0YXRlbWVudHMsIG9wdGlvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWx0ZXJEaWZmKGRpZmY6IFNjaGVtYURpZmYsIG9wdGlvbnM6IHsgc2FmZT86IGJvb2xlYW47IGRyb3A/OiBib29sZWFuIH0pOiBTY2hlbWFEaWZmIHtcbiAgICBjb25zdCBmaWx0ZXJlZERpZmYgPSB7IC4uLmRpZmYgfSBhcyB7IC1yZWFkb25seSBbSyBpbiBrZXlvZiBTY2hlbWFEaWZmXTogU2NoZW1hRGlmZltLXSB9O1xuICAgIGlmIChvcHRpb25zLnNhZmUgIT09IGZhbHNlKSB7XG4gICAgICAvLyBJbiBzYWZlIG1vZGUsIHdlIG9ubHkgYWxsb3cgYWRkaXRpb25zXG4gICAgICBkZWxldGUgZmlsdGVyZWREaWZmLmNvbHVtbnNUb0Ryb3A7XG4gICAgICBkZWxldGUgZmlsdGVyZWREaWZmLmluZGV4ZXNUb0Ryb3A7XG4gICAgICBkZWxldGUgZmlsdGVyZWREaWZmLmZvcmVpZ25LZXlzVG9Ecm9wO1xuICAgIH1cbiAgICBpZiAoIW9wdGlvbnMuZHJvcCkge1xuICAgICAgZGVsZXRlIGZpbHRlcmVkRGlmZi5jb2x1bW5zVG9Ecm9wO1xuICAgIH1cbiAgICByZXR1cm4gZmlsdGVyZWREaWZmO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlU3luY1N0YXRlbWVudHMoc3RhdGVtZW50czogc3RyaW5nW10sIG9wdGlvbnM6IHsgbG9nZ2luZz86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHF1ZXJpZXIgPSBhd2FpdCB0aGlzLnF1ZXJpZXJQb29sLmdldFF1ZXJpZXIoKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZGlhbGVjdCA9PT0gJ21vbmdvZGInKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZU1vbmdvU3luY1N0YXRlbWVudHMoc3RhdGVtZW50cywgb3B0aW9ucywgcXVlcmllciBhcyBNb25nb1F1ZXJpZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlU3FsU3luY1N0YXRlbWVudHMoc3RhdGVtZW50cywgb3B0aW9ucywgcXVlcmllcik7XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5sb2dnaW5nKSB0aGlzLmxvZ2dlcignU2NoZW1hIHN5bmNocm9uaXphdGlvbiBjb21wbGV0ZWQnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKHRoaXMuZGlhbGVjdCAhPT0gJ21vbmdvZGInICYmIGlzU3FsUXVlcmllcihxdWVyaWVyKSkge1xuICAgICAgICBhd2FpdCBxdWVyaWVyLnJvbGxiYWNrVHJhbnNhY3Rpb24oKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBxdWVyaWVyLnJlbGVhc2UoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVNb25nb1N5bmNTdGF0ZW1lbnRzKFxuICAgIHN0YXRlbWVudHM6IHN0cmluZ1tdLFxuICAgIG9wdGlvbnM6IHsgbG9nZ2luZz86IGJvb2xlYW4gfSxcbiAgICBxdWVyaWVyOiBNb25nb1F1ZXJpZXIsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRiID0gcXVlcmllci5kYjtcbiAgICBmb3IgKGNvbnN0IHN0bXQgb2Ygc3RhdGVtZW50cykge1xuICAgICAgY29uc3QgY21kID0gSlNPTi5wYXJzZShzdG10KSBhcyB7XG4gICAgICAgIGFjdGlvbjogc3RyaW5nO1xuICAgICAgICBuYW1lPzogc3RyaW5nO1xuICAgICAgICBjb2xsZWN0aW9uPzogc3RyaW5nO1xuICAgICAgICBpbmRleGVzPzogeyBuYW1lOiBzdHJpbmc7IGNvbHVtbnM6IHN0cmluZ1tdOyB1bmlxdWU/OiBib29sZWFuIH1bXTtcbiAgICAgICAga2V5PzogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbiAgICAgICAgb3B0aW9ucz86IGFueTtcbiAgICAgIH07XG4gICAgICBpZiAob3B0aW9ucy5sb2dnaW5nKSB0aGlzLmxvZ2dlcihgRXhlY3V0aW5nIE1vbmdvREI6ICR7c3RtdH1gKTtcblxuICAgICAgY29uc3QgY29sbGVjdGlvbk5hbWUgPSBjbWQubmFtZSB8fCBjbWQuY29sbGVjdGlvbjtcbiAgICAgIGlmICghY29sbGVjdGlvbk5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb25nb0RCIGNvbW1hbmQgbWlzc2luZyBjb2xsZWN0aW9uIG5hbWU6ICR7c3RtdH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbGxlY3Rpb24gPSBkYi5jb2xsZWN0aW9uKGNvbGxlY3Rpb25OYW1lKTtcblxuICAgICAgaWYgKGNtZC5hY3Rpb24gPT09ICdjcmVhdGVDb2xsZWN0aW9uJykge1xuICAgICAgICBhd2FpdCBkYi5jcmVhdGVDb2xsZWN0aW9uKGNtZC5uYW1lKTtcbiAgICAgICAgaWYgKGNtZC5pbmRleGVzPy5sZW5ndGgpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGlkeCBvZiBjbWQuaW5kZXhlcykge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gT2JqZWN0LmZyb21FbnRyaWVzKGlkeC5jb2x1bW5zLm1hcCgoYzogc3RyaW5nKSA9PiBbYywgMV0pKTtcbiAgICAgICAgICAgIGF3YWl0IGNvbGxlY3Rpb24uY3JlYXRlSW5kZXgoa2V5LCB7IHVuaXF1ZTogaWR4LnVuaXF1ZSwgbmFtZTogaWR4Lm5hbWUgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGNtZC5hY3Rpb24gPT09ICdkcm9wQ29sbGVjdGlvbicpIHtcbiAgICAgICAgYXdhaXQgY29sbGVjdGlvbi5kcm9wKCk7XG4gICAgICB9IGVsc2UgaWYgKGNtZC5hY3Rpb24gPT09ICdjcmVhdGVJbmRleCcpIHtcbiAgICAgICAgYXdhaXQgY29sbGVjdGlvbi5jcmVhdGVJbmRleChjbWQua2V5LCBjbWQub3B0aW9ucyk7XG4gICAgICB9IGVsc2UgaWYgKGNtZC5hY3Rpb24gPT09ICdkcm9wSW5kZXgnKSB7XG4gICAgICAgIGF3YWl0IGNvbGxlY3Rpb24uZHJvcEluZGV4KGNtZC5uYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVTcWxTeW5jU3RhdGVtZW50cyhcbiAgICBzdGF0ZW1lbnRzOiBzdHJpbmdbXSxcbiAgICBvcHRpb25zOiB7IGxvZ2dpbmc/OiBib29sZWFuIH0sXG4gICAgcXVlcmllcjogUXVlcmllcixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFpc1NxbFF1ZXJpZXIocXVlcmllcikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlncmF0b3IgcmVxdWlyZXMgYSBTUUwtYmFzZWQgcXVlcmllciBmb3IgdGhpcyBkaWFsZWN0Jyk7XG4gICAgfVxuICAgIGF3YWl0IHF1ZXJpZXIuYmVnaW5UcmFuc2FjdGlvbigpO1xuICAgIGZvciAoY29uc3Qgc3FsIG9mIHN0YXRlbWVudHMpIHtcbiAgICAgIGlmIChvcHRpb25zLmxvZ2dpbmcpIHRoaXMubG9nZ2VyKGBFeGVjdXRpbmc6ICR7c3FsfWApO1xuICAgICAgYXdhaXQgcXVlcmllci5ydW4oc3FsKTtcbiAgICB9XG4gICAgYXdhaXQgcXVlcmllci5jb21taXRUcmFuc2FjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBtaWdyYXRpb24gc3RhdHVzXG4gICAqL1xuICBhc3luYyBzdGF0dXMoKTogUHJvbWlzZTx7IHBlbmRpbmc6IHN0cmluZ1tdOyBleGVjdXRlZDogc3RyaW5nW10gfT4ge1xuICAgIGNvbnN0IFtwZW5kaW5nLCBleGVjdXRlZF0gPSBhd2FpdCBQcm9taXNlLmFsbChbdGhpcy5wZW5kaW5nKCkudGhlbigobSkgPT4gbS5tYXAoKHgpID0+IHgubmFtZSkpLCB0aGlzLmV4ZWN1dGVkKCldKTtcblxuICAgIHJldHVybiB7IHBlbmRpbmcsIGV4ZWN1dGVkIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IG1pZ3JhdGlvbiBmaWxlcyBmcm9tIHRoZSBtaWdyYXRpb25zIGRpcmVjdG9yeVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRNaWdyYXRpb25GaWxlcygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgcmVhZGRpcih0aGlzLm1pZ3JhdGlvbnNQYXRoKTtcbiAgICAgIHJldHVybiBmaWxlc1xuICAgICAgICAuZmlsdGVyKChmKSA9PiAvXFwuKHRzfGpzfG1qcykkLy50ZXN0KGYpKVxuICAgICAgICAuZmlsdGVyKChmKSA9PiAhZi5lbmRzV2l0aCgnLmQudHMnKSlcbiAgICAgICAgLnNvcnQoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKChlcnJvciBhcyBOb2RlSlMuRXJybm9FeGNlcHRpb24pLmNvZGUgPT09ICdFTk9FTlQnKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgbWlncmF0aW9uIGZyb20gYSBmaWxlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxvYWRNaWdyYXRpb24oZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8TWlncmF0aW9uIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBqb2luKHRoaXMubWlncmF0aW9uc1BhdGgsIGZpbGVOYW1lKTtcbiAgICBjb25zdCBmaWxlVXJsID0gcGF0aFRvRmlsZVVSTChmaWxlUGF0aCkuaHJlZjtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBpbXBvcnQoZmlsZVVybCk7XG4gICAgICBjb25zdCBtaWdyYXRpb24gPSBtb2R1bGUuZGVmYXVsdCA/PyBtb2R1bGU7XG5cbiAgICAgIGlmICh0aGlzLmlzTWlncmF0aW9uKG1pZ3JhdGlvbikpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lOiB0aGlzLmdldE1pZ3JhdGlvbk5hbWUoZmlsZU5hbWUpLFxuICAgICAgICAgIHVwOiBtaWdyYXRpb24udXAuYmluZChtaWdyYXRpb24pLFxuICAgICAgICAgIGRvd246IG1pZ3JhdGlvbi5kb3duLmJpbmQobWlncmF0aW9uKSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2dnZXIoYFdhcm5pbmc6ICR7ZmlsZU5hbWV9IGlzIG5vdCBhIHZhbGlkIG1pZ3JhdGlvbmApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5sb2dnZXIoYEVycm9yIGxvYWRpbmcgbWlncmF0aW9uICR7ZmlsZU5hbWV9OiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFuIG9iamVjdCBpcyBhIHZhbGlkIG1pZ3JhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBpc01pZ3JhdGlvbihvYmo6IHVua25vd24pOiBvYmogaXMgTWlncmF0aW9uRGVmaW5pdGlvbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmXG4gICAgICBvYmogIT09IHVuZGVmaW5lZCAmJlxuICAgICAgb2JqICE9PSBudWxsICYmXG4gICAgICB0eXBlb2YgKG9iaiBhcyBNaWdyYXRpb25EZWZpbml0aW9uKS51cCA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgdHlwZW9mIChvYmogYXMgTWlncmF0aW9uRGVmaW5pdGlvbikuZG93biA9PT0gJ2Z1bmN0aW9uJ1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBtaWdyYXRpb24gbmFtZSBmcm9tIGZpbGVuYW1lXG4gICAqL1xuICBwcml2YXRlIGdldE1pZ3JhdGlvbk5hbWUoZmlsZU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGJhc2VuYW1lKGZpbGVOYW1lLCBleHRuYW1lKGZpbGVOYW1lKSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgdGltZXN0YW1wIHN0cmluZyBmb3IgbWlncmF0aW9uIG5hbWVzXG4gICAqL1xuICBwcml2YXRlIGdldFRpbWVzdGFtcCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5vdy5nZXRGdWxsWWVhcigpLFxuICAgICAgU3RyaW5nKG5vdy5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKSxcbiAgICAgIFN0cmluZyhub3cuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpLFxuICAgICAgU3RyaW5nKG5vdy5nZXRIb3VycygpKS5wYWRTdGFydCgyLCAnMCcpLFxuICAgICAgU3RyaW5nKG5vdy5nZXRNaW51dGVzKCkpLnBhZFN0YXJ0KDIsICcwJyksXG4gICAgICBTdHJpbmcobm93LmdldFNlY29uZHMoKSkucGFkU3RhcnQoMiwgJzAnKSxcbiAgICBdLmpvaW4oJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBzbHVnIGZvciBmaWxlbmFtZXNcbiAgICovXG4gIHByaXZhdGUgc2x1Z2lmeSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0ZXh0XG4gICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgLnJlcGxhY2UoL1teYS16MC05XSsvZywgJ18nKVxuICAgICAgLnJlcGxhY2UoL15fK3xfKyQvZywgJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIG1pZ3JhdGlvbiBmaWxlIGNvbnRlbnRcbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVNaWdyYXRpb25Db250ZW50KG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIC8qdHMqLyBgaW1wb3J0IHR5cGUgeyBTcWxRdWVyaWVyIH0gZnJvbSAnQHVxbC9taWdyYXRlJztcblxuLyoqXG4gKiBNaWdyYXRpb246ICR7bmFtZX1cbiAqIENyZWF0ZWQ6ICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIGFzeW5jIHVwKHF1ZXJpZXI6IFNxbFF1ZXJpZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBBZGQgeW91ciBtaWdyYXRpb24gbG9naWMgaGVyZVxuICAgIC8vIEV4YW1wbGU6XG4gICAgLy8gYXdhaXQgcXVlcmllci5ydW4oXFxgXG4gICAgLy8gICBDUkVBVEUgVEFCTEUgXCJ1c2Vyc1wiIChcbiAgICAvLyAgICAgXCJpZFwiIFNFUklBTCBQUklNQVJZIEtFWSxcbiAgICAvLyAgICAgXCJuYW1lXCIgVkFSQ0hBUigyNTUpIE5PVCBOVUxMLFxuICAgIC8vICAgICBcImVtYWlsXCIgVkFSQ0hBUigyNTUpIFVOSVFVRSBOT1QgTlVMTCxcbiAgICAvLyAgICAgXCJjcmVhdGVkQXRcIiBUSU1FU1RBTVAgREVGQVVMVCBDVVJSRU5UX1RJTUVTVEFNUFxuICAgIC8vICAgKVxuICAgIC8vIFxcYCk7XG4gIH0sXG5cbiAgYXN5bmMgZG93bihxdWVyaWVyOiBTcWxRdWVyaWVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQWRkIHlvdXIgcm9sbGJhY2sgbG9naWMgaGVyZVxuICAgIC8vIEV4YW1wbGU6XG4gICAgLy8gYXdhaXQgcXVlcmllci5ydW4oXFxgRFJPUCBUQUJMRSBJRiBFWElTVFMgXCJ1c2Vyc1wiXFxgKTtcbiAgfSxcbn07XG5gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIG1pZ3JhdGlvbiBmaWxlIGNvbnRlbnQgd2l0aCBTUUwgc3RhdGVtZW50c1xuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZU1pZ3JhdGlvbkNvbnRlbnRXaXRoU3RhdGVtZW50cyhcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgdXBTdGF0ZW1lbnRzOiBzdHJpbmdbXSxcbiAgICBkb3duU3RhdGVtZW50czogc3RyaW5nW10sXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgdXBTcWwgPSB1cFN0YXRlbWVudHMubWFwKChzKSA9PiAvKnRzKi8gYCAgICBhd2FpdCBxdWVyaWVyLnJ1bihcXGAke3N9XFxgKTtgKS5qb2luKCdcXG4nKTtcbiAgICBjb25zdCBkb3duU3FsID0gZG93blN0YXRlbWVudHMubWFwKChzKSA9PiAvKnRzKi8gYCAgICBhd2FpdCBxdWVyaWVyLnJ1bihcXGAke3N9XFxgKTtgKS5qb2luKCdcXG4nKTtcblxuICAgIHJldHVybiAvKnRzKi8gYGltcG9ydCB0eXBlIHsgU3FsUXVlcmllciB9IGZyb20gJ0B1cWwvbWlncmF0ZSc7XG5cbi8qKlxuICogTWlncmF0aW9uOiAke25hbWV9XG4gKiBDcmVhdGVkOiAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1cbiAqIEdlbmVyYXRlZCBmcm9tIGVudGl0eSBkZWZpbml0aW9uc1xuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIGFzeW5jIHVwKHF1ZXJpZXI6IFNxbFF1ZXJpZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiR7dXBTcWx9XG4gIH0sXG5cbiAgYXN5bmMgZG93bihxdWVyaWVyOiBTcWxRdWVyaWVyKTogUHJvbWlzZTx2b2lkPiB7XG4ke2Rvd25TcWx9XG4gIH0sXG59O1xuYDtcbiAgfVxufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBkZWZpbmUgYSBtaWdyYXRpb24gd2l0aCBwcm9wZXIgdHlwaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVNaWdyYXRpb24obWlncmF0aW9uOiBNaWdyYXRpb25EZWZpbml0aW9uKTogTWlncmF0aW9uRGVmaW5pdGlvbiB7XG4gIHJldHVybiBtaWdyYXRpb247XG59XG4iXX0=