@upyo/resend 0.5.0-dev.136 → 0.5.0-dev.156

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,3 +1,27 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const __upyo_core = __toESM(require("@upyo/core"));
1
25
 
2
26
  //#region src/config.ts
3
27
  /**
@@ -25,14 +49,37 @@ function createResendConfig(config) {
25
49
  //#endregion
26
50
  //#region src/http-client.ts
27
51
  /**
28
- * Resend API error class for handling API-specific errors.
52
+ * Error thrown when a Resend API request fails.
53
+ *
54
+ * @since 0.5.0
29
55
  */
30
56
  var ResendApiError = class extends Error {
57
+ /**
58
+ * HTTP status code returned by Resend, if the request reached the API.
59
+ */
31
60
  statusCode;
32
- constructor(message, statusCode) {
61
+ /**
62
+ * Retry delay from Resend's `Retry-After` response header.
63
+ */
64
+ retryAfterMilliseconds;
65
+ /**
66
+ * Number of attempts made before this error was produced.
67
+ */
68
+ attempts;
69
+ /**
70
+ * Creates a Resend API error.
71
+ *
72
+ * @param message Error message.
73
+ * @param statusCode HTTP status code returned by Resend.
74
+ * @param retryAfterMilliseconds Retry delay from the response.
75
+ * @param attempts Number of attempts made before this error.
76
+ */
77
+ constructor(message, statusCode, retryAfterMilliseconds, attempts) {
33
78
  super(message);
34
79
  this.name = "ResendApiError";
35
80
  this.statusCode = statusCode;
81
+ this.retryAfterMilliseconds = retryAfterMilliseconds;
82
+ this.attempts = attempts;
36
83
  }
37
84
  };
38
85
  /**
@@ -102,7 +149,10 @@ var ResendHttpClient = class {
102
149
  const errorBody = JSON.parse(text);
103
150
  errorMessage = errorBody.message;
104
151
  } catch {}
105
- throw new ResendApiError(errorMessage || text || `HTTP ${response.status}`, response.status);
152
+ const parsedErrorMessage = errorMessage === "" ? void 0 : errorMessage;
153
+ const responseMessage = truncateErrorBody(text);
154
+ const fallbackMessage = responseMessage === "" ? void 0 : responseMessage;
155
+ throw new ResendApiError(parsedErrorMessage ?? fallbackMessage ?? `HTTP ${response.status}`, response.status, (0, __upyo_core.parseRetryAfter)(response.headers.get("Retry-After")), attempt + 1);
106
156
  }
107
157
  try {
108
158
  return JSON.parse(text);
@@ -111,9 +161,12 @@ var ResendHttpClient = class {
111
161
  }
112
162
  } catch (error) {
113
163
  lastError = error instanceof Error ? error : new Error(String(error));
114
- if (error instanceof ResendApiError && error.statusCode >= 400 && error.statusCode < 500) throw error;
164
+ if (error instanceof ResendApiError && error.statusCode !== void 0 && error.statusCode >= 400 && error.statusCode < 500) throw error;
115
165
  if (error instanceof Error && error.name === "AbortError") throw error;
116
- if (attempt === this.config.retries) throw lastError;
166
+ if (attempt === this.config.retries) {
167
+ if (lastError instanceof ResendApiError) throw lastError;
168
+ throw new ResendApiError(lastError.message, void 0, void 0, attempt + 1);
169
+ }
117
170
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt), 1e4);
118
171
  await new Promise((resolve) => setTimeout(resolve, backoffMs));
119
172
  }
@@ -132,26 +185,51 @@ var ResendHttpClient = class {
132
185
  for (const [key, value] of Object.entries(this.config.headers)) headers.set(key, value);
133
186
  const controller = new AbortController();
134
187
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
135
- let signal;
136
- if (options.signal) {
137
- const combinedController = new AbortController();
138
- const onAbort = () => combinedController.abort();
139
- options.signal.addEventListener("abort", onAbort, { once: true });
140
- controller.signal.addEventListener("abort", onAbort, { once: true });
141
- signal = combinedController.signal;
142
- } else signal = controller.signal;
188
+ const combinedSignal = combineSignals(controller.signal, options.signal);
143
189
  try {
144
190
  const response = await fetch(url, {
145
191
  ...options,
146
192
  headers,
147
- signal
193
+ signal: combinedSignal.signal
148
194
  });
149
195
  return response;
196
+ } catch (error) {
197
+ if (isAbortError$1(error) && controller.signal.aborted && !options.signal?.aborted) throw new Error(`Resend API request timed out after ${this.config.timeout} ms.`);
198
+ throw error;
150
199
  } finally {
200
+ combinedSignal.cleanup();
151
201
  clearTimeout(timeoutId);
152
202
  }
153
203
  }
154
204
  };
205
+ function combineSignals(timeoutSignal, externalSignal) {
206
+ if (externalSignal == null) return {
207
+ signal: timeoutSignal,
208
+ cleanup: () => {}
209
+ };
210
+ if (typeof AbortSignal.any === "function") return {
211
+ signal: AbortSignal.any([timeoutSignal, externalSignal]),
212
+ cleanup: () => {}
213
+ };
214
+ const controller = new AbortController();
215
+ const abort = () => controller.abort();
216
+ timeoutSignal.addEventListener("abort", abort, { once: true });
217
+ externalSignal.addEventListener("abort", abort, { once: true });
218
+ if (timeoutSignal.aborted || externalSignal.aborted) controller.abort();
219
+ return {
220
+ signal: controller.signal,
221
+ cleanup: () => {
222
+ timeoutSignal.removeEventListener("abort", abort);
223
+ externalSignal.removeEventListener("abort", abort);
224
+ }
225
+ };
226
+ }
227
+ function isAbortError$1(error) {
228
+ return error instanceof Error && error.name === "AbortError";
229
+ }
230
+ function truncateErrorBody(text) {
231
+ return text.length > 500 ? `${text.slice(0, 500)}...` : text;
232
+ }
155
233
 
156
234
  //#endregion
157
235
  //#region src/message-converter.ts
@@ -339,6 +417,7 @@ function generateIdempotencyKey() {
339
417
  * ```
340
418
  */
341
419
  var ResendTransport = class {
420
+ id = "resend";
342
421
  /**
343
422
  * The resolved Resend configuration used by this transport.
344
423
  */
@@ -396,14 +475,13 @@ var ResendTransport = class {
396
475
  const response = await this.httpClient.sendMessage(emailData, options?.signal, idempotencyKey);
397
476
  return {
398
477
  successful: true,
399
- messageId: response.id
478
+ messageId: response.id,
479
+ provider: "resend"
400
480
  };
401
481
  } catch (error) {
482
+ if (isAbortError(error) && options?.signal?.aborted) throw error;
402
483
  const errorMessage = error instanceof Error ? error.message : String(error);
403
- return {
404
- successful: false,
405
- errorMessages: [errorMessage]
406
- };
484
+ return createResendFailure(errorMessage, error);
407
485
  }
408
486
  }
409
487
  /**
@@ -512,14 +590,13 @@ var ResendTransport = class {
512
590
  const response = await this.httpClient.sendBatch(batchData, options?.signal, idempotencyKey);
513
591
  for (const result of response.data) yield {
514
592
  successful: true,
515
- messageId: result.id
593
+ messageId: result.id,
594
+ provider: "resend"
516
595
  };
517
596
  } catch (error) {
597
+ if (isAbortError(error) && options?.signal?.aborted) throw error;
518
598
  const errorMessage = error instanceof Error ? error.message : String(error);
519
- for (let i = 0; i < messages.length; i++) yield {
520
- successful: false,
521
- errorMessages: [errorMessage]
522
- };
599
+ for (let i = 0; i < messages.length; i++) yield createResendFailure(errorMessage, error);
523
600
  }
524
601
  }
525
602
  /**
@@ -549,6 +626,18 @@ var ResendTransport = class {
549
626
  return chunks;
550
627
  }
551
628
  };
629
+ function createResendFailure(message, error) {
630
+ if (error instanceof ResendApiError) return (0, __upyo_core.createFailedReceipt)(message, {
631
+ provider: "resend",
632
+ statusCode: error.statusCode,
633
+ retryAfterMilliseconds: error.retryAfterMilliseconds,
634
+ attempts: error.attempts
635
+ });
636
+ return (0, __upyo_core.createFailedReceipt)(message, { provider: "resend" });
637
+ }
638
+ function isAbortError(error) {
639
+ return error instanceof Error && error.name === "AbortError";
640
+ }
552
641
 
553
642
  //#endregion
554
643
  exports.ResendTransport = ResendTransport;
package/dist/index.d.cts CHANGED
@@ -99,7 +99,8 @@ type ResolvedResendConfig = Required<ResendConfig>;
99
99
  * }
100
100
  * ```
101
101
  */
102
- declare class ResendTransport implements Transport {
102
+ declare class ResendTransport implements Transport<"resend"> {
103
+ readonly id = "resend";
103
104
  /**
104
105
  * The resolved Resend configuration used by this transport.
105
106
  */
@@ -145,7 +146,7 @@ declare class ResendTransport implements Transport {
145
146
  * @returns A promise that resolves to a receipt indicating success or
146
147
  * failure.
147
148
  */
148
- send(message: Message, options?: TransportOptions): Promise<Receipt>;
149
+ send(message: Message, options?: TransportOptions): Promise<Receipt<"resend">>;
149
150
  /**
150
151
  * Sends multiple email messages efficiently via Resend API.
151
152
  *
@@ -200,7 +201,7 @@ declare class ResendTransport implements Transport {
200
201
  * cancellation.
201
202
  * @returns An async iterable of receipts, one for each message.
202
203
  */
203
- sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt>;
204
+ sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt<"resend">>;
204
205
  /**
205
206
  * Optimized batch sending that chooses the best strategy based on message features.
206
207
  *
@@ -274,11 +275,32 @@ interface ResendError {
274
275
  name?: string;
275
276
  }
276
277
  /**
277
- * Resend API error class for handling API-specific errors.
278
+ * Error thrown when a Resend API request fails.
279
+ *
280
+ * @since 0.5.0
278
281
  */
279
282
  declare class ResendApiError extends Error {
280
- readonly statusCode: number;
281
- constructor(message: string, statusCode: number);
283
+ /**
284
+ * HTTP status code returned by Resend, if the request reached the API.
285
+ */
286
+ readonly statusCode?: number;
287
+ /**
288
+ * Retry delay from Resend's `Retry-After` response header.
289
+ */
290
+ readonly retryAfterMilliseconds?: number;
291
+ /**
292
+ * Number of attempts made before this error was produced.
293
+ */
294
+ readonly attempts?: number;
295
+ /**
296
+ * Creates a Resend API error.
297
+ *
298
+ * @param message Error message.
299
+ * @param statusCode HTTP status code returned by Resend.
300
+ * @param retryAfterMilliseconds Retry delay from the response.
301
+ * @param attempts Number of attempts made before this error.
302
+ */
303
+ constructor(message: string, statusCode?: number, retryAfterMilliseconds?: number, attempts?: number);
282
304
  }
283
305
  /**
284
306
  * HTTP client wrapper for Resend API requests.
package/dist/index.d.ts CHANGED
@@ -99,7 +99,8 @@ type ResolvedResendConfig = Required<ResendConfig>;
99
99
  * }
100
100
  * ```
101
101
  */
102
- declare class ResendTransport implements Transport {
102
+ declare class ResendTransport implements Transport<"resend"> {
103
+ readonly id = "resend";
103
104
  /**
104
105
  * The resolved Resend configuration used by this transport.
105
106
  */
@@ -145,7 +146,7 @@ declare class ResendTransport implements Transport {
145
146
  * @returns A promise that resolves to a receipt indicating success or
146
147
  * failure.
147
148
  */
148
- send(message: Message, options?: TransportOptions): Promise<Receipt>;
149
+ send(message: Message, options?: TransportOptions): Promise<Receipt<"resend">>;
149
150
  /**
150
151
  * Sends multiple email messages efficiently via Resend API.
151
152
  *
@@ -200,7 +201,7 @@ declare class ResendTransport implements Transport {
200
201
  * cancellation.
201
202
  * @returns An async iterable of receipts, one for each message.
202
203
  */
203
- sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt>;
204
+ sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt<"resend">>;
204
205
  /**
205
206
  * Optimized batch sending that chooses the best strategy based on message features.
206
207
  *
@@ -274,11 +275,32 @@ interface ResendError {
274
275
  name?: string;
275
276
  }
276
277
  /**
277
- * Resend API error class for handling API-specific errors.
278
+ * Error thrown when a Resend API request fails.
279
+ *
280
+ * @since 0.5.0
278
281
  */
279
282
  declare class ResendApiError extends Error {
280
- readonly statusCode: number;
281
- constructor(message: string, statusCode: number);
283
+ /**
284
+ * HTTP status code returned by Resend, if the request reached the API.
285
+ */
286
+ readonly statusCode?: number;
287
+ /**
288
+ * Retry delay from Resend's `Retry-After` response header.
289
+ */
290
+ readonly retryAfterMilliseconds?: number;
291
+ /**
292
+ * Number of attempts made before this error was produced.
293
+ */
294
+ readonly attempts?: number;
295
+ /**
296
+ * Creates a Resend API error.
297
+ *
298
+ * @param message Error message.
299
+ * @param statusCode HTTP status code returned by Resend.
300
+ * @param retryAfterMilliseconds Retry delay from the response.
301
+ * @param attempts Number of attempts made before this error.
302
+ */
303
+ constructor(message: string, statusCode?: number, retryAfterMilliseconds?: number, attempts?: number);
282
304
  }
283
305
  /**
284
306
  * HTTP client wrapper for Resend API requests.
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { createFailedReceipt, parseRetryAfter } from "@upyo/core";
2
+
1
3
  //#region src/config.ts
2
4
  /**
3
5
  * Creates a resolved Resend configuration by applying default values to optional fields.
@@ -24,14 +26,37 @@ function createResendConfig(config) {
24
26
  //#endregion
25
27
  //#region src/http-client.ts
26
28
  /**
27
- * Resend API error class for handling API-specific errors.
29
+ * Error thrown when a Resend API request fails.
30
+ *
31
+ * @since 0.5.0
28
32
  */
29
33
  var ResendApiError = class extends Error {
34
+ /**
35
+ * HTTP status code returned by Resend, if the request reached the API.
36
+ */
30
37
  statusCode;
31
- constructor(message, statusCode) {
38
+ /**
39
+ * Retry delay from Resend's `Retry-After` response header.
40
+ */
41
+ retryAfterMilliseconds;
42
+ /**
43
+ * Number of attempts made before this error was produced.
44
+ */
45
+ attempts;
46
+ /**
47
+ * Creates a Resend API error.
48
+ *
49
+ * @param message Error message.
50
+ * @param statusCode HTTP status code returned by Resend.
51
+ * @param retryAfterMilliseconds Retry delay from the response.
52
+ * @param attempts Number of attempts made before this error.
53
+ */
54
+ constructor(message, statusCode, retryAfterMilliseconds, attempts) {
32
55
  super(message);
33
56
  this.name = "ResendApiError";
34
57
  this.statusCode = statusCode;
58
+ this.retryAfterMilliseconds = retryAfterMilliseconds;
59
+ this.attempts = attempts;
35
60
  }
36
61
  };
37
62
  /**
@@ -101,7 +126,10 @@ var ResendHttpClient = class {
101
126
  const errorBody = JSON.parse(text);
102
127
  errorMessage = errorBody.message;
103
128
  } catch {}
104
- throw new ResendApiError(errorMessage || text || `HTTP ${response.status}`, response.status);
129
+ const parsedErrorMessage = errorMessage === "" ? void 0 : errorMessage;
130
+ const responseMessage = truncateErrorBody(text);
131
+ const fallbackMessage = responseMessage === "" ? void 0 : responseMessage;
132
+ throw new ResendApiError(parsedErrorMessage ?? fallbackMessage ?? `HTTP ${response.status}`, response.status, parseRetryAfter(response.headers.get("Retry-After")), attempt + 1);
105
133
  }
106
134
  try {
107
135
  return JSON.parse(text);
@@ -110,9 +138,12 @@ var ResendHttpClient = class {
110
138
  }
111
139
  } catch (error) {
112
140
  lastError = error instanceof Error ? error : new Error(String(error));
113
- if (error instanceof ResendApiError && error.statusCode >= 400 && error.statusCode < 500) throw error;
141
+ if (error instanceof ResendApiError && error.statusCode !== void 0 && error.statusCode >= 400 && error.statusCode < 500) throw error;
114
142
  if (error instanceof Error && error.name === "AbortError") throw error;
115
- if (attempt === this.config.retries) throw lastError;
143
+ if (attempt === this.config.retries) {
144
+ if (lastError instanceof ResendApiError) throw lastError;
145
+ throw new ResendApiError(lastError.message, void 0, void 0, attempt + 1);
146
+ }
116
147
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt), 1e4);
117
148
  await new Promise((resolve) => setTimeout(resolve, backoffMs));
118
149
  }
@@ -131,26 +162,51 @@ var ResendHttpClient = class {
131
162
  for (const [key, value] of Object.entries(this.config.headers)) headers.set(key, value);
132
163
  const controller = new AbortController();
133
164
  const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
134
- let signal;
135
- if (options.signal) {
136
- const combinedController = new AbortController();
137
- const onAbort = () => combinedController.abort();
138
- options.signal.addEventListener("abort", onAbort, { once: true });
139
- controller.signal.addEventListener("abort", onAbort, { once: true });
140
- signal = combinedController.signal;
141
- } else signal = controller.signal;
165
+ const combinedSignal = combineSignals(controller.signal, options.signal);
142
166
  try {
143
167
  const response = await fetch(url, {
144
168
  ...options,
145
169
  headers,
146
- signal
170
+ signal: combinedSignal.signal
147
171
  });
148
172
  return response;
173
+ } catch (error) {
174
+ if (isAbortError$1(error) && controller.signal.aborted && !options.signal?.aborted) throw new Error(`Resend API request timed out after ${this.config.timeout} ms.`);
175
+ throw error;
149
176
  } finally {
177
+ combinedSignal.cleanup();
150
178
  clearTimeout(timeoutId);
151
179
  }
152
180
  }
153
181
  };
182
+ function combineSignals(timeoutSignal, externalSignal) {
183
+ if (externalSignal == null) return {
184
+ signal: timeoutSignal,
185
+ cleanup: () => {}
186
+ };
187
+ if (typeof AbortSignal.any === "function") return {
188
+ signal: AbortSignal.any([timeoutSignal, externalSignal]),
189
+ cleanup: () => {}
190
+ };
191
+ const controller = new AbortController();
192
+ const abort = () => controller.abort();
193
+ timeoutSignal.addEventListener("abort", abort, { once: true });
194
+ externalSignal.addEventListener("abort", abort, { once: true });
195
+ if (timeoutSignal.aborted || externalSignal.aborted) controller.abort();
196
+ return {
197
+ signal: controller.signal,
198
+ cleanup: () => {
199
+ timeoutSignal.removeEventListener("abort", abort);
200
+ externalSignal.removeEventListener("abort", abort);
201
+ }
202
+ };
203
+ }
204
+ function isAbortError$1(error) {
205
+ return error instanceof Error && error.name === "AbortError";
206
+ }
207
+ function truncateErrorBody(text) {
208
+ return text.length > 500 ? `${text.slice(0, 500)}...` : text;
209
+ }
154
210
 
155
211
  //#endregion
156
212
  //#region src/message-converter.ts
@@ -338,6 +394,7 @@ function generateIdempotencyKey() {
338
394
  * ```
339
395
  */
340
396
  var ResendTransport = class {
397
+ id = "resend";
341
398
  /**
342
399
  * The resolved Resend configuration used by this transport.
343
400
  */
@@ -395,14 +452,13 @@ var ResendTransport = class {
395
452
  const response = await this.httpClient.sendMessage(emailData, options?.signal, idempotencyKey);
396
453
  return {
397
454
  successful: true,
398
- messageId: response.id
455
+ messageId: response.id,
456
+ provider: "resend"
399
457
  };
400
458
  } catch (error) {
459
+ if (isAbortError(error) && options?.signal?.aborted) throw error;
401
460
  const errorMessage = error instanceof Error ? error.message : String(error);
402
- return {
403
- successful: false,
404
- errorMessages: [errorMessage]
405
- };
461
+ return createResendFailure(errorMessage, error);
406
462
  }
407
463
  }
408
464
  /**
@@ -511,14 +567,13 @@ var ResendTransport = class {
511
567
  const response = await this.httpClient.sendBatch(batchData, options?.signal, idempotencyKey);
512
568
  for (const result of response.data) yield {
513
569
  successful: true,
514
- messageId: result.id
570
+ messageId: result.id,
571
+ provider: "resend"
515
572
  };
516
573
  } catch (error) {
574
+ if (isAbortError(error) && options?.signal?.aborted) throw error;
517
575
  const errorMessage = error instanceof Error ? error.message : String(error);
518
- for (let i = 0; i < messages.length; i++) yield {
519
- successful: false,
520
- errorMessages: [errorMessage]
521
- };
576
+ for (let i = 0; i < messages.length; i++) yield createResendFailure(errorMessage, error);
522
577
  }
523
578
  }
524
579
  /**
@@ -548,6 +603,18 @@ var ResendTransport = class {
548
603
  return chunks;
549
604
  }
550
605
  };
606
+ function createResendFailure(message, error) {
607
+ if (error instanceof ResendApiError) return createFailedReceipt(message, {
608
+ provider: "resend",
609
+ statusCode: error.statusCode,
610
+ retryAfterMilliseconds: error.retryAfterMilliseconds,
611
+ attempts: error.attempts
612
+ });
613
+ return createFailedReceipt(message, { provider: "resend" });
614
+ }
615
+ function isAbortError(error) {
616
+ return error instanceof Error && error.name === "AbortError";
617
+ }
551
618
 
552
619
  //#endregion
553
620
  export { ResendTransport };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upyo/resend",
3
- "version": "0.5.0-dev.136",
3
+ "version": "0.5.0-dev.156",
4
4
  "description": "Resend transport for Upyo email library",
5
5
  "keywords": [
6
6
  "email",
@@ -53,18 +53,13 @@
53
53
  },
54
54
  "sideEffects": false,
55
55
  "peerDependencies": {
56
- "@upyo/core": "0.5.0-dev.136+adacf579"
56
+ "@upyo/core": "0.5.0-dev.156+edad9790"
57
57
  },
58
58
  "devDependencies": {
59
- "@dotenvx/dotenvx": "^1.47.3",
60
59
  "tsdown": "^0.12.7",
61
60
  "typescript": "5.8.3"
62
61
  },
63
62
  "scripts": {
64
- "build": "tsdown",
65
- "prepublish": "tsdown",
66
- "test": "tsdown && dotenvx run --ignore=MISSING_ENV_FILE -- node --experimental-transform-types --test",
67
- "test:bun": "tsdown && bun test --timeout=30000 --env-file=.env",
68
- "test:deno": "deno test --allow-env --allow-net --env-file=.env"
63
+ "prepublish": "mise run --no-deps :build"
69
64
  }
70
65
  }