@ontrails/core 1.0.0-beta.4 → 1.0.0-beta.41

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 (247) hide show
  1. package/CHANGELOG.md +412 -12
  2. package/README.md +112 -28
  3. package/package.json +11 -1
  4. package/src/activation-provenance.ts +116 -0
  5. package/src/activation-source-compatibility.ts +430 -0
  6. package/src/activation-source-projection.ts +227 -0
  7. package/src/activation-source.ts +93 -0
  8. package/src/blob-ref.ts +51 -0
  9. package/src/branded.ts +1 -1
  10. package/src/compose-batch.ts +69 -0
  11. package/src/compose-schema.ts +36 -0
  12. package/src/context.ts +59 -11
  13. package/src/derive.ts +271 -19
  14. package/src/detours.ts +8 -0
  15. package/src/diagnostics.ts +21 -0
  16. package/src/draft.ts +350 -0
  17. package/src/entity.ts +346 -0
  18. package/src/error-projection.ts +51 -0
  19. package/src/errors.ts +335 -48
  20. package/src/execute.ts +1577 -0
  21. package/src/fire.ts +1172 -0
  22. package/src/glob.ts +81 -0
  23. package/src/index.ts +568 -32
  24. package/src/internal/fork-ctx.ts +69 -0
  25. package/src/layer-projection.ts +193 -0
  26. package/src/layer.ts +43 -6
  27. package/src/observe.ts +361 -0
  28. package/src/path-scope.ts +66 -0
  29. package/src/path-security.ts +11 -3
  30. package/src/permits.ts +12 -0
  31. package/src/queue.ts +163 -0
  32. package/src/redaction/patterns.ts +6 -3
  33. package/src/resilience.ts +11 -11
  34. package/src/resource-config.ts +804 -0
  35. package/src/resource.ts +194 -0
  36. package/src/result.ts +18 -0
  37. package/src/run.ts +76 -0
  38. package/src/runtime-builtins.ts +69 -0
  39. package/src/schedule-runtime.ts +689 -0
  40. package/src/schedule.ts +326 -0
  41. package/src/serialization.ts +92 -55
  42. package/src/sha256.ts +136 -0
  43. package/src/signal-diagnostics.ts +633 -0
  44. package/src/signal-ref.ts +111 -0
  45. package/src/signal.ts +104 -0
  46. package/src/store/accessor-protocol.ts +56 -0
  47. package/src/store/index.ts +4 -0
  48. package/src/structured-examples.ts +248 -0
  49. package/src/surface-derivation.ts +91 -0
  50. package/src/surface-filter.ts +101 -0
  51. package/src/surface-overlay.ts +694 -0
  52. package/src/surface-versioning.ts +42 -0
  53. package/src/topo.ts +762 -38
  54. package/src/tracing.ts +346 -0
  55. package/src/trail-id-glob.ts +15 -0
  56. package/src/trail.ts +1244 -34
  57. package/src/trails/derive-trail.ts +835 -0
  58. package/src/trails/index.ts +9 -0
  59. package/src/trails/ingest.ts +152 -0
  60. package/src/trails-db.ts +212 -0
  61. package/src/transport-error-map.ts +174 -0
  62. package/src/type-utils.ts +87 -0
  63. package/src/types.ts +254 -12
  64. package/src/validate-established-topo.ts +73 -0
  65. package/src/validate-topo.ts +569 -55
  66. package/src/validation.ts +152 -4
  67. package/src/version-marker.ts +716 -0
  68. package/src/version-resolution.ts +308 -0
  69. package/src/version-runtime.ts +120 -0
  70. package/src/webhook.ts +461 -0
  71. package/src/workspace.ts +183 -16
  72. package/src/zod-wrappers.ts +72 -0
  73. package/.turbo/turbo-build.log +0 -1
  74. package/.turbo/turbo-lint.log +0 -3
  75. package/.turbo/turbo-typecheck.log +0 -1
  76. package/dist/adapters.d.ts +0 -39
  77. package/dist/adapters.d.ts.map +0 -1
  78. package/dist/adapters.js +0 -2
  79. package/dist/adapters.js.map +0 -1
  80. package/dist/blob-ref.d.ts +0 -20
  81. package/dist/blob-ref.d.ts.map +0 -1
  82. package/dist/blob-ref.js +0 -22
  83. package/dist/blob-ref.js.map +0 -1
  84. package/dist/branded.d.ts +0 -36
  85. package/dist/branded.d.ts.map +0 -1
  86. package/dist/branded.js +0 -89
  87. package/dist/branded.js.map +0 -1
  88. package/dist/collections.d.ts +0 -31
  89. package/dist/collections.d.ts.map +0 -1
  90. package/dist/collections.js +0 -60
  91. package/dist/collections.js.map +0 -1
  92. package/dist/context.d.ts +0 -10
  93. package/dist/context.d.ts.map +0 -1
  94. package/dist/context.js +0 -15
  95. package/dist/context.js.map +0 -1
  96. package/dist/derive.d.ts +0 -33
  97. package/dist/derive.d.ts.map +0 -1
  98. package/dist/derive.js +0 -125
  99. package/dist/derive.js.map +0 -1
  100. package/dist/errors.d.ts +0 -83
  101. package/dist/errors.d.ts.map +0 -1
  102. package/dist/errors.js +0 -142
  103. package/dist/errors.js.map +0 -1
  104. package/dist/event.d.ts +0 -45
  105. package/dist/event.d.ts.map +0 -1
  106. package/dist/event.js +0 -17
  107. package/dist/event.js.map +0 -1
  108. package/dist/fetch.d.ts +0 -15
  109. package/dist/fetch.d.ts.map +0 -1
  110. package/dist/fetch.js +0 -102
  111. package/dist/fetch.js.map +0 -1
  112. package/dist/guards.d.ts +0 -17
  113. package/dist/guards.d.ts.map +0 -1
  114. package/dist/guards.js +0 -25
  115. package/dist/guards.js.map +0 -1
  116. package/dist/health.d.ts +0 -18
  117. package/dist/health.d.ts.map +0 -1
  118. package/dist/health.js +0 -5
  119. package/dist/health.js.map +0 -1
  120. package/dist/index.d.ts +0 -34
  121. package/dist/index.d.ts.map +0 -1
  122. package/dist/index.js +0 -38
  123. package/dist/index.js.map +0 -1
  124. package/dist/job.d.ts +0 -24
  125. package/dist/job.d.ts.map +0 -1
  126. package/dist/job.js +0 -17
  127. package/dist/job.js.map +0 -1
  128. package/dist/layer.d.ts +0 -17
  129. package/dist/layer.d.ts.map +0 -1
  130. package/dist/layer.js +0 -21
  131. package/dist/layer.js.map +0 -1
  132. package/dist/path-security.d.ts +0 -28
  133. package/dist/path-security.d.ts.map +0 -1
  134. package/dist/path-security.js +0 -63
  135. package/dist/path-security.js.map +0 -1
  136. package/dist/patterns/bulk.d.ts +0 -15
  137. package/dist/patterns/bulk.d.ts.map +0 -1
  138. package/dist/patterns/bulk.js +0 -14
  139. package/dist/patterns/bulk.js.map +0 -1
  140. package/dist/patterns/change.d.ts +0 -10
  141. package/dist/patterns/change.d.ts.map +0 -1
  142. package/dist/patterns/change.js +0 -10
  143. package/dist/patterns/change.js.map +0 -1
  144. package/dist/patterns/date-range.d.ts +0 -10
  145. package/dist/patterns/date-range.d.ts.map +0 -1
  146. package/dist/patterns/date-range.js +0 -10
  147. package/dist/patterns/date-range.js.map +0 -1
  148. package/dist/patterns/index.d.ts +0 -9
  149. package/dist/patterns/index.d.ts.map +0 -1
  150. package/dist/patterns/index.js +0 -9
  151. package/dist/patterns/index.js.map +0 -1
  152. package/dist/patterns/pagination.d.ts +0 -18
  153. package/dist/patterns/pagination.d.ts.map +0 -1
  154. package/dist/patterns/pagination.js +0 -18
  155. package/dist/patterns/pagination.js.map +0 -1
  156. package/dist/patterns/progress.d.ts +0 -11
  157. package/dist/patterns/progress.d.ts.map +0 -1
  158. package/dist/patterns/progress.js +0 -11
  159. package/dist/patterns/progress.js.map +0 -1
  160. package/dist/patterns/sorting.d.ts +0 -13
  161. package/dist/patterns/sorting.d.ts.map +0 -1
  162. package/dist/patterns/sorting.js +0 -10
  163. package/dist/patterns/sorting.js.map +0 -1
  164. package/dist/patterns/status.d.ts +0 -15
  165. package/dist/patterns/status.d.ts.map +0 -1
  166. package/dist/patterns/status.js +0 -9
  167. package/dist/patterns/status.js.map +0 -1
  168. package/dist/patterns/timestamps.d.ts +0 -10
  169. package/dist/patterns/timestamps.d.ts.map +0 -1
  170. package/dist/patterns/timestamps.js +0 -10
  171. package/dist/patterns/timestamps.js.map +0 -1
  172. package/dist/redaction/index.d.ts +0 -4
  173. package/dist/redaction/index.d.ts.map +0 -1
  174. package/dist/redaction/index.js +0 -3
  175. package/dist/redaction/index.js.map +0 -1
  176. package/dist/redaction/patterns.d.ts +0 -9
  177. package/dist/redaction/patterns.d.ts.map +0 -1
  178. package/dist/redaction/patterns.js +0 -39
  179. package/dist/redaction/patterns.js.map +0 -1
  180. package/dist/redaction/redactor.d.ts +0 -27
  181. package/dist/redaction/redactor.d.ts.map +0 -1
  182. package/dist/redaction/redactor.js +0 -89
  183. package/dist/redaction/redactor.js.map +0 -1
  184. package/dist/resilience.d.ts +0 -34
  185. package/dist/resilience.d.ts.map +0 -1
  186. package/dist/resilience.js +0 -164
  187. package/dist/resilience.js.map +0 -1
  188. package/dist/result.d.ts +0 -57
  189. package/dist/result.d.ts.map +0 -1
  190. package/dist/result.js +0 -156
  191. package/dist/result.js.map +0 -1
  192. package/dist/serialization.d.ts +0 -27
  193. package/dist/serialization.d.ts.map +0 -1
  194. package/dist/serialization.js +0 -153
  195. package/dist/serialization.js.map +0 -1
  196. package/dist/topo.d.ts +0 -16
  197. package/dist/topo.d.ts.map +0 -1
  198. package/dist/topo.js +0 -66
  199. package/dist/topo.js.map +0 -1
  200. package/dist/trail.d.ts +0 -89
  201. package/dist/trail.d.ts.map +0 -1
  202. package/dist/trail.js +0 -18
  203. package/dist/trail.js.map +0 -1
  204. package/dist/types.d.ts +0 -46
  205. package/dist/types.d.ts.map +0 -1
  206. package/dist/types.js +0 -2
  207. package/dist/types.js.map +0 -1
  208. package/dist/validate-topo.d.ts +0 -24
  209. package/dist/validate-topo.d.ts.map +0 -1
  210. package/dist/validate-topo.js +0 -158
  211. package/dist/validate-topo.js.map +0 -1
  212. package/dist/validation.d.ts +0 -27
  213. package/dist/validation.d.ts.map +0 -1
  214. package/dist/validation.js +0 -134
  215. package/dist/validation.js.map +0 -1
  216. package/dist/workspace.d.ts +0 -25
  217. package/dist/workspace.d.ts.map +0 -1
  218. package/dist/workspace.js +0 -57
  219. package/dist/workspace.js.map +0 -1
  220. package/src/__tests__/blob-ref.test.ts +0 -103
  221. package/src/__tests__/branded.test.ts +0 -148
  222. package/src/__tests__/collections.test.ts +0 -126
  223. package/src/__tests__/context.test.ts +0 -66
  224. package/src/__tests__/derive.test.ts +0 -203
  225. package/src/__tests__/errors.test.ts +0 -309
  226. package/src/__tests__/event.test.ts +0 -82
  227. package/src/__tests__/fetch.test.ts +0 -217
  228. package/src/__tests__/guards.test.ts +0 -102
  229. package/src/__tests__/job.test.ts +0 -98
  230. package/src/__tests__/layer.test.ts +0 -212
  231. package/src/__tests__/path-security.test.ts +0 -114
  232. package/src/__tests__/patterns.test.ts +0 -273
  233. package/src/__tests__/redaction.test.ts +0 -244
  234. package/src/__tests__/resilience.test.ts +0 -246
  235. package/src/__tests__/result.test.ts +0 -155
  236. package/src/__tests__/serialization.test.ts +0 -401
  237. package/src/__tests__/topo.test.ts +0 -181
  238. package/src/__tests__/trail.test.ts +0 -217
  239. package/src/__tests__/validate-topo.test.ts +0 -278
  240. package/src/__tests__/validation.test.ts +0 -283
  241. package/src/__tests__/workspace.test.ts +0 -183
  242. package/src/adapters.ts +0 -68
  243. package/src/event.ts +0 -77
  244. package/src/health.ts +0 -23
  245. package/src/job.ts +0 -20
  246. package/tsconfig.json +0 -9
  247. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+
3
+ import { matchesAnyGlob, matchesGlob } from './glob.js';
4
+
5
+ declare const pathGlobBrand: unique symbol;
6
+
7
+ export type PathGlob = string & {
8
+ readonly [pathGlobBrand]: 'PathGlob';
9
+ };
10
+
11
+ export const normalizePathScopePath = (value: string): string =>
12
+ value.replaceAll('\\', '/').replace(/^\.\//, '');
13
+
14
+ export const matchesPathGlob = (path: string, pattern: string): boolean =>
15
+ matchesGlob(normalizePathScopePath(path), normalizePathScopePath(pattern), {
16
+ separator: '/',
17
+ });
18
+
19
+ export const matchesAnyPathGlob = (
20
+ path: string,
21
+ patterns: readonly string[] | undefined
22
+ ): boolean =>
23
+ matchesAnyGlob(
24
+ normalizePathScopePath(path),
25
+ patterns?.map(normalizePathScopePath),
26
+ { separator: '/' }
27
+ );
28
+
29
+ const pathGlobArraySchema = z.array(z.string()).readonly();
30
+
31
+ export const pathScopeSchema = z
32
+ .object({
33
+ exclude: pathGlobArraySchema.optional(),
34
+ extensions: z.array(z.string()).readonly().optional(),
35
+ include: pathGlobArraySchema.optional(),
36
+ })
37
+ .strict();
38
+
39
+ export type PathScope = z.output<typeof pathScopeSchema>;
40
+
41
+ export type ScanTargets = Pick<PathScope, 'exclude' | 'extensions'>;
42
+
43
+ const extensionOf = (path: string): string => {
44
+ const normalized = normalizePathScopePath(path);
45
+ const name = normalized.slice(normalized.lastIndexOf('/') + 1);
46
+ const dot = name.lastIndexOf('.');
47
+ return dot <= 0 ? '' : name.slice(dot);
48
+ };
49
+
50
+ const normalizeExtension = (extension: string): string =>
51
+ extension === '' || extension.startsWith('.') ? extension : `.${extension}`;
52
+
53
+ const includedByExtension = (
54
+ path: string,
55
+ extensions: readonly string[] | undefined
56
+ ): boolean =>
57
+ extensions === undefined ||
58
+ extensions.length === 0 ||
59
+ extensions.map(normalizeExtension).includes(extensionOf(path));
60
+
61
+ export const includedByPathScope = (path: string, scope?: PathScope): boolean =>
62
+ (scope?.include === undefined ||
63
+ scope.include.length === 0 ||
64
+ matchesAnyPathGlob(path, scope.include)) &&
65
+ !matchesAnyPathGlob(path, scope?.exclude) &&
66
+ includedByExtension(path, scope?.extensions);
@@ -4,10 +4,14 @@
4
4
  * All functions are runtime-agnostic (Node / Bun compatible).
5
5
  */
6
6
 
7
- import { resolve, relative, normalize, isAbsolute } from 'node:path';
8
-
9
7
  import { PermissionError } from './errors.js';
10
8
  import { Result } from './result.js';
9
+ // Path security guards filesystem access on tooling paths: node:path
10
+ // loads lazily at first use so the core barrel's module graph stays
11
+ // execution-portable on runtimes without node: builtins (TRL-1198).
12
+ import { loadRuntimeBuiltin } from './runtime-builtins.js';
13
+
14
+ const nodePath = () => loadRuntimeBuiltin('node:path');
11
15
 
12
16
  // ---------------------------------------------------------------------------
13
17
  // Internal
@@ -15,6 +19,7 @@ import { Result } from './result.js';
15
19
 
16
20
  /** Returns true when `target` is equal to or a descendant of `base`. */
17
21
  const isWithin = (base: string, target: string): boolean => {
22
+ const { isAbsolute, relative } = nodePath();
18
23
  const rel = relative(base, target);
19
24
  // Empty string means they are the same directory.
20
25
  // A relative path starting with ".." means it escapes.
@@ -39,6 +44,7 @@ export const securePath = (
39
44
  basePath: string,
40
45
  userPath: string
41
46
  ): Result<string, PermissionError> => {
47
+ const { resolve } = nodePath();
42
48
  const base = resolve(basePath);
43
49
  const resolved = resolve(base, userPath);
44
50
 
@@ -61,6 +67,7 @@ export const securePath = (
61
67
  * `basePath`.
62
68
  */
63
69
  export const isPathSafe = (basePath: string, userPath: string): boolean => {
70
+ const { resolve } = nodePath();
64
71
  const base = resolve(basePath);
65
72
  const resolved = resolve(base, userPath);
66
73
  return isWithin(base, resolved);
@@ -70,10 +77,11 @@ export const isPathSafe = (basePath: string, userPath: string): boolean => {
70
77
  * Joins multiple path segments, resolves them against `basePath`, and
71
78
  * validates the result stays within the base directory.
72
79
  */
73
- export const resolveSafePath = (
80
+ export const deriveSafePath = (
74
81
  basePath: string,
75
82
  ...segments: string[]
76
83
  ): Result<string, PermissionError> => {
84
+ const { normalize, resolve } = nodePath();
77
85
  const base = resolve(basePath);
78
86
  const joined = resolve(base, ...segments.map((s) => normalize(s)));
79
87
 
package/src/permits.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+
3
+ /** Minimal permit shape available on TrailContext. */
4
+ export interface BasePermit {
5
+ readonly id: string;
6
+ readonly scopes: readonly string[];
7
+ }
8
+
9
+ export const basePermitSchema: z.ZodType<BasePermit> = z.object({
10
+ id: z.string(),
11
+ scopes: z.array(z.string()).readonly(),
12
+ });
package/src/queue.ts ADDED
@@ -0,0 +1,163 @@
1
+ import type {
2
+ ActivationSource,
3
+ ActivationSourceMeta,
4
+ ActivationSourceParse,
5
+ } from './activation-source.js';
6
+ import { ValidationError } from './errors.js';
7
+
8
+ export interface QueueSpec<TOutput = unknown> {
9
+ readonly meta?: ActivationSourceMeta | undefined;
10
+ readonly parse: ActivationSourceParse<TOutput>;
11
+ readonly payload?: ActivationSource['payload'] | undefined;
12
+ /**
13
+ * Runtime queue name. Defaults to the source id, so authored queue
14
+ * contracts can stay stable while host bindings choose their own names.
15
+ */
16
+ readonly queue?: string | undefined;
17
+ /** Reserved for future queue-specific design; trail versioning is trail-only. */
18
+ readonly version?: never;
19
+ }
20
+
21
+ export interface QueueSource<TOutput = unknown> extends ActivationSource {
22
+ readonly kind: 'queue';
23
+ readonly meta?: ActivationSourceMeta | undefined;
24
+ readonly parse: ActivationSourceParse<TOutput>;
25
+ readonly payload?: ActivationSource['payload'] | undefined;
26
+ readonly queue: string;
27
+ }
28
+
29
+ export interface QueueValidationIssue {
30
+ readonly field: 'parse' | 'queue';
31
+ readonly message: string;
32
+ }
33
+
34
+ const normalizeQueueName = (queueName: string): string => queueName.trim();
35
+
36
+ const isObjectRecord = (value: unknown): value is Record<string, unknown> =>
37
+ typeof value === 'object' && value !== null && !Array.isArray(value);
38
+
39
+ const isZodSchema = (value: unknown): boolean =>
40
+ isObjectRecord(value) && typeof value['safeParse'] === 'function';
41
+
42
+ const validateQueueName = (queueName: unknown): QueueValidationIssue[] =>
43
+ typeof queueName === 'string' && queueName.trim().length > 0
44
+ ? []
45
+ : [
46
+ {
47
+ field: 'queue',
48
+ message: 'Queue source must define a non-empty queue name',
49
+ },
50
+ ];
51
+
52
+ const validateRequiredParse = (parse: unknown): QueueValidationIssue[] =>
53
+ parse === undefined
54
+ ? [
55
+ {
56
+ field: 'parse',
57
+ message: 'Queue sources must define parse',
58
+ },
59
+ ]
60
+ : [];
61
+
62
+ const validateParseShape = (parse: unknown): QueueValidationIssue[] => {
63
+ if (parse === undefined || isZodSchema(parse)) {
64
+ return [];
65
+ }
66
+ if (isObjectRecord(parse) && isZodSchema(parse['output'])) {
67
+ return [];
68
+ }
69
+ return [
70
+ {
71
+ field: 'parse',
72
+ message: 'Queue parse must be a Zod schema or define parse.output',
73
+ },
74
+ ];
75
+ };
76
+
77
+ const queueIssuesMessage = (
78
+ id: string,
79
+ issues: readonly QueueValidationIssue[]
80
+ ): string =>
81
+ `queue("${id}") is invalid: ${issues.map((issue) => `${issue.field}: ${issue.message}`).join('; ')}`;
82
+
83
+ const assertQueueSpec = <TOutput>(
84
+ id: string,
85
+ spec: QueueSpec<TOutput>
86
+ ): {
87
+ readonly queue: string;
88
+ } => {
89
+ const queueName = spec.queue === undefined ? id : spec.queue;
90
+ const issues = [
91
+ ...validateQueueName(queueName),
92
+ ...validateRequiredParse(spec.parse),
93
+ ...validateParseShape(spec.parse),
94
+ ];
95
+
96
+ if (issues.length > 0) {
97
+ throw new ValidationError(queueIssuesMessage(id, issues), {
98
+ context: { issues },
99
+ });
100
+ }
101
+
102
+ return { queue: normalizeQueueName(queueName) };
103
+ };
104
+
105
+ export const validateQueueSource = (
106
+ source: ActivationSource
107
+ ): readonly QueueValidationIssue[] => {
108
+ if (source.kind !== 'queue') {
109
+ return [];
110
+ }
111
+
112
+ return [
113
+ ...validateQueueName(source.queue),
114
+ ...validateRequiredParse(source.parse),
115
+ ...validateParseShape(source.parse),
116
+ ];
117
+ };
118
+
119
+ /**
120
+ * Define a queue activation source.
121
+ *
122
+ * Queue sources are inert contract data: they describe which runtime queue
123
+ * wakes a trail and how the message body becomes trail input. A host adapter
124
+ * such as `@ontrails/cloudflare/workers` owns delivery.
125
+ *
126
+ * @example
127
+ * ```ts
128
+ * import { queue } from '@ontrails/core';
129
+ * import { z } from 'zod';
130
+ *
131
+ * const source = queue('queue.email.outbox', {
132
+ * queue: 'email-outbox',
133
+ * parse: z.object({ messageId: z.string() }),
134
+ * });
135
+ * ```
136
+ */
137
+ export function queue<TOutput>(
138
+ id: string,
139
+ spec: QueueSpec<TOutput>
140
+ ): QueueSource<TOutput>;
141
+ export function queue<TOutput>(
142
+ spec: QueueSpec<TOutput> & { readonly id: string }
143
+ ): QueueSource<TOutput>;
144
+ export function queue<TOutput>(
145
+ idOrSpec: string | (QueueSpec<TOutput> & { readonly id: string }),
146
+ maybeSpec?: QueueSpec<TOutput>
147
+ ): QueueSource<TOutput> {
148
+ const id = typeof idOrSpec === 'string' ? idOrSpec : idOrSpec.id;
149
+ // oxlint-disable-next-line no-non-null-assertion -- overload guarantees maybeSpec when idOrSpec is string
150
+ const spec = typeof idOrSpec === 'string' ? maybeSpec! : idOrSpec;
151
+ const normalized = assertQueueSpec(id, spec);
152
+
153
+ return Object.freeze({
154
+ id,
155
+ kind: 'queue' as const,
156
+ parse: spec.parse,
157
+ queue: normalized.queue,
158
+ ...(spec.meta === undefined
159
+ ? {}
160
+ : { meta: Object.freeze({ ...spec.meta }) }),
161
+ ...(spec.payload === undefined ? {} : { payload: spec.payload }),
162
+ });
163
+ }
@@ -16,11 +16,14 @@ export const DEFAULT_PATTERNS: RegExp[] = [
16
16
  // SSN: XXX-XX-XXXX
17
17
  /\b\d{3}-\d{2}-\d{4}\b/g,
18
18
 
19
- // Bearer tokens
20
- /Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,
19
+ // Bearer tokens. Keep the threshold above short prose like "Bearer token".
20
+ /Bearer\s+[A-Za-z0-9\-._~+/=]{6,}/g,
21
21
 
22
22
  // Basic auth
23
- /Basic\s+[A-Za-z0-9+/]+=*/g,
23
+ /Basic\s+[A-Za-z0-9+/=]{8,}/g,
24
+
25
+ // Common key/value secrets embedded in strings
26
+ /\b(?:password|secret|token|api[_-]?key|cookie)\s*[:=]\s*[^\s,;]+/gi,
24
27
 
25
28
  // API keys: sk-*, pk_*, sk_* prefixed tokens
26
29
  /\b(?:sk-|pk_|sk_)[A-Za-z0-9_-]{8,}\b/g,
package/src/resilience.ts CHANGED
@@ -61,11 +61,11 @@ const sleep = (ms: number, signal?: AbortSignal): Promise<void> =>
61
61
  export const shouldRetry = (error: Error): boolean => isRetryable(error);
62
62
 
63
63
  // ---------------------------------------------------------------------------
64
- // getBackoffDelay
64
+ // deriveBackoffDelay
65
65
  // ---------------------------------------------------------------------------
66
66
 
67
67
  /** Compute exponential backoff delay with full jitter. */
68
- export const getBackoffDelay = (
68
+ export const deriveBackoffDelay = (
69
69
  attempt: number,
70
70
  options?: Pick<RetryOptions, 'baseDelay' | 'maxDelay' | 'backoffFactor'>
71
71
  ): number => {
@@ -108,7 +108,7 @@ const tryAttempt = async <T>(
108
108
  if (isLast || !retryPredicate(result.error)) {
109
109
  return { done: true, result };
110
110
  }
111
- const delay = getBackoffDelay(attempt, options);
111
+ const delay = deriveBackoffDelay(attempt, options);
112
112
  if (delay > 0) {
113
113
  await sleep(delay, options?.signal);
114
114
  }
@@ -203,10 +203,9 @@ export const withTimeout = <T>(
203
203
  );
204
204
  }, ms);
205
205
 
206
- // oxlint-disable-next-line prefer-await-to-then, no-void -- .then() needed inside Promise constructor; void discards unhandled rejection
207
- void fn().then(
208
- // oxlint-disable-next-line prefer-await-to-callbacks -- callback required inside .then()
209
- (result) => {
206
+ const run = async () => {
207
+ try {
208
+ const result = await fn();
210
209
  if (settled) {
211
210
  return;
212
211
  }
@@ -215,9 +214,7 @@ export const withTimeout = <T>(
215
214
  signal?.removeEventListener('abort', onAbort);
216
215
  // oxlint-disable-next-line promise/no-multiple-resolved -- settled guard ensures single resolution
217
216
  resolve(result);
218
- },
219
- // oxlint-disable-next-line prefer-await-to-callbacks -- rejection handler required inside .then()
220
- (error: unknown) => {
217
+ } catch (error: unknown) {
221
218
  if (settled) {
222
219
  return;
223
220
  }
@@ -229,6 +226,9 @@ export const withTimeout = <T>(
229
226
  Result.err(error instanceof Error ? error : new Error(String(error)))
230
227
  );
231
228
  }
232
- );
229
+ };
230
+
231
+ // oxlint-disable-next-line no-void -- fire-and-settle inside Promise constructor
232
+ void run();
233
233
  });
234
234
  };