@vite-hub/workflow 0.0.3 → 0.1.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 (47) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +187 -56
  3. package/dist/{_app-DgwN4ulW.d.ts → app-BojnC_yf.d.ts} +1 -4
  4. package/dist/{app-BZpq2cwC.js → app-CzPoP84f.js} +2 -1
  5. package/dist/client-DsGM3M4U.js +389 -0
  6. package/dist/cloudflare-env-BNrYo29x.js +113 -0
  7. package/dist/cloudflare-nF4abPd4.js +59 -0
  8. package/dist/cloudflare-shared-CaxrMD1A.d.ts +1 -0
  9. package/dist/{cloudflare-vite-B0zel2Do.js → cloudflare-vite-B3IabBsv.js} +18 -10
  10. package/dist/{config-BDqB6I4E.js → config-IJMb0eeZ.js} +39 -25
  11. package/dist/error-diagnostics-A_8Kp-48.js +116 -0
  12. package/dist/error-diagnostics-pwNFvAHP.js +67 -0
  13. package/dist/index.d.ts +24 -20
  14. package/dist/index.js +25 -334
  15. package/dist/inspect-B72iFyj-.js +70 -0
  16. package/dist/operations-B_rYG71W.js +230 -0
  17. package/dist/operations-tNUdj3G4.d.ts +212 -0
  18. package/dist/operations.d.ts +37 -0
  19. package/dist/operations.js +887 -0
  20. package/dist/out-CsaJxg8m.js +21755 -0
  21. package/dist/{provider-operation-CWIV4k42.js → provider-operation-CW2cYfVy.js} +13 -10
  22. package/dist/rolldown-runtime-CMFfr-1z.js +26 -0
  23. package/dist/runtime/cloudflare-runner.d.ts +8 -14
  24. package/dist/runtime/cloudflare-runner.js +77 -14
  25. package/dist/runtime/cloudflare-shared.d.ts +1 -0
  26. package/dist/runtime/cloudflare-shared.js +1 -1
  27. package/dist/runtime/cloudflare-vite.d.ts +8 -9
  28. package/dist/runtime/cloudflare-vite.js +2 -2
  29. package/dist/runtime/execute.d.ts +8 -7
  30. package/dist/runtime/execute.js +28 -5
  31. package/dist/runtime/openworkflow-worker.d.ts +6 -8
  32. package/dist/runtime/openworkflow-worker.js +43 -6
  33. package/dist/runtime/openworkflow.d.ts +8 -10
  34. package/dist/runtime/openworkflow.js +50 -32
  35. package/dist/runtime/state.d.ts +20 -21
  36. package/dist/runtime/state.js +90 -20
  37. package/dist/runtime/vercel-vite.d.ts +10 -11
  38. package/dist/runtime/vercel-vite.js +11 -8
  39. package/dist/runtime-type-DBCvIh5x.js +7 -0
  40. package/dist/{types-BUlYBZwH.d.ts → types-D82WmfZa.d.ts} +35 -18
  41. package/dist/{vercel-D2_J5D_Y.js → vercel-D-ZNtB_u.js} +59 -26
  42. package/dist/vite.d.ts +365 -6
  43. package/dist/vite.js +4667 -910
  44. package/package.json +78 -28
  45. package/dist/cloudflare-Cds1VIWa.js +0 -42
  46. package/dist/cloudflare-env-mFp2Uj6Z.js +0 -53
  47. package/dist/cloudflare-shared-BVVgDSdq.d.ts +0 -1
package/dist/index.js CHANGED
@@ -1,354 +1,45 @@
1
- import { t as normalizeWorkflowOptions } from "./config-BDqB6I4E.js";
2
- import { a as encodeNameHex, i as getCloudflareWorkflowName, n as getCloudflareWorkflowBindingName, r as getCloudflareWorkflowClassName } from "./cloudflare-Cds1VIWa.js";
3
- import { i as createWorkflowError, n as runWorkflowProviderOperation, r as safeWorkflowName } from "./provider-operation-CWIV4k42.js";
4
- import { n as getCloudflareEnv, r as resolveWaitUntil } from "./cloudflare-env-mFp2Uj6Z.js";
5
- import { runWorkflowHandler } from "./runtime/execute.js";
6
- import { getOpenWorkflowRun, runOpenWorkflow } from "./runtime/openworkflow.js";
7
- import { getWorkflowRunState, getWorkflowRuntimeConfig, getWorkflowRuntimeEvent, loadWorkflowDefinition, registerInlineWorkflowDefinition, runWithWorkflowRuntimeEvent, setWorkflowRun } from "./runtime/state.js";
8
- import { a as startVercelWorkflow, n as inspectVercelWorkflowRun, r as resumeVercelWorkflowSignal, t as cancelVercelWorkflow } from "./vercel-D2_J5D_Y.js";
9
- import { t as createWorkflowCloudflareWorker } from "./cloudflare-vite-B0zel2Do.js";
1
+ import { t as normalizeWorkflowOptions } from "./config-IJMb0eeZ.js";
2
+ import { t as workflowErrorDiagnostics } from "./error-diagnostics-pwNFvAHP.js";
3
+ import { i as getCloudflareWorkflowName, n as getCloudflareWorkflowBindingName, r as getCloudflareWorkflowClassName } from "./cloudflare-nF4abPd4.js";
4
+ import { a as resumeWorkflowSignal, i as getWorkflowRun, n as createWorkflow, o as runWorkflow, r as deferWorkflow, s as getVercelWorkflowName, t as cancelWorkflow } from "./client-DsGM3M4U.js";
5
+ import { t as createWorkflowCloudflareWorker } from "./cloudflare-vite-B3IabBsv.js";
10
6
  //#region src/definition.ts
11
7
  function defineWorkflow(handler, options) {
12
- if (typeof handler !== "function") throw new TypeError("`defineWorkflow()` requires a workflow handler.");
13
- if (typeof options !== "undefined" && (!options || typeof options !== "object" || Array.isArray(options))) throw new TypeError("`defineWorkflow()` options must be a plain object.");
14
- if (options?.native !== void 0 && typeof options.native !== "function") throw new TypeError("`defineWorkflow()` native entry must be a workflow handler.");
8
+ if (typeof handler !== "function") throw workflowErrorDiagnostics.WORKFLOW_C0014({ message: "`defineWorkflow()` requires a workflow handler." });
9
+ if (typeof options !== "undefined" && (!options || typeof options !== "object" || Array.isArray(options))) throw workflowErrorDiagnostics.WORKFLOW_C0015({ message: "`defineWorkflow()` options must be a plain object." });
10
+ if (options?.native !== void 0 && typeof options.native !== "function") throw workflowErrorDiagnostics.WORKFLOW_C0016({ message: "`defineWorkflow()` native entry must be a workflow handler." });
15
11
  return {
16
12
  handler,
17
13
  options
18
14
  };
19
15
  }
20
16
  //#endregion
21
- //#region src/integrations/vercel.ts
22
- function getVercelWorkflowName(name) {
23
- return `workflow--${encodeNameHex(name)}`;
24
- }
25
- //#endregion
26
- //#region ../internal/src/runtime/random.ts
27
- function randomId(prefix) {
28
- const body = `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
29
- return prefix ? `${prefix}_${body}` : body;
30
- }
31
- //#endregion
32
- //#region src/runtime/adapters.ts
33
- function unsupportedOperation(provider, operation) {
34
- throw createWorkflowError({
35
- code: "WORKFLOW_OPERATION_UNSUPPORTED",
36
- details: {
37
- operation,
38
- provider
39
- }
40
- });
41
- }
42
- function resolveCloudflareBinding(event, binding, name) {
43
- const bindingName = binding || getCloudflareWorkflowBindingName(name);
44
- return getCloudflareEnv(event)?.[bindingName];
45
- }
46
- const cloudflareStatusMap = {
47
- cancelled: "cancelled",
48
- complete: "completed",
49
- completed: "completed",
50
- errored: "failed",
51
- failed: "failed",
52
- queued: "queued",
53
- running: "running",
54
- success: "completed",
55
- terminated: "failed"
56
- };
57
- function normalizeCloudflareStatus(status) {
58
- const value = typeof status === "object" && status ? status.status : status;
59
- return cloudflareStatusMap[String(value || "").toLowerCase()] || "unknown";
60
- }
61
- function createCloudflareAdapter(config) {
62
- return {
63
- cancel: () => unsupportedOperation("cloudflare", "cancellation"),
64
- async get({ event, id, name }) {
65
- const binding = resolveCloudflareBinding(event, config.binding, name);
66
- if (binding) {
67
- const instance = await runWorkflowProviderOperation("cloudflare", "get", () => binding.get(id));
68
- const metadata = await runWorkflowProviderOperation("cloudflare", "status", () => instance.status());
69
- return {
70
- id,
71
- metadata,
72
- provider: "cloudflare",
73
- status: normalizeCloudflareStatus(metadata)
74
- };
75
- }
76
- return await inlineAdapter(config).get({
77
- event,
78
- id,
79
- name
80
- });
81
- },
82
- async run({ definition, event, id, name, options, payload }) {
83
- const binding = resolveCloudflareBinding(event, config.binding, name);
84
- if (binding) {
85
- const start = runWorkflowProviderOperation("cloudflare", "create", () => binding.create({
86
- id,
87
- params: payload
88
- }));
89
- const waitUntil = options.deferred ? resolveWaitUntil(event) : void 0;
90
- if (waitUntil) waitUntil(start);
91
- const instance = await start;
92
- return {
93
- id: instance.id,
94
- metadata: await runWorkflowProviderOperation("cloudflare", "status", () => instance.status()),
95
- payload,
96
- provider: "cloudflare",
97
- status: "queued"
98
- };
99
- }
100
- return await inlineAdapter(config).run({
101
- definition,
102
- event,
103
- id,
104
- name,
105
- options,
106
- payload
107
- });
108
- },
109
- resume: () => unsupportedOperation("cloudflare", "signals")
110
- };
111
- }
112
- function createOpenWorkflowAdapter(config) {
113
- return {
114
- cancel: () => unsupportedOperation("openworkflow", "cancellation"),
115
- get: async ({ id, name }) => await getOpenWorkflowRun(config, name, id),
116
- resume: () => unsupportedOperation("openworkflow", "signals"),
117
- run: async ({ definition, name, options, payload }) => await runOpenWorkflow(config, name, payload, definition, options)
118
- };
119
- }
120
- function inlineAdapter(config) {
121
- return {
122
- cancel: () => unsupportedOperation(config.provider, "cancellation"),
123
- async get({ id, name }) {
124
- const run = getWorkflowRunState(name, id);
125
- if (run) {
126
- if (run.status === "running") return {
127
- id,
128
- provider: config.provider,
129
- status: "running"
130
- };
131
- return {
132
- id,
133
- metadata: run.error,
134
- provider: config.provider,
135
- result: run.result,
136
- status: run.status
137
- };
138
- }
139
- return {
140
- id,
141
- provider: config.provider,
142
- status: "unknown"
143
- };
144
- },
145
- async run({ definition, event, id, name, payload }) {
146
- const runState = setWorkflowRun(name, id, Promise.resolve().then(() => runWorkflowHandler({
147
- id,
148
- name,
149
- payload,
150
- provider: config.provider
151
- }, definition)).then((result) => ({
152
- result,
153
- status: "completed"
154
- })).catch((error) => ({
155
- error,
156
- status: "failed"
157
- })));
158
- const waitUntil = resolveWaitUntil(event);
159
- if (waitUntil) waitUntil(runState.promise);
160
- return {
161
- id,
162
- metadata: config.provider === "vercel" ? {
163
- mode: "inline",
164
- workflow: getVercelWorkflowName(name)
165
- } : void 0,
166
- payload,
167
- provider: config.provider,
168
- status: "queued"
169
- };
170
- },
171
- resume: () => unsupportedOperation(config.provider, "signals")
172
- };
173
- }
174
- function createVercelAdapter(config) {
175
- const fallback = inlineAdapter(config);
176
- return {
177
- async cancel({ id, name }) {
178
- const definition = await loadWorkflowDefinition(name);
179
- if (!definition?.options?.native) return await fallback.cancel({
180
- event: void 0,
181
- id,
182
- name
183
- });
184
- return await cancelVercelWorkflow(name, definition, id);
185
- },
186
- async get({ id, name }) {
187
- const definition = await loadWorkflowDefinition(name);
188
- return definition?.options?.native ? await inspectVercelWorkflowRun(name, definition, id) : await fallback.get({
189
- event: void 0,
190
- id,
191
- name
192
- });
193
- },
194
- resume: async (token, payload) => await resumeVercelWorkflowSignal(token, payload),
195
- async run({ definition, event, id, name, options, payload }) {
196
- if (!definition.options?.native) return await fallback.run({
197
- definition,
198
- event,
199
- id,
200
- name,
201
- options,
202
- payload
203
- });
204
- if (options.id) throw createWorkflowError({
205
- code: "WORKFLOW_RUN_ID_UNSUPPORTED",
206
- details: {
207
- ...safeWorkflowName(name) ? { name } : {},
208
- provider: "vercel"
209
- }
210
- });
211
- return await startVercelWorkflow(name, definition, payload);
212
- }
213
- };
214
- }
215
- function getWorkflowRuntimeAdapter(config) {
216
- if (config.provider === "cloudflare") return createCloudflareAdapter(config);
217
- if (config.provider === "openworkflow") return createOpenWorkflowAdapter(config);
218
- return createVercelAdapter(config);
219
- }
220
- //#endregion
221
- //#region src/runtime/client.ts
222
- function getActiveWorkflowConfig() {
223
- const config = getWorkflowRuntimeConfig();
224
- if (config === false) return false;
225
- return config || normalizeWorkflowOptions(void 0, { hosting: "vercel" });
226
- }
227
- async function loadRequiredWorkflowDefinition(name) {
228
- const definition = await loadWorkflowDefinition(name);
229
- if (!definition) throw createWorkflowError({
230
- code: "WORKFLOW_DEFINITION_NOT_FOUND",
231
- details: safeWorkflowName(name) ? { name } : void 0
232
- });
233
- return definition;
234
- }
235
- function normalizeWorkflowRunIdValue(value) {
236
- if (value === void 0) return null;
237
- if (value === null || typeof value !== "object") return value;
238
- if (Array.isArray(value)) return value.map((item) => normalizeWorkflowRunIdValue(item));
239
- const record = value;
240
- return Object.fromEntries(Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, normalizeWorkflowRunIdValue(record[key])]));
241
- }
242
- async function sha256Hex(value) {
243
- const data = new TextEncoder().encode(value);
244
- const digest = await crypto.subtle.digest("SHA-256", data);
245
- return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
246
- }
247
- async function createStableWorkflowRunId(name, value) {
248
- const hash = await sha256Hex(`${name}:${JSON.stringify(normalizeWorkflowRunIdValue(value))}`);
249
- return `${name.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "workflow"}-${hash.slice(0, 32)}`;
250
- }
251
- async function resolveWorkflowStartOptions(name, payload, createOptions, startOptions) {
252
- if (startOptions.id || !createOptions?.id) return startOptions;
253
- return {
254
- ...startOptions,
255
- id: await createStableWorkflowRunId(name, await createOptions.id({
256
- name,
257
- payload
258
- }))
259
- };
260
- }
261
- function createWorkflow(nameOrOptions, handlerOrOptions, options) {
262
- if (typeof nameOrOptions === "object" && nameOrOptions !== null) {
263
- const createOptions = nameOrOptions;
264
- const { handler, name } = createOptions;
265
- if (!name || typeof name !== "string") throw new TypeError("`createWorkflow()` requires a workflow name.");
266
- if (typeof handler !== "function") throw new TypeError("`createWorkflow()` requires a workflow handler.");
267
- registerInlineWorkflowDefinition(name, { handler });
268
- return {
269
- cancel: (id) => cancelWorkflow(name, id),
270
- name,
271
- defer: async (payload, options = {}) => deferWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options)),
272
- getRun: (id) => getWorkflowRun(name, id),
273
- run: async (payload, options = {}) => runWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options))
274
- };
275
- }
276
- const name = nameOrOptions;
277
- if (!name || typeof name !== "string") throw new TypeError("`createWorkflow()` requires a workflow name.");
278
- const handler = typeof handlerOrOptions === "function" ? handlerOrOptions : typeof handlerOrOptions === "object" && handlerOrOptions !== null ? handlerOrOptions.handler : void 0;
279
- const createOptions = typeof handlerOrOptions === "function" ? options : handlerOrOptions;
280
- if (handler !== void 0) {
281
- if (typeof handler !== "function") throw new TypeError("`createWorkflow()` requires a workflow handler.");
282
- registerInlineWorkflowDefinition(name, { handler });
283
- } else if (handlerOrOptions !== void 0 && (typeof handlerOrOptions !== "object" || handlerOrOptions === null)) throw new TypeError("`createWorkflow()` options must be an object.");
284
- return {
285
- cancel: (id) => cancelWorkflow(name, id),
286
- name,
287
- defer: async (payload, options = {}) => deferWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options)),
288
- getRun: (id) => getWorkflowRun(name, id),
289
- run: async (payload, options = {}) => runWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options))
290
- };
291
- }
292
- async function runWorkflow(name, payload, options = {}) {
293
- const config = getActiveWorkflowConfig();
294
- if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
295
- const id = options.id || randomId("wrun");
296
- const definition = await loadRequiredWorkflowDefinition(name);
297
- return await getWorkflowRuntimeAdapter(config).run({
298
- definition,
299
- event: getWorkflowRuntimeEvent(),
300
- id,
301
- name,
302
- options,
303
- payload
304
- });
305
- }
306
- async function getWorkflowRun(name, id) {
307
- const config = getActiveWorkflowConfig();
308
- if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
309
- return await getWorkflowRuntimeAdapter(config).get({
310
- event: getWorkflowRuntimeEvent(),
311
- id,
312
- name
313
- });
314
- }
315
- async function cancelWorkflow(name, id) {
316
- const config = getActiveWorkflowConfig();
317
- if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
318
- await loadRequiredWorkflowDefinition(name);
319
- return await getWorkflowRuntimeAdapter(config).cancel({
320
- event: getWorkflowRuntimeEvent(),
321
- id,
322
- name
323
- });
324
- }
325
- async function resumeWorkflowSignal(token, payload) {
326
- if (!token || typeof token !== "string") throw new TypeError("`resumeWorkflowSignal()` requires an opaque signal token.");
327
- const config = getActiveWorkflowConfig();
328
- if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
329
- return await getWorkflowRuntimeAdapter(config).resume(token, payload);
330
- }
331
- function deferWorkflow(name, payload, options = {}) {
332
- return runWithWorkflowRuntimeEvent(getWorkflowRuntimeEvent(), () => runWorkflow(name, payload, {
333
- ...options,
334
- deferred: true
335
- }));
336
- }
337
- //#endregion
338
17
  //#region src/runtime/payload.ts
339
18
  async function readRequestPayload(request) {
340
- if ((request.headers.get("content-type") || "").includes("application/json")) return await request.json();
19
+ if (request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() === "application/json") return await request.json();
341
20
  return await request.text();
342
21
  }
343
22
  async function validatePayload(payload, schema) {
344
23
  if (typeof schema === "function") return await schema(payload);
345
- if ("safeParse" in schema && typeof schema.safeParse === "function") {
24
+ if (hasSchemaMethod(schema, "safeParse") && typeof schema.safeParse === "function") {
346
25
  const result = schema.safeParse(payload);
347
- if (!result.success) throw result.error || /* @__PURE__ */ new TypeError("Invalid workflow payload.");
26
+ if (!result.success) throw result.error || workflowErrorDiagnostics.WORKFLOW_R0021({ message: "Invalid workflow payload." });
348
27
  return result.data;
349
28
  }
350
- if ("parse" in schema && typeof schema.parse === "function") return schema.parse(payload);
351
- throw new TypeError("Invalid workflow payload schema.");
29
+ if (hasSchemaMethod(schema, "parse") && typeof schema.parse === "function") return schema.parse(payload);
30
+ throw workflowErrorDiagnostics.WORKFLOW_R0022({ message: "Invalid workflow payload schema." });
31
+ }
32
+ function hasSchemaMethod(value, key) {
33
+ if (Object.hasOwn(value, key)) return true;
34
+ let prototype = Object.getPrototypeOf(value);
35
+ while (prototype !== null) {
36
+ if (Object.hasOwn(prototype, key)) {
37
+ const constructor = Object.hasOwn(prototype, "constructor") ? prototype.constructor : void 0;
38
+ return typeof constructor === "function" && constructor.prototype === prototype && Function.prototype.toString.call(constructor) !== Function.prototype.toString.call(Object);
39
+ }
40
+ prototype = Object.getPrototypeOf(prototype);
41
+ }
42
+ return false;
352
43
  }
353
44
  async function readValidatedPayload(request, schema) {
354
45
  return await validatePayload(await readRequestPayload(request), schema);
@@ -0,0 +1,70 @@
1
+ import { relative } from "pathe";
2
+ //#region ../internal/src/inspect.ts
3
+ function relativeDefinitionFile(projectRoot, file) {
4
+ return relative(projectRoot, file).replaceAll("\\", "/");
5
+ }
6
+ const redactedInspectionValue = "[redacted]";
7
+ const secretKeyPattern = /secret|token|passw(?:or)?d|credential|api[-_\s]?key|private[-_\s]?key|authorization|cookie|signature|dsn|connection[-_\s]?string/i;
8
+ const secretValuePattern = /^(?:[a-z][a-z0-9+.-]*:\/\/[^/\s?#]*@|bearer\s)/i;
9
+ /** Whether an inspection field names a credential, regardless of its value. */
10
+ function isSecretInspectionKey(key) {
11
+ return secretKeyPattern.test(key);
12
+ }
13
+ const embeddedUrlCredentialPattern = /\b([a-z][a-z0-9+.-]*:\/\/)[^/\s?#]*@/gi;
14
+ const embeddedCookiePattern = /\b([\w-]*cookie[\w-]*["']?\s*[:=]\s*)(?:"(?:\\[^\r\n]|[^"\\\r\n])*"(?:\s*;\s*[\w.-]+\s*=[^;\r\n]*)*|'(?:\\[^\r\n]|[^'\\\r\n])*'(?:\s*;\s*[\w.-]+\s*=[^;\r\n]*)*|[^\r\n]+?(?=\s*(?:;\s*[^;=\r\n/]+\s*(?:\r?\n|$)|&|\r?\n|$)))/gi;
15
+ const embeddedBearerPattern = /\bbearer\s+[^\s,;]+/gi;
16
+ const embeddedAuthorizationPattern = new RegExp(String.raw`\b([\w-]*authorization[\w-]*["']?\s*[:=]\s*)(?!\[redacted\](?=$|[\s,;}&]))(?:"(?:\\[^\r\n]|[^"\\\r\n])*"|'(?:\\[^\r\n]|[^'\\\r\n])*'|[^\r\n]+?(?=\s*(?:[,;])?\s*(?:${secretKeyPattern.source})[\w-]*\s*[:=]|\s+rejected\b|$))`, "gi");
17
+ const embeddedSecretAssignmentPattern = new RegExp(String.raw`\b([\w-]*(?:${secretKeyPattern.source})[\w-]*["']?\s*[:=]\s*)(?!\[redacted\](?=$|[\s,;}&]))(?:"(?:\\[^\r\n]|[^"\\\r\n])*"|'(?:\\[^\r\n]|[^'\\\r\n])*'|[^\s,;&#&]+)`, "gi");
18
+ /**
19
+ * Removes credentials inside free text, for example an error message. URL credentials, bearer tokens, and
20
+ * `name=value` pairs with a secret name are replaced with `[redacted]`.
21
+ */
22
+ function redactInspectionText(value) {
23
+ return value.replace(embeddedUrlCredentialPattern, `$1${redactedInspectionValue}@`).replace(embeddedAuthorizationPattern, `$1${redactedInspectionValue}`).replace(embeddedCookiePattern, `$1${redactedInspectionValue}`).replace(embeddedBearerPattern, `Bearer ${redactedInspectionValue}`).replace(embeddedSecretAssignmentPattern, `$1${redactedInspectionValue}`);
24
+ }
25
+ /**
26
+ * Removes values that can carry credentials before inspection output leaves the process.
27
+ * Keys that name secrets, plaintext Worker `vars`, and URLs with embedded credentials are redacted.
28
+ */
29
+ function redactInspectionValue(value, key) {
30
+ const seen = /* @__PURE__ */ new WeakSet();
31
+ let remaining = 1e3;
32
+ function visit(entry, entryKey, depth = 0) {
33
+ if (entryKey && isSecretInspectionKey(entryKey)) return redactedInspectionValue;
34
+ if (--remaining < 0 || depth > 10) return "[truncated]";
35
+ if (typeof entry === "string") {
36
+ const text = entry.slice(0, 1e4);
37
+ return secretValuePattern.test(text) ? redactedInspectionValue : redactInspectionText(text);
38
+ }
39
+ if (typeof entry === "bigint") return entry.toString();
40
+ if (typeof entry === "number") return Number.isFinite(entry) ? entry : String(entry);
41
+ if (entry === null || typeof entry === "boolean") return entry;
42
+ if (typeof entry !== "object") return entry === void 0 ? null : "[unsupported]";
43
+ if (seen.has(entry)) return "[circular]";
44
+ seen.add(entry);
45
+ try {
46
+ let dateTime;
47
+ try {
48
+ dateTime = Date.prototype.getTime.call(entry);
49
+ } catch {}
50
+ if (dateTime !== void 0) return Number.isNaN(dateTime) ? "Invalid Date" : Date.prototype.toISOString.call(entry);
51
+ if (Array.isArray(entry)) return entry.slice(0, 100).map((item) => visit(item, void 0, depth + 1));
52
+ let setValues;
53
+ try {
54
+ setValues = [...Set.prototype.values.call(entry)];
55
+ } catch {}
56
+ if (setValues) return setValues.slice(0, 100).map((item) => visit(item, void 0, depth + 1));
57
+ let mapEntries;
58
+ try {
59
+ mapEntries = [...Map.prototype.entries.call(entry)];
60
+ } catch {}
61
+ const entries = mapEntries ? mapEntries.map(([name, item]) => [String(name), item]) : Object.entries(entry);
62
+ return Object.fromEntries(entries.slice(0, 100).map(([name, item]) => [name, name === "vars" && item && typeof item === "object" && !Array.isArray(item) ? Object.fromEntries(Object.keys(item).slice(0, 100).map((variable) => [variable, redactedInspectionValue])) : visit(item, name, depth + 1)]));
63
+ } finally {
64
+ seen.delete(entry);
65
+ }
66
+ }
67
+ return visit(value, key);
68
+ }
69
+ //#endregion
70
+ export { redactInspectionValue as n, relativeDefinitionFile as r, redactInspectionText as t };
@@ -0,0 +1,230 @@
1
+ import { a as resumeWorkflowSignal, i as getWorkflowRun, o as runWorkflow, t as cancelWorkflow } from "./client-DsGM3M4U.js";
2
+ import { getInlineWorkflowDefinitions, getWorkflowRuntimeConfig, getWorkflowRuntimeRegistry } from "./runtime/state.js";
3
+ import { n as redactInspectionValue, t as redactInspectionText } from "./inspect-B72iFyj-.js";
4
+ //#region src/results.ts
5
+ const inlineRunNote = "Runs the Workflow inline in the Nitro runtime, as the app does in development. Inline runs are not durable and have no retries.";
6
+ function unsupported(note) {
7
+ return {
8
+ note,
9
+ supported: false
10
+ };
11
+ }
12
+ /**
13
+ * Operations that each provider supports. A supported operation can still fail when the runtime decides, for example
14
+ * cancel on an inline Vercel run.
15
+ */
16
+ function resolveWorkflowOperationSupport(provider) {
17
+ if (provider === "cloudflare") return {
18
+ cancel: unsupported("Cloudflare Workflows do not support cancellation through ViteHub."),
19
+ get: {
20
+ note: "Reads the run from the Cloudflare Workflow binding when the runtime has one.",
21
+ supported: true
22
+ },
23
+ resume: unsupported("Cloudflare Workflows do not support ViteHub signals."),
24
+ start: {
25
+ note: `Uses the Cloudflare Workflow binding when the runtime has one. Otherwise: ${inlineRunNote}`,
26
+ supported: true
27
+ }
28
+ };
29
+ if (provider === "openworkflow") return {
30
+ cancel: unsupported("OpenWorkflow does not support cancellation through ViteHub."),
31
+ get: {
32
+ note: "Reads the run from OpenWorkflow storage.",
33
+ supported: true
34
+ },
35
+ resume: unsupported("OpenWorkflow does not support ViteHub signals."),
36
+ start: {
37
+ note: "Enqueues the run in OpenWorkflow storage. The run stays queued until an OpenWorkflow worker processes the same storage.",
38
+ supported: true
39
+ }
40
+ };
41
+ return {
42
+ cancel: {
43
+ note: "Only native Vercel Workflow runs can be cancelled. Inline runs return an unsupported error.",
44
+ supported: true
45
+ },
46
+ get: {
47
+ note: "Reads inline runs, which expire 5 minutes after they finish. Native Vercel Workflow runs need the Workflow DevKit runtime.",
48
+ supported: true
49
+ },
50
+ resume: {
51
+ note: "Signals need a native Vercel Workflow run and the Workflow DevKit runtime.",
52
+ supported: true
53
+ },
54
+ start: {
55
+ note: `${inlineRunNote} Native Vercel Workflow Definitions need the Workflow DevKit runtime.`,
56
+ supported: true
57
+ }
58
+ };
59
+ }
60
+ //#endregion
61
+ //#region src/runtime/operations.ts
62
+ const maxRememberedRuns = 1024;
63
+ /** A failure of a Workflow operation, with the status and code that every surface reports. */
64
+ var WorkflowOperationError = class extends Error {
65
+ code;
66
+ fix;
67
+ status;
68
+ constructor(message, status, code, fix) {
69
+ super(message);
70
+ this.name = "WorkflowOperationError";
71
+ this.code = code;
72
+ this.status = status;
73
+ if (fix) this.fix = fix;
74
+ }
75
+ };
76
+ function isRecord(value) {
77
+ return !!value && typeof value === "object" && !Array.isArray(value);
78
+ }
79
+ function isResponse(value) {
80
+ if (value instanceof Response) return true;
81
+ const statusGetter = Object.getOwnPropertyDescriptor(Response.prototype, "status")?.get;
82
+ if (!statusGetter) return false;
83
+ try {
84
+ statusGetter.call(value);
85
+ return true;
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+ function jsonReplacer(_key, value) {
91
+ if (typeof value === "bigint") return value.toString();
92
+ if (value instanceof Error) return serializeError(value);
93
+ if (isResponse(value)) return { response: {
94
+ status: value.status,
95
+ statusText: value.statusText
96
+ } };
97
+ return value;
98
+ }
99
+ function toJsonValue(value) {
100
+ if (value === void 0) return void 0;
101
+ try {
102
+ const text = JSON.stringify(value, jsonReplacer);
103
+ return text === void 0 ? void 0 : redactInspectionValue(JSON.parse(text));
104
+ } catch {
105
+ return "[unserializable]";
106
+ }
107
+ }
108
+ function errorCode(error) {
109
+ if (!error || typeof error !== "object") return;
110
+ const code = Reflect.get(error, "code");
111
+ return typeof code === "string" ? code : void 0;
112
+ }
113
+ function serializeError(error) {
114
+ const code = errorCode(error);
115
+ return {
116
+ ...code ? { code } : {},
117
+ message: redactInspectionText(error.message),
118
+ ...error.name && error.name !== "Error" ? { name: error.name } : {}
119
+ };
120
+ }
121
+ function toIsoDate(value) {
122
+ if (value instanceof Date) return Number.isNaN(value.getTime()) ? void 0 : value.toISOString();
123
+ return typeof value === "string" ? value : void 0;
124
+ }
125
+ function isErrorLike(value) {
126
+ return value instanceof Error || isRecord(value) && typeof value.message === "string";
127
+ }
128
+ async function readResult(result) {
129
+ if (!isResponse(result)) return result;
130
+ const text = await result.clone().text();
131
+ if (!text) return void 0;
132
+ try {
133
+ return JSON.parse(text);
134
+ } catch {
135
+ return text;
136
+ }
137
+ }
138
+ /**
139
+ * Converts a runtime Workflow run to JSON data. The view omits the start
140
+ * payload and redacts credentials in the metadata, result, and error message.
141
+ */
142
+ async function toWorkflowRunView(run, workflow) {
143
+ const createdAt = toIsoDate(run.createdAt);
144
+ const startedAt = toIsoDate(run.startedAt);
145
+ const completedAt = toIsoDate(run.completedAt);
146
+ const error = run.status === "failed" && isErrorLike(run.metadata) ? serializeError(run.metadata) : void 0;
147
+ const metadata = error ? void 0 : toJsonValue(run.metadata);
148
+ const result = toJsonValue(await readResult(run.result));
149
+ return {
150
+ ...completedAt ? { completedAt } : {},
151
+ ...createdAt ? { createdAt } : {},
152
+ ...error ? { error } : {},
153
+ id: run.id,
154
+ ...metadata === void 0 ? {} : { metadata },
155
+ provider: run.provider,
156
+ ...result === void 0 ? {} : { result },
157
+ ...startedAt ? { startedAt } : {},
158
+ status: run.status,
159
+ workflow
160
+ };
161
+ }
162
+ function runtimeFailure(operation, provider, error) {
163
+ if (error instanceof WorkflowOperationError) return error;
164
+ const code = errorCode(error);
165
+ if (code === "WORKFLOW_OPERATION_UNSUPPORTED") return new WorkflowOperationError(`workflow ${operation} is not supported by the ${provider} provider for this run.`, 501, code);
166
+ if (code === "WORKFLOW_DISABLED") return new WorkflowOperationError("Workflow is disabled in this runtime.", 409, code, "Enable Workflow with `vitehub({ workflow: true })` or `hubWorkflow()`.");
167
+ if (code === "WORKFLOW_DEFINITION_NOT_FOUND") return new WorkflowOperationError("Workflow definition was not found.", 404, code);
168
+ if (code === "VERCEL_WORKFLOW_SDK_LOAD_FAILED" || code === "WORKFLOW_NATIVE_ENTRY_INVALID" || code === "WORKFLOW_NATIVE_ENTRY_REQUIRED") return new WorkflowOperationError(`workflow ${operation} needs the Vercel Workflow DevKit runtime, which the runtime could not load.`, 501, code);
169
+ if (code === "WORKFLOW_PROVIDER_OPERATION_FAILED") {
170
+ const cause = error instanceof Error ? error.cause : void 0;
171
+ return new WorkflowOperationError(`workflow ${operation} failed in the ${provider} provider.${cause instanceof Error && cause.message ? ` ${redactInspectionText(cause.message)}` : ""}`, 502, code);
172
+ }
173
+ const message = error instanceof Error ? error.message : String(error);
174
+ return new WorkflowOperationError(redactInspectionText(message || "The Workflow operation failed."), 500, code || "WORKFLOW_OPERATION_FAILED");
175
+ }
176
+ function startableWorkflows() {
177
+ return [.../* @__PURE__ */ new Set([...Object.keys(getWorkflowRuntimeRegistry() ?? {}), ...getInlineWorkflowDefinitions().keys()])].sort();
178
+ }
179
+ const startedRuns = /* @__PURE__ */ new Map();
180
+ function rememberRun(id, workflow) {
181
+ startedRuns.delete(id);
182
+ startedRuns.set(id, workflow);
183
+ if (startedRuns.size > maxRememberedRuns) {
184
+ const oldest = startedRuns.keys().next().value;
185
+ if (oldest !== void 0) startedRuns.delete(oldest);
186
+ }
187
+ }
188
+ /**
189
+ * Runs one Workflow operation in the runtime of the app, so it uses the same Workflow state and registry as the app.
190
+ * It redacts credentials in run data and error messages. Failures are `WorkflowOperationError`s.
191
+ */
192
+ async function runWorkflowOperation(operation, input) {
193
+ const runtimeConfig = getWorkflowRuntimeConfig();
194
+ if (runtimeConfig === false) throw new WorkflowOperationError("Workflow is disabled in this runtime.", 409, "WORKFLOW_DISABLED", "Enable Workflow with `vitehub({ workflow: true })` or `hubWorkflow()`.");
195
+ const provider = runtimeConfig?.provider ?? "vercel";
196
+ const support = resolveWorkflowOperationSupport(provider)[operation];
197
+ if (!support.supported) throw new WorkflowOperationError(`workflow ${operation} is not supported by the ${provider} provider. ${support.note}`, 501, "WORKFLOW_OPERATION_UNSUPPORTED");
198
+ try {
199
+ return await run(operation, input);
200
+ } catch (error) {
201
+ throw runtimeFailure(operation, provider, error);
202
+ }
203
+ }
204
+ async function run(operation, input) {
205
+ if (operation === "start") {
206
+ const { payload, workflow } = input;
207
+ const workflows = startableWorkflows();
208
+ if (!workflows.includes(workflow)) {
209
+ if (!getWorkflowRuntimeRegistry()) throw new WorkflowOperationError(`Unknown Workflow: ${workflow}. The runtime has no Workflow registry.`, 409, "WORKFLOW_REGISTRY_MISSING", "Restart the dev server. In development the Workflow Vite plugin installs the registry with the Nitro plugin .vitehub/nitro/workflow/dev-plugin.mjs.");
210
+ throw new WorkflowOperationError(`Unknown Workflow: ${workflow}.${workflows.length ? ` Available Workflows: ${workflows.join(", ")}.` : " The Workflow registry of the runtime is empty."}`, 404, "WORKFLOW_DEFINITION_NOT_FOUND");
211
+ }
212
+ const started = await runWorkflow(workflow, payload);
213
+ rememberRun(started.id, workflow);
214
+ return { run: await toWorkflowRunView(started, workflow) };
215
+ }
216
+ if (operation === "resume") {
217
+ const { payload, token } = input;
218
+ const signal = await resumeWorkflowSignal(token, payload);
219
+ return { signal: {
220
+ id: signal.id,
221
+ provider: signal.provider
222
+ } };
223
+ }
224
+ const { runId, workflow: named } = input;
225
+ const workflow = named ?? startedRuns.get(runId);
226
+ if (!workflow) throw new WorkflowOperationError(`Run ${runId} was not started by \`workflow.start\` in this runtime.`, 400, "WORKFLOW_RUN_UNKNOWN", "Pass the name of the Workflow with `--workflow <name>`.");
227
+ return { run: await toWorkflowRunView(operation === "get" ? await getWorkflowRun(workflow, runId) : await cancelWorkflow(workflow, runId), workflow) };
228
+ }
229
+ //#endregion
230
+ export { WorkflowOperationError, runWorkflowOperation, toWorkflowRunView };