@outfitter/contracts 0.4.1 → 0.4.2

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/README.md CHANGED
@@ -34,7 +34,10 @@ import {
34
34
  } from "@outfitter/contracts";
35
35
 
36
36
  // Define a handler
37
- const getNote: Handler<{ id: string }, Note, NotFoundError> = async (input, ctx) => {
37
+ const getNote: Handler<{ id: string }, Note, NotFoundError> = async (
38
+ input,
39
+ ctx
40
+ ) => {
38
41
  const note = await db.notes.find(input.id);
39
42
  if (!note) return Result.err(NotFoundError.create("note", input.id));
40
43
  return Result.ok(note);
@@ -49,21 +52,21 @@ const result = await getNote({ id: "abc123" }, ctx);
49
52
 
50
53
  All error classes provide a static `create()` factory method that generates a consistent message from structured parameters. Use `create()` for structured errors and the constructor for custom messages.
51
54
 
52
- | Error Class | `create()` Signature | Generated Message |
53
- |---|---|---|
54
- | `ValidationError` | `create(field, reason, context?)` | `"email: format invalid"` |
55
- | `ValidationError` | `fromMessage(message, context?)` | *(your message as-is)* |
56
- | `AmbiguousError` | `create(what, candidates, context?)` | `"Ambiguous heading: 2 matches found"` |
57
- | `NotFoundError` | `create(resourceType, resourceId, context?)` | `"note not found: abc123"` |
55
+ | Error Class | `create()` Signature | Generated Message |
56
+ | -------------------- | -------------------------------------------- | ----------------------------------------- |
57
+ | `ValidationError` | `create(field, reason, context?)` | `"email: format invalid"` |
58
+ | `ValidationError` | `fromMessage(message, context?)` | _(your message as-is)_ |
59
+ | `AmbiguousError` | `create(what, candidates, context?)` | `"Ambiguous heading: 2 matches found"` |
60
+ | `NotFoundError` | `create(resourceType, resourceId, context?)` | `"note not found: abc123"` |
58
61
  | `AlreadyExistsError` | `create(resourceType, resourceId, context?)` | `"file already exists: notes/meeting.md"` |
59
- | `ConflictError` | `create(message, context?)` | *(your message as-is)* |
60
- | `PermissionError` | `create(message, context?)` | *(your message as-is)* |
61
- | `TimeoutError` | `create(operation, timeoutMs)` | `"database query timed out after 5000ms"` |
62
- | `RateLimitError` | `create(message, retryAfterSeconds?)` | *(your message as-is)* |
63
- | `NetworkError` | `create(message, context?)` | *(your message as-is)* |
64
- | `InternalError` | `create(message, context?)` | *(your message as-is)* |
65
- | `AuthError` | `create(message, reason?)` | *(your message as-is)* |
66
- | `CancelledError` | `create(message)` | *(your message as-is)* |
62
+ | `ConflictError` | `create(message, context?)` | _(your message as-is)_ |
63
+ | `PermissionError` | `create(message, context?)` | _(your message as-is)_ |
64
+ | `TimeoutError` | `create(operation, timeoutMs)` | `"database query timed out after 5000ms"` |
65
+ | `RateLimitError` | `create(message, retryAfterSeconds?)` | _(your message as-is)_ |
66
+ | `NetworkError` | `create(message, context?)` | _(your message as-is)_ |
67
+ | `InternalError` | `create(message, context?)` | _(your message as-is)_ |
68
+ | `AuthError` | `create(message, reason?)` | _(your message as-is)_ |
69
+ | `CancelledError` | `create(message)` | _(your message as-is)_ |
67
70
 
68
71
  ### Message Casing
69
72
 
package/dist/actions.js CHANGED
@@ -1,10 +1,29 @@
1
1
  // @bun
2
- import {
3
- ACTION_SURFACES,
4
- DEFAULT_REGISTRY_SURFACES,
5
- createActionRegistry,
6
- defineAction
7
- } from "./shared/@outfitter/contracts-q0v44kef.js";
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
+ }
8
27
  export {
9
28
  defineAction,
10
29
  createActionRegistry,
@@ -1,11 +1,33 @@
1
1
  // @bun
2
2
  import {
3
- assertDefined,
4
- assertMatches,
5
- assertNonEmpty,
6
- isNonEmptyArray
7
- } from "../shared/@outfitter/contracts-cp5c6dws.js";
8
- import"../shared/@outfitter/contracts-phjhz5q3.js";
3
+ AssertionError
4
+ } from "../shared/@outfitter/contracts-phjhz5q3.js";
5
+
6
+ // packages/contracts/src/assert/index.ts
7
+ import { Result } from "better-result";
8
+ var isNonEmptyArray = (arr) => {
9
+ return arr.length > 0;
10
+ };
11
+ var assertDefined = (value, message) => {
12
+ if (value === null || value === undefined) {
13
+ return Result.err(new AssertionError({ message: message ?? "Value is null or undefined" }));
14
+ }
15
+ return Result.ok(value);
16
+ };
17
+ var assertNonEmpty = (arr, message) => {
18
+ if (arr.length === 0) {
19
+ return Result.err(new AssertionError({ message: message ?? "Array is empty" }));
20
+ }
21
+ return Result.ok(arr);
22
+ };
23
+ function assertMatches(value, predicate, message) {
24
+ if (!predicate(value)) {
25
+ return Result.err(new AssertionError({
26
+ message: message ?? "Value does not match predicate"
27
+ }));
28
+ }
29
+ return Result.ok(value);
30
+ }
9
31
  export {
10
32
  isNonEmptyArray,
11
33
  assertNonEmpty,
@@ -1,12 +1,61 @@
1
1
  // @bun
2
- import {
3
- ACTION_CAPABILITIES,
4
- CAPABILITY_SURFACES,
5
- DEFAULT_ACTION_SURFACES,
6
- capability,
7
- capabilityAll,
8
- getActionsForSurface
9
- } from "./shared/@outfitter/contracts-d0tq2adf.js";
2
+ // packages/contracts/src/capabilities.ts
3
+ var CAPABILITY_SURFACES = ["cli", "mcp", "api", "server"];
4
+ var DEFAULT_ACTION_SURFACES = ["cli", "mcp"];
5
+ function capability(surfaces = DEFAULT_ACTION_SURFACES, notes) {
6
+ return notes ? { surfaces, notes } : { surfaces };
7
+ }
8
+ function capabilityAll(notes) {
9
+ return capability(CAPABILITY_SURFACES, notes);
10
+ }
11
+ var ACTION_CAPABILITIES = {
12
+ navigate: capability(),
13
+ back: capability(),
14
+ forward: capability(),
15
+ reload: capability(),
16
+ tab: capability(),
17
+ tabs: capability(),
18
+ newTab: capability(),
19
+ closeTab: capability(),
20
+ click: capability(),
21
+ type: capability(),
22
+ select: capability(),
23
+ hover: capability(),
24
+ focus: capability(["mcp"]),
25
+ scroll: capability(),
26
+ press: capability(),
27
+ fill: capability(),
28
+ find: capability(),
29
+ check: capability(),
30
+ uncheck: capability(),
31
+ upload: capability(),
32
+ download: capability(["server"], "Server-only for now"),
33
+ dialog: capability(),
34
+ waitFor: capability(["mcp"]),
35
+ waitForNavigation: capability(["mcp"]),
36
+ wait: capability(["mcp"]),
37
+ snap: capability(),
38
+ screenshot: capability(),
39
+ html: capability(["mcp"]),
40
+ text: capability(["mcp"]),
41
+ marker: capability(),
42
+ markers: capability(),
43
+ markerGet: capability(),
44
+ markerRead: capability(["mcp"]),
45
+ markerCompare: capability(),
46
+ markerDelete: capability(),
47
+ markerResolve: capability(["cli"], "CLI-only for now"),
48
+ viewport: capability(),
49
+ colorScheme: capability(),
50
+ mode: capability(["mcp"]),
51
+ evaluate: capability(["mcp"]),
52
+ session: capability(),
53
+ sessions: capability(["mcp"]),
54
+ steps: capability()
55
+ };
56
+ function getActionsForSurface(surface) {
57
+ return Object.entries(ACTION_CAPABILITIES).filter(([, capability2]) => capability2.surfaces.includes(surface)).map(([action]) => action);
58
+ }
10
59
  export {
11
60
  getActionsForSurface,
12
61
  capabilityAll,
package/dist/envelope.js CHANGED
@@ -1,12 +1,55 @@
1
1
  // @bun
2
2
  import {
3
- toEnvelope,
4
- toHttpResponse
5
- } from "./shared/@outfitter/contracts-85nd53s9.js";
6
- import"./shared/@outfitter/contracts-3wj7xghe.js";
3
+ serializeError
4
+ } from "./shared/@outfitter/contracts-5k6q4n48.js";
5
+ import {
6
+ generateRequestId
7
+ } from "./shared/@outfitter/contracts-agmt8915.js";
8
+ import {
9
+ statusCodeMap
10
+ } from "./shared/@outfitter/contracts-phjhz5q3.js";
7
11
  import"./shared/@outfitter/contracts-s15x2rs4.js";
8
- import"./shared/@outfitter/contracts-phjhz5q3.js";
9
- import"./shared/@outfitter/contracts-agmt8915.js";
12
+
13
+ // packages/contracts/src/envelope.ts
14
+ function buildMeta(overrides) {
15
+ const meta = {
16
+ requestId: overrides?.requestId ?? generateRequestId(),
17
+ timestamp: new Date().toISOString()
18
+ };
19
+ if (overrides?.durationMs !== undefined) {
20
+ meta.durationMs = overrides.durationMs;
21
+ }
22
+ return meta;
23
+ }
24
+ function toEnvelope(result, meta) {
25
+ const envelopeMeta = buildMeta(meta);
26
+ if (result.isOk()) {
27
+ return {
28
+ ok: true,
29
+ data: result.value,
30
+ meta: envelopeMeta
31
+ };
32
+ }
33
+ return {
34
+ ok: false,
35
+ error: serializeError(result.error),
36
+ meta: envelopeMeta
37
+ };
38
+ }
39
+ function toHttpResponse(result) {
40
+ const envelope = toEnvelope(result);
41
+ if (envelope.ok) {
42
+ return {
43
+ status: 200,
44
+ body: envelope
45
+ };
46
+ }
47
+ const status = statusCodeMap[envelope.error.category];
48
+ return {
49
+ status,
50
+ body: envelope
51
+ };
52
+ }
10
53
  export {
11
54
  toHttpResponse,
12
55
  toEnvelope
package/dist/index.d.ts CHANGED
@@ -1,20 +1,20 @@
1
1
  import "./shared/@outfitter/contracts-qaccq0gf.js";
2
- import { NonEmptyArray, assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "./shared/@outfitter/contracts-mmg0npfk.js";
3
- import { createValidator, validateInput } from "./shared/@outfitter/contracts-9wtm5nsw.js";
4
- import { ACTION_CAPABILITIES, ActionCapability, CAPABILITY_SURFACES, CapabilitySurface, DEFAULT_ACTION_SURFACES, capability, capabilityAll, getActionsForSurface } from "./shared/@outfitter/contracts-y8f0m1ze.js";
5
- import { DEFAULT_PATTERNS, DEFAULT_SENSITIVE_KEYS, RedactionCallback, RedactionEvent, Redactor, RedactorConfig, createRedactor } from "./shared/@outfitter/contracts-9yd4vrjg.js";
6
- import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-k71jqd1m.js";
7
- import { JsonSchema, zodToJsonSchema } from "./shared/@outfitter/contracts-t79engf9.js";
8
- import { ACTION_SURFACES, ActionApiSpec, ActionCliInputContext, ActionCliOption, ActionCliSpec, ActionMcpSpec, ActionRegistry, ActionSpec, ActionSurface, ActionTrpcSpec, AnyActionSpec, DEFAULT_REGISTRY_SURFACES, HttpMethod, createActionRegistry, defineAction } from "./shared/@outfitter/contracts-56pcsavx.js";
9
- import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-95cc3y06.js";
10
2
  import { combine2, combine3, expect, orElse, unwrapOrElse } from "./shared/@outfitter/contracts-ar0etwtx.js";
11
- import { AdapterAuthError, AuthAdapter, CacheAdapter, CacheError, IndexAdapter, IndexError, IndexStats, SearchOptions, SearchResult, StorageAdapter, StorageError } from "./shared/@outfitter/contracts-c2cfj172.js";
12
- import { Envelope, EnvelopeMeta, ErrorEnvelope, HttpResponse, PaginationMeta, SuccessEnvelope, toEnvelope, toHttpResponse } from "./shared/@outfitter/contracts-e4m948m7.js";
3
+ import { ACTION_SURFACES, ActionApiSpec, ActionCliInputContext, ActionCliOption, ActionCliSpec, ActionMcpSpec, ActionRegistry, ActionSpec, ActionSurface, ActionTrpcSpec, AnyActionSpec, DEFAULT_REGISTRY_SURFACES, HttpMethod, createActionRegistry, defineAction } from "./shared/@outfitter/contracts-56pcsavx.js";
4
+ import { ACTION_CAPABILITIES, ActionCapability, CAPABILITY_SURFACES, CapabilitySurface, DEFAULT_ACTION_SURFACES, capability, capabilityAll, getActionsForSurface } from "./shared/@outfitter/contracts-y8f0m1ze.js";
13
5
  import { SerializeErrorOptions, deserializeError, safeParse, safeStringify, serializeError } from "./shared/@outfitter/contracts-31penhwa.js";
6
+ import { JsonSchema, zodToJsonSchema } from "./shared/@outfitter/contracts-t79engf9.js";
14
7
  import { CreateContextOptions, createContext, generateRequestId } from "./shared/@outfitter/contracts-1waabxbk.js";
8
+ import { NonEmptyArray, assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "./shared/@outfitter/contracts-mmg0npfk.js";
9
+ import { Envelope, EnvelopeMeta, ErrorEnvelope, HttpResponse, PaginationMeta, SuccessEnvelope, toEnvelope, toHttpResponse } from "./shared/@outfitter/contracts-e4m948m7.js";
10
+ import { AdapterAuthError, AuthAdapter, CacheAdapter, CacheError, IndexAdapter, IndexError, IndexStats, SearchOptions, SearchResult, StorageAdapter, StorageError } from "./shared/@outfitter/contracts-c2cfj172.js";
11
+ import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-k71jqd1m.js";
12
+ import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-95cc3y06.js";
13
+ import { createValidator, validateInput } from "./shared/@outfitter/contracts-9wtm5nsw.js";
15
14
  import { Handler, HandlerContext, ResolvedConfig, SyncHandler } from "./shared/@outfitter/contracts-0akf2sm6.js";
16
15
  import { AlreadyExistsError, AmbiguousError, AnyKitError, AssertionError, AuthError, CancelledError, ConflictError, ERROR_CODES, ErrorCategory, ErrorCode, InternalError, KitErrorProps, NetworkError, NotFoundError, OutfitterError, PermissionError, RateLimitError, SerializedError, TimeoutError, ValidationError, exitCodeMap, getExitCode, getStatusCode, statusCodeMap } from "./shared/@outfitter/contracts-3gswmhb1.js";
17
16
  import { LogLevel, LogMetadata, LogMethod, Logger, LoggerAdapter, LoggerFactory, LoggerFactoryConfig, createLoggerFactory } from "./shared/@outfitter/contracts-rwzqy9rn.js";
17
+ import { DEFAULT_PATTERNS, DEFAULT_SENSITIVE_KEYS, RedactionCallback, RedactionEvent, Redactor, RedactorConfig, createRedactor } from "./shared/@outfitter/contracts-9yd4vrjg.js";
18
18
  import { TaggedErrorClass } from "better-result";
19
19
  import { Result, TaggedError } from "better-result";
20
20
  export { zodToJsonSchema, withTimeout, validateInput, unwrapOrElse, toHttpResponse, toEnvelope, statusCodeMap, shouldRetry, serializeError, safeStringify, safeParse, retry, orElse, isRetryable, isRecoverable, isNonEmptyArray, getStatusCode, getExitCode, getBackoffDelay, getActionsForSurface, generateRequestId, expect, exitCodeMap, deserializeError, defineAction, createValidator, createRedactor, createLoggerFactory, createContext, createActionRegistry, combine3, combine2, capabilityAll, capability, assertNonEmpty, assertMatches, assertDefined, ValidationError, TimeoutOptions, TimeoutError, TaggedErrorClass, TaggedError, SyncHandler, SuccessEnvelope, StorageError, StorageAdapter, SerializedError, SerializeErrorOptions, SearchResult, SearchOptions, RetryOptions, Result, ResolvedConfig, RedactorConfig, Redactor, RedactionEvent, RedactionCallback, RateLimitError, PermissionError, PaginationMeta, OutfitterError, NotFoundError, NonEmptyArray, NetworkError, LoggerFactoryConfig, LoggerFactory, LoggerAdapter, Logger, LogMethod, LogMetadata, LogLevel, KitErrorProps, JsonSchema, InternalError, IndexStats, IndexError, IndexAdapter, HttpResponse, HttpMethod, HandlerContext, Handler, ErrorEnvelope, ErrorCode, ErrorCategory, EnvelopeMeta, Envelope, ERROR_CODES, DEFAULT_SENSITIVE_KEYS, DEFAULT_REGISTRY_SURFACES, DEFAULT_PATTERNS, DEFAULT_ACTION_SURFACES, CreateContextOptions, ConflictError, CapabilitySurface, CancelledError, CacheError, CacheAdapter, CAPABILITY_SURFACES, BackoffOptions, AuthError, AuthAdapter, AssertionError, AnyKitError, AnyActionSpec, AmbiguousError, AlreadyExistsError, AdapterAuthError, ActionTrpcSpec, ActionSurface, ActionSpec, ActionRegistry, ActionMcpSpec, ActionCliSpec, ActionCliOption, ActionCliInputContext, ActionCapability, ActionApiSpec, ACTION_SURFACES, ACTION_CAPABILITIES };
package/dist/index.js CHANGED
@@ -1,153 +1,15 @@
1
- // @bun
2
- import"./shared/@outfitter/contracts-37gpc56f.js";
3
- import {
4
- assertDefined,
5
- assertMatches,
6
- assertNonEmpty,
7
- isNonEmptyArray
8
- } from "./shared/@outfitter/contracts-cp5c6dws.js";
9
- import {
10
- createValidator,
11
- validateInput
12
- } from "./shared/@outfitter/contracts-0snpmkdt.js";
13
- import {
14
- ACTION_CAPABILITIES,
15
- CAPABILITY_SURFACES,
16
- DEFAULT_ACTION_SURFACES,
17
- capability,
18
- capabilityAll,
19
- getActionsForSurface
20
- } from "./shared/@outfitter/contracts-d0tq2adf.js";
21
- import {
22
- getBackoffDelay,
23
- isRecoverable,
24
- isRetryable,
25
- shouldRetry
26
- } from "./shared/@outfitter/contracts-4zaj7ejb.js";
27
- import {
28
- zodToJsonSchema
29
- } from "./shared/@outfitter/contracts-wfht4q2b.js";
30
- import {
31
- ACTION_SURFACES,
32
- DEFAULT_REGISTRY_SURFACES,
33
- createActionRegistry,
34
- defineAction
35
- } from "./shared/@outfitter/contracts-q0v44kef.js";
36
- import {
37
- retry,
38
- withTimeout
39
- } from "./shared/@outfitter/contracts-r21yet6j.js";
40
- import {
41
- combine2,
42
- combine3,
43
- expect,
44
- orElse,
45
- unwrapOrElse
46
- } from "./shared/@outfitter/contracts-zx72gyh1.js";
47
- import {
48
- toEnvelope,
49
- toHttpResponse
50
- } from "./shared/@outfitter/contracts-85nd53s9.js";
51
- import {
52
- deserializeError,
53
- safeParse,
54
- safeStringify,
55
- serializeError
56
- } from "./shared/@outfitter/contracts-3wj7xghe.js";
57
- import {
58
- DEFAULT_PATTERNS,
59
- DEFAULT_SENSITIVE_KEYS,
60
- createRedactor
61
- } from "./shared/@outfitter/contracts-s15x2rs4.js";
62
- import {
63
- AlreadyExistsError,
64
- AmbiguousError,
65
- AssertionError,
66
- AuthError,
67
- CancelledError,
68
- ConflictError,
69
- ERROR_CODES,
70
- InternalError,
71
- NetworkError,
72
- NotFoundError,
73
- PermissionError,
74
- RateLimitError,
75
- TimeoutError,
76
- ValidationError,
77
- exitCodeMap,
78
- getExitCode,
79
- getStatusCode,
80
- statusCodeMap
81
- } from "./shared/@outfitter/contracts-phjhz5q3.js";
82
- import {
83
- createContext,
84
- generateRequestId
85
- } from "./shared/@outfitter/contracts-agmt8915.js";
86
- import {
87
- createLoggerFactory
88
- } from "./shared/@outfitter/contracts-sm6vak1a.js";
89
-
90
- // packages/contracts/src/index.ts
91
- import { Result, TaggedError } from "better-result";
92
- export {
93
- zodToJsonSchema,
94
- withTimeout,
95
- validateInput,
96
- unwrapOrElse,
97
- toHttpResponse,
98
- toEnvelope,
99
- statusCodeMap,
100
- shouldRetry,
101
- serializeError,
102
- safeStringify,
103
- safeParse,
104
- retry,
105
- orElse,
106
- isRetryable,
107
- isRecoverable,
108
- isNonEmptyArray,
109
- getStatusCode,
110
- getExitCode,
111
- getBackoffDelay,
112
- getActionsForSurface,
113
- generateRequestId,
114
- expect,
115
- exitCodeMap,
116
- deserializeError,
117
- defineAction,
118
- createValidator,
119
- createRedactor,
120
- createLoggerFactory,
121
- createContext,
122
- createActionRegistry,
123
- combine3,
124
- combine2,
125
- capabilityAll,
126
- capability,
127
- assertNonEmpty,
128
- assertMatches,
129
- assertDefined,
130
- ValidationError,
131
- TimeoutError,
132
- TaggedError,
133
- Result,
134
- RateLimitError,
135
- PermissionError,
136
- NotFoundError,
137
- NetworkError,
138
- InternalError,
139
- ERROR_CODES,
140
- DEFAULT_SENSITIVE_KEYS,
141
- DEFAULT_REGISTRY_SURFACES,
142
- DEFAULT_PATTERNS,
143
- DEFAULT_ACTION_SURFACES,
144
- ConflictError,
145
- CancelledError,
146
- CAPABILITY_SURFACES,
147
- AuthError,
148
- AssertionError,
149
- AmbiguousError,
150
- AlreadyExistsError,
151
- ACTION_SURFACES,
152
- ACTION_CAPABILITIES
153
- };
1
+ export { Result, TaggedError } from "better-result";
2
+ export { ACTION_SURFACES, createActionRegistry, DEFAULT_REGISTRY_SURFACES, defineAction } from "./actions.js";
3
+ export { assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "./assert/index.js";
4
+ export { ACTION_CAPABILITIES, CAPABILITY_SURFACES, capability, capabilityAll, DEFAULT_ACTION_SURFACES, getActionsForSurface } from "./capabilities.js";
5
+ export { createContext, generateRequestId } from "./context.js";
6
+ export { toEnvelope, toHttpResponse } from "./envelope.js";
7
+ export { AlreadyExistsError, AmbiguousError, AssertionError, AuthError, CancelledError, ConflictError, ERROR_CODES, exitCodeMap, getExitCode, getStatusCode, InternalError, NetworkError, NotFoundError, PermissionError, RateLimitError, statusCodeMap, TimeoutError, ValidationError } from "./errors.js";
8
+ export { createLoggerFactory } from "./logging.js";
9
+ export { getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./recovery.js";
10
+ export { createRedactor, DEFAULT_PATTERNS, DEFAULT_SENSITIVE_KEYS } from "./redactor.js";
11
+ export { retry, withTimeout } from "./resilience.js";
12
+ export { combine2, combine3, expect, orElse, unwrapOrElse } from "./result/index.js";
13
+ export { zodToJsonSchema } from "./schema.js";
14
+ export { deserializeError, safeParse, safeStringify, serializeError } from "./serialization.js";
15
+ export { createValidator, validateInput } from "./validation.js";
package/dist/logging.js CHANGED
@@ -1,7 +1,15 @@
1
1
  // @bun
2
- import {
3
- createLoggerFactory
4
- } from "./shared/@outfitter/contracts-sm6vak1a.js";
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
+ }
5
13
  export {
6
14
  createLoggerFactory
7
15
  };
package/dist/recovery.js CHANGED
@@ -1,10 +1,53 @@
1
1
  // @bun
2
- import {
3
- getBackoffDelay,
4
- isRecoverable,
5
- isRetryable,
6
- shouldRetry
7
- } from "./shared/@outfitter/contracts-4zaj7ejb.js";
2
+ // packages/contracts/src/recovery.ts
3
+ var RECOVERABLE_CATEGORIES = [
4
+ "network",
5
+ "timeout",
6
+ "rate_limit",
7
+ "conflict"
8
+ ];
9
+ var RETRYABLE_CATEGORIES = ["network", "timeout"];
10
+ var isRecoverable = (error) => {
11
+ return RECOVERABLE_CATEGORIES.includes(error.category);
12
+ };
13
+ var isRetryable = (error) => {
14
+ return RETRYABLE_CATEGORIES.includes(error.category);
15
+ };
16
+ var getBackoffDelay = (attempt, options = {}) => {
17
+ const {
18
+ baseDelayMs = 100,
19
+ maxDelayMs = 30000,
20
+ strategy = "exponential",
21
+ useJitter = true
22
+ } = options;
23
+ let delay;
24
+ switch (strategy) {
25
+ case "constant": {
26
+ delay = baseDelayMs;
27
+ break;
28
+ }
29
+ case "linear": {
30
+ delay = baseDelayMs * (attempt + 1);
31
+ break;
32
+ }
33
+ default: {
34
+ delay = baseDelayMs * 2 ** attempt;
35
+ }
36
+ }
37
+ delay = Math.min(delay, maxDelayMs);
38
+ if (useJitter) {
39
+ const jitterFactor = 0.1;
40
+ const jitter = delay * jitterFactor * (Math.random() * 2 - 1);
41
+ delay = Math.round(delay + jitter);
42
+ }
43
+ return Math.min(delay, maxDelayMs);
44
+ };
45
+ var shouldRetry = (error, attempt, maxAttempts = 3) => {
46
+ if (attempt >= maxAttempts) {
47
+ return false;
48
+ }
49
+ return isRetryable(error);
50
+ };
8
51
  export {
9
52
  shouldRetry,
10
53
  isRetryable,
@@ -1,9 +1,81 @@
1
1
  // @bun
2
2
  import {
3
- retry,
4
- withTimeout
5
- } from "./shared/@outfitter/contracts-r21yet6j.js";
6
- import"./shared/@outfitter/contracts-phjhz5q3.js";
3
+ TimeoutError
4
+ } from "./shared/@outfitter/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
+ }
7
79
  export {
8
80
  withTimeout,
9
81
  retry
@@ -1,16 +1 @@
1
- // @bun
2
- import"../shared/@outfitter/contracts-37gpc56f.js";
3
- import {
4
- combine2,
5
- combine3,
6
- expect,
7
- orElse,
8
- unwrapOrElse
9
- } from "../shared/@outfitter/contracts-zx72gyh1.js";
10
- export {
11
- unwrapOrElse,
12
- orElse,
13
- expect,
14
- combine3,
15
- combine2
16
- };
1
+ export { combine2, combine3, expect, orElse, unwrapOrElse } from "./utilities.js";