@gravito/echo 2.0.0 → 3.0.1
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/dist/core/src/Application.d.ts +189 -0
- package/dist/core/src/ConfigManager.d.ts +26 -0
- package/dist/core/src/Container.d.ts +44 -0
- package/dist/core/src/ErrorHandler.d.ts +63 -0
- package/dist/core/src/Event.d.ts +5 -0
- package/dist/core/src/EventManager.d.ts +123 -0
- package/dist/core/src/GlobalErrorHandlers.d.ts +47 -0
- package/dist/core/src/GravitoServer.d.ts +28 -0
- package/dist/core/src/HookManager.d.ts +82 -0
- package/dist/core/src/Listener.d.ts +4 -0
- package/dist/core/src/Logger.d.ts +20 -0
- package/dist/core/src/PlanetCore.d.ts +244 -0
- package/dist/core/src/Route.d.ts +36 -0
- package/dist/core/src/Router.d.ts +250 -0
- package/dist/core/src/ServiceProvider.d.ts +150 -0
- package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +26 -0
- package/dist/core/src/adapters/PhotonAdapter.d.ts +170 -0
- package/dist/core/src/adapters/bun/BunContext.d.ts +45 -0
- package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +30 -0
- package/dist/core/src/adapters/bun/BunRequest.d.ts +31 -0
- package/dist/core/src/adapters/bun/RadixNode.d.ts +19 -0
- package/dist/core/src/adapters/bun/RadixRouter.d.ts +31 -0
- package/dist/core/src/adapters/bun/types.d.ts +20 -0
- package/dist/core/src/adapters/photon-types.d.ts +73 -0
- package/dist/core/src/adapters/types.d.ts +196 -0
- package/dist/core/src/engine/AOTRouter.d.ts +134 -0
- package/dist/core/src/engine/FastContext.d.ts +98 -0
- package/dist/core/src/engine/Gravito.d.ts +137 -0
- package/dist/core/src/engine/MinimalContext.d.ts +77 -0
- package/dist/core/src/engine/analyzer.d.ts +27 -0
- package/dist/core/src/engine/constants.d.ts +23 -0
- package/dist/core/src/engine/index.d.ts +26 -0
- package/dist/core/src/engine/path.d.ts +26 -0
- package/dist/core/src/engine/pool.d.ts +83 -0
- package/dist/core/src/engine/types.d.ts +138 -0
- package/dist/core/src/exceptions/AuthenticationException.d.ts +8 -0
- package/dist/core/src/exceptions/AuthorizationException.d.ts +8 -0
- package/dist/core/src/exceptions/GravitoException.d.ts +23 -0
- package/dist/core/src/exceptions/HttpException.d.ts +9 -0
- package/dist/core/src/exceptions/ModelNotFoundException.d.ts +10 -0
- package/dist/core/src/exceptions/ValidationException.d.ts +22 -0
- package/dist/core/src/exceptions/index.d.ts +6 -0
- package/dist/core/src/helpers/Arr.d.ts +19 -0
- package/dist/core/src/helpers/Str.d.ts +23 -0
- package/dist/core/src/helpers/data.d.ts +25 -0
- package/dist/core/src/helpers/errors.d.ts +34 -0
- package/dist/core/src/helpers/response.d.ts +41 -0
- package/dist/core/src/helpers.d.ts +338 -0
- package/dist/core/src/http/CookieJar.d.ts +51 -0
- package/dist/core/src/http/middleware/BodySizeLimit.d.ts +16 -0
- package/dist/core/src/http/middleware/Cors.d.ts +24 -0
- package/dist/core/src/http/middleware/Csrf.d.ts +23 -0
- package/dist/core/src/http/middleware/HeaderTokenGate.d.ts +28 -0
- package/dist/core/src/http/middleware/SecurityHeaders.d.ts +29 -0
- package/dist/core/src/http/middleware/ThrottleRequests.d.ts +18 -0
- package/dist/core/src/http/types.d.ts +334 -0
- package/dist/core/src/index.d.ts +66 -0
- package/dist/core/src/runtime.d.ts +119 -0
- package/dist/core/src/security/Encrypter.d.ts +33 -0
- package/dist/core/src/security/Hasher.d.ts +29 -0
- package/dist/core/src/testing/HttpTester.d.ts +39 -0
- package/dist/core/src/testing/TestResponse.d.ts +78 -0
- package/dist/core/src/testing/index.d.ts +2 -0
- package/dist/core/src/types/events.d.ts +94 -0
- package/dist/echo/src/OrbitEcho.d.ts +60 -0
- package/dist/echo/src/index.d.ts +48 -0
- package/dist/echo/src/providers/GenericProvider.d.ts +34 -0
- package/dist/echo/src/providers/GitHubProvider.d.ts +26 -0
- package/dist/echo/src/providers/StripeProvider.d.ts +30 -0
- package/dist/echo/src/providers/index.d.ts +3 -0
- package/dist/echo/src/receive/SignatureValidator.d.ts +34 -0
- package/dist/echo/src/receive/WebhookReceiver.d.ts +67 -0
- package/dist/echo/src/receive/index.d.ts +2 -0
- package/dist/echo/src/send/WebhookDispatcher.d.ts +54 -0
- package/dist/echo/src/send/index.d.ts +1 -0
- package/dist/echo/src/types.d.ts +164 -0
- package/dist/index.js +6 -2
- package/dist/index.js.map +3 -3
- package/dist/photon/src/index.d.ts +20 -0
- package/dist/photon/src/middleware/binary.d.ts +34 -0
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event system type definitions.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Listener interface.
|
|
6
|
+
*
|
|
7
|
+
* All event listeners must implement this interface.
|
|
8
|
+
*/
|
|
9
|
+
export interface Listener<TEvent extends Event = Event> {
|
|
10
|
+
/**
|
|
11
|
+
* Handle an event.
|
|
12
|
+
* @param event - Event instance
|
|
13
|
+
*/
|
|
14
|
+
handle(event: TEvent): Promise<void> | void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Marker interface for listeners that should be queued.
|
|
18
|
+
*
|
|
19
|
+
* Listeners implementing this interface can be dispatched asynchronously via a queue.
|
|
20
|
+
*/
|
|
21
|
+
export interface ShouldQueue {
|
|
22
|
+
/**
|
|
23
|
+
* Queue name (optional).
|
|
24
|
+
*/
|
|
25
|
+
queue?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Connection name (optional).
|
|
28
|
+
*/
|
|
29
|
+
connection?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Delay before execution (seconds).
|
|
32
|
+
*/
|
|
33
|
+
delay?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Marker interface for events that should be broadcast.
|
|
37
|
+
*
|
|
38
|
+
* Events implementing this interface can be automatically broadcast to clients.
|
|
39
|
+
*/
|
|
40
|
+
export interface ShouldBroadcast {
|
|
41
|
+
/**
|
|
42
|
+
* Define the broadcast channel.
|
|
43
|
+
* @returns Channel name or channel object
|
|
44
|
+
*/
|
|
45
|
+
broadcastOn(): string | Channel;
|
|
46
|
+
/**
|
|
47
|
+
* Define broadcast payload (optional).
|
|
48
|
+
* If omitted, public event properties will be used.
|
|
49
|
+
* @returns Broadcast payload
|
|
50
|
+
*/
|
|
51
|
+
broadcastWith?(): Record<string, unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* Define the broadcast event name (optional).
|
|
54
|
+
* If omitted, the event class name will be used.
|
|
55
|
+
* @returns Event name
|
|
56
|
+
*/
|
|
57
|
+
broadcastAs?(): string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Channel interface.
|
|
61
|
+
*/
|
|
62
|
+
export interface Channel {
|
|
63
|
+
/**
|
|
64
|
+
* Channel name.
|
|
65
|
+
*/
|
|
66
|
+
name: string;
|
|
67
|
+
/**
|
|
68
|
+
* Channel type.
|
|
69
|
+
*/
|
|
70
|
+
type: 'public' | 'private' | 'presence';
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Base event class.
|
|
74
|
+
*
|
|
75
|
+
* All events should extend this class.
|
|
76
|
+
*/
|
|
77
|
+
export declare abstract class Event {
|
|
78
|
+
/**
|
|
79
|
+
* Whether this event should be broadcast.
|
|
80
|
+
*/
|
|
81
|
+
shouldBroadcast(): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Get broadcast channel.
|
|
84
|
+
*/
|
|
85
|
+
getBroadcastChannel(): string | Channel | null;
|
|
86
|
+
/**
|
|
87
|
+
* Get broadcast payload.
|
|
88
|
+
*/
|
|
89
|
+
getBroadcastData(): Record<string, unknown>;
|
|
90
|
+
/**
|
|
91
|
+
* Get broadcast event name.
|
|
92
|
+
*/
|
|
93
|
+
getBroadcastEventName(): string;
|
|
94
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
2
|
+
import { WebhookReceiver } from './receive/WebhookReceiver';
|
|
3
|
+
import { WebhookDispatcher } from './send/WebhookDispatcher';
|
|
4
|
+
import type { EchoConfig } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* OrbitEcho is the official webhook orchestration module for Gravito.
|
|
7
|
+
*
|
|
8
|
+
* It provides a secure way to receive incoming webhooks (e.g., from Stripe, GitHub)
|
|
9
|
+
* and a reliable way to dispatch outgoing webhooks to third-party services.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const echo = new OrbitEcho({
|
|
14
|
+
* providers: {
|
|
15
|
+
* stripe: { name: 'stripe', secret: 'whsec_...' }
|
|
16
|
+
* }
|
|
17
|
+
* });
|
|
18
|
+
* core.addOrbit(echo);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
* @since 3.0.0
|
|
23
|
+
*/
|
|
24
|
+
export declare class OrbitEcho implements GravitoOrbit {
|
|
25
|
+
private receiver;
|
|
26
|
+
private dispatcher?;
|
|
27
|
+
private echoConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Create a new OrbitEcho instance.
|
|
30
|
+
*
|
|
31
|
+
* @param config - The configuration object for providers and dispatcher.
|
|
32
|
+
*/
|
|
33
|
+
constructor(config?: EchoConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Install into PlanetCore
|
|
36
|
+
*
|
|
37
|
+
* Registers the OrbitEcho instance and its components into the service container.
|
|
38
|
+
*
|
|
39
|
+
* @param core - The PlanetCore instance.
|
|
40
|
+
*/
|
|
41
|
+
install(core: PlanetCore): void;
|
|
42
|
+
/**
|
|
43
|
+
* Get webhook receiver
|
|
44
|
+
*/
|
|
45
|
+
getReceiver(): WebhookReceiver;
|
|
46
|
+
/**
|
|
47
|
+
* Get webhook dispatcher
|
|
48
|
+
*/
|
|
49
|
+
getDispatcher(): WebhookDispatcher | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Get configuration
|
|
52
|
+
*/
|
|
53
|
+
getConfig(): EchoConfig;
|
|
54
|
+
}
|
|
55
|
+
declare module '@gravito/core' {
|
|
56
|
+
interface GravitoVariables {
|
|
57
|
+
/** Webhook receiver and dispatcher */
|
|
58
|
+
echo?: OrbitEcho;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview @gravito/echo - Enterprise Webhook Module
|
|
3
|
+
*
|
|
4
|
+
* Secure webhook receiving and reliable webhook sending for Gravito.
|
|
5
|
+
*
|
|
6
|
+
* @example Receiving webhooks
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { OrbitEcho, WebhookReceiver } from '@gravito/echo'
|
|
9
|
+
*
|
|
10
|
+
* const core = new PlanetCore()
|
|
11
|
+
*
|
|
12
|
+
* core.install(new OrbitEcho({
|
|
13
|
+
* providers: {
|
|
14
|
+
* stripe: { name: 'stripe', secret: process.env.STRIPE_WEBHOOK_SECRET! }
|
|
15
|
+
* }
|
|
16
|
+
* }))
|
|
17
|
+
*
|
|
18
|
+
* const receiver = core.container.make<WebhookReceiver>('echo.receiver')
|
|
19
|
+
* receiver.on('stripe', 'payment_intent.succeeded', async (event) => {
|
|
20
|
+
* console.log('Payment:', event.payload)
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example Sending webhooks
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { WebhookDispatcher } from '@gravito/echo'
|
|
27
|
+
*
|
|
28
|
+
* const dispatcher = new WebhookDispatcher({
|
|
29
|
+
* secret: 'my-secret'
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* await dispatcher.dispatch({
|
|
33
|
+
* url: 'https://example.com/webhook',
|
|
34
|
+
* event: 'order.created',
|
|
35
|
+
* data: { orderId: 123 }
|
|
36
|
+
* })
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @module @gravito/echo
|
|
40
|
+
*/
|
|
41
|
+
export { OrbitEcho } from './OrbitEcho';
|
|
42
|
+
export { GenericProvider } from './providers/GenericProvider';
|
|
43
|
+
export { GitHubProvider } from './providers/GitHubProvider';
|
|
44
|
+
export { StripeProvider } from './providers/StripeProvider';
|
|
45
|
+
export { computeHmacSha1, computeHmacSha256, parseStripeSignature, timingSafeEqual, validateTimestamp, } from './receive/SignatureValidator';
|
|
46
|
+
export { WebhookReceiver } from './receive/WebhookReceiver';
|
|
47
|
+
export { WebhookDispatcher } from './send/WebhookDispatcher';
|
|
48
|
+
export type { EchoConfig, RetryConfig, WebhookDeliveryResult, WebhookDispatcherConfig, WebhookEvent, WebhookHandler, WebhookPayload, WebhookProvider, WebhookProviderConfig, WebhookVerificationResult, } from './types';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Generic webhook provider
|
|
3
|
+
*
|
|
4
|
+
* Simple HMAC-SHA256 signature verification.
|
|
5
|
+
*
|
|
6
|
+
* @module @gravito/echo/providers
|
|
7
|
+
*/
|
|
8
|
+
import type { WebhookProvider, WebhookVerificationResult } from '../types';
|
|
9
|
+
/**
|
|
10
|
+
* Generic webhook provider using HMAC-SHA256
|
|
11
|
+
*
|
|
12
|
+
* Expected headers:
|
|
13
|
+
* - X-Webhook-Signature: HMAC-SHA256 hex signature
|
|
14
|
+
* - X-Webhook-Timestamp: Unix timestamp (optional)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const provider = new GenericProvider()
|
|
19
|
+
* const result = await provider.verify(body, headers, secret)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class GenericProvider implements WebhookProvider {
|
|
23
|
+
readonly name = "generic";
|
|
24
|
+
private signatureHeader;
|
|
25
|
+
private timestampHeader;
|
|
26
|
+
private tolerance;
|
|
27
|
+
constructor(options?: {
|
|
28
|
+
signatureHeader?: string;
|
|
29
|
+
timestampHeader?: string;
|
|
30
|
+
tolerance?: number;
|
|
31
|
+
});
|
|
32
|
+
verify(payload: string | Buffer, headers: Record<string, string | string[] | undefined>, secret: string): Promise<WebhookVerificationResult>;
|
|
33
|
+
private getHeader;
|
|
34
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview GitHub webhook provider
|
|
3
|
+
*
|
|
4
|
+
* Implements GitHub's webhook signature verification.
|
|
5
|
+
* @see https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries
|
|
6
|
+
*
|
|
7
|
+
* @module @gravito/echo/providers
|
|
8
|
+
*/
|
|
9
|
+
import type { WebhookProvider, WebhookVerificationResult } from '../types';
|
|
10
|
+
/**
|
|
11
|
+
* GitHub webhook provider
|
|
12
|
+
*
|
|
13
|
+
* Verifies GitHub webhook signatures using the X-Hub-Signature-256 header.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const provider = new GitHubProvider()
|
|
18
|
+
* const result = await provider.verify(body, headers, process.env.GITHUB_WEBHOOK_SECRET)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class GitHubProvider implements WebhookProvider {
|
|
22
|
+
readonly name = "github";
|
|
23
|
+
verify(payload: string | Buffer, headers: Record<string, string | string[] | undefined>, secret: string): Promise<WebhookVerificationResult>;
|
|
24
|
+
parseEventType(payload: unknown): string | undefined;
|
|
25
|
+
private getHeader;
|
|
26
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Stripe webhook provider
|
|
3
|
+
*
|
|
4
|
+
* Implements Stripe's webhook signature verification.
|
|
5
|
+
* @see https://stripe.com/docs/webhooks/signatures
|
|
6
|
+
*
|
|
7
|
+
* @module @gravito/echo/providers
|
|
8
|
+
*/
|
|
9
|
+
import type { WebhookProvider, WebhookVerificationResult } from '../types';
|
|
10
|
+
/**
|
|
11
|
+
* Stripe webhook provider
|
|
12
|
+
*
|
|
13
|
+
* Verifies Stripe webhook signatures using their standard format.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const provider = new StripeProvider()
|
|
18
|
+
* const result = await provider.verify(body, headers, process.env.STRIPE_WEBHOOK_SECRET)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class StripeProvider implements WebhookProvider {
|
|
22
|
+
readonly name = "stripe";
|
|
23
|
+
private tolerance;
|
|
24
|
+
constructor(options?: {
|
|
25
|
+
tolerance?: number;
|
|
26
|
+
});
|
|
27
|
+
verify(payload: string | Buffer, headers: Record<string, string | string[] | undefined>, secret: string): Promise<WebhookVerificationResult>;
|
|
28
|
+
parseEventType(payload: unknown): string | undefined;
|
|
29
|
+
private getHeader;
|
|
30
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Signature validation utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides HMAC-based signature verification for webhook payloads.
|
|
5
|
+
*
|
|
6
|
+
* @module @gravito/echo/receive
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Compute HMAC-SHA256 signature
|
|
10
|
+
*/
|
|
11
|
+
export declare function computeHmacSha256(payload: string | Buffer, secret: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Compute HMAC-SHA1 signature (for legacy providers)
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeHmacSha1(payload: string | Buffer, secret: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Timing-safe string comparison to prevent timing attacks
|
|
18
|
+
*/
|
|
19
|
+
export declare function timingSafeEqual(a: string, b: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Validate timestamp is within tolerance
|
|
22
|
+
*
|
|
23
|
+
* @param timestamp - Unix timestamp in seconds
|
|
24
|
+
* @param tolerance - Tolerance in seconds (default: 300 = 5 minutes)
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateTimestamp(timestamp: number, tolerance?: number): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Parse Stripe-style signature header
|
|
29
|
+
* Format: t=timestamp,v1=signature,v1=signature2
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseStripeSignature(header: string): {
|
|
32
|
+
timestamp: number;
|
|
33
|
+
signatures: string[];
|
|
34
|
+
} | null;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Webhook Receiver
|
|
3
|
+
*
|
|
4
|
+
* Handles incoming webhooks with signature verification.
|
|
5
|
+
*
|
|
6
|
+
* @module @gravito/echo/receive
|
|
7
|
+
*/
|
|
8
|
+
import type { WebhookHandler, WebhookProvider, WebhookVerificationResult } from '../types';
|
|
9
|
+
type ProviderClass = new (options?: any) => WebhookProvider;
|
|
10
|
+
/**
|
|
11
|
+
* Webhook Receiver
|
|
12
|
+
*
|
|
13
|
+
* Manages webhook providers and routes incoming webhooks to handlers.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const receiver = new WebhookReceiver()
|
|
18
|
+
*
|
|
19
|
+
* // Register provider
|
|
20
|
+
* receiver.registerProvider('stripe', process.env.STRIPE_WEBHOOK_SECRET!)
|
|
21
|
+
*
|
|
22
|
+
* // Register handler
|
|
23
|
+
* receiver.on('stripe', 'payment_intent.succeeded', async (event) => {
|
|
24
|
+
* console.log('Payment received:', event.payload)
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* // Handle incoming webhook
|
|
28
|
+
* const result = await receiver.handle('stripe', body, headers)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class WebhookReceiver {
|
|
32
|
+
private providers;
|
|
33
|
+
private handlers;
|
|
34
|
+
private globalHandlers;
|
|
35
|
+
constructor();
|
|
36
|
+
private providerTypes;
|
|
37
|
+
/**
|
|
38
|
+
* Register a custom provider type
|
|
39
|
+
*/
|
|
40
|
+
registerProviderType(name: string, ProviderCls: ProviderClass): this;
|
|
41
|
+
/**
|
|
42
|
+
* Register a provider with its secret
|
|
43
|
+
*/
|
|
44
|
+
registerProvider(name: string, secret: string, options?: {
|
|
45
|
+
type?: string;
|
|
46
|
+
tolerance?: number;
|
|
47
|
+
}): this;
|
|
48
|
+
/**
|
|
49
|
+
* Register an event handler
|
|
50
|
+
*/
|
|
51
|
+
on<T = unknown>(providerName: string, eventType: string, handler: WebhookHandler<T>): this;
|
|
52
|
+
/**
|
|
53
|
+
* Register a handler for all events from a provider
|
|
54
|
+
*/
|
|
55
|
+
onAll<T = unknown>(providerName: string, handler: WebhookHandler<T>): this;
|
|
56
|
+
/**
|
|
57
|
+
* Handle an incoming webhook
|
|
58
|
+
*/
|
|
59
|
+
handle(providerName: string, body: string | Buffer, headers: Record<string, string | string[] | undefined>): Promise<WebhookVerificationResult & {
|
|
60
|
+
handled: boolean;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Verify a webhook without handling
|
|
64
|
+
*/
|
|
65
|
+
verify(providerName: string, body: string | Buffer, headers: Record<string, string | string[] | undefined>): Promise<WebhookVerificationResult>;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
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 { WebhookDeliveryResult, WebhookDispatcherConfig, WebhookPayload } from '../types';
|
|
9
|
+
/**
|
|
10
|
+
* Webhook Dispatcher
|
|
11
|
+
*
|
|
12
|
+
* Sends webhooks with signature and retry support.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const dispatcher = new WebhookDispatcher({
|
|
17
|
+
* secret: 'my-webhook-secret',
|
|
18
|
+
* retry: { maxAttempts: 5 }
|
|
19
|
+
* })
|
|
20
|
+
*
|
|
21
|
+
* const result = await dispatcher.dispatch({
|
|
22
|
+
* url: 'https://example.com/webhook',
|
|
23
|
+
* event: 'order.created',
|
|
24
|
+
* data: { orderId: 123 }
|
|
25
|
+
* })
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class WebhookDispatcher {
|
|
29
|
+
private secret;
|
|
30
|
+
private retryConfig;
|
|
31
|
+
private timeout;
|
|
32
|
+
private userAgent;
|
|
33
|
+
constructor(config: WebhookDispatcherConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Dispatch a webhook with retries
|
|
36
|
+
*/
|
|
37
|
+
dispatch<T = unknown>(payload: WebhookPayload<T>): Promise<WebhookDeliveryResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Attempt a single delivery
|
|
40
|
+
*/
|
|
41
|
+
private attemptDelivery;
|
|
42
|
+
/**
|
|
43
|
+
* Check if we should retry based on result
|
|
44
|
+
*/
|
|
45
|
+
private shouldRetry;
|
|
46
|
+
/**
|
|
47
|
+
* Calculate delay for exponential backoff
|
|
48
|
+
*/
|
|
49
|
+
private calculateDelay;
|
|
50
|
+
/**
|
|
51
|
+
* Sleep helper
|
|
52
|
+
*/
|
|
53
|
+
private sleep;
|
|
54
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './WebhookDispatcher';
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Core types for @gravito/echo webhook module
|
|
3
|
+
* @module @gravito/echo
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for a specific webhook provider (e.g., Stripe, GitHub).
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface WebhookProviderConfig {
|
|
10
|
+
/** The unique name of the provider */
|
|
11
|
+
name: string;
|
|
12
|
+
/** The shared secret used to verify incoming webhook signatures */
|
|
13
|
+
secret: string;
|
|
14
|
+
/** The name of the HTTP header containing the signature (e.g., 'stripe-signature') */
|
|
15
|
+
signatureHeader?: string;
|
|
16
|
+
/** Maximum allowed time drift in seconds for timestamp validation (default: 300) */
|
|
17
|
+
tolerance?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The result of verifying an incoming webhook request.
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export interface WebhookVerificationResult {
|
|
24
|
+
/** True if the signature is valid and the timestamp is within tolerance */
|
|
25
|
+
valid: boolean;
|
|
26
|
+
/** Descriptive error message if the verification failed */
|
|
27
|
+
error?: string;
|
|
28
|
+
/** The parsed JSON payload from the request body */
|
|
29
|
+
payload?: unknown;
|
|
30
|
+
/** The specific event name extracted from the payload or headers */
|
|
31
|
+
eventType?: string;
|
|
32
|
+
/** The unique identifier for this webhook message, if provided by the source */
|
|
33
|
+
webhookId?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Interface that all webhook provider implementations must follow.
|
|
37
|
+
* Providers handle the logic for specific services like Stripe or Shopify.
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export interface WebhookProvider {
|
|
41
|
+
/** Uniquely identifies the provider (e.g., 'stripe') */
|
|
42
|
+
readonly name: string;
|
|
43
|
+
/**
|
|
44
|
+
* Validates the integrity and authenticity of an incoming request.
|
|
45
|
+
*
|
|
46
|
+
* @param payload - The raw request body as a string or Buffer.
|
|
47
|
+
* @param headers - The incoming HTTP headers.
|
|
48
|
+
* @param secret - The secret key used for verification.
|
|
49
|
+
*/
|
|
50
|
+
verify(payload: string | Buffer, headers: Record<string, string | string[] | undefined>, secret: string): Promise<WebhookVerificationResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Determines the event type from the validated payload.
|
|
53
|
+
* @param payload - The parsed JSON body.
|
|
54
|
+
*/
|
|
55
|
+
parseEventType?(payload: unknown): string | undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A callback function triggered when a valid webhook event is received.
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export type WebhookHandler<T = unknown> = (event: WebhookEvent<T>) => void | Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Represents a normalized webhook event processed by Echo.
|
|
64
|
+
* Provides a consistent interface regardless of the source provider.
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
export interface WebhookEvent<T = unknown> {
|
|
68
|
+
/** Name of the provider that sent the event */
|
|
69
|
+
provider: string;
|
|
70
|
+
/** The type of event (e.g., 'payment_intent.succeeded') */
|
|
71
|
+
type: string;
|
|
72
|
+
/** The parsed and type-safe data payload */
|
|
73
|
+
payload: T;
|
|
74
|
+
/** The original HTTP headers received with the request */
|
|
75
|
+
headers: Record<string, string | string[] | undefined>;
|
|
76
|
+
/** The raw, unparsed request body string */
|
|
77
|
+
rawBody: string;
|
|
78
|
+
/** The local system time when the webhook was received */
|
|
79
|
+
receivedAt: Date;
|
|
80
|
+
/** Unique ID for the event, if provided by the source */
|
|
81
|
+
id?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Data structure for sending a webhook to an external service.
|
|
85
|
+
* @public
|
|
86
|
+
*/
|
|
87
|
+
export interface WebhookPayload<T = unknown> {
|
|
88
|
+
/** The destination URL where the webhook should be POSTed */
|
|
89
|
+
url: string;
|
|
90
|
+
/** The name of the event being dispatched */
|
|
91
|
+
event: string;
|
|
92
|
+
/** The data to be JSON-encoded and sent in the body */
|
|
93
|
+
data: T;
|
|
94
|
+
/** Optional unique identifier for this specific delivery attempt */
|
|
95
|
+
id?: string;
|
|
96
|
+
/** Optional timestamp representing when the event occurred */
|
|
97
|
+
timestamp?: Date;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Summary of a webhook delivery attempt.
|
|
101
|
+
* @public
|
|
102
|
+
*/
|
|
103
|
+
export interface WebhookDeliveryResult {
|
|
104
|
+
/** True if the destination returned a 2xx status code */
|
|
105
|
+
success: boolean;
|
|
106
|
+
/** The HTTP status code returned by the destination server */
|
|
107
|
+
statusCode?: number;
|
|
108
|
+
/** The raw response body from the destination server */
|
|
109
|
+
body?: string;
|
|
110
|
+
/** Error message if the request failed (e.g., network timeout) */
|
|
111
|
+
error?: string;
|
|
112
|
+
/** Which attempt number this was (starts at 1) */
|
|
113
|
+
attempt: number;
|
|
114
|
+
/** Total time elapsed for the request in milliseconds */
|
|
115
|
+
duration: number;
|
|
116
|
+
/** Timestamp when the delivery attempt was recorded */
|
|
117
|
+
deliveredAt: Date;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Strategy for retrying failed webhook deliveries with exponential backoff.
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
123
|
+
export interface RetryConfig {
|
|
124
|
+
/** Maximum number of delivery attempts (default: 3) */
|
|
125
|
+
maxAttempts?: number;
|
|
126
|
+
/** Initial delay before the first retry in milliseconds (default: 1000) */
|
|
127
|
+
initialDelay?: number;
|
|
128
|
+
/** Multiplier for the delay between subsequent retries (default: 2) */
|
|
129
|
+
backoffMultiplier?: number;
|
|
130
|
+
/** Upper bound for the retry delay in milliseconds (default: 300,000) */
|
|
131
|
+
maxDelay?: number;
|
|
132
|
+
/** List of HTTP status codes that should trigger a retry (e.g., 502, 503) */
|
|
133
|
+
retryableStatuses?: number[];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Configuration for the outgoing webhook dispatcher.
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
export interface WebhookDispatcherConfig {
|
|
140
|
+
/** Secret key used to sign outgoing webhook payloads for security */
|
|
141
|
+
secret: string;
|
|
142
|
+
/** Optional retry strategy for failed deliveries */
|
|
143
|
+
retry?: RetryConfig;
|
|
144
|
+
/** Maximum time in milliseconds to wait for a response (default: 30,000) */
|
|
145
|
+
timeout?: number;
|
|
146
|
+
/** Custom User-Agent header for the outgoing request */
|
|
147
|
+
userAgent?: string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Full configuration for the OrbitEcho module.
|
|
151
|
+
* @public
|
|
152
|
+
*/
|
|
153
|
+
export interface EchoConfig {
|
|
154
|
+
/** Map of named provider configurations for receiving webhooks */
|
|
155
|
+
providers?: Record<string, WebhookProviderConfig>;
|
|
156
|
+
/** Settings for sending webhooks to other services */
|
|
157
|
+
dispatcher?: WebhookDispatcherConfig;
|
|
158
|
+
/**
|
|
159
|
+
* The URL prefix for the automatically generated webhook endpoints.
|
|
160
|
+
* (e.g., '/webhooks' will create '/webhooks/:provider')
|
|
161
|
+
* Default: '/webhooks'
|
|
162
|
+
*/
|
|
163
|
+
basePath?: string;
|
|
164
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -434,7 +434,6 @@ class WebhookDispatcher {
|
|
|
434
434
|
|
|
435
435
|
// src/OrbitEcho.ts
|
|
436
436
|
class OrbitEcho {
|
|
437
|
-
static config = { singleton: true };
|
|
438
437
|
receiver;
|
|
439
438
|
dispatcher;
|
|
440
439
|
echoConfig;
|
|
@@ -459,6 +458,11 @@ class OrbitEcho {
|
|
|
459
458
|
if (this.dispatcher) {
|
|
460
459
|
core.container.instance("echo.dispatcher", this.dispatcher);
|
|
461
460
|
}
|
|
461
|
+
core.adapter.use("*", async (c, next) => {
|
|
462
|
+
c.set("echo", this);
|
|
463
|
+
return await next();
|
|
464
|
+
});
|
|
465
|
+
core.logger.info("[OrbitEcho] Webhook receiver and dispatcher registered");
|
|
462
466
|
}
|
|
463
467
|
getReceiver() {
|
|
464
468
|
return this.receiver;
|
|
@@ -484,4 +488,4 @@ export {
|
|
|
484
488
|
GenericProvider
|
|
485
489
|
};
|
|
486
490
|
|
|
487
|
-
//# debugId=
|
|
491
|
+
//# debugId=ECB32FF3DBDFBFDC64756E2164756E21
|