create-nexgen 1.0.4

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 (240) hide show
  1. package/package.json +26 -0
  2. package/src/index.js +108 -0
  3. package/template/.dockerignore +14 -0
  4. package/template/.env +58 -0
  5. package/template/.env.example +59 -0
  6. package/template/.prettierignore +5 -0
  7. package/template/.prettierrc +8 -0
  8. package/template/README.md +447 -0
  9. package/template/drizzle.config.ts +29 -0
  10. package/template/eslint.config.js +52 -0
  11. package/template/gitignore-stub +24 -0
  12. package/template/package.json +96 -0
  13. package/template/public/assets/AuthLayout-CbswhpjJ.js +1 -0
  14. package/template/public/assets/Button-_7aQ7gHL.js +1 -0
  15. package/template/public/assets/Input-CLNJXmKc.css +1 -0
  16. package/template/public/assets/Input-z8GI8Aqo.js +1 -0
  17. package/template/public/assets/InputPasswordToggle-BxlzVGp3.js +1 -0
  18. package/template/public/assets/InputPasswordToggle-C77FI9Eg.css +1 -0
  19. package/template/public/assets/Layout-DotR1sQC.js +1 -0
  20. package/template/public/assets/Refresh-BdqsPPBC.js +1 -0
  21. package/template/public/assets/admin-ui-CU34rLdN.js +1 -0
  22. package/template/public/assets/bootstrap-icons-BeopsB42.woff +0 -0
  23. package/template/public/assets/bootstrap-icons-mSm7cUeB.woff2 +0 -0
  24. package/template/public/assets/dashboard-CwybEyLc.js +1 -0
  25. package/template/public/assets/dashboard-Dc4d-Pi7.css +1 -0
  26. package/template/public/assets/forgetPassword-CKEJaXsq.js +1 -0
  27. package/template/public/assets/index-Bleyx5dm.js +64 -0
  28. package/template/public/assets/index-DUw8E6Yg.css +1 -0
  29. package/template/public/assets/login-DC7PTlQF.js +1 -0
  30. package/template/public/assets/realtime-test-BPQdrFym.css +1 -0
  31. package/template/public/assets/realtime-test-tQZ0rBEJ.js +1 -0
  32. package/template/public/assets/register-3O7Qs28C.js +1 -0
  33. package/template/public/assets/resetPassword-A5AzMWKs.js +1 -0
  34. package/template/public/assets/verifyEmail-DDBEQHOv.js +1 -0
  35. package/template/public/index.html +17 -0
  36. package/template/src/database/migrations/mysql/0000_init.sql +73 -0
  37. package/template/src/database/migrations/mysql/meta/0000_snapshot.json +484 -0
  38. package/template/src/database/migrations/mysql/meta/_journal.json +13 -0
  39. package/template/src/database/schema.ts +4 -0
  40. package/template/src/env.ts +107 -0
  41. package/template/src/framework/cache/cache.ts +81 -0
  42. package/template/src/framework/database/connection.ts +168 -0
  43. package/template/src/framework/database/optional-db-drivers.d.ts +9 -0
  44. package/template/src/framework/database/paginate.ts +200 -0
  45. package/template/src/framework/database/schema.ts +26 -0
  46. package/template/src/framework/database/seed.ts +33 -0
  47. package/template/src/framework/events/dispatcher.ts +57 -0
  48. package/template/src/framework/facade.ts +27 -0
  49. package/template/src/framework/http/app.ts +61 -0
  50. package/template/src/framework/http/cors.ts +19 -0
  51. package/template/src/framework/http/logger.ts +85 -0
  52. package/template/src/framework/http/openapi.ts +34 -0
  53. package/template/src/framework/http/ratelimiter.ts +13 -0
  54. package/template/src/framework/http/router.ts +76 -0
  55. package/template/src/framework/http/static.ts +33 -0
  56. package/template/src/framework/http/validation.ts +24 -0
  57. package/template/src/framework/kernel.ts +40 -0
  58. package/template/src/framework/maker-cli/src/index.mjs +51 -0
  59. package/template/src/framework/maker-cli/src/levels/level-1/env-db.mjs +57 -0
  60. package/template/src/framework/maker-cli/src/levels/level-1/file-ops.mjs +30 -0
  61. package/template/src/framework/maker-cli/src/levels/level-1/flags.mjs +16 -0
  62. package/template/src/framework/maker-cli/src/levels/level-1/help.mjs +24 -0
  63. package/template/src/framework/maker-cli/src/levels/level-1/naming.mjs +13 -0
  64. package/template/src/framework/maker-cli/src/levels/level-1/process.mjs +47 -0
  65. package/template/src/framework/maker-cli/src/levels/level-2/db/core.mjs +299 -0
  66. package/template/src/framework/maker-cli/src/levels/level-2/db/index.mjs +177 -0
  67. package/template/src/framework/maker-cli/src/levels/level-2/deploy/core.mjs +635 -0
  68. package/template/src/framework/maker-cli/src/levels/level-2/deploy/index.mjs +145 -0
  69. package/template/src/framework/maker-cli/src/levels/level-2/module/core.mjs +707 -0
  70. package/template/src/framework/maker-cli/src/levels/level-2/module/index.mjs +116 -0
  71. package/template/src/framework/maker-cli/src/levels/level-2/runtime/build-frontend.mjs +16 -0
  72. package/template/src/framework/maker-cli/src/levels/level-2/runtime/core.mjs +311 -0
  73. package/template/src/framework/maker-cli/src/levels/level-2/runtime/index.mjs +71 -0
  74. package/template/src/framework/maker-cli/stubs/controller/openapi.ts.stub +55 -0
  75. package/template/src/framework/maker-cli/stubs/controller/openapi.with-model.ts.stub +56 -0
  76. package/template/src/framework/maker-cli/stubs/controller/plain.ts.stub +57 -0
  77. package/template/src/framework/maker-cli/stubs/controller/schema.plain.ts.stub +13 -0
  78. package/template/src/framework/maker-cli/stubs/controller/schema.ts.stub +32 -0
  79. package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.bun.stub +49 -0
  80. package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.pnpm.stub +53 -0
  81. package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.stub +49 -0
  82. package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.yarn.stub +53 -0
  83. package/template/src/framework/maker-cli/stubs/deploy/README.stub +55 -0
  84. package/template/src/framework/maker-cli/stubs/deploy/compose/mysql.server.stub +29 -0
  85. package/template/src/framework/maker-cli/stubs/deploy/compose/postgres.server.stub +29 -0
  86. package/template/src/framework/maker-cli/stubs/deploy/compose/sqlite.stub +29 -0
  87. package/template/src/framework/maker-cli/stubs/deploy/env/mysql.server.stub +73 -0
  88. package/template/src/framework/maker-cli/stubs/deploy/env/postgres.server.stub +73 -0
  89. package/template/src/framework/maker-cli/stubs/deploy/env/sqlite.stub +72 -0
  90. package/template/src/framework/maker-cli/stubs/deploy/scripts/auto-migrate.sh.stub +15 -0
  91. package/template/src/framework/maker-cli/stubs/deploy/server/README.stub +77 -0
  92. package/template/src/framework/maker-cli/stubs/deploy/server/compose/noredis.stub +118 -0
  93. package/template/src/framework/maker-cli/stubs/deploy/server/compose/redis.dev.stub +131 -0
  94. package/template/src/framework/maker-cli/stubs/deploy/server/compose/redis.stub +129 -0
  95. package/template/src/framework/maker-cli/stubs/deploy/server/env/local.example.stub +10 -0
  96. package/template/src/framework/maker-cli/stubs/deploy/server/env/noredis.stub +24 -0
  97. package/template/src/framework/maker-cli/stubs/deploy/server/env/redis.stub +24 -0
  98. package/template/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/README.stub +15 -0
  99. package/template/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/app.example.com.stub +12 -0
  100. package/template/src/framework/maker-cli/stubs/deploy/server/pgadmin/servers.stub +13 -0
  101. package/template/src/framework/maker-cli/stubs/deploy/server/redis/redis.conf.stub +6 -0
  102. package/template/src/framework/maker-cli/stubs/deploy/supervisor/noredis.stub +53 -0
  103. package/template/src/framework/maker-cli/stubs/deploy/supervisor/redis.stub +69 -0
  104. package/template/src/framework/maker-cli/stubs/deploy/workflow/local.json.stub +24 -0
  105. package/template/src/framework/maker-cli/stubs/deploy/workflow/remote.json.stub +20 -0
  106. package/template/src/framework/maker-cli/stubs/example/console.ts.stub +33 -0
  107. package/template/src/framework/maker-cli/stubs/example/controller.ts.stub +503 -0
  108. package/template/src/framework/maker-cli/stubs/example/job.ts.stub +74 -0
  109. package/template/src/framework/maker-cli/stubs/example/route.api.ts.stub +206 -0
  110. package/template/src/framework/maker-cli/stubs/example/schema.ts.stub +41 -0
  111. package/template/src/framework/maker-cli/stubs/job/name.ts.stub +24 -0
  112. package/template/src/framework/maker-cli/stubs/model/name.mysql.ts.stub +8 -0
  113. package/template/src/framework/maker-cli/stubs/model/name.postgresql.ts.stub +8 -0
  114. package/template/src/framework/maker-cli/stubs/model/name.sqlite.ts.stub +8 -0
  115. package/template/src/framework/maker-cli/stubs/notification/NotificationBell.vue.stub +218 -0
  116. package/template/src/framework/maker-cli/stubs/notification/controller.ts.stub +85 -0
  117. package/template/src/framework/maker-cli/stubs/notification/index.vue.stub +211 -0
  118. package/template/src/framework/maker-cli/stubs/notification/job.ts.stub +12 -0
  119. package/template/src/framework/maker-cli/stubs/notification/route.api.ts.stub +49 -0
  120. package/template/src/framework/maker-cli/stubs/notification/schema.ts.stub +25 -0
  121. package/template/src/framework/maker-cli/stubs/route/api.ts.stub +79 -0
  122. package/template/src/framework/maker-cli/stubs/route/plain.ts.stub +10 -0
  123. package/template/src/framework/maker-cli/stubs/schedule/name.ts.stub +35 -0
  124. package/template/src/framework/maker-cli/stubs/seeder/name.ts.stub +17 -0
  125. package/template/src/framework/modules/discover.ts +54 -0
  126. package/template/src/framework/modules/routes.ts +26 -0
  127. package/template/src/framework/notification/index.ts +109 -0
  128. package/template/src/framework/queue/clear.ts +20 -0
  129. package/template/src/framework/queue/queue.ts +213 -0
  130. package/template/src/framework/queue/ui.ts +104 -0
  131. package/template/src/framework/queue/worker.ts +33 -0
  132. package/template/src/framework/realtime/broadcast.ts +27 -0
  133. package/template/src/framework/realtime/index.ts +1 -0
  134. package/template/src/framework/realtime/socket-cookie.ts +65 -0
  135. package/template/src/framework/realtime/socket.ts +132 -0
  136. package/template/src/framework/realtime/types.ts +6 -0
  137. package/template/src/framework/realtime/ui.ts +16 -0
  138. package/template/src/framework/redis/client.ts +126 -0
  139. package/template/src/framework/scheduler/lock.ts +124 -0
  140. package/template/src/framework/scheduler/run.ts +26 -0
  141. package/template/src/framework/scheduler/scheduler.ts +82 -0
  142. package/template/src/framework/server.ts +147 -0
  143. package/template/src/framework/session/session.ts +116 -0
  144. package/template/src/framework/storage/storage.ts +743 -0
  145. package/template/src/framework/support/cookie.ts +78 -0
  146. package/template/src/framework/support/jwt.ts +45 -0
  147. package/template/src/framework/support/lifecycle.ts +35 -0
  148. package/template/src/framework/support/logger.ts +102 -0
  149. package/template/src/framework/support/mail.ts +43 -0
  150. package/template/src/framework/support/password.ts +23 -0
  151. package/template/src/framework/support/url.ts +25 -0
  152. package/template/src/middlewares/auth-middleware.ts +98 -0
  153. package/template/src/middlewares/role-middleware.ts +24 -0
  154. package/template/src/modules/auth/controllers/auth.controller.ts +445 -0
  155. package/template/src/modules/auth/controllers/auth.helpers.ts +110 -0
  156. package/template/src/modules/auth/controllers/auth.schema.ts +102 -0
  157. package/template/src/modules/auth/controllers/role.controller.ts +25 -0
  158. package/template/src/modules/auth/database/models/notifications.ts +22 -0
  159. package/template/src/modules/auth/database/models/role.ts +14 -0
  160. package/template/src/modules/auth/database/models/user.ts +46 -0
  161. package/template/src/modules/auth/database/seeders/role.ts +19 -0
  162. package/template/src/modules/auth/database/seeders/user.ts +33 -0
  163. package/template/src/modules/auth/jobs/forgetpass.ts +18 -0
  164. package/template/src/modules/auth/jobs/registeruser.ts +31 -0
  165. package/template/src/modules/auth/jobs/verifyemail.ts +18 -0
  166. package/template/src/modules/auth/routes/api.ts +151 -0
  167. package/template/src/modules/auth/routes/role.ts +39 -0
  168. package/template/src/modules/welcome/controllers/welcome.controller.ts +14 -0
  169. package/template/src/modules/welcome/controllers/welcome.schema.ts +6 -0
  170. package/template/src/modules/welcome/database/models/welcome.ts +6 -0
  171. package/template/src/modules/welcome/routes/api.ts +20 -0
  172. package/template/src/resources/index.html +16 -0
  173. package/template/src/resources/src/App.vue +5 -0
  174. package/template/src/resources/src/assets/css/styles.css +14934 -0
  175. package/template/src/resources/src/assets/css/styles.css.map +1 -0
  176. package/template/src/resources/src/assets/images/favicon/favicon.ico +0 -0
  177. package/template/src/resources/src/assets/images/favicon/favicon1.ico +0 -0
  178. package/template/src/resources/src/assets/images/logo-1.png +0 -0
  179. package/template/src/resources/src/assets/images/logo-dark-sm.png +0 -0
  180. package/template/src/resources/src/assets/images/logo-dark.png +0 -0
  181. package/template/src/resources/src/assets/images/logo-dark1.png +0 -0
  182. package/template/src/resources/src/assets/images/logo-sm.png +0 -0
  183. package/template/src/resources/src/assets/images/logo1.png +0 -0
  184. package/template/src/resources/src/assets/images/logo2.png +0 -0
  185. package/template/src/resources/src/assets/scss/custom.css +217 -0
  186. package/template/src/resources/src/assets/scss/custom.css.map +1 -0
  187. package/template/src/resources/src/assets/scss/custom.scss +1100 -0
  188. package/template/src/resources/src/components/Button.vue +35 -0
  189. package/template/src/resources/src/components/Checkbox.vue +29 -0
  190. package/template/src/resources/src/components/FloatButton.vue +36 -0
  191. package/template/src/resources/src/components/Href.vue +32 -0
  192. package/template/src/resources/src/components/Input.vue +227 -0
  193. package/template/src/resources/src/components/InputGroup.vue +153 -0
  194. package/template/src/resources/src/components/InputPasswordToggle.vue +226 -0
  195. package/template/src/resources/src/components/Modal.vue +102 -0
  196. package/template/src/resources/src/components/Pagebar.vue +28 -0
  197. package/template/src/resources/src/components/Refresh.vue +26 -0
  198. package/template/src/resources/src/components/Select.vue +390 -0
  199. package/template/src/resources/src/components/Spinner.vue +42 -0
  200. package/template/src/resources/src/components/Switch.vue +65 -0
  201. package/template/src/resources/src/components/TextArea.vue +121 -0
  202. package/template/src/resources/src/components/Toast.vue +56 -0
  203. package/template/src/resources/src/components/datatable/DataTableSkeleton.vue +99 -0
  204. package/template/src/resources/src/components/datatable/Pagination.vue +161 -0
  205. package/template/src/resources/src/components/datatable/SelectOpption.vue +54 -0
  206. package/template/src/resources/src/components/datatable/index.vue +237 -0
  207. package/template/src/resources/src/composables/useAuth.ts +52 -0
  208. package/template/src/resources/src/composables/useBrowserDetect.ts +5 -0
  209. package/template/src/resources/src/composables/useDialog.ts +5 -0
  210. package/template/src/resources/src/composables/useGum.ts +3 -0
  211. package/template/src/resources/src/composables/usePulse.ts +5 -0
  212. package/template/src/resources/src/env.d.ts +20 -0
  213. package/template/src/resources/src/helpers/nformatter.ts +10 -0
  214. package/template/src/resources/src/helpers/utils.ts +68 -0
  215. package/template/src/resources/src/layouts/AuthLayout.vue +20 -0
  216. package/template/src/resources/src/layouts/Layout/Footer.vue +23 -0
  217. package/template/src/resources/src/layouts/Layout/Header.vue +90 -0
  218. package/template/src/resources/src/layouts/Layout/Sidebar.vue +137 -0
  219. package/template/src/resources/src/layouts/Layout/index.vue +76 -0
  220. package/template/src/resources/src/main.ts +27 -0
  221. package/template/src/resources/src/pages/auth/forgetPassword.vue +76 -0
  222. package/template/src/resources/src/pages/auth/login.vue +93 -0
  223. package/template/src/resources/src/pages/auth/register.vue +130 -0
  224. package/template/src/resources/src/pages/auth/resetPassword.vue +119 -0
  225. package/template/src/resources/src/pages/auth/verifyEmail.vue +60 -0
  226. package/template/src/resources/src/pages/dashboard/index.vue +76 -0
  227. package/template/src/resources/src/plugins/axios.ts +33 -0
  228. package/template/src/resources/src/plugins/browserDetect.ts +55 -0
  229. package/template/src/resources/src/plugins/dialog.ts +167 -0
  230. package/template/src/resources/src/plugins/gum.ts +343 -0
  231. package/template/src/resources/src/plugins/pulse.ts +141 -0
  232. package/template/src/resources/src/plugins/routeProgress.ts +87 -0
  233. package/template/src/resources/src/router/index.ts +85 -0
  234. package/template/src/resources/src/stores/admin-ui.ts +148 -0
  235. package/template/src/resources/src/stores/auth.ts +151 -0
  236. package/template/src/resources/tsconfig.json +19 -0
  237. package/template/src/resources/vite.config.ts +43 -0
  238. package/template/src/storage/logs/app.log +20179 -0
  239. package/template/src/storage/logs/fatal.log +727 -0
  240. package/template/tsconfig.json +20 -0
@@ -0,0 +1,14 @@
1
+ import { relations } from "drizzle-orm";
2
+ import { mysqlTable, int, varchar, timestamp } from "drizzle-orm/mysql-core";
3
+ import { users } from "@/modules/auth/database/models/user.js";
4
+
5
+ export const roles = mysqlTable("roles", {
6
+ id: int("id").autoincrement().primaryKey(),
7
+ name: varchar("name", { length: 255 }).notNull().unique(),
8
+ createdAt: timestamp("created_at").defaultNow().notNull(),
9
+ updatedAt: timestamp("updated_at").defaultNow().notNull().onUpdateNow()
10
+ });
11
+
12
+ export const rolesRelations = relations(roles, ({ many }) => ({
13
+ users: many(users)
14
+ }));
@@ -0,0 +1,46 @@
1
+ import { relations } from "drizzle-orm";
2
+ import { mysqlTable, int, varchar, text, timestamp, boolean } from "drizzle-orm/mysql-core";
3
+ import { roles } from "@/modules/auth/database/models/role.js";
4
+
5
+ export const users = mysqlTable("users", {
6
+ id: int("id").autoincrement().primaryKey(),
7
+ name: varchar("name", { length: 255 }).notNull(),
8
+ email: varchar("email", { length: 255 }).notNull().unique(),
9
+ password: text("password").notNull(),
10
+ roleId: int("role_id").references(() => roles.id, { onUpdate: "cascade", onDelete: "set null" }),
11
+ emailVerifiedAt: timestamp("email_verified_at"),
12
+ createdAt: timestamp("created_at").defaultNow().notNull(),
13
+ updatedAt: timestamp("updated_at").defaultNow().notNull().onUpdateNow()
14
+ });
15
+
16
+ export const emailVerificationTokens = mysqlTable("email_verification_tokens", {
17
+ id: int("id").autoincrement().primaryKey(),
18
+ email: varchar("email", { length: 255 }).notNull(),
19
+ token: text("token").notNull(),
20
+ expiresAt: timestamp("expires_at").notNull(),
21
+ createdAt: timestamp("created_at").defaultNow().notNull()
22
+ });
23
+
24
+ export const passwordResetTokens = mysqlTable("password_reset_tokens", {
25
+ id: int("id").autoincrement().primaryKey(),
26
+ email: varchar("email", { length: 255 }).notNull(),
27
+ token: text("token").notNull(),
28
+ expiresAt: timestamp("expires_at").notNull(),
29
+ createdAt: timestamp("created_at").defaultNow().notNull()
30
+ });
31
+
32
+ export const refreshTokens = mysqlTable("refresh_tokens", {
33
+ id: int("id").autoincrement().primaryKey(),
34
+ userId: int("user_id").references(() => users.id, { onUpdate: "cascade", onDelete: "set null" }),
35
+ jti: varchar("jti", { length: 191 }).notNull().unique(),
36
+ revoked: boolean("revoked").default(false),
37
+ expiresAt: timestamp("expires_at").notNull(),
38
+ createdAt: timestamp("created_at").defaultNow().notNull()
39
+ });
40
+
41
+ export const usersRelations = relations(users, ({ one }) => ({
42
+ role: one(roles, {
43
+ fields: [users.roleId],
44
+ references: [roles.id]
45
+ })
46
+ }));
@@ -0,0 +1,19 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { db } from "@/framework/facade.js";
3
+ import { roles } from "@/modules/auth/database/models/role.js";
4
+
5
+ export default async function RoleSeeder() {
6
+ const rows = [
7
+ { name: "admin" },
8
+ { name: "user" }
9
+ ];
10
+
11
+ for (const row of rows) {
12
+ const existing = await db.query.roles.findFirst({ where: eq(roles.name, row.name) });
13
+ if (!existing) {
14
+ await db.insert(roles).values({ name: row.name });
15
+ }
16
+ }
17
+
18
+ console.log("Role seeder completed");
19
+ }
@@ -0,0 +1,33 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { db, password } from "@/framework/facade.js";
3
+ import { roles } from "@/modules/auth/database/models/role.js";
4
+ import { users } from "@/modules/auth/database/models/user.js";
5
+
6
+ export default async function UserSeeder() {
7
+ const adminRole = await db.query.roles.findFirst({ where: eq(roles.name, "admin") });
8
+ const userRole = await db.query.roles.findFirst({ where: eq(roles.name, "user") });
9
+
10
+ const rows = [
11
+ {
12
+ name: "Admin",
13
+ email: "admin@example.com",
14
+ password: await password.hashPassword("Password@123"),
15
+ roleId: adminRole?.id ?? null
16
+ },
17
+ {
18
+ name: "User One",
19
+ email: "user1@example.com",
20
+ password: await password.hashPassword("Password@123"),
21
+ roleId: userRole?.id ?? null
22
+ }
23
+ ];
24
+
25
+ for (const row of rows) {
26
+ const existing = await db.query.users.findFirst({ where: eq(users.email, row.email) });
27
+ if (!existing) {
28
+ await db.insert(users).values(row);
29
+ }
30
+ }
31
+
32
+ console.log("User seeder completed");
33
+ }
@@ -0,0 +1,18 @@
1
+ import { mail, shouldQueue } from "@/framework/facade.js";
2
+
3
+ shouldQueue("user:forget-password", "mail", async (job) => {
4
+ const { email, name, resetUrl } = job.data;
5
+
6
+ await mail.sendMail({
7
+ to: email,
8
+ subject: "Reset Your Password",
9
+ html: `
10
+ <p>Hello ${name},</p>
11
+ <p>Click the link below to reset your password:</p>
12
+ <p><a href="${resetUrl}">${resetUrl}</a></p>
13
+ <p>This link will expire in 15 minutes.</p>
14
+ `
15
+ });
16
+
17
+ return { ok: true, resetUrl };
18
+ });
@@ -0,0 +1,31 @@
1
+ import { dispatchEvent, mail, shouldQueue } from "@/framework/facade.js";
2
+ import { DateTime as Datetime } from "luxon";
3
+
4
+ shouldQueue("user:signup", "mail", async (job) => {
5
+ const { email, name, password, userId } = job.data;
6
+
7
+ await mail.sendMail({
8
+ to: email,
9
+ subject: "Account Creation",
10
+ html: `
11
+ <p>Hello ${name},</p>
12
+ <p>Your account was created successfully.</p>
13
+ <p>Email: ${email}</p>
14
+ <p>Password: ${password}</p>
15
+ `
16
+ });
17
+
18
+ await dispatchEvent(
19
+ "admin.user.registered",
20
+ { userId, name, email, createdAt: Datetime.now() },
21
+ { broadcast: { roles: ["admin"] } }
22
+ );
23
+
24
+ await dispatchEvent(
25
+ "user.registered",
26
+ { message: "Welcome! Your account has been created." },
27
+ { broadcast: { users: [userId] } }
28
+ );
29
+
30
+ return { ok: true, userId };
31
+ });
@@ -0,0 +1,18 @@
1
+ import { mail, shouldQueue } from "@/framework/facade.js";
2
+
3
+ shouldQueue("user:verify-email", "mail", async (job) => {
4
+ const { email, name, verifyUrl } = job.data;
5
+
6
+ await mail.sendMail({
7
+ to: email,
8
+ subject: "Verify Your Email",
9
+ html: `
10
+ <p>Hello ${name},</p>
11
+ <p>Thanks for registering. Please verify your email by clicking the link below:</p>
12
+ <p><a href="${verifyUrl}">${verifyUrl}</a></p>
13
+ <p>This link will expire in 24 hours.</p>
14
+ `
15
+ });
16
+
17
+ return { ok: true, verifyUrl };
18
+ });
@@ -0,0 +1,151 @@
1
+ import { createRoute, createRouter, HttpStatusCodes, jsonContent, z } from "@/framework/facade.js";
2
+ import { authMiddleware } from "@/middlewares/auth-middleware.js";
3
+ import {
4
+ forgotPassword,
5
+ login,
6
+ logout,
7
+ logoutAllDevices,
8
+ me,
9
+ refreshToken,
10
+ register,
11
+ resetPassword,
12
+ verifyEmail
13
+ } from "@/modules/auth/controllers/auth.controller.js";
14
+ import {
15
+ AuthResponseSchema,
16
+ ForgotPasswordSchema,
17
+ LoginSchema,
18
+ MessageSchema,
19
+ RefreshTokenSchema,
20
+ RegisterSchema,
21
+ ResetPasswordSchema,
22
+ VerifyEmailSchema,
23
+ UserSchema
24
+ } from "@/modules/auth/controllers/auth.schema.js";
25
+
26
+ const registerRoute = createRoute({
27
+ path: "/register",
28
+ method: "post",
29
+ tags: ["Auth"],
30
+ description: "Register a new user",
31
+ request: {
32
+ body: jsonContent(RegisterSchema, "Register payload")
33
+ },
34
+ responses: {
35
+ [HttpStatusCodes.CREATED]: jsonContent(AuthResponseSchema, "Registered")
36
+ }
37
+ });
38
+
39
+ const loginRoute = createRoute({
40
+ path: "/login",
41
+ method: "post",
42
+ tags: ["Auth"],
43
+ description: "Login user",
44
+ request: {
45
+ body: jsonContent(LoginSchema, "Login payload")
46
+ },
47
+ responses: {
48
+ [HttpStatusCodes.OK]: jsonContent(AuthResponseSchema, "Logged in")
49
+ }
50
+ });
51
+
52
+ const meRoute = createRoute({
53
+ path: "/me",
54
+ method: "get",
55
+ tags: ["Auth"],
56
+ description: "Get authenticated user",
57
+ responses: {
58
+ [HttpStatusCodes.OK]: jsonContent(
59
+ z.object({ message: z.string(), data: UserSchema }),
60
+ "Authenticated user"
61
+ )
62
+ }
63
+ });
64
+
65
+ const logoutRoute = createRoute({
66
+ path: "/logout",
67
+ method: "post",
68
+ tags: ["Auth"],
69
+ description: "Logout user from current device",
70
+ responses: {
71
+ [HttpStatusCodes.OK]: jsonContent(MessageSchema, "Logged out")
72
+ }
73
+ });
74
+
75
+ const logoutAllDevicesRoute = createRoute({
76
+ path: "/logout-all",
77
+ method: "post",
78
+ tags: ["Auth"],
79
+ description: "Logout user from all devices",
80
+ responses: {
81
+ [HttpStatusCodes.OK]: jsonContent(MessageSchema, "Logged out from all devices")
82
+ }
83
+ });
84
+
85
+ const forgotPasswordRoute = createRoute({
86
+ path: "/forgot-password",
87
+ method: "post",
88
+ tags: ["Auth"],
89
+ description: "Send reset password email",
90
+ request: {
91
+ body: jsonContent(ForgotPasswordSchema, "Forgot password payload")
92
+ },
93
+ responses: {
94
+ [HttpStatusCodes.OK]: jsonContent(MessageSchema, "Reset email sent")
95
+ }
96
+ });
97
+
98
+ const resetPasswordRoute = createRoute({
99
+ path: "/reset-password",
100
+ method: "post",
101
+ tags: ["Auth"],
102
+ description: "Reset password using token",
103
+ request: {
104
+ body: jsonContent(ResetPasswordSchema, "Reset password payload")
105
+ },
106
+ responses: {
107
+ [HttpStatusCodes.OK]: jsonContent(MessageSchema, "Password reset")
108
+ }
109
+ });
110
+
111
+ const refreshTokenRoute = createRoute({
112
+ path: "/refresh-token",
113
+ method: "post",
114
+ tags: ["Auth"],
115
+ description: "Refresh access token",
116
+ request: {
117
+ body: jsonContent(RefreshTokenSchema, "Refresh token payload")
118
+ },
119
+ responses: {
120
+ [HttpStatusCodes.OK]: jsonContent(AuthResponseSchema, "Token refreshed")
121
+ }
122
+ });
123
+
124
+ const verifyEmailRoute = createRoute({
125
+ path: "/verify-email",
126
+ method: "post",
127
+ tags: ["Auth"],
128
+ description: "Verify user email using token",
129
+ request: {
130
+ body: jsonContent(VerifyEmailSchema, "Verify email payload")
131
+ },
132
+ responses: {
133
+ [HttpStatusCodes.OK]: jsonContent(MessageSchema, "Email verified")
134
+ }
135
+ });
136
+
137
+ const publicRoute = createRouter()
138
+ .api(registerRoute, register)
139
+ .api(loginRoute, login)
140
+ .api(forgotPasswordRoute, forgotPassword)
141
+ .api(resetPasswordRoute, resetPassword)
142
+ .api(verifyEmailRoute, verifyEmail)
143
+ .api(refreshTokenRoute, refreshToken);
144
+
145
+ const protectedRoute = createRouter()
146
+ .group(authMiddleware)
147
+ .api(meRoute, me)
148
+ .api(logoutRoute, logout)
149
+ .api(logoutAllDevicesRoute, logoutAllDevices);
150
+
151
+ export default createRouter().route("/", publicRoute).route("/", protectedRoute);
@@ -0,0 +1,39 @@
1
+ import { createRoute, createRouter, HttpStatusCodes, jsonContent, z } from "@/framework/facade.js";
2
+ import { authMiddleware } from "@/middlewares/auth-middleware.js";
3
+ import { requireRole } from "@/middlewares/role-middleware.js";
4
+ import { index, show } from "@/modules/auth/controllers/role.controller.js";
5
+ import { IdParamsSchema, RoleSchema } from "@/modules/auth/controllers/auth.schema.js";
6
+
7
+ const indexRoute = createRoute({
8
+ path: "/role",
9
+ method: "get",
10
+ tags: ["Role"],
11
+ description: "List all roles",
12
+ responses: {
13
+ [HttpStatusCodes.OK]: jsonContent(
14
+ z.object({ message: z.string(), data: z.array(RoleSchema) }),
15
+ "Role list"
16
+ )
17
+ }
18
+ });
19
+
20
+ const showRoute = createRoute({
21
+ path: "/role/{id}",
22
+ method: "get",
23
+ tags: ["Role"],
24
+ description: "Show one role",
25
+ request: {
26
+ params: IdParamsSchema
27
+ },
28
+ responses: {
29
+ [HttpStatusCodes.OK]: jsonContent(
30
+ z.object({ message: z.string(), data: RoleSchema.nullable() }),
31
+ "Role item"
32
+ )
33
+ }
34
+ });
35
+
36
+ export default createRouter()
37
+ .group(authMiddleware)
38
+ .api(indexRoute, [requireRole("admin")], index)
39
+ .api(showRoute, [requireRole("admin")], show);
@@ -0,0 +1,14 @@
1
+ import type { Handler } from "hono";
2
+ import { cache } from "@/framework/facade.js";
3
+
4
+ // Why: Provides a stable starter endpoint for health/demo responses.
5
+ // When: Used when clients need a quick read-only payload without auth.
6
+ // Where: Mounted at the welcome module root route.
7
+ export const index: Handler = async (c) => {
8
+ const data = await cache.remember("welcome:index", 60, async () => [
9
+ { id: 1, title: "nexgen framework ready" },
10
+ { id: 2, title: "modules are auto-discovered" }
11
+ ]);
12
+
13
+ return c.json({ message: "Success", data });
14
+ };
@@ -0,0 +1,6 @@
1
+ import { z } from "@hono/zod-openapi";
2
+
3
+ export const WelcomeSchema = z.object({
4
+ id: z.number(),
5
+ title: z.string()
6
+ });
@@ -0,0 +1,6 @@
1
+ import { mysqlTable, int, varchar } from "drizzle-orm/mysql-core";
2
+
3
+ export const welcomes = mysqlTable("welcomes", {
4
+ id: int("id").autoincrement().primaryKey(),
5
+ title: varchar("title", { length: 255 }).notNull()
6
+ });
@@ -0,0 +1,20 @@
1
+ import { createRoute, createRouter, HttpStatusCodes, jsonContent, z } from "@/framework/facade.js";
2
+ import { index } from "@/modules/welcome/controllers/welcome.controller.js";
3
+ import { WelcomeSchema } from "@/modules/welcome/controllers/welcome.schema.js";
4
+
5
+ const indexRoute = createRoute({
6
+ path: "/",
7
+ method: "get",
8
+ tags: ["Welcome"],
9
+ responses: {
10
+ [HttpStatusCodes.OK]: jsonContent(
11
+ z.object({
12
+ message: z.string(),
13
+ data: z.array(WelcomeSchema)
14
+ }),
15
+ "Welcome list"
16
+ )
17
+ }
18
+ });
19
+
20
+ export default createRouter().api(indexRoute, index);
@@ -0,0 +1,16 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" type="image/x-icon" href="../admin/src/assets/images/favicon/favicon.ico" />
7
+ <title>NEXGEN</title>
8
+ </head>
9
+
10
+ <body>
11
+ <div id="modal-show"></div>
12
+ <div id="toast-show"></div>
13
+ <div id="app"></div>
14
+ <script type="module" src="/src/main.ts"></script>
15
+ </body>
16
+ </html>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <router-view />
3
+ </template>
4
+
5
+ <script setup lang="ts"></script>