@voyant-travel/workflows 0.107.10

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 (120) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +52 -0
  3. package/README.md +79 -0
  4. package/dist/auth/index.d.ts +125 -0
  5. package/dist/auth/index.d.ts.map +1 -0
  6. package/dist/auth/index.js +352 -0
  7. package/dist/bindings.d.ts +119 -0
  8. package/dist/bindings.d.ts.map +1 -0
  9. package/dist/bindings.js +19 -0
  10. package/dist/client.d.ts +135 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +305 -0
  13. package/dist/conditions.d.ts +29 -0
  14. package/dist/conditions.d.ts.map +1 -0
  15. package/dist/conditions.js +5 -0
  16. package/dist/config.d.ts +93 -0
  17. package/dist/config.d.ts.map +1 -0
  18. package/dist/config.js +7 -0
  19. package/dist/driver.d.ts +237 -0
  20. package/dist/driver.d.ts.map +1 -0
  21. package/dist/driver.js +53 -0
  22. package/dist/errors.d.ts +58 -0
  23. package/dist/errors.d.ts.map +1 -0
  24. package/dist/errors.js +76 -0
  25. package/dist/events/compile.d.ts +34 -0
  26. package/dist/events/compile.d.ts.map +1 -0
  27. package/dist/events/compile.js +204 -0
  28. package/dist/events/index.d.ts +8 -0
  29. package/dist/events/index.d.ts.map +1 -0
  30. package/dist/events/index.js +11 -0
  31. package/dist/events/input-mapper.d.ts +24 -0
  32. package/dist/events/input-mapper.d.ts.map +1 -0
  33. package/dist/events/input-mapper.js +169 -0
  34. package/dist/events/manifest-builder.d.ts +42 -0
  35. package/dist/events/manifest-builder.d.ts.map +1 -0
  36. package/dist/events/manifest-builder.js +313 -0
  37. package/dist/events/payload-hash.d.ts +46 -0
  38. package/dist/events/payload-hash.d.ts.map +1 -0
  39. package/dist/events/payload-hash.js +98 -0
  40. package/dist/events/predicate.d.ts +77 -0
  41. package/dist/events/predicate.d.ts.map +1 -0
  42. package/dist/events/predicate.js +347 -0
  43. package/dist/events/registry.d.ts +37 -0
  44. package/dist/events/registry.d.ts.map +1 -0
  45. package/dist/events/registry.js +47 -0
  46. package/dist/handler/index.d.ts +114 -0
  47. package/dist/handler/index.d.ts.map +1 -0
  48. package/dist/handler/index.js +267 -0
  49. package/dist/handler/resume.d.ts +41 -0
  50. package/dist/handler/resume.d.ts.map +1 -0
  51. package/dist/handler/resume.js +44 -0
  52. package/dist/http-ingest.d.ts +54 -0
  53. package/dist/http-ingest.d.ts.map +1 -0
  54. package/dist/http-ingest.js +214 -0
  55. package/dist/index.d.ts +6 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +10 -0
  58. package/dist/protocol/index.d.ts +345 -0
  59. package/dist/protocol/index.d.ts.map +1 -0
  60. package/dist/protocol/index.js +110 -0
  61. package/dist/rate-limit/index.d.ts +40 -0
  62. package/dist/rate-limit/index.d.ts.map +1 -0
  63. package/dist/rate-limit/index.js +139 -0
  64. package/dist/runtime/ctx.d.ts +111 -0
  65. package/dist/runtime/ctx.d.ts.map +1 -0
  66. package/dist/runtime/ctx.js +624 -0
  67. package/dist/runtime/determinism.d.ts +19 -0
  68. package/dist/runtime/determinism.d.ts.map +1 -0
  69. package/dist/runtime/determinism.js +61 -0
  70. package/dist/runtime/errors.d.ts +21 -0
  71. package/dist/runtime/errors.d.ts.map +1 -0
  72. package/dist/runtime/errors.js +45 -0
  73. package/dist/runtime/executor.d.ts +166 -0
  74. package/dist/runtime/executor.d.ts.map +1 -0
  75. package/dist/runtime/executor.js +226 -0
  76. package/dist/runtime/journal.d.ts +56 -0
  77. package/dist/runtime/journal.d.ts.map +1 -0
  78. package/dist/runtime/journal.js +28 -0
  79. package/dist/testing/index.d.ts +117 -0
  80. package/dist/testing/index.d.ts.map +1 -0
  81. package/dist/testing/index.js +599 -0
  82. package/dist/trigger.d.ts +37 -0
  83. package/dist/trigger.d.ts.map +1 -0
  84. package/dist/trigger.js +11 -0
  85. package/dist/types.d.ts +63 -0
  86. package/dist/types.d.ts.map +1 -0
  87. package/dist/types.js +3 -0
  88. package/dist/workflow.d.ts +222 -0
  89. package/dist/workflow.d.ts.map +1 -0
  90. package/dist/workflow.js +55 -0
  91. package/package.json +120 -0
  92. package/src/auth/index.ts +398 -0
  93. package/src/bindings.ts +135 -0
  94. package/src/client.ts +498 -0
  95. package/src/conditions.ts +43 -0
  96. package/src/config.ts +114 -0
  97. package/src/driver.ts +277 -0
  98. package/src/errors.ts +109 -0
  99. package/src/events/compile.ts +268 -0
  100. package/src/events/index.ts +42 -0
  101. package/src/events/input-mapper.ts +201 -0
  102. package/src/events/manifest-builder.ts +372 -0
  103. package/src/events/payload-hash.ts +110 -0
  104. package/src/events/predicate.ts +390 -0
  105. package/src/events/registry.ts +86 -0
  106. package/src/handler/index.ts +413 -0
  107. package/src/handler/resume.ts +100 -0
  108. package/src/http-ingest.ts +299 -0
  109. package/src/index.ts +18 -0
  110. package/src/protocol/index.ts +483 -0
  111. package/src/rate-limit/index.ts +181 -0
  112. package/src/runtime/ctx.ts +876 -0
  113. package/src/runtime/determinism.ts +75 -0
  114. package/src/runtime/errors.ts +58 -0
  115. package/src/runtime/executor.ts +442 -0
  116. package/src/runtime/journal.ts +80 -0
  117. package/src/testing/index.ts +796 -0
  118. package/src/trigger.ts +63 -0
  119. package/src/types.ts +80 -0
  120. package/src/workflow.ts +328 -0
@@ -0,0 +1,352 @@
1
+ // @voyant-travel/workflows/auth
2
+ //
3
+ // Paired HMAC signer + verifier for the `X-Voyant-Dispatch-Auth`
4
+ // header on `POST /__voyant/workflow-step`. Both sides share a
5
+ // symmetric secret — suitable for local dev and single-region
6
+ // deployments; asymmetric signing (control-plane issuer + tenant
7
+ // public-key) is a later upgrade that keeps the same header shape.
8
+ //
9
+ // Built on Web Crypto (`crypto.subtle`), so it works unchanged in
10
+ // Node 20+, Cloudflare Workers, Deno, Bun, and browsers.
11
+ //
12
+ // Usage on the orchestrator side:
13
+ //
14
+ // import { createHmacSigner } from "@voyant-travel/workflows/auth";
15
+ // const sign = await createHmacSigner(process.env.VOYANT_SIGNING_KEY!);
16
+ // createDispatchStepHandler(script, { dispatcher, sign });
17
+ //
18
+ // Usage on the tenant side:
19
+ //
20
+ // import { createHmacVerifier } from "@voyant-travel/workflows/auth";
21
+ // import { createStepHandler } from "@voyant-travel/workflows/handler";
22
+ // const verify = await createHmacVerifier(env.VOYANT_SIGNING_KEY);
23
+ // export default { fetch: createStepHandler({ verifyRequest: verify }) };
24
+ export const AUTH_HEADER = "x-voyant-dispatch-auth";
25
+ /**
26
+ * HMAC header carried on orchestrator → node-step-container dispatches
27
+ * (`POST /step`). Signed over the raw request body with the shared
28
+ * `VOYANT_WORKFLOW_STEP_AUTH_SECRET`. See `createCfContainerStepRunner`
29
+ * (signing side) and `apps/workflows-node-step-container` (verifying side).
30
+ */
31
+ export const STEP_AUTH_HEADER = "x-voyant-step-auth";
32
+ /**
33
+ * HMAC header returned by the node-step-container on successful `/step`
34
+ * responses. Signed over the raw JSON response body with the same
35
+ * `VOYANT_WORKFLOW_STEP_AUTH_SECRET` so the orchestrator can reject
36
+ * forged step journal entries before committing run state.
37
+ */
38
+ export const STEP_RESPONSE_AUTH_HEADER = "x-voyant-step-response-auth";
39
+ /** Parse a comma-separated token/origin list env var into trimmed, non-empty entries. */
40
+ export function parseTokenList(raw) {
41
+ return (raw ?? "")
42
+ .split(",")
43
+ .map((s) => s.trim())
44
+ .filter((s) => s.length > 0);
45
+ }
46
+ /**
47
+ * Returns a verifier that accepts `Authorization: Bearer <token>`
48
+ * where `<token>` matches any of the `validTokens` (case-sensitive,
49
+ * constant-time compared). Usable as the `verifyRequest` dep on
50
+ * `handleWorkerRequest` / `createStepHandler` for the public-facing
51
+ * surface of an orchestrator or tenant Worker.
52
+ *
53
+ * Intended for dev + single-tenant deployments. Production should
54
+ * issue per-tenant, short-lived tokens from a control plane.
55
+ */
56
+ export function createBearerVerifier(validTokens) {
57
+ if (validTokens.length === 0) {
58
+ throw new Error("createBearerVerifier: need at least one valid token");
59
+ }
60
+ return (req) => {
61
+ const header = req.headers.get("authorization");
62
+ if (!header)
63
+ throw new Error("missing Authorization header");
64
+ const match = /^Bearer (.+)$/.exec(header);
65
+ if (!match) {
66
+ throw new Error("Authorization header must use the Bearer scheme");
67
+ }
68
+ const presented = match[1];
69
+ for (const valid of validTokens) {
70
+ if (constantTimeEquals(presented, valid))
71
+ return;
72
+ }
73
+ throw new Error("bearer token does not match any configured value");
74
+ };
75
+ }
76
+ /**
77
+ * Constant-time string comparison. Does NOT early-return on length
78
+ * mismatch: the loop always runs over the longer input (out-of-range
79
+ * `charCodeAt` is NaN, which coerces to 0 under bitwise ops), and a
80
+ * length mismatch only sets a diff bit. This avoids leaking how many
81
+ * leading characters of a secret matched, or whether the length matched.
82
+ */
83
+ function constantTimeEquals(a, b) {
84
+ const length = Math.max(a.length, b.length, 1);
85
+ let diff = a.length === b.length ? 0 : 1;
86
+ for (let i = 0; i < length; i++) {
87
+ diff |= (a.charCodeAt(i) | 0) ^ (b.charCodeAt(i) | 0);
88
+ }
89
+ return diff === 0;
90
+ }
91
+ // ---- Fail-closed bearer auth resolution ----
92
+ /**
93
+ * Error thrown by verifiers produced in this module. Carries an HTTP
94
+ * `status` + machine-readable `code` so HTTP surfaces
95
+ * (`handleWorkerRequest`, the node dashboard server, step handlers)
96
+ * can map auth failures to the right response instead of a blanket 401.
97
+ */
98
+ export class RequestAuthError extends Error {
99
+ status;
100
+ code;
101
+ constructor(status, code, message) {
102
+ super(message);
103
+ this.name = "RequestAuthError";
104
+ this.status = status;
105
+ this.code = code;
106
+ }
107
+ }
108
+ const UNAUTHENTICATED_WARNING = "[voyant-workflows] AUTH DISABLED: no bearer tokens are configured and " +
109
+ "VOYANT_WORKFLOWS_ALLOW_UNAUTHENTICATED is set. Every caller can trigger, read, " +
110
+ "resume, and cancel workflow runs. This mode is for LOCAL DEVELOPMENT ONLY — " +
111
+ "configure VOYANT_API_TOKENS before deploying.";
112
+ /**
113
+ * Build a transport-agnostic bearer authorizer from a raw
114
+ * `Authorization` header value. Fail-closed semantics:
115
+ *
116
+ * - tokens configured → exact (constant-time) Bearer match or 401
117
+ * - no tokens + opt-out → always allowed (warns loudly once, at creation)
118
+ * - no tokens, no opt-out → always 503 `auth_not_configured`
119
+ */
120
+ export function createBearerAuthorizer(opts) {
121
+ const tokens = (opts.tokens ?? []).filter((t) => t.length > 0);
122
+ if (tokens.length === 0) {
123
+ if (opts.allowUnauthenticated) {
124
+ ;
125
+ (opts.warn ?? console.warn)(UNAUTHENTICATED_WARNING);
126
+ return () => ({ ok: true });
127
+ }
128
+ return () => ({
129
+ ok: false,
130
+ status: 503,
131
+ error: "auth_not_configured",
132
+ message: "no bearer tokens are configured for this workflows API; set VOYANT_API_TOKENS " +
133
+ "(or pass tokens explicitly), or opt out for local development with " +
134
+ "VOYANT_WORKFLOWS_ALLOW_UNAUTHENTICATED=1",
135
+ });
136
+ }
137
+ return (header) => {
138
+ if (!header) {
139
+ return {
140
+ ok: false,
141
+ status: 401,
142
+ error: "unauthorized",
143
+ message: "missing Authorization header",
144
+ };
145
+ }
146
+ const match = /^Bearer (.+)$/.exec(header);
147
+ if (!match) {
148
+ return {
149
+ ok: false,
150
+ status: 401,
151
+ error: "unauthorized",
152
+ message: "Authorization header must use the Bearer scheme",
153
+ };
154
+ }
155
+ const presented = match[1];
156
+ for (const valid of tokens) {
157
+ if (constantTimeEquals(presented, valid))
158
+ return { ok: true };
159
+ }
160
+ return {
161
+ ok: false,
162
+ status: 401,
163
+ error: "unauthorized",
164
+ message: "bearer token does not match any configured value",
165
+ };
166
+ };
167
+ }
168
+ /**
169
+ * Resolve a `verifyRequest` hook (the dep consumed by
170
+ * `handleWorkerRequest` / `createStepHandler`) with fail-closed
171
+ * defaults — the missing-token case yields a verifier that rejects
172
+ * every request with a 503 `auth_not_configured` `RequestAuthError`
173
+ * instead of `undefined` (which would skip auth entirely).
174
+ *
175
+ * Returns `undefined` (auth skipped) ONLY when no tokens are
176
+ * configured AND `allowUnauthenticated` is explicitly set.
177
+ */
178
+ export function resolveRequestVerifier(opts) {
179
+ const tokens = (opts.tokens ?? []).filter((t) => t.length > 0);
180
+ if (tokens.length === 0 && opts.allowUnauthenticated) {
181
+ ;
182
+ (opts.warn ?? console.warn)(UNAUTHENTICATED_WARNING);
183
+ return undefined;
184
+ }
185
+ const authorize = createBearerAuthorizer({ ...opts, allowUnauthenticated: false });
186
+ return (req) => {
187
+ const decision = authorize(req.headers.get("authorization"));
188
+ if (!decision.ok) {
189
+ throw new RequestAuthError(decision.status, decision.error, decision.message);
190
+ }
191
+ };
192
+ }
193
+ /** Returns a signer: `(body: string) => Promise<string>` (base64 HMAC-SHA256). */
194
+ export async function createHmacSigner(secret) {
195
+ const key = await importKey(secret, ["sign"]);
196
+ return async (body) => {
197
+ const sig = await crypto.subtle.sign("HMAC", key, encode(body));
198
+ return toBase64(sig);
199
+ };
200
+ }
201
+ /**
202
+ * Returns a verifier: `(req: Request) => Promise<void>`. Throws if:
203
+ * - the header is missing,
204
+ * - the signature is malformed,
205
+ * - the signature does not match the current body.
206
+ *
207
+ * The verifier consumes `req.body` via `req.text()`. Callers that
208
+ * need the body downstream should pre-clone: `req.clone()` before
209
+ * passing in.
210
+ */
211
+ export async function createHmacVerifier(secret) {
212
+ const key = await importKey(secret, ["verify"]);
213
+ return async (req) => {
214
+ const header = req.headers.get(AUTH_HEADER);
215
+ if (!header) {
216
+ throw new Error(`missing ${AUTH_HEADER} header`);
217
+ }
218
+ let sig;
219
+ try {
220
+ sig = fromBase64(header);
221
+ }
222
+ catch {
223
+ throw new Error(`malformed ${AUTH_HEADER} header (expected base64)`);
224
+ }
225
+ const body = await req.clone().text();
226
+ const ok = await crypto.subtle.verify("HMAC", key, sig, encode(body));
227
+ if (!ok) {
228
+ throw new Error(`${AUTH_HEADER} signature does not match request body`);
229
+ }
230
+ };
231
+ }
232
+ /**
233
+ * Returns a verifier over a raw body string + detached base64 HMAC
234
+ * signature (the value of `STEP_AUTH_HEADER`). Suitable for servers
235
+ * that have already buffered the request body (e.g. the node step
236
+ * container). `crypto.subtle.verify` is constant-time; malformed
237
+ * base64 or a missing signature simply yields `false`.
238
+ */
239
+ export async function createHmacBodyVerifier(secret) {
240
+ const key = await importKey(secret, ["verify"]);
241
+ return async (body, signatureBase64) => {
242
+ if (!signatureBase64)
243
+ return false;
244
+ let sig;
245
+ try {
246
+ sig = fromBase64(signatureBase64);
247
+ }
248
+ catch {
249
+ return false;
250
+ }
251
+ return crypto.subtle.verify("HMAC", key, sig, encode(body));
252
+ };
253
+ }
254
+ /**
255
+ * Default bundle source: Cloudflare R2's S3 endpoint
256
+ * (`<account>.r2.cloudflarestorage.com`), which is where deploy
257
+ * pipelines stage `container.mjs` and the orchestrator mints
258
+ * short-lived signed URLs. Anything else must be explicitly
259
+ * allowlisted via `allowedOrigins`.
260
+ */
261
+ const R2_HOST_SUFFIX = ".r2.cloudflarestorage.com";
262
+ /**
263
+ * Build an origin allowlist check for caller-supplied `bundle.url`
264
+ * values (the node step container dynamically `import()`s the fetched
265
+ * bytes, so an unrestricted URL is remote-code-execution-adjacent —
266
+ * the SHA-256 hash pin is supplied by the same caller and is not a
267
+ * security control on its own).
268
+ *
269
+ * - `allowedOrigins` set (e.g. from `VOYANT_BUNDLE_ALLOWED_ORIGINS`):
270
+ * the URL's origin must match one of the entries exactly.
271
+ * Invalid entries throw at creation time (misconfiguration should
272
+ * fail loudly, not silently widen).
273
+ * - unset/empty: only HTTPS URLs on `*.r2.cloudflarestorage.com`
274
+ * are allowed — the production bundle source.
275
+ */
276
+ export function createBundleUrlPolicy(opts) {
277
+ const entries = (opts?.allowedOrigins ?? []).filter((entry) => entry.length > 0);
278
+ const allowed = new Set();
279
+ for (const entry of entries) {
280
+ let parsed;
281
+ try {
282
+ parsed = new URL(entry);
283
+ }
284
+ catch {
285
+ throw new Error(`createBundleUrlPolicy: invalid origin in allowlist: "${entry}"`);
286
+ }
287
+ allowed.add(parsed.origin);
288
+ }
289
+ return (url) => {
290
+ let parsed;
291
+ try {
292
+ parsed = new URL(url);
293
+ }
294
+ catch {
295
+ return { ok: false, message: `bundle url is not a valid URL: "${url}"` };
296
+ }
297
+ if (allowed.size > 0) {
298
+ if (allowed.has(parsed.origin))
299
+ return { ok: true };
300
+ return {
301
+ ok: false,
302
+ message: `bundle url origin "${parsed.origin}" is not in the configured allowlist ` +
303
+ "(VOYANT_BUNDLE_ALLOWED_ORIGINS)",
304
+ };
305
+ }
306
+ if (parsed.protocol === "https:" && parsed.hostname.endsWith(R2_HOST_SUFFIX)) {
307
+ return { ok: true };
308
+ }
309
+ return {
310
+ ok: false,
311
+ message: `bundle url origin "${parsed.origin}" rejected: with no VOYANT_BUNDLE_ALLOWED_ORIGINS ` +
312
+ `configured, only https://*${R2_HOST_SUFFIX} bundle sources are allowed`,
313
+ };
314
+ };
315
+ }
316
+ // ---- Internals ----
317
+ async function importKey(secret, usages) {
318
+ if (secret.length === 0) {
319
+ throw new Error("HMAC secret must be a non-empty string");
320
+ }
321
+ return crypto.subtle.importKey("raw", encode(secret), { name: "HMAC", hash: "SHA-256" }, false, [
322
+ ...usages,
323
+ ]);
324
+ }
325
+ /**
326
+ * Encode to a freshly-allocated ArrayBuffer. TextEncoder's Uint8Array
327
+ * is typed as `Uint8Array<ArrayBufferLike>` under recent TS lib, which
328
+ * doesn't satisfy the `BufferSource` param of `subtle.sign/verify`.
329
+ * Copying into a new ArrayBuffer sidesteps the nominal mismatch.
330
+ */
331
+ function encode(s) {
332
+ const view = new TextEncoder().encode(s);
333
+ const buf = new ArrayBuffer(view.byteLength);
334
+ new Uint8Array(buf).set(view);
335
+ return buf;
336
+ }
337
+ function toBase64(buffer) {
338
+ // btoa is available in every modern runtime (Node 16+, Workers, browsers).
339
+ const bytes = new Uint8Array(buffer);
340
+ let bin = "";
341
+ for (let i = 0; i < bytes.length; i++)
342
+ bin += String.fromCharCode(bytes[i]);
343
+ return btoa(bin);
344
+ }
345
+ function fromBase64(s) {
346
+ const bin = atob(s);
347
+ const buf = new ArrayBuffer(bin.length);
348
+ const view = new Uint8Array(buf);
349
+ for (let i = 0; i < bin.length; i++)
350
+ view[i] = bin.charCodeAt(i);
351
+ return buf;
352
+ }
@@ -0,0 +1,119 @@
1
+ export interface Env {
2
+ [key: string]: Binding;
3
+ }
4
+ export type Binding = D1Database | R2Bucket | KVNamespace | Queue<unknown> | string;
5
+ export interface D1Database {
6
+ prepare(sql: string): D1PreparedStatement;
7
+ batch(statements: D1PreparedStatement[]): Promise<D1Result[]>;
8
+ exec(sql: string): Promise<D1ExecResult>;
9
+ }
10
+ export interface D1PreparedStatement {
11
+ bind(...values: unknown[]): D1PreparedStatement;
12
+ first<T = unknown>(column?: string): Promise<T | null>;
13
+ run(): Promise<D1Result>;
14
+ all<T = unknown>(): Promise<{
15
+ results: T[];
16
+ meta: D1Meta;
17
+ }>;
18
+ /** Per-step-invocation read cache. */
19
+ memoize(): D1PreparedStatement;
20
+ }
21
+ export interface D1Result {
22
+ success: boolean;
23
+ meta: D1Meta;
24
+ results?: unknown[];
25
+ }
26
+ export interface D1ExecResult {
27
+ count: number;
28
+ duration: number;
29
+ }
30
+ export interface D1Meta {
31
+ duration: number;
32
+ rows_read: number;
33
+ rows_written: number;
34
+ }
35
+ export interface R2Bucket {
36
+ get(key: string, opts?: R2GetOptions): Promise<R2Object | null>;
37
+ put(key: string, value: R2PutBody, opts?: R2PutOptions): Promise<R2Object>;
38
+ delete(keys: string | string[]): Promise<void>;
39
+ list(opts?: R2ListOptions): Promise<R2Objects>;
40
+ head(key: string): Promise<R2Object | null>;
41
+ }
42
+ export interface R2GetOptions {
43
+ range?: {
44
+ offset?: number;
45
+ length?: number;
46
+ };
47
+ onlyIf?: {
48
+ etagMatches?: string;
49
+ };
50
+ }
51
+ export interface R2PutOptions {
52
+ httpMetadata?: Record<string, string>;
53
+ customMetadata?: Record<string, string>;
54
+ }
55
+ export type R2PutBody = ReadableStream | ArrayBuffer | string;
56
+ export interface R2Object {
57
+ key: string;
58
+ size: number;
59
+ etag: string;
60
+ httpMetadata?: Record<string, string>;
61
+ customMetadata?: Record<string, string>;
62
+ body?: ReadableStream;
63
+ arrayBuffer(): Promise<ArrayBuffer>;
64
+ text(): Promise<string>;
65
+ json<T = unknown>(): Promise<T>;
66
+ }
67
+ export interface R2ListOptions {
68
+ prefix?: string;
69
+ cursor?: string;
70
+ limit?: number;
71
+ }
72
+ export interface R2Objects {
73
+ objects: R2Object[];
74
+ truncated: boolean;
75
+ cursor?: string;
76
+ }
77
+ export interface KVNamespace {
78
+ get<T = string>(key: string, opts?: KVGetOptions<T>): Promise<T | null>;
79
+ put(key: string, value: string | ArrayBuffer, opts?: KVPutOptions): Promise<void>;
80
+ delete(key: string): Promise<void>;
81
+ list(opts?: KVListOptions): Promise<KVList>;
82
+ }
83
+ export interface KVGetOptions<T> {
84
+ type?: T extends string ? "text" : "json" | "arrayBuffer" | "stream";
85
+ }
86
+ export interface KVPutOptions {
87
+ expiration?: number;
88
+ expirationTtl?: number;
89
+ metadata?: Record<string, unknown>;
90
+ }
91
+ export interface KVListOptions {
92
+ prefix?: string;
93
+ cursor?: string;
94
+ limit?: number;
95
+ }
96
+ export interface KVList {
97
+ keys: {
98
+ name: string;
99
+ expiration?: number;
100
+ metadata?: unknown;
101
+ }[];
102
+ list_complete: boolean;
103
+ cursor?: string;
104
+ }
105
+ export interface Queue<T> {
106
+ send(message: T, opts?: {
107
+ delaySeconds?: number;
108
+ }): Promise<void>;
109
+ sendBatch(messages: readonly T[]): Promise<void>;
110
+ }
111
+ /**
112
+ * The environment object tenant code reads bindings from.
113
+ *
114
+ * On the edge runtime, this is a pass-through to the tenant worker's
115
+ * `env` parameter (CF Workers). On the container runtime, the
116
+ * platform injects HTTP-based clients that mimic the shapes above.
117
+ */
118
+ export declare const env: Env;
119
+ //# sourceMappingURL=bindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ // @voyant-travel/workflows/bindings
2
+ //
3
+ // Runtime binding shim. Edge runtime passes through to native CF bindings;
4
+ // container runtime makes authenticated HTTPS calls to CF's per-binding APIs.
5
+ //
6
+ // Contract defined in docs/sdk-surface.md §9 and docs/design.md §5.2.
7
+ /**
8
+ * The environment object tenant code reads bindings from.
9
+ *
10
+ * On the edge runtime, this is a pass-through to the tenant worker's
11
+ * `env` parameter (CF Workers). On the container runtime, the
12
+ * platform injects HTTP-based clients that mimic the shapes above.
13
+ */
14
+ export const env = new Proxy({}, {
15
+ get(_, key) {
16
+ throw new Error(`@voyant-travel/workflows/bindings: env.${key} was accessed outside a workflow / step body. ` +
17
+ `Bindings are injected by the runtime — see docs/sdk-surface.md §9.`);
18
+ },
19
+ });
@@ -0,0 +1,135 @@
1
+ import type { WorkflowDriver } from "./driver.js";
2
+ import type { Duration, EnvironmentName, RunStatus } from "./types.js";
3
+ import type { WorkflowHandle } from "./workflow.js";
4
+ export interface WorkflowsClient {
5
+ trigger<TIn, TOut>(workflow: WorkflowHandle<TIn, TOut> | string, input: TIn, opts?: TriggerOptions): Promise<Run<TOut>>;
6
+ signal(runId: string, name: string, payload: unknown, opts?: {
7
+ nonce?: string;
8
+ }): Promise<void>;
9
+ completeToken(tokenId: string, payload: unknown): Promise<void>;
10
+ cancel(runId: string, opts?: {
11
+ compensate?: boolean;
12
+ reason?: string;
13
+ }): Promise<void>;
14
+ retry(runId: string, opts: {
15
+ mode: "re-trigger" | "resume";
16
+ }): Promise<Run>;
17
+ replay(runId: string, opts?: {
18
+ fromStepId?: string;
19
+ input?: unknown;
20
+ }): Promise<Run>;
21
+ get(runId: string): Promise<RunDetail>;
22
+ list(opts?: ListRunsOptions): Promise<{
23
+ runs: RunSummary[];
24
+ nextCursor?: string;
25
+ }>;
26
+ mintAccessToken(opts: MintAccessTokenOptions): Promise<PublicAccessToken>;
27
+ }
28
+ export interface TriggerOptions {
29
+ idempotencyKey?: string;
30
+ delay?: Duration | Date;
31
+ debounce?: {
32
+ key: string;
33
+ delay: Duration;
34
+ mode?: "leading" | "trailing";
35
+ };
36
+ ttl?: Duration;
37
+ tags?: string[];
38
+ priority?: number;
39
+ concurrencyKey?: string;
40
+ lockToVersion?: string;
41
+ environment?: EnvironmentName;
42
+ issuePublicAccessToken?: boolean;
43
+ }
44
+ export interface Run<TOut = unknown> {
45
+ id: string;
46
+ workflowId: string;
47
+ status: RunStatus;
48
+ startedAt: number;
49
+ accessToken?: string;
50
+ /** Phantom; used only for TypeScript inference. */
51
+ readonly __output?: TOut;
52
+ }
53
+ export interface RunSummary {
54
+ id: string;
55
+ workflowId: string;
56
+ status: RunStatus;
57
+ startedAt: number;
58
+ completedAt?: number;
59
+ tags: string[];
60
+ environment: EnvironmentName;
61
+ }
62
+ export interface RunDetail<TOut = unknown> extends RunSummary {
63
+ version: string;
64
+ input: unknown;
65
+ output?: TOut;
66
+ error?: unknown;
67
+ durationMs?: number;
68
+ }
69
+ export interface ListRunsOptions {
70
+ workflowId?: string;
71
+ status?: RunStatus | RunStatus[];
72
+ environment?: EnvironmentName;
73
+ tag?: string;
74
+ since?: Date | number;
75
+ until?: Date | number;
76
+ cursor?: string;
77
+ limit?: number;
78
+ }
79
+ export interface MintAccessTokenOptions {
80
+ target: {
81
+ kind: "run";
82
+ runId: string;
83
+ } | {
84
+ kind: "workflow";
85
+ workflowId: string;
86
+ } | {
87
+ kind: "tag";
88
+ tag: string;
89
+ };
90
+ scope: ("read" | "trigger" | "cancel")[];
91
+ ttl?: Duration;
92
+ }
93
+ export interface PublicAccessToken {
94
+ token: string;
95
+ exp: number;
96
+ }
97
+ export interface CloudWorkflowsClientEnv {
98
+ VOYANT_CLOUD_WORKFLOWS_URL?: string;
99
+ VOYANT_CLOUD_WORKFLOW_TRIGGER_TOKEN?: string;
100
+ VOYANT_CLOUD_APP_SLUG?: string;
101
+ VOYANT_CLOUD_ENVIRONMENT?: string;
102
+ }
103
+ export interface CloudWorkflowsClientOptions {
104
+ baseUrl?: string;
105
+ triggerToken?: string;
106
+ appSlug?: string;
107
+ environment?: EnvironmentName;
108
+ fetch?: typeof fetch;
109
+ env?: CloudWorkflowsClientEnv;
110
+ }
111
+ export interface CloudWorkflowDriverOptions extends CloudWorkflowsClientOptions {
112
+ /**
113
+ * Managed Cloud deployments should leave this disabled. Workflow releases
114
+ * are created by the deployment/control-plane path, not by the app runtime.
115
+ * The enabled mode exists only for explicitly wired adapters that own their
116
+ * release-registration boundary.
117
+ */
118
+ manifestRegistration?: "disabled" | "enabled";
119
+ }
120
+ /**
121
+ * Install the process-local `workflows` client implementation used by the
122
+ * root `@voyant-travel/workflows` singleton. Apps may call this during boot, or
123
+ * rely on deployment-injected Voyant Cloud environment variables.
124
+ */
125
+ export declare function configureWorkflowsClient(client: WorkflowsClient): void;
126
+ export declare function getConfiguredWorkflowsClient(): WorkflowsClient | undefined;
127
+ export declare const workflows: WorkflowsClient;
128
+ export declare function createCloudWorkflowsClient(options?: CloudWorkflowsClientOptions): WorkflowsClient;
129
+ /**
130
+ * Cloud-mode driver for framework event forwarding. It does not execute runs
131
+ * locally; it forwards triggers/events/manifests to the hosted runtime using
132
+ * the same deployment-scoped credentials as the client.
133
+ */
134
+ export declare function createCloudWorkflowDriver(options?: CloudWorkflowDriverOptions): WorkflowDriver;
135
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}