@ontrails/core 1.0.0-beta.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 (216) hide show
  1. package/.turbo/turbo-build.log +1 -0
  2. package/.turbo/turbo-lint.log +3 -0
  3. package/.turbo/turbo-typecheck.log +1 -0
  4. package/CHANGELOG.md +15 -0
  5. package/README.md +179 -0
  6. package/dist/adapters.d.ts +39 -0
  7. package/dist/adapters.d.ts.map +1 -0
  8. package/dist/adapters.js +2 -0
  9. package/dist/adapters.js.map +1 -0
  10. package/dist/blob-ref.d.ts +20 -0
  11. package/dist/blob-ref.d.ts.map +1 -0
  12. package/dist/blob-ref.js +22 -0
  13. package/dist/blob-ref.js.map +1 -0
  14. package/dist/branded.d.ts +36 -0
  15. package/dist/branded.d.ts.map +1 -0
  16. package/dist/branded.js +89 -0
  17. package/dist/branded.js.map +1 -0
  18. package/dist/collections.d.ts +31 -0
  19. package/dist/collections.d.ts.map +1 -0
  20. package/dist/collections.js +60 -0
  21. package/dist/collections.js.map +1 -0
  22. package/dist/context.d.ts +10 -0
  23. package/dist/context.d.ts.map +1 -0
  24. package/dist/context.js +15 -0
  25. package/dist/context.js.map +1 -0
  26. package/dist/derive.d.ts +33 -0
  27. package/dist/derive.d.ts.map +1 -0
  28. package/dist/derive.js +122 -0
  29. package/dist/derive.js.map +1 -0
  30. package/dist/errors.d.ts +83 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +142 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/event.d.ts +45 -0
  35. package/dist/event.d.ts.map +1 -0
  36. package/dist/event.js +17 -0
  37. package/dist/event.js.map +1 -0
  38. package/dist/fetch.d.ts +15 -0
  39. package/dist/fetch.d.ts.map +1 -0
  40. package/dist/fetch.js +102 -0
  41. package/dist/fetch.js.map +1 -0
  42. package/dist/guards.d.ts +17 -0
  43. package/dist/guards.d.ts.map +1 -0
  44. package/dist/guards.js +25 -0
  45. package/dist/guards.js.map +1 -0
  46. package/dist/health.d.ts +18 -0
  47. package/dist/health.d.ts.map +1 -0
  48. package/dist/health.js +5 -0
  49. package/dist/health.js.map +1 -0
  50. package/dist/hike.d.ts +36 -0
  51. package/dist/hike.d.ts.map +1 -0
  52. package/dist/hike.js +20 -0
  53. package/dist/hike.js.map +1 -0
  54. package/dist/index.d.ts +34 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +38 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/job.d.ts +24 -0
  59. package/dist/job.d.ts.map +1 -0
  60. package/dist/job.js +17 -0
  61. package/dist/job.js.map +1 -0
  62. package/dist/layer.d.ts +17 -0
  63. package/dist/layer.d.ts.map +1 -0
  64. package/dist/layer.js +21 -0
  65. package/dist/layer.js.map +1 -0
  66. package/dist/path-security.d.ts +28 -0
  67. package/dist/path-security.d.ts.map +1 -0
  68. package/dist/path-security.js +63 -0
  69. package/dist/path-security.js.map +1 -0
  70. package/dist/patterns/bulk.d.ts +15 -0
  71. package/dist/patterns/bulk.d.ts.map +1 -0
  72. package/dist/patterns/bulk.js +14 -0
  73. package/dist/patterns/bulk.js.map +1 -0
  74. package/dist/patterns/change.d.ts +10 -0
  75. package/dist/patterns/change.d.ts.map +1 -0
  76. package/dist/patterns/change.js +10 -0
  77. package/dist/patterns/change.js.map +1 -0
  78. package/dist/patterns/date-range.d.ts +10 -0
  79. package/dist/patterns/date-range.d.ts.map +1 -0
  80. package/dist/patterns/date-range.js +10 -0
  81. package/dist/patterns/date-range.js.map +1 -0
  82. package/dist/patterns/index.d.ts +9 -0
  83. package/dist/patterns/index.d.ts.map +1 -0
  84. package/dist/patterns/index.js +9 -0
  85. package/dist/patterns/index.js.map +1 -0
  86. package/dist/patterns/pagination.d.ts +18 -0
  87. package/dist/patterns/pagination.d.ts.map +1 -0
  88. package/dist/patterns/pagination.js +18 -0
  89. package/dist/patterns/pagination.js.map +1 -0
  90. package/dist/patterns/progress.d.ts +11 -0
  91. package/dist/patterns/progress.d.ts.map +1 -0
  92. package/dist/patterns/progress.js +11 -0
  93. package/dist/patterns/progress.js.map +1 -0
  94. package/dist/patterns/sorting.d.ts +13 -0
  95. package/dist/patterns/sorting.d.ts.map +1 -0
  96. package/dist/patterns/sorting.js +10 -0
  97. package/dist/patterns/sorting.js.map +1 -0
  98. package/dist/patterns/status.d.ts +15 -0
  99. package/dist/patterns/status.d.ts.map +1 -0
  100. package/dist/patterns/status.js +9 -0
  101. package/dist/patterns/status.js.map +1 -0
  102. package/dist/patterns/timestamps.d.ts +10 -0
  103. package/dist/patterns/timestamps.d.ts.map +1 -0
  104. package/dist/patterns/timestamps.js +10 -0
  105. package/dist/patterns/timestamps.js.map +1 -0
  106. package/dist/redaction/index.d.ts +4 -0
  107. package/dist/redaction/index.d.ts.map +1 -0
  108. package/dist/redaction/index.js +3 -0
  109. package/dist/redaction/index.js.map +1 -0
  110. package/dist/redaction/patterns.d.ts +9 -0
  111. package/dist/redaction/patterns.d.ts.map +1 -0
  112. package/dist/redaction/patterns.js +39 -0
  113. package/dist/redaction/patterns.js.map +1 -0
  114. package/dist/redaction/redactor.d.ts +27 -0
  115. package/dist/redaction/redactor.d.ts.map +1 -0
  116. package/dist/redaction/redactor.js +89 -0
  117. package/dist/redaction/redactor.js.map +1 -0
  118. package/dist/resilience.d.ts +34 -0
  119. package/dist/resilience.d.ts.map +1 -0
  120. package/dist/resilience.js +164 -0
  121. package/dist/resilience.js.map +1 -0
  122. package/dist/result.d.ts +57 -0
  123. package/dist/result.d.ts.map +1 -0
  124. package/dist/result.js +145 -0
  125. package/dist/result.js.map +1 -0
  126. package/dist/serialization.d.ts +27 -0
  127. package/dist/serialization.d.ts.map +1 -0
  128. package/dist/serialization.js +115 -0
  129. package/dist/serialization.js.map +1 -0
  130. package/dist/topo.d.ts +18 -0
  131. package/dist/topo.d.ts.map +1 -0
  132. package/dist/topo.js +74 -0
  133. package/dist/topo.js.map +1 -0
  134. package/dist/trail.d.ts +83 -0
  135. package/dist/trail.d.ts.map +1 -0
  136. package/dist/trail.js +16 -0
  137. package/dist/trail.js.map +1 -0
  138. package/dist/types.d.ts +46 -0
  139. package/dist/types.d.ts.map +1 -0
  140. package/dist/types.js +2 -0
  141. package/dist/types.js.map +1 -0
  142. package/dist/validate-topo.d.ts +24 -0
  143. package/dist/validate-topo.d.ts.map +1 -0
  144. package/dist/validate-topo.js +108 -0
  145. package/dist/validate-topo.js.map +1 -0
  146. package/dist/validation.d.ts +27 -0
  147. package/dist/validation.d.ts.map +1 -0
  148. package/dist/validation.js +134 -0
  149. package/dist/validation.js.map +1 -0
  150. package/dist/workspace.d.ts +25 -0
  151. package/dist/workspace.d.ts.map +1 -0
  152. package/dist/workspace.js +57 -0
  153. package/dist/workspace.js.map +1 -0
  154. package/package.json +21 -0
  155. package/src/__tests__/blob-ref.test.ts +103 -0
  156. package/src/__tests__/branded.test.ts +148 -0
  157. package/src/__tests__/collections.test.ts +126 -0
  158. package/src/__tests__/context.test.ts +66 -0
  159. package/src/__tests__/derive.test.ts +159 -0
  160. package/src/__tests__/errors.test.ts +309 -0
  161. package/src/__tests__/event.test.ts +82 -0
  162. package/src/__tests__/fetch.test.ts +217 -0
  163. package/src/__tests__/guards.test.ts +102 -0
  164. package/src/__tests__/hike.test.ts +117 -0
  165. package/src/__tests__/job.test.ts +98 -0
  166. package/src/__tests__/layer.test.ts +224 -0
  167. package/src/__tests__/path-security.test.ts +114 -0
  168. package/src/__tests__/patterns.test.ts +273 -0
  169. package/src/__tests__/redaction.test.ts +244 -0
  170. package/src/__tests__/resilience.test.ts +246 -0
  171. package/src/__tests__/result.test.ts +155 -0
  172. package/src/__tests__/serialization.test.ts +236 -0
  173. package/src/__tests__/topo.test.ts +184 -0
  174. package/src/__tests__/trail.test.ts +179 -0
  175. package/src/__tests__/validate-topo.test.ts +201 -0
  176. package/src/__tests__/validation.test.ts +283 -0
  177. package/src/__tests__/workspace.test.ts +183 -0
  178. package/src/adapters.ts +68 -0
  179. package/src/blob-ref.ts +39 -0
  180. package/src/branded.ts +135 -0
  181. package/src/collections.ts +99 -0
  182. package/src/context.ts +18 -0
  183. package/src/derive.ts +223 -0
  184. package/src/errors.ts +196 -0
  185. package/src/event.ts +77 -0
  186. package/src/fetch.ts +138 -0
  187. package/src/guards.ts +37 -0
  188. package/src/health.ts +23 -0
  189. package/src/hike.ts +77 -0
  190. package/src/index.ts +158 -0
  191. package/src/job.ts +20 -0
  192. package/src/layer.ts +44 -0
  193. package/src/path-security.ts +90 -0
  194. package/src/patterns/bulk.ts +16 -0
  195. package/src/patterns/change.ts +12 -0
  196. package/src/patterns/date-range.ts +12 -0
  197. package/src/patterns/index.ts +8 -0
  198. package/src/patterns/pagination.ts +22 -0
  199. package/src/patterns/progress.ts +13 -0
  200. package/src/patterns/sorting.ts +14 -0
  201. package/src/patterns/status.ts +11 -0
  202. package/src/patterns/timestamps.ts +12 -0
  203. package/src/redaction/index.ts +3 -0
  204. package/src/redaction/patterns.ts +47 -0
  205. package/src/redaction/redactor.ts +178 -0
  206. package/src/resilience.ts +234 -0
  207. package/src/result.ts +180 -0
  208. package/src/serialization.ts +183 -0
  209. package/src/topo.ts +123 -0
  210. package/src/trail.ts +130 -0
  211. package/src/types.ts +58 -0
  212. package/src/validate-topo.ts +151 -0
  213. package/src/validation.ts +182 -0
  214. package/src/workspace.ts +77 -0
  215. package/tsconfig.json +9 -0
  216. package/tsconfig.tsbuildinfo +1 -0
package/dist/derive.js ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Schema-driven field derivation for @ontrails/core
3
+ *
4
+ * Introspects Zod v4 schemas to produce a surface-agnostic Field[] descriptor
5
+ * that UI layers (CLI prompts, web forms, etc.) can consume.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Helpers
9
+ // ---------------------------------------------------------------------------
10
+ /** Convert camelCase / PascalCase to "Title Case" label. */
11
+ const humanize = (str) => str
12
+ .replaceAll(/([a-z])([A-Z])/g, '$1 $2')
13
+ .replaceAll(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
14
+ .replace(/^./, (ch) => ch.toUpperCase());
15
+ /** Get the inner type from an optional or default wrapper. */
16
+ const getInnerType = (current) => current._zod.def['innerType'];
17
+ /** Propagate description from inner to state if present. */
18
+ const propagateDescription = (inner, state) => {
19
+ if (inner.description) {
20
+ state.description = inner.description;
21
+ }
22
+ };
23
+ /** Step one level of optional/default unwrapping. Returns null if not a wrapper type. */
24
+ const unwrapStep = (current, state) => {
25
+ const defType = current._zod.def['type'];
26
+ if (defType !== 'optional' && defType !== 'default') {
27
+ return null;
28
+ }
29
+ state.required = false;
30
+ if (defType === 'default') {
31
+ state.defaultValue = current._zod.def['defaultValue'];
32
+ }
33
+ const inner = getInnerType(current);
34
+ propagateDescription(inner, state);
35
+ return inner;
36
+ };
37
+ /** Unwrap optional / default wrappers, collecting metadata. */
38
+ const unwrap = (s) => {
39
+ const state = {
40
+ defaultValue: undefined,
41
+ description: s.description,
42
+ required: true,
43
+ };
44
+ let current = s;
45
+ // eslint-disable-next-line no-constant-condition
46
+ while (true) {
47
+ const next = unwrapStep(current, state);
48
+ if (next === null) {
49
+ break;
50
+ }
51
+ current = next;
52
+ }
53
+ return { ...state, inner: current };
54
+ };
55
+ const fieldTypeByDef = {
56
+ array: (s) => {
57
+ const element = s._zod.def['element'];
58
+ const elementType = element._zod.def['type'];
59
+ if (elementType === 'enum') {
60
+ const entries = element._zod.def['entries'];
61
+ return { options: Object.values(entries), type: 'multiselect' };
62
+ }
63
+ return { options: undefined, type: 'string' };
64
+ },
65
+ boolean: () => ({ options: undefined, type: 'boolean' }),
66
+ enum: (s) => {
67
+ const entries = s._zod.def['entries'];
68
+ return { options: Object.values(entries), type: 'enum' };
69
+ },
70
+ number: () => ({ options: undefined, type: 'number' }),
71
+ string: () => ({ options: undefined, type: 'string' }),
72
+ };
73
+ /** Derive field type and raw options from the unwrapped Zod def. */
74
+ const deriveFieldType = (s) => {
75
+ const defType = s._zod.def['type'];
76
+ const derive = fieldTypeByDef[defType];
77
+ return derive ? derive(s) : { options: undefined, type: 'string' };
78
+ };
79
+ /** Build options array, merging with overrides when present. */
80
+ const buildOptions = (rawOptions, overrideOptions) => {
81
+ if (!rawOptions) {
82
+ return undefined;
83
+ }
84
+ if (!overrideOptions) {
85
+ return rawOptions.map((v) => ({ value: v }));
86
+ }
87
+ const overrideMap = new Map(overrideOptions.map((o) => [o.value, o]));
88
+ return rawOptions.map((v) => {
89
+ const ov = overrideMap.get(v);
90
+ return ov ? { hint: ov.hint, label: ov.label, value: v } : { value: v };
91
+ });
92
+ };
93
+ // ---------------------------------------------------------------------------
94
+ // Public API
95
+ // ---------------------------------------------------------------------------
96
+ /**
97
+ * Derive a surface-agnostic Field[] from a Zod object schema.
98
+ *
99
+ * Uses Zod v4's `_zod.def` for introspection. Returns fields sorted by name.
100
+ */
101
+ /** Derive a single field from a shape entry. */
102
+ const deriveField = (key, value, overrides) => {
103
+ const { inner, required, defaultValue, description } = unwrap(value);
104
+ const { type, options: rawOptions } = deriveFieldType(inner);
105
+ const override = overrides?.[key];
106
+ const label = override?.label ?? description ?? humanize(key);
107
+ const options = buildOptions(rawOptions, override?.options);
108
+ return { default: defaultValue, label, name: key, options, required, type };
109
+ };
110
+ export const deriveFields = (schema, overrides) => {
111
+ const s = schema;
112
+ if (s._zod.def['type'] !== 'object') {
113
+ return [];
114
+ }
115
+ const shape = s._zod.def['shape'];
116
+ if (!shape) {
117
+ return [];
118
+ }
119
+ const fields = Object.entries(shape).map(([key, value]) => deriveField(key, value, overrides));
120
+ return fields.toSorted((a, b) => a.name.localeCompare(b.name));
121
+ };
122
+ //# sourceMappingURL=derive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive.js","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Error taxonomy for @ontrails/core
3
+ *
4
+ * Provides a structured error hierarchy with category-based mapping
5
+ * to exit codes, HTTP status codes, and JSON-RPC error codes.
6
+ */
7
+ export type ErrorCategory = 'validation' | 'not_found' | 'conflict' | 'permission' | 'timeout' | 'rate_limit' | 'network' | 'internal' | 'auth' | 'cancelled';
8
+ export declare abstract class TrailsError extends Error {
9
+ abstract readonly category: ErrorCategory;
10
+ abstract readonly retryable: boolean;
11
+ readonly context?: Record<string, unknown> | undefined;
12
+ constructor(message: string, options?: {
13
+ cause?: Error;
14
+ context?: Record<string, unknown>;
15
+ });
16
+ }
17
+ export declare class ValidationError extends TrailsError {
18
+ readonly category: "validation";
19
+ readonly retryable: false;
20
+ }
21
+ export declare class AmbiguousError extends TrailsError {
22
+ readonly category: "validation";
23
+ readonly retryable: false;
24
+ }
25
+ export declare class AssertionError extends TrailsError {
26
+ readonly category: "internal";
27
+ readonly retryable: false;
28
+ }
29
+ export declare class NotFoundError extends TrailsError {
30
+ readonly category: "not_found";
31
+ readonly retryable: false;
32
+ }
33
+ export declare class AlreadyExistsError extends TrailsError {
34
+ readonly category: "conflict";
35
+ readonly retryable: false;
36
+ }
37
+ export declare class ConflictError extends TrailsError {
38
+ readonly category: "conflict";
39
+ readonly retryable: false;
40
+ }
41
+ export declare class PermissionError extends TrailsError {
42
+ readonly category: "permission";
43
+ readonly retryable: false;
44
+ }
45
+ export declare class TimeoutError extends TrailsError {
46
+ readonly category: "timeout";
47
+ readonly retryable: true;
48
+ }
49
+ export declare class RateLimitError extends TrailsError {
50
+ readonly category: "rate_limit";
51
+ readonly retryable: true;
52
+ readonly retryAfter?: number | undefined;
53
+ constructor(message: string, options?: {
54
+ cause?: Error;
55
+ context?: Record<string, unknown>;
56
+ retryAfter?: number;
57
+ });
58
+ }
59
+ export declare class NetworkError extends TrailsError {
60
+ readonly category: "network";
61
+ readonly retryable: true;
62
+ }
63
+ export declare class InternalError extends TrailsError {
64
+ readonly category: "internal";
65
+ readonly retryable: false;
66
+ }
67
+ export declare class AuthError extends TrailsError {
68
+ readonly category: "auth";
69
+ readonly retryable: false;
70
+ }
71
+ export declare class CancelledError extends TrailsError {
72
+ readonly category: "cancelled";
73
+ readonly retryable: false;
74
+ }
75
+ export declare const exitCodeMap: Record<ErrorCategory, number>;
76
+ export declare const statusCodeMap: Record<ErrorCategory, number>;
77
+ export declare const jsonRpcCodeMap: Record<ErrorCategory, number>;
78
+ export declare const retryableMap: Record<ErrorCategory, boolean>;
79
+ /** Type guard: narrows unknown to TrailsError */
80
+ export declare const isTrailsError: (error?: unknown) => error is TrailsError;
81
+ /** Returns true if the error is retryable (TrailsError with retryable category). */
82
+ export declare const isRetryable: (error: Error) => boolean;
83
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/errors.js ADDED
@@ -0,0 +1,142 @@
1
+ /* oxlint-disable max-classes-per-file -- error taxonomy requires co-located class definitions */
2
+ /**
3
+ * Error taxonomy for @ontrails/core
4
+ *
5
+ * Provides a structured error hierarchy with category-based mapping
6
+ * to exit codes, HTTP status codes, and JSON-RPC error codes.
7
+ */
8
+ // ---------------------------------------------------------------------------
9
+ // Base class
10
+ // ---------------------------------------------------------------------------
11
+ export class TrailsError extends Error {
12
+ context;
13
+ constructor(message, options) {
14
+ super(message, { cause: options?.cause });
15
+ this.name = this.constructor.name;
16
+ this.context = options?.context;
17
+ }
18
+ }
19
+ // ---------------------------------------------------------------------------
20
+ // Concrete error classes
21
+ // ---------------------------------------------------------------------------
22
+ export class ValidationError extends TrailsError {
23
+ category = 'validation';
24
+ retryable = false;
25
+ }
26
+ export class AmbiguousError extends TrailsError {
27
+ category = 'validation';
28
+ retryable = false;
29
+ }
30
+ export class AssertionError extends TrailsError {
31
+ category = 'internal';
32
+ retryable = false;
33
+ }
34
+ export class NotFoundError extends TrailsError {
35
+ category = 'not_found';
36
+ retryable = false;
37
+ }
38
+ export class AlreadyExistsError extends TrailsError {
39
+ category = 'conflict';
40
+ retryable = false;
41
+ }
42
+ export class ConflictError extends TrailsError {
43
+ category = 'conflict';
44
+ retryable = false;
45
+ }
46
+ export class PermissionError extends TrailsError {
47
+ category = 'permission';
48
+ retryable = false;
49
+ }
50
+ export class TimeoutError extends TrailsError {
51
+ category = 'timeout';
52
+ retryable = true;
53
+ }
54
+ export class RateLimitError extends TrailsError {
55
+ category = 'rate_limit';
56
+ retryable = true;
57
+ retryAfter;
58
+ constructor(message, options) {
59
+ super(message, options);
60
+ this.retryAfter = options?.retryAfter;
61
+ }
62
+ }
63
+ export class NetworkError extends TrailsError {
64
+ category = 'network';
65
+ retryable = true;
66
+ }
67
+ export class InternalError extends TrailsError {
68
+ category = 'internal';
69
+ retryable = false;
70
+ }
71
+ export class AuthError extends TrailsError {
72
+ category = 'auth';
73
+ retryable = false;
74
+ }
75
+ export class CancelledError extends TrailsError {
76
+ category = 'cancelled';
77
+ retryable = false;
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // Taxonomy maps
81
+ // ---------------------------------------------------------------------------
82
+ export const exitCodeMap = {
83
+ auth: 9,
84
+ cancelled: 130,
85
+ conflict: 3,
86
+ internal: 8,
87
+ network: 7,
88
+ not_found: 2,
89
+ permission: 4,
90
+ rate_limit: 6,
91
+ timeout: 5,
92
+ validation: 1,
93
+ };
94
+ export const statusCodeMap = {
95
+ auth: 401,
96
+ cancelled: 499,
97
+ conflict: 409,
98
+ internal: 500,
99
+ network: 502,
100
+ not_found: 404,
101
+ permission: 403,
102
+ rate_limit: 429,
103
+ timeout: 504,
104
+ validation: 400,
105
+ };
106
+ export const jsonRpcCodeMap = {
107
+ auth: -32_600,
108
+ cancelled: -32_603,
109
+ conflict: -32_603,
110
+ internal: -32_603,
111
+ network: -32_603,
112
+ not_found: -32_601,
113
+ permission: -32_600,
114
+ rate_limit: -32_603,
115
+ timeout: -32_603,
116
+ validation: -32_602,
117
+ };
118
+ export const retryableMap = {
119
+ auth: false,
120
+ cancelled: false,
121
+ conflict: false,
122
+ internal: false,
123
+ network: true,
124
+ not_found: false,
125
+ permission: false,
126
+ rate_limit: true,
127
+ timeout: true,
128
+ validation: false,
129
+ };
130
+ // ---------------------------------------------------------------------------
131
+ // Helper functions
132
+ // ---------------------------------------------------------------------------
133
+ /** Type guard: narrows unknown to TrailsError */
134
+ export const isTrailsError = (error) => error instanceof TrailsError;
135
+ /** Returns true if the error is retryable (TrailsError with retryable category). */
136
+ export const isRetryable = (error) => {
137
+ if (isTrailsError(error)) {
138
+ return retryableMap[error.category];
139
+ }
140
+ return false;
141
+ };
142
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Event — a named payload schema with optional provenance metadata.
3
+ */
4
+ import type { z } from 'zod';
5
+ export interface EventSpec<T> {
6
+ readonly payload: z.ZodType<T>;
7
+ readonly description?: string | undefined;
8
+ readonly markers?: Readonly<Record<string, unknown>> | undefined;
9
+ /** Trail IDs that produce this event (e.g. the trails it originates from). */
10
+ readonly from?: readonly string[] | undefined;
11
+ }
12
+ export interface Event<T> {
13
+ readonly id: string;
14
+ readonly kind: 'event';
15
+ readonly payload: z.ZodType<T>;
16
+ readonly description?: string | undefined;
17
+ readonly markers?: Readonly<Record<string, unknown>> | undefined;
18
+ /** Trail IDs that produce this event (e.g. the trails it originates from). */
19
+ readonly from?: readonly string[] | undefined;
20
+ }
21
+ /**
22
+ * Create an event definition.
23
+ *
24
+ * An event is a named payload schema describing something that happened.
25
+ * Returns a frozen object with `kind: "event"` and all spec fields.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * // ID as first argument
30
+ * const updated = event("entity.updated", {
31
+ * payload: EntityUpdatedSchema,
32
+ * from: ["entity.add", "entity.update"],
33
+ * });
34
+ *
35
+ * // Full spec object (programmatic)
36
+ * const updated = event({ id: "entity.updated", payload: ..., from: [...] });
37
+ * ```
38
+ */
39
+ export declare function event<T>(id: string, spec: EventSpec<T>): Event<T>;
40
+ export declare function event<T>(spec: EventSpec<T> & {
41
+ readonly id: string;
42
+ }): Event<T>;
43
+ /** Existential type for heterogeneous event collections */
44
+ export type AnyEvent = Event<unknown>;
45
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAM7B,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IACjE,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC/C;AAMD,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IACjE,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC/C;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,wBAAgB,KAAK,CAAC,CAAC,EACrB,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC3C,KAAK,CAAC,CAAC,CAAC,CAAC;AAkBZ,2DAA2D;AAC3D,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC"}
package/dist/event.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Event — a named payload schema with optional provenance metadata.
3
+ */
4
+ export function event(idOrSpec, maybeSpec) {
5
+ const resolvedId = typeof idOrSpec === 'string' ? idOrSpec : idOrSpec.id;
6
+ // oxlint-disable-next-line no-non-null-assertion -- overload guarantees maybeSpec when idOrSpec is string
7
+ const resolvedSpec = typeof idOrSpec === 'string' ? maybeSpec : idOrSpec;
8
+ return Object.freeze({
9
+ description: resolvedSpec.description,
10
+ from: resolvedSpec.from ? Object.freeze([...resolvedSpec.from]) : undefined,
11
+ id: resolvedId,
12
+ kind: 'event',
13
+ markers: resolvedSpec.markers,
14
+ payload: resolvedSpec.payload,
15
+ });
16
+ }
17
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwDH,MAAM,UAAU,KAAK,CACnB,QAA2D,EAC3D,SAAwB;IAExB,MAAM,UAAU,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;IACzE,0GAA0G;IAC1G,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1E,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,WAAW,EAAE,YAAY,CAAC,WAAW;QACrC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAC3E,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,OAAgB;QACtB,OAAO,EAAE,YAAY,CAAC,OAAO;QAC7B,OAAO,EAAE,YAAY,CAAC,OAAO;KAC9B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Fetch utilities for @ontrails/core
3
+ *
4
+ * Wraps the standard fetch API, mapping errors and HTTP status codes
5
+ * to the TrailsError taxonomy.
6
+ */
7
+ import { Result } from './result.js';
8
+ /**
9
+ * Wrap a fetch call in a Result, mapping failures to TrailsError subclasses.
10
+ *
11
+ * Network errors become NetworkError. Abort signals become CancelledError.
12
+ * HTTP error status codes map to the appropriate error category.
13
+ */
14
+ export declare const fromFetch: (input: string | URL | Request, init?: RequestInit) => Promise<Result<Response, Error>>;
15
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA+FrC;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GACpB,OAAO,MAAM,GAAG,GAAG,GAAG,OAAO,EAC7B,OAAO,WAAW,KACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAcjC,CAAC"}
package/dist/fetch.js ADDED
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Fetch utilities for @ontrails/core
3
+ *
4
+ * Wraps the standard fetch API, mapping errors and HTTP status codes
5
+ * to the TrailsError taxonomy.
6
+ */
7
+ import { AuthError, CancelledError, ConflictError, InternalError, NetworkError, NotFoundError, PermissionError, RateLimitError, TimeoutError, ValidationError, } from './errors.js';
8
+ import { Result } from './result.js';
9
+ // ---------------------------------------------------------------------------
10
+ // Internal helpers (defined before usage)
11
+ // ---------------------------------------------------------------------------
12
+ const toError = (err) => err instanceof Error ? err : new Error(String(err));
13
+ const parseRetryAfter = (header) => {
14
+ if (!header) {
15
+ return undefined;
16
+ }
17
+ const seconds = Number(header);
18
+ if (Number.isFinite(seconds) && seconds > 0) {
19
+ return seconds;
20
+ }
21
+ // Try parsing as HTTP-date
22
+ const date = Date.parse(header);
23
+ if (!Number.isNaN(date)) {
24
+ const delta = Math.ceil((date - Date.now()) / 1000);
25
+ return delta > 0 ? delta : undefined;
26
+ }
27
+ return undefined;
28
+ };
29
+ const mapFetchError = (err) => {
30
+ if (err instanceof DOMException && err.name === 'AbortError') {
31
+ return new CancelledError('Request was aborted', { cause: toError(err) });
32
+ }
33
+ // TypeError is thrown for network failures in the fetch spec
34
+ if (err instanceof TypeError) {
35
+ return new NetworkError('Network request failed', { cause: err });
36
+ }
37
+ return new NetworkError('Network request failed', {
38
+ cause: toError(err),
39
+ });
40
+ };
41
+ const statusMappers = {
42
+ 401: (ctx) => new AuthError('Unauthorized', { context: ctx }),
43
+ 403: (ctx) => new PermissionError('Forbidden', { context: ctx }),
44
+ 404: (ctx) => new NotFoundError('Not found', { context: ctx }),
45
+ 429: (ctx, response) => {
46
+ const retryAfter = parseRetryAfter(response.headers.get('retry-after'));
47
+ const opts = {
48
+ context: ctx,
49
+ };
50
+ if (retryAfter !== undefined) {
51
+ opts.retryAfter = retryAfter;
52
+ }
53
+ return new RateLimitError('Rate limited', opts);
54
+ },
55
+ 500: (ctx) => new InternalError('Internal server error', { context: ctx }),
56
+ 502: (ctx) => new NetworkError('Bad gateway', { context: ctx }),
57
+ 504: (ctx) => new TimeoutError('Gateway timeout', { context: ctx }),
58
+ };
59
+ /** Map 4xx status codes not in the explicit mapper to appropriate error types. */
60
+ const mapClientError = (status, context) => {
61
+ if (status === 400 || status === 422) {
62
+ return new ValidationError(`Validation error (${status})`, { context });
63
+ }
64
+ if (status === 409) {
65
+ return new ConflictError(`Conflict (${status})`, { context });
66
+ }
67
+ return new InternalError(`HTTP error (${status})`, { context });
68
+ };
69
+ const mapStatusCode = (response) => {
70
+ const context = { status: response.status, url: response.url };
71
+ const mapper = statusMappers[response.status];
72
+ if (mapper) {
73
+ return mapper(context, response);
74
+ }
75
+ if (response.status >= 500) {
76
+ return new InternalError(`Server error (${response.status})`, { context });
77
+ }
78
+ return mapClientError(response.status, context);
79
+ };
80
+ // ---------------------------------------------------------------------------
81
+ // fromFetch
82
+ // ---------------------------------------------------------------------------
83
+ /**
84
+ * Wrap a fetch call in a Result, mapping failures to TrailsError subclasses.
85
+ *
86
+ * Network errors become NetworkError. Abort signals become CancelledError.
87
+ * HTTP error status codes map to the appropriate error category.
88
+ */
89
+ export const fromFetch = async (input, init) => {
90
+ let response;
91
+ try {
92
+ response = await fetch(input, init);
93
+ }
94
+ catch (error) {
95
+ return Result.err(mapFetchError(error));
96
+ }
97
+ if (response.ok) {
98
+ return Result.ok(response);
99
+ }
100
+ return Result.err(mapStatusCode(response));
101
+ };
102
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Type guards and assertion helpers for @ontrails/core.
3
+ */
4
+ /** Narrows `T | null | undefined` to `T`. */
5
+ export declare const isDefined: <T>(value?: T | null | undefined) => value is T;
6
+ /** Returns true when `value` is a string with length > 0. */
7
+ export declare const isNonEmptyString: (value?: unknown) => value is string;
8
+ /** Returns true when `value` is a plain object (not an array, Date, etc.). */
9
+ export declare const isPlainObject: (value: unknown) => value is Record<string, unknown>;
10
+ /** Checks that `obj` is an object with the given key present. */
11
+ export declare const hasProperty: <K extends string>(obj: unknown, key: K) => obj is Record<K, unknown>;
12
+ /**
13
+ * Exhaustive switch helper. Place in the `default` branch to get a compile
14
+ * error when a union case is unhandled.
15
+ */
16
+ export declare const assertNever: (value: never) => never;
17
+ //# sourceMappingURL=guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6CAA6C;AAC7C,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,KAAG,KAAK,IAAI,CAC9B,CAAC;AAExC,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,KAAG,KAAK,IAAI,MACb,CAAC;AAEhD,8EAA8E;AAC9E,eAAO,MAAM,aAAa,GACxB,OAAO,OAAO,KACb,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAMjC,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAC1C,KAAK,OAAO,EACZ,KAAK,CAAC,KACL,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAC4B,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,KAAG,KAE1C,CAAC"}
package/dist/guards.js ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Type guards and assertion helpers for @ontrails/core.
3
+ */
4
+ /** Narrows `T | null | undefined` to `T`. */
5
+ export const isDefined = (value) => value !== null && value !== undefined;
6
+ /** Returns true when `value` is a string with length > 0. */
7
+ export const isNonEmptyString = (value) => typeof value === 'string' && value.length > 0;
8
+ /** Returns true when `value` is a plain object (not an array, Date, etc.). */
9
+ export const isPlainObject = (value) => {
10
+ if (typeof value !== 'object' || value === null) {
11
+ return false;
12
+ }
13
+ const proto = Object.getPrototypeOf(value);
14
+ return proto === Object.prototype || proto === null;
15
+ };
16
+ /** Checks that `obj` is an object with the given key present. */
17
+ export const hasProperty = (obj, key) => typeof obj === 'object' && obj !== null && key in obj;
18
+ /**
19
+ * Exhaustive switch helper. Place in the `default` branch to get a compile
20
+ * error when a union case is unhandled.
21
+ */
22
+ export const assertNever = (value) => {
23
+ throw new Error(`Unexpected value: ${String(value)}`);
24
+ };
25
+ //# sourceMappingURL=guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.js","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,KAA4B,EAAc,EAAE,CACvE,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;AAExC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAe,EAAmB,EAAE,CACnE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAEhD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,KAAc,EACoB,EAAE;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAY,CAAC;IACtD,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AACtD,CAAC,CAAC;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,GAAY,EACZ,GAAM,EACqB,EAAE,CAC7B,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC;AAExD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAY,EAAS,EAAE;IACjD,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /** Aggregate health status */
2
+ export type HealthStatus = 'healthy' | 'degraded' | 'unhealthy';
3
+ /** Individual component check result */
4
+ export interface HealthCheck {
5
+ readonly status: HealthStatus;
6
+ readonly message?: string | undefined;
7
+ /** Latency in milliseconds */
8
+ readonly latency?: number | undefined;
9
+ }
10
+ /** Full health report returned by a health endpoint */
11
+ export interface HealthResult {
12
+ readonly status: HealthStatus;
13
+ readonly checks: Readonly<Record<string, HealthCheck>>;
14
+ readonly version?: string | undefined;
15
+ /** Uptime in seconds */
16
+ readonly uptime?: number | undefined;
17
+ }
18
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAIA,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAEhE,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,uDAAuD;AACvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,wBAAwB;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC"}