@teever/ez-hook-effect 0.5.0 → 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 (56) hide show
  1. package/dist/errors/WebhookError.d.ts +295 -0
  2. package/dist/errors/WebhookError.js +322 -0
  3. package/dist/errors/WebhookError.js.map +1 -0
  4. package/dist/errors/index.d.ts +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 +89 -0
  8. package/dist/layers/Config.d.ts +48 -0
  9. package/dist/layers/Config.js +166 -0
  10. package/dist/layers/Config.js.map +1 -0
  11. package/dist/layers/Default.d.ts +6 -0
  12. package/dist/layers/Default.js +9 -0
  13. package/dist/layers/Default.js.map +1 -0
  14. package/dist/layers/HttpClient.d.ts +84 -0
  15. package/dist/layers/HttpClient.js +209 -0
  16. package/dist/layers/HttpClient.js.map +1 -0
  17. package/dist/layers/index.d.ts +2 -0
  18. package/dist/layers/index.js +3 -0
  19. package/dist/layers/index.js.map +1 -0
  20. package/dist/pipes/Embed.d.ts +51 -0
  21. package/dist/pipes/Embed.js +198 -0
  22. package/dist/pipes/Embed.js.map +1 -0
  23. package/dist/pipes/Webhook.d.ts +38 -0
  24. package/dist/pipes/Webhook.js +46 -0
  25. package/dist/pipes/Webhook.js.map +1 -0
  26. package/dist/pipes/index.d.ts +2 -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 +10 -0
  30. package/dist/schemas/Common.js +30 -0
  31. package/dist/schemas/Common.js.map +1 -0
  32. package/dist/schemas/Discord.d.ts +16 -0
  33. package/dist/schemas/Discord.js +19 -0
  34. package/dist/schemas/Discord.js.map +1 -0
  35. package/dist/schemas/Embed.d.ts +143 -0
  36. package/dist/schemas/Embed.js +139 -0
  37. package/dist/schemas/Embed.js.map +1 -0
  38. package/dist/schemas/Field.d.ts +24 -0
  39. package/dist/schemas/Field.js +25 -0
  40. package/dist/schemas/Field.js.map +1 -0
  41. package/dist/schemas/Webhook.d.ts +88 -0
  42. package/dist/schemas/Webhook.js +87 -0
  43. package/dist/schemas/Webhook.js.map +1 -0
  44. package/dist/schemas/index.d.ts +5 -0
  45. package/dist/schemas/index.js +6 -0
  46. package/dist/schemas/index.js.map +1 -0
  47. package/dist/services/WebhookService.d.ts +94 -0
  48. package/dist/services/WebhookService.js +116 -0
  49. package/dist/services/WebhookService.js.map +1 -0
  50. package/dist/services/index.d.ts +1 -0
  51. package/dist/services/index.js +2 -0
  52. package/dist/services/index.js.map +1 -0
  53. package/dist/utils/normalize.d.ts +1 -0
  54. package/dist/utils/normalize.js +17 -0
  55. package/dist/utils/normalize.js.map +1 -0
  56. package/package.json +3 -2
@@ -0,0 +1,89 @@
1
+ /**
2
+ * ez-hook-effect - Discord webhook library built with Effect
3
+ *
4
+ * Type-safe, composable, and resilient Discord webhook client.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { Webhook, Embed, sendWebhook, WebhookServiceLive, makeConfigLayer, HttpClientLive } from "ez-hook-effect";
9
+ * import { Effect, Layer, pipe } from "effect";
10
+ *
11
+ * const webhook = pipe(
12
+ * Webhook.make,
13
+ * Webhook.setContent("Hello from Effect!"),
14
+ * Webhook.build
15
+ * );
16
+ *
17
+ * const layer = WebhookServiceLive.pipe(
18
+ * Layer.provide(makeConfigLayer("https://discord.com/api/webhooks/...")),
19
+ * Layer.provide(HttpClientLive)
20
+ * );
21
+ *
22
+ * Effect.gen(function* () {
23
+ * const msg = yield* webhook;
24
+ * yield* sendWebhook(msg);
25
+ * }).pipe(Effect.provide(layer), Effect.runPromise);
26
+ * ```
27
+ *
28
+ * @packageDocumentation
29
+ */
30
+ /** Error types for handling webhook failures */
31
+ export { ConfigError, FileError, formatWebhookError, HttpError, type HttpErrorResponse, makeIssue, NetworkError, parseErrorToIssues, RateLimitError, ValidationError, type ValidationIssue, webhookErrorToLogObject, WebhookError, type WebhookErrors, } from "./errors";
32
+ /**
33
+ * Configuration service and layers.
34
+ * Use makeConfigLayer for programmatic config or ConfigFromEnv for environment variables.
35
+ */
36
+ export { Config, ConfigFromEnv, makeConfig, makeConfigLayer, parseWebhookUrl, type WebhookConfig, } from "./layers/Config";
37
+ /**
38
+ * HTTP client service and layers.
39
+ * Provides fetch-based HTTP client with retry and rate limit support.
40
+ */
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";
46
+ /**
47
+ * Embed builder namespace.
48
+ * Pipe-first API for building Discord embed objects.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * import { Embed } from "ez-hook-effect";
53
+ * import { pipe } from "effect";
54
+ *
55
+ * const embed = pipe(
56
+ * Embed.make,
57
+ * Embed.setTitle("Hello"),
58
+ * Embed.setDescription("World"),
59
+ * Embed.setColor("#5865F2"),
60
+ * Embed.build
61
+ * );
62
+ * ```
63
+ */
64
+ export * as Embed from "./pipes/Embed";
65
+ /**
66
+ * Webhook builder namespace.
67
+ * Pipe-first API for building Discord webhook payloads.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * import { Webhook } from "ez-hook-effect";
72
+ * import { pipe } from "effect";
73
+ *
74
+ * const webhook = pipe(
75
+ * Webhook.make,
76
+ * Webhook.setUsername("Bot"),
77
+ * Webhook.setContent("Hello!"),
78
+ * Webhook.build
79
+ * );
80
+ * ```
81
+ */
82
+ export * as Webhook from "./pipes/Webhook";
83
+ /** Schema types for Discord webhook payloads */
84
+ export * from "./schemas";
85
+ /**
86
+ * Webhook service and module-level accessors.
87
+ * Use these with Effect.flatMap or Effect.gen for sending webhooks.
88
+ */
89
+ export { deleteWebhook, getWebhook, makeWebhookService, modifyWebhook, sendWebhook, sendWebhookRaw, validateWebhook, type SendWebhookRawResult, WebhookService, WebhookServiceLive, } from "./services/WebhookService";
@@ -0,0 +1,48 @@
1
+ import { Effect, Layer, ServiceMap } from "effect";
2
+ import { ConfigError } from "../errors";
3
+ /**
4
+ * Webhook configuration
5
+ */
6
+ export interface WebhookConfig {
7
+ readonly webhookUrl: string;
8
+ readonly maxRetries?: number;
9
+ readonly baseDelayMs?: number;
10
+ readonly maxDelayMs?: number;
11
+ readonly enableJitter?: boolean;
12
+ }
13
+ declare const Config_base: ServiceMap.ServiceClass<Config, "Config", {
14
+ readonly webhook: WebhookConfig;
15
+ }>;
16
+ /**
17
+ * Config service tag
18
+ */
19
+ export declare class Config extends Config_base {
20
+ }
21
+ /**
22
+ * Create configuration from webhook URL
23
+ */
24
+ export declare const makeConfig: (webhookUrl: string, options?: Partial<WebhookConfig>) => Effect.Effect<{
25
+ webhook: {
26
+ webhookUrl: string;
27
+ maxRetries: number;
28
+ baseDelayMs: number;
29
+ maxDelayMs: number;
30
+ enableJitter: boolean;
31
+ };
32
+ }, ConfigError, never>;
33
+ /**
34
+ * Configuration layer from webhook URL
35
+ */
36
+ export declare const makeConfigLayer: (webhookUrl: string, options?: Partial<WebhookConfig>) => Layer.Layer<Config, ConfigError, never>;
37
+ /**
38
+ * Configuration layer from environment variables
39
+ */
40
+ export declare const ConfigFromEnv: Layer.Layer<Config, ConfigError, never>;
41
+ /**
42
+ * Extract webhook ID and token from URL
43
+ */
44
+ export declare const parseWebhookUrl: (url: string) => Effect.Effect<{
45
+ id: string;
46
+ token: string;
47
+ }, ConfigError>;
48
+ export {};
@@ -0,0 +1,166 @@
1
+ import { Effect, Layer, ServiceMap } from "effect";
2
+ import { ConfigError } from "../errors";
3
+ import { DISCORD_WEBHOOK_REGEX } from "../schemas/Discord";
4
+ /**
5
+ * Config service tag
6
+ */
7
+ export class Config extends ServiceMap.Service()("Config") {
8
+ }
9
+ /**
10
+ * Validate webhook URL format with detailed error messages
11
+ */
12
+ const validateWebhookUrl = (url) => {
13
+ if (!url || url.trim() === "") {
14
+ return Effect.fail(new ConfigError({
15
+ message: "Webhook URL is empty. Please provide a valid Discord webhook URL.\n" +
16
+ "Format: https://discord.com/api/webhooks/{webhook_id}/{webhook_token}\n" +
17
+ "You can create a webhook in Discord: Server Settings > Integrations > Webhooks",
18
+ parameter: "webhookUrl",
19
+ }));
20
+ }
21
+ if (!url.startsWith("https://")) {
22
+ return Effect.fail(new ConfigError({
23
+ message: "Webhook URL must use HTTPS protocol.\n" +
24
+ `Received: ${url.substring(0, 50)}${url.length > 50 ? "..." : ""}\n` +
25
+ "Expected format: https://discord.com/api/webhooks/{webhook_id}/{webhook_token}",
26
+ parameter: "webhookUrl",
27
+ }));
28
+ }
29
+ if (!DISCORD_WEBHOOK_REGEX.test(url)) {
30
+ const isDiscordDomain = url.includes("discord.com") || url.includes("discordapp.com");
31
+ const hasWebhooksPath = url.includes("/webhooks/");
32
+ let hint = "";
33
+ if (!isDiscordDomain) {
34
+ hint = "URL must be from discord.com or discordapp.com domain.";
35
+ }
36
+ else if (!hasWebhooksPath) {
37
+ hint = "URL must include /api/webhooks/ path.";
38
+ }
39
+ else {
40
+ hint =
41
+ "URL must include both webhook ID (numeric) and token after /webhooks/.";
42
+ }
43
+ return Effect.fail(new ConfigError({
44
+ message: `Invalid Discord webhook URL format.\n` +
45
+ `${hint}\n` +
46
+ `Received: ${url.substring(0, 80)}${url.length > 80 ? "..." : ""}\n` +
47
+ `Expected format: https://discord.com/api/webhooks/{webhook_id}/{webhook_token}`,
48
+ parameter: "webhookUrl",
49
+ }));
50
+ }
51
+ return Effect.succeed(url);
52
+ };
53
+ /**
54
+ * Validate retry configuration options
55
+ */
56
+ const validateRetryOptions = (options) => {
57
+ const errors = [];
58
+ if (options?.maxRetries !== undefined) {
59
+ if (!Number.isInteger(options.maxRetries) || options.maxRetries < 0) {
60
+ errors.push(`maxRetries must be a non-negative integer (received: ${options.maxRetries})`);
61
+ }
62
+ if (options.maxRetries > 10) {
63
+ errors.push(`maxRetries should not exceed 10 to avoid excessive retries (received: ${options.maxRetries})`);
64
+ }
65
+ }
66
+ if (options?.baseDelayMs !== undefined) {
67
+ if (!Number.isInteger(options.baseDelayMs) || options.baseDelayMs < 0) {
68
+ errors.push(`baseDelayMs must be a non-negative integer (received: ${options.baseDelayMs})`);
69
+ }
70
+ if (options.baseDelayMs > 60000) {
71
+ errors.push(`baseDelayMs should not exceed 60000ms (received: ${options.baseDelayMs})`);
72
+ }
73
+ }
74
+ if (options?.maxDelayMs !== undefined) {
75
+ if (!Number.isInteger(options.maxDelayMs) || options.maxDelayMs < 0) {
76
+ errors.push(`maxDelayMs must be a non-negative integer (received: ${options.maxDelayMs})`);
77
+ }
78
+ if (options.baseDelayMs !== undefined &&
79
+ options.maxDelayMs < options.baseDelayMs) {
80
+ errors.push(`maxDelayMs (${options.maxDelayMs}) must be >= baseDelayMs (${options.baseDelayMs})`);
81
+ }
82
+ }
83
+ if (errors.length > 0) {
84
+ return Effect.fail(new ConfigError({
85
+ message: `Invalid retry configuration:\n${errors.map((e) => ` - ${e}`).join("\n")}`,
86
+ parameter: "retryConfig",
87
+ }));
88
+ }
89
+ return Effect.succeed(options);
90
+ };
91
+ /**
92
+ * Create configuration from webhook URL
93
+ */
94
+ export const makeConfig = (webhookUrl, options) => Effect.gen(function* () {
95
+ const validatedUrl = yield* validateWebhookUrl(webhookUrl);
96
+ yield* validateRetryOptions(options);
97
+ return {
98
+ webhook: {
99
+ webhookUrl: validatedUrl,
100
+ maxRetries: options?.maxRetries ?? 3,
101
+ baseDelayMs: options?.baseDelayMs ?? 1000,
102
+ maxDelayMs: options?.maxDelayMs ?? 60000,
103
+ enableJitter: options?.enableJitter ?? true,
104
+ },
105
+ };
106
+ });
107
+ /**
108
+ * Configuration layer from webhook URL
109
+ */
110
+ export const makeConfigLayer = (webhookUrl, options) => Layer.effect(Config, makeConfig(webhookUrl, options));
111
+ /**
112
+ * Configuration layer from environment variables
113
+ */
114
+ export const ConfigFromEnv = Layer.effect(Config, Effect.gen(function* () {
115
+ const rawWebhookUrl = yield* Effect.sync(() => process.env.DISCORD_WEBHOOK_URL ?? "");
116
+ if (!rawWebhookUrl) {
117
+ return yield* Effect.fail(new ConfigError({
118
+ message: "DISCORD_WEBHOOK_URL environment variable not set.\n" +
119
+ "Please set DISCORD_WEBHOOK_URL in your environment or .env file.\n" +
120
+ "See .env.example for all available configuration options.",
121
+ parameter: "DISCORD_WEBHOOK_URL",
122
+ }));
123
+ }
124
+ const webhookUrl = yield* validateWebhookUrl(rawWebhookUrl);
125
+ const maxRetries = yield* Effect.sync(() => {
126
+ const v = process.env.WEBHOOK_MAX_RETRIES;
127
+ return v ? Number.parseInt(v, 10) : 3;
128
+ });
129
+ const baseDelayMs = yield* Effect.sync(() => {
130
+ const v = process.env.WEBHOOK_BASE_DELAY_MS;
131
+ return v ? Number.parseInt(v, 10) : 1000;
132
+ });
133
+ const maxDelayMs = yield* Effect.sync(() => {
134
+ const v = process.env.WEBHOOK_MAX_DELAY_MS;
135
+ return v ? Number.parseInt(v, 10) : 60000;
136
+ });
137
+ const enableJitter = yield* Effect.sync(() => {
138
+ const v = process.env.WEBHOOK_ENABLE_JITTER;
139
+ return v ? v === "true" : true;
140
+ });
141
+ yield* validateRetryOptions({ maxRetries, baseDelayMs, maxDelayMs });
142
+ return {
143
+ webhook: {
144
+ webhookUrl,
145
+ maxRetries,
146
+ baseDelayMs,
147
+ maxDelayMs,
148
+ enableJitter,
149
+ },
150
+ };
151
+ }));
152
+ /**
153
+ * Extract webhook ID and token from URL
154
+ */
155
+ export const parseWebhookUrl = (url) => Effect.gen(function* () {
156
+ const match = url.match(DISCORD_WEBHOOK_REGEX);
157
+ if (!match?.groups?.id || !match.groups.token) {
158
+ return yield* Effect.fail(new ConfigError({
159
+ message: "Invalid webhook URL format",
160
+ parameter: "webhookUrl",
161
+ }));
162
+ }
163
+ const { id, token } = match.groups;
164
+ return { id, token };
165
+ });
166
+ //# sourceMappingURL=Config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Config.js","sourceRoot":"","sources":["../../src/layers/Config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Layer } from "effect";
2
+ import { type WebhookConfig } from "./Config";
3
+ /**
4
+ * Convenience layer that wires Config + HttpClient + WebhookService.
5
+ */
6
+ export declare const makeDefaultLayer: (url: string, options?: Partial<WebhookConfig>) => Layer.Layer<import("..").WebhookService, import("..").ConfigError, never>;
@@ -0,0 +1,9 @@
1
+ import { Layer } from "effect";
2
+ import { WebhookServiceLive } from "../services/WebhookService";
3
+ import { makeConfigLayer } from "./Config";
4
+ import { HttpClientLive } from "./HttpClient";
5
+ /**
6
+ * Convenience layer that wires Config + HttpClient + WebhookService.
7
+ */
8
+ export const makeDefaultLayer = (url, options) => WebhookServiceLive.pipe(Layer.provide(makeConfigLayer(url, options)), Layer.provide(HttpClientLive));
9
+ //# sourceMappingURL=Default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Default.js","sourceRoot":"","sources":["../../src/layers/Default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAsB,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,GAAW,EACX,OAAgC,EAC/B,EAAE,CACH,kBAAkB,CAAC,IAAI,CACtB,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,EAC5C,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAC7B,CAAC"}
@@ -0,0 +1,84 @@
1
+ import { Duration, Effect, Layer, Schedule, ServiceMap } from "effect";
2
+ import { HttpError, NetworkError, RateLimitError } from "../errors";
3
+ /**
4
+ * HTTP request configuration
5
+ */
6
+ export interface HttpRequest {
7
+ method: "GET" | "POST" | "PATCH" | "DELETE";
8
+ url: string;
9
+ headers?: Record<string, string>;
10
+ body?: unknown;
11
+ timeout?: Duration.Duration;
12
+ }
13
+ /**
14
+ * HTTP response
15
+ */
16
+ export interface HttpResponse {
17
+ status: number;
18
+ statusText: string;
19
+ headers: Record<string, string>;
20
+ body: unknown;
21
+ text: string;
22
+ }
23
+ /**
24
+ * Retry configuration for HTTP requests
25
+ */
26
+ export interface RetryConfig {
27
+ maxRetries: number;
28
+ baseDelay: Duration.Duration;
29
+ maxDelay: Duration.Duration;
30
+ jitter: boolean;
31
+ }
32
+ declare const HttpClient_base: ServiceMap.ServiceClass<HttpClient, "HttpClient", {
33
+ readonly request: (request: HttpRequest) => Effect.Effect<HttpResponse, HttpError | NetworkError | RateLimitError>;
34
+ readonly retryConfig: RetryConfig;
35
+ }>;
36
+ /**
37
+ * HTTP Client service tag
38
+ */
39
+ export declare class HttpClient extends HttpClient_base {
40
+ }
41
+ /**
42
+ * Parse rate limit headers from Discord API response
43
+ */
44
+ export interface RateLimitInfo {
45
+ /** Retry after in milliseconds */
46
+ retryAfter: number;
47
+ /** Total rate limit for this endpoint */
48
+ limit?: number;
49
+ /** Remaining requests before rate limit */
50
+ remaining?: number;
51
+ /** When the rate limit resets */
52
+ reset?: Date;
53
+ /** Whether this is a global rate limit */
54
+ global?: boolean;
55
+ }
56
+ /**
57
+ * Parse rate limit information from response headers
58
+ */
59
+ export declare const parseRateLimitHeaders: (headers: Record<string, string>) => RateLimitInfo | null;
60
+ /**
61
+ * Default retry configuration
62
+ */
63
+ export declare const defaultRetryConfig: RetryConfig;
64
+ /**
65
+ * Create retry schedule based on configuration
66
+ */
67
+ export declare const createRetrySchedule: (config: RetryConfig) => Schedule.Schedule<Duration.Duration, unknown, never, never>;
68
+ /**
69
+ * Fetch-based HTTP client implementation
70
+ */
71
+ export declare const FetchHttpClient: (retryConfig?: RetryConfig) => ServiceMap.Service.Shape<typeof HttpClient>;
72
+ /**
73
+ * Live HTTP client layer with default configuration
74
+ */
75
+ export declare const HttpClientLive: Layer.Layer<HttpClient, never, never>;
76
+ /**
77
+ * HTTP client layer with custom retry configuration
78
+ */
79
+ export declare const makeHttpClientLayer: (retryConfig: Partial<RetryConfig>) => Layer.Layer<HttpClient, never, never>;
80
+ /**
81
+ * Test HTTP client layer for deterministic unit tests.
82
+ */
83
+ export declare const makeTestHttpClient: (resolver: (request: HttpRequest) => Effect.Effect<HttpResponse, NetworkError | HttpError | RateLimitError>, retryConfig?: RetryConfig) => Layer.Layer<HttpClient, never, never>;
84
+ export {};
@@ -0,0 +1,209 @@
1
+ import { Duration, Effect, Layer, Schedule, ServiceMap } from "effect";
2
+ import { HttpError, NetworkError, RateLimitError } from "../errors";
3
+ /**
4
+ * HTTP Client service tag
5
+ */
6
+ export class HttpClient extends ServiceMap.Service()("HttpClient") {
7
+ }
8
+ /**
9
+ * Parse rate limit information from response headers
10
+ */
11
+ export const parseRateLimitHeaders = (headers) => {
12
+ const retryAfterHeader = headers["retry-after"];
13
+ const rateLimitRemaining = headers["x-ratelimit-remaining"];
14
+ // Check if we have rate limit info
15
+ if (!retryAfterHeader && rateLimitRemaining !== "0") {
16
+ return null;
17
+ }
18
+ // Parse retry-after (Discord sends this in seconds)
19
+ let retryAfter = 0;
20
+ if (retryAfterHeader) {
21
+ const parsed = Number.parseFloat(retryAfterHeader);
22
+ if (!Number.isNaN(parsed)) {
23
+ // Discord sends seconds, convert to milliseconds
24
+ retryAfter = Math.ceil(parsed * 1000);
25
+ }
26
+ }
27
+ // Parse other rate limit headers
28
+ const limit = headers["x-ratelimit-limit"];
29
+ const remaining = headers["x-ratelimit-remaining"];
30
+ const resetHeader = headers["x-ratelimit-reset"];
31
+ const resetAfterHeader = headers["x-ratelimit-reset-after"];
32
+ const globalHeader = headers["x-ratelimit-global"];
33
+ let reset;
34
+ if (resetHeader) {
35
+ const resetTimestamp = Number.parseFloat(resetHeader);
36
+ if (!Number.isNaN(resetTimestamp)) {
37
+ reset = new Date(resetTimestamp * 1000);
38
+ }
39
+ }
40
+ else if (resetAfterHeader) {
41
+ const resetAfter = Number.parseFloat(resetAfterHeader);
42
+ if (!Number.isNaN(resetAfter)) {
43
+ reset = new Date(Date.now() + resetAfter * 1000);
44
+ }
45
+ }
46
+ // If we still don't have retryAfter, calculate from reset
47
+ if (retryAfter === 0 && reset) {
48
+ retryAfter = Math.max(0, reset.getTime() - Date.now());
49
+ }
50
+ // Default to 1 second if we have no timing info
51
+ if (retryAfter === 0) {
52
+ retryAfter = 1000;
53
+ }
54
+ return {
55
+ retryAfter,
56
+ ...(limit && { limit: Number.parseInt(limit, 10) }),
57
+ ...(remaining && { remaining: Number.parseInt(remaining, 10) }),
58
+ ...(reset && { reset }),
59
+ global: globalHeader === "true",
60
+ };
61
+ };
62
+ /**
63
+ * Default retry configuration
64
+ */
65
+ export const defaultRetryConfig = {
66
+ maxRetries: 3,
67
+ baseDelay: Duration.seconds(1),
68
+ maxDelay: Duration.seconds(60),
69
+ jitter: true,
70
+ };
71
+ /**
72
+ * Create retry schedule based on configuration
73
+ */
74
+ export const createRetrySchedule = (config) => {
75
+ const capDelay = (delay) => Duration.isLessThanOrEqualTo(delay, config.maxDelay)
76
+ ? delay
77
+ : config.maxDelay;
78
+ // Exponential backoff with optional jitter
79
+ let policy = Schedule.exponential(config.baseDelay, 2);
80
+ if (config.jitter) {
81
+ policy = policy.pipe(Schedule.modifyDelay((_, delay) => Effect.sync(() => {
82
+ const millis = Duration.toMillis(delay);
83
+ return Duration.millis(millis + Math.random() * millis);
84
+ })));
85
+ }
86
+ // Cap delay to maxDelay
87
+ policy = policy.pipe(Schedule.modifyDelay((_, delay) => Effect.succeed(capDelay(delay))));
88
+ // Apply a max retry cap while keeping output as Duration
89
+ const capped = Schedule.both(policy, Schedule.recurs(config.maxRetries));
90
+ return capped.pipe(Schedule.map(([delay]) => Effect.succeed(delay)));
91
+ };
92
+ // (Note) Rate limit parsing is now handled via parseRateLimitHeaders
93
+ // and returns RateLimitError for 429 responses.
94
+ /**
95
+ * Fetch-based HTTP client implementation
96
+ */
97
+ export const FetchHttpClient = (retryConfig = defaultRetryConfig) => ({
98
+ retryConfig,
99
+ request: (request) => Effect.gen(function* () {
100
+ const controller = new AbortController();
101
+ const timeout = request.timeout
102
+ ? setTimeout(() => controller.abort(), Duration.toMillis(request.timeout))
103
+ : undefined;
104
+ // Build headers as a real `Headers` instance so downstream
105
+ // code can reliably use `get()` in tests and callers.
106
+ const requestHeaders = new Headers({
107
+ "Content-Type": "application/json",
108
+ });
109
+ for (const [key, value] of Object.entries(request.headers ?? {})) {
110
+ requestHeaders.set(key, value);
111
+ }
112
+ const response = yield* Effect.tryPromise({
113
+ try: () => fetch(request.url, {
114
+ method: request.method,
115
+ headers: requestHeaders,
116
+ body: request.body ? JSON.stringify(request.body) : undefined,
117
+ signal: controller.signal,
118
+ }),
119
+ catch: (error) => new NetworkError({
120
+ message: `Network request failed: ${error instanceof Error ? error.message : String(error)}`,
121
+ statusCode: 0,
122
+ }),
123
+ });
124
+ if (timeout)
125
+ clearTimeout(timeout);
126
+ // Read response body as text; handle odd mocks that return a function
127
+ // by invoking it to retrieve the actual string.
128
+ const rawTextOrFn = yield* Effect.tryPromise({
129
+ try: () => response.text(),
130
+ catch: () => new NetworkError({ message: "Failed to read response body" }),
131
+ });
132
+ const text = typeof rawTextOrFn === "function"
133
+ ? yield* Effect.tryPromise({
134
+ try: () => rawTextOrFn(),
135
+ catch: () => new NetworkError({ message: "Failed to read response body" }),
136
+ })
137
+ : String(rawTextOrFn ?? "");
138
+ const headers = {};
139
+ response.headers.forEach((value, key) => {
140
+ headers[key.toLowerCase()] = value;
141
+ });
142
+ let body = text;
143
+ if (headers["content-type"]?.includes("application/json") && text) {
144
+ try {
145
+ body = JSON.parse(text);
146
+ }
147
+ catch {
148
+ // Keep as text if JSON parsing fails
149
+ }
150
+ }
151
+ const httpResponse = {
152
+ status: response.status,
153
+ statusText: response.statusText,
154
+ headers,
155
+ body,
156
+ text,
157
+ };
158
+ // Handle HTTP errors
159
+ if (!response.ok) {
160
+ // Handle rate limiting (429) with specific RateLimitError
161
+ if (response.status === 429) {
162
+ const rateLimitInfo = parseRateLimitHeaders(headers);
163
+ return yield* Effect.fail(new RateLimitError({
164
+ message: `Rate limited: retry after ${rateLimitInfo?.retryAfter ?? 1000}ms`,
165
+ retryAfter: rateLimitInfo?.retryAfter ?? 1000,
166
+ ...(rateLimitInfo?.limit !== undefined && {
167
+ limit: rateLimitInfo.limit,
168
+ }),
169
+ ...(rateLimitInfo?.remaining !== undefined && {
170
+ remaining: rateLimitInfo.remaining,
171
+ }),
172
+ ...(rateLimitInfo?.reset !== undefined && {
173
+ reset: rateLimitInfo.reset,
174
+ }),
175
+ }));
176
+ }
177
+ return yield* Effect.fail(new HttpError({
178
+ message: `HTTP ${response.status}: ${response.statusText}`,
179
+ request: {
180
+ method: request.method,
181
+ url: request.url,
182
+ },
183
+ response: {
184
+ status: response.status,
185
+ statusText: response.statusText,
186
+ headers,
187
+ body,
188
+ },
189
+ }));
190
+ }
191
+ return httpResponse;
192
+ }),
193
+ });
194
+ /**
195
+ * Live HTTP client layer with default configuration
196
+ */
197
+ export const HttpClientLive = Layer.succeed(HttpClient, FetchHttpClient());
198
+ /**
199
+ * HTTP client layer with custom retry configuration
200
+ */
201
+ export const makeHttpClientLayer = (retryConfig) => Layer.succeed(HttpClient, FetchHttpClient({ ...defaultRetryConfig, ...retryConfig }));
202
+ /**
203
+ * Test HTTP client layer for deterministic unit tests.
204
+ */
205
+ export const makeTestHttpClient = (resolver, retryConfig = defaultRetryConfig) => Layer.succeed(HttpClient, {
206
+ request: resolver,
207
+ retryConfig,
208
+ });
209
+ //# sourceMappingURL=HttpClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/layers/HttpClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from "./Config";
2
+ export * from "./HttpClient";
@@ -0,0 +1,3 @@
1
+ export * from "./Config";
2
+ export * from "./HttpClient";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/layers/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC"}