@gravito/core 1.2.0 → 1.6.0

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 CHANGED
@@ -12,15 +12,17 @@
12
12
  ## âœĻ Features
13
13
 
14
14
  - 🊐 **PlanetCore** - A centralized Photon-based kernel to manage your application lifecycle.
15
+ - ðŸĒ **Application Container** - Enterprise-grade container with auto-discovery of providers and convention-over-configuration patterns.
15
16
  - ðŸ“Ķ **IoC Container** - A lightweight dependency injection container with binding and singleton support.
16
17
  - ðŸ§Đ **Service Providers** - Modular service registration and booting lifecycle.
17
18
  - 🊝 **Hook System** - WordPress-style async **Filters** and **Actions** for powerful extensibility.
19
+ - ðŸ“Ą **Event System** - Centralized EventManager for cross-module communication and event-driven architecture.
18
20
  - 🛰ïļ **Orbit Mounting** - Easily mount external Photon applications (Orbits) to specific paths.
19
21
  - 📝 **Logger System** - PSR-3 style logger interface with default standard output implementation.
20
- - ⚙ïļ **Config Manager** - Unified configuration management supporting environment variables (`Bun.env`) and runtime injection.
22
+ - ⚙ïļ **Config Manager** - Unified configuration management supporting environment variables, runtime injection, and file-based config loading.
21
23
  - ðŸ›Ąïļ **Security Middleware** - Built-in protection including CSRF, CORS, HSTS, and request throttling.
22
24
  - 🔌 **Runtime Adapters** - Abstraction layer for underlying runtimes (Bun, Node.js) and HTTP engines.
23
- - ðŸ›Ąïļ **Error Handling** - Built-in standardized JSON error responses and 404 handling.
25
+ - ðŸ›Ąïļ **Error Handling** - Built-in standardized JSON error responses, 404 handling, and process-level error management.
24
26
  - 🚀 **Modern** - Built for **Bun** runtime with native TypeScript support.
25
27
  - ðŸŠķ **Lightweight** - Zero external dependencies (except `@gravito/photon`).
26
28
 
@@ -32,12 +34,28 @@ bun add @gravito/core
32
34
 
33
35
  ## 🚀 Quick Start
34
36
 
35
- ### 1. Initialize the Core
37
+ ### 1. Initialize the Application
38
+
39
+ For enterprise applications, use the `Application` class which provides auto-discovery and conventions:
40
+
41
+ ```typescript
42
+ import { Application } from '@gravito/core';
43
+
44
+ const app = new Application({
45
+ basePath: import.meta.dir,
46
+ env: process.env.NODE_ENV as 'development' | 'production',
47
+ });
48
+
49
+ await app.boot();
50
+
51
+ export default app.core.liftoff();
52
+ ```
53
+
54
+ Or use the lightweight `PlanetCore` directly:
36
55
 
37
56
  ```typescript
38
57
  import { PlanetCore } from '@gravito/core';
39
58
 
40
- // Initialize with options (v0.2.0+)
41
59
  const core = new PlanetCore({
42
60
  config: {
43
61
  PORT: 4000,
@@ -138,7 +156,15 @@ core.hooks.addAction('processError:report', async (ctx) => {
138
156
 
139
157
  ## 📖 API Reference
140
158
 
141
- ### `PlanetCore`
159
+ ### `Application` (Enterprise Container)
160
+
161
+ - **`constructor(options: ApplicationConfig)`**: Create an application instance.
162
+ - **`boot()`**: Orchestrate the boot sequence (config loading, provider discovery).
163
+ - **`make<T>(key)`**: Resolve a service from the shared container.
164
+ - **`getConfig(key, default?)`**: Retrieve configuration.
165
+ - **`path(...segments)`**: Path helper relative to base path.
166
+
167
+ ### `PlanetCore` (Micro-kernel)
142
168
 
143
169
  - **`constructor(options?)`**: Initialize the core with optional Logger and Config.
144
170
  - **`register(provider: ServiceProvider)`**: Register a service provider.
@@ -148,6 +174,7 @@ core.hooks.addAction('processError:report', async (ctx) => {
148
174
  - **`container`**: Access the IoC Container.
149
175
  - **`app`**: Access the internal Photon instance.
150
176
  - **`hooks`**: Access the HookManager.
177
+ - **`events`**: Access the EventManager.
151
178
  - **`logger`**: Access the Logger instance.
152
179
  - **`config`**: Access the ConfigManager.
153
180
 
@@ -155,10 +182,28 @@ core.hooks.addAction('processError:report', async (ctx) => {
155
182
 
156
183
  - **`bind(key, factory)`**: Register a transient binding.
157
184
  - **`singleton(key, factory)`**: Register a shared binding.
158
- - **`make<T>(key)`**: Resolve a service instance.
185
+ - **`make(key)`**: Resolve a service instance. Supports automatic type inference via `ServiceMap` augmentation.
159
186
  - **`instance(key, instance)`**: Register an existing object instance.
160
187
  - **`has(key)`**: Check if a service is bound.
161
188
 
189
+ #### Type Safety (ServiceMap)
190
+
191
+ You can extend the `ServiceMap` interface to get automatic type inference for `container.make()`:
192
+
193
+ ```typescript
194
+ // types.d.ts
195
+ import { Logger } from './Logger';
196
+
197
+ declare module '@gravito/core' {
198
+ interface ServiceMap {
199
+ logger: Logger;
200
+ }
201
+ }
202
+
203
+ // usage.ts
204
+ const logger = container.make('logger'); // inferred as Logger
205
+ ```
206
+
162
207
  ### `HookManager`
163
208
 
164
209
  - **`addFilter(hook, callback)`**: Register a filter.
@@ -166,6 +211,12 @@ core.hooks.addAction('processError:report', async (ctx) => {
166
211
  - **`addAction(hook, callback)`**: Register an action.
167
212
  - **`doAction(hook, ...args)`**: Execute actions.
168
213
 
214
+ ### `EventManager`
215
+
216
+ - **`emit(event, ...args)`**: Dispatch an event.
217
+ - **`on(event, callback)`**: Listen to an event.
218
+ - **`off(event, callback)`**: Remove a listener.
219
+
169
220
  ### `ConfigManager`
170
221
 
171
222
  - **`get(key, default?)`**: Retrieve a config value.
package/README.zh-TW.md CHANGED
@@ -1,24 +1,215 @@
1
1
  # @gravito/core
2
2
 
3
- > Galaxy æžķæ§‹įš„åūŪæ ļåŋƒïžŒåŸšæ–ž Photon 與 Bun įš„čž•é‡åŊæ“īå……æĄ†æžķæ ļåŋƒã€‚
3
+ > Galaxy æžķæ§‹įš„åūŪæ ļåŋƒã€‚čž•é‡ã€åŊæ“īåą•ïžŒåŸšæ–ž Photon 與 Bun 構åŧšã€‚
4
4
 
5
- ## åŪ‰čĢ
5
+ [![npm version](https://img.shields.io/npm/v/@gravito/core.svg)](https://www.npmjs.com/package/@gravito/core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
8
+ [![Bun](https://img.shields.io/badge/Bun-1.0+-black.svg)](https://bun.sh/)
9
+
10
+ **@gravito/core** æ˜Ŋä―ŋį”Ļ **Galaxy æžķ構** 構åŧšæĻĄįĩ„化åūŒįŦŊ應į”Ļįš„åŸšįĪŽã€‚åŪƒæäū›äš†äļ€å€‹åž·åĪ§įš„ Hook įģŧįĩąïžˆFilters 與 Actions和 Orbit æŽ›čž‰æĐŸåˆķčŪ“æ‚Ļčƒ―åĪ æ§‹åŧšä―Žč€Ķ合、éŦ˜æ“īåą•æ€§įš„įģŧįĩąã€‚
11
+
12
+ ## âœĻ į‰đ性
13
+
14
+ - 🊐 **PlanetCore** - 埚斞 Photon įš„äļ­åĪŪæ ļåŋƒïžŒįŪĄį†æ‡‰į”ĻįĻ‹åžį”Ÿå‘―é€ąæœŸã€‚
15
+ - ðŸĒ **Application Container** - 䞁æĨ­įīšåŪđå™Ļæ”Ŋæī Provider č‡Šå‹•į™žįū與æ…Ģäū‹å„Šæ–žé…į―ŪConvention-over-ConfigurationæĻĄåžã€‚
16
+ - ðŸ“Ķ **IoC Container** - 辕量įīšäūčģīæģĻå…ĨåŪđå™Ļæ”ŊæīįķåŪšïžˆBindingïž‰čˆ‡å–Ūäū‹ïžˆSingleton。
17
+ - ðŸ§Đ **Service Providers** - æĻĄįĩ„åŒ–įš„æœå‹™čĻŧå†Ščˆ‡å•Ÿå‹•į”Ÿå‘―é€ąæœŸã€‚
18
+ - 🊝 **Hook System** - WordPress éĒĻæ žįš„į•°æ­Ĩ **Filters** 與 **Actions**提äū›åž·åĪ§įš„æ“īåą•čƒ―åŠ›ã€‚
19
+ - ðŸ“Ą **Event System** - äļ­åĪŪ EventManageræ”Ŋæīč·ĻæĻĄįĩ„通čĻŠčˆ‡äš‹äŧķéĐ…å‹•æžķ構。
20
+ - 🛰ïļ **Orbit Mounting** - čž•éŽ†å°‡åĪ–éƒĻ Photon 應į”ĻįĻ‹åžïžˆOrbitsïž‰æŽ›čž‰åˆ°į‰đåۚč·Ŋåū‘。
21
+ - 📝 **Logger System** - PSR-3 éĒĻæ žįš„æ—Ĩ詌äŧ‹éĒ內åŧšæĻ™æš–čžļ凚åŊĶä―œã€‚
22
+ - ⚙ïļ **Config Manager** - įĩąäļ€įš„配į―ŪįŪĄį†ïžŒæ”Ŋæīį’°åǃčۊæ•ļã€é‹čĄŒæ™‚æģĻå…Ĩčˆ‡åŸšæ–žæŠ”æĄˆįš„é…į―Ū辉å…Ĩ。
23
+ - ðŸ›Ąïļ **Security Middleware** - 內åŧšäŋč­·åŠŸčƒ―包拎 CSRF、CORS、HSTS 與čŦ‹æą‚限æĩïžˆThrottling。
24
+ - 🔌 **Runtime Adapters** - åš•åąĪé‹čĄŒæ™‚ïžˆBun, Node.jsïž‰čˆ‡ HTTP åž•æ“Žįš„æŠ―čąĄåąĪ。
25
+ - ðŸ›Ąïļ **Error Handling** - 內åŧšæĻ™æš–化 JSON éŒŊčŠĪ回應、404 č™•į†čˆ‡é€ēįĻ‹įīšåˆĨéŒŊčŠĪįŪĄį†ã€‚
26
+ - 🚀 **Modern** - å°ˆį‚š **Bun** é‹čĄŒæ™‚čĻ­čĻˆïžŒåŽŸį”Ÿæ”Ŋæī TypeScript。
27
+ - ðŸŠķ **Lightweight** - é™Ī乆 `@gravito/photon` åĪ–é›ķåĪ–éƒĻäūčģī。
28
+
29
+ ## ðŸ“Ķ åŪ‰čĢ
6
30
 
7
31
  ```bash
8
32
  bun add @gravito/core
9
33
  ```
10
34
 
11
- ## åŋŦ速開始
35
+ ## 🚀 åŋŦ速ä‰‹
36
+
37
+ ### 1. 初始化應į”ĻįĻ‹åž
38
+
39
+ 對斞䞁æĨ­į‡‰į”Ļä―ŋį”Ļ `Application` 類åˆĨåŪƒæäū›č‡Šå‹•į™žįūčˆ‡é–‹į™žæ…Ģäū‹ïžš
40
+
41
+ ```typescript
42
+ import { Application } from '@gravito/core';
43
+
44
+ const app = new Application({
45
+ basePath: import.meta.dir,
46
+ env: process.env.NODE_ENV as 'development' | 'production',
47
+ });
48
+
49
+ await app.boot();
50
+
51
+ export default app.core.liftoff();
52
+ ```
53
+
54
+ æˆ–č€…į›īæŽĨä―ŋį”Ļ辕量įīšįš„ `PlanetCore`ïžš
12
55
 
13
56
  ```typescript
14
- import { PlanetCore } from '@gravito/core'
57
+ import { PlanetCore } from '@gravito/core';
15
58
 
16
59
  const core = new PlanetCore({
17
60
  config: {
18
61
  PORT: 4000,
19
62
  DEBUG: true
20
63
  }
21
- })
64
+ });
65
+ ```
66
+
67
+ ### 2. äūčģīæģĻå…Ĩ
68
+
69
+ ä―ŋį”Ļ IoC åŪđå™ĻįŪĄį†æ‡‰į”ĻįĻ‹åžæœå‹™ïžš
70
+
71
+ ```typescript
72
+ import { ServiceProvider, Container } from '@gravito/core';
73
+
74
+ class CacheServiceProvider extends ServiceProvider {
75
+ register(container: Container) {
76
+ // įķåۚå–Ūäū‹æœå‹™
77
+ container.singleton('cache', (c) => {
78
+ return new RedisCache(process.env.REDIS_URL);
79
+ });
80
+ }
81
+
82
+ async boot(core: PlanetCore) {
83
+ // åŸ·čĄŒå•Ÿå‹•é‚čžŊ
84
+ core.logger.info('Cache provider booted');
85
+ }
86
+ }
87
+
88
+ // čĻŧ冊 Provider
89
+ core.register(new CacheServiceProvider());
90
+
91
+ // 啟動應į”ĻįĻ‹åžïžˆåŸ·čĄŒ register() 與 boot()
92
+ await core.bootstrap();
93
+
94
+ // č§Ģ析服務
95
+ const cache = core.container.make('cache');
96
+ ```
97
+
98
+ ### 3. čĻŧ冊 Hooks
99
+
100
+ ä―ŋį”Ļ **Filters** äŋŪæ”đč쇿–™ïžš
101
+
102
+ ```typescript
103
+ core.hooks.addFilter('modify_content', async (content: string) => {
104
+ return content.toUpperCase();
105
+ });
106
+
107
+ const result = await core.hooks.applyFilters('modify_content', 'hello galaxy');
108
+ // 回å‚ģ: "HELLO GALAXY"
109
+ ```
110
+
111
+ ä―ŋį”Ļ **Actions** č§ļį™žå‰Ŋä―œį”Ļïžš
112
+
113
+ ```typescript
114
+ core.hooks.addAction('user_registered', async (userId: string) => {
115
+ core.logger.info(`Sending welcome email to ${userId}`);
116
+ });
117
+
118
+ await core.hooks.doAction('user_registered', 'user_123');
119
+ ```
120
+
121
+ ### 4. æŽ›čž‰ Orbit
122
+
123
+ Orbits æ˜ŊæĻ™æš–įš„ Photon 應į”ĻįĻ‹åžïžŒåŊäŧĨ插å…Ĩæ ļåŋƒäļ­ã€‚
124
+
125
+ ```typescript
126
+ import { Photon } from '@gravito/photon';
127
+
128
+ const blogOrbit = new Photon();
129
+ blogOrbit.get('/posts', (c) => c.json({ posts: [] }));
130
+
131
+ // 將 orbit æŽ›čž‰åˆ° /api/blog
132
+ core.mountOrbit('/api/blog', blogOrbit);
133
+ ```
134
+
135
+ ### 5. Liftoff! 🚀
136
+
137
+ ```typescript
138
+ // į‚š Bun.serve 導凚
139
+ export default core.liftoff(); // č‡Šå‹•ä―ŋį”Ļäū†č‡Šé…į―Ūæˆ–į’°åǃčۊæ•ļįš„ PORT
140
+ ```
22
141
 
23
- export default core.liftoff()
142
+ ### 6. é€ēįĻ‹įīšåˆĨéŒŊčŠĪč™•į†ïžˆæŽĻč–Ķ
143
+
144
+ čŦ‹æą‚įīšåˆĨįš„éŒŊčŠĪį”ą `PlanetCore` č‡Šå‹•č™•į†ïžŒä―†čƒŒæ™Ŋå·Ĩä―œčˆ‡å•Ÿå‹•äŧĢįĒžäŧåŊčƒ―åœĻčŦ‹æą‚į”Ÿå‘―é€ąæœŸåĪ–åĪąæ•—ã€‚
145
+
146
+ ```ts
147
+ // čĻŧ冊 `unhandledRejection` / `uncaughtException`
148
+ const unregister = core.registerGlobalErrorHandlers()
149
+
150
+ // éļé…ïžšå›žå ąč‡ģ Sentry / 臩åۚįūĐå›žå ąå™Ļ
151
+ core.hooks.addAction('processError:report', async (ctx) => {
152
+ // ctx.kind: 'unhandledRejection' | 'uncaughtException'
153
+ // ctx.error: unknown
154
+ })
24
155
  ```
156
+
157
+ ## 📖 API åƒč€ƒ
158
+
159
+ ### `Application` (䞁æĨ­įīšåŪđå™Ļ)
160
+
161
+ - **`constructor(options: ApplicationConfig)`**: åŧšįŦ‹æ‡‰į”ĻįĻ‹åžåŊĶäū‹ã€‚
162
+ - **`boot()`**: įĩąįąŒå•Ÿå‹•順嚏配į―Ū辉å…Ĩ、Provider į™žįū。
163
+ - **`make<T>(key)`**: åūžå…ąäšŦåŪđå™Ļäļ­č§Ģ析服務。
164
+ - **`getConfig(key, default?)`**: 取åū—配į―Ūčģ‡čĻŠã€‚
165
+ - **`path(...segments)`**: į›ļ對斞埚įĪŽč·Ŋåū‘įš„č·Ŋåū‘čž”åŠĐå‡―æ•ļ。
166
+
167
+ ### `PlanetCore` (åūŪæ ļåŋƒ)
168
+
169
+ - **`constructor(options?)`**: 初始化æ ļåŋƒïžŒåŊéļ配 Logger 與 Config。
170
+ - **`register(provider: ServiceProvider)`**: čĻŧ冊服務提äū›č€…。
171
+ - **`bootstrap()`**: 啟動所有å·ēčĻŧå†Šįš„æäū›č€…。
172
+ - **`mountOrbit(path: string, app: Photon)`**: 將 Photon 應į”ĻæŽ›čž‰åˆ°å­č·Ŋåū‘。
173
+ - **`liftoff(port?: number)`**: 回å‚ģį”Ļæ–ž `Bun.serve` įš„é…į―Ūį‰Đäŧķ。
174
+ - **`container`**: 存取 IoC åŪđå™Ļ。
175
+ - **`app`**: 存取內éƒĻ Photon åŊĶäū‹ã€‚
176
+ - **`hooks`**: 存取 HookManager。
177
+ - **`events`**: 存取 EventManager。
178
+ - **`logger`**: 存取 Logger åŊĶäū‹ã€‚
179
+ - **`config`**: 存取 ConfigManager。
180
+
181
+ ### `Container`
182
+
183
+ - **`bind(key, factory)`**: čĻŧå†ŠįžŽæ™‚įķåŪšïžˆæŊæŽĄč§Ģæžįš†åŧšįŦ‹æ–°åŊĶäū‹ïž‰ã€‚
184
+ - **`singleton(key, factory)`**: čĻŧå†Šå…ąäšŦįķåŪšïžˆå–Ūäū‹ïž‰ã€‚
185
+ - **`make<T>(key)`**: č§Ģ析服務åŊĶäū‹ã€‚
186
+ - **`instance(key, instance)`**: čĻŧ冊įūæœ‰įš„į‰ĐäŧķåŊĶäū‹ã€‚
187
+ - **`has(key)`**: æŠĒæŸĨ服務æ˜ŊåĶå·ēįķåŪšã€‚
188
+
189
+ ### `HookManager`
190
+
191
+ - **`addFilter(hook, callback)`**: čĻŧ冊過æŋūå™Ļ。
192
+ - **`applyFilters(hook, initialValue, ...args)`**: äūåšåŸ·čĄŒéŽæŋūå™Ļ。
193
+ - **`addAction(hook, callback)`**: čĻŧå†Šå‹•ä―œã€‚
194
+ - **`doAction(hook, ...args)`**: åŸ·čĄŒå‹•ä―œã€‚
195
+
196
+ ### `EventManager`
197
+
198
+ - **`emit(event, ...args)`**: č§ļį™žäš‹äŧķ。
199
+ - **`on(event, callback)`**: į›Ģč―äš‹äŧķ。
200
+ - **`off(event, callback)`**: į§ŧé™Īį›Ģč―å™Ļ。
201
+
202
+ ### `ConfigManager`
203
+
204
+ - **`get(key, default?)`**: 取åū—配į―Ū倞。
205
+ - **`set(key, value)`**: čĻ­åŪšé…į―Ū倞。
206
+ - **`has(key)`**: æŠĒæŸĨ配į―Ūéĩæ˜ŊåĶ存åœĻ。
207
+
208
+ ## ðŸĪ čēĒįŧ
209
+
210
+ æ­ĄčŋŽæäšĪčēĒįŧã€å•éĄŒčˆ‡åŠŸčƒ―čŦ‹æą‚
211
+ čŦ‹éšĻ時æŸĨįœ‹ [Issues 頁éĒ](https://github.com/gravito-framework/gravito/issues)。
212
+
213
+ ## 📝 授掊
214
+
215
+ MIT ÂĐ [Carl Lee](https://github.com/gravito-framework/gravito)
@@ -0,0 +1,357 @@
1
+ /**
2
+ * @fileoverview Core HTTP Types for Gravito Framework
3
+ *
4
+ * These types provide a unified abstraction layer that decouples the framework
5
+ * from any specific HTTP engine (Photon, Express, custom, etc.).
6
+ *
7
+ * @module @gravito/core/http
8
+ * @since 2.0.0
9
+ */
10
+ declare global {
11
+ interface ExecutionContext {
12
+ waitUntil(promise: Promise<unknown>): void;
13
+ passThroughOnException(): void;
14
+ }
15
+ }
16
+ /**
17
+ * Standard HTTP methods supported by Gravito
18
+ */
19
+ type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head';
20
+ /**
21
+ * HTTP status codes
22
+ */
23
+ type StatusCode = number;
24
+ /**
25
+ * Content-bearing HTTP status codes (excludes 1xx, 204, 304)
26
+ */
27
+ type ContentfulStatusCode = Exclude<StatusCode, 100 | 101 | 102 | 103 | 204 | 304>;
28
+ /**
29
+ * Base context variables available in every request
30
+ * Orbits can extend this interface via module augmentation
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // Extending variables in your orbit:
35
+ * declare module '@gravito/core' {
36
+ * interface GravitoVariables {
37
+ * myService: MyService
38
+ * }
39
+ * }
40
+ * ```
41
+ */
42
+ interface GravitoVariables {
43
+ /**
44
+ * The PlanetCore instance
45
+ * @remarks Always available in PlanetCore-managed contexts
46
+ */
47
+ core?: unknown;
48
+ /**
49
+ * Logger instance
50
+ */
51
+ logger?: unknown;
52
+ /**
53
+ * Configuration manager
54
+ */
55
+ config?: unknown;
56
+ /**
57
+ * Cookie jar for managing response cookies
58
+ */
59
+ cookieJar?: unknown;
60
+ /**
61
+ * Middleware scope tracking for Orbit isolation
62
+ * Tracks which Orbit/scope this request belongs to
63
+ * Used to prevent cross-Orbit middleware contamination
64
+ * @since 2.3.0
65
+ */
66
+ middlewareScope?: string;
67
+ /** @deprecated Use ctx.route() instead */
68
+ route?: unknown;
69
+ [key: string]: unknown;
70
+ }
71
+ /**
72
+ * Validated request data targets
73
+ */
74
+ type ValidationTarget = 'json' | 'query' | 'param' | 'header' | 'form' | 'cookie';
75
+ /**
76
+ * GravitoRequest - Unified request interface
77
+ *
78
+ * Provides a consistent API for accessing request data regardless of
79
+ * the underlying HTTP engine.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const userId = ctx.req.param('id')
84
+ * const search = ctx.req.query('q')
85
+ * const body = await ctx.req.json<CreateUserDto>()
86
+ * ```
87
+ */
88
+ interface GravitoRequest {
89
+ /** Full request URL */
90
+ readonly url: string;
91
+ /** HTTP method (uppercase) */
92
+ readonly method: string;
93
+ /** Request path without query string */
94
+ readonly path: string;
95
+ /**
96
+ * Route pattern (e.g., /users/:id) for the matched route
97
+ *
98
+ * This provides the parameterized route pattern instead of the concrete path,
99
+ * which is critical for preventing high cardinality issues in metrics systems.
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * // For request: GET /users/123
104
+ * ctx.req.path // => "/users/123"
105
+ * ctx.req.routePattern // => "/users/:id"
106
+ * ```
107
+ */
108
+ readonly routePattern?: string;
109
+ /**
110
+ * Get a route parameter value
111
+ * @param name - Parameter name (e.g., 'id' for route '/users/:id')
112
+ */
113
+ param(name: string): string | undefined;
114
+ /**
115
+ * Get all route parameters
116
+ */
117
+ params(): Record<string, string>;
118
+ /**
119
+ * Get a query string parameter
120
+ * @param name - Query parameter name
121
+ */
122
+ query(name: string): string | undefined;
123
+ /**
124
+ * Get all query parameters
125
+ */
126
+ queries(): Record<string, string | string[]>;
127
+ /**
128
+ * Get a request header value
129
+ * @param name - Header name (case-insensitive)
130
+ */
131
+ header(name: string): string | undefined;
132
+ /**
133
+ * Get all request headers
134
+ */
135
+ header(): Record<string, string>;
136
+ /**
137
+ * Parse request body as JSON
138
+ * @throws {Error} If body is not valid JSON
139
+ */
140
+ json<T = unknown>(): Promise<T>;
141
+ /**
142
+ * Parse request body as text
143
+ */
144
+ text(): Promise<string>;
145
+ /**
146
+ * Parse request body as FormData
147
+ */
148
+ formData(): Promise<FormData>;
149
+ /**
150
+ * Parse request body as ArrayBuffer
151
+ */
152
+ arrayBuffer(): Promise<ArrayBuffer>;
153
+ /**
154
+ * Parse form data (urlencoded or multipart)
155
+ */
156
+ parseBody<T = unknown>(): Promise<T>;
157
+ /**
158
+ * Get the raw Request object
159
+ */
160
+ readonly raw: Request;
161
+ /**
162
+ * Get validated data from a specific source
163
+ * @param target - The validation target
164
+ * @throws {Error} If validation was not performed for this target
165
+ */
166
+ valid<T = unknown>(target: ValidationTarget): T;
167
+ }
168
+ /**
169
+ * Options for request forwarding (Proxy)
170
+ */
171
+ interface ProxyOptions {
172
+ /** Override or add request headers */
173
+ headers?: Record<string, string>;
174
+ /** Whether to keep the original Host header (default: false) */
175
+ preserveHost?: boolean;
176
+ /** Whether to add X-Forwarded-* headers (default: true) */
177
+ addForwardedHeaders?: boolean;
178
+ /** Path rewriting logic */
179
+ rewritePath?: (path: string) => string;
180
+ }
181
+ /**
182
+ * GravitoContext - Unified request context
183
+ *
184
+ * This interface encapsulates all HTTP request/response operations,
185
+ * enabling seamless replacement of the underlying HTTP engine.
186
+ *
187
+ * @typeParam V - Context variables type
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * // In a controller
192
+ * async show(ctx: GravitoContext) {
193
+ * const id = ctx.req.param('id')
194
+ * const user = await User.find(id)
195
+ * return ctx.json({ user })
196
+ * }
197
+ * ```
198
+ */
199
+ interface GravitoContext<V extends GravitoVariables = GravitoVariables> {
200
+ /** The incoming request */
201
+ readonly req: GravitoRequest;
202
+ /**
203
+ * Send a JSON response
204
+ * @param data - Data to serialize as JSON
205
+ * @param status - HTTP status code (default: 200)
206
+ */
207
+ json<T>(data: T, status?: ContentfulStatusCode): Response;
208
+ /**
209
+ * Send a plain text response
210
+ * @param text - Text content
211
+ * @param status - HTTP status code (default: 200)
212
+ */
213
+ text(text: string, status?: ContentfulStatusCode): Response;
214
+ /**
215
+ * Send an HTML response
216
+ * @param html - HTML content
217
+ * @param status - HTTP status code (default: 200)
218
+ */
219
+ html(html: string, status?: ContentfulStatusCode): Response;
220
+ /**
221
+ * Send a redirect response
222
+ * @param url - Target URL
223
+ * @param status - Redirect status code (default: 302)
224
+ */
225
+ redirect(url: string, status?: 301 | 302 | 303 | 307 | 308): Response;
226
+ /**
227
+ * Create a Response with no body
228
+ * @param status - HTTP status code
229
+ */
230
+ body(data: BodyInit | null, status?: StatusCode): Response;
231
+ /**
232
+ * Stream a response
233
+ * @param stream - ReadableStream to send
234
+ * @param status - HTTP status code (default: 200)
235
+ */
236
+ stream(stream: ReadableStream, status?: ContentfulStatusCode): Response;
237
+ /**
238
+ * Send a 404 Not Found response
239
+ */
240
+ notFound(message?: string): Response;
241
+ /**
242
+ * Send a 403 Forbidden response
243
+ */
244
+ forbidden(message?: string): Response;
245
+ /**
246
+ * Send a 401 Unauthorized response
247
+ */
248
+ unauthorized(message?: string): Response;
249
+ /**
250
+ * Send a 400 Bad Request response
251
+ */
252
+ badRequest(message?: string): Response;
253
+ /**
254
+ * Forward the current request to another URL (Reverse Proxy)
255
+ * @param target - Target URL or base URL to forward to
256
+ * @param options - Optional proxy options
257
+ */
258
+ forward(target: string, options?: ProxyOptions): Promise<Response>;
259
+ /**
260
+ * Set a response header
261
+ * @param name - Header name
262
+ * @param value - Header value
263
+ * @param options - Options (append: true to add multiple values)
264
+ */
265
+ header(name: string, value: string, options?: {
266
+ append?: boolean;
267
+ }): void;
268
+ /**
269
+ * Get a request header
270
+ * @param name - Header name (case-insensitive)
271
+ */
272
+ header(name: string): string | undefined;
273
+ /**
274
+ * Set the response status code
275
+ * @param code - HTTP status code
276
+ */
277
+ status(code: StatusCode): void;
278
+ /**
279
+ * Get a context variable
280
+ * @param key - Variable key
281
+ */
282
+ get<K extends keyof V>(key: K): V[K];
283
+ /**
284
+ * Set a context variable
285
+ * @param key - Variable key
286
+ * @param value - Variable value
287
+ */
288
+ set<K extends keyof V>(key: K, value: V[K]): void;
289
+ /**
290
+ * Get the execution context (for Cloudflare Workers, etc.)
291
+ */
292
+ readonly executionCtx?: ExecutionContext;
293
+ /**
294
+ * Get environment bindings (for Cloudflare Workers, etc.)
295
+ */
296
+ readonly env?: Record<string, unknown>;
297
+ /**
298
+ * URL generator helper.
299
+ * Generates a URL for a named route.
300
+ */
301
+ route: (name: string, params?: Record<string, any>, query?: Record<string, any>) => string;
302
+ /**
303
+ * Access the native context object from the underlying HTTP engine.
304
+ *
305
+ * ⚠ïļ WARNING: Using this ties your code to a specific adapter.
306
+ * Prefer using the abstraction methods when possible.
307
+ *
308
+ * @example
309
+ * ```typescript
310
+ * // Only when absolutely necessary
311
+ * const photonCtx = ctx.native as Context // Photon Context
312
+ * ```
313
+ */
314
+ readonly native: unknown;
315
+ }
316
+ /**
317
+ * Next function for middleware chain
318
+ */
319
+ type GravitoNext = () => Promise<Response | undefined>;
320
+ /**
321
+ * GravitoHandler - Standard route handler type
322
+ *
323
+ * @typeParam V - Context variables type
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * const handler: GravitoHandler = async (ctx) => {
328
+ * return ctx.json({ message: 'Hello, World!' })
329
+ * }
330
+ * ```
331
+ */
332
+ type GravitoHandler<V extends GravitoVariables = GravitoVariables> = (ctx: GravitoContext<V>) => Response | Promise<Response>;
333
+ /**
334
+ * GravitoMiddleware - Standard middleware type
335
+ *
336
+ * @typeParam V - Context variables type
337
+ *
338
+ * @example
339
+ * ```typescript
340
+ * const logger: GravitoMiddleware = async (ctx, next) => {
341
+ * console.log(`${ctx.req.method} ${ctx.req.path}`)
342
+ * await next()
343
+ * return undefined
344
+ * }
345
+ * ```
346
+ */
347
+ type GravitoMiddleware<V extends GravitoVariables = GravitoVariables> = (ctx: GravitoContext<V>, next: GravitoNext) => Response | undefined | Promise<Response | undefined | undefined>;
348
+ /**
349
+ * Error handler type
350
+ */
351
+ type GravitoErrorHandler<V extends GravitoVariables = GravitoVariables> = (error: Error, ctx: GravitoContext<V>) => Response | Promise<Response>;
352
+ /**
353
+ * Not found handler type
354
+ */
355
+ type GravitoNotFoundHandler<V extends GravitoVariables = GravitoVariables> = (ctx: GravitoContext<V>) => Response | Promise<Response>;
356
+
357
+ export type { ContentfulStatusCode as C, GravitoVariables as G, HttpMethod as H, ProxyOptions as P, StatusCode as S, ValidationTarget as V, GravitoHandler as a, GravitoMiddleware as b, GravitoErrorHandler as c, GravitoNotFoundHandler as d, GravitoContext as e, GravitoRequest as f, GravitoNext as g };