@vite-hub/workflow 0.0.4 → 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.
- package/README.md +34 -14
- package/dist/{_app-DgwN4ulW.d.ts → app-BojnC_yf.d.ts} +1 -4
- package/dist/{app-BZpq2cwC.js → app-CzPoP84f.js} +2 -1
- package/dist/client-DsGM3M4U.js +389 -0
- package/dist/cloudflare-env-BNrYo29x.js +113 -0
- package/dist/{cloudflare-D0Di-QYL.js → cloudflare-nF4abPd4.js} +20 -4
- package/dist/cloudflare-shared-CaxrMD1A.d.ts +1 -0
- package/dist/{cloudflare-vite-BkDgB6Sr.js → cloudflare-vite-B3IabBsv.js} +5 -4
- package/dist/{config-BHknO_rT.js → config-IJMb0eeZ.js} +38 -30
- package/dist/error-diagnostics-A_8Kp-48.js +116 -0
- package/dist/error-diagnostics-pwNFvAHP.js +67 -0
- package/dist/index.d.ts +20 -21
- package/dist/index.js +25 -369
- package/dist/inspect-B72iFyj-.js +70 -0
- package/dist/operations-B_rYG71W.js +230 -0
- package/dist/operations-tNUdj3G4.d.ts +212 -0
- package/dist/operations.d.ts +37 -0
- package/dist/operations.js +887 -0
- package/dist/out-CsaJxg8m.js +21755 -0
- package/dist/rolldown-runtime-CMFfr-1z.js +26 -0
- package/dist/runtime/cloudflare-runner.d.ts +5 -15
- package/dist/runtime/cloudflare-runner.js +40 -5
- package/dist/runtime/cloudflare-shared.d.ts +1 -0
- package/dist/runtime/cloudflare-shared.js +1 -1
- package/dist/runtime/cloudflare-vite.d.ts +8 -10
- package/dist/runtime/cloudflare-vite.js +1 -1
- package/dist/runtime/execute.d.ts +8 -7
- package/dist/runtime/execute.js +28 -5
- package/dist/runtime/openworkflow-worker.d.ts +6 -8
- package/dist/runtime/openworkflow-worker.js +5 -4
- package/dist/runtime/openworkflow.d.ts +8 -10
- package/dist/runtime/openworkflow.js +23 -17
- package/dist/runtime/state.d.ts +20 -21
- package/dist/runtime/state.js +90 -20
- package/dist/runtime/vercel-vite.d.ts +10 -12
- package/dist/runtime/vercel-vite.js +2 -2
- package/dist/runtime-type-DBCvIh5x.js +7 -0
- package/dist/{types-B9RdRkKh.d.ts → types-D82WmfZa.d.ts} +23 -12
- package/dist/{vercel-B0MuIVgJ.js → vercel-D-ZNtB_u.js} +34 -9
- package/dist/vite.d.ts +325 -11
- package/dist/vite.js +1267 -691
- package/package.json +79 -29
- package/dist/cloudflare-env-DjxQNbrx.js +0 -58
- package/dist/cloudflare-shared-BVVgDSdq.d.ts +0 -1
- package/dist/runtime-type-DGUn8Ple.js +0 -37
package/dist/index.js
CHANGED
|
@@ -1,389 +1,45 @@
|
|
|
1
|
-
import { t as normalizeWorkflowOptions } from "./config-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { a as
|
|
5
|
-
import {
|
|
6
|
-
import { runWorkflowHandler } from "./runtime/execute.js";
|
|
7
|
-
import { getOpenWorkflowRun, runOpenWorkflow } from "./runtime/openworkflow.js";
|
|
8
|
-
import { getWorkflowRunState, getWorkflowRuntimeConfig, getWorkflowRuntimeEvent, getWorkflowRuntimeRegistry, loadWorkflowDefinition, registerInlineWorkflowDefinition, runWithWorkflowRuntimeEvent, setWorkflowRun } from "./runtime/state.js";
|
|
9
|
-
import { a as startVercelWorkflow, n as inspectVercelWorkflowRun, r as resumeVercelWorkflowSignal, t as cancelVercelWorkflow } from "./vercel-B0MuIVgJ.js";
|
|
10
|
-
import { t as createWorkflowCloudflareWorker } from "./cloudflare-vite-BkDgB6Sr.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";
|
|
11
6
|
//#region src/definition.ts
|
|
12
7
|
function defineWorkflow(handler, options) {
|
|
13
|
-
if (typeof handler !== "function") throw
|
|
14
|
-
if (typeof options !== "undefined" && (!options || typeof options !== "object" || Array.isArray(options))) throw
|
|
15
|
-
if (options?.native !== void 0 && typeof options.native !== "function") throw
|
|
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." });
|
|
16
11
|
return {
|
|
17
12
|
handler,
|
|
18
13
|
options
|
|
19
14
|
};
|
|
20
15
|
}
|
|
21
16
|
//#endregion
|
|
22
|
-
//#region src/integrations/vercel.ts
|
|
23
|
-
function getVercelWorkflowName(name) {
|
|
24
|
-
return `workflow--${encodeNameHex(name)}`;
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
27
|
-
//#region ../internal/src/runtime/random.ts
|
|
28
|
-
function randomId(prefix) {
|
|
29
|
-
const body = `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
30
|
-
return prefix ? `${prefix}_${body}` : body;
|
|
31
|
-
}
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/runtime/adapters.ts
|
|
34
|
-
function resolveSettlementObserver(event) {
|
|
35
|
-
if (!event || !hasRuntimeType(event, "object")) return void 0;
|
|
36
|
-
const candidate = "settled" in event ? event.settled : void 0;
|
|
37
|
-
if (hasRuntimeType(candidate, "function")) return candidate;
|
|
38
|
-
const context = "context" in event ? event.context : void 0;
|
|
39
|
-
if (!context || !hasRuntimeType(context, "object")) return void 0;
|
|
40
|
-
const nested = "settled" in context ? context.settled : void 0;
|
|
41
|
-
return hasRuntimeType(nested, "function") ? nested : void 0;
|
|
42
|
-
}
|
|
43
|
-
function unsupportedOperation(provider, operation) {
|
|
44
|
-
throw createWorkflowError({
|
|
45
|
-
code: "WORKFLOW_OPERATION_UNSUPPORTED",
|
|
46
|
-
details: {
|
|
47
|
-
operation,
|
|
48
|
-
provider
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
function resolveCloudflareBinding(event, binding, name, definition) {
|
|
53
|
-
const env = getCloudflareEnv(event);
|
|
54
|
-
const bindingName = definition?.internalAgentInvocationRecovery ? getCloudflareWorkflowBindingName(name) : binding || getCloudflareWorkflowBindingName(name);
|
|
55
|
-
return env?.[bindingName];
|
|
56
|
-
}
|
|
57
|
-
function resolveCloudflareInspectionBinding(event, binding, name) {
|
|
58
|
-
return resolveCloudflareBinding(event, binding, name, getWorkflowRuntimeRegistry()?.[name]);
|
|
59
|
-
}
|
|
60
|
-
const cloudflareStatusMap = {
|
|
61
|
-
cancelled: "cancelled",
|
|
62
|
-
complete: "completed",
|
|
63
|
-
completed: "completed",
|
|
64
|
-
errored: "failed",
|
|
65
|
-
failed: "failed",
|
|
66
|
-
queued: "queued",
|
|
67
|
-
running: "running",
|
|
68
|
-
success: "completed",
|
|
69
|
-
terminated: "failed"
|
|
70
|
-
};
|
|
71
|
-
function normalizeCloudflareStatus(status) {
|
|
72
|
-
const value = hasRuntimeType(status, "object") && status ? status.status : status;
|
|
73
|
-
return cloudflareStatusMap[String(value || "").toLowerCase()] || "unknown";
|
|
74
|
-
}
|
|
75
|
-
function hasUnknownWorkflowAcknowledgement(error) {
|
|
76
|
-
if (!error || !hasRuntimeType(error, "object")) return false;
|
|
77
|
-
const details = error.details;
|
|
78
|
-
return Boolean(details && hasRuntimeType(details, "object") && details.acknowledgement === "unknown");
|
|
79
|
-
}
|
|
80
|
-
function createCloudflareAdapter(config) {
|
|
81
|
-
return {
|
|
82
|
-
cancel: () => unsupportedOperation("cloudflare", "cancellation"),
|
|
83
|
-
async get({ event, id, name }) {
|
|
84
|
-
const binding = resolveCloudflareInspectionBinding(event, config.binding, name);
|
|
85
|
-
if (binding) {
|
|
86
|
-
const instance = await runWorkflowProviderOperation("cloudflare", "get", () => binding.get(id));
|
|
87
|
-
const metadata = await runWorkflowProviderOperation("cloudflare", "status", () => instance.status());
|
|
88
|
-
return {
|
|
89
|
-
id,
|
|
90
|
-
metadata,
|
|
91
|
-
provider: "cloudflare",
|
|
92
|
-
status: normalizeCloudflareStatus(metadata)
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
return await inlineAdapter(config).get({
|
|
96
|
-
event,
|
|
97
|
-
id,
|
|
98
|
-
name
|
|
99
|
-
});
|
|
100
|
-
},
|
|
101
|
-
async run({ definition, event, id, name, options, payload }) {
|
|
102
|
-
const binding = resolveCloudflareBinding(event, config.binding, name, definition);
|
|
103
|
-
if (binding) {
|
|
104
|
-
const start = () => runWorkflowProviderOperation("cloudflare", "create", async () => (await binding.createBatch([{
|
|
105
|
-
id,
|
|
106
|
-
params: payload
|
|
107
|
-
}]))[0] || await binding.get(id), { acknowledgementUnknown: (_error, status) => status === void 0 });
|
|
108
|
-
const creation = start().catch(async (firstError) => {
|
|
109
|
-
try {
|
|
110
|
-
return await start();
|
|
111
|
-
} catch (retryError) {
|
|
112
|
-
if (hasUnknownWorkflowAcknowledgement(firstError)) throw firstError;
|
|
113
|
-
throw retryError;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
const waitUntil = options.deferred ? resolveWaitUntil(event) : void 0;
|
|
117
|
-
if (waitUntil) waitUntil(creation);
|
|
118
|
-
return {
|
|
119
|
-
id: (await creation).id,
|
|
120
|
-
payload,
|
|
121
|
-
provider: "cloudflare",
|
|
122
|
-
status: "queued"
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
return await inlineAdapter(config).run({
|
|
126
|
-
definition,
|
|
127
|
-
event,
|
|
128
|
-
id,
|
|
129
|
-
name,
|
|
130
|
-
options,
|
|
131
|
-
payload
|
|
132
|
-
});
|
|
133
|
-
},
|
|
134
|
-
resume: () => unsupportedOperation("cloudflare", "signals")
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
function createOpenWorkflowAdapter(config) {
|
|
138
|
-
return {
|
|
139
|
-
cancel: () => unsupportedOperation("openworkflow", "cancellation"),
|
|
140
|
-
get: async ({ id, name }) => await getOpenWorkflowRun(config, name, id),
|
|
141
|
-
resume: () => unsupportedOperation("openworkflow", "signals"),
|
|
142
|
-
run: async ({ definition, name, options, payload }) => await runOpenWorkflow(config, name, payload, definition, options)
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
function inlineAdapter(config) {
|
|
146
|
-
return {
|
|
147
|
-
cancel: () => unsupportedOperation(config.provider, "cancellation"),
|
|
148
|
-
async get({ id, name }) {
|
|
149
|
-
const run = getWorkflowRunState(name, id);
|
|
150
|
-
if (run) {
|
|
151
|
-
if (run.status === "running") return {
|
|
152
|
-
id,
|
|
153
|
-
provider: config.provider,
|
|
154
|
-
status: "running"
|
|
155
|
-
};
|
|
156
|
-
return {
|
|
157
|
-
id,
|
|
158
|
-
metadata: run.error,
|
|
159
|
-
provider: config.provider,
|
|
160
|
-
result: run.result,
|
|
161
|
-
status: run.status
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
return {
|
|
165
|
-
id,
|
|
166
|
-
provider: config.provider,
|
|
167
|
-
status: "unknown"
|
|
168
|
-
};
|
|
169
|
-
},
|
|
170
|
-
async run({ definition, event, id, name, payload }) {
|
|
171
|
-
const runState = setWorkflowRun(name, id, Promise.resolve().then(() => runWorkflowHandler({
|
|
172
|
-
id,
|
|
173
|
-
name,
|
|
174
|
-
payload,
|
|
175
|
-
provider: config.provider
|
|
176
|
-
}, definition)).then((result) => ({
|
|
177
|
-
result,
|
|
178
|
-
status: "completed"
|
|
179
|
-
})).catch((error) => ({
|
|
180
|
-
error,
|
|
181
|
-
status: "failed"
|
|
182
|
-
})));
|
|
183
|
-
const waitUntil = resolveWaitUntil(event);
|
|
184
|
-
if (waitUntil) waitUntil(runState.promise);
|
|
185
|
-
return {
|
|
186
|
-
id,
|
|
187
|
-
metadata: config.provider === "vercel" ? {
|
|
188
|
-
mode: "inline",
|
|
189
|
-
workflow: getVercelWorkflowName(name)
|
|
190
|
-
} : void 0,
|
|
191
|
-
payload,
|
|
192
|
-
provider: config.provider,
|
|
193
|
-
status: "queued"
|
|
194
|
-
};
|
|
195
|
-
},
|
|
196
|
-
resume: () => unsupportedOperation(config.provider, "signals")
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
function createVercelAdapter(config) {
|
|
200
|
-
const fallback = inlineAdapter(config);
|
|
201
|
-
return {
|
|
202
|
-
async cancel({ id, name }) {
|
|
203
|
-
const definition = await loadWorkflowDefinition(name);
|
|
204
|
-
if (!definition?.options?.native) return await fallback.cancel({
|
|
205
|
-
event: void 0,
|
|
206
|
-
id,
|
|
207
|
-
name
|
|
208
|
-
});
|
|
209
|
-
return await cancelVercelWorkflow(name, definition, id);
|
|
210
|
-
},
|
|
211
|
-
async get({ id, name }) {
|
|
212
|
-
const definition = await loadWorkflowDefinition(name);
|
|
213
|
-
return definition?.options?.native ? await inspectVercelWorkflowRun(name, definition, id) : await fallback.get({
|
|
214
|
-
event: void 0,
|
|
215
|
-
id,
|
|
216
|
-
name
|
|
217
|
-
});
|
|
218
|
-
},
|
|
219
|
-
resume: async (token, payload) => await resumeVercelWorkflowSignal(token, payload),
|
|
220
|
-
async run({ definition, event, id, name, options, payload }) {
|
|
221
|
-
if (!definition.options?.native) return await fallback.run({
|
|
222
|
-
definition,
|
|
223
|
-
event,
|
|
224
|
-
id,
|
|
225
|
-
name,
|
|
226
|
-
options,
|
|
227
|
-
payload
|
|
228
|
-
});
|
|
229
|
-
if (options.id) throw createWorkflowError({
|
|
230
|
-
code: "WORKFLOW_RUN_ID_UNSUPPORTED",
|
|
231
|
-
details: {
|
|
232
|
-
...safeWorkflowName(name) ? { name } : {},
|
|
233
|
-
provider: "vercel"
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
return await startVercelWorkflow(name, definition, payload, resolveSettlementObserver(event));
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
function getWorkflowRuntimeAdapter(config) {
|
|
241
|
-
if (config.provider === "cloudflare") return createCloudflareAdapter(config);
|
|
242
|
-
if (config.provider === "openworkflow") return createOpenWorkflowAdapter(config);
|
|
243
|
-
return createVercelAdapter(config);
|
|
244
|
-
}
|
|
245
|
-
//#endregion
|
|
246
|
-
//#region src/runtime/client.ts
|
|
247
|
-
function getActiveWorkflowConfig() {
|
|
248
|
-
const config = getWorkflowRuntimeConfig();
|
|
249
|
-
if (config === false) return false;
|
|
250
|
-
return config || normalizeWorkflowOptions(void 0, { hosting: "vercel" });
|
|
251
|
-
}
|
|
252
|
-
async function loadRequiredWorkflowDefinition(name) {
|
|
253
|
-
const definition = await loadWorkflowDefinition(name);
|
|
254
|
-
if (!definition) throw createWorkflowError({
|
|
255
|
-
code: "WORKFLOW_DEFINITION_NOT_FOUND",
|
|
256
|
-
details: safeWorkflowName(name) ? { name } : void 0
|
|
257
|
-
});
|
|
258
|
-
return definition;
|
|
259
|
-
}
|
|
260
|
-
function normalizeWorkflowRunIdValue(value) {
|
|
261
|
-
if (value === void 0) return null;
|
|
262
|
-
if (value === null || !hasRuntimeType(value, "object")) return value;
|
|
263
|
-
if (Array.isArray(value)) return value.map((item) => normalizeWorkflowRunIdValue(item));
|
|
264
|
-
const record = value;
|
|
265
|
-
return Object.fromEntries(Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, normalizeWorkflowRunIdValue(record[key])]));
|
|
266
|
-
}
|
|
267
|
-
async function sha256Hex(value) {
|
|
268
|
-
const data = new TextEncoder().encode(value);
|
|
269
|
-
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
270
|
-
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
271
|
-
}
|
|
272
|
-
async function createStableWorkflowRunId(name, value) {
|
|
273
|
-
const hash = await sha256Hex(`${name}:${JSON.stringify(normalizeWorkflowRunIdValue(value))}`);
|
|
274
|
-
return `${name.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "workflow"}-${hash.slice(0, 32)}`;
|
|
275
|
-
}
|
|
276
|
-
async function resolveWorkflowStartOptions(name, payload, createOptions, startOptions) {
|
|
277
|
-
if (startOptions.id || !createOptions?.id) return startOptions;
|
|
278
|
-
return {
|
|
279
|
-
...startOptions,
|
|
280
|
-
id: await createStableWorkflowRunId(name, await createOptions.id({
|
|
281
|
-
name,
|
|
282
|
-
payload
|
|
283
|
-
}))
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
function createWorkflow(nameOrOptions, handlerOrOptions, options) {
|
|
287
|
-
if (hasRuntimeType(nameOrOptions, "object") && nameOrOptions !== null) {
|
|
288
|
-
const createOptions = nameOrOptions;
|
|
289
|
-
const { handler, name } = createOptions;
|
|
290
|
-
if (!name || !hasRuntimeType(name, "string")) throw new TypeError("`createWorkflow()` requires a workflow name.");
|
|
291
|
-
if (!hasRuntimeType(handler, "function")) throw new TypeError("`createWorkflow()` requires a workflow handler.");
|
|
292
|
-
registerInlineWorkflowDefinition(name, {
|
|
293
|
-
handler,
|
|
294
|
-
...createOptions.rootStep === void 0 ? {} : { options: { rootStep: createOptions.rootStep } }
|
|
295
|
-
});
|
|
296
|
-
return {
|
|
297
|
-
cancel: (id) => cancelWorkflow(name, id),
|
|
298
|
-
name,
|
|
299
|
-
defer: async (payload, options = {}) => deferWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options)),
|
|
300
|
-
getRun: (id) => getWorkflowRun(name, id),
|
|
301
|
-
async run(payload, options = {}) {
|
|
302
|
-
return await runWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options));
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
const name = nameOrOptions;
|
|
307
|
-
if (!name || !hasRuntimeType(name, "string")) throw new TypeError("`createWorkflow()` requires a workflow name.");
|
|
308
|
-
const handler = hasRuntimeType(handlerOrOptions, "function") ? handlerOrOptions : hasRuntimeType(handlerOrOptions, "object") && handlerOrOptions !== null ? handlerOrOptions.handler : void 0;
|
|
309
|
-
const createOptions = hasRuntimeType(handlerOrOptions, "function") ? options : handlerOrOptions;
|
|
310
|
-
if (handler !== void 0) {
|
|
311
|
-
if (!hasRuntimeType(handler, "function")) throw new TypeError("`createWorkflow()` requires a workflow handler.");
|
|
312
|
-
registerInlineWorkflowDefinition(name, {
|
|
313
|
-
handler,
|
|
314
|
-
...createOptions?.rootStep === void 0 ? {} : { options: { rootStep: createOptions.rootStep } }
|
|
315
|
-
});
|
|
316
|
-
} else if (handlerOrOptions !== void 0 && (!hasRuntimeType(handlerOrOptions, "object") || handlerOrOptions === null)) throw new TypeError("`createWorkflow()` options must be an object.");
|
|
317
|
-
return {
|
|
318
|
-
cancel: (id) => cancelWorkflow(name, id),
|
|
319
|
-
name,
|
|
320
|
-
defer: async (payload, options = {}) => deferWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options)),
|
|
321
|
-
getRun: (id) => getWorkflowRun(name, id),
|
|
322
|
-
async run(payload, options = {}) {
|
|
323
|
-
return await runWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options));
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
async function runWorkflow(name, payload, options = {}) {
|
|
328
|
-
const config = getActiveWorkflowConfig();
|
|
329
|
-
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
330
|
-
const id = options.id || randomId("wrun");
|
|
331
|
-
const definition = await loadRequiredWorkflowDefinition(name);
|
|
332
|
-
return await getWorkflowRuntimeAdapter(config).run({
|
|
333
|
-
definition,
|
|
334
|
-
event: getWorkflowRuntimeEvent(),
|
|
335
|
-
id,
|
|
336
|
-
name,
|
|
337
|
-
options,
|
|
338
|
-
payload
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
async function getWorkflowRun(name, id) {
|
|
342
|
-
const config = getActiveWorkflowConfig();
|
|
343
|
-
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
344
|
-
return await getWorkflowRuntimeAdapter(config).get({
|
|
345
|
-
event: getWorkflowRuntimeEvent(),
|
|
346
|
-
id,
|
|
347
|
-
name
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
async function cancelWorkflow(name, id) {
|
|
351
|
-
const config = getActiveWorkflowConfig();
|
|
352
|
-
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
353
|
-
await loadRequiredWorkflowDefinition(name);
|
|
354
|
-
return await getWorkflowRuntimeAdapter(config).cancel({
|
|
355
|
-
event: getWorkflowRuntimeEvent(),
|
|
356
|
-
id,
|
|
357
|
-
name
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
async function resumeWorkflowSignal(token, payload) {
|
|
361
|
-
if (!token || !hasRuntimeType(token, "string")) throw new TypeError("`resumeWorkflowSignal()` requires an opaque signal token.");
|
|
362
|
-
const config = getActiveWorkflowConfig();
|
|
363
|
-
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
364
|
-
return await getWorkflowRuntimeAdapter(config).resume(token, payload);
|
|
365
|
-
}
|
|
366
|
-
function deferWorkflow(name, payload, options = {}) {
|
|
367
|
-
return runWithWorkflowRuntimeEvent(getWorkflowRuntimeEvent(), () => runWorkflow(name, payload, {
|
|
368
|
-
...options,
|
|
369
|
-
deferred: true
|
|
370
|
-
}));
|
|
371
|
-
}
|
|
372
|
-
//#endregion
|
|
373
17
|
//#region src/runtime/payload.ts
|
|
374
18
|
async function readRequestPayload(request) {
|
|
375
|
-
if (
|
|
19
|
+
if (request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() === "application/json") return await request.json();
|
|
376
20
|
return await request.text();
|
|
377
21
|
}
|
|
378
22
|
async function validatePayload(payload, schema) {
|
|
379
23
|
if (typeof schema === "function") return await schema(payload);
|
|
380
|
-
if ("safeParse"
|
|
24
|
+
if (hasSchemaMethod(schema, "safeParse") && typeof schema.safeParse === "function") {
|
|
381
25
|
const result = schema.safeParse(payload);
|
|
382
|
-
if (!result.success) throw result.error ||
|
|
26
|
+
if (!result.success) throw result.error || workflowErrorDiagnostics.WORKFLOW_R0021({ message: "Invalid workflow payload." });
|
|
383
27
|
return result.data;
|
|
384
28
|
}
|
|
385
|
-
if ("parse"
|
|
386
|
-
throw
|
|
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;
|
|
387
43
|
}
|
|
388
44
|
async function readValidatedPayload(request, schema) {
|
|
389
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 };
|