sonamu 0.5.7 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (529) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +13 -2
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +71 -2
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +258 -2
  44. package/dist/api/config.d.ts +90 -0
  45. package/dist/api/config.d.ts.map +1 -0
  46. package/dist/api/config.js +25 -0
  47. package/dist/api/context.d.ts +4 -2
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +3 -2
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +235 -2
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +9 -2
  56. package/dist/api/sonamu.d.ts +10 -24
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +514 -2
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +6 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +15 -2
  65. package/dist/bin/cli.js +519 -2
  66. package/dist/bin/hot-hook-register.d.ts +11 -0
  67. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  68. package/dist/bin/hot-hook-register.js +21 -0
  69. package/dist/bin/loader-register.d.ts +2 -0
  70. package/dist/bin/loader-register.d.ts.map +1 -0
  71. package/dist/bin/loader-register.js +34 -0
  72. package/dist/database/_batch_update.d.ts +5 -3
  73. package/dist/database/_batch_update.d.ts.map +1 -1
  74. package/dist/database/_batch_update.js +95 -2
  75. package/dist/database/base-model.d.ts +96 -10
  76. package/dist/database/base-model.d.ts.map +1 -1
  77. package/dist/database/base-model.js +390 -2
  78. package/dist/database/base-model.types.d.ts +93 -0
  79. package/dist/database/base-model.types.d.ts.map +1 -0
  80. package/dist/database/base-model.types.js +10 -0
  81. package/dist/database/code-generator.d.ts +1 -1
  82. package/dist/database/code-generator.d.ts.map +1 -1
  83. package/dist/database/code-generator.js +54 -2
  84. package/dist/database/db.d.ts +6 -21
  85. package/dist/database/db.d.ts.map +1 -1
  86. package/dist/database/db.js +129 -2
  87. package/dist/database/puri-subset.test-d.js +81 -0
  88. package/dist/database/puri-subset.types.d.ts +123 -0
  89. package/dist/database/puri-subset.types.d.ts.map +1 -0
  90. package/dist/database/puri-subset.types.js +16 -0
  91. package/dist/database/puri-wrapper.d.ts +13 -11
  92. package/dist/database/puri-wrapper.d.ts.map +1 -1
  93. package/dist/database/puri-wrapper.js +109 -2
  94. package/dist/database/puri.d.ts +41 -23
  95. package/dist/database/puri.d.ts.map +1 -1
  96. package/dist/database/puri.js +601 -2
  97. package/dist/database/puri.types.d.ts +25 -6
  98. package/dist/database/puri.types.d.ts.map +1 -1
  99. package/dist/database/puri.types.js +6 -2
  100. package/dist/database/transaction-context.d.ts +1 -1
  101. package/dist/database/transaction-context.d.ts.map +1 -1
  102. package/dist/database/transaction-context.js +14 -2
  103. package/dist/database/upsert-builder.d.ts +9 -3
  104. package/dist/database/upsert-builder.d.ts.map +1 -1
  105. package/dist/database/upsert-builder.js +365 -2
  106. package/dist/entity/entity-manager.d.ts +167 -2
  107. package/dist/entity/entity-manager.d.ts.map +1 -1
  108. package/dist/entity/entity-manager.js +130 -2
  109. package/dist/entity/entity.d.ts +5 -3
  110. package/dist/entity/entity.d.ts.map +1 -1
  111. package/dist/entity/entity.js +750 -2
  112. package/dist/exceptions/error-handler.d.ts +1 -1
  113. package/dist/exceptions/error-handler.d.ts.map +1 -1
  114. package/dist/exceptions/error-handler.js +29 -2
  115. package/dist/exceptions/so-exceptions.d.ts +1 -1
  116. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  117. package/dist/exceptions/so-exceptions.js +85 -2
  118. package/dist/file-storage/driver.d.ts +1 -1
  119. package/dist/file-storage/driver.d.ts.map +1 -1
  120. package/dist/file-storage/driver.js +79 -2
  121. package/dist/file-storage/file-storage.js +75 -2
  122. package/dist/index.d.ts +18 -9
  123. package/dist/index.d.ts.map +1 -1
  124. package/dist/index.js +34 -2
  125. package/dist/migration/code-generation.d.ts +1 -1
  126. package/dist/migration/code-generation.d.ts.map +1 -1
  127. package/dist/migration/code-generation.js +614 -2
  128. package/dist/migration/migration-set.d.ts +2 -10
  129. package/dist/migration/migration-set.d.ts.map +1 -1
  130. package/dist/migration/migration-set.js +213 -2
  131. package/dist/migration/migrator.d.ts +24 -82
  132. package/dist/migration/migrator.d.ts.map +1 -1
  133. package/dist/migration/migrator.js +330 -2
  134. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  135. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  136. package/dist/migration/postgresql-schema-reader.js +245 -0
  137. package/dist/migration/types.d.ts +6 -38
  138. package/dist/migration/types.d.ts.map +1 -1
  139. package/dist/migration/types.js +3 -2
  140. package/dist/naite/messaging-types.d.ts +43 -0
  141. package/dist/naite/messaging-types.d.ts.map +1 -0
  142. package/dist/naite/messaging-types.js +7 -0
  143. package/dist/naite/naite-reporter.d.ts +41 -0
  144. package/dist/naite/naite-reporter.d.ts.map +1 -0
  145. package/dist/naite/naite-reporter.js +102 -0
  146. package/dist/naite/naite.d.ts +95 -0
  147. package/dist/naite/naite.d.ts.map +1 -0
  148. package/dist/naite/naite.js +316 -0
  149. package/dist/stream/index.js +3 -2
  150. package/dist/stream/sse.d.ts +2 -2
  151. package/dist/stream/sse.d.ts.map +1 -1
  152. package/dist/stream/sse.js +38 -2
  153. package/dist/syncer/api-parser.d.ts +10 -0
  154. package/dist/syncer/api-parser.d.ts.map +1 -0
  155. package/dist/syncer/api-parser.js +240 -0
  156. package/dist/syncer/checksum.d.ts +21 -0
  157. package/dist/syncer/checksum.d.ts.map +1 -0
  158. package/dist/syncer/checksum.js +98 -0
  159. package/dist/syncer/code-generator.d.ts +20 -0
  160. package/dist/syncer/code-generator.d.ts.map +1 -0
  161. package/dist/syncer/code-generator.js +161 -0
  162. package/dist/syncer/entity-operations.d.ts +17 -0
  163. package/dist/syncer/entity-operations.d.ts.map +1 -0
  164. package/dist/syncer/entity-operations.js +59 -0
  165. package/dist/syncer/file-patterns.d.ts +29 -0
  166. package/dist/syncer/file-patterns.d.ts.map +1 -0
  167. package/dist/syncer/file-patterns.js +38 -0
  168. package/dist/syncer/index.d.ts +6 -0
  169. package/dist/syncer/index.d.ts.map +1 -1
  170. package/dist/syncer/index.js +9 -2
  171. package/dist/syncer/module-loader.d.ts +35 -0
  172. package/dist/syncer/module-loader.d.ts.map +1 -0
  173. package/dist/syncer/module-loader.js +87 -0
  174. package/dist/syncer/syncer.d.ts +98 -106
  175. package/dist/syncer/syncer.d.ts.map +1 -1
  176. package/dist/syncer/syncer.js +422 -2
  177. package/dist/template/entity-converter.d.ts +14 -0
  178. package/dist/template/entity-converter.d.ts.map +1 -0
  179. package/dist/template/entity-converter.js +108 -0
  180. package/dist/template/helpers.d.ts +23 -0
  181. package/dist/template/helpers.d.ts.map +1 -0
  182. package/dist/template/helpers.js +64 -0
  183. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  184. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  185. package/dist/template/implementations/entity.template.js +86 -0
  186. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -4
  187. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  188. package/dist/template/implementations/generated.template.js +249 -0
  189. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -4
  190. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  191. package/dist/template/implementations/generated_http.template.js +131 -0
  192. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +4 -5
  193. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  194. package/dist/template/implementations/generated_sso.template.js +134 -0
  195. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  196. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  197. package/dist/template/implementations/init_types.template.js +38 -0
  198. package/dist/template/implementations/model.template.d.ts +17 -0
  199. package/dist/template/implementations/model.template.d.ts.map +1 -0
  200. package/dist/template/implementations/model.template.js +181 -0
  201. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  202. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  203. package/dist/template/implementations/model_test.template.js +35 -0
  204. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  205. package/dist/template/implementations/service.template.d.ts.map +1 -0
  206. package/dist/template/implementations/service.template.js +201 -0
  207. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  208. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  209. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  210. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  211. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  212. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  213. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  214. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  215. package/dist/template/implementations/view_enums_select.template.js +55 -0
  216. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  217. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  218. package/dist/template/implementations/view_form.template.js +337 -0
  219. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  220. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  221. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  222. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  223. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  224. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  225. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  226. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  227. package/dist/template/implementations/view_list.template.js +475 -0
  228. package/dist/template/implementations/view_list_columns.template.d.ts +17 -0
  229. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  230. package/dist/template/implementations/view_list_columns.template.js +49 -0
  231. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  232. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  233. package/dist/template/implementations/view_search_input.template.js +64 -0
  234. package/dist/template/index.d.ts +7 -0
  235. package/dist/template/index.d.ts.map +1 -0
  236. package/dist/template/index.js +8 -0
  237. package/dist/template/template-manager.d.ts +56 -0
  238. package/dist/template/template-manager.d.ts.map +1 -0
  239. package/dist/template/template-manager.js +125 -0
  240. package/dist/template/template-types.d.ts +16 -0
  241. package/dist/template/template-types.d.ts.map +1 -0
  242. package/dist/template/template-types.js +7 -0
  243. package/dist/template/template.d.ts +49 -0
  244. package/dist/template/template.d.ts.map +1 -0
  245. package/dist/template/template.js +60 -0
  246. package/dist/template/zod-converter.d.ts +51 -0
  247. package/dist/template/zod-converter.d.ts.map +1 -0
  248. package/dist/template/zod-converter.js +449 -0
  249. package/dist/testing/_relation-graph.d.ts +1 -1
  250. package/dist/testing/_relation-graph.d.ts.map +1 -1
  251. package/dist/testing/_relation-graph.js +89 -2
  252. package/dist/testing/fixture-manager.d.ts +42 -11
  253. package/dist/testing/fixture-manager.d.ts.map +1 -1
  254. package/dist/testing/fixture-manager.js +623 -2
  255. package/dist/types/types.d.ts +747 -143
  256. package/dist/types/types.d.ts.map +1 -1
  257. package/dist/types/types.js +546 -2
  258. package/dist/typings/knex.d.js +3 -2
  259. package/dist/utils/async-utils.d.ts +7 -0
  260. package/dist/utils/async-utils.d.ts.map +1 -1
  261. package/dist/utils/async-utils.js +57 -2
  262. package/dist/utils/console-util.d.ts +2 -0
  263. package/dist/utils/console-util.d.ts.map +1 -0
  264. package/dist/utils/console-util.js +6 -0
  265. package/dist/utils/controller.d.ts +1 -0
  266. package/dist/utils/controller.d.ts.map +1 -1
  267. package/dist/utils/controller.js +29 -2
  268. package/dist/utils/esm-utils.d.ts +39 -0
  269. package/dist/utils/esm-utils.d.ts.map +1 -0
  270. package/dist/utils/esm-utils.js +49 -0
  271. package/dist/utils/formatter.d.ts +3 -0
  272. package/dist/utils/formatter.d.ts.map +1 -0
  273. package/dist/utils/formatter.js +110 -0
  274. package/dist/utils/fs-utils.d.ts +1 -1
  275. package/dist/utils/fs-utils.d.ts.map +1 -1
  276. package/dist/utils/fs-utils.js +17 -2
  277. package/dist/utils/lodash-able.d.ts.map +1 -1
  278. package/dist/utils/lodash-able.js +6 -2
  279. package/dist/utils/model.js +22 -2
  280. package/dist/utils/object-utils.d.ts +44 -0
  281. package/dist/utils/object-utils.d.ts.map +1 -0
  282. package/dist/utils/object-utils.js +191 -0
  283. package/dist/utils/path-utils.d.ts +89 -0
  284. package/dist/utils/path-utils.d.ts.map +1 -0
  285. package/dist/utils/path-utils.js +60 -0
  286. package/dist/utils/process-utils.d.ts +13 -0
  287. package/dist/utils/process-utils.d.ts.map +1 -0
  288. package/dist/utils/process-utils.js +36 -0
  289. package/dist/utils/sql-parser.d.ts +5 -1
  290. package/dist/utils/sql-parser.d.ts.map +1 -1
  291. package/dist/utils/sql-parser.js +46 -2
  292. package/dist/utils/type-utils.d.ts +23 -0
  293. package/dist/utils/type-utils.d.ts.map +1 -0
  294. package/dist/utils/type-utils.js +45 -0
  295. package/dist/utils/utils.d.ts +10 -7
  296. package/dist/utils/utils.d.ts.map +1 -1
  297. package/dist/utils/utils.js +72 -2
  298. package/dist/utils/zod-error.d.ts +1 -1
  299. package/dist/utils/zod-error.d.ts.map +1 -1
  300. package/dist/utils/zod-error.js +19 -2
  301. package/package.json +65 -27
  302. package/src/ai/agents/agent.ts +87 -0
  303. package/src/ai/agents/index.ts +2 -0
  304. package/src/ai/agents/types.ts +47 -0
  305. package/src/ai/index.ts +1 -0
  306. package/src/ai/providers/rtzr/api.ts +37 -0
  307. package/src/ai/providers/rtzr/error.ts +34 -0
  308. package/src/ai/providers/rtzr/index.ts +4 -0
  309. package/src/ai/providers/rtzr/model.ts +201 -0
  310. package/src/ai/providers/rtzr/options.ts +49 -0
  311. package/src/ai/providers/rtzr/provider.ts +91 -0
  312. package/src/ai/providers/rtzr/utils.ts +127 -0
  313. package/src/api/base-frame.ts +4 -2
  314. package/src/api/caster.ts +17 -23
  315. package/src/api/code-converters.ts +178 -535
  316. package/src/api/config.ts +125 -0
  317. package/src/api/context.ts +7 -17
  318. package/src/api/decorators.ts +176 -46
  319. package/src/api/index.ts +2 -2
  320. package/src/api/sonamu.ts +190 -167
  321. package/src/api/validator.ts +83 -0
  322. package/src/bin/build-config.ts +8 -1
  323. package/src/bin/cli.ts +258 -124
  324. package/src/bin/hot-hook-register.ts +22 -0
  325. package/src/bin/loader-register.ts +38 -0
  326. package/src/database/_batch_update.ts +46 -31
  327. package/src/database/base-model.ts +390 -182
  328. package/src/database/base-model.types.ts +155 -0
  329. package/src/database/code-generator.ts +13 -32
  330. package/src/database/db.ts +40 -96
  331. package/src/database/puri-subset.test-d.ts +471 -0
  332. package/src/database/puri-subset.types.ts +195 -0
  333. package/src/database/puri-wrapper.ts +58 -67
  334. package/src/database/puri.ts +229 -148
  335. package/src/database/puri.types.ts +76 -30
  336. package/src/database/transaction-context.ts +1 -1
  337. package/src/database/upsert-builder.ts +262 -132
  338. package/src/entity/entity-manager.ts +48 -36
  339. package/src/entity/entity.ts +330 -248
  340. package/src/exceptions/error-handler.ts +3 -3
  341. package/src/exceptions/so-exceptions.ts +11 -11
  342. package/src/file-storage/driver.ts +5 -5
  343. package/src/file-storage/file-storage.ts +2 -2
  344. package/src/index.ts +18 -10
  345. package/src/migration/code-generation.ts +185 -172
  346. package/src/migration/migration-set.ts +80 -293
  347. package/src/migration/migrator.ts +199 -571
  348. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  349. package/src/migration/postgresql-schema-reader.ts +310 -0
  350. package/src/migration/types.ts +6 -39
  351. package/src/naite/messaging-types.ts +51 -0
  352. package/src/naite/naite-reporter.ts +128 -0
  353. package/src/naite/naite.ts +415 -0
  354. package/src/shared/web.shared.ts.txt +20 -24
  355. package/src/stream/sse.ts +5 -5
  356. package/src/syncer/api-parser.ts +282 -0
  357. package/src/syncer/checksum.ts +140 -0
  358. package/src/syncer/code-generator.ts +198 -0
  359. package/src/syncer/entity-operations.ts +65 -0
  360. package/src/syncer/file-patterns.ts +56 -0
  361. package/src/syncer/index.ts +6 -0
  362. package/src/syncer/module-loader.ts +128 -0
  363. package/src/syncer/syncer.ts +389 -1453
  364. package/src/template/entity-converter.ts +114 -0
  365. package/src/template/helpers.ts +81 -0
  366. package/src/{templates → template/implementations}/entity.template.ts +7 -7
  367. package/src/{templates → template/implementations}/generated.template.ts +101 -101
  368. package/src/{templates → template/implementations}/generated_http.template.ts +27 -57
  369. package/src/template/implementations/generated_sso.template.ts +151 -0
  370. package/src/{templates → template/implementations}/init_types.template.ts +5 -7
  371. package/src/{templates → template/implementations}/model.template.ts +52 -43
  372. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  373. package/src/{templates → template/implementations}/service.template.ts +66 -82
  374. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  375. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +4 -20
  376. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  377. package/src/{templates → template/implementations}/view_form.template.ts +40 -83
  378. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  379. package/src/{templates → template/implementations}/view_id_async_select.template.ts +10 -24
  380. package/src/{templates → template/implementations}/view_list.template.ts +60 -152
  381. package/src/{templates → template/implementations}/view_list_columns.template.ts +5 -11
  382. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  383. package/src/template/index.ts +6 -0
  384. package/src/template/template-manager.ts +166 -0
  385. package/src/template/template-types.ts +16 -0
  386. package/src/template/template.ts +105 -0
  387. package/src/template/zod-converter.ts +525 -0
  388. package/src/testing/_relation-graph.ts +18 -11
  389. package/src/testing/fixture-manager.ts +472 -359
  390. package/src/types/types.ts +553 -308
  391. package/src/typings/knex.d.ts +7 -9
  392. package/src/utils/async-utils.ts +23 -10
  393. package/src/utils/console-util.ts +4 -0
  394. package/src/utils/controller.ts +3 -0
  395. package/src/utils/esm-utils.ts +59 -0
  396. package/src/utils/formatter.ts +109 -0
  397. package/src/utils/fs-utils.ts +1 -1
  398. package/src/utils/lodash-able.ts +1 -4
  399. package/src/utils/object-utils.ts +217 -0
  400. package/src/utils/path-utils.ts +99 -0
  401. package/src/utils/process-utils.ts +46 -0
  402. package/src/utils/sql-parser.ts +23 -5
  403. package/src/utils/type-utils.ts +83 -0
  404. package/src/utils/utils.ts +66 -43
  405. package/src/utils/zod-error.ts +3 -4
  406. package/dist/api/base-frame.js.map +0 -1
  407. package/dist/api/caster.js.map +0 -1
  408. package/dist/api/code-converters.js.map +0 -1
  409. package/dist/api/context.js.map +0 -1
  410. package/dist/api/decorators.js.map +0 -1
  411. package/dist/api/index.js.map +0 -1
  412. package/dist/api/sonamu.js.map +0 -1
  413. package/dist/bin/build-config.js.map +0 -1
  414. package/dist/bin/cli-wrapper.d.ts +0 -3
  415. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  416. package/dist/bin/cli-wrapper.js +0 -3
  417. package/dist/bin/cli-wrapper.js.map +0 -1
  418. package/dist/bin/cli.js.map +0 -1
  419. package/dist/database/_batch_update.js.map +0 -1
  420. package/dist/database/base-model.js.map +0 -1
  421. package/dist/database/code-generator.js.map +0 -1
  422. package/dist/database/db.js.map +0 -1
  423. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  424. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  425. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -2
  426. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  427. package/dist/database/puri-wrapper.js.map +0 -1
  428. package/dist/database/puri.js.map +0 -1
  429. package/dist/database/puri.types.js.map +0 -1
  430. package/dist/database/transaction-context.js.map +0 -1
  431. package/dist/database/upsert-builder.js.map +0 -1
  432. package/dist/entity/entity-manager.js.map +0 -1
  433. package/dist/entity/entity-utils.d.ts +0 -61
  434. package/dist/entity/entity-utils.d.ts.map +0 -1
  435. package/dist/entity/entity-utils.js +0 -2
  436. package/dist/entity/entity-utils.js.map +0 -1
  437. package/dist/entity/entity.js.map +0 -1
  438. package/dist/exceptions/error-handler.js.map +0 -1
  439. package/dist/exceptions/so-exceptions.js.map +0 -1
  440. package/dist/file-storage/driver.js.map +0 -1
  441. package/dist/file-storage/file-storage.js.map +0 -1
  442. package/dist/index.js.map +0 -1
  443. package/dist/migration/code-generation.js.map +0 -1
  444. package/dist/migration/migration-set.js.map +0 -1
  445. package/dist/migration/migrator.js.map +0 -1
  446. package/dist/migration/types.js.map +0 -1
  447. package/dist/stream/index.js.map +0 -1
  448. package/dist/stream/sse.js.map +0 -1
  449. package/dist/syncer/index.js.map +0 -1
  450. package/dist/syncer/syncer.js.map +0 -1
  451. package/dist/templates/base-template.d.ts +0 -13
  452. package/dist/templates/base-template.d.ts.map +0 -1
  453. package/dist/templates/base-template.js +0 -2
  454. package/dist/templates/base-template.js.map +0 -1
  455. package/dist/templates/entity.template.d.ts.map +0 -1
  456. package/dist/templates/entity.template.js +0 -2
  457. package/dist/templates/entity.template.js.map +0 -1
  458. package/dist/templates/generated.template.d.ts.map +0 -1
  459. package/dist/templates/generated.template.js +0 -2
  460. package/dist/templates/generated.template.js.map +0 -1
  461. package/dist/templates/generated_http.template.d.ts.map +0 -1
  462. package/dist/templates/generated_http.template.js +0 -2
  463. package/dist/templates/generated_http.template.js.map +0 -1
  464. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  465. package/dist/templates/generated_sso.template.js +0 -2
  466. package/dist/templates/generated_sso.template.js.map +0 -1
  467. package/dist/templates/index.d.ts +0 -2
  468. package/dist/templates/index.d.ts.map +0 -1
  469. package/dist/templates/index.js +0 -2
  470. package/dist/templates/index.js.map +0 -1
  471. package/dist/templates/init_types.template.d.ts.map +0 -1
  472. package/dist/templates/init_types.template.js +0 -2
  473. package/dist/templates/init_types.template.js.map +0 -1
  474. package/dist/templates/model.template.d.ts +0 -17
  475. package/dist/templates/model.template.d.ts.map +0 -1
  476. package/dist/templates/model.template.js +0 -2
  477. package/dist/templates/model.template.js.map +0 -1
  478. package/dist/templates/model_test.template.d.ts.map +0 -1
  479. package/dist/templates/model_test.template.js +0 -2
  480. package/dist/templates/model_test.template.js.map +0 -1
  481. package/dist/templates/service.template.d.ts.map +0 -1
  482. package/dist/templates/service.template.js +0 -2
  483. package/dist/templates/service.template.js.map +0 -1
  484. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  485. package/dist/templates/view_enums_buttonset.template.js +0 -2
  486. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  487. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  488. package/dist/templates/view_enums_dropdown.template.js +0 -2
  489. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  490. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  491. package/dist/templates/view_enums_select.template.js +0 -2
  492. package/dist/templates/view_enums_select.template.js.map +0 -1
  493. package/dist/templates/view_form.template.d.ts.map +0 -1
  494. package/dist/templates/view_form.template.js +0 -2
  495. package/dist/templates/view_form.template.js.map +0 -1
  496. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  497. package/dist/templates/view_id_all_select.template.js +0 -2
  498. package/dist/templates/view_id_all_select.template.js.map +0 -1
  499. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  500. package/dist/templates/view_id_async_select.template.js +0 -2
  501. package/dist/templates/view_id_async_select.template.js.map +0 -1
  502. package/dist/templates/view_list.template.d.ts.map +0 -1
  503. package/dist/templates/view_list.template.js +0 -2
  504. package/dist/templates/view_list.template.js.map +0 -1
  505. package/dist/templates/view_list_columns.template.d.ts +0 -17
  506. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  507. package/dist/templates/view_list_columns.template.js +0 -2
  508. package/dist/templates/view_list_columns.template.js.map +0 -1
  509. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  510. package/dist/templates/view_search_input.template.js +0 -2
  511. package/dist/templates/view_search_input.template.js.map +0 -1
  512. package/dist/testing/_relation-graph.js.map +0 -1
  513. package/dist/testing/fixture-manager.js.map +0 -1
  514. package/dist/types/types.js.map +0 -1
  515. package/dist/typings/knex.d.js.map +0 -1
  516. package/dist/utils/async-utils.js.map +0 -1
  517. package/dist/utils/controller.js.map +0 -1
  518. package/dist/utils/fs-utils.js.map +0 -1
  519. package/dist/utils/lodash-able.js.map +0 -1
  520. package/dist/utils/model.js.map +0 -1
  521. package/dist/utils/sql-parser.js.map +0 -1
  522. package/dist/utils/utils.js.map +0 -1
  523. package/dist/utils/zod-error.js.map +0 -1
  524. package/src/bin/cli-wrapper.ts +0 -75
  525. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  526. package/src/entity/entity-utils.ts +0 -291
  527. package/src/templates/base-template.ts +0 -19
  528. package/src/templates/generated_sso.template.ts +0 -138
  529. package/src/templates/index.ts +0 -1
@@ -1,38 +1,38 @@
1
+ /** biome-ignore-all lint/suspicious/noThenProperty: Puri는 thenable 인터페이스를 구현하고 있습니다. */
2
+ /** biome-ignore-all lint/suspicious/noExplicitAny: Puri는 다양한 타입을 사용하고 있습니다. */
3
+
4
+ import assert from "assert";
5
+ import chalk from "chalk";
1
6
  import type { Knex } from "knex";
7
+ import { Naite } from "../naite/naite";
2
8
  import type {
3
9
  AvailableColumns,
4
- SelectObject,
5
- ParseSelectObject,
6
- WhereCondition,
10
+ ColumnKeys,
7
11
  ComparisonOperator,
8
- ExtractColumnType,
9
- SqlExpression,
10
12
  Expand,
13
+ ExtractColumnType,
11
14
  FulltextColumns,
12
- ResultAvailableColumns,
13
15
  InsertData,
16
+ InsertResult,
17
+ OnConflictAction,
18
+ ParseSelectObject,
19
+ ResultAvailableColumns,
20
+ SelectObject,
14
21
  SingleTableValue,
22
+ SqlExpression,
23
+ WhereCondition,
15
24
  } from "./puri.types";
16
- import chalk from "chalk";
17
- import assert from "assert";
25
+ import type { ClearStatements } from "./puri-subset.types";
18
26
 
19
- export class Puri<
20
- TSchema,
21
- TTables extends Record<string, any>,
22
- TResult,
23
- TResolved = Expand<TResult>[],
24
- > {
27
+ export class Puri<TSchema, TTables extends Record<string, any>, TResult> {
25
28
  private knexQuery: Knex.QueryBuilder;
26
29
 
27
30
  // 생성자 시그니처들
28
31
  constructor(knex: Knex, tableName: string);
32
+ constructor(knex: Knex, tableSpec: Record<string, string | Puri<TSchema, any, any>>);
29
33
  constructor(
30
- knex: Knex,
31
- tableSpec: Record<string, string | Puri<TSchema, any, any>>
32
- );
33
- constructor(
34
- private knex: Knex,
35
- tableNameOrSpec: any
34
+ public knex: Knex,
35
+ tableNameOrSpec: any,
36
36
  ) {
37
37
  if (typeof tableNameOrSpec === "string") {
38
38
  // Case: new Puri(knex, "users")
@@ -62,7 +62,7 @@ export class Puri<
62
62
  return {
63
63
  _type: "sql_expression",
64
64
  _return: "number",
65
- _sql: `COUNT(${column})`,
65
+ _sql: `COUNT(${column})::integer`,
66
66
  };
67
67
  }
68
68
  static sum(column: string): SqlExpression<"number"> {
@@ -129,21 +129,16 @@ export class Puri<
129
129
  return { _type: "sql_expression", _return: "date", _sql: sql };
130
130
  }
131
131
 
132
- // SELECT
132
+ // SELECT (overwrite)
133
133
  select<TSelect extends SelectObject<TTables>>(
134
- selectObj: TSelect
134
+ selectObj: TSelect,
135
135
  ): Puri<TSchema, TTables, ParseSelectObject<TTables, TSelect>> {
136
136
  const selectClauses: (string | Knex.Raw)[] = [];
137
137
 
138
138
  for (const [alias, columnOrFunction] of Object.entries(selectObj)) {
139
- if (
140
- typeof columnOrFunction === "object" &&
141
- columnOrFunction._type === "sql_expression"
142
- ) {
139
+ if (typeof columnOrFunction === "object" && columnOrFunction._type === "sql_expression") {
143
140
  // SQL 함수인 경우
144
- selectClauses.push(
145
- this.knex.raw(`${columnOrFunction._sql} as ${alias}`)
146
- );
141
+ selectClauses.push(this.knex.raw(`${columnOrFunction._sql} as ${alias}`));
147
142
  } else {
148
143
  // 일반 컬럼인 경우
149
144
  const columnPath = columnOrFunction as string;
@@ -161,17 +156,43 @@ export class Puri<
161
156
  return this as any;
162
157
  }
163
158
 
159
+ // SELECT (select는 overwrite, appendSelect는 append)
160
+ appendSelect<TSelect extends SelectObject<TTables>>(
161
+ selectObj: TSelect,
162
+ ): Puri<TSchema, TTables, TResult & ParseSelectObject<TTables, TSelect>> {
163
+ return this.select(selectObj) as any;
164
+ }
165
+
164
166
  // SELECT *
165
167
  selectAll(): this {
166
168
  this.knexQuery.select("*");
167
169
  return this as any;
168
170
  }
169
171
 
172
+ // CLEAR
173
+ clear(statement: ClearStatements): this {
174
+ this.knexQuery.clear(statement);
175
+ return this;
176
+ }
177
+
178
+ // knex에 없어서 직접 구현함
179
+ clearJoin(alias: string): this {
180
+ (this.knexQuery as any)._statements = (this.knexQuery as any)._statements.filter((s: any) => {
181
+ if ("joinType" in s) {
182
+ const [_alias, _table] = Object.entries(s.table)[0];
183
+ return _alias !== alias;
184
+ } else {
185
+ return true;
186
+ }
187
+ });
188
+ return this;
189
+ }
190
+
170
191
  // JOIN: 서브쿼리 + Alias
171
192
  join<TJoinAlias extends string, TSubResult>(
172
193
  tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
173
194
  left: AvailableColumns<TTables>,
174
- right: `${TJoinAlias}.${keyof TSubResult & string}`
195
+ right: `${TJoinAlias}.${ColumnKeys<TSubResult>}`,
175
196
  ): Puri<
176
197
  TSchema,
177
198
  TTables & Record<TJoinAlias, TSubResult>, // 서브쿼리의 TResult
@@ -181,7 +202,7 @@ export class Puri<
181
202
  join<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
182
203
  tableSpec: { [K in TJoinAlias]: TJoinTable },
183
204
  left: AvailableColumns<TTables>,
184
- right: `${TJoinAlias}.${keyof TSchema[TJoinTable] & string}`
205
+ right: `${TJoinAlias}.${ColumnKeys<TSchema[TJoinTable]>}`,
185
206
  ): Puri<
186
207
  TSchema,
187
208
  TTables & Record<TJoinAlias, TSchema[TJoinTable]>, // TTables 확장!
@@ -191,7 +212,7 @@ export class Puri<
191
212
  join<TJoinTable extends keyof TSchema>(
192
213
  tableName: TJoinTable,
193
214
  left: AvailableColumns<TTables>,
194
- right: `${TJoinTable & string}.${keyof TSchema[TJoinTable] & string}`
215
+ right: `${TJoinTable & string}.${ColumnKeys<TSchema[TJoinTable]>}`,
195
216
  ): Puri<
196
217
  TSchema,
197
218
  TTables & Record<TJoinTable, TSchema[TJoinTable]>, // 테이블명이 키
@@ -200,23 +221,17 @@ export class Puri<
200
221
  // JOIN: 서브쿼리 + Alias + 콜백
201
222
  join<TJoinAlias extends string, TSubResult>(
202
223
  tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
203
- callback: (
204
- j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>
205
- ) => void
224
+ callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>) => void,
206
225
  ): Puri<TSchema, TTables & Record<TJoinAlias, TSubResult>, TResult>;
207
226
  // JOIN: 테이블 + Alias + 콜백
208
227
  join<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
209
228
  tableSpec: { [K in TJoinAlias]: TJoinTable },
210
- callback: (
211
- j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>
212
- ) => void
229
+ callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>) => void,
213
230
  ): Puri<TSchema, TTables & Record<TJoinAlias, TSchema[TJoinTable]>, TResult>;
214
231
  // JOIN: 테이블명 + 콜백
215
232
  join<TJoinTable extends keyof TSchema>(
216
233
  tableName: TJoinTable,
217
- callback: (
218
- j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>
219
- ) => void
234
+ callback: (j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>) => void,
220
235
  ): Puri<TSchema, TTables & Record<TJoinTable, TSchema[TJoinTable]>, TResult>;
221
236
  // JOIN 실제 구현
222
237
  join(tableNameOrSpec: any, ...args: any[]): any {
@@ -227,7 +242,7 @@ export class Puri<
227
242
  leftJoin<TJoinAlias extends string, TSubResult>(
228
243
  tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
229
244
  left: AvailableColumns<TTables>,
230
- right: `${TJoinAlias}.${keyof TSubResult & string}`
245
+ right: `${TJoinAlias}.${ColumnKeys<TSubResult>}`,
231
246
  ): Puri<
232
247
  TSchema,
233
248
  TTables & Record<TJoinAlias, TSubResult>, // 서브쿼리의 TResult
@@ -237,7 +252,7 @@ export class Puri<
237
252
  leftJoin<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
238
253
  tableSpec: { [K in TJoinAlias]: TJoinTable },
239
254
  left: AvailableColumns<TTables>,
240
- right: `${TJoinAlias}.${keyof TSchema[TJoinTable] & string}`
255
+ right: `${TJoinAlias}.${ColumnKeys<TSchema[TJoinTable]>}`,
241
256
  ): Puri<
242
257
  TSchema,
243
258
  TTables & Record<TJoinAlias, TSchema[TJoinTable]>, // TTables 확장!
@@ -247,7 +262,7 @@ export class Puri<
247
262
  leftJoin<TJoinTable extends keyof TSchema>(
248
263
  tableName: TJoinTable,
249
264
  left: AvailableColumns<TTables>,
250
- right: `${TJoinTable & string}.${keyof TSchema[TJoinTable] & string}`
265
+ right: `${TJoinTable & string}.${ColumnKeys<TSchema[TJoinTable]>}`,
251
266
  ): Puri<
252
267
  TSchema,
253
268
  TTables & Record<TJoinTable, TSchema[TJoinTable]>, // 테이블명이 키
@@ -256,34 +271,24 @@ export class Puri<
256
271
  // LEFT JOIN: 서브쿼리 + Alias + 콜백
257
272
  leftJoin<TJoinAlias extends string, TSubResult>(
258
273
  tableSpec: { [K in TJoinAlias]: Puri<TSchema, any, TSubResult> },
259
- callback: (
260
- j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>
261
- ) => void
274
+ callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSubResult>>) => void,
262
275
  ): Puri<TSchema, TTables & Record<TJoinAlias, TSubResult>, TResult>;
263
276
  // LEFT JOIN: 테이블 + Alias + 콜백
264
277
  leftJoin<TJoinTable extends keyof TSchema, TJoinAlias extends string>(
265
278
  tableSpec: { [K in TJoinAlias]: TJoinTable },
266
- callback: (
267
- j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>
268
- ) => void
279
+ callback: (j: JoinClauseGroup<TTables, Record<TJoinAlias, TSchema[TJoinTable]>>) => void,
269
280
  ): Puri<TSchema, TTables & Record<TJoinAlias, TSchema[TJoinTable]>, TResult>;
270
281
  // LEFT JOIN: 테이블명 + 콜백
271
282
  leftJoin<TJoinTable extends keyof TSchema>(
272
283
  tableName: TJoinTable,
273
- callback: (
274
- j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>
275
- ) => void
284
+ callback: (j: JoinClauseGroup<TTables, Record<TJoinTable, TSchema[TJoinTable]>>) => void,
276
285
  ): Puri<TSchema, TTables & Record<TJoinTable, TSchema[TJoinTable]>, TResult>;
277
286
  // LEFT JOIN 실제 구현
278
287
  leftJoin(tableNameOrSpec: any, ...args: any[]): any {
279
288
  return this.__commonJoin("leftJoin", tableNameOrSpec, ...args);
280
289
  }
281
290
 
282
- __commonJoin(
283
- joinType: "join" | "leftJoin",
284
- tableNameOrSpec: any,
285
- ...args: any[]
286
- ): this {
291
+ __commonJoin(joinType: "join" | "leftJoin", tableNameOrSpec: any, ...args: any[]): this {
287
292
  if (typeof tableNameOrSpec === "string") {
288
293
  // Case 1: join("posts", ...)
289
294
  const tableName = tableNameOrSpec;
@@ -349,25 +354,26 @@ export class Puri<
349
354
  // WHERE: 컬럼 - 사용: .where("u.id", 1)
350
355
  where<TColumn extends AvailableColumns<TTables>>(
351
356
  column: TColumn,
352
- value: ExtractColumnType<TTables, TColumn & string>
357
+ value: ExtractColumnType<TTables, TColumn & string>,
353
358
  ): this;
354
359
  // WHERE: 컬럼 - 사용: .where("u.id", ">", 10)
355
360
  where<TColumn extends AvailableColumns<TTables>>(
356
361
  column: TColumn,
357
- operator: ComparisonOperator,
358
- value: ExtractColumnType<TTables, TColumn & string>
362
+ operator: ComparisonOperator | "like" | "not like",
363
+ value: ExtractColumnType<TTables, TColumn & string>,
359
364
  ): this;
360
365
  // WHERE: 컬럼 - 사용: .where("u.id", "like", "%test%")
361
- where(columnOrConditions: any, operatorOrValue?: any, value?: any): this {
366
+ where(...args: [columnOrConditions: any, operatorOrValue?: any, value?: any]): this {
367
+ const [columnOrConditions, operatorOrValue, value] = args;
362
368
  if (typeof columnOrConditions === "object") {
363
369
  this.knexQuery.where(columnOrConditions);
364
- } else if (arguments.length === 2) {
370
+ } else if (typeof value === "undefined") {
365
371
  if (operatorOrValue === null) {
366
372
  this.knexQuery.whereNull(columnOrConditions);
367
373
  return this;
368
374
  }
369
375
  this.knexQuery.where(columnOrConditions, operatorOrValue);
370
- } else if (arguments.length === 3) {
376
+ } else if (typeof value !== "undefined") {
371
377
  if (value === null) {
372
378
  if (operatorOrValue === "!=") {
373
379
  this.knexQuery.whereNotNull(columnOrConditions);
@@ -387,7 +393,7 @@ export class Puri<
387
393
  // WHERE IN
388
394
  whereIn<TColumn extends AvailableColumns<TTables>>(
389
395
  column: TColumn,
390
- values: ExtractColumnType<TTables, TColumn & string>[]
396
+ values: ExtractColumnType<TTables, TColumn & string>[],
391
397
  ): Puri<TSchema, TTables, TResult> {
392
398
  this.knexQuery.whereIn(column, values);
393
399
  return this as any;
@@ -396,17 +402,14 @@ export class Puri<
396
402
  // WHERE NOT IN
397
403
  whereNotIn<TColumn extends AvailableColumns<TTables>>(
398
404
  column: TColumn,
399
- values: ExtractColumnType<TTables, TColumn & string>[]
405
+ values: ExtractColumnType<TTables, TColumn & string>[],
400
406
  ): Puri<TSchema, TTables, TResult> {
401
- this.knexQuery.whereIn(column, values);
407
+ this.knexQuery.whereNotIn(column, values);
402
408
  return this as any;
403
409
  }
404
410
 
405
411
  // WHERE MATCH
406
- whereMatch<TColumn extends FulltextColumns<TTables>>(
407
- column: TColumn,
408
- value: string
409
- ): this {
412
+ whereMatch<TColumn extends FulltextColumns<TTables>>(column: TColumn, value: string): this {
410
413
  this.knexQuery.whereRaw(`MATCH (${String(column)}) AGAINST (?)`, [value]);
411
414
  return this;
412
415
  }
@@ -430,7 +433,7 @@ export class Puri<
430
433
  // ORDER BY
431
434
  orderBy<TColumn extends ResultAvailableColumns<TTables, TResult>>(
432
435
  column: TColumn,
433
- direction: "asc" | "desc"
436
+ direction: "asc" | "desc",
434
437
  ): this;
435
438
  orderBy(column: string, direction: "asc" | "desc" = "asc"): this {
436
439
  this.knexQuery.orderBy(column, direction);
@@ -449,9 +452,7 @@ export class Puri<
449
452
  }
450
453
 
451
454
  // GROUP BY
452
- groupBy<TColumns extends ResultAvailableColumns<TTables, TResult>>(
453
- ...columns: TColumns[]
454
- ): this;
455
+ groupBy<TColumns extends ResultAvailableColumns<TTables, TResult>>(...columns: TColumns[]): this;
455
456
  groupBy(...columns: string[]): this {
456
457
  this.knexQuery.groupBy(...(columns as string[]));
457
458
  return this;
@@ -462,16 +463,20 @@ export class Puri<
462
463
  having<TColumn extends ResultAvailableColumns<TTables, TResult>>(
463
464
  column: TColumn,
464
465
  operator: ComparisonOperator,
465
- value: any
466
+ value: any,
466
467
  ): this;
467
468
  // HAVING 구현
468
469
  having(...conditions: any[]): this {
469
470
  if (conditions.length === 1) {
470
471
  // having("COUNT(*) > 10")
471
- this.knexQuery.having(conditions[0]);
472
+ this.knexQuery.having(this.knex.raw(conditions[0]));
472
473
  } else if (conditions.length === 3) {
473
474
  // having("count", ">", 10)
474
- this.knexQuery.having(conditions[0], conditions[1], conditions[2]);
475
+ this.knexQuery.having(
476
+ this.knex.raw(conditions[0]),
477
+ conditions[1],
478
+ this.knex.raw(conditions[2]),
479
+ );
475
480
  } else {
476
481
  throw new Error("Invalid having arguments");
477
482
  }
@@ -479,101 +484,82 @@ export class Puri<
479
484
  }
480
485
 
481
486
  // 실행 메서드들 - thenable 구현
482
- then<TResult1 = TResolved, TResult2 = never>(
483
- onfulfilled?:
484
- | ((value: TResolved) => TResult1 | PromiseLike<TResult1>)
485
- | null,
486
- onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
487
+ then<TResult1 = Expand<TResult>[], TResult2 = never>(
488
+ onfulfilled?: ((value: Expand<TResult>[]) => TResult1 | PromiseLike<TResult1>) | null,
489
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
487
490
  ): Promise<TResult1 | TResult2> {
491
+ Naite.t("puri:executed-query", this.toQuery());
488
492
  return this.knexQuery.then(onfulfilled as any, onrejected);
489
493
  }
490
494
  catch<TResult2 = never>(
491
- onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
492
- ): Promise<Expand<TResult> | TResult2> {
495
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
496
+ ): Promise<TResult | TResult2> {
493
497
  return this.knexQuery.catch(onrejected);
494
498
  }
495
- finally(onfinally?: (() => void) | null): Promise<Expand<TResult>> {
499
+ finally(onfinally?: (() => void) | null): Promise<TResult> {
496
500
  return this.knexQuery.finally(onfinally);
497
501
  }
498
502
 
499
503
  // 하나만 쿼리
500
- async first(): Promise<Expand<TResult> | undefined> {
501
- return this.knexQuery.first();
502
- }
503
- // 하나만 쿼리 실패 시 에러
504
- async firstOrFail(): Promise<TResult> {
505
- const result = await this.knexQuery.first();
506
- if (!result) {
507
- throw new Error("No results found");
508
- }
509
- return result;
510
- }
511
-
512
- // 쿼리 후 인덱스 리턴
513
- async at(index: number): Promise<Expand<TResult> | undefined> {
514
- const results = (await this) as any[];
515
- return results[index];
516
- }
517
- // 쿼리 후 인덱스 리턴 실패 시 에러
518
- async assertAt(index: number): Promise<Expand<TResult>> {
519
- const results = (await this) as any[];
520
- const result = results[index];
521
- if (result === undefined) {
522
- throw new Error(`No result found at index ${index}`);
523
- }
524
- return result;
504
+ first(): ResolvedPuri<Expand<TResult>, never> {
505
+ this.knexQuery.first();
506
+ return new ResolvedPuri(this.knexQuery, this.knex);
525
507
  }
526
508
 
527
509
  // 쿼리한 레코드에서 특정 컬럼만 추출한 배열 리턴
528
- async pluck<TColumn extends ResultAvailableColumns<TTables, TResult>>(
529
- column: TColumn
530
- ): Promise<ExtractColumnType<TTables, TColumn & string>[]> {
531
- return this.knexQuery.pluck(column) as Promise<
532
- ExtractColumnType<TTables, TColumn & string>[]
533
- >;
510
+ pluck<TColumn extends keyof TResult | ResultAvailableColumns<TTables, TResult>>(
511
+ column: TColumn,
512
+ ): ResolvedPuri<
513
+ TColumn extends keyof TResult
514
+ ? TResult[TColumn][]
515
+ : ExtractColumnType<TTables, TColumn & string>[],
516
+ never
517
+ > {
518
+ this.knexQuery.pluck(column as string);
519
+ return new ResolvedPuri(this.knexQuery, this.knex);
534
520
  }
535
521
 
536
522
  // INSERT
537
523
  insert(
538
- data: InsertData<SingleTableValue<TTables>>
539
- ): Puri<TSchema, {}, number, number[]> {
524
+ data: InsertData<SingleTableValue<TTables>>,
525
+ ): ResolvedPuri<InsertResult, SingleTableValue<TTables>> {
540
526
  this.knexQuery.insert(data);
541
- return this as any;
527
+ return new ResolvedPuri(this.knexQuery, this.knex);
542
528
  }
543
529
 
544
530
  // UPDATE
545
- update(data: WhereCondition<TTables>): Puri<TSchema, {}, number, number> {
531
+ update(data: WhereCondition<TTables>): ResolvedPuri<number, SingleTableValue<TTables>> {
546
532
  this.knexQuery.update(data);
547
- return this as any;
533
+ return new ResolvedPuri(this.knexQuery, this.knex);
548
534
  }
549
535
 
550
536
  // Increment
551
537
  increment<TColumn extends AvailableColumns<TTables>>(
552
538
  column: TColumn,
553
- value: number
554
- ): this {
539
+ value: number,
540
+ ): ResolvedPuri<number, SingleTableValue<TTables>> {
555
541
  if (value <= 0) {
556
542
  throw new Error("Increment value must be greater than 0");
557
543
  }
558
544
  this.knexQuery.increment(column, value);
559
- return this;
545
+ return new ResolvedPuri(this.knexQuery, this.knex);
560
546
  }
561
547
  // Decrement
562
548
  decrement<TColumn extends AvailableColumns<TTables>>(
563
549
  column: TColumn,
564
- value: number
565
- ): this {
550
+ value: number,
551
+ ): ResolvedPuri<number, SingleTableValue<TTables>> {
566
552
  if (value <= 0) {
567
553
  throw new Error("Decrement value must be greater than 0");
568
554
  }
569
555
  this.knexQuery.decrement(column, value);
570
- return this;
556
+ return new ResolvedPuri(this.knexQuery, this.knex);
571
557
  }
572
558
 
573
559
  // DELETE
574
- delete(): Puri<TSchema, {}, number, number> {
560
+ delete(): ResolvedPuri<number, SingleTableValue<TTables>> {
575
561
  this.knexQuery.delete();
576
- return this as any;
562
+ return new ResolvedPuri(this.knexQuery, this.knex);
577
563
  }
578
564
 
579
565
  // 확인 쿼리 리턴
@@ -583,12 +569,17 @@ export class Puri<
583
569
 
584
570
  // 쿼리 디버깅 로그 출력
585
571
  debug(): this {
586
- console.log(
587
- `${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`
588
- );
572
+ console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
589
573
  return this;
590
574
  }
591
575
 
576
+ clone(): Puri<TSchema, TTables, TResult> {
577
+ // 'dual'은 더미 테이블이며, 바로 아래 줄에서 knexQuery가 덮어씌워집니다.
578
+ const newPuri = new Puri<TSchema, TTables, TResult>(this.knex, "dual");
579
+ newPuri.knexQuery = this.knexQuery.clone();
580
+ return newPuri;
581
+ }
582
+
592
583
  formatSQL(unformatted: string): string {
593
584
  // SQL 예약어 목록
594
585
  const keywords = [
@@ -662,10 +653,7 @@ export class Puri<
662
653
  });
663
654
 
664
655
  // JOIN 절 처리
665
- formatted = formatted.replace(
666
- /\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi,
667
- "\n$1JOIN "
668
- );
656
+ formatted = formatted.replace(/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi, "\n$1JOIN ");
669
657
 
670
658
  // AND, OR 조건 처리
671
659
  formatted = formatted.replace(/\s+(AND|OR)\s+/gi, "\n $1 ");
@@ -675,7 +663,7 @@ export class Puri<
675
663
  const indentedLines = [];
676
664
  let indentLevel = 0;
677
665
 
678
- for (let line of lines) {
666
+ for (const line of lines) {
679
667
  const trimmedLine = line.trim();
680
668
  if (!trimmedLine) continue;
681
669
 
@@ -713,12 +701,12 @@ export class WhereGroup<TTables extends Record<string, any>> {
713
701
  where(conditions: WhereCondition<TTables>): this;
714
702
  where<TColumn extends AvailableColumns<TTables>>(
715
703
  column: TColumn,
716
- value: ExtractColumnType<TTables, TColumn & string>
704
+ value: ExtractColumnType<TTables, TColumn & string>,
717
705
  ): this;
718
706
  where<TColumn extends AvailableColumns<TTables>>(
719
707
  column: TColumn,
720
708
  operator: ComparisonOperator,
721
- value: ExtractColumnType<TTables, TColumn & string>
709
+ value: ExtractColumnType<TTables, TColumn & string>,
722
710
  ): this;
723
711
  where(...args: any[]): WhereGroup<TTables> {
724
712
  this.builder.where(args[0], ...args.slice(1));
@@ -729,12 +717,12 @@ export class WhereGroup<TTables extends Record<string, any>> {
729
717
  orWhere(conditions: WhereCondition<TTables>): this;
730
718
  orWhere<TColumn extends AvailableColumns<TTables>>(
731
719
  column: TColumn,
732
- value: ExtractColumnType<TTables, TColumn & string>
720
+ value: ExtractColumnType<TTables, TColumn & string>,
733
721
  ): this;
734
722
  orWhere<TColumn extends AvailableColumns<TTables>>(
735
723
  column: TColumn,
736
724
  operator: ComparisonOperator,
737
- value: ExtractColumnType<TTables, TColumn & string>
725
+ value: ExtractColumnType<TTables, TColumn & string>,
738
726
  ): this;
739
727
  orWhere(...args: any[]): WhereGroup<TTables> {
740
728
  this.builder.orWhere(args[0], ...args.slice(1));
@@ -751,9 +739,7 @@ export class WhereGroup<TTables extends Record<string, any>> {
751
739
  return this;
752
740
  }
753
741
  orWhereGroup(callback: (g: WhereGroup<TTables>) => void): this;
754
- orWhereGroup(
755
- callback: (g: WhereGroup<TTables>) => void
756
- ): WhereGroup<TTables> {
742
+ orWhereGroup(callback: (g: WhereGroup<TTables>) => void): WhereGroup<TTables> {
757
743
  this.builder.orWhere((subBuilder) => {
758
744
  const subGroup = new WhereGroup<TTables>(subBuilder);
759
745
  callback(subGroup);
@@ -774,7 +760,7 @@ export class JoinClauseGroup<
774
760
  on(
775
761
  left: AvailableColumns<TLeft>,
776
762
  operator: ComparisonOperator,
777
- right: AvailableColumns<TRight>
763
+ right: AvailableColumns<TRight>,
778
764
  ): this;
779
765
  // ON(AND): 콜백
780
766
  on(callback: (nested: JoinClauseGroup<TLeft, TRight>) => void): this;
@@ -790,7 +776,7 @@ export class JoinClauseGroup<
790
776
  orOn(
791
777
  left: AvailableColumns<TLeft>,
792
778
  operator: ComparisonOperator,
793
- right: AvailableColumns<TRight>
779
+ right: AvailableColumns<TRight>,
794
780
  ): this;
795
781
  // ON(OR): 콜백
796
782
  orOn(callback: (nested: JoinClauseGroup<TLeft, TRight>) => void): this;
@@ -800,3 +786,98 @@ export class JoinClauseGroup<
800
786
  return this;
801
787
  }
802
788
  }
789
+
790
+ /*
791
+ TResolved: 쿼리 실행 후 반환될 결과 타입
792
+ TReturning: RETURNING 절에 사용될 타입
793
+ */
794
+ export class ResolvedPuri<TResolved, TReturning> {
795
+ constructor(
796
+ public knexQuery: Knex.QueryBuilder,
797
+ private knex: Knex,
798
+ ) {}
799
+
800
+ toQuery(): string {
801
+ return this.knexQuery.toQuery();
802
+ }
803
+
804
+ debug(): this {
805
+ console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
806
+ return this;
807
+ }
808
+
809
+ then<TResult1 = TResolved, TResult2 = never>(
810
+ onfulfilled?: ((value: TResolved) => TResult1 | PromiseLike<TResult1>) | null,
811
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
812
+ ): Promise<TResult1 | TResult2> {
813
+ Naite.t("puri:executed-query", this.toQuery());
814
+ return this.knexQuery.then(onfulfilled as any, onrejected);
815
+ }
816
+ catch<TResult2 = never>(
817
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
818
+ ): Promise<TResolved | TResult2> {
819
+ return this.knexQuery.catch(onrejected);
820
+ }
821
+ finally(onfinally?: (() => void) | null): Promise<TResolved> {
822
+ return this.knexQuery.finally(onfinally);
823
+ }
824
+
825
+ // ON CONFLICT - 컬럼 기반
826
+ onConflict<TTables extends Record<string, TReturning>>(
827
+ columns: string | string[],
828
+ action?: OnConflictAction<TTables>,
829
+ ): this {
830
+ const target = Array.isArray(columns) ? columns : [columns];
831
+
832
+ if (!action || action === "nothing") {
833
+ // DO NOTHING
834
+ this.knexQuery.onConflict(target).ignore();
835
+ } else {
836
+ // DO UPDATE
837
+ const { update } = action;
838
+
839
+ // action.update 배열 형태 : ["name", "email"]
840
+ if (Array.isArray(update)) {
841
+ this.knexQuery.onConflict(target).merge(update);
842
+ } else {
843
+ // action.update 객체 형태: { name: "John", count: raw(...) }
844
+ const mergeObj: Record<string, any> = {};
845
+
846
+ for (const [key, value] of Object.entries(update)) {
847
+ if (
848
+ value &&
849
+ typeof value === "object" &&
850
+ "_type" in value &&
851
+ value._type === "sql_expression"
852
+ ) {
853
+ // SqlExpression → knex.raw()로 변환
854
+ mergeObj[key] = this.knex.raw((value as SqlExpression<any>)._sql);
855
+ } else {
856
+ // 일반 값
857
+ mergeObj[key] = value;
858
+ }
859
+ }
860
+
861
+ this.knexQuery.onConflict(target).merge(mergeObj);
862
+ }
863
+ }
864
+
865
+ return this;
866
+ }
867
+
868
+ // RETURNING: "*" - 전체 컬럼
869
+ returning(column: "*"): ResolvedPuri<TReturning[], never>;
870
+ // RETURNING: 단일 컬럼
871
+ returning<TColumn extends ColumnKeys<TReturning>>(
872
+ column: TColumn,
873
+ ): ResolvedPuri<Pick<TReturning, TColumn>[], never>;
874
+ // RETURNING: 복수 컬럼 (배열)
875
+ returning<TColumn extends ColumnKeys<TReturning>>(
876
+ columns: TColumn[],
877
+ ): ResolvedPuri<Pick<TReturning, TColumn>[], never>;
878
+ // RETURNING 구현
879
+ returning(columnOrColumns: string | string[]): ResolvedPuri<any[], never> {
880
+ this.knexQuery.returning(columnOrColumns);
881
+ return new ResolvedPuri(this.knexQuery, this.knex);
882
+ }
883
+ }