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.
- package/package.json +26 -0
- package/src/index.js +108 -0
- package/template/.dockerignore +14 -0
- package/template/.env +58 -0
- package/template/.env.example +59 -0
- package/template/.prettierignore +5 -0
- package/template/.prettierrc +8 -0
- package/template/README.md +447 -0
- package/template/drizzle.config.ts +29 -0
- package/template/eslint.config.js +52 -0
- package/template/gitignore-stub +24 -0
- package/template/package.json +96 -0
- package/template/public/assets/AuthLayout-CbswhpjJ.js +1 -0
- package/template/public/assets/Button-_7aQ7gHL.js +1 -0
- package/template/public/assets/Input-CLNJXmKc.css +1 -0
- package/template/public/assets/Input-z8GI8Aqo.js +1 -0
- package/template/public/assets/InputPasswordToggle-BxlzVGp3.js +1 -0
- package/template/public/assets/InputPasswordToggle-C77FI9Eg.css +1 -0
- package/template/public/assets/Layout-DotR1sQC.js +1 -0
- package/template/public/assets/Refresh-BdqsPPBC.js +1 -0
- package/template/public/assets/admin-ui-CU34rLdN.js +1 -0
- package/template/public/assets/bootstrap-icons-BeopsB42.woff +0 -0
- package/template/public/assets/bootstrap-icons-mSm7cUeB.woff2 +0 -0
- package/template/public/assets/dashboard-CwybEyLc.js +1 -0
- package/template/public/assets/dashboard-Dc4d-Pi7.css +1 -0
- package/template/public/assets/forgetPassword-CKEJaXsq.js +1 -0
- package/template/public/assets/index-Bleyx5dm.js +64 -0
- package/template/public/assets/index-DUw8E6Yg.css +1 -0
- package/template/public/assets/login-DC7PTlQF.js +1 -0
- package/template/public/assets/realtime-test-BPQdrFym.css +1 -0
- package/template/public/assets/realtime-test-tQZ0rBEJ.js +1 -0
- package/template/public/assets/register-3O7Qs28C.js +1 -0
- package/template/public/assets/resetPassword-A5AzMWKs.js +1 -0
- package/template/public/assets/verifyEmail-DDBEQHOv.js +1 -0
- package/template/public/index.html +17 -0
- package/template/src/database/migrations/mysql/0000_init.sql +73 -0
- package/template/src/database/migrations/mysql/meta/0000_snapshot.json +484 -0
- package/template/src/database/migrations/mysql/meta/_journal.json +13 -0
- package/template/src/database/schema.ts +4 -0
- package/template/src/env.ts +107 -0
- package/template/src/framework/cache/cache.ts +81 -0
- package/template/src/framework/database/connection.ts +168 -0
- package/template/src/framework/database/optional-db-drivers.d.ts +9 -0
- package/template/src/framework/database/paginate.ts +200 -0
- package/template/src/framework/database/schema.ts +26 -0
- package/template/src/framework/database/seed.ts +33 -0
- package/template/src/framework/events/dispatcher.ts +57 -0
- package/template/src/framework/facade.ts +27 -0
- package/template/src/framework/http/app.ts +61 -0
- package/template/src/framework/http/cors.ts +19 -0
- package/template/src/framework/http/logger.ts +85 -0
- package/template/src/framework/http/openapi.ts +34 -0
- package/template/src/framework/http/ratelimiter.ts +13 -0
- package/template/src/framework/http/router.ts +76 -0
- package/template/src/framework/http/static.ts +33 -0
- package/template/src/framework/http/validation.ts +24 -0
- package/template/src/framework/kernel.ts +40 -0
- package/template/src/framework/maker-cli/src/index.mjs +51 -0
- package/template/src/framework/maker-cli/src/levels/level-1/env-db.mjs +57 -0
- package/template/src/framework/maker-cli/src/levels/level-1/file-ops.mjs +30 -0
- package/template/src/framework/maker-cli/src/levels/level-1/flags.mjs +16 -0
- package/template/src/framework/maker-cli/src/levels/level-1/help.mjs +24 -0
- package/template/src/framework/maker-cli/src/levels/level-1/naming.mjs +13 -0
- package/template/src/framework/maker-cli/src/levels/level-1/process.mjs +47 -0
- package/template/src/framework/maker-cli/src/levels/level-2/db/core.mjs +299 -0
- package/template/src/framework/maker-cli/src/levels/level-2/db/index.mjs +177 -0
- package/template/src/framework/maker-cli/src/levels/level-2/deploy/core.mjs +635 -0
- package/template/src/framework/maker-cli/src/levels/level-2/deploy/index.mjs +145 -0
- package/template/src/framework/maker-cli/src/levels/level-2/module/core.mjs +707 -0
- package/template/src/framework/maker-cli/src/levels/level-2/module/index.mjs +116 -0
- package/template/src/framework/maker-cli/src/levels/level-2/runtime/build-frontend.mjs +16 -0
- package/template/src/framework/maker-cli/src/levels/level-2/runtime/core.mjs +311 -0
- package/template/src/framework/maker-cli/src/levels/level-2/runtime/index.mjs +71 -0
- package/template/src/framework/maker-cli/stubs/controller/openapi.ts.stub +55 -0
- package/template/src/framework/maker-cli/stubs/controller/openapi.with-model.ts.stub +56 -0
- package/template/src/framework/maker-cli/stubs/controller/plain.ts.stub +57 -0
- package/template/src/framework/maker-cli/stubs/controller/schema.plain.ts.stub +13 -0
- package/template/src/framework/maker-cli/stubs/controller/schema.ts.stub +32 -0
- package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.bun.stub +49 -0
- package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.pnpm.stub +53 -0
- package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.stub +49 -0
- package/template/src/framework/maker-cli/stubs/deploy/Dockerfile.yarn.stub +53 -0
- package/template/src/framework/maker-cli/stubs/deploy/README.stub +55 -0
- package/template/src/framework/maker-cli/stubs/deploy/compose/mysql.server.stub +29 -0
- package/template/src/framework/maker-cli/stubs/deploy/compose/postgres.server.stub +29 -0
- package/template/src/framework/maker-cli/stubs/deploy/compose/sqlite.stub +29 -0
- package/template/src/framework/maker-cli/stubs/deploy/env/mysql.server.stub +73 -0
- package/template/src/framework/maker-cli/stubs/deploy/env/postgres.server.stub +73 -0
- package/template/src/framework/maker-cli/stubs/deploy/env/sqlite.stub +72 -0
- package/template/src/framework/maker-cli/stubs/deploy/scripts/auto-migrate.sh.stub +15 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/README.stub +77 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/compose/noredis.stub +118 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/compose/redis.dev.stub +131 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/compose/redis.stub +129 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/env/local.example.stub +10 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/env/noredis.stub +24 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/env/redis.stub +24 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/README.stub +15 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/app.example.com.stub +12 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/pgadmin/servers.stub +13 -0
- package/template/src/framework/maker-cli/stubs/deploy/server/redis/redis.conf.stub +6 -0
- package/template/src/framework/maker-cli/stubs/deploy/supervisor/noredis.stub +53 -0
- package/template/src/framework/maker-cli/stubs/deploy/supervisor/redis.stub +69 -0
- package/template/src/framework/maker-cli/stubs/deploy/workflow/local.json.stub +24 -0
- package/template/src/framework/maker-cli/stubs/deploy/workflow/remote.json.stub +20 -0
- package/template/src/framework/maker-cli/stubs/example/console.ts.stub +33 -0
- package/template/src/framework/maker-cli/stubs/example/controller.ts.stub +503 -0
- package/template/src/framework/maker-cli/stubs/example/job.ts.stub +74 -0
- package/template/src/framework/maker-cli/stubs/example/route.api.ts.stub +206 -0
- package/template/src/framework/maker-cli/stubs/example/schema.ts.stub +41 -0
- package/template/src/framework/maker-cli/stubs/job/name.ts.stub +24 -0
- package/template/src/framework/maker-cli/stubs/model/name.mysql.ts.stub +8 -0
- package/template/src/framework/maker-cli/stubs/model/name.postgresql.ts.stub +8 -0
- package/template/src/framework/maker-cli/stubs/model/name.sqlite.ts.stub +8 -0
- package/template/src/framework/maker-cli/stubs/notification/NotificationBell.vue.stub +218 -0
- package/template/src/framework/maker-cli/stubs/notification/controller.ts.stub +85 -0
- package/template/src/framework/maker-cli/stubs/notification/index.vue.stub +211 -0
- package/template/src/framework/maker-cli/stubs/notification/job.ts.stub +12 -0
- package/template/src/framework/maker-cli/stubs/notification/route.api.ts.stub +49 -0
- package/template/src/framework/maker-cli/stubs/notification/schema.ts.stub +25 -0
- package/template/src/framework/maker-cli/stubs/route/api.ts.stub +79 -0
- package/template/src/framework/maker-cli/stubs/route/plain.ts.stub +10 -0
- package/template/src/framework/maker-cli/stubs/schedule/name.ts.stub +35 -0
- package/template/src/framework/maker-cli/stubs/seeder/name.ts.stub +17 -0
- package/template/src/framework/modules/discover.ts +54 -0
- package/template/src/framework/modules/routes.ts +26 -0
- package/template/src/framework/notification/index.ts +109 -0
- package/template/src/framework/queue/clear.ts +20 -0
- package/template/src/framework/queue/queue.ts +213 -0
- package/template/src/framework/queue/ui.ts +104 -0
- package/template/src/framework/queue/worker.ts +33 -0
- package/template/src/framework/realtime/broadcast.ts +27 -0
- package/template/src/framework/realtime/index.ts +1 -0
- package/template/src/framework/realtime/socket-cookie.ts +65 -0
- package/template/src/framework/realtime/socket.ts +132 -0
- package/template/src/framework/realtime/types.ts +6 -0
- package/template/src/framework/realtime/ui.ts +16 -0
- package/template/src/framework/redis/client.ts +126 -0
- package/template/src/framework/scheduler/lock.ts +124 -0
- package/template/src/framework/scheduler/run.ts +26 -0
- package/template/src/framework/scheduler/scheduler.ts +82 -0
- package/template/src/framework/server.ts +147 -0
- package/template/src/framework/session/session.ts +116 -0
- package/template/src/framework/storage/storage.ts +743 -0
- package/template/src/framework/support/cookie.ts +78 -0
- package/template/src/framework/support/jwt.ts +45 -0
- package/template/src/framework/support/lifecycle.ts +35 -0
- package/template/src/framework/support/logger.ts +102 -0
- package/template/src/framework/support/mail.ts +43 -0
- package/template/src/framework/support/password.ts +23 -0
- package/template/src/framework/support/url.ts +25 -0
- package/template/src/middlewares/auth-middleware.ts +98 -0
- package/template/src/middlewares/role-middleware.ts +24 -0
- package/template/src/modules/auth/controllers/auth.controller.ts +445 -0
- package/template/src/modules/auth/controllers/auth.helpers.ts +110 -0
- package/template/src/modules/auth/controllers/auth.schema.ts +102 -0
- package/template/src/modules/auth/controllers/role.controller.ts +25 -0
- package/template/src/modules/auth/database/models/notifications.ts +22 -0
- package/template/src/modules/auth/database/models/role.ts +14 -0
- package/template/src/modules/auth/database/models/user.ts +46 -0
- package/template/src/modules/auth/database/seeders/role.ts +19 -0
- package/template/src/modules/auth/database/seeders/user.ts +33 -0
- package/template/src/modules/auth/jobs/forgetpass.ts +18 -0
- package/template/src/modules/auth/jobs/registeruser.ts +31 -0
- package/template/src/modules/auth/jobs/verifyemail.ts +18 -0
- package/template/src/modules/auth/routes/api.ts +151 -0
- package/template/src/modules/auth/routes/role.ts +39 -0
- package/template/src/modules/welcome/controllers/welcome.controller.ts +14 -0
- package/template/src/modules/welcome/controllers/welcome.schema.ts +6 -0
- package/template/src/modules/welcome/database/models/welcome.ts +6 -0
- package/template/src/modules/welcome/routes/api.ts +20 -0
- package/template/src/resources/index.html +16 -0
- package/template/src/resources/src/App.vue +5 -0
- package/template/src/resources/src/assets/css/styles.css +14934 -0
- package/template/src/resources/src/assets/css/styles.css.map +1 -0
- package/template/src/resources/src/assets/images/favicon/favicon.ico +0 -0
- package/template/src/resources/src/assets/images/favicon/favicon1.ico +0 -0
- package/template/src/resources/src/assets/images/logo-1.png +0 -0
- package/template/src/resources/src/assets/images/logo-dark-sm.png +0 -0
- package/template/src/resources/src/assets/images/logo-dark.png +0 -0
- package/template/src/resources/src/assets/images/logo-dark1.png +0 -0
- package/template/src/resources/src/assets/images/logo-sm.png +0 -0
- package/template/src/resources/src/assets/images/logo1.png +0 -0
- package/template/src/resources/src/assets/images/logo2.png +0 -0
- package/template/src/resources/src/assets/scss/custom.css +217 -0
- package/template/src/resources/src/assets/scss/custom.css.map +1 -0
- package/template/src/resources/src/assets/scss/custom.scss +1100 -0
- package/template/src/resources/src/components/Button.vue +35 -0
- package/template/src/resources/src/components/Checkbox.vue +29 -0
- package/template/src/resources/src/components/FloatButton.vue +36 -0
- package/template/src/resources/src/components/Href.vue +32 -0
- package/template/src/resources/src/components/Input.vue +227 -0
- package/template/src/resources/src/components/InputGroup.vue +153 -0
- package/template/src/resources/src/components/InputPasswordToggle.vue +226 -0
- package/template/src/resources/src/components/Modal.vue +102 -0
- package/template/src/resources/src/components/Pagebar.vue +28 -0
- package/template/src/resources/src/components/Refresh.vue +26 -0
- package/template/src/resources/src/components/Select.vue +390 -0
- package/template/src/resources/src/components/Spinner.vue +42 -0
- package/template/src/resources/src/components/Switch.vue +65 -0
- package/template/src/resources/src/components/TextArea.vue +121 -0
- package/template/src/resources/src/components/Toast.vue +56 -0
- package/template/src/resources/src/components/datatable/DataTableSkeleton.vue +99 -0
- package/template/src/resources/src/components/datatable/Pagination.vue +161 -0
- package/template/src/resources/src/components/datatable/SelectOpption.vue +54 -0
- package/template/src/resources/src/components/datatable/index.vue +237 -0
- package/template/src/resources/src/composables/useAuth.ts +52 -0
- package/template/src/resources/src/composables/useBrowserDetect.ts +5 -0
- package/template/src/resources/src/composables/useDialog.ts +5 -0
- package/template/src/resources/src/composables/useGum.ts +3 -0
- package/template/src/resources/src/composables/usePulse.ts +5 -0
- package/template/src/resources/src/env.d.ts +20 -0
- package/template/src/resources/src/helpers/nformatter.ts +10 -0
- package/template/src/resources/src/helpers/utils.ts +68 -0
- package/template/src/resources/src/layouts/AuthLayout.vue +20 -0
- package/template/src/resources/src/layouts/Layout/Footer.vue +23 -0
- package/template/src/resources/src/layouts/Layout/Header.vue +90 -0
- package/template/src/resources/src/layouts/Layout/Sidebar.vue +137 -0
- package/template/src/resources/src/layouts/Layout/index.vue +76 -0
- package/template/src/resources/src/main.ts +27 -0
- package/template/src/resources/src/pages/auth/forgetPassword.vue +76 -0
- package/template/src/resources/src/pages/auth/login.vue +93 -0
- package/template/src/resources/src/pages/auth/register.vue +130 -0
- package/template/src/resources/src/pages/auth/resetPassword.vue +119 -0
- package/template/src/resources/src/pages/auth/verifyEmail.vue +60 -0
- package/template/src/resources/src/pages/dashboard/index.vue +76 -0
- package/template/src/resources/src/plugins/axios.ts +33 -0
- package/template/src/resources/src/plugins/browserDetect.ts +55 -0
- package/template/src/resources/src/plugins/dialog.ts +167 -0
- package/template/src/resources/src/plugins/gum.ts +343 -0
- package/template/src/resources/src/plugins/pulse.ts +141 -0
- package/template/src/resources/src/plugins/routeProgress.ts +87 -0
- package/template/src/resources/src/router/index.ts +85 -0
- package/template/src/resources/src/stores/admin-ui.ts +148 -0
- package/template/src/resources/src/stores/auth.ts +151 -0
- package/template/src/resources/tsconfig.json +19 -0
- package/template/src/resources/vite.config.ts +43 -0
- package/template/src/storage/logs/app.log +20179 -0
- package/template/src/storage/logs/fatal.log +727 -0
- package/template/tsconfig.json +20 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
# nexgen
|
|
2
|
+
|
|
3
|
+
**nexgen** is a full-stack TypeScript framework for building modern web applications. It combines a modular backend architecture with a Vue 3 single-page application frontend, providing everything you need out of the box:
|
|
4
|
+
|
|
5
|
+
- **API** — [Hono](https://hono.dev) HTTP server with Zod validation and OpenAPI docs
|
|
6
|
+
- **Frontend** — [Vue 3](https://vuejs.org) SPA with Pinia, Vue Router, and real-time Pulse integration
|
|
7
|
+
- **Database** — [Drizzle ORM](https://orm.drizzle.team) with SQLite, MySQL, and PostgreSQL support
|
|
8
|
+
- **Queue** — [BullMQ](https://docs.bullmq.io) for background job processing
|
|
9
|
+
- **Realtime** — [Socket.IO](https://socket.io) for bidirectional event broadcasting
|
|
10
|
+
- **Cache & Session** — Redis-backed with graceful fallback
|
|
11
|
+
- **CLI** — `maker` command for code generation, migrations, runtime, and deploy
|
|
12
|
+
- **Deploy** — Docker Compose with nginx-proxy, auto SSL, and supervisor
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Quick Start](#quick-start)
|
|
17
|
+
- [Architecture](#architecture)
|
|
18
|
+
- [Modules](#modules)
|
|
19
|
+
- [Database](#database)
|
|
20
|
+
- [Events & Queue](#events--queue)
|
|
21
|
+
- [Scheduler](#scheduler)
|
|
22
|
+
- [Realtime](#realtime)
|
|
23
|
+
- [Storage](#storage)
|
|
24
|
+
- [CLI Reference](#cli-reference)
|
|
25
|
+
- [Deploy](#deploy)
|
|
26
|
+
- [Optional Packages](#optional-packages)
|
|
27
|
+
- [Full Documentation](#full-documentation)
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cp .env.example .env
|
|
33
|
+
npm install
|
|
34
|
+
npm run maker db:schema
|
|
35
|
+
npm run maker db:seed
|
|
36
|
+
npm run maker dev
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This starts the API server, Vue 3 frontend, and queue worker (if Redis enabled) in parallel.
|
|
40
|
+
|
|
41
|
+
### Package Manager
|
|
42
|
+
|
|
43
|
+
Commands in this README use `bun maker` as shorthand. Use the equivalent for your package manager:
|
|
44
|
+
|
|
45
|
+
| Manager | Command |
|
|
46
|
+
|---|---|
|
|
47
|
+
| npm | `npm run maker -- <command>` |
|
|
48
|
+
| pnpm | `pnpm maker <command>` |
|
|
49
|
+
| yarn | `yarn maker <command>` |
|
|
50
|
+
| bun | `bun maker <command>` |
|
|
51
|
+
|
|
52
|
+
## Architecture
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
src/
|
|
56
|
+
├── env.ts # Environment configuration (Zod validated)
|
|
57
|
+
├── database/ # Drizzle schema, migrations, seeders
|
|
58
|
+
├── framework/ # Framework internals (reusable engine)
|
|
59
|
+
│ ├── server.ts # HTTP server entrypoint
|
|
60
|
+
│ ├── kernel.ts # App kernel (boots all subsystems)
|
|
61
|
+
│ ├── facade.ts # Public API surface
|
|
62
|
+
│ ├── http/ # Router, middleware, OpenAPI, static files
|
|
63
|
+
│ ├── database/ # Connection, pagination
|
|
64
|
+
│ ├── events/ # Command & event dispatcher
|
|
65
|
+
│ ├── queue/ # BullMQ queue, worker, dashboard
|
|
66
|
+
│ ├── realtime/ # Socket.IO server, broadcast
|
|
67
|
+
│ ├── cache/ # Redis cache
|
|
68
|
+
│ ├── session/ # Session management
|
|
69
|
+
│ ├── scheduler/ # Cron scheduler
|
|
70
|
+
│ ├── storage/ # File storage (local/S3)
|
|
71
|
+
│ ├── redis/ # Redis client
|
|
72
|
+
│ ├── support/ # JWT, mail, logger, password, URL
|
|
73
|
+
│ └── maker-cli/ # CLI source and stubs
|
|
74
|
+
├── modules/ # Application modules (auto-discovered)
|
|
75
|
+
├── middlewares/ # Auth, role middlewares
|
|
76
|
+
├── resources/ # Vue 3 frontend app
|
|
77
|
+
└── storage/ # Uploaded and generated files
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Boot Sequence
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
server.ts
|
|
84
|
+
└─ createKernel()
|
|
85
|
+
├─ createHttpApp() → Builds Hono app with middleware stack
|
|
86
|
+
│ ├─ sessionMiddleware
|
|
87
|
+
│ ├─ corsMiddleware
|
|
88
|
+
│ ├─ loggerMiddleware
|
|
89
|
+
│ ├─ rateLimiterMiddleware
|
|
90
|
+
│ ├─ OpenAPI docs (if enabled)
|
|
91
|
+
│ └─ Health endpoint
|
|
92
|
+
├─ initDatabase() → Connect configured dialect
|
|
93
|
+
├─ initRedis() → Connect Redis (if enabled)
|
|
94
|
+
├─ bootQueueJobs() → Register queue handlers
|
|
95
|
+
├─ registerModuleRoutes() → Auto-discover routes
|
|
96
|
+
├─ setupBullBoard() → Queue management UI
|
|
97
|
+
└─ Frontend static → Serve SPA if build exists
|
|
98
|
+
└─ serve() → Start HTTP listener
|
|
99
|
+
└─ initRealtime() → Attach Socket.IO
|
|
100
|
+
└─ registerShutdownSignals() → Graceful cleanup
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Request Lifecycle
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
Client → @hono/node-server → sessionMiddleware → corsMiddleware
|
|
107
|
+
→ loggerMiddleware → rateLimiterMiddleware → [module route]
|
|
108
|
+
→ [authMiddleware] → [controller] → JSON response
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Modules
|
|
112
|
+
|
|
113
|
+
Modules are self-contained units under `src/modules/<name>/`. Each module can contain:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
src/modules/blog/
|
|
117
|
+
├── controllers/ # Request handlers + Zod schemas
|
|
118
|
+
│ ├── blog.controller.ts
|
|
119
|
+
│ └── blog.schema.ts
|
|
120
|
+
├── routes/ # Route definitions (auto-discovered)
|
|
121
|
+
│ └── api.ts
|
|
122
|
+
├── database/
|
|
123
|
+
│ ├── models/ # Drizzle table definitions
|
|
124
|
+
│ ├── seeders/ # Database seeders
|
|
125
|
+
│ └── index.ts
|
|
126
|
+
├── jobs/ # Queue job handlers
|
|
127
|
+
└── console/ # Scheduled commands
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Creating a Module
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
bun maker module:make blog
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Adding Components
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
bun maker module:make-controller blog post
|
|
140
|
+
bun maker module:make-route blog post
|
|
141
|
+
bun maker module:make-model blog post
|
|
142
|
+
bun maker module:make-seeder blog post
|
|
143
|
+
bun maker module:make-job blog send-welcome
|
|
144
|
+
bun maker module:make-console blog cleanup
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Facade
|
|
148
|
+
|
|
149
|
+
The framework's public API is exported from `@/framework/facade.js`:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { db, cache, session, queue, dispatchEvent, notify, storage, mail, jwt, password, urls, logger, paginate } from "@/framework/facade.js";
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Database
|
|
156
|
+
|
|
157
|
+
nexgen supports SQLite, MySQL, and PostgreSQL through Drizzle ORM. The active dialect is detected from `DATABASE_URL` in `.env`.
|
|
158
|
+
|
|
159
|
+
### Migrations
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
bun maker db:schema # Generate schema index from all module models
|
|
163
|
+
bun maker db:generate # Generate migration SQL files
|
|
164
|
+
bun maker db:migrate # Generate + run migrations
|
|
165
|
+
bun maker db:migrate --seed
|
|
166
|
+
bun maker db:fresh # Drop all tables, re-migrate, re-seed
|
|
167
|
+
bun maker db:status # List migration files
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Models
|
|
171
|
+
|
|
172
|
+
Models are Drizzle table definitions in `src/modules/<module>/database/models/`. They are auto-detected by dialect and aggregated into `src/database/schema.ts` via `db:schema`.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { sqliteTable, int, text } from "drizzle-orm/sqlite-core";
|
|
176
|
+
|
|
177
|
+
export const posts = sqliteTable("posts", {
|
|
178
|
+
id: int().primaryKey({ autoIncrement: true }),
|
|
179
|
+
title: text().notNull(),
|
|
180
|
+
body: text(),
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Seeders
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
bun maker db:seed # Run all seeders
|
|
188
|
+
bun maker db:seed posts # Run single module seeders
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Pagination
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { db, paginate } from "@/framework/facade.js";
|
|
195
|
+
|
|
196
|
+
const query = db.select().from(posts).orderBy(desc(posts.id));
|
|
197
|
+
const result = await paginate(c, query, 10);
|
|
198
|
+
// { data, meta: { current_page, per_page, total, last_page, from, to }, links: { first, last, prev, next } }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Events & Queue
|
|
202
|
+
|
|
203
|
+
### dispatchEvent
|
|
204
|
+
|
|
205
|
+
Fire domain events that can be broadcast via WebSocket and/or queued as background jobs.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import { dispatchEvent } from "@/framework/facade.js";
|
|
209
|
+
|
|
210
|
+
// Fire event (local in-process)
|
|
211
|
+
await dispatchEvent("user:signup", { userId: 1 });
|
|
212
|
+
|
|
213
|
+
// Fire and queue background job
|
|
214
|
+
await dispatchEvent("user:signup", { userId: 1 }, { queue: "default" });
|
|
215
|
+
|
|
216
|
+
// Fire and broadcast to authenticated users
|
|
217
|
+
await dispatchEvent("post.created", { postId: 1 }, { broadcast: { auth: true } });
|
|
218
|
+
|
|
219
|
+
// Queue, then broadcast from handler (recommended pattern)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Queue Jobs
|
|
223
|
+
|
|
224
|
+
Define handlers in `src/modules/<module>/jobs/*.ts`:
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
import { shouldQueue } from "@/framework/facade.js";
|
|
228
|
+
|
|
229
|
+
shouldQueue("user:signup", "default", async (job) => {
|
|
230
|
+
const { userId } = job.data;
|
|
231
|
+
// Process the job
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Start the worker:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
bun maker queue:work --queue=default,mail
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### dispatchCommand
|
|
242
|
+
|
|
243
|
+
Synchronous command pattern with optional async fallback:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import { command, dispatchCommand } from "@/framework/facade.js";
|
|
247
|
+
|
|
248
|
+
command("send-welcome-email", async (payload) => {
|
|
249
|
+
// Handler runs in-process
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
await dispatchCommand("send-welcome-email", { userId: 1 });
|
|
253
|
+
await dispatchCommand("send-welcome-email", { userId: 1 }, { async: true }); // Queue instead
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Scheduler
|
|
257
|
+
|
|
258
|
+
Define scheduled tasks in `src/modules/<module>/console/*.ts`:
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
import { defineSchedule } from "@/framework/facade.js";
|
|
262
|
+
|
|
263
|
+
defineSchedule({
|
|
264
|
+
name: "cleanup-temp-files",
|
|
265
|
+
expression: "*/5 * * * *",
|
|
266
|
+
runOnInit: false,
|
|
267
|
+
ttlMs: 120000,
|
|
268
|
+
handler: async () => {
|
|
269
|
+
// Scheduled task logic
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Start the scheduler:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
bun maker schedule:work
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Realtime
|
|
281
|
+
|
|
282
|
+
### Server-side
|
|
283
|
+
|
|
284
|
+
Broadcast events to connected clients via Socket.IO:
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
await dispatchEvent("chat.message", { text: "Hello" }, {
|
|
288
|
+
broadcast: { users: [recipientId] }
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
await dispatchEvent("admin.alert", { cpu: 92 }, {
|
|
292
|
+
broadcast: { roles: ["admin"] }
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
await dispatchEvent("system.update", { status: "ok" }, {
|
|
296
|
+
broadcast: { all: true }
|
|
297
|
+
});
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Client-side
|
|
301
|
+
|
|
302
|
+
The frontend uses the Pulse plugin for real-time channels:
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
import { pulse } from "@/plugins/pulse";
|
|
306
|
+
|
|
307
|
+
const channel = pulse.channel("user:42");
|
|
308
|
+
channel.listen("notification.created", (data) => {
|
|
309
|
+
showToast(data.title);
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Storage
|
|
314
|
+
|
|
315
|
+
Supports local disk and S3-compatible object storage (AWS S3, DigitalOcean Spaces, Cloudflare R2, MinIO).
|
|
316
|
+
|
|
317
|
+
```env
|
|
318
|
+
STORAGE_DRIVER=s3
|
|
319
|
+
STORAGE_BUCKET=my-bucket
|
|
320
|
+
STORAGE_REGION=us-east-1
|
|
321
|
+
STORAGE_ENDPOINT=
|
|
322
|
+
STORAGE_ACCESS_KEY_ID=
|
|
323
|
+
STORAGE_SECRET_ACCESS_KEY=
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
```ts
|
|
327
|
+
import { storage } from "@/framework/facade.js";
|
|
328
|
+
|
|
329
|
+
const path = await storage.put("uploads/report.pdf", fileBuffer);
|
|
330
|
+
const url = await storage.temporaryUrl(path, 3600);
|
|
331
|
+
await storage.delete(path);
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## CLI Reference
|
|
335
|
+
|
|
336
|
+
### Module Commands
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
bun maker module:make <name> # Create full module scaffold
|
|
340
|
+
bun maker module:make-notification [name] # Generate notification module
|
|
341
|
+
bun maker module:example [name] # Generate example module
|
|
342
|
+
bun maker module:delete <name> # Soft-delete module to trash
|
|
343
|
+
bun maker module:delete-notification [name] # Remove notification module
|
|
344
|
+
bun maker module:trash:clean [name] # Permanently remove trash
|
|
345
|
+
bun maker module:list # List all modules
|
|
346
|
+
bun maker module:seed <module> # Run module seeders
|
|
347
|
+
bun maker module:migrate <module> # Run module migration
|
|
348
|
+
bun maker module:make-route <module> [controller]
|
|
349
|
+
bun maker module:make-controller <module> [name]
|
|
350
|
+
bun maker module:make-model <module> [name]
|
|
351
|
+
bun maker module:make-seeder <module> [name]
|
|
352
|
+
bun maker module:make-job <module> [name]
|
|
353
|
+
bun maker module:make-console <module> [name]
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Database Commands
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
bun maker db:schema # Generate schema index
|
|
360
|
+
bun maker db:generate # Generate migration files
|
|
361
|
+
bun maker db:migrate [--seed] # Run migrations
|
|
362
|
+
bun maker db:migrate:run # Run pending migrations only
|
|
363
|
+
bun maker db:fresh [--seed] # Drop all + re-migrate
|
|
364
|
+
bun maker db:reset # Drop and recreate database
|
|
365
|
+
bun maker db:seed [module] # Run seeders
|
|
366
|
+
bun maker db:status # List migration files
|
|
367
|
+
bun maker db:push # Push schema directly
|
|
368
|
+
bun maker db:studio # Launch Drizzle Studio
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Runtime Commands
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
bun maker dev # Full dev stack
|
|
375
|
+
bun maker dev --view=redis,maildev,studio # Dev stack with tools
|
|
376
|
+
bun maker serve [--prod] # Start API server
|
|
377
|
+
bun maker queue:work [--queue=default] # Start queue worker
|
|
378
|
+
bun maker queue:clear # Clear queue keys
|
|
379
|
+
bun maker schedule:work # Start scheduler
|
|
380
|
+
bun maker frontend:dev # Frontend dev server
|
|
381
|
+
bun maker maildev:view # MailDev web UI
|
|
382
|
+
bun maker redis:view # Redis Commander UI
|
|
383
|
+
bun maker vite:cache:clear # Clear Vite cache
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Deploy Commands
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
bun maker deploy:create --server # Generate deploy scaffolding
|
|
390
|
+
bun maker deploy:server # Start shared infra
|
|
391
|
+
bun maker deploy:app # Build and start app
|
|
392
|
+
bun maker deploy:workflow:local # Full local deploy
|
|
393
|
+
bun maker deploy:workflow:remote # Full remote deploy
|
|
394
|
+
bun maker deploy:workflow:promote # Local then remote deploy
|
|
395
|
+
bun maker deploy:db:import # Import SQL dump
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Deploy
|
|
399
|
+
|
|
400
|
+
nexgen uses a two-layer Docker architecture: shared infrastructure (nginx-proxy, MySQL, PostgreSQL, Redis) runs once per host, and the application stack builds and deploys per release.
|
|
401
|
+
|
|
402
|
+
### Local Deploy
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
bun maker deploy:create --server # Generate files (one-time)
|
|
406
|
+
bun maker deploy:server # Start database, Redis, proxy
|
|
407
|
+
bun maker deploy:app # Build and start app
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Remote Deploy
|
|
411
|
+
|
|
412
|
+
Configure `deploy/workflow.remote.json` with your SSH details, then:
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
bun maker deploy:workflow:remote
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
This rsyncs your project to the server, creates Docker networks, starts the infra, builds and runs the app container with supervisor managing API, queue, and scheduler processes.
|
|
419
|
+
|
|
420
|
+
### Supervisor Inside Container
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
supervisord
|
|
424
|
+
├─ auto-migrate.sh (one-shot, if AUTO_MIGRATE=true)
|
|
425
|
+
├─ maker serve --prod → HTTP API on port 3000
|
|
426
|
+
├─ maker queue:work → BullMQ worker (if Redis enabled)
|
|
427
|
+
└─ maker schedule:work → Cron scheduler
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
See the [deploy documentation](https://niyamulahsan.github.io/nexgen/deploy/overview) for full details.
|
|
431
|
+
|
|
432
|
+
## Optional Packages
|
|
433
|
+
|
|
434
|
+
| Package | Feature | When needed |
|
|
435
|
+
|---|---|---|
|
|
436
|
+
| `exceljs` | Excel import/export | If using `/examples/download/excel/*` endpoints |
|
|
437
|
+
| `playwright` | PDF export | If using `/examples/download/pdf/*` endpoints |
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
npm i exceljs
|
|
441
|
+
npm i playwright
|
|
442
|
+
npx playwright install chromium
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
## Full Documentation
|
|
446
|
+
|
|
447
|
+
Complete documentation is available at **[https://niyamulahsan.github.io/nexgen](https://niyamulahsan.github.io/nexgen)**
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { config } from "dotenv";
|
|
2
|
+
import { defineConfig } from "drizzle-kit";
|
|
3
|
+
|
|
4
|
+
config({ path: ".env" });
|
|
5
|
+
|
|
6
|
+
function sqlitePathFromUrl(url: string) {
|
|
7
|
+
if (url.startsWith("sqlite:///")) return url.replace("sqlite:///", "/");
|
|
8
|
+
if (url.startsWith("sqlite://")) return url.replace("sqlite://", "");
|
|
9
|
+
if (url.startsWith("sqlite:")) return url.replace("sqlite:", "");
|
|
10
|
+
return url;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const databaseUrl = process.env.DATABASE_URL || "sqlite:./src/storage/database/nexgen.sqlite";
|
|
14
|
+
const dialect = databaseUrl.startsWith("mysql")
|
|
15
|
+
? "mysql"
|
|
16
|
+
: databaseUrl.startsWith("postgres")
|
|
17
|
+
? "postgresql"
|
|
18
|
+
: "sqlite";
|
|
19
|
+
|
|
20
|
+
export default defineConfig({
|
|
21
|
+
schema: process.env.DRIZZLE_SCHEMA || "./src/database/schema.ts",
|
|
22
|
+
out: `./src/database/migrations/${dialect}`,
|
|
23
|
+
dialect,
|
|
24
|
+
dbCredentials: databaseUrl.startsWith("mysql")
|
|
25
|
+
? { url: databaseUrl }
|
|
26
|
+
: databaseUrl.startsWith("postgres")
|
|
27
|
+
? { url: databaseUrl }
|
|
28
|
+
: { url: sqlitePathFromUrl(databaseUrl) }
|
|
29
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import globals from "globals";
|
|
3
|
+
import tsParser from "@typescript-eslint/parser";
|
|
4
|
+
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
|
5
|
+
import vueParser from "vue-eslint-parser";
|
|
6
|
+
import vuePlugin from "eslint-plugin-vue";
|
|
7
|
+
import eslintConfigPrettier from "eslint-config-prettier";
|
|
8
|
+
|
|
9
|
+
export default [
|
|
10
|
+
{
|
|
11
|
+
ignores: ["node_modules/**", "dist/**", "src/resources/dist/**", "coverage/**", "**/*.d.ts"]
|
|
12
|
+
},
|
|
13
|
+
js.configs.recommended,
|
|
14
|
+
...vuePlugin.configs["flat/recommended"],
|
|
15
|
+
{
|
|
16
|
+
files: ["**/*.{js,mjs,cjs,ts,tsx,vue}"],
|
|
17
|
+
languageOptions: {
|
|
18
|
+
parser: vueParser,
|
|
19
|
+
parserOptions: {
|
|
20
|
+
parser: tsParser,
|
|
21
|
+
ecmaVersion: "latest",
|
|
22
|
+
sourceType: "module",
|
|
23
|
+
extraFileExtensions: [".vue"]
|
|
24
|
+
},
|
|
25
|
+
globals: {
|
|
26
|
+
...globals.node,
|
|
27
|
+
...globals.browser
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
plugins: {
|
|
31
|
+
"@typescript-eslint": tsPlugin
|
|
32
|
+
},
|
|
33
|
+
rules: {
|
|
34
|
+
"no-empty": "off",
|
|
35
|
+
"no-useless-escape": "off",
|
|
36
|
+
"no-redeclare": "off",
|
|
37
|
+
"no-unused-vars": "off",
|
|
38
|
+
"@typescript-eslint/no-unused-vars": [
|
|
39
|
+
"warn",
|
|
40
|
+
{
|
|
41
|
+
argsIgnorePattern: "^_",
|
|
42
|
+
varsIgnorePattern: "^_"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"vue/multi-word-component-names": "off",
|
|
46
|
+
"vue/no-reserved-component-names": "off",
|
|
47
|
+
"vue/valid-template-root": "off",
|
|
48
|
+
"vue/no-ref-as-operand": "off"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
eslintConfigPrettier
|
|
52
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.env
|
|
2
|
+
node_modules/
|
|
3
|
+
dist/
|
|
4
|
+
|
|
5
|
+
public/*
|
|
6
|
+
!public/.gitkeep
|
|
7
|
+
|
|
8
|
+
deploy/.env
|
|
9
|
+
deploy/server/.env
|
|
10
|
+
|
|
11
|
+
*.log
|
|
12
|
+
npm-debug.log*
|
|
13
|
+
yarn-debug.log*
|
|
14
|
+
yarn-error.log*
|
|
15
|
+
pnpm-debug.log*
|
|
16
|
+
|
|
17
|
+
.DS_Store
|
|
18
|
+
Thumbs.db
|
|
19
|
+
|
|
20
|
+
# Lock files — regenerated per developer's package manager
|
|
21
|
+
bun.lock
|
|
22
|
+
package-lock.json
|
|
23
|
+
pnpm-lock.yaml
|
|
24
|
+
yarn.lock
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nexgen",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"bin": {
|
|
7
|
+
"maker": "./src/framework/maker-cli/src/index.mjs"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "npm run build:all",
|
|
11
|
+
"build:all": "npm run build:backend && npm run build:frontend",
|
|
12
|
+
"build:backend": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
|
13
|
+
"build:frontend": "node src/framework/maker-cli/src/levels/level-2/runtime/build-frontend.mjs",
|
|
14
|
+
"dev": "node src/framework/maker-cli/src/index.mjs dev",
|
|
15
|
+
"frontend": "node src/framework/maker-cli/src/index.mjs frontend:dev",
|
|
16
|
+
"maildev:view": "node src/framework/maker-cli/src/index.mjs maildev:view",
|
|
17
|
+
"redis:view": "node src/framework/maker-cli/src/index.mjs redis:view",
|
|
18
|
+
"db:studio": "node src/framework/maker-cli/src/index.mjs db:studio",
|
|
19
|
+
"maker": "node src/framework/maker-cli/src/index.mjs",
|
|
20
|
+
"lint": "eslint .",
|
|
21
|
+
"lint:fix": "eslint . --fix",
|
|
22
|
+
"format": "prettier . --write",
|
|
23
|
+
"format:check": "prettier . --check"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@aws-sdk/client-s3": "^3.1045.0",
|
|
27
|
+
"@aws-sdk/s3-request-presigner": "^3.1045.0",
|
|
28
|
+
"@bull-board/api": "^7.1.5",
|
|
29
|
+
"@bull-board/hono": "^7.1.5",
|
|
30
|
+
"@hono/node-server": "^2.0.3",
|
|
31
|
+
"@hono/zod-openapi": "^1.4.0",
|
|
32
|
+
"@scalar/hono-api-reference": "^0.10.14",
|
|
33
|
+
"@socket.io/admin-ui": "^0.5.1",
|
|
34
|
+
"@socket.io/redis-adapter": "^8.3.0",
|
|
35
|
+
"@vitejs/plugin-vue": "^6.0.7",
|
|
36
|
+
"@vueuse/core": "^14.3.0",
|
|
37
|
+
"@vueuse/head": "^2.0.0",
|
|
38
|
+
"axios": "^1.16.0",
|
|
39
|
+
"bcryptjs": "^3.0.3",
|
|
40
|
+
"bootstrap": "^5.3.8",
|
|
41
|
+
"bootstrap-icons": "^1.13.1",
|
|
42
|
+
"bullmq": "^5.76.6",
|
|
43
|
+
"chalk": "^5.6.2",
|
|
44
|
+
"commander": "^14.0.3",
|
|
45
|
+
"dotenv": "^17.4.2",
|
|
46
|
+
"dotenv-expand": "^13.0.0",
|
|
47
|
+
"drizzle-orm": "^0.45.2",
|
|
48
|
+
"glob": "^13.0.6",
|
|
49
|
+
"hono": "^4.12.18",
|
|
50
|
+
"hono-rate-limiter": "^0.5.3",
|
|
51
|
+
"ioredis": "^5.10.1",
|
|
52
|
+
"lodash-es": "^4.18.1",
|
|
53
|
+
"luxon": "^3.7.2",
|
|
54
|
+
"maildev": "^2.2.1",
|
|
55
|
+
"mime-types": "^3.0.2",
|
|
56
|
+
"mysql2": "^3.22.3",
|
|
57
|
+
"node-cron": "^4.2.1",
|
|
58
|
+
"nodemailer": "^8.0.7",
|
|
59
|
+
"pinia": "^3.0.4",
|
|
60
|
+
"redis-commander": "^0.9.0",
|
|
61
|
+
"sass-embedded": "^1.99.0",
|
|
62
|
+
"socket.io": "^4.8.3",
|
|
63
|
+
"socket.io-client": "^4.8.3",
|
|
64
|
+
"stoker": "^2.0.1",
|
|
65
|
+
"vite": "^8.0.13",
|
|
66
|
+
"vue": "^3.5.34",
|
|
67
|
+
"vue-router": "^5.0.6",
|
|
68
|
+
"vue-select": "^4.0.0-beta.6",
|
|
69
|
+
"winston": "^3.19.0",
|
|
70
|
+
"zod": "^4.4.3"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@eslint/js": "^10.0.1",
|
|
74
|
+
"@types/bootstrap": "^5.2.10",
|
|
75
|
+
"@types/lodash-es": "^4.17.12",
|
|
76
|
+
"@types/node": "^25.9.0",
|
|
77
|
+
"@typescript-eslint/eslint-plugin": "^8.59.2",
|
|
78
|
+
"@typescript-eslint/parser": "^8.59.2",
|
|
79
|
+
"drizzle-kit": "^0.31.10",
|
|
80
|
+
"eslint": "^10.4.0",
|
|
81
|
+
"eslint-config-prettier": "^10.1.8",
|
|
82
|
+
"eslint-plugin-vue": "^10.9.1",
|
|
83
|
+
"globals": "^17.6.0",
|
|
84
|
+
"prettier": "^3.8.3",
|
|
85
|
+
"tsc-alias": "^1.8.17",
|
|
86
|
+
"tsx": "^4.21.0",
|
|
87
|
+
"typescript": "^6.0.3",
|
|
88
|
+
"vue-eslint-parser": "^10.4.0"
|
|
89
|
+
},
|
|
90
|
+
"engines": {
|
|
91
|
+
"node": ">=24 <25",
|
|
92
|
+
"bun": ">=1.3.0 <2",
|
|
93
|
+
"pnpm": ">=10 <11",
|
|
94
|
+
"yarn": ">=1.22.0 <2"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,C as t,D as n,N as r,O as i,_ as a}from"./index-Bleyx5dm.js";import{t as o}from"./admin-ui-CU34rLdN.js";var s=t({__name:`AuthLayout`,setup(t){let s=o();return i(()=>{s.initTheme()}),n(()=>{s.cleanupTheme()}),(t,n)=>{let i=r(`router-view`);return e(),a(i)}}});export{s as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,C as t,H as n,I as r,M as i,T as a,U as o,g as s,h as c,p as l,v as u,y as d}from"./index-Bleyx5dm.js";var f=[`type`],p={key:1},m=t({name:`Button`,inheritAttrs:!1,__name:`Button`,props:{label:{},icon:{},type:{default:`button`}},setup(t){let m=r(),h=t,g=c(()=>!!m.default?.().length);return(t,r)=>(e(),d(`button`,a({class:`d-flex justify-content-center align-items-center custom-btn shadow-none`,type:h.type},t.$attrs),[g.value?i(t.$slots,`default`,{key:0}):(e(),d(l,{key:1},[h.label?(e(),d(`span`,{key:0,class:n([`text-capitalize`,{"me-1":h.icon}])},o(h.label),3)):u(``,!0),h.icon?(e(),d(`span`,p,[s(`i`,{class:n(h.icon)},null,2)])):u(``,!0)],64))],16,f))}});export{m as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.must[data-v-60b4d1ec]{width:4px;height:4px;margin-top:5px;margin-left:2px}.max[data-v-60b4d1ec]{font-size:.6rem}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,C as t,E as n,H as r,O as i,P as a,T as o,U as s,V as c,g as l,h as u,i as d,y as f}from"./index-Bleyx5dm.js";var p=typeof navigator<`u`?navigator.userAgent.toLowerCase():``,m=p.includes(`firefox`),h=p.includes(`edg`),g=p.includes(`opr`)||p.includes(`opera`),_=p.includes(`brave`),v=p.includes(`chrome`)&&!h&&!g&&!_,y=p.includes(`android`),b=p.includes(`safari`)&&!v&&!y,x=/iphone|ipad|ipod/.test(p),S=p.includes(`windows`),C=p.includes(`macintosh`),w={userAgent:p,isFirefox:u(()=>m),isChrome:u(()=>v),isSafari:u(()=>b),isEdge:u(()=>h),isOpera:u(()=>g),isBrave:u(()=>_),isAndroid:u(()=>y),isIOS:u(()=>x),isWindows:u(()=>S),isMac:u(()=>C)};function T(){return w}var E={class:`position-relative`},D=[`for`],O={class:`position-relative`},k=[`innerHTML`],A=[`innerHTML`],j=[`value`,`maxlength`,`readonly`,`autocomplete`],M=[`id`],N=d(t({name:`Input`,inheritAttrs:!1,__name:`Input`,props:{focus:{type:Boolean},must:{type:Boolean},err:{type:[String,Boolean],default:!1},modelValue:{default:``},category:{},hood:{type:[String,Boolean,Number]},readonly:{type:Boolean}},emits:[`update:modelValue`],setup(t,{emit:d}){let{isFirefox:p}=T(),m=a(),h=t,g=u(()=>m.topclass||`mb-2`),_=u(()=>m.id||``),v=u(()=>m.label||``),y=u(()=>m.type||`text`),b=u(()=>{let e=m.maxlength;return e==null?null:Number(e)}),x=u(()=>m.autocomplete||([`number`,`decimal`].includes(h.category??``)?`off`:`on`)),S=u(()=>b.value??void 0),C=u(()=>h.hood===!1||h.hood==null?``:String(h.hood)),w=u(()=>b.value==null||!p&&y.value===`month`?``:b.value-String(h.modelValue).length),N=d,P=e=>{let t=e.target;if(h.category===`number`)N(`update:modelValue`,t.value=t.value.replace(/[^\d]/gi,``));else if(h.category===`decimal`){let e=t.value;e=e.replace(/[^0-9.]/g,``);let n=e.split(`.`);n.length>2&&(e=n[0]+`.`+n.slice(1).join(``)),N(`update:modelValue`,t.value=e)}else if(h.category===`+decimal-`){let e=t.value;e=e.replace(/[^0-9.-]/g,``);let n=e.includes(`-`);e=e.replace(/-/g,``),n&&(e=`-`+e);let r=e.split(`.`);r.length>2&&(e=r[0]+`.`+r.slice(1).join(``)),N(`update:modelValue`,t.value=e)}else if(h.category===`mobile`){let e=t.value.replace(/[^\d]/g,``),n=e;t.value.includes(`+`)&&(n=`+`+e),N(`update:modelValue`,t.value=n)}else if(h.category===`tax-period`){let e=t.value.replace(/[^\d-]/g,``);if(e=e.replace(/-/g,``),e=e.slice(0,6),e.length>4){let t=e.slice(0,4),n=e.slice(4,6);if(n.length===2){let e=parseInt(n,10);e<1&&(e=1),e>12&&(e=12),n=e.toString().padStart(2,`0`)}e=t+`-`+n}N(`update:modelValue`,t.value=e)}else if(h.category===`bin`){let e=t.value.replace(/[^\d]/g,``);e=e.slice(0,14);let n=e;e.length>9&&(n=e.slice(0,9)+`-`+e.slice(9,14)),N(`update:modelValue`,t.value=n)}else if(h.category===`challan-number`){let e=t.value.replace(/[^\d]/g,``);e=e.slice(0,16);let n=e;e.length>4&&(n=e.slice(0,4)+`-`+e.slice(4,16)),N(`update:modelValue`,t.value=n)}else N(`update:modelValue`,t.value)};return i(()=>{!h.focus||!_.value||n(()=>{document.querySelector(`#${_.value}`)?.focus()})}),(t,n)=>(e(),f(`div`,{class:r(g.value)},[l(`div`,E,[l(`label`,{for:_.value,class:r([`d-flex align-items-center mb-1`,{"d-none":!v.value}])},[l(`div`,O,[l(`span`,{class:`text-capitalize`,innerHTML:v.value},null,8,k),l(`span`,{class:r([`position-absolute text-danger rounded-circle bg-danger must`,{"d-none":!h.must}])},null,2)]),l(`div`,{class:r([`text-end ms-auto text-primary fw-semibold`,{"d-none":!h.hood}]),style:{"font-size":`12px`,"margin-top":`0.15rem`},innerHTML:C.value},null,10,A)],10,D),l(`input`,o({class:`form-control`,value:h.modelValue,maxlength:S.value,readonly:h.readonly},c(m),{autocomplete:x.value,onInput:P}),null,16,j),l(`div`,{class:r([`position-absolute bottom-0 end-0 pe-1 text-secondary max`,{"d-none":!b.value}])},s(w.value),3)]),l(`div`,{id:`${_.value}Help`,class:r([`form-text mt-1 text-danger`,{"d-none":!h.err}])},s(h.err),11,M)],2))}}),[[`__scopeId`,`data-v-60b4d1ec`]]);export{T as n,N as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,B as t,C as n,E as r,H as i,O as a,P as o,T as s,U as c,V as l,g as u,h as d,i as f,y as p}from"./index-Bleyx5dm.js";import{n as m}from"./Input-z8GI8Aqo.js";var h={class:`position-relative`},g=[`for`],_={class:`position-relative`},v=[`innerHTML`],y=[`innerHTML`],b={class:`input-group mb-3`},x=[`type`,`value`,`maxlength`,`readonly`],S=[`id`],C=f(n({name:`InputPasswordToggle`,inheritAttrs:!1,__name:`InputPasswordToggle`,props:{focus:{type:Boolean},must:{type:Boolean},err:{type:[String,Boolean],default:!1},modelValue:{default:``},category:{},hood:{type:[String,Boolean,Number]},readonly:{type:Boolean}},emits:[`update:modelValue`],setup(n,{emit:f}){let{isFirefox:C}=m(),w=o(),T=n,E=d(()=>w.topclass||`mb-3`),D=d(()=>w.id||``),O=d(()=>w.label||``),k=d(()=>w.type||`text`),A=d(()=>{let e=w.maxlength;return e==null?null:Number(e)}),j=d(()=>A.value??void 0),M=d(()=>T.hood===!1||T.hood==null?``:String(T.hood)),N=d(()=>A.value==null||!C&&k.value===`month`?``:A.value-String(T.modelValue).length),P=f,F=e=>{let t=e.target;if(T.category===`number`)P(`update:modelValue`,t.value=t.value.replace(/[^\d]/gi,``));else if(T.category===`decimal`){let e=t.value.replace(/[^\d.]/g,``),n=e.split(`.`);e=n[0],n.length>1&&(e+=`.`+n.slice(1).join(``)),P(`update:modelValue`,t.value=e)}else if(T.category===`mobile`){let e=t.value.replace(/[^\d]/g,``),n=e;t.value.includes(`+`)&&(n=`+`+e),P(`update:modelValue`,t.value=n)}else if(T.category===`tax-period`){let e=t.value.replace(/[^\d-]/g,``);if(e=e.replace(/-/g,``),e=e.slice(0,6),e.length>4){let t=e.slice(0,4),n=e.slice(4,6);if(n.length===2){let e=parseInt(n,10);e<1&&(e=1),e>12&&(e=12),n=e.toString().padStart(2,`0`)}e=t+`-`+n}P(`update:modelValue`,t.value=e)}else if(T.category===`bin`){let e=t.value.replace(/[^\d]/g,``);e=e.slice(0,14);let n=e;e.length>9&&(n=e.slice(0,9)+`-`+e.slice(9,14)),P(`update:modelValue`,t.value=n)}else if(T.category===`challan-number`){let e=t.value.replace(/[^\d]/g,``);e=e.slice(0,16);let n=e;e.length>4&&(n=e.slice(0,4)+`-`+e.slice(4,16)),P(`update:modelValue`,t.value=n)}else P(`update:modelValue`,t.value)},I=t(!1),L=()=>I.value=!I.value;return a(()=>{!T.focus||!D.value||r(()=>{document.querySelector(`#${D.value}`)?.focus()})}),(t,n)=>(e(),p(`div`,{class:i(E.value)},[u(`div`,h,[u(`label`,{for:D.value,class:i([`d-flex align-items-center`,{"d-none":!O.value}])},[u(`div`,_,[u(`span`,{class:`text-capitalize mb-1`,innerHTML:O.value},null,8,v),u(`span`,{class:i([`position-absolute text-danger rounded-circle bg-danger must`,{"d-none":!T.must}])},null,2)]),u(`div`,{class:i([`text-end ms-auto text-primary align-self-center`,{"d-none":!T.hood}]),style:{"font-size":`12px`,"margin-top":`0.15rem`},innerHTML:M.value},null,10,y)],10,g),u(`div`,b,[u(`input`,s({class:`form-control border-0`,type:I.value?`text`:`password`,value:T.modelValue,maxlength:j.value,readonly:T.readonly},l(w),{onInput:F}),null,16,x),u(`button`,{class:`input-group-text p-0 border-0 border-start border-1 position-relative z-1`,type:`button`,onClick:L},[u(`i`,{class:i([`py-2 px-3`,I.value?`bi bi-eye`:`bi bi-eye-slash`]),style:{"font-size":`15px`}},null,2)])]),u(`div`,{class:i([`position-absolute bottom-0 end-0 pe-1 text-secondary max`,{"d-none":!A.value}])},c(N.value),3)]),u(`div`,{id:`${D.value}Help`,class:i([`form-text mt-1 text-danger`,{"d-none":!T.err}])},c(T.err),11,S)],2))}}),[[`__scopeId`,`data-v-917a8bc2`]]);export{C as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
input[data-v-917a8bc2]{border-color:#ccc}input[data-v-917a8bc2]:read-only{background-color:#f8f8f8}input[data-v-917a8bc2]::placeholder{color:#bfbfbf}button[data-v-917a8bc2]:focus-visible{box-shadow:none;border:none}.form-text[data-v-917a8bc2]{font-size:.75rem}.must[data-v-917a8bc2]{width:4px;height:4px;margin-top:5px;margin-left:2px}.max[data-v-917a8bc2]{font-size:.6rem}
|