sonamu 0.5.7 → 0.7.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 (529) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +13 -2
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +71 -2
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +258 -2
  44. package/dist/api/config.d.ts +90 -0
  45. package/dist/api/config.d.ts.map +1 -0
  46. package/dist/api/config.js +25 -0
  47. package/dist/api/context.d.ts +4 -2
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +3 -2
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +235 -2
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +9 -2
  56. package/dist/api/sonamu.d.ts +10 -24
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +514 -2
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +6 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +15 -2
  65. package/dist/bin/cli.js +519 -2
  66. package/dist/bin/hot-hook-register.d.ts +11 -0
  67. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  68. package/dist/bin/hot-hook-register.js +21 -0
  69. package/dist/bin/loader-register.d.ts +2 -0
  70. package/dist/bin/loader-register.d.ts.map +1 -0
  71. package/dist/bin/loader-register.js +34 -0
  72. package/dist/database/_batch_update.d.ts +5 -3
  73. package/dist/database/_batch_update.d.ts.map +1 -1
  74. package/dist/database/_batch_update.js +95 -2
  75. package/dist/database/base-model.d.ts +96 -10
  76. package/dist/database/base-model.d.ts.map +1 -1
  77. package/dist/database/base-model.js +390 -2
  78. package/dist/database/base-model.types.d.ts +93 -0
  79. package/dist/database/base-model.types.d.ts.map +1 -0
  80. package/dist/database/base-model.types.js +10 -0
  81. package/dist/database/code-generator.d.ts +1 -1
  82. package/dist/database/code-generator.d.ts.map +1 -1
  83. package/dist/database/code-generator.js +54 -2
  84. package/dist/database/db.d.ts +6 -21
  85. package/dist/database/db.d.ts.map +1 -1
  86. package/dist/database/db.js +129 -2
  87. package/dist/database/puri-subset.test-d.js +81 -0
  88. package/dist/database/puri-subset.types.d.ts +123 -0
  89. package/dist/database/puri-subset.types.d.ts.map +1 -0
  90. package/dist/database/puri-subset.types.js +16 -0
  91. package/dist/database/puri-wrapper.d.ts +13 -11
  92. package/dist/database/puri-wrapper.d.ts.map +1 -1
  93. package/dist/database/puri-wrapper.js +109 -2
  94. package/dist/database/puri.d.ts +41 -23
  95. package/dist/database/puri.d.ts.map +1 -1
  96. package/dist/database/puri.js +601 -2
  97. package/dist/database/puri.types.d.ts +25 -6
  98. package/dist/database/puri.types.d.ts.map +1 -1
  99. package/dist/database/puri.types.js +6 -2
  100. package/dist/database/transaction-context.d.ts +1 -1
  101. package/dist/database/transaction-context.d.ts.map +1 -1
  102. package/dist/database/transaction-context.js +14 -2
  103. package/dist/database/upsert-builder.d.ts +9 -3
  104. package/dist/database/upsert-builder.d.ts.map +1 -1
  105. package/dist/database/upsert-builder.js +365 -2
  106. package/dist/entity/entity-manager.d.ts +167 -2
  107. package/dist/entity/entity-manager.d.ts.map +1 -1
  108. package/dist/entity/entity-manager.js +130 -2
  109. package/dist/entity/entity.d.ts +5 -3
  110. package/dist/entity/entity.d.ts.map +1 -1
  111. package/dist/entity/entity.js +750 -2
  112. package/dist/exceptions/error-handler.d.ts +1 -1
  113. package/dist/exceptions/error-handler.d.ts.map +1 -1
  114. package/dist/exceptions/error-handler.js +29 -2
  115. package/dist/exceptions/so-exceptions.d.ts +1 -1
  116. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  117. package/dist/exceptions/so-exceptions.js +85 -2
  118. package/dist/file-storage/driver.d.ts +1 -1
  119. package/dist/file-storage/driver.d.ts.map +1 -1
  120. package/dist/file-storage/driver.js +79 -2
  121. package/dist/file-storage/file-storage.js +75 -2
  122. package/dist/index.d.ts +18 -9
  123. package/dist/index.d.ts.map +1 -1
  124. package/dist/index.js +34 -2
  125. package/dist/migration/code-generation.d.ts +1 -1
  126. package/dist/migration/code-generation.d.ts.map +1 -1
  127. package/dist/migration/code-generation.js +614 -2
  128. package/dist/migration/migration-set.d.ts +2 -10
  129. package/dist/migration/migration-set.d.ts.map +1 -1
  130. package/dist/migration/migration-set.js +213 -2
  131. package/dist/migration/migrator.d.ts +24 -82
  132. package/dist/migration/migrator.d.ts.map +1 -1
  133. package/dist/migration/migrator.js +330 -2
  134. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  135. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  136. package/dist/migration/postgresql-schema-reader.js +245 -0
  137. package/dist/migration/types.d.ts +6 -38
  138. package/dist/migration/types.d.ts.map +1 -1
  139. package/dist/migration/types.js +3 -2
  140. package/dist/naite/messaging-types.d.ts +43 -0
  141. package/dist/naite/messaging-types.d.ts.map +1 -0
  142. package/dist/naite/messaging-types.js +7 -0
  143. package/dist/naite/naite-reporter.d.ts +41 -0
  144. package/dist/naite/naite-reporter.d.ts.map +1 -0
  145. package/dist/naite/naite-reporter.js +102 -0
  146. package/dist/naite/naite.d.ts +95 -0
  147. package/dist/naite/naite.d.ts.map +1 -0
  148. package/dist/naite/naite.js +316 -0
  149. package/dist/stream/index.js +3 -2
  150. package/dist/stream/sse.d.ts +2 -2
  151. package/dist/stream/sse.d.ts.map +1 -1
  152. package/dist/stream/sse.js +38 -2
  153. package/dist/syncer/api-parser.d.ts +10 -0
  154. package/dist/syncer/api-parser.d.ts.map +1 -0
  155. package/dist/syncer/api-parser.js +240 -0
  156. package/dist/syncer/checksum.d.ts +21 -0
  157. package/dist/syncer/checksum.d.ts.map +1 -0
  158. package/dist/syncer/checksum.js +98 -0
  159. package/dist/syncer/code-generator.d.ts +20 -0
  160. package/dist/syncer/code-generator.d.ts.map +1 -0
  161. package/dist/syncer/code-generator.js +161 -0
  162. package/dist/syncer/entity-operations.d.ts +17 -0
  163. package/dist/syncer/entity-operations.d.ts.map +1 -0
  164. package/dist/syncer/entity-operations.js +59 -0
  165. package/dist/syncer/file-patterns.d.ts +29 -0
  166. package/dist/syncer/file-patterns.d.ts.map +1 -0
  167. package/dist/syncer/file-patterns.js +38 -0
  168. package/dist/syncer/index.d.ts +6 -0
  169. package/dist/syncer/index.d.ts.map +1 -1
  170. package/dist/syncer/index.js +9 -2
  171. package/dist/syncer/module-loader.d.ts +35 -0
  172. package/dist/syncer/module-loader.d.ts.map +1 -0
  173. package/dist/syncer/module-loader.js +87 -0
  174. package/dist/syncer/syncer.d.ts +98 -106
  175. package/dist/syncer/syncer.d.ts.map +1 -1
  176. package/dist/syncer/syncer.js +422 -2
  177. package/dist/template/entity-converter.d.ts +14 -0
  178. package/dist/template/entity-converter.d.ts.map +1 -0
  179. package/dist/template/entity-converter.js +108 -0
  180. package/dist/template/helpers.d.ts +23 -0
  181. package/dist/template/helpers.d.ts.map +1 -0
  182. package/dist/template/helpers.js +64 -0
  183. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  184. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  185. package/dist/template/implementations/entity.template.js +86 -0
  186. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -4
  187. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  188. package/dist/template/implementations/generated.template.js +249 -0
  189. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -4
  190. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  191. package/dist/template/implementations/generated_http.template.js +131 -0
  192. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +4 -5
  193. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  194. package/dist/template/implementations/generated_sso.template.js +134 -0
  195. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  196. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  197. package/dist/template/implementations/init_types.template.js +38 -0
  198. package/dist/template/implementations/model.template.d.ts +17 -0
  199. package/dist/template/implementations/model.template.d.ts.map +1 -0
  200. package/dist/template/implementations/model.template.js +181 -0
  201. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  202. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  203. package/dist/template/implementations/model_test.template.js +35 -0
  204. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  205. package/dist/template/implementations/service.template.d.ts.map +1 -0
  206. package/dist/template/implementations/service.template.js +201 -0
  207. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  208. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  209. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  210. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  211. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  212. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  213. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  214. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  215. package/dist/template/implementations/view_enums_select.template.js +55 -0
  216. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  217. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  218. package/dist/template/implementations/view_form.template.js +337 -0
  219. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  220. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  221. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  222. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  223. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  224. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  225. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  226. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  227. package/dist/template/implementations/view_list.template.js +475 -0
  228. package/dist/template/implementations/view_list_columns.template.d.ts +17 -0
  229. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  230. package/dist/template/implementations/view_list_columns.template.js +49 -0
  231. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  232. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  233. package/dist/template/implementations/view_search_input.template.js +64 -0
  234. package/dist/template/index.d.ts +7 -0
  235. package/dist/template/index.d.ts.map +1 -0
  236. package/dist/template/index.js +8 -0
  237. package/dist/template/template-manager.d.ts +56 -0
  238. package/dist/template/template-manager.d.ts.map +1 -0
  239. package/dist/template/template-manager.js +125 -0
  240. package/dist/template/template-types.d.ts +16 -0
  241. package/dist/template/template-types.d.ts.map +1 -0
  242. package/dist/template/template-types.js +7 -0
  243. package/dist/template/template.d.ts +49 -0
  244. package/dist/template/template.d.ts.map +1 -0
  245. package/dist/template/template.js +60 -0
  246. package/dist/template/zod-converter.d.ts +51 -0
  247. package/dist/template/zod-converter.d.ts.map +1 -0
  248. package/dist/template/zod-converter.js +449 -0
  249. package/dist/testing/_relation-graph.d.ts +1 -1
  250. package/dist/testing/_relation-graph.d.ts.map +1 -1
  251. package/dist/testing/_relation-graph.js +89 -2
  252. package/dist/testing/fixture-manager.d.ts +42 -11
  253. package/dist/testing/fixture-manager.d.ts.map +1 -1
  254. package/dist/testing/fixture-manager.js +623 -2
  255. package/dist/types/types.d.ts +747 -143
  256. package/dist/types/types.d.ts.map +1 -1
  257. package/dist/types/types.js +546 -2
  258. package/dist/typings/knex.d.js +3 -2
  259. package/dist/utils/async-utils.d.ts +7 -0
  260. package/dist/utils/async-utils.d.ts.map +1 -1
  261. package/dist/utils/async-utils.js +57 -2
  262. package/dist/utils/console-util.d.ts +2 -0
  263. package/dist/utils/console-util.d.ts.map +1 -0
  264. package/dist/utils/console-util.js +6 -0
  265. package/dist/utils/controller.d.ts +1 -0
  266. package/dist/utils/controller.d.ts.map +1 -1
  267. package/dist/utils/controller.js +29 -2
  268. package/dist/utils/esm-utils.d.ts +39 -0
  269. package/dist/utils/esm-utils.d.ts.map +1 -0
  270. package/dist/utils/esm-utils.js +49 -0
  271. package/dist/utils/formatter.d.ts +3 -0
  272. package/dist/utils/formatter.d.ts.map +1 -0
  273. package/dist/utils/formatter.js +110 -0
  274. package/dist/utils/fs-utils.d.ts +1 -1
  275. package/dist/utils/fs-utils.d.ts.map +1 -1
  276. package/dist/utils/fs-utils.js +17 -2
  277. package/dist/utils/lodash-able.d.ts.map +1 -1
  278. package/dist/utils/lodash-able.js +6 -2
  279. package/dist/utils/model.js +22 -2
  280. package/dist/utils/object-utils.d.ts +44 -0
  281. package/dist/utils/object-utils.d.ts.map +1 -0
  282. package/dist/utils/object-utils.js +191 -0
  283. package/dist/utils/path-utils.d.ts +89 -0
  284. package/dist/utils/path-utils.d.ts.map +1 -0
  285. package/dist/utils/path-utils.js +60 -0
  286. package/dist/utils/process-utils.d.ts +13 -0
  287. package/dist/utils/process-utils.d.ts.map +1 -0
  288. package/dist/utils/process-utils.js +36 -0
  289. package/dist/utils/sql-parser.d.ts +5 -1
  290. package/dist/utils/sql-parser.d.ts.map +1 -1
  291. package/dist/utils/sql-parser.js +46 -2
  292. package/dist/utils/type-utils.d.ts +23 -0
  293. package/dist/utils/type-utils.d.ts.map +1 -0
  294. package/dist/utils/type-utils.js +45 -0
  295. package/dist/utils/utils.d.ts +10 -7
  296. package/dist/utils/utils.d.ts.map +1 -1
  297. package/dist/utils/utils.js +72 -2
  298. package/dist/utils/zod-error.d.ts +1 -1
  299. package/dist/utils/zod-error.d.ts.map +1 -1
  300. package/dist/utils/zod-error.js +19 -2
  301. package/package.json +65 -27
  302. package/src/ai/agents/agent.ts +87 -0
  303. package/src/ai/agents/index.ts +2 -0
  304. package/src/ai/agents/types.ts +47 -0
  305. package/src/ai/index.ts +1 -0
  306. package/src/ai/providers/rtzr/api.ts +37 -0
  307. package/src/ai/providers/rtzr/error.ts +34 -0
  308. package/src/ai/providers/rtzr/index.ts +4 -0
  309. package/src/ai/providers/rtzr/model.ts +201 -0
  310. package/src/ai/providers/rtzr/options.ts +49 -0
  311. package/src/ai/providers/rtzr/provider.ts +91 -0
  312. package/src/ai/providers/rtzr/utils.ts +127 -0
  313. package/src/api/base-frame.ts +4 -2
  314. package/src/api/caster.ts +17 -23
  315. package/src/api/code-converters.ts +178 -535
  316. package/src/api/config.ts +125 -0
  317. package/src/api/context.ts +7 -17
  318. package/src/api/decorators.ts +176 -46
  319. package/src/api/index.ts +2 -2
  320. package/src/api/sonamu.ts +190 -167
  321. package/src/api/validator.ts +83 -0
  322. package/src/bin/build-config.ts +8 -1
  323. package/src/bin/cli.ts +258 -124
  324. package/src/bin/hot-hook-register.ts +22 -0
  325. package/src/bin/loader-register.ts +38 -0
  326. package/src/database/_batch_update.ts +46 -31
  327. package/src/database/base-model.ts +390 -182
  328. package/src/database/base-model.types.ts +155 -0
  329. package/src/database/code-generator.ts +13 -32
  330. package/src/database/db.ts +40 -96
  331. package/src/database/puri-subset.test-d.ts +471 -0
  332. package/src/database/puri-subset.types.ts +195 -0
  333. package/src/database/puri-wrapper.ts +58 -67
  334. package/src/database/puri.ts +229 -148
  335. package/src/database/puri.types.ts +76 -30
  336. package/src/database/transaction-context.ts +1 -1
  337. package/src/database/upsert-builder.ts +262 -132
  338. package/src/entity/entity-manager.ts +48 -36
  339. package/src/entity/entity.ts +330 -248
  340. package/src/exceptions/error-handler.ts +3 -3
  341. package/src/exceptions/so-exceptions.ts +11 -11
  342. package/src/file-storage/driver.ts +5 -5
  343. package/src/file-storage/file-storage.ts +2 -2
  344. package/src/index.ts +18 -10
  345. package/src/migration/code-generation.ts +185 -172
  346. package/src/migration/migration-set.ts +80 -293
  347. package/src/migration/migrator.ts +199 -571
  348. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  349. package/src/migration/postgresql-schema-reader.ts +310 -0
  350. package/src/migration/types.ts +6 -39
  351. package/src/naite/messaging-types.ts +51 -0
  352. package/src/naite/naite-reporter.ts +128 -0
  353. package/src/naite/naite.ts +415 -0
  354. package/src/shared/web.shared.ts.txt +20 -24
  355. package/src/stream/sse.ts +5 -5
  356. package/src/syncer/api-parser.ts +282 -0
  357. package/src/syncer/checksum.ts +140 -0
  358. package/src/syncer/code-generator.ts +198 -0
  359. package/src/syncer/entity-operations.ts +65 -0
  360. package/src/syncer/file-patterns.ts +56 -0
  361. package/src/syncer/index.ts +6 -0
  362. package/src/syncer/module-loader.ts +128 -0
  363. package/src/syncer/syncer.ts +389 -1453
  364. package/src/template/entity-converter.ts +114 -0
  365. package/src/template/helpers.ts +81 -0
  366. package/src/{templates → template/implementations}/entity.template.ts +7 -7
  367. package/src/{templates → template/implementations}/generated.template.ts +101 -101
  368. package/src/{templates → template/implementations}/generated_http.template.ts +27 -57
  369. package/src/template/implementations/generated_sso.template.ts +151 -0
  370. package/src/{templates → template/implementations}/init_types.template.ts +5 -7
  371. package/src/{templates → template/implementations}/model.template.ts +52 -43
  372. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  373. package/src/{templates → template/implementations}/service.template.ts +66 -82
  374. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  375. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +4 -20
  376. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  377. package/src/{templates → template/implementations}/view_form.template.ts +40 -83
  378. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  379. package/src/{templates → template/implementations}/view_id_async_select.template.ts +10 -24
  380. package/src/{templates → template/implementations}/view_list.template.ts +60 -152
  381. package/src/{templates → template/implementations}/view_list_columns.template.ts +5 -11
  382. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  383. package/src/template/index.ts +6 -0
  384. package/src/template/template-manager.ts +166 -0
  385. package/src/template/template-types.ts +16 -0
  386. package/src/template/template.ts +105 -0
  387. package/src/template/zod-converter.ts +525 -0
  388. package/src/testing/_relation-graph.ts +18 -11
  389. package/src/testing/fixture-manager.ts +472 -359
  390. package/src/types/types.ts +553 -308
  391. package/src/typings/knex.d.ts +7 -9
  392. package/src/utils/async-utils.ts +23 -10
  393. package/src/utils/console-util.ts +4 -0
  394. package/src/utils/controller.ts +3 -0
  395. package/src/utils/esm-utils.ts +59 -0
  396. package/src/utils/formatter.ts +109 -0
  397. package/src/utils/fs-utils.ts +1 -1
  398. package/src/utils/lodash-able.ts +1 -4
  399. package/src/utils/object-utils.ts +217 -0
  400. package/src/utils/path-utils.ts +99 -0
  401. package/src/utils/process-utils.ts +46 -0
  402. package/src/utils/sql-parser.ts +23 -5
  403. package/src/utils/type-utils.ts +83 -0
  404. package/src/utils/utils.ts +66 -43
  405. package/src/utils/zod-error.ts +3 -4
  406. package/dist/api/base-frame.js.map +0 -1
  407. package/dist/api/caster.js.map +0 -1
  408. package/dist/api/code-converters.js.map +0 -1
  409. package/dist/api/context.js.map +0 -1
  410. package/dist/api/decorators.js.map +0 -1
  411. package/dist/api/index.js.map +0 -1
  412. package/dist/api/sonamu.js.map +0 -1
  413. package/dist/bin/build-config.js.map +0 -1
  414. package/dist/bin/cli-wrapper.d.ts +0 -3
  415. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  416. package/dist/bin/cli-wrapper.js +0 -3
  417. package/dist/bin/cli-wrapper.js.map +0 -1
  418. package/dist/bin/cli.js.map +0 -1
  419. package/dist/database/_batch_update.js.map +0 -1
  420. package/dist/database/base-model.js.map +0 -1
  421. package/dist/database/code-generator.js.map +0 -1
  422. package/dist/database/db.js.map +0 -1
  423. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  424. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  425. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -2
  426. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  427. package/dist/database/puri-wrapper.js.map +0 -1
  428. package/dist/database/puri.js.map +0 -1
  429. package/dist/database/puri.types.js.map +0 -1
  430. package/dist/database/transaction-context.js.map +0 -1
  431. package/dist/database/upsert-builder.js.map +0 -1
  432. package/dist/entity/entity-manager.js.map +0 -1
  433. package/dist/entity/entity-utils.d.ts +0 -61
  434. package/dist/entity/entity-utils.d.ts.map +0 -1
  435. package/dist/entity/entity-utils.js +0 -2
  436. package/dist/entity/entity-utils.js.map +0 -1
  437. package/dist/entity/entity.js.map +0 -1
  438. package/dist/exceptions/error-handler.js.map +0 -1
  439. package/dist/exceptions/so-exceptions.js.map +0 -1
  440. package/dist/file-storage/driver.js.map +0 -1
  441. package/dist/file-storage/file-storage.js.map +0 -1
  442. package/dist/index.js.map +0 -1
  443. package/dist/migration/code-generation.js.map +0 -1
  444. package/dist/migration/migration-set.js.map +0 -1
  445. package/dist/migration/migrator.js.map +0 -1
  446. package/dist/migration/types.js.map +0 -1
  447. package/dist/stream/index.js.map +0 -1
  448. package/dist/stream/sse.js.map +0 -1
  449. package/dist/syncer/index.js.map +0 -1
  450. package/dist/syncer/syncer.js.map +0 -1
  451. package/dist/templates/base-template.d.ts +0 -13
  452. package/dist/templates/base-template.d.ts.map +0 -1
  453. package/dist/templates/base-template.js +0 -2
  454. package/dist/templates/base-template.js.map +0 -1
  455. package/dist/templates/entity.template.d.ts.map +0 -1
  456. package/dist/templates/entity.template.js +0 -2
  457. package/dist/templates/entity.template.js.map +0 -1
  458. package/dist/templates/generated.template.d.ts.map +0 -1
  459. package/dist/templates/generated.template.js +0 -2
  460. package/dist/templates/generated.template.js.map +0 -1
  461. package/dist/templates/generated_http.template.d.ts.map +0 -1
  462. package/dist/templates/generated_http.template.js +0 -2
  463. package/dist/templates/generated_http.template.js.map +0 -1
  464. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  465. package/dist/templates/generated_sso.template.js +0 -2
  466. package/dist/templates/generated_sso.template.js.map +0 -1
  467. package/dist/templates/index.d.ts +0 -2
  468. package/dist/templates/index.d.ts.map +0 -1
  469. package/dist/templates/index.js +0 -2
  470. package/dist/templates/index.js.map +0 -1
  471. package/dist/templates/init_types.template.d.ts.map +0 -1
  472. package/dist/templates/init_types.template.js +0 -2
  473. package/dist/templates/init_types.template.js.map +0 -1
  474. package/dist/templates/model.template.d.ts +0 -17
  475. package/dist/templates/model.template.d.ts.map +0 -1
  476. package/dist/templates/model.template.js +0 -2
  477. package/dist/templates/model.template.js.map +0 -1
  478. package/dist/templates/model_test.template.d.ts.map +0 -1
  479. package/dist/templates/model_test.template.js +0 -2
  480. package/dist/templates/model_test.template.js.map +0 -1
  481. package/dist/templates/service.template.d.ts.map +0 -1
  482. package/dist/templates/service.template.js +0 -2
  483. package/dist/templates/service.template.js.map +0 -1
  484. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  485. package/dist/templates/view_enums_buttonset.template.js +0 -2
  486. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  487. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  488. package/dist/templates/view_enums_dropdown.template.js +0 -2
  489. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  490. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  491. package/dist/templates/view_enums_select.template.js +0 -2
  492. package/dist/templates/view_enums_select.template.js.map +0 -1
  493. package/dist/templates/view_form.template.d.ts.map +0 -1
  494. package/dist/templates/view_form.template.js +0 -2
  495. package/dist/templates/view_form.template.js.map +0 -1
  496. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  497. package/dist/templates/view_id_all_select.template.js +0 -2
  498. package/dist/templates/view_id_all_select.template.js.map +0 -1
  499. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  500. package/dist/templates/view_id_async_select.template.js +0 -2
  501. package/dist/templates/view_id_async_select.template.js.map +0 -1
  502. package/dist/templates/view_list.template.d.ts.map +0 -1
  503. package/dist/templates/view_list.template.js +0 -2
  504. package/dist/templates/view_list.template.js.map +0 -1
  505. package/dist/templates/view_list_columns.template.d.ts +0 -17
  506. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  507. package/dist/templates/view_list_columns.template.js +0 -2
  508. package/dist/templates/view_list_columns.template.js.map +0 -1
  509. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  510. package/dist/templates/view_search_input.template.js +0 -2
  511. package/dist/templates/view_search_input.template.js.map +0 -1
  512. package/dist/testing/_relation-graph.js.map +0 -1
  513. package/dist/testing/fixture-manager.js.map +0 -1
  514. package/dist/types/types.js.map +0 -1
  515. package/dist/typings/knex.d.js.map +0 -1
  516. package/dist/utils/async-utils.js.map +0 -1
  517. package/dist/utils/controller.js.map +0 -1
  518. package/dist/utils/fs-utils.js.map +0 -1
  519. package/dist/utils/lodash-able.js.map +0 -1
  520. package/dist/utils/model.js.map +0 -1
  521. package/dist/utils/sql-parser.js.map +0 -1
  522. package/dist/utils/utils.js.map +0 -1
  523. package/dist/utils/zod-error.js.map +0 -1
  524. package/src/bin/cli-wrapper.ts +0 -75
  525. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  526. package/src/entity/entity-utils.ts +0 -291
  527. package/src/templates/base-template.ts +0 -19
  528. package/src/templates/generated_sso.template.ts +0 -138
  529. package/src/templates/index.ts +0 -1
@@ -1,2 +1,390 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});function _export(target,all){for(var name in all)Object.defineProperty(target,name,{enumerable:true,get:Object.getOwnPropertyDescriptor(all,name).get})}_export(exports,{get BaseModel(){return BaseModel},get BaseModelClass(){return BaseModelClass}});var _luxon=require("luxon");var _lodash=require("lodash");var _db=require("./db");var _types=require("../types/types");var _inflection=/*#__PURE__*/_interop_require_default(require("inflection"));var _chalk=/*#__PURE__*/_interop_require_default(require("chalk"));var _upsertbuilder=require("./upsert-builder");var _nodesqlparser=/*#__PURE__*/_interop_require_default(require("node-sql-parser"));var _sqlparser=require("../utils/sql-parser");var _puriwrapper=require("./puri-wrapper");function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["return"]=verb(2),typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]<t[3])){_.label=op[1];break}if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break}if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break}if(t[2])_.ops.pop();_.trys.pop();continue}op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0}if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true}}}function _ts_values(o){var s=typeof Symbol==="function"&&Symbol.iterator,m=s&&o[s],i=0;if(m)return m.call(o);if(o&&typeof o.length==="number")return{next:function(){if(o&&i>=o.length)o=void 0;return{value:o&&o[i++],done:!o}}};throw new TypeError(s?"Object is not iterable.":"Symbol.iterator is not defined.")}var BaseModelClass=/*#__PURE__*/function(){"use strict";function BaseModelClass(){_class_call_check(this,BaseModelClass);_define_property(this,"modelName","Unknown")}_create_class(BaseModelClass,[{key:"getDB",value:function getDB(which){return _db.DB.getDB(which)}},{key:"getPuri",value:function getPuri(which){var trx=_db.DB.getTransactionContext().getTransaction(which);if(trx){return trx}var db=this.getDB(which);return new _puriwrapper.PuriWrapper(db,this.getUpsertBuilder())}},{key:"destroy",value:function destroy(){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,_db.DB.destroy()]})})()}},{key:"myNow",value:function myNow(timestamp){var dt=timestamp===undefined?_luxon.DateTime.local():_luxon.DateTime.fromSeconds(timestamp);return dt.toFormat("yyyy-MM-dd HH:mm:ss")}},{key:"getInsertedIds",value:function getInsertedIds(wdb,rows,tableName,unqKeyFields){var chunkSize=arguments.length>4&&arguments[4]!==void 0?arguments[4]:500;return _async_to_generator(function(){var unqKeys,whereInField,selectField,chunks,resultIds,_iteratorNormalCompletion,_didIteratorError,_iteratorError,_iterator,_step,_$chunk,dbRows,err;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(!wdb){wdb=this.getDB("w")}if(unqKeyFields.length>1){whereInField=wdb.raw("CONCAT_WS('_', '".concat(unqKeyFields.join(","),"')"));selectField="".concat(whereInField," as tmpUid");unqKeys=rows.map(function(row){return unqKeyFields.map(function(field){return row[field]}).join("_")})}else{whereInField=unqKeyFields[0];selectField=unqKeyFields[0];unqKeys=rows.map(function(row){return row[unqKeyFields[0]]})}chunks=(0,_lodash.chunk)(unqKeys,chunkSize);resultIds=[];_iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;_state.label=1;case 1:_state.trys.push([1,6,7,8]);_iterator=chunks[Symbol.iterator]();_state.label=2;case 2:if(!!(_iteratorNormalCompletion=(_step=_iterator.next()).done))return[3,5];_$chunk=_step.value;return[4,wdb(tableName).select("id",wdb.raw(selectField)).whereIn(whereInField,_$chunk)];case 3:dbRows=_state.sent();resultIds=resultIds.concat(dbRows.map(function(dbRow){return parseInt(dbRow.id)}));_state.label=4;case 4:_iteratorNormalCompletion=true;return[3,2];case 5:return[3,8];case 6:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,8];case 7:try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}return[7];case 8:return[2,resultIds]}})}).call(this)}},{key:"useLoaders",value:function useLoaders(db,rows,loaders){return _async_to_generator(function(){var _this,_iteratorNormalCompletion,_didIteratorError,_iteratorError,_this1,_loop,_iterator,_step,err;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;if(loaders.length===0){return[2,rows]}_iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;_state.label=1;case 1:_state.trys.push([1,6,7,8]);_loop=function(){var loader,subQ,subRows,toCol,fromIds,idColumn,idColumn1,subRowGroups;return _ts_generator(this,function(_state){switch(_state.label){case 0:loader=_step.value;subQ=void 0;subRows=void 0;toCol=void 0;fromIds=rows.map(function(row){return row[loader.manyJoin.idField]});if(loader.manyJoin.through===undefined){idColumn="".concat(loader.manyJoin.toTable,".").concat(loader.manyJoin.toCol);subQ=db(loader.manyJoin.toTable).whereIn(idColumn,fromIds).select(_to_consumable_array(loader.select).concat([idColumn]));loader.oneJoins.map(function(join){if(join.join=="inner"){subQ.innerJoin("".concat(join.table," as ").concat(join.as),_this.getJoinClause(db,join))}else if(join.join=="outer"){subQ.leftOuterJoin("".concat(join.table," as ").concat(join.as),_this.getJoinClause(db,join))}});toCol=loader.manyJoin.toCol}else{idColumn1="".concat(loader.manyJoin.through.table,".").concat(loader.manyJoin.through.fromCol);subQ=db(loader.manyJoin.through.table).join(loader.manyJoin.toTable,"".concat(loader.manyJoin.through.table,".").concat(loader.manyJoin.through.toCol),"".concat(loader.manyJoin.toTable,".").concat(loader.manyJoin.toCol)).whereIn(idColumn1,fromIds).select((0,_lodash.uniq)(_to_consumable_array(loader.select).concat([idColumn1])));loader.oneJoins.map(function(join){if(join.join=="inner"){subQ.innerJoin("".concat(join.table," as ").concat(join.as),_this.getJoinClause(db,join))}else if(join.join=="outer"){subQ.leftOuterJoin("".concat(join.table," as ").concat(join.as),_this.getJoinClause(db,join))}});toCol=loader.manyJoin.through.fromCol}return[4,subQ];case 1:subRows=_state.sent();if(!loader.loaders)return[3,3];return[4,_this1.useLoaders(db,subRows,loader.loaders)];case 2:subRows=_state.sent();_state.label=3;case 3:subRowGroups=(0,_lodash.groupBy)(subRows,toCol);rows=rows.map(function(row){var _subRowGroups_row_loader_manyJoin_idField;row[loader.as]=((_subRowGroups_row_loader_manyJoin_idField=subRowGroups[row[loader.manyJoin.idField]])!==null&&_subRowGroups_row_loader_manyJoin_idField!==void 0?_subRowGroups_row_loader_manyJoin_idField:[]).map(function(r){return(0,_lodash.omit)(r,toCol)});return row});return[2]}})};_iterator=loaders[Symbol.iterator]();_state.label=2;case 2:if(!!(_iteratorNormalCompletion=(_step=_iterator.next()).done))return[3,5];_this1=this;return[5,_ts_values(_loop())];case 3:_state.sent();_state.label=4;case 4:_iteratorNormalCompletion=true;return[3,2];case 5:return[3,8];case 6:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,8];case 7:try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}return[7];case 8:return[2,rows]}})}).call(this)}},{key:"hydrate",value:function hydrate(rows){var _this=this;return rows.map(function(row){var nestedKeys=Object.keys(row).filter(function(key){return key.includes("__")});var groups=(0,_lodash.groupBy)(nestedKeys,function(key){return key.split("__")[0]});var nullKeys=Object.keys(groups).filter(function(key){return groups[key].length>1&&groups[key].every(function(field){return row[field]===null||Array.isArray(row[field])&&row[field].length===0})});var hydrated=Object.keys(row).reduce(function(r,field){if(!field.includes("__")){if(Array.isArray(row[field])&&(0,_lodash.isObject)(row[field][0])){r[field]=_this.hydrate(row[field]);return r}else{r[field]=row[field];return r}}var parts=field.split("__");var objPath=parts[0]+parts.slice(1).map(function(part){return"[".concat(part,"]")}).join("");(0,_lodash.set)(r,objPath,row[field]&&Array.isArray(row[field])&&(0,_lodash.isObject)(row[field][0])?_this.hydrate(row[field]):row[field]);return r},{});nullKeys.map(function(nullKey){return hydrated[nullKey]=null});return hydrated})}},{key:"runSubsetQuery",value:function runSubsetQuery(_0){return _async_to_generator(function(param){var _this,params,baseTable,subset,subsetQuery,build,afterBuild,debug,_db,optimizeCountQuery,db,_params_queryMode,queryMode,select,virtual,joins,loaders,qb,applyJoinClause,total,rows;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;params=param.params,baseTable=param.baseTable,subset=param.subset,subsetQuery=param.subsetQuery,build=param.build,afterBuild=param.afterBuild,debug=param.debug,_db=param.db,optimizeCountQuery=param.optimizeCountQuery;db=_db!==null&&_db!==void 0?_db:this.getDB(subset.startsWith("A")?"w":"r");baseTable=baseTable!==null&&baseTable!==void 0?baseTable:_inflection.default.pluralize(_inflection.default.underscore(this.modelName));queryMode=(_params_queryMode=params.queryMode)!==null&&_params_queryMode!==void 0?_params_queryMode:params.id!==undefined?"list":"both";select=subsetQuery.select,virtual=subsetQuery.virtual,joins=subsetQuery.joins,loaders=subsetQuery.loaders;qb=build({qb:db.from(baseTable),db:db,select:select,joins:joins,virtual:virtual});applyJoinClause=function(qb,joins){joins.map(function(join){if(join.join=="inner"){qb.innerJoin("".concat(join.table," as ").concat(join.as),_this.getJoinClause(db,join))}else if(join.join=="outer"){qb.leftOuterJoin("".concat(join.table," as ").concat(join.as),_this.getJoinClause(db,join))}})};return[4,function(){return _async_to_generator(function(){var clonedQb,parser,parsedQuery,tables,needToJoin,_afterBuild,processedQb,parsedQuery1,q,countQuery,countRow,_countRow_total;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(queryMode==="list"){return[2,undefined]}clonedQb=qb.clone().clear("order").clear("offset").clear("limit");parser=new _nodesqlparser.default.Parser;if(optimizeCountQuery){parsedQuery=parser.astify(clonedQb.toQuery());tables=(0,_sqlparser.getTableNamesFromWhere)(parsedQuery);needToJoin=(0,_lodash.uniq)(tables.flatMap(function(table){return table.split("__").map(function(t){return _inflection.default.pluralize(t)})}));applyJoinClause(clonedQb,joins.filter(function(j){return needToJoin.includes(j.table)}))}else{applyJoinClause(clonedQb,joins)}processedQb=(_afterBuild=afterBuild===null||afterBuild===void 0?void 0:afterBuild({qb:clonedQb,db:db,select:select,joins:joins,virtual:virtual}))!==null&&_afterBuild!==void 0?_afterBuild:clonedQb;parsedQuery1=parser.astify(processedQb.toQuery());q=Array.isArray(parsedQuery1)?parsedQuery1[0]:parsedQuery1;if(q.type!=="select"){throw new Error("Invalid query")}countQuery=q.distinct!==null?clonedQb.clear("select").select(db.raw("COUNT(DISTINCT `".concat((0,_sqlparser.getTableName)(q.columns[0].expr),"`.`").concat(q.columns[0].expr.column,"`) as total"))).first():clonedQb.clear("select").count("*",{as:"total"}).first();return[4,countQuery];case 1:countRow=_state.sent();if(debug===true||debug==="count"){console.debug("DEBUG: count query",_chalk.default.blue(countQuery.toQuery().toString()))}return[2,(_countRow_total=countRow===null||countRow===void 0?void 0:countRow.total)!==null&&_countRow_total!==void 0?_countRow_total:0]}})})()}()];case 1:total=_state.sent();return[4,function(){return _async_to_generator(function(){var clonedQb,_afterBuild,listQuery,rows;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(queryMode==="count"){return[2,[]]}if(params.num!==0){qb.limit(params.num);qb.offset(params.num*(params.page-1))}clonedQb=qb.clone().select(select);applyJoinClause(clonedQb,joins);listQuery=(_afterBuild=afterBuild===null||afterBuild===void 0?void 0:afterBuild({qb:clonedQb,db:db,select:select,joins:joins,virtual:virtual}))!==null&&_afterBuild!==void 0?_afterBuild:clonedQb;return[4,listQuery];case 1:rows=_state.sent();if(debug===true||debug==="list"){console.debug("DEBUG: list query",_chalk.default.blue(listQuery.toQuery().toString()))}return[4,this.useLoaders(db,rows,loaders)];case 2:rows=_state.sent();rows=this.hydrate(rows);return[2,rows]}})}).call(_this)}()];case 2:rows=_state.sent();return[2,{rows:rows,total:total,subsetQuery:subsetQuery,qb:qb}]}})}).apply(this,arguments)}},{key:"getJoinClause",value:function getJoinClause(db,join){if(!(0,_types.isCustomJoinClause)(join)){return db.raw("".concat(join.from," = ").concat(join.to))}else{return db.raw(join.custom)}}},{key:"getUpsertBuilder",value:function getUpsertBuilder(){return new _upsertbuilder.UpsertBuilder}}]);return BaseModelClass}();var BaseModel=new BaseModelClass;
2
- //# sourceMappingURL=base-model.js.map
1
+ import assert from "assert";
2
+ import inflection from "inflection";
3
+ import { group, isObject, omit, set, unique } from "radashi";
4
+ import { Sonamu } from "../api/index.js";
5
+ import { isCustomJoinClause } from "../types/types.js";
6
+ import { getJoinTables, getTableNamesFromWhere } from "../utils/sql-parser.js";
7
+ import { chunk } from "../utils/utils.js";
8
+ import { DB } from "./db.js";
9
+ import { Puri } from "./puri.js";
10
+ import { PuriWrapper } from "./puri-wrapper.js";
11
+ import { UpsertBuilder } from "./upsert-builder.js";
12
+ /**
13
+ * 모든 Model 클래스의 기본 클래스
14
+ *
15
+ * @template TSubsetKey - 서브셋 키 유니온 (예: "A" | "P" | "SS")
16
+ * @template TSubsetMapping - 서브셋별 최종 결과 타입 매핑
17
+ * @template TSubsetQueries - 서브셋 쿼리 함수 객체
18
+ * @template TLoaderQueries - 서브셋별 로더 쿼리 배열 객체
19
+ */ export class BaseModelClass {
20
+ subsetQueries;
21
+ loaderQueries;
22
+ modelName = "Unknown";
23
+ constructor(subsetQueries, loaderQueries){
24
+ this.subsetQueries = subsetQueries;
25
+ this.loaderQueries = loaderQueries;
26
+ }
27
+ getDB(which) {
28
+ return DB.getDB(which);
29
+ }
30
+ getPuri(which) {
31
+ // 트랜잭션 컨텍스트에서 트랜잭션 획득
32
+ const trx = DB.getTransactionContext().getTransaction(which);
33
+ if (trx) {
34
+ return trx;
35
+ }
36
+ // 트랜잭션이 없으면 새로운 PuriWrapper 반환
37
+ const db = this.getDB(which);
38
+ return new PuriWrapper(db, this.getUpsertBuilder());
39
+ }
40
+ async destroy() {
41
+ return DB.destroy();
42
+ }
43
+ async getInsertedIds(wdb, rows, tableName, unqKeyFields, chunkSize = 500) {
44
+ if (!wdb) {
45
+ wdb = this.getDB("w");
46
+ }
47
+ let unqKeys;
48
+ let whereInField;
49
+ let selectField;
50
+ if (unqKeyFields.length > 1) {
51
+ whereInField = wdb.raw(`CONCAT_WS('_', '${unqKeyFields.join(",")}')`);
52
+ selectField = `${whereInField} as tmpUid`;
53
+ unqKeys = rows.map((row)=>unqKeyFields.map((field)=>row[field]).join("_"));
54
+ } else {
55
+ whereInField = unqKeyFields[0];
56
+ selectField = unqKeyFields[0];
57
+ unqKeys = rows.map((row)=>row[unqKeyFields[0]]);
58
+ }
59
+ let resultIds = [];
60
+ for (const items of chunk(unqKeys, chunkSize)){
61
+ const dbRows = await wdb(tableName).select("id", wdb.raw(selectField)).whereIn(whereInField, items);
62
+ resultIds = resultIds.concat(dbRows.map((dbRow)=>parseInt(String(dbRow.id))));
63
+ }
64
+ return resultIds;
65
+ }
66
+ /**
67
+ * 특정 서브셋에 대한 쿼리 빌더 획득
68
+ *
69
+ * @returns qb - 쿼리 빌더 (조건 추가용)
70
+ * @returns onSubset - 특정 서브셋 전용 타입이 필요할 때 사용
71
+ */ getSubsetQueries(subset) {
72
+ if (!this.subsetQueries) {
73
+ throw new Error("subsetQueries is not defined");
74
+ }
75
+ const puriWrapper = new PuriWrapper(this.getDB("r"), new UpsertBuilder());
76
+ const qb = this.subsetQueries[subset]?.(puriWrapper);
77
+ return {
78
+ qb: qb,
79
+ onSubset: (_subset)=>qb
80
+ };
81
+ }
82
+ /**
83
+ * Enhancer 객체 생성 헬퍼
84
+ * 타입 검증 및 추론을 도와줌
85
+ */ createEnhancers(enhancers) {
86
+ return enhancers;
87
+ }
88
+ /**
89
+ * 서브셋 쿼리 실행
90
+ *
91
+ * 1. 쿼리 실행 (pagination 적용)
92
+ * 2. 로더 실행 (1:N, N:M 관계 데이터 로딩)
93
+ * 3. Hydrate (flat → 중첩 객체)
94
+ * 4. Enhancer 적용 (virtual 필드 계산)
95
+ */ async executeSubsetQuery(params) {
96
+ const { subset, qb, params: queryParams, debug = false, optimizeCountQuery = false } = params;
97
+ if (!this.loaderQueries) {
98
+ throw new Error("loaderQueries is not defined");
99
+ }
100
+ if (!queryParams.num || !queryParams.page) {
101
+ throw new Error("num and page are required");
102
+ }
103
+ const { num, page } = queryParams;
104
+ // COUNT 쿼리 실행
105
+ const total = await this.executeCountQuery(qb, queryParams, debug, optimizeCountQuery);
106
+ // LIST 쿼리 실행
107
+ const computedRows = await this.executeListQuery(subset, qb, queryParams, num, page, debug);
108
+ // Enhancer 적용
109
+ const enhancer = params.enhancers?.[subset];
110
+ const rows = await Promise.all(computedRows.map((row)=>enhancer?.(row) ?? row));
111
+ return {
112
+ rows,
113
+ total
114
+ };
115
+ }
116
+ /**
117
+ * COUNT 쿼리 실행 (내부 메서드)
118
+ */ async executeCountQuery(qb, params, debug, optimizeCountQuery) {
119
+ if (params.queryMode === "list") {
120
+ return 0;
121
+ }
122
+ const countPuri = qb.clone().clear("order").clear("limit").clear("offset");
123
+ if (optimizeCountQuery) {
124
+ const { default: SqlParser } = await import("node-sql-parser");
125
+ const parser = new SqlParser.Parser();
126
+ const parsedQuery = parser.astify(countPuri.toQuery(), {
127
+ database: Sonamu.config.database.database
128
+ });
129
+ const leftJoinTables = getJoinTables(parsedQuery, [
130
+ "LEFT JOIN"
131
+ ]);
132
+ const whereTables = getTableNamesFromWhere(parsedQuery);
133
+ const tablesToRemove = leftJoinTables.filter((j)=>!whereTables.includes(j));
134
+ tablesToRemove.forEach((table)=>{
135
+ countPuri.clearJoin(table);
136
+ });
137
+ }
138
+ // COUNT(*)로 전체 레코드 수를 계산
139
+ // TODO: qb의 DISTINCT가 있는 경우 처리해야 함
140
+ const countResult = await countPuri.clear("select").select({
141
+ total: Puri.rawNumber(`COUNT(*)`)
142
+ }).first();
143
+ if (debug) {
144
+ countPuri.debug();
145
+ }
146
+ return countResult?.total ?? 0;
147
+ }
148
+ /**
149
+ * LIST 쿼리 실행 (내부 메서드)
150
+ */ async executeListQuery(subset, qb, params, num, page, debug) {
151
+ if (params.queryMode === "count") {
152
+ return [];
153
+ }
154
+ let unloadedRows = await qb.limit(num).offset(num * (page - 1));
155
+ if (debug) {
156
+ qb.debug();
157
+ }
158
+ // 로더 처리
159
+ const loaders = this.loaderQueries[subset];
160
+ if (loaders && Array.isArray(loaders)) {
161
+ unloadedRows = await this.processLoaders(unloadedRows, loaders, debug);
162
+ }
163
+ return this.hydrate(unloadedRows);
164
+ }
165
+ /**
166
+ * 재귀적 로더 처리
167
+ */ async processLoaders(rows, loaders, debug) {
168
+ for (const resolveLoader of loaders){
169
+ const { as, refId, qb: resolveLoaderQbFn, loaders: nestedLoaders } = resolveLoader;
170
+ const resolveLoaderQb = resolveLoaderQbFn(new PuriWrapper(this.getDB("r"), new UpsertBuilder()), rows.map((row)=>row[refId]));
171
+ if (debug) {
172
+ resolveLoaderQb.debug();
173
+ }
174
+ let loadedRows = await resolveLoaderQb;
175
+ // 중첩 loaders가 있으면 재귀 처리
176
+ if (nestedLoaders && nestedLoaders.length > 0) {
177
+ loadedRows = await this.processLoaders(loadedRows, nestedLoaders, debug);
178
+ }
179
+ const subRowGroups = group(loadedRows, (row)=>row.refId);
180
+ rows = rows.map((row)=>{
181
+ row[as] = (subRowGroups[row[refId]] ?? []).map((r)=>omit(r, [
182
+ "refId"
183
+ ]));
184
+ return row;
185
+ });
186
+ }
187
+ return rows;
188
+ }
189
+ /**
190
+ * Flat 레코드를 중첩 객체로 변환
191
+ *
192
+ * - `user__name` → `{ user: { name } }`
193
+ * - nullable relation의 경우 모든 필드가 null이면 객체 자체를 null로
194
+ */ hydrate(rows) {
195
+ return rows.map((row)=>{
196
+ // nullable relation 처리: 관련 필드가 전부 null인 경우 방지
197
+ const nestedKeys = Object.keys(row).filter((key)=>key.includes("__"));
198
+ const groups = Object.groupBy(nestedKeys, (key)=>key.split("__")[0]);
199
+ const nullKeys = Object.entries(groups).filter(([_, data])=>data && data.length > 1 && data.every((field)=>row[field] === null || Array.isArray(row[field]) && row[field].length === 0)).map(([key])=>key);
200
+ const hydrated = Object.keys(row).reduce((r, field)=>{
201
+ if (!field.includes("__")) {
202
+ // 일반 필드: 배열 내 객체면 재귀 hydrate
203
+ if (Array.isArray(row[field]) && isObject(row[field][0])) {
204
+ r[field] = this.hydrate(row[field]);
205
+ } else {
206
+ r[field] = row[field];
207
+ }
208
+ return r;
209
+ }
210
+ // 중첩 필드 처리: user__name → user[name]
211
+ const parts = field.split("__");
212
+ const objPath = parts[0] + parts.slice(1).map((part)=>`[${part}]`).join("");
213
+ r = set(r, objPath, row[field] && Array.isArray(row[field]) && isObject(row[field][0]) ? this.hydrate(row[field]) : row[field]);
214
+ return r;
215
+ }, {});
216
+ // null relation 처리
217
+ nullKeys.forEach((nullKey)=>{
218
+ hydrated[nullKey] = null;
219
+ });
220
+ return hydrated;
221
+ });
222
+ }
223
+ // Legacy SubsetQuery 실행 (Puri 도입 전 호환용)
224
+ async runSubsetQuery({ params, baseTable, subset, subsetQuery, build, afterBuild, debug, db: _db, optimizeCountQuery }) {
225
+ const chalk = (await import("chalk")).default;
226
+ const SqlParser = (await import("node-sql-parser")).default;
227
+ const { getTableName, getTableNamesFromWhere } = await import("../utils/sql-parser.js");
228
+ const db = _db ?? this.getDB(subset.startsWith("A") ? "w" : "r");
229
+ baseTable = baseTable ?? inflection.pluralize(inflection.underscore(this.modelName));
230
+ const queryMode = params.queryMode ?? (params.id !== undefined ? "list" : "both");
231
+ const { select, virtual, joins, loaders } = subsetQuery;
232
+ const qb = build({
233
+ qb: db.from(baseTable),
234
+ db,
235
+ select,
236
+ joins,
237
+ virtual
238
+ });
239
+ const applyJoinClause = (qb, joins)=>{
240
+ joins.forEach((join)=>{
241
+ if (join.join === "inner") {
242
+ qb.innerJoin(`${join.table} as ${join.as}`, this.getJoinClause(db, join));
243
+ } else if (join.join === "outer") {
244
+ qb.leftOuterJoin(`${join.table} as ${join.as}`, this.getJoinClause(db, join));
245
+ }
246
+ });
247
+ };
248
+ // countQuery
249
+ const total = await (async ()=>{
250
+ if (queryMode === "list") {
251
+ return undefined;
252
+ }
253
+ const clonedQb = qb.clone().clear("order").clear("offset").clear("limit");
254
+ const parser = new SqlParser.Parser();
255
+ if (optimizeCountQuery) {
256
+ const parsedQuery = parser.astify(clonedQb.toQuery(), {
257
+ database: Sonamu.config.database.database
258
+ });
259
+ const tables = getTableNamesFromWhere(parsedQuery);
260
+ const needToJoin = unique(tables.flatMap((table)=>table.split("__").map((t)=>inflection.pluralize(t))));
261
+ applyJoinClause(clonedQb, joins.filter((j)=>needToJoin.includes(j.table)));
262
+ } else {
263
+ applyJoinClause(clonedQb, joins);
264
+ }
265
+ const processedQb = afterBuild?.({
266
+ qb: clonedQb,
267
+ db,
268
+ select,
269
+ joins,
270
+ virtual
271
+ }) ?? clonedQb;
272
+ const parsedQuery = parser.astify(processedQb.toQuery(), {
273
+ database: Sonamu.config.database.database
274
+ });
275
+ const q = Array.isArray(parsedQuery) ? parsedQuery[0] : parsedQuery;
276
+ if (q.type !== "select") {
277
+ throw new Error("Invalid query");
278
+ }
279
+ const countQuery = q.distinct !== null ? clonedQb.clear("select").select(db.raw(`COUNT(DISTINCT \`${getTableName(q.columns[0].expr)}\`.\`${q.columns[0].expr.column}\`) as total`)).first() : clonedQb.clear("select").count("*", {
280
+ as: "total"
281
+ }).first();
282
+ const countRow = await countQuery;
283
+ if (debug === true || debug === "count") {
284
+ console.debug("DEBUG: count query", chalk.blue(countQuery.toQuery().toString()));
285
+ }
286
+ return countRow?.total ?? 0;
287
+ })();
288
+ // listQuery
289
+ const rows = await (async ()=>{
290
+ if (queryMode === "count") {
291
+ return [];
292
+ }
293
+ if (params.num !== 0) {
294
+ assert(params.num);
295
+ qb.limit(params.num);
296
+ qb.offset(params.num * ((params.page ?? 1) - 1));
297
+ }
298
+ const clonedQb = qb.clone().select(select);
299
+ applyJoinClause(clonedQb, joins);
300
+ const listQuery = afterBuild?.({
301
+ qb: clonedQb,
302
+ db,
303
+ select,
304
+ joins,
305
+ virtual
306
+ }) ?? clonedQb;
307
+ let rows = await listQuery;
308
+ if (debug === true || debug === "list") {
309
+ console.debug("DEBUG: list query", chalk.blue(listQuery.toQuery().toString()));
310
+ }
311
+ rows = await this.useLoaders(db, rows, loaders);
312
+ rows = this.hydrate(rows);
313
+ return rows;
314
+ })();
315
+ return {
316
+ rows,
317
+ total,
318
+ subsetQuery,
319
+ qb
320
+ };
321
+ }
322
+ // Legacy Loader 처리 (Puri 도입 전 호환용)
323
+ async useLoaders(db, rows, loaders) {
324
+ if (loaders.length === 0) {
325
+ return rows;
326
+ }
327
+ for (const loader of loaders){
328
+ let subQ;
329
+ let subRows;
330
+ let toCol;
331
+ const fromIds = rows.map((row)=>row[loader.manyJoin.idField]);
332
+ if (loader.manyJoin.through === undefined) {
333
+ // HasMany
334
+ const idColumn = `${loader.manyJoin.toTable}.${loader.manyJoin.toCol}`;
335
+ subQ = db(loader.manyJoin.toTable).whereIn(idColumn, fromIds).select([
336
+ ...loader.select,
337
+ idColumn
338
+ ]);
339
+ loader.oneJoins.forEach((join)=>{
340
+ if (join.join === "inner") {
341
+ subQ.innerJoin(`${join.table} as ${join.as}`, this.getJoinClause(db, join));
342
+ } else if (join.join === "outer") {
343
+ subQ.leftOuterJoin(`${join.table} as ${join.as}`, this.getJoinClause(db, join));
344
+ }
345
+ });
346
+ toCol = loader.manyJoin.toCol;
347
+ } else {
348
+ // ManyToMany
349
+ const idColumn = `${loader.manyJoin.through.table}.${loader.manyJoin.through.fromCol}`;
350
+ subQ = db(loader.manyJoin.through.table).join(loader.manyJoin.toTable, `${loader.manyJoin.through.table}.${loader.manyJoin.through.toCol}`, `${loader.manyJoin.toTable}.${loader.manyJoin.toCol}`).whereIn(idColumn, fromIds).select(unique([
351
+ ...loader.select,
352
+ idColumn
353
+ ]));
354
+ loader.oneJoins.forEach((join)=>{
355
+ if (join.join === "inner") {
356
+ subQ.innerJoin(`${join.table} as ${join.as}`, this.getJoinClause(db, join));
357
+ } else if (join.join === "outer") {
358
+ subQ.leftOuterJoin(`${join.table} as ${join.as}`, this.getJoinClause(db, join));
359
+ }
360
+ });
361
+ toCol = loader.manyJoin.through.fromCol;
362
+ }
363
+ subRows = await subQ;
364
+ if (loader.loaders) {
365
+ subRows = await this.useLoaders(db, subRows, loader.loaders);
366
+ }
367
+ const subRowGroups = group(subRows, (row)=>row[toCol]);
368
+ rows = rows.map((row)=>{
369
+ row[loader.as] = (subRowGroups[row[loader.manyJoin.idField]] ?? []).map((r)=>omit(r, [
370
+ toCol
371
+ ]));
372
+ return row;
373
+ });
374
+ }
375
+ return rows;
376
+ }
377
+ getJoinClause(db, join) {
378
+ if (!isCustomJoinClause(join)) {
379
+ return db.raw(`${join.from} = ${join.to}`);
380
+ } else {
381
+ return db.raw(join.custom);
382
+ }
383
+ }
384
+ getUpsertBuilder() {
385
+ return new UpsertBuilder();
386
+ }
387
+ }
388
+ export const BaseModel = new BaseModelClass();
389
+
390
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS9iYXNlLW1vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IGluZmxlY3Rpb24gZnJvbSBcImluZmxlY3Rpb25cIjtcbmltcG9ydCB0eXBlIHsgS25leCB9IGZyb20gXCJrbmV4XCI7XG5pbXBvcnQgeyBncm91cCwgaXNPYmplY3QsIG9taXQsIHNldCwgdW5pcXVlIH0gZnJvbSBcInJhZGFzaGlcIjtcbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGlcIjtcbmltcG9ydCB7IHR5cGUgRGF0YWJhc2VTY2hlbWFFeHRlbmQsIGlzQ3VzdG9tSm9pbkNsYXVzZSwgdHlwZSBTdWJzZXRRdWVyeSB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBCYXNlTGlzdFBhcmFtcyB9IGZyb20gXCIuLi91dGlscy9tb2RlbFwiO1xuaW1wb3J0IHsgZ2V0Sm9pblRhYmxlcywgZ2V0VGFibGVOYW1lc0Zyb21XaGVyZSB9IGZyb20gXCIuLi91dGlscy9zcWwtcGFyc2VyXCI7XG5pbXBvcnQgeyBjaHVuayB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuaW1wb3J0IHR5cGUge1xuICBFbmhhbmNlck1hcCxcbiAgRXhlY3V0ZVN1YnNldFF1ZXJ5UmVzdWx0LFxuICBSZXNvbHZlU3Vic2V0SW50ZXJzZWN0aW9uLFxuICBVbmlvbkV4dHJhY3RlZFRUYWJsZXMsXG59IGZyb20gXCIuL2Jhc2UtbW9kZWwudHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgREJQcmVzZXQgfSBmcm9tIFwiLi9kYlwiO1xuaW1wb3J0IHsgREIgfSBmcm9tIFwiLi9kYlwiO1xuaW1wb3J0IHsgUHVyaSB9IGZyb20gXCIuL3B1cmlcIjtcbmltcG9ydCB0eXBlIHsgSW5mZXJBbGxTdWJzZXRzLCBQdXJpTG9hZGVyUXVlcmllcywgUHVyaVN1YnNldEZuIH0gZnJvbSBcIi4vcHVyaS1zdWJzZXQudHlwZXNcIjtcbmltcG9ydCB7IFB1cmlXcmFwcGVyIH0gZnJvbSBcIi4vcHVyaS13cmFwcGVyXCI7XG5pbXBvcnQgeyBVcHNlcnRCdWlsZGVyIH0gZnJvbSBcIi4vdXBzZXJ0LWJ1aWxkZXJcIjtcblxudHlwZSBVbmtub3duREJSZWNvcmQgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuLyoqXG4gKiDrqqjrk6AgTW9kZWwg7YG0656Y7Iqk7J2YIOq4sOuzuCDtgbTrnpjsiqRcbiAqXG4gKiBAdGVtcGxhdGUgVFN1YnNldEtleSAtIOyEnOu4jOyFiyDtgqQg7Jyg64uI7JioICjsmIg6IFwiQVwiIHwgXCJQXCIgfCBcIlNTXCIpXG4gKiBAdGVtcGxhdGUgVFN1YnNldE1hcHBpbmcgLSDshJzruIzshYvrs4Qg7LWc7KKFIOqysOqzvCDtg4DsnoUg66ek7ZWRXG4gKiBAdGVtcGxhdGUgVFN1YnNldFF1ZXJpZXMgLSDshJzruIzshYsg7L+866asIO2VqOyImCDqsJ3ssrRcbiAqIEB0ZW1wbGF0ZSBUTG9hZGVyUXVlcmllcyAtIOyEnOu4jOyFi+uzhCDroZzrjZQg7L+866asIOuwsOyXtCDqsJ3ssrRcbiAqL1xuZXhwb3J0IGNsYXNzIEJhc2VNb2RlbENsYXNzPFxuICBUU3Vic2V0S2V5IGV4dGVuZHMgc3RyaW5nID0gbmV2ZXIsXG4gIFRTdWJzZXRNYXBwaW5nIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiA9IG5ldmVyLFxuICBUU3Vic2V0UXVlcmllcyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBQdXJpU3Vic2V0Rm4+ID0gbmV2ZXIsXG4gIFRMb2FkZXJRdWVyaWVzIGV4dGVuZHMgUHVyaUxvYWRlclF1ZXJpZXM8VFN1YnNldEtleT4gPSBuZXZlcixcbj4ge1xuICBwdWJsaWMgbW9kZWxOYW1lOiBzdHJpbmcgPSBcIlVua25vd25cIjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgc3Vic2V0UXVlcmllcz86IFRTdWJzZXRRdWVyaWVzLFxuICAgIHByb3RlY3RlZCBsb2FkZXJRdWVyaWVzPzogVExvYWRlclF1ZXJpZXMsXG4gICkge31cblxuICBnZXREQih3aGljaDogREJQcmVzZXQpOiBLbmV4IHtcbiAgICByZXR1cm4gREIuZ2V0REIod2hpY2gpO1xuICB9XG5cbiAgZ2V0UHVyaSh3aGljaDogREJQcmVzZXQpOiBQdXJpV3JhcHBlciB7XG4gICAgLy8g7Yq4656c7J6t7IWYIOy7qO2FjeyKpO2KuOyXkOyEnCDtirjrnpzsnq3shZgg7ZqN65OdXG4gICAgY29uc3QgdHJ4ID0gREIuZ2V0VHJhbnNhY3Rpb25Db250ZXh0KCkuZ2V0VHJhbnNhY3Rpb24od2hpY2gpO1xuICAgIGlmICh0cngpIHtcbiAgICAgIHJldHVybiB0cng7XG4gICAgfVxuXG4gICAgLy8g7Yq4656c7J6t7IWY7J20IOyXhuycvOuptCDsg4jroZzsmrQgUHVyaVdyYXBwZXIg67CY7ZmYXG4gICAgY29uc3QgZGIgPSB0aGlzLmdldERCKHdoaWNoKTtcbiAgICByZXR1cm4gbmV3IFB1cmlXcmFwcGVyKGRiLCB0aGlzLmdldFVwc2VydEJ1aWxkZXIoKSk7XG4gIH1cblxuICBhc3luYyBkZXN0cm95KCkge1xuICAgIHJldHVybiBEQi5kZXN0cm95KCk7XG4gIH1cblxuICBhc3luYyBnZXRJbnNlcnRlZElkcyhcbiAgICB3ZGI6IEtuZXgsXG4gICAgcm93czogVW5rbm93bkRCUmVjb3JkW10sXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgdW5xS2V5RmllbGRzOiBzdHJpbmdbXSxcbiAgICBjaHVua1NpemU6IG51bWJlciA9IDUwMCxcbiAgKSB7XG4gICAgaWYgKCF3ZGIpIHtcbiAgICAgIHdkYiA9IHRoaXMuZ2V0REIoXCJ3XCIpO1xuICAgIH1cblxuICAgIGxldCB1bnFLZXlzOiBzdHJpbmdbXTtcbiAgICBsZXQgd2hlcmVJbkZpZWxkOiBzdHJpbmcgfCBLbmV4LlJhdztcbiAgICBsZXQgc2VsZWN0RmllbGQ6IHN0cmluZztcblxuICAgIGlmICh1bnFLZXlGaWVsZHMubGVuZ3RoID4gMSkge1xuICAgICAgd2hlcmVJbkZpZWxkID0gd2RiLnJhdyhgQ09OQ0FUX1dTKCdfJywgJyR7dW5xS2V5RmllbGRzLmpvaW4oXCIsXCIpfScpYCk7XG4gICAgICBzZWxlY3RGaWVsZCA9IGAke3doZXJlSW5GaWVsZH0gYXMgdG1wVWlkYDtcbiAgICAgIHVucUtleXMgPSByb3dzLm1hcCgocm93KSA9PiB1bnFLZXlGaWVsZHMubWFwKChmaWVsZCkgPT4gcm93W2ZpZWxkXSkuam9pbihcIl9cIikpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aGVyZUluRmllbGQgPSB1bnFLZXlGaWVsZHNbMF07XG4gICAgICBzZWxlY3RGaWVsZCA9IHVucUtleUZpZWxkc1swXTtcbiAgICAgIHVucUtleXMgPSByb3dzLm1hcCgocm93KSA9PiByb3dbdW5xS2V5RmllbGRzWzBdXSBhcyBzdHJpbmcpO1xuICAgIH1cblxuICAgIGxldCByZXN1bHRJZHM6IG51bWJlcltdID0gW107XG4gICAgZm9yIChjb25zdCBpdGVtcyBvZiBjaHVuayh1bnFLZXlzLCBjaHVua1NpemUpKSB7XG4gICAgICBjb25zdCBkYlJvd3MgPSBhd2FpdCB3ZGIodGFibGVOYW1lKVxuICAgICAgICAuc2VsZWN0KFwiaWRcIiwgd2RiLnJhdyhzZWxlY3RGaWVsZCkpXG4gICAgICAgIC53aGVyZUluKHdoZXJlSW5GaWVsZCBhcyBzdHJpbmcsIGl0ZW1zKTtcbiAgICAgIHJlc3VsdElkcyA9IHJlc3VsdElkcy5jb25jYXQoXG4gICAgICAgIGRiUm93cy5tYXAoKGRiUm93OiBVbmtub3duREJSZWNvcmQpID0+IHBhcnNlSW50KFN0cmluZyhkYlJvdy5pZCkpKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdElkcztcbiAgfVxuXG4gIC8qKlxuICAgKiDtirnsoJUg7ISc67iM7IWL7JeQIOuMgO2VnCDsv7zrpqwg67mM642UIO2ajeuTnVxuICAgKlxuICAgKiBAcmV0dXJucyBxYiAtIOy/vOumrCDruYzrjZQgKOyhsOqxtCDstpTqsIDsmqkpXG4gICAqIEByZXR1cm5zIG9uU3Vic2V0IC0g7Yq57KCVIOyEnOu4jOyFiyDsoITsmqkg7YOA7J6F7J20IO2VhOyalO2VoCDrlYwg7IKs7JqpXG4gICAqL1xuICBnZXRTdWJzZXRRdWVyaWVzPFQgZXh0ZW5kcyBUU3Vic2V0S2V5PihzdWJzZXQ6IFQpIHtcbiAgICBpZiAoIXRoaXMuc3Vic2V0UXVlcmllcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwic3Vic2V0UXVlcmllcyBpcyBub3QgZGVmaW5lZFwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBwdXJpV3JhcHBlciA9IG5ldyBQdXJpV3JhcHBlcih0aGlzLmdldERCKFwiclwiKSwgbmV3IFVwc2VydEJ1aWxkZXIoKSk7XG4gICAgY29uc3QgcWIgPSB0aGlzLnN1YnNldFF1ZXJpZXNbc3Vic2V0XT8uKHB1cmlXcmFwcGVyKTtcblxuICAgIC8vIE5vbkFsbG93ZWRBc1NpbmdsZVRhYmxlOiDri6jsnbwg7YWM7J2067iUIOy7rOufvCDsoJHqt7wg67Cp7KeA7JqpIOuniOy7pFxuICAgIHR5cGUgUUJUYWJsZXMgPSBVbmlvbkV4dHJhY3RlZFRUYWJsZXM8VFN1YnNldEtleSwgVFN1YnNldFF1ZXJpZXM+ICYge1xuICAgICAgTm9uQWxsb3dlZEFzU2luZ2xlVGFibGU6IHsgX19mdWxsdGV4dF9fOiB0cnVlIH07XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBxYjogcWIgYXMgdW5rbm93biBhcyBQdXJpPERhdGFiYXNlU2NoZW1hRXh0ZW5kLCBRQlRhYmxlcywge30+LFxuICAgICAgb25TdWJzZXQ6ICgoX3N1YnNldDogVFN1YnNldEtleSB8IHJlYWRvbmx5IFRTdWJzZXRLZXlbXSkgPT4gcWIpIGFzIHtcbiAgICAgICAgLy8g64uo7J28IO2CpFxuICAgICAgICA8UyBleHRlbmRzIFRTdWJzZXRLZXk+KHN1YnNldDogUyk6IFJldHVyblR5cGU8VFN1YnNldFF1ZXJpZXNbU10+O1xuICAgICAgICAvLyDtgqQg67Cw7Je0IC0+IOq1kOynke2VqSDrsJjtmZhcbiAgICAgICAgPEFyciBleHRlbmRzIHJlYWRvbmx5IFRTdWJzZXRLZXlbXT4oXG4gICAgICAgICAgc3Vic2V0czogWy4uLkFycl0sXG4gICAgICAgICk6IFJlc29sdmVTdWJzZXRJbnRlcnNlY3Rpb248QXJyLCBUU3Vic2V0UXVlcmllcz47XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRW5oYW5jZXIg6rCd7LK0IOyDneyEsSDtl6ztjbxcbiAgICog7YOA7J6FIOqygOymnSDrsI8g7LaU66Gg7J2EIOuPhOyZgOykjFxuICAgKi9cbiAgY3JlYXRlRW5oYW5jZXJzPFQgZXh0ZW5kcyBUU3Vic2V0S2V5PihcbiAgICBlbmhhbmNlcnM6IEVuaGFuY2VyTWFwPFQsIEluZmVyQWxsU3Vic2V0czxUU3Vic2V0UXVlcmllcywgVExvYWRlclF1ZXJpZXM+LCBUU3Vic2V0TWFwcGluZz4sXG4gICkge1xuICAgIHJldHVybiBlbmhhbmNlcnM7XG4gIH1cblxuICAvKipcbiAgICog7ISc67iM7IWLIOy/vOumrCDsi6TtlolcbiAgICpcbiAgICogMS4g7L+866asIOyLpO2WiSAocGFnaW5hdGlvbiDsoIHsmqkpXG4gICAqIDIuIOuhnOuNlCDsi6TtlokgKDE6TiwgTjpNIOq0gOqzhCDrjbDsnbTthLAg66Gc65SpKVxuICAgKiAzLiBIeWRyYXRlIChmbGF0IOKGkiDspJHssqkg6rCd7LK0KVxuICAgKiA0LiBFbmhhbmNlciDsoIHsmqkgKHZpcnR1YWwg7ZWE65OcIOqzhOyCsClcbiAgICovXG4gIGFzeW5jIGV4ZWN1dGVTdWJzZXRRdWVyeTxcbiAgICBUIGV4dGVuZHMgVFN1YnNldEtleSxcbiAgICBUQ29tcHV0ZWRSZXN1bHRzIGV4dGVuZHMgSW5mZXJBbGxTdWJzZXRzPFRTdWJzZXRRdWVyaWVzLCBUTG9hZGVyUXVlcmllcz4sXG4gID4oXG4gICAgcGFyYW1zOiB7XG4gICAgICBzdWJzZXQ6IFQ7XG4gICAgICBxYjogUHVyaTxhbnksIGFueSwgYW55PjtcbiAgICAgIHBhcmFtczoge1xuICAgICAgICBudW0/OiBudW1iZXI7XG4gICAgICAgIHBhZ2U/OiBudW1iZXI7XG4gICAgICAgIHF1ZXJ5TW9kZT86IFwibGlzdFwiIHwgXCJjb3VudFwiIHwgXCJib3RoXCI7XG4gICAgICB9O1xuICAgICAgZGVidWc/OiBib29sZWFuO1xuICAgICAgb3B0aW1pemVDb3VudFF1ZXJ5PzogYm9vbGVhbjtcbiAgICB9ICYgRW5oYW5jZXJQYXJhbTxUU3Vic2V0S2V5LCBUQ29tcHV0ZWRSZXN1bHRzLCBUU3Vic2V0TWFwcGluZz4sXG4gICk6IFByb21pc2U8RXhlY3V0ZVN1YnNldFF1ZXJ5UmVzdWx0PFRTdWJzZXRNYXBwaW5nLCBUPj4ge1xuICAgIGNvbnN0IHsgc3Vic2V0LCBxYiwgcGFyYW1zOiBxdWVyeVBhcmFtcywgZGVidWcgPSBmYWxzZSwgb3B0aW1pemVDb3VudFF1ZXJ5ID0gZmFsc2UgfSA9IHBhcmFtcztcblxuICAgIGlmICghdGhpcy5sb2FkZXJRdWVyaWVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJsb2FkZXJRdWVyaWVzIGlzIG5vdCBkZWZpbmVkXCIpO1xuICAgIH1cblxuICAgIGlmICghcXVlcnlQYXJhbXMubnVtIHx8ICFxdWVyeVBhcmFtcy5wYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJudW0gYW5kIHBhZ2UgYXJlIHJlcXVpcmVkXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbnVtLCBwYWdlIH0gPSBxdWVyeVBhcmFtcztcblxuICAgIC8vIENPVU5UIOy/vOumrCDsi6TtlolcbiAgICBjb25zdCB0b3RhbCA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvdW50UXVlcnkocWIsIHF1ZXJ5UGFyYW1zLCBkZWJ1Zywgb3B0aW1pemVDb3VudFF1ZXJ5KTtcblxuICAgIC8vIExJU1Qg7L+866asIOyLpO2WiVxuICAgIGNvbnN0IGNvbXB1dGVkUm93cyA9IGF3YWl0IHRoaXMuZXhlY3V0ZUxpc3RRdWVyeShzdWJzZXQsIHFiLCBxdWVyeVBhcmFtcywgbnVtLCBwYWdlLCBkZWJ1Zyk7XG5cbiAgICAvLyBFbmhhbmNlciDsoIHsmqlcbiAgICBjb25zdCBlbmhhbmNlciA9IChwYXJhbXMgYXMgYW55KS5lbmhhbmNlcnM/LltzdWJzZXRdO1xuICAgIGNvbnN0IHJvd3MgPSAoYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBjb21wdXRlZFJvd3MubWFwKChyb3cpID0+IGVuaGFuY2VyPy4ocm93KSA/PyByb3cpLFxuICAgICkpIGFzIFRTdWJzZXRNYXBwaW5nW1RdW107XG5cbiAgICByZXR1cm4geyByb3dzLCB0b3RhbCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENPVU5UIOy/vOumrCDsi6TtlokgKOuCtOu2gCDrqZTshJzrk5wpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVDb3VudFF1ZXJ5KFxuICAgIHFiOiBQdXJpPGFueSwgYW55LCBhbnk+LFxuICAgIHBhcmFtczogeyBxdWVyeU1vZGU/OiBcImxpc3RcIiB8IFwiY291bnRcIiB8IFwiYm90aFwiIH0sXG4gICAgZGVidWc6IGJvb2xlYW4sXG4gICAgb3B0aW1pemVDb3VudFF1ZXJ5OiBib29sZWFuLFxuICApOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGlmIChwYXJhbXMucXVlcnlNb2RlID09PSBcImxpc3RcIikge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgY29uc3QgY291bnRQdXJpID0gcWIuY2xvbmUoKS5jbGVhcihcIm9yZGVyXCIpLmNsZWFyKFwibGltaXRcIikuY2xlYXIoXCJvZmZzZXRcIik7XG5cbiAgICBpZiAob3B0aW1pemVDb3VudFF1ZXJ5KSB7XG4gICAgICBjb25zdCB7IGRlZmF1bHQ6IFNxbFBhcnNlciB9ID0gYXdhaXQgaW1wb3J0KFwibm9kZS1zcWwtcGFyc2VyXCIpO1xuICAgICAgY29uc3QgcGFyc2VyID0gbmV3IFNxbFBhcnNlci5QYXJzZXIoKTtcbiAgICAgIGNvbnN0IHBhcnNlZFF1ZXJ5ID0gcGFyc2VyLmFzdGlmeShjb3VudFB1cmkudG9RdWVyeSgpLCB7XG4gICAgICAgIGRhdGFiYXNlOiBTb25hbXUuY29uZmlnLmRhdGFiYXNlLmRhdGFiYXNlLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGxlZnRKb2luVGFibGVzID0gZ2V0Sm9pblRhYmxlcyhwYXJzZWRRdWVyeSwgW1wiTEVGVCBKT0lOXCJdKTtcbiAgICAgIGNvbnN0IHdoZXJlVGFibGVzID0gZ2V0VGFibGVOYW1lc0Zyb21XaGVyZShwYXJzZWRRdWVyeSk7XG5cbiAgICAgIGNvbnN0IHRhYmxlc1RvUmVtb3ZlID0gbGVmdEpvaW5UYWJsZXMuZmlsdGVyKChqKSA9PiAhd2hlcmVUYWJsZXMuaW5jbHVkZXMoaikpO1xuICAgICAgdGFibGVzVG9SZW1vdmUuZm9yRWFjaCgodGFibGUpID0+IHtcbiAgICAgICAgY291bnRQdXJpLmNsZWFySm9pbih0YWJsZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBDT1VOVCgqKeuhnCDsoITssrQg66CI7L2U65OcIOyImOulvCDqs4TsgrBcbiAgICAvLyBUT0RPOiBxYuydmCBESVNUSU5DVOqwgCDsnojripQg6rK97JqwIOyymOumrO2VtOyVvCDtlahcbiAgICBjb25zdCBjb3VudFJlc3VsdDogeyB0b3RhbD86IG51bWJlciB9ID0gYXdhaXQgY291bnRQdXJpXG4gICAgICAuY2xlYXIoXCJzZWxlY3RcIilcbiAgICAgIC5zZWxlY3QoeyB0b3RhbDogUHVyaS5yYXdOdW1iZXIoYENPVU5UKCopYCkgfSlcbiAgICAgIC5maXJzdCgpO1xuXG4gICAgaWYgKGRlYnVnKSB7XG4gICAgICBjb3VudFB1cmkuZGVidWcoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY291bnRSZXN1bHQ/LnRvdGFsID8/IDA7XG4gIH1cblxuICAvKipcbiAgICogTElTVCDsv7zrpqwg7Iuk7ZaJICjrgrTrtoAg66mU7ISc65OcKVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlTGlzdFF1ZXJ5PFQgZXh0ZW5kcyBUU3Vic2V0S2V5PihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcWI6IFB1cmk8YW55LCBhbnksIGFueT4sXG4gICAgcGFyYW1zOiB7IHF1ZXJ5TW9kZT86IFwibGlzdFwiIHwgXCJjb3VudFwiIHwgXCJib3RoXCIgfSxcbiAgICBudW06IG51bWJlcixcbiAgICBwYWdlOiBudW1iZXIsXG4gICAgZGVidWc6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8YW55W10+IHtcbiAgICBpZiAocGFyYW1zLnF1ZXJ5TW9kZSA9PT0gXCJjb3VudFwiKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgbGV0IHVubG9hZGVkUm93cyA9IChhd2FpdCBxYi5saW1pdChudW0pLm9mZnNldChudW0gKiAocGFnZSAtIDEpKSkgYXMgYW55W107XG5cbiAgICBpZiAoZGVidWcpIHtcbiAgICAgIHFiLmRlYnVnKCk7XG4gICAgfVxuXG4gICAgLy8g66Gc642UIOyymOumrFxuICAgIGNvbnN0IGxvYWRlcnMgPSAodGhpcy5sb2FkZXJRdWVyaWVzIGFzIGFueSlbc3Vic2V0XTtcbiAgICBpZiAobG9hZGVycyAmJiBBcnJheS5pc0FycmF5KGxvYWRlcnMpKSB7XG4gICAgICB1bmxvYWRlZFJvd3MgPSBhd2FpdCB0aGlzLnByb2Nlc3NMb2FkZXJzKHVubG9hZGVkUm93cywgbG9hZGVycywgZGVidWcpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmh5ZHJhdGUodW5sb2FkZWRSb3dzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDsnqzqt4DsoIEg66Gc642UIOyymOumrFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzTG9hZGVycyhyb3dzOiBhbnlbXSwgbG9hZGVyczogYW55W10sIGRlYnVnOiBib29sZWFuKTogUHJvbWlzZTxhbnlbXT4ge1xuICAgIGZvciAoY29uc3QgcmVzb2x2ZUxvYWRlciBvZiBsb2FkZXJzKSB7XG4gICAgICBjb25zdCB7IGFzLCByZWZJZCwgcWI6IHJlc29sdmVMb2FkZXJRYkZuLCBsb2FkZXJzOiBuZXN0ZWRMb2FkZXJzIH0gPSByZXNvbHZlTG9hZGVyO1xuXG4gICAgICBjb25zdCByZXNvbHZlTG9hZGVyUWIgPSByZXNvbHZlTG9hZGVyUWJGbihcbiAgICAgICAgbmV3IFB1cmlXcmFwcGVyKHRoaXMuZ2V0REIoXCJyXCIpLCBuZXcgVXBzZXJ0QnVpbGRlcigpKSxcbiAgICAgICAgcm93cy5tYXAoKHJvdykgPT4gcm93W3JlZklkXSksXG4gICAgICApO1xuXG4gICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgcmVzb2x2ZUxvYWRlclFiLmRlYnVnKCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBsb2FkZWRSb3dzID0gKGF3YWl0IHJlc29sdmVMb2FkZXJRYikgYXMgYW55W107XG5cbiAgICAgIC8vIOykkeyyqSBsb2FkZXJz6rCAIOyeiOycvOuptCDsnqzqt4Ag7LKY66asXG4gICAgICBpZiAobmVzdGVkTG9hZGVycyAmJiBuZXN0ZWRMb2FkZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbG9hZGVkUm93cyA9IGF3YWl0IHRoaXMucHJvY2Vzc0xvYWRlcnMobG9hZGVkUm93cywgbmVzdGVkTG9hZGVycywgZGVidWcpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdWJSb3dHcm91cHMgPSBncm91cChsb2FkZWRSb3dzLCAocm93KSA9PiByb3cucmVmSWQpO1xuXG4gICAgICByb3dzID0gcm93cy5tYXAoKHJvdykgPT4ge1xuICAgICAgICByb3dbYXNdID0gKHN1YlJvd0dyb3Vwc1tyb3dbcmVmSWRdXSA/PyBbXSkubWFwKChyKSA9PiBvbWl0KHIsIFtcInJlZklkXCJdKSk7XG4gICAgICAgIHJldHVybiByb3c7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGF0IOugiOy9lOuTnOulvCDspJHssqkg6rCd7LK066GcIOuzgO2ZmFxuICAgKlxuICAgKiAtIGB1c2VyX19uYW1lYCDihpIgYHsgdXNlcjogeyBuYW1lIH0gfWBcbiAgICogLSBudWxsYWJsZSByZWxhdGlvbuydmCDqsr3smrAg66qo65OgIO2VhOuTnOqwgCBudWxs7J2066m0IOqwneyytCDsnpDssrTrpbwgbnVsbOuhnFxuICAgKi9cbiAgaHlkcmF0ZTxUIGV4dGVuZHMgVW5rbm93bkRCUmVjb3JkPihyb3dzOiBUW10pOiBUW10ge1xuICAgIHJldHVybiByb3dzLm1hcCgocm93OiBUKSA9PiB7XG4gICAgICAvLyBudWxsYWJsZSByZWxhdGlvbiDsspjrpqw6IOq0gOugqCDtlYTrk5zqsIAg7KCE67aAIG51bGzsnbgg6rK97JqwIOuwqeyngFxuICAgICAgY29uc3QgbmVzdGVkS2V5cyA9IE9iamVjdC5rZXlzKHJvdykuZmlsdGVyKChrZXkpID0+IGtleS5pbmNsdWRlcyhcIl9fXCIpKTtcbiAgICAgIGNvbnN0IGdyb3VwcyA9IE9iamVjdC5ncm91cEJ5KG5lc3RlZEtleXMsIChrZXkpID0+IGtleS5zcGxpdChcIl9fXCIpWzBdKTtcbiAgICAgIGNvbnN0IG51bGxLZXlzID0gT2JqZWN0LmVudHJpZXMoZ3JvdXBzKVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChbXywgZGF0YV0pID0+XG4gICAgICAgICAgICBkYXRhICYmXG4gICAgICAgICAgICBkYXRhLmxlbmd0aCA+IDEgJiZcbiAgICAgICAgICAgIGRhdGEuZXZlcnkoXG4gICAgICAgICAgICAgIChmaWVsZCkgPT5cbiAgICAgICAgICAgICAgICByb3dbZmllbGRdID09PSBudWxsIHx8IChBcnJheS5pc0FycmF5KHJvd1tmaWVsZF0pICYmIHJvd1tmaWVsZF0ubGVuZ3RoID09PSAwKSxcbiAgICAgICAgICAgICksXG4gICAgICAgIClcbiAgICAgICAgLm1hcCgoW2tleV0pID0+IGtleSk7XG5cbiAgICAgIGNvbnN0IGh5ZHJhdGVkID0gT2JqZWN0LmtleXMocm93KS5yZWR1Y2UoKHIsIGZpZWxkKSA9PiB7XG4gICAgICAgIGlmICghZmllbGQuaW5jbHVkZXMoXCJfX1wiKSkge1xuICAgICAgICAgIC8vIOydvOuwmCDtlYTrk5w6IOuwsOyXtCDrgrQg6rCd7LK066m0IOyerOq3gCBoeWRyYXRlXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocm93W2ZpZWxkXSkgJiYgaXNPYmplY3Qocm93W2ZpZWxkXVswXSkpIHtcbiAgICAgICAgICAgIHJbZmllbGRdID0gdGhpcy5oeWRyYXRlKHJvd1tmaWVsZF0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByW2ZpZWxkXSA9IHJvd1tmaWVsZF07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g7KSR7LKpIO2VhOuTnCDsspjrpqw6IHVzZXJfX25hbWUg4oaSIHVzZXJbbmFtZV1cbiAgICAgICAgY29uc3QgcGFydHMgPSBmaWVsZC5zcGxpdChcIl9fXCIpO1xuICAgICAgICBjb25zdCBvYmpQYXRoID1cbiAgICAgICAgICBwYXJ0c1swXSArXG4gICAgICAgICAgcGFydHNcbiAgICAgICAgICAgIC5zbGljZSgxKVxuICAgICAgICAgICAgLm1hcCgocGFydCkgPT4gYFske3BhcnR9XWApXG4gICAgICAgICAgICAuam9pbihcIlwiKTtcblxuICAgICAgICByID0gc2V0KFxuICAgICAgICAgIHIsXG4gICAgICAgICAgb2JqUGF0aCxcbiAgICAgICAgICByb3dbZmllbGRdICYmIEFycmF5LmlzQXJyYXkocm93W2ZpZWxkXSkgJiYgaXNPYmplY3Qocm93W2ZpZWxkXVswXSlcbiAgICAgICAgICAgID8gdGhpcy5oeWRyYXRlKHJvd1tmaWVsZF0pXG4gICAgICAgICAgICA6IHJvd1tmaWVsZF0sXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9LCB7fSBhcyBVbmtub3duREJSZWNvcmQpO1xuXG4gICAgICAvLyBudWxsIHJlbGF0aW9uIOyymOumrFxuICAgICAgbnVsbEtleXMuZm9yRWFjaCgobnVsbEtleSkgPT4ge1xuICAgICAgICBoeWRyYXRlZFtudWxsS2V5XSA9IG51bGw7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGh5ZHJhdGVkO1xuICAgIH0pIGFzIFRbXTtcbiAgfVxuXG4gIC8vIExlZ2FjeSBTdWJzZXRRdWVyeSDsi6TtlokgKFB1cmkg64+E7J6FIOyghCDtmLjtmZjsmqkpXG4gIGFzeW5jIHJ1blN1YnNldFF1ZXJ5PFQgZXh0ZW5kcyBCYXNlTGlzdFBhcmFtcywgVSBleHRlbmRzIHN0cmluZz4oe1xuICAgIHBhcmFtcyxcbiAgICBiYXNlVGFibGUsXG4gICAgc3Vic2V0LFxuICAgIHN1YnNldFF1ZXJ5LFxuICAgIGJ1aWxkLFxuICAgIGFmdGVyQnVpbGQsXG4gICAgZGVidWcsXG4gICAgZGI6IF9kYixcbiAgICBvcHRpbWl6ZUNvdW50UXVlcnksXG4gIH06IHtcbiAgICBzdWJzZXQ6IFU7XG4gICAgcGFyYW1zOiBUO1xuICAgIHN1YnNldFF1ZXJ5OiBTdWJzZXRRdWVyeTtcbiAgICBidWlsZDogKGJ1aWxkUGFyYW1zOiB7XG4gICAgICBxYjogS25leC5RdWVyeUJ1aWxkZXI7XG4gICAgICBkYjogS25leDtcbiAgICAgIHNlbGVjdDogKHN0cmluZyB8IEtuZXguUmF3KVtdO1xuICAgICAgam9pbnM6IFN1YnNldFF1ZXJ5W1wiam9pbnNcIl07XG4gICAgICB2aXJ0dWFsOiBzdHJpbmdbXTtcbiAgICB9KSA9PiBLbmV4LlF1ZXJ5QnVpbGRlcjtcbiAgICBhZnRlckJ1aWxkPzogKGJ1aWxkUGFyYW1zOiB7XG4gICAgICBxYjogS25leC5RdWVyeUJ1aWxkZXI7XG4gICAgICBkYjogS25leDtcbiAgICAgIHNlbGVjdDogKHN0cmluZyB8IEtuZXguUmF3KVtdO1xuICAgICAgam9pbnM6IFN1YnNldFF1ZXJ5W1wiam9pbnNcIl07XG4gICAgICB2aXJ0dWFsOiBzdHJpbmdbXTtcbiAgICB9KSA9PiBLbmV4LlF1ZXJ5QnVpbGRlcjtcbiAgICBiYXNlVGFibGU/OiBzdHJpbmc7XG4gICAgZGVidWc/OiBib29sZWFuIHwgXCJsaXN0XCIgfCBcImNvdW50XCI7XG4gICAgZGI/OiBLbmV4O1xuICAgIG9wdGltaXplQ291bnRRdWVyeT86IGJvb2xlYW47XG4gIH0pOiBQcm9taXNlPHtcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IFB1cmkg64+E7J6FIOyghOq5jOyngCBhbnnroZwg7Jyg7KeAXG4gICAgcm93czogYW55W107XG4gICAgdG90YWw/OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgc3Vic2V0UXVlcnk6IFN1YnNldFF1ZXJ5O1xuICAgIHFiOiBLbmV4LlF1ZXJ5QnVpbGRlcjtcbiAgfT4ge1xuICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgIGNvbnN0IFNxbFBhcnNlciA9IChhd2FpdCBpbXBvcnQoXCJub2RlLXNxbC1wYXJzZXJcIikpLmRlZmF1bHQ7XG4gICAgY29uc3QgeyBnZXRUYWJsZU5hbWUsIGdldFRhYmxlTmFtZXNGcm9tV2hlcmUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3NxbC1wYXJzZXJcIik7XG5cbiAgICBjb25zdCBkYiA9IF9kYiA/PyB0aGlzLmdldERCKHN1YnNldC5zdGFydHNXaXRoKFwiQVwiKSA/IFwid1wiIDogXCJyXCIpO1xuICAgIGJhc2VUYWJsZSA9IGJhc2VUYWJsZSA/PyBpbmZsZWN0aW9uLnBsdXJhbGl6ZShpbmZsZWN0aW9uLnVuZGVyc2NvcmUodGhpcy5tb2RlbE5hbWUpKTtcbiAgICBjb25zdCBxdWVyeU1vZGUgPSBwYXJhbXMucXVlcnlNb2RlID8/IChwYXJhbXMuaWQgIT09IHVuZGVmaW5lZCA/IFwibGlzdFwiIDogXCJib3RoXCIpO1xuXG4gICAgY29uc3QgeyBzZWxlY3QsIHZpcnR1YWwsIGpvaW5zLCBsb2FkZXJzIH0gPSBzdWJzZXRRdWVyeTtcbiAgICBjb25zdCBxYiA9IGJ1aWxkKHtcbiAgICAgIHFiOiBkYi5mcm9tKGJhc2VUYWJsZSksXG4gICAgICBkYixcbiAgICAgIHNlbGVjdCxcbiAgICAgIGpvaW5zLFxuICAgICAgdmlydHVhbCxcbiAgICB9KTtcblxuICAgIGNvbnN0IGFwcGx5Sm9pbkNsYXVzZSA9IChxYjogS25leC5RdWVyeUJ1aWxkZXIsIGpvaW5zOiBTdWJzZXRRdWVyeVtcImpvaW5zXCJdKSA9PiB7XG4gICAgICBqb2lucy5mb3JFYWNoKChqb2luKSA9PiB7XG4gICAgICAgIGlmIChqb2luLmpvaW4gPT09IFwiaW5uZXJcIikge1xuICAgICAgICAgIHFiLmlubmVySm9pbihgJHtqb2luLnRhYmxlfSBhcyAke2pvaW4uYXN9YCwgdGhpcy5nZXRKb2luQ2xhdXNlKGRiLCBqb2luKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoam9pbi5qb2luID09PSBcIm91dGVyXCIpIHtcbiAgICAgICAgICBxYi5sZWZ0T3V0ZXJKb2luKGAke2pvaW4udGFibGV9IGFzICR7am9pbi5hc31gLCB0aGlzLmdldEpvaW5DbGF1c2UoZGIsIGpvaW4pKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIGNvdW50UXVlcnlcbiAgICBjb25zdCB0b3RhbCA9IGF3YWl0IChhc3luYyAoKSA9PiB7XG4gICAgICBpZiAocXVlcnlNb2RlID09PSBcImxpc3RcIikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjbG9uZWRRYiA9IHFiLmNsb25lKCkuY2xlYXIoXCJvcmRlclwiKS5jbGVhcihcIm9mZnNldFwiKS5jbGVhcihcImxpbWl0XCIpO1xuICAgICAgY29uc3QgcGFyc2VyID0gbmV3IFNxbFBhcnNlci5QYXJzZXIoKTtcblxuICAgICAgaWYgKG9wdGltaXplQ291bnRRdWVyeSkge1xuICAgICAgICBjb25zdCBwYXJzZWRRdWVyeSA9IHBhcnNlci5hc3RpZnkoY2xvbmVkUWIudG9RdWVyeSgpLCB7XG4gICAgICAgICAgZGF0YWJhc2U6IFNvbmFtdS5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB0YWJsZXMgPSBnZXRUYWJsZU5hbWVzRnJvbVdoZXJlKHBhcnNlZFF1ZXJ5KTtcbiAgICAgICAgY29uc3QgbmVlZFRvSm9pbiA9IHVuaXF1ZShcbiAgICAgICAgICB0YWJsZXMuZmxhdE1hcCgodGFibGUpID0+IHRhYmxlLnNwbGl0KFwiX19cIikubWFwKCh0KSA9PiBpbmZsZWN0aW9uLnBsdXJhbGl6ZSh0KSkpLFxuICAgICAgICApO1xuICAgICAgICBhcHBseUpvaW5DbGF1c2UoXG4gICAgICAgICAgY2xvbmVkUWIsXG4gICAgICAgICAgam9pbnMuZmlsdGVyKChqKSA9PiBuZWVkVG9Kb2luLmluY2x1ZGVzKGoudGFibGUpKSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFwcGx5Sm9pbkNsYXVzZShjbG9uZWRRYiwgam9pbnMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9jZXNzZWRRYiA9IGFmdGVyQnVpbGQ/Lih7IHFiOiBjbG9uZWRRYiwgZGIsIHNlbGVjdCwgam9pbnMsIHZpcnR1YWwgfSkgPz8gY2xvbmVkUWI7XG5cbiAgICAgIGNvbnN0IHBhcnNlZFF1ZXJ5ID0gcGFyc2VyLmFzdGlmeShwcm9jZXNzZWRRYi50b1F1ZXJ5KCksIHtcbiAgICAgICAgZGF0YWJhc2U6IFNvbmFtdS5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHEgPSBBcnJheS5pc0FycmF5KHBhcnNlZFF1ZXJ5KSA/IHBhcnNlZFF1ZXJ5WzBdIDogcGFyc2VkUXVlcnk7XG4gICAgICBpZiAocS50eXBlICE9PSBcInNlbGVjdFwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcXVlcnlcIik7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvdW50UXVlcnkgPVxuICAgICAgICBxLmRpc3RpbmN0ICE9PSBudWxsXG4gICAgICAgICAgPyBjbG9uZWRRYlxuICAgICAgICAgICAgICAuY2xlYXIoXCJzZWxlY3RcIilcbiAgICAgICAgICAgICAgLnNlbGVjdChcbiAgICAgICAgICAgICAgICBkYi5yYXcoXG4gICAgICAgICAgICAgICAgICBgQ09VTlQoRElTVElOQ1QgXFxgJHtnZXRUYWJsZU5hbWUocS5jb2x1bW5zWzBdLmV4cHIpfVxcYC5cXGAke3EuY29sdW1uc1swXS5leHByLmNvbHVtbn1cXGApIGFzIHRvdGFsYCxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5maXJzdCgpXG4gICAgICAgICAgOiBjbG9uZWRRYi5jbGVhcihcInNlbGVjdFwiKS5jb3VudChcIipcIiwgeyBhczogXCJ0b3RhbFwiIH0pLmZpcnN0KCk7XG4gICAgICBjb25zdCBjb3VudFJvdzogeyB0b3RhbD86IG51bWJlciB9ID0gYXdhaXQgY291bnRRdWVyeTtcblxuICAgICAgaWYgKGRlYnVnID09PSB0cnVlIHx8IGRlYnVnID09PSBcImNvdW50XCIpIHtcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcIkRFQlVHOiBjb3VudCBxdWVyeVwiLCBjaGFsay5ibHVlKGNvdW50UXVlcnkudG9RdWVyeSgpLnRvU3RyaW5nKCkpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNvdW50Um93Py50b3RhbCA/PyAwO1xuICAgIH0pKCk7XG5cbiAgICAvLyBsaXN0UXVlcnlcbiAgICBjb25zdCByb3dzID0gYXdhaXQgKGFzeW5jICgpID0+IHtcbiAgICAgIGlmIChxdWVyeU1vZGUgPT09IFwiY291bnRcIikge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMubnVtICE9PSAwKSB7XG4gICAgICAgIGFzc2VydChwYXJhbXMubnVtKTtcbiAgICAgICAgcWIubGltaXQocGFyYW1zLm51bSk7XG4gICAgICAgIHFiLm9mZnNldChwYXJhbXMubnVtICogKChwYXJhbXMucGFnZSA/PyAxKSAtIDEpKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2xvbmVkUWIgPSBxYi5jbG9uZSgpLnNlbGVjdChzZWxlY3QpO1xuICAgICAgYXBwbHlKb2luQ2xhdXNlKGNsb25lZFFiLCBqb2lucyk7XG5cbiAgICAgIGNvbnN0IGxpc3RRdWVyeSA9IGFmdGVyQnVpbGQ/Lih7IHFiOiBjbG9uZWRRYiwgZGIsIHNlbGVjdCwgam9pbnMsIHZpcnR1YWwgfSkgPz8gY2xvbmVkUWI7XG5cbiAgICAgIGxldCByb3dzID0gYXdhaXQgbGlzdFF1ZXJ5O1xuICAgICAgaWYgKGRlYnVnID09PSB0cnVlIHx8IGRlYnVnID09PSBcImxpc3RcIikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKFwiREVCVUc6IGxpc3QgcXVlcnlcIiwgY2hhbGsuYmx1ZShsaXN0UXVlcnkudG9RdWVyeSgpLnRvU3RyaW5nKCkpKTtcbiAgICAgIH1cblxuICAgICAgcm93cyA9IGF3YWl0IHRoaXMudXNlTG9hZGVycyhkYiwgcm93cywgbG9hZGVycyk7XG4gICAgICByb3dzID0gdGhpcy5oeWRyYXRlKHJvd3MpO1xuICAgICAgcmV0dXJuIHJvd3M7XG4gICAgfSkoKTtcblxuICAgIHJldHVybiB7IHJvd3MsIHRvdGFsLCBzdWJzZXRRdWVyeSwgcWIgfTtcbiAgfVxuXG4gIC8vIExlZ2FjeSBMb2FkZXIg7LKY66asIChQdXJpIOuPhOyehSDsoIQg7Zi47ZmY7JqpKVxuICBhc3luYyB1c2VMb2FkZXJzKGRiOiBLbmV4LCByb3dzOiBVbmtub3duREJSZWNvcmRbXSwgbG9hZGVyczogU3Vic2V0UXVlcnlbXCJsb2FkZXJzXCJdKSB7XG4gICAgaWYgKGxvYWRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gcm93cztcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGxvYWRlciBvZiBsb2FkZXJzKSB7XG4gICAgICBsZXQgc3ViUTogS25leC5RdWVyeUJ1aWxkZXI7XG4gICAgICBsZXQgc3ViUm93czogVW5rbm93bkRCUmVjb3JkW107XG4gICAgICBsZXQgdG9Db2w6IHN0cmluZztcblxuICAgICAgY29uc3QgZnJvbUlkcyA9IHJvd3MubWFwKChyb3cpID0+IHJvd1tsb2FkZXIubWFueUpvaW4uaWRGaWVsZF0pO1xuXG4gICAgICBpZiAobG9hZGVyLm1hbnlKb2luLnRocm91Z2ggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBIYXNNYW55XG4gICAgICAgIGNvbnN0IGlkQ29sdW1uID0gYCR7bG9hZGVyLm1hbnlKb2luLnRvVGFibGV9LiR7bG9hZGVyLm1hbnlKb2luLnRvQ29sfWA7XG4gICAgICAgIHN1YlEgPSBkYihsb2FkZXIubWFueUpvaW4udG9UYWJsZSlcbiAgICAgICAgICAud2hlcmVJbihpZENvbHVtbiBhcyBzdHJpbmcsIGZyb21JZHMgYXMgc3RyaW5nW10pXG4gICAgICAgICAgLnNlbGVjdChbLi4ubG9hZGVyLnNlbGVjdCwgaWRDb2x1bW5dKTtcblxuICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbikgPT4ge1xuICAgICAgICAgIGlmIChqb2luLmpvaW4gPT09IFwiaW5uZXJcIikge1xuICAgICAgICAgICAgc3ViUS5pbm5lckpvaW4oYCR7am9pbi50YWJsZX0gYXMgJHtqb2luLmFzfWAsIHRoaXMuZ2V0Sm9pbkNsYXVzZShkYiwgam9pbikpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoam9pbi5qb2luID09PSBcIm91dGVyXCIpIHtcbiAgICAgICAgICAgIHN1YlEubGVmdE91dGVySm9pbihgJHtqb2luLnRhYmxlfSBhcyAke2pvaW4uYXN9YCwgdGhpcy5nZXRKb2luQ2xhdXNlKGRiLCBqb2luKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdG9Db2wgPSBsb2FkZXIubWFueUpvaW4udG9Db2w7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBNYW55VG9NYW55XG4gICAgICAgIGNvbnN0IGlkQ29sdW1uID0gYCR7bG9hZGVyLm1hbnlKb2luLnRocm91Z2gudGFibGV9LiR7bG9hZGVyLm1hbnlKb2luLnRocm91Z2guZnJvbUNvbH1gO1xuICAgICAgICBzdWJRID0gZGIobG9hZGVyLm1hbnlKb2luLnRocm91Z2gudGFibGUpXG4gICAgICAgICAgLmpvaW4oXG4gICAgICAgICAgICBsb2FkZXIubWFueUpvaW4udG9UYWJsZSxcbiAgICAgICAgICAgIGAke2xvYWRlci5tYW55Sm9pbi50aHJvdWdoLnRhYmxlfS4ke2xvYWRlci5tYW55Sm9pbi50aHJvdWdoLnRvQ29sfWAsXG4gICAgICAgICAgICBgJHtsb2FkZXIubWFueUpvaW4udG9UYWJsZX0uJHtsb2FkZXIubWFueUpvaW4udG9Db2x9YCxcbiAgICAgICAgICApXG4gICAgICAgICAgLndoZXJlSW4oaWRDb2x1bW4gYXMgc3RyaW5nLCBmcm9tSWRzIGFzIHN0cmluZ1tdKVxuICAgICAgICAgIC5zZWxlY3QodW5pcXVlKFsuLi5sb2FkZXIuc2VsZWN0LCBpZENvbHVtbl0pKTtcblxuICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbikgPT4ge1xuICAgICAgICAgIGlmIChqb2luLmpvaW4gPT09IFwiaW5uZXJcIikge1xuICAgICAgICAgICAgc3ViUS5pbm5lckpvaW4oYCR7am9pbi50YWJsZX0gYXMgJHtqb2luLmFzfWAsIHRoaXMuZ2V0Sm9pbkNsYXVzZShkYiwgam9pbikpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoam9pbi5qb2luID09PSBcIm91dGVyXCIpIHtcbiAgICAgICAgICAgIHN1YlEubGVmdE91dGVySm9pbihgJHtqb2luLnRhYmxlfSBhcyAke2pvaW4uYXN9YCwgdGhpcy5nZXRKb2luQ2xhdXNlKGRiLCBqb2luKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdG9Db2wgPSBsb2FkZXIubWFueUpvaW4udGhyb3VnaC5mcm9tQ29sO1xuICAgICAgfVxuICAgICAgc3ViUm93cyA9IGF3YWl0IHN1YlE7XG5cbiAgICAgIGlmIChsb2FkZXIubG9hZGVycykge1xuICAgICAgICBzdWJSb3dzID0gYXdhaXQgdGhpcy51c2VMb2FkZXJzKGRiLCBzdWJSb3dzLCBsb2FkZXIubG9hZGVycyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN1YlJvd0dyb3VwcyA9IGdyb3VwKHN1YlJvd3MsIChyb3cpID0+IHJvd1t0b0NvbF0gYXMgc3RyaW5nKTtcbiAgICAgIHJvd3MgPSByb3dzLm1hcCgocm93KSA9PiB7XG4gICAgICAgIHJvd1tsb2FkZXIuYXNdID0gKHN1YlJvd0dyb3Vwc1tyb3dbbG9hZGVyLm1hbnlKb2luLmlkRmllbGRdIGFzIHN0cmluZ10gPz8gW10pLm1hcCgocikgPT5cbiAgICAgICAgICBvbWl0KHIsIFt0b0NvbF0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gcm93O1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByb3dzO1xuICB9XG5cbiAgZ2V0Sm9pbkNsYXVzZShkYjogS25leDxhbnksIHVua25vd24+LCBqb2luOiBTdWJzZXRRdWVyeVtcImpvaW5zXCJdW251bWJlcl0pOiBLbmV4LlJhdzxhbnk+IHtcbiAgICBpZiAoIWlzQ3VzdG9tSm9pbkNsYXVzZShqb2luKSkge1xuICAgICAgcmV0dXJuIGRiLnJhdyhgJHtqb2luLmZyb219ID0gJHtqb2luLnRvfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZGIucmF3KGpvaW4uY3VzdG9tKTtcbiAgICB9XG4gIH1cblxuICBnZXRVcHNlcnRCdWlsZGVyKCk6IFVwc2VydEJ1aWxkZXIge1xuICAgIHJldHVybiBuZXcgVXBzZXJ0QnVpbGRlcigpO1xuICB9XG59XG5cbi8qKlxuICogRW5oYW5jZXIg7YyM652866+47YSwIOyhsOqxtOu2gCDtg4DsnoVcbiAqIFJlcXVpcmVkRW5oYW5jZXJLZXlz6rCAIOyXhuycvOuptCBlbmhhbmNlcnMg7ISg7YOd7KCBLCDsnojsnLzrqbQg7ZWE7IiYXG4gKi9cbnR5cGUgRW5oYW5jZXJQYXJhbTxcbiAgVFN1YnNldEtleSBleHRlbmRzIHN0cmluZyxcbiAgVENvbXB1dGVkUmVzdWx0cyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBhbnk+LFxuICBUU3Vic2V0TWFwcGluZyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBhbnk+LFxuPiA9IFtSZXF1aXJlZEVuaGFuY2VyS2V5czxUU3Vic2V0S2V5LCBUQ29tcHV0ZWRSZXN1bHRzLCBUU3Vic2V0TWFwcGluZz5dIGV4dGVuZHMgW25ldmVyXVxuICA/IHsgZW5oYW5jZXJzPzogRW5oYW5jZXJNYXA8VFN1YnNldEtleSwgVENvbXB1dGVkUmVzdWx0cywgVFN1YnNldE1hcHBpbmc+IH1cbiAgOiB7IGVuaGFuY2VyczogRW5oYW5jZXJNYXA8VFN1YnNldEtleSwgVENvbXB1dGVkUmVzdWx0cywgVFN1YnNldE1hcHBpbmc+IH07XG5cbnR5cGUgUmVxdWlyZWRFbmhhbmNlcktleXM8XG4gIFRTdWJzZXRLZXkgZXh0ZW5kcyBzdHJpbmcsXG4gIFRDb21wdXRlZFJlc3VsdHMgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgYW55PixcbiAgVFN1YnNldE1hcHBpbmcgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgYW55Pixcbj4gPSB7XG4gIFtLIGluIFRTdWJzZXRLZXldOiBUQ29tcHV0ZWRSZXN1bHRzW0tdIGV4dGVuZHMgVFN1YnNldE1hcHBpbmdbS10gPyBuZXZlciA6IEs7XG59W1RTdWJzZXRLZXldO1xuXG5leHBvcnQgY29uc3QgQmFzZU1vZGVsID0gbmV3IEJhc2VNb2RlbENsYXNzKCk7XG4iXSwibmFtZXMiOlsiYXNzZXJ0IiwiaW5mbGVjdGlvbiIsImdyb3VwIiwiaXNPYmplY3QiLCJvbWl0Iiwic2V0IiwidW5pcXVlIiwiU29uYW11IiwiaXNDdXN0b21Kb2luQ2xhdXNlIiwiZ2V0Sm9pblRhYmxlcyIsImdldFRhYmxlTmFtZXNGcm9tV2hlcmUiLCJjaHVuayIsIkRCIiwiUHVyaSIsIlB1cmlXcmFwcGVyIiwiVXBzZXJ0QnVpbGRlciIsIkJhc2VNb2RlbENsYXNzIiwibW9kZWxOYW1lIiwic3Vic2V0UXVlcmllcyIsImxvYWRlclF1ZXJpZXMiLCJnZXREQiIsIndoaWNoIiwiZ2V0UHVyaSIsInRyeCIsImdldFRyYW5zYWN0aW9uQ29udGV4dCIsImdldFRyYW5zYWN0aW9uIiwiZGIiLCJnZXRVcHNlcnRCdWlsZGVyIiwiZGVzdHJveSIsImdldEluc2VydGVkSWRzIiwid2RiIiwicm93cyIsInRhYmxlTmFtZSIsInVucUtleUZpZWxkcyIsImNodW5rU2l6ZSIsInVucUtleXMiLCJ3aGVyZUluRmllbGQiLCJzZWxlY3RGaWVsZCIsImxlbmd0aCIsInJhdyIsImpvaW4iLCJtYXAiLCJyb3ciLCJmaWVsZCIsInJlc3VsdElkcyIsIml0ZW1zIiwiZGJSb3dzIiwic2VsZWN0Iiwid2hlcmVJbiIsImNvbmNhdCIsImRiUm93IiwicGFyc2VJbnQiLCJTdHJpbmciLCJpZCIsImdldFN1YnNldFF1ZXJpZXMiLCJzdWJzZXQiLCJFcnJvciIsInB1cmlXcmFwcGVyIiwicWIiLCJvblN1YnNldCIsIl9zdWJzZXQiLCJjcmVhdGVFbmhhbmNlcnMiLCJlbmhhbmNlcnMiLCJleGVjdXRlU3Vic2V0UXVlcnkiLCJwYXJhbXMiLCJxdWVyeVBhcmFtcyIsImRlYnVnIiwib3B0aW1pemVDb3VudFF1ZXJ5IiwibnVtIiwicGFnZSIsInRvdGFsIiwiZXhlY3V0ZUNvdW50UXVlcnkiLCJjb21wdXRlZFJvd3MiLCJleGVjdXRlTGlzdFF1ZXJ5IiwiZW5oYW5jZXIiLCJQcm9taXNlIiwiYWxsIiwicXVlcnlNb2RlIiwiY291bnRQdXJpIiwiY2xvbmUiLCJjbGVhciIsImRlZmF1bHQiLCJTcWxQYXJzZXIiLCJwYXJzZXIiLCJQYXJzZXIiLCJwYXJzZWRRdWVyeSIsImFzdGlmeSIsInRvUXVlcnkiLCJkYXRhYmFzZSIsImNvbmZpZyIsImxlZnRKb2luVGFibGVzIiwid2hlcmVUYWJsZXMiLCJ0YWJsZXNUb1JlbW92ZSIsImZpbHRlciIsImoiLCJpbmNsdWRlcyIsImZvckVhY2giLCJ0YWJsZSIsImNsZWFySm9pbiIsImNvdW50UmVzdWx0IiwicmF3TnVtYmVyIiwiZmlyc3QiLCJ1bmxvYWRlZFJvd3MiLCJsaW1pdCIsIm9mZnNldCIsImxvYWRlcnMiLCJBcnJheSIsImlzQXJyYXkiLCJwcm9jZXNzTG9hZGVycyIsImh5ZHJhdGUiLCJyZXNvbHZlTG9hZGVyIiwiYXMiLCJyZWZJZCIsInJlc29sdmVMb2FkZXJRYkZuIiwibmVzdGVkTG9hZGVycyIsInJlc29sdmVMb2FkZXJRYiIsImxvYWRlZFJvd3MiLCJzdWJSb3dHcm91cHMiLCJyIiwibmVzdGVkS2V5cyIsIk9iamVjdCIsImtleXMiLCJrZXkiLCJncm91cHMiLCJncm91cEJ5Iiwic3BsaXQiLCJudWxsS2V5cyIsImVudHJpZXMiLCJfIiwiZGF0YSIsImV2ZXJ5IiwiaHlkcmF0ZWQiLCJyZWR1Y2UiLCJwYXJ0cyIsIm9ialBhdGgiLCJzbGljZSIsInBhcnQiLCJudWxsS2V5IiwicnVuU3Vic2V0UXVlcnkiLCJiYXNlVGFibGUiLCJzdWJzZXRRdWVyeSIsImJ1aWxkIiwiYWZ0ZXJCdWlsZCIsIl9kYiIsImNoYWxrIiwiZ2V0VGFibGVOYW1lIiwic3RhcnRzV2l0aCIsInBsdXJhbGl6ZSIsInVuZGVyc2NvcmUiLCJ1bmRlZmluZWQiLCJ2aXJ0dWFsIiwiam9pbnMiLCJmcm9tIiwiYXBwbHlKb2luQ2xhdXNlIiwiaW5uZXJKb2luIiwiZ2V0Sm9pbkNsYXVzZSIsImxlZnRPdXRlckpvaW4iLCJjbG9uZWRRYiIsInRhYmxlcyIsIm5lZWRUb0pvaW4iLCJmbGF0TWFwIiwidCIsInByb2Nlc3NlZFFiIiwicSIsInR5cGUiLCJjb3VudFF1ZXJ5IiwiZGlzdGluY3QiLCJjb2x1bW5zIiwiZXhwciIsImNvbHVtbiIsImNvdW50IiwiY291bnRSb3ciLCJjb25zb2xlIiwiYmx1ZSIsInRvU3RyaW5nIiwibGlzdFF1ZXJ5IiwidXNlTG9hZGVycyIsImxvYWRlciIsInN1YlEiLCJzdWJSb3dzIiwidG9Db2wiLCJmcm9tSWRzIiwibWFueUpvaW4iLCJpZEZpZWxkIiwidGhyb3VnaCIsImlkQ29sdW1uIiwidG9UYWJsZSIsIm9uZUpvaW5zIiwiZnJvbUNvbCIsInRvIiwiY3VzdG9tIiwiQmFzZU1vZGVsIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxZQUFZLFNBQVM7QUFDNUIsT0FBT0Ms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
@@ -0,0 +1,93 @@
1
+ /**
2
+ * BaseModel 타입 시스템
3
+ *
4
+ * BaseModelClass에서 사용하는 타입 유틸리티들.
5
+ * Enhancer, SubsetQuery 교집합 등 Model 계층에서 필요한 타입 정의.
6
+ */
7
+ import type { DatabaseSchemaExtend } from "../types/types";
8
+ import type { Puri } from "./puri";
9
+ import type { PuriSubsetFn } from "./puri-subset.types";
10
+ /**
11
+ * Puri 인스턴스에서 TTables 타입 추출
12
+ */
13
+ export type ExtractPuriTables<T> = T extends Puri<any, infer TTables, any> ? TTables : never;
14
+ /**
15
+ * SubsetQueries에서 모든 TTables의 유니온 추출
16
+ * getSubsetQueries의 qb 타입 정의에 사용
17
+ */
18
+ export type UnionExtractedTTables<TSubsetKey extends string, TSubsetQueries extends Record<TSubsetKey, PuriSubsetFn>> = ExtractPuriTables<ReturnType<TSubsetQueries[TSubsetKey]>>;
19
+ /**
20
+ * 두 Puri의 테이블 교집합을 가진 새로운 Puri 생성
21
+ */
22
+ type MergePuriTables<A, B, TA = ExtractPuriTables<A>, TB = ExtractPuriTables<B>> = Puri<DatabaseSchemaExtend, Pick<TA, Extract<keyof TA, keyof TB>>, any>;
23
+ /**
24
+ * 서브셋 키 배열을 순회하며 테이블 교집합 Puri 계산
25
+ *
26
+ * onSubset(['A', 'P'])와 같이 여러 subset을 지정했을 때,
27
+ * 공통으로 사용 가능한 테이블만 포함된 Puri 타입 반환
28
+ */
29
+ export type ResolveSubsetIntersection<Keys extends readonly string[], Queries extends Record<string, (...args: any) => any>> = Keys extends [infer Head extends string, ...infer Tail extends string[]] ? Tail extends [] ? ReturnType<Queries[Head]> : MergePuriTables<ReturnType<Queries[Head]>, ResolveSubsetIntersection<Tail, Queries>> : never;
30
+ /**
31
+ * 단일 Enhancer 함수 타입
32
+ * computed 결과를 받아 최종 mapping 타입으로 변환
33
+ */
34
+ export type EnhancerFn<TComputed, TMapping> = (row: TComputed) => TMapping | Promise<TMapping>;
35
+ /**
36
+ * Enhancer가 필수인 SubsetKey 추출
37
+ *
38
+ * ComputedResults[K]가 SubsetMapping[K]에 할당 불가능하면 해당 K는 필수
39
+ * (즉, virtual 필드 등 추가 변환이 필요한 경우)
40
+ */
41
+ export type RequiredEnhancerKeys<TSubsetKey extends string, TComputedResults extends Record<TSubsetKey, any>, TSubsetMapping extends Record<TSubsetKey, any>> = {
42
+ [K in TSubsetKey]: TComputedResults[K] extends TSubsetMapping[K] ? never : K;
43
+ }[TSubsetKey];
44
+ /**
45
+ * Enhancer 객체 타입 정의
46
+ *
47
+ * - ComputedResults[K]가 SubsetMapping[K]에 assignable하면 → enhancer 선택적
48
+ * - 그렇지 않으면 → enhancer 필수
49
+ *
50
+ * @example
51
+ * // virtual 필드 employee_count가 있는 경우
52
+ * type Computed = { id: number; name: string }
53
+ * type Mapping = { id: number; name: string; employee_count: number }
54
+ * // → Enhancer 필수 (employee_count 계산 필요)
55
+ */
56
+ export type EnhancerMap<TSubsetKey extends string, TComputedResults extends Record<TSubsetKey, any>, TSubsetMapping extends Record<TSubsetKey, any>> = {
57
+ [K in TSubsetKey as TComputedResults[K] extends TSubsetMapping[K] ? K : never]?: EnhancerFn<TComputedResults[K], TSubsetMapping[K]>;
58
+ } & {
59
+ [K in TSubsetKey as TComputedResults[K] extends TSubsetMapping[K] ? never : K]: EnhancerFn<TComputedResults[K], TSubsetMapping[K]>;
60
+ };
61
+ /**
62
+ * executeSubsetQuery 기본 파라미터
63
+ */
64
+ export type ExecuteSubsetQueryBaseParams<TSubsetKey extends string> = {
65
+ subset: TSubsetKey;
66
+ qb: Puri<any, any, any>;
67
+ params: {
68
+ num?: number;
69
+ page?: number;
70
+ queryMode?: "list" | "count" | "both";
71
+ };
72
+ debug?: boolean;
73
+ optimizeCountQuery?: boolean;
74
+ };
75
+ /**
76
+ * executeSubsetQuery 파라미터 (Enhancer 포함)
77
+ *
78
+ * RequiredEnhancerKeys가 없으면 enhancers 선택적, 있으면 필수
79
+ */
80
+ export type ExecuteSubsetQueryParams<TSubsetKey extends string, TComputedResults extends Record<TSubsetKey, any>, TSubsetMapping extends Record<TSubsetKey, any>, T extends TSubsetKey> = ExecuteSubsetQueryBaseParams<T> & ([RequiredEnhancerKeys<TSubsetKey, TComputedResults, TSubsetMapping>] extends [never] ? {
81
+ enhancers?: EnhancerMap<TSubsetKey, TComputedResults, TSubsetMapping>;
82
+ } : {
83
+ enhancers: EnhancerMap<TSubsetKey, TComputedResults, TSubsetMapping>;
84
+ });
85
+ /**
86
+ * executeSubsetQuery 반환 타입
87
+ */
88
+ export type ExecuteSubsetQueryResult<TSubsetMapping extends Record<string, any>, T extends string> = {
89
+ rows: TSubsetMapping[T][];
90
+ total: number;
91
+ };
92
+ export {};
93
+ //# sourceMappingURL=base-model.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-model.types.d.ts","sourceRoot":"","sources":["../../src/database/base-model.types.ts"],"names":[],"mappings":"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"}