semola 0.5.3 → 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 (367) hide show
  1. package/README.md +18 -45
  2. package/dist/chunk-CKQMccvm.cjs +28 -0
  3. package/dist/lib/api/index.cjs +536 -4
  4. package/dist/lib/api/index.d.cts +270 -4
  5. package/dist/lib/api/index.d.mts +270 -4
  6. package/dist/lib/api/index.mjs +534 -2
  7. package/dist/lib/cache/index.cjs +47 -22
  8. package/dist/lib/cache/index.d.cts +14 -23
  9. package/dist/lib/cache/index.d.mts +14 -23
  10. package/dist/lib/cache/index.mjs +48 -25
  11. package/dist/lib/cron/index.cjs +734 -12
  12. package/dist/lib/cron/index.d.cts +145 -3
  13. package/dist/lib/cron/index.d.mts +145 -3
  14. package/dist/lib/cron/index.mjs +725 -3
  15. package/dist/lib/errors/index.d.cts +4 -4
  16. package/dist/lib/errors/index.d.mts +4 -4
  17. package/dist/lib/errors/index.mjs +0 -2
  18. package/dist/lib/i18n/index.d.cts +12 -4
  19. package/dist/lib/i18n/index.d.mts +12 -4
  20. package/dist/lib/i18n/index.mjs +0 -2
  21. package/dist/lib/logging/index.cjs +387 -17
  22. package/dist/lib/logging/index.d.cts +107 -6
  23. package/dist/lib/logging/index.d.mts +107 -6
  24. package/dist/lib/logging/index.mjs +373 -4
  25. package/dist/lib/orm/index.cjs +1641 -19
  26. package/dist/lib/orm/index.d.cts +402 -7
  27. package/dist/lib/orm/index.d.mts +402 -7
  28. package/dist/lib/orm/index.mjs +1630 -6
  29. package/dist/lib/policy/index.cjs +206 -20
  30. package/dist/lib/policy/index.d.cts +61 -5
  31. package/dist/lib/policy/index.d.mts +61 -5
  32. package/dist/lib/policy/index.mjs +187 -3
  33. package/dist/lib/prompts/index.cjs +374 -14
  34. package/dist/lib/prompts/index.d.cts +73 -29
  35. package/dist/lib/prompts/index.d.mts +73 -29
  36. package/dist/lib/prompts/index.mjs +361 -4
  37. package/dist/lib/pubsub/index.cjs +43 -19
  38. package/dist/lib/pubsub/index.d.cts +12 -22
  39. package/dist/lib/pubsub/index.d.mts +12 -22
  40. package/dist/lib/pubsub/index.mjs +44 -22
  41. package/dist/lib/queue/index.cjs +40 -10
  42. package/dist/lib/queue/index.d.cts +57 -8
  43. package/dist/lib/queue/index.d.mts +57 -8
  44. package/dist/lib/queue/index.mjs +39 -13
  45. package/dist/lib/workflow/index.cjs +285 -282
  46. package/dist/lib/workflow/index.d.cts +147 -4
  47. package/dist/lib/workflow/index.d.mts +147 -4
  48. package/dist/lib/workflow/index.mjs +278 -286
  49. package/package.json +11 -1
  50. package/dist/api/core/index.cjs +0 -206
  51. package/dist/api/core/index.d.cts +0 -21
  52. package/dist/api/core/index.d.cts.map +0 -1
  53. package/dist/api/core/index.d.mts +0 -21
  54. package/dist/api/core/index.d.mts.map +0 -1
  55. package/dist/api/core/index.mjs +0 -208
  56. package/dist/api/core/index.mjs.map +0 -1
  57. package/dist/api/core/types.d.cts +0 -107
  58. package/dist/api/core/types.d.cts.map +0 -1
  59. package/dist/api/core/types.d.mts +0 -107
  60. package/dist/api/core/types.d.mts.map +0 -1
  61. package/dist/api/middleware/index.cjs +0 -8
  62. package/dist/api/middleware/index.d.cts +0 -11
  63. package/dist/api/middleware/index.d.cts.map +0 -1
  64. package/dist/api/middleware/index.d.mts +0 -11
  65. package/dist/api/middleware/index.d.mts.map +0 -1
  66. package/dist/api/middleware/index.mjs +0 -10
  67. package/dist/api/middleware/index.mjs.map +0 -1
  68. package/dist/api/middleware/types.d.cts +0 -16
  69. package/dist/api/middleware/types.d.cts.map +0 -1
  70. package/dist/api/middleware/types.d.mts +0 -16
  71. package/dist/api/middleware/types.d.mts.map +0 -1
  72. package/dist/api/openapi/index.cjs +0 -254
  73. package/dist/api/openapi/index.mjs +0 -256
  74. package/dist/api/openapi/index.mjs.map +0 -1
  75. package/dist/api/openapi/types.d.cts +0 -60
  76. package/dist/api/openapi/types.d.cts.map +0 -1
  77. package/dist/api/openapi/types.d.mts +0 -60
  78. package/dist/api/openapi/types.d.mts.map +0 -1
  79. package/dist/api/validation/index.cjs +0 -64
  80. package/dist/api/validation/index.mjs +0 -61
  81. package/dist/api/validation/index.mjs.map +0 -1
  82. package/dist/cache/types.d.cts +0 -17
  83. package/dist/cache/types.d.cts.map +0 -1
  84. package/dist/cache/types.d.mts +0 -17
  85. package/dist/cache/types.d.mts.map +0 -1
  86. package/dist/cron/builder/index.cjs +0 -166
  87. package/dist/cron/builder/index.d.cts +0 -28
  88. package/dist/cron/builder/index.d.cts.map +0 -1
  89. package/dist/cron/builder/index.d.mts +0 -28
  90. package/dist/cron/builder/index.d.mts.map +0 -1
  91. package/dist/cron/builder/index.mjs +0 -163
  92. package/dist/cron/builder/index.mjs.map +0 -1
  93. package/dist/cron/builder/types.cjs +0 -27
  94. package/dist/cron/builder/types.d.cts +0 -79
  95. package/dist/cron/builder/types.d.cts.map +0 -1
  96. package/dist/cron/builder/types.d.mts +0 -79
  97. package/dist/cron/builder/types.d.mts.map +0 -1
  98. package/dist/cron/builder/types.mjs +0 -28
  99. package/dist/cron/builder/types.mjs.map +0 -1
  100. package/dist/cron/core/index.cjs +0 -308
  101. package/dist/cron/core/index.d.cts +0 -39
  102. package/dist/cron/core/index.d.cts.map +0 -1
  103. package/dist/cron/core/index.d.mts +0 -39
  104. package/dist/cron/core/index.d.mts.map +0 -1
  105. package/dist/cron/core/index.mjs +0 -310
  106. package/dist/cron/core/index.mjs.map +0 -1
  107. package/dist/cron/core/scanner.cjs +0 -237
  108. package/dist/cron/core/scanner.mjs +0 -238
  109. package/dist/cron/core/scanner.mjs.map +0 -1
  110. package/dist/cron/core/types.d.cts +0 -11
  111. package/dist/cron/core/types.d.cts.map +0 -1
  112. package/dist/cron/core/types.d.mts +0 -11
  113. package/dist/cron/core/types.d.mts.map +0 -1
  114. package/dist/errors/types.d.cts +0 -5
  115. package/dist/errors/types.d.cts.map +0 -1
  116. package/dist/errors/types.d.mts +0 -5
  117. package/dist/errors/types.d.mts.map +0 -1
  118. package/dist/i18n/types.d.cts +0 -13
  119. package/dist/i18n/types.d.cts.map +0 -1
  120. package/dist/i18n/types.d.mts +0 -13
  121. package/dist/i18n/types.d.mts.map +0 -1
  122. package/dist/lib/cache/index.d.cts.map +0 -1
  123. package/dist/lib/cache/index.d.mts.map +0 -1
  124. package/dist/lib/cache/index.mjs.map +0 -1
  125. package/dist/lib/errors/index.d.cts.map +0 -1
  126. package/dist/lib/errors/index.d.mts.map +0 -1
  127. package/dist/lib/errors/index.mjs.map +0 -1
  128. package/dist/lib/i18n/index.d.cts.map +0 -1
  129. package/dist/lib/i18n/index.d.mts.map +0 -1
  130. package/dist/lib/i18n/index.mjs.map +0 -1
  131. package/dist/lib/policy/index.d.cts.map +0 -1
  132. package/dist/lib/policy/index.d.mts.map +0 -1
  133. package/dist/lib/policy/index.mjs.map +0 -1
  134. package/dist/lib/prompts/index.d.cts.map +0 -1
  135. package/dist/lib/prompts/index.d.mts.map +0 -1
  136. package/dist/lib/prompts/index.mjs.map +0 -1
  137. package/dist/lib/pubsub/index.d.cts.map +0 -1
  138. package/dist/lib/pubsub/index.d.mts.map +0 -1
  139. package/dist/lib/pubsub/index.mjs.map +0 -1
  140. package/dist/lib/queue/index.d.cts.map +0 -1
  141. package/dist/lib/queue/index.d.mts.map +0 -1
  142. package/dist/lib/queue/index.mjs.map +0 -1
  143. package/dist/lib/workflow/index.d.cts.map +0 -1
  144. package/dist/lib/workflow/index.d.mts.map +0 -1
  145. package/dist/lib/workflow/index.mjs.map +0 -1
  146. package/dist/logging/core/index.cjs +0 -99
  147. package/dist/logging/core/index.d.cts +0 -26
  148. package/dist/logging/core/index.d.cts.map +0 -1
  149. package/dist/logging/core/index.d.mts +0 -26
  150. package/dist/logging/core/index.d.mts.map +0 -1
  151. package/dist/logging/core/index.mjs +0 -99
  152. package/dist/logging/core/index.mjs.map +0 -1
  153. package/dist/logging/core/types.cjs +0 -10
  154. package/dist/logging/core/types.d.cts +0 -22
  155. package/dist/logging/core/types.d.cts.map +0 -1
  156. package/dist/logging/core/types.d.mts +0 -22
  157. package/dist/logging/core/types.d.mts.map +0 -1
  158. package/dist/logging/core/types.mjs +0 -12
  159. package/dist/logging/core/types.mjs.map +0 -1
  160. package/dist/logging/formatter/index.cjs +0 -119
  161. package/dist/logging/formatter/index.d.cts +0 -27
  162. package/dist/logging/formatter/index.d.cts.map +0 -1
  163. package/dist/logging/formatter/index.d.mts +0 -27
  164. package/dist/logging/formatter/index.d.mts.map +0 -1
  165. package/dist/logging/formatter/index.mjs +0 -115
  166. package/dist/logging/formatter/index.mjs.map +0 -1
  167. package/dist/logging/formatter/types.d.cts +0 -5
  168. package/dist/logging/formatter/types.d.cts.map +0 -1
  169. package/dist/logging/formatter/types.d.mts +0 -5
  170. package/dist/logging/formatter/types.d.mts.map +0 -1
  171. package/dist/logging/provider/index.cjs +0 -165
  172. package/dist/logging/provider/index.d.cts +0 -28
  173. package/dist/logging/provider/index.d.cts.map +0 -1
  174. package/dist/logging/provider/index.d.mts +0 -28
  175. package/dist/logging/provider/index.d.mts.map +0 -1
  176. package/dist/logging/provider/index.mjs +0 -165
  177. package/dist/logging/provider/index.mjs.map +0 -1
  178. package/dist/logging/provider/types.d.cts +0 -23
  179. package/dist/logging/provider/types.d.cts.map +0 -1
  180. package/dist/logging/provider/types.d.mts +0 -23
  181. package/dist/logging/provider/types.d.mts.map +0 -1
  182. package/dist/node_modules/@standard-schema/spec/dist/index.d.cts +0 -80
  183. package/dist/node_modules/@standard-schema/spec/dist/index.d.cts.map +0 -1
  184. package/dist/node_modules/@standard-schema/spec/dist/index.d.mts +0 -80
  185. package/dist/node_modules/@standard-schema/spec/dist/index.d.mts.map +0 -1
  186. package/dist/orm/column.cjs +0 -137
  187. package/dist/orm/column.d.cts +0 -121
  188. package/dist/orm/column.d.cts.map +0 -1
  189. package/dist/orm/column.d.mts +0 -121
  190. package/dist/orm/column.d.mts.map +0 -1
  191. package/dist/orm/column.mjs +0 -132
  192. package/dist/orm/column.mjs.map +0 -1
  193. package/dist/orm/dialect/index.cjs +0 -14
  194. package/dist/orm/dialect/index.mjs +0 -16
  195. package/dist/orm/dialect/index.mjs.map +0 -1
  196. package/dist/orm/dialect/mysql.cjs +0 -31
  197. package/dist/orm/dialect/mysql.mjs +0 -33
  198. package/dist/orm/dialect/mysql.mjs.map +0 -1
  199. package/dist/orm/dialect/postgres.cjs +0 -23
  200. package/dist/orm/dialect/postgres.mjs +0 -25
  201. package/dist/orm/dialect/postgres.mjs.map +0 -1
  202. package/dist/orm/dialect/sqlite.cjs +0 -31
  203. package/dist/orm/dialect/sqlite.mjs +0 -33
  204. package/dist/orm/dialect/sqlite.mjs.map +0 -1
  205. package/dist/orm/dialect/utils.cjs +0 -8
  206. package/dist/orm/dialect/utils.mjs +0 -10
  207. package/dist/orm/dialect/utils.mjs.map +0 -1
  208. package/dist/orm/internal/table-columns.cjs +0 -31
  209. package/dist/orm/internal/table-columns.mjs +0 -32
  210. package/dist/orm/internal/table-columns.mjs.map +0 -1
  211. package/dist/orm/internal/table-lookup.cjs +0 -35
  212. package/dist/orm/internal/table-lookup.mjs +0 -35
  213. package/dist/orm/internal/table-lookup.mjs.map +0 -1
  214. package/dist/orm/internal/table-relations.cjs +0 -28
  215. package/dist/orm/internal/table-relations.mjs +0 -29
  216. package/dist/orm/internal/table-relations.mjs.map +0 -1
  217. package/dist/orm/migration/config.cjs +0 -7
  218. package/dist/orm/migration/config.d.cts +0 -7
  219. package/dist/orm/migration/config.d.cts.map +0 -1
  220. package/dist/orm/migration/config.d.mts +0 -7
  221. package/dist/orm/migration/config.d.mts.map +0 -1
  222. package/dist/orm/migration/config.mjs +0 -8
  223. package/dist/orm/migration/config.mjs.map +0 -1
  224. package/dist/orm/migration/types.d.cts +0 -20
  225. package/dist/orm/migration/types.d.cts.map +0 -1
  226. package/dist/orm/migration/types.d.mts +0 -20
  227. package/dist/orm/migration/types.d.mts.map +0 -1
  228. package/dist/orm/orm.cjs +0 -41
  229. package/dist/orm/orm.d.cts +0 -18
  230. package/dist/orm/orm.d.cts.map +0 -1
  231. package/dist/orm/orm.d.mts +0 -18
  232. package/dist/orm/orm.d.mts.map +0 -1
  233. package/dist/orm/orm.mjs +0 -43
  234. package/dist/orm/orm.mjs.map +0 -1
  235. package/dist/orm/relation.cjs +0 -18
  236. package/dist/orm/relation.d.cts +0 -8
  237. package/dist/orm/relation.d.cts.map +0 -1
  238. package/dist/orm/relation.d.mts +0 -8
  239. package/dist/orm/relation.d.mts.map +0 -1
  240. package/dist/orm/relation.mjs +0 -19
  241. package/dist/orm/relation.mjs.map +0 -1
  242. package/dist/orm/runtime/builders/mutations.cjs +0 -29
  243. package/dist/orm/runtime/builders/mutations.mjs +0 -28
  244. package/dist/orm/runtime/builders/mutations.mjs.map +0 -1
  245. package/dist/orm/runtime/builders/select.cjs +0 -18
  246. package/dist/orm/runtime/builders/select.mjs +0 -19
  247. package/dist/orm/runtime/builders/select.mjs.map +0 -1
  248. package/dist/orm/runtime/client.cjs +0 -90
  249. package/dist/orm/runtime/client.mjs +0 -92
  250. package/dist/orm/runtime/client.mjs.map +0 -1
  251. package/dist/orm/runtime/context.cjs +0 -49
  252. package/dist/orm/runtime/context.mjs +0 -51
  253. package/dist/orm/runtime/context.mjs.map +0 -1
  254. package/dist/orm/runtime/dialect/index.cjs +0 -11
  255. package/dist/orm/runtime/dialect/index.mjs +0 -13
  256. package/dist/orm/runtime/dialect/index.mjs.map +0 -1
  257. package/dist/orm/runtime/dialect/mysql.cjs +0 -95
  258. package/dist/orm/runtime/dialect/mysql.mjs +0 -97
  259. package/dist/orm/runtime/dialect/mysql.mjs.map +0 -1
  260. package/dist/orm/runtime/dialect/postgres.cjs +0 -51
  261. package/dist/orm/runtime/dialect/postgres.mjs +0 -53
  262. package/dist/orm/runtime/dialect/postgres.mjs.map +0 -1
  263. package/dist/orm/runtime/dialect/sqlite.cjs +0 -4
  264. package/dist/orm/runtime/dialect/sqlite.mjs +0 -7
  265. package/dist/orm/runtime/dialect/sqlite.mjs.map +0 -1
  266. package/dist/orm/runtime/errors.cjs +0 -19
  267. package/dist/orm/runtime/errors.mjs +0 -21
  268. package/dist/orm/runtime/errors.mjs.map +0 -1
  269. package/dist/orm/runtime/hydrate/many.cjs +0 -46
  270. package/dist/orm/runtime/hydrate/many.mjs +0 -48
  271. package/dist/orm/runtime/hydrate/many.mjs.map +0 -1
  272. package/dist/orm/runtime/hydrate/one.cjs +0 -38
  273. package/dist/orm/runtime/hydrate/one.mjs +0 -40
  274. package/dist/orm/runtime/hydrate/one.mjs.map +0 -1
  275. package/dist/orm/runtime/hydrate.cjs +0 -49
  276. package/dist/orm/runtime/hydrate.mjs +0 -51
  277. package/dist/orm/runtime/hydrate.mjs.map +0 -1
  278. package/dist/orm/runtime/rows.cjs +0 -30
  279. package/dist/orm/runtime/rows.mjs +0 -31
  280. package/dist/orm/runtime/rows.mjs.map +0 -1
  281. package/dist/orm/runtime/utils.cjs +0 -27
  282. package/dist/orm/runtime/utils.mjs +0 -27
  283. package/dist/orm/runtime/utils.mjs.map +0 -1
  284. package/dist/orm/sql/parse-array.cjs +0 -64
  285. package/dist/orm/sql/parse-array.mjs +0 -66
  286. package/dist/orm/sql/parse-array.mjs.map +0 -1
  287. package/dist/orm/sql/plan/select.cjs +0 -36
  288. package/dist/orm/sql/plan/select.mjs +0 -38
  289. package/dist/orm/sql/plan/select.mjs.map +0 -1
  290. package/dist/orm/sql/plan/where/operators.cjs +0 -95
  291. package/dist/orm/sql/plan/where/operators.mjs +0 -97
  292. package/dist/orm/sql/plan/where/operators.mjs.map +0 -1
  293. package/dist/orm/sql/plan/where.cjs +0 -59
  294. package/dist/orm/sql/plan/where.mjs +0 -61
  295. package/dist/orm/sql/plan/where.mjs.map +0 -1
  296. package/dist/orm/sql/serialize/clauses.cjs +0 -36
  297. package/dist/orm/sql/serialize/clauses.mjs +0 -37
  298. package/dist/orm/sql/serialize/clauses.mjs.map +0 -1
  299. package/dist/orm/sql/serialize/joins.cjs +0 -31
  300. package/dist/orm/sql/serialize/joins.mjs +0 -33
  301. package/dist/orm/sql/serialize/joins.mjs.map +0 -1
  302. package/dist/orm/sql/serialize/values.cjs +0 -30
  303. package/dist/orm/sql/serialize/values.mjs +0 -32
  304. package/dist/orm/sql/serialize/values.mjs.map +0 -1
  305. package/dist/orm/sql/serialize/where/predicate.cjs +0 -73
  306. package/dist/orm/sql/serialize/where/predicate.mjs +0 -75
  307. package/dist/orm/sql/serialize/where/predicate.mjs.map +0 -1
  308. package/dist/orm/sql/serialize/where/tree.cjs +0 -26
  309. package/dist/orm/sql/serialize/where/tree.mjs +0 -28
  310. package/dist/orm/sql/serialize/where/tree.mjs.map +0 -1
  311. package/dist/orm/sql/serialize/where.cjs +0 -10
  312. package/dist/orm/sql/serialize/where.mjs +0 -12
  313. package/dist/orm/sql/serialize/where.mjs.map +0 -1
  314. package/dist/orm/sql/serialize.cjs +0 -24
  315. package/dist/orm/sql/serialize.mjs +0 -25
  316. package/dist/orm/sql/serialize.mjs.map +0 -1
  317. package/dist/orm/table.cjs +0 -12
  318. package/dist/orm/table.d.cts +0 -12
  319. package/dist/orm/table.d.cts.map +0 -1
  320. package/dist/orm/table.d.mts +0 -12
  321. package/dist/orm/table.d.mts.map +0 -1
  322. package/dist/orm/table.mjs +0 -14
  323. package/dist/orm/table.mjs.map +0 -1
  324. package/dist/orm/types.d.cts +0 -183
  325. package/dist/orm/types.d.cts.map +0 -1
  326. package/dist/orm/types.d.mts +0 -183
  327. package/dist/orm/types.d.mts.map +0 -1
  328. package/dist/policy/helpers.cjs +0 -206
  329. package/dist/policy/helpers.d.cts +0 -50
  330. package/dist/policy/helpers.d.cts.map +0 -1
  331. package/dist/policy/helpers.d.mts +0 -50
  332. package/dist/policy/helpers.d.mts.map +0 -1
  333. package/dist/policy/helpers.mjs +0 -190
  334. package/dist/policy/helpers.mjs.map +0 -1
  335. package/dist/policy/types.d.cts +0 -16
  336. package/dist/policy/types.d.cts.map +0 -1
  337. package/dist/policy/types.d.mts +0 -16
  338. package/dist/policy/types.d.mts.map +0 -1
  339. package/dist/prompts/core/keys.cjs +0 -165
  340. package/dist/prompts/core/keys.mjs +0 -167
  341. package/dist/prompts/core/keys.mjs.map +0 -1
  342. package/dist/prompts/core/runtime.cjs +0 -104
  343. package/dist/prompts/core/runtime.mjs +0 -106
  344. package/dist/prompts/core/runtime.mjs.map +0 -1
  345. package/dist/prompts/core/session.cjs +0 -98
  346. package/dist/prompts/core/session.mjs +0 -100
  347. package/dist/prompts/core/session.mjs.map +0 -1
  348. package/dist/prompts/core/types.d.cts +0 -21
  349. package/dist/prompts/core/types.d.cts.map +0 -1
  350. package/dist/prompts/core/types.d.mts +0 -21
  351. package/dist/prompts/core/types.d.mts.map +0 -1
  352. package/dist/prompts/types.d.cts +0 -52
  353. package/dist/prompts/types.d.cts.map +0 -1
  354. package/dist/prompts/types.d.mts +0 -52
  355. package/dist/prompts/types.d.mts.map +0 -1
  356. package/dist/pubsub/types.d.cts +0 -10
  357. package/dist/pubsub/types.d.cts.map +0 -1
  358. package/dist/pubsub/types.d.mts +0 -10
  359. package/dist/pubsub/types.d.mts.map +0 -1
  360. package/dist/queue/types.d.cts +0 -47
  361. package/dist/queue/types.d.cts.map +0 -1
  362. package/dist/queue/types.d.mts +0 -47
  363. package/dist/queue/types.d.mts.map +0 -1
  364. package/dist/workflow/types.d.cts +0 -83
  365. package/dist/workflow/types.d.cts.map +0 -1
  366. package/dist/workflow/types.d.mts +0 -83
  367. package/dist/workflow/types.d.mts.map +0 -1
package/README.md CHANGED
@@ -27,11 +27,11 @@ Type-safe APIs, Redis queues, pub/sub, i18n, caching & auth with tree-shakeable
27
27
  | **🌍 i18n** | Compile-time validated internationalization | `semola/i18n` |
28
28
  | **💾 Cache** | Redis cache wrapper with TTL & automatic serialization | `semola/cache` |
29
29
  | **⏰ Cron** | In-memory cron scheduler for periodic task execution | `semola/cron` |
30
- | **🔁 Workflow** | Durable resumable workflows with step persistence | `semola/workflow` |
30
+ | **🔁 Workflow** | Durable resumable workflows with retries and hooks | `semola/workflow` |
31
31
  | **⚠️ Errors** | Result-based error handling without try/catch | `semola/errors` |
32
32
  | **📃 Logging** | A simple logging utility | `semola/logging` |
33
33
  | **⌨️ Prompts** | Interactive zero-dependency CLI prompts | `semola/prompts` |
34
- | **🗄️ ORM** | Type-safe data layer with query APIs + migrations | `semola/orm` |
34
+ | **🗄️ ORM** | Type-safe data layer with query APIs | `semola/orm` |
35
35
 
36
36
  ---
37
37
 
@@ -122,16 +122,14 @@ const pubsub = new PubSub({
122
122
  });
123
123
 
124
124
  // Subscribe to messages
125
- const [, unsubscribeHandler] = await pubsub.subscribe((message) => {
125
+ const unsubscribe = await pubsub.subscribe((message) => {
126
126
  console.log("Received:", message);
127
127
  });
128
128
 
129
129
  // Publish a message
130
130
  await pubsub.publish({ userId: 123, text: "New alert!" });
131
131
 
132
- if (unsubscribeHandler) {
133
- await unsubscribeHandler();
134
- }
132
+ await unsubscribe();
135
133
  ```
136
134
 
137
135
  ### Cache Data with TTL
@@ -148,8 +146,8 @@ const cache = new Cache({
148
146
  await cache.set("user:123", { name: "John", age: 30 });
149
147
 
150
148
  // Retrieve data
151
- const [error, user] = await cache.get("user:123");
152
- if (!error) console.log(user);
149
+ const user = await cache.get("user:123");
150
+ console.log(user);
153
151
  ```
154
152
 
155
153
  ### Schedule Recurring Tasks
@@ -172,60 +170,35 @@ cleanup.start();
172
170
  ### Query a Database
173
171
 
174
172
  ```typescript
175
- import { createOrm, createTable, string, uuid } from "semola/orm";
173
+ import { createOrm, defineTable, json, string, uuid } from "semola/orm";
176
174
 
177
- const users = createTable("users", {
178
- id: uuid("id").primaryKey(),
175
+ const users = defineTable("users", {
176
+ id: uuid("id").primaryKey().notNull(),
179
177
  name: string("name").notNull(),
180
178
  email: string("email").unique().notNull(),
179
+ metadata: json<{ plan: string }>("metadata"),
181
180
  });
182
181
 
183
182
  const db = createOrm({
184
- url: "sqlite::memory:",
183
+ adapter: "sqlite",
184
+ url: ":memory:",
185
185
  tables: { users },
186
186
  });
187
187
 
188
- // Result-pattern query
189
- const [findErr, rows] = await db.users.findMany({
188
+ const rows = await db.users.findMany({
190
189
  where: { name: { contains: "John" } },
191
190
  take: 10,
192
191
  });
193
192
 
194
- if (findErr) {
195
- console.error(findErr.type, findErr.message);
196
- }
197
-
198
- // Create record (result pattern)
199
- const [createErr, user] = await db.users.create({
193
+ const user = await db.users.create({
200
194
  data: {
195
+ id: "1",
201
196
  name: "John Doe",
202
197
  email: "john@example.com",
203
198
  },
204
199
  });
205
200
 
206
- // Low-level SQL-style methods are also available
207
- const insertedRows = await db.users.insert({
208
- data: {
209
- name: "Jane Doe",
210
- email: "jane@example.com",
211
- },
212
- returning: true,
213
- });
214
-
215
- console.log(rows, user, createErr, insertedRows);
216
- ```
217
-
218
- ### Run ORM Migrations
219
-
220
- ```bash
221
- # create migration from schema diff
222
- semola orm migrations create add-users
223
-
224
- # apply pending migrations
225
- semola orm migrations apply
226
-
227
- # rollback last applied migration
228
- semola orm migrations rollback
201
+ console.log(rows, user);
229
202
  ```
230
203
 
231
204
  ### Check Permissions
@@ -345,14 +318,14 @@ _Higher is better for req/sec, lower is better for latency._
345
318
  - [Queue](./docs/queue.md) - Redis-backed job queue with timeouts & concurrency
346
319
  - [PubSub](./docs/pubsub.md) - Type-safe Redis pub/sub
347
320
  - [Cron](./docs/cron.md) - In-memory cron scheduler for periodic task execution
348
- - [Workflow](./docs/workflow.md) - Durable and resumable workflows with step persistence
321
+ - [Workflow](./docs/workflow.md) - Durable and resumable workflows with retries and hooks
349
322
  - [Policy](./docs/policy.md) - Policy-based authorization
350
323
  - [i18n](./docs/i18n.md) - Type-safe internationalization
351
324
  - [Cache](./docs/cache.md) - Redis cache wrapper with TTL
352
325
  - [Errors](./docs/errors.md) - Result-based error handling
353
326
  - [Logging](./docs/logging.md) - Logging utility
354
327
  - [Prompts](./docs/prompts.md) - Interactive CLI prompts
355
- - [ORM](./docs/orm.md) - Type-safe data layer, result-pattern DX, and migrations
328
+ - [ORM](./docs/orm.md) - Type-safe data layer with SQLite support
356
329
 
357
330
  ---
358
331
 
@@ -0,0 +1,28 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ Object.defineProperty(exports, "__toESM", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return __toESM;
27
+ }
28
+ });
@@ -1,5 +1,537 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_index = require("../../api/core/index.cjs");
3
- const require_index$1 = require("../../api/middleware/index.cjs");
4
- exports.Api = require_index.Api;
5
- exports.Middleware = require_index$1.Middleware;
2
+ const require_lib_errors_index = require("../errors/index.cjs");
3
+ //#region src/lib/api/openapi/index.ts
4
+ const toOpenAPISchema = (schema, io = "input") => ({ schema: schema["~standard"].jsonSchema[io]({ target: "draft-2020-12" }) });
5
+ const getSchemaDescription = (schema) => {
6
+ const metadata = schema["~standard"];
7
+ if (!metadata) return "";
8
+ if ("description" in metadata && typeof metadata.description === "string") return metadata.description;
9
+ return "";
10
+ };
11
+ const requestFields = [
12
+ "body",
13
+ "query",
14
+ "headers",
15
+ "cookies",
16
+ "params"
17
+ ];
18
+ const mergeRequestSchemas = (schemas) => {
19
+ const merged = {};
20
+ for (const schema of schemas) {
21
+ if (!schema) continue;
22
+ for (const field of requestFields) if (schema[field]) merged[field] = schema[field];
23
+ }
24
+ return merged;
25
+ };
26
+ const mergeResponseSchemas = (schemas) => {
27
+ const merged = {};
28
+ for (const schema of schemas) {
29
+ if (!schema) continue;
30
+ for (const status in schema) {
31
+ const statusCode = Number(status);
32
+ const responseSchema = schema[statusCode];
33
+ if (responseSchema) merged[statusCode] = responseSchema;
34
+ }
35
+ }
36
+ return Object.keys(merged).length > 0 ? merged : void 0;
37
+ };
38
+ const convertSchemaToOpenApi = async (schema, io = "input") => {
39
+ const result = toOpenAPISchema(schema, io);
40
+ const { schema: jsonSchema } = result;
41
+ const schemaId = jsonSchema.id;
42
+ if (schemaId && typeof schemaId === "string") {
43
+ const schemaWithoutId = { ...jsonSchema };
44
+ delete schemaWithoutId.id;
45
+ delete schemaWithoutId.$schema;
46
+ return {
47
+ schema: { $ref: `#/components/schemas/${schemaId}` },
48
+ components: { schemas: { [schemaId]: schemaWithoutId } }
49
+ };
50
+ }
51
+ if (jsonSchema.$schema) {
52
+ const schemaWithoutMeta = { ...jsonSchema };
53
+ delete schemaWithoutMeta.$schema;
54
+ return {
55
+ schema: schemaWithoutMeta,
56
+ components: void 0
57
+ };
58
+ }
59
+ return result;
60
+ };
61
+ const convertSchemaToInlineOpenApi = async (schema, io = "input") => {
62
+ const { schema: jsonSchema } = toOpenAPISchema(schema, io);
63
+ const cleanSchema = { ...jsonSchema };
64
+ delete cleanSchema.$schema;
65
+ delete cleanSchema.id;
66
+ return {
67
+ schema: cleanSchema,
68
+ components: void 0
69
+ };
70
+ };
71
+ const extractParametersFromSchema = async (schema, location) => {
72
+ const { schema: jsonSchema, components } = await convertSchemaToInlineOpenApi(schema);
73
+ if (jsonSchema.type !== "object") return {
74
+ parameters: [],
75
+ components
76
+ };
77
+ if (!jsonSchema.properties) return {
78
+ parameters: [],
79
+ components
80
+ };
81
+ const parameters = [];
82
+ const requiredFields = jsonSchema.required ?? [];
83
+ for (const name in jsonSchema.properties) {
84
+ const propertySchema = jsonSchema.properties[name];
85
+ const isRequired = requiredFields.includes(name);
86
+ parameters.push({
87
+ name,
88
+ in: location,
89
+ required: isRequired,
90
+ schema: propertySchema
91
+ });
92
+ }
93
+ return {
94
+ parameters,
95
+ components
96
+ };
97
+ };
98
+ const normalizePathForOpenAPI = (path) => {
99
+ return path.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, "{$1}");
100
+ };
101
+ const extractPathParameters = (path) => {
102
+ const matches = path.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
103
+ if (!matches) return [];
104
+ return matches.map((match) => match.slice(1));
105
+ };
106
+ const paramSources = [
107
+ ["query", "query"],
108
+ ["headers", "header"],
109
+ ["cookies", "cookie"]
110
+ ];
111
+ const createParameters = async (request, path) => {
112
+ const parameters = [];
113
+ const allComponents = [];
114
+ for (const [field, location] of paramSources) if (request[field]) {
115
+ const { parameters: params, components } = await extractParametersFromSchema(request[field], location);
116
+ parameters.push(...params);
117
+ if (components) allComponents.push(components);
118
+ }
119
+ const pathParamNames = extractPathParameters(path);
120
+ if (pathParamNames.length > 0 && request.params) {
121
+ const { schema: jsonSchema, components } = await convertSchemaToInlineOpenApi(request.params);
122
+ if (components) allComponents.push(components);
123
+ if (jsonSchema.type === "object" && jsonSchema.properties) for (const name of pathParamNames) {
124
+ const propertySchema = jsonSchema.properties[name];
125
+ if (propertySchema) parameters.push({
126
+ name,
127
+ in: "path",
128
+ required: true,
129
+ schema: propertySchema
130
+ });
131
+ }
132
+ }
133
+ return {
134
+ parameters,
135
+ components: allComponents
136
+ };
137
+ };
138
+ const createRequestBody = async (bodySchema) => {
139
+ const { schema, components } = await convertSchemaToOpenApi(bodySchema);
140
+ return {
141
+ components,
142
+ requestBody: {
143
+ required: true,
144
+ content: { "application/json": { schema } }
145
+ }
146
+ };
147
+ };
148
+ const createResponses = async (response) => {
149
+ const responses = {};
150
+ const allComponents = [];
151
+ if (!response) return {
152
+ responses,
153
+ components: allComponents
154
+ };
155
+ for (const status in response) {
156
+ const statusCode = String(status);
157
+ const schema = response[Number(status)];
158
+ if (!schema) continue;
159
+ const description = getSchemaDescription(schema);
160
+ const { schema: jsonSchema, components } = await convertSchemaToOpenApi(schema, "output");
161
+ if (components) allComponents.push(components);
162
+ responses[statusCode] = {
163
+ description: description || `Response with status ${statusCode}`,
164
+ content: { "application/json": { schema: jsonSchema } }
165
+ };
166
+ }
167
+ return {
168
+ responses,
169
+ components: allComponents
170
+ };
171
+ };
172
+ const createOperation = async (route, globalMiddlewares, prefix) => {
173
+ const allMiddlewares = [...globalMiddlewares ?? [], ...route.middlewares ?? []];
174
+ const requestSchemas = [];
175
+ const responseSchemas = [];
176
+ for (const middleware of allMiddlewares) {
177
+ requestSchemas.push(middleware.options.request);
178
+ responseSchemas.push(middleware.options.response);
179
+ }
180
+ requestSchemas.push(route.request);
181
+ responseSchemas.push(route.response);
182
+ const mergedRequest = mergeRequestSchemas(requestSchemas);
183
+ const mergedResponse = mergeResponseSchemas(responseSchemas);
184
+ const { parameters, components: parameterComponents } = await createParameters(mergedRequest, prefix ? prefix + route.path : route.path);
185
+ const { responses, components: responseComponents } = await createResponses(mergedResponse);
186
+ const operation = { responses };
187
+ const allComponents = [];
188
+ allComponents.push(...responseComponents);
189
+ allComponents.push(...parameterComponents);
190
+ for (const field of [
191
+ "summary",
192
+ "description",
193
+ "operationId"
194
+ ]) if (route[field]) operation[field] = route[field];
195
+ if (route.tags && route.tags.length > 0) operation.tags = route.tags;
196
+ if (parameters.length > 0) operation.parameters = parameters;
197
+ const bodySchema = mergedRequest.body;
198
+ if (bodySchema) {
199
+ const { requestBody, components: bodyComponents } = await createRequestBody(bodySchema);
200
+ operation.requestBody = requestBody;
201
+ if (bodyComponents) allComponents.push(bodyComponents);
202
+ }
203
+ return {
204
+ operation,
205
+ components: allComponents
206
+ };
207
+ };
208
+ const componentKeys = [
209
+ "schemas",
210
+ "responses",
211
+ "parameters",
212
+ "requestBodies"
213
+ ];
214
+ const mergeComponents = (componentsArray) => {
215
+ const merged = {};
216
+ for (const components of componentsArray) {
217
+ if (!components) continue;
218
+ for (const key of componentKeys) if (components[key]) merged[key] = {
219
+ ...merged[key],
220
+ ...components[key]
221
+ };
222
+ }
223
+ return merged;
224
+ };
225
+ const generateOpenApiSpec = async (options) => {
226
+ const spec = {
227
+ openapi: "3.1.0",
228
+ info: {
229
+ title: options.title,
230
+ description: options.description,
231
+ version: options.version
232
+ },
233
+ paths: {}
234
+ };
235
+ if (options.servers && options.servers.length > 0) spec.servers = options.servers;
236
+ if (options.securitySchemes) spec.components = { securitySchemes: options.securitySchemes };
237
+ const allRouteComponents = [];
238
+ for (const route of options.routes) {
239
+ const openApiPath = normalizePathForOpenAPI(options.prefix ? options.prefix + route.path : route.path);
240
+ const method = route.method.toLowerCase();
241
+ if (!spec.paths[openApiPath]) spec.paths[openApiPath] = {};
242
+ const { operation, components } = await createOperation(route, options.globalMiddlewares ?? [], options.prefix);
243
+ spec.paths[openApiPath][method] = operation;
244
+ allRouteComponents.push(...components);
245
+ }
246
+ const mergedComponents = mergeComponents(allRouteComponents);
247
+ if (!spec.components) spec.components = {};
248
+ if (options.securitySchemes) spec.components.securitySchemes = options.securitySchemes;
249
+ for (const key of componentKeys) {
250
+ const value = mergedComponents[key];
251
+ if (value && Object.keys(value).length > 0) spec.components[key] = value;
252
+ }
253
+ return spec;
254
+ };
255
+ //#endregion
256
+ //#region src/lib/api/errors.ts
257
+ var ParseError = class extends Error {
258
+ constructor(message) {
259
+ super(message);
260
+ this.name = "ParseError";
261
+ }
262
+ };
263
+ var ValidationError = class extends Error {
264
+ constructor(message) {
265
+ super(message);
266
+ this.name = "ValidationError";
267
+ }
268
+ };
269
+ //#endregion
270
+ //#region src/lib/api/validation/index.ts
271
+ const validateSchema = async (schema, data) => {
272
+ const result = await schema["~standard"].validate(data);
273
+ if (!result.issues) return result.value;
274
+ throw new ValidationError(result.issues.map((issue) => {
275
+ let path = "unknown";
276
+ if (Array.isArray(issue.path)) path = issue.path.map(String).join(".");
277
+ return `${path}: ${issue.message ?? "validation failed"}`;
278
+ }).join(", "));
279
+ };
280
+ const validateBody = async (req, bodySchema, bodyCache) => {
281
+ if (!bodySchema) return true;
282
+ if (!(req.headers.get("content-type") ?? "").includes("application/json")) return;
283
+ if (bodyCache?.parsed) return validateSchema(bodySchema, bodyCache.value);
284
+ const [parseError, parsedBody] = await require_lib_errors_index.mightThrow(req.json());
285
+ if (parseError) throw new ParseError("Invalid JSON body");
286
+ if (bodyCache) {
287
+ bodyCache.parsed = true;
288
+ bodyCache.value = parsedBody;
289
+ }
290
+ return validateSchema(bodySchema, parsedBody);
291
+ };
292
+ const validateQuery = async (req, querySchema) => {
293
+ if (!querySchema) return true;
294
+ const qIndex = req.url.indexOf("?");
295
+ if (qIndex === -1) return validateSchema(querySchema, {});
296
+ const hashIndex = req.url.indexOf("#", qIndex + 1);
297
+ const queryString = hashIndex === -1 ? req.url.slice(qIndex + 1) : req.url.slice(qIndex + 1, hashIndex);
298
+ const searchParams = new URLSearchParams(queryString);
299
+ const queryParams = {};
300
+ for (const key of searchParams.keys()) {
301
+ const values = searchParams.getAll(key);
302
+ const [firstValue] = values;
303
+ if (values.length === 1) queryParams[key] = firstValue;
304
+ else queryParams[key] = values;
305
+ }
306
+ return validateSchema(querySchema, queryParams);
307
+ };
308
+ const validateHeaders = async (req, headersSchema) => {
309
+ if (!headersSchema) return true;
310
+ const headers = {};
311
+ req.headers.forEach((value, key) => {
312
+ headers[key] = value;
313
+ });
314
+ return validateSchema(headersSchema, headers);
315
+ };
316
+ const validateCookies = async (req, cookiesSchema) => {
317
+ if (!cookiesSchema) return true;
318
+ const cookieHeader = req.headers.get("cookie") ?? "";
319
+ const cookieMap = new Bun.CookieMap(cookieHeader);
320
+ return validateSchema(cookiesSchema, Object.fromEntries(cookieMap));
321
+ };
322
+ const validateParams = async (req, paramsSchema) => {
323
+ if (!paramsSchema) return true;
324
+ return validateSchema(paramsSchema, req.params);
325
+ };
326
+ //#endregion
327
+ //#region src/lib/api/core/index.ts
328
+ const defaultValidated = Object.freeze({
329
+ body: void 0,
330
+ query: void 0,
331
+ headers: void 0,
332
+ cookies: void 0,
333
+ params: void 0
334
+ });
335
+ const responseHelpers = {
336
+ json: (status, data) => Response.json(data, { status }),
337
+ text: (status, text) => new Response(text, { status }),
338
+ html: (status, html) => new Response(html, {
339
+ status,
340
+ headers: { "Content-Type": "text/html" }
341
+ }),
342
+ redirect: (status, url) => Response.redirect(url, status)
343
+ };
344
+ const noopGet = () => void 0;
345
+ const stripTrailingSlash = (path) => {
346
+ if (path !== "/" && path.endsWith("/")) return path.slice(0, -1);
347
+ return path;
348
+ };
349
+ const hasSchemas = (schema) => schema && (schema.body || schema.query || schema.headers || schema.cookies || schema.params);
350
+ const needsBodyCache = (schema) => schema?.body !== void 0;
351
+ const shouldCreateBodyCache = (hasMiddlewares, allMiddlewares, request) => {
352
+ if (needsBodyCache(request)) return true;
353
+ if (!hasMiddlewares) return false;
354
+ return allMiddlewares.some((mw) => needsBodyCache(mw.options.request));
355
+ };
356
+ const resolveValidation = (v) => {
357
+ if (v === void 0 || v === true) return {
358
+ input: true,
359
+ output: true
360
+ };
361
+ if (v === false) return {
362
+ input: false,
363
+ output: false
364
+ };
365
+ return {
366
+ input: v.input !== false,
367
+ output: v.output !== false
368
+ };
369
+ };
370
+ var Api = class {
371
+ options;
372
+ routes = [];
373
+ constructor(options = {}) {
374
+ this.options = options;
375
+ }
376
+ getFullPath(path) {
377
+ const normalizedPath = stripTrailingSlash(path) || "/";
378
+ if (!this.options.prefix) return normalizedPath;
379
+ const normalizedPrefix = stripTrailingSlash(this.options.prefix);
380
+ if (normalizedPrefix === "/") return normalizedPath;
381
+ if (normalizedPath === "/") return normalizedPrefix;
382
+ return normalizedPrefix + normalizedPath;
383
+ }
384
+ async validateRequestSchema(req, schema, bodyCache) {
385
+ if (!schema) return {
386
+ success: true,
387
+ data: {}
388
+ };
389
+ const v = {};
390
+ if (schema.body) {
391
+ const [err, val] = await require_lib_errors_index.mightThrow(validateBody(req, schema.body, bodyCache));
392
+ if (err) return {
393
+ success: false,
394
+ error: err
395
+ };
396
+ v.body = val;
397
+ }
398
+ if (schema.query) {
399
+ const [err, val] = await require_lib_errors_index.mightThrow(validateQuery(req, schema.query));
400
+ if (err) return {
401
+ success: false,
402
+ error: err
403
+ };
404
+ v.query = val;
405
+ }
406
+ if (schema.headers) {
407
+ const [err, val] = await require_lib_errors_index.mightThrow(validateHeaders(req, schema.headers));
408
+ if (err) return {
409
+ success: false,
410
+ error: err
411
+ };
412
+ v.headers = val;
413
+ }
414
+ if (schema.cookies) {
415
+ const [err, val] = await require_lib_errors_index.mightThrow(validateCookies(req, schema.cookies));
416
+ if (err) return {
417
+ success: false,
418
+ error: err
419
+ };
420
+ v.cookies = val;
421
+ }
422
+ if (schema.params) {
423
+ const [err, val] = await require_lib_errors_index.mightThrow(validateParams(req, schema.params));
424
+ if (err) return {
425
+ success: false,
426
+ error: err
427
+ };
428
+ v.params = val;
429
+ }
430
+ return {
431
+ success: true,
432
+ data: v
433
+ };
434
+ }
435
+ createContext(req, validated, extensions) {
436
+ return {
437
+ raw: req,
438
+ req: validated,
439
+ ...responseHelpers,
440
+ get: (key) => extensions[key]
441
+ };
442
+ }
443
+ async validateResponseBody(response, schema) {
444
+ if (!schema) return response;
445
+ const statusSchema = schema[response.status];
446
+ if (!statusSchema) return response;
447
+ if (!(response.headers.get("content-type") ?? "").includes("application/json")) return response;
448
+ const [parseError, body] = await require_lib_errors_index.mightThrow(response.clone().json());
449
+ if (parseError) return responseHelpers.json(400, { message: "Invalid response body" });
450
+ const [validationError] = await require_lib_errors_index.mightThrow(validateSchema(statusSchema, body));
451
+ if (validationError) return responseHelpers.json(400, { message: validationError.message });
452
+ return response;
453
+ }
454
+ buildBunRoutes() {
455
+ const bunRoutes = {};
456
+ const validationConfig = resolveValidation(this.options.validation);
457
+ for (const route of this.routes) {
458
+ const { path, method, handler, request, response, middlewares } = route;
459
+ const fullPath = this.getFullPath(path);
460
+ if (!bunRoutes[fullPath]) bunRoutes[fullPath] = {};
461
+ const allMiddlewares = [...this.options.middlewares ?? [], ...middlewares ?? []];
462
+ const hasMiddlewares = allMiddlewares.length > 0;
463
+ const hasRouteSchemas = hasSchemas(request);
464
+ const effectiveOutputValidation = validationConfig.output && !!response;
465
+ if (!hasMiddlewares && !(validationConfig.input && hasRouteSchemas) && !effectiveOutputValidation) bunRoutes[fullPath][method] = (req) => {
466
+ const context = Object.create(responseHelpers);
467
+ context.raw = req;
468
+ context.req = defaultValidated;
469
+ context.get = noopGet;
470
+ return handler(context);
471
+ };
472
+ else bunRoutes[fullPath][method] = async (req) => {
473
+ const extensions = {};
474
+ const bodyCache = validationConfig.input && shouldCreateBodyCache(hasMiddlewares, allMiddlewares, request) ? {
475
+ parsed: false,
476
+ value: void 0
477
+ } : void 0;
478
+ for (const mw of allMiddlewares) {
479
+ const { request: reqSchema, handler: mwHandler } = mw.options;
480
+ let validated = defaultValidated;
481
+ if (validationConfig.input && hasSchemas(reqSchema)) {
482
+ const result = await this.validateRequestSchema(req, reqSchema, bodyCache);
483
+ if (!result.success) return responseHelpers.json(400, { message: result.error?.message });
484
+ validated = result.data;
485
+ }
486
+ const mwResult = await mwHandler(this.createContext(req, validated, extensions));
487
+ if (mwResult instanceof Response) return mwResult;
488
+ if (mwResult) Object.assign(extensions, mwResult);
489
+ }
490
+ let routeValidated = defaultValidated;
491
+ if (validationConfig.input && hasRouteSchemas) {
492
+ const result = await this.validateRequestSchema(req, request, bodyCache);
493
+ if (!result.success) return responseHelpers.json(400, { message: result.error?.message });
494
+ routeValidated = result.data;
495
+ }
496
+ const handlerResponse = await handler(this.createContext(req, routeValidated, extensions));
497
+ if (effectiveOutputValidation) return this.validateResponseBody(handlerResponse, response);
498
+ return handlerResponse;
499
+ };
500
+ }
501
+ return bunRoutes;
502
+ }
503
+ defineRoute(config) {
504
+ this.routes.push(config);
505
+ }
506
+ getOpenApiSpec() {
507
+ return generateOpenApiSpec({
508
+ title: this.options.openapi?.title ?? "API",
509
+ description: this.options.openapi?.description,
510
+ version: this.options.openapi?.version ?? "1.0.0",
511
+ prefix: this.options.prefix,
512
+ servers: this.options.openapi?.servers,
513
+ securitySchemes: this.options.openapi?.securitySchemes,
514
+ routes: this.routes,
515
+ globalMiddlewares: this.options.middlewares
516
+ });
517
+ }
518
+ serve(port, callback) {
519
+ const bunRoutes = this.buildBunRoutes();
520
+ const server = Bun.serve({
521
+ port,
522
+ routes: bunRoutes,
523
+ fetch: () => new Response("Not found", { status: 404 })
524
+ });
525
+ if (callback) callback(server);
526
+ }
527
+ };
528
+ //#endregion
529
+ //#region src/lib/api/middleware/index.ts
530
+ var Middleware = class {
531
+ constructor(options) {
532
+ this.options = options;
533
+ }
534
+ };
535
+ //#endregion
536
+ exports.Api = Api;
537
+ exports.Middleware = Middleware;