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.
Files changed (150) hide show
  1. package/README.md +195 -39
  2. package/dist/cli/commands/dev.d.ts +4 -0
  3. package/dist/cli/commands/dev.d.ts.map +1 -1
  4. package/dist/cli/commands/dev.js +136 -32
  5. package/dist/cli/commands/dev.js.map +1 -1
  6. package/dist/cli/commands/run.d.ts +7 -0
  7. package/dist/cli/commands/run.d.ts.map +1 -0
  8. package/dist/cli/commands/run.js +99 -0
  9. package/dist/cli/commands/run.js.map +1 -0
  10. package/dist/cli/index.js +29 -13
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/manifest.d.ts.map +1 -1
  13. package/dist/cli/manifest.js +18 -3
  14. package/dist/cli/manifest.js.map +1 -1
  15. package/dist/cli/routes.d.ts +6 -0
  16. package/dist/cli/routes.d.ts.map +1 -1
  17. package/dist/cli/routes.js +224 -135
  18. package/dist/cli/routes.js.map +1 -1
  19. package/dist/config/config.d.ts +2 -1
  20. package/dist/config/config.d.ts.map +1 -1
  21. package/dist/config/config.js.map +1 -1
  22. package/dist/config/types.d.ts +30 -9
  23. package/dist/config/types.d.ts.map +1 -1
  24. package/dist/database/lifecycle.d.ts +6 -1
  25. package/dist/database/lifecycle.d.ts.map +1 -1
  26. package/dist/database/lifecycle.js +15 -4
  27. package/dist/database/lifecycle.js.map +1 -1
  28. package/dist/decorators/params.d.ts +21 -0
  29. package/dist/decorators/params.d.ts.map +1 -1
  30. package/dist/decorators/params.js +21 -1
  31. package/dist/decorators/params.js.map +1 -1
  32. package/dist/di/container.d.ts +15 -6
  33. package/dist/di/container.d.ts.map +1 -1
  34. package/dist/di/container.js +26 -3
  35. package/dist/di/container.js.map +1 -1
  36. package/dist/di/index.d.ts +1 -1
  37. package/dist/di/index.d.ts.map +1 -1
  38. package/dist/di/index.js.map +1 -1
  39. package/dist/di/inject.d.ts +2 -1
  40. package/dist/di/inject.d.ts.map +1 -1
  41. package/dist/di/inject.js +2 -1
  42. package/dist/di/inject.js.map +1 -1
  43. package/dist/docs/BENCHMARKS.md +4 -4
  44. package/dist/docs/content/README.md +43 -44
  45. package/dist/docs/content/boundaries.mdx +141 -48
  46. package/dist/docs/content/cli/commands.mdx +161 -107
  47. package/dist/docs/content/cli/overview.mdx +61 -46
  48. package/dist/docs/content/cli/usage.mdx +107 -30
  49. package/dist/docs/content/config.mdx +145 -147
  50. package/dist/docs/content/controllers.mdx +193 -464
  51. package/dist/docs/content/cron.mdx +183 -69
  52. package/dist/docs/content/decorators.mdx +449 -154
  53. package/dist/docs/content/errors.mdx +202 -305
  54. package/dist/docs/content/exisjs-mcp.mdx +59 -49
  55. package/dist/docs/content/installation.mdx +243 -157
  56. package/dist/docs/content/introduction.mdx +220 -48
  57. package/dist/docs/content/middleware.mdx +171 -497
  58. package/dist/docs/content/modules.mdx +141 -83
  59. package/dist/docs/content/providers.mdx +216 -180
  60. package/dist/docs/content/requests.mdx +168 -488
  61. package/dist/docs/content/responses.mdx +200 -533
  62. package/dist/docs/content/routing.mdx +239 -558
  63. package/dist/docs/content/security.mdx +233 -57
  64. package/dist/docs/content/structure.mdx +151 -240
  65. package/dist/docs/content/swagger.mdx +192 -91
  66. package/dist/docs/content/testing.mdx +205 -74
  67. package/dist/docs/content/validation.mdx +479 -341
  68. package/dist/docs/reference/README.md +34 -2
  69. package/dist/docs/reference/config.mdx +277 -73
  70. package/dist/docs/reference/context.mdx +197 -106
  71. package/dist/docs/reference/cron.mdx +266 -152
  72. package/dist/docs/reference/database.mdx +135 -53
  73. package/dist/docs/reference/decorators.mdx +234 -116
  74. package/dist/docs/reference/di.mdx +146 -112
  75. package/dist/docs/reference/error.mdx +155 -178
  76. package/dist/docs/reference/exis.mdx +141 -70
  77. package/dist/docs/reference/logger.mdx +110 -126
  78. package/dist/docs/reference/middleware.mdx +235 -158
  79. package/dist/docs/reference/plugin.mdx +136 -64
  80. package/dist/docs/reference/router.mdx +277 -251
  81. package/dist/docs/reference/sanitize.mdx +91 -87
  82. package/dist/docs/reference/swagger.mdx +280 -100
  83. package/dist/docs/reference/testing.mdx +223 -89
  84. package/dist/docs/reference/validator.mdx +194 -206
  85. package/dist/lib/inspect-routes.d.ts +2 -0
  86. package/dist/lib/inspect-routes.d.ts.map +1 -0
  87. package/dist/lib/inspect-routes.js +148 -0
  88. package/dist/lib/inspect-routes.js.map +1 -0
  89. package/dist/lib/start-server.js +13 -8
  90. package/dist/lib/start-server.js.map +1 -1
  91. package/dist/module/module.d.ts +6 -3
  92. package/dist/module/module.d.ts.map +1 -1
  93. package/dist/module/module.js +17 -3
  94. package/dist/module/module.js.map +1 -1
  95. package/dist/router/controller-registrar.d.ts.map +1 -1
  96. package/dist/router/controller-registrar.js +26 -4
  97. package/dist/router/controller-registrar.js.map +1 -1
  98. package/dist/router/scanner/cron-mounter.d.ts.map +1 -1
  99. package/dist/router/scanner/cron-mounter.js +9 -2
  100. package/dist/router/scanner/cron-mounter.js.map +1 -1
  101. package/dist/server/app.d.ts +3 -1
  102. package/dist/server/app.d.ts.map +1 -1
  103. package/dist/server/app.js +29 -8
  104. package/dist/server/app.js.map +1 -1
  105. package/dist/server/define.d.ts.map +1 -1
  106. package/dist/server/define.js +5 -0
  107. package/dist/server/define.js.map +1 -1
  108. package/dist/server/request.d.ts +2 -0
  109. package/dist/server/request.d.ts.map +1 -1
  110. package/dist/server/request.js +11 -0
  111. package/dist/server/request.js.map +1 -1
  112. package/dist/swagger/generator.d.ts.map +1 -1
  113. package/dist/swagger/generator.js +130 -10
  114. package/dist/swagger/generator.js.map +1 -1
  115. package/dist/telemetry/index.d.ts +12 -0
  116. package/dist/telemetry/index.d.ts.map +1 -0
  117. package/dist/telemetry/index.js +121 -0
  118. package/dist/telemetry/index.js.map +1 -0
  119. package/dist/testing/client.d.ts +1 -0
  120. package/dist/testing/client.d.ts.map +1 -1
  121. package/dist/testing/client.js +4 -1
  122. package/dist/testing/client.js.map +1 -1
  123. package/dist/testing/index.d.ts.map +1 -1
  124. package/dist/testing/index.js +20 -4
  125. package/dist/testing/index.js.map +1 -1
  126. package/dist/validator/builder.d.ts +26 -1
  127. package/dist/validator/builder.d.ts.map +1 -1
  128. package/dist/validator/builder.js +31 -0
  129. package/dist/validator/builder.js.map +1 -1
  130. package/dist/validator/engine.d.ts +23 -0
  131. package/dist/validator/engine.d.ts.map +1 -1
  132. package/dist/validator/engine.js +228 -31
  133. package/dist/validator/engine.js.map +1 -1
  134. package/dist/validator/index.d.ts +8 -4
  135. package/dist/validator/index.d.ts.map +1 -1
  136. package/dist/validator/index.js +4 -1
  137. package/dist/validator/index.js.map +1 -1
  138. package/dist/validator/tex-types.d.ts +15 -0
  139. package/dist/validator/tex-types.d.ts.map +1 -1
  140. package/dist/validator/tex-types.js +102 -0
  141. package/dist/validator/tex-types.js.map +1 -1
  142. package/dist/validator/tex.d.ts +1 -1
  143. package/dist/validator/tex.d.ts.map +1 -1
  144. package/dist/validator/tex.js +3 -1
  145. package/dist/validator/tex.js.map +1 -1
  146. package/dist/validator/types.d.ts +1 -0
  147. package/dist/validator/types.d.ts.map +1 -1
  148. package/package.json +47 -14
  149. package/dist/docs/content/dataloader.mdx +0 -170
  150. 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 (`exis` / `exisjs`) can be executed in two primary contexts: **globally / on-demand** via `npx`, or **locally** via your project's `package.json` scripts.
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
- ## Global vs. Local Execution
12
+ ---
13
+
14
+ ## Execution Methods
15
+
16
+ ### 1. On-Demand Execution (`npx`)
11
17
 
12
- When bootstrapping a brand-new project, invoke the initialization tool using `npx`:
18
+ When initializing a new application or running ad-hoc commands without a global install:
13
19
 
14
20
  ```bash
15
- $ npx exisjs init my-api
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
- Once inside an initialized ExisJS project, execution through `npm run` ensures deterministic behavior pinned to the local `exisjs` version in `node_modules`.
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
- Every ExisJS project scaffolded with `init` includes the standard script targets in `package.json`:
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
- Invoke these scripts using your package manager:
76
+ Run these scripts using your preferred package manager:
36
77
 
37
78
  ```bash
38
- $ npm run dev
39
- $ npm run build
40
- $ npm run start
41
- $ npm test
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
- ## Passing Arguments via Scripts
95
+ ---
96
+
97
+ ## Passing Arguments to Scripts
45
98
 
46
- To pass options through `npm run`, append a double-dash (`--`) before the CLI flags:
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
- # Start the dev server on port 5000
50
- $ npm run dev -- -p 5000
102
+ # Run dev server on a custom port
103
+ npm run dev -- -p 4000
51
104
 
52
105
  # Run a specific test file
53
- $ npm test -- tests/users.test.ts
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
- Direct commands can also be called via `npx exisjs`:
112
+ With `pnpm` or `yarn`:
57
113
 
58
114
  ```bash
59
- # Scaffold a new resource slice
60
- $ npx exisjs g resource users
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
- # Print the routing table
63
- $ npx exisjs routes
126
+ The CLI automatically loads environment variables according to the current execution mode:
64
127
 
65
- # Inspect available public exports
66
- $ npx exisjs exports
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
- ## Recommended Workflow
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
- nextUrl: '/docs/routing'
3
- nextTitle: 'Routing'
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 fully typed configuration engine that closely resembles Vite or Next.js.
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
- ## 1. Basic Configuration
14
+ ## Static Configuration
15
15
 
16
- A basic configuration simply exports the result of `defineConfig`. This provides TypeScript autocomplete for all available options.
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: 'debug',
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
- ## 2. Dynamic & Phase-Based Config
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 allows you to export an `async function` that provides the current `phase` (Environment).
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 { defineConfig, PHASE_DEVELOPMENT_SERVER } from 'exisjs/config'
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
- // Enable pretty logging only in Development
55
- logger: isDev ? { level: 'debug', pretty: true } : false,
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
- // Compress responses in Production
58
- compression: !isDev,
74
+ cluster: {
75
+ workers: phase === PHASE_PRODUCTION_SERVER ? 'auto' : 1
76
+ }
59
77
  })
60
78
  }
61
79
  ```
62
80
 
63
- The available phases are:
81
+ ### Lifecycle Phase Constants
64
82
 
65
- - `PHASE_DEVELOPMENT_SERVER` (Triggered via `exis dev`)
66
- - `PHASE_PRODUCTION_SERVER` (Triggered via `exis start`)
67
- - `PHASE_TEST` (Triggered when `NODE_ENV=test`)
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
- ## 3. Type-Safe Environment Variables
92
+ ## Environment Variable Management
72
93
 
73
- We highly recommend using `v.env()` from `exisjs/validator` to strongly type and validate your environment variables before the server starts. You can create an `env.ts` file and import it directly into your `exis.config.ts`.
94
+ ExisJS automatically loads and expands `.env` files in cascade priority:
74
95
 
75
- ```typescript filename="env.ts"
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, optional: true }),
81
- NODE_ENV: tex.string({ optional: true }),
82
- MONGODB_URI: tex.string(),
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.ts' // Fails fast if variables are missing!
120
+ import { env } from './src/config/env'
90
121
 
91
122
  export default defineConfig({
92
123
  port: env.PORT,
93
- logger: {
94
- pretty: env.NODE_ENV !== 'production',
95
- },
124
+ env: env.NODE_ENV
96
125
  })
97
126
  ```
98
127
 
99
128
  ---
100
129
 
101
- ## 4. Background Jobs & Workers
102
-
103
- To enable the background job engine (which powers scheduled Cron jobs and the task queue), you must explicitly configure a `queue` driver in `exis.config.ts`.
104
-
105
- If this is missing, the job scheduler is completely disabled to save memory.
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
- queue: {
110
- driver: 'memory', // Use 'redis' for multi-server production
111
- enableWorkers: true, // Set to false to push jobs but not process them
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
- ## 5. The Underlying Server Engine
184
+ ## File Watcher & Development Configuration
119
185
 
120
- By default, ExisJS uses the native Node.js HTTP/HTTPS modules. However, you can seamlessly switch the underlying engine to **uWebSockets.js (uWS)** for significantly higher throughput.
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
- // 'auto' will use uWS if installed, otherwise gracefully fallback to Node
125
- server: 'auto', // 'auto' | 'node' | 'bun'
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
- - `port` _(number)_: The port the server will bind to. (Default: `4000`)
138
- - `host` _(string)_: The host interface to bind to. (Default: `'0.0.0.0'`)
139
- - `ssl` _(object)_: Provide `{ key, cert }` strings or Buffers to enable HTTPS natively.
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
- ## 7. ExisJS Plugin Ecosystem
188
-
189
- The ExisJS configuration file is also where you integrate native plugins and modules.
214
+ ## Plugin Integration
190
215
 
191
- You can easily build your own plugins using `defineModule` from `exisjs/module`. Under the hood, plugins get full access to the `app` instance to register routes, providers, or lifecycle hooks!
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
- // 1. Create a custom plugin (e.g., a mock GraphQL endpoint)
198
- const graphqlPlugin = (options: { endpoint: string }) =>
199
- defineModule({
200
- name: 'graphql',
201
- routes: (app) => {
202
- app.post(options.endpoint, (req, res) =>
203
- res.json({ data: 'GraphQL Response' })
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: [graphqlPlugin({ endpoint: '/graphql' })],
232
+ plugins: [metricsPlugin]
211
233
  })
212
234
  ```
213
235
 
214
236
  ---
215
237
 
216
- ## 8. Process Model & Multi-Tenancy
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
- When deploying in Kubernetes, Docker Swarm, AWS ECS, or PM2, containers receive `SIGTERM` signals when being replaced. ExisJS handles graceful shutdown out of the box:
240
+ ExisJS automatically listens for `SIGTERM` and `SIGINT` signals in containerized environments:
238
241
 
239
- 1. **Stops Accepting New Connections**: Immediately closes the server listener so load balancers stop routing new traffic to the terminating instance.
240
- 2. **Closes Idle Keep-Alive Connections**: Closes lingering idle HTTP keep-alive sockets instantly via `server.closeIdleConnections()`, preventing the process from hanging.
241
- 3. **Drains In-Flight Requests**: Grants in-flight requests time to finish before terminating.
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 './db'
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
  ```