@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.
Files changed (54) hide show
  1. package/README.md +88 -10
  2. package/dist/errors/WebhookError.d.ts +142 -3
  3. package/dist/errors/WebhookError.js +322 -0
  4. package/dist/errors/WebhookError.js.map +1 -0
  5. package/dist/errors/index.js +2 -0
  6. package/dist/errors/index.js.map +1 -0
  7. package/dist/index.d.ts +7 -3
  8. package/dist/index.js +493 -264
  9. package/dist/index.js.map +16 -14
  10. package/dist/layers/Config.d.ts +3 -3
  11. package/dist/layers/Config.js +166 -0
  12. package/dist/layers/Config.js.map +1 -0
  13. package/dist/layers/Default.d.ts +6 -0
  14. package/dist/layers/Default.js +9 -0
  15. package/dist/layers/Default.js.map +1 -0
  16. package/dist/layers/HttpClient.d.ts +8 -4
  17. package/dist/layers/HttpClient.js +209 -0
  18. package/dist/layers/HttpClient.js.map +1 -0
  19. package/dist/layers/index.js +3 -0
  20. package/dist/layers/index.js.map +1 -0
  21. package/dist/pipes/Embed.d.ts +2 -2
  22. package/dist/pipes/Embed.js +198 -0
  23. package/dist/pipes/Embed.js.map +1 -0
  24. package/dist/pipes/Webhook.d.ts +3 -2
  25. package/dist/pipes/Webhook.js +46 -0
  26. package/dist/pipes/Webhook.js.map +1 -0
  27. package/dist/pipes/index.js +3 -0
  28. package/dist/pipes/index.js.map +1 -0
  29. package/dist/schemas/Common.d.ts +6 -6
  30. package/dist/schemas/Common.js +30 -0
  31. package/dist/schemas/Common.js.map +1 -0
  32. package/dist/schemas/Discord.d.ts +1 -1
  33. package/dist/schemas/Discord.js +19 -0
  34. package/dist/schemas/Discord.js.map +1 -0
  35. package/dist/schemas/Embed.d.ts +58 -229
  36. package/dist/schemas/Embed.js +139 -0
  37. package/dist/schemas/Embed.js.map +1 -0
  38. package/dist/schemas/Field.d.ts +6 -27
  39. package/dist/schemas/Field.js +25 -0
  40. package/dist/schemas/Field.js.map +1 -0
  41. package/dist/schemas/Webhook.d.ts +42 -160
  42. package/dist/schemas/Webhook.js +87 -0
  43. package/dist/schemas/Webhook.js.map +1 -0
  44. package/dist/schemas/index.js +6 -0
  45. package/dist/schemas/index.js.map +1 -0
  46. package/dist/services/WebhookService.d.ts +27 -5
  47. package/dist/services/WebhookService.js +116 -0
  48. package/dist/services/WebhookService.js.map +1 -0
  49. package/dist/services/index.js +2 -0
  50. package/dist/services/index.js.map +1 -0
  51. package/dist/utils/normalize.d.ts +1 -0
  52. package/dist/utils/normalize.js +17 -0
  53. package/dist/utils/normalize.js.map +1 -0
  54. 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, Layer, pipe } from 'effect'
29
- import { sendWebhook, makeConfigLayer, HttpClientLive, WebhookServiceLive, Webhook } from '@teever/ez-hook-effect'
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 layers
35
- const AppLayer = WebhookServiceLive.pipe(
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(program, AppLayer))
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. You only need to handle errors that persist after retries are exhausted:
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 ParseResult } from "effect";
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: ParseResult.ParseError) => ValidationIssue[];
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: ParseResult.ParseError, context?: {
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,2 @@
1
+ export * from "./WebhookError";
2
+ //# sourceMappingURL=index.js.map
@@ -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";