exisjs 0.7.12 → 0.7.14
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 +195 -39
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +3 -1
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/config/types.d.ts +2 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/decorators/params.d.ts +21 -0
- package/dist/decorators/params.d.ts.map +1 -1
- package/dist/decorators/params.js +21 -1
- package/dist/decorators/params.js.map +1 -1
- package/dist/di/container.d.ts +15 -6
- package/dist/di/container.d.ts.map +1 -1
- package/dist/di/container.js +26 -3
- package/dist/di/container.js.map +1 -1
- package/dist/di/index.d.ts +1 -1
- package/dist/di/index.d.ts.map +1 -1
- package/dist/di/index.js.map +1 -1
- package/dist/di/inject.d.ts +2 -1
- package/dist/di/inject.d.ts.map +1 -1
- package/dist/di/inject.js +2 -1
- package/dist/di/inject.js.map +1 -1
- package/dist/docs/ARCHITECTURE.md +130 -78
- package/dist/docs/BENCHMARKS.md +4 -4
- package/dist/docs/content/README.md +43 -44
- package/dist/docs/content/boundaries.mdx +138 -61
- package/dist/docs/content/cli/commands.mdx +151 -128
- package/dist/docs/content/cli/overview.mdx +61 -47
- package/dist/docs/content/cli/usage.mdx +107 -30
- package/dist/docs/content/config.mdx +145 -158
- package/dist/docs/content/controllers.mdx +193 -464
- package/dist/docs/content/cron.mdx +183 -69
- package/dist/docs/content/decorators.mdx +449 -154
- package/dist/docs/content/errors.mdx +202 -305
- package/dist/docs/content/exisjs-mcp.mdx +59 -49
- package/dist/docs/content/installation.mdx +243 -157
- package/dist/docs/content/introduction.mdx +220 -48
- package/dist/docs/content/middleware.mdx +171 -497
- package/dist/docs/content/modules.mdx +141 -83
- package/dist/docs/content/providers.mdx +216 -180
- package/dist/docs/content/requests.mdx +168 -488
- package/dist/docs/content/responses.mdx +200 -533
- package/dist/docs/content/routing.mdx +235 -598
- package/dist/docs/content/security.mdx +233 -57
- package/dist/docs/content/structure.mdx +151 -240
- package/dist/docs/content/swagger.mdx +192 -91
- package/dist/docs/content/testing.mdx +205 -74
- package/dist/docs/content/validation.mdx +479 -341
- package/dist/docs/reference/README.md +34 -2
- package/dist/docs/reference/config.mdx +277 -75
- package/dist/docs/reference/context.mdx +197 -106
- package/dist/docs/reference/cron.mdx +266 -152
- package/dist/docs/reference/database.mdx +135 -53
- package/dist/docs/reference/decorators.mdx +234 -116
- package/dist/docs/reference/di.mdx +146 -112
- package/dist/docs/reference/error.mdx +155 -178
- package/dist/docs/reference/exis.mdx +141 -70
- package/dist/docs/reference/logger.mdx +110 -126
- package/dist/docs/reference/middleware.mdx +235 -158
- package/dist/docs/reference/plugin.mdx +136 -64
- package/dist/docs/reference/router.mdx +275 -293
- package/dist/docs/reference/sanitize.mdx +91 -87
- package/dist/docs/reference/swagger.mdx +280 -100
- package/dist/docs/reference/testing.mdx +223 -89
- package/dist/docs/reference/validator.mdx +194 -206
- package/dist/lib/start-server.js +22 -8
- package/dist/lib/start-server.js.map +1 -1
- package/dist/module/module.d.ts +6 -3
- package/dist/module/module.d.ts.map +1 -1
- package/dist/module/module.js +17 -3
- package/dist/module/module.js.map +1 -1
- package/dist/router/controller-registrar.d.ts.map +1 -1
- package/dist/router/controller-registrar.js +26 -4
- package/dist/router/controller-registrar.js.map +1 -1
- package/dist/router/scanner/fs-scanner.d.ts.map +1 -1
- package/dist/router/scanner/fs-scanner.js +22 -0
- package/dist/router/scanner/fs-scanner.js.map +1 -1
- package/dist/router/types.d.ts +6 -4
- package/dist/router/types.d.ts.map +1 -1
- package/dist/server/app.d.ts +3 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +24 -8
- package/dist/server/app.js.map +1 -1
- package/dist/server/bootstrapper.d.ts.map +1 -1
- package/dist/server/bootstrapper.js +19 -0
- package/dist/server/bootstrapper.js.map +1 -1
- package/dist/server/request.d.ts +2 -0
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +11 -0
- package/dist/server/request.js.map +1 -1
- package/dist/server/response.d.ts +10 -5
- package/dist/server/response.d.ts.map +1 -1
- package/dist/server/response.js +65 -18
- package/dist/server/response.js.map +1 -1
- package/dist/swagger/generator.d.ts.map +1 -1
- package/dist/swagger/generator.js +130 -10
- package/dist/swagger/generator.js.map +1 -1
- package/dist/telemetry/index.d.ts +12 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +121 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/testing/client.d.ts +1 -0
- package/dist/testing/client.d.ts.map +1 -1
- package/dist/testing/client.js +4 -1
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +11 -4
- package/dist/testing/index.js.map +1 -1
- package/dist/validator/builder.d.ts +26 -1
- package/dist/validator/builder.d.ts.map +1 -1
- package/dist/validator/builder.js +31 -0
- package/dist/validator/builder.js.map +1 -1
- package/dist/validator/engine.d.ts +23 -0
- package/dist/validator/engine.d.ts.map +1 -1
- package/dist/validator/engine.js +228 -31
- package/dist/validator/engine.js.map +1 -1
- package/dist/validator/index.d.ts +8 -4
- package/dist/validator/index.d.ts.map +1 -1
- package/dist/validator/index.js +4 -1
- package/dist/validator/index.js.map +1 -1
- package/dist/validator/tex-types.d.ts +19 -4
- package/dist/validator/tex-types.d.ts.map +1 -1
- package/dist/validator/tex-types.js +102 -0
- package/dist/validator/tex-types.js.map +1 -1
- package/dist/validator/tex.d.ts +1 -1
- package/dist/validator/tex.d.ts.map +1 -1
- package/dist/validator/tex.js +3 -1
- package/dist/validator/tex.js.map +1 -1
- package/dist/validator/types.d.ts +1 -0
- package/dist/validator/types.d.ts.map +1 -1
- package/package.json +46 -14
- package/dist/docs/content/dataloader.mdx +0 -170
- package/dist/docs/reference/dataloader.mdx +0 -91
|
@@ -1,96 +1,268 @@
|
|
|
1
1
|
---
|
|
2
|
+
title: 'Introduction'
|
|
3
|
+
description: 'An overview of the ExisJS backend framework architecture, design philosophy, and core features.'
|
|
2
4
|
nextUrl: '/docs/installation'
|
|
3
5
|
nextTitle: 'Installation'
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Introduction
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
**ExisJS** is an opinionated web framework for building TypeScript backends on Node.js. It brings convention-over-configuration and automatic file-system routing to backend API development.
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
Rather than manually assembling, wiring, and maintaining separate third-party libraries for routing, input validation, dependency injection, OpenAPI documentation, rate limiting, and background task scheduling, ExisJS provides a standard library integrated with a native Rust acceleration engine (`@exisjs/rs`).
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Why ExisJS?
|
|
17
|
+
|
|
18
|
+
TypeScript backend development often faces two approaches:
|
|
19
|
+
|
|
20
|
+
1. **Micro-frameworks (Express, Fastify)**: Require developers to manually select, wire, and maintain middleware packages for validation, OpenAPI schemas, dependency injection, and security headers. Over time, projects diverge in structure and maintenance overhead increases.
|
|
21
|
+
2. **Heavy enterprise frameworks**: Introduce deep class hierarchies, verbose configuration modules, and steep learning curves.
|
|
13
22
|
|
|
14
|
-
|
|
23
|
+
ExisJS combines convention-based file routing, built-in standard modules, and native Rust primitives with support for both functional and object-oriented paradigms.
|
|
15
24
|
|
|
16
|
-
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Architectural Pillars
|
|
17
28
|
|
|
18
|
-
|
|
29
|
+
```
|
|
30
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
31
|
+
│ ExisJS Application │
|
|
32
|
+
│ Functional Paradigm │ Class-Based (OOP) Paradigm │
|
|
33
|
+
│ controller(), route.get(), tex │ @Controller(), @Get(), @Injectable │
|
|
34
|
+
└──────────────────────────────────────┬──────────────────────────────────────┘
|
|
35
|
+
│
|
|
36
|
+
┌──────────────────────────────────────▼──────────────────────────────────────┐
|
|
37
|
+
│ TypeScript HTTP Pipeline │
|
|
38
|
+
│ Request Context (ExisRequest/Response) · Hierarchical Boundaries · Swagger │
|
|
39
|
+
│ Rate Limiting · Helmet Headers · CSRF · Idempotency · Telemetry │
|
|
40
|
+
└──────────────────────────────────────┬──────────────────────────────────────┘
|
|
41
|
+
│ (N-API Direct Bindings with Fallback)
|
|
42
|
+
┌──────────────────────────────────────▼──────────────────────────────────────┐
|
|
43
|
+
│ Native Rust Engine (@exisjs/rs) │
|
|
44
|
+
│ NativeRadixTree Routing │ LRU Memory Cache │ Fast CIDR IP Filtering │
|
|
45
|
+
│ TexValidator Accelerator │ Safe Sanitization Body Parser │
|
|
46
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 1. File-System Native Routing
|
|
50
|
+
The file-system routing engine scans the `src/http` directory and compiles route paths into a native Rust radix tree (`NativeRadixTree`). Path parameter extraction and endpoint dispatching execute through native N-API bindings.
|
|
51
|
+
|
|
52
|
+
### 2. Dual-Paradigm Parity
|
|
53
|
+
ExisJS provides feature parity across both functional and object-oriented paradigms. Both compile down to the same runtime execution pipeline:
|
|
54
|
+
- **Functional**: `controller()`, `route.get()`, `route.post()`, `defineBoundary()`, `inject()`.
|
|
55
|
+
- **Class-Based (OOP)**: `@Controller()`, `@Get()`, `@Post()`, `@Boundary()`, `@Injectable()`.
|
|
56
|
+
|
|
57
|
+
### 3. Integrated Schema Validation & OpenAPI 3.1
|
|
58
|
+
The built-in `tex` schema builder provides runtime type validation, parameter coercion, and automated OpenAPI 3.1 schema generation. Every schema defined on a route automatically surfaces in the interactive Swagger UI (`/docs`) and exports types for compile-time frontend client generation.
|
|
59
|
+
|
|
60
|
+
### 4. Hierarchical Security & Error Boundaries
|
|
61
|
+
Directory-based `boundary.ts` files allow you to declare scoped authentication guards, rate limits, CORS configurations, and error handlers that cascade down folder trees without manual middleware repetition.
|
|
62
|
+
|
|
63
|
+
### 5. Resilient Native Fallbacks
|
|
64
|
+
All native Rust bindings (`@exisjs/rs`) include pure TypeScript fallback implementations. If native binaries cannot load on an unsupported architecture, ExisJS automatically runs its pure TypeScript fallback implementations.
|
|
65
|
+
|
|
66
|
+
---
|
|
19
67
|
|
|
20
|
-
|
|
68
|
+
## Feature Matrix
|
|
21
69
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
70
|
+
| Feature Area | ExisJS Built-In Capability | Benefit |
|
|
71
|
+
| :--- | :--- | :--- |
|
|
72
|
+
| **Routing** | File-system route discovery (`src/http/**/route.ts`) | No manual router mounting or path strings |
|
|
73
|
+
| **Validation** | `tex` Schema Validator (Rust accelerated) | Fast parsing, zero-crash sanitization, automatic OpenAPI types |
|
|
74
|
+
| **Documentation** | Automatic Swagger / OpenAPI 3.1 at `/docs` | Self-updating interactive documentation with zero manual sync |
|
|
75
|
+
| **Traffic Control** | Native Token Bucket Rate Limiting & CIDR Filtering | Fast DoS prevention and client throttling |
|
|
76
|
+
| **Security** | Security headers (`helmet`), CSRF, HPP, Body Sanitization | Secure defaults without installing separate packages |
|
|
77
|
+
| **Dependency Injection** | Type-safe IoC container with circular ref resolution | Clean service decoupling with `@Injectable()` and `inject()` |
|
|
78
|
+
| **Background Tasks** | In-process cron scheduler with drift correction | Scheduled jobs without external cron infrastructure |
|
|
79
|
+
| **Observability** | Native OpenTelemetry integration (`exisjs/telemetry`) | Standardized traces, metrics, and structured Pino logging |
|
|
25
80
|
|
|
26
|
-
|
|
27
|
-
The CLI walks you through initial project setup (TypeScript config, import
|
|
28
|
-
aliases, and package manager selection: it detects npm, yarn, pnpm, or bun
|
|
29
|
-
automatically). See [Installation](/docs/installation) for the full list of
|
|
30
|
-
prompts and options.
|
|
31
|
-
</Hint>
|
|
81
|
+
---
|
|
32
82
|
|
|
33
|
-
##
|
|
83
|
+
## Quickstart Comparison
|
|
34
84
|
|
|
35
|
-
|
|
85
|
+
ExisJS allows you to choose the paradigm that best matches your team's conventions.
|
|
36
86
|
|
|
37
|
-
### Functional
|
|
87
|
+
### Functional Paradigm
|
|
38
88
|
|
|
39
89
|
```typescript filename="src/http/users/route.ts"
|
|
40
90
|
import { controller, route } from 'exisjs/router'
|
|
91
|
+
import { tex } from 'exisjs/validator'
|
|
92
|
+
|
|
93
|
+
// 1. Define runtime validation schema
|
|
94
|
+
const CreateUserSchema = tex.object({
|
|
95
|
+
name: tex.string().min(2),
|
|
96
|
+
email: tex.string().email(),
|
|
97
|
+
role: tex.enum(['admin', 'member']).default('member'),
|
|
98
|
+
})
|
|
41
99
|
|
|
100
|
+
// 2. Export functional controller
|
|
42
101
|
export default controller({
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
102
|
+
// GET /users
|
|
103
|
+
listUsers: route.get('/', {
|
|
104
|
+
summary: 'List all active users',
|
|
105
|
+
handle: async () => {
|
|
106
|
+
return [
|
|
107
|
+
{ id: 1, name: 'Alice', role: 'admin' },
|
|
108
|
+
{ id: 2, name: 'Bob', role: 'member' },
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
|
|
113
|
+
// POST /users
|
|
114
|
+
createUser: route.post('/', {
|
|
115
|
+
summary: 'Create a new user',
|
|
116
|
+
body: CreateUserSchema,
|
|
117
|
+
handle: async ({ body }) => {
|
|
46
118
|
return {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
total: 2,
|
|
119
|
+
id: Date.now(),
|
|
120
|
+
name: body.name,
|
|
121
|
+
email: body.email,
|
|
122
|
+
role: body.role,
|
|
52
123
|
}
|
|
53
124
|
},
|
|
54
125
|
}),
|
|
55
126
|
})
|
|
56
127
|
```
|
|
57
128
|
|
|
58
|
-
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
### Class-Based (OOP) Paradigm
|
|
59
132
|
|
|
60
133
|
```typescript filename="src/http/users/route.ts"
|
|
61
|
-
import { Controller, Get,
|
|
62
|
-
import
|
|
134
|
+
import { Controller, Get, Post, Body, ApiOperation } from 'exisjs/decorators'
|
|
135
|
+
import { tex } from 'exisjs/validator'
|
|
63
136
|
|
|
137
|
+
// 1. Define runtime validation schema & inferred type
|
|
138
|
+
const CreateUserSchema = tex.object({
|
|
139
|
+
name: tex.string().min(2),
|
|
140
|
+
email: tex.string().email(),
|
|
141
|
+
role: tex.enum(['admin', 'member']).default('member'),
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
type CreateUserDto = typeof CreateUserSchema.infer
|
|
145
|
+
|
|
146
|
+
// 2. Export class controller
|
|
64
147
|
@Controller()
|
|
65
148
|
export default class UsersController {
|
|
66
149
|
@Get('/')
|
|
67
|
-
|
|
68
|
-
|
|
150
|
+
@ApiOperation({ summary: 'List all active users' })
|
|
151
|
+
async listUsers() {
|
|
152
|
+
return [
|
|
153
|
+
{ id: 1, name: 'Alice', role: 'admin' },
|
|
154
|
+
{ id: 2, name: 'Bob', role: 'member' },
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@Post('/')
|
|
159
|
+
@ApiOperation({ summary: 'Create a new user' })
|
|
160
|
+
async createUser(@Body(CreateUserSchema) body: CreateUserDto) {
|
|
69
161
|
return {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
total: 2,
|
|
162
|
+
id: Date.now(),
|
|
163
|
+
name: body.name,
|
|
164
|
+
email: body.email,
|
|
165
|
+
role: body.role,
|
|
75
166
|
}
|
|
76
167
|
}
|
|
77
168
|
}
|
|
78
169
|
```
|
|
79
170
|
|
|
80
|
-
|
|
171
|
+
---
|
|
81
172
|
|
|
82
|
-
##
|
|
173
|
+
## The Request Lifecycle
|
|
83
174
|
|
|
84
|
-
|
|
175
|
+
Every HTTP request dispatched through ExisJS follows a predictable, high-performance execution lifecycle:
|
|
85
176
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
177
|
+
```
|
|
178
|
+
Incoming Request
|
|
179
|
+
│
|
|
180
|
+
▼
|
|
181
|
+
1. Native Radix Path Match (@exisjs/rs)
|
|
182
|
+
│
|
|
183
|
+
▼
|
|
184
|
+
2. CIDR IP Filter & Rate Limit Check
|
|
185
|
+
│
|
|
186
|
+
▼
|
|
187
|
+
3. Root Boundary (Global Middleware & CORS)
|
|
188
|
+
│
|
|
189
|
+
▼
|
|
190
|
+
4. Nested Folder Boundaries (Scoped Guards & Interceptors)
|
|
191
|
+
│
|
|
192
|
+
▼
|
|
193
|
+
5. Request Body Parsing & TexValidation
|
|
194
|
+
│
|
|
195
|
+
▼
|
|
196
|
+
6. Controller Handler Execution (Functional or Class Method)
|
|
197
|
+
│
|
|
198
|
+
▼
|
|
199
|
+
7. Response Envelope / Stream Serialization
|
|
200
|
+
│
|
|
201
|
+
▼
|
|
202
|
+
Client Response
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Getting Started
|
|
208
|
+
|
|
209
|
+
### Option 1: Create a New Project (Recommended)
|
|
210
|
+
|
|
211
|
+
Use the interactive scaffolding CLI to create a configured ExisJS project:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
npm create exisjs@latest my-backend
|
|
215
|
+
cd my-backend
|
|
216
|
+
npm run dev
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The CLI configures TypeScript, builds the initial directory structure, and starts the development server at `http://localhost:4000`.
|
|
220
|
+
|
|
221
|
+
### Option 2: Add to an Existing Project
|
|
222
|
+
|
|
223
|
+
Install the framework into an existing Node.js project:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm install exisjs
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Create an application configuration file:
|
|
230
|
+
|
|
231
|
+
```typescript filename="exis.config.ts"
|
|
232
|
+
import type { ExisConfig } from 'exisjs/config'
|
|
233
|
+
|
|
234
|
+
const config: ExisConfig = {
|
|
235
|
+
port: Number(process.env.PORT) || 4000,
|
|
236
|
+
cors: {
|
|
237
|
+
origin: '*',
|
|
238
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
|
|
239
|
+
},
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export default config
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Add your first endpoint in `src/http/health/route.ts`:
|
|
246
|
+
|
|
247
|
+
```typescript filename="src/http/health/route.ts"
|
|
248
|
+
import { controller, route } from 'exisjs/router'
|
|
249
|
+
|
|
250
|
+
export default controller({
|
|
251
|
+
check: route.get('/', {
|
|
252
|
+
summary: 'Health check endpoint',
|
|
253
|
+
handle: () => ({ status: 'ok', uptime: process.uptime() }),
|
|
254
|
+
}),
|
|
255
|
+
})
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
89
259
|
|
|
90
|
-
|
|
260
|
+
## Next Steps
|
|
91
261
|
|
|
92
|
-
|
|
262
|
+
Explore the documentation to learn more about developing with ExisJS:
|
|
93
263
|
|
|
94
|
-
- [Installation](/docs/installation)
|
|
95
|
-
- [Structure](/docs/structure)
|
|
96
|
-
- [Routing](/docs/routing)
|
|
264
|
+
- **[Installation Guide](/docs/installation)**: CLI flags, system prerequisites, and TypeScript setup.
|
|
265
|
+
- **[Project Structure](/docs/structure)**: Directory layout and architectural conventions.
|
|
266
|
+
- **[Routing & Endpoints](/docs/routing)**: Dynamic parameters, catch-alls, and nested route groups.
|
|
267
|
+
- **[Validation Guide](/docs/validation)**: Complete schema reference, data coercion, and custom rules.
|
|
268
|
+
- **[Boundaries & Middleware](/docs/boundaries)**: Hierarchical middleware cascading and error boundaries.
|