create-nexwire 4.0.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 (488) hide show
  1. package/README.md +233 -0
  2. package/express/.dockerignore +14 -0
  3. package/express/.env +44 -0
  4. package/express/.env.example +42 -0
  5. package/express/.vscode/settings.json +26 -0
  6. package/express/LICENSE +21 -0
  7. package/express/README.md +211 -0
  8. package/express/biome.json +66 -0
  9. package/express/drizzle.config.ts +25 -0
  10. package/express/gitignore-stub +24 -0
  11. package/express/package.json +108 -0
  12. package/express/public/.gitkeep +0 -0
  13. package/express/src/config/app.ts +41 -0
  14. package/express/src/config/auth.ts +12 -0
  15. package/express/src/config/cache.ts +16 -0
  16. package/express/src/config/cookie.ts +15 -0
  17. package/express/src/config/cors.ts +12 -0
  18. package/express/src/config/database.ts +29 -0
  19. package/express/src/config/index.ts +83 -0
  20. package/express/src/config/jwt.ts +19 -0
  21. package/express/src/config/logging.ts +13 -0
  22. package/express/src/config/mail.ts +24 -0
  23. package/express/src/config/openapi.ts +54 -0
  24. package/express/src/config/queue.ts +30 -0
  25. package/express/src/config/rateLimit.ts +17 -0
  26. package/express/src/config/realtime.ts +15 -0
  27. package/express/src/config/redis.ts +18 -0
  28. package/express/src/config/security.ts +44 -0
  29. package/express/src/config/session.ts +17 -0
  30. package/express/src/config/storage.ts +22 -0
  31. package/express/src/config/validate.ts +40 -0
  32. package/express/src/database/migrations/sqlite/0000_init.sql +61 -0
  33. package/express/src/database/migrations/sqlite/meta/0000_snapshot.json +412 -0
  34. package/express/src/database/migrations/sqlite/meta/_journal.json +13 -0
  35. package/express/src/database/schema.ts +3 -0
  36. package/express/src/env.ts +76 -0
  37. package/express/src/framework/cache/cache.ts +81 -0
  38. package/express/src/framework/circuit-breaker/cb.ts +60 -0
  39. package/express/src/framework/database/connection.ts +196 -0
  40. package/express/src/framework/database/migrate-hooks.ts +87 -0
  41. package/express/src/framework/database/paginate.ts +227 -0
  42. package/express/src/framework/database/schema.ts +20 -0
  43. package/express/src/framework/database/seed.ts +139 -0
  44. package/express/src/framework/events/dispatcher.ts +49 -0
  45. package/express/src/framework/facade.ts +48 -0
  46. package/express/src/framework/http/app.ts +107 -0
  47. package/express/src/framework/http/cors.ts +7 -0
  48. package/express/src/framework/http/logger.ts +69 -0
  49. package/express/src/framework/http/metrics.ts +22 -0
  50. package/express/src/framework/http/openapi.ts +54 -0
  51. package/express/src/framework/http/ratelimiter.ts +16 -0
  52. package/express/src/framework/http/router.ts +178 -0
  53. package/express/src/framework/http/security.ts +23 -0
  54. package/express/src/framework/http/static.ts +23 -0
  55. package/express/src/framework/http/validation.ts +18 -0
  56. package/express/src/framework/kernel.ts +52 -0
  57. package/express/src/framework/maker-cli/db/core.mjs +288 -0
  58. package/express/src/framework/maker-cli/db/index.mjs +204 -0
  59. package/express/src/framework/maker-cli/deploy/core.mjs +1047 -0
  60. package/express/src/framework/maker-cli/deploy/index.mjs +91 -0
  61. package/express/src/framework/maker-cli/index.mjs +53 -0
  62. package/express/src/framework/maker-cli/middleware/core.mjs +47 -0
  63. package/express/src/framework/maker-cli/middleware/index.mjs +17 -0
  64. package/express/src/framework/maker-cli/module/core.mjs +684 -0
  65. package/express/src/framework/maker-cli/module/index.mjs +140 -0
  66. package/express/src/framework/maker-cli/runtime/build-ui.mjs +16 -0
  67. package/express/src/framework/maker-cli/runtime/core.mjs +543 -0
  68. package/express/src/framework/maker-cli/runtime/index.mjs +104 -0
  69. package/express/src/framework/maker-cli/runtime/redis-commander-patch.cjs +20 -0
  70. package/express/src/framework/maker-cli/stubs/controller/openapi.ts.stub +47 -0
  71. package/express/src/framework/maker-cli/stubs/controller/openapi.with-model.ts.stub +48 -0
  72. package/express/src/framework/maker-cli/stubs/controller/plain.ts.stub +54 -0
  73. package/express/src/framework/maker-cli/stubs/controller/schema.plain.ts.stub +14 -0
  74. package/express/src/framework/maker-cli/stubs/controller/schema.ts.stub +33 -0
  75. package/express/src/framework/maker-cli/stubs/deploy/Dockerfile.bun.stub +52 -0
  76. package/express/src/framework/maker-cli/stubs/deploy/Dockerfile.pnpm.stub +55 -0
  77. package/express/src/framework/maker-cli/stubs/deploy/Dockerfile.stub +51 -0
  78. package/express/src/framework/maker-cli/stubs/deploy/Dockerfile.yarn.stub +55 -0
  79. package/express/src/framework/maker-cli/stubs/deploy/README.stub +59 -0
  80. package/express/src/framework/maker-cli/stubs/deploy/compose/mysql.server.stub +45 -0
  81. package/express/src/framework/maker-cli/stubs/deploy/compose/postgres.server.stub +45 -0
  82. package/express/src/framework/maker-cli/stubs/deploy/compose/sqlite.stub +45 -0
  83. package/express/src/framework/maker-cli/stubs/deploy/env/mysql.server.stub +68 -0
  84. package/express/src/framework/maker-cli/stubs/deploy/env/postgres.server.stub +68 -0
  85. package/express/src/framework/maker-cli/stubs/deploy/env/sqlite.stub +67 -0
  86. package/express/src/framework/maker-cli/stubs/deploy/scripts/auto-migrate.sh.stub +41 -0
  87. package/express/src/framework/maker-cli/stubs/deploy/server/README.stub +78 -0
  88. package/express/src/framework/maker-cli/stubs/deploy/server/compose/noredis.stub +120 -0
  89. package/express/src/framework/maker-cli/stubs/deploy/server/compose/redis.dev.stub +133 -0
  90. package/express/src/framework/maker-cli/stubs/deploy/server/compose/redis.stub +131 -0
  91. package/express/src/framework/maker-cli/stubs/deploy/server/env/local.example.stub +11 -0
  92. package/express/src/framework/maker-cli/stubs/deploy/server/env/noredis.stub +25 -0
  93. package/express/src/framework/maker-cli/stubs/deploy/server/env/redis.stub +25 -0
  94. package/express/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/README.stub +16 -0
  95. package/express/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/app.example.com.stub +13 -0
  96. package/express/src/framework/maker-cli/stubs/deploy/server/pgadmin/servers.stub +14 -0
  97. package/express/src/framework/maker-cli/stubs/deploy/server/redis/redis.conf.stub +7 -0
  98. package/express/src/framework/maker-cli/stubs/deploy/supervisor/noredis.stub +54 -0
  99. package/express/src/framework/maker-cli/stubs/deploy/supervisor/redis.stub +70 -0
  100. package/express/src/framework/maker-cli/stubs/deploy/workflow/local.json.stub +25 -0
  101. package/express/src/framework/maker-cli/stubs/deploy/workflow/remote.json.stub +24 -0
  102. package/express/src/framework/maker-cli/stubs/example/console.ts.stub +34 -0
  103. package/express/src/framework/maker-cli/stubs/example/controller.ts.stub +418 -0
  104. package/express/src/framework/maker-cli/stubs/example/job.ts.stub +75 -0
  105. package/express/src/framework/maker-cli/stubs/example/route.api.ts.stub +207 -0
  106. package/express/src/framework/maker-cli/stubs/example/route.plain.ts.stub +18 -0
  107. package/express/src/framework/maker-cli/stubs/example/schema.plain.ts.stub +42 -0
  108. package/express/src/framework/maker-cli/stubs/example/schema.ts.stub +42 -0
  109. package/express/src/framework/maker-cli/stubs/job/name.ts.stub +25 -0
  110. package/express/src/framework/maker-cli/stubs/middleware/name.ts.stub +14 -0
  111. package/express/src/framework/maker-cli/stubs/model/name.mysql.ts.stub +9 -0
  112. package/express/src/framework/maker-cli/stubs/model/name.postgresql.ts.stub +9 -0
  113. package/express/src/framework/maker-cli/stubs/model/name.sqlite.ts.stub +9 -0
  114. package/express/src/framework/maker-cli/stubs/notification/controller.ts.stub +77 -0
  115. package/express/src/framework/maker-cli/stubs/notification/job.ts.stub +13 -0
  116. package/express/src/framework/maker-cli/stubs/notification/route.api.ts.stub +50 -0
  117. package/express/src/framework/maker-cli/stubs/notification/route.plain.ts.stub +12 -0
  118. package/express/src/framework/maker-cli/stubs/notification/schema.plain.ts.stub +26 -0
  119. package/express/src/framework/maker-cli/stubs/notification/schema.ts.stub +26 -0
  120. package/express/src/framework/maker-cli/stubs/route/api.ts.stub +80 -0
  121. package/express/src/framework/maker-cli/stubs/route/plain.ts.stub +11 -0
  122. package/express/src/framework/maker-cli/stubs/schedule/name.ts.stub +36 -0
  123. package/express/src/framework/maker-cli/stubs/seeder/name.ts.stub +20 -0
  124. package/express/src/framework/maker-cli/stubs/test/unit.ts.stub +22 -0
  125. package/express/src/framework/maker-cli/utils/env-config.mjs +44 -0
  126. package/express/src/framework/maker-cli/utils/env-db.mjs +61 -0
  127. package/express/src/framework/maker-cli/utils/file-ops.mjs +30 -0
  128. package/express/src/framework/maker-cli/utils/flags.mjs +14 -0
  129. package/express/src/framework/maker-cli/utils/help.mjs +50 -0
  130. package/express/src/framework/maker-cli/utils/naming.mjs +13 -0
  131. package/express/src/framework/maker-cli/utils/process.mjs +52 -0
  132. package/express/src/framework/modules/discover.ts +54 -0
  133. package/express/src/framework/modules/routes.ts +21 -0
  134. package/express/src/framework/notification/index.ts +116 -0
  135. package/express/src/framework/queue/clear.ts +22 -0
  136. package/express/src/framework/queue/queue.ts +342 -0
  137. package/express/src/framework/queue/ui.ts +187 -0
  138. package/express/src/framework/queue/worker.ts +61 -0
  139. package/express/src/framework/realtime/broadcast.ts +46 -0
  140. package/express/src/framework/realtime/index.ts +2 -0
  141. package/express/src/framework/realtime/socket-cookie.ts +71 -0
  142. package/express/src/framework/realtime/socket.ts +119 -0
  143. package/express/src/framework/realtime/types.ts +6 -0
  144. package/express/src/framework/realtime/ui.ts +16 -0
  145. package/express/src/framework/redis/client.ts +151 -0
  146. package/express/src/framework/runtime/runtime.ts +23 -0
  147. package/express/src/framework/runtime/server-adapter.ts +34 -0
  148. package/express/src/framework/scheduler/lock.ts +116 -0
  149. package/express/src/framework/scheduler/run.ts +48 -0
  150. package/express/src/framework/scheduler/scheduler.ts +155 -0
  151. package/express/src/framework/server.ts +177 -0
  152. package/express/src/framework/session/session.ts +98 -0
  153. package/express/src/framework/storage/storage.ts +785 -0
  154. package/express/src/framework/support/cookie.ts +62 -0
  155. package/express/src/framework/support/jwt.ts +33 -0
  156. package/express/src/framework/support/lifecycle.ts +35 -0
  157. package/express/src/framework/support/logger.ts +148 -0
  158. package/express/src/framework/support/mail.ts +48 -0
  159. package/express/src/framework/support/password.ts +23 -0
  160. package/express/src/framework/support/upload.ts +160 -0
  161. package/express/src/framework/support/url.ts +41 -0
  162. package/express/src/middlewares/auth-middleware.ts +98 -0
  163. package/express/src/middlewares/role-middleware.ts +25 -0
  164. package/express/src/modules/auth/controllers/auth.controller.ts +358 -0
  165. package/express/src/modules/auth/controllers/auth.helpers.ts +104 -0
  166. package/express/src/modules/auth/controllers/auth.schema.ts +102 -0
  167. package/express/src/modules/auth/controllers/role.controller.ts +15 -0
  168. package/express/src/modules/auth/database/models/notifications.ts +24 -0
  169. package/express/src/modules/auth/database/models/role.ts +14 -0
  170. package/express/src/modules/auth/database/models/user.ts +46 -0
  171. package/express/src/modules/auth/database/seeders/role.ts +18 -0
  172. package/express/src/modules/auth/database/seeders/user.ts +35 -0
  173. package/express/src/modules/auth/jobs/forgetpass.ts +20 -0
  174. package/express/src/modules/auth/jobs/registeruser.ts +23 -0
  175. package/express/src/modules/auth/jobs/verifyemail.ts +18 -0
  176. package/express/src/modules/auth/routes/api.ts +150 -0
  177. package/express/src/modules/auth/routes/role.ts +33 -0
  178. package/express/src/resources/index.html +17 -0
  179. package/express/src/resources/src/App.vue +5 -0
  180. package/express/src/resources/src/assets/css/styles.css +14761 -0
  181. package/express/src/resources/src/assets/css/styles.css.map +1 -0
  182. package/express/src/resources/src/assets/fonts/public-sans/public-sans-latin-ext.woff2 +0 -0
  183. package/express/src/resources/src/assets/fonts/public-sans/public-sans-latin.woff2 +0 -0
  184. package/express/src/resources/src/assets/images/favicon/favicon.ico +0 -0
  185. package/express/src/resources/src/assets/images/logo.png +0 -0
  186. package/express/src/resources/src/assets/scss/custom.css +217 -0
  187. package/express/src/resources/src/assets/scss/custom.css.map +1 -0
  188. package/express/src/resources/src/assets/scss/custom.scss +1346 -0
  189. package/express/src/resources/src/components/Button.vue +32 -0
  190. package/express/src/resources/src/components/Checkbox.vue +29 -0
  191. package/express/src/resources/src/components/Datepicker.vue +106 -0
  192. package/express/src/resources/src/components/FeatureButton.vue +53 -0
  193. package/express/src/resources/src/components/FloatButton.vue +33 -0
  194. package/express/src/resources/src/components/Href.vue +32 -0
  195. package/express/src/resources/src/components/Input.vue +223 -0
  196. package/express/src/resources/src/components/InputGroup.vue +145 -0
  197. package/express/src/resources/src/components/InputPasswordToggle.vue +213 -0
  198. package/express/src/resources/src/components/Modal.vue +55 -0
  199. package/express/src/resources/src/components/Pagebar.vue +26 -0
  200. package/express/src/resources/src/components/Select.vue +384 -0
  201. package/express/src/resources/src/components/Spinner.vue +42 -0
  202. package/express/src/resources/src/components/Switch.vue +65 -0
  203. package/express/src/resources/src/components/TextArea.vue +117 -0
  204. package/express/src/resources/src/components/Toast.vue +56 -0
  205. package/express/src/resources/src/components/datatable/DataTableSkeleton.vue +98 -0
  206. package/express/src/resources/src/components/datatable/Pagination.vue +147 -0
  207. package/express/src/resources/src/components/datatable/SelectOpption.vue +64 -0
  208. package/express/src/resources/src/components/datatable/index.vue +199 -0
  209. package/express/src/resources/src/composables/useAuth.ts +52 -0
  210. package/express/src/resources/src/helpers/nformatter.ts +10 -0
  211. package/express/src/resources/src/helpers/utils.ts +75 -0
  212. package/express/src/resources/src/layouts/AuthLayout.vue +20 -0
  213. package/express/src/resources/src/layouts/Layout/Footer.vue +23 -0
  214. package/express/src/resources/src/layouts/Layout/Header.vue +105 -0
  215. package/express/src/resources/src/layouts/Layout/Sidebar.vue +137 -0
  216. package/express/src/resources/src/layouts/Layout/index.vue +87 -0
  217. package/express/src/resources/src/main.ts +26 -0
  218. package/express/src/resources/src/pages/auth/forgetPassword.vue +82 -0
  219. package/express/src/resources/src/pages/auth/login.vue +99 -0
  220. package/express/src/resources/src/pages/auth/register.vue +133 -0
  221. package/express/src/resources/src/pages/auth/resetPassword.vue +118 -0
  222. package/express/src/resources/src/pages/auth/verifyEmail.vue +68 -0
  223. package/express/src/resources/src/pages/dashboard/index.vue +66 -0
  224. package/express/src/resources/src/plugins/axios.ts +31 -0
  225. package/express/src/resources/src/plugins/browserDetect.ts +55 -0
  226. package/express/src/resources/src/plugins/dialog.ts +216 -0
  227. package/express/src/resources/src/plugins/gum.ts +367 -0
  228. package/express/src/resources/src/plugins/pulse.ts +147 -0
  229. package/express/src/resources/src/plugins/routeProgress.ts +87 -0
  230. package/express/src/resources/src/router/index.ts +85 -0
  231. package/express/src/resources/src/stores/admin-ui.ts +148 -0
  232. package/express/src/resources/src/stores/auth.ts +164 -0
  233. package/express/src/resources/tsconfig.json +19 -0
  234. package/express/src/resources/vite.config.ts +46 -0
  235. package/express/src/storage/app/private/.gitkeep +0 -0
  236. package/express/src/storage/app/public/.gitkeep +0 -0
  237. package/express/src/storage/app/tmp/generated/.gitkeep +0 -0
  238. package/express/src/storage/database/nexwire.sqlite +0 -0
  239. package/express/src/storage/logs/.gitkeep +0 -0
  240. package/express/src/storage/tmp/.gitkeep +0 -0
  241. package/express/src/storage/trash/modules/.gitkeep +0 -0
  242. package/express/src/types/global.d.ts +26 -0
  243. package/express/tsconfig.json +19 -0
  244. package/express/vitest.config.ts +23 -0
  245. package/hono/.dockerignore +14 -0
  246. package/hono/.env +44 -0
  247. package/hono/.env.example +42 -0
  248. package/hono/.vscode/settings.json +26 -0
  249. package/hono/LICENSE +21 -0
  250. package/hono/README.md +211 -0
  251. package/hono/biome.json +76 -0
  252. package/hono/drizzle.config.ts +25 -0
  253. package/hono/gitignore-stub +24 -0
  254. package/hono/package.json +99 -0
  255. package/hono/public/.gitkeep +0 -0
  256. package/hono/src/config/app.ts +41 -0
  257. package/hono/src/config/auth.ts +12 -0
  258. package/hono/src/config/cache.ts +16 -0
  259. package/hono/src/config/cookie.ts +15 -0
  260. package/hono/src/config/cors.ts +12 -0
  261. package/hono/src/config/database.ts +29 -0
  262. package/hono/src/config/index.ts +83 -0
  263. package/hono/src/config/jwt.ts +19 -0
  264. package/hono/src/config/logging.ts +13 -0
  265. package/hono/src/config/mail.ts +24 -0
  266. package/hono/src/config/openapi.ts +54 -0
  267. package/hono/src/config/queue.ts +30 -0
  268. package/hono/src/config/rateLimit.ts +17 -0
  269. package/hono/src/config/realtime.ts +15 -0
  270. package/hono/src/config/redis.ts +18 -0
  271. package/hono/src/config/security.ts +44 -0
  272. package/hono/src/config/session.ts +17 -0
  273. package/hono/src/config/storage.ts +22 -0
  274. package/hono/src/config/validate.ts +40 -0
  275. package/hono/src/database/migrations/sqlite/0000_init.sql +61 -0
  276. package/hono/src/database/migrations/sqlite/meta/0000_snapshot.json +412 -0
  277. package/hono/src/database/migrations/sqlite/meta/_journal.json +13 -0
  278. package/hono/src/database/schema.ts +3 -0
  279. package/hono/src/env.ts +76 -0
  280. package/hono/src/framework/cache/cache.ts +81 -0
  281. package/hono/src/framework/circuit-breaker/cb.ts +60 -0
  282. package/hono/src/framework/database/connection.ts +196 -0
  283. package/hono/src/framework/database/migrate-hooks.ts +87 -0
  284. package/hono/src/framework/database/paginate.ts +253 -0
  285. package/hono/src/framework/database/schema.ts +20 -0
  286. package/hono/src/framework/database/seed.ts +139 -0
  287. package/hono/src/framework/events/dispatcher.ts +49 -0
  288. package/hono/src/framework/facade.ts +29 -0
  289. package/hono/src/framework/http/app.ts +109 -0
  290. package/hono/src/framework/http/cors.ts +19 -0
  291. package/hono/src/framework/http/logger.ts +81 -0
  292. package/hono/src/framework/http/metrics.ts +22 -0
  293. package/hono/src/framework/http/openapi.ts +42 -0
  294. package/hono/src/framework/http/ratelimiter.ts +172 -0
  295. package/hono/src/framework/http/router.ts +76 -0
  296. package/hono/src/framework/http/security.ts +23 -0
  297. package/hono/src/framework/http/static.ts +70 -0
  298. package/hono/src/framework/http/validation.ts +21 -0
  299. package/hono/src/framework/kernel.ts +48 -0
  300. package/hono/src/framework/maker-cli/db/core.mjs +288 -0
  301. package/hono/src/framework/maker-cli/db/index.mjs +204 -0
  302. package/hono/src/framework/maker-cli/deploy/core.mjs +1038 -0
  303. package/hono/src/framework/maker-cli/deploy/index.mjs +91 -0
  304. package/hono/src/framework/maker-cli/index.mjs +53 -0
  305. package/hono/src/framework/maker-cli/middleware/core.mjs +47 -0
  306. package/hono/src/framework/maker-cli/middleware/index.mjs +12 -0
  307. package/hono/src/framework/maker-cli/module/core.mjs +684 -0
  308. package/hono/src/framework/maker-cli/module/index.mjs +140 -0
  309. package/hono/src/framework/maker-cli/runtime/build-ui.mjs +17 -0
  310. package/hono/src/framework/maker-cli/runtime/core.mjs +543 -0
  311. package/hono/src/framework/maker-cli/runtime/index.mjs +104 -0
  312. package/hono/src/framework/maker-cli/runtime/redis-commander-patch.cjs +20 -0
  313. package/hono/src/framework/maker-cli/stubs/controller/openapi.ts.stub +57 -0
  314. package/hono/src/framework/maker-cli/stubs/controller/openapi.with-model.ts.stub +58 -0
  315. package/hono/src/framework/maker-cli/stubs/controller/plain.ts.stub +59 -0
  316. package/hono/src/framework/maker-cli/stubs/controller/schema.plain.ts.stub +14 -0
  317. package/hono/src/framework/maker-cli/stubs/controller/schema.ts.stub +33 -0
  318. package/hono/src/framework/maker-cli/stubs/deploy/Dockerfile.bun.stub +52 -0
  319. package/hono/src/framework/maker-cli/stubs/deploy/Dockerfile.pnpm.stub +55 -0
  320. package/hono/src/framework/maker-cli/stubs/deploy/Dockerfile.stub +51 -0
  321. package/hono/src/framework/maker-cli/stubs/deploy/Dockerfile.yarn.stub +55 -0
  322. package/hono/src/framework/maker-cli/stubs/deploy/README.stub +59 -0
  323. package/hono/src/framework/maker-cli/stubs/deploy/compose/mysql.server.stub +45 -0
  324. package/hono/src/framework/maker-cli/stubs/deploy/compose/postgres.server.stub +45 -0
  325. package/hono/src/framework/maker-cli/stubs/deploy/compose/sqlite.stub +45 -0
  326. package/hono/src/framework/maker-cli/stubs/deploy/env/mysql.server.stub +68 -0
  327. package/hono/src/framework/maker-cli/stubs/deploy/env/postgres.server.stub +68 -0
  328. package/hono/src/framework/maker-cli/stubs/deploy/env/sqlite.stub +67 -0
  329. package/hono/src/framework/maker-cli/stubs/deploy/scripts/auto-migrate.sh.stub +41 -0
  330. package/hono/src/framework/maker-cli/stubs/deploy/server/README.stub +78 -0
  331. package/hono/src/framework/maker-cli/stubs/deploy/server/compose/noredis.stub +120 -0
  332. package/hono/src/framework/maker-cli/stubs/deploy/server/compose/redis.dev.stub +133 -0
  333. package/hono/src/framework/maker-cli/stubs/deploy/server/compose/redis.stub +131 -0
  334. package/hono/src/framework/maker-cli/stubs/deploy/server/env/local.example.stub +11 -0
  335. package/hono/src/framework/maker-cli/stubs/deploy/server/env/noredis.stub +25 -0
  336. package/hono/src/framework/maker-cli/stubs/deploy/server/env/redis.stub +25 -0
  337. package/hono/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/README.stub +16 -0
  338. package/hono/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/app.example.com.stub +13 -0
  339. package/hono/src/framework/maker-cli/stubs/deploy/server/pgadmin/servers.stub +14 -0
  340. package/hono/src/framework/maker-cli/stubs/deploy/server/redis/redis.conf.stub +7 -0
  341. package/hono/src/framework/maker-cli/stubs/deploy/supervisor/noredis.stub +54 -0
  342. package/hono/src/framework/maker-cli/stubs/deploy/supervisor/redis.stub +70 -0
  343. package/hono/src/framework/maker-cli/stubs/deploy/workflow/local.json.stub +25 -0
  344. package/hono/src/framework/maker-cli/stubs/deploy/workflow/remote.json.stub +24 -0
  345. package/hono/src/framework/maker-cli/stubs/example/console.ts.stub +34 -0
  346. package/hono/src/framework/maker-cli/stubs/example/controller.ts.stub +505 -0
  347. package/hono/src/framework/maker-cli/stubs/example/job.ts.stub +75 -0
  348. package/hono/src/framework/maker-cli/stubs/example/route.api.ts.stub +207 -0
  349. package/hono/src/framework/maker-cli/stubs/example/route.plain.ts.stub +18 -0
  350. package/hono/src/framework/maker-cli/stubs/example/schema.plain.ts.stub +42 -0
  351. package/hono/src/framework/maker-cli/stubs/example/schema.ts.stub +42 -0
  352. package/hono/src/framework/maker-cli/stubs/job/name.ts.stub +25 -0
  353. package/hono/src/framework/maker-cli/stubs/middleware/name.ts.stub +14 -0
  354. package/hono/src/framework/maker-cli/stubs/model/name.mysql.ts.stub +9 -0
  355. package/hono/src/framework/maker-cli/stubs/model/name.postgresql.ts.stub +9 -0
  356. package/hono/src/framework/maker-cli/stubs/model/name.sqlite.ts.stub +9 -0
  357. package/hono/src/framework/maker-cli/stubs/notification/controller.ts.stub +86 -0
  358. package/hono/src/framework/maker-cli/stubs/notification/job.ts.stub +13 -0
  359. package/hono/src/framework/maker-cli/stubs/notification/route.api.ts.stub +50 -0
  360. package/hono/src/framework/maker-cli/stubs/notification/route.plain.ts.stub +12 -0
  361. package/hono/src/framework/maker-cli/stubs/notification/schema.plain.ts.stub +26 -0
  362. package/hono/src/framework/maker-cli/stubs/notification/schema.ts.stub +26 -0
  363. package/hono/src/framework/maker-cli/stubs/route/api.ts.stub +80 -0
  364. package/hono/src/framework/maker-cli/stubs/route/plain.ts.stub +11 -0
  365. package/hono/src/framework/maker-cli/stubs/schedule/name.ts.stub +36 -0
  366. package/hono/src/framework/maker-cli/stubs/seeder/name.ts.stub +20 -0
  367. package/hono/src/framework/maker-cli/stubs/test/unit.ts.stub +22 -0
  368. package/hono/src/framework/maker-cli/utils/env-config.mjs +44 -0
  369. package/hono/src/framework/maker-cli/utils/env-db.mjs +61 -0
  370. package/hono/src/framework/maker-cli/utils/file-ops.mjs +30 -0
  371. package/hono/src/framework/maker-cli/utils/flags.mjs +14 -0
  372. package/hono/src/framework/maker-cli/utils/help.mjs +50 -0
  373. package/hono/src/framework/maker-cli/utils/naming.mjs +13 -0
  374. package/hono/src/framework/maker-cli/utils/process.mjs +52 -0
  375. package/hono/src/framework/modules/discover.ts +54 -0
  376. package/hono/src/framework/modules/routes.ts +24 -0
  377. package/hono/src/framework/notification/index.ts +116 -0
  378. package/hono/src/framework/queue/clear.ts +22 -0
  379. package/hono/src/framework/queue/queue.ts +342 -0
  380. package/hono/src/framework/queue/ui.ts +214 -0
  381. package/hono/src/framework/queue/worker.ts +61 -0
  382. package/hono/src/framework/realtime/broadcast.ts +46 -0
  383. package/hono/src/framework/realtime/index.ts +2 -0
  384. package/hono/src/framework/realtime/socket-cookie.ts +68 -0
  385. package/hono/src/framework/realtime/socket.ts +196 -0
  386. package/hono/src/framework/realtime/types.ts +6 -0
  387. package/hono/src/framework/realtime/ui.ts +16 -0
  388. package/hono/src/framework/redis/client.ts +151 -0
  389. package/hono/src/framework/runtime/runtime.ts +23 -0
  390. package/hono/src/framework/runtime/server-adapter.ts +94 -0
  391. package/hono/src/framework/scheduler/lock.ts +116 -0
  392. package/hono/src/framework/scheduler/run.ts +48 -0
  393. package/hono/src/framework/scheduler/scheduler.ts +155 -0
  394. package/hono/src/framework/server.ts +183 -0
  395. package/hono/src/framework/session/session.ts +116 -0
  396. package/hono/src/framework/storage/storage.ts +785 -0
  397. package/hono/src/framework/support/cookie.ts +99 -0
  398. package/hono/src/framework/support/jwt.ts +45 -0
  399. package/hono/src/framework/support/lifecycle.ts +35 -0
  400. package/hono/src/framework/support/logger.ts +148 -0
  401. package/hono/src/framework/support/mail.ts +48 -0
  402. package/hono/src/framework/support/password.ts +23 -0
  403. package/hono/src/framework/support/url.ts +41 -0
  404. package/hono/src/middlewares/auth-middleware.ts +98 -0
  405. package/hono/src/middlewares/role-middleware.ts +25 -0
  406. package/hono/src/modules/auth/controllers/auth.controller.ts +413 -0
  407. package/hono/src/modules/auth/controllers/auth.helpers.ts +128 -0
  408. package/hono/src/modules/auth/controllers/auth.schema.ts +102 -0
  409. package/hono/src/modules/auth/controllers/role.controller.ts +25 -0
  410. package/hono/src/modules/auth/database/models/notifications.ts +24 -0
  411. package/hono/src/modules/auth/database/models/role.ts +14 -0
  412. package/hono/src/modules/auth/database/models/user.ts +46 -0
  413. package/hono/src/modules/auth/database/seeders/role.ts +18 -0
  414. package/hono/src/modules/auth/database/seeders/user.ts +35 -0
  415. package/hono/src/modules/auth/jobs/forgetpass.ts +20 -0
  416. package/hono/src/modules/auth/jobs/registeruser.ts +23 -0
  417. package/hono/src/modules/auth/jobs/verifyemail.ts +18 -0
  418. package/hono/src/modules/auth/routes/api.ts +150 -0
  419. package/hono/src/modules/auth/routes/role.ts +33 -0
  420. package/hono/src/resources/index.html +17 -0
  421. package/hono/src/resources/src/App.vue +5 -0
  422. package/hono/src/resources/src/assets/css/styles.css +14913 -0
  423. package/hono/src/resources/src/assets/css/styles.css.map +1 -0
  424. package/hono/src/resources/src/assets/fonts/public-sans/public-sans-latin-ext.woff2 +0 -0
  425. package/hono/src/resources/src/assets/fonts/public-sans/public-sans-latin.woff2 +0 -0
  426. package/hono/src/resources/src/assets/images/favicon/favicon.ico +0 -0
  427. package/hono/src/resources/src/assets/images/logo.png +0 -0
  428. package/hono/src/resources/src/assets/scss/custom.css +217 -0
  429. package/hono/src/resources/src/assets/scss/custom.css.map +1 -0
  430. package/hono/src/resources/src/assets/scss/custom.scss +1346 -0
  431. package/hono/src/resources/src/components/Button.vue +32 -0
  432. package/hono/src/resources/src/components/Checkbox.vue +29 -0
  433. package/hono/src/resources/src/components/Datepicker.vue +106 -0
  434. package/hono/src/resources/src/components/FeatureButton.vue +53 -0
  435. package/hono/src/resources/src/components/FloatButton.vue +33 -0
  436. package/hono/src/resources/src/components/Href.vue +32 -0
  437. package/hono/src/resources/src/components/Input.vue +234 -0
  438. package/hono/src/resources/src/components/InputGroup.vue +149 -0
  439. package/hono/src/resources/src/components/InputPasswordToggle.vue +222 -0
  440. package/hono/src/resources/src/components/Modal.vue +55 -0
  441. package/hono/src/resources/src/components/Pagebar.vue +26 -0
  442. package/hono/src/resources/src/components/Select.vue +415 -0
  443. package/hono/src/resources/src/components/Spinner.vue +42 -0
  444. package/hono/src/resources/src/components/Switch.vue +65 -0
  445. package/hono/src/resources/src/components/TextArea.vue +121 -0
  446. package/hono/src/resources/src/components/Toast.vue +56 -0
  447. package/hono/src/resources/src/components/datatable/DataTableSkeleton.vue +98 -0
  448. package/hono/src/resources/src/components/datatable/Pagination.vue +147 -0
  449. package/hono/src/resources/src/components/datatable/SelectOpption.vue +64 -0
  450. package/hono/src/resources/src/components/datatable/index.vue +199 -0
  451. package/hono/src/resources/src/composables/useAuth.ts +52 -0
  452. package/hono/src/resources/src/helpers/nformatter.ts +10 -0
  453. package/hono/src/resources/src/helpers/utils.ts +75 -0
  454. package/hono/src/resources/src/layouts/AuthLayout.vue +20 -0
  455. package/hono/src/resources/src/layouts/Layout/Footer.vue +23 -0
  456. package/hono/src/resources/src/layouts/Layout/Header.vue +105 -0
  457. package/hono/src/resources/src/layouts/Layout/Sidebar.vue +137 -0
  458. package/hono/src/resources/src/layouts/Layout/index.vue +87 -0
  459. package/hono/src/resources/src/main.ts +26 -0
  460. package/hono/src/resources/src/pages/auth/forgetPassword.vue +82 -0
  461. package/hono/src/resources/src/pages/auth/login.vue +99 -0
  462. package/hono/src/resources/src/pages/auth/register.vue +133 -0
  463. package/hono/src/resources/src/pages/auth/resetPassword.vue +118 -0
  464. package/hono/src/resources/src/pages/auth/verifyEmail.vue +68 -0
  465. package/hono/src/resources/src/pages/dashboard/index.vue +66 -0
  466. package/hono/src/resources/src/plugins/axios.ts +31 -0
  467. package/hono/src/resources/src/plugins/browserDetect.ts +55 -0
  468. package/hono/src/resources/src/plugins/dialog.ts +216 -0
  469. package/hono/src/resources/src/plugins/gum.ts +367 -0
  470. package/hono/src/resources/src/plugins/pulse.ts +147 -0
  471. package/hono/src/resources/src/plugins/routeProgress.ts +87 -0
  472. package/hono/src/resources/src/router/index.ts +85 -0
  473. package/hono/src/resources/src/stores/admin-ui.ts +148 -0
  474. package/hono/src/resources/src/stores/auth.ts +164 -0
  475. package/hono/src/resources/tsconfig.json +19 -0
  476. package/hono/src/resources/vite.config.ts +46 -0
  477. package/hono/src/storage/app/private/.gitkeep +0 -0
  478. package/hono/src/storage/app/public/.gitkeep +0 -0
  479. package/hono/src/storage/app/tmp/generated/.gitkeep +0 -0
  480. package/hono/src/storage/database/nexwire.sqlite +0 -0
  481. package/hono/src/storage/logs/.gitkeep +0 -0
  482. package/hono/src/storage/tmp/.gitkeep +0 -0
  483. package/hono/src/storage/trash/modules/.gitkeep +0 -0
  484. package/hono/src/types/global.d.ts +26 -0
  485. package/hono/tsconfig.json +20 -0
  486. package/hono/vitest.config.ts +23 -0
  487. package/package.json +238 -0
  488. package/src/index.js +204 -0
@@ -0,0 +1,99 @@
1
+ import type { Context } from "hono";
2
+ import { deleteCookie, getSignedCookie, setSignedCookie } from "hono/cookie";
3
+ import { appConfig, cookieConfig, jwtConfig } from "@/config/index.js";
4
+
5
+ function originOf(url?: string) {
6
+ if (!url) return "";
7
+ try {
8
+ return new URL(url).origin;
9
+ } catch {
10
+ return "";
11
+ }
12
+ }
13
+
14
+ function needsCrossSiteCookie() {
15
+ const appOrigin = originOf(appConfig.url);
16
+ const frontendOrigin = originOf(appConfig.frontendUrl);
17
+ return Boolean(appOrigin && frontendOrigin && appOrigin !== frontendOrigin);
18
+ }
19
+
20
+ function baseOptions() {
21
+ const crossSiteCookie = needsCrossSiteCookie();
22
+ const sameSite: "None" | "Lax" = crossSiteCookie ? "None" : "Lax";
23
+ return {
24
+ httpOnly: true,
25
+ secure: crossSiteCookie,
26
+ sameSite,
27
+ path: "/"
28
+ };
29
+ }
30
+
31
+ export const cookie = {
32
+ /**
33
+ * Why: Stores short-lived access token cookie for authenticated requests.
34
+ * When: Login/register/refresh responses.
35
+ * Where: Auth controllers/helpers.
36
+ * How: Sets httpOnly cookie with configured access expiry.
37
+ */
38
+ async setAuth(c: Context, token: string) {
39
+ await setSignedCookie(c, `${cookieConfig.name}_access`, token, cookieConfig.secret, {
40
+ ...baseOptions(),
41
+ maxAge: jwtConfig.accessExpirySeconds
42
+ });
43
+ },
44
+
45
+ /**
46
+ * Why: Stores refresh token cookie for token rotation.
47
+ * When: Login/register/refresh responses.
48
+ * Where: Auth controllers/helpers.
49
+ * How: Sets httpOnly cookie with explicit or default refresh maxAge.
50
+ */
51
+ async setRefresh(c: Context, token: string, maxAge?: number) {
52
+ await setSignedCookie(c, `${cookieConfig.name}_refresh`, token, cookieConfig.secret, {
53
+ ...baseOptions(),
54
+ maxAge: typeof maxAge === "number" ? maxAge : jwtConfig.refreshExpirySeconds
55
+ });
56
+ },
57
+
58
+ /**
59
+ * Why: Reads access token cookie from request context.
60
+ * When: Auth middleware validates request identity.
61
+ * Where: Middleware and auth helpers.
62
+ * How: Resolves cookie by configured access cookie name.
63
+ */
64
+ async getAuth(c: Context) {
65
+ const token = await getSignedCookie(c, cookieConfig.secret, `${cookieConfig.name}_access`);
66
+ return token || undefined;
67
+ },
68
+
69
+ /**
70
+ * Why: Reads refresh token cookie from request context.
71
+ * When: Refresh and logout flows.
72
+ * Where: Auth middleware/controllers.
73
+ * How: Resolves cookie by configured refresh cookie name.
74
+ */
75
+ async getRefresh(c: Context) {
76
+ const token = await getSignedCookie(c, cookieConfig.secret, `${cookieConfig.name}_refresh`);
77
+ return token || undefined;
78
+ },
79
+
80
+ /**
81
+ * Why: Clears access token cookie.
82
+ * When: Logout or invalid token handling.
83
+ * Where: Auth middleware/controllers.
84
+ * How: Deletes cookie path-scoped to root.
85
+ */
86
+ deleteAuth(c: Context) {
87
+ deleteCookie(c, `${cookieConfig.name}_access`, { path: "/" });
88
+ },
89
+
90
+ /**
91
+ * Why: Clears refresh token cookie.
92
+ * When: Logout or invalid token handling.
93
+ * Where: Auth middleware/controllers.
94
+ * How: Deletes cookie path-scoped to root.
95
+ */
96
+ deleteRefresh(c: Context) {
97
+ deleteCookie(c, `${cookieConfig.name}_refresh`, { path: "/" });
98
+ }
99
+ };
@@ -0,0 +1,45 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { sign, verify } from "hono/jwt";
3
+ import { jwtConfig } from "@/config/index.js";
4
+
5
+ export const jwt = {
6
+ /**
7
+ * Why: Creates signed JWT access/refresh tokens with project claims.
8
+ * When: Auth flows issue or rotate credentials.
9
+ * Where: Auth controllers/helpers.
10
+ * How: Builds payload with iat/exp/type (+jti for refresh) and signs HS256.
11
+ */
12
+ async generateToken(payload: any, type: "access" | "refresh", expirySeconds?: number) {
13
+ const now = Math.floor(Date.now() / 1000);
14
+ const exp =
15
+ now +
16
+ (typeof expirySeconds === "number"
17
+ ? expirySeconds
18
+ : type === "refresh"
19
+ ? jwtConfig.refreshExpirySeconds
20
+ : jwtConfig.accessExpirySeconds);
21
+ const secret = type === "refresh" ? jwtConfig.refreshSecret : jwtConfig.accessSecret;
22
+ const jti = type === "refresh" ? randomUUID() : undefined;
23
+
24
+ const tokenPayload = { ...payload, type, iat: now, exp, ...(jti ? { jti } : {}) };
25
+ const token = await sign(tokenPayload, secret, jwtConfig.algorithm);
26
+
27
+ return { token, jti, exp };
28
+ },
29
+
30
+ /**
31
+ * Why: Validates JWT and enforces token type.
32
+ * When: Middleware and refresh flows verify credentials.
33
+ * Where: Auth and realtime handshake.
34
+ * How: Verifies signature/expiry with type-specific secret and checks payload type.
35
+ */
36
+ async verifyToken(token: string, type: "access" | "refresh") {
37
+ try {
38
+ const secret = type === "refresh" ? jwtConfig.refreshSecret : jwtConfig.accessSecret;
39
+ const payload = await verify(token, secret, jwtConfig.algorithm);
40
+ return payload.type === type ? payload : null;
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+ };
@@ -0,0 +1,35 @@
1
+ const shutdownSignals = ["SIGINT", "SIGTERM"] as const;
2
+ export type ShutdownSignal = (typeof shutdownSignals)[number];
3
+
4
+ type ShutdownHandler = (signal: ShutdownSignal) => Promise<void>;
5
+
6
+ /**
7
+ * Why: Avoid duplicated graceful-shutdown wiring across runtime entrypoints.
8
+ * When: Server/worker/scheduler need signal handling.
9
+ * Where: Runtime bootstrap files.
10
+ * How: Registers SIGINT/SIGTERM handlers and forwards signal to async callback.
11
+ */
12
+ export function registerShutdownSignals(handler: ShutdownHandler) {
13
+ for (const signal of shutdownSignals) {
14
+ process.on(signal, () => {
15
+ void handler(signal);
16
+ });
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Why: Keep comma-separated CLI/env parsing consistent.
22
+ * When: Runtime options are provided as a single CSV string.
23
+ * Where: Worker and other entrypoints.
24
+ * How: Trims tokens, removes blanks, and falls back when empty.
25
+ */
26
+ export function parseCsvOrFallback(value: string | undefined, fallback: string[]) {
27
+ if (!value) return fallback;
28
+
29
+ const parsed = value
30
+ .split(",")
31
+ .map((item) => item.trim())
32
+ .filter(Boolean);
33
+
34
+ return parsed.length ? parsed : fallback;
35
+ }
@@ -0,0 +1,148 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { Writable } from "node:stream";
4
+ import pino from "pino";
5
+ import { appConfig, loggingConfig } from "@/config/index.js";
6
+
7
+ const logDir = path.resolve(process.cwd(), "src", "storage", "logs");
8
+ const MAX_FILE_BYTES = 10 * 1024 * 1024;
9
+
10
+ if (!fs.existsSync(logDir)) {
11
+ fs.mkdirSync(logDir, { recursive: true });
12
+ }
13
+
14
+ const LEVEL_COLORS: Record<number, string> = {
15
+ 10: "\x1b[90m",
16
+ 20: "\x1b[90m",
17
+ 30: "\x1b[32m",
18
+ 40: "\x1b[33m",
19
+ 50: "\x1b[31m",
20
+ 60: "\x1b[31m"
21
+ };
22
+
23
+ const RESET = "\x1b[0m";
24
+
25
+ function formatLine(chunk: string, colorize: boolean): string {
26
+ const line = chunk.trim();
27
+ if (!line) return "";
28
+
29
+ let record: Record<string, unknown>;
30
+ try {
31
+ record = JSON.parse(line);
32
+ } catch {
33
+ return colorize ? line : `${line}\n`;
34
+ }
35
+
36
+ const time = typeof record.time === "number" ? new Date(record.time) : new Date(String(record.time));
37
+ const timestamp = Number.isNaN(time.getTime()) ? "" : `[${time.toLocaleTimeString("en-GB", { hour12: false })}] `;
38
+ const levelNumber = typeof record.level === "number" ? record.level : 30;
39
+ const label = pino.levels.labels[levelNumber] ?? "info";
40
+ const message = typeof record.msg === "string" ? record.msg : "";
41
+
42
+ const ignored = new Set(["time", "level", "msg", "pid", "hostname", "service"]);
43
+ const meta: Record<string, unknown> = {};
44
+ for (const [key, value] of Object.entries(record)) {
45
+ if (!ignored.has(key)) meta[key] = value;
46
+ }
47
+
48
+ const level = colorize ? `${LEVEL_COLORS[levelNumber] ?? ""}${label}${RESET}` : label;
49
+ const metaString = Object.keys(meta).length ? `\n${JSON.stringify(meta, null, 2)}` : "";
50
+ return `${timestamp}${level} -> ${message}${metaString}\n`;
51
+ }
52
+
53
+ function consoleWriter() {
54
+ return new Writable({
55
+ write(chunk, _encoding, callback) {
56
+ const text = formatLine(chunk.toString("utf8"), true);
57
+ if (text) process.stdout.write(text);
58
+ callback();
59
+ }
60
+ });
61
+ }
62
+
63
+ function rotate(filePath: string, maxFiles: number) {
64
+ for (let index = maxFiles - 1; index >= 1; index--) {
65
+ const from = `${filePath}.${index}`;
66
+ const to = `${filePath}.${index + 1}`;
67
+ if (fs.existsSync(from)) fs.renameSync(from, to);
68
+ }
69
+ if (fs.existsSync(filePath)) fs.renameSync(filePath, `${filePath}.1`);
70
+ }
71
+
72
+ function fileWriter(filePath: string, maxFiles: number) {
73
+ let bytes = 0;
74
+
75
+ return new Writable({
76
+ write(chunk, _encoding, callback) {
77
+ const text = formatLine(chunk.toString("utf8"), false);
78
+ bytes += Buffer.byteLength(text);
79
+ if (bytes >= MAX_FILE_BYTES) {
80
+ rotate(filePath, maxFiles);
81
+ bytes = 0;
82
+ }
83
+ try {
84
+ fs.appendFileSync(filePath, text);
85
+ } catch {
86
+ // best-effort file logging
87
+ }
88
+ callback();
89
+ }
90
+ });
91
+ }
92
+
93
+ const base = pino(
94
+ {
95
+ level: loggingConfig.level,
96
+ base: { service: appConfig.name },
97
+ timestamp: pino.stdTimeFunctions.isoTime
98
+ },
99
+ pino.multistream([
100
+ { stream: consoleWriter(), level: loggingConfig.level },
101
+ { stream: fileWriter(path.join(logDir, "app.log"), 5), level: "info" },
102
+ { stream: fileWriter(path.join(logDir, "fatal.log"), 3), level: "error" }
103
+ ])
104
+ );
105
+
106
+ type CompatLogger = {
107
+ fatal: (message: string, meta?: Record<string, unknown>) => void;
108
+ error: (message: string, meta?: Record<string, unknown>) => void;
109
+ warn: (message: string, meta?: Record<string, unknown>) => void;
110
+ info: (message: string, meta?: Record<string, unknown>) => void;
111
+ debug: (message: string, meta?: Record<string, unknown>) => void;
112
+ trace: (message: string, meta?: Record<string, unknown>) => void;
113
+ child: (bindings: Record<string, unknown>) => CompatLogger;
114
+ };
115
+
116
+ function compat(child: pino.Logger): CompatLogger {
117
+ const wrap = (log: (obj: object, msg?: string, ...args: unknown[]) => void) => (message: string, meta?: Record<string, unknown>) =>
118
+ log.call(child, meta ?? {}, message);
119
+
120
+ return {
121
+ fatal: wrap(child.fatal),
122
+ error: wrap(child.error),
123
+ warn: wrap(child.warn),
124
+ info: wrap(child.info),
125
+ debug: wrap(child.debug),
126
+ trace: wrap(child.trace),
127
+ child: (bindings) => compat(child.child(bindings))
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Why: Shared structured logger for app/runtime/framework internals.
133
+ * When: Any code needs operational logs or error reporting.
134
+ * Where: Imported across framework and modules.
135
+ * How: Emits JSON via pino to a color console sink plus rotating app/fatal
136
+ * files, keeping the legacy `(message, meta)` call signature.
137
+ */
138
+ export const logger: CompatLogger = compat(base);
139
+
140
+ process.on("uncaughtException", (error) => {
141
+ logger.error("Uncaught exception", { error: { name: error.name, message: error.message, stack: error.stack } });
142
+ process.exit(1);
143
+ });
144
+
145
+ process.on("unhandledRejection", (reason) => {
146
+ const error = reason instanceof Error ? reason : new Error(String(reason));
147
+ logger.error("Unhandled rejection", { error: { name: error.name, message: error.message, stack: error.stack } });
148
+ });
@@ -0,0 +1,48 @@
1
+ import nodemailer from "nodemailer";
2
+ import { mailConfig } from "@/config/index.js";
3
+ import { CircuitBreaker } from "@/framework/circuit-breaker/cb.js";
4
+ import { logger } from "@/framework/support/logger.js";
5
+
6
+ type MailPayload = {
7
+ to: string;
8
+ subject: string;
9
+ html?: string;
10
+ text?: string;
11
+ };
12
+
13
+ const transport = nodemailer.createTransport({
14
+ host: mailConfig.host,
15
+ port: mailConfig.port,
16
+ secure: mailConfig.encryption === "ssl",
17
+ auth: mailConfig.username ? { user: mailConfig.username, pass: mailConfig.password } : undefined
18
+ });
19
+
20
+ const mailBreaker = new CircuitBreaker();
21
+
22
+ export const mail = {
23
+ /**
24
+ * Why: Sends transactional email through configured SMTP transport.
25
+ * When: Features need notifications/password reset/signup email.
26
+ * Where: Jobs and event handlers.
27
+ * How: Uses nodemailer transport and respects the fail-silent setting.
28
+ */
29
+ async sendMail(payload: MailPayload) {
30
+ try {
31
+ return await mailBreaker.exec(() =>
32
+ transport.sendMail({
33
+ from: mailConfig.fromAddress,
34
+ ...payload
35
+ })
36
+ );
37
+ } catch (error) {
38
+ logger.error("Mail send failed", {
39
+ to: payload.to,
40
+ subject: payload.subject,
41
+ error: error instanceof Error ? error.message : error
42
+ });
43
+
44
+ if (!mailConfig.failSilent) throw error;
45
+ return null;
46
+ }
47
+ }
48
+ };
@@ -0,0 +1,23 @@
1
+ import bcrypt from "bcryptjs";
2
+
3
+ export const password = {
4
+ /**
5
+ * Why: Hashes plaintext password before persistence.
6
+ * When: Registration and password reset flows.
7
+ * Where: Auth controllers/seeders.
8
+ * How: Uses bcrypt with cost factor 10.
9
+ */
10
+ async hashPassword(inputPassword: string) {
11
+ return await bcrypt.hash(inputPassword, 10);
12
+ },
13
+
14
+ /**
15
+ * Why: Compares plaintext password to stored hash.
16
+ * When: Login/authentication checks.
17
+ * Where: Auth controllers/middleware.
18
+ * How: Uses bcrypt secure compare.
19
+ */
20
+ async verifyPassword(inputPassword: string, hashedPassword: string) {
21
+ return await bcrypt.compare(inputPassword, hashedPassword);
22
+ }
23
+ };
@@ -0,0 +1,41 @@
1
+ import { appConfig } from "@/config/index.js";
2
+ import { hasUiBuild } from "@/framework/http/static.js";
3
+
4
+ export const urls = {
5
+ /**
6
+ * Why: Returns normalized app base URL without trailing slash.
7
+ * When: Building absolute links.
8
+ * Where: Mail/reset URL generation.
9
+ * How: Trims trailing slash from the configured app URL.
10
+ */
11
+ appUrl() {
12
+ return appConfig.url.replace(/\/$/, "");
13
+ },
14
+
15
+ /**
16
+ * Why: Builds absolute URL pointing at the SPA page that handles the path.
17
+ * When: Creating links for emails / external callbacks (reset, verify).
18
+ * Where: Auth/password reset and integrations.
19
+ * How: Three independent knobs decide the origin —
20
+ * appConfig.frontendUrl: the SPA is a separate build/origin (dev Vite
21
+ * dev server, or a separately deployed SPA). Link there.
22
+ * appConfig.uiEnabled + hasUiBuild(): the framework serves the built
23
+ * SPA itself, so the page resolves to the app origin.
24
+ * appConfig.uiEnabled + no UI build: the Vite dev server is still
25
+ * running (UI not built yet) — use the origin the maker-cli
26
+ * injected (NEXWIRE_FRONTEND_URL, dev Vite dev server).
27
+ * When BOTH origin knobs are unset (API-only mode) there is no SPA to
28
+ * point at — fall back to the app URL so the link is valid.
29
+ */
30
+ url(path = "") {
31
+ const base =
32
+ appConfig.frontendUrl || // explicit SPA origin — wins
33
+ (appConfig.uiEnabled
34
+ ? hasUiBuild()
35
+ ? urls.appUrl() // built SPA, framework serves it — same origin
36
+ : process.env.NEXWIRE_FRONTEND_URL || urls.appUrl() // dev Vite dev server — injected by maker-cli
37
+ : appConfig.url); // API-only
38
+ if (!path) return base;
39
+ return `${base}${path.startsWith("/") ? path : `/${path}`}`;
40
+ }
41
+ };
@@ -0,0 +1,98 @@
1
+ import { eq } from "drizzle-orm";
2
+ import type { Context, Next } from "hono";
3
+ import { cookie, db, jwt, HttpStatusCodes } from "@/framework/facade.js";
4
+ import { refreshTokens, users } from "@/modules/auth/database/models/user.js";
5
+
6
+ export async function authMiddleware(c: Context, next: Next) {
7
+ const accessToken = await cookie.getAuth(c);
8
+
9
+ if (accessToken) {
10
+ const accessPayload = await jwt.verifyToken(accessToken, "access");
11
+
12
+ if (accessPayload) {
13
+ const user = await db.query.users.findFirst({
14
+ where: eq(users.id, accessPayload.id as number),
15
+ with: { role: true }
16
+ });
17
+
18
+ if (!user) {
19
+ cookie.deleteAuth(c);
20
+ cookie.deleteRefresh(c);
21
+ return c.json({ message: "Unauthorized" }, HttpStatusCodes.UNAUTHORIZED);
22
+ }
23
+
24
+ c.set("auth", {
25
+ ...accessPayload,
26
+ id: user.id,
27
+ email: user.email,
28
+ roleId: user.role?.id ?? null,
29
+ role: user.role?.name ?? null
30
+ });
31
+ return await next();
32
+ }
33
+ }
34
+
35
+ const refreshToken = await cookie.getRefresh(c);
36
+
37
+ if (!refreshToken) {
38
+ cookie.deleteAuth(c);
39
+ cookie.deleteRefresh(c);
40
+ return c.json({ message: "Unauthorized" }, HttpStatusCodes.UNAUTHORIZED);
41
+ }
42
+
43
+ const refreshPayload = await jwt.verifyToken(refreshToken, "refresh");
44
+
45
+ if (!refreshPayload?.jti) {
46
+ cookie.deleteAuth(c);
47
+ cookie.deleteRefresh(c);
48
+ return c.json({ message: "Invalid token" }, HttpStatusCodes.UNAUTHORIZED);
49
+ }
50
+
51
+ const storedToken = await db.query.refreshTokens.findFirst({
52
+ where: eq(refreshTokens.jti, refreshPayload.jti as string)
53
+ });
54
+
55
+ if (!storedToken || storedToken.revoked) {
56
+ cookie.deleteAuth(c);
57
+ cookie.deleteRefresh(c);
58
+ return c.json({ message: "Invalid token" }, HttpStatusCodes.UNAUTHORIZED);
59
+ }
60
+
61
+ if (storedToken.expiresAt.getTime() < Date.now()) {
62
+ await db.delete(refreshTokens).where(eq(refreshTokens.id, storedToken.id));
63
+ cookie.deleteAuth(c);
64
+ cookie.deleteRefresh(c);
65
+ return c.json({ message: "Invalid token" }, HttpStatusCodes.UNAUTHORIZED);
66
+ }
67
+
68
+ const user = await db.query.users.findFirst({
69
+ where: eq(users.id, refreshPayload.id as number),
70
+ with: { role: true }
71
+ });
72
+
73
+ if (!user) {
74
+ cookie.deleteAuth(c);
75
+ cookie.deleteRefresh(c);
76
+ return c.json({ message: "Unauthorized" }, HttpStatusCodes.UNAUTHORIZED);
77
+ }
78
+
79
+ const newAccessToken = await jwt.generateToken(
80
+ {
81
+ id: user.id,
82
+ email: user.email,
83
+ roleId: user.role?.id ?? null,
84
+ role: user.role?.name ?? null
85
+ },
86
+ "access"
87
+ );
88
+
89
+ await cookie.setAuth(c, newAccessToken.token);
90
+ c.set("auth", {
91
+ id: user.id,
92
+ email: user.email,
93
+ roleId: user.role?.id ?? null,
94
+ role: user.role?.name ?? null,
95
+ type: "access"
96
+ });
97
+ return await next();
98
+ }
@@ -0,0 +1,25 @@
1
+ import type { Context, Next } from "hono";
2
+ import { HttpStatusCodes } from "@/framework/facade.js";
3
+
4
+ type AuthPayload = {
5
+ role?: string | null;
6
+ };
7
+
8
+ export function requireRole(...allowedRoles: string[]) {
9
+ const roles = allowedRoles.map((role) => role.toLowerCase());
10
+
11
+ return async (c: Context, next: Next) => {
12
+ const auth = c.get("auth") as AuthPayload | undefined;
13
+
14
+ if (!auth) {
15
+ return c.json({ message: "Unauthorized" }, HttpStatusCodes.UNAUTHORIZED);
16
+ }
17
+
18
+ const userRole = String(auth.role ?? "").toLowerCase();
19
+ if (!roles.includes(userRole)) {
20
+ return c.json({ message: "Forbidden: Insufficient permissions" }, HttpStatusCodes.FORBIDDEN);
21
+ }
22
+
23
+ return await next();
24
+ };
25
+ }