sonamu 0.5.6 → 0.6.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 (365) hide show
  1. package/dist/api/base-frame.js +12 -2
  2. package/dist/api/caster.js +66 -2
  3. package/dist/api/code-converters.js +489 -2
  4. package/dist/api/config.d.ts +76 -0
  5. package/dist/api/config.d.ts.map +1 -0
  6. package/dist/api/config.js +32 -0
  7. package/dist/api/context.d.ts +1 -0
  8. package/dist/api/context.d.ts.map +1 -1
  9. package/dist/api/context.js +3 -2
  10. package/dist/api/decorators.d.ts +1 -0
  11. package/dist/api/decorators.d.ts.map +1 -1
  12. package/dist/api/decorators.js +142 -2
  13. package/dist/api/index.js +9 -2
  14. package/dist/api/sonamu.d.ts +8 -22
  15. package/dist/api/sonamu.d.ts.map +1 -1
  16. package/dist/api/sonamu.js +482 -2
  17. package/dist/bin/build-config.d.ts +2 -1
  18. package/dist/bin/build-config.d.ts.map +1 -1
  19. package/dist/bin/build-config.js +12 -2
  20. package/dist/bin/cli-wrapper.js +71 -2
  21. package/dist/bin/cli.js +418 -2
  22. package/dist/bin/hot-hook-register.d.ts +11 -0
  23. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  24. package/dist/bin/hot-hook-register.js +21 -0
  25. package/dist/database/_batch_update.js +78 -2
  26. package/dist/database/base-model.js +247 -2
  27. package/dist/database/code-generator.js +53 -2
  28. package/dist/database/db.d.ts +5 -16
  29. package/dist/database/db.d.ts.map +1 -1
  30. package/dist/database/db.js +132 -2
  31. package/dist/database/knex-plugins/knex-on-duplicate-update.js +39 -2
  32. package/dist/database/puri-wrapper.d.ts +22 -10
  33. package/dist/database/puri-wrapper.d.ts.map +1 -1
  34. package/dist/database/puri-wrapper.js +109 -2
  35. package/dist/database/puri.d.ts +105 -73
  36. package/dist/database/puri.d.ts.map +1 -1
  37. package/dist/database/puri.js +539 -2
  38. package/dist/database/puri.types.d.ts +33 -42
  39. package/dist/database/puri.types.d.ts.map +1 -1
  40. package/dist/database/puri.types.js +3 -2
  41. package/dist/database/transaction-context.d.ts +3 -3
  42. package/dist/database/transaction-context.d.ts.map +1 -1
  43. package/dist/database/transaction-context.js +14 -2
  44. package/dist/database/upsert-builder.js +215 -2
  45. package/dist/entity/entity-manager.d.ts +3 -1
  46. package/dist/entity/entity-manager.d.ts.map +1 -1
  47. package/dist/entity/entity-manager.js +114 -2
  48. package/dist/entity/entity-utils.js +210 -2
  49. package/dist/entity/entity.d.ts.map +1 -1
  50. package/dist/entity/entity.js +651 -2
  51. package/dist/exceptions/error-handler.js +29 -2
  52. package/dist/exceptions/so-exceptions.js +85 -2
  53. package/dist/file-storage/driver.js +79 -2
  54. package/dist/file-storage/file-storage.js +75 -2
  55. package/dist/index.d.ts +2 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +28 -2
  58. package/dist/migration/code-generation.js +558 -2
  59. package/dist/migration/migration-set.js +364 -2
  60. package/dist/migration/migrator.d.ts +0 -9
  61. package/dist/migration/migrator.d.ts.map +1 -1
  62. package/dist/migration/migrator.js +510 -2
  63. package/dist/migration/types.js +3 -2
  64. package/dist/naite/naite.d.ts +12 -0
  65. package/dist/naite/naite.d.ts.map +1 -0
  66. package/dist/naite/naite.js +72 -0
  67. package/dist/stream/index.js +3 -2
  68. package/dist/stream/sse.js +38 -2
  69. package/dist/syncer/api-parser.d.ts +20 -0
  70. package/dist/syncer/api-parser.d.ts.map +1 -0
  71. package/dist/syncer/api-parser.js +229 -0
  72. package/dist/syncer/checksum.d.ts +21 -0
  73. package/dist/syncer/checksum.d.ts.map +1 -0
  74. package/dist/syncer/checksum.js +98 -0
  75. package/dist/syncer/code-generator.d.ts +20 -0
  76. package/dist/syncer/code-generator.d.ts.map +1 -0
  77. package/dist/syncer/code-generator.js +141 -0
  78. package/dist/syncer/entity-operations.d.ts +17 -0
  79. package/dist/syncer/entity-operations.d.ts.map +1 -0
  80. package/dist/syncer/entity-operations.js +58 -0
  81. package/dist/syncer/file-patterns.d.ts +29 -0
  82. package/dist/syncer/file-patterns.d.ts.map +1 -0
  83. package/dist/syncer/file-patterns.js +38 -0
  84. package/dist/syncer/index.d.ts +6 -0
  85. package/dist/syncer/index.d.ts.map +1 -1
  86. package/dist/syncer/index.js +9 -2
  87. package/dist/syncer/module-loader.d.ts +35 -0
  88. package/dist/syncer/module-loader.d.ts.map +1 -0
  89. package/dist/syncer/module-loader.js +82 -0
  90. package/dist/syncer/syncer.d.ts +93 -108
  91. package/dist/syncer/syncer.d.ts.map +1 -1
  92. package/dist/syncer/syncer.js +375 -2
  93. package/dist/template/entity-converter.d.ts +14 -0
  94. package/dist/template/entity-converter.d.ts.map +1 -0
  95. package/dist/template/entity-converter.js +101 -0
  96. package/dist/template/helpers.d.ts +23 -0
  97. package/dist/template/helpers.d.ts.map +1 -0
  98. package/dist/template/helpers.js +64 -0
  99. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  100. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  101. package/dist/template/implementations/entity.template.js +87 -0
  102. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -3
  103. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  104. package/dist/template/implementations/generated.template.js +232 -0
  105. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -3
  106. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  107. package/dist/template/implementations/generated_http.template.js +131 -0
  108. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +3 -3
  109. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  110. package/dist/template/implementations/generated_sso.template.js +105 -0
  111. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  112. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  113. package/dist/template/implementations/init_types.template.js +38 -0
  114. package/dist/template/implementations/model.template.d.ts +17 -0
  115. package/dist/template/implementations/model.template.d.ts.map +1 -0
  116. package/dist/template/implementations/model.template.js +171 -0
  117. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  118. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  119. package/dist/template/implementations/model_test.template.js +35 -0
  120. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  121. package/dist/template/implementations/service.template.d.ts.map +1 -0
  122. package/dist/template/implementations/service.template.js +193 -0
  123. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  124. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  125. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  126. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  127. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  128. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  129. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  130. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  131. package/dist/template/implementations/view_enums_select.template.js +55 -0
  132. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  133. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  134. package/dist/template/implementations/view_form.template.js +337 -0
  135. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  136. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  137. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  138. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  139. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  140. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  141. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  142. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  143. package/dist/template/implementations/view_list.template.js +465 -0
  144. package/dist/{templates → template/implementations}/view_list_columns.template.d.ts +3 -3
  145. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  146. package/dist/template/implementations/view_list_columns.template.js +49 -0
  147. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  148. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  149. package/dist/template/implementations/view_search_input.template.js +64 -0
  150. package/dist/template/index.d.ts +5 -0
  151. package/dist/template/index.d.ts.map +1 -0
  152. package/dist/template/index.js +6 -0
  153. package/dist/template/template.d.ts +39 -0
  154. package/dist/template/template.d.ts.map +1 -0
  155. package/dist/template/template.js +47 -0
  156. package/dist/template/zod-converter.d.ts +18 -0
  157. package/dist/template/zod-converter.d.ts.map +1 -0
  158. package/dist/template/zod-converter.js +166 -0
  159. package/dist/testing/_relation-graph.js +80 -2
  160. package/dist/testing/fixture-manager.d.ts.map +1 -1
  161. package/dist/testing/fixture-manager.js +521 -2
  162. package/dist/types/types.d.ts +39 -40
  163. package/dist/types/types.d.ts.map +1 -1
  164. package/dist/types/types.js +289 -2
  165. package/dist/typings/knex.d.js +3 -2
  166. package/dist/utils/async-utils.d.ts +7 -0
  167. package/dist/utils/async-utils.d.ts.map +1 -1
  168. package/dist/utils/async-utils.js +57 -2
  169. package/dist/utils/console-util.d.ts +2 -0
  170. package/dist/utils/console-util.d.ts.map +1 -0
  171. package/dist/utils/console-util.js +6 -0
  172. package/dist/utils/controller.js +26 -2
  173. package/dist/utils/esm-utils.d.ts +45 -0
  174. package/dist/utils/esm-utils.d.ts.map +1 -0
  175. package/dist/utils/esm-utils.js +56 -0
  176. package/dist/utils/fs-utils.js +17 -2
  177. package/dist/utils/lodash-able.js +6 -2
  178. package/dist/utils/model.js +22 -2
  179. package/dist/utils/path-utils.d.ts +89 -0
  180. package/dist/utils/path-utils.d.ts.map +1 -0
  181. package/dist/utils/path-utils.js +60 -0
  182. package/dist/utils/process-utils.d.ts +13 -0
  183. package/dist/utils/process-utils.d.ts.map +1 -0
  184. package/dist/utils/process-utils.js +36 -0
  185. package/dist/utils/sql-parser.js +35 -2
  186. package/dist/utils/utils.d.ts +4 -7
  187. package/dist/utils/utils.d.ts.map +1 -1
  188. package/dist/utils/utils.js +33 -2
  189. package/dist/utils/zod-error.d.ts.map +1 -1
  190. package/dist/utils/zod-error.js +19 -2
  191. package/package.json +21 -9
  192. package/src/api/code-converters.ts +2 -2
  193. package/src/api/config.ts +142 -0
  194. package/src/api/context.ts +1 -0
  195. package/src/api/decorators.ts +15 -5
  196. package/src/api/sonamu.ts +102 -87
  197. package/src/bin/build-config.ts +2 -1
  198. package/src/bin/cli-wrapper.ts +10 -3
  199. package/src/bin/cli.ts +108 -56
  200. package/src/bin/hot-hook-register.ts +22 -0
  201. package/src/database/base-model.ts +1 -1
  202. package/src/database/code-generator.ts +1 -1
  203. package/src/database/db.ts +53 -60
  204. package/src/database/puri-wrapper.ts +104 -26
  205. package/src/database/puri.ts +477 -580
  206. package/src/database/puri.types.ts +111 -201
  207. package/src/database/transaction-context.ts +4 -4
  208. package/src/database/upsert-builder.ts +1 -1
  209. package/src/entity/entity-manager.ts +19 -15
  210. package/src/entity/entity.ts +4 -3
  211. package/src/index.ts +2 -0
  212. package/src/migration/code-generation.ts +1 -1
  213. package/src/migration/migration-set.ts +1 -1
  214. package/src/migration/migrator.ts +23 -152
  215. package/src/naite/naite.ts +70 -0
  216. package/src/syncer/api-parser.ts +299 -0
  217. package/src/syncer/checksum.ts +152 -0
  218. package/src/syncer/code-generator.ts +202 -0
  219. package/src/syncer/entity-operations.ts +68 -0
  220. package/src/syncer/file-patterns.ts +56 -0
  221. package/src/syncer/index.ts +6 -0
  222. package/src/syncer/module-loader.ts +125 -0
  223. package/src/syncer/syncer.ts +363 -1420
  224. package/src/template/entity-converter.ts +123 -0
  225. package/src/template/helpers.ts +84 -0
  226. package/src/{templates → template/implementations}/entity.template.ts +4 -4
  227. package/src/{templates → template/implementations}/generated.template.ts +9 -9
  228. package/src/{templates → template/implementations}/generated_http.template.ts +9 -6
  229. package/src/{templates → template/implementations}/generated_sso.template.ts +7 -7
  230. package/src/{templates → template/implementations}/init_types.template.ts +4 -4
  231. package/src/{templates → template/implementations}/model.template.ts +9 -9
  232. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  233. package/src/{templates → template/implementations}/service.template.ts +29 -12
  234. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  235. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +5 -21
  236. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  237. package/src/{templates → template/implementations}/view_form.template.ts +11 -13
  238. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  239. package/src/{templates → template/implementations}/view_id_async_select.template.ts +3 -3
  240. package/src/{templates → template/implementations}/view_list.template.ts +13 -64
  241. package/src/{templates → template/implementations}/view_list_columns.template.ts +3 -3
  242. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  243. package/src/template/index.ts +4 -0
  244. package/src/template/template.ts +86 -0
  245. package/src/template/zod-converter.ts +219 -0
  246. package/src/testing/fixture-manager.ts +8 -1
  247. package/src/types/types.ts +39 -62
  248. package/src/utils/async-utils.ts +17 -0
  249. package/src/utils/console-util.ts +4 -0
  250. package/src/utils/esm-utils.ts +69 -0
  251. package/src/utils/path-utils.ts +102 -0
  252. package/src/utils/process-utils.ts +46 -0
  253. package/src/utils/sql-parser.ts +1 -1
  254. package/src/utils/utils.ts +14 -40
  255. package/src/utils/zod-error.ts +0 -1
  256. package/dist/api/base-frame.js.map +0 -1
  257. package/dist/api/caster.js.map +0 -1
  258. package/dist/api/code-converters.js.map +0 -1
  259. package/dist/api/context.js.map +0 -1
  260. package/dist/api/decorators.js.map +0 -1
  261. package/dist/api/index.js.map +0 -1
  262. package/dist/api/sonamu.js.map +0 -1
  263. package/dist/bin/build-config.js.map +0 -1
  264. package/dist/bin/cli-wrapper.js.map +0 -1
  265. package/dist/bin/cli.js.map +0 -1
  266. package/dist/database/_batch_update.js.map +0 -1
  267. package/dist/database/base-model.js.map +0 -1
  268. package/dist/database/code-generator.js.map +0 -1
  269. package/dist/database/db.js.map +0 -1
  270. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  271. package/dist/database/puri-wrapper.js.map +0 -1
  272. package/dist/database/puri.js.map +0 -1
  273. package/dist/database/puri.types.js.map +0 -1
  274. package/dist/database/transaction-context.js.map +0 -1
  275. package/dist/database/upsert-builder.js.map +0 -1
  276. package/dist/entity/entity-manager.js.map +0 -1
  277. package/dist/entity/entity-utils.js.map +0 -1
  278. package/dist/entity/entity.js.map +0 -1
  279. package/dist/exceptions/error-handler.js.map +0 -1
  280. package/dist/exceptions/so-exceptions.js.map +0 -1
  281. package/dist/file-storage/driver.js.map +0 -1
  282. package/dist/file-storage/file-storage.js.map +0 -1
  283. package/dist/index.js.map +0 -1
  284. package/dist/migration/code-generation.js.map +0 -1
  285. package/dist/migration/migration-set.js.map +0 -1
  286. package/dist/migration/migrator.js.map +0 -1
  287. package/dist/migration/types.js.map +0 -1
  288. package/dist/stream/index.js.map +0 -1
  289. package/dist/stream/sse.js.map +0 -1
  290. package/dist/syncer/index.js.map +0 -1
  291. package/dist/syncer/syncer.js.map +0 -1
  292. package/dist/templates/base-template.d.ts +0 -13
  293. package/dist/templates/base-template.d.ts.map +0 -1
  294. package/dist/templates/base-template.js +0 -2
  295. package/dist/templates/base-template.js.map +0 -1
  296. package/dist/templates/entity.template.d.ts.map +0 -1
  297. package/dist/templates/entity.template.js +0 -2
  298. package/dist/templates/entity.template.js.map +0 -1
  299. package/dist/templates/generated.template.d.ts.map +0 -1
  300. package/dist/templates/generated.template.js +0 -2
  301. package/dist/templates/generated.template.js.map +0 -1
  302. package/dist/templates/generated_http.template.d.ts.map +0 -1
  303. package/dist/templates/generated_http.template.js +0 -2
  304. package/dist/templates/generated_http.template.js.map +0 -1
  305. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  306. package/dist/templates/generated_sso.template.js +0 -2
  307. package/dist/templates/generated_sso.template.js.map +0 -1
  308. package/dist/templates/index.d.ts +0 -2
  309. package/dist/templates/index.d.ts.map +0 -1
  310. package/dist/templates/index.js +0 -2
  311. package/dist/templates/index.js.map +0 -1
  312. package/dist/templates/init_types.template.d.ts.map +0 -1
  313. package/dist/templates/init_types.template.js +0 -2
  314. package/dist/templates/init_types.template.js.map +0 -1
  315. package/dist/templates/model.template.d.ts +0 -17
  316. package/dist/templates/model.template.d.ts.map +0 -1
  317. package/dist/templates/model.template.js +0 -2
  318. package/dist/templates/model.template.js.map +0 -1
  319. package/dist/templates/model_test.template.d.ts.map +0 -1
  320. package/dist/templates/model_test.template.js +0 -2
  321. package/dist/templates/model_test.template.js.map +0 -1
  322. package/dist/templates/service.template.d.ts.map +0 -1
  323. package/dist/templates/service.template.js +0 -2
  324. package/dist/templates/service.template.js.map +0 -1
  325. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  326. package/dist/templates/view_enums_buttonset.template.js +0 -2
  327. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  328. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  329. package/dist/templates/view_enums_dropdown.template.js +0 -2
  330. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  331. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  332. package/dist/templates/view_enums_select.template.js +0 -2
  333. package/dist/templates/view_enums_select.template.js.map +0 -1
  334. package/dist/templates/view_form.template.d.ts.map +0 -1
  335. package/dist/templates/view_form.template.js +0 -2
  336. package/dist/templates/view_form.template.js.map +0 -1
  337. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  338. package/dist/templates/view_id_all_select.template.js +0 -2
  339. package/dist/templates/view_id_all_select.template.js.map +0 -1
  340. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  341. package/dist/templates/view_id_async_select.template.js +0 -2
  342. package/dist/templates/view_id_async_select.template.js.map +0 -1
  343. package/dist/templates/view_list.template.d.ts.map +0 -1
  344. package/dist/templates/view_list.template.js +0 -2
  345. package/dist/templates/view_list.template.js.map +0 -1
  346. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  347. package/dist/templates/view_list_columns.template.js +0 -2
  348. package/dist/templates/view_list_columns.template.js.map +0 -1
  349. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  350. package/dist/templates/view_search_input.template.js +0 -2
  351. package/dist/templates/view_search_input.template.js.map +0 -1
  352. package/dist/testing/_relation-graph.js.map +0 -1
  353. package/dist/testing/fixture-manager.js.map +0 -1
  354. package/dist/types/types.js.map +0 -1
  355. package/dist/typings/knex.d.js.map +0 -1
  356. package/dist/utils/async-utils.js.map +0 -1
  357. package/dist/utils/controller.js.map +0 -1
  358. package/dist/utils/fs-utils.js.map +0 -1
  359. package/dist/utils/lodash-able.js.map +0 -1
  360. package/dist/utils/model.js.map +0 -1
  361. package/dist/utils/sql-parser.js.map +0 -1
  362. package/dist/utils/utils.js.map +0 -1
  363. package/dist/utils/zod-error.js.map +0 -1
  364. package/src/templates/base-template.ts +0 -19
  365. package/src/templates/index.ts +0 -1
@@ -1,2 +1,482 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"Sonamu",{enumerable:true,get:function(){return Sonamu}});var _async_hooks=require("async_hooks");var _chalk=/*#__PURE__*/_interop_require_default(require("chalk"));var _fastify=/*#__PURE__*/_interop_require_default(require("fastify"));var _promises=require("fs/promises");var _path=/*#__PURE__*/_interop_require_default(require("path"));var _fsutils=require("../utils/fs-utils");var _datefnstz=require("date-fns-tz");var _zod=require("zod");var _db=require("../database/db");var _knexonduplicateupdate=require("../database/knex-plugins/knex-on-duplicate-update");var _soexceptions=require("../exceptions/so-exceptions");var _sse=require("../stream/sse");var _types=require("../types/types");var _controller=require("../utils/controller");var _utils=require("../utils/utils");var _zoderror=require("../utils/zod-error");var _caster=require("./caster");var _codeconverters=require("./code-converters");var _passport=/*#__PURE__*/_interop_require_default(require("@fastify/passport"));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_with_holes(arr){if(Array.isArray(arr))return 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 _instanceof(left,right){if(right!=null&&typeof Symbol!=="undefined"&&right[Symbol.hasInstance]){return!!right[Symbol.hasInstance](left)}else{return left instanceof right}}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap;var cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interop_require_wildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule){return obj}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj}}var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj)){return cache.get(obj)}var newObj={__proto__:null};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(key!=="default"&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc)}else{newObj[key]=obj[key]}}}newObj.default=obj;if(cache){cache.set(obj,newObj)}return newObj}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};var ownKeys=Object.keys(source);if(typeof Object.getOwnPropertySymbols==="function"){ownKeys=ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym){return Object.getOwnPropertyDescriptor(source,sym).enumerable}))}ownKeys.forEach(function(key){_define_property(target,key,source[key])})}return target}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}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}}}var SonamuClass=/*#__PURE__*/function(){"use strict";function SonamuClass(){_class_call_check(this,SonamuClass);_define_property(this,"isInitialized",false);_define_property(this,"asyncLocalStorage",new _async_hooks.AsyncLocalStorage);_define_property(this,"uploadStorage",new _async_hooks.AsyncLocalStorage);_define_property(this,"_apiRootPath",null);_define_property(this,"_dbConfig",null);_define_property(this,"_syncer",null);_define_property(this,"_config",null);_define_property(this,"_secrets",null);_define_property(this,"_storage",null);_define_property(this,"watcher",null);_define_property(this,"pendingFiles",[]);_define_property(this,"hmrStartTime",0);_define_property(this,"server",null)}_create_class(SonamuClass,[{key:"getContext",value:function getContext(){var store=this.asyncLocalStorage.getStore();if(store===null||store===void 0?void 0:store.context){return store.context}throw new Error("Sonamu cannot find context")}},{key:"getUploadContext",value:function getUploadContext(){var store=this.uploadStorage.getStore();if(store===null||store===void 0?void 0:store.uploadContext){return store.uploadContext}throw new Error("Sonamu cannot find upload context. Did you use @upload decorator?")}},{key:"apiRootPath",get:function get(){if(this._apiRootPath===null){throw new Error("Sonamu has not been initialized")}return this._apiRootPath},set:function set(apiRootPath){this._apiRootPath=apiRootPath}},{key:"appRootPath",get:function get(){return this.apiRootPath.split(_path.default.sep).slice(0,-1).join(_path.default.sep)}},{key:"dbConfig",get:function get(){if(this._dbConfig===null){throw new Error("Sonamu has not been initialized")}return this._dbConfig},set:function set(dbConfig){this._dbConfig=dbConfig}},{key:"syncer",get:function get(){if(this._syncer===null){throw new Error("Sonamu has not been initialized")}return this._syncer},set:function set(syncer){this._syncer=syncer}},{key:"config",get:function get(){if(this._config===null){throw new Error("Sonamu has not been initialized")}return this._config},set:function set(config){this._config=config}},{key:"secrets",get:function get(){return this._secrets},set:function set(secrets){this._secrets=secrets}},{key:"storage",get:function get(){return this._storage},set:function set(storage){this._storage=storage}},{key:"initForTesting",value:function initForTesting(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.init(true,false,undefined,true)];case 1:_state.sent();return[2]}})}).call(this)}},{key:"init",value:function init(){var doSilent=arguments.length>0&&arguments[0]!==void 0?arguments[0]:false,enableSync=arguments.length>1&&arguments[1]!==void 0?arguments[1]:true,apiRootPath=arguments.length>2?arguments[2]:void 0,forTesting=arguments.length>3&&arguments[3]!==void 0?arguments[3]:false;return _async_to_generator(function(){var configPath,secretsPath,_,_1,_2,_3,_4,EntityManager,Syncer;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(this.isInitialized){return[2]}!doSilent&&console.time(_chalk.default.cyan("Sonamu.init".concat(forTesting?" for testing":"")));this.apiRootPath=apiRootPath!==null&&apiRootPath!==void 0?apiRootPath:(0,_utils.findApiRootPath)();configPath=_path.default.join(this.apiRootPath,"sonamu.config.json");secretsPath=_path.default.join(this.apiRootPath,"sonamu.secrets.json");return[4,(0,_fsutils.exists)(configPath)];case 1:if(!_state.sent()){throw new Error("Cannot find sonamu.config.json in ".concat(configPath))}_=this;_1=JSON.parse;return[4,(0,_promises.readFile)(configPath)];case 2:_.config=_1.apply(JSON,[_state.sent().toString()]);return[4,(0,_fsutils.exists)(secretsPath)];case 3:if(!_state.sent())return[3,5];_2=this;_3=JSON.parse;return[4,(0,_promises.readFile)(secretsPath)];case 4:_2.secrets=_3.apply(JSON,[_state.sent().toString()]);_state.label=5;case 5:_4=this;return[4,_db.DB.readKnexfile()];case 6:_4.dbConfig=_state.sent();!doSilent&&console.log(_chalk.default.green("DB Config Loaded!"));(0,_knexonduplicateupdate.attachOnDuplicateUpdate)();if(forTesting){this.isInitialized=true;return[2]}return[4,Promise.resolve().then(function(){return /*#__PURE__*/_interop_require_wildcard(require("../entity/entity-manager"))})];case 7:EntityManager=_state.sent().EntityManager;return[4,EntityManager.autoload(doSilent)];case 8:_state.sent();return[4,Promise.resolve().then(function(){return /*#__PURE__*/_interop_require_wildcard(require("../syncer/syncer"))})];case 9:Syncer=_state.sent().Syncer;this.syncer=new Syncer;return[4,this.syncer.autoloadModels()];case 10:_state.sent();return[4,this.syncer.autoloadTypes()];case 11:_state.sent();return[4,this.syncer.autoloadApis()];case 12:_state.sent();if(!((0,_controller.isLocal)()&&!(0,_controller.isTest)()&&enableSync))return[3,14];return[4,this.syncer.sync()];case 13:_state.sent();this.startWatcher();this.syncer.syncUI();_state.label=14;case 14:this.isInitialized=true;!doSilent&&console.timeEnd(_chalk.default.cyan("Sonamu.init"));return[2]}})}).call(this)}},{key:"createServer",value:function createServer(options,initOptions){return _async_to_generator(function(){var server,_options_plugins;return _ts_generator(this,function(_state){switch(_state.label){case 0:server=(0,_fastify.default)(options.fastify);this.server=server;if(options.storage){this.storage=options.storage}if(options.plugins){this.registerPlugins(server,options.plugins)}if(options.auth){;if(!((_options_plugins=options.plugins)===null||_options_plugins===void 0?void 0:_options_plugins.session)){throw new Error("Auth requires session plugin. Please add plugins.session configuration.")}this.registerAuth(server,options.auth)}return[4,this.withFastify(server,options.apiConfig,{enableSync:initOptions===null||initOptions===void 0?void 0:initOptions.enableSync,doSilent:initOptions===null||initOptions===void 0?void 0:initOptions.doSilent})];case 1:_state.sent();return[4,this.boot(server,options)];case 2:_state.sent();return[2,server]}})}).call(this)}},{key:"withFastify",value:function withFastify(server,config,options){return _async_to_generator(function(){var _this,timezone,DATE_FORMAT,ISO_DATE_REGEX;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;if(!(this.isInitialized===false))return[3,2];return[4,this.init(options===null||options===void 0?void 0:options.doSilent,options===null||options===void 0?void 0:options.enableSync)];case 1:_state.sent();_state.label=2;case 2:this.server=server;timezone=this.config.timezone;if(timezone){DATE_FORMAT="yyyy-MM-dd'T'HH:mm:ssXXX";ISO_DATE_REGEX=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;server.setReplySerializer(function(payload){return JSON.stringify(payload,function(_key,value){if(typeof value==="string"&&ISO_DATE_REGEX.test(value)){return(0,_datefnstz.formatInTimeZone)(new Date(value),timezone,DATE_FORMAT)}return value})});!(options===null||options===void 0?void 0:options.doSilent)&&console.log(_chalk.default.green("Timezone set to ".concat(timezone)))}server.get("".concat(this.config.route.prefix,"/routes"),function(_request,_reply){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.syncer.apis]})}).call(_this)});server.get("".concat(this.config.route.prefix,"/healthcheck"),function(_request,_reply){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,"ok"]})})()});if((0,_controller.isLocal)()){server.all("*",function(request,reply){var found=_this.syncer.apis.find(function(api){var _api_options_httpMethod;return _this.config.route.prefix+api.path===request.url.split("?")[0]&&((_api_options_httpMethod=api.options.httpMethod)!==null&&_api_options_httpMethod!==void 0?_api_options_httpMethod:"GET")===request.method.toUpperCase()});if(found){return _this.getApiHandler(found,config)(request,reply)}throw new _soexceptions.NotFoundException("존재하지 않는 API 접근입니다.")})}else{this.syncer.apis.map(function(api){if(_this.syncer.models[api.modelName]===undefined){throw new Error("정의되지 않은 모델에 접근 ".concat(api.modelName))}server.route({method:api.options.httpMethod,url:_this.config.route.prefix+api.path,handler:_this.getApiHandler(api,config)})})}return[2]}})}).call(this)}},{key:"getApiHandler",value:function getApiHandler(api,config){var _this=this;return function(request,reply){return _async_to_generator(function(){var _api_options_guards,ReqType,which,reqBody,_request_which,messages,_api_options_contentType,_ref,cacheKey,cacheTtl,cachedData,createSSE,_request_user,context,model;return _ts_generator(this,function(_state){switch(_state.label){case 0:((_api_options_guards=api.options.guards)!==null&&_api_options_guards!==void 0?_api_options_guards:[]).every(function(guard){return config.guardHandler(guard,request,api)});ReqType=(0,_codeconverters.getZodObjectFromApi)(api,this.syncer.types);which=api.options.httpMethod==="GET"?"query":"body";try{;reqBody=(0,_caster.fastifyCaster)(ReqType).parse((_request_which=request[which])!==null&&_request_which!==void 0?_request_which:{})}catch(e){if(_instanceof(e,_zod.ZodError)){messages=(0,_zoderror.humanizeZodError)(e).map(function(issue){return issue.message}).join(" ");throw new _soexceptions.BadRequestException(messages,{zodError:e})}else{throw e}}reply.type((_api_options_contentType=api.options.contentType)!==null&&_api_options_contentType!==void 0?_api_options_contentType:"application/json");return[4,function(){return _async_to_generator(function(){var cacheKeyRes,cacheKey,cacheTtl,cachedData,e;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(!config.cache)return[3,5];_state.label=1;case 1:_state.trys.push([1,3,,4]);cacheKeyRes=config.cache.resolveKey(api.path,reqBody);if(cacheKeyRes.cache===false){return[2,{cacheKey:null,cachedData:null}]}cacheKey=cacheKeyRes.key;cacheTtl=cacheKeyRes.ttl;return[4,config.cache.get(cacheKey)];case 2:cachedData=_state.sent();return[2,{cacheKey:cacheKey,cacheTtl:cacheTtl,cachedData:cachedData}];case 3:e=_state.sent();console.error(e);return[3,4];case 4:return[2,{cacheKey:null,cachedData:null}];case 5:return[2,{cacheKey:null,cachedData:null}]}})})()}()];case 1:_ref=_state.sent(),cacheKey=_ref.cacheKey,cacheTtl=_ref.cacheTtl,cachedData=_ref.cachedData;if(cachedData!==null){return[2,cachedData]}createSSE=(function(_request,_reply,_events){return(0,_sse.createSSEFactory)(_request.socket,_reply,_events)}).bind(null,request,reply);context=_object_spread({},config.contextProvider({request:request,reply:reply,headers:request.headers,createSSE:createSSE,user:(_request_user=request.user)!==null&&_request_user!==void 0?_request_user:null,passport:{login:request.login.bind(request),logout:request.logout.bind(request)}},request,reply));model=this.syncer.models[api.modelName];return[2,this.asyncLocalStorage.run({context:context},function(){return _async_to_generator(function(){var result,_api_options_contentType;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,model[api.methodName].apply(model,api.parameters.map(function(param){if(_types.ApiParamType.isContext(param.type)){return context}else{return reqBody[param.name]}}))];case 1:result=_state.sent();reply.type((_api_options_contentType=api.options.contentType)!==null&&_api_options_contentType!==void 0?_api_options_contentType:"application/json");if(!(config.cache&&cacheKey))return[3,3];return[4,config.cache.put(cacheKey,result,cacheTtl)];case 2:_state.sent();_state.label=3;case 3:return[2,result]}})})()})]}})}).call(_this)}}},{key:"startWatcher",value:function startWatcher(){var _this=this;var watchPath=_path.default.join(this.apiRootPath,"src");var chokidar=require("chokidar");this.watcher=chokidar.watch(watchPath,{ignored:function(path,stats){return!!(stats===null||stats===void 0?void 0:stats.isFile())&&!path.endsWith(".ts")&&!path.endsWith(".json")||path.endsWith("src/index.ts")},persistent:true,ignoreInitial:true});this.watcher.on("all",function(event,filePath){return _async_to_generator(function(){var e;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(event!=="change"&&event!=="add"){return[2]}_state.label=1;case 1:_state.trys.push([1,3,,4]);return[4,this.handleFileChange(event,filePath)];case 2:_state.sent();return[3,4];case 3:e=_state.sent();console.error(e);return[3,4];case 4:return[2]}})}).call(_this)})}},{key:"runScript",value:function runScript(fn){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.init(true,false,undefined,false)];case 1:_state.sent();_state.label=2;case 2:_state.trys.push([2,,4,6]);return[4,fn()];case 3:_state.sent();return[3,6];case 4:return[4,this.destroy()];case 5:_state.sent();return[7];case 6:return[2]}})}).call(this)}},{key:"registerPlugins",value:function registerPlugins(server,plugins){if(!plugins){return}var pluginsModules={cors:"@fastify/cors",formbody:"@fastify/formbody",multipart:"@fastify/multipart",qs:"fastify-qs",sse:"fastify-sse-v2",static:"@fastify/static",session:"@fastify/secure-session"};var registerPlugin=function(key,pluginName){var option=plugins[key];if(!option)return;if(option===true){server.register(Promise.resolve(pluginName).then(function(p){return /*#__PURE__*/_interop_require_wildcard(require(p))}))}else{server.register(Promise.resolve(pluginName).then(function(p){return /*#__PURE__*/_interop_require_wildcard(require(p))}),option)}};Object.entries(pluginsModules).forEach(function(param){var _param=_sliced_to_array(param,2),key=_param[0],pluginName=_param[1];registerPlugin(key,pluginName)});if(plugins.custom){plugins.custom(server)}}},{key:"registerAuth",value:function registerAuth(server,options){return _async_to_generator(function(){return _ts_generator(this,function(_state){server.register(_passport.default.initialize());server.register(_passport.default.secureSession());if(typeof options==="boolean"){_passport.default.registerUserSerializer(function(user,_request){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,user]})})()});_passport.default.registerUserDeserializer(function(serialized,_request){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,serialized]})})()})}else{_passport.default.registerUserSerializer(options.userSerializer);_passport.default.registerUserDeserializer(options.userDeserializer)}return[2]})})()}},{key:"boot",value:function boot(server,options){return _async_to_generator(function(){var _this,_options_listen,_options_listen1,_options_lifecycle,_options_listen_port,port,_options_listen_host,host,shutdown,_options_lifecycle1;return _ts_generator(this,function(_state){_this=this;port=(_options_listen_port=(_options_listen=options.listen)===null||_options_listen===void 0?void 0:_options_listen.port)!==null&&_options_listen_port!==void 0?_options_listen_port:3e3;host=(_options_listen_host=(_options_listen1=options.listen)===null||_options_listen1===void 0?void 0:_options_listen1.host)!==null&&_options_listen_host!==void 0?_options_listen_host:"localhost";server.addHook("onClose",function(){return _async_to_generator(function(){var _options_lifecycle_onShutdown,_options_lifecycle;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(_options_lifecycle=options.lifecycle)===null||_options_lifecycle===void 0?void 0:(_options_lifecycle_onShutdown=_options_lifecycle.onShutdown)===null||_options_lifecycle_onShutdown===void 0?void 0:_options_lifecycle_onShutdown.call(_options_lifecycle,server)];case 1:_state.sent();return[4,this.destroy()];case 2:_state.sent();return[2]}})}).call(_this)});shutdown=function(){return _async_to_generator(function(){var err;return _ts_generator(this,function(_state){switch(_state.label){case 0:_state.trys.push([0,2,,3]);return[4,server.close()];case 1:_state.sent();process.exit(0);return[3,3];case 2:err=_state.sent();console.error("Error during shutdown:",err);process.exit(1);return[3,3];case 3:return[2]}})})()};process.on("SIGINT",shutdown);process.on("SIGTERM",shutdown);if((_options_lifecycle=options.lifecycle)===null||_options_lifecycle===void 0?void 0:_options_lifecycle.onError){;server.setErrorHandler((_options_lifecycle1=options.lifecycle)===null||_options_lifecycle1===void 0?void 0:_options_lifecycle1.onError)}server.listen({port:port,host:host}).then(function(){return _async_to_generator(function(){var _options_lifecycle_onStart,_options_lifecycle;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(_options_lifecycle=options.lifecycle)===null||_options_lifecycle===void 0?void 0:(_options_lifecycle_onStart=_options_lifecycle.onStart)===null||_options_lifecycle_onStart===void 0?void 0:_options_lifecycle_onStart.call(_options_lifecycle,server)];case 1:_state.sent();return[2]}})})()}).catch(function(err){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:console.error(_chalk.default.red("Failed to start server:",err));return[4,shutdown()];case 1:_state.sent();return[2]}})})()});return[2]})}).call(this)}},{key:"handleFileChange",value:function handleFileChange(event,filePath){return _async_to_generator(function(){var relativePath;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(this.pendingFiles.length===0){this.hmrStartTime=Date.now()}this.pendingFiles.push(filePath);relativePath=filePath.replace(this.apiRootPath,"api");console.log(_chalk.default.bold("Detected(".concat(event,"): ").concat(_chalk.default.blue(relativePath))));return[4,this.syncer.syncFromWatcher([filePath])];case 1:_state.sent();this.pendingFiles=this.pendingFiles.slice(1);if(!(this.pendingFiles.length===0))return[3,3];return[4,this.finishHMR()];case 2:_state.sent();_state.label=3;case 3:return[2]}})}).call(this)}},{key:"finishHMR",value:function finishHMR(){return _async_to_generator(function(){var _,_1,endTime,totalTime,msg,margin;return _ts_generator(this,function(_state){switch(_state.label){case 0:_1=(_=this.syncer).saveChecksums;return[4,this.syncer.getCurrentChecksums()];case 1:return[4,_1.apply(_,[_state.sent()])];case 2:_state.sent();endTime=Date.now();totalTime=endTime-this.hmrStartTime;msg="HMR Done! ".concat(_chalk.default.bold.white("".concat(totalTime,"ms")));margin=Math.max(0,(process.stdout.columns-msg.length)/2);console.log(_chalk.default.black.bgGreen(" ".repeat(margin)+msg+" ".repeat(margin)));return[2]}})}).call(this)}},{key:"destroy",value:function destroy(){return _async_to_generator(function(){var _this_watcher,_this_storage,BaseModel;return _ts_generator(this,function(_state){switch(_state.label){case 0:BaseModel=require("../database/base-model").BaseModel;return[4,BaseModel.destroy()];case 1:_state.sent();return[4,(_this_watcher=this.watcher)===null||_this_watcher===void 0?void 0:_this_watcher.close()];case 2:_state.sent();(_this_storage=this.storage)===null||_this_storage===void 0?void 0:_this_storage.destroy();return[2]}})}).call(this)}}]);return SonamuClass}();var Sonamu=new SonamuClass;
2
- //# sourceMappingURL=sonamu.js.map
1
+ import { AsyncLocalStorage } from "async_hooks";
2
+ import chalk from "chalk";
3
+ import fastify from "fastify";
4
+ import { readFile } from "node:fs/promises";
5
+ import path from "path";
6
+ import { exists } from "../utils/fs-utils.js";
7
+ import chokidar from "chokidar";
8
+ import { formatInTimeZone } from "date-fns-tz";
9
+ import { ZodError } from "zod";
10
+ import { DB } from "../database/db.js";
11
+ import { attachOnDuplicateUpdate } from "../database/knex-plugins/knex-on-duplicate-update.js";
12
+ import { BadRequestException, NotFoundException } from "../exceptions/so-exceptions.js";
13
+ import { createSSEFactory } from "../stream/sse.js";
14
+ import { ApiParamType } from "../types/types.js";
15
+ import { isLocal, isTest } from "../utils/controller.js";
16
+ import { findApiRootPath } from "../utils/utils.js";
17
+ import { humanizeZodError } from "../utils/zod-error.js";
18
+ import { fastifyCaster } from "./caster.js";
19
+ import { getZodObjectFromApi } from "./code-converters.js";
20
+ import fastifyPassport from "@fastify/passport";
21
+ import { loadConfig } from "./config.js";
22
+ import { isHotReloadServer } from "../utils/esm-utils.js";
23
+ import { Template } from "../template/index.js";
24
+ import assert from "assert";
25
+ import { centerText } from "../utils/console-util.js";
26
+ import { BaseModel } from "../database/base-model.js";
27
+ class SonamuClass {
28
+ isInitialized = false;
29
+ asyncLocalStorage = new AsyncLocalStorage();
30
+ uploadStorage = new AsyncLocalStorage();
31
+ getContext() {
32
+ const store = this.asyncLocalStorage.getStore();
33
+ if (store?.context) {
34
+ return store.context;
35
+ }
36
+ if (process.env.NODE_ENV === "test") {
37
+ // 테스팅 환경에서 컨텍스트가 주입되지 않은 경우 빈 컨텍스트 리턴
38
+ return {
39
+ request: null,
40
+ reply: null,
41
+ headers: {},
42
+ createSSE: ()=>{},
43
+ naiteStore: new Map()
44
+ };
45
+ } else {
46
+ throw new Error("Sonamu cannot find context");
47
+ }
48
+ }
49
+ getUploadContext() {
50
+ const store = this.uploadStorage.getStore();
51
+ if (store?.uploadContext) {
52
+ return store.uploadContext;
53
+ }
54
+ throw new Error("Sonamu cannot find upload context. Did you use @upload decorator?");
55
+ }
56
+ _apiRootPath = null;
57
+ set apiRootPath(apiRootPath) {
58
+ this._apiRootPath = apiRootPath;
59
+ }
60
+ get apiRootPath() {
61
+ if (this._apiRootPath === null) {
62
+ throw new Error("Sonamu has not been initialized");
63
+ }
64
+ return this._apiRootPath;
65
+ }
66
+ get appRootPath() {
67
+ return this.apiRootPath.split(path.sep).slice(0, -1).join(path.sep);
68
+ }
69
+ _dbConfig = null;
70
+ set dbConfig(dbConfig) {
71
+ this._dbConfig = dbConfig;
72
+ }
73
+ get dbConfig() {
74
+ if (this._dbConfig === null) {
75
+ throw new Error("Sonamu has not been initialized");
76
+ }
77
+ return this._dbConfig;
78
+ }
79
+ _syncer = null;
80
+ set syncer(syncer) {
81
+ this._syncer = syncer;
82
+ }
83
+ get syncer() {
84
+ if (this._syncer === null) {
85
+ throw new Error("Sonamu has not been initialized");
86
+ }
87
+ return this._syncer;
88
+ }
89
+ _config = null;
90
+ set config(config) {
91
+ this._config = config;
92
+ }
93
+ get config() {
94
+ if (this._config === null) {
95
+ throw new Error("Sonamu has not been initialized");
96
+ }
97
+ return this._config;
98
+ }
99
+ _secrets = null;
100
+ set secrets(secrets) {
101
+ this._secrets = secrets;
102
+ }
103
+ get secrets() {
104
+ return this._secrets;
105
+ }
106
+ _storage = null;
107
+ set storage(storage) {
108
+ this._storage = storage;
109
+ }
110
+ get storage() {
111
+ return this._storage;
112
+ }
113
+ // HMR 처리
114
+ watcher = null;
115
+ pendingFiles = [];
116
+ hmrStartTime = 0;
117
+ server = null;
118
+ async initForTesting() {
119
+ await this.init(true, false, undefined, true);
120
+ }
121
+ async init(doSilent = false, enableSync = true, apiRootPath, forTesting = false) {
122
+ if (this.isInitialized) {
123
+ return;
124
+ }
125
+ !doSilent && console.time(chalk.cyan(`Sonamu.init${forTesting ? " for testing" : ""}`));
126
+ // API 루트 패스
127
+ this.apiRootPath = apiRootPath ?? findApiRootPath();
128
+ this.config = await loadConfig(this.apiRootPath);
129
+ const secretsPath = path.join(this.apiRootPath, "sonamu.secrets.json");
130
+ if (await exists(secretsPath)) {
131
+ this.secrets = JSON.parse((await readFile(secretsPath)).toString());
132
+ }
133
+ // DB 로드
134
+ this.dbConfig = DB.generateDBConfig(this.config.database);
135
+ !doSilent && console.log(chalk.green("DB Config Loaded!"));
136
+ attachOnDuplicateUpdate();
137
+ // 테스팅인 경우 엔티티 로드 & 싱크 없이 중단
138
+ if (forTesting) {
139
+ this.isInitialized = true;
140
+ return;
141
+ }
142
+ // Entity 로드
143
+ const { EntityManager } = await import("../entity/entity-manager.js");
144
+ await EntityManager.autoload(doSilent);
145
+ // Syncer
146
+ const { Syncer } = await import("../syncer/syncer.js");
147
+ this.syncer = new Syncer();
148
+ // Autoload: Models / Types / APIs
149
+ await this.syncer.autoloadTypes();
150
+ await this.syncer.autoloadModels();
151
+ await this.syncer.autoloadApis();
152
+ await Template.autoload();
153
+ if (isLocal() && !isTest() && isHotReloadServer() && enableSync) {
154
+ await this.syncer.sync();
155
+ this.startWatcher();
156
+ this.syncer.syncUI();
157
+ }
158
+ this.isInitialized = true;
159
+ !doSilent && console.timeEnd(chalk.cyan("Sonamu.init"));
160
+ }
161
+ async createServer(initOptions) {
162
+ if (this.isInitialized === false) {
163
+ await this.init(initOptions?.doSilent, initOptions?.enableSync);
164
+ }
165
+ const options = this.config.server;
166
+ const server = fastify(options.fastify);
167
+ this.server = server;
168
+ // Storage 설정 저장
169
+ if (options.storage) {
170
+ this.storage = options.storage;
171
+ }
172
+ // 플러그인 등록
173
+ if (options.plugins) {
174
+ this.registerPlugins(server, options.plugins);
175
+ }
176
+ if (options.auth) {
177
+ if (!options.plugins?.session) {
178
+ throw new Error("Auth requires session plugin. Please add plugins.session configuration.");
179
+ }
180
+ this.registerAuth(server, options.auth);
181
+ }
182
+ // API 라우팅 설정
183
+ await this.withFastify(server, options.apiConfig, {
184
+ enableSync: initOptions?.enableSync,
185
+ doSilent: initOptions?.doSilent
186
+ });
187
+ // 서버 시작
188
+ await this.boot(server, options);
189
+ return server;
190
+ }
191
+ async withFastify(server, config, options) {
192
+ if (this.isInitialized === false) {
193
+ await this.init(options?.doSilent, options?.enableSync);
194
+ }
195
+ this.server = server;
196
+ // timezone 설정
197
+ const timezone = this.config.api.timezone;
198
+ if (timezone) {
199
+ const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
200
+ // ISO 8601 날짜 형식 정규식 (예: 2024-01-15T09:30:00.000Z)
201
+ const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
202
+ server.setReplySerializer((payload)=>{
203
+ return JSON.stringify(payload, (_key, value)=>{
204
+ if (typeof value === "string" && ISO_DATE_REGEX.test(value)) {
205
+ return formatInTimeZone(new Date(value), timezone, DATE_FORMAT);
206
+ }
207
+ return value;
208
+ });
209
+ });
210
+ !options?.doSilent && console.log(chalk.green(`Timezone set to ${timezone}`));
211
+ }
212
+ // 전체 라우팅 리스트
213
+ server.get(`${this.config.api.route.prefix}/routes`, async (_request, _reply)=>{
214
+ return this.syncer.apis;
215
+ });
216
+ // Healthcheck API
217
+ server.get(`${this.config.api.route.prefix}/healthcheck`, async (_request, _reply)=>{
218
+ return "ok";
219
+ });
220
+ // API 라우팅 (로컬HMR 상태와 구분)
221
+ if (isLocal()) {
222
+ server.all("*", (request, reply)=>{
223
+ const found = this.syncer.apis.find((api)=>this.config.api.route.prefix + api.path === request.url.split("?")[0] && (api.options.httpMethod ?? "GET") === request.method.toUpperCase());
224
+ if (found) {
225
+ return this.getApiHandler(found, config)(request, reply);
226
+ }
227
+ throw new NotFoundException("존재하지 않는 API 접근입니다.");
228
+ });
229
+ } else {
230
+ this.syncer.apis.map((api)=>{
231
+ // model
232
+ if (this.syncer.models[api.modelName] === undefined) {
233
+ throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);
234
+ }
235
+ // route
236
+ server.route({
237
+ method: api.options.httpMethod,
238
+ url: this.config.api.route.prefix + api.path,
239
+ handler: this.getApiHandler(api, config)
240
+ }); // END server.route
241
+ });
242
+ }
243
+ }
244
+ getApiHandler(api, config) {
245
+ return async (request, reply)=>{
246
+ (api.options.guards ?? []).every((guard)=>config.guardHandler(guard, request, api));
247
+ // 파라미터 정보로 zod 스키마 빌드
248
+ const ReqType = getZodObjectFromApi(api, this.syncer.types);
249
+ // request 파싱
250
+ const which = api.options.httpMethod === "GET" ? "query" : "body";
251
+ let reqBody;
252
+ try {
253
+ reqBody = fastifyCaster(ReqType).parse(request[which] ?? {});
254
+ } catch (e) {
255
+ if (e instanceof ZodError) {
256
+ const messages = humanizeZodError(e).map((issue)=>issue.message).join(" ");
257
+ throw new BadRequestException(messages, {
258
+ zodError: e
259
+ });
260
+ } else {
261
+ throw e;
262
+ }
263
+ }
264
+ // Content-Type
265
+ reply.type(api.options.contentType ?? "application/json");
266
+ // 캐시
267
+ const { cacheKey, cacheTtl, cachedData } = await (async ()=>{
268
+ if (config.cache) {
269
+ try {
270
+ const cacheKeyRes = config.cache.resolveKey(api.path, reqBody);
271
+ if (cacheKeyRes.cache === false) {
272
+ return {
273
+ cacheKey: null,
274
+ cachedData: null
275
+ };
276
+ }
277
+ const cacheKey = cacheKeyRes.key;
278
+ const cacheTtl = cacheKeyRes.ttl;
279
+ const cachedData = await config.cache.get(cacheKey);
280
+ return {
281
+ cacheKey,
282
+ cacheTtl,
283
+ cachedData
284
+ };
285
+ } catch (e) {
286
+ console.error(e);
287
+ }
288
+ return {
289
+ cacheKey: null,
290
+ cachedData: null
291
+ };
292
+ }
293
+ return {
294
+ cacheKey: null,
295
+ cachedData: null
296
+ };
297
+ })();
298
+ if (cachedData !== null) {
299
+ return cachedData;
300
+ }
301
+ // createSSEFactory 함수에 미리 request의 socket과 reply를 바인딩.
302
+ const createSSE = ((_request, _reply, _events)=>createSSEFactory(_request.socket, _reply, _events)).bind(null, request, reply);
303
+ const context = {
304
+ ...await Promise.resolve(config.contextProvider({
305
+ request,
306
+ reply,
307
+ headers: request.headers,
308
+ createSSE,
309
+ naiteStore: new Map(),
310
+ // auth
311
+ user: request.user ?? null,
312
+ passport: {
313
+ login: request.login.bind(request),
314
+ logout: request.logout.bind(request)
315
+ }
316
+ }, request, reply))
317
+ };
318
+ const model = this.syncer.models[api.modelName];
319
+ return this.asyncLocalStorage.run({
320
+ context
321
+ }, async ()=>{
322
+ const result = await model[api.methodName].apply(model, api.parameters.map((param)=>{
323
+ // Context 인젝션
324
+ if (ApiParamType.isContext(param.type)) {
325
+ return context;
326
+ } else {
327
+ return reqBody[param.name];
328
+ }
329
+ }));
330
+ reply.type(api.options.contentType ?? "application/json");
331
+ // 캐시 키 있는 경우 갱신 후 저장
332
+ if (config.cache && cacheKey) {
333
+ await config.cache.put(cacheKey, result, cacheTtl);
334
+ }
335
+ return result;
336
+ });
337
+ };
338
+ }
339
+ startWatcher() {
340
+ const watchPath = [
341
+ path.join(this.apiRootPath, "src"),
342
+ path.join(this.apiRootPath, "sonamu.config.ts")
343
+ ];
344
+ this.watcher = chokidar.watch(watchPath, {
345
+ ignored: (path, stats)=>!!stats?.isFile() && !path.endsWith(".ts") && !path.endsWith(".json"),
346
+ persistent: true,
347
+ ignoreInitial: true
348
+ });
349
+ this.watcher.on("all", async (event, filePath)=>{
350
+ const absolutePath = filePath;
351
+ assert(absolutePath.startsWith(this.apiRootPath), "File path is not within the API root path");
352
+ if (event !== "change" && event !== "add") {
353
+ return;
354
+ }
355
+ try {
356
+ // sonamu.config.ts 변경 시 재시작
357
+ const isConfigTs = filePath === path.join(this.apiRootPath, "sonamu.config.ts");
358
+ if (isConfigTs) {
359
+ const relativePath = filePath.replace(this.apiRootPath, "api");
360
+ console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)} - Restarting...`));
361
+ process.kill(process.pid, "SIGUSR2");
362
+ return;
363
+ }
364
+ await this.handleFileChange(event, absolutePath);
365
+ } catch (e) {
366
+ console.error(e);
367
+ }
368
+ });
369
+ }
370
+ /*
371
+ A function that automatically handles init and destroy when using Sonamu via scripts.
372
+ */ async runScript(fn) {
373
+ await this.init(true, false, undefined, false);
374
+ try {
375
+ await fn();
376
+ } finally{
377
+ await this.destroy();
378
+ }
379
+ }
380
+ registerPlugins(server, plugins) {
381
+ if (!plugins) {
382
+ return;
383
+ }
384
+ const pluginsModules = {
385
+ cors: "@fastify/cors",
386
+ formbody: "@fastify/formbody",
387
+ multipart: "@fastify/multipart",
388
+ qs: "fastify-qs",
389
+ sse: "fastify-sse-v2",
390
+ static: "@fastify/static",
391
+ session: "@fastify/secure-session"
392
+ };
393
+ const registerPlugin = (key, pluginName)=>{
394
+ const option = plugins[key];
395
+ if (!option) return;
396
+ if (option === true) {
397
+ server.register(import(pluginName));
398
+ } else {
399
+ server.register(import(pluginName), option);
400
+ }
401
+ };
402
+ Object.entries(pluginsModules).forEach(([key, pluginName])=>{
403
+ registerPlugin(key, pluginName);
404
+ });
405
+ if (plugins.custom) {
406
+ plugins.custom(server);
407
+ }
408
+ }
409
+ async registerAuth(server, options) {
410
+ server.register(fastifyPassport.initialize());
411
+ server.register(fastifyPassport.secureSession());
412
+ if (typeof options === "boolean") {
413
+ fastifyPassport.registerUserSerializer(async (user, _request)=>user);
414
+ fastifyPassport.registerUserDeserializer(async (serialized, _request)=>serialized);
415
+ } else {
416
+ fastifyPassport.registerUserSerializer(options.userSerializer);
417
+ fastifyPassport.registerUserDeserializer(options.userDeserializer);
418
+ }
419
+ }
420
+ async boot(server, options) {
421
+ const port = options.listen?.port ?? 3000;
422
+ const host = options.listen?.host ?? "localhost";
423
+ server.addHook("onClose", async ()=>{
424
+ await options.lifecycle?.onShutdown?.(server);
425
+ await this.destroy();
426
+ });
427
+ const shutdown = async ()=>{
428
+ try {
429
+ await server.close();
430
+ process.exit(0);
431
+ } catch (err) {
432
+ console.error("Error during shutdown:", err);
433
+ process.exit(1);
434
+ }
435
+ };
436
+ process.on("SIGINT", shutdown);
437
+ process.on("SIGTERM", shutdown);
438
+ if (options.lifecycle?.onError) {
439
+ server.setErrorHandler(options.lifecycle?.onError);
440
+ }
441
+ server.listen({
442
+ port,
443
+ host
444
+ }).then(async ()=>{
445
+ await options.lifecycle?.onStart?.(server);
446
+ }).catch(async (err)=>{
447
+ console.error(chalk.red("Failed to start server:", err));
448
+ await shutdown();
449
+ });
450
+ }
451
+ async handleFileChange(event, filePath) {
452
+ // 첫 번째 파일이면 HMR 시작 시간 기록
453
+ if (this.pendingFiles.length === 0) {
454
+ this.hmrStartTime = Date.now();
455
+ }
456
+ this.pendingFiles.push(filePath);
457
+ const relativePath = path.relative(this.apiRootPath, filePath);
458
+ console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)}`));
459
+ await this.syncer.syncFromWatcher(event, filePath);
460
+ // 처리 완료된 파일을 대기 목록에서 제거
461
+ this.pendingFiles = this.pendingFiles.slice(1);
462
+ // 모든 파일 처리가 완료되면 최종 메시지 출력
463
+ if (this.pendingFiles.length === 0) {
464
+ await this.finishHMR();
465
+ }
466
+ }
467
+ async finishHMR() {
468
+ await this.syncer.renewChecksums();
469
+ const endTime = Date.now();
470
+ const totalTime = endTime - this.hmrStartTime;
471
+ const msg = `HMR Done! ${chalk.bold.white(`${totalTime}ms`)}`;
472
+ console.log(chalk.black.bgGreen(centerText(msg)));
473
+ }
474
+ async destroy() {
475
+ await BaseModel.destroy();
476
+ await this.watcher?.close();
477
+ this.storage?.destroy();
478
+ }
479
+ }
480
+ export const Sonamu = new SonamuClass();
481
+
482
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvc29uYW11LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFzeW5jTG9jYWxTdG9yYWdlIH0gZnJvbSBcImFzeW5jX2hvb2tzXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgZmFzdGlmeSBmcm9tIFwiZmFzdGlmeVwiO1xuaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBleGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCBjaG9raWRhciwgeyB0eXBlIEZTV2F0Y2hlciB9IGZyb20gXCJjaG9raWRhclwiO1xuaW1wb3J0IHsgZm9ybWF0SW5UaW1lWm9uZSB9IGZyb20gXCJkYXRlLWZucy10elwiO1xuaW1wb3J0IHR5cGUgeyBGYXN0aWZ5SW5zdGFuY2UsIEZhc3RpZnlSZXBseSwgRmFzdGlmeVJlcXVlc3QgfSBmcm9tIFwiZmFzdGlmeVwiO1xuaW1wb3J0IHR5cGUgeyBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlciwgU2VydmVyUmVzcG9uc2UgfSBmcm9tIFwiaHR0cFwiO1xuaW1wb3J0IHsgWm9kRXJyb3IsIFpvZE9iamVjdCB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IERCLCBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgYXR0YWNoT25EdXBsaWNhdGVVcGRhdGUgfSBmcm9tIFwiLi4vZGF0YWJhc2Uva25leC1wbHVnaW5zL2tuZXgtb24tZHVwbGljYXRlLXVwZGF0ZVwiO1xuaW1wb3J0IHtcbiAgQmFkUmVxdWVzdEV4Y2VwdGlvbixcbiAgTm90Rm91bmRFeGNlcHRpb24sXG59IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB0eXBlIHsgRHJpdmVyIH0gZnJvbSBcIi4uL2ZpbGUtc3RvcmFnZS9kcml2ZXJcIjtcbmltcG9ydCB7IGNyZWF0ZVNTRUZhY3RvcnkgfSBmcm9tIFwiLi4vc3RyZWFtL3NzZVwiO1xuaW1wb3J0IHR5cGUgeyBTeW5jZXIgfSBmcm9tIFwiLi4vc3luY2VyL3N5bmNlclwiO1xuaW1wb3J0IHsgQXBpUGFyYW1UeXBlLCBTb25hbXVGYXN0aWZ5Q29uZmlnIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBpc0xvY2FsLCBpc1Rlc3QgfSBmcm9tIFwiLi4vdXRpbHMvY29udHJvbGxlclwiO1xuaW1wb3J0IHsgZmluZEFwaVJvb3RQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBodW1hbml6ZVpvZEVycm9yIH0gZnJvbSBcIi4uL3V0aWxzL3pvZC1lcnJvclwiO1xuaW1wb3J0IHsgZmFzdGlmeUNhc3RlciB9IGZyb20gXCIuL2Nhc3RlclwiO1xuaW1wb3J0IHsgZ2V0Wm9kT2JqZWN0RnJvbUFwaSB9IGZyb20gXCIuL2NvZGUtY29udmVydGVyc1wiO1xuaW1wb3J0IHR5cGUgeyBBdXRoQ29udGV4dCwgQ29udGV4dCwgVXBsb2FkQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB0eXBlIHsgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgZmFzdGlmeVBhc3Nwb3J0IGZyb20gXCJAZmFzdGlmeS9wYXNzcG9ydFwiO1xuaW1wb3J0IHsgbG9hZENvbmZpZywgU29uYW11Q29uZmlnLCBTb25hbXVTZXJ2ZXJPcHRpb25zIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgeyBBYnNvbHV0ZVBhdGggfSBmcm9tIFwiLi4vdXRpbHMvcGF0aC11dGlsc1wiO1xuaW1wb3J0IHsgaXNIb3RSZWxvYWRTZXJ2ZXIgfSBmcm9tIFwiLi4vdXRpbHMvZXNtLXV0aWxzXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZSB9IGZyb20gXCIuLi90ZW1wbGF0ZVwiO1xuaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgeyBjZW50ZXJUZXh0IH0gZnJvbSBcIi4uL3V0aWxzL2NvbnNvbGUtdXRpbFwiO1xuaW1wb3J0IHsgQmFzZU1vZGVsIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2Jhc2UtbW9kZWxcIjtcblxuZXhwb3J0IHR5cGUgU29uYW11U2VjcmV0cyA9IHtcbiAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xufTtcbmNsYXNzIFNvbmFtdUNsYXNzIHtcbiAgcHVibGljIGlzSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGFzeW5jTG9jYWxTdG9yYWdlOiBBc3luY0xvY2FsU3RvcmFnZTx7XG4gICAgY29udGV4dDogQ29udGV4dDtcbiAgfT4gPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKTtcblxuICBwdWJsaWMgdXBsb2FkU3RvcmFnZTogQXN5bmNMb2NhbFN0b3JhZ2U8e1xuICAgIHVwbG9hZENvbnRleHQ6IFVwbG9hZENvbnRleHQ7XG4gIH0+ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKCk7XG5cbiAgcHVibGljIGdldENvbnRleHQoKTogQ29udGV4dCB7XG4gICAgY29uc3Qgc3RvcmUgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy5jb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUuY29udGV4dDtcbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICAvLyDthYzsiqTtjIUg7ZmY6rK97JeQ7IScIOy7qO2FjeyKpO2KuOqwgCDso7zsnoXrkJjsp4Ag7JWK7J2AIOqyveyasCDruYgg7Luo7YWN7Iqk7Yq4IOumrO2EtFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVxdWVzdDogbnVsbCxcbiAgICAgICAgcmVwbHk6IG51bGwsXG4gICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICBjcmVhdGVTU0U6ICgpID0+IHt9LFxuICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwPHN0cmluZywgYW55PigpLFxuICAgICAgfSBhcyB1bmtub3duIGFzIENvbnRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBjYW5ub3QgZmluZCBjb250ZXh0XCIpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRVcGxvYWRDb250ZXh0KCk6IFVwbG9hZENvbnRleHQge1xuICAgIGNvbnN0IHN0b3JlID0gdGhpcy51cGxvYWRTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy51cGxvYWRDb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUudXBsb2FkQ29udGV4dDtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJTb25hbXUgY2Fubm90IGZpbmQgdXBsb2FkIGNvbnRleHQuIERpZCB5b3UgdXNlIEB1cGxvYWQgZGVjb3JhdG9yP1wiXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2FwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGggfCBudWxsID0gbnVsbDtcbiAgc2V0IGFwaVJvb3RQYXRoKGFwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGgpIHtcbiAgICB0aGlzLl9hcGlSb290UGF0aCA9IGFwaVJvb3RQYXRoO1xuICB9XG4gIGdldCBhcGlSb290UGF0aCgpOiBBYnNvbHV0ZVBhdGgge1xuICAgIGlmICh0aGlzLl9hcGlSb290UGF0aCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2FwaVJvb3RQYXRoITtcbiAgfVxuICBnZXQgYXBwUm9vdFBhdGgoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5hcGlSb290UGF0aC5zcGxpdChwYXRoLnNlcCkuc2xpY2UoMCwgLTEpLmpvaW4ocGF0aC5zZXApO1xuICB9XG5cbiAgcHJpdmF0ZSBfZGJDb25maWc6IFNvbmFtdURCQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHNldCBkYkNvbmZpZyhkYkNvbmZpZzogU29uYW11REJDb25maWcpIHtcbiAgICB0aGlzLl9kYkNvbmZpZyA9IGRiQ29uZmlnO1xuICB9XG4gIGdldCBkYkNvbmZpZygpOiBTb25hbXVEQkNvbmZpZyB7XG4gICAgaWYgKHRoaXMuX2RiQ29uZmlnID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fZGJDb25maWchO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3luY2VyOiBTeW5jZXIgfCBudWxsID0gbnVsbDtcbiAgc2V0IHN5bmNlcihzeW5jZXI6IFN5bmNlcikge1xuICAgIHRoaXMuX3N5bmNlciA9IHN5bmNlcjtcbiAgfVxuICBnZXQgc3luY2VyKCk6IFN5bmNlciB7XG4gICAgaWYgKHRoaXMuX3N5bmNlciA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N5bmNlciE7XG4gIH1cblxuICBwcml2YXRlIF9jb25maWc6IFNvbmFtdUNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgY29uZmlnKGNvbmZpZzogU29uYW11Q29uZmlnKSB7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuICB9XG4gIGdldCBjb25maWcoKTogU29uYW11Q29uZmlnIHtcbiAgICBpZiAodGhpcy5fY29uZmlnID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2VjcmV0czogU29uYW11U2VjcmV0cyB8IG51bGwgPSBudWxsO1xuICBzZXQgc2VjcmV0cyhzZWNyZXRzOiBTb25hbXVTZWNyZXRzKSB7XG4gICAgdGhpcy5fc2VjcmV0cyA9IHNlY3JldHM7XG4gIH1cbiAgZ2V0IHNlY3JldHMoKTogU29uYW11U2VjcmV0cyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zZWNyZXRzO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3RvcmFnZTogRHJpdmVyIHwgbnVsbCA9IG51bGw7XG4gIHNldCBzdG9yYWdlKHN0b3JhZ2U6IERyaXZlcikge1xuICAgIHRoaXMuX3N0b3JhZ2UgPSBzdG9yYWdlO1xuICB9XG4gIGdldCBzdG9yYWdlKCk6IERyaXZlciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zdG9yYWdlO1xuICB9XG5cbiAgLy8gSE1SIOyymOumrFxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcGVuZGluZ0ZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIGhtclN0YXJ0VGltZTogbnVtYmVyID0gMDtcblxuICBwdWJsaWMgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UgfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBpbml0Rm9yVGVzdGluZygpIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBpbml0KFxuICAgIGRvU2lsZW50OiBib29sZWFuID0gZmFsc2UsXG4gICAgZW5hYmxlU3luYzogYm9vbGVhbiA9IHRydWUsXG4gICAgYXBpUm9vdFBhdGg/OiBBYnNvbHV0ZVBhdGgsXG4gICAgZm9yVGVzdGluZzogYm9vbGVhbiA9IGZhbHNlXG4gICkge1xuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgIWRvU2lsZW50ICYmXG4gICAgICBjb25zb2xlLnRpbWUoXG4gICAgICAgIGNoYWxrLmN5YW4oYFNvbmFtdS5pbml0JHtmb3JUZXN0aW5nID8gXCIgZm9yIHRlc3RpbmdcIiA6IFwiXCJ9YClcbiAgICAgICk7XG5cbiAgICAvLyBBUEkg66Oo7Yq4IO2MqOyKpFxuICAgIHRoaXMuYXBpUm9vdFBhdGggPSBhcGlSb290UGF0aCA/PyBmaW5kQXBpUm9vdFBhdGgoKTtcbiAgICB0aGlzLmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcodGhpcy5hcGlSb290UGF0aCk7XG4gICAgY29uc3Qgc2VjcmV0c1BhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJzb25hbXUuc2VjcmV0cy5qc29uXCIpO1xuICAgIGlmIChhd2FpdCBleGlzdHMoc2VjcmV0c1BhdGgpKSB7XG4gICAgICB0aGlzLnNlY3JldHMgPSBKU09OLnBhcnNlKFxuICAgICAgICAoYXdhaXQgcmVhZEZpbGUoc2VjcmV0c1BhdGgpKS50b1N0cmluZygpXG4gICAgICApIGFzIFNvbmFtdVNlY3JldHM7XG4gICAgfVxuXG4gICAgLy8gREIg66Gc65OcXG4gICAgdGhpcy5kYkNvbmZpZyA9IERCLmdlbmVyYXRlREJDb25maWcodGhpcy5jb25maWcuZGF0YWJhc2UpO1xuICAgICFkb1NpbGVudCAmJiBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihcIkRCIENvbmZpZyBMb2FkZWQhXCIpKTtcbiAgICBhdHRhY2hPbkR1cGxpY2F0ZVVwZGF0ZSgpO1xuXG4gICAgLy8g7YWM7Iqk7YyF7J24IOqyveyasCDsl5Tti7Dti7Ag66Gc65OcICYg7Iux7YGsIOyXhuydtCDspJHri6hcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBFbnRpdHkg66Gc65OcXG4gICAgY29uc3QgeyBFbnRpdHlNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIik7XG4gICAgYXdhaXQgRW50aXR5TWFuYWdlci5hdXRvbG9hZChkb1NpbGVudCk7XG5cbiAgICAvLyBTeW5jZXJcbiAgICBjb25zdCB7IFN5bmNlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3luY2VyL3N5bmNlclwiKTtcbiAgICB0aGlzLnN5bmNlciA9IG5ldyBTeW5jZXIoKTtcblxuICAgIC8vIEF1dG9sb2FkOiBNb2RlbHMgLyBUeXBlcyAvIEFQSXNcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRNb2RlbHMoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZEFwaXMoKTtcblxuICAgIGF3YWl0IFRlbXBsYXRlLmF1dG9sb2FkKCk7XG5cbiAgICBpZiAoaXNMb2NhbCgpICYmICFpc1Rlc3QoKSAmJiBpc0hvdFJlbG9hZFNlcnZlcigpICYmIGVuYWJsZVN5bmMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY2VyLnN5bmMoKTtcblxuICAgICAgdGhpcy5zdGFydFdhdGNoZXIoKTtcblxuICAgICAgdGhpcy5zeW5jZXIuc3luY1VJKCk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAhZG9TaWxlbnQgJiYgY29uc29sZS50aW1lRW5kKGNoYWxrLmN5YW4oXCJTb25hbXUuaW5pdFwiKSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVTZXJ2ZXIoaW5pdE9wdGlvbnM/OiB7XG4gICAgZW5hYmxlU3luYz86IGJvb2xlYW47XG4gICAgZG9TaWxlbnQ/OiBib29sZWFuO1xuICB9KSB7XG4gICAgaWYgKHRoaXMuaXNJbml0aWFsaXplZCA9PT0gZmFsc2UpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChpbml0T3B0aW9ucz8uZG9TaWxlbnQsIGluaXRPcHRpb25zPy5lbmFibGVTeW5jKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5jb25maWcuc2VydmVyO1xuICAgIGNvbnN0IHNlcnZlciA9IGZhc3RpZnkob3B0aW9ucy5mYXN0aWZ5KTtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcblxuICAgIC8vIFN0b3JhZ2Ug7ISk7KCVIOyggOyepVxuICAgIGlmIChvcHRpb25zLnN0b3JhZ2UpIHtcbiAgICAgIHRoaXMuc3RvcmFnZSA9IG9wdGlvbnMuc3RvcmFnZTtcbiAgICB9XG5cbiAgICAvLyDtlIzrn6zqt7jsnbgg65Ox66GdXG4gICAgaWYgKG9wdGlvbnMucGx1Z2lucykge1xuICAgICAgdGhpcy5yZWdpc3RlclBsdWdpbnMoc2VydmVyLCBvcHRpb25zLnBsdWdpbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmF1dGgpIHtcbiAgICAgIGlmICghb3B0aW9ucy5wbHVnaW5zPy5zZXNzaW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIkF1dGggcmVxdWlyZXMgc2Vzc2lvbiBwbHVnaW4uIFBsZWFzZSBhZGQgcGx1Z2lucy5zZXNzaW9uIGNvbmZpZ3VyYXRpb24uXCJcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5yZWdpc3RlckF1dGgoc2VydmVyLCBvcHRpb25zLmF1dGgpO1xuICAgIH1cblxuICAgIC8vIEFQSSDrnbzsmrDtjIUg7ISk7KCVXG4gICAgYXdhaXQgdGhpcy53aXRoRmFzdGlmeShzZXJ2ZXIsIG9wdGlvbnMuYXBpQ29uZmlnLCB7XG4gICAgICBlbmFibGVTeW5jOiBpbml0T3B0aW9ucz8uZW5hYmxlU3luYyxcbiAgICAgIGRvU2lsZW50OiBpbml0T3B0aW9ucz8uZG9TaWxlbnQsXG4gICAgfSk7XG5cbiAgICAvLyDshJzrsoQg7Iuc7J6RXG4gICAgYXdhaXQgdGhpcy5ib290KHNlcnZlciwgb3B0aW9ucyk7XG5cbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgYXN5bmMgd2l0aEZhc3RpZnkoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIGVuYWJsZVN5bmM/OiBib29sZWFuO1xuICAgICAgZG9TaWxlbnQ/OiBib29sZWFuO1xuICAgIH1cbiAgKSB7XG4gICAgaWYgKHRoaXMuaXNJbml0aWFsaXplZCA9PT0gZmFsc2UpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChvcHRpb25zPy5kb1NpbGVudCwgb3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG5cbiAgICAvLyB0aW1lem9uZSDshKTsoJVcbiAgICBjb25zdCB0aW1lem9uZSA9IHRoaXMuY29uZmlnLmFwaS50aW1lem9uZTtcbiAgICBpZiAodGltZXpvbmUpIHtcbiAgICAgIGNvbnN0IERBVEVfRk9STUFUID0gXCJ5eXl5LU1NLWRkJ1QnSEg6bW06c3NYWFhcIjtcbiAgICAgIC8vIElTTyA4NjAxIOuCoOynnCDtmJXsi50g7KCV6rec7IudICjsmIg6IDIwMjQtMDEtMTVUMDk6MzA6MDAuMDAwWilcbiAgICAgIGNvbnN0IElTT19EQVRFX1JFR0VYID0gL15cXGR7NH0tXFxkezJ9LVxcZHsyfVRcXGR7Mn06XFxkezJ9OlxcZHsyfShcXC5cXGR7M30pP1okLztcblxuICAgICAgc2VydmVyLnNldFJlcGx5U2VyaWFsaXplcigocGF5bG9hZCkgPT4ge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgKF9rZXksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiBJU09fREFURV9SRUdFWC50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdEluVGltZVpvbmUobmV3IERhdGUodmFsdWUpLCB0aW1lem9uZSwgREFURV9GT1JNQVQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICAhb3B0aW9ucz8uZG9TaWxlbnQgJiZcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYFRpbWV6b25lIHNldCB0byAke3RpbWV6b25lfWApKTtcbiAgICB9XG5cbiAgICAvLyDsoITssrQg65287Jqw7YyFIOumrOyKpO2KuFxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9yb3V0ZXNgLFxuICAgICAgYXN5bmMgKF9yZXF1ZXN0LCBfcmVwbHkpOiBQcm9taXNlPGFueT4gPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jZXIuYXBpcztcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gSGVhbHRoY2hlY2sgQVBJXG4gICAgc2VydmVyLmdldChcbiAgICAgIGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9L2hlYWx0aGNoZWNrYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgcmV0dXJuIFwib2tcIjtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gQVBJIOudvOyasO2MhSAo66Gc7LusSE1SIOyDge2DnOyZgCDqtazrtoQpXG4gICAgaWYgKGlzTG9jYWwoKSkge1xuICAgICAgc2VydmVyLmFsbChcIipcIiwgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IGZvdW5kID0gdGhpcy5zeW5jZXIuYXBpcy5maW5kKFxuICAgICAgICAgIChhcGkpID0+XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGggPT09XG4gICAgICAgICAgICAgIHJlcXVlc3QudXJsLnNwbGl0KFwiP1wiKVswXSAmJlxuICAgICAgICAgICAgKGFwaS5vcHRpb25zLmh0dHBNZXRob2QgPz8gXCJHRVRcIikgPT09IHJlcXVlc3QubWV0aG9kLnRvVXBwZXJDYXNlKClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXBpSGFuZGxlcihmb3VuZCwgY29uZmlnKShyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFwi7KG07J6s7ZWY7KeAIOyViuuKlCBBUEkg7KCR6re87J6F64uI64ukLlwiKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN5bmNlci5hcGlzLm1hcCgoYXBpKSA9PiB7XG4gICAgICAgIC8vIG1vZGVsXG4gICAgICAgIGlmICh0aGlzLnN5bmNlci5tb2RlbHNbYXBpLm1vZGVsTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7KCV7J2Y65CY7KeAIOyViuydgCDrqqjrjbjsl5Ag7KCR6re8ICR7YXBpLm1vZGVsTmFtZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJvdXRlXG4gICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgbWV0aG9kOiBhcGkub3B0aW9ucy5odHRwTWV0aG9kISxcbiAgICAgICAgICB1cmw6IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCxcbiAgICAgICAgICBoYW5kbGVyOiB0aGlzLmdldEFwaUhhbmRsZXIoYXBpLCBjb25maWcpLFxuICAgICAgICB9KTsgLy8gRU5EIHNlcnZlci5yb3V0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0QXBpSGFuZGxlcihhcGk6IEV4dGVuZGVkQXBpLCBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcpIHtcbiAgICByZXR1cm4gYXN5bmMgKFxuICAgICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgICByZXBseTogRmFzdGlmeVJlcGx5XG4gICAgKTogUHJvbWlzZTx1bmtub3duPiA9PiB7XG4gICAgICAoYXBpLm9wdGlvbnMuZ3VhcmRzID8/IFtdKS5ldmVyeSgoZ3VhcmQpID0+XG4gICAgICAgIGNvbmZpZy5ndWFyZEhhbmRsZXIoZ3VhcmQsIHJlcXVlc3QsIGFwaSlcbiAgICAgICk7XG5cbiAgICAgIC8vIO2MjOudvOuvuO2EsCDsoJXrs7TroZwgem9kIOyKpO2CpOuniCDruYzrk5xcbiAgICAgIGNvbnN0IFJlcVR5cGUgPSBnZXRab2RPYmplY3RGcm9tQXBpKGFwaSwgdGhpcy5zeW5jZXIudHlwZXMpO1xuXG4gICAgICAvLyByZXF1ZXN0IO2MjOyLsVxuICAgICAgY29uc3Qgd2hpY2ggPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID09PSBcIkdFVFwiID8gXCJxdWVyeVwiIDogXCJib2R5XCI7XG4gICAgICBsZXQgcmVxQm9keToge1xuICAgICAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICAgICAgfTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcUJvZHkgPSBmYXN0aWZ5Q2FzdGVyKFJlcVR5cGUpLnBhcnNlKHJlcXVlc3Rbd2hpY2hdID8/IHt9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBab2RFcnJvcikge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gaHVtYW5pemVab2RFcnJvcihlKVxuICAgICAgICAgICAgLm1hcCgoaXNzdWUpID0+IGlzc3VlLm1lc3NhZ2UpXG4gICAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24obWVzc2FnZXMsIHtcbiAgICAgICAgICAgIHpvZEVycm9yOiBlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQ29udGVudC1UeXBlXG4gICAgICByZXBseS50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgICAgLy8g7LqQ7IucXG4gICAgICBjb25zdCB7IGNhY2hlS2V5LCBjYWNoZVR0bCwgY2FjaGVkRGF0YSB9ID0gYXdhaXQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKGNvbmZpZy5jYWNoZSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjYWNoZUtleVJlcyA9IGNvbmZpZy5jYWNoZS5yZXNvbHZlS2V5KGFwaS5wYXRoLCByZXFCb2R5KTtcbiAgICAgICAgICAgIGlmIChjYWNoZUtleVJlcy5jYWNoZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgY2FjaGVLZXk6IG51bGwsIGNhY2hlZERhdGE6IG51bGwgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY2FjaGVLZXkgPSBjYWNoZUtleVJlcy5rZXk7XG4gICAgICAgICAgICBjb25zdCBjYWNoZVR0bCA9IGNhY2hlS2V5UmVzLnR0bDtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlZERhdGEgPSBhd2FpdCBjb25maWcuY2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgICAgICAgICAgIHJldHVybiB7IGNhY2hlS2V5LCBjYWNoZVR0bCwgY2FjaGVkRGF0YSB9O1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7IGNhY2hlS2V5OiBudWxsLCBjYWNoZWREYXRhOiBudWxsIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgY2FjaGVLZXk6IG51bGwsIGNhY2hlZERhdGE6IG51bGwgfTtcbiAgICAgIH0pKCk7XG4gICAgICBpZiAoY2FjaGVkRGF0YSAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gY2FjaGVkRGF0YTtcbiAgICAgIH1cblxuICAgICAgLy8gY3JlYXRlU1NFRmFjdG9yeSDtlajsiJjsl5Ag66+466asIHJlcXVlc3TsnZggc29ja2V06rO8IHJlcGx566W8IOuwlOyduOuUqS5cbiAgICAgIGNvbnN0IGNyZWF0ZVNTRSA9ICg8VCBleHRlbmRzIFpvZE9iamVjdD4oXG4gICAgICAgIF9yZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICAgICAgX3JlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICAgICAgIF9ldmVudHM6IFRcbiAgICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQoXG4gICAgICAgIG51bGwsXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIHJlcGx5XG4gICAgICApO1xuXG4gICAgICBjb25zdCBjb250ZXh0OiBDb250ZXh0ID0ge1xuICAgICAgICAuLi4oYXdhaXQgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIGNvbmZpZy5jb250ZXh0UHJvdmlkZXIoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgIHJlcGx5LFxuICAgICAgICAgICAgICBoZWFkZXJzOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcDxzdHJpbmcsIGFueT4oKSxcbiAgICAgICAgICAgICAgLy8gYXV0aFxuICAgICAgICAgICAgICB1c2VyOiByZXF1ZXN0LnVzZXIgPz8gbnVsbCxcbiAgICAgICAgICAgICAgcGFzc3BvcnQ6IHtcbiAgICAgICAgICAgICAgICBsb2dpbjogcmVxdWVzdC5sb2dpbi5iaW5kKFxuICAgICAgICAgICAgICAgICAgcmVxdWVzdFxuICAgICAgICAgICAgICAgICkgYXMgQXV0aENvbnRleHRbXCJwYXNzcG9ydFwiXVtcImxvZ2luXCJdLFxuICAgICAgICAgICAgICAgIGxvZ291dDogcmVxdWVzdC5sb2dvdXQuYmluZChcbiAgICAgICAgICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgICAgICAgICApIGFzIEF1dGhDb250ZXh0W1wicGFzc3BvcnRcIl1bXCJsb2dvdXRcIl0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIHJlcGx5XG4gICAgICAgICAgKVxuICAgICAgICApKSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1vZGVsID0gdGhpcy5zeW5jZXIubW9kZWxzW2FwaS5tb2RlbE5hbWVdO1xuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChtb2RlbCBhcyBhbnkpW2FwaS5tZXRob2ROYW1lXS5hcHBseShcbiAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgICAgICAvLyBDb250ZXh0IOyduOygneyFmFxuICAgICAgICAgICAgaWYgKEFwaVBhcmFtVHlwZS5pc0NvbnRleHQocGFyYW0udHlwZSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gcmVxQm9keVtwYXJhbS5uYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgICByZXBseS50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgICAgICAvLyDsupDsi5wg7YKkIOyeiOuKlCDqsr3smrAg6rCx7IugIO2bhCDsoIDsnqVcbiAgICAgICAgaWYgKGNvbmZpZy5jYWNoZSAmJiBjYWNoZUtleSkge1xuICAgICAgICAgIGF3YWl0IGNvbmZpZy5jYWNoZS5wdXQoY2FjaGVLZXksIHJlc3VsdCwgY2FjaGVUdGwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgc3RhcnRXYXRjaGVyKCk6IHZvaWQge1xuICAgIGNvbnN0IHdhdGNoUGF0aCA9IFtcbiAgICAgIHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcInNyY1wiKSxcbiAgICAgIHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcInNvbmFtdS5jb25maWcudHNcIiksXG4gICAgXTtcblxuICAgIHRoaXMud2F0Y2hlciA9IGNob2tpZGFyLndhdGNoKHdhdGNoUGF0aCwge1xuICAgICAgaWdub3JlZDogKHBhdGgsIHN0YXRzKSA9PlxuICAgICAgICAhIXN0YXRzPy5pc0ZpbGUoKSAmJiAhcGF0aC5lbmRzV2l0aChcIi50c1wiKSAmJiAhcGF0aC5lbmRzV2l0aChcIi5qc29uXCIpLFxuICAgICAgcGVyc2lzdGVudDogdHJ1ZSxcbiAgICAgIGlnbm9yZUluaXRpYWw6IHRydWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLndhdGNoZXIub24oXCJhbGxcIiwgYXN5bmMgKGV2ZW50OiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IGZpbGVQYXRoIGFzIEFic29sdXRlUGF0aDtcbiAgICAgIGFzc2VydChcbiAgICAgICAgYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgodGhpcy5hcGlSb290UGF0aCksXG4gICAgICAgIFwiRmlsZSBwYXRoIGlzIG5vdCB3aXRoaW4gdGhlIEFQSSByb290IHBhdGhcIlxuICAgICAgKTtcblxuICAgICAgaWYgKGV2ZW50ICE9PSBcImNoYW5nZVwiICYmIGV2ZW50ICE9PSBcImFkZFwiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gc29uYW11LmNvbmZpZy50cyDrs4Dqsr0g7IucIOyerOyLnOyekVxuICAgICAgICBjb25zdCBpc0NvbmZpZ1RzID1cbiAgICAgICAgICBmaWxlUGF0aCA9PT0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwic29uYW11LmNvbmZpZy50c1wiKTtcblxuICAgICAgICBpZiAoaXNDb25maWdUcykge1xuICAgICAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGZpbGVQYXRoLnJlcGxhY2UodGhpcy5hcGlSb290UGF0aCwgXCJhcGlcIik7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBjaGFsay5ib2xkKFxuICAgICAgICAgICAgICBgRGV0ZWN0ZWQoJHtldmVudH0pOiAke2NoYWxrLmJsdWUocmVsYXRpdmVQYXRoKX0gLSBSZXN0YXJ0aW5nLi4uYFxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcHJvY2Vzcy5raWxsKHByb2Nlc3MucGlkLCBcIlNJR1VTUjJcIik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVGaWxlQ2hhbmdlKGV2ZW50LCBhYnNvbHV0ZVBhdGgpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLypcbiAgICAgQSBmdW5jdGlvbiB0aGF0IGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbml0IGFuZCBkZXN0cm95IHdoZW4gdXNpbmcgU29uYW11IHZpYSBzY3JpcHRzLiAgICBcbiAgKi9cbiAgYXN5bmMgcnVuU2NyaXB0KGZuOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSB7XG4gICAgYXdhaXQgdGhpcy5pbml0KHRydWUsIGZhbHNlLCB1bmRlZmluZWQsIGZhbHNlKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZm4oKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgdGhpcy5kZXN0cm95KCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlclBsdWdpbnMoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsXG4gICAgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl1cbiAgKSB7XG4gICAgaWYgKCFwbHVnaW5zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGx1Z2luc01vZHVsZXMgPSB7XG4gICAgICBjb3JzOiBcIkBmYXN0aWZ5L2NvcnNcIixcbiAgICAgIGZvcm1ib2R5OiBcIkBmYXN0aWZ5L2Zvcm1ib2R5XCIsXG4gICAgICBtdWx0aXBhcnQ6IFwiQGZhc3RpZnkvbXVsdGlwYXJ0XCIsXG4gICAgICBxczogXCJmYXN0aWZ5LXFzXCIsXG4gICAgICBzc2U6IFwiZmFzdGlmeS1zc2UtdjJcIixcbiAgICAgIHN0YXRpYzogXCJAZmFzdGlmeS9zdGF0aWNcIixcbiAgICAgIHNlc3Npb246IFwiQGZhc3RpZnkvc2VjdXJlLXNlc3Npb25cIixcbiAgICB9IGFzIGNvbnN0O1xuXG4gICAgY29uc3QgcmVnaXN0ZXJQbHVnaW4gPSA8SyBleHRlbmRzIGtleW9mIE5vbk51bGxhYmxlPHR5cGVvZiBwbHVnaW5zPj4oXG4gICAgICBrZXk6IEssXG4gICAgICBwbHVnaW5OYW1lOiBzdHJpbmdcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IG9wdGlvbiA9IHBsdWdpbnNba2V5XTtcbiAgICAgIGlmICghb3B0aW9uKSByZXR1cm47XG5cbiAgICAgIGlmIChvcHRpb24gPT09IHRydWUpIHtcbiAgICAgICAgc2VydmVyLnJlZ2lzdGVyKGltcG9ydChwbHVnaW5OYW1lKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoaW1wb3J0KHBsdWdpbk5hbWUpLCBvcHRpb24pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykuZm9yRWFjaCgoW2tleSwgcGx1Z2luTmFtZV0pID0+IHtcbiAgICAgIHJlZ2lzdGVyUGx1Z2luKGtleSBhcyBrZXlvZiB0eXBlb2YgcGx1Z2lucywgcGx1Z2luTmFtZSk7XG4gICAgfSk7XG5cbiAgICBpZiAocGx1Z2lucy5jdXN0b20pIHtcbiAgICAgIHBsdWdpbnMuY3VzdG9tKHNlcnZlcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckF1dGgoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsXG4gICAgb3B0aW9uczogTm9uTnVsbGFibGU8U29uYW11U2VydmVyT3B0aW9uc1tcImF1dGhcIl0+XG4gICkge1xuICAgIHNlcnZlci5yZWdpc3RlcihmYXN0aWZ5UGFzc3BvcnQuaW5pdGlhbGl6ZSgpKTtcbiAgICBzZXJ2ZXIucmVnaXN0ZXIoZmFzdGlmeVBhc3Nwb3J0LnNlY3VyZVNlc3Npb24oKSk7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICBmYXN0aWZ5UGFzc3BvcnQucmVnaXN0ZXJVc2VyU2VyaWFsaXplcihhc3luYyAodXNlciwgX3JlcXVlc3QpID0+IHVzZXIpO1xuICAgICAgZmFzdGlmeVBhc3Nwb3J0LnJlZ2lzdGVyVXNlckRlc2VyaWFsaXplcihcbiAgICAgICAgYXN5bmMgKHNlcmlhbGl6ZWQsIF9yZXF1ZXN0KSA9PiBzZXJpYWxpemVkXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBmYXN0aWZ5UGFzc3BvcnQucmVnaXN0ZXJVc2VyU2VyaWFsaXplcihvcHRpb25zLnVzZXJTZXJpYWxpemVyKTtcbiAgICAgIGZhc3RpZnlQYXNzcG9ydC5yZWdpc3RlclVzZXJEZXNlcmlhbGl6ZXIob3B0aW9ucy51c2VyRGVzZXJpYWxpemVyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3Qoc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsIG9wdGlvbnM6IFNvbmFtdVNlcnZlck9wdGlvbnMpIHtcbiAgICBjb25zdCBwb3J0ID0gb3B0aW9ucy5saXN0ZW4/LnBvcnQgPz8gMzAwMDtcbiAgICBjb25zdCBob3N0ID0gb3B0aW9ucy5saXN0ZW4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcblxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TaHV0ZG93bj8uKHNlcnZlcik7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHNodXRkb3duID0gYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZHVyaW5nIHNodXRkb3duOlwiLCBlcnIpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgc2h1dGRvd24pO1xuICAgIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHNodXRkb3duKTtcblxuICAgIGlmIChvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcikge1xuICAgICAgc2VydmVyLnNldEVycm9ySGFuZGxlcihvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcik7XG4gICAgfVxuXG4gICAgc2VydmVyXG4gICAgICAubGlzdGVuKHsgcG9ydCwgaG9zdCB9KVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TdGFydD8uKHNlcnZlcik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnIpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoXCJGYWlsZWQgdG8gc3RhcnQgc2VydmVyOlwiLCBlcnIpKTtcbiAgICAgICAgYXdhaXQgc2h1dGRvd24oKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVGaWxlQ2hhbmdlKFxuICAgIGV2ZW50OiBzdHJpbmcsXG4gICAgZmlsZVBhdGg6IEFic29sdXRlUGF0aFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDssqsg67KI7Ke4IO2MjOydvOydtOuptCBITVIg7Iuc7J6RIOyLnOqwhCDquLDroZ1cbiAgICBpZiAodGhpcy5wZW5kaW5nRmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmhtclN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgfVxuICAgIHRoaXMucGVuZGluZ0ZpbGVzLnB1c2goZmlsZVBhdGgpO1xuXG4gICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLmFwaVJvb3RQYXRoLCBmaWxlUGF0aCk7XG4gICAgY29uc29sZS5sb2coY2hhbGsuYm9sZChgRGV0ZWN0ZWQoJHtldmVudH0pOiAke2NoYWxrLmJsdWUocmVsYXRpdmVQYXRoKX1gKSk7XG5cbiAgICBhd2FpdCB0aGlzLnN5bmNlci5zeW5jRnJvbVdhdGNoZXIoZXZlbnQsIGZpbGVQYXRoKTtcblxuICAgIC8vIOyymOumrCDsmYTro4zrkJwg7YyM7J287J2EIOuMgOq4sCDrqqnroZ3sl5DshJwg7KCc6rGwXG4gICAgdGhpcy5wZW5kaW5nRmlsZXMgPSB0aGlzLnBlbmRpbmdGaWxlcy5zbGljZSgxKTtcblxuICAgIC8vIOuqqOuToCDtjIzsnbwg7LKY66as6rCAIOyZhOujjOuQmOuptCDstZzsooUg66mU7Iuc7KeAIOy2nOugpVxuICAgIGlmICh0aGlzLnBlbmRpbmdGaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGF3YWl0IHRoaXMuZmluaXNoSE1SKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmaW5pc2hITVIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIucmVuZXdDaGVja3N1bXMoKTtcblxuICAgIGNvbnN0IGVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHRvdGFsVGltZSA9IGVuZFRpbWUgLSB0aGlzLmhtclN0YXJ0VGltZTtcbiAgICBjb25zdCBtc2cgPSBgSE1SIERvbmUhICR7Y2hhbGsuYm9sZC53aGl0ZShgJHt0b3RhbFRpbWV9bXNgKX1gO1xuXG4gICAgY29uc29sZS5sb2coY2hhbGsuYmxhY2suYmdHcmVlbihjZW50ZXJUZXh0KG1zZykpKTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgQmFzZU1vZGVsLmRlc3Ryb3koKTtcbiAgICBhd2FpdCB0aGlzLndhdGNoZXI/LmNsb3NlKCk7XG4gICAgdGhpcy5zdG9yYWdlPy5kZXN0cm95KCk7XG4gIH1cbn1cbmV4cG9ydCBjb25zdCBTb25hbXUgPSBuZXcgU29uYW11Q2xhc3MoKTtcbiJdLCJuYW1lcyI6WyJBc3luY0xvY2FsU3RvcmFnZSIsImNoYWxrIiwiZmFzdGlmeSIsInJlYWRGaWxlIiwicGF0aCIsImV4aXN0cyIsImNob2tpZGFyIiwiZm9ybWF0SW5UaW1lWm9uZSIsIlpvZEVycm9yIiwiREIiLCJhdHRhY2hPbkR1cGxpY2F0ZVVwZGF0ZSIsIkJhZFJlcXVlc3RFeGNlcHRpb24iLCJOb3RGb3VuZEV4Y2VwdGlvbiIsImNyZWF0ZVNTRUZhY3RvcnkiLCJBcGlQYXJhbVR5cGUiLCJpc0xvY2FsIiwiaXNUZXN0IiwiZmluZEFwaVJvb3RQYXRoIiwiaHVtYW5pemVab2RFcnJvciIsImZhc3RpZnlDYXN0ZXIiLCJnZXRab2RPYmplY3RGcm9tQXBpIiwiZmFzdGlmeVBhc3Nwb3J0IiwibG9hZENvbmZpZyIsImlzSG90UmVsb2FkU2VydmVyIiwiVGVtcGxhdGUiLCJhc3NlcnQiLCJjZW50ZXJUZXh0IiwiQmFzZU1vZGVsIiwiU29uYW11Q2xhc3MiLCJpc0luaXRpYWxpemVkIiwiYXN5bmNMb2NhbFN0b3JhZ2UiLCJ1cGxvYWRTdG9yYWdlIiwiZ2V0Q29udGV4dCIsInN0b3JlIiwiZ2V0U3RvcmUiLCJjb250ZXh0IiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwicmVxdWVzdCIsInJlcGx5IiwiaGVhZGVycyIsImNyZWF0ZVNTRSIsIm5haXRlU3RvcmUiLCJNYXAiLCJFcnJvciIsImdldFVwbG9hZENvbnRleHQiLCJ1cGxvYWRDb250ZXh0IiwiX2FwaVJvb3RQYXRoIiwiYXBpUm9vdFBhdGgiLCJhcHBSb290UGF0aCIsInNwbGl0Iiwic2VwIiwic2xpY2UiLCJqb2luIiwiX2RiQ29uZmlnIiwiZGJDb25maWciLCJfc3luY2VyIiwic3luY2VyIiwiX2NvbmZpZyIsImNvbmZpZyIsIl9zZWNyZXRzIiwic2VjcmV0cyIsIl9zdG9yYWdlIiwic3RvcmFnZSIsIndhdGNoZXIiLCJwZW5kaW5nRmlsZXMiLCJobXJTdGFydFRpbWUiLCJzZXJ2ZXIiLCJpbml0Rm9yVGVzdGluZyIsImluaXQiLCJ1bmRlZmluZWQiLCJkb1NpbGVudCIsImVuYWJsZVN5bmMiLCJmb3JUZXN0aW5nIiwiY29uc29sZSIsInRpbWUiLCJjeWFuIiwic2VjcmV0c1BhdGgiLCJKU09OIiwicGFyc2UiLCJ0b1N0cmluZyIsImdlbmVyYXRlREJDb25maWciLCJkYXRhYmFzZSIsImxvZyIsImdyZWVuIiwiRW50aXR5TWFuYWdlciIsImF1dG9sb2FkIiwiU3luY2VyIiwiYXV0b2xvYWRUeXBlcyIsImF1dG9sb2FkTW9kZWxzIiwiYXV0b2xvYWRBcGlzIiwic3luYyIsInN0YXJ0V2F0Y2hlciIsInN5bmNVSSIsInRpbWVFbmQiLCJjcmVhdGVTZXJ2ZXIiLCJpbml0T3B0aW9ucyIsIm9wdGlvbnMiLCJwbHVnaW5zIiwicmVnaXN0ZXJQbHVnaW5zIiwiYXV0aCIsInNlc3Npb24iLCJyZWdpc3RlckF1dGgiLCJ3aXRoRmFzdGlmeSIsImFwaUNvbmZpZyIsImJvb3QiLCJ0aW1lem9uZSIsImFwaSIsIkRBVEVfRk9STUFUIiwiSVNPX0RBVEVfUkVHRVgiLCJzZXRSZXBseVNlcmlhbGl6ZXIiLCJwYXlsb2FkIiwic3RyaW5naWZ5IiwiX2tleSIsInZhbHVlIiwidGVzdCIsIkRhdGUiLCJnZXQiLCJyb3V0ZSIsInByZWZpeCIsIl9yZXF1ZXN0IiwiX3JlcGx5IiwiYXBpcyIsImFsbCIsImZvdW5kIiwiZmluZCIsInVybCIsImh0dHBNZXRob2QiLCJtZXRob2QiLCJ0b1VwcGVyQ2FzZSIsImdldEFwaUhhbmRsZXIiLCJtYXAiLCJtb2RlbHMiLCJtb2RlbE5hbWUiLCJoYW5kbGVyIiwiZ3VhcmRzIiwiZXZlcnkiLCJndWFyZCIsImd1YXJkSGFuZGxlciIsIlJlcVR5cGUiLCJ0eXBlcyIsIndoaWNoIiwicmVxQm9keSIsImUiLCJtZXNzYWdlcyIsImlzc3VlIiwibWVzc2FnZSIsInpvZEVycm9yIiwidHlwZSIsImNvbnRlbnRUeXBlIiwiY2FjaGVLZXkiLCJjYWNoZVR0bCIsImNhY2hlZERhdGEiLCJjYWNoZSIsImNhY2hlS2V5UmVzIiwicmVzb2x2ZUtleSIsImtleSIsInR0bCIsImVycm9yIiwiX2V2ZW50cyIsInNvY2tldCIsImJpbmQiLCJQcm9taXNlIiwicmVzb2x2ZSIsImNvbnRleHRQcm92aWRlciIsInVzZXIiLCJwYXNzcG9ydCIsImxvZ2luIiwibG9nb3V0IiwibW9kZWwiLCJydW4iLCJyZXN1bHQiLCJtZXRob2ROYW1lIiwiYXBwbHkiLCJwYXJhbWV0ZXJzIiwicGFyYW0iLCJpc0NvbnRleHQiLCJuYW1lIiwicHV0Iiwid2F0Y2hQYXRoIiwid2F0Y2giLCJpZ25vcmVkIiwic3RhdHMiLCJpc0ZpbGUiLCJlbmRzV2l0aCIsInBlcnNpc3RlbnQiLCJpZ25vcmVJbml0aWFsIiwib24iLCJldmVudCIsImZpbGVQYXRoIiwiYWJzb2x1dGVQYXRoIiwic3RhcnRzV2l0aCIsImlzQ29uZmlnVHMiLCJyZWxhdGl2ZVBhdGgiLCJyZXBsYWNlIiwiYm9sZCIsImJsdWUiLCJraWxsIiwicGlkIiwiaGFuZGxlRmlsZUNoYW5nZSIsInJ1blNjcmlwdCIsImZuIiwiZGVzdHJveSIsInBsdWdpbnNNb2R1bGVzIiwiY29ycyIsImZvcm1ib2R5IiwibXVsdGlwYXJ0IiwicXMiLCJzc2UiLCJzdGF0aWMiLCJyZWdpc3RlclBsdWdpbiIsInBsdWdpbk5hbWUiLCJvcHRpb24iLCJyZWdpc3RlciIsIk9iamVjdCIsImVudHJpZXMiLCJmb3JFYWNoIiwiY3VzdG9tIiwiaW5pdGlhbGl6ZSIsInNlY3VyZVNlc3Npb24iLCJyZWdpc3RlclVzZXJTZXJpYWxpemVyIiwicmVnaXN0ZXJVc2VyRGVzZXJpYWxpemVyIiwic2VyaWFsaXplZCIsInVzZXJTZXJpYWxpemVyIiwidXNlckRlc2VyaWFsaXplciIsInBvcnQiLCJsaXN0ZW4iLCJob3N0IiwiYWRkSG9vayIsImxpZmVjeWNsZSIsIm9uU2h1dGRvd24iLCJzaHV0ZG93biIsImNsb3NlIiwiZXhpdCIsImVyciIsIm9uRXJyb3IiLCJzZXRFcnJvckhhbmRsZXIiLCJ0aGVuIiwib25TdGFydCIsImNhdGNoIiwicmVkIiwibGVuZ3RoIiwibm93IiwicHVzaCIsInJlbGF0aXZlIiwic3luY0Zyb21XYXRjaGVyIiwiZmluaXNoSE1SIiwicmVuZXdDaGVja3N1bXMiLCJlbmRUaW1lIiwidG90YWxUaW1lIiwibXNnIiwid2hpdGUiLCJibGFjayIsImJnR3JlZW4iLCJTb25hbXUiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLGlCQUFpQixRQUFRLGNBQWM7QUFDaEQsT0FBT0MsV0FBVyxRQUFRO0FBQzFCLE9BQU9DLGFBQWEsVUFBVTtBQUM5QixTQUFTQyxRQUFRLFFBQVEsbUJBQWM7QUFDdkMsT0FBT0MsVUFBVSxPQUFPO0FBQ3hCLFNBQVNDLE1BQU0sUUFBUSx1QkFBb0I7QUFDM0MsT0FBT0MsY0FBa0MsV0FBVztBQUNwRCxTQUFTQyxnQkFBZ0IsUUFBUSxjQUFjO0FBRy9DLFNBQVNDLFFBQVEsUUFBbUIsTUFBTTtBQUMxQyxTQUFTQyxFQUFFLFFBQXdCLG9CQUFpQjtBQUNwRCxTQUFTQyx1QkFBdUIsUUFBUSx1REFBb0Q7QUFDNUYsU0FDRUMsbUJBQW1CLEVBQ25CQyxpQkFBaUIsUUFDWixpQ0FBOEI7QUFFckMsU0FBU0MsZ0JBQWdCLFFBQVEsbUJBQWdCO0FBRWpELFNBQVNDLFlBQVksUUFBNkIsb0JBQWlCO0FBQ25FLFNBQVNDLE9BQU8sRUFBRUMsTUFBTSxRQUFRLHlCQUFzQjtBQUN0RCxTQUFTQyxlQUFlLFFBQVEsb0JBQWlCO0FBQ2pELFNBQVNDLGdCQUFnQixRQUFRLHdCQUFxQjtBQUN0RCxTQUFTQyxhQUFhLFFBQVEsY0FBVztBQUN6QyxTQUFTQyxtQkFBbUIsUUFBUSx1QkFBb0I7QUFHeEQsT0FBT0MscUJBQXFCLG9CQUFvQjtBQUNoRCxT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
@@ -4,8 +4,9 @@
4
4
  export declare const BUILD_DIR = "dist";
5
5
  /**
6
6
  * SWC 빌드 명령어
7
+ * .swcrc 설정 사용
7
8
  */
8
- export declare const SWC_BUILD_COMMAND = "swc src -d dist --strip-leading-paths --source-maps -C module.type=commonjs -C jsc.parser.syntax=typescript -C jsc.parser.decorators=true -C jsc.target=es5";
9
+ export declare const SWC_BUILD_COMMAND = "swc src -d dist --strip-leading-paths";
9
10
  /**
10
11
  * TSC 타입 체크 명령어
11
12
  */