@outfitter/contracts 0.4.1 → 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 (100) hide show
  1. package/README.md +18 -15
  2. package/dist/actions.d.ts +8 -3
  3. package/dist/actions.js +25 -6
  4. package/dist/assert/index.d.ts +7 -3
  5. package/dist/assert/index.js +59 -6
  6. package/dist/capabilities.js +57 -8
  7. package/dist/context.d.ts +8 -3
  8. package/dist/context.js +1 -1
  9. package/dist/envelope.d.ts +6 -2
  10. package/dist/envelope.js +49 -7
  11. package/dist/errors.d.ts +6 -2
  12. package/dist/errors.js +7 -1
  13. package/dist/from-fetch.d.ts +7 -0
  14. package/dist/from-fetch.js +110 -0
  15. package/dist/handler.d.ts +7 -2
  16. package/dist/hints.d.ts +2 -0
  17. package/dist/index.d.ts +25 -14
  18. package/dist/index.js +17 -153
  19. package/dist/internal/error-base.d.ts +2 -0
  20. package/dist/internal/error-base.js +31 -0
  21. package/dist/internal/error-operational.d.ts +3 -0
  22. package/dist/internal/error-operational.js +125 -0
  23. package/dist/internal/error-serialization.d.ts +7 -0
  24. package/dist/{shared/@outfitter/contracts-3wj7xghe.js → internal/error-serialization.js} +28 -67
  25. package/dist/internal/error-taxonomy.d.ts +2 -0
  26. package/dist/internal/error-taxonomy.js +21 -0
  27. package/dist/internal/error-validation.d.ts +3 -0
  28. package/dist/internal/error-validation.js +121 -0
  29. package/dist/internal/safe-json.d.ts +7 -0
  30. package/dist/internal/safe-json.js +66 -0
  31. package/dist/internal/schema-converters.d.ts +26 -0
  32. package/dist/internal/schema-converters.js +12 -0
  33. package/dist/internal/schema-primitives.d.ts +10 -0
  34. package/dist/internal/schema-primitives.js +9 -0
  35. package/dist/internal/schema-types.d.ts +2 -0
  36. package/dist/internal/schema-types.js +9 -0
  37. package/dist/logging.js +11 -3
  38. package/dist/recovery.d.ts +6 -2
  39. package/dist/recovery.js +49 -6
  40. package/dist/resilience.d.ts +6 -2
  41. package/dist/resilience.js +80 -4
  42. package/dist/result/index.js +1 -16
  43. package/dist/result/utilities.js +29 -7
  44. package/dist/schema.d.ts +2 -1
  45. package/dist/schema.js +165 -2
  46. package/dist/serialization.d.ts +8 -2
  47. package/dist/serialization.js +1 -3
  48. package/dist/shared/@outfitter/{contracts-k71jqd1m.d.ts → contracts-10p5q75w.d.ts} +1 -1
  49. package/dist/shared/@outfitter/contracts-1zzcpfyg.d.ts +40 -0
  50. package/dist/shared/@outfitter/contracts-3f5k5tg5.d.ts +28 -0
  51. package/dist/shared/@outfitter/contracts-3qmyq81n.d.ts +78 -0
  52. package/dist/shared/@outfitter/contracts-3re9d4bp.js +114 -0
  53. package/dist/shared/@outfitter/contracts-735ecmbq.d.ts +107 -0
  54. package/dist/shared/@outfitter/contracts-7a0xmwbg.d.ts +11 -0
  55. package/dist/shared/@outfitter/contracts-8cmkh2db.d.ts +31 -0
  56. package/dist/shared/@outfitter/{contracts-agmt8915.js → contracts-c3qfce25.js} +3 -0
  57. package/dist/shared/@outfitter/{contracts-1waabxbk.d.ts → contracts-drwd9ywk.d.ts} +4 -1
  58. package/dist/shared/@outfitter/{contracts-0snpmkdt.js → contracts-hgh47193.js} +10 -4
  59. package/dist/shared/@outfitter/contracts-hrepwwne.js +62 -0
  60. package/dist/shared/@outfitter/contracts-jtn6b927.js +18 -0
  61. package/dist/shared/@outfitter/contracts-jtt6dnmg.js +2 -0
  62. package/dist/shared/@outfitter/contracts-jyhqr766.js +25 -0
  63. package/dist/shared/@outfitter/contracts-mehpmvwp.d.ts +164 -0
  64. package/dist/shared/@outfitter/contracts-msxdg52h.d.ts +125 -0
  65. package/dist/shared/@outfitter/{contracts-95cc3y06.d.ts → contracts-mt027fqj.d.ts} +2 -1
  66. package/dist/shared/@outfitter/contracts-njb2art4.d.ts +174 -0
  67. package/dist/shared/@outfitter/contracts-p77yjs4g.d.ts +46 -0
  68. package/dist/shared/@outfitter/contracts-qpbv29bg.d.ts +59 -0
  69. package/dist/shared/@outfitter/contracts-sawwfgb5.js +111 -0
  70. package/dist/shared/@outfitter/{contracts-e4m948m7.d.ts → contracts-t4txv24h.d.ts} +2 -1
  71. package/dist/shared/@outfitter/contracts-vbgt9rfn.d.ts +74 -0
  72. package/dist/shared/@outfitter/{contracts-56pcsavx.d.ts → contracts-vhajx4gg.d.ts} +8 -2
  73. package/dist/shared/@outfitter/contracts-vhr2ep6b.js +3 -0
  74. package/dist/shared/@outfitter/contracts-w7nvcwrp.d.ts +44 -0
  75. package/dist/shared/@outfitter/contracts-x0ppyt7e.d.ts +76 -0
  76. package/dist/shared/@outfitter/{contracts-0akf2sm6.d.ts → contracts-zma4mscd.d.ts} +16 -1
  77. package/dist/shared/@outfitter/contracts-zsgxsa91.d.ts +84 -0
  78. package/dist/stream.d.ts +2 -0
  79. package/dist/stream.js +1 -0
  80. package/dist/validation.d.ts +7 -3
  81. package/dist/validation.js +6 -2
  82. package/dist/wrap-error.d.ts +7 -0
  83. package/dist/wrap-error.js +71 -0
  84. package/package.json +44 -20
  85. package/dist/shared/@outfitter/contracts-31penhwa.d.ts +0 -81
  86. package/dist/shared/@outfitter/contracts-3gswmhb1.d.ts +0 -446
  87. package/dist/shared/@outfitter/contracts-4zaj7ejb.js +0 -52
  88. package/dist/shared/@outfitter/contracts-85nd53s9.js +0 -53
  89. package/dist/shared/@outfitter/contracts-9wtm5nsw.d.ts +0 -42
  90. package/dist/shared/@outfitter/contracts-cp5c6dws.js +0 -32
  91. package/dist/shared/@outfitter/contracts-d0tq2adf.js +0 -60
  92. package/dist/shared/@outfitter/contracts-mmg0npfk.d.ts +0 -30
  93. package/dist/shared/@outfitter/contracts-phjhz5q3.js +0 -293
  94. package/dist/shared/@outfitter/contracts-q0v44kef.js +0 -28
  95. package/dist/shared/@outfitter/contracts-r21yet6j.js +0 -80
  96. package/dist/shared/@outfitter/contracts-sm6vak1a.js +0 -14
  97. package/dist/shared/@outfitter/contracts-t79engf9.d.ts +0 -60
  98. package/dist/shared/@outfitter/contracts-wfht4q2b.js +0 -341
  99. package/dist/shared/@outfitter/contracts-zx72gyh1.js +0 -32
  100. /package/dist/{shared/@outfitter/contracts-37gpc56f.js → hints.js} +0 -0
@@ -1,30 +0,0 @@
1
- import { AssertionError } from "./contracts-3gswmhb1.js";
2
- import { Result } from "better-result";
3
- /**
4
- * Array type guaranteed to have at least one element.
5
- */
6
- type NonEmptyArray<T> = [T, ...T[]];
7
- /**
8
- * Type guard for NonEmptyArray.
9
- */
10
- declare const isNonEmptyArray: <T>(arr: readonly T[]) => arr is NonEmptyArray<T>;
11
- /**
12
- * Assert a value is defined (not null or undefined).
13
- * Returns Result instead of throwing.
14
- */
15
- declare const assertDefined: <T>(value: T | null | undefined, message?: string) => Result<T, InstanceType<typeof AssertionError>>;
16
- /**
17
- * Assert array has at least one element.
18
- * Returns NonEmptyArray on success.
19
- */
20
- declare const assertNonEmpty: <T>(arr: readonly T[], message?: string) => Result<NonEmptyArray<T>, InstanceType<typeof AssertionError>>;
21
- /**
22
- * Assert value matches a predicate.
23
- * Supports type guard predicates for narrowing.
24
- */
25
- declare function assertMatches<
26
- T,
27
- U extends T
28
- >(value: T, predicate: (v: T) => v is U, message?: string): Result<U, InstanceType<typeof AssertionError>>;
29
- declare function assertMatches<T>(value: T, predicate: (v: T) => boolean, message?: string): Result<T, InstanceType<typeof AssertionError>>;
30
- export { NonEmptyArray, isNonEmptyArray, assertDefined, assertNonEmpty, assertMatches };
@@ -1,293 +0,0 @@
1
- // @bun
2
- // packages/contracts/src/errors.ts
3
- import { TaggedError } from "better-result";
4
- var exitCodeMap = {
5
- validation: 1,
6
- not_found: 2,
7
- conflict: 3,
8
- permission: 4,
9
- timeout: 5,
10
- rate_limit: 6,
11
- network: 7,
12
- internal: 8,
13
- auth: 9,
14
- cancelled: 130
15
- };
16
- var statusCodeMap = {
17
- validation: 400,
18
- not_found: 404,
19
- conflict: 409,
20
- permission: 403,
21
- timeout: 504,
22
- rate_limit: 429,
23
- network: 502,
24
- internal: 500,
25
- auth: 401,
26
- cancelled: 499
27
- };
28
- var ERROR_CODES = {
29
- validation: {
30
- FIELD_REQUIRED: 1001,
31
- INVALID_FORMAT: 1002,
32
- OUT_OF_RANGE: 1003,
33
- TYPE_MISMATCH: 1004,
34
- AMBIGUOUS_MATCH: 1005
35
- },
36
- not_found: {
37
- RESOURCE_NOT_FOUND: 2001,
38
- FILE_NOT_FOUND: 2002
39
- },
40
- conflict: {
41
- ALREADY_EXISTS: 3001,
42
- VERSION_MISMATCH: 3002
43
- },
44
- permission: {
45
- FORBIDDEN: 4001,
46
- INSUFFICIENT_RIGHTS: 4002
47
- },
48
- timeout: {
49
- OPERATION_TIMEOUT: 5001,
50
- CONNECTION_TIMEOUT: 5002
51
- },
52
- rate_limit: {
53
- QUOTA_EXCEEDED: 6001,
54
- THROTTLED: 6002
55
- },
56
- network: {
57
- CONNECTION_REFUSED: 7001,
58
- DNS_FAILED: 7002
59
- },
60
- internal: {
61
- UNEXPECTED_STATE: 8001,
62
- ASSERTION_FAILED: 8002
63
- },
64
- auth: {
65
- INVALID_TOKEN: 9001,
66
- EXPIRED_TOKEN: 9002
67
- },
68
- cancelled: {
69
- USER_CANCELLED: 10001,
70
- SIGNAL_RECEIVED: 10002
71
- }
72
- };
73
- function getExitCode(category) {
74
- return exitCodeMap[category];
75
- }
76
- function getStatusCode(category) {
77
- return statusCodeMap[category];
78
- }
79
- var ValidationErrorBase = TaggedError("ValidationError")();
80
- var AmbiguousErrorBase = TaggedError("AmbiguousError")();
81
- var AssertionErrorBase = TaggedError("AssertionError")();
82
- var NotFoundErrorBase = TaggedError("NotFoundError")();
83
- var AlreadyExistsErrorBase = TaggedError("AlreadyExistsError")();
84
- var ConflictErrorBase = TaggedError("ConflictError")();
85
- var PermissionErrorBase = TaggedError("PermissionError")();
86
- var TimeoutErrorBase = TaggedError("TimeoutError")();
87
- var RateLimitErrorBase = TaggedError("RateLimitError")();
88
- var NetworkErrorBase = TaggedError("NetworkError")();
89
- var InternalErrorBase = TaggedError("InternalError")();
90
- var AuthErrorBase = TaggedError("AuthError")();
91
- var CancelledErrorBase = TaggedError("CancelledError")();
92
-
93
- class ValidationError extends ValidationErrorBase {
94
- category = "validation";
95
- static create(field, reason, context) {
96
- return new ValidationError({
97
- message: `${field}: ${reason}`,
98
- field,
99
- ...context != null && { context }
100
- });
101
- }
102
- static fromMessage(message, context) {
103
- return new ValidationError({
104
- message,
105
- ...context != null && { context }
106
- });
107
- }
108
- exitCode() {
109
- return getExitCode(this.category);
110
- }
111
- statusCode() {
112
- return getStatusCode(this.category);
113
- }
114
- }
115
-
116
- class AmbiguousError extends AmbiguousErrorBase {
117
- category = "validation";
118
- static create(what, candidates, context) {
119
- return new AmbiguousError({
120
- message: `Ambiguous ${what}: ${candidates.length} matches found`,
121
- candidates,
122
- ...context != null && { context }
123
- });
124
- }
125
- exitCode() {
126
- return getExitCode(this.category);
127
- }
128
- statusCode() {
129
- return getStatusCode(this.category);
130
- }
131
- }
132
-
133
- class AssertionError extends AssertionErrorBase {
134
- category = "internal";
135
- exitCode() {
136
- return getExitCode(this.category);
137
- }
138
- statusCode() {
139
- return getStatusCode(this.category);
140
- }
141
- }
142
-
143
- class NotFoundError extends NotFoundErrorBase {
144
- category = "not_found";
145
- static create(resourceType, resourceId, context) {
146
- return new NotFoundError({
147
- message: `${resourceType} not found: ${resourceId}`,
148
- resourceType,
149
- resourceId,
150
- ...context != null && { context }
151
- });
152
- }
153
- exitCode() {
154
- return getExitCode(this.category);
155
- }
156
- statusCode() {
157
- return getStatusCode(this.category);
158
- }
159
- }
160
-
161
- class AlreadyExistsError extends AlreadyExistsErrorBase {
162
- category = "conflict";
163
- static create(resourceType, resourceId, context) {
164
- return new AlreadyExistsError({
165
- message: `${resourceType} already exists: ${resourceId}`,
166
- resourceType,
167
- resourceId,
168
- ...context != null && { context }
169
- });
170
- }
171
- exitCode() {
172
- return getExitCode(this.category);
173
- }
174
- statusCode() {
175
- return getStatusCode(this.category);
176
- }
177
- }
178
-
179
- class ConflictError extends ConflictErrorBase {
180
- category = "conflict";
181
- static create(message, context) {
182
- return new ConflictError({ message, ...context != null && { context } });
183
- }
184
- exitCode() {
185
- return getExitCode(this.category);
186
- }
187
- statusCode() {
188
- return getStatusCode(this.category);
189
- }
190
- }
191
-
192
- class PermissionError extends PermissionErrorBase {
193
- category = "permission";
194
- static create(message, context) {
195
- return new PermissionError({
196
- message,
197
- ...context != null && { context }
198
- });
199
- }
200
- exitCode() {
201
- return getExitCode(this.category);
202
- }
203
- statusCode() {
204
- return getStatusCode(this.category);
205
- }
206
- }
207
-
208
- class TimeoutError extends TimeoutErrorBase {
209
- category = "timeout";
210
- static create(operation, timeoutMs) {
211
- return new TimeoutError({
212
- message: `${operation} timed out after ${timeoutMs}ms`,
213
- operation,
214
- timeoutMs
215
- });
216
- }
217
- exitCode() {
218
- return getExitCode(this.category);
219
- }
220
- statusCode() {
221
- return getStatusCode(this.category);
222
- }
223
- }
224
-
225
- class RateLimitError extends RateLimitErrorBase {
226
- category = "rate_limit";
227
- static create(message, retryAfterSeconds) {
228
- return new RateLimitError({
229
- message,
230
- ...retryAfterSeconds != null && { retryAfterSeconds }
231
- });
232
- }
233
- exitCode() {
234
- return getExitCode(this.category);
235
- }
236
- statusCode() {
237
- return getStatusCode(this.category);
238
- }
239
- }
240
-
241
- class NetworkError extends NetworkErrorBase {
242
- category = "network";
243
- static create(message, context) {
244
- return new NetworkError({ message, ...context != null && { context } });
245
- }
246
- exitCode() {
247
- return getExitCode(this.category);
248
- }
249
- statusCode() {
250
- return getStatusCode(this.category);
251
- }
252
- }
253
-
254
- class InternalError extends InternalErrorBase {
255
- category = "internal";
256
- static create(message, context) {
257
- return new InternalError({ message, ...context != null && { context } });
258
- }
259
- exitCode() {
260
- return getExitCode(this.category);
261
- }
262
- statusCode() {
263
- return getStatusCode(this.category);
264
- }
265
- }
266
-
267
- class AuthError extends AuthErrorBase {
268
- category = "auth";
269
- static create(message, reason) {
270
- return new AuthError({ message, ...reason != null && { reason } });
271
- }
272
- exitCode() {
273
- return getExitCode(this.category);
274
- }
275
- statusCode() {
276
- return getStatusCode(this.category);
277
- }
278
- }
279
-
280
- class CancelledError extends CancelledErrorBase {
281
- category = "cancelled";
282
- static create(message) {
283
- return new CancelledError({ message });
284
- }
285
- exitCode() {
286
- return getExitCode(this.category);
287
- }
288
- statusCode() {
289
- return getStatusCode(this.category);
290
- }
291
- }
292
-
293
- export { exitCodeMap, statusCodeMap, ERROR_CODES, getExitCode, getStatusCode, ValidationError, AmbiguousError, AssertionError, NotFoundError, AlreadyExistsError, ConflictError, PermissionError, TimeoutError, RateLimitError, NetworkError, InternalError, AuthError, CancelledError };
@@ -1,28 +0,0 @@
1
- // @bun
2
- // packages/contracts/src/actions.ts
3
- var ACTION_SURFACES = ["cli", "mcp", "api", "server"];
4
- var DEFAULT_REGISTRY_SURFACES = ACTION_SURFACES;
5
- function defineAction(action) {
6
- return action;
7
- }
8
- function createActionRegistry() {
9
- const actions = new Map;
10
- return {
11
- add(action) {
12
- actions.set(action.id, action);
13
- return this;
14
- },
15
- list() {
16
- return Array.from(actions.values());
17
- },
18
- get(id) {
19
- return actions.get(id);
20
- },
21
- forSurface(surface) {
22
- const defaults = DEFAULT_REGISTRY_SURFACES;
23
- return Array.from(actions.values()).filter((action) => (action.surfaces ?? defaults).includes(surface));
24
- }
25
- };
26
- }
27
-
28
- export { ACTION_SURFACES, DEFAULT_REGISTRY_SURFACES, defineAction, createActionRegistry };
@@ -1,80 +0,0 @@
1
- // @bun
2
- import {
3
- TimeoutError
4
- } from "./contracts-phjhz5q3.js";
5
-
6
- // packages/contracts/src/resilience.ts
7
- import { Result } from "better-result";
8
- function defaultIsRetryable(error) {
9
- return error.category === "network" || error.category === "timeout" || error.category === "rate_limit";
10
- }
11
- function calculateDelay(attempt, initialDelayMs, maxDelayMs, backoffMultiplier, jitter) {
12
- const baseDelay = initialDelayMs * backoffMultiplier ** (attempt - 1);
13
- const cappedDelay = Math.min(baseDelay, maxDelayMs);
14
- if (jitter) {
15
- const jitterFactor = 0.5 + Math.random();
16
- return Math.floor(cappedDelay * jitterFactor);
17
- }
18
- return cappedDelay;
19
- }
20
- function sleep(ms) {
21
- return new Promise((resolve) => setTimeout(resolve, ms));
22
- }
23
- async function retry(fn, options) {
24
- const maxAttempts = options?.maxAttempts ?? 3;
25
- const initialDelayMs = options?.initialDelayMs ?? 1000;
26
- const maxDelayMs = options?.maxDelayMs ?? 30000;
27
- const backoffMultiplier = options?.backoffMultiplier ?? 2;
28
- const jitter = options?.jitter ?? true;
29
- const isRetryable = options?.isRetryable ?? defaultIsRetryable;
30
- const onRetry = options?.onRetry;
31
- const signal = options?.signal;
32
- let lastError;
33
- let attempt = 0;
34
- while (attempt < maxAttempts) {
35
- attempt++;
36
- if (signal?.aborted) {
37
- return Result.err(lastError ?? new TimeoutError({
38
- message: "Operation cancelled",
39
- operation: "retry",
40
- timeoutMs: 0
41
- }));
42
- }
43
- const result = await fn();
44
- if (result.isOk()) {
45
- return result;
46
- }
47
- lastError = result.error;
48
- if (attempt >= maxAttempts || !isRetryable(lastError)) {
49
- return result;
50
- }
51
- const delayMs = calculateDelay(attempt, initialDelayMs, maxDelayMs, backoffMultiplier, jitter);
52
- if (onRetry) {
53
- onRetry(attempt, lastError, delayMs);
54
- }
55
- await sleep(delayMs);
56
- }
57
- throw new Error("Unexpected: retry loop completed without returning a result");
58
- }
59
- async function withTimeout(fn, options) {
60
- const { timeoutMs, operation = "operation" } = options;
61
- let timeoutId;
62
- const timeoutPromise = new Promise((resolve) => {
63
- timeoutId = setTimeout(() => {
64
- resolve(Result.err(new TimeoutError({
65
- message: `${operation} timed out after ${timeoutMs}ms`,
66
- operation,
67
- timeoutMs
68
- })));
69
- }, timeoutMs);
70
- });
71
- try {
72
- return await Promise.race([fn(), timeoutPromise]);
73
- } finally {
74
- if (timeoutId !== undefined) {
75
- clearTimeout(timeoutId);
76
- }
77
- }
78
- }
79
-
80
- export { retry, withTimeout };
@@ -1,14 +0,0 @@
1
- // @bun
2
- // packages/contracts/src/logging.ts
3
- function createLoggerFactory(adapter) {
4
- return {
5
- createLogger(config) {
6
- return adapter.createLogger(config);
7
- },
8
- async flush() {
9
- await adapter.flush?.();
10
- }
11
- };
12
- }
13
-
14
- export { createLoggerFactory };
@@ -1,60 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * JSON Schema representation.
4
- */
5
- interface JsonSchema {
6
- $defs?: Record<string, JsonSchema>;
7
- $ref?: string;
8
- $schema?: string;
9
- additionalProperties?: boolean | JsonSchema;
10
- allOf?: JsonSchema[];
11
- anyOf?: JsonSchema[];
12
- const?: unknown;
13
- default?: unknown;
14
- definitions?: Record<string, JsonSchema>;
15
- description?: string;
16
- enum?: unknown[];
17
- exclusiveMaximum?: number;
18
- exclusiveMinimum?: number;
19
- format?: string;
20
- items?: JsonSchema | JsonSchema[];
21
- maximum?: number;
22
- maxLength?: number;
23
- minimum?: number;
24
- minLength?: number;
25
- not?: JsonSchema | Record<string, never>;
26
- oneOf?: JsonSchema[];
27
- pattern?: string;
28
- properties?: Record<string, JsonSchema>;
29
- required?: string[];
30
- type?: string;
31
- }
32
- /**
33
- * Convert a Zod schema to JSON Schema format.
34
- *
35
- * This is a simplified converter that handles common Zod types.
36
- * For complex schemas, consider using a full zod-to-json-schema library.
37
- *
38
- * @param schema - Zod schema to convert
39
- * @returns JSON Schema representation
40
- *
41
- * @example
42
- * ```typescript
43
- * const zodSchema = z.object({
44
- * name: z.string(),
45
- * age: z.number().optional(),
46
- * });
47
- *
48
- * const jsonSchema = zodToJsonSchema(zodSchema);
49
- * // {
50
- * // type: "object",
51
- * // properties: {
52
- * // name: { type: "string" },
53
- * // age: { type: "number" },
54
- * // },
55
- * // required: ["name"],
56
- * // }
57
- * ```
58
- */
59
- declare function zodToJsonSchema(schema: z.ZodType<unknown>): JsonSchema;
60
- export { JsonSchema, zodToJsonSchema };