@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
@@ -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"}
@@ -1,4 +1,4 @@
1
- import { Context, Duration, Effect, Layer, Schedule } from "effect";
1
+ import { Duration, Effect, Layer, Schedule, ServiceMap } from "effect";
2
2
  import { HttpError, NetworkError, RateLimitError } from "../errors";
3
3
  /**
4
4
  * HTTP request configuration
@@ -29,7 +29,7 @@ export interface RetryConfig {
29
29
  maxDelay: Duration.Duration;
30
30
  jitter: boolean;
31
31
  }
32
- declare const HttpClient_base: Context.TagClass<HttpClient, "HttpClient", {
32
+ declare const HttpClient_base: ServiceMap.ServiceClass<HttpClient, "HttpClient", {
33
33
  readonly request: (request: HttpRequest) => Effect.Effect<HttpResponse, HttpError | NetworkError | RateLimitError>;
34
34
  readonly retryConfig: RetryConfig;
35
35
  }>;
@@ -64,11 +64,11 @@ export declare const defaultRetryConfig: RetryConfig;
64
64
  /**
65
65
  * Create retry schedule based on configuration
66
66
  */
67
- export declare const createRetrySchedule: (config: RetryConfig) => Schedule.Schedule<Duration.Duration, unknown, never>;
67
+ export declare const createRetrySchedule: (config: RetryConfig) => Schedule.Schedule<Duration.Duration, unknown, never, never>;
68
68
  /**
69
69
  * Fetch-based HTTP client implementation
70
70
  */
71
- export declare const FetchHttpClient: (retryConfig?: RetryConfig) => Context.Tag.Service<typeof HttpClient>;
71
+ export declare const FetchHttpClient: (retryConfig?: RetryConfig) => ServiceMap.Service.Shape<typeof HttpClient>;
72
72
  /**
73
73
  * Live HTTP client layer with default configuration
74
74
  */
@@ -77,4 +77,8 @@ export declare const HttpClientLive: Layer.Layer<HttpClient, never, never>;
77
77
  * HTTP client layer with custom retry configuration
78
78
  */
79
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>;
80
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,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"}
@@ -6,8 +6,8 @@ export declare const addFieldImpl: (fieldOrName: Field | string, value?: string,
6
6
  fields: Field[];
7
7
  url?: string;
8
8
  title?: string;
9
- description?: string;
10
9
  type?: "rich";
10
+ description?: string;
11
11
  timestamp?: string;
12
12
  color?: number;
13
13
  footer?: Footer;
@@ -22,8 +22,8 @@ export declare const addFieldDirect: (fieldOrName: Field | string, value?: strin
22
22
  fields: Field[];
23
23
  url?: string;
24
24
  title?: string;
25
- description?: string;
26
25
  type?: "rich";
26
+ description?: string;
27
27
  timestamp?: string;
28
28
  color?: number;
29
29
  footer?: Footer;