@gzl10/nexus-backend 0.11.1 → 0.12.1
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/README.md +59 -164
- package/package.json +24 -31
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -30
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts +0 -1305
- package/dist/index.js +0 -10591
- package/dist/index.js.map +0 -1
- package/ui/dist/assets/ChangePasswordPage-ISVw_L0v.js +0 -1
- package/ui/dist/assets/DashboardPage-DP3-Udu4.js +0 -1
- package/ui/dist/assets/DynamicForm-CeB4C5_P.css +0 -1
- package/ui/dist/assets/DynamicForm.vue_vue_type_script_setup_true_lang-BEGbMqFJ.js +0 -153
- package/ui/dist/assets/LandingPage-ChqK0fze.js +0 -1
- package/ui/dist/assets/LoginPage-CoI_dKR7.js +0 -1
- package/ui/dist/assets/ModuleEntityForm-C-NNG-EQ.js +0 -1
- package/ui/dist/assets/ModuleManagement-bSQPd5tJ.js +0 -1
- package/ui/dist/assets/RegisterPage-BPJNkVpO.js +0 -1
- package/ui/dist/assets/apl-B4CMkyY2.js +0 -1
- package/ui/dist/assets/asciiarmor-Df11BRmG.js +0 -1
- package/ui/dist/assets/asn1-EdZsLKOL.js +0 -1
- package/ui/dist/assets/asterisk-B-8jnY81.js +0 -1
- package/ui/dist/assets/brainfuck-C4LP7Hcl.js +0 -1
- package/ui/dist/assets/clike-B9uivgTg.js +0 -1
- package/ui/dist/assets/clojure-BMjYHr_A.js +0 -1
- package/ui/dist/assets/cmake-BQqOBYOt.js +0 -1
- package/ui/dist/assets/cobol-CWcv1MsR.js +0 -1
- package/ui/dist/assets/coffeescript-S37ZYGWr.js +0 -1
- package/ui/dist/assets/commonlisp-DBKNyK5s.js +0 -1
- package/ui/dist/assets/crystal-SjHAIU92.js +0 -1
- package/ui/dist/assets/css-BnMrqG3P.js +0 -1
- package/ui/dist/assets/cypher-C_CwsFkJ.js +0 -1
- package/ui/dist/assets/d-pRatUO7H.js +0 -1
- package/ui/dist/assets/diff-DbItnlRl.js +0 -1
- package/ui/dist/assets/dist-7DF6COJ5-BU0JAua0.js +0 -16
- package/ui/dist/assets/dockerfile-BKs6k2Af.js +0 -1
- package/ui/dist/assets/dtd-DF_7sFjM.js +0 -1
- package/ui/dist/assets/dylan-DwRh75JA.js +0 -1
- package/ui/dist/assets/ebnf-CDyGwa7X.js +0 -1
- package/ui/dist/assets/ecl-Cabwm37j.js +0 -1
- package/ui/dist/assets/eiffel-CnydiIhH.js +0 -1
- package/ui/dist/assets/elm-vLlmbW-K.js +0 -1
- package/ui/dist/assets/erlang-BNw1qcRV.js +0 -1
- package/ui/dist/assets/factor-kuTfRLto.js +0 -1
- package/ui/dist/assets/fcl-Kvtd6kyn.js +0 -1
- package/ui/dist/assets/forth-Ffai-XNe.js +0 -1
- package/ui/dist/assets/fortran-DYz_wnZ1.js +0 -1
- package/ui/dist/assets/gas-Bneqetm1.js +0 -1
- package/ui/dist/assets/gherkin-heZmZLOM.js +0 -1
- package/ui/dist/assets/groovy-D9Dt4D0W.js +0 -1
- package/ui/dist/assets/haskell-Cw1EW3IL.js +0 -1
- package/ui/dist/assets/haxe-H-WmDvRZ.js +0 -1
- package/ui/dist/assets/http-DBlCnlav.js +0 -1
- package/ui/dist/assets/idl-BEugSyMb.js +0 -1
- package/ui/dist/assets/index-B2aO8s3Z.js +0 -1
- package/ui/dist/assets/index-BEgwKIPR.js +0 -1
- package/ui/dist/assets/index-BK8vn9eH.js +0 -3
- package/ui/dist/assets/index-BhvHOKjg.js +0 -2
- package/ui/dist/assets/index-CMceDQ1X.js +0 -1
- package/ui/dist/assets/index-CS_77FlC.js +0 -1
- package/ui/dist/assets/index-CjAC8nV-.js +0 -1
- package/ui/dist/assets/index-Crsm9Fe1.js +0 -1
- package/ui/dist/assets/index-DDExxVjn.js +0 -1
- package/ui/dist/assets/index-DHhnrfv6.js +0 -1
- package/ui/dist/assets/index-DV-FEWVR.css +0 -1
- package/ui/dist/assets/index-Dd-pLSL2.js +0 -1
- package/ui/dist/assets/index-DnEeKmzb.js +0 -1
- package/ui/dist/assets/index-Droz4BH2.js +0 -1
- package/ui/dist/assets/index-DvcKvpja.js +0 -1
- package/ui/dist/assets/index-Mzaxi0V6.js +0 -1
- package/ui/dist/assets/index-TCvHxt3m.js +0 -1
- package/ui/dist/assets/index-XPcj9SOt.js +0 -1
- package/ui/dist/assets/index-Xvxye7rE.js +0 -7355
- package/ui/dist/assets/index-YVp781F2.js +0 -7
- package/ui/dist/assets/javascript-iXu5QeM3.js +0 -1
- package/ui/dist/assets/julia-DuME0IfC.js +0 -1
- package/ui/dist/assets/livescript-BwQOo05w.js +0 -1
- package/ui/dist/assets/lua-BgMRiT3U.js +0 -1
- package/ui/dist/assets/mathematica-DTrFuWx2.js +0 -1
- package/ui/dist/assets/mbox-CNhZ1qSd.js +0 -1
- package/ui/dist/assets/mirc-CjQqDB4T.js +0 -1
- package/ui/dist/assets/mllike-CXdrOF99.js +0 -1
- package/ui/dist/assets/modelica-Dc1JOy9r.js +0 -1
- package/ui/dist/assets/mscgen-BA5vi2Kp.js +0 -1
- package/ui/dist/assets/mumps-BT43cFF4.js +0 -1
- package/ui/dist/assets/nginx-DdIZxoE0.js +0 -1
- package/ui/dist/assets/nsis-LdVXkNf5.js +0 -1
- package/ui/dist/assets/ntriples-BfvgReVJ.js +0 -1
- package/ui/dist/assets/octave-Ck1zUtKM.js +0 -1
- package/ui/dist/assets/oz-BzwKVEFT.js +0 -1
- package/ui/dist/assets/pascal--L3eBynH.js +0 -1
- package/ui/dist/assets/perl-CdXCOZ3F.js +0 -1
- package/ui/dist/assets/pig-CevX1Tat.js +0 -1
- package/ui/dist/assets/powershell-CFHJl5sT.js +0 -1
- package/ui/dist/assets/properties-C78fOPTZ.js +0 -1
- package/ui/dist/assets/protobuf-ChK-085T.js +0 -1
- package/ui/dist/assets/pug-DeIclll2.js +0 -1
- package/ui/dist/assets/puppet-DMA9R1ak.js +0 -1
- package/ui/dist/assets/python-BuPzkPfP.js +0 -1
- package/ui/dist/assets/q-pXgVlZs6.js +0 -1
- package/ui/dist/assets/r-B6wPVr8A.js +0 -1
- package/ui/dist/assets/rpm-CTu-6PCP.js +0 -1
- package/ui/dist/assets/ruby-B2Rjki9n.js +0 -1
- package/ui/dist/assets/sas-B4kiWyti.js +0 -1
- package/ui/dist/assets/scheme-C41bIUwD.js +0 -1
- package/ui/dist/assets/shell-CjFT_Tl9.js +0 -1
- package/ui/dist/assets/sieve-C3Gn_uJK.js +0 -1
- package/ui/dist/assets/simple-mode-GW_nhZxv.js +0 -1
- package/ui/dist/assets/smalltalk-CnHTOXQT.js +0 -1
- package/ui/dist/assets/solr-DehyRSwq.js +0 -1
- package/ui/dist/assets/sparql-DkYu6x3z.js +0 -1
- package/ui/dist/assets/spreadsheet-BCZA_wO0.js +0 -1
- package/ui/dist/assets/sql-D0XecflT.js +0 -1
- package/ui/dist/assets/stex-C3f8Ysf7.js +0 -1
- package/ui/dist/assets/stylus-B533Al4x.js +0 -1
- package/ui/dist/assets/swift-BzpIVaGY.js +0 -1
- package/ui/dist/assets/tcl-DVfN8rqt.js +0 -1
- package/ui/dist/assets/textile-CnDTJFAw.js +0 -1
- package/ui/dist/assets/tiddlywiki-DO-Gjzrf.js +0 -1
- package/ui/dist/assets/tiki-DGYXhP31.js +0 -1
- package/ui/dist/assets/toml-Bm5Em-hy.js +0 -1
- package/ui/dist/assets/troff-wAsdV37c.js +0 -1
- package/ui/dist/assets/ttcn-CfJYG6tj.js +0 -1
- package/ui/dist/assets/ttcn-cfg-B9xdYoR4.js +0 -1
- package/ui/dist/assets/turtle-B1tBg_DP.js +0 -1
- package/ui/dist/assets/vb-CmGdzxic.js +0 -1
- package/ui/dist/assets/vbscript-BuJXcnF6.js +0 -1
- package/ui/dist/assets/velocity-D8B20fx6.js +0 -1
- package/ui/dist/assets/verilog-C6RDOZhf.js +0 -1
- package/ui/dist/assets/vhdl-lSbBsy5d.js +0 -1
- package/ui/dist/assets/webidl-ZXfAyPTL.js +0 -1
- package/ui/dist/assets/xquery-DzFWVndE.js +0 -1
- package/ui/dist/assets/yacas-BJ4BC0dw.js +0 -1
- package/ui/dist/assets/z80-Hz9HOZM7.js +0 -1
- package/ui/dist/favicon-16.png +0 -0
- package/ui/dist/favicon-32.png +0 -0
- package/ui/dist/favicon.ico +0 -0
- package/ui/dist/index.html +0 -17
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @gzl10/nexus-backend
|
|
2
2
|
|
|
3
|
-
[](https://gitlab.gzl10.com/oss/nexus-backend/-/pipelines)
|
|
4
3
|
[](https://www.npmjs.com/package/@gzl10/nexus-backend)
|
|
5
4
|
[](https://www.npmjs.com/package/@gzl10/nexus-backend)
|
|
6
5
|
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
[](https://nodejs.org/)
|
|
8
6
|
|
|
9
7
|
> **Warning**: This project is currently in testing/experimental phase. Use at your own risk.
|
|
10
8
|
|
|
11
|
-
Backend as a Service (BaaS) with Express 5, Knex and CASL.
|
|
9
|
+
Backend as a Service (BaaS) with Express 5, Knex and CASL. Build modular, type-safe backends with authentication, authorization, and real-time features.
|
|
12
10
|
|
|
13
|
-
**Repository**: [https://gitlab.gzl10.com/oss/nexus
|
|
11
|
+
**Repository**: [https://gitlab.gzl10.com/oss/nexus](https://gitlab.gzl10.com/oss/nexus)
|
|
14
12
|
|
|
15
13
|
## Installation
|
|
16
14
|
|
|
@@ -18,187 +16,84 @@ Backend as a Service (BaaS) with Express 5, Knex and CASL. Ready to use as an np
|
|
|
18
16
|
pnpm add @gzl10/nexus-backend
|
|
19
17
|
```
|
|
20
18
|
|
|
21
|
-
##
|
|
19
|
+
## Quick Start
|
|
22
20
|
|
|
23
21
|
```typescript
|
|
24
|
-
import { start
|
|
22
|
+
import { start } from '@gzl10/nexus-backend'
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// Start server
|
|
30
|
-
await start({
|
|
31
|
-
port: 3000,
|
|
32
|
-
database: { url: 'file:./data.db' }
|
|
33
|
-
})
|
|
24
|
+
start()
|
|
25
|
+
```
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
nexusEvents.on('db.users.created', ({ data }) => {
|
|
37
|
-
console.log('User created:', data)
|
|
38
|
-
})
|
|
27
|
+
## Features
|
|
39
28
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
29
|
+
| Feature | Description |
|
|
30
|
+
| ------- | ----------- |
|
|
31
|
+
| Express 5 | Modern async error handling |
|
|
32
|
+
| Knex ORM | SQLite, PostgreSQL, MySQL support |
|
|
33
|
+
| CASL | Attribute-based access control |
|
|
34
|
+
| JWT Auth | Access + refresh tokens with rotation |
|
|
35
|
+
| Socket.IO | Real-time events and notifications |
|
|
36
|
+
| Modular | Plugin architecture for extensions |
|
|
37
|
+
| Storage | Local and S3-compatible storage |
|
|
38
|
+
| Rate Limiting | Built-in rate limiting middleware |
|
|
43
39
|
|
|
44
40
|
## Configuration
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
| Option | Description | Default |
|
|
49
|
-
| -------------- | ------------------- | ----------------------- |
|
|
50
|
-
| `port` | Server port | `3000` |
|
|
51
|
-
| `host` | Server host | `0.0.0.0` |
|
|
52
|
-
| `homePath` | Home path (redirect `/`) | `/ui` |
|
|
53
|
-
| `database.url` | Database URL | `file:./dev.db` |
|
|
54
|
-
| `cors.origin` | Allowed CORS origin | `http://localhost:3001` |
|
|
55
|
-
| `timezone` | Server timezone | `Europe/Madrid` |
|
|
56
|
-
| `admin.email` | Admin email (seed) | Optional |
|
|
57
|
-
| `admin.password` | Admin password (seed) | Optional |
|
|
58
|
-
|
|
59
|
-
### Environment Variables (Core)
|
|
60
|
-
|
|
61
|
-
| Variable | Description | Default |
|
|
62
|
-
| ---------------- | -------------------------- | ---------------------- |
|
|
63
|
-
| `NODE_ENV` | Environment | `development` |
|
|
64
|
-
| `PORT` | Server port | `3000` |
|
|
65
|
-
| `HOME_PATH` | Home path (redirect `/`) | `/ui` |
|
|
66
|
-
| `CORS_ORIGIN` | Allowed CORS origin | `http://localhost:3001`|
|
|
67
|
-
| `DATABASE_URL` | Database URL | `file:./dev.db` |
|
|
68
|
-
| `ADMIN_EMAIL` | Admin email (seed) | Optional |
|
|
69
|
-
| `ADMIN_PASSWORD` | Admin password (seed) | Optional |
|
|
70
|
-
| `BACKEND_URL` | Base URL for logs/CLI | Optional |
|
|
71
|
-
| `TZ` | Server timezone | `Europe/Madrid` |
|
|
72
|
-
|
|
73
|
-
### Environment Variables (Auth)
|
|
74
|
-
|
|
75
|
-
| Variable | Description | Default |
|
|
76
|
-
| ---------------------- | ------------------------------ | --------- |
|
|
77
|
-
| `AUTH_SECRET` | JWT secret (min 32 chars) | Required |
|
|
78
|
-
| `AUTH_ACCESS_EXPIRES` | Access token expiration | `15m` |
|
|
79
|
-
| `AUTH_REFRESH_EXPIRES` | Refresh token expiration | `7d` |
|
|
80
|
-
|
|
81
|
-
### Supported Databases
|
|
82
|
-
|
|
83
|
-
- **SQLite**: `file:./data.db`
|
|
84
|
-
- **PostgreSQL**: `postgresql://user:pass@host:5432/db`
|
|
85
|
-
- **MySQL**: `mysql://user:pass@host:3306/db`
|
|
86
|
-
|
|
87
|
-
## API Endpoints
|
|
88
|
-
|
|
89
|
-
- `POST /api/v1/auth/login` - Login
|
|
90
|
-
- `POST /api/v1/auth/refresh` - Refresh token
|
|
91
|
-
- `POST /api/v1/auth/logout` - Logout
|
|
92
|
-
- `GET /api/v1/users` - List users
|
|
93
|
-
- `GET /api/v1/users/roles` - List roles
|
|
94
|
-
- `GET /api/v1/system/modules` - List modules
|
|
95
|
-
- `GET /api/v1/storage/files` - List files
|
|
96
|
-
- `GET /health` - Health check
|
|
97
|
-
- `GET /api/openapi.json` - OpenAPI spec
|
|
98
|
-
|
|
99
|
-
## Architecture
|
|
100
|
-
|
|
101
|
-
```text
|
|
102
|
-
┌──────────────────────────────────────────────────────────────────────────┐
|
|
103
|
-
│ NEXUS-BACKEND │
|
|
104
|
-
├──────────────────────────────────────────────────────────────────────────┤
|
|
105
|
-
│ │
|
|
106
|
-
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
|
107
|
-
│ │ ENGINE │ │
|
|
108
|
-
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │ │
|
|
109
|
-
│ │ │ Registry │ │ Loader │ │ Queries │ │ │
|
|
110
|
-
│ │ │ (modules & │ │ (core mods) │ │ (getModules, getPlugins)│ │ │
|
|
111
|
-
│ │ │ plugins) │ │ │ │ │ │ │
|
|
112
|
-
│ │ └──────────────┘ └──────────────┘ └──────────────────────────┘ │ │
|
|
113
|
-
│ └────────────────────────────────────────────────────────────────────┘ │
|
|
114
|
-
│ │ │
|
|
115
|
-
│ ▼ │
|
|
116
|
-
│ ┌────────────────────────────────────────────────────────────────────┐ │
|
|
117
|
-
│ │ RUNTIME │ │
|
|
118
|
-
│ │ EntityDefinition ──► Service ──► Controller ──► Routes │ │
|
|
119
|
-
│ │ │ │
|
|
120
|
-
│ │ Para cada entity en module.definitions[]: │ │
|
|
121
|
-
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌────────────────┐ │ │
|
|
122
|
-
│ │ │ CollectionService│ │EntityController │ │ GET /items │ │ │
|
|
123
|
-
│ │ │ SingleService │ ──►│ (findAll, │ ──►│ GET /items/:id │ │ │
|
|
124
|
-
│ │ │ EventService │ │ findById, │ │ POST /items │ │ │
|
|
125
|
-
│ │ │ ActionService │ │ create, ...) │ │ PUT /items/:id │ │ │
|
|
126
|
-
│ │ │ ... │ │ │ │ DELETE /... │ │ │
|
|
127
|
-
│ │ └─────────────────┘ └─────────────────┘ └────────────────┘ │ │
|
|
128
|
-
│ └────────────────────────────────────────────────────────────────────┘ │
|
|
129
|
-
│ ▲ │
|
|
130
|
-
│ ┌──────────────────────────┼──────────────────────────┐ │
|
|
131
|
-
│ │ │ │ │
|
|
132
|
-
│ ┌──────┴───────┐ ┌───────┴───────┐ ┌───────┴───────┐ │
|
|
133
|
-
│ │ MODULE │ │ MODULE │ │ PLUGIN │ │
|
|
134
|
-
│ │ (core) │ │ (core) │ │ (external) │ │
|
|
135
|
-
│ ├──────────────┤ ├───────────────┤ ├───────────────┤ │
|
|
136
|
-
│ │ name: auth │ │ name: users │ │ name: cms │ │
|
|
137
|
-
│ │ definitions: │ │ definitions: │ │ definitions: │ │
|
|
138
|
-
│ │ - tokens │ │ - users │ │ - posts │ │
|
|
139
|
-
│ │ (temp) │ │ (collection│ │ (collection│ │
|
|
140
|
-
│ │ - audit │ │ - roles │ │ - pages │ │
|
|
141
|
-
│ │ (event) │ │ (collection│ │ (collection│ │
|
|
142
|
-
│ └──────────────┘ └───────────────┘ └───────────────┘ │
|
|
143
|
-
│ │
|
|
144
|
-
└──────────────────────────────────────────────────────────────────────────┘
|
|
145
|
-
```
|
|
42
|
+
Create a `.env` file:
|
|
146
43
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
| reference | GET (read-only) | Countries, currencies, status codes |
|
|
154
|
-
| event | GET, POST | Audit logs, activity history, notifications |
|
|
155
|
-
| action | POST /execute | Send email, process payment, generate report |
|
|
156
|
-
| temp | CRUD + TTL | Sessions, OTP codes, temporary tokens |
|
|
157
|
-
| config | GET, PUT (scoped) | Module settings, feature flags per tenant |
|
|
158
|
-
| view | GET (query) | Dashboard stats, aggregated reports |
|
|
159
|
-
| computed | GET (on-demand) | Real-time metrics, calculated fields |
|
|
160
|
-
| external | GET (adapter) | Third-party APIs, external databases |
|
|
161
|
-
| virtual | GET (combine) | Unified search, merged data from sources |
|
|
44
|
+
```env
|
|
45
|
+
PORT=3000
|
|
46
|
+
CORS_ORIGIN=http://localhost:5173
|
|
47
|
+
DATABASE_URL=file:./data/nexus.db
|
|
48
|
+
JWT_SECRET=your-secret-key
|
|
49
|
+
```
|
|
162
50
|
|
|
163
|
-
##
|
|
51
|
+
## CLI
|
|
164
52
|
|
|
165
53
|
```bash
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
pnpm typecheck # Type check
|
|
169
|
-
pnpm lint # Linting
|
|
170
|
-
pnpm db:migrate # Run migrations
|
|
171
|
-
pnpm db:seed # Initial seed
|
|
172
|
-
```
|
|
54
|
+
# Start server
|
|
55
|
+
npx nexus start
|
|
173
56
|
|
|
174
|
-
|
|
57
|
+
# Run migrations
|
|
58
|
+
npx nexus migrate
|
|
175
59
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
pnpm test:coverage # Run tests with coverage
|
|
60
|
+
# Seed database
|
|
61
|
+
npx nexus seed
|
|
179
62
|
```
|
|
180
63
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
| Metric | Coverage |
|
|
184
|
-
| ---------- | -------- |
|
|
185
|
-
| Statements | 76% |
|
|
186
|
-
| Branches | 65% |
|
|
187
|
-
| Functions | 79% |
|
|
188
|
-
| Lines | 77% |
|
|
64
|
+
## Exported Functions
|
|
189
65
|
|
|
190
|
-
|
|
66
|
+
| Function | Description |
|
|
67
|
+
| -------- | ----------- |
|
|
68
|
+
| `start()` | Start the server |
|
|
69
|
+
| `stop()` | Stop the server |
|
|
70
|
+
| `createApp()` | Create Express app instance |
|
|
71
|
+
| `registerModule()` | Register a custom module |
|
|
72
|
+
| `registerPlugin()` | Register a plugin |
|
|
73
|
+
| `defineAbilityFor()` | Create CASL abilities |
|
|
74
|
+
| `getIO()` | Get Socket.IO instance |
|
|
191
75
|
|
|
192
|
-
|
|
193
|
-
| ---------------------- | -------------------------------- |
|
|
194
|
-
| `test/runtime/` | Unit tests for entity services |
|
|
195
|
-
| `test/runtime/routes/` | Integration tests with supertest |
|
|
76
|
+
## Development
|
|
196
77
|
|
|
197
|
-
|
|
78
|
+
```bash
|
|
79
|
+
pnpm dev # Start dev server with watch
|
|
80
|
+
pnpm build # Build for production
|
|
81
|
+
pnpm start # Start production server
|
|
82
|
+
pnpm typecheck # Type check
|
|
83
|
+
pnpm lint # Linting
|
|
84
|
+
pnpm test # Run tests
|
|
85
|
+
pnpm test:coverage # Tests with coverage
|
|
86
|
+
```
|
|
198
87
|
|
|
199
|
-
##
|
|
88
|
+
## Stack
|
|
200
89
|
|
|
201
|
-
|
|
90
|
+
- **Express 5** - Web framework
|
|
91
|
+
- **Knex** - SQL query builder
|
|
92
|
+
- **CASL** - Authorization
|
|
93
|
+
- **JWT** - Authentication
|
|
94
|
+
- **Socket.IO** - Real-time
|
|
95
|
+
- **Zod** - Validation
|
|
96
|
+
- **Pino** - Logging
|
|
202
97
|
|
|
203
98
|
## License
|
|
204
99
|
|
package/package.json
CHANGED
|
@@ -1,22 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gzl10/nexus-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Backend as a Service (BaaS) with Express 5, Knex and CASL",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
-
"homepage": "https://www.gzl10.com",
|
|
9
|
-
"repository": {
|
|
10
|
-
"type": "git",
|
|
11
|
-
"url": "https://gitlab.gzl10.com/oss/nexus-backend.git"
|
|
12
|
-
},
|
|
13
|
-
"bugs": {
|
|
14
|
-
"url": "https://gitlab.gzl10.com/oss/nexus-backend/-/issues"
|
|
15
|
-
},
|
|
16
|
-
"funding": {
|
|
17
|
-
"type": "buymeacoffee",
|
|
18
|
-
"url": "https://www.buymeacoffee.com/gzl10g"
|
|
19
|
-
},
|
|
20
8
|
"bin": {
|
|
21
9
|
"nexus": "./dist/cli.js"
|
|
22
10
|
},
|
|
@@ -28,10 +16,23 @@
|
|
|
28
16
|
},
|
|
29
17
|
"files": [
|
|
30
18
|
"dist",
|
|
31
|
-
"ui/dist",
|
|
32
19
|
"public"
|
|
33
20
|
],
|
|
34
21
|
"license": "MIT",
|
|
22
|
+
"author": "Gonzalo Díez <gonzalo@gzl10.com>",
|
|
23
|
+
"homepage": "https://gitlab.gzl10.com/oss/nexus",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://gitlab.gzl10.com/oss/nexus.git",
|
|
27
|
+
"directory": "packages/backend"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://gitlab.gzl10.com/oss/nexus/-/issues"
|
|
31
|
+
},
|
|
32
|
+
"funding": {
|
|
33
|
+
"type": "buymeacoffee",
|
|
34
|
+
"url": "https://www.buymeacoffee.com/gzl10g"
|
|
35
|
+
},
|
|
35
36
|
"keywords": [
|
|
36
37
|
"baas",
|
|
37
38
|
"backend",
|
|
@@ -52,7 +53,6 @@
|
|
|
52
53
|
"dependencies": {
|
|
53
54
|
"@aws-sdk/client-s3": "^3.962.0",
|
|
54
55
|
"@casl/ability": "^6.7.5",
|
|
55
|
-
"@gzl10/nexus-sdk": "*",
|
|
56
56
|
"@sentry/node": "^10.32.1",
|
|
57
57
|
"bcryptjs": "^2.4.3",
|
|
58
58
|
"better-sqlite3": "^11.0.0",
|
|
@@ -78,10 +78,10 @@
|
|
|
78
78
|
"pino": "^10.1.0",
|
|
79
79
|
"sharp": "^0.34.5",
|
|
80
80
|
"socket.io": "^4.8.3",
|
|
81
|
-
"zod": "^3.24.0"
|
|
81
|
+
"zod": "^3.24.0",
|
|
82
|
+
"@gzl10/nexus-sdk": "0.12.1"
|
|
82
83
|
},
|
|
83
84
|
"devDependencies": {
|
|
84
|
-
"@eslint/js": "^9.39.2",
|
|
85
85
|
"@types/bcryptjs": "^2.4.0",
|
|
86
86
|
"@types/better-sqlite3": "^7.6.0",
|
|
87
87
|
"@types/compression": "^1.7.0",
|
|
@@ -95,24 +95,19 @@
|
|
|
95
95
|
"@types/nodemailer": "^7.0.4",
|
|
96
96
|
"@types/supertest": "^6.0.3",
|
|
97
97
|
"@vitest/coverage-v8": "^4.0.16",
|
|
98
|
-
"concurrently": "^9.2.1",
|
|
99
|
-
"cross-env": "^10.1.0",
|
|
100
|
-
"eslint": "^9.17.0",
|
|
101
98
|
"pino-pretty": "^13.1.3",
|
|
102
99
|
"supertest": "^7.1.4",
|
|
103
100
|
"tsup": "^8.3.0",
|
|
104
101
|
"tsx": "^4.19.0",
|
|
105
|
-
"typescript": "^5.7.0",
|
|
106
|
-
"typescript-eslint": "^8.51.0",
|
|
107
102
|
"vitest": "^4.0.16"
|
|
108
103
|
},
|
|
104
|
+
"publishConfig": {
|
|
105
|
+
"access": "public",
|
|
106
|
+
"registry": "https://registry.npmjs.org"
|
|
107
|
+
},
|
|
109
108
|
"scripts": {
|
|
110
|
-
"dev": "
|
|
111
|
-
"
|
|
112
|
-
"dev:backend": "tsx watch src/index.ts",
|
|
113
|
-
"dev:ui": "pnpm --filter nexus-ui build:watch",
|
|
114
|
-
"build": "tsup && pnpm run build:ui",
|
|
115
|
-
"build:ui": "pnpm --filter nexus-ui build",
|
|
109
|
+
"dev": "tsx watch src/index.ts",
|
|
110
|
+
"build": "tsup",
|
|
116
111
|
"start": "node dist/index.js",
|
|
117
112
|
"db:migrate": "tsx src/db/migrate.ts",
|
|
118
113
|
"db:seed": "tsx src/db/seed.ts",
|
|
@@ -121,8 +116,6 @@
|
|
|
121
116
|
"test": "vitest run",
|
|
122
117
|
"test:watch": "vitest",
|
|
123
118
|
"test:coverage": "vitest run --coverage",
|
|
124
|
-
"
|
|
125
|
-
"kill:dev": "pkill -9 -f 'tsx.*watch' || true",
|
|
126
|
-
"clean": "rm -rf node_modules pnpm-lock.yaml dist"
|
|
119
|
+
"clean": "rm -rf dist node_modules coverage"
|
|
127
120
|
}
|
|
128
121
|
}
|
package/dist/cli.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
package/dist/cli.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/cli.ts
|
|
4
|
-
import { existsSync } from "fs";
|
|
5
|
-
import { Command } from "commander";
|
|
6
|
-
import { consola } from "consola";
|
|
7
|
-
if (existsSync(".env")) {
|
|
8
|
-
process.loadEnvFile(".env");
|
|
9
|
-
}
|
|
10
|
-
var program = new Command();
|
|
11
|
-
program.name("nexus").description("Nexus Backend CLI").version("0.1.0");
|
|
12
|
-
program.command("ui").description("Open UI in browser").option("-p, --port <port>", "Nexus backend port").action(async (options) => {
|
|
13
|
-
const port = parseInt(options.port || process.env["PORT"] || "3000", 10);
|
|
14
|
-
const baseUrl = (process.env["BACKEND_URL"] || `http://localhost:${port}`).replace(/\/$/, "");
|
|
15
|
-
const url = `${baseUrl}/ui`;
|
|
16
|
-
try {
|
|
17
|
-
const res = await fetch(`${baseUrl}/health`);
|
|
18
|
-
if (!res.ok) throw new Error();
|
|
19
|
-
} catch {
|
|
20
|
-
consola.error(`Nexus no est\xE1 corriendo en ${baseUrl}`);
|
|
21
|
-
consola.info("Inicia el servidor primero con: pnpm dev");
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
24
|
-
const { exec } = await import("child_process");
|
|
25
|
-
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
26
|
-
exec(`${cmd} ${url}`);
|
|
27
|
-
consola.success(`Abriendo: ${url}`);
|
|
28
|
-
});
|
|
29
|
-
program.parse();
|
|
30
|
-
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync } from 'fs'\nimport { Command } from 'commander'\nimport { consola } from 'consola'\n\n// Cargar .env si existe (Node 20+)\nif (existsSync('.env')) {\n process.loadEnvFile('.env')\n}\n\nconst program = new Command()\n\nprogram\n .name('nexus')\n .description('Nexus Backend CLI')\n .version('0.1.0')\n\nprogram\n .command('ui')\n .description('Open UI in browser')\n .option('-p, --port <port>', 'Nexus backend port')\n .action(async (options) => {\n const port = parseInt(options.port || process.env['PORT'] || '3000', 10)\n const baseUrl = (process.env['BACKEND_URL'] || `http://localhost:${port}`).replace(/\\/$/, '')\n const url = `${baseUrl}/ui`\n\n // Verificar que Nexus está corriendo\n try {\n const res = await fetch(`${baseUrl}/health`)\n if (!res.ok) throw new Error()\n } catch {\n consola.error(`Nexus no está corriendo en ${baseUrl}`)\n consola.info('Inicia el servidor primero con: pnpm dev')\n process.exit(1)\n }\n\n // Abrir navegador\n const { exec } = await import('child_process')\n const cmd = process.platform === 'darwin' ? 'open'\n : process.platform === 'win32' ? 'start'\n : 'xdg-open'\n\n exec(`${cmd} ${url}`)\n consola.success(`Abriendo: ${url}`)\n })\n\nprogram.parse()\n"],"mappings":";;;AACA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,eAAe;AAGxB,IAAI,WAAW,MAAM,GAAG;AACtB,UAAQ,YAAY,MAAM;AAC5B;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,OAAO,EACZ,YAAY,mBAAmB,EAC/B,QAAQ,OAAO;AAElB,QACG,QAAQ,IAAI,EACZ,YAAY,oBAAoB,EAChC,OAAO,qBAAqB,oBAAoB,EAChD,OAAO,OAAO,YAAY;AACzB,QAAM,OAAO,SAAS,QAAQ,QAAQ,QAAQ,IAAI,MAAM,KAAK,QAAQ,EAAE;AACvE,QAAM,WAAW,QAAQ,IAAI,aAAa,KAAK,oBAAoB,IAAI,IAAI,QAAQ,OAAO,EAAE;AAC5F,QAAM,MAAM,GAAG,OAAO;AAGtB,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,OAAO,SAAS;AAC3C,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM;AAAA,EAC/B,QAAQ;AACN,YAAQ,MAAM,iCAA8B,OAAO,EAAE;AACrD,YAAQ,KAAK,0CAA0C;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,eAAe;AAC7C,QAAM,MAAM,QAAQ,aAAa,WAAW,SAChC,QAAQ,aAAa,UAAU,UAC/B;AAEZ,OAAK,GAAG,GAAG,IAAI,GAAG,EAAE;AACpB,UAAQ,QAAQ,aAAa,GAAG,EAAE;AACpC,CAAC;AAEH,QAAQ,MAAM;","names":[]}
|