@teever/ez-hook-effect 0.4.4 → 0.5.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/README.md +88 -10
- package/dist/errors/WebhookError.d.ts +142 -3
- package/dist/errors/WebhookError.js +322 -0
- package/dist/errors/WebhookError.js.map +1 -0
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +493 -264
- package/dist/index.js.map +16 -14
- package/dist/layers/Config.d.ts +3 -3
- package/dist/layers/Config.js +166 -0
- package/dist/layers/Config.js.map +1 -0
- package/dist/layers/Default.d.ts +6 -0
- package/dist/layers/Default.js +9 -0
- package/dist/layers/Default.js.map +1 -0
- package/dist/layers/HttpClient.d.ts +8 -4
- package/dist/layers/HttpClient.js +209 -0
- package/dist/layers/HttpClient.js.map +1 -0
- package/dist/layers/index.js +3 -0
- package/dist/layers/index.js.map +1 -0
- package/dist/pipes/Embed.d.ts +2 -2
- package/dist/pipes/Embed.js +198 -0
- package/dist/pipes/Embed.js.map +1 -0
- package/dist/pipes/Webhook.d.ts +3 -2
- package/dist/pipes/Webhook.js +46 -0
- package/dist/pipes/Webhook.js.map +1 -0
- package/dist/pipes/index.js +3 -0
- package/dist/pipes/index.js.map +1 -0
- package/dist/schemas/Common.d.ts +6 -6
- package/dist/schemas/Common.js +30 -0
- package/dist/schemas/Common.js.map +1 -0
- package/dist/schemas/Discord.d.ts +1 -1
- package/dist/schemas/Discord.js +19 -0
- package/dist/schemas/Discord.js.map +1 -0
- package/dist/schemas/Embed.d.ts +58 -229
- package/dist/schemas/Embed.js +139 -0
- package/dist/schemas/Embed.js.map +1 -0
- package/dist/schemas/Field.d.ts +6 -27
- package/dist/schemas/Field.js +25 -0
- package/dist/schemas/Field.js.map +1 -0
- package/dist/schemas/Webhook.d.ts +42 -160
- package/dist/schemas/Webhook.js +87 -0
- package/dist/schemas/Webhook.js.map +1 -0
- package/dist/schemas/index.js +6 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/services/WebhookService.d.ts +27 -5
- package/dist/services/WebhookService.js +116 -0
- package/dist/services/WebhookService.js.map +1 -0
- package/dist/services/index.js +2 -0
- package/dist/services/index.js.map +1 -0
- package/dist/utils/normalize.d.ts +1 -0
- package/dist/utils/normalize.js +17 -0
- package/dist/utils/normalize.js.map +1 -0
- package/package.json +56 -54
package/README.md
CHANGED
|
@@ -25,17 +25,14 @@ npx jsr add @teever/ez-hook-effect
|
|
|
25
25
|
## Quick Start
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
|
-
import { Effect,
|
|
29
|
-
import {
|
|
28
|
+
import { Effect, pipe } from 'effect'
|
|
29
|
+
import { makeDefaultLayer, sendWebhook, Webhook } from '@teever/ez-hook-effect'
|
|
30
30
|
|
|
31
31
|
// Configure your webhook
|
|
32
32
|
const WEBHOOK_URL = 'https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN'
|
|
33
33
|
|
|
34
|
-
// Create service
|
|
35
|
-
const AppLayer =
|
|
36
|
-
Layer.provide(makeConfigLayer(WEBHOOK_URL)),
|
|
37
|
-
Layer.provide(HttpClientLive)
|
|
38
|
-
)
|
|
34
|
+
// Create service layer
|
|
35
|
+
const AppLayer = makeDefaultLayer(WEBHOOK_URL)
|
|
39
36
|
|
|
40
37
|
// Send a simple message
|
|
41
38
|
const program = pipe(
|
|
@@ -47,7 +44,7 @@ const program = pipe(
|
|
|
47
44
|
)
|
|
48
45
|
|
|
49
46
|
// Run the program
|
|
50
|
-
Effect.runPromise(Effect.provide(
|
|
47
|
+
Effect.runPromise(program.pipe(Effect.provide(AppLayer)))
|
|
51
48
|
```
|
|
52
49
|
|
|
53
50
|
### Pipe-First API (Recommended)
|
|
@@ -105,7 +102,7 @@ const embedProgram = pipe(
|
|
|
105
102
|
|
|
106
103
|
## Error Handling
|
|
107
104
|
|
|
108
|
-
Retries for rate limits (429) and transient errors (5xx) are handled automatically using configurable exponential backoff.
|
|
105
|
+
Retries for rate limits (429) and transient errors (5xx) are handled automatically using configurable exponential backoff. `sendWebhook` fails the Effect on any non-204 response, so errors always surface to your error handling paths.
|
|
109
106
|
|
|
110
107
|
```typescript
|
|
111
108
|
import { Effect, pipe } from 'effect'
|
|
@@ -144,6 +141,54 @@ Effect.catchTag('ValidationError', (error) =>
|
|
|
144
141
|
)
|
|
145
142
|
```
|
|
146
143
|
|
|
144
|
+
### Error Helpers
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { Effect, pipe } from 'effect'
|
|
148
|
+
import { Webhook, sendWebhook, formatWebhookError, webhookErrorToLogObject } from '@teever/ez-hook-effect'
|
|
149
|
+
|
|
150
|
+
const program = pipe(
|
|
151
|
+
Webhook.make,
|
|
152
|
+
Webhook.setContent('Hello!'),
|
|
153
|
+
Webhook.build,
|
|
154
|
+
Effect.flatMap(sendWebhook),
|
|
155
|
+
Effect.catchAll((error) =>
|
|
156
|
+
Effect.logError(formatWebhookError(error)).pipe(
|
|
157
|
+
Effect.tap(() => Effect.log(JSON.stringify(webhookErrorToLogObject(error))))
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Raw Response
|
|
164
|
+
|
|
165
|
+
When you need status/body, use `sendWebhookRaw`:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import { Effect, pipe } from 'effect'
|
|
169
|
+
import { sendWebhookRaw, Webhook } from '@teever/ez-hook-effect'
|
|
170
|
+
|
|
171
|
+
const program = pipe(
|
|
172
|
+
Webhook.make,
|
|
173
|
+
Webhook.setContent('Hello!'),
|
|
174
|
+
Webhook.build,
|
|
175
|
+
Effect.flatMap(sendWebhookRaw),
|
|
176
|
+
Effect.tap((res) => Effect.log(`Status: ${res.status}`))
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Validate Only
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { Effect, pipe } from 'effect'
|
|
184
|
+
import { Webhook } from '@teever/ez-hook-effect'
|
|
185
|
+
|
|
186
|
+
const program = pipe(
|
|
187
|
+
Webhook.validate({ content: 'Hello!' }),
|
|
188
|
+
Effect.tap(() => Effect.log('Valid payload'))
|
|
189
|
+
)
|
|
190
|
+
```
|
|
191
|
+
|
|
147
192
|
## Configuration Options
|
|
148
193
|
|
|
149
194
|
### Programmatic Configuration
|
|
@@ -160,6 +205,17 @@ const AppLayer = WebhookServiceLive.pipe(
|
|
|
160
205
|
)
|
|
161
206
|
```
|
|
162
207
|
|
|
208
|
+
### One-Liner Configuration
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import { makeDefaultLayer } from '@teever/ez-hook-effect'
|
|
212
|
+
|
|
213
|
+
const AppLayer = makeDefaultLayer(WEBHOOK_URL, {
|
|
214
|
+
maxRetries: 5,
|
|
215
|
+
baseDelayMs: 1000,
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
163
219
|
### Environment Variables
|
|
164
220
|
|
|
165
221
|
```typescript
|
|
@@ -198,7 +254,7 @@ Beyond sending messages, the library supports full webhook CRUD:
|
|
|
198
254
|
|
|
199
255
|
```typescript
|
|
200
256
|
import { Effect, Layer, pipe } from 'effect'
|
|
201
|
-
import { getWebhook, modifyWebhook, deleteWebhook, validateWebhook, WebhookServiceLive, makeConfigLayer, HttpClientLive } from '@teever/ez-hook-effect'
|
|
257
|
+
import { getWebhook, modifyWebhook, deleteWebhook, validateWebhook, WebhookService, WebhookServiceLive, makeConfigLayer, HttpClientLive } from '@teever/ez-hook-effect'
|
|
202
258
|
|
|
203
259
|
const AppLayer = WebhookServiceLive.pipe(
|
|
204
260
|
Layer.provide(makeConfigLayer(WEBHOOK_URL)),
|
|
@@ -226,6 +282,28 @@ const program = Effect.gen(function* () {
|
|
|
226
282
|
Effect.runPromise(Effect.provide(program, AppLayer))
|
|
227
283
|
```
|
|
228
284
|
|
|
285
|
+
## Testing Utilities
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { Effect, Layer, pipe } from 'effect'
|
|
289
|
+
import { makeTestHttpClient, WebhookServiceLive, makeConfigLayer } from '@teever/ez-hook-effect'
|
|
290
|
+
|
|
291
|
+
const TestHttpClient = makeTestHttpClient((_req) =>
|
|
292
|
+
Effect.succeed({
|
|
293
|
+
status: 204,
|
|
294
|
+
statusText: 'No Content',
|
|
295
|
+
headers: {},
|
|
296
|
+
body: null,
|
|
297
|
+
text: '',
|
|
298
|
+
})
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
const AppLayer = WebhookServiceLive.pipe(
|
|
302
|
+
Layer.provide(makeConfigLayer('https://discord.com/api/webhooks/123/abc')),
|
|
303
|
+
Layer.provide(TestHttpClient)
|
|
304
|
+
)
|
|
305
|
+
```
|
|
306
|
+
|
|
229
307
|
## Development
|
|
230
308
|
|
|
231
309
|
```bash
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Schema } from "effect";
|
|
2
2
|
declare const WebhookError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
3
3
|
readonly _tag: "WebhookError";
|
|
4
4
|
} & Readonly<A>;
|
|
@@ -28,7 +28,7 @@ export interface ValidationIssue {
|
|
|
28
28
|
/**
|
|
29
29
|
* Convert Effect Schema ParseError to ValidationIssue array
|
|
30
30
|
*/
|
|
31
|
-
export declare const parseErrorToIssues: (error:
|
|
31
|
+
export declare const parseErrorToIssues: (error: Schema.SchemaError) => ValidationIssue[];
|
|
32
32
|
/**
|
|
33
33
|
* Create a single ValidationIssue from simple field validation
|
|
34
34
|
*/
|
|
@@ -62,7 +62,7 @@ export declare class ValidationError extends ValidationError_base<{
|
|
|
62
62
|
/**
|
|
63
63
|
* Create ValidationError from Effect Schema ParseError
|
|
64
64
|
*/
|
|
65
|
-
static fromParseError(parseError:
|
|
65
|
+
static fromParseError(parseError: Schema.SchemaError, context?: {
|
|
66
66
|
field?: string;
|
|
67
67
|
value?: unknown;
|
|
68
68
|
}): ValidationError;
|
|
@@ -153,4 +153,143 @@ export declare class HttpError extends HttpError_base<{
|
|
|
153
153
|
* All possible webhook errors
|
|
154
154
|
*/
|
|
155
155
|
export type WebhookErrors = WebhookError | ValidationError | NetworkError | RateLimitError | ConfigError | FileError | HttpError;
|
|
156
|
+
/**
|
|
157
|
+
* Create a readable message for any webhook error.
|
|
158
|
+
*/
|
|
159
|
+
export declare const formatWebhookError: (error: WebhookErrors, options?: {
|
|
160
|
+
maxIssues?: number;
|
|
161
|
+
}) => string;
|
|
162
|
+
/**
|
|
163
|
+
* Produce a structured log object for any webhook error.
|
|
164
|
+
*/
|
|
165
|
+
export declare const webhookErrorToLogObject: (error: WebhookErrors) => {
|
|
166
|
+
tag: "ValidationError";
|
|
167
|
+
message: string;
|
|
168
|
+
issues: readonly ValidationIssue[];
|
|
169
|
+
field: string;
|
|
170
|
+
value: unknown;
|
|
171
|
+
retryAfter?: undefined;
|
|
172
|
+
limit?: undefined;
|
|
173
|
+
remaining?: undefined;
|
|
174
|
+
reset?: undefined;
|
|
175
|
+
request?: undefined;
|
|
176
|
+
response?: undefined;
|
|
177
|
+
statusCode?: undefined;
|
|
178
|
+
parameter?: undefined;
|
|
179
|
+
filename?: undefined;
|
|
180
|
+
size?: undefined;
|
|
181
|
+
maxSize?: undefined;
|
|
182
|
+
cause?: undefined;
|
|
183
|
+
} | {
|
|
184
|
+
tag: "RateLimitError";
|
|
185
|
+
message: string;
|
|
186
|
+
retryAfter: number;
|
|
187
|
+
limit: number;
|
|
188
|
+
remaining: number;
|
|
189
|
+
reset: Date;
|
|
190
|
+
issues?: undefined;
|
|
191
|
+
field?: undefined;
|
|
192
|
+
value?: undefined;
|
|
193
|
+
request?: undefined;
|
|
194
|
+
response?: undefined;
|
|
195
|
+
statusCode?: undefined;
|
|
196
|
+
parameter?: undefined;
|
|
197
|
+
filename?: undefined;
|
|
198
|
+
size?: undefined;
|
|
199
|
+
maxSize?: undefined;
|
|
200
|
+
cause?: undefined;
|
|
201
|
+
} | {
|
|
202
|
+
tag: "HttpError";
|
|
203
|
+
message: string;
|
|
204
|
+
request: {
|
|
205
|
+
method: string;
|
|
206
|
+
url: string;
|
|
207
|
+
};
|
|
208
|
+
response: HttpErrorResponse;
|
|
209
|
+
issues?: undefined;
|
|
210
|
+
field?: undefined;
|
|
211
|
+
value?: undefined;
|
|
212
|
+
retryAfter?: undefined;
|
|
213
|
+
limit?: undefined;
|
|
214
|
+
remaining?: undefined;
|
|
215
|
+
reset?: undefined;
|
|
216
|
+
statusCode?: undefined;
|
|
217
|
+
parameter?: undefined;
|
|
218
|
+
filename?: undefined;
|
|
219
|
+
size?: undefined;
|
|
220
|
+
maxSize?: undefined;
|
|
221
|
+
cause?: undefined;
|
|
222
|
+
} | {
|
|
223
|
+
tag: "NetworkError";
|
|
224
|
+
message: string;
|
|
225
|
+
statusCode: number;
|
|
226
|
+
response: unknown;
|
|
227
|
+
issues?: undefined;
|
|
228
|
+
field?: undefined;
|
|
229
|
+
value?: undefined;
|
|
230
|
+
retryAfter?: undefined;
|
|
231
|
+
limit?: undefined;
|
|
232
|
+
remaining?: undefined;
|
|
233
|
+
reset?: undefined;
|
|
234
|
+
request?: undefined;
|
|
235
|
+
parameter?: undefined;
|
|
236
|
+
filename?: undefined;
|
|
237
|
+
size?: undefined;
|
|
238
|
+
maxSize?: undefined;
|
|
239
|
+
cause?: undefined;
|
|
240
|
+
} | {
|
|
241
|
+
tag: "ConfigError";
|
|
242
|
+
message: string;
|
|
243
|
+
parameter: string;
|
|
244
|
+
issues?: undefined;
|
|
245
|
+
field?: undefined;
|
|
246
|
+
value?: undefined;
|
|
247
|
+
retryAfter?: undefined;
|
|
248
|
+
limit?: undefined;
|
|
249
|
+
remaining?: undefined;
|
|
250
|
+
reset?: undefined;
|
|
251
|
+
request?: undefined;
|
|
252
|
+
response?: undefined;
|
|
253
|
+
statusCode?: undefined;
|
|
254
|
+
filename?: undefined;
|
|
255
|
+
size?: undefined;
|
|
256
|
+
maxSize?: undefined;
|
|
257
|
+
cause?: undefined;
|
|
258
|
+
} | {
|
|
259
|
+
tag: "FileError";
|
|
260
|
+
message: string;
|
|
261
|
+
filename: string;
|
|
262
|
+
size: number;
|
|
263
|
+
maxSize: number;
|
|
264
|
+
issues?: undefined;
|
|
265
|
+
field?: undefined;
|
|
266
|
+
value?: undefined;
|
|
267
|
+
retryAfter?: undefined;
|
|
268
|
+
limit?: undefined;
|
|
269
|
+
remaining?: undefined;
|
|
270
|
+
reset?: undefined;
|
|
271
|
+
request?: undefined;
|
|
272
|
+
response?: undefined;
|
|
273
|
+
statusCode?: undefined;
|
|
274
|
+
parameter?: undefined;
|
|
275
|
+
cause?: undefined;
|
|
276
|
+
} | {
|
|
277
|
+
tag: "WebhookError";
|
|
278
|
+
message: string;
|
|
279
|
+
cause: unknown;
|
|
280
|
+
issues?: undefined;
|
|
281
|
+
field?: undefined;
|
|
282
|
+
value?: undefined;
|
|
283
|
+
retryAfter?: undefined;
|
|
284
|
+
limit?: undefined;
|
|
285
|
+
remaining?: undefined;
|
|
286
|
+
reset?: undefined;
|
|
287
|
+
request?: undefined;
|
|
288
|
+
response?: undefined;
|
|
289
|
+
statusCode?: undefined;
|
|
290
|
+
parameter?: undefined;
|
|
291
|
+
filename?: undefined;
|
|
292
|
+
size?: undefined;
|
|
293
|
+
maxSize?: undefined;
|
|
294
|
+
};
|
|
156
295
|
export {};
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/* c8 ignore start */
|
|
2
|
+
import { Data } from "effect";
|
|
3
|
+
/**
|
|
4
|
+
* Base error class for all webhook-related errors
|
|
5
|
+
*/
|
|
6
|
+
/* c8 ignore stop */
|
|
7
|
+
export class WebhookError extends Data.TaggedError("WebhookError") {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Extract constraint name from Effect Schema error message
|
|
11
|
+
*/
|
|
12
|
+
const extractConstraint = (message) => {
|
|
13
|
+
if (message.includes("at most") || message.includes("maximum"))
|
|
14
|
+
return "MaxLength";
|
|
15
|
+
if (message.includes("at least") || message.includes("minimum"))
|
|
16
|
+
return "MinLength";
|
|
17
|
+
if (message.includes("required") || message.includes("missing"))
|
|
18
|
+
return "Required";
|
|
19
|
+
if (message.includes("expected") && message.includes("to be"))
|
|
20
|
+
return "Type";
|
|
21
|
+
if (message.includes("URL") || message.includes("url"))
|
|
22
|
+
return "URL";
|
|
23
|
+
if (message.includes("integer") || message.includes("number"))
|
|
24
|
+
return "Number";
|
|
25
|
+
return undefined;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Truncate large values for error display
|
|
29
|
+
*/
|
|
30
|
+
const truncateValue = (value, maxLength = 100) => {
|
|
31
|
+
if (typeof value === "string" && value.length > maxLength) {
|
|
32
|
+
return `${value.slice(0, maxLength)}... (${value.length} chars)`;
|
|
33
|
+
}
|
|
34
|
+
if (Array.isArray(value) && value.length > 5) {
|
|
35
|
+
return `[Array with ${value.length} items]`;
|
|
36
|
+
}
|
|
37
|
+
if (typeof value === "object" && value !== null) {
|
|
38
|
+
const keys = Object.keys(value);
|
|
39
|
+
if (keys.length > 5) {
|
|
40
|
+
return `{Object with ${keys.length} keys}`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Convert Effect Schema ParseIssue path to JSONPath string
|
|
47
|
+
*/
|
|
48
|
+
const pathToString = (path) => {
|
|
49
|
+
if (path.length === 0)
|
|
50
|
+
return "$";
|
|
51
|
+
return path.reduce((acc, segment) => {
|
|
52
|
+
if (typeof segment === "number") {
|
|
53
|
+
return `${acc}[${segment}]`;
|
|
54
|
+
}
|
|
55
|
+
return `${acc}.${String(segment)}`;
|
|
56
|
+
}, "$");
|
|
57
|
+
};
|
|
58
|
+
const toArray = (value) => Array.isArray(value) ? value : [value];
|
|
59
|
+
// Helper to safely access issue properties via unknown
|
|
60
|
+
const getIssueProp = (issue, key) => issue[key];
|
|
61
|
+
const extractIssuesFromParseIssue = (issue, currentPath = []) => {
|
|
62
|
+
const issues = [];
|
|
63
|
+
switch (issue._tag) {
|
|
64
|
+
case "InvalidType": {
|
|
65
|
+
const ast = getIssueProp(issue, "ast");
|
|
66
|
+
const message = getIssueProp(issue, "message") ?? `Expected ${ast?._tag}`;
|
|
67
|
+
issues.push({
|
|
68
|
+
path: pathToString(currentPath),
|
|
69
|
+
message,
|
|
70
|
+
constraint: extractConstraint(message) ?? "Type",
|
|
71
|
+
actual: truncateValue(getIssueProp(issue, "actual")),
|
|
72
|
+
});
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case "Forbidden": {
|
|
76
|
+
issues.push({
|
|
77
|
+
path: pathToString(currentPath),
|
|
78
|
+
message: getIssueProp(issue, "message") ?? "Value is forbidden",
|
|
79
|
+
constraint: "Forbidden",
|
|
80
|
+
});
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case "MissingKey": {
|
|
84
|
+
issues.push({
|
|
85
|
+
path: pathToString(currentPath),
|
|
86
|
+
message: "Required field is missing",
|
|
87
|
+
constraint: "Required",
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case "UnexpectedKey": {
|
|
92
|
+
issues.push({
|
|
93
|
+
path: pathToString(currentPath),
|
|
94
|
+
message: getIssueProp(issue, "message") ?? "Unexpected field",
|
|
95
|
+
constraint: "Unexpected",
|
|
96
|
+
actual: truncateValue(getIssueProp(issue, "actual")),
|
|
97
|
+
});
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case "Pointer": {
|
|
101
|
+
const pathSegments = getIssueProp(issue, "path") ?? [];
|
|
102
|
+
const newPath = [...currentPath, ...pathSegments];
|
|
103
|
+
const nested = getIssueProp(issue, "issue");
|
|
104
|
+
if (nested)
|
|
105
|
+
issues.push(...extractIssuesFromParseIssue(nested, newPath));
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case "Composite": {
|
|
109
|
+
const rawIssues = getIssueProp(issue, "issues");
|
|
110
|
+
const subIssues = rawIssues ? toArray(rawIssues) : [];
|
|
111
|
+
for (const subIssue of subIssues) {
|
|
112
|
+
issues.push(...extractIssuesFromParseIssue(subIssue, currentPath));
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case "Filter":
|
|
117
|
+
case "Encoding": {
|
|
118
|
+
const nested = getIssueProp(issue, "issue");
|
|
119
|
+
if (nested)
|
|
120
|
+
issues.push(...extractIssuesFromParseIssue(nested, currentPath));
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case "InvalidValue":
|
|
124
|
+
case "OneOf":
|
|
125
|
+
case "AnyOf": {
|
|
126
|
+
issues.push({
|
|
127
|
+
path: pathToString(currentPath),
|
|
128
|
+
message: getIssueProp(issue, "message") ?? "Invalid value",
|
|
129
|
+
constraint: "Value",
|
|
130
|
+
actual: truncateValue(getIssueProp(issue, "actual")),
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
default: {
|
|
135
|
+
const message = getIssueProp(issue, "message") ?? "Invalid value";
|
|
136
|
+
const constraint = extractConstraint(message);
|
|
137
|
+
issues.push({
|
|
138
|
+
path: pathToString(currentPath),
|
|
139
|
+
message,
|
|
140
|
+
...(constraint !== undefined && { constraint }),
|
|
141
|
+
...(getIssueProp(issue, "actual") !== undefined && {
|
|
142
|
+
actual: truncateValue(getIssueProp(issue, "actual")),
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return issues;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Convert Effect Schema ParseError to ValidationIssue array
|
|
152
|
+
*/
|
|
153
|
+
export const parseErrorToIssues = (error) => {
|
|
154
|
+
return extractIssuesFromParseIssue(error.issue);
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Create a single ValidationIssue from simple field validation
|
|
158
|
+
*/
|
|
159
|
+
export const makeIssue = (field, message, options) => {
|
|
160
|
+
const constraint = options?.constraint ?? extractConstraint(message);
|
|
161
|
+
return {
|
|
162
|
+
path: field.startsWith("$") ? field : `$.${field}`,
|
|
163
|
+
message,
|
|
164
|
+
...(constraint !== undefined && { constraint }),
|
|
165
|
+
...(options?.expected !== undefined && { expected: options.expected }),
|
|
166
|
+
...(options?.actual !== undefined && {
|
|
167
|
+
actual: truncateValue(options.actual),
|
|
168
|
+
}),
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Validation errors for webhook data with structured issues
|
|
173
|
+
*/
|
|
174
|
+
export class ValidationError extends Data.TaggedError("ValidationError") {
|
|
175
|
+
/**
|
|
176
|
+
* Format issues as a human-readable string
|
|
177
|
+
*/
|
|
178
|
+
format(options) {
|
|
179
|
+
const maxIssues = options?.maxIssues ?? 10;
|
|
180
|
+
const displayIssues = this.issues.slice(0, maxIssues);
|
|
181
|
+
const lines = displayIssues.map((issue) => {
|
|
182
|
+
let line = ` - ${issue.path}: ${issue.message}`;
|
|
183
|
+
if (issue.constraint) {
|
|
184
|
+
line += ` [${issue.constraint}]`;
|
|
185
|
+
}
|
|
186
|
+
return line;
|
|
187
|
+
});
|
|
188
|
+
if (this.issues.length > maxIssues) {
|
|
189
|
+
lines.push(` ... and ${this.issues.length - maxIssues} more issues`);
|
|
190
|
+
}
|
|
191
|
+
return `${this.message}\n${lines.join("\n")}`;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create ValidationError from Effect Schema ParseError
|
|
195
|
+
*/
|
|
196
|
+
static fromParseError(parseError, context) {
|
|
197
|
+
const issues = parseErrorToIssues(parseError);
|
|
198
|
+
const firstIssue = issues[0];
|
|
199
|
+
const message = issues.length === 1 && firstIssue
|
|
200
|
+
? firstIssue.message
|
|
201
|
+
: `Validation failed (${issues.length} issues)`;
|
|
202
|
+
return new ValidationError({
|
|
203
|
+
message,
|
|
204
|
+
issues,
|
|
205
|
+
...(context?.field !== undefined && { field: context.field }),
|
|
206
|
+
...(context?.value !== undefined && { value: context.value }),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Create ValidationError from a single issue
|
|
211
|
+
*/
|
|
212
|
+
static fromIssue(field, message, options) {
|
|
213
|
+
const issue = makeIssue(field, message, options);
|
|
214
|
+
return new ValidationError({
|
|
215
|
+
message,
|
|
216
|
+
issues: [issue],
|
|
217
|
+
field,
|
|
218
|
+
value: options?.actual,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Network-related errors
|
|
224
|
+
*/
|
|
225
|
+
export class NetworkError extends Data.TaggedError("NetworkError") {
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Rate limit errors
|
|
229
|
+
*/
|
|
230
|
+
export class RateLimitError extends Data.TaggedError("RateLimitError") {
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Configuration errors
|
|
234
|
+
*/
|
|
235
|
+
export class ConfigError extends Data.TaggedError("ConfigError") {
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* File-related errors
|
|
239
|
+
*/
|
|
240
|
+
export class FileError extends Data.TaggedError("FileError") {
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* HTTP errors with detailed response information
|
|
244
|
+
*/
|
|
245
|
+
export class HttpError extends Data.TaggedError("HttpError") {
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Create a readable message for any webhook error.
|
|
249
|
+
*/
|
|
250
|
+
export const formatWebhookError = (error, options) => {
|
|
251
|
+
switch (error._tag) {
|
|
252
|
+
case "ValidationError":
|
|
253
|
+
return error.format(options);
|
|
254
|
+
case "RateLimitError":
|
|
255
|
+
return `${error.message} (retryAfter=${error.retryAfter}ms)`;
|
|
256
|
+
case "HttpError": {
|
|
257
|
+
const status = error.response?.status;
|
|
258
|
+
return status ? `${error.message} (status=${status})` : error.message;
|
|
259
|
+
}
|
|
260
|
+
default:
|
|
261
|
+
return error.message;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
/**
|
|
265
|
+
* Produce a structured log object for any webhook error.
|
|
266
|
+
*/
|
|
267
|
+
export const webhookErrorToLogObject = (error) => {
|
|
268
|
+
switch (error._tag) {
|
|
269
|
+
case "ValidationError":
|
|
270
|
+
return {
|
|
271
|
+
tag: error._tag,
|
|
272
|
+
message: error.message,
|
|
273
|
+
issues: error.issues,
|
|
274
|
+
field: error.field,
|
|
275
|
+
value: error.value,
|
|
276
|
+
};
|
|
277
|
+
case "RateLimitError":
|
|
278
|
+
return {
|
|
279
|
+
tag: error._tag,
|
|
280
|
+
message: error.message,
|
|
281
|
+
retryAfter: error.retryAfter,
|
|
282
|
+
limit: error.limit,
|
|
283
|
+
remaining: error.remaining,
|
|
284
|
+
reset: error.reset,
|
|
285
|
+
};
|
|
286
|
+
case "HttpError":
|
|
287
|
+
return {
|
|
288
|
+
tag: error._tag,
|
|
289
|
+
message: error.message,
|
|
290
|
+
request: error.request,
|
|
291
|
+
response: error.response,
|
|
292
|
+
};
|
|
293
|
+
case "NetworkError":
|
|
294
|
+
return {
|
|
295
|
+
tag: error._tag,
|
|
296
|
+
message: error.message,
|
|
297
|
+
statusCode: error.statusCode,
|
|
298
|
+
response: error.response,
|
|
299
|
+
};
|
|
300
|
+
case "ConfigError":
|
|
301
|
+
return {
|
|
302
|
+
tag: error._tag,
|
|
303
|
+
message: error.message,
|
|
304
|
+
parameter: error.parameter,
|
|
305
|
+
};
|
|
306
|
+
case "FileError":
|
|
307
|
+
return {
|
|
308
|
+
tag: error._tag,
|
|
309
|
+
message: error.message,
|
|
310
|
+
filename: error.filename,
|
|
311
|
+
size: error.size,
|
|
312
|
+
maxSize: error.maxSize,
|
|
313
|
+
};
|
|
314
|
+
default:
|
|
315
|
+
return {
|
|
316
|
+
tag: error._tag,
|
|
317
|
+
message: error.message,
|
|
318
|
+
cause: error.cause,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
//# sourceMappingURL=WebhookError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebhookError.js","sourceRoot":"","sources":["../../src/errors/WebhookError.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* @packageDocumentation
|
|
29
29
|
*/
|
|
30
30
|
/** Error types for handling webhook failures */
|
|
31
|
-
export { ConfigError, FileError, HttpError, type HttpErrorResponse, makeIssue, NetworkError, parseErrorToIssues, RateLimitError, ValidationError, type ValidationIssue, WebhookError, type WebhookErrors, } from "./errors";
|
|
31
|
+
export { ConfigError, FileError, formatWebhookError, HttpError, type HttpErrorResponse, makeIssue, NetworkError, parseErrorToIssues, RateLimitError, ValidationError, type ValidationIssue, webhookErrorToLogObject, WebhookError, type WebhookErrors, } from "./errors";
|
|
32
32
|
/**
|
|
33
33
|
* Configuration service and layers.
|
|
34
34
|
* Use makeConfigLayer for programmatic config or ConfigFromEnv for environment variables.
|
|
@@ -38,7 +38,11 @@ export { Config, ConfigFromEnv, makeConfig, makeConfigLayer, parseWebhookUrl, ty
|
|
|
38
38
|
* HTTP client service and layers.
|
|
39
39
|
* Provides fetch-based HTTP client with retry and rate limit support.
|
|
40
40
|
*/
|
|
41
|
-
export { createRetrySchedule, defaultRetryConfig, FetchHttpClient, HttpClient, HttpClientLive, type HttpRequest, type HttpResponse, makeHttpClientLayer, parseRateLimitHeaders, type RateLimitInfo, type RetryConfig, } from "./layers/HttpClient";
|
|
41
|
+
export { createRetrySchedule, defaultRetryConfig, FetchHttpClient, HttpClient, HttpClientLive, type HttpRequest, type HttpResponse, makeHttpClientLayer, makeTestHttpClient, parseRateLimitHeaders, type RateLimitInfo, type RetryConfig, } from "./layers/HttpClient";
|
|
42
|
+
/**
|
|
43
|
+
* Convenience layer to wire Config + HttpClient + WebhookService.
|
|
44
|
+
*/
|
|
45
|
+
export { makeDefaultLayer } from "./layers/Default";
|
|
42
46
|
/**
|
|
43
47
|
* Embed builder namespace.
|
|
44
48
|
* Pipe-first API for building Discord embed objects.
|
|
@@ -82,4 +86,4 @@ export * from "./schemas";
|
|
|
82
86
|
* Webhook service and module-level accessors.
|
|
83
87
|
* Use these with Effect.flatMap or Effect.gen for sending webhooks.
|
|
84
88
|
*/
|
|
85
|
-
export { deleteWebhook, getWebhook, makeWebhookService, modifyWebhook, sendWebhook, validateWebhook, WebhookService, WebhookServiceLive, } from "./services/WebhookService";
|
|
89
|
+
export { deleteWebhook, getWebhook, makeWebhookService, modifyWebhook, sendWebhook, sendWebhookRaw, validateWebhook, type SendWebhookRawResult, WebhookService, WebhookServiceLive, } from "./services/WebhookService";
|