create-nexwire 4.2.5 → 4.4.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 (399) hide show
  1. package/README.md +29 -12
  2. package/express/.env +1 -1
  3. package/express/package.json +1 -1
  4. package/express/src/config/database.ts +48 -29
  5. package/express/src/config/index.ts +83 -83
  6. package/express/src/config/openapi.ts +6 -24
  7. package/express/src/config/queue.ts +30 -30
  8. package/express/src/config/validate.ts +50 -40
  9. package/express/src/database/migrations/sqlite/0000_init.sql +47 -47
  10. package/express/src/database/migrations/sqlite/meta/0000_snapshot.json +1 -1
  11. package/express/src/database/migrations/sqlite/meta/_journal.json +1 -1
  12. package/express/src/framework/cache/cache.ts +40 -8
  13. package/express/src/framework/circuit-breaker/cb.ts +88 -60
  14. package/express/src/framework/database/connection.ts +52 -27
  15. package/express/src/framework/events/dispatcher.ts +61 -49
  16. package/express/src/framework/facade.ts +47 -3
  17. package/express/src/framework/http/app.ts +28 -22
  18. package/express/src/framework/http/logger.ts +37 -17
  19. package/express/src/framework/http/openapi.ts +9 -11
  20. package/express/src/framework/maker-cli/runtime/core.mjs +1 -2
  21. package/express/src/framework/modules/routes.ts +26 -21
  22. package/express/src/framework/notification/channels/broadcast.ts +15 -0
  23. package/express/src/framework/notification/channels/mail.ts +42 -0
  24. package/express/src/framework/notification/contracts.ts +29 -0
  25. package/express/src/framework/notification/index.ts +19 -94
  26. package/express/src/framework/notification/registry.ts +15 -0
  27. package/express/src/framework/providers/adapter.ts +27 -17
  28. package/express/src/framework/queue/queue.ts +43 -44
  29. package/express/src/framework/realtime/broadcast.ts +29 -5
  30. package/express/src/framework/realtime/socket.ts +149 -119
  31. package/express/src/framework/redis/client.ts +148 -151
  32. package/express/src/framework/runtime/server-adapter.ts +39 -34
  33. package/express/src/framework/scheduler/lock.ts +128 -116
  34. package/express/src/framework/server.ts +33 -49
  35. package/express/src/framework/session/session.ts +69 -14
  36. package/express/src/framework/storage/storage.ts +744 -785
  37. package/express/src/framework/support/mail.ts +15 -7
  38. package/express/src/middlewares/auth-middleware.ts +1 -2
  39. package/express/src/middlewares/role-middleware.ts +3 -13
  40. package/express/src/modules/auth/routes/index.ts +1 -2
  41. package/express/src/providers/notification.ts +4 -0
  42. package/express/src/resources/src/components/Switch.vue +60 -65
  43. package/express/src/resources/src/layouts/Layout/Header.vue +124 -105
  44. package/express/src/resources/src/pages/auth/forgetPassword.vue +23 -30
  45. package/express/src/resources/src/pages/auth/login.vue +25 -28
  46. package/express/src/resources/src/pages/auth/register.vue +35 -39
  47. package/express/src/resources/src/pages/auth/resetPassword.vue +29 -37
  48. package/express/src/resources/src/pages/auth/verifyEmail.vue +15 -19
  49. package/express/src/resources/src/plugins/gum.ts +519 -203
  50. package/express/src/resources/src/plugins/pulse.ts +157 -147
  51. package/express/src/resources/src/stores/auth.ts +9 -6
  52. package/express/src/resources/vite.config.ts +54 -43
  53. package/express/src/storage/database/nexwire.sqlite +0 -0
  54. package/express/src/storage/logs/app.log +0 -0
  55. package/express/src/storage/logs/fatal.log +0 -0
  56. package/express/src/types/global.d.ts +32 -26
  57. package/fastify/.dockerignore +14 -0
  58. package/fastify/.env +44 -0
  59. package/fastify/.env.example +42 -0
  60. package/fastify/.vscode/extensions.json +6 -0
  61. package/fastify/.vscode/settings.json +37 -0
  62. package/fastify/LICENSE +21 -0
  63. package/fastify/README.md +232 -0
  64. package/fastify/biome.json +99 -0
  65. package/fastify/drizzle.config.ts +25 -0
  66. package/fastify/gitignore-stub +31 -0
  67. package/fastify/package.json +130 -0
  68. package/fastify/public/.gitkeep +0 -0
  69. package/fastify/src/config/app.ts +41 -0
  70. package/fastify/src/config/auth.ts +12 -0
  71. package/fastify/src/config/cache.ts +16 -0
  72. package/fastify/src/config/cookie.ts +15 -0
  73. package/fastify/src/config/cors.ts +12 -0
  74. package/fastify/src/config/database.ts +48 -0
  75. package/fastify/src/config/index.ts +83 -0
  76. package/fastify/src/config/jwt.ts +19 -0
  77. package/fastify/src/config/logging.ts +13 -0
  78. package/fastify/src/config/mail.ts +24 -0
  79. package/fastify/src/config/openapi.ts +36 -0
  80. package/fastify/src/config/queue.ts +30 -0
  81. package/fastify/src/config/rateLimit.ts +17 -0
  82. package/fastify/src/config/realtime.ts +15 -0
  83. package/fastify/src/config/redis.ts +18 -0
  84. package/fastify/src/config/security.ts +44 -0
  85. package/fastify/src/config/session.ts +17 -0
  86. package/fastify/src/config/storage.ts +22 -0
  87. package/fastify/src/config/validate.ts +50 -0
  88. package/fastify/src/database/migrations/sqlite/0000_init.sql +48 -0
  89. package/fastify/src/database/migrations/sqlite/meta/0000_snapshot.json +324 -0
  90. package/fastify/src/database/migrations/sqlite/meta/_journal.json +13 -0
  91. package/fastify/src/database/schema.ts +2 -0
  92. package/fastify/src/env.ts +76 -0
  93. package/fastify/src/framework/cache/cache.ts +114 -0
  94. package/fastify/src/framework/circuit-breaker/cb.ts +88 -0
  95. package/fastify/src/framework/database/app-schema.ts +37 -0
  96. package/fastify/src/framework/database/connection.ts +223 -0
  97. package/fastify/src/framework/database/migrate-hooks.ts +87 -0
  98. package/fastify/src/framework/database/paginate.ts +226 -0
  99. package/fastify/src/framework/database/schema.ts +20 -0
  100. package/fastify/src/framework/database/seed.ts +152 -0
  101. package/fastify/src/framework/events/dispatcher.ts +61 -0
  102. package/fastify/src/framework/facade.ts +96 -0
  103. package/fastify/src/framework/http/app.ts +176 -0
  104. package/fastify/src/framework/http/cors.ts +13 -0
  105. package/fastify/src/framework/http/fastify.d.ts +13 -0
  106. package/fastify/src/framework/http/logger.ts +110 -0
  107. package/fastify/src/framework/http/metrics.ts +22 -0
  108. package/fastify/src/framework/http/openapi.ts +48 -0
  109. package/fastify/src/framework/http/ratelimiter.ts +47 -0
  110. package/fastify/src/framework/http/security.ts +25 -0
  111. package/fastify/src/framework/http/static.ts +83 -0
  112. package/fastify/src/framework/http/validation.ts +49 -0
  113. package/fastify/src/framework/kernel.ts +43 -0
  114. package/fastify/src/framework/maker-cli/db/core.mjs +291 -0
  115. package/fastify/src/framework/maker-cli/db/index.mjs +204 -0
  116. package/fastify/src/framework/maker-cli/deploy/core.mjs +1046 -0
  117. package/fastify/src/framework/maker-cli/deploy/index.mjs +91 -0
  118. package/fastify/src/framework/maker-cli/index.mjs +65 -0
  119. package/fastify/src/framework/maker-cli/middleware/core.mjs +41 -0
  120. package/fastify/src/framework/maker-cli/middleware/index.mjs +17 -0
  121. package/fastify/src/framework/maker-cli/module/core.mjs +1066 -0
  122. package/fastify/src/framework/maker-cli/module/index.mjs +211 -0
  123. package/fastify/src/framework/maker-cli/provider/core.mjs +49 -0
  124. package/fastify/src/framework/maker-cli/provider/index.mjs +12 -0
  125. package/fastify/src/framework/maker-cli/runtime/build-ui.mjs +16 -0
  126. package/fastify/src/framework/maker-cli/runtime/core.mjs +560 -0
  127. package/fastify/src/framework/maker-cli/runtime/index.mjs +120 -0
  128. package/fastify/src/framework/maker-cli/runtime/redis-commander-patch.cjs +20 -0
  129. package/fastify/src/framework/maker-cli/stubs/controller/openapi.ts.stub +74 -0
  130. package/fastify/src/framework/maker-cli/stubs/controller/plain.ts.stub +77 -0
  131. package/fastify/src/framework/maker-cli/stubs/controller/standalone.ts.stub +51 -0
  132. package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.bun.stub +52 -0
  133. package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.pnpm.stub +55 -0
  134. package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.stub +51 -0
  135. package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.yarn.stub +55 -0
  136. package/fastify/src/framework/maker-cli/stubs/deploy/README.stub +59 -0
  137. package/fastify/src/framework/maker-cli/stubs/deploy/compose/mysql.server.stub +45 -0
  138. package/fastify/src/framework/maker-cli/stubs/deploy/compose/postgres.server.stub +45 -0
  139. package/fastify/src/framework/maker-cli/stubs/deploy/compose/sqlite.stub +45 -0
  140. package/fastify/src/framework/maker-cli/stubs/deploy/env/mysql.server.stub +68 -0
  141. package/fastify/src/framework/maker-cli/stubs/deploy/env/postgres.server.stub +68 -0
  142. package/fastify/src/framework/maker-cli/stubs/deploy/env/sqlite.stub +67 -0
  143. package/fastify/src/framework/maker-cli/stubs/deploy/scripts/auto-migrate.sh.stub +41 -0
  144. package/fastify/src/framework/maker-cli/stubs/deploy/server/README.stub +78 -0
  145. package/fastify/src/framework/maker-cli/stubs/deploy/server/compose/noredis.stub +120 -0
  146. package/fastify/src/framework/maker-cli/stubs/deploy/server/compose/redis.dev.stub +133 -0
  147. package/fastify/src/framework/maker-cli/stubs/deploy/server/compose/redis.stub +131 -0
  148. package/fastify/src/framework/maker-cli/stubs/deploy/server/env/local.example.stub +11 -0
  149. package/fastify/src/framework/maker-cli/stubs/deploy/server/env/noredis.stub +25 -0
  150. package/fastify/src/framework/maker-cli/stubs/deploy/server/env/redis.stub +25 -0
  151. package/fastify/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/README.stub +16 -0
  152. package/fastify/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/app.example.com.stub +13 -0
  153. package/fastify/src/framework/maker-cli/stubs/deploy/server/pgadmin/servers.stub +14 -0
  154. package/fastify/src/framework/maker-cli/stubs/deploy/server/redis/redis.conf.stub +7 -0
  155. package/fastify/src/framework/maker-cli/stubs/deploy/supervisor/noredis.stub +54 -0
  156. package/fastify/src/framework/maker-cli/stubs/deploy/supervisor/redis.stub +70 -0
  157. package/fastify/src/framework/maker-cli/stubs/deploy/workflow/local.json.stub +25 -0
  158. package/fastify/src/framework/maker-cli/stubs/deploy/workflow/remote.json.stub +24 -0
  159. package/fastify/src/framework/maker-cli/stubs/facade/name.ts.stub +12 -0
  160. package/fastify/src/framework/maker-cli/stubs/helper/name.ts.stub +14 -0
  161. package/fastify/src/framework/maker-cli/stubs/job/name.ts.stub +25 -0
  162. package/fastify/src/framework/maker-cli/stubs/middleware/name.local.ts.stub +15 -0
  163. package/fastify/src/framework/maker-cli/stubs/middleware/name.ts.stub +15 -0
  164. package/fastify/src/framework/maker-cli/stubs/model/name.mysql.ts.stub +10 -0
  165. package/fastify/src/framework/maker-cli/stubs/model/name.postgresql.ts.stub +10 -0
  166. package/fastify/src/framework/maker-cli/stubs/model/name.sqlite.ts.stub +10 -0
  167. package/fastify/src/framework/maker-cli/stubs/notification/controller.ts.stub +79 -0
  168. package/fastify/src/framework/maker-cli/stubs/notification/job.ts.stub +11 -0
  169. package/fastify/src/framework/maker-cli/stubs/notification/model.ts.stub +29 -0
  170. package/fastify/src/framework/maker-cli/stubs/notification/provider.ts.stub +174 -0
  171. package/fastify/src/framework/maker-cli/stubs/notification/route.api.ts.stub +71 -0
  172. package/fastify/src/framework/maker-cli/stubs/notification/route.plain.ts.stub +15 -0
  173. package/fastify/src/framework/maker-cli/stubs/notification/schema.plain.ts.stub +26 -0
  174. package/fastify/src/framework/maker-cli/stubs/notification/schema.ts.stub +26 -0
  175. package/fastify/src/framework/maker-cli/stubs/provider/module-barrel.ts.stub +19 -0
  176. package/fastify/src/framework/maker-cli/stubs/provider/module.ts.stub +21 -0
  177. package/fastify/src/framework/maker-cli/stubs/provider/name.ts.stub +21 -0
  178. package/fastify/src/framework/maker-cli/stubs/route/api.ts.stub +101 -0
  179. package/fastify/src/framework/maker-cli/stubs/route/plain.ts.stub +23 -0
  180. package/fastify/src/framework/maker-cli/stubs/route/standalone.api.ts.stub +120 -0
  181. package/fastify/src/framework/maker-cli/stubs/route/standalone.plain.ts.stub +50 -0
  182. package/fastify/src/framework/maker-cli/stubs/schedule/name.ts.stub +36 -0
  183. package/fastify/src/framework/maker-cli/stubs/schema/name.plain.ts.stub +14 -0
  184. package/fastify/src/framework/maker-cli/stubs/schema/name.ts.stub +33 -0
  185. package/fastify/src/framework/maker-cli/stubs/seeder/name.ts.stub +18 -0
  186. package/fastify/src/framework/maker-cli/stubs/seeder/standalone.ts.stub +22 -0
  187. package/fastify/src/framework/maker-cli/stubs/service/name.plain.ts.stub +67 -0
  188. package/fastify/src/framework/maker-cli/stubs/service/name.ts.stub +65 -0
  189. package/fastify/src/framework/maker-cli/stubs/test/unit.ts.stub +22 -0
  190. package/fastify/src/framework/maker-cli/stubs/type/name.ts.stub +22 -0
  191. package/fastify/src/framework/maker-cli/utils/env-config.mjs +44 -0
  192. package/fastify/src/framework/maker-cli/utils/env-db.mjs +61 -0
  193. package/fastify/src/framework/maker-cli/utils/file-ops.mjs +30 -0
  194. package/fastify/src/framework/maker-cli/utils/flags.mjs +14 -0
  195. package/fastify/src/framework/maker-cli/utils/help.mjs +379 -0
  196. package/fastify/src/framework/maker-cli/utils/naming.mjs +119 -0
  197. package/fastify/src/framework/maker-cli/utils/process.mjs +52 -0
  198. package/fastify/src/framework/maker-cli/utils/project-commands.mjs +201 -0
  199. package/fastify/src/framework/modules/discover.ts +57 -0
  200. package/fastify/src/framework/modules/routes.ts +31 -0
  201. package/fastify/src/framework/notification/channels/broadcast.ts +15 -0
  202. package/fastify/src/framework/notification/channels/mail.ts +42 -0
  203. package/fastify/src/framework/notification/contracts.ts +29 -0
  204. package/fastify/src/framework/notification/index.ts +59 -0
  205. package/fastify/src/framework/notification/registry.ts +15 -0
  206. package/fastify/src/framework/providers/adapter.ts +149 -0
  207. package/fastify/src/framework/providers/contracts.ts +126 -0
  208. package/fastify/src/framework/providers/loader.ts +105 -0
  209. package/fastify/src/framework/providers/registry.ts +88 -0
  210. package/fastify/src/framework/queue/clear.ts +22 -0
  211. package/fastify/src/framework/queue/queue.ts +401 -0
  212. package/fastify/src/framework/queue/ui.ts +194 -0
  213. package/fastify/src/framework/queue/worker.ts +61 -0
  214. package/fastify/src/framework/realtime/broadcast.ts +70 -0
  215. package/fastify/src/framework/realtime/index.ts +2 -0
  216. package/fastify/src/framework/realtime/socket-cookie.ts +72 -0
  217. package/fastify/src/framework/realtime/socket.ts +149 -0
  218. package/fastify/src/framework/realtime/types.ts +6 -0
  219. package/fastify/src/framework/realtime/ui.ts +16 -0
  220. package/fastify/src/framework/redis/client.ts +148 -0
  221. package/fastify/src/framework/runtime/runtime.ts +23 -0
  222. package/fastify/src/framework/runtime/server-adapter.ts +33 -0
  223. package/fastify/src/framework/scheduler/lock.ts +128 -0
  224. package/fastify/src/framework/scheduler/run.ts +48 -0
  225. package/fastify/src/framework/scheduler/scheduler.ts +155 -0
  226. package/fastify/src/framework/server.ts +162 -0
  227. package/fastify/src/framework/session/session.ts +160 -0
  228. package/fastify/src/framework/storage/storage.ts +744 -0
  229. package/fastify/src/framework/support/cookie.ts +71 -0
  230. package/fastify/src/framework/support/jwt.ts +33 -0
  231. package/fastify/src/framework/support/lifecycle.ts +35 -0
  232. package/fastify/src/framework/support/logger.ts +148 -0
  233. package/fastify/src/framework/support/mail.ts +56 -0
  234. package/fastify/src/framework/support/password.ts +23 -0
  235. package/fastify/src/framework/support/status-codes.ts +75 -0
  236. package/fastify/src/framework/support/upload.ts +181 -0
  237. package/fastify/src/framework/support/url.ts +41 -0
  238. package/fastify/src/middlewares/auth-middleware.ts +134 -0
  239. package/fastify/src/middlewares/role-middleware.ts +19 -0
  240. package/fastify/src/modules/auth/__tests__/forgetpass.test.ts +200 -0
  241. package/fastify/src/modules/auth/__tests__/login.test.ts +171 -0
  242. package/fastify/src/modules/auth/__tests__/logout.test.ts +60 -0
  243. package/fastify/src/modules/auth/__tests__/logoutalldevices.test.ts +49 -0
  244. package/fastify/src/modules/auth/__tests__/me.test.ts +91 -0
  245. package/fastify/src/modules/auth/__tests__/refreshtoken.test.ts +305 -0
  246. package/fastify/src/modules/auth/__tests__/register.test.ts +291 -0
  247. package/fastify/src/modules/auth/__tests__/resetpass.test.ts +206 -0
  248. package/fastify/src/modules/auth/__tests__/verifyemail.test.ts +183 -0
  249. package/fastify/src/modules/auth/controllers/auth.ts +252 -0
  250. package/fastify/src/modules/auth/controllers/role.ts +35 -0
  251. package/fastify/src/modules/auth/database/models/role.ts +14 -0
  252. package/fastify/src/modules/auth/database/models/user.ts +46 -0
  253. package/fastify/src/modules/auth/database/seeders/role.ts +18 -0
  254. package/fastify/src/modules/auth/database/seeders/user.ts +35 -0
  255. package/fastify/src/modules/auth/facade.ts +12 -0
  256. package/fastify/src/modules/auth/helpers/auth.ts +115 -0
  257. package/fastify/src/modules/auth/jobs/forgetpass.ts +20 -0
  258. package/fastify/src/modules/auth/jobs/registeruser.ts +23 -0
  259. package/fastify/src/modules/auth/jobs/verifyemail.ts +18 -0
  260. package/fastify/src/modules/auth/routes/index.ts +185 -0
  261. package/fastify/src/modules/auth/routes/role.ts +56 -0
  262. package/fastify/src/modules/auth/schemas/auth.ts +116 -0
  263. package/fastify/src/modules/auth/services/forgetpassword.ts +66 -0
  264. package/fastify/src/modules/auth/services/login.ts +63 -0
  265. package/fastify/src/modules/auth/services/logout.ts +25 -0
  266. package/fastify/src/modules/auth/services/logoutalldevices.ts +19 -0
  267. package/fastify/src/modules/auth/services/me.ts +31 -0
  268. package/fastify/src/modules/auth/services/refreshtoken.ts +110 -0
  269. package/fastify/src/modules/auth/services/register.ts +141 -0
  270. package/fastify/src/modules/auth/services/resetpassword.ts +69 -0
  271. package/fastify/src/modules/auth/services/verifyemail.ts +77 -0
  272. package/fastify/src/modules/auth/types/auth.ts +31 -0
  273. package/fastify/src/providers/README.md +107 -0
  274. package/fastify/src/providers/notification.ts +4 -0
  275. package/fastify/src/resources/index.html +17 -0
  276. package/fastify/src/resources/src/App.vue +5 -0
  277. package/fastify/src/resources/src/assets/css/styles.css +14761 -0
  278. package/fastify/src/resources/src/assets/css/styles.css.map +1 -0
  279. package/fastify/src/resources/src/assets/fonts/public-sans/public-sans-latin-ext.woff2 +0 -0
  280. package/fastify/src/resources/src/assets/fonts/public-sans/public-sans-latin.woff2 +0 -0
  281. package/fastify/src/resources/src/assets/images/favicon/favicon.ico +0 -0
  282. package/fastify/src/resources/src/assets/images/logo.png +0 -0
  283. package/fastify/src/resources/src/assets/scss/custom.css +217 -0
  284. package/fastify/src/resources/src/assets/scss/custom.css.map +1 -0
  285. package/fastify/src/resources/src/assets/scss/custom.scss +1346 -0
  286. package/fastify/src/resources/src/components/Button.vue +32 -0
  287. package/fastify/src/resources/src/components/Checkbox.vue +32 -0
  288. package/fastify/src/resources/src/components/Datepicker.vue +106 -0
  289. package/fastify/src/resources/src/components/FeatureButton.vue +53 -0
  290. package/fastify/src/resources/src/components/FloatButton.vue +33 -0
  291. package/fastify/src/resources/src/components/Href.vue +32 -0
  292. package/fastify/src/resources/src/components/Input.vue +243 -0
  293. package/fastify/src/resources/src/components/InputGroup.vue +147 -0
  294. package/fastify/src/resources/src/components/InputPasswordToggle.vue +229 -0
  295. package/fastify/src/resources/src/components/Modal.vue +71 -0
  296. package/fastify/src/resources/src/components/Pagebar.vue +26 -0
  297. package/fastify/src/resources/src/components/Refresh.vue +19 -0
  298. package/fastify/src/resources/src/components/Select.vue +384 -0
  299. package/fastify/src/resources/src/components/Spinner.vue +42 -0
  300. package/fastify/src/resources/src/components/Switch.vue +60 -0
  301. package/fastify/src/resources/src/components/TextArea.vue +117 -0
  302. package/fastify/src/resources/src/components/Toast.vue +56 -0
  303. package/fastify/src/resources/src/components/datatable/DataTableSkeleton.vue +98 -0
  304. package/fastify/src/resources/src/components/datatable/Pagination.vue +147 -0
  305. package/fastify/src/resources/src/components/datatable/SelectOpption.vue +64 -0
  306. package/fastify/src/resources/src/components/datatable/index.vue +199 -0
  307. package/fastify/src/resources/src/composables/useAuth.ts +52 -0
  308. package/fastify/src/resources/src/helpers/assets.ts +51 -0
  309. package/fastify/src/resources/src/helpers/nformatter.ts +10 -0
  310. package/fastify/src/resources/src/helpers/utils.ts +75 -0
  311. package/fastify/src/resources/src/layouts/AuthLayout.vue +20 -0
  312. package/fastify/src/resources/src/layouts/Layout/Footer.vue +23 -0
  313. package/fastify/src/resources/src/layouts/Layout/Header.vue +124 -0
  314. package/fastify/src/resources/src/layouts/Layout/Sidebar.vue +137 -0
  315. package/fastify/src/resources/src/layouts/Layout/index.vue +87 -0
  316. package/fastify/src/resources/src/main.ts +28 -0
  317. package/fastify/src/resources/src/pages/auth/forgetPassword.vue +76 -0
  318. package/fastify/src/resources/src/pages/auth/login.vue +96 -0
  319. package/fastify/src/resources/src/pages/auth/register.vue +129 -0
  320. package/fastify/src/resources/src/pages/auth/resetPassword.vue +110 -0
  321. package/fastify/src/resources/src/pages/auth/verifyEmail.vue +64 -0
  322. package/fastify/src/resources/src/pages/dashboard/index.vue +66 -0
  323. package/fastify/src/resources/src/plugins/axios.ts +31 -0
  324. package/fastify/src/resources/src/plugins/browserDetect.ts +55 -0
  325. package/fastify/src/resources/src/plugins/dialog.ts +216 -0
  326. package/fastify/src/resources/src/plugins/gum.ts +683 -0
  327. package/fastify/src/resources/src/plugins/pulse.ts +157 -0
  328. package/fastify/src/resources/src/plugins/routeProgress.ts +87 -0
  329. package/fastify/src/resources/src/router/index.ts +85 -0
  330. package/fastify/src/resources/src/stores/admin-ui.ts +148 -0
  331. package/fastify/src/resources/src/stores/auth.ts +187 -0
  332. package/fastify/src/resources/tsconfig.json +19 -0
  333. package/fastify/src/resources/vite.config.ts +64 -0
  334. package/fastify/src/storage/app/private/.gitkeep +0 -0
  335. package/fastify/src/storage/app/public/.gitkeep +0 -0
  336. package/fastify/src/storage/app/tmp/generated/.gitkeep +0 -0
  337. package/fastify/src/storage/database/nexwire.sqlite +0 -0
  338. package/fastify/src/storage/logs/.gitkeep +0 -0
  339. package/fastify/src/storage/logs/app.log +0 -0
  340. package/fastify/src/storage/logs/fatal.log +0 -0
  341. package/fastify/src/storage/tmp/.gitkeep +0 -0
  342. package/fastify/src/storage/trash/modules/.gitkeep +0 -0
  343. package/fastify/src/types/global.d.ts +32 -0
  344. package/fastify/tsconfig.json +19 -0
  345. package/fastify/vitest.config.ts +38 -0
  346. package/hono/.env +1 -1
  347. package/hono/package.json +1 -1
  348. package/hono/src/config/database.ts +48 -29
  349. package/hono/src/config/index.ts +83 -83
  350. package/hono/src/config/openapi.ts +6 -24
  351. package/hono/src/config/queue.ts +30 -30
  352. package/hono/src/config/validate.ts +50 -40
  353. package/hono/src/database/migrations/sqlite/0000_init.sql +47 -47
  354. package/hono/src/database/migrations/sqlite/meta/0000_snapshot.json +1 -1
  355. package/hono/src/database/migrations/sqlite/meta/_journal.json +1 -1
  356. package/hono/src/framework/cache/cache.ts +40 -8
  357. package/hono/src/framework/circuit-breaker/cb.ts +88 -60
  358. package/hono/src/framework/database/connection.ts +52 -27
  359. package/hono/src/framework/events/dispatcher.ts +61 -49
  360. package/hono/src/framework/facade.ts +39 -1
  361. package/hono/src/framework/http/logger.ts +86 -81
  362. package/hono/src/framework/http/openapi.ts +7 -9
  363. package/hono/src/framework/maker-cli/runtime/core.mjs +1 -2
  364. package/hono/src/framework/notification/channels/broadcast.ts +15 -0
  365. package/hono/src/framework/notification/channels/mail.ts +42 -0
  366. package/hono/src/framework/notification/contracts.ts +29 -0
  367. package/hono/src/framework/notification/index.ts +19 -94
  368. package/hono/src/framework/notification/registry.ts +15 -0
  369. package/hono/src/framework/providers/adapter.ts +27 -17
  370. package/hono/src/framework/queue/queue.ts +43 -44
  371. package/hono/src/framework/realtime/broadcast.ts +29 -5
  372. package/hono/src/framework/realtime/socket.ts +217 -196
  373. package/hono/src/framework/redis/client.ts +148 -151
  374. package/hono/src/framework/scheduler/lock.ts +128 -116
  375. package/hono/src/framework/server.ts +27 -29
  376. package/hono/src/framework/session/session.ts +62 -14
  377. package/hono/src/framework/storage/storage.ts +744 -785
  378. package/hono/src/framework/support/mail.ts +56 -48
  379. package/hono/src/middlewares/auth-middleware.ts +1 -2
  380. package/hono/src/middlewares/role-middleware.ts +3 -13
  381. package/hono/src/modules/auth/routes/index.ts +1 -2
  382. package/hono/src/providers/notification.ts +4 -0
  383. package/hono/src/resources/src/components/Switch.vue +60 -65
  384. package/hono/src/resources/src/layouts/Layout/Header.vue +124 -105
  385. package/hono/src/resources/src/pages/auth/forgetPassword.vue +23 -29
  386. package/hono/src/resources/src/pages/auth/login.vue +26 -29
  387. package/hono/src/resources/src/pages/auth/register.vue +36 -40
  388. package/hono/src/resources/src/pages/auth/resetPassword.vue +29 -37
  389. package/hono/src/resources/src/pages/auth/verifyEmail.vue +15 -19
  390. package/hono/src/resources/src/plugins/gum.ts +519 -203
  391. package/hono/src/resources/src/plugins/pulse.ts +157 -147
  392. package/hono/src/resources/src/stores/auth.ts +9 -6
  393. package/hono/src/resources/vite.config.ts +54 -43
  394. package/hono/src/storage/database/nexwire.sqlite +0 -0
  395. package/hono/src/storage/logs/app.log +0 -0
  396. package/hono/src/storage/logs/fatal.log +0 -0
  397. package/hono/src/types/global.d.ts +32 -26
  398. package/package.json +4 -3
  399. package/src/index.js +143 -15
package/README.md CHANGED
@@ -27,29 +27,45 @@ nexwire ships that stack **already connected**. Auth reads the database. Enqueue
27
27
 
28
28
  ## Quick Start
29
29
 
30
- ### Hono (default)
30
+ ### Choose a backend
31
+
32
+ The CLI asks which backend to scaffold when you don't pass `--engine`:
31
33
 
32
34
  ```bash
33
35
  npm create nexwire@latest my-app
34
- cd my-app
35
- npm install
36
- npm run maker dev
37
36
  ```
38
37
 
39
- ### Express
38
+ ```
39
+ Choose a backend:
40
+ ❯ Hono Hono-based HTTP layer and OpenAPI
41
+ Express Express-based HTTP layer and OpenAPI
42
+ Fastify Fastify-based HTTP layer and OpenAPI
43
+ ```
44
+
45
+ Arrow keys to move, `1`/`2`/`3` to jump, Enter to confirm. Press Enter to accept the default (**Hono**). Point at a specific one and the prompt is skipped:
40
46
 
41
47
  ```bash
48
+ # Hono (default)
49
+ npm create nexwire@latest my-app
50
+
51
+ # Express
42
52
  npm create nexwire@latest my-app -- --engine=express
43
- cd my-app
44
- npm install
45
- npm run maker dev
53
+
54
+ # Fastify
55
+ npm create nexwire@latest my-app -- --engine=fastify
56
+ ```
57
+
58
+ For CI or scripts, `-y` / `--yes` skips every prompt and accepts the defaults (a project name is still required):
59
+
60
+ ```bash
61
+ npm create nexwire@latest my-app -- --yes
46
62
  ```
47
63
 
48
64
  Your API is live at `http://localhost:3000`, Scalar docs at `/api-docs`, and the Vue frontend at `http://localhost:5173`.
49
65
 
50
66
  The scaffold already ships a pre-migrated, pre-seeded SQLite database, so there is no migration step before `maker dev`. If you point `DATABASE_URL` at MySQL or PostgreSQL, run `npm run maker db:migrate -- --seed` once to build and populate that database instead.
51
67
 
52
- Requires **Node.js >= 22** or **Bun >= 1.3**.
68
+ Requires **Node.js >= 22**. Hono and Express also support **Bun >= 1.3**; Fastify is Node-only.
53
69
 
54
70
  ### Current directory
55
71
 
@@ -58,6 +74,7 @@ Scaffold directly into the current directory:
58
74
  ```bash
59
75
  npm create nexwire@latest .
60
76
  npm create nexwire@latest . -- --engine=express
77
+ npm create nexwire@latest . -- --engine=fastify
61
78
  ```
62
79
 
63
80
  Works with any package manager: `pnpm`, `yarn`, or `bun`.
@@ -80,8 +97,8 @@ nexwire runs on **Node.js** or **Bun** — pick whichever fits your deployment:
80
97
 
81
98
  | Runtime | Minimum version | Notes |
82
99
  | ----------- | --------------- | --------------------------------------------------------------------- |
83
- | **Node.js** | `>= 22` | Default. Uses `node` in Dockerfile. |
84
- | **Bun** | `>= 1.3` | Pass `--runtime=bun` to `deploy:init`. Uses `oven/bun` in Dockerfile. |
100
+ | **Node.js** | `>= 22` | Default. Uses `node` in Dockerfile. Required by Fastify. |
101
+ | **Bun** | `>= 1.3` | Hono and Express only. Pass `--runtime=bun` to deploy:init. |
85
102
 
86
103
  ## Demo
87
104
 
@@ -103,7 +120,7 @@ Real recordings from a freshly scaffolded project — no mockups, no staging dat
103
120
 
104
121
  | Category | What you get |
105
122
  | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
106
- | **API** | Hono/Express HTTP server with Zod validation, OpenAPI/Scalar docs, CORS, rate limiting |
123
+ | **API** | Hono/Express/Fastify HTTP server with Zod validation, OpenAPI/Scalar docs, CORS, rate limiting |
107
124
  | **Database** | Drizzle ORM — SQLite by default, shipped pre-migrated and seeded; MySQL/PostgreSQL also supported, dialect auto-detected from `DATABASE_URL`. |
108
125
  | **Auth** | JWT access + refresh token rotation, signed httpOnly cookies, role middleware |
109
126
  | **Queue** | BullMQ background jobs with `shouldQueue` decorator and Bull Board dashboard |
package/express/.env CHANGED
@@ -37,7 +37,7 @@ UI=true
37
37
  # Set true to enable OpenAPI / Scalar docs at /api-docs
38
38
  OPEN_API=true
39
39
  # Set false to disable Socket.IO realtime server
40
- SOCKET=true
40
+ SOCKET=false
41
41
  # Set false to disable browser security headers (CSP, HSTS, X-Frame)
42
42
  SECURITY_HEADERS=true
43
43
 
@@ -65,7 +65,7 @@
65
65
  "jsonwebtoken": "^9.0.2",
66
66
  "lodash-es": "^4.18.1",
67
67
  "luxon": "^3.7.2",
68
- "maildev": "^3.0.0",
68
+ "maildev": "^2.2.1",
69
69
  "morgan": "^1.10.0",
70
70
  "multer": "^2.5.0",
71
71
  "mysql2": "^3.23.3",
@@ -1,29 +1,48 @@
1
- import { env } from "@/env.js";
2
-
3
- /**
4
- * Why: Database connection settings for Drizzle.
5
- * When: Database bootstrap and dialect detection.
6
- * Where: src/config/database.ts.
7
- * How: The connection URL contains credentials, so it stays in .env
8
- * (`DATABASE_URL`). Dialect is derived from the URL prefix.
9
- */
10
- export const databaseConfig = {
11
- url: env.DATABASE_URL
12
- };
13
-
14
- export type DatabaseConfig = typeof databaseConfig;
15
-
16
- /**
17
- * Why: Maps a connection URL to its Drizzle dialect.
18
- * When: Selecting the pool driver and dialect-specific branching.
19
- * Where: Framework database connection helpers.
20
- * How: Matches the URL prefix; anything that isn't mysql/postgres is sqlite.
21
- */
22
- export function detectDialectFrom(url: string): "sqlite" | "mysql" | "postgresql" {
23
- const value = url.toLowerCase();
24
- if (value.startsWith("mysql")) return "mysql";
25
- if (value.startsWith("postgres")) return "postgresql";
26
- return "sqlite";
27
- }
28
-
29
- export const databaseDialect = detectDialectFrom(databaseConfig.url);
1
+ import { env } from "@/env.js";
2
+
3
+ /**
4
+ * Why: Database connection settings.
5
+ * When: Database bootstrap and dialect detection.
6
+ * Where: src/config/database.ts.
7
+ * How: Only DATABASE_URL is required. Pool settings use generic,
8
+ * provider-agnostic defaults.
9
+ */
10
+
11
+ const rawUrl = env.DATABASE_URL;
12
+
13
+ export const databaseConfig = {
14
+ // If it's sqlite, convert "sqlite:./db.sqlite" to "file:./db.sqlite"
15
+ url: rawUrl.startsWith("sqlite:") ? `file:${rawUrl.slice("sqlite:".length)}` : rawUrl,
16
+
17
+ /** Generic, sensible pool defaults for any provider */
18
+ pool: {
19
+ max: 10,
20
+ idleTimeout: 20000, // ms
21
+ connectTimeout: 10000, // ms
22
+ keepAlive: true
23
+ },
24
+
25
+ /**
26
+ * Default to true. If a provider (like a pooler) doesn't support it,
27
+ * they usually indicate this in the connection string or require the user
28
+ * to handle it at the driver level.
29
+ */
30
+ prepare: true,
31
+
32
+ /**
33
+ * Require TLS for MySQL and PostgreSQL connections. Set this to true, or
34
+ * append `?sslmode=require` to DATABASE_URL if your provider documents that.
35
+ */
36
+ ssl: false
37
+ };
38
+
39
+ export type DatabaseConfig = typeof databaseConfig;
40
+
41
+ export function detectDialectFrom(url: string): "sqlite" | "mysql" | "postgresql" {
42
+ const value = url.toLowerCase();
43
+ if (value.startsWith("mysql")) return "mysql";
44
+ if (value.startsWith("postgres")) return "postgresql";
45
+ return "sqlite";
46
+ }
47
+
48
+ export const databaseDialect = detectDialectFrom(rawUrl);
@@ -1,83 +1,83 @@
1
- import { type AppConfig, appConfig } from "./app.js";
2
- import { type AuthConfig, authConfig } from "./auth.js";
3
- import { type CacheConfig, cacheConfig } from "./cache.js";
4
- import { type CookieConfig, cookieConfig } from "./cookie.js";
5
- import { type CorsConfig, corsConfig } from "./cors.js";
6
- import { type DatabaseConfig, databaseConfig } from "./database.js";
7
- import { type JwtConfig, jwtConfig } from "./jwt.js";
8
- import { type LoggingConfig, loggingConfig } from "./logging.js";
9
- import { type MailConfig, mailConfig } from "./mail.js";
10
- import { type OpenApiConfig, openApiConfig } from "./openapi.js";
11
- import { type QueueConfig, queueConfig } from "./queue.js";
12
- import { type RateLimitConfig, rateLimitConfig } from "./rateLimit.js";
13
- import { type RealtimeConfig, realtimeConfig } from "./realtime.js";
14
- import { type RedisConfig, redisConfig } from "./redis.js";
15
- import { type SecurityConfig, securityConfig } from "./security.js";
16
- import { type SessionConfig, sessionConfig } from "./session.js";
17
- import { type StorageConfig, storageConfig } from "./storage.js";
18
-
19
- export { appConfig } from "./app.js";
20
- export { authConfig } from "./auth.js";
21
- export { cacheConfig } from "./cache.js";
22
- export { cookieConfig } from "./cookie.js";
23
- export { corsConfig } from "./cors.js";
24
- export { databaseConfig } from "./database.js";
25
- export { jwtConfig } from "./jwt.js";
26
- export { loggingConfig } from "./logging.js";
27
- export { mailConfig } from "./mail.js";
28
- export { openApiConfig } from "./openapi.js";
29
- export { queueConfig } from "./queue.js";
30
- export { rateLimitConfig } from "./rateLimit.js";
31
- export { realtimeConfig } from "./realtime.js";
32
- export { redisConfig } from "./redis.js";
33
- export { securityConfig } from "./security.js";
34
- export { sessionConfig } from "./session.js";
35
- export { storageConfig } from "./storage.js";
36
-
37
- /**
38
- * Why: Single import point for every config domain.
39
- * When: Application code needs configuration values.
40
- * Where: Imported as `import { config } from "@/config/index.js"`.
41
- * How: Aggregates per-domain config objects; individual files remain the
42
- * place to edit each setting.
43
- */
44
- export const config = {
45
- app: appConfig,
46
- auth: authConfig,
47
- cache: cacheConfig,
48
- cookie: cookieConfig,
49
- cors: corsConfig,
50
- database: databaseConfig,
51
- jwt: jwtConfig,
52
- logging: loggingConfig,
53
- mail: mailConfig,
54
- openApi: openApiConfig,
55
- queue: queueConfig,
56
- rateLimit: rateLimitConfig,
57
- realtime: realtimeConfig,
58
- redis: redisConfig,
59
- session: sessionConfig,
60
- security: securityConfig,
61
- storage: storageConfig
62
- } as const;
63
-
64
- export type Config = typeof config;
65
- export type {
66
- AppConfig,
67
- AuthConfig,
68
- CacheConfig,
69
- CookieConfig,
70
- CorsConfig,
71
- DatabaseConfig,
72
- JwtConfig,
73
- LoggingConfig,
74
- MailConfig,
75
- OpenApiConfig,
76
- QueueConfig,
77
- RateLimitConfig,
78
- RealtimeConfig,
79
- RedisConfig,
80
- SecurityConfig,
81
- SessionConfig,
82
- StorageConfig
83
- };
1
+ import { type AppConfig, appConfig } from "./app.js";
2
+ import { type AuthConfig, authConfig } from "./auth.js";
3
+ import { type CacheConfig, cacheConfig } from "./cache.js";
4
+ import { type CookieConfig, cookieConfig } from "./cookie.js";
5
+ import { type CorsConfig, corsConfig } from "./cors.js";
6
+ import { type DatabaseConfig, databaseConfig } from "./database.js";
7
+ import { type JwtConfig, jwtConfig } from "./jwt.js";
8
+ import { type LoggingConfig, loggingConfig } from "./logging.js";
9
+ import { type MailConfig, mailConfig } from "./mail.js";
10
+ import { type OpenApiConfig, openApiConfig } from "./openapi.js";
11
+ import { type QueueConfig, queueConfig } from "./queue.js";
12
+ import { type RateLimitConfig, rateLimitConfig } from "./rateLimit.js";
13
+ import { type RealtimeConfig, realtimeConfig } from "./realtime.js";
14
+ import { type RedisConfig, redisConfig } from "./redis.js";
15
+ import { type SecurityConfig, securityConfig } from "./security.js";
16
+ import { type SessionConfig, sessionConfig } from "./session.js";
17
+ import { type StorageConfig, storageConfig } from "./storage.js";
18
+
19
+ export { appConfig } from "./app.js";
20
+ export { authConfig } from "./auth.js";
21
+ export { cacheConfig } from "./cache.js";
22
+ export { cookieConfig } from "./cookie.js";
23
+ export { corsConfig } from "./cors.js";
24
+ export { databaseConfig, databaseDialect, detectDialectFrom } from "./database.js";
25
+ export { jwtConfig } from "./jwt.js";
26
+ export { loggingConfig } from "./logging.js";
27
+ export { mailConfig } from "./mail.js";
28
+ export { openApiConfig } from "./openapi.js";
29
+ export { queueConfig } from "./queue.js";
30
+ export { rateLimitConfig } from "./rateLimit.js";
31
+ export { realtimeConfig } from "./realtime.js";
32
+ export { redisConfig } from "./redis.js";
33
+ export { securityConfig } from "./security.js";
34
+ export { sessionConfig } from "./session.js";
35
+ export { storageConfig } from "./storage.js";
36
+
37
+ /**
38
+ * Why: Single import point for every config domain.
39
+ * When: Application code needs configuration values.
40
+ * Where: Imported as `import { config } from "@/config/index.js"`.
41
+ * How: Aggregates per-domain config objects; individual files remain the
42
+ * place to edit each setting.
43
+ */
44
+ export const config = {
45
+ app: appConfig,
46
+ auth: authConfig,
47
+ cache: cacheConfig,
48
+ cookie: cookieConfig,
49
+ cors: corsConfig,
50
+ database: databaseConfig,
51
+ jwt: jwtConfig,
52
+ logging: loggingConfig,
53
+ mail: mailConfig,
54
+ openApi: openApiConfig,
55
+ queue: queueConfig,
56
+ rateLimit: rateLimitConfig,
57
+ realtime: realtimeConfig,
58
+ redis: redisConfig,
59
+ session: sessionConfig,
60
+ security: securityConfig,
61
+ storage: storageConfig
62
+ } as const;
63
+
64
+ export type Config = typeof config;
65
+ export type {
66
+ AppConfig,
67
+ AuthConfig,
68
+ CacheConfig,
69
+ CookieConfig,
70
+ CorsConfig,
71
+ DatabaseConfig,
72
+ JwtConfig,
73
+ LoggingConfig,
74
+ MailConfig,
75
+ OpenApiConfig,
76
+ QueueConfig,
77
+ RateLimitConfig,
78
+ RealtimeConfig,
79
+ RedisConfig,
80
+ SecurityConfig,
81
+ SessionConfig,
82
+ StorageConfig
83
+ };
@@ -8,46 +8,28 @@ import { appConfig } from "./app.js";
8
8
  * and the Scalar docs UI appearance.
9
9
  */
10
10
  export const openApiConfig = {
11
- /** OpenAPI spec version */
12
11
  version: "3.0.0",
13
-
14
- /** API title shown in docs and the /doc spec */
15
12
  title: `${appConfig.name} API`,
16
-
17
- /** API version shown in docs */
18
13
  apiVersion: "1.0.0",
19
-
20
- /** Optional description shown in the /doc spec */
21
14
  description: "",
22
15
 
23
16
  /** Scalar docs UI settings */
24
17
  scalar: {
25
- /** URL path to the OpenAPI JSON spec */
26
- specUrl: "/doc",
27
-
28
- /** URL path to the interactive docs UI */
29
- docsPath: "/api-docs",
30
-
31
- /** UI layout: "classic" or "modern" */
32
- layout: "classic" as const,
33
-
18
+ specUrl: "/doc", // URL path to the OpenAPI JSON spec
19
+ docsPath: "/api-docs", // URL path to the interactive docs UI
20
+ layout: "classic" as const, // UI layout: "classic" or "modern"
34
21
  /** UI theme: "default", "moon", "purple", "solarized", "bluePlanet", "fastify", "kepler", "mars", "nebula", "none" */
35
22
  theme: "moon" as const,
36
-
37
- /** HTML page title for the /api-docs page */
38
- pageTitle: `${appConfig.name} API`,
39
-
23
+ pageTitle: `${appConfig.name} API`, // HTML page title for the /api-docs page
40
24
  /** Favicon file (project-relative) served at /favicon.ico for the /api-docs page */
41
25
  favicon: "src/resources/src/assets/images/favicon/favicon.ico",
42
-
43
26
  /** Default HTTP client shown in code examples */
44
27
  defaultHttpClient: {
45
28
  targetKey: "js" as const,
46
29
  clientKey: "fetch" as const
47
30
  },
48
-
49
- /** Expand all tags on load */
50
- defaultOpenAllTags: true
31
+ defaultOpenAllTags: true, // Expand all tags on load
32
+ showDeveloperTools: "never"
51
33
  }
52
34
  } as const;
53
35
 
@@ -1,30 +1,30 @@
1
- import { redisConfig } from "./redis.js";
2
-
3
- /**
4
- * Why: Queue workers, concurrency, and BullMQ key namespaces.
5
- * When: The queue facade bootstraps workers and the dashboard connects.
6
- * Where: src/config/queue.ts.
7
- * How: `queues` lists which queue names get a worker by default (default,
8
- * mail, maintenance). `concurrency` caps parallel jobs per worker.
9
- * Key prefixes derive from the shared `REDIS_PREFIX`.
10
- */
11
- export const queueConfig = {
12
- queues: ["default", "mail", "maintenance"],
13
- concurrency: 10,
14
- /**
15
- * autoPruneQueues
16
- * Why: Automatically deletes phantom queues (Redis keys for queue names that
17
- * no longer exist in `queues`) when a queue worker boots. Safe because
18
- * only empty, unconfigured queues are removed, and BullMQ recreates a
19
- * queue's keys on demand if code still dispatches to it.
20
- * When: Set false to disable automatic pruning and rely on manual
21
- * `queue:clear` instead.
22
- */
23
- autoPruneQueues: true,
24
- prefix: `${redisConfig.prefix}:queue`,
25
- durablePrefix: `${redisConfig.prefix}:durable`,
26
- queueUi: "/queues",
27
- allowedEmails: ""
28
- };
29
-
30
- export type QueueConfig = typeof queueConfig;
1
+ import { redisConfig } from "./redis.js";
2
+
3
+ /**
4
+ * Why: Queue workers, concurrency, and BullMQ key namespaces.
5
+ * When: The queue facade bootstraps workers and the dashboard connects.
6
+ * Where: src/config/queue.ts.
7
+ * How: `queues` lists which queue names get a worker by default (default,
8
+ * mail, maintenance). `concurrency` caps parallel jobs per worker.
9
+ * Key prefixes derive from the shared `REDIS_PREFIX`.
10
+ */
11
+ export const queueConfig = {
12
+ queues: ["default", "mail", "maintenance"],
13
+ concurrency: 10,
14
+ /**
15
+ * autoPruneQueues
16
+ * Why: Automatically deletes phantom queues (Redis keys for queue names that
17
+ * no longer exist in `queues`) when a queue worker boots. Safe because
18
+ * only empty, unconfigured queues are removed, and BullMQ recreates a
19
+ * queue's keys on demand if code still dispatches to it.
20
+ * When: Set false to disable automatic pruning and rely on manual
21
+ * `queue:clear` instead.
22
+ */
23
+ autoPruneQueues: true,
24
+ prefix: `${redisConfig.prefix}:queue`,
25
+ durablePrefix: `${redisConfig.prefix}:durable`,
26
+ queueUi: "/queues",
27
+ allowedEmails: "" // Comma-separated list of email addresses allowed to access the queue UI. Empty means no restriction.
28
+ };
29
+
30
+ export type QueueConfig = typeof queueConfig;
@@ -1,40 +1,50 @@
1
- import { databaseConfig } from "./database.js";
2
- import { mailConfig } from "./mail.js";
3
- import { redisConfig } from "./redis.js";
4
- import { storageConfig } from "./storage.js";
5
-
6
- /**
7
- * Why: Validates that resolved configs are internally consistent at startup.
8
- * When: Called before any framework subsystem initializes.
9
- * Where: kernel.ts, before storage.init() and initRedis().
10
- * How: Checks cross-config dependencies and throws clear errors for inconsistencies.
11
- */
12
- export function validateConfig(): void {
13
- if (!databaseConfig.url) {
14
- throw new Error("DATABASE_URL is required but is empty");
15
- }
16
-
17
- if (storageConfig.driver === "s3") {
18
- if (!storageConfig.bucket) {
19
- throw new Error("STORAGE_BUCKET is required when storage driver is s3");
20
- }
21
- if (!storageConfig.accessKeyId || !storageConfig.secretAccessKey) {
22
- throw new Error("STORAGE_ACCESS_KEY_ID and STORAGE_SECRET_ACCESS_KEY are required when storage driver is s3");
23
- }
24
- }
25
-
26
- if (redisConfig.enabled) {
27
- try {
28
- const url = new URL(redisConfig.url);
29
- if (!url.hostname || url.port === "") {
30
- throw new Error(`REDIS_URL is invalid: "${redisConfig.url}" — must include host and port`);
31
- }
32
- } catch (error) {
33
- throw new Error(`REDIS_URL is invalid: "${redisConfig.url}" — ${error instanceof Error ? error.message : error}`);
34
- }
35
- }
36
-
37
- if (!mailConfig.failSilent && !mailConfig.username) {
38
- throw new Error("MAIL_USERNAME is required when MAIL_FAIL_SILENT is false");
39
- }
40
- }
1
+ import { databaseConfig } from "./database.js";
2
+ import { mailConfig } from "./mail.js";
3
+ import { redisConfig } from "./redis.js";
4
+ import { storageConfig } from "./storage.js";
5
+
6
+ /**
7
+ * Why: Validates that resolved configs are internally consistent at startup.
8
+ * When: Called before any framework subsystem initializes.
9
+ * Where: kernel.ts, before storage.init() and initRedis().
10
+ * How: Checks cross-config dependencies and throws clear errors for inconsistencies.
11
+ */
12
+ export function validateConfig(): void {
13
+ if (!databaseConfig.url) {
14
+ throw new Error("DATABASE_URL is required but is empty");
15
+ }
16
+
17
+ if (storageConfig.driver === "s3") {
18
+ if (!storageConfig.bucket) {
19
+ throw new Error("STORAGE_BUCKET is required when storage driver is s3");
20
+ }
21
+ if (!storageConfig.accessKeyId || !storageConfig.secretAccessKey) {
22
+ throw new Error("STORAGE_ACCESS_KEY_ID and STORAGE_SECRET_ACCESS_KEY are required when storage driver is s3");
23
+ }
24
+ }
25
+
26
+ if (redisConfig.enabled) {
27
+ try {
28
+ const url = new URL(redisConfig.url);
29
+
30
+ // Ensure it starts with redis:// or rediss://
31
+ if (url.protocol !== "redis:" && url.protocol !== "rediss:") {
32
+ throw new Error("URL must start with redis:// or rediss://");
33
+ }
34
+
35
+ // Hostname is mandatory (e.g., localhost, 127.0.0.1, redis-container)
36
+ if (!url.hostname) {
37
+ throw new Error("URL must include a valid hostname");
38
+ }
39
+
40
+ // Note: We do NOT check if the port is empty.
41
+ // ioredis automatically defaults to 6379 if no port is provided.
42
+ } catch (error) {
43
+ throw new Error(`REDIS_URL is invalid: "${redisConfig.url}" — ${error instanceof Error ? error.message : error}`);
44
+ }
45
+ }
46
+
47
+ if (!mailConfig.failSilent && !mailConfig.username) {
48
+ throw new Error("MAIL_USERNAME is required when MAIL_FAIL_SILENT is false");
49
+ }
50
+ }
@@ -1,48 +1,48 @@
1
- CREATE TABLE `roles` (
2
- `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
3
- `name` text NOT NULL,
4
- `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
5
- `updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
6
- );
7
- --> statement-breakpoint
8
- CREATE UNIQUE INDEX `roles_name_unique` ON `roles` (`name`);--> statement-breakpoint
9
- CREATE TABLE `email_verification_tokens` (
10
- `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
11
- `email` text NOT NULL,
12
- `token` text NOT NULL,
13
- `expires_at` integer NOT NULL,
14
- `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
15
- );
16
- --> statement-breakpoint
17
- CREATE TABLE `password_reset_tokens` (
18
- `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
19
- `email` text NOT NULL,
20
- `token` text NOT NULL,
21
- `expires_at` integer NOT NULL,
22
- `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
23
- );
24
- --> statement-breakpoint
25
- CREATE TABLE `refresh_tokens` (
26
- `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
27
- `user_id` integer,
28
- `jti` text NOT NULL,
29
- `revoked` integer DEFAULT false,
30
- `expires_at` integer NOT NULL,
31
- `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
32
- FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE set null
33
- );
34
- --> statement-breakpoint
35
- CREATE UNIQUE INDEX `refresh_tokens_jti_unique` ON `refresh_tokens` (`jti`);--> statement-breakpoint
36
- CREATE TABLE `users` (
37
- `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
38
- `name` text NOT NULL,
39
- `email` text NOT NULL,
40
- `password` text NOT NULL,
41
- `role_id` integer,
42
- `email_verified_at` integer,
43
- `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
44
- `updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
45
- FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON UPDATE cascade ON DELETE set null
46
- );
47
- --> statement-breakpoint
1
+ CREATE TABLE `roles` (
2
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
3
+ `name` text NOT NULL,
4
+ `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
5
+ `updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
6
+ );
7
+ --> statement-breakpoint
8
+ CREATE UNIQUE INDEX `roles_name_unique` ON `roles` (`name`);--> statement-breakpoint
9
+ CREATE TABLE `email_verification_tokens` (
10
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
11
+ `email` text NOT NULL,
12
+ `token` text NOT NULL,
13
+ `expires_at` integer NOT NULL,
14
+ `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
15
+ );
16
+ --> statement-breakpoint
17
+ CREATE TABLE `password_reset_tokens` (
18
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
19
+ `email` text NOT NULL,
20
+ `token` text NOT NULL,
21
+ `expires_at` integer NOT NULL,
22
+ `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
23
+ );
24
+ --> statement-breakpoint
25
+ CREATE TABLE `refresh_tokens` (
26
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
27
+ `user_id` integer,
28
+ `jti` text NOT NULL,
29
+ `revoked` integer DEFAULT false,
30
+ `expires_at` integer NOT NULL,
31
+ `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
32
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE set null
33
+ );
34
+ --> statement-breakpoint
35
+ CREATE UNIQUE INDEX `refresh_tokens_jti_unique` ON `refresh_tokens` (`jti`);--> statement-breakpoint
36
+ CREATE TABLE `users` (
37
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
38
+ `name` text NOT NULL,
39
+ `email` text NOT NULL,
40
+ `password` text NOT NULL,
41
+ `role_id` integer,
42
+ `email_verified_at` integer,
43
+ `created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
44
+ `updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
45
+ FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON UPDATE cascade ON DELETE set null
46
+ );
47
+ --> statement-breakpoint
48
48
  CREATE UNIQUE INDEX `users_email_unique` ON `users` (`email`);