@outfitter/contracts 0.4.2 → 0.5.0

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 (84) hide show
  1. package/dist/actions.d.ts +8 -3
  2. package/dist/assert/index.d.ts +7 -3
  3. package/dist/assert/index.js +32 -1
  4. package/dist/context.d.ts +8 -3
  5. package/dist/context.js +1 -1
  6. package/dist/envelope.d.ts +6 -2
  7. package/dist/envelope.js +5 -6
  8. package/dist/errors.d.ts +6 -2
  9. package/dist/errors.js +7 -1
  10. package/dist/from-fetch.d.ts +7 -0
  11. package/dist/from-fetch.js +110 -0
  12. package/dist/handler.d.ts +7 -2
  13. package/dist/hints.d.ts +2 -0
  14. package/dist/hints.js +1 -0
  15. package/dist/index.d.ts +24 -13
  16. package/dist/index.js +5 -3
  17. package/dist/internal/error-base.d.ts +2 -0
  18. package/dist/internal/error-base.js +31 -0
  19. package/dist/internal/error-operational.d.ts +3 -0
  20. package/dist/internal/error-operational.js +125 -0
  21. package/dist/internal/error-serialization.d.ts +7 -0
  22. package/dist/{shared/@outfitter/contracts-5k6q4n48.js → internal/error-serialization.js} +28 -67
  23. package/dist/internal/error-taxonomy.d.ts +2 -0
  24. package/dist/internal/error-taxonomy.js +21 -0
  25. package/dist/internal/error-validation.d.ts +3 -0
  26. package/dist/internal/error-validation.js +121 -0
  27. package/dist/internal/safe-json.d.ts +7 -0
  28. package/dist/internal/safe-json.js +66 -0
  29. package/dist/internal/schema-converters.d.ts +26 -0
  30. package/dist/internal/schema-converters.js +12 -0
  31. package/dist/internal/schema-primitives.d.ts +10 -0
  32. package/dist/internal/schema-primitives.js +9 -0
  33. package/dist/internal/schema-types.d.ts +2 -0
  34. package/dist/internal/schema-types.js +9 -0
  35. package/dist/recovery.d.ts +6 -2
  36. package/dist/resilience.d.ts +6 -2
  37. package/dist/resilience.js +6 -2
  38. package/dist/schema.d.ts +2 -1
  39. package/dist/schema.js +15 -187
  40. package/dist/serialization.d.ts +8 -2
  41. package/dist/serialization.js +1 -3
  42. package/dist/shared/@outfitter/{contracts-k71jqd1m.d.ts → contracts-10p5q75w.d.ts} +1 -1
  43. package/dist/shared/@outfitter/contracts-1zzcpfyg.d.ts +40 -0
  44. package/dist/shared/@outfitter/contracts-3f5k5tg5.d.ts +28 -0
  45. package/dist/shared/@outfitter/contracts-3qmyq81n.d.ts +78 -0
  46. package/dist/shared/@outfitter/contracts-3re9d4bp.js +114 -0
  47. package/dist/shared/@outfitter/contracts-735ecmbq.d.ts +107 -0
  48. package/dist/shared/@outfitter/contracts-7a0xmwbg.d.ts +11 -0
  49. package/dist/shared/@outfitter/contracts-8cmkh2db.d.ts +31 -0
  50. package/dist/shared/@outfitter/{contracts-agmt8915.js → contracts-c3qfce25.js} +3 -0
  51. package/dist/shared/@outfitter/{contracts-1waabxbk.d.ts → contracts-drwd9ywk.d.ts} +4 -1
  52. package/dist/shared/@outfitter/contracts-hgh47193.js +46 -0
  53. package/dist/shared/@outfitter/contracts-hrepwwne.js +62 -0
  54. package/dist/shared/@outfitter/contracts-jtn6b927.js +18 -0
  55. package/dist/shared/@outfitter/contracts-jtt6dnmg.js +2 -0
  56. package/dist/shared/@outfitter/contracts-jyhqr766.js +25 -0
  57. package/dist/shared/@outfitter/contracts-mehpmvwp.d.ts +164 -0
  58. package/dist/shared/@outfitter/contracts-msxdg52h.d.ts +125 -0
  59. package/dist/shared/@outfitter/{contracts-95cc3y06.d.ts → contracts-mt027fqj.d.ts} +2 -1
  60. package/dist/shared/@outfitter/contracts-njb2art4.d.ts +174 -0
  61. package/dist/shared/@outfitter/contracts-p77yjs4g.d.ts +46 -0
  62. package/dist/shared/@outfitter/contracts-qpbv29bg.d.ts +59 -0
  63. package/dist/shared/@outfitter/contracts-sawwfgb5.js +111 -0
  64. package/dist/shared/@outfitter/{contracts-e4m948m7.d.ts → contracts-t4txv24h.d.ts} +2 -1
  65. package/dist/shared/@outfitter/contracts-vbgt9rfn.d.ts +74 -0
  66. package/dist/shared/@outfitter/{contracts-56pcsavx.d.ts → contracts-vhajx4gg.d.ts} +8 -2
  67. package/dist/shared/@outfitter/contracts-vhr2ep6b.js +3 -0
  68. package/dist/shared/@outfitter/contracts-w7nvcwrp.d.ts +44 -0
  69. package/dist/shared/@outfitter/contracts-x0ppyt7e.d.ts +76 -0
  70. package/dist/shared/@outfitter/{contracts-0akf2sm6.d.ts → contracts-zma4mscd.d.ts} +16 -1
  71. package/dist/shared/@outfitter/contracts-zsgxsa91.d.ts +84 -0
  72. package/dist/stream.d.ts +2 -0
  73. package/dist/stream.js +1 -0
  74. package/dist/validation.d.ts +7 -3
  75. package/dist/validation.js +8 -36
  76. package/dist/wrap-error.d.ts +7 -0
  77. package/dist/wrap-error.js +71 -0
  78. package/package.json +41 -17
  79. package/dist/shared/@outfitter/contracts-31penhwa.d.ts +0 -81
  80. package/dist/shared/@outfitter/contracts-3gswmhb1.d.ts +0 -446
  81. package/dist/shared/@outfitter/contracts-9wtm5nsw.d.ts +0 -42
  82. package/dist/shared/@outfitter/contracts-mmg0npfk.d.ts +0 -30
  83. package/dist/shared/@outfitter/contracts-phjhz5q3.js +0 -293
  84. package/dist/shared/@outfitter/contracts-t79engf9.d.ts +0 -60
@@ -13,15 +13,9 @@ import {
13
13
  RateLimitError,
14
14
  TimeoutError,
15
15
  ValidationError
16
- } from "./contracts-phjhz5q3.js";
17
- import {
18
- DEFAULT_PATTERNS,
19
- DEFAULT_SENSITIVE_KEYS,
20
- createRedactor
21
- } from "./contracts-s15x2rs4.js";
16
+ } from "../shared/@outfitter/contracts-vhr2ep6b.js";
22
17
 
23
- // packages/contracts/src/serialization.ts
24
- import { Result } from "better-result";
18
+ // packages/contracts/src/internal/error-serialization.ts
25
19
  var errorRegistry = {
26
20
  ValidationError,
27
21
  AmbiguousError,
@@ -45,6 +39,9 @@ function extractContext(error) {
45
39
  switch (error._tag) {
46
40
  case "ValidationError": {
47
41
  const ve = error;
42
+ if (ve.context !== undefined) {
43
+ Object.assign(context, ve.context);
44
+ }
48
45
  if (ve.field !== undefined) {
49
46
  context["field"] = ve.field;
50
47
  }
@@ -90,6 +87,9 @@ function extractContext(error) {
90
87
  }
91
88
  case "AmbiguousError": {
92
89
  const amb = error;
90
+ if (amb.context !== undefined) {
91
+ Object.assign(context, amb.context);
92
+ }
93
93
  context["candidates"] = amb.candidates;
94
94
  break;
95
95
  }
@@ -110,9 +110,9 @@ function extractContext(error) {
110
110
  }
111
111
  return Object.keys(context).length > 0 ? context : undefined;
112
112
  }
113
- function serializeError(error, options) {
114
- const isProduction = process.env["NODE_ENV"] === "production";
115
- const includeStack = options?.includeStack ?? !isProduction;
113
+ function serializeError(error, options, isProduction) {
114
+ const production = isProduction ?? process.env["NODE_ENV"] === "production";
115
+ const includeStack = options?.includeStack ?? !production;
116
116
  const context = extractContext(error);
117
117
  const serialized = {
118
118
  _tag: error._tag,
@@ -151,6 +151,10 @@ function deserializeError(data) {
151
151
  if (field !== undefined) {
152
152
  props.field = field;
153
153
  }
154
+ const contextWithoutField = Object.fromEntries(Object.entries(context).filter(([key]) => key !== "field"));
155
+ if (Object.keys(contextWithoutField).length > 0) {
156
+ props.context = contextWithoutField;
157
+ }
154
158
  return new ValidationError(props);
155
159
  }
156
160
  case "NotFoundError": {
@@ -239,11 +243,17 @@ function deserializeError(data) {
239
243
  }
240
244
  return new AuthError(props);
241
245
  }
242
- case "AmbiguousError":
243
- return new AmbiguousError({
246
+ case "AmbiguousError": {
247
+ const props = {
244
248
  message: data.message,
245
249
  candidates: context["candidates"] ?? []
246
- });
250
+ };
251
+ const contextWithoutCandidates = Object.fromEntries(Object.entries(context).filter(([key]) => key !== "candidates"));
252
+ if (Object.keys(contextWithoutCandidates).length > 0) {
253
+ props.context = contextWithoutCandidates;
254
+ }
255
+ return new AmbiguousError(props);
256
+ }
247
257
  case "AssertionError":
248
258
  return new AssertionError({
249
259
  message: data.message
@@ -263,56 +273,7 @@ function deserializeError(data) {
263
273
  }
264
274
  }
265
275
  }
266
- function safeStringify(value, space) {
267
- const seen = new WeakSet;
268
- const redactor = createRedactor({
269
- patterns: [...DEFAULT_PATTERNS],
270
- keys: [...DEFAULT_SENSITIVE_KEYS]
271
- });
272
- const replacer = (key, val) => {
273
- if (typeof val === "bigint") {
274
- return val.toString();
275
- }
276
- if (typeof val === "object" && val !== null) {
277
- if (seen.has(val)) {
278
- return "[Circular]";
279
- }
280
- seen.add(val);
281
- }
282
- if (key !== "" && redactor.isSensitiveKey(key) && val !== null && val !== undefined) {
283
- return "[REDACTED]";
284
- }
285
- if (typeof val === "string") {
286
- return redactor.redactString(val);
287
- }
288
- return val;
289
- };
290
- return JSON.stringify(value, replacer, space);
291
- }
292
- function safeParse(json, schema) {
293
- let parsed;
294
- try {
295
- parsed = JSON.parse(json);
296
- } catch (err) {
297
- const errorMessage = err instanceof Error ? err.message : "Unknown parse error";
298
- return Result.err(new ValidationError({
299
- message: `JSON parse error: ${errorMessage}`
300
- }));
301
- }
302
- if (schema === undefined) {
303
- return Result.ok(parsed);
304
- }
305
- const parseResult = schema.safeParse(parsed);
306
- if (parseResult.success) {
307
- return Result.ok(parseResult.data);
308
- }
309
- const issues = parseResult.error.issues.map((issue) => {
310
- const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
311
- return `${path}: ${issue.message}`;
312
- }).join("; ");
313
- return Result.err(new ValidationError({
314
- message: `Schema validation failed: ${issues}`
315
- }));
316
- }
317
-
318
- export { serializeError, deserializeError, safeStringify, safeParse };
276
+ export {
277
+ serializeError,
278
+ deserializeError
279
+ };
@@ -0,0 +1,2 @@
1
+ import { ERROR_CODES, ErrorCategory, ErrorCategoryMeta, ErrorCode, KitErrorProps, SerializedError, errorCategoryMeta, exitCodeMap, getExitCode, getStatusCode, jsonRpcCodeMap, retryableMap, statusCodeMap } from "../shared/@outfitter/contracts-njb2art4.js";
2
+ export { statusCodeMap, retryableMap, jsonRpcCodeMap, getStatusCode, getExitCode, exitCodeMap, errorCategoryMeta, SerializedError, KitErrorProps, ErrorCode, ErrorCategoryMeta, ErrorCategory, ERROR_CODES };
@@ -0,0 +1,21 @@
1
+ // @bun
2
+ import {
3
+ ERROR_CODES,
4
+ errorCategoryMeta,
5
+ exitCodeMap,
6
+ getExitCode,
7
+ getStatusCode,
8
+ jsonRpcCodeMap,
9
+ retryableMap,
10
+ statusCodeMap
11
+ } from "../shared/@outfitter/contracts-sawwfgb5.js";
12
+ export {
13
+ statusCodeMap,
14
+ retryableMap,
15
+ jsonRpcCodeMap,
16
+ getStatusCode,
17
+ getExitCode,
18
+ exitCodeMap,
19
+ errorCategoryMeta,
20
+ ERROR_CODES
21
+ };
@@ -0,0 +1,3 @@
1
+ import { AlreadyExistsError, AmbiguousError, AssertionError, ConflictError, NotFoundError, ValidationError } from "../shared/@outfitter/contracts-mehpmvwp.js";
2
+ import "../shared/@outfitter/contracts-qpbv29bg.js";
3
+ export { ValidationError, NotFoundError, ConflictError, AssertionError, AmbiguousError, AlreadyExistsError };
@@ -0,0 +1,121 @@
1
+ // @bun
2
+ import {
3
+ AlreadyExistsErrorBase,
4
+ AmbiguousErrorBase,
5
+ AssertionErrorBase,
6
+ ConflictErrorBase,
7
+ NotFoundErrorBase,
8
+ ValidationErrorBase
9
+ } from "../shared/@outfitter/contracts-jtn6b927.js";
10
+ import {
11
+ getExitCode,
12
+ getStatusCode
13
+ } from "../shared/@outfitter/contracts-sawwfgb5.js";
14
+
15
+ // packages/contracts/src/internal/error-validation.ts
16
+ class ValidationError extends ValidationErrorBase {
17
+ category = "validation";
18
+ static create(field, reason, context) {
19
+ return new ValidationError({
20
+ message: `${field}: ${reason}`,
21
+ field,
22
+ ...context != null && { context }
23
+ });
24
+ }
25
+ static fromMessage(message, context) {
26
+ return new ValidationError({
27
+ message,
28
+ ...context != null && { context }
29
+ });
30
+ }
31
+ exitCode() {
32
+ return getExitCode(this.category);
33
+ }
34
+ statusCode() {
35
+ return getStatusCode(this.category);
36
+ }
37
+ }
38
+
39
+ class AmbiguousError extends AmbiguousErrorBase {
40
+ category = "validation";
41
+ static create(what, candidates, context) {
42
+ return new AmbiguousError({
43
+ message: `Ambiguous ${what}: ${candidates.length} matches found`,
44
+ candidates,
45
+ ...context != null && { context }
46
+ });
47
+ }
48
+ exitCode() {
49
+ return getExitCode(this.category);
50
+ }
51
+ statusCode() {
52
+ return getStatusCode(this.category);
53
+ }
54
+ }
55
+
56
+ class AssertionError extends AssertionErrorBase {
57
+ category = "internal";
58
+ exitCode() {
59
+ return getExitCode(this.category);
60
+ }
61
+ statusCode() {
62
+ return getStatusCode(this.category);
63
+ }
64
+ }
65
+
66
+ class NotFoundError extends NotFoundErrorBase {
67
+ category = "not_found";
68
+ static create(resourceType, resourceId, context) {
69
+ return new NotFoundError({
70
+ message: `${resourceType} not found: ${resourceId}`,
71
+ resourceType,
72
+ resourceId,
73
+ ...context != null && { context }
74
+ });
75
+ }
76
+ exitCode() {
77
+ return getExitCode(this.category);
78
+ }
79
+ statusCode() {
80
+ return getStatusCode(this.category);
81
+ }
82
+ }
83
+
84
+ class AlreadyExistsError extends AlreadyExistsErrorBase {
85
+ category = "conflict";
86
+ static create(resourceType, resourceId, context) {
87
+ return new AlreadyExistsError({
88
+ message: `${resourceType} already exists: ${resourceId}`,
89
+ resourceType,
90
+ resourceId,
91
+ ...context != null && { context }
92
+ });
93
+ }
94
+ exitCode() {
95
+ return getExitCode(this.category);
96
+ }
97
+ statusCode() {
98
+ return getStatusCode(this.category);
99
+ }
100
+ }
101
+
102
+ class ConflictError extends ConflictErrorBase {
103
+ category = "conflict";
104
+ static create(message, context) {
105
+ return new ConflictError({ message, ...context != null && { context } });
106
+ }
107
+ exitCode() {
108
+ return getExitCode(this.category);
109
+ }
110
+ statusCode() {
111
+ return getStatusCode(this.category);
112
+ }
113
+ }
114
+ export {
115
+ ValidationError,
116
+ NotFoundError,
117
+ ConflictError,
118
+ AssertionError,
119
+ AmbiguousError,
120
+ AlreadyExistsError
121
+ };
@@ -0,0 +1,7 @@
1
+ import { safeParse, safeStringify } from "../shared/@outfitter/contracts-1zzcpfyg.js";
2
+ import "../shared/@outfitter/contracts-7a0xmwbg.js";
3
+ import "../shared/@outfitter/contracts-735ecmbq.js";
4
+ import "../shared/@outfitter/contracts-mehpmvwp.js";
5
+ import "../shared/@outfitter/contracts-qpbv29bg.js";
6
+ import "../shared/@outfitter/contracts-njb2art4.js";
7
+ export { safeStringify, safeParse };
@@ -0,0 +1,66 @@
1
+ // @bun
2
+ import {
3
+ DEFAULT_PATTERNS,
4
+ DEFAULT_SENSITIVE_KEYS,
5
+ createRedactor
6
+ } from "../shared/@outfitter/contracts-s15x2rs4.js";
7
+ import {
8
+ formatZodIssues
9
+ } from "../shared/@outfitter/contracts-hgh47193.js";
10
+ import {
11
+ ValidationError
12
+ } from "../shared/@outfitter/contracts-vhr2ep6b.js";
13
+
14
+ // packages/contracts/src/internal/safe-json.ts
15
+ import { Result } from "better-result";
16
+ var defaultRedactor = createRedactor({
17
+ patterns: [...DEFAULT_PATTERNS],
18
+ keys: [...DEFAULT_SENSITIVE_KEYS]
19
+ });
20
+ function safeStringify(value, space) {
21
+ const seen = new WeakSet;
22
+ const replacer = (key, val) => {
23
+ if (typeof val === "bigint") {
24
+ return val.toString();
25
+ }
26
+ if (typeof val === "object" && val !== null) {
27
+ if (seen.has(val)) {
28
+ return "[Circular]";
29
+ }
30
+ seen.add(val);
31
+ }
32
+ if (key !== "" && defaultRedactor.isSensitiveKey(key) && val !== null && val !== undefined) {
33
+ return "[REDACTED]";
34
+ }
35
+ if (typeof val === "string") {
36
+ return defaultRedactor.redactString(val);
37
+ }
38
+ return val;
39
+ };
40
+ return JSON.stringify(value, replacer, space);
41
+ }
42
+ function safeParse(json, schema) {
43
+ let parsed;
44
+ try {
45
+ parsed = JSON.parse(json);
46
+ } catch (err) {
47
+ const errorMessage = err instanceof Error ? err.message : "Unknown parse error";
48
+ return Result.err(new ValidationError({
49
+ message: `JSON parse error: ${errorMessage}`
50
+ }));
51
+ }
52
+ if (schema === undefined) {
53
+ return Result.ok(parsed);
54
+ }
55
+ const parseResult = schema.safeParse(parsed);
56
+ if (parseResult.success) {
57
+ return Result.ok(parseResult.data);
58
+ }
59
+ return Result.err(new ValidationError({
60
+ message: `Schema validation failed: ${formatZodIssues(parseResult.error.issues)}`
61
+ }));
62
+ }
63
+ export {
64
+ safeStringify,
65
+ safeParse
66
+ };
@@ -0,0 +1,26 @@
1
+ import { JsonSchema } from "../shared/@outfitter/contracts-w7nvcwrp.js";
2
+ import { z } from "zod";
3
+ /**
4
+ * Converter function type for the main dispatch function.
5
+ *
6
+ * This is injected to avoid circular dependencies between the converters
7
+ * and the dispatcher in schema.ts.
8
+ */
9
+ type ZodTypeConverter = (schema: z.ZodType<unknown>) => JsonSchema;
10
+ /**
11
+ * Convert Zod array schema.
12
+ */
13
+ declare function convertArray(def: any, convertZodType: ZodTypeConverter): JsonSchema;
14
+ /**
15
+ * Check if a Zod field is optional by unwrapping wrapper types.
16
+ *
17
+ * This handles cases where optional fields are wrapped in ZodEffects
18
+ * (refinements, transforms) or ZodPipeline, which would otherwise
19
+ * incorrectly appear as required.
20
+ */
21
+ declare function isFieldOptional(fieldDef: any): boolean;
22
+ /**
23
+ * Convert Zod object schema.
24
+ */
25
+ declare function convertObject(def: any, convertZodType: ZodTypeConverter): JsonSchema;
26
+ export { isFieldOptional, convertObject, convertArray, ZodTypeConverter };
@@ -0,0 +1,12 @@
1
+ // @bun
2
+ import {
3
+ convertArray,
4
+ convertObject,
5
+ isFieldOptional
6
+ } from "../shared/@outfitter/contracts-hrepwwne.js";
7
+ import"../shared/@outfitter/contracts-jyhqr766.js";
8
+ export {
9
+ isFieldOptional,
10
+ convertObject,
11
+ convertArray
12
+ };
@@ -0,0 +1,10 @@
1
+ import { JsonSchema } from "../shared/@outfitter/contracts-w7nvcwrp.js";
2
+ /**
3
+ * Convert Zod string schema with checks.
4
+ */
5
+ declare function convertString(def: any): JsonSchema;
6
+ /**
7
+ * Convert Zod number schema with checks.
8
+ */
9
+ declare function convertNumber(def: any): JsonSchema;
10
+ export { convertString, convertNumber };
@@ -0,0 +1,9 @@
1
+ // @bun
2
+ import {
3
+ convertNumber,
4
+ convertString
5
+ } from "../shared/@outfitter/contracts-3re9d4bp.js";
6
+ export {
7
+ convertString,
8
+ convertNumber
9
+ };
@@ -0,0 +1,2 @@
1
+ import { JsonSchema, getDef, getDescription } from "../shared/@outfitter/contracts-w7nvcwrp.js";
2
+ export { getDescription, getDef, JsonSchema };
@@ -0,0 +1,9 @@
1
+ // @bun
2
+ import {
3
+ getDef,
4
+ getDescription
5
+ } from "../shared/@outfitter/contracts-jyhqr766.js";
6
+ export {
7
+ getDescription,
8
+ getDef
9
+ };
@@ -1,3 +1,7 @@
1
- import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-k71jqd1m.js";
2
- import "./shared/@outfitter/contracts-3gswmhb1.js";
1
+ import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-10p5q75w.js";
2
+ import "./shared/@outfitter/contracts-7a0xmwbg.js";
3
+ import "./shared/@outfitter/contracts-735ecmbq.js";
4
+ import "./shared/@outfitter/contracts-mehpmvwp.js";
5
+ import "./shared/@outfitter/contracts-qpbv29bg.js";
6
+ import "./shared/@outfitter/contracts-njb2art4.js";
3
7
  export { shouldRetry, isRetryable, isRecoverable, getBackoffDelay, BackoffOptions };
@@ -1,3 +1,7 @@
1
- import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-95cc3y06.js";
2
- import "./shared/@outfitter/contracts-3gswmhb1.js";
1
+ import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-mt027fqj.js";
2
+ import "./shared/@outfitter/contracts-7a0xmwbg.js";
3
+ import "./shared/@outfitter/contracts-735ecmbq.js";
4
+ import "./shared/@outfitter/contracts-mehpmvwp.js";
5
+ import "./shared/@outfitter/contracts-qpbv29bg.js";
6
+ import "./shared/@outfitter/contracts-njb2art4.js";
3
7
  export { withTimeout, retry, TimeoutOptions, RetryOptions };
@@ -1,7 +1,8 @@
1
1
  // @bun
2
2
  import {
3
+ InternalError,
3
4
  TimeoutError
4
- } from "./shared/@outfitter/contracts-phjhz5q3.js";
5
+ } from "./shared/@outfitter/contracts-vhr2ep6b.js";
5
6
 
6
7
  // packages/contracts/src/resilience.ts
7
8
  import { Result } from "better-result";
@@ -22,6 +23,9 @@ function sleep(ms) {
22
23
  }
23
24
  async function retry(fn, options) {
24
25
  const maxAttempts = options?.maxAttempts ?? 3;
26
+ if (!(maxAttempts >= 1)) {
27
+ return Result.err(InternalError.create("maxAttempts must be >= 1", { maxAttempts }));
28
+ }
25
29
  const initialDelayMs = options?.initialDelayMs ?? 1000;
26
30
  const maxDelayMs = options?.maxDelayMs ?? 30000;
27
31
  const backoffMultiplier = options?.backoffMultiplier ?? 2;
@@ -54,7 +58,7 @@ async function retry(fn, options) {
54
58
  }
55
59
  await sleep(delayMs);
56
60
  }
57
- throw new Error("Unexpected: retry loop completed without returning a result");
61
+ return Result.err(InternalError.create("Unexpected: retry loop completed without returning a result"));
58
62
  }
59
63
  async function withTimeout(fn, options) {
60
64
  const { timeoutMs, operation = "operation" } = options;
package/dist/schema.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- import { JsonSchema, zodToJsonSchema } from "./shared/@outfitter/contracts-t79engf9.js";
1
+ import { zodToJsonSchema } from "./shared/@outfitter/contracts-8cmkh2db.js";
2
+ import { JsonSchema } from "./shared/@outfitter/contracts-w7nvcwrp.js";
2
3
  export { zodToJsonSchema, JsonSchema };