@gravito/echo 3.0.1 → 3.1.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 +211 -0
- package/dist/atlas/src/DB.d.ts +301 -0
- package/dist/atlas/src/OrbitAtlas.d.ts +9 -0
- package/dist/atlas/src/config/defineConfig.d.ts +14 -0
- package/dist/atlas/src/config/index.d.ts +7 -0
- package/dist/atlas/src/config/loadConfig.d.ts +48 -0
- package/dist/atlas/src/connection/Connection.d.ts +108 -0
- package/dist/atlas/src/connection/ConnectionManager.d.ts +111 -0
- package/dist/atlas/src/drivers/BunSQLDriver.d.ts +32 -0
- package/dist/atlas/src/drivers/BunSQLPreparedStatement.d.ts +118 -0
- package/dist/atlas/src/drivers/MongoDBDriver.d.ts +36 -0
- package/dist/atlas/src/drivers/MySQLDriver.d.ts +66 -0
- package/dist/atlas/src/drivers/PostgresDriver.d.ts +83 -0
- package/dist/atlas/src/drivers/RedisDriver.d.ts +43 -0
- package/dist/atlas/src/drivers/SQLiteDriver.d.ts +45 -0
- package/dist/atlas/src/drivers/types.d.ts +260 -0
- package/dist/atlas/src/errors/index.d.ts +45 -0
- package/dist/atlas/src/grammar/Grammar.d.ts +342 -0
- package/dist/atlas/src/grammar/MongoGrammar.d.ts +47 -0
- package/dist/atlas/src/grammar/MySQLGrammar.d.ts +54 -0
- package/dist/atlas/src/grammar/NullGrammar.d.ts +35 -0
- package/dist/atlas/src/grammar/PostgresGrammar.d.ts +62 -0
- package/dist/atlas/src/grammar/SQLiteGrammar.d.ts +32 -0
- package/dist/atlas/src/index.d.ts +67 -0
- package/dist/atlas/src/migration/Migration.d.ts +64 -0
- package/dist/atlas/src/migration/MigrationRepository.d.ts +65 -0
- package/dist/atlas/src/migration/Migrator.d.ts +110 -0
- package/dist/atlas/src/migration/index.d.ts +6 -0
- package/dist/atlas/src/observability/AtlasMetrics.d.ts +11 -0
- package/dist/atlas/src/observability/AtlasObservability.d.ts +15 -0
- package/dist/atlas/src/observability/AtlasTracer.d.ts +12 -0
- package/dist/atlas/src/observability/index.d.ts +9 -0
- package/dist/atlas/src/orm/index.d.ts +5 -0
- package/dist/atlas/src/orm/model/DirtyTracker.d.ts +121 -0
- package/dist/atlas/src/orm/model/Model.d.ts +449 -0
- package/dist/atlas/src/orm/model/ModelRegistry.d.ts +20 -0
- package/dist/atlas/src/orm/model/concerns/HasAttributes.d.ts +136 -0
- package/dist/atlas/src/orm/model/concerns/HasEvents.d.ts +36 -0
- package/dist/atlas/src/orm/model/concerns/HasPersistence.d.ts +87 -0
- package/dist/atlas/src/orm/model/concerns/HasRelationships.d.ts +117 -0
- package/dist/atlas/src/orm/model/concerns/HasSerialization.d.ts +64 -0
- package/dist/atlas/src/orm/model/concerns/applyMixins.d.ts +15 -0
- package/dist/atlas/src/orm/model/concerns/index.d.ts +12 -0
- package/dist/atlas/src/orm/model/decorators.d.ts +109 -0
- package/dist/atlas/src/orm/model/errors.d.ts +52 -0
- package/dist/atlas/src/orm/model/index.d.ts +10 -0
- package/dist/atlas/src/orm/model/relationships.d.ts +207 -0
- package/dist/atlas/src/orm/model/types.d.ts +12 -0
- package/dist/atlas/src/orm/schema/SchemaRegistry.d.ts +123 -0
- package/dist/atlas/src/orm/schema/SchemaSniffer.d.ts +54 -0
- package/dist/atlas/src/orm/schema/index.d.ts +6 -0
- package/dist/atlas/src/orm/schema/types.d.ts +85 -0
- package/dist/atlas/src/query/Expression.d.ts +60 -0
- package/dist/atlas/src/query/NPlusOneDetector.d.ts +10 -0
- package/dist/atlas/src/query/QueryBuilder.d.ts +573 -0
- package/dist/atlas/src/query/clauses/GroupByClause.d.ts +51 -0
- package/dist/atlas/src/query/clauses/HavingClause.d.ts +70 -0
- package/dist/atlas/src/query/clauses/JoinClause.d.ts +87 -0
- package/dist/atlas/src/query/clauses/LimitClause.d.ts +82 -0
- package/dist/atlas/src/query/clauses/OrderByClause.d.ts +69 -0
- package/dist/atlas/src/query/clauses/SelectClause.d.ts +71 -0
- package/dist/atlas/src/query/clauses/WhereClause.d.ts +167 -0
- package/dist/atlas/src/query/clauses/index.d.ts +11 -0
- package/dist/atlas/src/schema/Blueprint.d.ts +276 -0
- package/dist/atlas/src/schema/ColumnDefinition.d.ts +154 -0
- package/dist/atlas/src/schema/ForeignKeyDefinition.d.ts +37 -0
- package/dist/atlas/src/schema/Schema.d.ts +131 -0
- package/dist/atlas/src/schema/grammars/MySQLSchemaGrammar.d.ts +23 -0
- package/dist/atlas/src/schema/grammars/PostgresSchemaGrammar.d.ts +26 -0
- package/dist/atlas/src/schema/grammars/SQLiteSchemaGrammar.d.ts +28 -0
- package/dist/atlas/src/schema/grammars/SchemaGrammar.d.ts +97 -0
- package/dist/atlas/src/schema/grammars/index.d.ts +7 -0
- package/dist/atlas/src/schema/index.d.ts +8 -0
- package/dist/atlas/src/seed/Factory.d.ts +90 -0
- package/dist/atlas/src/seed/Seeder.d.ts +28 -0
- package/dist/atlas/src/seed/SeederRunner.d.ts +74 -0
- package/dist/atlas/src/seed/index.d.ts +6 -0
- package/dist/atlas/src/types/index.d.ts +1100 -0
- package/dist/atlas/src/utils/levenshtein.d.ts +9 -0
- package/dist/core/src/Application.d.ts +43 -17
- package/dist/core/src/CommandKernel.d.ts +33 -0
- package/dist/core/src/Container.d.ts +78 -14
- package/dist/core/src/HookManager.d.ts +422 -8
- package/dist/core/src/PlanetCore.d.ts +52 -7
- package/dist/core/src/Router.d.ts +41 -7
- package/dist/core/src/ServiceProvider.d.ts +14 -8
- package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +1 -0
- package/dist/core/src/adapters/PhotonAdapter.d.ts +1 -0
- package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +1 -0
- package/dist/core/src/adapters/types.d.ts +39 -0
- package/dist/core/src/engine/AOTRouter.d.ts +1 -11
- package/dist/core/src/engine/FastContext.d.ts +4 -2
- package/dist/core/src/engine/Gravito.d.ts +1 -1
- package/dist/core/src/engine/MinimalContext.d.ts +4 -2
- package/dist/core/src/engine/types.d.ts +6 -1
- package/dist/core/src/events/CircuitBreaker.d.ts +229 -0
- package/dist/core/src/events/DeadLetterQueue.d.ts +145 -0
- package/dist/core/src/events/EventBackend.d.ts +11 -0
- package/dist/core/src/events/EventOptions.d.ts +109 -0
- package/dist/core/src/events/EventPriorityQueue.d.ts +202 -0
- package/dist/core/src/events/IdempotencyCache.d.ts +60 -0
- package/dist/core/src/events/index.d.ts +14 -0
- package/dist/core/src/events/observability/EventMetrics.d.ts +132 -0
- package/dist/core/src/events/observability/EventTracer.d.ts +68 -0
- package/dist/core/src/events/observability/EventTracing.d.ts +161 -0
- package/dist/core/src/events/observability/OTelEventMetrics.d.ts +240 -0
- package/dist/core/src/events/observability/ObservableHookManager.d.ts +108 -0
- package/dist/core/src/events/observability/index.d.ts +20 -0
- package/dist/core/src/events/observability/metrics-types.d.ts +16 -0
- package/dist/core/src/events/types.d.ts +75 -0
- package/dist/core/src/exceptions/CircularDependencyException.d.ts +9 -0
- package/dist/core/src/exceptions/index.d.ts +1 -0
- package/dist/core/src/http/cookie.d.ts +29 -0
- package/dist/core/src/http/types.d.ts +21 -0
- package/dist/core/src/index.d.ts +13 -3
- package/dist/core/src/instrumentation/index.d.ts +35 -0
- package/dist/core/src/instrumentation/opentelemetry.d.ts +178 -0
- package/dist/core/src/instrumentation/types.d.ts +182 -0
- package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +316 -0
- package/dist/core/src/reliability/RetryPolicy.d.ts +217 -0
- package/dist/core/src/reliability/index.d.ts +6 -0
- package/dist/core/src/router/ControllerDispatcher.d.ts +12 -0
- package/dist/core/src/router/RequestValidator.d.ts +20 -0
- package/dist/echo/src/OrbitEcho.d.ts +71 -16
- package/dist/echo/src/dlq/DeadLetterQueue.d.ts +94 -0
- package/dist/echo/src/dlq/MemoryDeadLetterQueue.d.ts +36 -0
- package/dist/echo/src/dlq/index.d.ts +2 -0
- package/dist/echo/src/index.d.ts +31 -15
- package/dist/echo/src/middleware/RequestBufferMiddleware.d.ts +62 -0
- package/dist/echo/src/middleware/index.d.ts +8 -0
- package/dist/echo/src/observability/index.d.ts +3 -0
- package/dist/echo/src/observability/logging/ConsoleEchoLogger.d.ts +37 -0
- package/dist/echo/src/observability/logging/EchoLogger.d.ts +38 -0
- package/dist/echo/src/observability/logging/index.d.ts +2 -0
- package/dist/echo/src/observability/metrics/MetricsProvider.d.ts +69 -0
- package/dist/echo/src/observability/metrics/NoopMetricsProvider.d.ts +17 -0
- package/dist/echo/src/observability/metrics/PrometheusMetricsProvider.d.ts +39 -0
- package/dist/echo/src/observability/metrics/index.d.ts +3 -0
- package/dist/echo/src/observability/tracing/NoopTracer.d.ts +33 -0
- package/dist/echo/src/observability/tracing/Tracer.d.ts +75 -0
- package/dist/echo/src/observability/tracing/index.d.ts +2 -0
- package/dist/echo/src/providers/GenericProvider.d.ts +37 -18
- package/dist/echo/src/providers/GitHubProvider.d.ts +21 -12
- package/dist/echo/src/providers/LinearProvider.d.ts +27 -0
- package/dist/echo/src/providers/PaddleProvider.d.ts +31 -0
- package/dist/echo/src/providers/ShopifyProvider.d.ts +27 -0
- package/dist/echo/src/providers/SlackProvider.d.ts +27 -0
- package/dist/echo/src/providers/StripeProvider.d.ts +20 -12
- package/dist/echo/src/providers/TwilioProvider.d.ts +31 -0
- package/dist/echo/src/providers/base/BaseProvider.d.ts +87 -0
- package/dist/echo/src/providers/base/HeaderUtils.d.ts +34 -0
- package/dist/echo/src/providers/index.d.ts +14 -3
- package/dist/echo/src/receive/SignatureValidator.d.ts +33 -0
- package/dist/echo/src/receive/WebhookReceiver.d.ts +139 -21
- package/dist/echo/src/replay/WebhookReplayService.d.ts +35 -0
- package/dist/echo/src/replay/index.d.ts +1 -0
- package/dist/echo/src/resilience/CircuitBreaker.d.ts +117 -0
- package/dist/echo/src/resilience/index.d.ts +10 -0
- package/dist/echo/src/rotation/KeyRotationManager.d.ts +127 -0
- package/dist/echo/src/rotation/index.d.ts +10 -0
- package/dist/echo/src/send/WebhookDispatcher.d.ts +159 -15
- package/dist/echo/src/storage/MemoryWebhookStore.d.ts +14 -0
- package/dist/echo/src/storage/WebhookStore.d.ts +236 -0
- package/dist/echo/src/storage/index.d.ts +2 -0
- package/dist/echo/src/types.d.ts +656 -64
- package/dist/index.js +1327 -189
- package/dist/index.js.map +28 -10
- package/dist/photon/src/index.d.ts +69 -5
- package/dist/photon/src/middleware/binary.d.ts +12 -15
- package/dist/photon/src/middleware/htmx.d.ts +39 -0
- package/dist/photon/src/middleware/ratelimit.d.ts +157 -0
- package/dist/photon/src/openapi.d.ts +19 -0
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
- **Built-in Providers** - Stripe, GitHub, and generic provider support
|
|
9
9
|
- **Reliable Sending** - Exponential backoff retry with configurable strategy
|
|
10
10
|
- **Gravito Integration** - First-class OrbitEcho module for PlanetCore
|
|
11
|
+
- **Request Buffering (v1.1)** - Prevents signature verification failures from framework auto-parsing
|
|
12
|
+
- **Circuit Breaker (v1.1)** - Protects downstream services with automatic failure detection
|
|
13
|
+
- **Key Rotation (v1.2)** - Zero-downtime key updates with multi-version support
|
|
11
14
|
|
|
12
15
|
## Installation
|
|
13
16
|
|
|
@@ -90,8 +93,174 @@ if (result.success) {
|
|
|
90
93
|
} else {
|
|
91
94
|
console.error('Delivery failed:', result.error)
|
|
92
95
|
}
|
|
96
|
+
|
|
97
|
+
// Batch sending
|
|
98
|
+
const batchResult = await dispatcher.dispatchBatch([
|
|
99
|
+
{ url: 'https://a.com', event: 'e1', data: { id: 1 } },
|
|
100
|
+
{ url: 'https://b.com', event: 'e1', data: { id: 2 } }
|
|
101
|
+
], { concurrency: 5 })
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Persistence & Reliability
|
|
105
|
+
|
|
106
|
+
Echo supports persistence for audit logs and Dead Letter Queues (DLQ) for failed deliveries.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import {
|
|
110
|
+
OrbitEcho,
|
|
111
|
+
MemoryWebhookStore,
|
|
112
|
+
MemoryDeadLetterQueue
|
|
113
|
+
} from '@gravito/echo'
|
|
114
|
+
|
|
115
|
+
const echo = new OrbitEcho({
|
|
116
|
+
providers: { /* ... */ },
|
|
117
|
+
dispatcher: { /* ... */ },
|
|
118
|
+
// Configure persistence
|
|
119
|
+
store: new MemoryWebhookStore(), // Or your DB implementation
|
|
120
|
+
deadLetterQueue: new MemoryDeadLetterQueue()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// Replay failed events
|
|
124
|
+
const replayService = new WebhookReplayService(echo.getConfig().store!, echo.getDispatcher()!)
|
|
125
|
+
await replayService.replay({
|
|
126
|
+
timeRange: { from: new Date(Date.now() - 86400000), to: new Date() },
|
|
127
|
+
dryRun: true
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// Observability
|
|
131
|
+
const echoWithObservability = new OrbitEcho({
|
|
132
|
+
providers: { /* ... */ },
|
|
133
|
+
observability: {
|
|
134
|
+
logger: new ConsoleEchoLogger(),
|
|
135
|
+
metrics: new PrometheusMetricsProvider(),
|
|
136
|
+
// tracer: opentelemetryTracer
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Advanced Features (v1.1+)
|
|
142
|
+
|
|
143
|
+
### Request Buffer Middleware
|
|
144
|
+
|
|
145
|
+
防止框架自動解析 JSON 導致簽章驗證失敗。預設啟用,會在驗證前緩存原始 request body。
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const echo = new OrbitEcho({
|
|
149
|
+
providers: { /* ... */ },
|
|
150
|
+
requestBuffer: {
|
|
151
|
+
enabled: true, // 預設 true
|
|
152
|
+
maxBodySize: 10485760, // 預設 10MB
|
|
153
|
+
skipContentTypes: [ // 跳過特定 content types
|
|
154
|
+
'multipart/form-data',
|
|
155
|
+
'application/octet-stream'
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
})
|
|
93
159
|
```
|
|
94
160
|
|
|
161
|
+
Request Buffer 會自動整合到接收流程,無需額外配置。若需停用:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const echo = new OrbitEcho({
|
|
165
|
+
providers: { /* ... */ },
|
|
166
|
+
requestBuffer: { enabled: false }
|
|
167
|
+
})
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Circuit Breaker
|
|
171
|
+
|
|
172
|
+
保護下游服務免於雪崩效應,當失敗率超過閾值時自動斷路。
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { WebhookDispatcher } from '@gravito/echo'
|
|
176
|
+
|
|
177
|
+
const dispatcher = new WebhookDispatcher({
|
|
178
|
+
secret: process.env.OUTGOING_WEBHOOK_SECRET!,
|
|
179
|
+
circuitBreaker: {
|
|
180
|
+
enabled: true, // 預設 true
|
|
181
|
+
failureThreshold: 5, // 預設 5 次失敗後開路
|
|
182
|
+
successThreshold: 2, // 預設 2 次成功後關路
|
|
183
|
+
windowSize: 60000, // 預設 1 分鐘窗口
|
|
184
|
+
openTimeout: 30000, // 預設 30 秒後嘗試半開
|
|
185
|
+
// 可選的狀態變更回調
|
|
186
|
+
onOpen: (target) => console.log(`Circuit opened for ${target}`),
|
|
187
|
+
onHalfOpen: (target) => console.log(`Circuit half-open for ${target}`),
|
|
188
|
+
onClose: (target) => console.log(`Circuit closed for ${target}`)
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
// 檢查熔斷器狀態
|
|
193
|
+
const metrics = dispatcher.getCircuitBreakerMetrics('example.com')
|
|
194
|
+
console.log(metrics.state) // 'CLOSED' | 'OPEN' | 'HALF_OPEN'
|
|
195
|
+
|
|
196
|
+
// 手動重置熔斷器
|
|
197
|
+
dispatcher.resetCircuitBreaker('example.com')
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**熔斷器運作邏輯**:
|
|
201
|
+
- **CLOSED(關路)**:正常運作,所有請求通過
|
|
202
|
+
- **OPEN(開路)**:失敗次數超過閾值,立即拒絕所有請求
|
|
203
|
+
- **HALF_OPEN(半開)**:嘗試恢復,允許有限請求測試服務狀態
|
|
204
|
+
|
|
205
|
+
每個目標 host 使用獨立的熔斷器,避免單點故障影響全域。
|
|
206
|
+
|
|
207
|
+
### Key Rotation
|
|
208
|
+
|
|
209
|
+
支援 Provider 密鑰的動態輪換,無需重啟應用。
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { OrbitEcho } from '@gravito/echo'
|
|
213
|
+
|
|
214
|
+
const echo = new OrbitEcho({
|
|
215
|
+
// 啟用密鑰輪換功能
|
|
216
|
+
keyRotation: {
|
|
217
|
+
enabled: true,
|
|
218
|
+
autoCleanup: true, // 自動清理過期密鑰
|
|
219
|
+
gracePeriod: 86400000, // 24 小時寬限期
|
|
220
|
+
onRotate: (provider, newKey) => {
|
|
221
|
+
console.log(`Key rotated for ${provider}: ${newKey.version}`)
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
// 使用多密鑰配置 Provider
|
|
225
|
+
providers: {
|
|
226
|
+
stripe: {
|
|
227
|
+
name: 'stripe',
|
|
228
|
+
secret: '', // 主密鑰會從 keys 中自動設定
|
|
229
|
+
keys: [
|
|
230
|
+
{
|
|
231
|
+
key: 'whsec_new_key',
|
|
232
|
+
version: 'v2',
|
|
233
|
+
isPrimary: true,
|
|
234
|
+
activeFrom: new Date('2026-01-15')
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
key: 'whsec_old_key',
|
|
238
|
+
version: 'v1',
|
|
239
|
+
isPrimary: false,
|
|
240
|
+
activeFrom: new Date('2025-01-01'),
|
|
241
|
+
expiresAt: new Date('2026-02-15') // 寬限期結束時間
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
// 執行密鑰輪換
|
|
249
|
+
await echo.rotateProviderKey('stripe', {
|
|
250
|
+
key: 'whsec_newest_key',
|
|
251
|
+
version: 'v3',
|
|
252
|
+
activeFrom: new Date()
|
|
253
|
+
})
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**密鑰輪換運作邏輯**:
|
|
257
|
+
1. 在輪換期間,系統同時接受新舊密鑰驗證
|
|
258
|
+
2. 舊主密鑰自動降級為輔助密鑰,並設定過期時間(當前時間 + gracePeriod)
|
|
259
|
+
3. 新密鑰成為主密鑰,用於所有新的簽章驗證
|
|
260
|
+
4. 過期密鑰會自動清理(若啟用 autoCleanup)
|
|
261
|
+
|
|
262
|
+
這確保了正在傳輸中的 Webhook 不會因密鑰輪換而失敗。
|
|
263
|
+
|
|
95
264
|
## Providers
|
|
96
265
|
|
|
97
266
|
### Built-in Providers
|
|
@@ -101,6 +270,11 @@ if (result.success) {
|
|
|
101
270
|
| `stripe` | HMAC-SHA256 + Timestamp | `Stripe-Signature` |
|
|
102
271
|
| `github` | HMAC-SHA256 | `X-Hub-Signature-256` |
|
|
103
272
|
| `generic` | HMAC-SHA256 | `X-Webhook-Signature` |
|
|
273
|
+
| `shopify` | HMAC-SHA256 (base64) | `X-Shopify-Hmac-Sha256` |
|
|
274
|
+
| `twilio` | HMAC-SHA1 (base64) | `X-Twilio-Signature` |
|
|
275
|
+
| `slack` | HMAC-SHA256 + Timestamp | `X-Slack-Signature` |
|
|
276
|
+
| `paddle` | HMAC-SHA256 + Timestamp | `Paddle-Signature` |
|
|
277
|
+
| `linear` | HMAC-SHA256 | `Linear-Signature` |
|
|
104
278
|
|
|
105
279
|
### Custom Provider
|
|
106
280
|
|
|
@@ -122,6 +296,8 @@ receiver.registerProvider('custom', 'secret', { type: 'my-provider' })
|
|
|
122
296
|
|
|
123
297
|
## Configuration
|
|
124
298
|
|
|
299
|
+
For detailed API information, please refer to the [API Documentation](./docs/api/README.md).
|
|
300
|
+
|
|
125
301
|
### WebhookDispatcher
|
|
126
302
|
|
|
127
303
|
```typescript
|
|
@@ -143,6 +319,18 @@ interface WebhookDispatcherConfig {
|
|
|
143
319
|
|
|
144
320
|
/** Custom User-Agent */
|
|
145
321
|
userAgent?: string
|
|
322
|
+
|
|
323
|
+
/** Circuit breaker configuration (v1.1+) */
|
|
324
|
+
circuitBreaker?: {
|
|
325
|
+
enabled?: boolean // default: true
|
|
326
|
+
failureThreshold?: number // default: 5
|
|
327
|
+
successThreshold?: number // default: 2
|
|
328
|
+
windowSize?: number // default: 60000 (1 minute)
|
|
329
|
+
openTimeout?: number // default: 30000 (30 seconds)
|
|
330
|
+
onOpen?: (target: string) => void
|
|
331
|
+
onHalfOpen?: (target: string) => void
|
|
332
|
+
onClose?: (target: string) => void
|
|
333
|
+
}
|
|
146
334
|
}
|
|
147
335
|
```
|
|
148
336
|
|
|
@@ -155,6 +343,14 @@ interface EchoConfig {
|
|
|
155
343
|
name: string
|
|
156
344
|
secret: string
|
|
157
345
|
tolerance?: number // timestamp tolerance in seconds
|
|
346
|
+
// Key rotation support (v1.2+)
|
|
347
|
+
keys?: Array<{
|
|
348
|
+
key: string
|
|
349
|
+
version: string
|
|
350
|
+
isPrimary: boolean
|
|
351
|
+
activeFrom: Date
|
|
352
|
+
expiresAt?: Date
|
|
353
|
+
}>
|
|
158
354
|
}>
|
|
159
355
|
|
|
160
356
|
/** Dispatcher configuration */
|
|
@@ -162,6 +358,21 @@ interface EchoConfig {
|
|
|
162
358
|
|
|
163
359
|
/** Base path for webhook endpoints */
|
|
164
360
|
basePath?: string // default: '/webhooks'
|
|
361
|
+
|
|
362
|
+
/** Request buffer configuration (v1.1+) */
|
|
363
|
+
requestBuffer?: {
|
|
364
|
+
enabled?: boolean // default: true
|
|
365
|
+
maxBodySize?: number // default: 10485760 (10MB)
|
|
366
|
+
skipContentTypes?: string[] // default: ['multipart/form-data', 'application/octet-stream']
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/** Key rotation configuration (v1.2+) */
|
|
370
|
+
keyRotation?: {
|
|
371
|
+
enabled?: boolean // default: false
|
|
372
|
+
autoCleanup?: boolean // default: true
|
|
373
|
+
gracePeriod?: number // default: 86400000 (24 hours)
|
|
374
|
+
onRotate?: (providerName: string, newKey: ProviderKeyEntry) => void
|
|
375
|
+
}
|
|
165
376
|
}
|
|
166
377
|
```
|
|
167
378
|
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { type AtlasMetrics, type AtlasTracer } from './observability';
|
|
2
|
+
import type { AtlasConfig, CacheInterface, ConnectionConfig, ConnectionContract, QueryBuilderContract, QueryResult } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* DB Facade - Static entry point for database operations.
|
|
5
|
+
*
|
|
6
|
+
* Provides a Laravel-style static interface for managing connections,
|
|
7
|
+
* building queries, and executing transactions. Acts as the primary
|
|
8
|
+
* gateway for application-level database interaction.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Setup
|
|
13
|
+
* DB.configure({
|
|
14
|
+
* default: 'main',
|
|
15
|
+
* connections: { main: { driver: 'sqlite', database: ':memory:' } }
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Fluent Querying
|
|
19
|
+
* const users = await DB.table('users').where('id', 1).get();
|
|
20
|
+
*
|
|
21
|
+
* // Raw Execution
|
|
22
|
+
* const stats = await DB.raw('SELECT count(*) FROM users');
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class DB {
|
|
26
|
+
private static manager;
|
|
27
|
+
private static initialized;
|
|
28
|
+
private static cache;
|
|
29
|
+
private static _debug;
|
|
30
|
+
private static _queryLog;
|
|
31
|
+
private static readonly MAX_LOG_SIZE;
|
|
32
|
+
private static queryListener?;
|
|
33
|
+
/**
|
|
34
|
+
* Sets the global cache provider for query results.
|
|
35
|
+
*
|
|
36
|
+
* @param cache - Implementation of CacheInterface (e.g., Redis, In-Memory).
|
|
37
|
+
*/
|
|
38
|
+
static setCache(cache: CacheInterface): void;
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves the active global cache provider.
|
|
41
|
+
*
|
|
42
|
+
* @returns The cache interface or undefined if none is configured.
|
|
43
|
+
*/
|
|
44
|
+
static getCache(): CacheInterface | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Toggles debug mode for query logging.
|
|
47
|
+
*
|
|
48
|
+
* When enabled, executed queries are stored in an internal log with
|
|
49
|
+
* performance metrics.
|
|
50
|
+
*
|
|
51
|
+
* @param enabled - Whether to enable logging.
|
|
52
|
+
*/
|
|
53
|
+
static debug(enabled?: boolean): void;
|
|
54
|
+
/**
|
|
55
|
+
* Indicates if debug mode is currently active.
|
|
56
|
+
*/
|
|
57
|
+
static isDebug(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Retrieves the last executed SQL statement with interpolated values.
|
|
60
|
+
*
|
|
61
|
+
* Useful for debugging and integration testing.
|
|
62
|
+
*
|
|
63
|
+
* @returns The full SQL string or null if no queries were run.
|
|
64
|
+
*/
|
|
65
|
+
static getLastQuery(): string | null;
|
|
66
|
+
/**
|
|
67
|
+
* Retrieves the complete query log for the current session.
|
|
68
|
+
*
|
|
69
|
+
* @returns A copy of the query log array.
|
|
70
|
+
*/
|
|
71
|
+
static getQueryLog(): typeof this._queryLog;
|
|
72
|
+
/**
|
|
73
|
+
* Flushes the internal query log.
|
|
74
|
+
*/
|
|
75
|
+
static clearQueryLog(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Records a query execution event.
|
|
78
|
+
*
|
|
79
|
+
* @param sql - The SQL statement.
|
|
80
|
+
* @param bindings - The parameter values.
|
|
81
|
+
* @param duration - Time taken in ms.
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
static logQuery(sql: string, bindings: unknown[], duration: number): void;
|
|
85
|
+
/**
|
|
86
|
+
* Interpolates bindings into a SQL string for display purposes.
|
|
87
|
+
*
|
|
88
|
+
* Warning: This is only for logging/debugging and NOT for execution
|
|
89
|
+
* to avoid SQL injection risks.
|
|
90
|
+
*
|
|
91
|
+
* @param sql - The SQL template with placeholders.
|
|
92
|
+
* @param bindings - The values to inject.
|
|
93
|
+
* @returns The readable SQL string.
|
|
94
|
+
*/
|
|
95
|
+
private static interpolateBindings;
|
|
96
|
+
/**
|
|
97
|
+
* Executes a callback in "pretend" mode where queries are captured but not run.
|
|
98
|
+
*
|
|
99
|
+
* Ideal for verifying generated SQL without side effects.
|
|
100
|
+
*
|
|
101
|
+
* @param callback - Logic to simulate.
|
|
102
|
+
* @returns Captured SQL strings and the callback result.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const { queries } = await DB.pretend(() => User.create({ name: 'Test' }));
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
static pretend<T>(callback: () => Promise<T>): Promise<{
|
|
110
|
+
queries: string[];
|
|
111
|
+
result?: T;
|
|
112
|
+
}>;
|
|
113
|
+
private constructor();
|
|
114
|
+
/**
|
|
115
|
+
* Retrieves performance metrics from the SQL compiler cache.
|
|
116
|
+
*
|
|
117
|
+
* @returns Stats including hit rate and cache utilization.
|
|
118
|
+
*/
|
|
119
|
+
static getCacheStats(): {
|
|
120
|
+
size: number;
|
|
121
|
+
maxSize: number;
|
|
122
|
+
hitRate: number;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Initializes the database subsystem with the provided configuration.
|
|
126
|
+
*
|
|
127
|
+
* Configures the connection manager and observability (Tracing/Metrics).
|
|
128
|
+
* This method must be called before any database operations.
|
|
129
|
+
*
|
|
130
|
+
* @param config - The Atlas configuration object.
|
|
131
|
+
* @throws {Error} If configuration is invalid.
|
|
132
|
+
*/
|
|
133
|
+
static configure(config: AtlasConfig): void;
|
|
134
|
+
/**
|
|
135
|
+
* Retrieves the global tracer for manual span creation.
|
|
136
|
+
*/
|
|
137
|
+
static getTracer(): AtlasTracer | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Retrieves the global metrics reporter.
|
|
140
|
+
*/
|
|
141
|
+
static getMetrics(): AtlasMetrics | undefined;
|
|
142
|
+
/**
|
|
143
|
+
* Configures the database using environment variables.
|
|
144
|
+
*
|
|
145
|
+
* Looks for standard DB_* variables or DATABASE_URL.
|
|
146
|
+
*
|
|
147
|
+
* @param connectionName - The name to assign to the primary connection.
|
|
148
|
+
*/
|
|
149
|
+
static configureFromEnv(connectionName?: string): void;
|
|
150
|
+
/**
|
|
151
|
+
* Loads configuration from a file.
|
|
152
|
+
*
|
|
153
|
+
* Automatically detects common patterns like config/database.ts.
|
|
154
|
+
*
|
|
155
|
+
* @param configPath - Explicit path to the config file.
|
|
156
|
+
*/
|
|
157
|
+
static configureFromFile(configPath?: string): Promise<void>;
|
|
158
|
+
/**
|
|
159
|
+
* Best-effort configuration using file detection then environment variables.
|
|
160
|
+
*
|
|
161
|
+
* @param configPath - Optional path to try first.
|
|
162
|
+
*/
|
|
163
|
+
static autoConfigure(configPath?: string): Promise<void>;
|
|
164
|
+
/**
|
|
165
|
+
* Manually adds a connection to the manager.
|
|
166
|
+
*
|
|
167
|
+
* @param name - Unique connection name.
|
|
168
|
+
* @param config - Connection settings.
|
|
169
|
+
*/
|
|
170
|
+
static addConnection(name: string, config: ConnectionConfig): void;
|
|
171
|
+
/**
|
|
172
|
+
* Adds a connection configured via prefixed environment variables.
|
|
173
|
+
*
|
|
174
|
+
* @param name - Connection name.
|
|
175
|
+
* @param prefix - Env variable prefix (e.g. "READ_ONLY").
|
|
176
|
+
*/
|
|
177
|
+
static addConnectionFromEnv(name: string, prefix?: string): void;
|
|
178
|
+
/**
|
|
179
|
+
* Sets the global default connection.
|
|
180
|
+
*
|
|
181
|
+
* @param name - The connection identifier.
|
|
182
|
+
*/
|
|
183
|
+
static setDefaultConnection(name: string): void;
|
|
184
|
+
/**
|
|
185
|
+
* Returns the name of the current default connection.
|
|
186
|
+
*/
|
|
187
|
+
static getDefaultConnection(): string;
|
|
188
|
+
/**
|
|
189
|
+
* Retrieves a connection instance.
|
|
190
|
+
*
|
|
191
|
+
* @param name - Name of the connection (defaults to the global default).
|
|
192
|
+
* @returns The active connection instance.
|
|
193
|
+
* @throws {Error} If DB is not configured or connection name is unknown.
|
|
194
|
+
*/
|
|
195
|
+
static connection(name?: string): ConnectionContract;
|
|
196
|
+
/**
|
|
197
|
+
* Checks if a specific connection has been configured.
|
|
198
|
+
*/
|
|
199
|
+
static hasConnection(name: string): boolean;
|
|
200
|
+
/**
|
|
201
|
+
* Lists all configured connection identifiers.
|
|
202
|
+
*/
|
|
203
|
+
static getConnectionNames(): string[];
|
|
204
|
+
/**
|
|
205
|
+
* Retrieves the raw configuration for a connection.
|
|
206
|
+
*/
|
|
207
|
+
static getConnectionConfig(name?: string): ConnectionConfig | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* Initializes a fluent query builder for a specific table.
|
|
210
|
+
*
|
|
211
|
+
* @template T - The row type.
|
|
212
|
+
* @param tableName - The database table name.
|
|
213
|
+
* @returns A QueryBuilder instance.
|
|
214
|
+
*/
|
|
215
|
+
static table<T = Record<string, unknown>>(tableName: string): QueryBuilderContract<T>;
|
|
216
|
+
/**
|
|
217
|
+
* Executes a raw SQL statement with telemetry tracking.
|
|
218
|
+
*
|
|
219
|
+
* @template T - The expected row type.
|
|
220
|
+
* @param sql - The SQL string with placeholders.
|
|
221
|
+
* @param bindings - Array of values.
|
|
222
|
+
* @returns The raw query result.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* const users = await DB.raw('SELECT * FROM users WHERE active = ?', [true]);
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
static raw<T = Record<string, unknown>>(sql: string, bindings?: unknown[]): Promise<QueryResult<T>>;
|
|
230
|
+
/**
|
|
231
|
+
* Alias for {@link raw}.
|
|
232
|
+
*/
|
|
233
|
+
static rawQuery<T = Record<string, unknown>>(sql: string, bindings?: unknown[]): Promise<QueryResult<T>>;
|
|
234
|
+
/**
|
|
235
|
+
* Executes logic within a managed database transaction.
|
|
236
|
+
*
|
|
237
|
+
* Automatically commits on success and rolls back on error.
|
|
238
|
+
* Receives a connection instance scoped to the transaction.
|
|
239
|
+
*
|
|
240
|
+
* @template T - Logic result type.
|
|
241
|
+
* @param callback - The transactional logic.
|
|
242
|
+
* @param connectionName - Optional specific connection.
|
|
243
|
+
* @returns The callback's return value.
|
|
244
|
+
*/
|
|
245
|
+
static transaction<T>(callback: (connection: ConnectionContract) => Promise<T>, connectionName?: string): Promise<T>;
|
|
246
|
+
/**
|
|
247
|
+
* Manually starts a database transaction.
|
|
248
|
+
*
|
|
249
|
+
* Caller is responsible for calling commit() or rollback().
|
|
250
|
+
*
|
|
251
|
+
* @param connectionName - Connection to use.
|
|
252
|
+
* @returns A transaction-scoped connection.
|
|
253
|
+
* @throws {Error} If the driver does not support transactions.
|
|
254
|
+
*/
|
|
255
|
+
static beginTransaction(connectionName?: string): Promise<ConnectionContract>;
|
|
256
|
+
/**
|
|
257
|
+
* Closes the specified connection.
|
|
258
|
+
*/
|
|
259
|
+
static disconnect(name?: string): Promise<void>;
|
|
260
|
+
/**
|
|
261
|
+
* Closes all managed connections.
|
|
262
|
+
*/
|
|
263
|
+
static disconnectAll(): Promise<void>;
|
|
264
|
+
/**
|
|
265
|
+
* Safely shuts down the database subsystem.
|
|
266
|
+
*/
|
|
267
|
+
static shutdown(): Promise<void>;
|
|
268
|
+
/**
|
|
269
|
+
* Closes and re-opens a connection.
|
|
270
|
+
*/
|
|
271
|
+
static reconnect(name?: string): Promise<ConnectionContract>;
|
|
272
|
+
/**
|
|
273
|
+
* Removes a connection from the internal cache without closing it.
|
|
274
|
+
*/
|
|
275
|
+
static purge(name?: string): void;
|
|
276
|
+
/**
|
|
277
|
+
* Shortcut for starting a query with specific columns.
|
|
278
|
+
*/
|
|
279
|
+
static select<T = Record<string, unknown>>(tableName: string, columns?: string[]): QueryBuilderContract<T>;
|
|
280
|
+
/**
|
|
281
|
+
* Shortcut for inserting records.
|
|
282
|
+
*/
|
|
283
|
+
static insert<T = Record<string, unknown>>(tableName: string, data: Partial<T> | Partial<T>[]): Promise<T[]>;
|
|
284
|
+
/**
|
|
285
|
+
* Shortcut for updating records based on key-value filters.
|
|
286
|
+
*/
|
|
287
|
+
static update<T = Record<string, unknown>>(tableName: string, where: Record<string, unknown>, data: Partial<T>): Promise<number>;
|
|
288
|
+
/**
|
|
289
|
+
* Shortcut for deleting records based on key-value filters.
|
|
290
|
+
*/
|
|
291
|
+
static delete(tableName: string, where: Record<string, unknown>): Promise<number>;
|
|
292
|
+
/**
|
|
293
|
+
* Ensures the DB facade is ready for use.
|
|
294
|
+
*/
|
|
295
|
+
private static ensureConfigured;
|
|
296
|
+
/**
|
|
297
|
+
* Internal reset for testing.
|
|
298
|
+
* @internal
|
|
299
|
+
*/
|
|
300
|
+
static _reset(): Promise<void>;
|
|
301
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
2
|
+
/**
|
|
3
|
+
* Atlas Orbit - Database & ORM Integration
|
|
4
|
+
* Integrates the Atlas ORM engine into the Gravito Core ecosystem.
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare class OrbitAtlas implements GravitoOrbit {
|
|
8
|
+
install(core: PlanetCore): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AtlasConfig, AtlasObservabilityConfig, ConnectionConfig, PostgresConfig } from '../types';
|
|
2
|
+
export type { AtlasConfig, AtlasObservabilityConfig, ConnectionConfig, PostgresConfig };
|
|
3
|
+
/**
|
|
4
|
+
* Define configuration with type checking
|
|
5
|
+
*/
|
|
6
|
+
export declare function defineConfig(config: AtlasConfig): AtlasConfig;
|
|
7
|
+
/**
|
|
8
|
+
* Load configuration from environment variables with optional prefix
|
|
9
|
+
* Supports both DATABASE_URL and individual DB_* variables
|
|
10
|
+
*
|
|
11
|
+
* @param connectionName - Name for the connection
|
|
12
|
+
* @param prefix - Optional prefix for environment variables (e.g., 'READ' for DB_READ_*)
|
|
13
|
+
*/
|
|
14
|
+
export declare function fromEnv(connectionName?: string, prefix?: string): AtlasConfig;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Module
|
|
3
|
+
* @description Database configuration utilities
|
|
4
|
+
*/
|
|
5
|
+
export type { AtlasConfig, ConnectionConfig } from '../types';
|
|
6
|
+
export { defineConfig, fromEnv } from './defineConfig';
|
|
7
|
+
export { autoConfigure, loadConfig, loadConfigFile } from './loadConfig';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Loader
|
|
3
|
+
* @description Load database configuration from various sources
|
|
4
|
+
*/
|
|
5
|
+
import type { AtlasConfig } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Load configuration from a TypeScript/JavaScript config file
|
|
8
|
+
*
|
|
9
|
+
* @param configPath - Path to the config file (default: 'config/database.ts' or 'config/database.js')
|
|
10
|
+
* @returns Atlas configuration
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // config/database.ts
|
|
15
|
+
* import { defineConfig } from '@gravito/atlas'
|
|
16
|
+
*
|
|
17
|
+
* export default defineConfig({
|
|
18
|
+
* default: 'default',
|
|
19
|
+
* connections: {
|
|
20
|
+
* default: {
|
|
21
|
+
* driver: 'postgres',
|
|
22
|
+
* host: 'localhost',
|
|
23
|
+
* database: 'myapp'
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadConfigFile(configPath?: string): Promise<AtlasConfig>;
|
|
30
|
+
/**
|
|
31
|
+
* Load configuration from multiple sources with priority
|
|
32
|
+
* Priority: 1. Config file, 2. Environment variables, 3. Default
|
|
33
|
+
*
|
|
34
|
+
* @param options - Loading options
|
|
35
|
+
* @returns Atlas configuration
|
|
36
|
+
*/
|
|
37
|
+
export declare function loadConfig(options?: {
|
|
38
|
+
configPath?: string;
|
|
39
|
+
useEnv?: boolean;
|
|
40
|
+
envPrefix?: string;
|
|
41
|
+
}): Promise<AtlasConfig>;
|
|
42
|
+
/**
|
|
43
|
+
* Auto-configure database from config file or environment
|
|
44
|
+
* This is a convenience function that tries config file first, then environment
|
|
45
|
+
*
|
|
46
|
+
* @param configPath - Optional path to config file
|
|
47
|
+
*/
|
|
48
|
+
export declare function autoConfigure(configPath?: string): Promise<void>;
|