@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
@@ -0,0 +1,59 @@
1
+ import { TaggedErrorClass } from "better-result";
2
+ declare const ValidationErrorBase: TaggedErrorClass<"ValidationError", {
3
+ message: string;
4
+ field?: string;
5
+ context?: Record<string, unknown>;
6
+ }>;
7
+ declare const AmbiguousErrorBase: TaggedErrorClass<"AmbiguousError", {
8
+ message: string;
9
+ candidates: string[];
10
+ context?: Record<string, unknown>;
11
+ }>;
12
+ declare const AssertionErrorBase: TaggedErrorClass<"AssertionError", {
13
+ message: string;
14
+ }>;
15
+ declare const NotFoundErrorBase: TaggedErrorClass<"NotFoundError", {
16
+ message: string;
17
+ resourceType: string;
18
+ resourceId: string;
19
+ context?: Record<string, unknown>;
20
+ }>;
21
+ declare const AlreadyExistsErrorBase: TaggedErrorClass<"AlreadyExistsError", {
22
+ message: string;
23
+ resourceType: string;
24
+ resourceId: string;
25
+ context?: Record<string, unknown>;
26
+ }>;
27
+ declare const ConflictErrorBase: TaggedErrorClass<"ConflictError", {
28
+ message: string;
29
+ context?: Record<string, unknown>;
30
+ }>;
31
+ declare const PermissionErrorBase: TaggedErrorClass<"PermissionError", {
32
+ message: string;
33
+ context?: Record<string, unknown>;
34
+ }>;
35
+ declare const TimeoutErrorBase: TaggedErrorClass<"TimeoutError", {
36
+ message: string;
37
+ operation: string;
38
+ timeoutMs: number;
39
+ }>;
40
+ declare const RateLimitErrorBase: TaggedErrorClass<"RateLimitError", {
41
+ message: string;
42
+ retryAfterSeconds?: number;
43
+ }>;
44
+ declare const NetworkErrorBase: TaggedErrorClass<"NetworkError", {
45
+ message: string;
46
+ context?: Record<string, unknown>;
47
+ }>;
48
+ declare const InternalErrorBase: TaggedErrorClass<"InternalError", {
49
+ message: string;
50
+ context?: Record<string, unknown>;
51
+ }>;
52
+ declare const AuthErrorBase: TaggedErrorClass<"AuthError", {
53
+ message: string;
54
+ reason?: "missing" | "invalid" | "expired";
55
+ }>;
56
+ declare const CancelledErrorBase: TaggedErrorClass<"CancelledError", {
57
+ message: string;
58
+ }>;
59
+ export { ValidationErrorBase, AmbiguousErrorBase, AssertionErrorBase, NotFoundErrorBase, AlreadyExistsErrorBase, ConflictErrorBase, PermissionErrorBase, TimeoutErrorBase, RateLimitErrorBase, NetworkErrorBase, InternalErrorBase, AuthErrorBase, CancelledErrorBase };
@@ -0,0 +1,111 @@
1
+ // @bun
2
+ // packages/contracts/src/internal/error-taxonomy.ts
3
+ var exitCodeMap = {
4
+ validation: 1,
5
+ not_found: 2,
6
+ conflict: 3,
7
+ permission: 4,
8
+ timeout: 5,
9
+ rate_limit: 6,
10
+ network: 7,
11
+ internal: 8,
12
+ auth: 9,
13
+ cancelled: 130
14
+ };
15
+ var statusCodeMap = {
16
+ validation: 400,
17
+ not_found: 404,
18
+ conflict: 409,
19
+ permission: 403,
20
+ timeout: 504,
21
+ rate_limit: 429,
22
+ network: 502,
23
+ internal: 500,
24
+ auth: 401,
25
+ cancelled: 499
26
+ };
27
+ var jsonRpcCodeMap = {
28
+ validation: -32602,
29
+ not_found: -32007,
30
+ internal: -32603,
31
+ auth: -32000,
32
+ timeout: -32001,
33
+ conflict: -32002,
34
+ permission: -32003,
35
+ rate_limit: -32004,
36
+ network: -32005,
37
+ cancelled: -32006
38
+ };
39
+ var retryableMap = {
40
+ validation: false,
41
+ not_found: false,
42
+ conflict: false,
43
+ permission: false,
44
+ timeout: true,
45
+ rate_limit: true,
46
+ network: true,
47
+ internal: false,
48
+ auth: false,
49
+ cancelled: false
50
+ };
51
+ function errorCategoryMeta(category) {
52
+ return {
53
+ exitCode: exitCodeMap[category],
54
+ statusCode: statusCodeMap[category],
55
+ jsonRpcCode: jsonRpcCodeMap[category],
56
+ retryable: retryableMap[category]
57
+ };
58
+ }
59
+ var ERROR_CODES = {
60
+ validation: {
61
+ FIELD_REQUIRED: 1001,
62
+ INVALID_FORMAT: 1002,
63
+ OUT_OF_RANGE: 1003,
64
+ TYPE_MISMATCH: 1004,
65
+ AMBIGUOUS_MATCH: 1005
66
+ },
67
+ not_found: {
68
+ RESOURCE_NOT_FOUND: 2001,
69
+ FILE_NOT_FOUND: 2002
70
+ },
71
+ conflict: {
72
+ ALREADY_EXISTS: 3001,
73
+ VERSION_MISMATCH: 3002
74
+ },
75
+ permission: {
76
+ FORBIDDEN: 4001,
77
+ INSUFFICIENT_RIGHTS: 4002
78
+ },
79
+ timeout: {
80
+ OPERATION_TIMEOUT: 5001,
81
+ CONNECTION_TIMEOUT: 5002
82
+ },
83
+ rate_limit: {
84
+ QUOTA_EXCEEDED: 6001,
85
+ THROTTLED: 6002
86
+ },
87
+ network: {
88
+ CONNECTION_REFUSED: 7001,
89
+ DNS_FAILED: 7002
90
+ },
91
+ internal: {
92
+ UNEXPECTED_STATE: 8001,
93
+ ASSERTION_FAILED: 8002
94
+ },
95
+ auth: {
96
+ INVALID_TOKEN: 9001,
97
+ EXPIRED_TOKEN: 9002
98
+ },
99
+ cancelled: {
100
+ USER_CANCELLED: 10001,
101
+ SIGNAL_RECEIVED: 10002
102
+ }
103
+ };
104
+ function getExitCode(category) {
105
+ return exitCodeMap[category];
106
+ }
107
+ function getStatusCode(category) {
108
+ return statusCodeMap[category];
109
+ }
110
+
111
+ export { exitCodeMap, statusCodeMap, jsonRpcCodeMap, retryableMap, errorCategoryMeta, ERROR_CODES, getExitCode, getStatusCode };
@@ -1,4 +1,5 @@
1
- import { OutfitterError, SerializedError } from "./contracts-3gswmhb1.js";
1
+ import { OutfitterError } from "./contracts-7a0xmwbg.js";
2
+ import { SerializedError } from "./contracts-njb2art4.js";
2
3
  import { Result } from "better-result";
3
4
  /**
4
5
  * Metadata attached to every response envelope.
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Hint types for agent-navigable responses.
3
+ *
4
+ * Hints are transport-local suggestions attached to command/tool responses.
5
+ * They guide agents (and humans) toward next actions without coupling
6
+ * handler logic to any specific transport.
7
+ *
8
+ * - {@link ActionHint} — Base hint with description and optional params
9
+ * - {@link CLIHint} — CLI-specific hint with a runnable command
10
+ * - {@link MCPHint} — MCP-specific hint with tool name and optional input
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ /**
15
+ * Base hint type for action responses.
16
+ *
17
+ * Describes a suggested next action with optional structured parameters.
18
+ * Transport-specific hints ({@link CLIHint}, {@link MCPHint}) extend this
19
+ * with transport-appropriate fields.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const hint: ActionHint = {
24
+ * description: "Retry the operation with a longer timeout",
25
+ * params: { timeoutMs: 10_000 },
26
+ * };
27
+ * ```
28
+ */
29
+ interface ActionHint {
30
+ /** Human-readable description of the suggested action. */
31
+ readonly description: string;
32
+ /** Optional structured parameters for the suggested action. */
33
+ readonly params?: Record<string, unknown>;
34
+ }
35
+ /**
36
+ * CLI-specific hint with a runnable command string.
37
+ *
38
+ * Extends {@link ActionHint} with a `command` field that agents or users
39
+ * can execute directly in the terminal.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const hint: CLIHint = {
44
+ * description: "Fix lint issues automatically",
45
+ * command: "outfitter lint --fix",
46
+ * };
47
+ * ```
48
+ */
49
+ interface CLIHint extends ActionHint {
50
+ /** CLI command string that can be executed to perform the suggested action. */
51
+ readonly command: string;
52
+ }
53
+ /**
54
+ * MCP-specific hint with a tool name and optional input.
55
+ *
56
+ * Extends {@link ActionHint} with a `tool` field identifying the MCP tool
57
+ * to invoke, and an optional `input` payload for that tool.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const hint: MCPHint = {
62
+ * description: "Search for related notes",
63
+ * tool: "search-notes",
64
+ * input: { query: "architecture patterns", limit: 5 },
65
+ * };
66
+ * ```
67
+ */
68
+ interface MCPHint extends ActionHint {
69
+ /** MCP tool name to invoke for the suggested action. */
70
+ readonly tool: string;
71
+ /** Optional input payload for the MCP tool. */
72
+ readonly input?: unknown;
73
+ }
74
+ export { ActionHint, CLIHint, MCPHint };
@@ -1,5 +1,5 @@
1
- import { Handler, SyncHandler } from "./contracts-0akf2sm6.js";
2
- import { OutfitterError } from "./contracts-3gswmhb1.js";
1
+ import { Handler, SyncHandler } from "./contracts-zma4mscd.js";
2
+ import { OutfitterError } from "./contracts-7a0xmwbg.js";
3
3
  import { z } from "zod";
4
4
  declare const ACTION_SURFACES: readonly ["cli", "mcp", "api", "server"];
5
5
  type ActionSurface = (typeof ACTION_SURFACES)[number];
@@ -25,7 +25,13 @@ interface ActionCliSpec<TInput = unknown> {
25
25
  interface ActionMcpSpec<TInput = unknown> {
26
26
  readonly deferLoading?: boolean;
27
27
  readonly description?: string;
28
+ /** When true, the action modifies or deletes data */
29
+ readonly destructive?: boolean;
30
+ /** When true, calling the action multiple times with the same input has the same effect */
31
+ readonly idempotent?: boolean;
28
32
  readonly mapInput?: (input: unknown) => TInput;
33
+ /** When true, the action does not modify any state */
34
+ readonly readOnly?: boolean;
29
35
  readonly tool?: string;
30
36
  }
31
37
  type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
@@ -0,0 +1,3 @@
1
+ export { ERROR_CODES, errorCategoryMeta, exitCodeMap, getExitCode, getStatusCode, jsonRpcCodeMap, retryableMap, statusCodeMap } from "../../internal/error-taxonomy.js";
2
+ export { AlreadyExistsError, AmbiguousError, AssertionError, ConflictError, NotFoundError, ValidationError } from "../../internal/error-validation.js";
3
+ export { AuthError, CancelledError, InternalError, NetworkError, PermissionError, RateLimitError, TimeoutError } from "../../internal/error-operational.js";
@@ -0,0 +1,44 @@
1
+ /**
2
+ * JSON Schema type definitions and Zod introspection helpers.
3
+ *
4
+ * @internal
5
+ */
6
+ /**
7
+ * JSON Schema representation.
8
+ */
9
+ interface JsonSchema {
10
+ $defs?: Record<string, JsonSchema>;
11
+ $ref?: string;
12
+ $schema?: string;
13
+ additionalProperties?: boolean | JsonSchema;
14
+ allOf?: JsonSchema[];
15
+ anyOf?: JsonSchema[];
16
+ const?: unknown;
17
+ default?: unknown;
18
+ definitions?: Record<string, JsonSchema>;
19
+ description?: string;
20
+ enum?: unknown[];
21
+ exclusiveMaximum?: number;
22
+ exclusiveMinimum?: number;
23
+ format?: string;
24
+ items?: JsonSchema | JsonSchema[];
25
+ maximum?: number;
26
+ maxLength?: number;
27
+ minimum?: number;
28
+ minLength?: number;
29
+ not?: JsonSchema | Record<string, never>;
30
+ oneOf?: JsonSchema[];
31
+ pattern?: string;
32
+ properties?: Record<string, JsonSchema>;
33
+ required?: string[];
34
+ type?: string;
35
+ }
36
+ /**
37
+ * Extract the internal _def object from a Zod schema or def.
38
+ */
39
+ declare function getDef(schemaOrDef: any): any;
40
+ /**
41
+ * Extract description from a Zod schema or its def.
42
+ */
43
+ declare function getDescription(schema: any, def: any): string | undefined;
44
+ export { JsonSchema, getDef, getDescription };
@@ -0,0 +1,76 @@
1
+ import { ValidationError } from "./contracts-mehpmvwp.js";
2
+ import { Result } from "better-result";
3
+ import { z } from "zod";
4
+ /**
5
+ * Format Zod issues into a human-readable error message.
6
+ *
7
+ * @param issues - Array of Zod validation issues
8
+ * @returns Formatted error message string
9
+ */
10
+ declare function formatZodIssues(issues: z.ZodIssue[]): string;
11
+ /**
12
+ * Create a validator function from a Zod schema.
13
+ *
14
+ * @typeParam T - The validated output type
15
+ * @param schema - Zod schema to validate against
16
+ * @returns A function that validates input and returns Result
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const NoteSchema = z.object({
21
+ * id: z.string().uuid(),
22
+ * title: z.string().min(1),
23
+ * });
24
+ *
25
+ * const validateNote = createValidator(NoteSchema);
26
+ * const result = validateNote(input); // Result<Note, ValidationError>
27
+ * ```
28
+ */
29
+ declare function createValidator<T>(schema: z.ZodType<T>): (input: unknown) => Result<T, ValidationError>;
30
+ /**
31
+ * Validate input against a Zod schema.
32
+ *
33
+ * Standardized wrapper for Zod schemas that returns Result instead of throwing.
34
+ *
35
+ * @typeParam T - The validated output type
36
+ * @param schema - Zod schema to validate against
37
+ * @param input - Unknown input to validate
38
+ * @returns Result with validated data or ValidationError
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const result = validateInput(NoteSchema, userInput);
43
+ * if (result.isErr()) {
44
+ * console.error(result.unwrapErr().message);
45
+ * }
46
+ * ```
47
+ */
48
+ declare function validateInput<T>(schema: z.ZodType<T>, input: unknown): Result<T, ValidationError>;
49
+ /**
50
+ * Parse and validate data against a Zod schema, returning a Result.
51
+ *
52
+ * Wraps Zod's `safeParse` into `Result<T, ValidationError>` where `T` is
53
+ * automatically inferred from the schema — no manual type argument needed.
54
+ *
55
+ * @typeParam TSchema - The Zod schema type (inferred from `schema` argument)
56
+ * @param schema - Zod schema to parse/validate against
57
+ * @param data - Unknown data to parse
58
+ * @returns `Ok<z.infer<TSchema>>` for valid data, `Err<ValidationError>` for invalid data
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const UserSchema = z.object({
63
+ * name: z.string().min(1),
64
+ * email: z.string().email(),
65
+ * });
66
+ *
67
+ * const result = parseInput(UserSchema, input);
68
+ * // Result<{ name: string; email: string }, ValidationError>
69
+ *
70
+ * if (result.isOk()) {
71
+ * result.value.name; // string — fully typed, no manual annotation
72
+ * }
73
+ * ```
74
+ */
75
+ declare function parseInput<TSchema extends z.ZodType>(schema: TSchema, data: unknown): Result<z.infer<TSchema>, ValidationError>;
76
+ export { formatZodIssues, createValidator, validateInput, parseInput };
@@ -1,4 +1,5 @@
1
- import { OutfitterError } from "./contracts-3gswmhb1.js";
1
+ import { ProgressCallback } from "./contracts-msxdg52h.js";
2
+ import { OutfitterError } from "./contracts-7a0xmwbg.js";
2
3
  import { Logger } from "./contracts-rwzqy9rn.js";
3
4
  import { Result } from "better-result";
4
5
  /**
@@ -29,6 +30,20 @@ interface HandlerContext {
29
30
  env: Record<string, string | undefined>;
30
31
  /** Structured logger with automatic redaction */
31
32
  logger: Logger;
33
+ /**
34
+ * Optional streaming progress callback.
35
+ *
36
+ * When provided by a transport adapter, the handler can emit progress
37
+ * events without knowing which transport consumes them. When `undefined`,
38
+ * the handler does not stream — it simply returns its final result.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * ctx.progress?.({ type: "start", command: "check", ts: new Date().toISOString() });
43
+ * ctx.progress?.({ type: "progress", current: 5, total: 10 });
44
+ * ```
45
+ */
46
+ progress?: ProgressCallback;
32
47
  /** Unique request identifier for tracing (UUIDv7) */
33
48
  requestId: string;
34
49
  /** Abort signal for cancellation propagation */
@@ -0,0 +1,84 @@
1
+ import { OutfitterError } from "./contracts-7a0xmwbg.js";
2
+ /**
3
+ * An error mapper converts an unknown error into a typed OutfitterError.
4
+ *
5
+ * Return `undefined` if the mapper does not handle this error (pass to next mapper or default).
6
+ */
7
+ type ErrorMapper = (error: unknown) => OutfitterError | undefined;
8
+ /**
9
+ * Type guard: checks whether `value` is a typed Outfitter error (has a `category` field
10
+ * matching a known {@link ErrorCategory}).
11
+ */
12
+ declare function isOutfitterError(value: unknown): value is OutfitterError;
13
+ /**
14
+ * Extract a human-readable message from an unknown error value.
15
+ *
16
+ * Handles Error instances, plain strings, objects with a `message` property,
17
+ * and falls back to `"Unknown error"` for everything else.
18
+ */
19
+ declare function extractMessage(error: unknown): string;
20
+ /**
21
+ * Normalize an unknown error into a typed OutfitterError.
22
+ *
23
+ * - Typed Outfitter errors pass through unchanged (same reference, mapper NOT called).
24
+ * - Untyped errors go through optional mapper.
25
+ * - Without mapper or when mapper returns `undefined`, wraps as {@link InternalError}.
26
+ * - Plain strings are wrapped as InternalError with the string as message.
27
+ *
28
+ * @param error - The unknown error to normalize
29
+ * @param mapper - Optional mapper to convert untyped errors into typed OutfitterErrors
30
+ * @returns A typed OutfitterError
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // Typed errors pass through
35
+ * const typed = new ValidationError({ message: "bad input" });
36
+ * wrapError(typed) === typed; // true — same reference
37
+ *
38
+ * // Untyped errors go through mapper
39
+ * const mapper: ErrorMapper = (err) => {
40
+ * if (err instanceof Error && err.message.includes("ECONNREFUSED")) {
41
+ * return new NetworkError({ message: err.message });
42
+ * }
43
+ * return undefined;
44
+ * };
45
+ * wrapError(new Error("ECONNREFUSED"), mapper); // NetworkError
46
+ *
47
+ * // Unmatched errors become InternalError
48
+ * wrapError(new Error("unknown")); // InternalError
49
+ *
50
+ * // Strings become InternalError with message
51
+ * wrapError("something failed"); // InternalError { message: "something failed" }
52
+ * ```
53
+ */
54
+ declare function wrapError(error: unknown, mapper?: ErrorMapper): OutfitterError;
55
+ /**
56
+ * Compose multiple error mappers into a single mapper.
57
+ *
58
+ * Mappers run in declared order and short-circuit on the first match
59
+ * (first mapper to return a non-`undefined` value wins).
60
+ *
61
+ * @param mappers - Error mappers to compose
62
+ * @returns A single composed error mapper
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const networkMapper: ErrorMapper = (err) => {
67
+ * if (err instanceof Error && err.message.includes("ECONNREFUSED")) {
68
+ * return new NetworkError({ message: err.message });
69
+ * }
70
+ * return undefined;
71
+ * };
72
+ * const timeoutMapper: ErrorMapper = (err) => {
73
+ * if (err instanceof Error && err.message.includes("ETIMEDOUT")) {
74
+ * return TimeoutError.create("request", 5000);
75
+ * }
76
+ * return undefined;
77
+ * };
78
+ *
79
+ * const composed = composeMappers(networkMapper, timeoutMapper);
80
+ * wrapError(new Error("ECONNREFUSED"), composed); // NetworkError
81
+ * ```
82
+ */
83
+ declare function composeMappers(...mappers: ErrorMapper[]): ErrorMapper;
84
+ export { ErrorMapper, isOutfitterError, extractMessage, wrapError, composeMappers };
@@ -0,0 +1,2 @@
1
+ import { ProgressCallback, StreamEvent, StreamProgressEvent, StreamStartEvent, StreamStepEvent } from "./shared/@outfitter/contracts-msxdg52h.js";
2
+ export { StreamStepEvent, StreamStartEvent, StreamProgressEvent, StreamEvent, ProgressCallback };
package/dist/stream.js ADDED
@@ -0,0 +1 @@
1
+ // @bun
@@ -1,3 +1,7 @@
1
- import { createValidator, validateInput } from "./shared/@outfitter/contracts-9wtm5nsw.js";
2
- import "./shared/@outfitter/contracts-3gswmhb1.js";
3
- export { validateInput, createValidator };
1
+ import { createValidator, formatZodIssues, parseInput, validateInput } from "./shared/@outfitter/contracts-x0ppyt7e.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 { validateInput, parseInput, formatZodIssues, createValidator };
@@ -1,42 +1,14 @@
1
1
  // @bun
2
2
  import {
3
- ValidationError
4
- } from "./shared/@outfitter/contracts-phjhz5q3.js";
5
-
6
- // packages/contracts/src/validation.ts
7
- import { Result } from "better-result";
8
- function formatZodIssues(issues) {
9
- return issues.map((issue) => {
10
- const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
11
- return `${path}: ${issue.message}`;
12
- }).join("; ");
13
- }
14
- function extractField(issues) {
15
- const firstIssue = issues[0];
16
- if (firstIssue && firstIssue.path.length > 0) {
17
- return firstIssue.path.join(".");
18
- }
19
- return;
20
- }
21
- function createValidator(schema) {
22
- return (input) => {
23
- return validateInput(schema, input);
24
- };
25
- }
26
- function validateInput(schema, input) {
27
- const parseResult = schema.safeParse(input);
28
- if (parseResult.success) {
29
- return Result.ok(parseResult.data);
30
- }
31
- const message = formatZodIssues(parseResult.error.issues);
32
- const field = extractField(parseResult.error.issues);
33
- const errorProps = { message };
34
- if (field !== undefined) {
35
- errorProps.field = field;
36
- }
37
- return Result.err(new ValidationError(errorProps));
38
- }
3
+ createValidator,
4
+ formatZodIssues,
5
+ parseInput,
6
+ validateInput
7
+ } from "./shared/@outfitter/contracts-hgh47193.js";
8
+ import"./shared/@outfitter/contracts-vhr2ep6b.js";
39
9
  export {
40
10
  validateInput,
11
+ parseInput,
12
+ formatZodIssues,
41
13
  createValidator
42
14
  };
@@ -0,0 +1,7 @@
1
+ import { ErrorMapper, composeMappers, extractMessage, isOutfitterError, wrapError } from "./shared/@outfitter/contracts-zsgxsa91.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 { wrapError, isOutfitterError, extractMessage, composeMappers, ErrorMapper };
@@ -0,0 +1,71 @@
1
+ // @bun
2
+ import {
3
+ InternalError
4
+ } from "./shared/@outfitter/contracts-vhr2ep6b.js";
5
+
6
+ // packages/contracts/src/wrap-error.ts
7
+ function isOutfitterError(value) {
8
+ if (!(value instanceof Error)) {
9
+ return false;
10
+ }
11
+ const candidate = value;
12
+ return typeof candidate["category"] === "string" && typeof candidate["message"] === "string" && typeof candidate["_tag"] === "string" && isErrorCategory(candidate["category"]);
13
+ }
14
+ var ERROR_CATEGORIES = new Set([
15
+ "validation",
16
+ "not_found",
17
+ "conflict",
18
+ "permission",
19
+ "timeout",
20
+ "rate_limit",
21
+ "network",
22
+ "internal",
23
+ "auth",
24
+ "cancelled"
25
+ ]);
26
+ function isErrorCategory(value) {
27
+ return ERROR_CATEGORIES.has(value);
28
+ }
29
+ function extractMessage(error) {
30
+ if (typeof error === "string") {
31
+ return error || "Unknown error";
32
+ }
33
+ if (error instanceof Error) {
34
+ return error.message || "Unknown error";
35
+ }
36
+ if (error != null && typeof error === "object" && "message" in error) {
37
+ const msg = error["message"];
38
+ return typeof msg === "string" && msg ? msg : "Unknown error";
39
+ }
40
+ return "Unknown error";
41
+ }
42
+ function wrapError(error, mapper) {
43
+ if (isOutfitterError(error)) {
44
+ return error;
45
+ }
46
+ if (mapper != null) {
47
+ const mapped = mapper(error);
48
+ if (mapped != null) {
49
+ return mapped;
50
+ }
51
+ }
52
+ const message = extractMessage(error);
53
+ return new InternalError({ message });
54
+ }
55
+ function composeMappers(...mappers) {
56
+ return (error) => {
57
+ for (const mapper of mappers) {
58
+ const result = mapper(error);
59
+ if (result != null) {
60
+ return result;
61
+ }
62
+ }
63
+ return;
64
+ };
65
+ }
66
+ export {
67
+ wrapError,
68
+ isOutfitterError,
69
+ extractMessage,
70
+ composeMappers
71
+ };