exisjs 0.7.11 → 0.7.12

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 (53) hide show
  1. package/dist/cli/commands/dev.d.ts +4 -0
  2. package/dist/cli/commands/dev.d.ts.map +1 -1
  3. package/dist/cli/commands/dev.js +136 -32
  4. package/dist/cli/commands/dev.js.map +1 -1
  5. package/dist/cli/commands/run.d.ts +7 -0
  6. package/dist/cli/commands/run.d.ts.map +1 -0
  7. package/dist/cli/commands/run.js +99 -0
  8. package/dist/cli/commands/run.js.map +1 -0
  9. package/dist/cli/index.js +29 -13
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/cli/manifest.d.ts.map +1 -1
  12. package/dist/cli/manifest.js +18 -3
  13. package/dist/cli/manifest.js.map +1 -1
  14. package/dist/cli/routes.d.ts +6 -0
  15. package/dist/cli/routes.d.ts.map +1 -1
  16. package/dist/cli/routes.js +224 -135
  17. package/dist/cli/routes.js.map +1 -1
  18. package/dist/config/config.d.ts +2 -1
  19. package/dist/config/config.d.ts.map +1 -1
  20. package/dist/config/config.js.map +1 -1
  21. package/dist/config/types.d.ts +28 -7
  22. package/dist/config/types.d.ts.map +1 -1
  23. package/dist/database/lifecycle.d.ts +6 -1
  24. package/dist/database/lifecycle.d.ts.map +1 -1
  25. package/dist/database/lifecycle.js +15 -4
  26. package/dist/database/lifecycle.js.map +1 -1
  27. package/dist/docs/content/boundaries.mdx +19 -3
  28. package/dist/docs/content/cli/commands.mdx +31 -0
  29. package/dist/docs/content/cli/overview.mdx +1 -0
  30. package/dist/docs/content/config.mdx +14 -3
  31. package/dist/docs/content/routing.mdx +44 -0
  32. package/dist/docs/reference/config.mdx +6 -4
  33. package/dist/docs/reference/database.mdx +7 -7
  34. package/dist/docs/reference/router.mdx +45 -1
  35. package/dist/lib/inspect-routes.d.ts +2 -0
  36. package/dist/lib/inspect-routes.d.ts.map +1 -0
  37. package/dist/lib/inspect-routes.js +148 -0
  38. package/dist/lib/inspect-routes.js.map +1 -0
  39. package/dist/lib/start-server.js +10 -0
  40. package/dist/lib/start-server.js.map +1 -1
  41. package/dist/router/scanner/cron-mounter.d.ts.map +1 -1
  42. package/dist/router/scanner/cron-mounter.js +9 -2
  43. package/dist/router/scanner/cron-mounter.js.map +1 -1
  44. package/dist/server/app.d.ts.map +1 -1
  45. package/dist/server/app.js +5 -0
  46. package/dist/server/app.js.map +1 -1
  47. package/dist/server/define.d.ts.map +1 -1
  48. package/dist/server/define.js +5 -0
  49. package/dist/server/define.js.map +1 -1
  50. package/dist/testing/index.d.ts.map +1 -1
  51. package/dist/testing/index.js +9 -0
  52. package/dist/testing/index.js.map +1 -1
  53. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ export interface DatabaseRegistration {
11
11
  connect: () => Promise<void> | void;
12
12
  disconnect: () => Promise<void> | void;
13
13
  isHealthy?: () => Promise<boolean | DatabaseHealthInfo> | boolean | DatabaseHealthInfo;
14
+ healthCheck?: () => Promise<boolean | DatabaseHealthInfo> | boolean | DatabaseHealthInfo;
14
15
  }
15
16
  /**
16
17
  * Universal Database Manager for ExisJS.
@@ -25,7 +26,7 @@ export declare class DatabaseManager {
25
26
  */
26
27
  static register(db: DatabaseRegistration): void;
27
28
  /**
28
- * Connects all registered databases.
29
+ * Connects all registered databases that are not already connected.
29
30
  */
30
31
  static connectAll(): Promise<void>;
31
32
  /**
@@ -39,6 +40,10 @@ export declare class DatabaseManager {
39
40
  healthy: boolean;
40
41
  databases: Record<string, DatabaseHealthInfo>;
41
42
  }>;
43
+ /**
44
+ * Returns the number of registered databases.
45
+ */
46
+ static get size(): number;
42
47
  /**
43
48
  * Clears registered databases (useful for testing).
44
49
  */
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/database/lifecycle.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC9B,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,OAAO,CAAA;AAEvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,oBAAoB,CAAA;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACnC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtC,SAAS,CAAC,EAAE,MACV,OAAO,CAAC,OAAO,GAAG,kBAAkB,CAAC,GAAG,OAAO,GAAG,kBAAkB,CAAA;CACvE;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAA0C;IAClE,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAQ;IAE/C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,oBAAoB,GAAG,IAAI;IAK/C;;OAEG;WACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcxC;;OAEG;WACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3C;;OAEG;WACU,WAAW,IAAI,OAAO,CAAC;QAClC,OAAO,EAAE,OAAO,CAAA;QAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;KAC9C,CAAC;IA+CF;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;IAIpB,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAanC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,GAAG,EACZ,OAAO,CAAC,EAAE,oBAAoB,GAC7B,IAAI,CAGN"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/database/lifecycle.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC9B,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,OAAO,CAAA;AAEvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,oBAAoB,CAAA;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACnC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtC,SAAS,CAAC,EAAE,MACV,OAAO,CAAC,OAAO,GAAG,kBAAkB,CAAC,GAAG,OAAO,GAAG,kBAAkB,CAAA;IACtE,WAAW,CAAC,EAAE,MACZ,OAAO,CAAC,OAAO,GAAG,kBAAkB,CAAC,GAAG,OAAO,GAAG,kBAAkB,CAAA;CACvE;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAGrB;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAQ;IAE/C;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,oBAAoB,GAAG,IAAI;IAK/C;;OAEG;WACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBxC;;OAEG;WACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3C;;OAEG;WACU,WAAW,IAAI,OAAO,CAAC;QAClC,OAAO,EAAE,OAAO,CAAA;QAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;KAC9C,CAAC;IAgDF;;OAEG;IACH,MAAM,KAAK,IAAI,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;IAIpB,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAanC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,GAAG,EACZ,OAAO,CAAC,EAAE,oBAAoB,GAC7B,IAAI,CAGN"}
@@ -12,16 +12,19 @@ class DatabaseManager {
12
12
  * Registers a database connection lifecycle with the framework.
13
13
  */
14
14
  static register(db) {
15
- this.databases.set(db.name, db);
15
+ this.databases.set(db.name, { ...db, _connected: false });
16
16
  this.ensureShutdownHooks();
17
17
  }
18
18
  /**
19
- * Connects all registered databases.
19
+ * Connects all registered databases that are not already connected.
20
20
  */
21
21
  static async connectAll() {
22
22
  for (const [name, db] of this.databases) {
23
+ if (db._connected)
24
+ continue;
23
25
  try {
24
26
  await db.connect();
27
+ db._connected = true;
25
28
  }
26
29
  catch (err) {
27
30
  const error = new Error(`[ExisJS Database] Failed to connect database "${name}": ${err.message}`);
@@ -37,6 +40,7 @@ class DatabaseManager {
37
40
  const disconnectPromises = Array.from(this.databases.values()).map(async (db) => {
38
41
  try {
39
42
  await db.disconnect();
43
+ db._connected = false;
40
44
  }
41
45
  catch (err) {
42
46
  console.error(`[ExisJS Database] Error disconnecting "${db.name}":`, err);
@@ -53,11 +57,12 @@ class DatabaseManager {
53
57
  for (const [name, db] of this.databases) {
54
58
  const start = Date.now();
55
59
  try {
56
- if (!db.isHealthy) {
60
+ const healthFn = db.isHealthy || db.healthCheck;
61
+ if (!healthFn) {
57
62
  results[name] = { name, status: 'connected', latencyMs: 0 };
58
63
  continue;
59
64
  }
60
- const healthRes = await db.isHealthy();
65
+ const healthRes = await healthFn();
61
66
  const latencyMs = Date.now() - start;
62
67
  if (typeof healthRes === 'boolean') {
63
68
  results[name] = {
@@ -93,6 +98,12 @@ class DatabaseManager {
93
98
  databases: results,
94
99
  };
95
100
  }
101
+ /**
102
+ * Returns the number of registered databases.
103
+ */
104
+ static get size() {
105
+ return this.databases.size;
106
+ }
96
107
  /**
97
108
  * Clears registered databases (useful for testing).
98
109
  */
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/database/lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/database/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -159,9 +159,25 @@ src/http/
159
159
  └── route.ts # Handled by both Root Boundary and Admin Boundary
160
160
  ```
161
161
 
162
- 1. **Wrappers & Chain Steps**: Outer boundaries execute first. Root wrappers wrap nested wrappers, and root chain steps run before nested chain steps.
163
- 2. **CORS & Headers**: Sub-boundaries inherit and merge or override parent headers and CORS policies.
164
- 3. **Exclusions**: When a route matches an exclusion pattern (e.g. `/admin/health` in `exclude`), that boundary's chain steps and wrappers are bypassed for the request.
162
+ 1. **Wrappers & Chain Steps**: Outer boundaries execute first. Root wrappers wrap nested wrappers, and root chain steps run before nested chain steps top-down.
163
+ 2. **CORS Precedence & Inheritance**:
164
+ - **Innermost Boundary Wins**: If a nested boundary specifies `cors`, it overrides any CORS configuration set in parent boundaries or `exis.config.ts`.
165
+ - **Inheritance**: If a sub-boundary omits `cors`, it seamlessly inherits the parent boundary's CORS configuration (or global config).
166
+ - **Per-Route Overrides**: A `route.ts` handler can define its own `cors` setting to override boundary settings for that single endpoint.
167
+ - **Disabling CORS**: Setting `cors: false` on a boundary or route explicitly disables CORS headers and preflight handling for that sub-tree or route.
168
+ 3. **Headers Merging**: Headers are deep-merged from root to child. Child headers override parent headers if keys collide.
169
+ 4. **Exclusions**: When a route matches an exclusion pattern (e.g. `/admin/health` in `exclude`), that boundary's chain steps and wrappers are bypassed for the request.
170
+
171
+ ### CORS Resolution Hierarchy
172
+
173
+ ExisJS resolves CORS in a 3-tier precedence order:
174
+
175
+ | Level | Where to Define | Priority | Description |
176
+ |---|---|---|---|
177
+ | **Route** | `route.get('/', { cors: ... })` or `@Cors(...)` | 🥇 **Highest** | Specific to a single endpoint. Overrides boundary and global config. |
178
+ | **Nested Boundary** | `src/http/admin/boundary.ts` | 🥈 **High** | Scoped to the subfolder tree. Overrides parent boundaries and global config. |
179
+ | **Parent / Root Boundary** | `src/http/boundary.ts` | 🥉 **Medium** | Scoped to all API routes under the folder. Overrides global config. |
180
+ | **Global Config** | `exis.config.ts` (`defineConfig({ cors })`) | **Base** | Fallback baseline for any route not covered by a boundary or route override. |
165
181
 
166
182
  ---
167
183
 
@@ -158,6 +158,37 @@ $ npx exisjs test [files...] [options]
158
158
 
159
159
  ---
160
160
 
161
+ ### `exisjs run`
162
+
163
+ Executes any standalone TypeScript script, migration runner, or external tool (e.g. `drizzle-kit`, `prisma`, `knex`) with ExisJS `.env` files automatically loaded into `process.env`.
164
+
165
+ ```bash
166
+ $ npx exisjs run <scriptOrCmd> [args...] [options]
167
+ $ npx exisjs exec <scriptOrCmd> [args...] [options]
168
+ ```
169
+
170
+ **Options**
171
+
172
+ | Option | Description |
173
+ | :--- | :--- |
174
+ | `-e, --env <file>` | Custom environment file to load. |
175
+ | `-m, --mode <mode>` | Environment mode to load (e.g. `production`, `development`, `staging`). |
176
+
177
+ **Examples**
178
+
179
+ ```bash
180
+ # Run Drizzle migrations with auto-loaded .env database credentials
181
+ $ npx exisjs run drizzle-kit push
182
+
183
+ # Execute a TypeScript database seed script
184
+ $ npx exisjs run src/database/seed.ts
185
+
186
+ # Run with a custom environment file
187
+ $ npx exisjs run scripts/report.ts --env .env.staging
188
+ ```
189
+
190
+ ---
191
+
161
192
  ### `exisjs repl`
162
193
 
163
194
  Starts an interactive Node.js REPL console loaded with your application context.
@@ -76,6 +76,7 @@ $ npx exisjs g r users --oop
76
76
  | `routes` | | Prints the application routing table to the terminal. |
77
77
  | `generate` | `g` | Scaffolds framework slices (resource, route, service, schema, boundary, plugin, middleware, test). |
78
78
  | `test` | | Runs the native Node.js test suite (`node:test`) with custom Jest-style reporting. |
79
+ | `run` | `exec` | Executes a script or external tool (e.g. `drizzle-kit`, `prisma`) with auto-loaded `.env`. |
79
80
  | `repl` | `console` | Starts an interactive Node.js REPL loaded with the application context. |
80
81
  | `exports` | | Displays all available `@exisjs` and `exisjs/*` subpath exports. |
81
82
  | `info` | | Displays system, Node.js, and ExisJS runtime information. |
@@ -147,6 +147,7 @@ Here is a full breakdown of the configuration schema:
147
147
  - Regular expressions (e.g. `/localhost:\d+/`).
148
148
  - Arrays mixing strings and regexes (`['https://app.example.com', /https:\/\/.*\.domain\.com/']`).
149
149
  - Dynamic callbacks: `(origin, cb) => ...` or async functions: `async (origin) => boolean` for multi-tenant setups.
150
+ - **Precedence & Overrides**: Global CORS acts as the baseline default. It can be overridden at the directory level using `boundary.ts` (`defineBoundary({ cors })`), or at the individual endpoint level using `route.get('/', { cors })` / `@Cors()`. Setting `cors: false` at any level disables CORS for that scope.
150
151
  - `transformResponse` _(boolean | function)_: Automatically wraps all successful handler responses into a standardized envelope:
151
152
  - When `true`: `{ success: true, data: ..., timestamp: ... }` (matching `HttpError`'s `{ success: false, error: ... }`).
152
153
  - When a function: `(data, req, res) => ({ ... })` to provide your own custom envelope.
@@ -169,14 +170,24 @@ Here is a full breakdown of the configuration schema:
169
170
  - `debugRouting` _(boolean)_: Enables detailed logging of the resolved route file and applied gateways for every incoming request.
170
171
  - `test` _(object)_: Configuration for the native test runner (`include`, `exclude`, `setupFiles`, `concurrency`, `coverage`).
171
172
 
172
- ### Development Server & File Watcher (`dev`)
173
+ ### Development Server & File Watcher (`watch` & `dev`)
173
174
 
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.
175
+ ExisJS dev server (`exis dev`) features intelligent hot-reloading with strict extension filtering and automatic runtime artifact exclusion:
176
+
177
+ - `watch.paths` / `dev.watch` _(string[])_: Custom paths to watch for hot reloads. Defaults to `['src', ...configFiles]` (or `[cwd]` if no `src` folder exists).
178
+ - `watch.ignore` / `dev.ignored` _((string | RegExp)[])_: Additional files, directories, or regex patterns to ignore during watch restarts.
179
+ - `watch.extensions` / `dev.extensions` _(string[])_: Explicit file extensions that trigger reloads (defaults to `['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']`).
180
+ - `watch.debounceMs` / `dev.debounceMs` _(number)_: Debounce interval before restarting the server on file changes (default: `250ms`).
176
181
  - `dev.usePolling` _(boolean)_: Enables filesystem polling for cross-platform/Windows NTFS reliability (defaults to `true` on Windows).
177
182
  - `dev.interval` _(number)_: Polling interval in milliseconds (default: `100`).
178
183
  - `dev.binaryInterval` _(number)_: Polling binary interval in milliseconds (default: `300`).
179
184
 
185
+ <Info title="Default Ignored Artifacts">
186
+ By default, ExisJS automatically ignores non-source files and runtime artifact folders to prevent accidental server restarts:
187
+ - **Folders**: `node_modules`, `.git`, `.exis`, `dist`, `build`, `out`, `.turbo`, `.next`, `.cache`, `downloads`, `storage`, `uploads`, `tmp`, `temp`, `logs`, `data`, `fixtures`, `reports`, `artifacts`, `public`, `tests`, `coverage`.
188
+ - **Files**: `.csv`, `.xlsx`, `.pdf`, `.log`, `.sqlite`, `.db`, `.png`, `.jpg`, `.svg`, `.webp`, `.md`, `.txt`, `.zip`, `.tar.gz`, `package-lock.json`, `*.d.ts`.
189
+ </Info>
190
+
180
191
  ### Queues & Plugins
181
192
 
182
193
  - `queue` _(object)_: Configures the Global Job Queue driver (`memory` or `redis`) and backpressure settings.
@@ -537,6 +537,50 @@ export default controller({
537
537
  })
538
538
  ```
539
539
 
540
+ ### Route-Level CORS Overrides
541
+
542
+ Routes can also override CORS policies defined in parent `boundary.ts` files or `exis.config.ts`. Route-level CORS has the **highest precedence** in the framework:
543
+
544
+ #### Functional Paradigm
545
+ ```typescript filename="src/http/webhooks/stripe/route.ts"
546
+ import { controller, route } from 'exisjs/router'
547
+
548
+ export default controller({
549
+ // Open webhook endpoint to Stripe servers only, bypassing restrictive boundary CORS
550
+ webhook: route.post('/', {
551
+ cors: {
552
+ origin: 'https://hooks.stripe.com',
553
+ methods: ['POST'],
554
+ },
555
+ handle({ req }) {
556
+ return { received: true }
557
+ }
558
+ }),
559
+
560
+ // Disable CORS completely for internal endpoints
561
+ internalHealth: route.get('/health', {
562
+ cors: false,
563
+ handle() {
564
+ return { status: 'healthy' }
565
+ }
566
+ })
567
+ })
568
+ ```
569
+
570
+ #### Class-Based (OOP) Paradigm
571
+ ```typescript filename="src/http/webhooks/stripe/route.ts"
572
+ import { Controller, Post, Cors } from 'exisjs/decorators'
573
+
574
+ @Controller('/webhooks/stripe')
575
+ export default class StripeWebhookController {
576
+ @Post('/')
577
+ @Cors({ origin: 'https://hooks.stripe.com', methods: ['POST'] })
578
+ handleWebhook() {
579
+ return { received: true }
580
+ }
581
+ }
582
+ ```
583
+
540
584
  ### Query Pagination Schemas
541
585
 
542
586
  ExisJS provides the `tex.pagination()` primitive for declarative pagination, sorting, and ordering query parameters. String query parameters are automatically coerced into numbers:
@@ -108,17 +108,19 @@ Here is the full list of options supported natively by the ExisJS configuration
108
108
 
109
109
  ### Security & Middlewares
110
110
 
111
- - **`cors`** _(boolean | object)_: Enable and configure Cross-Origin Resource Sharing globally.
111
+ - **`cors`** _(boolean | object)_: Enable and configure Cross-Origin Resource Sharing globally. Acts as the base configuration; can be overridden per directory via `boundary.ts` (`defineBoundary({ cors })`) or per endpoint via `route.ts` (`route.get({ cors })` / `@Cors()`).
112
112
  - **`helmet`** _(boolean | object)_: Enable strict security headers. Enabled by default.
113
113
  - **`logger`** _(boolean | object)_: Configure the efficient Pino request logger.
114
114
  - **`compression`** _(boolean | object)_: Enable gzip/brotli response compression.
115
115
  - **`etag`** _(boolean)_: Automatic ETag generation for HTTP conditional requests (default: `false` for dynamic API routes).
116
116
  - **`bodyLimit`** _(number)_: Maximum JSON/URL-encoded payload size in bytes (default: `10MB`).
117
117
 
118
- ### Development Server & File Watcher (`dev`)
118
+ ### Development Server & File Watcher (`watch` & `dev`)
119
119
 
120
- - **`dev.watch`** _(string[])_: Custom directories or files to watch during development (default: `[cwd]`).
121
- - **`dev.ignored`** _((string | RegExp)[])_: Additional files, extensions, or regex patterns to ignore during hot reload.
120
+ - **`watch.paths`** / **`dev.watch`** _(string[])_: Custom directories or files to watch during development (default: `['src', ...configFiles]`).
121
+ - **`watch.ignore`** / **`dev.ignored`** _((string | RegExp)[])_: Additional files, extensions, or regex patterns to ignore during hot reload.
122
+ - **`watch.extensions`** / **`dev.extensions`** _(string[])_: Explicit file extensions that trigger reloads (defaults to `['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']`).
123
+ - **`watch.debounceMs`** / **`dev.debounceMs`** _(number)_: Debounce interval in ms before restarting the server (default: `250ms`).
122
124
  - **`dev.usePolling`** _(boolean)_: Enables chokidar polling fallback (default: `true` on Windows).
123
125
  - **`dev.interval`** _(number)_: Polling file system interval in milliseconds (default: `100`).
124
126
 
@@ -11,15 +11,15 @@ ExisJS provides a unified, database-agnostic lifecycle and transaction layer. It
11
11
 
12
12
  ## 1. Lifecycle Management
13
13
 
14
- ### `registerDatabase(app, options)`
14
+ ### `registerDatabase(app, options)` or `registerDatabase(options)`
15
15
 
16
- Registers a database connection into the application lifecycle. Automatically calls `connect()` during server boot and `disconnect()` during graceful shutdown (`SIGTERM`, `SIGINT`, or `app.close()`).
16
+ Registers a database connection into the application lifecycle. Automatically coordinates `connect()` during server boot and `disconnect()` during graceful shutdown (`SIGTERM`, `SIGINT`, or `app.close()`).
17
17
 
18
- #### Options (`DatabaseRegistrationOptions`)
18
+ #### Options (`DatabaseRegistration`)
19
19
  - `name` (`string`): Unique identifier for the database connection (e.g. `'postgres'`, `'mongodb'`).
20
- - `connect` (`() => Promise<void>`): Async callback to establish connection and connection pools.
21
- - `disconnect` (`() => Promise<void>`): Async callback to close connections gracefully.
22
- - `healthCheck` (`() => Promise<boolean>`): Optional health check callback returning `true` when healthy.
20
+ - `connect` (`() => Promise<void> | void`): Async callback to establish connections and connection pools.
21
+ - `disconnect` (`() => Promise<void> | void`): Async callback to close connections gracefully.
22
+ - `isHealthy` / `healthCheck` (`() => Promise<boolean | DatabaseHealthInfo> | boolean | DatabaseHealthInfo`): Optional health check callback returning `true` / `false` or detailed health info (`{ status: 'connected' | 'disconnected' | 'error', latencyMs?, error?, details? }`).
23
23
 
24
24
  ```typescript filename="src/http/server.ts"
25
25
  import { exis } from 'exisjs'
@@ -56,7 +56,7 @@ Singleton registry managing all registered database adapters.
56
56
  - `DatabaseManager.register(options)`: Registers a database adapter.
57
57
  - `DatabaseManager.connectAll()`: Connects all registered databases concurrently.
58
58
  - `DatabaseManager.disconnectAll()`: Gracefully disconnects all databases concurrently.
59
- - `DatabaseManager.checkHealth()`: Runs health checks across all registered databases and returns `{ healthy: boolean, databases: Record<string, boolean> }`.
59
+ - `DatabaseManager.checkHealth()`: Runs health checks across all registered databases and returns `{ healthy: boolean, databases: Record<string, DatabaseHealthInfo> }`.
60
60
  - `DatabaseManager.clear()`: Clears all registered database adapters (useful for test tear-downs).
61
61
 
62
62
  ```typescript filename="src/http/health/route.ts"
@@ -335,7 +335,50 @@ The response object supports universal streaming with backpressure management ac
335
335
 
336
336
  ---
337
337
 
338
- ## 4. `AppRouter` Client Manifest Contract
338
+ ## 4. Boundaries & Folder-Scoped Pipelines (`boundary.ts`)
339
+
340
+ ExisJS introduces **Boundaries** (`boundary.ts`) to manage folder-scoped middleware, CORS policies, security probes, guards, interceptors, and default headers without having to wire them manually across every route file.
341
+
342
+ ### How Boundaries Work
343
+
344
+ Place a `boundary.ts` file in any route directory (e.g., `src/http/boundary.ts` or `src/http/api/v1/boundary.ts`):
345
+
346
+ ```typescript filename="src/http/api/boundary.ts"
347
+ import { defineBoundary } from 'exisjs/router'
348
+ import { authGuard } from '../../guards/auth'
349
+
350
+ export default defineBoundary({
351
+ // Applied to all routes in src/http/api/* and subdirectories
352
+ cors: {
353
+ origin: 'https://app.example.com',
354
+ credentials: true,
355
+ },
356
+ guards: [authGuard],
357
+ headers: {
358
+ 'X-API-Version': 'v1',
359
+ },
360
+ // Exclude public endpoints from this boundary's pipeline
361
+ exclude: ['/api/health', '/api/public/*'],
362
+ })
363
+ ```
364
+
365
+ ### Cascading & Precedence Rules
366
+
367
+ When route slices are nested in subdirectories (e.g. `src/http/boundary.ts` -> `src/http/api/boundary.ts` -> `src/http/api/users/route.ts`), ExisJS evaluates boundary configurations using the following rules:
368
+
369
+ 1. **Middlewares, Guards, Filters, & Interceptors (Cascading / Additive)**:
370
+ - Evaluated **top-down** from parent boundary -> child boundary -> route-level controller.
371
+ 2. **CORS Configuration (Innermost Precedence)**:
372
+ - **Route-Level `cors`** (in `route.ts` / `controller({ cors: ... })`) overrides any boundary CORS.
373
+ - **Child Boundary `cors`** (in `src/http/api/boundary.ts`) overrides parent boundary `cors` (in `src/http/boundary.ts`).
374
+ - **Parent Boundary `cors`** applies if no child boundary or route overrides it.
375
+ - **Global `app.options.cors`** acts as the root fallback.
376
+ 3. **Response Headers (Deep Merge with Child Precedence)**:
377
+ - Headers defined in child boundaries or route definitions overwrite identical header keys from parent boundaries.
378
+
379
+ ---
380
+
381
+ ## 5. `AppRouter` Client Manifest Contract
339
382
 
340
383
  ExisJS generates a compile-time route manifest in `.exis/types.d.ts` and `.exis/types/index.d.ts`:
341
384
 
@@ -345,3 +388,4 @@ ExisJS generates a compile-time route manifest in `.exis/types.d.ts` and `.exis/
345
388
  - `RouteDefinition.__type`: Phantom type property on every route definition preserving exact inferred return types, DTO schemas, and Drizzle/Prisma models.
346
389
 
347
390
 
391
+
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=inspect-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-routes.d.ts","sourceRoot":"","sources":["../../src/lib/inspect-routes.ts"],"names":[],"mappings":""}
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const node_url_1 = require("node:url");
40
+ const node_path_1 = __importDefault(require("node:path"));
41
+ const node_fs_1 = __importDefault(require("node:fs"));
42
+ async function inspect() {
43
+ const entryFile = process.env.EXIS_ENTRY_FILE;
44
+ if (!entryFile) {
45
+ console.error('EXIS_ENTRY_FILE environment variable is missing.');
46
+ process.exit(1);
47
+ }
48
+ const cwd = process.cwd();
49
+ const dynamicImport = new Function('specifier', 'return import(specifier)');
50
+ // 1. Load .env
51
+ try {
52
+ const { loadEnv } = await Promise.resolve().then(() => __importStar(require('../config/env.js')));
53
+ loadEnv(cwd);
54
+ }
55
+ catch {
56
+ /* ignore */
57
+ }
58
+ // 2. Register path alias loader
59
+ try {
60
+ const { registerPathAliasLoader } = await Promise.resolve().then(() => __importStar(require('../cli/resolve-aliases.js')));
61
+ registerPathAliasLoader(cwd);
62
+ }
63
+ catch {
64
+ /* ignore */
65
+ }
66
+ // 3. Auto-load Environment variables validation file if it exists
67
+ const envFiles = [
68
+ node_path_1.default.join(cwd, 'src', 'config', 'env.ts'),
69
+ node_path_1.default.join(cwd, 'src', 'config', 'env.js'),
70
+ ];
71
+ for (const envFile of envFiles) {
72
+ if (node_fs_1.default.existsSync(envFile)) {
73
+ await dynamicImport((0, node_url_1.pathToFileURL)(envFile).href).catch(() => {
74
+ /* ignore */
75
+ });
76
+ break;
77
+ }
78
+ }
79
+ try {
80
+ const url = (0, node_url_1.pathToFileURL)(entryFile).href;
81
+ const mod = await dynamicImport(url);
82
+ const isApp = (obj) => !!(obj &&
83
+ typeof obj === 'object' &&
84
+ 'getRoutes' in obj &&
85
+ typeof obj.getRoutes === 'function');
86
+ let rawApp = mod.default || mod.app;
87
+ if (rawApp &&
88
+ !rawApp._isExisAppDefinition &&
89
+ typeof rawApp.create !== 'function' &&
90
+ rawApp.default) {
91
+ rawApp = rawApp.default;
92
+ }
93
+ let app;
94
+ if (rawApp && rawApp._isExisAppDefinition) {
95
+ const { App, setActiveAppInstance } = await Promise.resolve().then(() => __importStar(require('../server/app.js')));
96
+ app = new App(rawApp.options);
97
+ setActiveAppInstance(app);
98
+ }
99
+ else if (rawApp &&
100
+ typeof rawApp === 'function' &&
101
+ rawApp.prototype &&
102
+ rawApp.prototype[Symbol.for('exisjs:server_config')]) {
103
+ const serverConfig = rawApp.prototype[Symbol.for('exisjs:server_config')];
104
+ const { App, setActiveAppInstance } = await Promise.resolve().then(() => __importStar(require('../server/app.js')));
105
+ app = new App({ plugins: serverConfig.plugins });
106
+ setActiveAppInstance(app);
107
+ }
108
+ else {
109
+ const appExport = Object.values(mod).find(isApp);
110
+ app = isApp(rawApp) ? rawApp : appExport;
111
+ }
112
+ if (!app) {
113
+ console.error('\x1b[31m[Exis CLI Error]\x1b[0m Your entry file must export an instance of Exis App.');
114
+ process.exit(1);
115
+ }
116
+ // Boot the app to register file-system routes
117
+ try {
118
+ await app.create();
119
+ if (app.routeScanner?.loadAllRoutes) {
120
+ await app.routeScanner.loadAllRoutes();
121
+ }
122
+ }
123
+ catch {
124
+ /* ignore if already created */
125
+ }
126
+ const routes = app.getRoutes().map((r) => ({
127
+ method: r.method,
128
+ path: r.path,
129
+ handlersCount: r.handlers ? r.handlers.length : 1,
130
+ sourceFile: r.sourceFile || null,
131
+ }));
132
+ // Send the extracted routes via IPC if available, otherwise print serialized payload marker
133
+ if (process.send) {
134
+ process.send({ type: 'exis:routes', routes });
135
+ process.exit(0);
136
+ }
137
+ else {
138
+ console.log(`__EXIS_ROUTES_PAYLOAD__:${JSON.stringify(routes)}`);
139
+ process.exit(0);
140
+ }
141
+ }
142
+ catch (err) {
143
+ console.error('\x1b[31m[Exis CLI Error]\x1b[0m Failed to import app:', err?.message || err);
144
+ process.exit(1);
145
+ }
146
+ }
147
+ inspect();
148
+ //# sourceMappingURL=inspect-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-routes.js","sourceRoot":"","sources":["../../src/lib/inspect-routes.ts"],"names":[],"mappings":"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"}
@@ -171,6 +171,16 @@ async function start() {
171
171
  if (typeof app.onStartHook === 'function') {
172
172
  await app.onStartHook(app);
173
173
  }
174
+ // Auto-connect any databases registered in onStartHook or plugins before listening
175
+ try {
176
+ const { DatabaseManager } = await Promise.resolve().then(() => __importStar(require('../database/lifecycle')));
177
+ if (DatabaseManager.size > 0) {
178
+ await DatabaseManager.connectAll();
179
+ }
180
+ }
181
+ catch {
182
+ // ignore if database module unavailable
183
+ }
174
184
  await app.listen();
175
185
  // ─── Graceful Shutdown ───────────────────────────────────────────────────
176
186
  // On SIGTERM (Kubernetes, Docker stop) or SIGINT (Ctrl+C), close the