@gravito/echo 3.0.0 → 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.
Files changed (221) hide show
  1. package/README.md +211 -0
  2. package/dist/atlas/src/DB.d.ts +301 -0
  3. package/dist/atlas/src/OrbitAtlas.d.ts +9 -0
  4. package/dist/atlas/src/config/defineConfig.d.ts +14 -0
  5. package/dist/atlas/src/config/index.d.ts +7 -0
  6. package/dist/atlas/src/config/loadConfig.d.ts +48 -0
  7. package/dist/atlas/src/connection/Connection.d.ts +108 -0
  8. package/dist/atlas/src/connection/ConnectionManager.d.ts +111 -0
  9. package/dist/atlas/src/drivers/BunSQLDriver.d.ts +32 -0
  10. package/dist/atlas/src/drivers/BunSQLPreparedStatement.d.ts +118 -0
  11. package/dist/atlas/src/drivers/MongoDBDriver.d.ts +36 -0
  12. package/dist/atlas/src/drivers/MySQLDriver.d.ts +66 -0
  13. package/dist/atlas/src/drivers/PostgresDriver.d.ts +83 -0
  14. package/dist/atlas/src/drivers/RedisDriver.d.ts +43 -0
  15. package/dist/atlas/src/drivers/SQLiteDriver.d.ts +45 -0
  16. package/dist/atlas/src/drivers/types.d.ts +260 -0
  17. package/dist/atlas/src/errors/index.d.ts +45 -0
  18. package/dist/atlas/src/grammar/Grammar.d.ts +342 -0
  19. package/dist/atlas/src/grammar/MongoGrammar.d.ts +47 -0
  20. package/dist/atlas/src/grammar/MySQLGrammar.d.ts +54 -0
  21. package/dist/atlas/src/grammar/NullGrammar.d.ts +35 -0
  22. package/dist/atlas/src/grammar/PostgresGrammar.d.ts +62 -0
  23. package/dist/atlas/src/grammar/SQLiteGrammar.d.ts +32 -0
  24. package/dist/atlas/src/index.d.ts +67 -0
  25. package/dist/atlas/src/migration/Migration.d.ts +64 -0
  26. package/dist/atlas/src/migration/MigrationRepository.d.ts +65 -0
  27. package/dist/atlas/src/migration/Migrator.d.ts +110 -0
  28. package/dist/atlas/src/migration/index.d.ts +6 -0
  29. package/dist/atlas/src/observability/AtlasMetrics.d.ts +11 -0
  30. package/dist/atlas/src/observability/AtlasObservability.d.ts +15 -0
  31. package/dist/atlas/src/observability/AtlasTracer.d.ts +12 -0
  32. package/dist/atlas/src/observability/index.d.ts +9 -0
  33. package/dist/atlas/src/orm/index.d.ts +5 -0
  34. package/dist/atlas/src/orm/model/DirtyTracker.d.ts +121 -0
  35. package/dist/atlas/src/orm/model/Model.d.ts +449 -0
  36. package/dist/atlas/src/orm/model/ModelRegistry.d.ts +20 -0
  37. package/dist/atlas/src/orm/model/concerns/HasAttributes.d.ts +136 -0
  38. package/dist/atlas/src/orm/model/concerns/HasEvents.d.ts +36 -0
  39. package/dist/atlas/src/orm/model/concerns/HasPersistence.d.ts +87 -0
  40. package/dist/atlas/src/orm/model/concerns/HasRelationships.d.ts +117 -0
  41. package/dist/atlas/src/orm/model/concerns/HasSerialization.d.ts +64 -0
  42. package/dist/atlas/src/orm/model/concerns/applyMixins.d.ts +15 -0
  43. package/dist/atlas/src/orm/model/concerns/index.d.ts +12 -0
  44. package/dist/atlas/src/orm/model/decorators.d.ts +109 -0
  45. package/dist/atlas/src/orm/model/errors.d.ts +52 -0
  46. package/dist/atlas/src/orm/model/index.d.ts +10 -0
  47. package/dist/atlas/src/orm/model/relationships.d.ts +207 -0
  48. package/dist/atlas/src/orm/model/types.d.ts +12 -0
  49. package/dist/atlas/src/orm/schema/SchemaRegistry.d.ts +123 -0
  50. package/dist/atlas/src/orm/schema/SchemaSniffer.d.ts +54 -0
  51. package/dist/atlas/src/orm/schema/index.d.ts +6 -0
  52. package/dist/atlas/src/orm/schema/types.d.ts +85 -0
  53. package/dist/atlas/src/query/Expression.d.ts +60 -0
  54. package/dist/atlas/src/query/NPlusOneDetector.d.ts +10 -0
  55. package/dist/atlas/src/query/QueryBuilder.d.ts +573 -0
  56. package/dist/atlas/src/query/clauses/GroupByClause.d.ts +51 -0
  57. package/dist/atlas/src/query/clauses/HavingClause.d.ts +70 -0
  58. package/dist/atlas/src/query/clauses/JoinClause.d.ts +87 -0
  59. package/dist/atlas/src/query/clauses/LimitClause.d.ts +82 -0
  60. package/dist/atlas/src/query/clauses/OrderByClause.d.ts +69 -0
  61. package/dist/atlas/src/query/clauses/SelectClause.d.ts +71 -0
  62. package/dist/atlas/src/query/clauses/WhereClause.d.ts +167 -0
  63. package/dist/atlas/src/query/clauses/index.d.ts +11 -0
  64. package/dist/atlas/src/schema/Blueprint.d.ts +276 -0
  65. package/dist/atlas/src/schema/ColumnDefinition.d.ts +154 -0
  66. package/dist/atlas/src/schema/ForeignKeyDefinition.d.ts +37 -0
  67. package/dist/atlas/src/schema/Schema.d.ts +131 -0
  68. package/dist/atlas/src/schema/grammars/MySQLSchemaGrammar.d.ts +23 -0
  69. package/dist/atlas/src/schema/grammars/PostgresSchemaGrammar.d.ts +26 -0
  70. package/dist/atlas/src/schema/grammars/SQLiteSchemaGrammar.d.ts +28 -0
  71. package/dist/atlas/src/schema/grammars/SchemaGrammar.d.ts +97 -0
  72. package/dist/atlas/src/schema/grammars/index.d.ts +7 -0
  73. package/dist/atlas/src/schema/index.d.ts +8 -0
  74. package/dist/atlas/src/seed/Factory.d.ts +90 -0
  75. package/dist/atlas/src/seed/Seeder.d.ts +28 -0
  76. package/dist/atlas/src/seed/SeederRunner.d.ts +74 -0
  77. package/dist/atlas/src/seed/index.d.ts +6 -0
  78. package/dist/atlas/src/types/index.d.ts +1100 -0
  79. package/dist/atlas/src/utils/levenshtein.d.ts +9 -0
  80. package/dist/core/src/Application.d.ts +215 -0
  81. package/dist/core/src/CommandKernel.d.ts +33 -0
  82. package/dist/core/src/ConfigManager.d.ts +26 -0
  83. package/dist/core/src/Container.d.ts +108 -0
  84. package/dist/core/src/ErrorHandler.d.ts +63 -0
  85. package/dist/core/src/Event.d.ts +5 -0
  86. package/dist/core/src/EventManager.d.ts +123 -0
  87. package/dist/core/src/GlobalErrorHandlers.d.ts +47 -0
  88. package/dist/core/src/GravitoServer.d.ts +28 -0
  89. package/dist/core/src/HookManager.d.ts +496 -0
  90. package/dist/core/src/Listener.d.ts +4 -0
  91. package/dist/core/src/Logger.d.ts +20 -0
  92. package/dist/core/src/PlanetCore.d.ts +289 -0
  93. package/dist/core/src/Route.d.ts +36 -0
  94. package/dist/core/src/Router.d.ts +284 -0
  95. package/dist/core/src/ServiceProvider.d.ts +156 -0
  96. package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +27 -0
  97. package/dist/core/src/adapters/PhotonAdapter.d.ts +171 -0
  98. package/dist/core/src/adapters/bun/BunContext.d.ts +45 -0
  99. package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +31 -0
  100. package/dist/core/src/adapters/bun/BunRequest.d.ts +31 -0
  101. package/dist/core/src/adapters/bun/RadixNode.d.ts +19 -0
  102. package/dist/core/src/adapters/bun/RadixRouter.d.ts +31 -0
  103. package/dist/core/src/adapters/bun/types.d.ts +20 -0
  104. package/dist/core/src/adapters/photon-types.d.ts +73 -0
  105. package/dist/core/src/adapters/types.d.ts +235 -0
  106. package/dist/core/src/engine/AOTRouter.d.ts +124 -0
  107. package/dist/core/src/engine/FastContext.d.ts +100 -0
  108. package/dist/core/src/engine/Gravito.d.ts +137 -0
  109. package/dist/core/src/engine/MinimalContext.d.ts +79 -0
  110. package/dist/core/src/engine/analyzer.d.ts +27 -0
  111. package/dist/core/src/engine/constants.d.ts +23 -0
  112. package/dist/core/src/engine/index.d.ts +26 -0
  113. package/dist/core/src/engine/path.d.ts +26 -0
  114. package/dist/core/src/engine/pool.d.ts +83 -0
  115. package/dist/core/src/engine/types.d.ts +143 -0
  116. package/dist/core/src/events/CircuitBreaker.d.ts +229 -0
  117. package/dist/core/src/events/DeadLetterQueue.d.ts +145 -0
  118. package/dist/core/src/events/EventBackend.d.ts +11 -0
  119. package/dist/core/src/events/EventOptions.d.ts +109 -0
  120. package/dist/core/src/events/EventPriorityQueue.d.ts +202 -0
  121. package/dist/core/src/events/IdempotencyCache.d.ts +60 -0
  122. package/dist/core/src/events/index.d.ts +14 -0
  123. package/dist/core/src/events/observability/EventMetrics.d.ts +132 -0
  124. package/dist/core/src/events/observability/EventTracer.d.ts +68 -0
  125. package/dist/core/src/events/observability/EventTracing.d.ts +161 -0
  126. package/dist/core/src/events/observability/OTelEventMetrics.d.ts +240 -0
  127. package/dist/core/src/events/observability/ObservableHookManager.d.ts +108 -0
  128. package/dist/core/src/events/observability/index.d.ts +20 -0
  129. package/dist/core/src/events/observability/metrics-types.d.ts +16 -0
  130. package/dist/core/src/events/types.d.ts +75 -0
  131. package/dist/core/src/exceptions/AuthenticationException.d.ts +8 -0
  132. package/dist/core/src/exceptions/AuthorizationException.d.ts +8 -0
  133. package/dist/core/src/exceptions/CircularDependencyException.d.ts +9 -0
  134. package/dist/core/src/exceptions/GravitoException.d.ts +23 -0
  135. package/dist/core/src/exceptions/HttpException.d.ts +9 -0
  136. package/dist/core/src/exceptions/ModelNotFoundException.d.ts +10 -0
  137. package/dist/core/src/exceptions/ValidationException.d.ts +22 -0
  138. package/dist/core/src/exceptions/index.d.ts +7 -0
  139. package/dist/core/src/helpers/Arr.d.ts +19 -0
  140. package/dist/core/src/helpers/Str.d.ts +23 -0
  141. package/dist/core/src/helpers/data.d.ts +25 -0
  142. package/dist/core/src/helpers/errors.d.ts +34 -0
  143. package/dist/core/src/helpers/response.d.ts +41 -0
  144. package/dist/core/src/helpers.d.ts +338 -0
  145. package/dist/core/src/http/CookieJar.d.ts +51 -0
  146. package/dist/core/src/http/cookie.d.ts +29 -0
  147. package/dist/core/src/http/middleware/BodySizeLimit.d.ts +16 -0
  148. package/dist/core/src/http/middleware/Cors.d.ts +24 -0
  149. package/dist/core/src/http/middleware/Csrf.d.ts +23 -0
  150. package/dist/core/src/http/middleware/HeaderTokenGate.d.ts +28 -0
  151. package/dist/core/src/http/middleware/SecurityHeaders.d.ts +29 -0
  152. package/dist/core/src/http/middleware/ThrottleRequests.d.ts +18 -0
  153. package/dist/core/src/http/types.d.ts +355 -0
  154. package/dist/core/src/index.d.ts +76 -0
  155. package/dist/core/src/instrumentation/index.d.ts +35 -0
  156. package/dist/core/src/instrumentation/opentelemetry.d.ts +178 -0
  157. package/dist/core/src/instrumentation/types.d.ts +182 -0
  158. package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +316 -0
  159. package/dist/core/src/reliability/RetryPolicy.d.ts +217 -0
  160. package/dist/core/src/reliability/index.d.ts +6 -0
  161. package/dist/core/src/router/ControllerDispatcher.d.ts +12 -0
  162. package/dist/core/src/router/RequestValidator.d.ts +20 -0
  163. package/dist/core/src/runtime.d.ts +119 -0
  164. package/dist/core/src/security/Encrypter.d.ts +33 -0
  165. package/dist/core/src/security/Hasher.d.ts +29 -0
  166. package/dist/core/src/testing/HttpTester.d.ts +39 -0
  167. package/dist/core/src/testing/TestResponse.d.ts +78 -0
  168. package/dist/core/src/testing/index.d.ts +2 -0
  169. package/dist/core/src/types/events.d.ts +94 -0
  170. package/dist/echo/src/OrbitEcho.d.ts +115 -0
  171. package/dist/echo/src/dlq/DeadLetterQueue.d.ts +94 -0
  172. package/dist/echo/src/dlq/MemoryDeadLetterQueue.d.ts +36 -0
  173. package/dist/echo/src/dlq/index.d.ts +2 -0
  174. package/dist/echo/src/index.d.ts +64 -0
  175. package/dist/echo/src/middleware/RequestBufferMiddleware.d.ts +62 -0
  176. package/dist/echo/src/middleware/index.d.ts +8 -0
  177. package/dist/echo/src/observability/index.d.ts +3 -0
  178. package/dist/echo/src/observability/logging/ConsoleEchoLogger.d.ts +37 -0
  179. package/dist/echo/src/observability/logging/EchoLogger.d.ts +38 -0
  180. package/dist/echo/src/observability/logging/index.d.ts +2 -0
  181. package/dist/echo/src/observability/metrics/MetricsProvider.d.ts +69 -0
  182. package/dist/echo/src/observability/metrics/NoopMetricsProvider.d.ts +17 -0
  183. package/dist/echo/src/observability/metrics/PrometheusMetricsProvider.d.ts +39 -0
  184. package/dist/echo/src/observability/metrics/index.d.ts +3 -0
  185. package/dist/echo/src/observability/tracing/NoopTracer.d.ts +33 -0
  186. package/dist/echo/src/observability/tracing/Tracer.d.ts +75 -0
  187. package/dist/echo/src/observability/tracing/index.d.ts +2 -0
  188. package/dist/echo/src/providers/GenericProvider.d.ts +53 -0
  189. package/dist/echo/src/providers/GitHubProvider.d.ts +35 -0
  190. package/dist/echo/src/providers/LinearProvider.d.ts +27 -0
  191. package/dist/echo/src/providers/PaddleProvider.d.ts +31 -0
  192. package/dist/echo/src/providers/ShopifyProvider.d.ts +27 -0
  193. package/dist/echo/src/providers/SlackProvider.d.ts +27 -0
  194. package/dist/echo/src/providers/StripeProvider.d.ts +38 -0
  195. package/dist/echo/src/providers/TwilioProvider.d.ts +31 -0
  196. package/dist/echo/src/providers/base/BaseProvider.d.ts +87 -0
  197. package/dist/echo/src/providers/base/HeaderUtils.d.ts +34 -0
  198. package/dist/echo/src/providers/index.d.ts +14 -0
  199. package/dist/echo/src/receive/SignatureValidator.d.ts +67 -0
  200. package/dist/echo/src/receive/WebhookReceiver.d.ts +185 -0
  201. package/dist/echo/src/receive/index.d.ts +2 -0
  202. package/dist/echo/src/replay/WebhookReplayService.d.ts +35 -0
  203. package/dist/echo/src/replay/index.d.ts +1 -0
  204. package/dist/echo/src/resilience/CircuitBreaker.d.ts +117 -0
  205. package/dist/echo/src/resilience/index.d.ts +10 -0
  206. package/dist/echo/src/rotation/KeyRotationManager.d.ts +127 -0
  207. package/dist/echo/src/rotation/index.d.ts +10 -0
  208. package/dist/echo/src/send/WebhookDispatcher.d.ts +198 -0
  209. package/dist/echo/src/send/index.d.ts +1 -0
  210. package/dist/echo/src/storage/MemoryWebhookStore.d.ts +14 -0
  211. package/dist/echo/src/storage/WebhookStore.d.ts +236 -0
  212. package/dist/echo/src/storage/index.d.ts +2 -0
  213. package/dist/echo/src/types.d.ts +756 -0
  214. package/dist/index.js +1332 -190
  215. package/dist/index.js.map +28 -10
  216. package/dist/photon/src/index.d.ts +84 -0
  217. package/dist/photon/src/middleware/binary.d.ts +31 -0
  218. package/dist/photon/src/middleware/htmx.d.ts +39 -0
  219. package/dist/photon/src/middleware/ratelimit.d.ts +157 -0
  220. package/dist/photon/src/openapi.d.ts +19 -0
  221. package/package.json +7 -5
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @fileoverview Key Rotation Manager
3
+ *
4
+ * Manages the lifecycle of webhook provider secrets, including multi-version
5
+ * support, automatic cleanup, and grace periods for smooth transitions.
6
+ *
7
+ * @module @gravito/echo/rotation
8
+ * @since v1.2
9
+ */
10
+ import type { KeyRotationConfig, ProviderKeyEntry } from '../types';
11
+ /**
12
+ * KeyRotationManager orchestrates the lifecycle of webhook provider secrets.
13
+ *
14
+ * It provides a central hub for managing multiple concurrent versions of signing
15
+ * secrets, enabling zero-downtime rotation. By maintaining a set of "active"
16
+ * keys (including those in a grace period), it ensures that webhooks signed
17
+ * with either an old or new secret are successfully verified during transition.
18
+ *
19
+ * Key features:
20
+ * - Multi-version secret management.
21
+ * - Automatic background cleanup of expired keys.
22
+ * - Grace period support for smooth cut-overs.
23
+ * - Promotion of new primary keys.
24
+ *
25
+ * @example Managing zero-downtime rotation
26
+ * ```typescript
27
+ * const manager = new KeyRotationManager({
28
+ * gracePeriod: 86400000, // 24 hours
29
+ * autoCleanup: true,
30
+ * });
31
+ *
32
+ * // Register initial keys
33
+ * manager.registerKeys('stripe', [
34
+ * {
35
+ * key: 'whsec_primary',
36
+ * version: 'v2',
37
+ * isPrimary: true,
38
+ * activeFrom: new Date(),
39
+ * }
40
+ * ]);
41
+ *
42
+ * // Rotate to a new secret
43
+ * await manager.rotatePrimaryKey('stripe', {
44
+ * key: 'whsec_new_secret',
45
+ * version: 'v3',
46
+ * activeFrom: new Date(),
47
+ * });
48
+ * ```
49
+ *
50
+ * @public
51
+ */
52
+ export declare class KeyRotationManager {
53
+ private providerKeys;
54
+ private cleanupTimer?;
55
+ private config;
56
+ /**
57
+ * Constructs a new KeyRotationManager with the specified policy.
58
+ *
59
+ * @param config - Configuration for auto-cleanup, grace periods, and rotation hooks.
60
+ */
61
+ constructor(config?: KeyRotationConfig);
62
+ /**
63
+ * Registers a collection of keys for a specific provider.
64
+ *
65
+ * Validation ensures that exactly one primary key is specified for the provider.
66
+ *
67
+ * @param providerName - Canonical name of the provider instance.
68
+ * @param keys - Array of valid key entries with metadata.
69
+ * @throws {Error} If no primary key is provided or if multiple primary keys are detected.
70
+ */
71
+ registerKeys(providerName: string, keys: ProviderKeyEntry[]): void;
72
+ /**
73
+ * Retrieves all currently valid keys for a provider to attempt verification.
74
+ *
75
+ * A key is considered active if the current time is after its `activeFrom` date
76
+ * and before its `expiresAt` date (if defined).
77
+ *
78
+ * @param providerName - Canonical name of the provider instance.
79
+ * @returns An array of currently active key entries.
80
+ */
81
+ getActiveKeys(providerName: string): ProviderKeyEntry[];
82
+ /**
83
+ * Retrieves the current primary key used for signature generation.
84
+ *
85
+ * @param providerName - Canonical name of the provider instance.
86
+ * @returns The primary key entry, or null if no active primary key exists.
87
+ */
88
+ getPrimaryKey(providerName: string): ProviderKeyEntry | null;
89
+ /**
90
+ * Promotes a new primary key for the provider and retires the old one.
91
+ *
92
+ * The previous primary key is automatically assigned an expiration date based on
93
+ * the configured `gracePeriod`, allowing it to remain valid for incoming requests
94
+ * that were signed before the rotation propagated.
95
+ *
96
+ * @param providerName - Canonical name of the provider instance.
97
+ * @param newKey - Metadata and secret for the new primary key.
98
+ */
99
+ rotatePrimaryKey(providerName: string, newKey: Omit<ProviderKeyEntry, 'isPrimary'>): Promise<void>;
100
+ /**
101
+ * Manually triggers a purge of all expired keys across all providers.
102
+ *
103
+ * @returns The total number of keys removed during this cycle.
104
+ */
105
+ cleanupExpiredKeys(): number;
106
+ /**
107
+ * Initializes the background timer for periodic key purging.
108
+ */
109
+ private startAutoCleanup;
110
+ /**
111
+ * Stops the auto-cleanup background process.
112
+ */
113
+ destroy(): void;
114
+ /**
115
+ * Provides a read-only snapshot of all keys across all providers.
116
+ *
117
+ * @returns A map of provider names to their complete key history.
118
+ */
119
+ getAllProviderKeys(): Map<string, ProviderKeyEntry[]>;
120
+ /**
121
+ * Checks if a specific provider has any keys registered in the manager.
122
+ *
123
+ * @param providerName - Canonical name of the provider instance.
124
+ * @returns True if the provider is tracked.
125
+ */
126
+ hasProvider(providerName: string): boolean;
127
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Echo Key Rotation
3
+ *
4
+ * 提供密鑰輪換功能
5
+ *
6
+ * @module @gravito/echo/rotation
7
+ * @since v1.2
8
+ */
9
+ export type { KeyRotationConfig, ProviderKeyEntry } from '../types';
10
+ export { KeyRotationManager } from './KeyRotationManager';
@@ -0,0 +1,198 @@
1
+ /**
2
+ * @fileoverview Webhook Dispatcher
3
+ *
4
+ * Reliably sends webhooks to external services with retry support.
5
+ *
6
+ * @module @gravito/echo/send
7
+ */
8
+ import type { DeadLetterQueue } from '../dlq/DeadLetterQueue';
9
+ import type { EchoLogger } from '../observability/logging';
10
+ import { type MetricsProvider } from '../observability/metrics';
11
+ import { type Tracer } from '../observability/tracing';
12
+ import type { BatchDispatchOptions, BatchDispatchResult, CircuitBreakerMetrics, WebhookDeliveryResult, WebhookDispatcherConfig, WebhookPayload } from '../types';
13
+ /**
14
+ * WebhookDispatcher manages the secure and reliable delivery of events to external targets.
15
+ *
16
+ * It provides a robust engine for sending signed webhook payloads to third-party
17
+ * consumers, incorporating enterprise-grade reliability features such as:
18
+ * - Exponential backoff retries for transient network/server errors.
19
+ * - Per-host Circuit Breaking to prevent cascading failures.
20
+ * - Dead Letter Queue (DLQ) integration for capturing permanently failed events.
21
+ * - HMAC-SHA256 payload signing for authenticity.
22
+ *
23
+ * @example Dispatching a signed event
24
+ * ```typescript
25
+ * const dispatcher = new WebhookDispatcher({
26
+ * secret: 'app-outbound-secret',
27
+ * retry: { maxAttempts: 5 }
28
+ * });
29
+ *
30
+ * const result = await dispatcher.dispatch({
31
+ * url: 'https://consumer.com/webhooks',
32
+ * event: 'order.shipped',
33
+ * data: { orderId: 'ORD-123' }
34
+ * });
35
+ *
36
+ * if (result.success) {
37
+ * console.log('Webhook delivered successfully');
38
+ * }
39
+ * ```
40
+ *
41
+ * @public
42
+ */
43
+ export declare class WebhookDispatcher {
44
+ private secret;
45
+ private retryConfig;
46
+ private timeout;
47
+ private userAgent;
48
+ private dlq?;
49
+ private metrics;
50
+ private tracer;
51
+ private logger?;
52
+ private circuitBreakers;
53
+ private circuitBreakerConfig?;
54
+ /**
55
+ * Initializes the dispatcher with security and reliability policies.
56
+ *
57
+ * @param config - The configuration for payload signing, retry logic, and timeouts.
58
+ */
59
+ constructor(config: WebhookDispatcherConfig);
60
+ /**
61
+ * Attaches a Dead Letter Queue for capturing events that fail all delivery attempts.
62
+ *
63
+ * @param dlq - Implementation of the DeadLetterQueue interface.
64
+ * @returns The current instance for method chaining.
65
+ */
66
+ setDeadLetterQueue(dlq: DeadLetterQueue): this;
67
+ /**
68
+ * Configures the metrics provider for delivery and failure tracking.
69
+ *
70
+ * @param metrics - Implementation of the MetricsProvider interface.
71
+ * @returns The current instance for method chaining.
72
+ */
73
+ setMetrics(metrics: MetricsProvider): this;
74
+ /**
75
+ * Configures the distributed tracer for end-to-end request visibility.
76
+ *
77
+ * @param tracer - Implementation of the Tracer interface.
78
+ * @returns The current instance for method chaining.
79
+ */
80
+ setTracer(tracer: Tracer): this;
81
+ /**
82
+ * Configures the logger for diagnostic and delivery audit logging.
83
+ *
84
+ * @param logger - Implementation of the EchoLogger interface.
85
+ * @returns The current instance for method chaining.
86
+ */
87
+ setLogger(logger: EchoLogger): this;
88
+ /**
89
+ * Resolves or creates a dedicated circuit breaker instance for a specific host.
90
+ *
91
+ * Using per-host isolation ensures that an outage at one consumer does not
92
+ * block or slow down deliveries to other healthy consumers.
93
+ *
94
+ * @param url - Destination URL used to derive the target host.
95
+ * @returns The active circuit breaker instance, or undefined if disabled.
96
+ */
97
+ private getCircuitBreaker;
98
+ /**
99
+ * Retrieves the current health metrics for a specific target's circuit breaker.
100
+ *
101
+ * @param url - The target URL whose host metrics are requested.
102
+ * @returns Current metrics or null if circuit breaking is not active for the host.
103
+ */
104
+ getCircuitBreakerMetrics(url: string): CircuitBreakerMetrics | null;
105
+ /**
106
+ * Manually resets a tripped circuit breaker to its CLOSED state for a specific target.
107
+ *
108
+ * @param url - The target URL whose host circuit should be reset.
109
+ */
110
+ resetCircuitBreaker(url: string): void;
111
+ /**
112
+ * Executes the end-to-end delivery of a signed webhook event.
113
+ *
114
+ * This method performs the following:
115
+ * 1. Wraps the payload with an authenticity signature (HMAC-SHA256).
116
+ * 2. Checks the state of the target's circuit breaker.
117
+ * 3. Executes the HTTP POST request.
118
+ * 4. Manages the retry lifecycle if errors occur.
119
+ * 5. Enqueues failed events to the DLQ if configured.
120
+ *
121
+ * @param payload - Data and destination parameters for the dispatch.
122
+ * @returns Final delivery outcome including success status and attempt count.
123
+ * @throws {Error} If critical internal operations (like signing) fail.
124
+ */
125
+ dispatch<T = unknown>(payload: WebhookPayload<T>): Promise<WebhookDeliveryResult>;
126
+ /**
127
+ * Internal orchestration for the delivery retry loop.
128
+ *
129
+ * @param payload - The webhook payload.
130
+ * @returns Final delivery result after all retry attempts.
131
+ */
132
+ private dispatchInternal;
133
+ /**
134
+ * Dispatches a batch of webhooks concurrently using an optimized worker pool.
135
+ *
136
+ * This method balances high throughput with source/target resource constraints
137
+ * by allowing you to tune concurrency and error propagation policies.
138
+ *
139
+ * @param payloads - Collection of payloads to deliver.
140
+ * @param options - Tuning parameters for concurrency and failure handling.
141
+ * @returns A summary result of all dispatch attempts in the batch.
142
+ *
143
+ * @example Batch dispatch with concurrency control
144
+ * ```typescript
145
+ * const results = await dispatcher.dispatchBatch(payloads, {
146
+ * concurrency: 10,
147
+ * stopOnFirstFailure: false
148
+ * });
149
+ * console.log(`Batch complete. Succeeded: ${results.succeeded}, Failed: ${results.failed}`);
150
+ * ```
151
+ */
152
+ dispatchBatch<T = unknown>(payloads: WebhookPayload<T>[], options?: BatchDispatchOptions): Promise<BatchDispatchResult>;
153
+ /**
154
+ * Re-attempts the delivery of a previously failed event from the Dead Letter Queue.
155
+ *
156
+ * If the delivery succeeds, the event is automatically removed from the DLQ.
157
+ *
158
+ * @param id - The unique identifier of the event in the DLQ.
159
+ * @returns Result of the retry attempt, or null if the event ID is invalid.
160
+ */
161
+ retryFromDlq(id: string): Promise<WebhookDeliveryResult | null>;
162
+ /**
163
+ * Executes a single delivery attempt including signing and circuit breaker check.
164
+ *
165
+ * @param payload - The webhook payload.
166
+ * @param attempt - The current attempt number.
167
+ * @returns Detailed result of the single attempt.
168
+ */
169
+ private attemptDelivery;
170
+ /**
171
+ * Internal logic to decide if an attempt should be retried.
172
+ *
173
+ * @param result - The delivery result to evaluate.
174
+ * @returns True if retry is eligible.
175
+ */
176
+ private shouldRetry;
177
+ /**
178
+ * Calculates the exponential backoff delay for the next attempt.
179
+ *
180
+ * @param attempt - The current attempt number.
181
+ * @returns Delay in milliseconds.
182
+ */
183
+ private calculateDelay;
184
+ /**
185
+ * Standardized categorization of delivery errors for metrics.
186
+ *
187
+ * @param result - The delivery result to categorize.
188
+ * @returns Category string.
189
+ */
190
+ private categorizeError;
191
+ /**
192
+ * Utility for asynchronous sleep.
193
+ *
194
+ * @param ms - Duration to sleep in ms.
195
+ * @returns Promise that resolves after delay.
196
+ */
197
+ private sleep;
198
+ }
@@ -0,0 +1 @@
1
+ export * from './WebhookDispatcher';
@@ -0,0 +1,14 @@
1
+ import type { DeliveryAttempt, EventQueryFilter, IncomingWebhookRecord, OutgoingWebhookRecord, WebhookRecord, WebhookStore } from './WebhookStore';
2
+ /**
3
+ * 記憶體儲存實作(開發/測試用)
4
+ */
5
+ export declare class MemoryWebhookStore implements WebhookStore {
6
+ private events;
7
+ saveIncomingEvent(event: IncomingWebhookRecord): Promise<string>;
8
+ saveOutgoingEvent(event: OutgoingWebhookRecord): Promise<string>;
9
+ updateDeliveryAttempt(id: string, attempt: DeliveryAttempt): Promise<void>;
10
+ getEvent(id: string): Promise<WebhookRecord | null>;
11
+ queryEvents(filter: EventQueryFilter): Promise<WebhookRecord[]>;
12
+ markProcessed(id: string): Promise<void>;
13
+ markFailed(id: string, error: string): Promise<void>;
14
+ }
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Interface for the Webhook Event Storage layer.
3
+ *
4
+ * Implementations of this interface are responsible for providing durable
5
+ * persistence for both incoming and outgoing webhook events. This layer is
6
+ * critical for:
7
+ * - Security Auditing: Maintaining a verifiable trail of all received events.
8
+ * - Reliability: Enabling re-dispatch of failed outgoing webhooks.
9
+ * - Idempotency: Checking for duplicate events to prevent double-processing.
10
+ * - Observability: Providing data for historical analysis and reporting.
11
+ *
12
+ * @example Implementing a custom database store
13
+ * ```typescript
14
+ * class MyStore implements WebhookStore {
15
+ * async saveIncomingEvent(event: IncomingWebhookRecord) {
16
+ * const id = await db.insert('webhooks').values(event).returning('id');
17
+ * return id;
18
+ * }
19
+ * // ... implement other methods
20
+ * }
21
+ * ```
22
+ *
23
+ * @public
24
+ */
25
+ export interface WebhookStore {
26
+ /**
27
+ * Persists a record of a successfully verified incoming webhook.
28
+ *
29
+ * @param event - Metadata and payload of the verified incoming event.
30
+ * @returns A promise resolving to a unique identifier for the stored event.
31
+ */
32
+ saveIncomingEvent(event: IncomingWebhookRecord): Promise<string>;
33
+ /**
34
+ * Persists a record of a webhook that is being dispatched to a consumer.
35
+ *
36
+ * @param event - Metadata and payload of the outgoing event intent.
37
+ * @returns A promise resolving to a unique identifier for the stored record.
38
+ */
39
+ saveOutgoingEvent(event: OutgoingWebhookRecord): Promise<string>;
40
+ /**
41
+ * Updates or appends a delivery attempt result for an outgoing webhook.
42
+ *
43
+ * @param id - The unique ID of the original outgoing event record.
44
+ * @param attempt - Detailed outcome of the specific delivery attempt.
45
+ */
46
+ updateDeliveryAttempt(id: string, attempt: DeliveryAttempt): Promise<void>;
47
+ /**
48
+ * Retrieves a specific webhook event record by its unique identifier.
49
+ *
50
+ * @param id - The unique ID assigned by the storage layer.
51
+ * @returns The event record if found, otherwise null.
52
+ */
53
+ getEvent(id: string): Promise<WebhookRecord | null>;
54
+ /**
55
+ * Performs a filtered search across persisted webhook events.
56
+ *
57
+ * @param filter - Criteria for filtering events (e.g., provider, date range).
58
+ * @returns A collection of matching webhook records.
59
+ */
60
+ queryEvents(filter: EventQueryFilter): Promise<WebhookRecord[]>;
61
+ /**
62
+ * Transitions an incoming event status to 'processed' after successful handling.
63
+ *
64
+ * @param id - The unique ID of the incoming event.
65
+ */
66
+ markProcessed(id: string): Promise<void>;
67
+ /**
68
+ * Records a processing failure for an incoming event with diagnostic details.
69
+ *
70
+ * @param id - The unique ID of the incoming event.
71
+ * @param error - A descriptive message detailing why processing failed.
72
+ */
73
+ markFailed(id: string, error: string): Promise<void>;
74
+ }
75
+ /**
76
+ * Persisted representation of an authenticated incoming webhook event.
77
+ *
78
+ * @public
79
+ */
80
+ export interface IncomingWebhookRecord {
81
+ /**
82
+ * Unique identifier assigned by the storage layer.
83
+ */
84
+ id?: string;
85
+ /**
86
+ * The name of the provider instance that verified the event.
87
+ */
88
+ provider: string;
89
+ /**
90
+ * The semantic type of the event (e.g., 'invoice.paid').
91
+ */
92
+ eventType: string;
93
+ /**
94
+ * The parsed JSON data extracted from the verified webhook body.
95
+ */
96
+ payload: unknown;
97
+ /**
98
+ * Filtered set of HTTP headers received with the original request.
99
+ */
100
+ headers: Record<string, string | undefined>;
101
+ /**
102
+ * The exact unparsed request body, preserved for audit or re-verification.
103
+ */
104
+ rawBody: string;
105
+ /**
106
+ * The timestamp when the event was first recorded by the system.
107
+ */
108
+ receivedAt: Date;
109
+ /**
110
+ * The current stage in the event's processing lifecycle.
111
+ */
112
+ status: 'pending' | 'processed' | 'failed';
113
+ /**
114
+ * Diagnostic details provided if the status is 'failed'.
115
+ */
116
+ processingError?: string;
117
+ /**
118
+ * Discriminator field used for heterogeneous storage collections.
119
+ */
120
+ direction?: 'incoming';
121
+ }
122
+ /**
123
+ * Persisted representation of an outgoing webhook dispatch and its delivery status.
124
+ *
125
+ * @public
126
+ */
127
+ export interface OutgoingWebhookRecord {
128
+ /**
129
+ * Unique identifier assigned by the storage layer.
130
+ */
131
+ id?: string;
132
+ /**
133
+ * The destination URL where the webhook is being delivered.
134
+ */
135
+ url: string;
136
+ /**
137
+ * The semantic name of the event being dispatched.
138
+ */
139
+ event: string;
140
+ /**
141
+ * The JSON payload sent to the destination server.
142
+ */
143
+ payload: unknown;
144
+ /**
145
+ * The timestamp when the dispatch operation was first initiated.
146
+ */
147
+ createdAt: Date;
148
+ /**
149
+ * The overall delivery status based on attempt history.
150
+ */
151
+ status: 'pending' | 'delivered' | 'failed';
152
+ /**
153
+ * Chronological history of all delivery attempts for this dispatch.
154
+ */
155
+ attempts: DeliveryAttempt[];
156
+ /**
157
+ * Discriminator field used for heterogeneous storage collections.
158
+ */
159
+ direction?: 'outgoing';
160
+ }
161
+ /**
162
+ * Union type representing any type of persisted webhook transaction.
163
+ *
164
+ * @public
165
+ */
166
+ export type WebhookRecord = IncomingWebhookRecord | OutgoingWebhookRecord;
167
+ /**
168
+ * Detailed telemetry for a single HTTP delivery attempt to an external consumer.
169
+ *
170
+ * @public
171
+ */
172
+ export interface DeliveryAttempt {
173
+ /**
174
+ * The sequence number of this attempt (starts at 1).
175
+ */
176
+ attemptNumber: number;
177
+ /**
178
+ * The exact timestamp when the network request was initiated.
179
+ */
180
+ timestamp: Date;
181
+ /**
182
+ * The HTTP status code returned by the destination server (if reached).
183
+ */
184
+ statusCode?: number;
185
+ /**
186
+ * The raw response body returned by the target server for diagnostics.
187
+ */
188
+ responseBody?: string;
189
+ /**
190
+ * The error message if the attempt failed at the network or protocol level.
191
+ */
192
+ error?: string;
193
+ /**
194
+ * The total duration of the HTTP request in milliseconds.
195
+ */
196
+ duration: number;
197
+ }
198
+ /**
199
+ * Parameters for querying and filtering the webhook event audit log.
200
+ *
201
+ * @public
202
+ */
203
+ export interface EventQueryFilter {
204
+ /**
205
+ * Limit search to either 'incoming' or 'outgoing' events.
206
+ */
207
+ direction?: 'incoming' | 'outgoing';
208
+ /**
209
+ * Filter by the name of the provider instance.
210
+ */
211
+ provider?: string;
212
+ /**
213
+ * Filter by the semantic event type.
214
+ */
215
+ eventType?: string;
216
+ /**
217
+ * Filter by current processing or delivery status.
218
+ */
219
+ status?: string;
220
+ /**
221
+ * Start boundary for the search time range.
222
+ */
223
+ from?: Date;
224
+ /**
225
+ * End boundary for the search time range.
226
+ */
227
+ to?: Date;
228
+ /**
229
+ * Maximum number of records to return for this query.
230
+ */
231
+ limit?: number;
232
+ /**
233
+ * Number of records to skip for paginated results.
234
+ */
235
+ offset?: number;
236
+ }
@@ -0,0 +1,2 @@
1
+ export * from './MemoryWebhookStore';
2
+ export * from './WebhookStore';