exisjs 0.7.11 → 0.7.13
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/dev.d.ts +4 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +136 -32
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/run.d.ts +7 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +99 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/index.js +29 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/manifest.d.ts.map +1 -1
- package/dist/cli/manifest.js +18 -3
- package/dist/cli/manifest.js.map +1 -1
- package/dist/cli/routes.d.ts +6 -0
- package/dist/cli/routes.d.ts.map +1 -1
- package/dist/cli/routes.js +224 -135
- package/dist/cli/routes.js.map +1 -1
- package/dist/config/config.d.ts +2 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +30 -9
- package/dist/config/types.d.ts.map +1 -1
- package/dist/database/lifecycle.d.ts +6 -1
- package/dist/database/lifecycle.d.ts.map +1 -1
- package/dist/database/lifecycle.js +15 -4
- package/dist/database/lifecycle.js.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/BENCHMARKS.md +4 -4
- package/dist/docs/content/README.md +43 -44
- package/dist/docs/content/boundaries.mdx +141 -48
- package/dist/docs/content/cli/commands.mdx +161 -107
- package/dist/docs/content/cli/overview.mdx +61 -46
- package/dist/docs/content/cli/usage.mdx +107 -30
- package/dist/docs/content/config.mdx +145 -147
- 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 +239 -558
- 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 -73
- 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 +277 -251
- 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/inspect-routes.d.ts +2 -0
- package/dist/lib/inspect-routes.d.ts.map +1 -0
- package/dist/lib/inspect-routes.js +148 -0
- package/dist/lib/inspect-routes.js.map +1 -0
- package/dist/lib/start-server.js +13 -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/cron-mounter.d.ts.map +1 -1
- package/dist/router/scanner/cron-mounter.js +9 -2
- package/dist/router/scanner/cron-mounter.js.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 +29 -8
- package/dist/server/app.js.map +1 -1
- package/dist/server/define.d.ts.map +1 -1
- package/dist/server/define.js +5 -0
- package/dist/server/define.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/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 +20 -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 +15 -0
- 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 +47 -14
- package/dist/docs/content/dataloader.mdx +0 -170
- package/dist/docs/reference/dataloader.mdx +0 -91
|
@@ -1,75 +1,152 @@
|
|
|
1
1
|
---
|
|
2
|
+
title: "CLI Usage"
|
|
3
|
+
description: "How to run the ExisJS CLI, configure package scripts, forward command-line arguments, and load environments."
|
|
2
4
|
nextUrl: "/docs/cli/commands"
|
|
3
5
|
nextTitle: "CLI Commands"
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# CLI Usage
|
|
7
9
|
|
|
8
|
-
The ExisJS CLI (`
|
|
10
|
+
The ExisJS CLI (`exisjs` or `exis`) can be executed through global package managers, on-demand runner utilities like `npx`, or locally defined `package.json` scripts.
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Execution Methods
|
|
15
|
+
|
|
16
|
+
### 1. On-Demand Execution (`npx`)
|
|
11
17
|
|
|
12
|
-
When
|
|
18
|
+
When initializing a new application or running ad-hoc commands without a global install:
|
|
13
19
|
|
|
14
20
|
```bash
|
|
15
|
-
|
|
21
|
+
# Initialize a project in the current working directory
|
|
22
|
+
npx exisjs init
|
|
23
|
+
|
|
24
|
+
# Check environment diagnostics
|
|
25
|
+
npx exisjs doctor
|
|
26
|
+
|
|
27
|
+
# Print the application routing table
|
|
28
|
+
npx exisjs routes
|
|
16
29
|
```
|
|
17
30
|
|
|
18
|
-
|
|
31
|
+
### 2. Global Installation
|
|
32
|
+
|
|
33
|
+
For system-wide command availability:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Install globally
|
|
37
|
+
npm install -g exisjs
|
|
38
|
+
|
|
39
|
+
# Run directly
|
|
40
|
+
exisjs dev
|
|
41
|
+
exis routes
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 3. Project-Local Scripts (Recommended)
|
|
45
|
+
|
|
46
|
+
When working inside an established project, invoking the CLI via `npm run` ensures consistent execution pinned to the local `exisjs` dependency in `node_modules`.
|
|
47
|
+
|
|
48
|
+
---
|
|
19
49
|
|
|
20
50
|
## Default Package Scripts
|
|
21
51
|
|
|
22
|
-
|
|
52
|
+
Applications initialized with `npx exisjs init` include standard npm lifecycle scripts in `package.json`:
|
|
23
53
|
|
|
24
54
|
```json
|
|
25
55
|
{
|
|
56
|
+
"name": "my-exis-app",
|
|
57
|
+
"version": "1.0.0",
|
|
26
58
|
"scripts": {
|
|
27
59
|
"dev": "exisjs dev",
|
|
28
60
|
"build": "exisjs build",
|
|
61
|
+
"clean": "exisjs clean",
|
|
29
62
|
"start": "exisjs start",
|
|
30
|
-
"test": "exisjs test"
|
|
63
|
+
"test": "exisjs test",
|
|
64
|
+
"routes": "exisjs routes",
|
|
65
|
+
"doctor": "exisjs doctor"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"exisjs": "^1.0.0"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"typescript": "^5.0.0"
|
|
31
72
|
}
|
|
32
73
|
}
|
|
33
74
|
```
|
|
34
75
|
|
|
35
|
-
|
|
76
|
+
Run these scripts using your preferred package manager:
|
|
36
77
|
|
|
37
78
|
```bash
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
79
|
+
# Start development server
|
|
80
|
+
npm run dev
|
|
81
|
+
|
|
82
|
+
# Compile TypeScript and build route manifests
|
|
83
|
+
npm run build
|
|
84
|
+
|
|
85
|
+
# Start production server
|
|
86
|
+
npm run start
|
|
87
|
+
|
|
88
|
+
# Run native test runner
|
|
89
|
+
npm test
|
|
90
|
+
|
|
91
|
+
# Print routing table
|
|
92
|
+
npm run routes
|
|
42
93
|
```
|
|
43
94
|
|
|
44
|
-
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Passing Arguments to Scripts
|
|
45
98
|
|
|
46
|
-
|
|
99
|
+
When invoking CLI commands through `npm run`, use the double-dash delimiter (`--`) to forward flags and positional arguments to `exisjs`:
|
|
47
100
|
|
|
48
101
|
```bash
|
|
49
|
-
#
|
|
50
|
-
|
|
102
|
+
# Run dev server on a custom port
|
|
103
|
+
npm run dev -- -p 4000
|
|
51
104
|
|
|
52
105
|
# Run a specific test file
|
|
53
|
-
|
|
106
|
+
npm test -- tests/users.test.ts
|
|
107
|
+
|
|
108
|
+
# Filter routes table by method and path
|
|
109
|
+
npm run routes -- -m POST -f /api/v1
|
|
54
110
|
```
|
|
55
111
|
|
|
56
|
-
|
|
112
|
+
With `pnpm` or `yarn`:
|
|
57
113
|
|
|
58
114
|
```bash
|
|
59
|
-
#
|
|
60
|
-
|
|
115
|
+
# pnpm forwards arguments directly
|
|
116
|
+
pnpm dev -p 4000
|
|
117
|
+
|
|
118
|
+
# yarn forwards arguments directly
|
|
119
|
+
yarn dev -p 4000
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Environment Configuration
|
|
61
125
|
|
|
62
|
-
|
|
63
|
-
$ npx exisjs routes
|
|
126
|
+
The CLI automatically loads environment variables according to the current execution mode:
|
|
64
127
|
|
|
65
|
-
|
|
66
|
-
|
|
128
|
+
| File | Loaded In | Priority |
|
|
129
|
+
| :--- | :--- | :--- |
|
|
130
|
+
| `.env.local` | All modes (except test) | High |
|
|
131
|
+
| `.env.<mode>` | Matching mode (e.g. `.env.production`) | Medium |
|
|
132
|
+
| `.env` | All modes | Default |
|
|
133
|
+
|
|
134
|
+
### Overriding the Environment Mode
|
|
135
|
+
|
|
136
|
+
Use the `-m, --mode <mode>` flag or set `NODE_ENV`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Build with staging environment variables
|
|
140
|
+
npx exisjs build --mode staging
|
|
141
|
+
|
|
142
|
+
# Execute a script under staging configuration
|
|
143
|
+
npx exisjs run scripts/seed.ts --mode staging
|
|
67
144
|
```
|
|
68
145
|
|
|
69
|
-
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Next Steps
|
|
149
|
+
|
|
150
|
+
- Explore the complete command catalog in the [CLI Command Reference](/docs/cli/commands).
|
|
151
|
+
- Review global server configurations in the [Configuration Guide](/docs/config).
|
|
70
152
|
|
|
71
|
-
1. Use `npx exisjs init <name>` to scaffold new applications.
|
|
72
|
-
2. Use `npm run dev` for local hot-reloading development with automatic port conflict handling.
|
|
73
|
-
3. Use `npx exisjs generate <type> <name>` to scaffold file conventions (`route`, `service`, `schema`, `boundary`, `resource`).
|
|
74
|
-
4. Use `npm test` to run the integrated test runner.
|
|
75
|
-
5. Use `npm run build` and `npm run start` for production deployment.
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
title: "Configuration"
|
|
3
|
+
description: "Global runtime configuration, phases, environment loading, server engine selection, and cluster options in exis.config.ts."
|
|
4
|
+
nextUrl: "/docs/exisjs-mcp"
|
|
5
|
+
nextTitle: "AI Integration (MCP)"
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Configuration (`exis.config.ts`)
|
|
7
9
|
|
|
8
|
-
ExisJS uses a
|
|
9
|
-
|
|
10
|
-
By placing an `exis.config.ts` file in the root of your project, you gain complete control over the underlying server (Node.js or uWebSockets), middleware (CORS, Helmet, Compression), SSL, and the Plugin ecosystem.
|
|
10
|
+
ExisJS uses a typed configuration file located at the project root (`exis.config.ts` or `exis.config.js`). It controls global server behavior, middleware defaults, file watcher options, cluster concurrency, and runtime environments.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## Static Configuration
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Export the result of `defineConfig()` from `exis.config.ts` for full TypeScript type safety and autocompletion:
|
|
17
17
|
|
|
18
18
|
```typescript filename="exis.config.ts"
|
|
19
19
|
import { defineConfig } from 'exisjs/config'
|
|
@@ -23,235 +23,233 @@ export default defineConfig({
|
|
|
23
23
|
host: '0.0.0.0',
|
|
24
24
|
|
|
25
25
|
cors: {
|
|
26
|
-
origin: '
|
|
26
|
+
origin: ['https://example.com', 'https://admin.example.com'],
|
|
27
27
|
credentials: true,
|
|
28
|
+
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
|
|
28
29
|
},
|
|
29
30
|
|
|
30
31
|
logger: {
|
|
31
|
-
level: '
|
|
32
|
-
pretty: true
|
|
32
|
+
level: 'info',
|
|
33
|
+
pretty: true
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
helmet: {
|
|
37
|
+
enabled: true,
|
|
38
|
+
xFrameOptions: 'SAMEORIGIN'
|
|
33
39
|
},
|
|
40
|
+
|
|
41
|
+
bodyLimit: 10 * 1024 * 1024 // 10MB
|
|
34
42
|
})
|
|
35
43
|
```
|
|
36
44
|
|
|
37
45
|
---
|
|
38
46
|
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
Often, you'll need different configurations for Development, Production, or Testing (e.g., enabling pretty logging only in development, or changing the Database URL).
|
|
47
|
+
## Dynamic Phase-Based Configuration
|
|
42
48
|
|
|
43
|
-
ExisJS
|
|
49
|
+
ExisJS supports exporting an asynchronous function that receives the current lifecycle `phase` and the framework's default configuration:
|
|
44
50
|
|
|
45
51
|
```typescript filename="exis.config.ts"
|
|
46
|
-
import {
|
|
52
|
+
import {
|
|
53
|
+
defineConfig,
|
|
54
|
+
PHASE_DEVELOPMENT_SERVER,
|
|
55
|
+
PHASE_PRODUCTION_SERVER,
|
|
56
|
+
PHASE_TEST
|
|
57
|
+
} from 'exisjs/config'
|
|
47
58
|
|
|
48
59
|
export default async (phase: string, { defaultConfig }: any) => {
|
|
49
60
|
const isDev = phase === PHASE_DEVELOPMENT_SERVER
|
|
61
|
+
const isTest = phase === PHASE_TEST
|
|
50
62
|
|
|
51
63
|
return defineConfig({
|
|
52
64
|
port: Number(process.env.PORT) || 4000,
|
|
53
65
|
|
|
54
|
-
|
|
55
|
-
|
|
66
|
+
logger: isDev
|
|
67
|
+
? { level: 'debug', pretty: true }
|
|
68
|
+
: isTest
|
|
69
|
+
? false
|
|
70
|
+
: { level: 'info', pretty: false },
|
|
71
|
+
|
|
72
|
+
compression: !isDev && !isTest,
|
|
56
73
|
|
|
57
|
-
|
|
58
|
-
|
|
74
|
+
cluster: {
|
|
75
|
+
workers: phase === PHASE_PRODUCTION_SERVER ? 'auto' : 1
|
|
76
|
+
}
|
|
59
77
|
})
|
|
60
78
|
}
|
|
61
79
|
```
|
|
62
80
|
|
|
63
|
-
|
|
81
|
+
### Lifecycle Phase Constants
|
|
64
82
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
83
|
+
| Constant | Value | Triggered By |
|
|
84
|
+
| :--- | :--- | :--- |
|
|
85
|
+
| `PHASE_DEVELOPMENT_SERVER` | `'phase-development-server'` | `exisjs dev` |
|
|
86
|
+
| `PHASE_PRODUCTION_SERVER` | `'phase-production-server'` | `exisjs start` |
|
|
87
|
+
| `PHASE_PRODUCTION_BUILD` | `'phase-production-build'` | `exisjs build` |
|
|
88
|
+
| `PHASE_TEST` | `'phase-test'` | `exisjs test` / `NODE_ENV=test` |
|
|
68
89
|
|
|
69
90
|
---
|
|
70
91
|
|
|
71
|
-
##
|
|
92
|
+
## Environment Variable Management
|
|
72
93
|
|
|
73
|
-
|
|
94
|
+
ExisJS automatically loads and expands `.env` files in cascade priority:
|
|
74
95
|
|
|
75
|
-
|
|
96
|
+
1. `.env.${NODE_ENV}.local`
|
|
97
|
+
2. `.env.local` (ignored when `NODE_ENV=test`)
|
|
98
|
+
3. `.env.${NODE_ENV}`
|
|
99
|
+
4. `.env`
|
|
100
|
+
|
|
101
|
+
### Type-Safe Validation with `tex`
|
|
102
|
+
|
|
103
|
+
To ensure configuration values are valid before starting the HTTP server:
|
|
104
|
+
|
|
105
|
+
```typescript filename="src/config/env.ts"
|
|
76
106
|
import { tex } from 'exisjs/validator'
|
|
77
107
|
|
|
78
108
|
export const env = tex
|
|
79
109
|
.object({
|
|
80
|
-
PORT: tex.number({ coerce: true,
|
|
81
|
-
NODE_ENV: tex.
|
|
82
|
-
|
|
110
|
+
PORT: tex.number({ coerce: true, default: 4000 }),
|
|
111
|
+
NODE_ENV: tex.enum(['development', 'production', 'test'], { default: 'development' }),
|
|
112
|
+
DATABASE_URL: tex.string(),
|
|
113
|
+
REDIS_URL: tex.string({ optional: true })
|
|
83
114
|
})
|
|
84
115
|
.parse(process.env)
|
|
85
116
|
```
|
|
86
117
|
|
|
87
118
|
```typescript filename="exis.config.ts"
|
|
88
119
|
import { defineConfig } from 'exisjs/config'
|
|
89
|
-
import { env } from './env
|
|
120
|
+
import { env } from './src/config/env'
|
|
90
121
|
|
|
91
122
|
export default defineConfig({
|
|
92
123
|
port: env.PORT,
|
|
93
|
-
|
|
94
|
-
pretty: env.NODE_ENV !== 'production',
|
|
95
|
-
},
|
|
124
|
+
env: env.NODE_ENV
|
|
96
125
|
})
|
|
97
126
|
```
|
|
98
127
|
|
|
99
128
|
---
|
|
100
129
|
|
|
101
|
-
##
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
130
|
+
## Configuration Options Reference
|
|
131
|
+
|
|
132
|
+
### Network & Transport
|
|
133
|
+
|
|
134
|
+
| Option | Type | Default | Description |
|
|
135
|
+
| :--- | :--- | :--- | :--- |
|
|
136
|
+
| `port` | `number` | `4000` | Port number to bind the HTTP server to. |
|
|
137
|
+
| `host` | `string` | `'0.0.0.0'` | Network host interface. |
|
|
138
|
+
| `server` | `'auto' \| 'node' \| 'bun' \| 'uws'` | `'auto'` | Underlying server adapter engine. |
|
|
139
|
+
| `ssl` | `{ key: string \| Buffer, cert: string \| Buffer }` | `undefined` | SSL certificate credentials for native HTTPS. |
|
|
140
|
+
| `http2` | `boolean` | `true` | Enables HTTP/2 (active when SSL is configured). |
|
|
141
|
+
| `redirectHttp` | `boolean \| number` | `false` | Automatically redirects plaintext HTTP traffic to HTTPS. |
|
|
142
|
+
| `trustProxy` | `boolean \| number` | `false` | Respects `X-Forwarded-For` and `X-Forwarded-Proto` proxy headers. |
|
|
143
|
+
| `keepAlive` | `boolean \| KeepAliveConfig` | `false` | Configures socket keep-alive (`timeoutMs`, `headersTimeoutMs`, `maxRequests`). |
|
|
144
|
+
|
|
145
|
+
### Middleware Defaults & Security
|
|
146
|
+
|
|
147
|
+
| Option | Type | Default | Description |
|
|
148
|
+
| :--- | :--- | :--- | :--- |
|
|
149
|
+
| `cors` | `boolean \| CorsConfig` | `{ origin: '*' }` | Global CORS policy. Can be overridden in boundaries or routes. |
|
|
150
|
+
| `helmet` | `boolean \| HelmetConfig` | `{ enabled: true }` | Security headers (CSP, X-Frame-Options, HSTS). |
|
|
151
|
+
| `compression` | `boolean` | `false` | Gzip/Brotli HTTP response compression. |
|
|
152
|
+
| `bodyLimit` | `number` | `10485760` (10MB) | Maximum request payload body size in bytes. |
|
|
153
|
+
| `blockSuspiciousProbes` | `boolean \| BlockProbesOptions` | `false` | Blocks known vulnerability scanners and malicious probes (`.php`, `wp-admin`). |
|
|
154
|
+
| `etag` | `boolean` | `false` | Generates weak ETags for cache validation on responses. |
|
|
155
|
+
| `transformResponse` | `boolean \| Function` | `false` | Standardizes handler response payload envelopes. |
|
|
156
|
+
|
|
157
|
+
### Logging & Diagnostics
|
|
158
|
+
|
|
159
|
+
| Option | Type | Default | Description |
|
|
160
|
+
| :--- | :--- | :--- | :--- |
|
|
161
|
+
| `logger` | `boolean \| LoggerConfig` | `false` | Pino logger settings (`level`, `pretty`, `redact`). |
|
|
162
|
+
| `debugRouting` | `boolean` | `false` | Outputs detailed route resolution logs per request in development. |
|
|
163
|
+
| `asyncContext` | `boolean` | `false` | Enables `AsyncLocalStorage` context tracking (`getContext()`). |
|
|
164
|
+
| `docs` / `swagger` | `boolean \| SwaggerConfig` | `{ enabled: false }` | OpenAPI 3.1 specification and Swagger UI endpoint generation. |
|
|
165
|
+
| `healthcheck` | `boolean \| HealthCheckConfig` | `{ enabled: false }` | System health endpoint (`path: '/_health'`). |
|
|
166
|
+
| `metrics` | `boolean \| MetricsConfig` | `{ enabled: false }` | Prometheus metrics endpoint (`path: '/metrics'`). |
|
|
167
|
+
| `telemetry` | `boolean \| TelemetryConfig` | `{ enabled: false }` | OpenTelemetry tracing and metrics export. |
|
|
168
|
+
|
|
169
|
+
### Concurrency & Clustering
|
|
106
170
|
|
|
107
171
|
```typescript filename="exis.config.ts"
|
|
172
|
+
import { defineConfig } from 'exisjs/config'
|
|
173
|
+
|
|
108
174
|
export default defineConfig({
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
175
|
+
cluster: {
|
|
176
|
+
// 1 (single-threaded), 'safe' (up to 2 cores), 'auto'/'max' (all available CPU cores)
|
|
177
|
+
workers: 'auto'
|
|
178
|
+
}
|
|
113
179
|
})
|
|
114
180
|
```
|
|
115
181
|
|
|
116
182
|
---
|
|
117
183
|
|
|
118
|
-
##
|
|
184
|
+
## File Watcher & Development Configuration
|
|
119
185
|
|
|
120
|
-
|
|
186
|
+
The development server (`exisjs dev`) provides file watching with debounce and ignore rules:
|
|
121
187
|
|
|
122
188
|
```typescript filename="exis.config.ts"
|
|
189
|
+
import { defineConfig } from 'exisjs/config'
|
|
190
|
+
|
|
123
191
|
export default defineConfig({
|
|
124
|
-
|
|
125
|
-
|
|
192
|
+
watch: {
|
|
193
|
+
paths: ['src', '.env'],
|
|
194
|
+
ignore: [/tests\//, 'temp/**'],
|
|
195
|
+
extensions: ['.ts', '.tsx', '.js', '.json'],
|
|
196
|
+
debounceMs: 250
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
dev: {
|
|
200
|
+
usePolling: false, // Set to true for network mounts or WSL
|
|
201
|
+
interval: 100
|
|
202
|
+
}
|
|
126
203
|
})
|
|
127
204
|
```
|
|
128
205
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
## 6. Complete Options Reference
|
|
132
|
-
|
|
133
|
-
Here is a full breakdown of the configuration schema:
|
|
134
|
-
|
|
135
|
-
### Network & SSL
|
|
206
|
+
### Automatically Excluded Artifacts
|
|
136
207
|
|
|
137
|
-
|
|
138
|
-
- `
|
|
139
|
-
-
|
|
140
|
-
- `http2` _(boolean)_: Enables HTTP/2 support natively. (Defaults to `true` when SSL is provided).
|
|
141
|
-
- `redirectHttp` _(boolean | number)_: Automatically intercepts HTTP requests and redirects them to HTTPS.
|
|
142
|
-
|
|
143
|
-
### Global Middleware
|
|
144
|
-
|
|
145
|
-
- `cors` _(object | boolean)_: Global CORS policy configuration. Supports:
|
|
146
|
-
- Exact string origins (e.g. `'https://example.com'` or `'*'`).
|
|
147
|
-
- Regular expressions (e.g. `/localhost:\d+/`).
|
|
148
|
-
- Arrays mixing strings and regexes (`['https://app.example.com', /https:\/\/.*\.domain\.com/']`).
|
|
149
|
-
- Dynamic callbacks: `(origin, cb) => ...` or async functions: `async (origin) => boolean` for multi-tenant setups.
|
|
150
|
-
- `transformResponse` _(boolean | function)_: Automatically wraps all successful handler responses into a standardized envelope:
|
|
151
|
-
- When `true`: `{ success: true, data: ..., timestamp: ... }` (matching `HttpError`'s `{ success: false, error: ... }`).
|
|
152
|
-
- When a function: `(data, req, res) => ({ ... })` to provide your own custom envelope.
|
|
153
|
-
- `helmet` _(object | boolean)_: Automatically secures your app with standard HTTP headers. (Enabled by default).
|
|
154
|
-
- `compression` _(object | boolean)_: Enables Gzip/Brotli compression for all HTTP responses.
|
|
155
|
-
- `logger` _(object | boolean)_: Configures the internal Pino-based logger (`level`, `pretty`).
|
|
156
|
-
- `etag` _(boolean)_: Automatically generates ETag headers for cache-invalidation.
|
|
157
|
-
|
|
158
|
-
### Performance & Security
|
|
159
|
-
|
|
160
|
-
- `bodyLimit` _(number)_: The maximum allowed size (in bytes) for incoming request bodies. (Default: `10MB` / `10485760` bytes, raising HTTP 413 `PayloadTooLargeError` when exceeded)
|
|
161
|
-
- `trustProxy` _(boolean | number)_: If true, respects `X-Forwarded-For` and `X-Forwarded-Host` headers (essential for apps deployed behind NGINX, Cloudflare, or AWS ELB). If a number, trusts that many hops.
|
|
162
|
-
- `keepAlive` _(object | boolean)_: Tunes the Keep-Alive timeout and Header timeout limits.
|
|
163
|
-
- `workers` _(number | 'safe' | 'max')_: Number of CPU workers for cluster mode. Defaults to 1. 'safe' caps to 2. 'max' uses all available cores.
|
|
164
|
-
|
|
165
|
-
### Execution & Debugging
|
|
166
|
-
|
|
167
|
-
- `env` _(string)_: Overrides the environment. Can be 'development', 'production', or 'test'.
|
|
168
|
-
- `server` _('auto' | 'node' | 'uws')_: Server backend to use. Defaults to 'node'.
|
|
169
|
-
- `debugRouting` _(boolean)_: Enables detailed logging of the resolved route file and applied gateways for every incoming request.
|
|
170
|
-
- `test` _(object)_: Configuration for the native test runner (`include`, `exclude`, `setupFiles`, `concurrency`, `coverage`).
|
|
171
|
-
|
|
172
|
-
### Development Server & File Watcher (`dev`)
|
|
173
|
-
|
|
174
|
-
- `dev.watch` _(string[])_: Custom paths or glob patterns to watch during development (defaults to `[cwd]`).
|
|
175
|
-
- `dev.ignored` _((string | RegExp)[])_: Additional files or patterns to ignore during watch restarts.
|
|
176
|
-
- `dev.usePolling` _(boolean)_: Enables filesystem polling for cross-platform/Windows NTFS reliability (defaults to `true` on Windows).
|
|
177
|
-
- `dev.interval` _(number)_: Polling interval in milliseconds (default: `100`).
|
|
178
|
-
- `dev.binaryInterval` _(number)_: Polling binary interval in milliseconds (default: `300`).
|
|
179
|
-
|
|
180
|
-
### Queues & Plugins
|
|
181
|
-
|
|
182
|
-
- `queue` _(object)_: Configures the Global Job Queue driver (`memory` or `redis`) and backpressure settings.
|
|
183
|
-
- `plugins` _(array)_: Registers framework-level plugins.
|
|
208
|
+
ExisJS automatically excludes build output and temp folders from triggering watcher reloads:
|
|
209
|
+
- **Folders**: `node_modules`, `.git`, `.exis`, `dist`, `build`, `out`, `.turbo`, `.next`, `.cache`, `logs`, `tmp`, `temp`, `tests`, `coverage`.
|
|
210
|
+
- **Files**: `.log`, `.sqlite`, `.db`, `.png`, `.jpg`, `.svg`, `package-lock.json`, `*.d.ts`.
|
|
184
211
|
|
|
185
212
|
---
|
|
186
213
|
|
|
187
|
-
##
|
|
188
|
-
|
|
189
|
-
The ExisJS configuration file is also where you integrate native plugins and modules.
|
|
214
|
+
## Plugin Integration
|
|
190
215
|
|
|
191
|
-
|
|
216
|
+
Plugins extend framework capabilities by intercepting server configuration or registering global routes:
|
|
192
217
|
|
|
193
218
|
```typescript filename="exis.config.ts"
|
|
194
219
|
import { defineConfig } from 'exisjs/config'
|
|
195
220
|
import { defineModule } from 'exisjs/module'
|
|
196
221
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
},
|
|
206
|
-
})
|
|
222
|
+
const metricsPlugin = defineModule({
|
|
223
|
+
name: 'custom-metrics',
|
|
224
|
+
routes: (app) => {
|
|
225
|
+
app.get('/metrics/live', (req, res) => {
|
|
226
|
+
res.json({ memory: process.memoryUsage() })
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
})
|
|
207
230
|
|
|
208
|
-
// 2. Register it in your config
|
|
209
231
|
export default defineConfig({
|
|
210
|
-
plugins: [
|
|
232
|
+
plugins: [metricsPlugin]
|
|
211
233
|
})
|
|
212
234
|
```
|
|
213
235
|
|
|
214
236
|
---
|
|
215
237
|
|
|
216
|
-
##
|
|
217
|
-
|
|
218
|
-
ExisJS expects a **One App Per Process** architecture.
|
|
219
|
-
|
|
220
|
-
### Zero-Config Singletons
|
|
221
|
-
|
|
222
|
-
ExisJS's highly ergonomic integrations (e.g., `redis.ts`, `prisma.ts`, `s3.ts`) are implemented using ES6 Proxies that cache the underlying clients at the module level. This means they are **process-wide singletons**.
|
|
223
|
-
If you attempt to mount multiple `App` instances inside a single Node.js process to serve different tenants, they will **share the exact same database connections, redis pools, and caches**.
|
|
224
|
-
|
|
225
|
-
### Multi-Tenant Guidance
|
|
226
|
-
|
|
227
|
-
If you are building a multi-tenant B2B application, do not boot multiple ExisJS `App` instances per tenant. Instead, use one of the following standard approaches:
|
|
228
|
-
|
|
229
|
-
1. **Row-Level Tenancy (Recommended)**: Run a single `App` connected to a single database. Use request context or middleware to inject the `tenantId` and scope all queries via Prisma/SQL.
|
|
230
|
-
2. **Factory-Based Clients**: If you need true database-per-tenant isolation, do not use the zero-config singleton exports (like `import { db } from 'exisjs/prisma'`). Instead, manually construct the client factories inside a tenant-resolution middleware and attach them to the request context (`req.tenantDb`).
|
|
231
|
-
3. **Containerized Deployments**: Run separate Node.js processes (Docker containers) for each tenant, passing tenant-specific `DATABASE_URL`s to each container.
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
## 9. Graceful Shutdown & Zero-Downtime Deployments
|
|
238
|
+
## Graceful Process Termination
|
|
236
239
|
|
|
237
|
-
|
|
240
|
+
ExisJS automatically listens for `SIGTERM` and `SIGINT` signals in containerized environments:
|
|
238
241
|
|
|
239
|
-
1.
|
|
240
|
-
2.
|
|
241
|
-
3.
|
|
242
|
-
4. **Lifecycle Teardown**: Automatically invokes your application's `onStop(app)` hook so you can cleanly disconnect databases, Redis pools, or message brokers.
|
|
242
|
+
1. Closes the HTTP server listener to stop accepting incoming traffic.
|
|
243
|
+
2. Closes idle keep-alive sockets (`server.closeIdleConnections()`).
|
|
244
|
+
3. Executes registered `onStop(app)` hooks to disconnect databases, Redis pools, or message brokers.
|
|
243
245
|
|
|
244
246
|
```typescript filename="src/http/server.ts"
|
|
245
247
|
import { exis } from 'exisjs'
|
|
246
|
-
import { db } from '
|
|
248
|
+
import { db } from '../database/db'
|
|
247
249
|
|
|
248
250
|
export default exis({
|
|
249
|
-
async onStart(app) {
|
|
250
|
-
await db.connect()
|
|
251
|
-
},
|
|
252
251
|
async onStop(app) {
|
|
253
|
-
// Cleanly close database pools when SIGTERM or SIGINT is received
|
|
254
252
|
await db.disconnect()
|
|
255
|
-
}
|
|
253
|
+
}
|
|
256
254
|
})
|
|
257
255
|
```
|